;; EXAMPLE 04c - Identifying Collisions
;;
;; RAPTOR USER FILE
;;
;; Note: 	This file, and all other files, are tabulated for Notepad++
;;			Tabulation might be incorrect in other editors.
;;			use Notepad++ for maximum readability. 
;;


;; DO NOT MODIFY THE FOLLOWING LINES

			include				"../../JAGUAR.INC"										; Include JAGUAR system labels
			include				"../../RAPTOR/INCS/RAPTOR.INC"							; Include RAPTOR library labels
			include				"../../U235SE.021/U235SE.INC"							; Include U235SE library labels

			.text							

;; YOUR APPLICATION GOES HERE
;; MODIFY AWAY!
						
;; VIDEO SETUP EQUATES
			
raptor_video_mode				equ				vidRGB16								; tell RAPTOR we want RGB 16 mode
raptor_video_enabled			equ				vidENABLE								; tell RAPTOR we want to Video ENABLED
raptor_video_VARMOD				equ				vidVARMOD_OFF							; tell RAPTOR we want VARMOD disabled
			
;; MAP MODULE SETUP EQUATES
			
raptor_first_map_object			equ				0										; Point RAPTOR to the first object of the map data
raptor_map_tiles_per_y			equ				0										; tell RAPTOR the height (in tiles) to display
raptor_map_tiles_per_x			equ				0										; tell RAPTOR the width (in tiles) to display
raptor_map_height				equ				0										; tell RAPTOR the map height (in tiles)
raptor_map_width				equ				0										; tell RAPTOR the map width (in tiles)
raptor_tilesize_x				equ				0										; tell RAPTOR the map tilesize (x) in pixels
raptor_tilesize_y				equ				0										; tell RAPTOR the map tilesize (y) in pixels
raptor_tilelinesz				equ				raptor_tilesize_x/2						; calculate the offset to next line of tile data
raptor_tilesize					equ				raptor_tilelinesz*raptor_tilesize_y		; calculate the byte size of a single tile

;; PARTICLE MODULE SETUP EQUATES

raptor_particle_buffer_width	equ				368										; tell RAPTOR the Particle / Text Buffer is 368 pixels wide
raptor_particle_buffer_height	equ				240										; tell RAPTOR the Particle / Text Buffer is 240 pixels high
raptor_particle_pixels			equ				50										; tell RAPTOR the maximum number of particles
raptor_particle_drift_x			equ				0										; tell RAPTOR the Particle Drift Factor (x)
raptor_particle_drift_y			equ				0										; tell RAPTOR the Particle Drift Factor (y)

;; some human friendly names

LIST_display					equ				0										; the first display list

ID_backdrop						equ				0										; RAPTOR Object number for the backdrop
ID_player						equ				ID_backdrop+1							; RAPTOR Object number for player
ID_enemy						equ				ID_player+1								; RAPTOR Object number for the first enemy
ID_bullets						equ				ID_enemy+50								; RAPTOR Object number for the first bullet
ID_textlayer					equ				ID_bullets+5							; RAPTOR Object number for text layer

CLUT_player						equ				0										; 16 colour sub index into the 256 colour CLUT for the player sprite
CLUT_enemy						equ				1										; CLUT for enemies
CLUT_text						equ				15										; Text / Particle layer ALWAYS uses CLUT15

;;
;; The following lines **MUST** be at the start of EVERY RAPTOR APPLICATION
;; They configure the .OBJ file for use
;;	
			move.l	#raptor_video_mode,raptor_vidmode
			move.l	#raptor_video_enabled,raptor_videnable
			move.l	#raptor_video_VARMOD,raptor_varmod
			move.l	#raptor_first_map_object,raptor_maptop_obj
			move.l	#raptor_tilesize_x,raptor_tiles_x
			move.l	#raptor_tilesize_y,raptor_tiles_y
			move.l	#raptor_map_tiles_per_x+2,raptor_tilesperx
			move.l	#raptor_map_tiles_per_y+1,raptor_tilespery
			move.l	#raptor_map_width,raptor_mapwidth
			move.l	#raptor_map_height,raptor_mapheight
			move.l	#raptor_particle_pixels,raptor_maxparts
			move.l	#raptor_tilesize_x-1,raptor_tilerem_mask
			move.l	#raptor_particle_buffer_width,raptor_partbuf_x
			move.l	#raptor_particle_buffer_height,raptor_partbuf_y
			move.l	#raptor_particle_drift_x,raptor_pdriftx
			move.l	#raptor_particle_drift_y,raptor_pdrifty
			move.l	#top_of_bss,raptor_top_of_bss
			move.l	#_trashram,raptor_trashram
			move.l	#RAPTOR_MTtrash,raptor_MTwork
			move.l	#RAPTOR_user_vbi,raptor_uvbi_jmp
			move.l	#RAPTOR_POST_Object_List,raptor_poobjl
			move.l	#RAPTOR_PRE_Object_List,raptor_probjl
			move.l	#RAPTOR_font8x8,raptor_8x8_addr
			move.l	#RAPTOR_font8x16,raptor_8x16_addr
			move.l	#RAPTOR_font16x16,raptor_16x16_addr
			move.l	#RAPTOR_particle_palette,raptor_partipal
			move.l	#RAPTOR_particle_gfx,raptor_pgfx
			move.l	#RAPTOR_particle_gfxe,raptor_pgfxe
			move.l	#RAPTOR_sprite_table,raptor_spritetab
			move.l	#RAPTOR_particle_table,raptor_partitab
			move.l	#RAPTOR_MT_app_name,raptor_mtapp
			move.l	#RAPTOR_MT_file_name,raptor_mtfn
			move.l	#raptor_init_table,raptor_inittab
			move.l	#RAPTOR_samplebank,raptor_samplebank_ptr
			move.l	#0,raptor_mapbmptiles					; <<<<---- THIS WILL NEED TO BE CHANGED IF USING THE TILEMAP MODULE <<<<----
			jsr		RAPTOR_HWinit														; Setup Jaguar hardware / install RAPTOR library

;; convert some graphics

			lea		BMP_BACKDROP,a0														; point to our TGA file
			lea		_trashram,a1														; some workram
			jsr		RAPTOR_GFXConvert													; Convert to Jaguar Bitmap 

			lea		BMP_PLAYER,a0														; point to our Windows BMP for the player
			lea		_trashram,a1														; some workram
			jsr		RAPTOR_GFXConvert													; Convert to Jaguar Bitmap
			lea		$f00400+(32*CLUT_player),a1											; which CLUT palette needs to move into
			jsr		RAPTOR_move_palette													; Copy the palette for the last converted bitmap to CLUT

			lea		BMP_ENEMY,a0														; point to our Windows BMP for the enemies
			lea		_trashram,a1														; some workram
			jsr		RAPTOR_GFXConvert													; Convert to Jaguar Bitmap
			lea		$f00400+(32*CLUT_enemy),a1											; which CLUT palette needs to move into
			jsr		RAPTOR_move_palette													; Copy the palette for the last converted bitmap to CLUT

			lea		BMP_BULLETS,a0														; point to our TGA file for the bullets
			lea		_trashram,a1														; some workram
			jsr		RAPTOR_GFXConvert													; Convert to Jaguar Bitmap
			
;; we're using Joystick input, so we now need U235 Sound Engine running
			jsr		RAPTOR_U235init														; init the U235 Sound Engine
			
;; configure the initial enemy positions
			jsr		Enemy_Initial_Positions
			
;; get something on the screen
	
			jsr		RAPTOR_start_video													; start video processing
			move.l	#LIST_display,d0													; set RAPTOR to display initial RAPTOR list
			jsr		RAPTOR_setlist														; tell RAPTOR which list to process
			jsr		RAPTOR_UPDATE_ALL													; and update the object list with initial values
			
;; put some text on the screen
			

			clr.l	U235SE_pad1															; clear pad input flags
			
LOOP:		jsr		RAPTOR_wait_frame_UPDATE_ALL										; Sync to VBLANK and Update ALL RAPTOR objects
			jsr		Enemy_Update_Positions												; Make them march!
			jsr		Player_Update_Position												; Move the player
			jsr		Player_Shooting														; Handle the fire button
			jsr		Check_Collisions													; Collision checking
			jsr		What_Was_Hit														; Check what was hit
			jsr		Enemies_Dead_Check													; Check if all enemies are dead
			jsr		Update_Score														; Update the scoreboard
			bra		LOOP																; Loop around!
			
;;
;; Subroutines
;;
			
Enemy_Initial_Positions:
			move.l	#$00008000,enemy_direction											; X addition in 16.16 (so 0.5 pixels / update)
			lea		RAPTOR_sprite_table+(ID_enemy*sprite_tabwidth),a0					; point to RAPTOR object table
			move.l	#40,d1																; initial Y
			move.l	#4,d7																; 5 rows
.vert:		move.l	#20,d0																; initial X per row
			move.l	#9,d6																; 10 per row
.horiz:		move.l	enemy_direction,sprite_xadd(a0)										; x-addition value
			move.w	d0,sprite_x(a0)														; set x-position
			move.w	d1,sprite_y(a0)														; set y-position
			move.l	#can_hit,sprite_colchk(a0)											; tell RAPTOR this sprite can hit things
			move.l	#-1,sprite_was_hit(a0)												; clear the Object collision flag in case it was previously set)
			move.l	#1,sprite_hitpoint(a0)												; reset this Obejcts Hitpoint value
			move.l	#is_active,sprite_active(a0)										; object is active
			lea		sprite_tabwidth(a0),a0												; next object
			add.w	#20,d0																; add 20 to x
			dbra	d6,.horiz															; loop for horiz
			add.w	#20,d1																; add 20 to y
			dbra	d7,.vert															; loop for vertical
			rts																			; exit

enemy_direction:	dc.l	$00008000
			
Enemy_Update_Positions:
			lea		RAPTOR_sprite_table+(ID_enemy*sprite_tabwidth),a0					; point to RAPTOR object table
; check if any enemies hit the edge:
			move.l	#49,d7																; 50 enemies
.edgechk:	move.w	sprite_x(a0),d0														; get x-position of current enemy	
			cmp.w	#19,d0																; left edge?
			beq		.change_direction													; if yes, change direction on all enemies
			cmp.w	#320,d0																; right edge?
			beq		.change_direction													; if yes, change direction on all enemies
			lea		sprite_tabwidth(a0),a0												; next object
			dbra	d7,.edgechk															; loop around for all
			rts																			; exit
			
; ok, we need to change the direction of all enemies
.change_direction:
			not.w	enemy_direction														; flip X addition value
			move.l	enemy_direction,d0													; get the X-value
			lea		RAPTOR_sprite_table+(ID_enemy*sprite_tabwidth),a0					; point to RAPTOR object table
			move.l	#49,d7																; 50 enemies
.change:	move.l	d0,sprite_xadd(a0)													; write new direction
			cmp.w	#220,sprite_y(a0)													; Y on player line?
			beq		Enemy_Initial_Positions												; if yes, reset everything!
			add.w	#10,sprite_y(a0)													; drop down 10 lines of pixels
			lea		sprite_tabwidth(a0),a0												; next object
			dbra	d7,.change															; loop around for all
			rts																			; exit

Player_Update_Position:
			lea		RAPTOR_sprite_table+(ID_player*sprite_tabwidth),a0					; point to RAPTOR object table
			move.w	sprite_x(a0),d0														; get player's current X position
			move.l	U235SE_pad1,d1														; get PAD1 status (from U235)

.chk_left:	btst	#U235SE_BBUT_LEFT,d1												; was LEFT pressed?
			beq		.chk_right															; if not, check next condition
			cmp.w	#20,d0																; already at far-left position?
			beq		.chk_done															; if so, don't move and exit routine
			subq	#1,d0																; subtract 1 from X-positoin
			bra		.chk_done															; exit the routine
	
.chk_right:	btst	#U235SE_BBUT_RIGHT,d1												; was RIGHT pressed?
			beq		.chk_done															; if not, exit the routine
			cmp.w	#320,d0																; alrady at far-right position?
			beq		.chk_done															; if so, don't move and exit routine
			addq	#1,d0																; add 1 to X-position
		
.chk_done:	move.w	d0,sprite_x(a0)														; store the new x-position
			rts																			; exit

fire_delay:	dc.w	10																	; frames between shots
			
Player_Shooting:
			tst.w	fire_delay															; can we shoot again yet?
			bmi		.can_shoot															; if -ve then we can shoot
			sub.w	#1,fire_delay														; decrement counter
			rts																			; and exit
.can_shoot:
			move.l	U235SE_pad1,d1														; get PAD1 status (from U235)
			btst	#U235SE_BBUT_B,d1													; was B pressed?
			bne		.proc_fire															; yes, so do something!
			rts																			; exit!
		
; Now we need to find a free bullet object to use
		
.proc_fire:	lea		RAPTOR_sprite_table+(ID_bullets*sprite_tabwidth),a0					; point to RAPTOR object table
			moveq	#4,d7																; there are 5 bullets
.find:		tst.l	sprite_active(a0)													; is this one active?
			bmi		.found																; if -ve then it's unuse, we can use this one!
			lea		sprite_tabwidth(a0),a0												; next object!
			dbra	d7,.find															; loop around all 10
			rts																			; none free, exit!
.found:		move.w	#10,fire_delay														; can't shoot again for 10 frames
			lea		RAPTOR_sprite_table+(ID_player*sprite_tabwidth),a1					; point to RAPTOR address for the player
			move.l	sprite_x(a1),sprite_x(a0)											; copy player x to bullet x
			add.w	#6,sprite_x(a0)														; add an offset so it's centered to the player
			move.l	sprite_y(a1),sprite_y(a0)											; copy player y to bullet y
			sub.w	#4,sprite_y(a0)														; subtract an offset so it shoots from above the player
			move.w	#-2,sprite_yadd(a0)													; subtract 1 per frame from bullet y
			move.l	#can_hit,sprite_colchk(a0)											; tell RAPTOR this sprite can hit things
			move.l	#-1,sprite_was_hit(a0)												; clear the Object collision flag in case it was previously set)
			move.l	#1,sprite_hitpoint(a0)												; reset this Obejcts Hitpoint value
			move.l	#is_active,sprite_active(a0)										; tell RAPTOR this object is active!
			rts

Check_Collisions:
			clr.l	raptor_result														; reset the RAPTOR collision flag
			move.l	#ID_bullets,raptor_sourcel											; Object ID for first bullet
			move.l	#ID_bullets+4,raptor_sourceh										; Object ID for last bullet
			move.l	#ID_enemy,raptor_targetl											; Object ID for first enemy
			move.l	#ID_enemy+49,raptor_targeth											; Object ID for last enemy
			lea		RAPTOR_GPU_COLLISION,a0												; now call the RAPTOR collision handler
			jsr 	RAPTOR_call_GPU_code

			clr.l	raptor_result														; reset the RAPTOR collision flag
			move.l	#ID_player,raptor_sourcel											; Object ID for the player
			move.l	#ID_player,raptor_sourceh											; Object ID for the player
			move.l	#ID_enemy,raptor_targetl											; Object ID for first enemy
			move.l	#ID_enemy+49,raptor_targeth											; Object ID for last enemy
			lea		RAPTOR_GPU_COLLISION,a0												; now call the RAPTOR collision handler
			jsr 	RAPTOR_call_GPU_code
			
			tst.l	raptor_result														; check the global collision flag
			bmi		.no_hit																; if -ve, then nothing collided
			bsr		Enemy_Initial_Positions												; otherwise reset the wave
			
.no_hit:	rts		

Enemies_Dead_Check:
			lea		RAPTOR_sprite_table+(ID_enemy*sprite_tabwidth),a0					; point to RAPTOR object table
			move.l	#49,d7																; 50 enemies
.dead:		tst.l	sprite_active(a0)													; is this one alive?
			bpl		.done																; if *any* are alive, we can exit
			lea		sprite_tabwidth(a0),a0												; next enemy
			dbra	d7,.dead															; loop around for all enemies
			bsr		Enemy_Initial_Positions												; if we get here, they're all dead and we can reset
.done:		rts																			; exit!

score:		dc.l	0																	; somewhere to store the score

What_Was_Hit:
			lea		RAPTOR_sprite_table+(ID_enemy*sprite_tabwidth),a0					; point to RAPTOR object table
			move.l	#49,d7																; 50 enemies
.chk_hit:	tst.l	sprite_was_hit(a0)													; check if this object was hit
			bmi		.not_hit															; skip if not
.was_hit:	move.l	#-1,sprite_was_hit(a0)												; clear RAPTOR collision flag
			add.l	#1,score															; if it was we can increment the score
.not_hit:	lea		sprite_tabwidth(a0),a0												; next object
			dbra	d7,.chk_hit															; loop for all
			rts																			; exit

Update_Score:
			move.l	score,d1
			move.l	#7,d4
			lea		asc_score,a0
			jsr		RAPTOR_HEXtoDEC

			lea		txt_score,a0														; point to a text string
			move.l	#20,d0																; x=20
			move.l	#20,d1																; y=20
			moveq	#0,d2																; Font Size = 0 (8x8)
			moveq	#0,d3																; Font Index = 0
			jsr		RAPTOR_print														; PRINT the version
			rts
			
;;
;; Some text to demo the RAPTOR_print command
;;
	
txt_score:	
			dc.b	raptor_t_font_siz,0													; set font size to 0 (8x8)
			dc.b	"SCORE: "
asc_score:	dc.b	"00000000"
			dc.b	raptor_t_quit														; end of string
			.even		
						
;;
;; RAPTOR user VBI vector
;;

RAPTOR_user_vbi:	
			rts																			; we're not using this, nothing tied to the vblank

;;
;; Creating Non-RAPTOR objects around the list
;;		

RAPTOR_PRE_Object_List:																	; No unmanaged objects before the list
			rts

RAPTOR_POST_Object_List:																; No unmanaged Objects after the list									
			rts
						
							include		"_RAPPIXL.S"									; RAPTOR particle module user data
							include 	"_RAPINIT.S"									; RAPTOR object user data
							include 	"_RAPU235.S"									; RAPTOR u235se user data
	
;;
;; Graphics
;;
							.dphrase
							dc.l	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
				
RAPTOR_font8x8:				incbin	"../../RAPTOR/FONTS/F_8x8.BMP"						; User defined 8x8 fonts
							.dphrase
RAPTOR_font8x16:			incbin	"../../RAPTOR/FONTS/F_8x16.BMP"						; User defined 8x16 fonts
							.dphrase
RAPTOR_font16x16:			incbin	"../../RAPTOR/FONTS/F_16x16.BMP"					; User defined 16x16 fonts
							.dphrase
RAPTOR_particle_palette:	incbin	"../../RAPTOR/FONTS/PARTIPAL.BMP"					; User defined palette for fonts and particles
							
							.dphrase
BMP_BACKDROP:				incbin	"../DATAFILE/GFX/BACKDROP.TGA"						; screen backdrop bitmap
							.dphrase
BMP_PLAYER:					incbin	"../DATAFILE/GFX/PLAYER.BMP"						; animated object for player
							.dphrase
BMP_ENEMY:					incbin	"../DATAFILE/GFX/ENEMY.BMP"							; animated object for enemies
							.dphrase
BMP_BULLETS:				incbin	"../DATAFILE/GFX/BULLETS.TGA"						; bitmap for 8 bullets
							.dphrase
;;
;; BSS SECTION
;;

							.bss
top_of_bss:

RAPTOR_MTtrash:				.ds.b	16384																		; Workspace for MemoryTrack routines

							.dphrase
RAPTOR_particle_gfx:		.ds.b	(raptor_particle_buffer_width/2)*raptor_particle_buffer_height				; particle FX buffer
RAPTOR_particle_gfxe:			
							.dphrase
RAPTOR_sprite_table:		.ds.b	sprite_max*sprite_tabwidth													; RAPTOR sprite database
							.dphrase
RAPTOR_particle_table:		.ds.b	raptor_particle_pixels*particle_tabwidth									; RAPTOR particle database
							.dphrase
							
_trashram:
								
;END OF FILE

				
