Jump to content

Photo

Night Stalker - Complete (XB256 compiled)


108 replies to this topic

#26 Opry99er OFFLINE  

Opry99er

    Quadrunner

  • 9,797 posts
  • Location:Hustisford, WI

Posted Tue Mar 13, 2018 2:34 PM

majestyx, the compiler now handles more complex IF THEN statements since falcons last release.

Your suggestion with the ON DS is a good one. :)

#27 majestyx OFFLINE  

majestyx

    Chopper Commander

  • 211 posts
  • Location:Port Carbon, Pennsylvania

Posted Tue Mar 13, 2018 2:46 PM

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)



#28 --- Ω --- OFFLINE  

--- Ω ---

    --- Ω ---

  • 12,698 posts
  • Location:워싱턴 주

Posted Tue Mar 13, 2018 2:50 PM

 

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.



#29 Opry99er OFFLINE  

Opry99er

    Quadrunner

  • 9,797 posts
  • Location:Hustisford, WI

Posted Tue Mar 13, 2018 3:07 PM

I think he is looking for the new compiler

#30 Opry99er OFFLINE  

Opry99er

    Quadrunner

  • 9,797 posts
  • Location:Hustisford, WI

Posted Tue Mar 13, 2018 3:11 PM

http://atariage.com/...e/?fromsearch=1

#31 unhuman OFFLINE  

unhuman

    Stargunner

  • 1,207 posts
  • Location:Vienna, VA

Posted Tue Mar 13, 2018 4:18 PM

This code:

890 IF (MX>8)*(MX<14) THEN MX=9
900 IF (MX>28)*(MX<40) THEN MX=33
910 IF (MX>50)*(MX<64) THEN MX=57
920 IF (MX>75)*(MX<89) THEN MX=81
930 IF (MX>103)*(MX<121) THEN MX=113
940 IF (MX>123)*(MX<136) THEN MX=129
950 IF (MX>138)*(MX<152) THEN MX=148
960 IF (MX>161)*(MX<177) THEN MX=169
970 IF (MX>186)*(MX<199) THEN MX=193
980 IF (MX>210)*(MX<224) THEN MX=217
990 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?



#32 LASooner OFFLINE  

LASooner

    Moonsweeper

  • Topic Starter
  • 291 posts

Posted Tue Mar 13, 2018 5:09 PM

Got it, Thanks

#33 LASooner OFFLINE  

LASooner

    Moonsweeper

  • Topic Starter
  • 291 posts

Posted Tue Mar 13, 2018 8:28 PM

 

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.



#34 Airshack OFFLINE  

Airshack

    Dragonstomper

  • 787 posts
  • Location:Phoenix, AZ

Posted Tue Mar 13, 2018 11:25 PM

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...er_(video_game)



#35 LASooner OFFLINE  

LASooner

    Moonsweeper

  • Topic Starter
  • 291 posts

Posted Wed Mar 14, 2018 12:41 AM

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...er_(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



#36 OLD CS1 OFFLINE  

OLD CS1

    Technomancer

  • 5,497 posts
  • Technology Samurai
  • Location:Tallahassee, FL

Posted Wed Mar 14, 2018 2:13 AM

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=9
900 IF (MX>28)*(MX<40) THEN MX=33
910 IF (MX>50)*(MX<64) THEN MX=57
920 IF (MX>75)*(MX<89) THEN MX=81
930 IF (MX>103)*(MX<121) THEN MX=113
940 IF (MX>123)*(MX<136) THEN MX=129
950 IF (MX>138)*(MX<152) THEN MX=148
960 IF (MX>161)*(MX<177) THEN MX=169
970 IF (MX>186)*(MX<199) THEN MX=193
980 IF (MX>210)*(MX<224) THEN MX=217
990 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.



#37 LASooner OFFLINE  

LASooner

    Moonsweeper

  • Topic Starter
  • 291 posts

Posted Wed Mar 14, 2018 2:54 AM

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=9
900 IF (MX>28)*(MX<40) THEN MX=33
910 IF (MX>50)*(MX<64) THEN MX=57
920 IF (MX>75)*(MX<89) THEN MX=81
930 IF (MX>103)*(MX<121) THEN MX=113
940 IF (MX>123)*(MX<136) THEN MX=129
950 IF (MX>138)*(MX<152) THEN MX=148
960 IF (MX>161)*(MX<177) THEN MX=169
970 IF (MX>186)*(MX<199) THEN MX=193
980 IF (MX>210)*(MX<224) THEN MX=217
990 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/...-8#entry3974965


Edited by LASooner, Wed Mar 14, 2018 4:15 AM.


#38 senior_falcon OFFLINE  

senior_falcon

    Stargunner

  • 1,233 posts
  • Location:Lansing, NY, USA

Posted Wed Mar 14, 2018 6:37 AM

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/...-8#entry3974965

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.



#39 Airshack OFFLINE  

Airshack

    Dragonstomper

  • 787 posts
  • Location:Phoenix, AZ

Posted Wed Mar 14, 2018 10:23 AM

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

#40 LASooner OFFLINE  

LASooner

    Moonsweeper

  • Topic Starter
  • 291 posts

Posted Wed Mar 14, 2018 2:20 PM

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$(8),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=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-8)*(BLY(A)<MY+8)*(BLX(A)>MX-8)*(BLX(A)<MX+8) 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)-8)*(BLY(1)<RY(1)+8)*(BLX(1)>RX(1)-8)*(BLX(1)<RX(1)+8) THEN _ROBOTSHOT ELSE RETURN
					
		_BAT1HIT:	IF DR(2)=1 THEN RETURN		
					IF (BLY(1)>RY(2)-8)*(BLY(1)<RY(2)+8)*(BLX(1)>RX(2)-8)*(BLX(1)<RX(2)+8) THEN _BATSHOT1 ELSE RETURN
					
		_BAT2HIT:	IF DR(3)=1 THEN RETURN		
					IF (BLY(1)>RY(3)-8)*(BLY(1)<RY(3)+8)*(BLX(1)>RX(3)-8)*(BLX(1)<RX(3)+8) THEN _BATSHOT2 ELSE RETURN
		
		_SPIDERHIT:	IF DR(4)=1 THEN RETURN		
					IF (BLY(1)>RY(4)-8)*(BLY(1)<RY(4)+8)*(BLX(1)>RX(4)-8)*(BLX(1)<RX(4)+8) 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::P=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$(8),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=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-8)*(BLY(A)<MY+8)*(BLX(A)>MX-8)*(BLX(A)<MX+8) 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)-8)*(BLY(1)<RY(1)+8)*(BLX(1)>RX(1)-8)*(BLX(1)<RX(1)+8) THEN 1810 ELSE RETURN
1740 IF DR(2)=1 THEN RETURN
1750 IF (BLY(1)>RY(2)-8)*(BLY(1)<RY(2)+8)*(BLX(1)>RX(2)-8)*(BLX(1)<RX(2)+8) THEN 1840 ELSE RETURN
1760 IF DR(3)=1 THEN RETURN
1770 IF (BLY(1)>RY(3)-8)*(BLY(1)<RY(3)+8)*(BLX(1)>RX(3)-8)*(BLX(1)<RX(3)+8) THEN 1850 ELSE RETURN
1780 IF DR(4)=1 THEN RETURN
1790 IF (BLY(1)>RY(4)-8)*(BLY(1)<RY(4)+8)*(BLX(1)>RX(4)-8)*(BLX(1)<RX(4)+8) 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

 

Attached File  data.zip   2.79KB   5 downloads


Edited by LASooner, Wed Mar 14, 2018 2:33 PM.


#41 Opry99er OFFLINE  

Opry99er

    Quadrunner

  • 9,797 posts
  • Location:Hustisford, WI

Posted Wed Mar 14, 2018 2:49 PM

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.

#42 LASooner OFFLINE  

LASooner

    Moonsweeper

  • Topic Starter
  • 291 posts

Posted Wed Mar 14, 2018 4:07 PM

Excuse my ignorance here, but how does a variable holding the value of 1, take up less space than the value 1?



#43 Airshack OFFLINE  

Airshack

    Dragonstomper

  • 787 posts
  • Location:Phoenix, AZ

Posted Wed Mar 14, 2018 4:48 PM

What LASooner said.


Sent from my iPhone using Tapatalk Pro

#44 Opry99er OFFLINE  

Opry99er

    Quadrunner

  • 9,797 posts
  • Location:Hustisford, WI

Posted Wed Mar 14, 2018 5:01 PM

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. :D

Edited by Opry99er, Wed Mar 14, 2018 5:22 PM.


#45 Opry99er OFFLINE  

Opry99er

    Quadrunner

  • 9,797 posts
  • Location:Hustisford, WI

Posted Wed Mar 14, 2018 5:12 PM

There is one downside though... it kind of makes code readability a little rough if you go too far ;)

#46 Opry99er OFFLINE  

Opry99er

    Quadrunner

  • 9,797 posts
  • Location:Hustisford, WI

Posted Wed Mar 14, 2018 5:19 PM

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)


#47 LASooner OFFLINE  

LASooner

    Moonsweeper

  • Topic Starter
  • 291 posts

Posted Wed Mar 14, 2018 9:02 PM

Interesting

1st One:

1CUHCIM.png
 

2nd one:

aSUACyJ.png

 

 

 

 

 

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 by LASooner, Wed Mar 14, 2018 9:03 PM.


#48 senior_falcon OFFLINE  

senior_falcon

    Stargunner

  • 1,233 posts
  • Location:Lansing, NY, USA

Posted Wed Mar 14, 2018 9:02 PM

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 by senior_falcon, Wed Mar 14, 2018 9:04 PM.


#49 Opry99er OFFLINE  

Opry99er

    Quadrunner

  • 9,797 posts
  • Location:Hustisford, WI

Posted Wed Mar 14, 2018 9:57 PM

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.

#50 Opry99er OFFLINE  

Opry99er

    Quadrunner

  • 9,797 posts
  • Location:Hustisford, WI

Posted Wed Mar 14, 2018 10:13 PM

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.

 

 

Spoiler





0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users