;****************************************************************************
;*	Mario Kart							    *
;*			Back braund control module			    *
;*							 1992.07.13	    *
;****************************************************************************
		glb	Screen_control
		glb	Set_position
		glb	IRQ_subroutin
		glb	Camera_controlA,Camera_controlB
		glb	Set_back_scroll,Area_check
		glb	Regular_IRQ,Regular_IRQ_init
;----------------------------------------------------------------------------
		ext	Cos_data,Sin_data,Call_bgm
		ext	Set_OAM_screen1,Set_OAM_screen2
		ext	OBJ_transport,Color_transport_s
		ext	Pers_parameter,Rank_subroutin
		ext	All_check_rank,Set_rank_mark
		ext	Camera_spin,Calc_target
		ext	Change_pers,Goal_in_sound
		ext	Check_trigger_SE,Goalin_control
;----------------------------------------------------------------------------
		ext	IRQ_Entry
		ext 	BGcheck
;----------------------------------------------------------------------------
		include rp5a22
		include rp5c77
		include D77C25
		include	work.def
		include	buffer.def
		include ../join/object.def
;****************************************************************************
;
old_pos_y	equ	0eh
new_pos_y	equ	0ch
new_pos_x	equ	0ah
distance_data	equ	10h
force_direction	equ	12h
;
sin_data	equ	010h
cos_data	equ	011h
angle_data	equ	sin_data
counter		equ	012h
counter1	equ	counter
counter2	equ	14h
;
tempolary	equ	000h		;6byte	
;
ofset_data	equ	020h		;calc hdma data offset data
;****************************************************************************
bank80		sect	rel
;----------------------------------------------------------------------------
		mem16
		idx16
Camera_controlA
		ldy	<camera_index+00h		;y=1000,1100....
		ldx	#0000h
		bra	Set_camera_data
;----------------------------------------------------------------------------
Camera_controlB
		jsr     !Set_double_buffer
		ldy	<camera_index+02h		;y=1000,1100,...
		ldx	#0002h
Set_camera_data
		jsr	!Set_camera_position
		jsr	!Set_camera_direction
		jmp     !Pers_parameter
;----------------------------------------------------------------------------
Set_camera_direction
		lda	<camera_mode,x
		beq	Nomal_set_direc
		cmp	#06h
		beq	Long_pers_mode
Reverse_direction
		cpx	#0002h
		beq	Lower_reverse
Upper_reverse
		lda	<camera_direction+02h
		clc
		adc	#08000h
		sta	<camera_direction+00h
		eor	#0ffffh
		inc	a
		bra	Set_back_scroll
Lower_reverse
		lda	<camera_direction+00h
		clc
		adc	#08000h
		sta	<camera_direction+02h
		eor	#0ffffh
		inc	a
		bra	Set_back_scroll
Nomal_set_direc
		lda	<camera_control,x
		bit	#0100000000000000b
		beq	Fix_camera_direction
		bit	#0010000000000000b
		beq	Not_camera_spin
		jsr	!Camera_spin		;camera spining!!!
Not_camera_spin
		lda	!kart_direction,y
		clc
		adc	<camera_drift,x
		sta	<camera_direction,x
Fix_camera_direction
		lda	<camera_direction,x
Set_back_scroll
		pha
		xba
		cmp	#08000h
		rol	a
		and	#01ffh
		sta	<back_3h,x
		pla
		rol	a
		rol	a
		pha
		rol	a
		rol	a
		and	#00000110b
		tay
		lda	!Back_v_data,y
		sec
		sbc	!Ofset_data,x
		sta	<back_2v,x
		pla
		xba
		and	#0000000011111111b
		sta	<back_2h,x
		lda	!Long_sight_data,x
		sta	<back_3v,x
Long_pers_mode
		rts
;----------------------------------------------------------------------------
Set_camera_position
		lda	<camera_mode,x
		cmp	#0002h
		beq	Back_milar_pos
		lda	<camera_control,x
		bpl	Disable_move_camera
Back_milar_pos
		lda	!obj_pos_xl,y
		sta	<tempolary
		lda	!obj_pos_xh,y
		rol	<tempolary
		rol	a
		rol	<tempolary
		rol	a
		sta	<camera_x,x
		lda	!obj_pos_yl,y
		sta	<tempolary
		lda	!obj_pos_yh,y
		rol	<tempolary
		rol	a
		rol	<tempolary
		rol	a
		sta	<camera_y,x
Disable_move_camera
		rts
;----------------------------------------------------------------------------
Back_v_data
		word    0007h,0027h,0047h,0067h
Ofset_data  
		word    0000h,0070h
Long_sight_data
		word	0087h,0017h
;----------------------------------------------------------------------------
		mem16
Set_double_buffer
		lda     <scroll_h+02h
		sta     <scroll_h+04h
		lda     <scroll_v+02h
		sta     <scroll_v+04h
		lda	<center_x+02h
		sta	<center_x+04h
		lda	<center_y+02h
		sta	<center_y+04h
		lda	<back_3h+02h
		sta	<back_3h+04h
		lda	<back_3v+02h
		sta	<back_3v+04h
		lda	<back_2h+02h
		sta	<back_2h+04h
		lda	<back_2v+02h
		sta	<back_2v+04h
		rts
;----------------------------------------------------------------------------
		mem8
		idx8		;00=screen A 04=screen B(need double buffer)
BG_resister_A
		ldx	#00h
		lda	<camera_mode+00
		cmp	#02h
		bne	Nomal_screen
Backmilar_A
		lda	#0c0h-backmilar_line
		bra	Set_scrool_01
BG_resister_B
		ldx	#04h
		lda	<camera_mode+02
		cmp	#02h
		bne     Nomal_screen
Backmilar_B
		lda	#070h-backmilar_line
		bra     Set_scrool_01
Nomal_screen
		lda	!Back_v_pos+00h,x
Set_scrool_01
		sta	!Scroll_1V
		stz	!Scroll_1V
Common_BG_resister
		lda	<scroll_h+00h,x
		sta	!Scroll_0H
		lda	<scroll_h+01h,x
		sta	!Scroll_0H
		lda	<scroll_v+00h,x
		sta	!Scroll_0V
		lda	<scroll_v+01h,x
		sta	!Scroll_0V
;
		lda	<center_x+00h,x
		sta	!Rotation_X
		lda	<center_x+01h,x
		sta	!Rotation_X
		lda	<center_y+00h,x
		sta	!Rotation_Y
		lda	<center_y+01h,x
		sta	!Rotation_Y
;
		stz	!Scroll_1H
		stz	!Scroll_1H
;
		lda	<back_2h+00h,x
		sta	!Scroll_2H
		lda	<back_2h+01h,x
		sta	!Scroll_2H
		lda	<back_2v+00h,x
		sta	!Scroll_2V
		lda     <back_2v+01h,x
		sta	!Scroll_2V		;set back screen
;
		lda	<back_3h+00h,x
		sta	!Scroll_3H
		lda     <back_3h+01h,x
		sta	!Scroll_3H
		lda	<back_3v+00h,x
		sta	!Scroll_3V
		lda     <back_3v+01h,x
		sta	!Scroll_3V		;set back screen
		rts
;----------------------------------------------------------------------------
backmilar_line	equ	0010h
;----------------------------------------------------------------------------
Back_v_pos
		word	00c0h,0000h,0070h
;----------------------------------------------------------------------------
		mem16
		idx16				;X=1000h+80h*index(0,2,4,..)
Set_position
		ldx	#01000h
Set_pos_loop
		lda	!kart_flag,x
		beq	Next_kart_pos
		jsr	!Calc_position
		jsr	!Area_check
Next_kart_pos
		txa
		clc
		adc	#0100h
		cmp	#1800h
		bcs	End_pos_loop
		tax
		bra	Set_pos_loop
End_pos_loop
		jsr	!Goalin_control
		rts
;----------------------------------------------------------------------------
		mem16
		idx16
Calc_position
		jsr	!Magnetic_effect
		clc
		lda	<obj_velocity_x-01h,x
		and	#0ff00h
		adc	<obj_pos_xl,x
		sta	<obj_pos_xl,x
		lda	#0ff00h
		and	<obj_velocity_x,x
		bpl	Velo_x_plus	
		ora	#00ffh
Velo_x_plus
		xba
		adc	<obj_pos_xh,x
		clc
		sta	<obj_pos_xh,x
		sta	<new_pos_x
		lda	<obj_pos_yh,x
		sta	<old_pos_y
		clc
		lda	<obj_velocity_y-01h,x
		and	#0ff00h
		adc	<obj_pos_yl,x
		sta	<obj_pos_yl,x
		lda	#0ff00h
		and	<obj_velocity_y,x
 		bpl	Velo_y_plus	
		ora	#00ffh
Velo_y_plus
		xba
		adc	<old_pos_y
		sta	<obj_pos_yh,x
		sta	<new_pos_y
No_effect
		rts
;----------------------------------------------------------------------------
Magnetic_effect
		lda	<kart_flag,x
		bmi	No_effect
		bit	#0100000000000000b
		bne	No_effect
		lda	!vector_velocity,x
		cmp	#080h
		bcc	No_effect
		lda	<event_index,x
		bne	No_effect
		cpx	!1100h+behind_index
		beq	Behind_1100h
		cpx	!1000h+behind_index
		beq	Behind_1000h
		rts
Behind_1000h
		lda	#04000h
		sta	<force_direction
		lda	<_posV_A,x
		cmp	#0ff89h
		bcc	No_effect
Check_1000h
		ldy	#1000h
		lda	!1000h+behind_distance
		sta	<distance_data
		lda	<_posH_A,x
		clc
		adc	#080h
		bpl	Right_side
Left_side
		lda	!kart_direction,y
		sec
		sbc	<force_direction
		bra	Calc_magnetic_effect
Behind_1100h
		lda	#04000h
		sta	<force_direction
		lda	<_posV_B,x
		bpl	Check_1100h
		cmp	#0fffah
		bcc	No_effect
Check_1100h
		ldy	#1100h
		lda	!1100h+behind_distance
		sta     <distance_data
		lda	<_posH_B,x
		clc
		adc	#080h
		bmi	Left_side	
Right_side
		lda	!kart_direction,y
		clc
		adc	<force_direction
Calc_magnetic_effect
		sta	<force_direction
		sec
		sbc	<move_direction,x
		bpl	Dif_direc_plus
		eor	#0ffffh
		inc	a
Dif_direc_plus
		cmp	#01800h
		bcc	Skip_effect
		mem8
		sep	#00100000b
		lda	#dsp_triangle
		sta	!DSP_data
		mem16
		rep	#00100000b
		lda	<force_direction
		sta	!DSP_data
		lda	<distance_data
		cmp	#40h
		bcc	Not_over_40h
		lda	#3fh
Not_over_40h
		lsr	a
		and	#01eh
		tay
		lda	!map_type
		beq	Obake_course
		cmp	#0eh
		beq	Star_course
		lda	!Magnetic_data,y
		bra	Set_dsp_resister
Obake_course
Star_course
		lda	!Magnetic_data_s,y
Set_dsp_resister
		sta	!DSP_data
		lda	!DSP_status
		bpl	$-3
		lda	!DSP_data
		clc
		adc	<obj_velocity_x,x
		sta	<obj_velocity_x,x
		lda	!DSP_data
		eor	#0ffffh
		inc	a
		clc
		adc	<obj_velocity_y,x
		sta	<obj_velocity_y,x
Skip_effect
		rts
;----------------------------------------------------------------------------
Magnetic_data
		word	0d0h,0e0h,0f0h,100h,100h,0f0h,0e0h,0d0h
		word	0c0h,0b0h,0a0h,090h,080h,070h,060h,040h
Magnetic_data_s
		word	040h,040h,030h,030h,020h,020h,010h,010h
		word	000h,000h,000h,000h,000h,000h,000h,000h
;----------------------------------------------------------------------------
		mem16
		idx16
Area_check
		lda	<kart_flag,x
		and	#1111111111111100b
		sta	<kart_flag,x
		lda	<new_pos_x
		cmp	#0400h
		bcs	Area_over
		lsr	a
		lsr	a
		lsr	a
		lsr	a
		sta	<new_pos_x
		lda	<new_pos_y			
		asl	a
		asl	a
		and	#1111111111000000b
		ora	<new_pos_x
		cmp	#1000h
		bcs	Area_over
		phx
		tax
		lda	>area_buffer,x			;lokk up area buffer
		and	#0ffh
		plx
		bit	#10000000b
		beq	Not_goal_box
		and	#01111111b
		cmp	#07fh
		bne	Nomal_goal_box			;data=0ffh off area
		lda	#0010b
		ora	<kart_flag,x
		sta	<kart_flag,x
		bra	Skip_set_area
Nomal_goal_box
		mem8
		sep	#00100000b
		cmp	<old_area,x
		beq	Skip_set_area
		sta	<kart_area,x
		sta	<old_area,x
		mem16
Skip_set_area
		rep	#00100000b
		jsr	!Check_goal_line
		jsr     !Rank_subroutin
		rts
Not_goal_box
		cmp	#07fh
		beq	Area_ff
		ldy	<kart_status,x
		bpl	Not_jump_status
		pha
		asl	a
		tay
		lda	!target_status-01,y
		bmi	Junction_area
		pla
Not_jump_status
		mem8
		sep	#00100000b
		cmp	<old_area,x
		beq	Not_new_area
		sta	<kart_area,x
		sta	<old_area,x
		mem16
		rep	#00100000b
		jsr	!Rank_subroutin
Not_new_area
		rep	#00100000b
		rts
Area_over
		lda	#0000000000000001b
		bra	Set_illegal_flag
Junction_area
		pla
Area_ff
		lda	#0000000000000010b
Set_illegal_flag
		ora	<kart_flag,x
		sta	<kart_flag,x
Kart_still_goalin
Stop_on_line
		rts
;----------------------------------------------------------------------------
		mem16
		idx16
Check_goal_line
		lda	<kart_flag,x
		bit	#0000000000100000b		;still gaol in???
		bne	Kart_still_goalin
		and	#1111111111110011b
		sta	<kart_flag,x
		lda	!goal_line			;check goal line
		cmp	<old_pos_y
		bne	Not_old_y_online
		cmp	<new_pos_y
		beq	Stop_on_line
		bcs	Increce_lap
		rts
Not_old_y_online
		bcs	Check_decrece_lap
		cmp	<new_pos_y
		beq	Not_change_lap
		bcc	Not_change_lap
Increce_lap
		lda	<kart_area,x
		clc
		adc	#00100h
		and     #0ff00h
		sta	<kart_area,x
		cmp	<lap_counter,x
		bcc	Not_change_lap
		beq	Not_change_lap
;NEW NEXT LAP!!!!
		sta	<lap_counter,x
		cmp	#08000h
		beq	Not_change_lap		;just after start
		sec
		sbc	!lap_number
		bcs	Goal_in
		cmp	#0ff00h
		beq	Final_lap
;----------------------------------------------------------------------------
Lap_increment
		lda	#0000000000000100b
		ora	<kart_flag,x
		sta	<kart_flag,x
		bpl	No_lap_bord
Set_official_lap
		lda	#0000000100000000b
		ora	<official_control,x
		sta	<official_control,x
		jsr	!Set_lap_time
No_lap_bord
		rts
;----------------------------------------------------------------------------
Check_decrece_lap
		cmp	<new_pos_y
		beq	Dec_laps
		bcs	Not_change_lap
Dec_laps
		lda	<kart_area,x
		sec
		sbc	#00100h
		sta	<kart_area,x
Not_change_lap
		rts	
;----------------------------------------------------------------------------
Goal_in
		lda	<kart_flag,x
		bit	#0000000000100000b
		bne	Skip_goalin
		cpx	#1100h
		beq	Check_1100h_goalin
		bcs	Skip_enemy_goalin
Check_1000h_goalin
		lda	<game_mode
		cmp	#04h
		bne	Set_mykart_goalin
		bra	Skip_enemy_goalin
Check_1100h_goalin
		lda	!g_kart_flag
		bne	Skip_ghost_kart		;Ghost kart ON!!!
		lda	<game_mode
		cmp	#02h
		beq	Skip_enemy_goalin
Set_mykart_goalin
		jsr	!Goal_in_sound
		lda	#0100000000000000b
		ora	<official_control,x
		sta     <official_control,x
		lda	#68h
		jsl	>Check_trigger_SE
Skip_enemy_goalin
		lda	!decimal_timer
		sta	<driver_time+00h,x
		lda	!second_timer
		sta	<driver_time+02h,x
		lda	!minute_timer
		sta	<driver_time+04h,x
		ldy	!goalin_pointer
		txa
		sta	!goalin_buffer,y
		inc	!goalin_pointer
		inc	!goalin_pointer
Skip_ghost_kart
		lda	<kart_flag,x
		and     #1111111111000111b
		ora     #0010000000111000b
		sta	<kart_flag,x
Skip_goalin
No_final_lap
		rts
;----------------------------------------------------------------------------
Final_lap
		lda	#0000000000001000b
							;set final lap flag
		ora	<kart_flag,x
		sta	<kart_flag,x
		cpx	#1100h
		beq	Check_1100h_final
		bcs	No_final_lap
Check_1000h_final
		lda	<game_mode
		cmp	#04h
		bne	 Set_official_final
		rts
Check_1100h_final
		lda	<game_mode
		cmp	#02h
		beq	No_final_lap
Set_official_final
		lda	!bgm_status
		bne	Not_finallap_sound
		inc	!bgm_status
		lda	#02*60/2
		sta	!finallap_counter
		lda	#0ah
		sta	!pause_wait			;wait enable pause
		lda	#05h
		jsr	!Call_bgm
Not_finallap_sound
		lda	#0000000010000000b
		ora	<official_control,x
		sta     <official_control,x		;goto set lap!!!
;----------------------------------------------------------------------------
Set_lap_time
		phx
		txa
		xba
		and	#0000000000000001b
		asl	a
		tay
		lda	<lap_counter+01h,x
		asl	a
		clc
		adc	<lap_counter+01h,x
		asl	a				;lap*06h
		clc
		adc	!Lap_address_data,y
		and	#00ffh
		tax
Set_lap_sub
		lda	!decimal_timer
		sta	!laptime_buffer-06h,x
		lda	!second_timer
		sta	!laptime_buffer-04h,x
		lda	!minute_timer
		sta	!laptime_buffer-02h,x
		plx
		rts
;--------------------------------------------------------------------------
Lap_address_data		;7e2000h----or 7e201eh-----until 7e203b 
		word	0000h,001eh
;---------------------------------------------------------------------------
Screen_control					;V_blank prossess
		mem8
		idx8
		sep	#00110000b
		lda	#00000010b
		sta	!2101h			;obj bank set

		jsr	!IRQ_control			;IRQ control
							; & HDMA control
		lda	#11111110b
		sta	!DMA_syncro
		lda	<camera_flip+00h	;camera_A flip
		sta	!Screen_flip
;						;H_DMA switch
;						;b7=window HDMA
;						;b6=throgh screen HDMA
;						;b5=mode change HDMA
;						;b4,3,2,1=perse HDMA
		lda	!nuki_color+00h
		beq	Not_trans_grandA
		stz	!Color_address
		sta	!Color_write
		lda	!nuki_color+01h
		sta	!Color_write
Not_trans_grandA
		jsr	!BG_resister_A		;for screen A
		jsr	!Set_window_bias
		rep	#00110000b		;return mem16 idx16
		rts
;----------------------------------------------------------------------------
IRQ_control
		lda	!camera_counter
		cmp	#04h
		bne	Not_change_IRQ
Change_IRQ
		mem16
		idx16
		rep	#00110000b
		lda	<game_mode
		and	#0000000000000010b
		tax
		lda	!camera_mode_stock
		sta	<camera_mode,x
		tay
		lda	!Camera_flip_data,y
		sta	<camera_flip,x
		jsl	>Change_pers
		mem8
		idx8
		sep	#00110000b
Not_change_IRQ
		rts
;----------------------------------------------------------------------------
Camera_flip_data
		word	00h,0c1h,00h,0c0h
;----------------------------------------------------------------------------
IRQ_subroutin
		word    IRQ_0,IRQ_2,IRQ_3,IRQ_4,IRQ_5,IRQ_6
;----------------------------------------------------------------------------
Regular_IRQ_init
		jsr	!Regular_IRQ
		rtl
Regular_IRQ
		mem8
		idx8
		lda	#02h
		sta	<irq_index
		lda	#0c0h
		sta	<camera_flip+00h
		sta	<camera_flip+02h
		lda	#10110001b
		sta	!Timer_control		;eneble timer
		lda	#06bh
		sta	!Timer_V+00h
IRQ_0;-----------------------------------------------------------------------
		rts
IRQ_2;-----------------------------------------------------------------------
		
		ldx	#00001010b
						;obj bank set
		ldy	#10000000b
;
		lda	#01000000b
Wait_IRQ2
		bit	!4212h
		beq	Wait_IRQ2
;
		sty	!PPU_control			;blanking!!!
		stx	!2101h
		lda	#072h
		sta	!Timer_V+00h
		lda	<camera_flip+02h		;B screen flip
		sta	!Screen_flip
		lda	#04h
		sta	<irq_index
		lda	!nuki_color+02h
		beq	Not_trans_grandB
		stz	!Color_address
		sta	!Color_write
		lda	!nuki_color+03h
		sta	!Color_write
Not_trans_grandB
		jsr	!BG_resister_B	;for screen B(pre 1 frame)
;
		ldx	#01h
		jsr	!Set_window_bias
;
		jsr     !Set_OAM_screen2        ;reset OAM data
;
		rts
;----------------------------------------------------------------------------
IRQ_3
		ldx	!fade_data+01h
		lda	#01000000b
Wait_IRQ3
		bit	!4212h
		beq	Wait_IRQ3
;
		stx	!PPU_control
		lda	#08h
		sta	<irq_index
		lda	#0e0h-05h-08h
		sta	!Timer_V+00h
		rts
;----------------------------------------------------------------------------
IRQ_4
		jsl	>IRQ_Entry
		rts
;----------------------------------------------------------------------------
IRQ_5
		lda	#0ah
		sta	<irq_index
		lda	#0e0h-05h
		sta	!Timer_V+00h
		dec	!time_checker
		rts
;----------------------------------------------------------------------------
IRQ_6
		ldx	#80h
		lda	#01000000b
Wait_IRQ6
		bit	!4212h
		beq	Wait_IRQ6
		stx	!PPU_control
		stz     !DMA_syncro	
		lda	#02h
		sta	<irq_index
		lda	#06bh
		sta	!Timer_V+00h
		rep	#00110000b
		jsr     !Set_OAM_screen1
		jsr	!Color_transport_s
		sep	#00110000b
		rts
;----------------------------------------------------------------------------
		mem8
		idx8
Set_window_bias
		lda	!window_color,x
		sta	!Color_brend		;2131h
		lda	!red_color,x
		sta	!Color_bias      	;2132H
		lda	!green_color,x
		sta	!Color_bias      	;2132H
		lda	!blue_color,x
		sta	!Color_bias      	;2132H
		lda	!window_mask,x
		sta	!2125h
		lda	!window_through,x
		sta	!212eh
		lda	!window_switch,x
		sta	!2130h
		rts
		end
