lightcycles.asm
dschmenk_LightCycles/lightcycles.asm
;*
;* Light Cycles 3D
;*
KEYBD	=	$C000	; Keyboard addresses
KEYSTRB	=	$C010
SPEAKER	=	$C030
GCSTROBE =	$C070
GC0	=	$C064
GC1	=	$C065
GCPB1	=	$C061
GCPB2	=	$C062
STPTRL	=	$06
STPTRH	=	$07
STPTR	=	STPTRL
ANGLE	=	$08
SCANIDX	=	$08
SCANLN	=	$09
VIEWPORT =	$0A
XVIEWF	=	$20
XVIEWI	=	$21
YVIEWF	=	$22
YVIEWI	=	$23
CH	=	$24
CV	=	$25
TBAS1L	=	$28
TBAS1H	=	$29
TBAS1	=	TBAS1L
TBAS2L	=	$2A
TBAS2H	=	$2B
TBAS2	=	TBAS2L
INVFLAG	=	$32
S_FRACL	=	$1A
S_FRACH	=	$1B
S_INT	=	$1C
T_FRACL	=	$1D
T_FRACH	=	$1E
T_INT	=	$1F
DS_FRACL=	$4E
DS_FRACH=	$3A
DS_INT	=	$3B
DT_FRACL=	$4F
DT_FRACH=	$3C
DT_INT	=	$3D
S_MIDFL	=	$50
S_MIDFH	=	$51
S_MIDI	=	$52
T_MIDFL	=	$53
T_MIDFH	=	$54
T_MIDI	=	$55
SRCMASK	=	$60
DSTMASK	=	$61
DVSR	=	$F8	; and $F9
DVDND	=	$FA	; and $FB
QUADRNT	=	$FC
SIGN	=	$FD
TMP	=	$FE	; and $FF
GBASL	=	$26	; GR ZP addresses
GBASH	=	$27
GBASE	=	GBASL
GPAGE	=	$2F
GCLR	=	$30
BLACK	=	$00	; GR colors
MAGENTA	=	$11
DRKBLU	=	$22
PURPLE	=	$33
DRKGRN	=	$44
GREY	=	$55
MEDBLU	=	$66
LGTBLU	=	$77
BROWN	=	$88
ORANGE	=	$99
GRAY	=	$AA
PINK	=	$BB
LGTGRN	=	$CC
YELLOW	=	$DD
AQUA	=	$EE
WHITE	=	$FF
HORIZON	=	16
VIEWBOT	=	19	; Bottom viewport
VIEWTOP	=	09
GCMAX	=	127	; Max value for game controller
;GCXPOS	=	$F0
;GCYPOS	=	$F1
;GCBTTNS	=	$F2
GCBTTN1	=	$80	; Game controller
GCBTTN2	=	$40
GCLIMITDLY =	15
MAP	=	$A000	; Arena map
P1CLR	=	DRKGRN;LGTGRN
P1TLCLR	=	LGTGRN;DRKGRN
P2CLR	=	BROWN;PURPLE
P2TLCLR	=	PURPLE;BROWN
FULLBOOST = 	$F0
*	=	$1000
	!SOURCE	"intro.asm"
	!SOURCE	"drawview.asm"
	!SOURCE	"utils.asm"
;*
;* Main game loop
;*	
GAMELOOP
	LDA	#$00	; Clear player status
	STA	PSTATUS
;*
;* Calculate angle and distance^2 between players
;*
	LDA	P2XF
	SEC
	SBC	P1XF
	TAY
	LDA	P2XI
	SBC	P1XI
	TAX
	TYA
	LDY	#$00	; Assume no X coord flip
	CPX	#$80
	BCC	+
	JSR	NEG
	LDY	#$3F
+	STY	QUADRNT
	STA	DVSR
	STX	DVSR+1
	TXA
	JSR	MUL8X8	; Calc triangle edge (a*a)
	PHA
	TXA
	PHA
	LDA	P2YF
	SEC
	SBC	P1YF
	TAY
	LDA	P2YI
	SBC	P1YI
	TAX
	TYA
	LDY	#$00	; Assume no Y coord flip
	CPX	#$80
	BCC	+
	JSR	NEG
	LDY	#$7F
+	STA	DVDND
	STX	DVDND+1
	TYA
	EOR	QUADRNT
	STA	QUADRNT
	TXA
	JSR	MUL8X8	; Calc triangle edge (b*b)
	STA	TMP
	STX	TMP+1
	PLA
	TAX
	PLA
	CLC
	ADC	TMP
	STA	TMP
	TXA
	LDX	#$00
	ADC	TMP+1
	STA	PPDIST
	BNE	+	; Convert distance^2 (c*c) to size for rendering
	LDX	#$08	; Less than 16 tiles away (16*16=256)
	LDA	TMP
-	DEX
	LSR
	BNE	-
+	STX	PPSIZE
	LDX	#$00	; Assume no octant flip
	LDA	DVDND	; Calc tan() in first octant for precision
	CMP	DVSR
	LDA	DVDND+1
	SBC	DVSR+1
	BCC	+
	LDA	DVDND	; Flip octant
	LDX	DVSR	; Swap divisor <-> dividend
	STA	DVSR
	STX	DVDND
	LDA	DVDND+1
	LDX	DVSR+1
	STA	DVSR+1
	STX	DVDND+1
	LDX	#$80
+	STX	SIGN	; Use SIGN to save octant flip flag
	LDX	DVSR+1	; Divide 8.8 by 8.0 to get 8.8 result
	LDA	DVSR	; Convert divisor to 8.0
	ASL		; Round up
	BCC	+
	INX
+	STX	DVSR
	LDA	#$00
	STA	DVSR+1
	JSR	DIV
	CPX	#$00
	BEQ	+
	LDA	#$10	; On the diagonal
	BNE	++
+	LDX	#$FE
SRCHTAN	INX	; Scan tan() table LSBs for matching angle
	INX
	CMP	TAN_TBL,X
	BEQ	+
	BCS	SRCHTAN	; Less than, reload MSB and keep searching
+	TXA
	LSR		; Convert index to angle
	LDX	SIGN
	BPL	++
	STA	TMP	; Reflect octant
	LDA	#$20
	SEC
	SBC	TMP
++	EOR	QUADRNT	; Reflect into correct quadrant
	STA	PPANGLE
;*
;* Update rythm based on player-to-player distance
;*
	LDA	DRYTHM
	CLC
	ADC	#$01
	CMP	PPDIST
	BCC	+
	LDA	#$00
	LSR	VTONE
	BNE	+
	LDX	#$02
	STX	VTONE
+	STA	DRYTHM
;*
;* Render views
;*	
	LDA	P1ANGLE
	STA	ANGLE
	LDA	P1XF
	STA	XVIEWF
	LDA	P1XI
	STA	XVIEWI
	LDA	P1YF
	STA	YVIEWF
	LDA	P1YI
	STA	YVIEWI
	LDA	#$02
	SEC
	SBC	P1TURBO
	STA	MTONE
	LDA	#VIEWTOP
	JSR	DRAWVIEW
	LDA	P2CYCLE
	STA	GCLR
	LDA	P1ANGLE
	SEC
	SBC	PPANGLE
	AND	#$7F
	TAX
	LDA	#VIEWTOP
	JSR	DRAWENEMY
	LDA	P2ANGLE
	STA	ANGLE
	LDA	P2XF
	STA	XVIEWF
	LDA	P2XI
	STA	XVIEWI
	LDA	P2YF
	STA	YVIEWF
	LDA	P2YI
	STA	YVIEWI
	LDA	#$02
	SEC
	SBC	P2TURBO
	STA	MTONE
	LDA	#VIEWBOT
	JSR	DRAWVIEW
	LDA	P1CYCLE
	STA	GCLR
	LDA	P2ANGLE
	SEC
	SBC	PPANGLE
	CLC
	ADC	#$40	; Flip angle to opposite direction
	AND	#$7F
	TAX
	LDA	#VIEWBOT
	JSR	DRAWENEMY
	JSR	GSWAP
;*
;* AI player update
;*
AI1	LDA	P1MAN
	BNE	AI2
;	BEQ	+
;	JMP	AI2
;+
	LDX	P1XI
	LDY	P1YI
	JSR	MAPWTS	; Calc best direction based on map
	LDY	P2ANGLE
	LDX	#$00
	LDA	COS_TBL,Y
	ASL
	BCC	+
	DEX
	CLC
+	ADC	P2XF
	TXA
	ADC	P2XI
	SEC
	SBC	P1XI
	PHA
	LDX	#$00
	LDA	SIN_TBL,Y
	ASL
	BCC	+
	DEX
	CLC
+	ADC	P2YF
	TXA
	ADC	P2YI
	SEC
	SBC	P1YI
	TAY
	PLA
	TAX
;	LDA	P2XF
;	CMP	P1XF
;	LDA	P2XI
;	SBC	P1XI
;	TAX
;	LDA	P2YF
;	CMP	P1YF
;	LDA	P2YI
;	SBC	P1YI
;	TAY
	JSR	ENMYWT	; Calc best dir based on enemy relative pos
	LDA	P1ANGLE	; Default to current angle
	LSR
	LSR
	LSR
	LSR
	LSR
	TAY
	EOR	#$02	; Don't allow 180 degree turns
	TAX
	LDA	#$00
	STA	AIMOVE,X
	LDA	AIMOVE,Y
	LDX	#$03
-	CMP	AIMOVE,X ; Select highest weighted direction
	BCS	+
	TXA
	TAY
	LDA	AIMOVE,X
+	DEX
	BPL	-
	TYA		; Convert to angle
	ASL
	ASL
	ASL
	ASL
	ASL
;	CMP	P1ANGLE
;	BEQ	+
	STA	P1ANGLE
;	LDA	#$80
;	STA	P1XF
;	STA	P1YF
+	LDY	#$00
	LDX	PPSIZE	; Turbo when enemy is close
;	DEX
	BEQ	+
	INY
+	STY	P1TURBO
;	LDX	#5
;	LDY	#23
;	JSR	GOTOXY
;	LDA	AIMOVE+0
;	JSR	PUTA
;	LDA	#' '
;	JSR	PUTC
;	LDA	AIMOVE+1
;	JSR	PUTA
;	LDA	#' '
;	JSR	PUTC
;	LDA	AIMOVE+2
;	JSR	PUTA
;	LDA	#' '
;	JSR	PUTC
;	LDA	AIMOVE+3
;	JSR	PUTA
;	LDA	#'='
;	JSR	PUTC
;	LDA	P1ANGLE
;	JSR	PUTA
AI2	LDA	P2MAN
	BNE	READKBD
;	BEQ	+
;	JMP	READKBD
;+
	LDX	P2XI
	LDY	P2YI
	JSR	MAPWTS	; Calc best direction based on map
	LDY	P1ANGLE
	LDX	#$00
	LDA	COS_TBL,Y
	ASL
	BCC	+
	DEX
	CLC
+	ADC	P1XF
	TXA
	ADC	P1XI
	SEC
	SBC	P2XI
	PHA
	LDX	#$00
	LDA	SIN_TBL,Y
	ASL
	BCC	+
	DEX
	CLC
+	ADC	P1YF
	TXA
	ADC	P1YI
	SEC
	SBC	P2YI
	TAY
	PLA
	TAX
;	LDA	P1XF
;	CMP	P2XF
;	LDA	P1XI
;	SBC	P2XI
;	TAX
;	LDA	P1YF
;	CMP	P2YF
;	LDA	P1YI
;	SBC	P2YI
;	TAY
	JSR	ENMYWT	; Calc best dir based on enemy relative pos
	LDA	P2ANGLE	; Default to current angle
	LSR
	LSR
	LSR
	LSR
	LSR
	TAY
	EOR	#$02	; Don't allow 180 degree turns
	TAX
	LDA	#$00
	STA	AIMOVE,X
	LDA	AIMOVE,Y
	LDX	#$03
-	CMP	AIMOVE,X ; Select highest weighted direction
	BCS	+
	TXA
	TAY
	LDA	AIMOVE,X
+	DEX
	BPL	-
	TYA		; Convert to angle
	ASL
	ASL
	ASL
	ASL
	ASL
;	CMP	P2ANGLE
;	BEQ	+
	STA	P2ANGLE
;	LDA	#$80
;	STA	P2XF
;	STA	P2YF
+	LDY	#$00
	LDX	PPSIZE	; Turbo when enemy is close
;	DEX
	BEQ	+
	INY
+	STY	P2TURBO
;	LDX	#25
;	LDY	#23
;	JSR	GOTOXY
;	LDA	AIMOVE+0
;	JSR	PUTA
;	LDA	#' '
;	JSR	PUTC
;	LDA	AIMOVE+1
;	JSR	PUTA
;	LDA	#' '
;	JSR	PUTC
;	LDA	AIMOVE+2
;	JSR	PUTA
;	LDA	#' '
;	JSR	PUTC
;	LDA	AIMOVE+3
;	JSR	PUTA
;	LDA	#'='
;	JSR	PUTC
;	LDA	P2ANGLE
;	JSR	PUTA
;*
;* Get player input and update position
;*
READKBD	LDA	KEYBD
	BMI	+
	JMP	READPDL
+	BIT	KEYSTRB
	CMP	#$9B	; ESC key?
	BNE	+
-	LDA	KEYBD	; Pause
	BPL	-
	BIT	KEYSTRB
	CMP	#$D1	; Quit
	BNE	+
	LDA	#$03
	STA	PSTATUS
	RTS
+	LDX	USEPDLS
	BEQ	+
	JMP	READPDL
+	LDX	P1MAN
	BEQ	++
	CMP	#$C1	; A key
	BNE	+
	LDA	P1ANGLE
	SEC
	SBC	#$20
	AND	#$7F
	STA	P1ANGLE
;	LDA	#$80
;	STA	P1XF
;	STA	P1YF
	BNE	READPDL
+	CMP	#$C4	; D key
	BNE	+
	LDA	P1ANGLE
	CLC
	ADC	#$20
	AND	#$7F
	STA	P1ANGLE
;	LDA	#$80
;	STA	P1XF
;	STA	P1YF
	BNE	READPDL
+	CMP	#$D3	; S key
	BNE	++
	LDA	P1TURBO
	EOR	#$01
	STA	P1TURBO
	BPL	READPDL
++	LDX	P2MAN
	BEQ	READPDL
	CMP	#$CA	; J key
	BNE	+
	LDA	P2ANGLE
	SEC
	SBC	#$20
	AND	#$7F
	STA	P2ANGLE
;	LDA	#$80
;	STA	P2XF
;	STA	P2YF
	BNE	READPDL
+	CMP	#$CC	; L key
	BNE	+
	LDA	P2ANGLE
	CLC
	ADC	#$20
	AND	#$7F
	STA	P2ANGLE
;	LDA	#$80
;	STA	P2XF
;	STA	P2YF
	BNE	READPDL
+	CMP	#$CB	; K key
	BNE	READPDL
	LDA	P2TURBO
	EOR	#$01
	STA	P2TURBO
READPDL	JSR	GCREAD
	PHA
	LDA	USEPDLS
	BNE	+
	PLA
	JMP	CHKBOOST
+	LDA	P1MAN	; Check for player 1 AI
	BEQ	+
	LDA	#$00
	STA	P1TURBO
	PLA
	PHA
	BPL	++	
	INC	P1TURBO
	BNE	++
+	LDY	#GCMAX/2
++	LDA	P2MAN	; Check for player 2 AI
	BEQ	+
	LDA	#$00
	STA	P2TURBO
	PLA
	ASL
	BPL	++
	INC	P2TURBO
	BNE	++
+	LDX	#GCMAX/2
	PLA
++	JSR	UPDTPDL
	TYA
	SEC
	SBC	#GCMAX/16
	CLC
	ADC	P1ANGLE
	AND	#$7F
	STA	P1ANGLE
	TXA
	SEC
	SBC	#GCMAX/16
	CLC
	ADC	P2ANGLE
	AND	#$7F
	STA	P2ANGLE
CHKBOOST LDA	P1TURBO
	BEQ	++
	LDA	P1BOOST
	BEQ	+
	SEC
	SBC	#$08
	STA	P1BOOST
	LDX	#3
	LDY	#21
	JSR	UPDTBST
	LDA	#$01
+	STA	P1TURBO
++	LDA	P2TURBO
	BEQ	P1MOVE
	LDA	P2BOOST
	BEQ	+
	SEC
	SBC	#$08
	STA	P2BOOST
	LDX	#22
	LDY	#21
	JSR	UPDTBST	
	LDA	#$01
+	STA	P2TURBO
;*
;* Update player 1
;*
P1MOVE	LDY	P1ANGLE
	LDA	P1TURBO
	LSR
	LDX	#$00
	LDA	COS_TBL,Y
	BPL	+	; Sign extend into X
	DEX
+	BCS	+	; Turbo active?
	CMP	#$80
	ROR
+	CLC
	ADC	P1XF
	STA	P1XF
	TXA
	ADC	P1XI
	STA	P1XI
	LDA	P1TURBO
	LSR
	LDX	#$00
	LDA	SIN_TBL,Y
	BPL	+	; Sign extend into X
	DEX
+	BCS	+	; Turbo active?
	CMP	#$80
	ROR
+	CLC
	ADC	P1YF
	STA	P1YF
	TXA
	ADC	P1YI
	STA	P1YI
;*
;* Update player 2
;*
P2MOVE	LDY	P2ANGLE
	LDA	P2TURBO
	LSR
	LDX	#$00
	LDA	COS_TBL,Y
	BPL	+	; Sign extend into X
	DEX
+	BCS	+	; Turbo active?
	CMP	#$80
	ROR
+	CLC
	ADC	P2XF
	STA	P2XF
	TXA
	ADC	P2XI
	STA	P2XI
	LDA	P2TURBO
	LSR
	LDX	#$00
	LDA	SIN_TBL,Y
	BPL	+	; Sign extend into X
	DEX
+	BCS	+	; Turbo active?
	CMP	#$80
	ROR
+	CLC
	ADC	P2YF
	STA	P2YF
	TXA
	ADC	P2YI
	STA	P2YI
;*
;* Check for collision
;*
	;LDA	P2YI
	CMP	P1YI
	BNE	UPDTAIL1
	LDA	P2XI
	CMP	P1XI
	BNE	UPDTAIL1
	LDA	#$03
	STA	PSTATUS
;*
;* Update map with tails
;*
UPDTAIL1 LDX	P1XI	; Player 1 tail
	LDY	P1YI
	CPX	P1XPREV
	BNE	+
	CPY	P1YPREV
	BEQ	UPDTAIL2
+	STX	P1XPREV
	STY	P1YPREV
	INC	P1HEAD
	LDA	P1HEAD
	AND	LENTAIL
	TAX
	PHA
	LDY	P1XTAIL,X
	LDA	P1YTAIL,X
	TAX
	LDA	MAP_TBLL,X
	STA	TMP
	LDA	MAP_TBLH,X
	STA	TMP+1
	TXA	 	; Which color to clear to
	LSR
	TYA
	ADC	#$00
;	LDA	P1XTAIL,X ; Which color to clear to
;	EOR	P1YTAIL,X
	LSR
	LDA	#GREY
	BCS	+
	LDA	#DRKBLU
+	STA	(TMP),Y	; Clear map
	PLA
	TAX
	LDA	P1XI
	CMP	#$40
	BCS	DEREZ1
	STA	P1XTAIL,X
	TAY
	LDA	P1YI
	CMP	#$40
	BCS	DEREZ1
	STA	P1YTAIL,X
	TAX
	LDA	MAP_TBLL,X
	STA	TMP
	LDA	MAP_TBLH,X
	STA	TMP+1
	LDA	(TMP),Y
	CMP	#DRKBLU
	BEQ	+
	CMP	#GREY
	BEQ	+
DEREZ1	LDA	#$01	; Uh, oh. Player 1 derez!
	ORA	PSTATUS
	STA	PSTATUS
	BNE	UPDTAIL2
+	LDA	#P1TLCLR
	STA	(TMP),Y
UPDTAIL2 LDX	P2XI	; Player 2 tail
	LDY	P2YI
	CPX	P2XPREV
	BNE	+
	CPY	P2YPREV
	BEQ	CHKSTAT
+	STX	P2XPREV
	STY	P2YPREV
	INC	P2HEAD
	LDA	P2HEAD
	AND	LENTAIL
	TAX
	PHA
	LDY	P2XTAIL,X	
	LDA	P2YTAIL,X
	TAX
	LDA	MAP_TBLL,X
	STA	TMP
	LDA	MAP_TBLH,X
	STA	TMP+1
	TXA 		; Which color to clear to
	LSR
	TYA
	ADC	#$00
;	LDA	P2XTAIL,X ; Which color to clear to
;	EOR	P2YTAIL,X
	LSR
	LDA	#GREY
	BCS	+
	LDA	#DRKBLU
+	STA	(TMP),Y	; Clear map
	PLA
	TAX
	LDA	P2XI
	CMP	#$40
	BCS	DEREZ2
	STA	P2XTAIL,X
	TAY
	LDA	P2YI
	CMP	#$40
	BCS	DEREZ2
	STA	P2YTAIL,X
	TAX
	LDA	MAP_TBLL,X
	STA	TMP
	LDA	MAP_TBLH,X
	STA	TMP+1
	LDA	(TMP),Y
	CMP	#DRKBLU
	BEQ	+
	CMP	#GREY
	BEQ	+
DEREZ2	LDA	#$02	; Uh, oh. Player 2 derez!
	ORA	PSTATUS
	STA	PSTATUS
	BNE	GAMEOVER
+	LDA	#P2TLCLR
	STA	(TMP),Y
CHKSTAT	LDA	PSTATUS
	BNE	GAMEOVER
	INC	FRAMENUM
	LDA	FRAMENUM
	LSR
	AND	#$03
	TAX
	LDA	P1CYCLE+1,X
	STA	P1CYCLE
	LDA	P2CYCLE+1,X
	STA	P2CYCLE
;	LDX	#19
;	LDY	#23
;	JSR	GOTOXY
;	LDA	FRAMENUM
;	JSR	PUTA
	JMP	GAMELOOP
GAMEOVER RTS
;*
;* Calc best direction based on map
;*
MAPWTS	LDA	#$00
	STA	AIMOVE+0
	STA	AIMOVE+1
	STA	AIMOVE+2
	STA	AIMOVE+3
	TYA
	PHA
	TXA
	PHA
	TYA
	TAX
	LDA	MAP_TBLL,X
	STA	TMP
	LDA	MAP_TBLH,X
	STA	TMP+1	; Check map for obstacles
	PLA
	PHA
	TAY
	INY		; Check +X
	CPY	#$40
	BCS	++	; Off map
	LDA	(TMP),Y
	CMP	#DRKBLU
	BEQ	+
	CMP	#GREY
	BNE	++	; Some kind of obstacle
+	LDA	#$04
	STA	AIMOVE+0
	INY		; Check ++X
	CPY	#$40
	BCS	++	; Off map
	LDA	(TMP),Y
	CMP	#DRKBLU
	BEQ	+
	CMP	#GREY
	BNE	++	; Some kind of obstacle
+	LDA	#$05
	STA	AIMOVE+0
++	PLA
	PHA
	TAY
	DEY		; Check -X
	BMI	++	; Off map
	LDA	(TMP),Y
	CMP	#DRKBLU
	BEQ	+
	CMP	#GREY
	BNE	++	; Some kind of obstacle
+	LDA	#$04
	STA	AIMOVE+2
	DEY		; Check --X
	BMI	++	; Off map
	LDA	(TMP),Y
	CMP	#DRKBLU
	BEQ	+
	CMP	#GREY
	BNE	++	; Some kind of obstacle
+	LDA	#$05
	STA	AIMOVE+2
++	PLA
	TAY
	PLA
	PHA
	TAX
	INX		; Check +Y
	CPX	#$40
	BCS	++
	LDA	MAP_TBLL,X
	STA	TMP
	LDA	MAP_TBLH,X
	STA	TMP+1
	LDA	(TMP),Y
	CMP	#DRKBLU
	BEQ	+
	CMP	#GREY
	BNE	++	; Some kind of obstacle
+	LDA	#$04
	STA	AIMOVE+1
	INX		; Check ++Y
	CPX	#$40
	BCS	++
	LDA	MAP_TBLL,X
	STA	TMP
	LDA	MAP_TBLH,X
	STA	TMP+1
	LDA	(TMP),Y
	CMP	#DRKBLU
	BEQ	+
	CMP	#GREY
	BNE	++	; Some kind of obstacle
+	LDA	#$05
	STA	AIMOVE+1
++	PLA
	TAX
	DEX		; Check -Y
	BMI	++
	LDA	MAP_TBLL,X
	STA	TMP
	LDA	MAP_TBLH,X
	STA	TMP+1
	LDA	(TMP),Y
	CMP	#DRKBLU
	BEQ	+
	CMP	#GREY
	BNE	++	; Some kind of obstacle
+	LDA	#$04
	STA	AIMOVE+3
	DEX		; Check --Y
	BMI	++
	LDA	MAP_TBLL,X
	STA	TMP
	LDA	MAP_TBLH,X
	STA	TMP+1
	LDA	(TMP),Y
	CMP	#DRKBLU
	BEQ	+
	CMP	#GREY
	BNE	++	; Some kind of obstacle
+	LDA	#$05
	STA	AIMOVE+3
++	RTS
;*
;* Calc best direction based on relative enemy poition
;*
ENMYWT	TXA
	BEQ	++
	BMI	+
	INC	AIMOVE+0 ; Enemy to the right
	INC	AIMOVE+0
	BNE	++
+	INC	AIMOVE+2 ; Enemy to the left
	INC	AIMOVE+2
++	TYA
	BEQ	++
	BMI	+
	INC	AIMOVE+1 ; Enemy above
	INC	AIMOVE+1
	RTS
+	INC	AIMOVE+3 ; Enemy below
	INC	AIMOVE+3
++	RTS
;*
;* Player variables
;*
PSTATUS	!BYTE	$00	; Player alive status
PPANGLE	!BYTE	$00	; Player-to-player angle
PPDIST	!BYTE	$00	; Player-to=player distance^2
PPSIZE	!BYTE	$00	; Player-to-player size
LENTAIL	!BYTE	$0F	; Tail length
P1MAN	!BYTE	$01	; Human/AI
P1ANGLE	!BYTE	$00	; Direction
P1XF	!BYTE	$00	; Position
P1XI	!BYTE	$00
P1YF	!BYTE	$00
P1YI	!BYTE	$00
P1TURBO	!BYTE	$00
P1BOOST	!BYTE	$F0
P1XPREV	!BYTE	$FF
P1YPREV	!BYTE	$FF
P1HEAD	!BYTE	$00	; Tail list - set length for easy/med/hard
P1XTAIL	!FILL	256
P1YTAIL	!FILL	256
P1CYCLE	!BYTE	P1CLR,GRAY,P1CLR,WHITE,P1CLR
P2MAN	!BYTE	$01	; Human/AI
P2ANGLE	!BYTE	$00	; Direction
P2XF	!BYTE	$00	; Position
P2XI	!BYTE	$00
P2YF	!BYTE	$00
P2YI	!BYTE	$00
P2TURBO	!BYTE	$00
P2BOOST	!BYTE	$F0
P2XPREV	!BYTE	$FF
P2YPREV	!BYTE	$FF
P2HEAD	!BYTE	$00	; Tail list - set length for easy/med/hard
P2XTAIL	!FILL	256
P2YTAIL	!FILL	256
P2CYCLE	!BYTE	P2CLR,GRAY,P2CLR,WHITE,P2CLR
;*
;* AI best move weights
;*
AIMOVE	!BYTE	$00,$00,$00,$00
;*
;* Working variables
;*
USEPDLS	!BYTE	$00
CURPAGE	!BYTE	$01
PGBASE	!BYTE	$08,$04
FRAMENUM !BYTE	$00
DRYTHM	!BYTE	$00
VTONE	!BYTE	$01
VDLY	!BYTE	$01
MTONE	!BYTE	$01
MDLY	!BYTE	$01
;*
;* Background walls - set each wall quadrant to a different color
;*
WALLS	!BYTE	PINK,PINK,PINK,PINK,PINK,PINK,PINK,PINK,PINK,PINK,PINK,PINK,PINK,PINK,PINK,PINK
	!BYTE	YELLOW,YELLOW,YELLOW,YELLOW,YELLOW,YELLOW,YELLOW,YELLOW,YELLOW,YELLOW,YELLOW,YELLOW,YELLOW,YELLOW,YELLOW,YELLOW
	!BYTE	YELLOW,YELLOW,YELLOW,YELLOW,YELLOW,YELLOW,YELLOW,YELLOW,YELLOW,YELLOW,YELLOW,YELLOW,YELLOW,YELLOW,YELLOW,YELLOW
	!BYTE	AQUA,AQUA,AQUA,AQUA,AQUA,AQUA,AQUA,AQUA,AQUA,AQUA,AQUA,AQUA,AQUA,AQUA,AQUA,AQUA
	!BYTE	AQUA,AQUA,AQUA,AQUA,AQUA,AQUA,AQUA,AQUA,AQUA,AQUA,AQUA,AQUA,AQUA,AQUA,AQUA,AQUA
	!BYTE	ORANGE,ORANGE,ORANGE,ORANGE,ORANGE,ORANGE,ORANGE,ORANGE,ORANGE,ORANGE,ORANGE,ORANGE,ORANGE,ORANGE,ORANGE,ORANGE
	!BYTE	ORANGE,ORANGE,ORANGE,ORANGE,ORANGE,ORANGE,ORANGE,ORANGE,ORANGE,ORANGE,ORANGE,ORANGE,ORANGE,ORANGE,ORANGE,ORANGE
	!BYTE	PINK,PINK,PINK,PINK,PINK,PINK,PINK,PINK,PINK,PINK,PINK,PINK,PINK,PINK,PINK,PINK
;*
;* Map row addresses
;*
MAP_TBLL !BYTE	$00,$40,$80,$C0,$00,$40,$80,$C0,$00,$40,$80,$C0,$00,$40,$80,$C0
	!BYTE	$00,$40,$80,$C0,$00,$40,$80,$C0,$00,$40,$80,$C0,$00,$40,$80,$C0
	!BYTE	$00,$40,$80,$C0,$00,$40,$80,$C0,$00,$40,$80,$C0,$00,$40,$80,$C0
	!BYTE	$00,$40,$80,$C0,$00,$40,$80,$C0,$00,$40,$80,$C0,$00,$40,$80,$C0
MAP_TBLH !BYTE	$00+>MAP,$00+>MAP,$00+>MAP,$00+>MAP,$01+>MAP,$01+>MAP,$01+>MAP,$01+>MAP,$02+>MAP,$02+>MAP,$02+>MAP,$02+>MAP,$03+>MAP,$03+>MAP,$03+>MAP,$03+>MAP
	!BYTE	$04+>MAP,$04+>MAP,$04+>MAP,$04+>MAP,$05+>MAP,$05+>MAP,$05+>MAP,$05+>MAP,$06+>MAP,$06+>MAP,$06+>MAP,$06+>MAP,$07+>MAP,$07+>MAP,$07+>MAP,$07+>MAP
	!BYTE	$08+>MAP,$08+>MAP,$08+>MAP,$08+>MAP,$09+>MAP,$09+>MAP,$09+>MAP,$09+>MAP,$0A+>MAP,$0A+>MAP,$0A+>MAP,$0A+>MAP,$0B+>MAP,$0B+>MAP,$0B+>MAP,$0B+>MAP
	!BYTE	$0C+>MAP,$0C+>MAP,$0C+>MAP,$0C+>MAP,$0D+>MAP,$0D+>MAP,$0D+>MAP,$0D+>MAP,$0E+>MAP,$0E+>MAP,$0E+>MAP,$0E+>MAP,$0F+>MAP,$0F+>MAP,$0F+>MAP,$0F+>MAP
;*
;* Text/GR screen row addresses
;*
TXT_TBLL		; TXT/GR row pointers
	!BYTE	<$000,<$080,<$100,<$180,<$200,<$280,<$300,<$380
	!BYTE	<$028,<$0A8,<$128,<$1A8,<$228,<$2A8,<$328,<$3A8
	!BYTE	<$050,<$0D0,<$150,<$1D0,<$250,<$2D0,<$350,<$3D0
TXT_TBLH		; TXT/GR row pointers
	!BYTE	>$000,>$080,>$100,>$180,>$200,>$280,>$300,>$380
	!BYTE	>$028,>$0A8,>$128,>$1A8,>$228,>$2A8,>$328,>$3A8
	!BYTE	>$050,>$0D0,>$150,>$1D0,>$250,>$2D0,>$350,>$3D0
	!SOURCE	"grnd_st.asm"
	!SOURCE	"sincos.asm"
	!SOURCE	"tan.asm"
	!WORD	$FFFF	; Make sure tan() table search stops here

