;Masks for un-drawable co-ordinates 
CollisionMaskY equ %11111000	
CollisionMaskX equ %11111100


ScreenWidth20 equ 1
ScreenWidth equ 20
ScreenHeight equ 18
ScreenObjWidth equ 80
ScreenObjHeight equ 144

UserRam Equ &D000		;Game Vars
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	ifdef vasm
		include "\SrcALL\VasmBuildCompat.asm"
	else
		read "\SrcALL\WinApeBuildCompat.asm"
	endif
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	read "\SrcALL\CPU_Compatability.asm"


;"The eight gameboy buttons/direction keys are arranged in form of a 2x4 matrix. Select either button or direction keys by writing to this register, then read-out bit 0-3.
  ;Bit 7 - Not used
  ;Bit 6 - Not used
  ;Bit 5 - P15 Select Button Keys      (0=Select)
  ;Bit 4 - P14 Select Direction Keys   (0=Select)
  ;Bit 3 - P13 Input Down  or Start    (0=Pressed) (Read Only)
  ;Bit 2 - P12 Input Up    or Select   (0=Pressed) (Read Only)
;  Bit 1 - P11 Input Left  or Button B (0=Pressed) (Read Only)
 ; Bit 0 - P10 Input Right or Button A (0=Pressed) (Read Only)


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;										Header												
	org &0000				;RST 0-7
	org &0040				;Interrupt: Vblank
		reti				
	org &0048				;Interrupt:	LCD-Stat
		reti
	org &0050				;Interrupt: Timer
		reti
	org &0058				;Interrupt: Serial
		reti
	org &0060				;Interrupt: Joypad
		reti
	org &0100
	nop				;0100-0103	Entry point (start of program)
	jp	begin
					;0104-0133	Nintendo logo (Must match ROM logo)	
	db &CE,&ED,&66,&66,&CC,&0D,&00,&0B,&03,&73,&00,&83,&00,&0C,&00,&0D
	db &00,&08,&11,&1F,&88,&89,&00,&0E,&DC,&CC,&6E,&E6,&DD,&DD,&D9,&99
	db &BB,&BB,&67,&63,&6E,&0E,&EC,&CC,&DD,&DC,&99,&9F,&BB,&B9,&33,&3E
	db "YQUEST         " ;0134-0142	Game Name (UCASE)
	ifdef BuildGBC 
		db &80		;0143 		Color gameboy flag (&80 = GB+CGB,&C0 = CGB only)
	else 
		db &00
	endif
	db 0,0       	;0144-0145	Game Manufacturer code
	db 0         	;0146		Super GameBoy flag (&00=normal, &03=SGB)
	db 2	  	  	;0147		Cartridge type (special upgrade hardware) 
	db 2        	;0148		Rom size (0=32k, 1=64k,2=128k etc)
	db 3         	;0149		Cart Ram size (0=none,1=2k 2=8k, 3=32k)
	db 1         	;014A		Destination Code (0=JPN 1=EU/US)
	db &33       	;014B		Old Licensee code (must be &33 for SGB)
	db 0         	;014C		Rom Version Number (usually 0)
	db 0         	;014D		Header Checksum - ‘ones complement' checksum of bytes 0134-014C… (not needed for emulators)
	dw 0         	;014E-014F	Global Checksum – 16 bit sum of all rom bytes (except 014E-014F)… unused by gameboy

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;										Start of code												
	 
begin:
	nop						;No-op for safety!
	di
	ld	sp, &ffff			; set the stack pointer to highest mem location + 1
	
	xor a					;We're going to reset the tilemap pos	
	ld hl,&FF42				
	ldi	(hl), a				;FF42: SCY - Tile Scroll Y
	ld	(hl), a				;FF43: SCX - Tile Scroll X
	
StopLCD_wait:				;Turn off the screen so we can define our patterns
	ld      a,(&FF44)		;Loop until we are in VBlank
	cp      145             ;Is display on scan line 145 yet?
	jr      nz,StopLCD_wait ;no? keep waiting!
	ld      hl,&FF40		;LCDC - LCD Control (R/W)
	res     7,(hl)      	;Turn off the screen
	
;Transfer Tiles to Vram
	ld	de, 0*16+&8000 	;$8000 is the start of Tile Ram , 16 bytes per Tile
	ld	hl, BitmapData		;Source of Tile images
	ld	bc, BitmapDataEnd-BitmapData	;Length
	call DefineTiles

;Define palette
	ifdef BuildGBC
		ld c,0*8		;palette no 0 (back)
		call SetGBCPalettes
	else
		ld a,%00011011		;DDCCBBAA .... A=Background 3=Black, =White
		ld hl,&FF47
		ldi (hl),a			;FF47 	BGP	BG & Window Palette Data  (R/W)	= &FC
		ldi (hl),a			;FF48  	OBP0	Object Palette 0 Data (R/W)	= &FF
		cpl					;Set sprite Palette 2 to the opposite
		ldi (hl),a			;FF49  	OBP1	Object Palette 1 Data (R/W)	= &FF
	endif
	ld      hl,&FF40		;LCDC - LCD Control (R/W)	EWwBbOoC 
    set     7,(hl)          ;Turn on the screen
    
	ld hl,UserRam		;Clear Game Ram
	ld de,UserRam+1
	ld bc,&800
	ld (hl),0
	z_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
	ld c,0
TitlePixNextY:
	ld b,0
TitlePixNextX:
	push bc		
		push hl
			ld a,(hl)	;Sprite number
			or a
			jr z,TitleNoSprite
			call ShowSprite ;BC=XY HL=Sprnum
TitleNoSprite:
		pop hl
		inc hl
	pop bc
	inc b
	ld a,b
	cp ScreenWidth
	jr nz,TitlePixNextX	
	inc C
	ld a,c
	cp ScreenHeight
	jr nz,TitlePixNextY

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

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

	ld hl,&0411
	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
	

infloop:	
	ld bc,1000
	ld d,0
PauseBC:
	push de
	push bc
		call ReadJoystick 	;Read from Joystick
	pop bc
	pop de
	cp %00111111
	jr z,PauseNoKey
	ld d,a
PauseNoKey:
	dec bc
	ld a,b
	or c
	jr nz,PauseBC
	
StartDraw:
	push de
		push bc
			call DrawUi
			z_ld_ix PlayerObject ;Load IX from Player Object
			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
	bit 0,d
	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:
	bit 1,d
	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
	bit 2,d
	jr nz,JoyNotLeft 	;Jump if LEFT not presesd
	ld a,(hl)
	sub 1
	ld (hl),a			;Move X Left 
	ld e,5
JoyNotLeft:
	bit 3,d
	jr nz,JoyNotRight	;Jump if RIGHT not presesd
	ld a,(hl)
	add 1
	ld (hl),a			;Move X Right
	ld e,5
JoyNotRight: 
	bit 4,d
	jr nz,JoyNotFire	;Jump if Fire not presesd
	call PlayerFirebullet
JoyNotFire: 
	bit 5,d
	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:					;Print a Font Char Sprite 
	push bc	
		sub 32				;No Character below 32
		ld h,a
		ld l,2				;Palette for font
		z_ld_bc_from CursorY;Get Xy Pos
	jr ShowSpriteB
	
ShowSprite:	
	push af
		push hl
			ld hl,SpritePalettes
			add l
			ld l,a
			ld a,(hl)
		pop hl
		ld l,a
	pop af
	add 96
	ld h,a
ShowSpriteA:
	push bc					;Show Sprite A	
	jr ShowSpriteB
	
DoGetSpriteObj:
	push bc
		ld a,(SpriteFrame)	;Show Sprite of Object XY
		rlca				;SpriteFrame*16 (16 sprites per bank)
		rlca
		rlca
		rlca
		ld h,a
		z_ld_a_ix_plusn O_SprNum	;Sprite Source
		push af
			push hl
				ld hl,SpritePalettes
				add l
				ld l,a
				ld a,(hl)
			pop hl			
			ld l,a
		pop af
		
		add 96
		add h
		ld h,a
DrawBoth:
		z_ld_b_ix_plusn O_Xpos ;Skip unusable bits of XYpos 
		srl b					;(limit to 8x8 tile)
		srl b
		z_ld_c_ix_plusn O_Ypos ;ld c,(IX+O_Ypos)
		srl c
		srl c
		srl c
ShowSpriteB:
	ifdef BuildGBC
		ld a,l
		push af
	endif
		ld a,h
		push af
			call GetVDPScreenPos	;Calculate Tile VRAM Pos
			call LCDWait			;Wait for LCD
		pop af
		ld (hl),a				;Set tile to 128
		ifdef BuildGBC
			ld bc,&FF4F	;VBK - CGB Mode Only - VRAM Bank
			ld a,1		;Turn on GBC extras
			ld (bc),a					
			call LCDWait			;Wait for LCD
			pop af
			ld (hl),a	;Set Palette
			xor a		;Turn off GBC extras
			ld (bc),a
		endif
	pop bc
	ret

BlankSprite:	
	z_ld_a_ix_plusn O_CollProg ;ld a,(IX+O_CollProg)
	cp 250					;don't draw if CollProg is >=250
	ret nc
	push bc
		ld h,0
		ld l,0
	jp DrawBoth

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CLS:
	ld c,0
CLSNextY:
	ld b,0
CLSNextX:
	push bc		
		push hl
			ld h,0			;Zero Tile
			ld l,0			;Palette
			call ShowSpriteA ;BC=XY HL=Sprnum
		pop hl
		inc hl
	pop bc
	inc b
	ld a,b
	cp 20					;Screen Width
	jr nz,CLSNextX	
	inc C
	ld a,c
	cp 18					;Screen Height
	jr nz,CLSNextY
	ret	
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

DefineTiles:	;Write BC bytes from HL to DE for tile definition
	call LCDWait	;Wait for VDP Sync
	ldi a,(hl)		;LD a,(hl), inc HL
	ld (de),a			
	inc de
	dec bc
	ld a,b
	or c
	jr nz,DefineTiles
	ret

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

GetVDPScreenPos:;Set HL to tilepos B=Xpos, C=Ypos
	xor a
	ld h,c		;Ypos*32
	rr h		;Each line is 32 tiles
	rra			;and each tile is 1 byte
	rr h
	rra
	rr h
	rra
	or b		;Add XPOS
	ld l,a
	ld a,h
	add &98		;The tilemap starts at &9800
	ld h,a
	ret
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


LCDWait:	;Wait for Vblanks so we can write to VRAM
	push af
        di
LCDWaitAgain
        ld a,(&FF41)  	;STAT - LCD Status (R/W)
			;-LOVHCMM
        and %00000010	;MM=video mode (0/1 =Vram available)  		
        jr nz,LCDWaitAgain 
    pop af	
	ret
 

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

BitmapData:
FontData:
	incbin "\ResALL\Yquest\FontGB.raw"

SpriteData:
	incbin "\ResALL\Yquest\GMB_Yquest.raw"
	incbin "\ResALL\Yquest\GMB_Yquest2.raw"
	incbin "\ResALL\Yquest\GMB_Yquest3.raw"
	incbin "\ResALL\Yquest\GMB_Yquest4.raw"
BitmapDataEnd:

	

ReadJoystick:
	ld a,%11101111 	;Select UDLR
	ld (&FF00),a
	
	ld a,(&FF00)	;Read in Keys
;We Need to swap position of RL and UD 
	rra				;Store R into L
	rl l			
	rra				;Store L into L
	rl l
	
	rra
	rr h			;Put U into H
	rra
	rr h			;Put D into H
		
	ld a,%11011111		;Select Fire/SelectStart
	ld (&FF00),a
	
	rr l			;Put LR into H
	rr h
	rr l
	rr h
	
	ld a,(&FF00)	;Read in the Fire Buttons
	rra			;	A
	rr h
	rra			;	B
	rr h
	rra			;Select
	rr h
	rra			;Start
	rr h
	ld a,h
	ret
	
WaitForFire:
	call DoRandom		;Randomize seed
	call ReadJoystick 	
	and %00010000
	jr nz,WaitForFire

WaitForFireB:
	call DoRandom		;Randomize seed
	call ReadJoystick 	
	and %00010000
	jr z,WaitForFireB
	ret
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
	
	
	read "YQ_DataDefs.asm"
	read "YQ_RamDefs.asm"
	read "YQ_Multiplatform_GBZ80.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

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
	
	
SetGBCPalettes:
	ifdef BuildGBC
		ld hl,GBPal		
SetGBCPalettesb:
		ldi a,(hl)  	;GGGRRRRR
		ld e,a
		ldi a,(hl)  	;xBBBBBGG
		ld d,a
		inc a 			;cp 255
		ret z
		push hl
			call lcdwait ;Wait for VDP Sync
			ld hl,&ff68	
			ld (hl),c	;FF68 - BCPS/BGPI - CGB Mode Only - Background Palette Index
			inc hl			
			ld (hl),e	;FF69 - BCPD/BGPD - CGB Mode Only - Background Palette Data
			dec hl		
			inc	c		;Increase palette address
			ld (hl),c	;FF68 - BCPS/BGPI - CGB Mode Only - Background Palette Index
			inc hl		
			ld (hl),d	;FF69 - BCPD/BGPD - CGB Mode Only - Background Palette Data
			inc c		;Increase palette address
		pop hl
		jr SetGBCPalettesb
	endif
	
	
	
	align 32
SpritePalettes:	;One palette per sprite num (0-15)
	db 1
	db 0
	db 2
	db 2
	
	db 0
	db 1
	db 0
	db 4
	
	db 0
	db 0
	db 2
	db 3
	
	db 2
	db 4
	db 3
	db 0
	

;		 	xBBBBBGGGGGRRRRR
GBPal:	dw %0000000000000000	;col 0
		dw %0011110000001111	;col 1
		dw %0001111111100111	;col 2
		dw %0111111111111111	;col 3
		
		dw %0000000000000000	;col 0	Reds
		dw %0000001111111111	;col 1
		dw %0000000000011111	;col 2
		dw %0111111111111111	;col 3
		
		dw %0000000000000000	;col 0  Blues
		dw %0111110000000000	;col 1
		dw %0111111111100000	;col 2
		dw %0111111111101111	;col 3
		
		dw %0000000000000000	;col 0	Reds2
		dw %0000000000011111	;col 1
		dw %0000001111111111	;col 2
		dw %0111111111111111	;col 3
		
		dw %0000000000000000	;col 0	Greys
		dw %0001110011100111	;col 1
		dw %0011110111101111	;col 2
		dw %0111111111111111	;col 3
		
		dw %1111111111111111	;End of list
	
	