;************************************************************************
;*	 EN_CHECK	   -- enemy car check module --			*
;************************************************************************
		INCLUDE	  RP5A22:
		INCLUDE	  RP5C77:
		INCLUDE	  BUFFER
		INCLUDE	  VARIABLE
		INCLUDE	  WORK
;-----------------------------------------------------------------------
		EXT	  Set_disp_pos
		EXT	  You_lost
		EXT	  OAM_PTR_07
		EXT	  Change_point
		EXT	  Set_mycar_buffer
		EXT	  mark_point_x,mark_point_y
		EXT	  line_data,angle_data,status_data
;-----------------------------------------------------------------------
		GLB	  Check_enemy
		GLB	  Check_jump
		GLB	  Battle_jump_data
		GLB	  Free_jump_data
		GLB	  Set_enemy_engine
		GLB	  Calc_distance
;***********************************************************************
;*		Define local variable				       *
;***********************************************************************
work0		EQU	  0000H		      ; 2 byte	:work
work1		EQU	  0002H		      ; 2 byte	:work
work2		EQU	  0004H		      ; 2 byte	:work
tempolary	EQU	  0008H		      ;		 work
;
comp_distance	EQU	  0010H		      ;2byte	comp tempolary
near_index	EQU	  0012H		      ;1byte	near car index
sin_data	EQU	  0014H		      ; 2 byte	:SIN data
cos_data	EQU	  0016H		      ; 2 byte	:COS data
scrn_homepos_x	EQU	  0018H
scrn_homepos_y	EQU	  0020H
scrn_locate_x	EQU	  0022H		      ; 2 byte	:Enemy screen location x
scrn_locate_y	EQU	  0024H		      ; 2 byte	:Enemy screen location y
sign_x		EQU	  0026H		      ; 1 byte	:
sign_y		EQU	  0028H		      ; 1 byte	:
distance_x	EQU	  002AH		      ; 2 byte	:Distance x
distance_y	EQU	  002CH		      ; 2 byte	:Distance y
rotate_pos_x	EQU	  002EH		      ; 2 byte	:
rotate_pos_y	EQU	  0030H		      ; 2 byte	:
;=======================================================================================
;		PRG
;=========================================================================
		EXTEND
		PROG
		MEM8
		IDX8
Set_enemy_engine
		SEP		#00110000B
		JSR		Check_nearcar
		MEM8
		IDX8
		SEP		#00110000B
		CPX		!set_pointa
		BEQ		No_engine_sound
		LDA		!car_flag+00H,X
		BPL		No_engine_sound
		CPX		!nearcar_sub
		BNE		Reset_nearcar
		LDA		<exception_flag
		BIT		#00010000B
		BEQ		Set_sound_status
		LDX		#0AH
Set_sound_status
		MEM16
		REP		#00100000B
		LDA		!rotate_x,X
		CLC
		ADC		#0100H
		CMP		#0200H
		BCS		No_engine_sound
		LSR		A
		LSR		A
		LSR		A
		LSR		A
		TAY
		LDA		Enemy_pan,Y
		TAY
		STY		<sound_status_3
		LDA		!rotate_y,X
		CLC
		ADC		#0100H
		CMP		#0180H
		BCS		No_engine_sound
		LSR		A
		LSR		A
		LSR		A
		LSR		A
		TAY
		LDA		Enemy_volume,Y
		MEM8
		SEP		#00100000B
		TSB		<sound_status_3
		RTS
Reset_nearcar
		STX		!nearcar_sub
		BRA		No_sound_status
No_engine_sound
		STZ		!nearcar_sub
No_sound_status
		STZ		<sound_status_3
		RTS
Enemy_pan
		BYTE		0E0H,0E0H,0E0H,0E0H,0D0H,0D0H,0D0H,0D0H
		BYTE		0C0H,0C0H,0C0H,0B0H,0B0H,0A0H,090H,080H
		BYTE		070H,060H,050H,040H,040H,030H,030H,030H
		BYTE		020H,020H,020H,020H,010H,010H,010H,010H
Enemy_volume
		BYTE		0FH,0FH,0FH,0EH,0EH,0EH,0DH,0DH
		BYTE		0CH,0CH,0BH,0AH,09H,08H,07H,06H
		BYTE		05H,04H,03H,02H,01H,01H,01H,01H
;---------------------------------------------------------------------------------
Calc_distance
		MEM16
		REP		#00100000B
		LDA		!rotate_x,X
		JSR		Check_dist_sub
		BCS		Far_distance
		JSR		Square_calc
		STA		<tempolary
		LDA		!rotate_y,X
		JSR		Check_dist_sub
		BCS		Far_distance
		JSR		Square_calc
		CLC
		ADC		<tempolary
		BCC		Set_car_dist
Far_distance
		LDA		#0FFFFH
Set_car_dist
		STA		!car_distance,X
		RTS
;-------------------------------------------------------------------------
Check_dist_sub
		BPL		Plus_dist
		EOR		#0FFFFH
		INC		A
Plus_dist
		LSR		A
		LSR		A
		LSR		A
		CMP		#0100H
		RTS
;--------------------------------------------------------------------------
Square_calc
		MEM8
		SEP		#00100000B
		STA		!Multiplicand
		STA		!Multiplier
		MEM16
		REP		#00100000B
		NOP
		NOP
		NOP
		LDA		!Multiply
		RTS
;------------------------------------------------------------------------------------
Check_nearcar
		MEM8
		IDX8
		LDX		!top_priority
		BEQ		No_top_priority
		LDA		!car_size,X
		CMP		#03H
		BCS		No_top_priority
		BRA		Set_near_index
No_top_priority
		MEM16
		REP		#00100000B
		LDX		#02H
		STX		<near_index
		LDA		!car_distance+02H
		STA		<comp_distance
		LDX		#04H
Comp_dist_loop
		LDA		!car_distance,X
		CMP		<comp_distance
		BCS		No_change_comp
		STA		<comp_distance
		STX		<near_index
No_change_comp
		INX
		INX
		CPX		#0CH
		BNE		Comp_dist_loop
		LDX		<near_index
Set_near_index
		STX		!nearcar_index
Not_grandprix
		RTS
;------------------------------------------------------------------------------
		MEM8
		IDX8
Check_jump
		LDA		!jump_checker
		BNE		On_jumping
		LDA		!control_status+00H
		BPL		Check_jump_RTS
		BIT		#00000001B
		BNE		Check_jump_RTS
;Trigger_jump_start
		DEC		!jump_checker
		MEM16
		REP		#00100000B
		LDA		!car_locatex_h+00H
		STA		!jump_startx
		LDA		!car_locatey_h+00H
		STA		!jump_starty
		RTS
On_jumping
		MEM8
		LDA		!control_status+00H
		BMI		Check_jump_RTS
;Trigger_jump_end
		LDA		<exception_flag
		BIT		#01000000B
		BNE		Check_jump_RTS
		STZ		!jump_checker
		MEM16
		REP		#00100000B
		LDA		!car_locatex_h+00H
		STA		!jump_endx
		LDA		!car_locatey_h+00H
		STA		!jump_endy
		LDX		!check_jump_address
		JSR		(!Check_jump_address,X)
Check_jump_RTS
		RTS
;---------------------------------------------------------------------------
		MEM16
Port_town
		CMP		#0400H
		BCC		No_jump_sub
		LDA		!jump_startx
		CMP		#1300H
		BCC		PT_001
		CMP		#1680H
		BCC		PT_002
PT_001
		LDY		#14H
		BRA		Penalty_area
PT_002
		LDY		#0FH
		BRA		Penalty_area
;--------------------------------------------------------------------------------
Red_canyon_I
		LDA		!jump_endx
		CMP		#1700H
		BCC		Next_RCI
		LDA		!jump_endy
		CMP		#0A00H
		BCS		Next_RCI
		LDY		#1AH
		BRA		Penalty_area
Next_RCI
		RTS
;----------------------------------------------------------------------------------
Red_canyon_II
		LDA		!jump_startx
		CMP		#1080H
		BCS		Red_canyon_I
		LDA		!jump_endy
		CMP		#09F8H
		BCS		Next_RCII
		LDA		!jump_endx
		CMP		#0B00H
		BCC		Next_RCII
		LDY		#2EH
		BRA		Penalty_area
Next_RCII
		BRA		Red_canyon_I
;-------------------------------------------------------------------------------
White_land_I
		LDA		!jump_endx
		CMP		#1B00H
		BCC		Next_WLI
		LDA		!jump_endy
		CMP		#0400H
		BCC		Next_WLI
		LDY		#1CH
		BRA		Penalty_area
Next_WLI
		LDA		!jump_endx
		CMP		#1400H
		BCC		No_penalty
		LDA		!jump_endy
		CMP		#0600H
		BCC		No_penalty
		LDY		#37H
		BRA		Penalty_area
;-------------------------------------------------------------------------------
White_land_II
		LDA		!jump_endx
		CMP		#1E00H
		BCC		No_penalty
		LDY		#4EH
		BRA		Penalty_area
No_penalty
;-----------------------------------------------------------------------------------------
No_jump_sub
Mute_city
		RTS
;-------------------------------------------------------------------------
;				Entry	Y  penalty area number
		MEM16
		IDX8
Penalty_area
		STY		!car_area+00H
		STZ		!car_course+00H
		JSR		Set_mycar_buffer
		MEM8
		DEC		!short_cut_flag
		LDA		!Area_angle
		STA		!short_cut_angle+01H
		MEM16
		REP		#00100000B
		LDA		!Foward_x
		CLC
		ADC		!Behind_x
		LSR		A
		STA		!short_cut_posx
		LDA		!Foward_y
		CLC
		ADC		!Behind_y
		LSR		A
		STA		!short_cut_posy
		RTS
;------------------------------------------------------------------------
Check_jump_address
		WORD		Mute_city
		WORD		Port_town
		WORD		Red_canyon_I
		WORD		Red_canyon_II
		WORD		White_land_I
		WORD		White_land_II
		WORD		No_jump_sub
Battle_jump_data				     ;plus fall flag
		BYTE		00H,0CH,0CH,0CH,0CH  ;	Mute city
		BYTE		00H,02H,04H,08H,0AH  ;	  &
		BYTE		00H,0CH,02H,06H,0CH  ;	   Port town
Free_jump_data
		BYTE		00H,0CH,0CH,0CH,0CH,08H,02H
;***********************************************************************
;*		Enemy position check				       *
;***********************************************************************
		MEM8
		IDX8
Check_enemy
		PHP
		SEP	  #00110000B	      ; Index 8 bit mode
;=============== Set sin,cos data ======================================
		LDX	  <screen_angle
		LDA	  >SIN_absolute,X
		STA	  <sin_data+0	      ; Set sin data
		LDA	  >SIN_sign,X
		STA	  <sin_data+1
		LDA	  >COS_absolute,X
		STA	  <cos_data+0	      ; Set cos data
		LDA	  >COS_sign,X
		STA	  <cos_data+1
;=============== Position check main ===================================
		STZ	  !priority_index
		LDX	  #02H
Position_check
		MEM8
		SEP	  #00100000B	      ; Memory 8 bit mode
;
		LDA	  !car_flag+0,X
		BMI	  Check_car_exist
		LDA	  #0FFH
		STA	  !car_distance+00H,X
		STA	  !car_distance+01H,X
		BRA	  Next_check_enemy
Check_car_exist
		MEM16
		REP	  #00100000B	      ; memory 16 bit mode
		PHX
		JSR	  Set_distance	      ; Set distance between my bar and enemy
		PLX
					      ;A=distance_x
		BCS	  Not_on_the_screen
;
		LDA	  <distance_x+0
		STA	  !car_position_h,X
		LDA	  <distance_y+0
		STA	  !car_position_v,X
		LDA	  #0FFFFH
		STA	  !car_distance,X
;
		MEM8
		SEP	  #00100000B	      ; Memory 8 bit mode
		LDA	  !car_flag+00H,X
		BIT	  #00001000B
		BEQ	  Car_apear
		BIT	  #00010000B
		BEQ	  Next_check_enemy
		AND	  #11101111B
Car_apear
		ORA	  #00001000B
		STA	  !car_flag+00H,X
		LDA	  !car_flag+01H,X
		ORA	  #00001000B
		STA	  !car_flag+01H,X
		LDA	  #0FFH
		STA	  !old_pointer,X
		STZ	  !old_disp_h,X
		LDA	  !priority_index
		BNE	  Next_check_enemy
		STX	  !priority_index
;-------------------------------------------------------------------------
Next_check_enemy
		INX
		INX
		CPX	  #0CH
		BNE	  Position_check
End_of_check
		PLP
		RTS
;-----------------------------------------------------------------------------
Not_on_the_screen
		JSR	  Calc_distance
		MEM8
		SEP	  #00110000B
		LDA	  #08H
		STA	  !car_size,X
		LDA	  !car_flag+00H,X
		BIT	  #00001000B
		BEQ	  Next_check_enemy
Car_disapear
		BIT	  #00010000B
		BEQ	  Not_jump_special
		LDA	  !control_status,X
		BMI	  Next_check_enemy	    ;continue
End_jump_special
		LDA	  !car_flag+00H,X
		AND	  #11100101B
		STA	  !car_flag+00H,X
		BRA	  Reset_disp_flag
Not_jump_special
		LDA	  !control_status,X
		BPL	  Reset_disp_flag
Set_jump_special
		LDA	  !car_position_v+00H,X
		CMP	  #0C0H
		BCC	  Reset_disp_flag
		LDA	  !car_flag+00H,X
		ORA	  #00011000B
		STA	  !car_flag+00H,X
		LDA	  #0FFH
		STA	  !car_position_v+00H,X
		BRA	  Next_check_enemy
Reset_disp_flag
		LDA	  #LOW OAM_PTR_07
		STA	  !car_table_addr+00H,X
		LDA	  #HIGH OAM_PTR_07
		STA	  !car_table_addr+01H,X
		LDA	  !car_flag+00H,X
		BIT	  #00000010B
		BNE	  Car_crashing
		AND	  #11100111B
		STA	  !car_flag+00H,X
		BRA	  Clear_disp_bit
Car_crashing
		ORA	  #00100100B
		AND	  #11110100B
		STA	  !car_flag+00H,X
Clear_disp_bit
		LDA	  !car_flag+01H,X
		AND	  #11110111B
		STA	  !car_flag+01H,X
		BRA	  Next_check_enemy
;***********************************************************************
;*		Set distance					       *
;***********************************************************************
		MEM16
		IDX8
Set_distance
;=============== Set distance x ========================================
		LDY	  #00H
		LDA	  !car_locatex_h,X
		SEC
		SBC	  !car_locatex_h       ;My car position
		BCS	  Set_distance110
		CMP	  #0F000H
		BCS	  Set_distance100
		ADC	  #2000H
		BRA	  Set_distance120
Set_distance100
		EOR	  #0FFFFH
		INC	  A
		DEY			      ; sign flag x = minus
		BRA	  Set_distance120
Set_distance110
		CMP	  #1000H
		BCC	  Set_distance120
		SBC	  #2000H
		EOR	  #0FFFFH
		INC	  A
		DEY
Set_distance120
		STA	  <distance_x
		STY	  <sign_x
;=============== Set distance y ========================================
		LDY	  #00H
		LDA	  !car_locatey_h,X
		SEC
		SBC	  !car_locatey_h       ;My car position
		BCS	  Set_distance130
		CMP	  #0F800H
		BCS	  Set_distance125
		ADC	  #01000H
		BRA	  Set_distance140
Set_distance125
		EOR	  #0FFFFH
		INC	  A
		DEY			      ; sign flag x = minus
		BRA	  Set_distance140
Set_distance130
		CMP	  #0800H
		BCC	  Set_distance140
		SBC	  #1000H
		EOR	  #0FFFFH
		INC	  A
		DEY
Set_distance140
		STA	  <distance_y
		STY	  <sign_y
;***********************************************************************
;*		Rotate position					       *
;***********************************************************************
		MEM16
		IDX8
;=============== Rotate x ==============================================
		PHX
Rotate_position
		LDA	  <distance_x
		LDY	  <sign_x
		JSR	  Multi_cos
		STA	  <rotate_pos_x
;
		LDA	  <distance_y
		LDY	  <sign_y
		JSR	  Multi_sin
		EOR	  #0FFFFH
		INC	  A
		CLC
		ADC	  <rotate_pos_x
		STA	  <rotate_pos_x
		PLX
		STA	  !rotate_x,X
;=============== Rotate y ==============================================
		PHX
		LDA	  <distance_x
		LDY	  <sign_x
		JSR	  Multi_sin
		STA	  <rotate_pos_y
;
		LDA	  <distance_y
		LDY	  <sign_y
		JSR	  Multi_cos
		CLC
		ADC	  <rotate_pos_y
		PLX
		STA	  !rotate_y,X
;***********************************************************************
;*		Perspective					       *
;***********************************************************************
		MEM16
		IDX16
		REP	  #00110000B
Perspective
		CLC
		ADC	  #027FH    ;(+6)
		CMP	  #0292H    ;(+0)
		BCC	  Perspective_calc
;
		SEP	  #00010001B	      ; Index 8 bit mode
		RTS
;=============== Perspective calclation=================================
Perspective_calc
		MEM16
		IDX16
		TAX
		LDA	  >Position_data,X
		AND	  #00FFH
		STA	  <distance_y
		EOR	  #0FFFFH
		SEC
		ADC	  #255
		TAX
;=============== Perspective x =========================================
		IDX8
		SEP	  #00010000B	      ; Index 8 bit mode
;-----------------------------------------------------------------------
		LDA	  >Pers_data,X
		STA	  <work2
;
		LDY	  #00H		      ; IX = sign of rotate_pos_x
		LDA	  <rotate_pos_x
		BPL	  Perspective710
		EOR	  #0FFFFH
		INC	  A
		DEY			      ; Set sign flag = minus
Perspective710
		STY	  <work1
		STA	  <work0
;-----------------------------------------------------------------------
		MEM8
		SEP	  #00100000B	      ; memory 8 bit mode
		LDA	  <work0+0
		STA	  !Multiplicand
		LDA	  <work2+0
		STA	  !Multiplier
		LDA	  <work0+1
		STA	  !Multiplicand
		MEM16
		REP	  #00100000B
		LDY	  <work2+0
		LDA	  !Multiply+0
		STY	  !Multiplier
		XBA
		STA	  <tempolary+0
		AND	  #00FFH
		STA	  <tempolary+2
		LDA	  !Multiply
		CLC
		ADC	  <tempolary+2
		ASL	  <tempolary+0
		ROL	  A
		ASL	  <tempolary+0
		ROL	  A
;
		LDY	  <work1
		BEQ	  Perspective750
		EOR	  #0FFFFH
		INC	  A
;-----------------------------------------------------------------------
Perspective750
		CLC
		ADC	  #0080H
		CMP	  #0FFE0H
		BCS	  Car_on_the_screen
		CMP	  #00120H
		BCC	  Car_on_the_screen
Car_out_of_screen
		SEP	  #00010001B
		RTS
Car_on_the_screen
		STA	  <distance_x
		CLC
		SEP	  #00010000B
		RTS
;***********************************************************************
;*		Multiply sin,cos * distance			       *
;***********************************************************************
		MEM16
Multi_sin
		STA	  <work0	      ; work0.w = mul_absolute
		STY	  <work1+0	      ; work1.b = sign
		LDA	  <sin_data
		STA	  <work2
		BRA	  Multi_func
;-----------------------------------------------------------------------
Multi_cos
		STA	  <work0	      ; work0.w = mul_absolute
		STY	  <work1+0	      ; work1.b = sign
		LDA	  <cos_data
		STA	  <work2
;=======================================================================
Multi_func
		MEM8
		SEP	  #00100000B	      ; Memory 8 bit mode
;-----------------------------------------------------------------------
		LDA	  <work2+0
		STA	  !Multiplicand
		LDA	  <work0+0
		STA	  !Multiplier
;
		LDA	  <work2+1
		EOR	  <work1+0
		TAY
;
		MEM16
		REP	  #00100000B
		LDX	  <work0+1
;
		LDA	  !Multiply+0
		STX	  !Multiplier
		XBA
		STA	  <tempolary+0
		AND	  #00FFH
		STA	  <tempolary+2
;
		CLC
		LDA	  !Multiply+0
		ADC	  <tempolary+2
		ASL	  <tempolary+0
		ROL	  A
		CPY	  #00H
		BEQ	  Multi_func999
		EOR	  #0FFFFH
		INC	  A
Multi_func999
		RTS

		END
