+Retrospect Posted December 9, 2021 Share Posted December 9, 2021 Hi everyone. I am working on a possible new game and I wanted the enemies to cascade down the screen with a movement like Centipede. My idea is, the segments move across the screen and only react to anything that isn't character code 32 - space. So if it hits the edges of the walls the segment would move down one character and then move the opposite way. So far all my experiments have one thing in common, they're slow. Even when compiled, specially with player movement and other stuff going on. Does any of you guys know a routine that would work? It would be best using characters to get around TI's wonder 5-in-a-line-and-you're-buggered limitation on "hardware sprites". 1 Quote Link to comment Share on other sites More sharing options...
+TheBF Posted December 9, 2021 Share Posted December 9, 2021 4 hours ago, Retrospect said: Hi everyone. I am working on a possible new game and I wanted the enemies to cascade down the screen with a movement like Centipede. My idea is, the segments move across the screen and only react to anything that isn't character code 32 - space. So if it hits the edges of the walls the segment would move down one character and then move the opposite way. So far all my experiments have one thing in common, they're slow. Even when compiled, specially with player movement and other stuff going on. Does any of you guys know a routine that would work? It would be best using characters to get around TI's wonder 5-in-a-line-and-you're-buggered limitation on "hardware sprites". Could you show us a short video example of what you mean by slow. Not fancy, just one of these things falling down the screen. And maybe show the mission critical part of the code? I am by no means the expert in these things but I have found that when you need the old 99 to go really fast any extra code in the inner loops has a huge impact. ( found this trying to make code that goes as fast as GCC) It could be that the normally acceptable overhead of using arrays for example, as we have in BASIC, or even IF ELSE, is just that little extra that is too much for this application. All that to say you might need a tiny little Assembler routine to push you over the top. 1 Quote Link to comment Share on other sites More sharing options...
+Retrospect Posted December 9, 2021 Author Share Posted December 9, 2021 (edited) As I've screwed up my code and binned it I can't show it, but I can explain what I've done partly. I wanted 16 segments of a centipede-like alien (really just 16 aliens travelling together) ... they start at the top left of the screen, they all have arrays for their positions and mode of travel. DIM AM(16) ! This is Alien Mode , each is set to either 1 or 2 for going left or right DIM AA(16) ! This is Alien Alive, set to 1 if alien is not dead DIM AX(16),AY(16) ! Alien's XY coordinates So the gosub routine was something like this, there's a variable called "C" to count which alien to move next; and let's say char 128 is the segments. And let's assume that AM(xx) is all set to 1 to start with, moving leftwards ..... 4000 C=C+1 4005 IF C>16 THEN C=1 4010 IF AA(C)=0 THEN 4099 4015 ON AM(C) GOTO 4020,4040 4020 CALL HCHAR(AX(C),AY(C),32) :: AY(C)=AY(C)+1 4025 IF AY(C)>31 THEN 4030 ELSE 4035 4030 AX(C)=AX(C)+1 :: AY(C)=AY(C)-1 ::CALL HCHAR(AX(C),AY(C),128) :: AM(C)=2 :: GOTO 4099 ! Sets to mode 2 and return 4035 CALL HCHAR(AX(C),AY(C),128) :: GOTO 4099 4040 CALL HCHAR(AX(C),AY(C),32) :: AY(C)=AY(C)-1 4045 IF AY(C)<2 THEN 4050 ELSE 4055 4050 AX(C)=AX(C)+1 :: AY(C)=AY(C)+1 :: CALL HCHAR(AX(C),AY(C),128) :: AM(C)=1 :: GOTO 4099 ! Sets to mode 1 and return 4055 CALL HCHAR(AX(C),AY(C),128) 4099 RETURN A routine like mine doesn't actually work! So that's why I need help. If anyone's done a centipede-like game before please tell me where I've done wrong. This code is intended to be compiled. I did get one bit of code something similar to this working but it was far from fast enough. Edited December 9, 2021 by Retrospect 1 Quote Link to comment Share on other sites More sharing options...
+OLD CS1 Posted December 9, 2021 Share Posted December 9, 2021 I see a little optimizing I would do. Instead of using 1 and 2 as directional indicators, in my programs I would use -1 and 1, that way just can simply add the direction value to the current location. To change directions, you simply negate the direction value. I set up 16 aliens with random direction, and X,Y in {1..16},{4..28} then let it rip until a key is pressed. There is no checking to see if a space is occupied, some aliens will cause others to disappear as they pass each other, or they might over-lap if traveling in the same direction. The speed still is not great but I have not tried compiling. I have attached a compiled version. (BTW, there is also no test for going off the bottom of the screen, and doing so in XB256 has some interesting effects.) 5 CALL CLEAR 6 RANDOMIZE 10 DIM AM(16),AA(16),AX(16),AY(16) ! SET UP 16 ALIENS WITH RANDOM DIRECTION {-1,1} AND X{1..16),Y{4..28} 20 FOR I=1 TO 16 :: AA(I)=1 :: AM(I)=INT(RND*2)*2-1 :: AX(I)=INT(RND*16)+1 :: AY(I)=INT(RND*25)+4 :: NEXT I 30 GOSUB 4000 :: CALL KEY(0,K,S) :: IF S=0 THEN 30 ELSE STOP 4000 C=C+1+16*(C=16) ! THE MAGIC STARTS HERE 4010 IF AA(C)=0 THEN RETURN 4020 CALL HCHAR(AX(C),AY(C),32):: AY(C)=AY(C)+AM(C) 4025 IF AY(C)>32 OR AY(C)<1 THEN AX(C)=AX(C)+1 :: AY(C)=AY(C)-AM(C):: CALL HCHAR(AX(C),AY(C),30):: AM(C)=-AM(C):: RETURN 4035 CALL HCHAR(AX(C),AY(C),30):: RETURN (EDIT: Removed the C=1 initialization so alien 1 is not skipped the first time around.) (I see another optimization I should have made in the bounds checking... but I do not think it will impact speed.) AL-X 2 Quote Link to comment Share on other sites More sharing options...
+TheBF Posted December 9, 2021 Share Posted December 9, 2021 I was wondering how to do binary wrap-around by masking in BASIC. I tried AND. It does not work for the job. You have the magic here. Well done! 4000 C=C+1+16*(C=16) ! THE MAGIC STARTS HERE 1 Quote Link to comment Share on other sites More sharing options...
+TheBF Posted December 9, 2021 Share Posted December 9, 2021 Now I want to see how much code that generates since the machine can do it on a register in two instructions. On a memory location maybe 4 ? Quote Link to comment Share on other sites More sharing options...
+OLD CS1 Posted December 9, 2021 Share Posted December 9, 2021 1 minute ago, TheBF said: Now I want to see how much code that generates since the machine can do it on a register in two instructions. On a memory location maybe 4 ? Way bloated compared to Forth or assembly. The compiled result is around 6k, which includes the XB support routines -- placing characters on the screen, array variables, &c. Quote Link to comment Share on other sites More sharing options...
+TheBF Posted December 9, 2021 Share Posted December 9, 2021 1 minute ago, OLD CS1 said: Way bloated compared to Forth or assembly. The compiled result is around 6k, which includes the XB support routines -- placing characters on the screen, array variables, &c. That's a nice small runtime block. I was meaning just the expression you wrote. C=C+1+16*(C=16) 2 Quote Link to comment Share on other sites More sharing options...
+Retrospect Posted December 9, 2021 Author Share Posted December 9, 2021 thanks guys ... old cs1 i'll try this routine you sent tomorro as i've ended up going out and getting smashed drunk in town, im too far gone to do anything constructive but that code looks good. i should say tho, the one thing i should have presented was the counter variable C should have started at 16 and counted down to 1 instead of otherway round. i think. 3 Quote Link to comment Share on other sites More sharing options...
+OLD CS1 Posted December 9, 2021 Share Posted December 9, 2021 25 minutes ago, Retrospect said: thanks guys ... old cs1 i'll try this routine you sent tomorro as i've ended up going out and getting smashed drunk in town, im too far gone to do anything constructive but that code looks good. i should say tho, the one thing i should have presented was the counter variable C should have started at 16 and counted down to 1 instead of otherway round. i think. I am envious. Still working on house chores. Maybe a little nip will help with motivation. But, changing the count is easy enough. C=16 C=C-1-16*(C=1) 3 Quote Link to comment Share on other sites More sharing options...
+TheBF Posted December 10, 2021 Share Posted December 10, 2021 2 hours ago, Retrospect said: thanks guys ... old cs1 i'll try this routine you sent tomorro as i've ended up going out and getting smashed drunk in town, im too far gone to do anything constructive but that code looks good. i should say tho, the one thing i should have presented was the counter variable C should have started at 16 and counted down to 1 instead of otherway round. i think. Bodington's or Tetley? Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted December 10, 2021 Share Posted December 10, 2021 6 hours ago, OLD CS1 said: (I see another optimization I should have made in the bounds checking... but I do not think it will impact speed.) Why not from 4025 IF AY(C)>32 OR AY(C)<1 THEN AX(C)=AX(C)+1 :: AY(C)=AY(C)-AM(C):: CALL HCHAR(AX(C),AY(C),30):: AM(C)=-AM(C):: RETURN to 4025 IF AY(C)>32 OR AY(C)<1 THEN AX(C)=AX(C)+1 :: AY(C)=AY(C)-AM(C):: AM(C)=-AM(C) or was that your optimizing thought? ...lee 2 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted December 10, 2021 Share Posted December 10, 2021 7 hours ago, OLD CS1 said: 4000 C=C+1+16*(C=16) ! THE MAGIC STARTS HERE If C were 0-based, i.e., 0 – 15, the above could be changed to 4000 C = (C+1) AND 15 ! THE MAGIC STARTS HERE I do not know whether it is faster, but it should work. Of course it would necessitate changes in initialization code to left-shift the arrays indexed with C. ...lee 3 Quote Link to comment Share on other sites More sharing options...
+TheBF Posted December 10, 2021 Share Posted December 10, 2021 11 hours ago, Lee Stewart said: If C were 0-based, i.e., 0 – 15, the above could be changed to 4000 C = (C+1) AND 15 ! THE MAGIC STARTS HERE I do not know whether it is faster, but it should work. Of course it would necessitate changes in initialization code to left-shift the arrays indexed with C. ...lee I was thinking the same thing yesterday and tried a quick test. It seems I have failed my BASIC test. Too much RPN I guess. I suspect the compiler will generate way better code with your expression and using OPTION BASE 0 arrays. Edit: It occurred to me that @Retrospect might never have encountered this kind of number "wrapping" without using IF THEN so here is some demo code. 10 ! binary wrap demo 20 C=(C+1)AND 15 30 PRINT C; 40 GOTO 20 1 Quote Link to comment Share on other sites More sharing options...
+OLD CS1 Posted December 10, 2021 Share Posted December 10, 2021 11 hours ago, Lee Stewart said: If C were 0-based, i.e., 0 – 15, the above could be changed to 4000 C = (C+1) AND 15 ! THE MAGIC STARTS HERE I do not know whether it is faster, but it should work. Of course it would necessitate changes in initialization code to left-shift the arrays indexed with C. This also works the other way around, since a negative number is all binary ones in the least significant positions. ! TRY THIS IN IMMEDIATE MODE C=15 :: FOR I=1 TO 1000 :: PRINT C :: C=C-1 AND 15 :: NEXT I Of course, this can only work for and upper value of (2^x)-1, where 0 is in the included set of numbers. So, {0..3}, {0..7}, {0..15} .. {0,255} ... Many times I wish XB had included the MOD operator. 12 hours ago, Lee Stewart said: or was that your optimizing thought? Turns out my thought on the additional optimization breaks movement and causes them to run down the screen edge. 2 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted December 10, 2021 Share Posted December 10, 2021 56 minutes ago, OLD CS1 said: Many times I wish XB had included the MOD operator. Me, too! ...lee Quote Link to comment Share on other sites More sharing options...
+Retrospect Posted December 11, 2021 Author Share Posted December 11, 2021 On 12/10/2021 at 1:22 AM, TheBF said: Bodington's or Tetley? Carling. Still unwell. 1 Quote Link to comment Share on other sites More sharing options...
PeteE Posted December 11, 2021 Share Posted December 11, 2021 Here's little centipede movement program I cooked up. The centipede is defined as three arrays: one for x-coordinate, one for y-coordinate, and one for state. State can take one of 4 values: 1 = middle part (nothing changes on screen) 2 = tail part (erases current char) 3 = head moving right (moves right or down if blocked) 4 = head moving left (moves left or down if blocked) The trick is that the states rotate through the array - the head and tail states move into to the previous array index "j", which allows the coordinate arrays to remain largely untouched on each step. 100 randomize::call clear::for i=1 to 100::call hchar(rnd*23+1,rnd*31+1,35)::next i 110 call vchar(1,1,35,24)::call vchar(1,32,35,24) 120 dim cx(20),cy(20),cs(20)::for i=1 to 20::cx(i)=2::cy(i)=1::cs(i)=1::next i::cs(1)=2::cs(2)=3::j=20 130 for i=1 to 20::on cs(i) goto 230,220,150,180 140 rem right-moving head state=3 150 x=cx(i)::y=cy(i)::call hchar(y,x,48)::cs(i)=1::call gchar(y,x+1,c)::if c<>32 then cs(j)=4::goto 200 160 call hchar(y,x+1,62)::cx(j)=x+1::cy(j)=y::cs(j)=3::goto 230 170 rem left-moving head state=4 180 x=cx(i)::y=cy(i)::call hchar(y,x,48)::cs(i)=1::call gchar(y,x-1,c)::if c<>32 then cs(j)=3::goto 200 190 call hchar(y,x-1,60)::cx(j)=x-1::cy(j)=y::cs(j)=4::goto 230 200 if (y=24) then y=0 201 call hchar(y+1,x,86)::cx(j)=x::cy(j)=y+1::goto 230 210 rem tail state=2 220 call hchar(cy(i),cx(i),32)::cs(j)=2::cs(i)=1 230 j=i::next i::goto 130 This can theoretically handle multiple heads and tails. If a player bullet hits a centipede part, find the index at that location and change the state to a head, and the next state a tail. 7 Quote Link to comment Share on other sites More sharing options...
+RXB Posted December 11, 2021 Share Posted December 11, 2021 On 12/10/2021 at 7:07 AM, Lee Stewart said: Me, too! ...lee I am right now writing a CALL MOD(number,divisor,result) in RXB 2021 2 Quote Link to comment Share on other sites More sharing options...
+OLD CS1 Posted December 11, 2021 Share Posted December 11, 2021 44 minutes ago, RXB said: I am right now writing a CALL MOD(number,divisor,result) in RXB 2021 Any way to make that a function which can be called in-line with a mathematical formula? 1 Quote Link to comment Share on other sites More sharing options...
+RXB Posted December 11, 2021 Share Posted December 11, 2021 3 hours ago, OLD CS1 said: Any way to make that a function which can be called in-line with a mathematical formula? I still am stuck trying to figure out how to add tokens to XB, all my attempts have crashed. 1 Quote Link to comment Share on other sites More sharing options...
+Retrospect Posted December 12, 2021 Author Share Posted December 12, 2021 20 hours ago, RXB said: all my attempts have crashed I can so relate to that, but with different things! Quote Link to comment Share on other sites More sharing options...
+RXB Posted December 12, 2021 Share Posted December 12, 2021 Just now, Retrospect said: I can so relate to that, but with different things! Yea was hoping Lee could help me figure out the Assembly ROMs. 1 Quote Link to comment Share on other sites More sharing options...
+TheBF Posted December 12, 2021 Share Posted December 12, 2021 23 hours ago, OLD CS1 said: Any way to make that a function which can be called in-line with a mathematical formula? Ahh ... if only we had a programmable programming language ... Quote Link to comment Share on other sites More sharing options...
+Retrospect Posted December 12, 2021 Author Share Posted December 12, 2021 Here's PeteE's centipede program running compiled recorded on JS99er! Goes like the clappers! js99er-20211212192027.webm 7 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.