Opry99er Posted March 13, 2018 Share Posted March 13, 2018 majestyx, the compiler now handles more complex IF THEN statements since falcons last release. Your suggestion with the ON DS is a good one. Quote Link to comment Share on other sites More sharing options...
majestyx Posted March 13, 2018 Share Posted March 13, 2018 majestyx, the compiler now handles more complex IF THEN statements since falcons last release. Really? When did this happen and how did I miss it? (not trying to hijack the thread - just wondering where this new version is) Quote Link to comment Share on other sites More sharing options...
Omega-TI Posted March 13, 2018 Share Posted March 13, 2018 Really? When did this happen and how did I miss it? (not trying to hijack the thread - just wondering where this new version is) << CLICK HERE >> to go to message #1 in this thread. It was last updated today. Quote Link to comment Share on other sites More sharing options...
Opry99er Posted March 13, 2018 Share Posted March 13, 2018 I think he is looking for the new compiler Quote Link to comment Share on other sites More sharing options...
Opry99er Posted March 13, 2018 Share Posted March 13, 2018 http://atariage.com/forums/topic/224905-xb-game-developers-package/?fromsearch=1 1 Quote Link to comment Share on other sites More sharing options...
unhuman Posted March 13, 2018 Share Posted March 13, 2018 This code: 890 IF (MX>8)*(MX<14) THEN MX=9900 IF (MX>28)*(MX<40) THEN MX=33910 IF (MX>50)*(MX<64) THEN MX=57920 IF (MX>75)*(MX<89) THEN MX=81930 IF (MX>103)*(MX<121) THEN MX=113940 IF (MX>123)*(MX<136) THEN MX=129950 IF (MX>138)*(MX<152) THEN MX=148960 IF (MX>161)*(MX<177) THEN MX=169970 IF (MX>186)*(MX<199) THEN MX=193980 IF (MX>210)*(MX<224) THEN MX=217990 IF (MX>225)*(MX<233) THEN MX=233 Could be reworked as:1 DIM MX1(11)::DIM MX2(11)::DIM MX3(11)::MX1(0)=8::MX2(0)=14::MX3(0)=9.... You could also use data statements. 890 FOR I=0 TO 10::IF (MX>MX1(I)*(MX<MX2(I)) THEN MX=MX3(I)::GOTO 892 891 NEXT I 892 REM continue on... We have short circuited all the conditionals. Video should be working now YouTube marked it private for some reason So put the sprite positions for the robots and bats in a 2 dimensional array and check against that? Is that what you guys are saying? Something like XX(ROW,COL), Storing all the the intersection locations in that to check against. Do I have that right? And would that improve speed as well? 2 Quote Link to comment Share on other sites More sharing options...
LASooner Posted March 13, 2018 Author Share Posted March 13, 2018 Got it, Thanks 2 Quote Link to comment Share on other sites More sharing options...
LASooner Posted March 14, 2018 Author Share Posted March 14, 2018 Really? When did this happen and how did I miss it? (not trying to hijack the thread - just wondering where this new version is) You go to sleep in this forum and the world changes a week later. Senior Falcon is the man. His new Game Dev kit, makes compiling almost a completely friction free experience. 2 Quote Link to comment Share on other sites More sharing options...
Airshack Posted March 14, 2018 Share Posted March 14, 2018 Wow LASooner! This is really already a fairly magnificent achievement. Your rendition of the game is simply beautiful! Here's a video for any of you out there whom haven't seen the original (1982) Night Stalker game on Intellivision: Being a long-time fan of the system, I absolutely love playing Night Stalker. Definitely one of the best games on the Intellivision. LASooner has nailed the look-sound-feel of the original game. BRAVO Sir! Especially notable: Love the Intellivision running man character and the spot-on: Maze, Gun, Spiders (better actually) and Robots... to include Spot-On Robot explosions. Sweet! Pulsing beat in the background? It's here too! The original game felt sluggish on Intellivision so I really don't feel like you're too far off on the pacing. Especially since yours is written in a variant of XB. Sure, it's compiled..but hey. I encourage you to continue to refine this game and show-off what can be done with Senior Falcon's XB256+Compiler tools. Very cool of you to post the code which will not only allow others to help optimize your code but will also allow noobs to learn from your experience! Again, BRAVO! WE NEED MORE BASIC PROGRAMMERS TRYING OUT THE AMAZING TOOLS SENIOR FALCON HAS PROVIDED. You even incorporated box art into the intro screen?! You ROCK! Learn more...wiki: https://en.wikipedia.org/wiki/Night_Stalker_(video_game) 3 Quote Link to comment Share on other sites More sharing options...
LASooner Posted March 14, 2018 Author Share Posted March 14, 2018 Wow LASooner! This is really already a fairly magnificent achievement. Your rendition of the game is simply beautiful! Here's a video for any of you out there whom haven't seen the original (1982) Night Stalker game on Intellivision: Being a long-time fan of the system, I absolutely love playing Night Stalker. Definitely one of the best games on the Intellivision. LASooner has nailed the look-sound-feel of the original game. BRAVO Sir! Especially notable: Love the Intellivision running man character and the spot-on: Maze, Gun, Spiders (better actually) and Robots... to include Spot-On Robot explosions. Sweet! Pulsing beat in the background? It's here too! The original game felt sluggish on Intellivision so I really don't feel like you're too far off on the pacing. Especially since yours is written in a variant of XB. Sure, it's compiled..but hey. I encourage you to continue to refine this game and show-off what can be done with Senior Falcon's XB256+Compiler tools. Very cool of you to post the code which will not only allow others to help optimize your code but will also allow noobs to learn from your experience! Again, BRAVO! WE NEED MORE BASIC PROGRAMMERS TRYING OUT THE AMAZING TOOLS SENIOR FALCON HAS PROVIDED. You even incorporated box art into the intro screen?! You ROCK! Learn more...wiki: https://en.wikipedia.org/wiki/Night_Stalker_(video_game) That game play looks sped up, am I crazy? Or maybe it's because I've been playing my dogsh*t slow version so much lately. :-) Thanks for the kind words shack, you've been a lot of help with the XB256 stuff Quote Link to comment Share on other sites More sharing options...
+OLD CS1 Posted March 14, 2018 Share Posted March 14, 2018 When converting my game from BASIC to XB I changed all of the mathematical logic statements in my IF-THENs to actual logic operators OR and AND. It will save a few bytes here and there, make it easier to read, and may even help execution speed (like that will matter when compiled, right?) So the code: 890 IF (MX>8 )*(MX<14) THEN MX=9900 IF (MX>28)*(MX<40) THEN MX=33910 IF (MX>50)*(MX<64) THEN MX=57920 IF (MX>75)*(MX<89) THEN MX=81930 IF (MX>103)*(MX<121) THEN MX=113940 IF (MX>123)*(MX<136) THEN MX=129950 IF (MX>138)*(MX<152) THEN MX=148960 IF (MX>161)*(MX<177) THEN MX=169970 IF (MX>186)*(MX<199) THEN MX=193980 IF (MX>210)*(MX<224) THEN MX=217990 IF (MX>225)*(MX<233) THEN MX=233 Could all be re-worked as 890 IF MX>8 AND MX<14 THEN MX=9 900 IF MX>28 AND MX<40 THEN MX=33 910 IF MX>50 AND MX<64 THEN MX=57 etc... Also, I spend a lot of time finding relationships and patterns, and sometimes reworking things to produce them, so I can use long mathematical formulas to produce desired results. Though I really recommend against that as it does tend to drive me bonkers and I get overly obsessed with it. So like here, spacing for your target values is 24 apart (9, 33, 57, 81, 133, ..., 217, 233) Find a way to quantify your testing ranges and you can give each range a value to multiply by 24 and add 9 ( MX=r*24+9, r=[0..10] ) Or, like I said, spare your sanity. 1 Quote Link to comment Share on other sites More sharing options...
LASooner Posted March 14, 2018 Author Share Posted March 14, 2018 (edited) Updated Rom Image Find space or make new title screen Title screen is back I took the suggestion to use variable arrays for the maze constraints and intersections, and got a lot of memory back, the speed is about the same though. When converting my game from BASIC to XB I changed all of the mathematical logic statements in my IF-THENs to actual logic operators OR and AND. It will save a few bytes here and there, make it easier to read, and may even help execution speed (like that will matter when compiled, right?) So the code: 890 IF (MX>8 )*(MX<14) THEN MX=9900 IF (MX>28)*(MX<40) THEN MX=33910 IF (MX>50)*(MX<64) THEN MX=57920 IF (MX>75)*(MX<89) THEN MX=81930 IF (MX>103)*(MX<121) THEN MX=113940 IF (MX>123)*(MX<136) THEN MX=129950 IF (MX>138)*(MX<152) THEN MX=148960 IF (MX>161)*(MX<177) THEN MX=169970 IF (MX>186)*(MX<199) THEN MX=193980 IF (MX>210)*(MX<224) THEN MX=217990 IF (MX>225)*(MX<233) THEN MX=233 Could all be re-worked as 890 IF MX>8 AND MX<14 THEN MX=9 900 IF MX>28 AND MX<40 THEN MX=33 910 IF MX>50 AND MX<64 THEN MX=57 etc... Also, I spend a lot of time finding relationships and patterns, and sometimes reworking things to produce them, so I can use long mathematical formulas to produce desired results. Though I really recommend against that as it does tend to drive me bonkers and I get overly obsessed with it. So like here, spacing for your target values is 24 apart (9, 33, 57, 81, 133, ..., 217, 233) Find a way to quantify your testing ranges and you can give each range a value to multiply by 24 and add 9 ( MX=r*24+9, r=[0..10] ) Or, like I said, spare your sanity. Senior Falcon had posted the opposite of this in some other message thread. That is why I went with using * for AND and + for OR because he said it saved a little bit of memory. Is that not right? Here's the link: http://atariage.com/forums/topic/273371-4k-shortnsweet-game-contest/page-8?do=findComment&comment=3974965 Edited March 14, 2018 by LASooner Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted March 14, 2018 Share Posted March 14, 2018 Senior Falcon had posted the opposite of this in some other message thread. That is why I went with using * for AND and + for OR because he said it saved a little bit of memory. Is that not right? http://atariage.com/forums/topic/273371-4k-shortnsweet-game-contest/page-8?do=findComment&comment=3974965 That quote had to do with saving memory in the TI BASIC program that Owen was writing. I don't know if it saves memory over using the more versatile TI XB IF/THEN/ELSE format. Also, it may not save memory when you compile the program - I don't know without trying out a test program. Quote Link to comment Share on other sites More sharing options...
Airshack Posted March 14, 2018 Share Posted March 14, 2018 Many thanks to the Falconator (Aka Senior Falcon) for providing awesome BASIC extensions and Compiler tools, and for updating them and enhancing the usability of his Game Developers Toolkit! I really think if Retro fans outside the TI community get exposed to this stuff it will generate a significantly increased buzz for the platform. Maybe we can get Randy Kindig from the FloppyDays podcast to interview Harry? As usual, there’s probably minimal awareness out there regarding the amazing progress being made with TI tools and even the new hardware. Hats off to all the creatives who keep the TI-99/4A fascinating. Sent from my iPad using Tapatalk 1 Quote Link to comment Share on other sites More sharing options...
LASooner Posted March 14, 2018 Author Share Posted March 14, 2018 (edited) Here's my updated code TID Bit: ///////////////////////////////////////////////////////////////////////////////////////////// // NIGHT STALKER TI 99/4a // --------------------------------------------------------------------------- // By John McGinley (AtariAge:LASOONER) // 3/14/2018 // // VARIABLE LIST // --------------------------- // SCR = Score // SCOR$ = Score Print String // P = Players left // B = Bullets left // DS = Player Death state (0-Alive, 1-Dead, 2-Stunned, 3-Game Over) // FRM = Animation Frame Number // M = Enemy Array Value // A = Variable for FOR/NEXT loop // BA(1) = Active Bullet State Player // BA(2) = Active Bullet State Main Robot // BA(3) = Active Bullet State Second Robot // BA(4) = Active Bullet State Third Robot // S = Fire Button State // RBT = Robot Character Value // BAT1A = Bat1/2nd Robot Character Value // BAT2A = Bat2/3rd Robot Character Value // GP = Gun Position Spawn Location Value // GPX = Gun Position Spawn X // GPY = Gun Position Spawn Y // PKX = Player Sprite Coincidence Value X // PKY = Player Sprite Coincidence Value Y // MX = Player Sprite Position X // MY = Player Sprite Position Y // PX = Joystick Value Left/Right // PY = Joystick Value Up/Down // AN = Animation Character offset // GA(1) = Player GCHAR Y Offset 1 // GA(2) = Player GCHAR X Offset 1 // GA(3) = Player GCHAR Y Offset 2 // GA(4) = Player GCHAR X Offset 2 // MZ1 = Maze Character Check 1 // MZ2 = Maze Character Check 2 // DD = Player Death Animation Frame // DW = Player After Death Respawn delay // ST = Player Stunner Animation Frame // SW = Player After Stun Recovery delay // BD(1) = Bullet Direction Player // BD(2) = Bullet Direction Main Robot // BD(3) = Bullet Direction 2nd Robot // BD(4) = Bullet Direction 3rd Robot // BYO(1) = Bullet Origin Y Player // BXO(1) = Bullet Origin X Player // BYO(2) = Bullet Origin Y Main Robot // BXO(2) = Bullet Origin X Main Robot // BYO(3) = Bullet Origin Y 2nd Robot // BXO(3) = Bullet Origin X 2nd Robot // BYO(4) = Bullet Origin Y 3rd Robot // BXO(5) = Bullet Origin X 3rd Robot // BLY(1) = Bullet Position Y Player // BLX(1) = Bullet Position X Player // BLY(2) = Bullet Position Y Main Robot // BLX(2) = Bullet Position X Main Robot // BLY(3) = Bullet Position Y 2nd Robot // BLX(3) = Bullet Position X 2nd Robot // BLY(4) = Bullet Position Y 3rd Robot // BLX(5) = Bullet Position X 3rd Robot // DR(1) = Main Robot Death State (0-Alive, 1-Dead) // DR(2) = Bat1/2nd Robot Death State (0-Alive, 1-Dead) // DR(3) = Bat2/3rd Robot Death State (0-Alive, 1-Dead) // DR(4) = Spider Death State (0-Alive, 1-Dead) // BC = Bullet Collision GCHAR check upper/left // BC1 = Bullet Collision GCHAR check upper/right // BC2 = Bullet Collision GCHAR check lower/left // BC3 = Bullet Collision GCHAR check lower/right // GC = Gun Pick Up Coincidence Value // PV(1) = Robot Point Value // PV(2) = Bat1/Robot 2 Point Value // PV(3) = Bat2/Robot 3 Point Value // PV(4) = Spider Point Value // RY(1) = Main Robot Y Position // RX(1) = Main Robot X Position // RP(1) = Main Robot Direction // RS(1) = Main Robot Speed // RY(2) = Bat1/2nd Robot Y Position // RX(2) = Bat1/2nd Robot X Position // RP(2) = Bat1/2nd Robot Direction // RS(2) = Bat1/2nd Robot Speed // RY(3) = Bat2/3rd Robot Y Position // RX(3) = Bat2/3rd X Position // RP(3) = Bat2/3rd Direction // RS(3) = Bat2/3rd Speed // RY(4) = Spider Y Position // RX(4) = Spider X Position // RP(4) = Spider Direction // RS(4) = Spider Speed // RBC = Main Robot Color // RD(1) = Main Robot Direction Multiplier // RD(2) = Bat1/2nd Direction Multiplier // RD(3) = Bat2/3rd Direction Multiplier // RD(4) = Spider Direction Multiplier // RC = Intersection Direction Value // DRW = Main Robot Respawn Delay // // Audio VDP Addresses // ------------------- // Shooting=2832 // Pick Up Item=2760 // Player Spawn=2649 // Bat Explosion=2585 // Robot Explosion=2513 // Heartbeat=2432 // Theme Music=2930 // ///////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////// // / // / // / // / / // TITLE SCREEN / // / // / // / // / ///////////////////////////////////////////////////////////////////////////////////////////// DIM BA(5),GA(4),BD(4),BXO(4),BYO(4),BLY(4),BLX(4),DR(4),PV(4),RY(4),RX(4),RS(4),RP(4),RD(4),DRW(4) DIM YA(7),YB(7),YC(7),XA(11),XB(11),XC(11),I1A(6),I2A(4),I3A(5),I4A(7),I5A(3),I6A(5),I7A(3),I8A(3) DIM I1B(6), I2B(4),I3B(5),I4B(7),I5B(3),I6B(5),I7B(3),I8B(3) CALL LINK("SCRN2") :: CALL SCREEN(2) :: CALL MAGNIFY (3) ::CALL CLEAR :: GOSUB _SETMAZEDATALIMITS :: RANDOMIZE :: GOSUB _SOUNDS //:: CALL LINK("PLAY",2930) :: GOSUB _TITLE //_TITLEPAUSE: //CALL LINK("DELAY",6000) _GAMESTART: CALL SCREEN(2):: CALL CLEAR :: SCR=0 :: P=5 :: B=0 :: DS=0 :: FRM=0 :: CDT=0 :: BNK=1 :: GOSUB _SPRITES ///////////////////////////////////////////////////////////////////////////////////////////// // / // / // / // / / // SET UP SPRITES AND MAZE / // / // / // / // / ///////////////////////////////////////////////////////////////////////////////////////////// _CREATESPRITES: CALL LINK("PLAY",0) :: GOSUB _MAZE :: CALL LINK("PLAY",2432) :: GOSUB _SHOWBUNKERSPRITES :: GOSUB _SPAWNPLAYER :: GOSUB _SPAWNSPIDER :: GOSUB _SPAWNROBOT :: GOSUB _SPAWNBAT1 :: GOSUB _SPAWNBAT2 CALL LINK("DISPLY",1,31,CHR$(48+B)) :: CALL LINK("DISPLY",1,14,CHR$(,1,6) :: FOR A=1 TO 4 :: BA(A)=0 :: NEXT A :: GOSUB _GUNPOS2 :: CALL LOAD(-1,5) ///////////////////////////////////////////////////////////////////////////////////////////// // / // / // / // / / // GAME LOOP / // / // / // / // / ///////////////////////////////////////////////////////////////////////////////////////////// _LOOP: M=M+1 :: IF M=5 THEN M=1 ON M GOSUB _FRAME1,_FRAME2,_FRAME1,_FRAME2 :: GOSUB _MOVECHARACTER :: GOSUB _MOVEROBOT :: GOSUB _HITDETECTION :: GOSUB _CHARACTERCOLLISION IF BA(M)=1 THEN GOSUB _SHOOTMOVE IF BNK=1 AND BDW=1 THEN GOSUB _SHOWBUNKERSPRITES IF BNK=0 AND BDW=0 THEN GOSUB _HIDEBUNKERSPRITES IF (S>0)*(BA(1)=0) THEN GOSUB _SHOOT IF BA(M+1)=0 THEN GOSUB _ROBOTSHOOT CALL LINK("SYNC") :: GOTO _LOOP ///////////////////////////////////////////////////////////////////////////////////////////// // / // / // / // / / // ANIMATION FRAMES / // / // / // / // / ///////////////////////////////////////////////////////////////////////////////////////////// _FRAME1: CALL PATTERN(#4,RBT,#5,BAT1A,#6,BAT2A,#7,SPIDA) :: IF B>0 THEN RETURN CALL LINK("COLOR2",-1,12,5) :: RETURN //Gun Flash 1 _FRAME2: CALL PATTERN(#4,RBT+4,#5,BAT1B,#6,BAT2B,#7,SPIDB) IF B>0 THEN RETURN CALL LINK("COLOR2",-1,5,5) :: RETURN //Gun Flash 2 ///////////////////////////////////////////////////////////////////////////////////////////// // / // / // / // / / // GUN SPAWNING / // / // / // / // / ///////////////////////////////////////////////////////////////////////////////////////////// _SPAWNGUN: CALL LINK("IRND",9,GP) :: IF GP>4 THEN GP=GP/2 ON GP+1 GOTO _GUNPOS1,_GUNPOS2,_GUNPOS3,_GUNPOS4,_GUNPOS5 _GUNPOS1: GPX=15 :: GPY=13 :: PKX=113 :: PKY=97 :: GOTO _DISPLAYGUN _GUNPOS2: GPX=15 :: GPY=7 :: PKX=113 :: PKY=49 :: GOTO _DISPLAYGUN _GUNPOS3: GPX=29 :: GPY=21 :: PKX=225 :: PKY=161 :: GOTO _DISPLAYGUN _GUNPOS4: GPX=28 :: GPY=7 :: PKX=217 :: PKY=49 :: GOTO _DISPLAYGUN _GUNPOS5: GPX=5 :: GPY=21 :: PKX=33 :: PKY=161 :: GOTO _DISPLAYGUN _DISPLAYGUN: CALL LINK("DISPLY",GPY,GPX,CHR$(16)) :: CALL LINK("DISPLY",GPY,GPX+1,CHR$(18)) :: CALL LINK("DISPLY",GPY+1,GPX,CHR$(17)) :: CALL LINK("DISPLY",GPY+1,GPX+1,CHR$(19)) :: RETURN _CLEARGUN: CALL LINK("PLAY",2760) :: CALL LINK("DISPLY",GPY,GPX,CHR$(32),1,2) :: CALL LINK("DISPLY",GPY+1,GPX,CHR$(32),1,2) :: RETURN ///////////////////////////////////////////////////////////////////////////////////////////// // / // / // / // / / // PLAYER MOVEMENT / // / // / // / // / ///////////////////////////////////////////////////////////////////////////////////////////// _DEADSTATE: ON DS GOSUB _DEAD,_STUNNED,_GAMEOVER :: RETURN _MOVECHARACTER: CALL POSITION(#3,MY,MX) IF DS>0 THEN GOTO _DEADSTATE _KEEPMOVING: IF B=0 THEN GOSUB _CHECKGUN CALL KEY(1,K,S) :: CALL JOYST(1,PX,PY) :: AN=AN+4 :: IF (PX=0)*(PY=0) THEN _STAND IF PX<0 THEN _RUNLEFT IF PX>0 THEN _RUNRIGHT IF PY<0 THEN _RUNDN IF PY>0 THEN _RUNUP _RUNLEFT: IF AN>12 THEN AN=0 CALL PATTERN(#3,32+AN) :: PY=0 :: GOSUB _MAZEHORZ _COLMAP: GA(1)=1 :: GA(2)=1 :: GA(3)=2 :: GA(4)=1 :: GOSUB _GRAPHICCHK IF (MZ1=32)*(MZ2=32) THEN GOSUB _LEFT IF (MZ1>15)*(MZ1<20)*(MZ2>15)*(MZ2<20) THEN GOSUB _LEFT IF (MX>33)*(MY>33) THEN _LEFTEND IF (MZ1>31)*(MZ1<47)*(MZ2>31)*(MZ2<47) THEN GOSUB _WEBLEFT _LEFTEND: GOTO _MOVERETURN _RUNRIGHT: IF AN>12 THEN AN=0 CALL PATTERN(#3,48+AN) :: PY=0 :: GOSUB _MAZEHORZ _COLMAP2: GA(1)=1 :: GA(2)=3 :: GA(3)=2 :: GA(4)=3 :: GOSUB _GRAPHICCHK IF (MZ1=32)*(MZ2=32) THEN GOSUB _RIGHT IF (MZ1>15)*(MZ1<20)*(MZ2>15)*(MZ2<20) THEN GOSUB _RIGHT IF (MX>33)*(MY>33) THEN _RIGHTEND IF (MZ1>31)*(MZ1<47)*(MZ2>31)*(MZ2<47) THEN GOSUB _WEBRIGHT _RIGHTEND: GOTO _MOVERETURN _RUNUP: IF AN>4 THEN AN=0 CALL PATTERN(#3,68+AN) :: PX=0 :: GOSUB _MAZEVERT _COLMAP4: GA(1)=1 :: GA(2)=1 :: GA(3)=1 :: GA(4)=2 :: GOSUB _GRAPHICCHK IF (MZ1=32)*(MZ2=32) THEN GOSUB _UP IF (MZ1>15)*(MZ1<20)*(MZ2>15)*(MZ2<20) THEN GOSUB _UP IF (MX>33)*(MY>33) THEN _UPEND IF (MZ1>31)*(MZ1<47)*(MZ2>31)*(MZ2<47) THEN GOSUB _WEBUP _UPEND: GOTO _MOVERETURN _RUNDN: IF AN>4 THEN AN=0 CALL PATTERN(#3,68+AN) :: PX=0 :: GOSUB _MAZEVERT _COLMAP6: GA(1)=3 :: GA(2)=1 :: GA(3)=3 :: GA(4)=2 :: GOSUB _GRAPHICCHK IF (MZ1=32)*(MZ2=32) THEN GOSUB _DOWN IF (MZ1>15)*(MZ1<20) THEN GOSUB _DOWN IF (MX>33)*(MY>33) THEN _DNEND IF (MZ1>31)*(MZ1<47)*(MZ2>31)*(MZ2<47) THEN GOSUB _WEBDOWN _DNEND: GOTO _MOVERETURN _GRAPHICCHK: CALL GCHAR(INT(MY/8)+GA(1),INT(MX/8)+GA(2),MZ1) :: CALL GCHAR(INT(MY/8)+GA(3),INT(MX/8)+GA(4),MZ2) :: RETURN _MAZEHORZ: FOR A=1 TO 7 :: IF MY>YA(A) AND MY<YB(A) THEN MY=YC(A) NEXT A :: IF (MX>97)*(MX<137)*(MY>41)*(MY<89) THEN _DRAWBUNKERTOKEN IF (MX<97)+(MX>137) THEN _HIDEBUNKERTOKEN ELSE RETURN _DRAWBUNKERTOKEN: BNK=1 :: BDW=1 :: RETURN _HIDEBUNKERTOKEN: BNK=0 :: BDW=0 :: RETURN _MAZEVERT: FOR A=1 TO 11 :: IF MX>XA(A) AND MX<XB(A) THEN MX=XC(A) NEXT A :: RETURN ////////////////////////////////////////////////////////////// // // // // // // // PLAYER ANIMATIONS // // // // // // // ////////////////////////////////////////////////////////////// _STAND: CALL PATTERN(#3,64) :: AN=-4 :: GOTO _MOVERETURN //Set Dead anim frames and Wait before respawn _DEAD: DS=1 :: DD=DD+1 :: DW=DW+1 :: IF DW=15 THEN _RESETPLAYER IF DD>2 THEN DD=1 ON DD GOSUB _DEADFRAME1,_DEADFRAME2 :: CALL LINK("PLAY",2649) :: RETURN //Set Stunned anim frames and Wait before respawn _STUNNED: DS=2 :: ST=ST+1 :: SW=SW+1 :: IF SW=60 THEN DS=0 :: ST=0 :: SW=0 :: RETURN IF ST=4 THEN ST=3 ON ST GOSUB _STUNFRAME1,_STUNFRAME2,_STUNFRAME3 :: RETURN _DEADFRAME1: DF1=48 :: DF2=12 :: GOTO _DEADSTATEDRAW _DEADFRAME2: DF1=48 :: DF2=9 :: GOTO _DEADSTATEDRAW _STUNFRAME1: DF1=76 :: DF2=12 :: GOTO _DEADSTATEDRAW _STUNFRAME2: DF1=80 :: DF2=12 :: GOTO _DEADSTATEDRAW _STUNFRAME3: DF1=84 :: DF2=12 :: GOTO _DEADSTATEDRAW _DEADSTATEDRAW: CALL SPRITE(#3,DF1,DF2,MY,MX) :: RETURN _RESETPLAYER: DW=0 :=P-1 :: B=0 :: DD=0 :: BNK=1 :: BDW=1 IF P<0 THEN DS=3 :: CALL LINK("DISPLY",1,28,CHR$(48)) :: RETURN CALL LINK("DISPLY",1,28,CHR$(48+P)) :: GOSUB _CLEARGUN :: CALL LINK("DISPLY",1,31,CHR$(48+B)) :: GOSUB _SPAWNGUN :: GOSUB _SPAWNPLAYER :: RETURN _MOVERETURN: IF PX=0 AND PY=0 THEN RETURN _LIMITS: IF MY<17 THEN MY=17 IF MY>161 THEN MY=161 IF MX<9 THEN MX=9 IF MX>233 THEN MX=233 _POSITION: CALL LOCATE(#3,MY,MX) :: RETURN _GAMEOVER: CALL LINK("PLAY",0) :: CALL DELSPRITE (#3) :: CALL LINK("DISPLY",14,12,"GAME OVER") :: CALL KEY(1,K,S) :: IF S=0 THEN _GAMEOVER CALL DELSPRITE (ALL) :: GOTO _GAMESTART _DOWN: BD(1)=3 :: MY=MY+2 :: RETURN _UP: BD(1)=1 :: MY=MY-2 :: RETURN _LEFT: BD(1)=4 :: MX=MX-2 :: RETURN _RIGHT: BD(1)=2 :: MX=MX+2 :: RETURN _WEBDOWN: MY=MY+1 :: RETURN _WEBUP: MY=MY-1 :: RETURN _WEBLEFT: MX=MX-1 :: RETURN _WEBRIGHT: MX=MX+1 :: RETURN ///////////////////////////////////////////////////////////////////////////////////////////// // / // / // / // / / // PLAYER SHOOTING / // / // / // / // / ///////////////////////////////////////////////////////////////////////////////////////////// _SHOOT: IF B=0 THEN RETURN BYO(1)=0 :: BXO(1)=0 :: ON BD(1) GOTO _BULLETUP,_BULLETRT,_BULLETDN,_BULLETLT _BULLETUP: BYO(1)=-1 :: GOSUB _BULLETDIRECTION :: RETURN _BULLETRT: BXO(1)=1 :: GOSUB _BULLETDIRECTION :: RETURN _BULLETDN: BYO(1)=1 :: GOSUB _BULLETDIRECTION :: RETURN _BULLETLT: BXO(1)=-1 :: GOSUB _BULLETDIRECTION :: RETURN _BULLETDIRECTION: BA(1)=1 :: BLY(1)=MY+BYO(1) :: BLX(1)=MX+BXO(1) :: B=B-1 :: IF B=0 THEN GOSUB _SPAWNGUN CALL LINK("DISPLY",1,31,CHR$(48+B)) :: CALL LINK("PLAY",2832) :: CALL SPRITE (#8,96,10,BLY(1),BLX(1)) :: RETURN ///////////////////////////////////////////////////////////////////////////////////////////// // / // / // / // / / // ROBOT SHOOTING / // / // / // / // / ///////////////////////////////////////////////////////////////////////////////////////////// _ROBOTSHOOT: IF M=4 THEN RETURN IF DR(M)=1 THEN RETURN GOTO _NOBATS _ROBOTSHOOTRTN: IF M+1=5 THEN RETURN IF BA(M+1)=1 THEN RETURN BYO(M+1)=0 :: BXO(M+1)=0 :: IF (RX(M)>MX-16)*(RX(M)<MX+16) THEN _ROBOTSHOTUPDN IF (RY(M)>MY-16)*(RY(M)<MY+16) THEN _ROBOTSHOTLEFTRIGHT RETURN _ROBOTSHOTDRAW: BA(M+1)=1 :: BLY(M+1)=RY(M)+BYO(M+1) :: BLX(M+1)=RX(M)+BXO(M+1) :: CALL LINK("PLAY",2832) :: CALL SPRITE (#8+M,96,10,BLY(M+1),BLX(M+1)) :: RETURN ////////////////////////////////////// // // // ROBOT BULLET Direction // // // ////////////////////////////////////// //Robot Shoots UP if player is UP, Robot Shoots DOWN if player is DOWN _ROBOTSHOTUPDN: IF RY(M)>MY THEN BYO(M+1)=-1 ELSE BYO(M+1)=1 GOTO _ROBOTSHOTDRAW //Robot Shoots Left if player is left, Robot Shoots Right if player is right _ROBOTSHOTLEFTRIGHT: IF RX(M)>MX THEN BXO(M+1)=-1 ELSE BXO(M+1)=1 GOTO _ROBOTSHOTDRAW _NOBATS: IF (M=2)*(BAT1A=140) THEN RETURN IF (M=3)*(BAT2A=116) THEN RETURN ELSE _ROBOTSHOOTRTN ///////////////////////////////////////////////////////////////////////////////////////////// // / // / // / // / / // MOVE BULLET / // / // / // / // / ///////////////////////////////////////////////////////////////////////////////////////////// _SHOOTMOVE: IF (BA(M)=0)+(M=5) THEN RETURN IF (M=3)*(BAT1A=140) THEN RETURN IF (M=4)*(BAT2A=116) THEN RETURN IF BYO(M)=-1 THEN BLD(M)=-1 :: GOTO _BULUPDN IF BXO(M)=1 THEN BLD(M)=1 :: GOTO _BULLEFTRIGHT IF BYO(M)=1 THEN BLD(M)=1 :: GOTO _BULUPDN IF BXO(M)=-1 THEN BLD(M)=-1 :: GOTO _BULLEFTRIGHT _BULUPDN: BLY(M)=BLY(M)+8*BLD(M) :: GOTO _BULPOSITION _BULLEFTRIGHT: BLX(M)=BLX(M)+8*BLD(M) _BULPOSITION: FOR A=1 TO 4 :: IF BA(A)=1 THEN CALL LOCATE(#7+A,BLY(A),BLX(A)) NEXT A IF (BLY(M)<17)+(BLY(M)>161)+(BLX(M)<9)+(BLX(M)>233) THEN GOSUB _BULKILL IF (BLY(M)<65)*(BLY(M)>55)*(BLX(M)>88)*(BLX(M)<138) THEN GOSUB _BULKILL CALL GCHAR(INT(BLY(M)/8)+1,INT(BLX(M)/8)+1,BC) :: CALL GCHAR(INT(BLY(M)/8)+2,INT(BLX(M)/8)+1,BC1) CALL GCHAR(INT(BLY(M)/8)+1,INT(BLX(M)/8)+2,BC2) :: CALL GCHAR(INT(BLY(M)/8)+2,INT(BLX(M)/8)+2,BC3) IF (BC<>32)+(BC1<>32)+(BC2<>32)+(BC3<>32) THEN _BULPENITRATION RETURN _BULKILL: CALL DELSPRITE (#7+M) :: BA(M)=0 :: BLY(M)=0 :: BLX(M)=0 :: RETURN _BULPENITRATION: IF (BC>15)*(BC<20) THEN RETURN ELSE _BP1 _BP1: IF (BC1>15)*(BC1<20) THEN RETURN ELSE _BP2 _BP2: IF (BC2>15)*(BC2<20) THEN RETURN ELSE _BP3 _BP3: IF (BC3>15)*(BC3<20) THEN RETURN ELSE _BULKILL _CHECKGUN: CALL COINC(#3,PKY,PKX,4,GC) :: IF GC=0 THEN RETURN CALL LINK("PLAY",2760) :: GOSUB _CLEARGUN :: B=6 :: CALL LINK("DISPLY",1,31,CHR$(48+B)) :: RETURN ///////////////////////////////////////////////////////////////////////////////////////////// // / // / // / // / / // HIT DETECTION / // / // / // / // / ///////////////////////////////////////////////////////////////////////////////////////////// _HITDETECTION: IF DS=1 THEN _BADGUYS FOR A=2 TO 4 IF (BLY(A)>MY-*(BLY(A)<MY+*(BLX(A)>MX-*(BLX(A)<MX+ THEN DS=1 :: IF M>2 THEN _ROBOTHIT NEXT A _BADGUYS: ON M GOTO _ROBOTHIT,_BAT1HIT,_BAT2HIT,_SPIDERHIT _ROBOTHIT: IF DR(1)=1 THEN RETURN IF (BLY(1)>RY(1)-*(BLY(1)<RY(1)+*(BLX(1)>RX(1)-*(BLX(1)<RX(1)+ THEN _ROBOTSHOT ELSE RETURN _BAT1HIT: IF DR(2)=1 THEN RETURN IF (BLY(1)>RY(2)-*(BLY(1)<RY(2)+*(BLX(1)>RX(2)-*(BLX(1)<RX(2)+ THEN _BATSHOT1 ELSE RETURN _BAT2HIT: IF DR(3)=1 THEN RETURN IF (BLY(1)>RY(3)-*(BLY(1)<RY(3)+*(BLX(1)>RX(3)-*(BLX(1)<RX(3)+ THEN _BATSHOT2 ELSE RETURN _SPIDERHIT: IF DR(4)=1 THEN RETURN IF (BLY(1)>RY(4)-*(BLY(1)<RY(4)+*(BLX(1)>RX(4)-*(BLX(1)<RX(4)+ THEN _SPIDERSHOT ELSE RETURN RETURN _ROBOTSHOT: HP=HP-1 :: IF HP<0 THEN _SHIELDSDOWN CALL SPRITE(#16,92,12,RY(1),RX(1)) :: CALL LINK("PLAY",2760) :: CALL DELSPRITE (#8,#16) :: BA(1)=0 :: BLY(1)=0 :: BLX(1)=0 :: RBC=16 :: RETURN _SHIELDSDOWN: N=1 :: DR(1)=1 :: RBT=120 ::CALL SPRITE(#12,128,RBC,RY(1),RX(1),-3,3) ::CALL MOTION(#4,-3,-3) :: GOTO _UPDATESCORE _BATSHOT1: N=2 :: DR(2)=1 :: BAT1A=120 :: BAT1B=124 :: GOTO _DRAWDEADBAT _BATSHOT2: N=3 :: DR(3)=1 :: BAT2A=120 :: BAT2B=124 :: GOTO _DRAWDEADBAT _SPIDERSHOT: N=4 :: DR(4)=1 :: SPIDA=120 :: SPIDB=124 :: GOTO _DRAWDEADBAT _DRAWDEADBAT: CALL SPRITE(#3+N,120,10,RY(N),RX(N)) :: GOTO _UPDATESCORE _UPDATESCORE: RX(N)=6 :: RY(N)=6 :: CALL LINK("PLAY",2513) :: SCR=SCR+PV(N) :: SCOR$=STR$(SCR)&"00" :: CALL LINK("DISPLY",1,14,SCOR$):: RETURN _CHARACTERCOLLISION: IF (DS=1)+(DS=2) THEN RETURN IF (RY(M)>MY-12)*(RY(M)<MY+12)*(RX(M)>MX-12)*(RX(M)<MX+12) THEN _STUNCHK ELSE RETURN _STUNCHK: IF M=1 THEN DS=1 IF SCR<50 THEN _BATSTUN IF (BS1=2)*(M=2) THEN DS=1 IF (BS2=2)*(M=3) THEN DS=1 DS=2 :: RETURN _BATSTUN: IF M>1 THEN DS=2 RETURN ///////////////////////////////////////////////////////////////////////////////////////////// // / // / // / // / / // SPAWNS / // / // / // / // / ///////////////////////////////////////////////////////////////////////////////////////////// _SPAWNPLAYER: CALL SPRITE(#3,64,12,73,113) :: CALL LINK("PLAY",2649) :: DS=0 :: RETURN _SPAWNROBOT: //Robot RY(1)=161 :: RX(1)=17 :: RP(1)=2 IF SCR>=800 THEN _SPAWNINVS IF SCR>=300 THEN _SPAWNBLACK IF SCR>=150 THEN _SPAWNWHITE IF SCR>=50 THEN _SPAWNBLUE RBT=100 :: RBC=15 :: PV(1)=3 :: RS(1)=2 :: HP=0 _DRAWROBOT: CALL SPRITE(#4,RBT,RBC,RY(1),RX(1)) :: RETURN _SPAWNBLUE: GOSUB _ADVROBOT :: RBC=6 :: PV(1)=5 :: HP=0 :: GOTO _DRAWROBOT _SPAWNWHITE: GOSUB _WHITEROBOTSPRITE :: GOSUB _ADVROBOT :: RBC=16 :: PV(1)=10 :: HP=2 :: GOTO _DRAWROBOT _SPAWNBLACK: GOSUB _BLACKROBOTSPRITE :: GOSUB _ADVROBOT :: RBC=2 :: PV(1)=20 :: HP=2 :: GOTO _DRAWROBOT _SPAWNINVS: GOSUB _ADVROBOT :: RBC=1 :: PV(1)=40 :: HP=2 :: GOTO _DRAWROBOT _ADVROBOT: RBT=108 :: RS(1)=4 :: RETURN _SPAWNBAT1: //Bat 1/ Robot 2 IF SCR<50 THEN _BAT1 ELSE _RB2 _BAT1: BAT1A=140 :: BAT1B=116 :: RY(2)=49 :: RX(2)=217 :: RP(2)=4 :: RS(2)=2 :: PV(2)=2 :: BS1=1 :: CALL SPRITE(#5,BAT1A,2,RY(2),RX(2)) :: RETURN _RB2: BAT1A=100 :: BAT1B=104 :: RY(2)=161 :: RX(2)=17 :: RP(2)=2 :: RS(2)=2 :: PV(2)=3 :: BS1=2 :: CALL SPRITE(#5,BAT1A,15,RY(2),RX(2)) :: RETURN _SPAWNBAT2: //Bat 2/ Robot 3 IF SCR<50 THEN _BAT2 ELSE _RB3 _BAT2: BAT2A=116 :: BAT2B=140 :: RY(3)=113 :: RX(3)=209 :: RP(3)=2 :: RS(3)=2 :: PV(3)=2 :: BS2=1 :: CALL SPRITE(#6,BAT2A,2,RY(3),RX(3)) :: RETURN _RB3: BAT2A=104 :: BAT2B=100 :: RY(3)=161 :: RX(3)=17 :: RP(3)=2 :: RS(3)=2 :: PV(3)=3 :: BS2=2 :: CALL SPRITE(#6,BAT2A,15,RY(3),RX(3)) :: RETURN _SPAWNSPIDER: //Spider SPIDA=132 :: SPIDB=136 :: RY(4)=49 :: RX(4)=9 :: RP(4)=3 :: RS(4)=2 :: PV(4)=2 :: CALL SPRITE(#7,SPIDA,4,RY(4),RX(4)) :: RETURN ///////////////////////////////////////////////////////////////////////////////////////////// // / // / // / // / / // MOVE ROBOT SUBROUTINE / // / // / // / // / ///////////////////////////////////////////////////////////////////////////////////////////// _MOVEROBOT: IF (M=1)*(DR(1)=1) THEN _ROBOTDEATH IF (M=2)*(DR(2)=1) THEN _BAT1DEATH IF (M=3)*(DR(3)=1) THEN _BAT2DEATH IF (M=4)*(DR(4)=1) THEN _SPIDDEATH _MVBACK: GOSUB _MAZECHECK :: ON RP(M) GOTO _MOVROBOTUP,_MOVROBOTRT,_MOVROBOTDN,_MOVROBOTLT _MOVROBOTUP: RD(M)=-1 :: GOTO _ROBOTUPDN _MOVROBOTRT: RD(M)=1 :: GOTO _ROBOTLEFTRIGHT _MOVROBOTDN: RD(M)=1 :: GOTO _ROBOTUPDN _MOVROBOTLT: RD(M)=-1 :: GOTO _ROBOTLEFTRIGHT _ROBOTUPDN: RY(M)=RY(M)+RS(M)*RD(M) :: GOTO _ROBOTPOSITION _ROBOTLEFTRIGHT: RX(M)=RX(M)+RS(M)*RD(M) _ROBOTPOSITION: CALL LOCATE(#M+3,RY(M),RX(M)) :: RETURN ///////////////////////////////////////////////////////////////////////////////////////////// // / / // ROBOT DECISION TREES / // / ///////////////////////////////////////////////////////////////////////////////////////////// _MAZECHECK: IF (RX(M)=9)*(RY(M)=161) THEN RP(M)=2 :: RETURN FOR A=1 TO 6 :: IF RX(M)=I1A(A) AND RY(M)=I1B(A) THEN _INTERSECTION1 NEXT A FOR A=1 TO 4 :: IF RX(M)=I2A(A) AND RY(M)=I2B(A) THEN _INTERSECTION2 NEXT A FOR A=1 TO 5 :: IF RX(M)=I3A(A) AND RY(M)=I3B(A) THEN _INTERSECTION3 NEXT A FOR A=1 TO 7 :: IF RX(M)=I4A(A) AND RY(M)=I4B(A) THEN _INTERSECTION4 NEXT A FOR A=1 TO 3 :: IF RX(M)=I5A(A) AND RY(M)=I5B(A) THEN _INTERSECTION5 NEXT A FOR A=1 TO 5 :: IF RX(M)=I6A(A) AND RY(M)=I6B(A) THEN _INTERSECTION6 NEXT A FOR A=1 TO 3 :: IF RX(M)=I7A(A) AND RY(M)=I7B(A) THEN _INTERSECTION7 NEXT A FOR A=1 TO 3 :: IF RX(M)=I8A(A) AND RY(M)=I8B(A) THEN _INTERSECTION8 NEXT A RETURN _RND3: CALL LINK("IRND",4,RC) :: RC=RC+1:: RETURN _INTERSECTION1: GOSUB _LEVELCHK :: ON RC GOTO _INUP,_INRT,_INDN,_INRT _INTERSECTION2: GOSUB _LEVELCHK :: ON RC GOTO _INUP,_INLT,_INDN,_INLT _INTERSECTION3: GOSUB _LEVELCHK :: ON RC GOTO _INDN,_INRT,_INDN,_INLT _INTERSECTION4: GOSUB _LEVELCHK :: ON RC GOTO _INUP,_INRT,_INUP,_INLT _INTERSECTION5: GOSUB _LEVELCHK :: ON RC GOTO _INDN,_INRT,_INDN,_INRT _INTERSECTION6: GOSUB _LEVELCHK :: ON RC GOTO _INDN,_INLT,_INDN,_INLT _INTERSECTION7: GOSUB _LEVELCHK :: ON RC GOTO _INUP,_INRT,_INUP,_INRT _INTERSECTION8: GOSUB _LEVELCHK :: ON RC GOTO _INUP,_INLT,_INUP,_INLT _LEVELCHK: IF (M=1)*(RS(1)=4) THEN GOSUB _CHASE ELSE GOSUB _RND3 RETURN _INTERSECTIONDIRECTIONS: _INUP: RP(M)=1 :: RETURN _INRT: RP(M)=2 :: RETURN _INDN: RP(M)=3 :: RETURN _INLT: RP(M)=4 :: RETURN _CHASE: IF (RY(1)>MY-32)*(RY(1)<MY+32)*(RX(1)<MX) THEN RC=2 :: RETURN IF (RY(1)>MY-32)*(RY(1)<MY+32)*(RX(1)>MX) THEN RC=4 :: RETURN IF (RX(1)>MX-32)*(RX(1)<MX+32)*(RY(1)>MY) THEN RC=1 :: RETURN IF (RX(1)>MX-32)*(RX(1)<MX+32)*(RY(1)<MY) THEN RC=3 :: RETURN GOSUB _RND3 :: RETURN ///////////////////////////////////////////////////////////////////////////////////////////// // / // / // / // / / // ROBOT DEATH / // / // / // / // / ///////////////////////////////////////////////////////////////////////////////////////////// _ROBOTDEATH: //Set Dead anim frames and Wait before respawn DR(1)=1 :: DRW(1)=DRW(1)+1 :: IF DRW(1)<10 THEN RETURN DR(1)=0 :: DRW(1)=0 :: CALL DELSPRITE(#4,#12) :: GOTO _SPAWNROBOT _BAT1DEATH: DR(2)=1 :: DRW(2)=DRW(2)+1 :: IF DRW(2)<10 THEN RETURN DR(2)=0 :: DRW(2)=0 :: CALL DELSPRITE(#5) :: GOTO _SPAWNBAT1 _BAT2DEATH: DR(3)=1 :: DRW(3)=DRW(3)+1 :: IF DRW(3)<10 THEN RETURN DR(3)=0 :: DRW(3)=0 :: CALL DELSPRITE(#6) :: GOTO _SPAWNBAT2 _SPIDDEATH: DR(4)=1 :: DRW(4)=DRW(4)+1 :: IF DRW(4)<10 THEN RETURN DR(4)=0 :: DRW(4)=0 :: CALL DELSPRITE(#5) :: GOTO _SPAWNSPIDER ///////////////////////////////////////////////////////////////////////////////////////////// // / // / // / // / / // READ DATA SUBROUTINES / // / // / // / // / ///////////////////////////////////////////////////////////////////////////////////////////// _MAZE: RESTORE 30001 :: GOTO _READDATA //_TITLE: //RESTORE 10001 :: GOTO _READDATA _SPRITES: RESTORE 20001 :: GOTO _READDATA _WHITEROBOTSPRITE: RESTORE 30501 :: GOTO _READDATA _BLACKROBOTSPRITE: RESTORE 30531 :: GOTO _READDATA _SOUNDS: RESTORE 30602 :: GOTO _READDATA _READDATA: READ A$ :: IF A$="" THEN _READDATADONE :: CALL LINK("CWRITE",A$) :: GOTO _READDATA _READDATADONE: RETURN ///////////////////////////////////////////////////////////////////////////////////////////// // / // / // / // / / // MAZE DATA / // / // / // / // / ///////////////////////////////////////////////////////////////////////////////////////////// _SETMAZEDATALIMITS: RESTORE _PLAYERMAZELIMITS FOR MD=1 TO 7 :: READ MDA,MDB,MDC :: YA(MD)=MDA :: YB(MD)=MDB :: YC(MD)=MDC :: NEXT MD FOR MD=1 TO 11 :: READ MDA,MDB,MDC :: XA(MD)=MDA :: XB(MD)=MDB :: XC(MD)=MDC :: NEXT MD FOR MD=1 TO 6 :: READ MDA,MDB :: I1A(MD)=MDA :: I1B(MD)=MDB :: NEXT MD FOR MD=1 TO 4 :: READ MDA,MDB :: I2A(MD)=MDA :: I2B(MD)=MDB :: NEXT MD FOR MD=1 TO 5 :: READ MDA,MDB :: I3A(MD)=MDA :: I3B(MD)=MDB :: NEXT MD FOR MD=1 TO 7 :: READ MDA,MDB :: I4A(MD)=MDA :: I4B(MD)=MDB :: NEXT MD FOR MD=1 TO 3 :: READ MDA,MDB :: I5A(MD)=MDA :: I5B(MD)=MDB :: NEXT MD FOR MD=1 TO 5 :: READ MDA,MDB :: I6A(MD)=MDA :: I6B(MD)=MDB :: NEXT MD FOR MD=1 TO 3 :: READ MDA,MDB :: I7A(MD)=MDA :: I7B(MD)=MDB :: NEXT MD FOR MD=1 TO 3 :: READ MDA,MDB :: I8A(MD)=MDA :: I8B(MD)=MDB :: NEXT MD RETURN _PLAYERMAZELIMITS: DATA 14,26,17,43,57,49,73,87,81,91,109,97,107,114,113,123,148,129,153,180,161 DATA 8,14,9,28,40,33,50,64,57,75,89,81,103,121,113,123,136,129,138,152,148 DATA 161,177,169,186,199,193,210,224,217,225,233,233 _ROBOTMAZELIMITS: DATA 33,81,57,49,57,129,81,97,169,129,169,81,33,129,57,81,169,97,233,113 DATA 81,49,129,17,169,17,193,17,217,49,57,161,81,129,129,49,145,97,145,161,169,161,217,81 DATA 9,17,57,17,193,113,33,17,145,49,145,129,233,17,233,81,9,129,33,161,193,49 DATA 193,129,233,49,233,161 ///////////////////////////////////////////////////////////////////////////////////////////// // / // / // / // / / // BUNKER SPRITES / // / // / // / // / ///////////////////////////////////////////////////////////////////////////////////////////// _SHOWBUNKERSPRITES: CALL SPRITE(#1,88,6,65,113,#2,92,6,81,113) CALL LINK("DISPLY",9,15,CHR$(32),1,2) :: CALL LINK("DISPLY",10,15,CHR$(32),1,2) :: CALL LINK("DISPLY",11,15,CHR$(32),1,2) :: BDW=0 :: RETURN _HIDEBUNKERSPRITES: CALL LINK("DISPLY",9,15,CHR$(5),1,2) :: CALL LINK("DISPLY",10,15,CHR$(6),1,2) :: CALL LINK("DISPLY",11,15,CHR$(0),1,2) :: CALL DELSPRITE (#1,#2) BDW=1 :: RETURN Here's the translated Basic Code 100 DIM BA(5),GA(4),BD(4),BXO(4),BYO(4),BLY(4),BLX(4),DR(4),PV(4),RY(4),RX(4),RS(4),RP(4),RD(4),DRW(4) 110 DIM YA(7),YB(7),YC(7),XA(11),XB(11),XC(11),I1A(6),I2A(4),I3A(5),I4A(7),I5A(3),I6A(5),I7A(3),I8A(3) 120 DIM I1B(6),I2B(4),I3B(5),I4B(7),I5B(3),I6B(5),I7B(3),I8B(3) 130 CALL LINK("SCRN2")::CALL SCREEN(2)::CALL MAGNIFY (3)::CALL CLEAR::GOSUB 2830::RANDOMIZE::GOSUB 2800 140 CALL SCREEN(2)::CALL CLEAR::SCR=0:=5::B=0::DS=0::FRM=0::CDT=0::BNK=1::GOSUB 2770 150 CALL LINK("PLAY",0)::GOSUB 2760::CALL LINK("PLAY",2432)::GOSUB 3020::GOSUB 1980::GOSUB 2170::GOSUB 1990::GOSUB 2110::GOSUB 2140 160 CALL LINK("DISPLY",1,31,CHR$(48+B))::CALL LINK("DISPLY",1,14,CHR$(,1,6)::FOR A=1 TO 4::BA(A)=0::NEXT A::GOSUB 330::CALL LOAD(-1,5) 170 M=M+1::IF M=5 THEN M=1 180 ON M GOSUB 250,270,250,270::GOSUB 400::GOSUB 2180::GOSUB 1670::GOSUB 1890 190 IF BA(M)=1 THEN GOSUB 1430 200 IF BNK=1 AND BDW=1 THEN GOSUB 3020 210 IF BNK=0 AND BDW=0 THEN GOSUB 3040 220 IF (S>0)*(BA(1)=0) THEN GOSUB 1200 230 IF BA(M+1)=0 THEN GOSUB 1280 240 CALL LINK("SYNC")::GOTO 170 250 CALL PATTERN(#4,RBT,#5,BAT1A,#6,BAT2A,#7,SPIDA)::IF B>0 THEN RETURN 260 CALL LINK("COLOR2",-1,12,5)::RETURN 270 CALL PATTERN(#4,RBT+4,#5,BAT1B,#6,BAT2B,#7,SPIDB) 280 IF B>0 THEN RETURN 290 CALL LINK("COLOR2",-1,5,5)::RETURN 300 CALL LINK("IRND",9,GP)::IF GP>4 THEN GP=GP/2 310 ON GP+1 GOTO 320,330,340,350,360 320 GPX=15::GPY=13::PKX=113::PKY=97::GOTO 370 330 GPX=15::GPY=7::PKX=113::PKY=49::GOTO 370 340 GPX=29::GPY=21::PKX=225::PKY=161::GOTO 370 350 GPX=28::GPY=7::PKX=217::PKY=49::GOTO 370 360 GPX=5::GPY=21::PKX=33::PKY=161::GOTO 370 370 CALL LINK("DISPLY",GPY,GPX,CHR$(16))::CALL LINK("DISPLY",GPY,GPX+1,CHR$(18))::CALL LINK("DISPLY",GPY+1,GPX,CHR$(17))::CALL LINK("DISPLY",GPY+1,GPX+1,CHR$(19))::RETURN 380 CALL LINK("PLAY",2760)::CALL LINK("DISPLY",GPY,GPX,CHR$(32),1,2)::CALL LINK("DISPLY",GPY+1,GPX,CHR$(32),1,2)::RETURN 390 ON DS GOSUB 890,920,1100::RETURN 400 CALL POSITION(#3,MY,MX) 410 IF DS>0 THEN GOTO 390 420 IF B=0 THEN GOSUB 1650 430 CALL KEY(1,K,S)::CALL JOYST(1,PX,PY)::AN=AN+4::IF (PX=0)*(PY=0) THEN 880 440 IF PX<0 THEN 480 450 IF PX>0 THEN 560 460 IF PY<0 THEN 720 470 IF PY>0 THEN 640 480 IF AN>12 THEN AN=0 490 CALL PATTERN(#3,32+AN)::PY=0::GOSUB 810 500 GA(1)=1::GA(2)=1::GA(3)=2::GA(4)=1::GOSUB 800 510 IF (MZ1=32)*(MZ2=32) THEN GOSUB 1140 520 IF (MZ1>15)*(MZ1<20)*(MZ2>15)*(MZ2<20) THEN GOSUB 1140 530 IF (MX>33)*(MY>33) THEN 550 540 IF (MZ1>31)*(MZ1<47)*(MZ2>31)*(MZ2<47) THEN GOSUB 1180 550 GOTO 1040 560 IF AN>12 THEN AN=0 570 CALL PATTERN(#3,48+AN)::PY=0::GOSUB 810 580 GA(1)=1::GA(2)=3::GA(3)=2::GA(4)=3::GOSUB 800 590 IF (MZ1=32)*(MZ2=32) THEN GOSUB 1150 600 IF (MZ1>15)*(MZ1<20)*(MZ2>15)*(MZ2<20) THEN GOSUB 1150 610 IF (MX>33)*(MY>33) THEN 630 620 IF (MZ1>31)*(MZ1<47)*(MZ2>31)*(MZ2<47) THEN GOSUB 1190 630 GOTO 1040 640 IF AN>4 THEN AN=0 650 CALL PATTERN(#3,68+AN)::PX=0::GOSUB 860 660 GA(1)=1::GA(2)=1::GA(3)=1::GA(4)=2::GOSUB 800 670 IF (MZ1=32)*(MZ2=32) THEN GOSUB 1130 680 IF (MZ1>15)*(MZ1<20)*(MZ2>15)*(MZ2<20) THEN GOSUB 1130 690 IF (MX>33)*(MY>33) THEN 710 700 IF (MZ1>31)*(MZ1<47)*(MZ2>31)*(MZ2<47) THEN GOSUB 1170 710 GOTO 1040 720 IF AN>4 THEN AN=0 730 CALL PATTERN(#3,68+AN)::PX=0::GOSUB 860 740 GA(1)=3::GA(2)=1::GA(3)=3::GA(4)=2::GOSUB 800 750 IF (MZ1=32)*(MZ2=32) THEN GOSUB 1120 760 IF (MZ1>15)*(MZ1<20) THEN GOSUB 1120 770 IF (MX>33)*(MY>33) THEN 790 780 IF (MZ1>31)*(MZ1<47)*(MZ2>31)*(MZ2<47) THEN GOSUB 1160 790 GOTO 1040 800 CALL GCHAR(INT(MY/8)+GA(1),INT(MX/8)+GA(2),MZ1)::CALL GCHAR(INT(MY/8)+GA(3),INT(MX/8)+GA(4),MZ2)::RETURN 810 FOR A=1 TO 7::IF MY>YA(A) AND MY<YB(A) THEN MY=YC(A) 820 NEXT A::IF (MX>97)*(MX<137)*(MY>41)*(MY<89) THEN 840 830 IF (MX<97)+(MX>137) THEN 850 ELSE RETURN 840 BNK=1::BDW=1::RETURN 850 BNK=0::BDW=0::RETURN 860 FOR A=1 TO 11::IF MX>XA(A) AND MX<XB(A) THEN MX=XC(A) 870 NEXT A::RETURN 880 CALL PATTERN(#3,64)::AN=-4::GOTO 1040 890 DS=1::DD=DD+1::DW=DW+1::IF DW=15 THEN 1010 900 IF DD>2 THEN DD=1 910 ON DD GOSUB 950,960::CALL LINK("PLAY",2649)::RETURN 920 DS=2::ST=ST+1::SW=SW+1::IF SW=60 THEN DS=0::ST=0::SW=0::RETURN 930 IF ST=4 THEN ST=3 940 ON ST GOSUB 970,980,990::RETURN 950 DF1=48::DF2=12::GOTO 1000 960 DF1=48::DF2=9::GOTO 1000 970 DF1=76::DF2=12::GOTO 1000 980 DF1=80::DF2=12::GOTO 1000 990 DF1=84::DF2=12::GOTO 1000 1000 CALL SPRITE(#3,DF1,DF2,MY,MX)::RETURN 1010 DW=0:=P-1::B=0::DD=0::BNK=1::BDW=1 1020 IF P<0 THEN DS=3::CALL LINK("DISPLY",1,28,CHR$(48))::RETURN 1030 CALL LINK("DISPLY",1,28,CHR$(48+P))::GOSUB 380::CALL LINK("DISPLY",1,31,CHR$(48+B))::GOSUB 300::GOSUB 1980::RETURN 1040 IF PX=0 AND PY=0 THEN RETURN 1050 IF MY<17 THEN MY=17 1060 IF MY>161 THEN MY=161 1070 IF MX<9 THEN MX=9 1080 IF MX>233 THEN MX=233 1090 CALL LOCATE(#3,MY,MX)::RETURN 1100 CALL LINK("PLAY",0)::CALL DELSPRITE (#3)::CALL LINK("DISPLY",14,12,"GAME OVER")::CALL KEY(1,K,S)::IF S=0 THEN 1100 1110 CALL DELSPRITE (ALL)::GOTO 140 1120 BD(1)=3::MY=MY+2::RETURN 1130 BD(1)=1::MY=MY-2::RETURN 1140 BD(1)=4::MX=MX-2::RETURN 1150 BD(1)=2::MX=MX+2::RETURN 1160 MY=MY+1::RETURN 1170 MY=MY-1::RETURN 1180 MX=MX-1::RETURN 1190 MX=MX+1::RETURN 1200 IF B=0 THEN RETURN 1210 BYO(1)=0::BXO(1)=0::ON BD(1) GOTO 1220,1230,1240,1250 1220 BYO(1)=-1::GOSUB 1260::RETURN 1230 BXO(1)=1::GOSUB 1260::RETURN 1240 BYO(1)=1::GOSUB 1260::RETURN 1250 BXO(1)=-1::GOSUB 1260::RETURN 1260 BA(1)=1::BLY(1)=MY+BYO(1)::BLX(1)=MX+BXO(1)::B=B-1::IF B=0 THEN GOSUB 300 1270 CALL LINK("DISPLY",1,31,CHR$(48+B))::CALL LINK("PLAY",2832)::CALL SPRITE (#8,96,10,BLY(1),BLX(1))::RETURN 1280 IF M=4 THEN RETURN 1290 IF DR(M)=1 THEN RETURN 1300 GOTO 1410 1310 IF M+1=5 THEN RETURN 1320 IF BA(M+1)=1 THEN RETURN 1330 BYO(M+1)=0::BXO(M+1)=0::IF (RX(M)>MX-16)*(RX(M)<MX+16) THEN 1370 1340 IF (RY(M)>MY-16)*(RY(M)<MY+16) THEN 1390 1350 RETURN 1360 BA(M+1)=1::BLY(M+1)=RY(M)+BYO(M+1)::BLX(M+1)=RX(M)+BXO(M+1)::CALL LINK("PLAY",2832)::CALL SPRITE (#8+M,96,10,BLY(M+1),BLX(M+1))::RETURN 1370 IF RY(M)>MY THEN BYO(M+1)=-1 ELSE BYO(M+1)=1 1380 GOTO 1360 1390 IF RX(M)>MX THEN BXO(M+1)=-1 ELSE BXO(M+1)=1 1400 GOTO 1360 1410 IF (M=2)*(BAT1A=140) THEN RETURN 1420 IF (M=3)*(BAT2A=116) THEN RETURN ELSE 1310 1430 IF (BA(M)=0)+(M=5) THEN RETURN 1440 IF (M=3)*(BAT1A=140) THEN RETURN 1450 IF (M=4)*(BAT2A=116) THEN RETURN 1460 IF BYO(M)=-1 THEN BLD(M)=-1::GOTO 1500 1470 IF BXO(M)=1 THEN BLD(M)=1::GOTO 1510 1480 IF BYO(M)=1 THEN BLD(M)=1::GOTO 1500 1490 IF BXO(M)=-1 THEN BLD(M)=-1::GOTO 1510 1500 BLY(M)=BLY(M)+8*BLD(M)::GOTO 1520 1510 BLX(M)=BLX(M)+8*BLD(M) 1520 FOR A=1 TO 4::IF BA(A)=1 THEN CALL LOCATE(#7+A,BLY(A),BLX(A)) 1530 NEXT A 1540 IF (BLY(M)<17)+(BLY(M)>161)+(BLX(M)<9)+(BLX(M)>233) THEN GOSUB 1600 1550 IF (BLY(M)<65)*(BLY(M)>55)*(BLX(M)>88)*(BLX(M)<138) THEN GOSUB 1600 1560 CALL GCHAR(INT(BLY(M)/8)+1,INT(BLX(M)/8)+1,BC)::CALL GCHAR(INT(BLY(M)/8)+2,INT(BLX(M)/8)+1,BC1) 1570 CALL GCHAR(INT(BLY(M)/8)+1,INT(BLX(M)/8)+2,BC2)::CALL GCHAR(INT(BLY(M)/8)+2,INT(BLX(M)/8)+2,BC3) 1580 IF (BC<>32)+(BC1<>32)+(BC2<>32)+(BC3<>32) THEN 1610 1590 RETURN 1600 CALL DELSPRITE (#7+M)::BA(M)=0::BLY(M)=0::BLX(M)=0::RETURN 1610 IF (BC>15)*(BC<20) THEN RETURN ELSE 1620 1620 IF (BC1>15)*(BC1<20) THEN RETURN ELSE 1630 1630 IF (BC2>15)*(BC2<20) THEN RETURN ELSE 1640 1640 IF (BC3>15)*(BC3<20) THEN RETURN ELSE 1600 1650 CALL COINC(#3,PKY,PKX,4,GC)::IF GC=0 THEN RETURN 1660 CALL LINK("PLAY",2760)::GOSUB 380::B=6::CALL LINK("DISPLY",1,31,CHR$(48+B))::RETURN 1670 IF DS=1 THEN 1710 1680 FOR A=2 TO 4 1690 IF (BLY(A)>MY-*(BLY(A)<MY+*(BLX(A)>MX-*(BLX(A)<MX+ THEN DS=1::IF M>2 THEN 1720 1700 NEXT A 1710 ON M GOTO 1720,1740,1760,1780 1720 IF DR(1)=1 THEN RETURN 1730 IF (BLY(1)>RY(1)-*(BLY(1)<RY(1)+*(BLX(1)>RX(1)-*(BLX(1)<RX(1)+ THEN 1810 ELSE RETURN 1740 IF DR(2)=1 THEN RETURN 1750 IF (BLY(1)>RY(2)-*(BLY(1)<RY(2)+*(BLX(1)>RX(2)-*(BLX(1)<RX(2)+ THEN 1840 ELSE RETURN 1760 IF DR(3)=1 THEN RETURN 1770 IF (BLY(1)>RY(3)-*(BLY(1)<RY(3)+*(BLX(1)>RX(3)-*(BLX(1)<RX(3)+ THEN 1850 ELSE RETURN 1780 IF DR(4)=1 THEN RETURN 1790 IF (BLY(1)>RY(4)-*(BLY(1)<RY(4)+*(BLX(1)>RX(4)-*(BLX(1)<RX(4)+ THEN 1860 ELSE RETURN 1800 RETURN 1810 HP=HP-1::IF HP<0 THEN 1830 1820 CALL SPRITE(#16,92,12,RY(1),RX(1))::CALL LINK("PLAY",2760)::CALL DELSPRITE (#8,#16)::BA(1)=0::BLY(1)=0::BLX(1)=0::RBC=16::RETURN 1830 N=1::DR(1)=1::RBT=120::CALL SPRITE(#12,128,RBC,RY(1),RX(1),-3,3)::CALL MOTION(#4,-3,-3)::GOTO 1880 1840 N=2::DR(2)=1::BAT1A=120::BAT1B=124::GOTO 1870 1850 N=3::DR(3)=1::BAT2A=120::BAT2B=124::GOTO 1870 1860 N=4::DR(4)=1::SPIDA=120::SPIDB=124::GOTO 1870 1870 CALL SPRITE(#3+N,120,10,RY(N),RX(N))::GOTO 1880 1880 RX(N)=6::RY(N)=6::CALL LINK("PLAY",2513)::SCR=SCR+PV(N)::SCOR$=STR$(SCR)&"00"::CALL LINK("DISPLY",1,14,SCOR$)::RETURN 1890 IF (DS=1)+(DS=2) THEN RETURN 1900 IF (RY(M)>MY-12)*(RY(M)<MY+12)*(RX(M)>MX-12)*(RX(M)<MX+12) THEN 1910 ELSE RETURN 1910 IF M=1 THEN DS=1 1920 IF SCR<50 THEN 1960 1930 IF (BS1=2)*(M=2) THEN DS=1 1940 IF (BS2=2)*(M=3) THEN DS=1 1950 DS=2::RETURN 1960 IF M>1 THEN DS=2 1970 RETURN 1980 CALL SPRITE(#3,64,12,73,113)::CALL LINK("PLAY",2649)::DS=0::RETURN 1990 RY(1)=161::RX(1)=17::RP(1)=2 2000 IF SCR>=800 THEN 2090 2010 IF SCR>=300 THEN 2080 2020 IF SCR>=150 THEN 2070 2030 IF SCR>=50 THEN 2060 2040 RBT=100::RBC=15::PV(1)=3::RS(1)=2::HP=0 2050 CALL SPRITE(#4,RBT,RBC,RY(1),RX(1))::RETURN 2060 GOSUB 2100::RBC=6::PV(1)=5::HP=0::GOTO 2050 2070 GOSUB 2780::GOSUB 2100::RBC=16::PV(1)=10::HP=2::GOTO 2050 2080 GOSUB 2790::GOSUB 2100::RBC=2::PV(1)=20::HP=2::GOTO 2050 2090 GOSUB 2100::RBC=1::PV(1)=40::HP=2::GOTO 2050 2100 RBT=108::RS(1)=4::RETURN 2110 IF SCR<50 THEN 2120 ELSE 2130 2120 BAT1A=140::BAT1B=116::RY(2)=49::RX(2)=217::RP(2)=4::RS(2)=2::PV(2)=2::BS1=1::CALL SPRITE(#5,BAT1A,2,RY(2),RX(2))::RETURN 2130 BAT1A=100::BAT1B=104::RY(2)=161::RX(2)=17::RP(2)=2::RS(2)=2::PV(2)=3::BS1=2::CALL SPRITE(#5,BAT1A,15,RY(2),RX(2))::RETURN 2140 IF SCR<50 THEN 2150 ELSE 2160 2150 BAT2A=116::BAT2B=140::RY(3)=113::RX(3)=209::RP(3)=2::RS(3)=2::PV(3)=2::BS2=1::CALL SPRITE(#6,BAT2A,2,RY(3),RX(3))::RETURN 2160 BAT2A=104::BAT2B=100::RY(3)=161::RX(3)=17::RP(3)=2::RS(3)=2::PV(3)=3::BS2=2::CALL SPRITE(#6,BAT2A,15,RY(3),RX(3))::RETURN 2170 SPIDA=132::SPIDB=136::RY(4)=49::RX(4)=9::RP(4)=3::RS(4)=2::PV(4)=2::CALL SPRITE(#7,SPIDA,4,RY(4),RX(4))::RETURN 2180 IF (M=1)*(DR(1)=1) THEN 2680 2190 IF (M=2)*(DR(2)=1) THEN 2700 2200 IF (M=3)*(DR(3)=1) THEN 2720 2210 IF (M=4)*(DR(4)=1) THEN 2740 2220 GOSUB 2300::ON RP(M) GOTO 2230,2240,2250,2260 2230 RD(M)=-1::GOTO 2270 2240 RD(M)=1::GOTO 2280 2250 RD(M)=1::GOTO 2270 2260 RD(M)=-1::GOTO 2280 2270 RY(M)=RY(M)+RS(M)*RD(M)::GOTO 2290 2280 RX(M)=RX(M)+RS(M)*RD(M) 2290 CALL LOCATE(#M+3,RY(M),RX(M))::RETURN 2300 IF (RX(M)=9)*(RY(M)=161) THEN RP(M)=2::RETURN 2310 FOR A=1 TO 6::IF RX(M)=I1A(A) AND RY(M)=I1B(A) THEN 2490 2320 NEXT A 2330 FOR A=1 TO 4::IF RX(M)=I2A(A) AND RY(M)=I2B(A) THEN 2500 2340 NEXT A 2350 FOR A=1 TO 5::IF RX(M)=I3A(A) AND RY(M)=I3B(A) THEN 2510 2360 NEXT A 2370 FOR A=1 TO 7::IF RX(M)=I4A(A) AND RY(M)=I4B(A) THEN 2520 2380 NEXT A 2390 FOR A=1 TO 3::IF RX(M)=I5A(A) AND RY(M)=I5B(A) THEN 2530 2400 NEXT A 2410 FOR A=1 TO 5::IF RX(M)=I6A(A) AND RY(M)=I6B(A) THEN 2540 2420 NEXT A 2430 FOR A=1 TO 3::IF RX(M)=I7A(A) AND RY(M)=I7B(A) THEN 2550 2440 NEXT A 2450 FOR A=1 TO 3::IF RX(M)=I8A(A) AND RY(M)=I8B(A) THEN 2560 2460 NEXT A 2470 RETURN 2480 CALL LINK("IRND",4,RC)::RC=RC+1::RETURN 2490 GOSUB 2570::ON RC GOTO 2590,2600,2610,2600 2500 GOSUB 2570::ON RC GOTO 2590,2620,2610,2620 2510 GOSUB 2570::ON RC GOTO 2610,2600,2610,2620 2520 GOSUB 2570::ON RC GOTO 2590,2600,2590,2620 2530 GOSUB 2570::ON RC GOTO 2610,2600,2610,2600 2540 GOSUB 2570::ON RC GOTO 2610,2620,2610,2620 2550 GOSUB 2570::ON RC GOTO 2590,2600,2590,2600 2560 GOSUB 2570::ON RC GOTO 2590,2620,2590,2620 2570 IF (M=1)*(RS(1)=4) THEN GOSUB 2630 ELSE GOSUB 2480 2580 RETURN 2590 RP(M)=1::RETURN 2600 RP(M)=2::RETURN 2610 RP(M)=3::RETURN 2620 RP(M)=4::RETURN 2630 IF (RY(1)>MY-32)*(RY(1)<MY+32)*(RX(1)<MX) THEN RC=2::RETURN 2640 IF (RY(1)>MY-32)*(RY(1)<MY+32)*(RX(1)>MX) THEN RC=4::RETURN 2650 IF (RX(1)>MX-32)*(RX(1)<MX+32)*(RY(1)>MY) THEN RC=1::RETURN 2660 IF (RX(1)>MX-32)*(RX(1)<MX+32)*(RY(1)<MY) THEN RC=3::RETURN 2670 GOSUB 2480::RETURN 2680 DR(1)=1::DRW(1)=DRW(1)+1::IF DRW(1)<10 THEN RETURN 2690 DR(1)=0::DRW(1)=0::CALL DELSPRITE(#4,#12)::GOTO 1990 2700 DR(2)=1::DRW(2)=DRW(2)+1::IF DRW(2)<10 THEN RETURN 2710 DR(2)=0::DRW(2)=0::CALL DELSPRITE(#5)::GOTO 2110 2720 DR(3)=1::DRW(3)=DRW(3)+1::IF DRW(3)<10 THEN RETURN 2730 DR(3)=0::DRW(3)=0::CALL DELSPRITE(#6)::GOTO 2140 2740 DR(4)=1::DRW(4)=DRW(4)+1::IF DRW(4)<10 THEN RETURN 2750 DR(4)=0::DRW(4)=0::CALL DELSPRITE(#5)::GOTO 2170 2760 RESTORE 30001::GOTO 2810 2770 RESTORE 20001::GOTO 2810 2780 RESTORE 30501::GOTO 2810 2790 RESTORE 30531::GOTO 2810 2800 RESTORE 30602::GOTO 2810 2810 READ A$::IF A$="" THEN 2820::CALL LINK("CWRITE",A$)::GOTO 2810 2820 RETURN 2830 RESTORE 2950 2840 FOR MD=1 TO 7::READ MDA,MDB,MDC::YA(MD)=MDA::YB(MD)=MDB::YC(MD)=MDC::NEXT MD 2850 FOR MD=1 TO 11::READ MDA,MDB,MDC::XA(MD)=MDA::XB(MD)=MDB::XC(MD)=MDC::NEXT MD 2860 FOR MD=1 TO 6::READ MDA,MDB::I1A(MD)=MDA::I1B(MD)=MDB::NEXT MD 2870 FOR MD=1 TO 4::READ MDA,MDB::I2A(MD)=MDA::I2B(MD)=MDB::NEXT MD 2880 FOR MD=1 TO 5::READ MDA,MDB::I3A(MD)=MDA::I3B(MD)=MDB::NEXT MD 2890 FOR MD=1 TO 7::READ MDA,MDB::I4A(MD)=MDA::I4B(MD)=MDB::NEXT MD 2900 FOR MD=1 TO 3::READ MDA,MDB::I5A(MD)=MDA::I5B(MD)=MDB::NEXT MD 2910 FOR MD=1 TO 5::READ MDA,MDB::I6A(MD)=MDA::I6B(MD)=MDB::NEXT MD 2920 FOR MD=1 TO 3::READ MDA,MDB::I7A(MD)=MDA::I7B(MD)=MDB::NEXT MD 2930 FOR MD=1 TO 3::READ MDA,MDB::I8A(MD)=MDA::I8B(MD)=MDB::NEXT MD 2940 RETURN 2950 DATA 14,26,17,43,57,49,73,87,81,91,109,97,107,114,113,123,148,129,153,180,161 2960 DATA 8,14,9,28,40,33,50,64,57,75,89,81,103,121,113,123,136,129,138,152,148 2970 DATA 161,177,169,186,199,193,210,224,217,225,233,233 2980 DATA 33,81,57,49,57,129,81,97,169,129,169,81,33,129,57,81,169,97,233,113 2990 DATA 81,49,129,17,169,17,193,17,217,49,57,161,81,129,129,49,145,97,145,161,169,161,217,81 3000 DATA 9,17,57,17,193,113,33,17,145,49,145,129,233,17,233,81,9,129,33,161,193,49 3010 DATA 193,129,233,49,233,161 3020 CALL SPRITE(#1,88,6,65,113,#2,92,6,81,113) 3030 CALL LINK("DISPLY",9,15,CHR$(32),1,2)::CALL LINK("DISPLY",10,15,CHR$(32),1,2)::CALL LINK("DISPLY",11,15,CHR$(32),1,2)::BDW=0::RETURN 3040 CALL LINK("DISPLY",9,15,CHR$(5),1,2)::CALL LINK("DISPLY",10,15,CHR$(6),1,2)::CALL LINK("DISPLY",11,15,CHR$(0),1,2)::CALL DELSPRITE (#1,#2) 3050 BDW=1::RETURN If you want to run the game in XB (which is awful), merge the attached compressed data statements file data.zip Edited March 14, 2018 by LASooner Quote Link to comment Share on other sites More sharing options...
Opry99er Posted March 14, 2018 Share Posted March 14, 2018 In my recent development effort (4K game) it became evident that I was going to be several hundred bytes over the limit. One thing I did was find the most commonly used integers in my program and replace them with a variable. For instance, I used the integer *1* about 35 times in my code. I simply changed all the *1* integers in the code to a variable reference, and added *O=1* to the top of the code during the variable allocation section and it saved me a ton of program space. Additionally, I did this with the length fields in all my CALL SOUNDs and also the pitch values as well. CALL SOUND(300,440,1,659,1) became: CALL SOUND(Q, A,O,E,O) This doesnt just save bytes by shortening the length of the line, it actually decreases the amount of program space overhead by defining the variable with an integer once, and then making references to it throughout the code. I dont know how much this will help when using the compiler, but I saved almost 400 bytes in a very short code listing. With your multi-statement lines and larger program size, I imagine that doing only a few of these integer replacements will make a significant impact. Just find the integers you use most, and do one... see if it helps. Quote Link to comment Share on other sites More sharing options...
LASooner Posted March 14, 2018 Author Share Posted March 14, 2018 Excuse my ignorance here, but how does a variable holding the value of 1, take up less space than the value 1? Quote Link to comment Share on other sites More sharing options...
Airshack Posted March 14, 2018 Share Posted March 14, 2018 What LASooner said. Sent from my iPhone using Tapatalk Pro Quote Link to comment Share on other sites More sharing options...
Opry99er Posted March 14, 2018 Share Posted March 14, 2018 (edited) because program size is equated both pre-RUN and post-RUN. Once you run the program, the variable space is reserved for whatever you decide to call the variable... rather than having an integer value repeated a hundred times. All thats left is a single, 1 byte reference to the integer. I could see how this might increase speed of the program as well. Write a simple test program and try it out. Edited March 14, 2018 by Opry99er 1 Quote Link to comment Share on other sites More sharing options...
Opry99er Posted March 14, 2018 Share Posted March 14, 2018 There is one downside though... it kind of makes code readability a little rough if you go too far Quote Link to comment Share on other sites More sharing options...
Opry99er Posted March 14, 2018 Share Posted March 14, 2018 Alright, try this out... RUN program 1, then check the SIZE (in XB) then... RUN program 2, then check the SIZE (in XB) I haven't tested the results yet, but I'm pretty confident what they will be. **Note, the second program also has 1 additional line (so one more entry into the line table, plus code size) 100 CALL SOUND(300,220,1,440,1,659,1) 110 CALL SOUND(300,220,1,440,1,659,1) 120 CALL SOUND(300,220,1,440,1,659,1) 130 CALL SOUND(300,220,1,440,1,659,1) 140 CALL SOUND(300,220,1,440,1,659,1) 150 CALL SOUND(300,220,1,440,1,659,1) 160 CALL SOUND(300,220,1,440,1,659,1) 170 CALL SOUND(300,220,1,440,1,659,1) 180 CALL SOUND(300,220,1,440,1,659,1) 190 CALL SOUND(300,220,1,440,1,659,1) 200 CALL SOUND(300,220,1,440,1,659,1) 10 A=1 100 CALL SOUND(300,220,A,440,A,659,A) 110 CALL SOUND(300,220,A,440,A,659,A) 120 CALL SOUND(300,220,A,440,A,659,A) 130 CALL SOUND(300,220,A,440,A,659,A) 140 CALL SOUND(300,220,A,440,A,659,A) 150 CALL SOUND(300,220,A,440,A,659,A) 160 CALL SOUND(300,220,A,440,A,659,A) 170 CALL SOUND(300,220,A,440,A,659,A) 180 CALL SOUND(300,220,A,440,A,659,A) 190 CALL SOUND(300,220,A,440,A,659,A) 200 CALL SOUND(300,220,A,440,A,659,A) Quote Link to comment Share on other sites More sharing options...
LASooner Posted March 15, 2018 Author Share Posted March 15, 2018 (edited) Interesting 1st One: 2nd one: Guess it's worth taking a shot, I use values 1 thru 4 to define the different bullets and monsters, suppose I could start there and see what fruit it bares, thanks! Edited March 15, 2018 by LASooner Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted March 15, 2018 Share Posted March 15, 2018 (edited) I tested both these and am surprised at the results: For the first one there are 23927 bytes of memory left before and after running. For the second one there are 23993 bytes left before running and 23985 left after running.(I didn't put in line 10) So there is a savings in memory, and that would be even better if you were to substitute a 1 character variable for 220 or 659 (For what it's worth, I don't think these memory savings translate to compiled XB code; I'm pretty sure there is no difference.) Edited March 15, 2018 by senior_falcon 1 Quote Link to comment Share on other sites More sharing options...
Opry99er Posted March 15, 2018 Share Posted March 15, 2018 I found my biggest savings was converting larger numbers (like the durations of the music)... that got me a big chunk. It was after a conversation with Tursi that I tried substituting even my single digit integers and that yielded savings as well. Its all in how memory is allocated during the initial variable set up. If you use Notepad++, you can type in a value and search for every iteration of that value in your code. You use *1* for loops as well... like FOR I=1 TO 16 could become FOR I=A TO 16. Any place in your code that holds the integer *1* can be substituted for the variable name of your choosing. Quote Link to comment Share on other sites More sharing options...
Opry99er Posted March 15, 2018 Share Posted March 15, 2018 When I finished Markus of Marinus (but was over on my code size) I had to move it over to the PC for tweaking. I converted the BASIC listing to TIdBiT and made the adjustments. It's not quite as heavily commented as yours, but you can see how much adjusting I did to remove values and substitute them for variables. I think you have to use a value 4 times or more to justify the additional line table and code space to define the variable. This was all a big conversation I had with Tursi and some heavy testing on my end to find what worked best. In retrospect, I would have done a few things differently to create even more space, but here's the code I ended up with. Once translated, it put me at 4080 bytes of program space. // Markus of Marinus (2018) // Entry for the 4K contest on Atariage INITIALIZE: Q=1 // this is the level number AND the seed for each level LI=15 // this is the variable for "Lives" BO=104 // this is the blacked out border character B=120 // this is the door character MN=105 // this is the monster graphic KY=112 // this is the key graphic DU=128 // this is the player character graphic SP=32 // this is the replacement for the integer "32" H=2 // this is the replacement for the integer "2" U=24 // this is the replacement for the integer "24" J=300 // this is the replacement for the integer "300" HJ=150 // this it the replacement for the integer "150" E=165 // this is the replacement for the integer "165" Y=16 // this is the replacement for the integer "16" O=659 // this is the replacement for the integer "659" D=294 // this is the replacement for the integer "294" V=587 // this is the replacement for the integer "587" F=1 // this is the replacement for the integer "1" CALL CLEAR CALL SCREEN(H) CALL CHAR(BO,"FFFFFFFFFFFFFFFF") CALL CHAR(MN,"") CALL CHAR(KY,"00E0A0BFA5E50100") CALL CHAR(B,"7E6642424A42667E") CALL CHAR(DU,"3C3D19FF98982424") // MAKE SETS 3-8 WHITE (TEXT) FOR T=3 TO 8 CALL COLOR(T,Y,F) NEXT T // Title screen goes here // TITLE: PRINT " MARKUS OF MARINUS": : : // Music Goes Here GOSUB MUSIC PRINT " PRESS ANY KEY TO BEGIN" KEYCHECK: CALL KEY(0,K,S) IF S=0 THEN KEYCHECK // TOP OF OUTER LOOP // Q IS THE LEVEL SEED WHICH IS USED TO GENERATE MAPS, ITEMS, AND MONSTERS // PR and PC are the starting row and column of the player // DK is door key (start every level without it) // PLS is the Possible Level Score (starts at 100, and subtracts 20 for each monster hit) OUTERLOOP: RANDOMIZE (Q) PR=23 PC=3 DK=0 PLS=100 // BLACK OUT THE CHARACTERS SO YOU CANNOT SEE THEM POPULATE CALL CLEAR CALL COLOR(11,H,F) CALL COLOR(12,H,F) CALL SCREEN(H) // WRITE THE LEVEL ONSCREEN FOR DISPLAY PURPOSES RESTORE LOADDATA FOR K=F TO 13 READ P CALL HCHAR(U,K+7,P) NEXT K IF Q>9 THEN DOUBLEDIGITS CALL HCHAR(U,22,Q+48) GOTO MAPGEN // IF THE LEVEL NUMBER IS A DOUBLE DIGIT NUMBER, USE THE FOLLOWING LINES OF CODE DOUBLEDIGITS: CALL HCHAR(U,22,49) CALL HCHAR(U,23,Q+38) // GENERATE THE MAP PROCEDURALLY USING THE LEVEL SEED MAPGEN: FOR I=F TO 80 GOSUB GENRAND RR=INT(RND*5)+F CALL HCHAR(R,P,BO,RR) NEXT I // GENERATE THE KEY CALL HCHAR(R,P+H,KY) // GENERATE THE DOOR GOSUB GENRAND CALL HCHAR(R+F,P,B) // GENERATE MONSTERS ON THE SCREEN, THEY WILL BE TRANSPARENT IN COLOR (SNEAKY) FOR X=F TO 15 GOSUB GENRAND CALL HCHAR(R+F,P+F,MN) NEXT X // GENERATE PLAYER CHARACTER GOSUB REDRAW // DRAW THE BORDER CALL HCHAR(F,F,BO,SP) CALL HCHAR(U,F,BO,SP) CALL VCHAR(F,F,BO,U) CALL VCHAR(F,SP,BO,U) // GIVE THE KEY AND THE DOOR A COLOR, COLOR THE SCREEN PURPLE CALL COLOR(11,11,F) CALL COLOR(12,8,F) CALL SCREEN(6) // THIS IS WHERE THE MAIN GAME LOOP WILL BE. MAINLOOP: CALL KEY(0,K,S) IF S=0 THEN MAINLOOP IF K=69 THEN UP IF K=88 THEN DOWN IF K=83 THEN LEFT IF K=68 THEN RIGHT GOTO MAINLOOP UP: CALL GCHAR(PR-F,PC,G) GOSUB CHECKER IF G=SP THEN UP2 IF G=MN THEN UP2 IF G=KY THEN UP2 GOTO MAINLOOP UP2: GOSUB CLEARSPOT PR=PR-F GOSUB REDRAW GOTO MAINLOOP DOWN: CALL GCHAR(PR+F,PC,G) GOSUB CHECKER IF G=SP THEN DOWN2 IF G=MN THEN DOWN2 IF G=KY THEN DOWN2 GOTO MAINLOOP DOWN2: GOSUB CLEARSPOT PR=PR+F GOSUB REDRAW GOTO MAINLOOP LEFT: CALL GCHAR(PR,PC-F,G) GOSUB CHECKER IF G=SP THEN LEFT2 IF G=MN THEN LEFT2 IF G=KY THEN LEFT2 GOTO MAINLOOP LEFT2: GOSUB CLEARSPOT PC=PC-F GOSUB REDRAW GOTO MAINLOOP RIGHT: CALL GCHAR(PR,PC+F,G) GOSUB CHECKER IF G=SP THEN RIGHT2 IF G=MN THEN RIGHT2 IF G=KY THEN RIGHT2 GOTO MAINLOOP RIGHT2: GOSUB CLEARSPOT PC=PC+F GOSUB REDRAW GOTO MAINLOOP // CHECK IF YOU HAVE THE KEY... IF NOT, RETURN TO THE MAIN LOOP // IF YOU HAVE KEY, MAKE A SOUND AND END THE LEVEL DOOR: IF DK=0 THEN DOOR2 CALL SOUND(400,110,F,440,F,O,F) GOTO LEVELEND DOOR2: CALL SOUND(200,-3,F) GOTO MAINLOOP // GO TO NEXT LEVEL... IF YOU BEAT LEVEL 15, THEN GO TO END OF GAME SEQUENCE LEVELEND: Q=Q+F TSCO=TSCO+PLS IF Q=Y THEN GAMEEND2 CALL CLEAR CALL SCREEN(H) PRINT "LEVEL SCORE: ";PLS : "TOTAL SCORE: ";TSCO : : "LIVES REMAINING: ";LI FOR DEL=F TO 2000 NEXT DEL GOTO OUTERLOOP ///////////////////////////////////////////////////// // END OF GAME LOOP. WHAT FOLLOWS ARE SUBROUTINES // ///////////////////////////////////////////////////// // Check the tile you're going to with the return from GCHAR CHECKER: IF G=MN THEN BATTLE IF G=KY THEN GETKEY IF G=B THEN DOOR RETURN // Clear the current location, get ready to do HCHAR for the player character on // The new spot. CLEARSPOT: CALL HCHAR(PR,PC,SP) RETURN // draw the player character in its new spot REDRAW: CALL HCHAR(PR,PC,DU) RETURN // THIS IS THE RANDOM ROW/COLUMN GENERATION SUBROUTINE GENRAND: R=INT(RND*22)+F P=INT(RND*30)+F RETURN BATTLE: CALL SCREEN(Y) CALL CHAR(MN,"43FCA2345ACB1F12") CALL SOUND(800,-5,F) FOR DEL=F TO 800 NEXT DEL CALL SCREEN(6) CALL CHAR(MN,"") PLS=PLS-20 LI=LI-F IF LI=0 THEN GAMEEND IF PLS<20 THEN BATTLE2 RETURN BATTLE2: PLS=0 RETURN GETKEY: DK=F CALL SOUND(100,C,F) CALL SOUND(100,330,F) CALL SOUND(100,392,F) CALL SOUND(400,523,F) RETURN // THIS IS THE "END OF GAME" SEQUENCE GAMEEND: GOSUB BLACKLETTERS CALL SCREEN(7) PRINT "YOU HAVE DIED...": : : "YOU REACHED LEVEL";Q: : GOTO GAMEEND3 GAMEEND2: GOSUB BLACKLETTERS CALL SCREEN(12) PRINT "CONGRATULATIONS! YOU HAVE":" COMPLETED YOUR QUEST!!!": : : GAMEEND3: LB=LI*20 TOTS=LB+TSCO PRINT "QUEST SCORE: ";TSCO : "LIFE BONUS: ";LB : : "FINAL TALLY: ";TOTS : : : : GOSUB MUSIC PRINT "PRESS ANY KEY TO PLAY AGAIN" REPLAYKEY: CALL KEY(0,K,S) IF S=0 THEN REPLAYKEY GOTO INITIALIZE BLACKLETTERS: FOR I=F TO Y CALL COLOR(I,2,F) NEXT I CALL CLEAR RETURN MUSIC: C=262 G=392 K=494 // Em Ascending Arpeggio CALL SOUND(HJ,K,F) CALL SOUND(HJ,523,F) CALL SOUND(HJ,V,F) CALL SOUND(HJ,O,F) CALL SOUND(HJ,740,F) CALL SOUND(HJ,880,F) // Em+G CALL SOUND(J,E,F,784,F) CALL SOUND(J,E,F,784,F,K,F) CALL SOUND(J,E,F,K,F,G,F) // Em+F# CALL SOUND(J,E,F,740,F) CALL SOUND(J,E,F,740,F,K,F) CALL SOUND(J,E,F,K,F,G,F) // Em (2x) FOR Z=F TO H CALL SOUND(J,E,F,O,F) CALL SOUND(J,E,F,O,F,K,F) CALL SOUND(J,E,F,K,F,G,F) NEXT Z // C CALL SOUND(J,C,F,G,F) CALL SOUND(J,C,F,G,F,523,F) CALL SOUND(J,C,F,G,F,V,F) CALL SOUND(J,C,F,G,F,O,F) CALL SOUND(J,C,F,G,F,V,F) CALL SOUND(J,C,F,G,F,523,F) // D FOR Z=F TO H CALL SOUND(J,D,F,880,F) CALL SOUND(J,D,F,O,F) CALL SOUND(J,D,F,V,F) NEXT Z // Em CALL SOUND(J*5,E,F,1319,F,784,F) RETURN // THIS IS DATA FOR DISPLAYING "LOADING LEVEL X" LOADDATA: DATA 76,79,65,68,73,78,71 DATA 32,76,69,86,69,76 1 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.