
;CollisionMaskY equ %11111000 ;Because we're using 8x8 tiles
;CollisionMaskX equ %11111100	;We're masking the collision detection routines

PlayerHsprite equ 1


UserRam Equ &C000			;Game Ram

ScreenWidth32 equ 1
ScreenWidth equ 32
ScreenHeight equ 24
ScreenObjWidth equ 128-2
ScreenObjHeight equ 192-8

VdpOut_Data equ &98			;For Data writes
VdpOut_Control equ &99		;For Reg settings /Selecting Dest addr in VRAM

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	ifdef vasm
		include "\SrcALL\VasmBuildCompat.asm"
	else
		read "\SrcALL\WinApeBuildCompat.asm"
	endif
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	read "\SrcALL\CPU_Compatability.asm"

;For Cartridge	
	org &4000				;Base Cart Address
	db "AB"					;Fixed Header
	dw ProgramStart 		;Pointer to start of program
	db 00,00,00,00,00,00	;Unused
	
	;Effectively Code starts at address &400A
	
ProgramStart:				;Program Code Starts Here
	di
	;Set up our screen
	ld c,VdpOut_Control
	ld b,VDPScreenInitData_End-VDPScreenInitData
	ld hl,VDPScreenInitData
	otir				;Out (c),(hl).. inc HL... dec B, djnz 
	
	
	ld hl,&0000		;Define Tiles 128+ (8 Bytes per tile)
	call VDP_SetWriteAddress
	
	ld hl,BitmapData		;Copy Tile pixel Data
	ld bc,BitmapDataEnd-BitmapData	;Bytes
	call dootir					
	nop 					;Delay
	
	
	
	ld hl,&2000		;Define Tile Palette 128+ (8 Bytes per tile)
	call VDP_SetWriteAddress
	
	ld hl,TestSpritePalette ;Copy Tile Palette Data
	ld bc,TestSpritePalette_END-TestSpritePalette;Bytes
	call dootir				
	
	
	
	
	ld hl,&3800				;Define Hardware Sprites
	call VDP_SetWriteAddress
	
	ld hl,SpriteData		;Copy Hpsprite pixel Data
	ld bc,SpriteDataEnd-SpriteData	;Bytes
	call dootir					
	nop 					;Delay
	
	
	
	ld hl,UserRam			;Clear Game Ram
	ld de,UserRam+1
	ld bc,&1000
	ld (hl),0
	ldir

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;										Our program													

	
ShowTitle:
;Init Game Defaults
	ld a,3
	ld (lives),a			;Life count
	xor a
	ld (level),a			;Level number
	ld (PlayerObject),a		;Player Sprite
	call ChibiSound			;Mute sound

	call Cls				;Scr Clear
	
	ld hl,TitlePic			;Title Image
	ld c,0
TitlePixNextY:
	ld b,0
TitlePixNextX:
	push bc		
		push hl
			ld a,(hl)		;Sprite number
			or a
			jr z,TitleNoSprite
			add 96
			ld h,a
			call ShowSprite ;BC=XY HL=Sprnum
TitleNoSprite:
		pop hl
		inc hl
	pop bc
	inc b
	ld a,b
	cp ScreenWidth			;Do next Tile on line
	jr nz,TitlePixNextX	
	inc C
	ld a,c
	cp ScreenHeight			;Do next line
	jr nz,TitlePixNextY

	ld hl,&0D10
	call Locate
	ld hl,txtFire			;Show Press Fire
	call PrintString

	ld hl,&1202
	call Locate
	ld hl,txtUrl			;Show URL
	call PrintString

	ld hl,&1000
	call Locate
	ld hl,txtHiScore
	call PrintString
	ld de,HiScore 			;Show the highscore
	ld b,4
	call BCD_Show

StartLevel:
	Call WaitForFire
	call CLS
	Call ResetPlayer
	call LevelInit
	
	ld c,1						;Select 1st hardware sprite
	ld IX,PlayerObject
	ld (IX+O_HSprNum),c			;Player Sprite (1)
	
	inc c
	
	ld ix,BulletArray			;Player Bullets (8)
	ld b,BulletCount
	call SetHardwareSprites		
	
	ld ix,EnemyBulletArray		;Enemy Bullets (8)
	ld b,BulletCount
	call SetHardwareSprites		;17 sprites total
	
	;MSX1 has 32 sprites - not enough for the object array
	
	
	

infloop:	
	ld bc,250				;Game Speed delay
	ld d,0					;Buffer for presesd key
PauseBC:
	push de
	push bc
		call ReadJoystick 	;Read from Joystick
	pop bc				
	pop de
	cp 0
	jr z,PauseNoKey
	ld d,a					;Store pressed key
PauseNoKey:
	dec bc
	ld a,b
	or c
	jr nz,PauseBC
	
StartDraw:
	push de
		push bc
			call DrawUi
			ld IX,PlayerObject
			call BlankSprite;Remove old player sprite
		pop bc
	pop de
	
	ld hl,KeyTimeout
	ld a,(hl)
	or a
	jr z,ProcessKeys
	dec (hl)
	jp JoySkip		;skip player input
	
ProcessKeys:
	ld hl,PlayerAccY
	ld e,0				;Timeout in E
	ld a,d
	cp 1
	jr nz,JoyNotUp		;Jump if UP not presesd
	ld a,(hl)
	sub 1				;Move Y Up the screen
	ld (hl),a
	ld e,5
JoyNotUp:
	ld a,d
	cp 5
	jr nz,JoyNotDown	;Jump if DOWN not presesd
	ld a,(hl)
	add 1				;Move Y Down the screen
	ld (hl),a
	ld e,5
JoyNotDown:
	ld hl,PlayerAccX
	ld a,d
	cp 7
	jr nz,JoyNotLeft 	;Jump if LEFT not presesd
	ld a,(hl)
	sub 1
	ld (hl),a			;Move X Left 
	ld e,5
JoyNotLeft:
	ld a,d
	cp 3
	jr nz,JoyNotRight	;Jump if RIGHT not presesd
	ld a,(hl)
	add 1
	ld (hl),a			;Move X Right
	ld e,5
JoyNotRight: 

	ld a,1				;Select Fire 1
	call &00D8			;Joystick Fire button firmwaer call
	cp 255
	jr nz,JoyNotFire	;Jump if Fire not presesd
	call PlayerFirebullet
JoyNotFire: 
	ld a,3				;Select Fire 2
	call &00D8			;Joystick Fire button firmwaer call
	cp 255
	jr nz,JoyNotFire2	;Jump if Fire2 not presesd
	xor a
	ld (PlayerAccX),a	;Stop Motion
	ld (PlayerAccY),a
JoyNotFire2: 

	ld a,e
	ld (KeyTimeout),a	;Update Timeout if a key was pressed
JoySkip: 
	call DrawAndMove

	jp infloop

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PrintCharB:
	push bc
		sub 32				;No Char below space
		ld h,a
		ld bc,(CursorY)	
	jr ShowSpriteB
	
ShowSprite:
	push bc
	jr ShowSpriteB

DoGetSpriteObj:
	push bc
		ld a,(SpriteFrame)
		rlca				;16 tiles per bank
		rlca
		rlca
		rlca
		ld h,a
		
		ld a,(IX+O_SprNum)	;Sprite Source
		add 96				;First 96 tiles are font
		add h
		ld h,a
DrawBoth:
		ld b,(IX+O_Xpos)
		srl b				;Skip unusable bits of XY pos
		srl b					;(Limit to 8x8 tile grid)
		ld c,(IX+O_Ypos)
		srl c
		srl c
		srl c
ShowSpriteB:
			call GetVDPScreenPos;Move to the correcr VDP location
			ld a,h
			out (VdpOut_Data),a	;Tile number to Vram
	pop bc
	ret		
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
BlankSprite:	
	ld a,(IX+O_CollProg)
	cp 250					;don't draw if CollProg is >=250
	ret nc

	ld a,(IX+O_HSprNum)
	dec a
	cp 128
	jp nc,BlankSpriteSoft
	cp 255 
	jp nz,BlankSpriteHard
BlankSpriteSoft:		
	push bc
		ld h,0
	jp DrawBoth
	
BlankSpriteHard:	
	push bc
		push af
			ld h,0
			ld c,200
			jr DrawBothHard
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DoGetHSpriteObj:
	push bc
		push af
			ld a,(SpriteFrame)	;Show Sprite of Objec XY
			rlca				;SpriteFrame*16 (16 sprites per bank)
			rlca
			rlca
			rlca
			ld h,a

			ld a,(IX+O_SprNum)	;Sprite Source
			push af
				push hl
					ld hl,SpritePalette
					add l
					ld l,a
					ld a,(hl)
				pop hl
				ld l,a
			pop af
			add h
			ld h,a
			
			ld d,0
			ld b,(IX+O_Xpos)	;Skip unusable bits of XYpos 
			sla b					;(limit to 8x8 tile)
			ld c,(IX+O_Ypos)
DrawBothHard:
		pop af
;A=Hardware Sprite No. B,C = X,Y , D,E = Source Data, H=Palette etc
		call SetHardwareSprite	
	pop bc
	ret
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
	
SetHardwareSprite:
	rlca					;4 bytes per sprite
	rlca
	push bc
	push hl
		ld h,&1B			;Sprite Attribs start at &1B00
		ld l,a
		call VDP_SetWriteAddress
	pop hl
	pop bc
	ld a,c
	out (VdpOut_Data),a		;y
	nop
	nop
	ld a,B
	out (VdpOut_Data),a		;x
	nop
	nop
	ld a,h
	out (VdpOut_Data),a		;Pattern
	nop
	nop
	ld a,l
	out (VdpOut_Data),a		;Color + 'EC'
	nop
	nop
	ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

CLS:						;Set all tiles to 0
	ld c,0
CLSNextY:
	ld b,0
CLSNextX:
	push bc		
		push hl
			ld h,0
			call ShowSprite ;BC=XY HL=Sprnum
		pop hl
		inc hl
	pop bc
	inc b
	ld a,b
	cp ScreenWidth
	jr nz,CLSNextX	
	inc C
	ld a,c
	cp ScreenHeight
	jr nz,CLSNextY
	
;Clear Hardware sprites	
	ld b,32			;Hardware sprite count
ClearSprites:
	push bc
		ld a,b
		dec a
		ld c,200	;Ypos - move offscreen
		call SetHardwareSprite
	pop bc
	djnz ClearSprites
	ret	

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Move the VDP write pointer to a memory location by XY location
GetVDPScreenPos:
	push hl
		ld h,c		;B=Xpos (0-31), C=Ypos (0-23)
		xor a
		
		srl h	;32 bytes per line, so shift L left 5 times, 
		rr a		;and push any overflow into H
		srl h
		rr a
		srl h
		rr a
		
		or b	;Or in the X co-ordinate
		ld l,a
		
		ld a,h
		or &18	;Tilemap starts at &1800
		ld h,a
		call VDP_SetWriteAddress
	pop hl
	ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

VDP_SetWriteAddress:		;Set VRAM address next write will occur
	di
	ld a, l
    out (VdpOut_Control), a	;Send L byte
    ld a, h
    or %01000000			;Set WRITE (0=read)
    out (VdpOut_Control), a	;Send H  byte
	
	ld c,VdpOut_Data		;Set C to data Write Addr
	ret            
	
		
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
BitmapData:
FontData:
	incbin "\ResALL\Yquest\FontZXS.raw"				;2 color bitmap data
SpriteData:
	incbin "\ResALL\Yquest\ZXS_YQuest.RAW"
	incbin "\ResALL\Yquest\ZXS_YQuest2.RAW"
	incbin "\ResALL\Yquest\ZXS_YQuest3.RAW"
	incbin "\ResALL\Yquest\ZXS_YQuest4.RAW"
SpriteDataEnd:
	
TestSpritePalette:
	incbin "\ResALL\Yquest\FontZXS.raw.COL"			;MSX1 Color Data
	incbin "\ResALL\Yquest\ZXS_YQuest.RAW.COL"
	incbin "\ResALL\Yquest\ZXS_YQuest2.RAW.COL"
	incbin "\ResALL\Yquest\ZXS_YQuest3.RAW.COL"
	incbin "\ResALL\Yquest\ZXS_YQuest4.RAW.COL"
TestSpritePalette_END:
BitmapDataEnd:


SpritePalette:
	db 9,5,5,5
	db 5,10,14,6
	db 5,5,5,5
	db 5,5,5,5

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ReadJoystick:
	ei
		ld a,1				;Joystick 1 (0=keyboard 1=joy1 2=joy2)
		call &00D5			;GTSTCK - Get Keypress
	ret
	
WaitForFire:
	call DoRandom
	ld a,1					;Select Fire 1
	call &00D8				;Read Trigger
	cp 255
	jr z,WaitForFire

WaitForFireB:
	call DoRandom
	ld a,1					;Select Fire 1
	call &00D8				;Read Trigger
	cp 255
	jr nz,WaitForFireB
	ret
	

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
	
	
	read "YQ_DataDefs.asm"
	read "YQ_RamDefs.asm"
	read "YQ_Multiplatform2.asm"
	
	read "\SrcALL\Multiplatform_ChibiSound.asm"			;Sound Driver
	read "\SrcALL\MultiPlatform_ShowDecimal.asm"		;Show decimal numbers
	read "\SrcALL\Multiplatform_BCD.asm"				;Show Binary Coded Decimal
	;read "\SrcALL\Multiplatform_ShowHex.asm"			;Hex Display

	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;					VDP Register settings (needed to turn on screen)							
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
dootir:			;HL=Source BC=Bytecount
	push bc
		ld c,VdpOut_Data
		outi
	pop bc
	dec bc
	ld a, b
	or c
	jr nz,dootir
	ret

VDPScreenInitData:
	;	Value   ,Register
	db %00000010,128+0	;mode register #0
	db %01100000,128+1	;mode register #1
	db %10011111,128+3	;colour table (LOW)
	db %00000000,128+4	;pattern generator table
	db %00110110,128+5	;sprite attribute table (LOW)
	db %00000111,128+6	;sprite pattern generator table
	db %11110000,128+7	;border colour/character colour at text mode
VDPScreenInitData_End:

	org &C000			;Make cartridge 32k
 