'-----------------------------------------------------------
'
'					SHIELDS UP!
'
'Mashup of Castle Crisis and Missle Command
'For Atari 800XL 8-Bit BASIC 10-Liner
'One-player game with PADDLE
'
'Jeff Piepmeier
'March 11, 2017
'http://jeffpiepmeier.blogspot.com/
'http://github.com/jeffpiep/
'
'Parsed with TurboBASIC XL Parser Tool: 
'http://github.com/dmsc/tbxl-parser
$options +optimize, optimize=-convert_percent-const_replace
'PM design with Mad Studio:
'http://atariage.com/forums/topic/258728-Mad-Studio
'Tested on Altirra:
'http://www.virtualdub.org/altirra.html
'-----------------------------------------------------------

'SET UP DISPLAY
GRAPHICS 8 : REM USE GR.8 TO CLEAR OUT 8KBYTES
GRAPHICS 7 : REM GR.7 HAS 4 COLORS AND TAKES 4KBYTES
SETCOLOR 0,0,6 : REM CHANGE COLOR 1 TO BE GRAY (CASTLE)
SETCOLOR 1,1,10 : REM CHANGE COLOR 2 TO BE GOLD (EGG)
SETCOLOR 2,8,14 : REM CHANGE COLOR 3 TO BE WHITE (MISSLES)
'FIDDLE WITH THE DL TO PUT BIG TEXT ON THE BOTTOM
MOVE ADR("\46\60\BF\06\06\06\41"),DPEEK(560)+85,7
SCREEN = DPEEK(DPEEK(560)+4) : REM THIS IS WHERE THE BITMAP STARTS

'SET UP SPRITES/PLAYER MISSLE GRAPHICS
POKE 54279,168 : REM PM=168($A8) ON 64K 800XL - 24 PAGES BELOW RAMTOP
PM = $A800 : REM PM*$100 POINT TO PM AREA
DPOKE 704, $3434 : REM RED COLOR FOR PLAYERS 1 & 0
DPOKE $D00C, 1  : REM DOUBLE WIDTH MISSLES
POKE 53277,3 : REM ENABLE PM DISPLAY
POKE 559,46 : REM ENABLE PM DMA WITH 2-LINE RES
'DEFINE SPRITES/PLAYERS AND PUT IN UNUSED PM AREA
'LEFT SHIELD
MOVE ADR("\08\18\38\70\E0\C0\80"), PM+128, 7
'RIGHT SHIELD
MOVE ADR("\80\C0\E0\70\38\18\08"), PM+256, 7

'INITIALIZE SOME STATE VARIABLES
LEVEL = 1 : REM GAME LEVEL, THERE ARE 4 
SPEED = 2 : REM MISSLE SPEED
RADIUS = 67 : REM MISSLE DISTANCE

'OUTER GAME LOOP
REPEAT
	MOVE SCREEN,SCREEN+1,3200 : REM CLEAR SCREEN

	MAXSCORE = 5+LEVEL*5 : REM COMPUTE SCORE NEEDED TO CLEAR LEVEL
	POKE 657,1 : REM POSITION CURSOR IN GR.2 AREA AT SPACE 1
	?"level ";LEVEL;" of 4","score ";SCORE;" of ";MAXSCORE;" ";

	'DRAW PYRAMID
	'LOOP THROUGH ROWS AND INCREASING NUMBER OF COLUMNS
	'DRAW BLOCKS(USE INVERSE SPACE CHARACTER) AND GOLDEN EGG PER LOGIC RECIPE
	FOR I=0 TO 5
		FOR J=0 TO 2*I
			'LOGIC TO DETERMINE KEEP AND EGG LOCATIONS
			KEEP = (I>2)*((I-2)<J)*((I+2)>J) 
			EGG = (I=4)*(J=4)
			'COLOR 1 USUALLY, UNLESS IN KEEP, AND THEN EGG
			COLOR 1 - KEEP + 2*EGG
			'BLOCKS AND DIAMOND
			TEXT 76 + (J-I)*8,32 + I*8,CHR$(160 - 64*EGG )
		NEXT J
	NEXT I

	PAUSE 60 : REM WAIT A SECOND BEFORE WE START

	'INNER GAME LOOP
	REPEAT

		DPOKE PM+384+15+MY,$0000 : REM ERASE MISSLE 

		'FIRE MISSLE?
		COLOR 3 : REM NEED TO SELECT MISSLE EXHAUST TRAIL COLOR
		IF M=0
			STARTPOS=RND*(3.14+2*.18)-.18 : REM PICK A RANDOM ANGLE
			CC=COS(STARTPOS) : REM UNIT VECTOR COMPONENTS OF ANGLE
			SS=SIN(STARTPOS)
			MX = 80 + RADIUS * CC: REM COMPUTE X STARTING POINT
			MY = 68 - RADIUS * SS : REM COMPUTE Y STARTING POINT
			DMX = -SPEED*CC : REM COMPUTE X COMPONENT OF VELOCITY
			DMY = SPEED*SS : REM COMPUTE Y COMPONENT OF VELOCITY
			M=1 : REM SET MISSLE FLAG TO TRUE
			PLOT MX,MY : REM START EXHAUST TRAIL
		ENDIF

		'CLEAR COLLISION REGISTER
		POKE 53278,0

		MX=MX+DMX : REM UPDATE X POSITION
		POKE $D004,MX+45 : REM MOVE MISSLE TO NEW X POSITION
		MY=MY+DMY : REM UPDATE Y POSITION
		DPOKE PM+384+15+MY,$0101 : REM DRAW MISSLE AT NEW Y POSITION
		DRAWTO MX,MY : REM CONTINUE EXHAUST TRAIL

		PAUSE 1 : REM MAKE SURE ENTIRE SCREEN HAS BEEN REWRITTEN AT LEAST ONCE
		'DETECT CASTLE HIT
		IF PEEK($D000)&1=1 : REM CHECK FOR COLLISION WITH COLOR 1
			FOR CC=0 TO 1 : REM LOOP THROUGH TWO COLORS
				COLOR (1-CC)*3 : REM DRAW CIRCLES THEN ERASE CIRCLES
				FOR RR=1 TO 8 : REM LOOP THROUGH 8 RADII
					CIRCLE MX,MY,RR : REM CREATE EXPLOSION OUT OF CIRCLES
					SETCOLOR 2,RAND(16),10 : REM FLASH EXPLOSION WITH RANDOM COLORS
				NEXT RR
			NEXT CC
			PLOT MX,MY : REM ERASE THE LAST LITTLE DOT IN THE MIDDLE
			SETCOLOR 2,8,14 : REM RESET COLOR 3
			M=0 : REM NOTE THERE IS NO MORE MISSLE IN PLAY
		ELSE
			IF PEEK($D000)&2=2 : REM CHECK FOR COLLSION WITH COLOR 2 (GOLDEN EGG)
				?,"GAME OVER";
				FOR RR=1 TO 48 : REM DRAW A BIG EXPLOSION
					CIRCLE MX,MY,2*RR
					SETCOLOR 4,RAND(16),4 : REM FLASH BACKGROUND COLOR RANDOMLY
				NEXT RR
				RUN : REM START OVER
			ENDIF
		ENDIF

		'CLEAR COLLISION REGISTER
		POKE 53278,0

		'MOVE THE SHIELD: NOTE THESE LONG MOVE STATEMENTS ARE TRICKY TO PLACE IN THE CODE AND AVOID BLANK SPACE
		PP=INT(0.395*(228-PADDLE(0))) : REM READ PADDLE VALUE AND SCALE IT
		PAUSE 0 : REM TRY TO SYNC UP SPRITE MOVE WITH VSYNC
		'MOVE IN Y-AXIS BUT DEPENDS UPON X-AXIS
		MOVE PM+128+128*(PP>46)-87+PP*(PP<47)-(PP-95)*(PP>46)+38,PM+512+37,56
		POKE $D000,78+PP : REM MOVE IN X AXIS
		PAUSE 0 : REM TRY TO SYNC UP SPRITE MOVE WITH VSYNC
		'MOVE IN Y-AXIS BUT DEPENDS UPON X-AXIS
		MOVE PM+128+128*(PP>43)-82+PP*(PP<44)-(PP-85)*(PP>43)+38,PM+640+37,56
		POKE $D001,83+PP : REM MOVE IN X AXIS

		'DETECT BOUNCE
		IF PEEK($D008)>0 : REM IF ANY COLLISION BETWEEN MISSLE AND PLAYERS
			M=0 : REM NO MORE MISSLE
			SCORE=SCORE+1 : REM ADD A POINT!
			'UPDATE SCORE
			POKE 657,21
			?"score ";SCORE;" of ";MAXSCORE;
		ENDIF

	UNTIL SCORE=MAXSCORE : REM THAT LEVEL CLEARED!

	SCORE=0 : REM RESET THE SCORE FOR THE NEXT LEVEL
	LEVEL = LEVEL + 1 : REM INCREASE LEVEL COUNTER
	SPEED = SPEED + .33 : REM MAKE THE MISSLES MOVE A LITTLE FASTER 
	RADIUS = RADIUS - 4 : REM START THE MISSLES A LITTLE CLOSER

UNTIL LEVEL=5 : REM CLEARED ALL THE LEVELS!

?,"YoU wIn!";
DO
LOOP : REM WAIT FOREVER
