*	    2035    030784
*
*
** UFO.S **
** ASTEROIDS FOR THE ATARI 3600 **
** THIS FILE CONTAINS THE UFO HANDLING ROUTINE **
**
** TRASHES: X, Y, AC AND FIRST 7 BYTES OF TEMP.

URTS:
	RTS
UFO:
	LDA	STATUS+25	;CHECK STATUS OF UFO
	BMI	TOOFAR
	JMP	NOTNEW		;DON'T INITIALIZE IF ALREADY EXISTS
TOOFAR:
	CMP	#$FF		;IF HE'S BLOWING UP, DO NOTHING TILL
	BNE	URTS		; HE'S DEAD.

	LDA	DIFF		;IF NOVICE THEN NO UFO
	BEQ	URTS
	LDA	MODE		;CHECK STATUS OF SHIPS
	CMP	#1
	BMI	NOTTEAM
	LDA	STATE
	AND	STATE+1
	BNE	URTS

	BEQ	BRINGOUT	;BEQ = JMP

NOTTEAM:
	LDX	PLAYER
	LDA	STATE,X
	BNE	URTS

BRINGOUT:
	LDA	FRMCNT		;EVERY FORTH FRAME
	AND	#2
	BNE	URTS

	LDX	PLAYER
	LDA	ROCKTOT,X	;DON'T BRING OUT UFO IF NO ROCKS.
	BEQ	URTS

	LDY	RTIMER		;DEC RTIMER, BUT PEG AT ZERO
	BEQ	Z2
	DEC	RTIMER
Z2:
	DEC	EDELAY
	BNE	URTS
	INC	EDELAY		;HOLD AT ONE

	CPY	#0		;DON'T CARE NUM ROCKS IF RTIMER=0
	BEQ	LOGG
	CMP	STARTNUM,X	;OR OVER NUMBER TO START
	BCS	URTS

	;NEW UFO TIME!
LOGG:
	LDA	SDELAY		;EVERY TIME UFO GOES REDUCE SDELAY
	SEC
	SBC	#6
	CMP	#20
	BCC	DIES
	STA	SDELAY
DIES:
	LDA	SDELAY
	STA	EDELAY

	LDA	#$15		;INITIALIZE SHOT REPEATER
	STA	USHOTCNT

	JSR	NEWRAND		;SET Y POSITION TO RANDOM #
	LSR			; BETWEEN $10 AND $10+$7F
	ADC	#$10		; (KEEP AWAY FROM TOP AND BOTTOM)
	STA	YPOSH+25

	LDX	PALTAB+25	;LOADER MUST USE CORRECT PAL/WIDTH
	LDA	MODE
	CMP	#1
	BNE	ONE
	LDY	#8
	BPL	TWO
ONE:
	LDA	PLAYER	; CHECK SCORE
	ASL
	ASL
	TAY
TWO:
	LDA	SCORE+1,Y
	CMP	#2
	BCS	MRBILL		; IF MORE THAN 30K THAN MR BILL
	LDA	SDELAY		;IF SDELAY IS BIG THEN SLUGGO
	BMI	SLUGGO
	JSR	NEWRAND
	STA	TEMP
	LDA	SDELAY
	LSR
	CMP	TEMP
	BCS	SLUGGO
MRBILL:
	INX			;ADD ONE FOR SMALLER WIDTH STAMP
	LDY	#SMALLUFO
	BNE	NEWUFO		;UNCONDITIONAL BRANCH
SLUGGO:
	LDY	#LARGEUFO

NEWUFO:
	STY	STATUS+25
	STX	PALS+25
	JSR	NEWRAND		;GOING RIGHT OR LEFT?
	LSR			; SHIFT A RANDOM BIT INTO CARRY
	BCC	GORIGHT		; IF BIT 0, GO RIGHT TO LEFT
	LDA	#XPOSMAX+4	; ELSE LEFT TO RIGHT.
	STA	XPOSH+25
	LDA	#(-1)&255	; XVEL -1 = LEFT TO RIGHT.
	BMI	STORXVEL
GORIGHT:
	LDA	#(XPOSMIN-4)&255
	STA	XPOSH+25
	LDA	#1		; XVEL 1 = RIGHT TO LEFT
STORXVEL:
	STA	XVELH+25
	LDA	#0		; LO BYTE OF XVEL SET TO ZERO
	STA	XVELL+25
	BEQ	ZYVEL		;INITIALLY UFO HAS ZERO Y VELOCITY

NOTNEW:
	LDA	FRMCNT
	CMP	#$FE
	BCC	NOCHNGY		;CHANGE Y VELOCITY ONLY PERIODICALLY
	LDA	DIFF		;FOR INTER ALWAYS STRAIGHT ACROSS
	CMP	#1
	BEQ	ZYVEL
	JSR	NEWRAND		;GET NEW RANDOM VALUE
	CMP	#$AA	
	BCS	MOVEDN		;ONE THIRD OF THE TIME MOVE DOWN
	CMP	#$55
	BCS	MOVEUP		;ONE THIRD MOVE UP
	;DON'T GO STRAIGHT IF TOO CLOSE TO TOP OR BOTTOM: AVOID CLIPPED UFO
	LDA	YPOSH+25
	CMP	#YPOSMAX-20
	BCS	NOCHNGY
	CMP	#YPOSMIN+10
	BCC	NOCHNGY
ZYVEL:
	LDA	#0		;ONE THIRD GO STRAIGHT ACROSS
	STA	YVELH+25
	STA	YVELL+25
	BEQ	NOCHNGY
MOVEDN:
	LDA	#(-1)&255
	BMI	STORYVEL	;BMI = JMP
MOVEUP:
	LDA	#1
STORYVEL:
	STA	YVELH+25	;STORE Y VELOCITY
	LDA	#0
	STA	YVELL+25
NOCHNGY:
	LDA	XVELH+25	;CHECK IF UFO GOES OFF THE SCREEN
	CLC
	ADC	XPOSH+25
	CMP	#XPOSMAX+4	;UFO GOES PAST RIGHT?
	BCC	UCHKSHOT	; NO.  CHECK IF HE MAY SHOOT.
	CMP	#(XPOSMIN-3)&255	;UFO GOES PAST LEFT?
	BCS	UCHKSHOT	; NO.  CHECK IF HE MAY SHOOT.
UFODONE:
	LDA	#$FF		;UFO HAS GONE OFF SCREEN: NUKE HIM
	STA	STATUS+25
	LDA	#$08		;KILL UFO TUNES
	JSR	KILLTUNE
	LDA	#$09
	JSR	KILLTUNE
	RTS

* CHECK TO SEE IF WE SHOULD FIRE NOW
UCHKSHOT:
	LDX	#1		;HAVE 2 UFO SHOTS TO USE
UFOSHOT:
	LDA	STATUS+26,X	;TEST SHOT STATUS
	BMI	ADDUSHOT	;SEE IF SHOT IS ALREADY ON SCREEN
	DEX			;YES, TRY OTHER SHOT
	BPL	UFOSHOT
	BMI	UANIMATE	;NO MORE SHOTS, JUMP TO VARY STAMPS

ADDUSHOT:
	DEC	USHOTCNT	;CHECK COUNTER FOR NEXT SHOT
	BNE	UANIMATE	;NOT TIME YET, JUMP TO VARY STAMPS
	LDA	#$20		;RESET COUNTER
	STA	USHOTCNT
	LDA	#SHOT		;STORE STATUS AS SHOT
	STA	STATUS+26,X
	LDA	#$EC		;STORE COUNTER VALUE
	STA	SHOTCNT,X
	LDA	COLXPOSH+25	;STORE SHOT POSITION AS CENTER OF UFO
	CMP	#XPOSMAX
	BCC	USTXPOS
	SBC	#XPOSMAX
USTXPOS:
	STA	XPOSH+26,X
	LDA	COLYPOSH+25
	CMP	#YPOSMAX
	BCC	USTYPOS
	SBC	#YPOSMAX
USTYPOS:
	STA	YPOSH+26,X
	LDA	#00
	STA	XPOSL+26,X
	STA	YPOSL+26,X

	LDA	STATUS+25	;DETERMINE HOW TO SHOOT
	CMP	#SMALLUFO
	BEQ	AIMSHOT		;MR. BILL AIMS HIS SHOTS
	JSR	NEWRAND		;SLUGGO IS RANDOM
USHOOT:
	AND	#$1F
	TAY
	LDA	HUSHVCTX,Y
	STA	XVELH+26,X
	LDA	USHVCTX,Y
	STA	XVELL+26,X
	LDA	HUSHVCTY,Y
	STA	YVELH+26,X
	LDA	USHVCTY,Y
	STA	YVELL+26,X
	LDA	#$0D		;PLAY UFO SHOT SOUND
	JSR	DOTUNE

UANIMATE:
	LDA	FRMCNT		;VARY UFO STAMPS WITH TIME
	LSR
	LSR
	AND	#$3		;MASK ALL BUT 2 LSBITS

	LDY	STATUS+25	;WHICH TYPE?
	CPY	#SMALLUFO
	BEQ	UANIMSM
	ASL			;BIG UFO HAS 2 BYTES PER ANIMATION
	CLC
	ADC	#UFOL1 & 255	;ADD IN POINTER TO BASE OF LARGE UFO
	JMP	USTACYC
UANIMSM:
	CLC
	ADC	#UFOS1 & 255
USTACYC:
	STA	ACYC+25		;STORE ANIMATION FRAME POINTER
	RTS

AIMSHOT:
* INITIALIZE FLAGS FOR OCTANT SELECTION
	LDA	#0
	STA	TEMP+2		;UDXNEG
	STA	TEMP+3		;UDYNEG
	STA	TEMP+4		;UDIAGNEG

* DETERMINE WHICH SHIP TO SHOOT AT
	LDA	MODE
	CMP	#1
	BMI	ZNOTTEAM	;ISSOLATE CASE OF TEAM PLAY

ZTEAM:
	LDA	STATE		;SEE IF BOTH ALIVE
	AND	STATE+1
	BEQ	PICKSRAN
	LDA	STATE		;NO, SEE WHICH IS, KNOW AT LEAST 1 IS
	BNE	AIMSHIP2

AIMSHIP1:
	LDY	#0		;AIM AT SHIP 1
	BPL	COMPVECT	;BPL = JMP

PICKSRAN:
	JSR	NEWRAND		;PICK A SHIP RANDOMLY
	ASL			;WE'RE SUCH ASL'S
	BCC	AIMSHIP1

AIMSHIP2:
	LDY	#8		;AIM AT SHIP 2
	BPL	COMPVECT	;BPL = JMP HERE

ZNOTTEAM:
	LDY	OFFPLAY2

* COMPUTE VECTORS
COMPVECT:
	LDA	COLXPOSH+24,Y
	SEC
	SBC	COLXPOSH+25	;SUBTRACT UFO'S POSITION TO GET 'DX'
	BCS	UDXPOS
	INC	TEMP+2
	EOR	#$FF
;	CLC			;CARRY IS CLEAR ALREADY
	ADC	#1
UDXPOS:
	STA	TEMP		;SAVE DX

	LDA	COLYPOSH+24,Y
	SEC
	SBC	COLYPOSH+25	;SUBTRACT UFO'S POSITION TO GET 'DY'
	BCS	UDYPOS
	INC	TEMP+3
	EOR	#$FF
;	CLC
	ADC	#1
UDYPOS:
	STA	TEMP+1		;SAVE DY

* NORMALIZE VECTOR TO CORRECT FOR ASPECT RATIO.  WE ALSO SCALE DOWN TO AVOID
* OVERFLOW.  ALSO, FLIP THE VECTOR TO THE FIRST OCTANT (ABOVE THE LINE Y = X).
	LSR			;5/8 = 1/2 + 1/8
	STA	TEMP+5
	LSR
	LSR
	CLC
	ADC	TEMP+5
	CMP	TEMP
	BCS	UDIAGOK		;ON CORRECT SIDE OF DIAGONAL Y = X.
	INC	TEMP+4		;NOT ON CORRECT SIDE:
	TAY			; SWAP DX AND DY
	LDA	TEMP
	STY	TEMP
UDIAGOK:
	LSR			;SCALE    DY <- DY / 4
	LSR
	STA	TEMP+1

* COMPUTE AND SAVE "3/8 DX", TO BE USED BELOW.
	LDA	TEMP		;TEMP+6 <- DX/4 + DX/8
	LSR
	LSR
	STA	TEMP+5
	LSR
	CLC
	ADC	TEMP+5
	STA	TEMP+6

* COMPUTE CORRECT SECTOR (32TH OF CIRCLE) IN Y.
* FIRST, FIGURE OUT WHICH 16TH OF THE CIRCLE.
* WE USE THE 68.2 DEGREE LINE, 'CAUSE IT'S EASIER TO COMPUTE (ATAN(5/8 / 2/8)).
	LDA	TEMP		;5/8 = 1/2 + 1/8
	LSR
	STA	TEMP+5
	LSR
	LSR
	CLC
	ADC	TEMP+5

	LDY	#0
	CMP	TEMP+1
	BCC	SECTOR01
	LDY	#2		;SECTOR 2 OR 3
	LDA	#0
	BEQ	SECTOR23	;UNCONDITIONAL BRANCH
SECTOR01:
	LDA	TEMP
SECTOR23:
	CLC
	ADC	TEMP+6		;1 +  3/8 = 11/8
	CMP	TEMP+1
	BCC	SECTOR02
SECTOR13:
	INY
SECTOR02:
	STY	TEMP

* UNFOLD VECTOR INTO CORRECT OCTANT, QUADRANT AND HALF-SPACE
	LDY	TEMP+4		;CHECK UDIAGNEG
	BEQ	NODIAGN
	LDA	#7
	SEC
	SBC	TEMP
	STA	TEMP
NODIAGN:
	LDY	TEMP+3		;CHECK UDYNEG
	BEQ	NODYNEG
	LDA	#15
	SEC
	SBC	TEMP
	STA	TEMP
NODYNEG:
	LDY	TEMP+2		;CHECK UDXNEG
	BEQ	NODXNEG
	LDA	#31
	SEC
	SBC	TEMP
	STA	TEMP
NODXNEG:
	; PERTERB VECTOR BY RANDOM NUMBER OF INDEX NOTCHES.
	LDA	UFOACC		;COMPUTE UFOACC / 2
	LSR
	STA	TEMP+6

UTOOPOOR:
	JSR	NEWRAND
	LDY	TEMP+6
	AND	UFOPMASK-1,Y	;TABLE IS 1-ORIGIN (Y > 0)
	CMP	UFOACC
	BCS	UTOOPOOR	;TOO POOR A SHOT, TRY AGAIN

;	CLC			;CARRY IS CLEAR
	ADC	TEMP		;ADD TO PRECISE VECTOR
	SEC
	SBC	TEMP+6		;SUBTRACT UFOACC/2 (OFFSET)
	JMP	USHOOT

UFOPMASK:
	.DC.B	$03,$07,$07,$0F	;RANGE MASKS FOR RANDOM #'S


* UFO SHOT VECTORS.
HUSHVCTX:
	.DC.B	$00,$00,$01,$02,$03,$03,$04,$04
	.DC.B	$04,$04,$04,$03,$03,$02,$01,$00
	.DC.B	$00,$FF,$FE,$FD,$FC,$FC,$FB,$FB
	.DC.B	$FB,$FB,$FB,$FC,$FC,$FD,$FE,$FF

USHVCTX:
	.DC.B	$00,$DB,$AD,$6E,$18,$A3,$0B,$4A
	.DC.B	$60,$4A,$0B,$A3,$18,$6E,$AD,$DB
	.DC.B	$00,$26,$54,$93,$E9,$5E,$F6,$B7
	.DC.B	$A1,$B7,$F6,$5E,$E9,$93,$54,$26

HUSHVCTY:
	.DC.B	$07,$06,$06,$05,$04,$03,$02,$01
	.DC.B	$00,$FE,$FD,$FC,$FB,$FA,$F9,$F9
	.DC.B	$F9,$F9,$F9,$FA,$FB,$FC,$FD,$FE
	.DC.B	$00,$01,$02,$03,$04,$05,$06,$06

USHVCTY:
	.DC.B	$00,$DE,$78,$D2,$F3,$E4,$AE,$5E
	.DC.B	$00,$A3,$53,$1D,$0E,$2F,$89,$23
	.DC.B	$01,$23,$89,$2F,$0E,$1D,$53,$A3
	.DC.B	$00,$5E,$AE,$E4,$F3,$D2,$78,$DE

	.DC.B	$01,$23,$89,$2F,$0E,$1D,$53,$A3
	.DC.B	$00,$5E,$AE,$E4,$F3,$D2,$78,$DE

