ScreenWidth40 equ 1
ScreenWidth equ 40
ScreenHeight equ 25
ScreenObjWidth equ 160-2
ScreenObjHeight equ 200-8

UserRam Equ &8000				;System Memory

CLS equ &BC14					;Clear Screen Function (Bios)

	nolist
;BuildCPC equ 1	; Build for Amstrad CPC

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

	read "\SrcALL\CPU_Compatability.asm"

	org &100		;Start of our program

	ld a,1
	call &BC0E		;Scr Set Mode
	
;Set up Palette
	xor a
	ld hl,Palette
PaletteAgain:
	push hl
	push af
		ld b,(hl)	;2 Flashing colors
		ld c,(hl)
		call &bc32	;Set Color A=Pal num, BC=Colors
	pop af
	pop hl
	inc hl			;Next Palette Entry
	inc a
	cp 4			;Palette Count
	jr nz,PaletteAgain

	ld bc,&0101			;2 Flashing colors
	call &bc38			;Set Border BC


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

;Show Title Screen	
	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
		ld h,a
		push bc
			call GetSpriteAddr 	;H=spritenum
		pop bc
		sla b
		sla c
		sla c
		sla c
		call ShowSprite			;BC=XY HL=Sprnum
TitleNoSprite:
	pop hl
	inc hl
	pop bc
	inc b
	ld a,b
	cp 40						;Screen Width
	jr nz,TitlePixNextX	
	inc C
	ld a,c
	cp 24						;Screen Height
	jr nz,TitlePixNextY


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

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

	ld hl,&1818
	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:					;Main Loop
	ld bc,60				;Slow Down Delay
	ld d,0
PauseBC:
	push de
	push bc
		call &bb24 			;KM Get Joystick... Returns ---FRLDU
	pop bc
	pop de
	or a
	jr z,PauseNoKey
	ld d,a					;Store any pressed joystick buttons
PauseNoKey:
	dec bc
	ld a,b
	or c
	jr nz,PauseBC
	ld a,d

StartDraw:
	push af
		push bc
			call DrawUi
			ld IX,PlayerObject
			call BlankSprite;Remove old player sprite
		pop bc
	pop af
	ld d,a

	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

	bit 0,d
	jr z,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 z,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 z,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 z,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 z,JoyNotFire		;Jump if Fire not presesd
	call PlayerFirebullet
JoyNotFire: 
	bit 5,d
	jr z,JoyNotFire2	;Jump if Fire2 not presesd
	xor a
	ld (PlayerAccX),a
	ld (PlayerAccY),a
JoyNotFire2: 
	ld a,e
	ld (KeyTimeout),a
JoySkip: 
	call DrawAndMove
	jp infloop

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

PrintCharB:					;Print Char A with Sprite Routine
	push bc
		sub 32				;No Char below 32
		ld h,a
		ld l,0
		
		srl h				;Font * 16
		rr l
		srl h
		rr l
		srl h
		rr l
		srl h
		rr l
		ld bc,FontData
		add hl,bc

		ld bc,(CursorY)		;Get XY into BC
		rl c				;Y*8
		rl c
		rl c
		rl b				;X*2
	jr ShowSpriteB
	
ShowSprite:					;Draw Sprite A at XY pos BC
	push bc
	jr ShowSpriteB

DoGetSpriteObj:				;Get Settings from Object IX
	push bc
		ld h,(IX+O_SprNum)	;Sprite Source
		call GetSpriteAddr
	
DrawBoth:
		ld b,(IX+O_Xpos)
		srl b				;Skip bottom bit of Xpos 
		ld c,(IX+O_Ypos)
ShowSpriteB:
		call GetScreenPos

		ld bc,&08FF			;Lines (Height)
SpriteNextLine:
		push de
SpriteNextByte:
			ldi				;Do 2 bytes of sprite
			ldi
		pop de
		call GetNextLine	;Scr Next Line (Alter HL to move down a line)
		djnz SpriteNextLine	;Repeat for next line
	pop bc
	ret		

BlankSprite:	
	ld a,(IX+O_CollProg)
	cp 250
	ret nc

	push bc
		ld hl,FontData			;Sprite Source (Space)
	jp DrawBoth

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

GetSpriteAddr:
		ld l,0				;Sprite Source
		
		srl h				;16 bytes per sprite
		rr l
		srl h
		rr l
		srl h
		rr l
		srl h
		rr l
		ld bc,SpriteData
		add hl,bc

		ld a,(SpriteFrame)	;Sprite frame (256 bytes per bank)
		add h
		ld h,a	
	ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	; Input  BC= XY (x=bytes - so 80 across)
;	; output HL= screen mem pos
;	; de is wiped
;

;Looking at Y line (in C) - we need to take each set of bits, and work with them separately:
;YYYYYYYY	Y line number (0-200)
;-----YYY	(0-7)  - this part needs to be multiplied by &0800 and added to the total
;YYYYY---	(0-31) - This part needs to be multiplied by 80 (&50)



;YYYYY---	(0-31) - This part needs to be multiplied by 80 (&50)

GetScreenPos:	;return memory pos in HL of screen co-ord B,C (X,Y)
	push hl
		;screen is 80 bytes wide = -------- %01010000
		ld a,C		; 00000000 01010000
		and %11111000 	; -------- -YYYY---
		ld h,0
		ld l,a
				; 00000000 01010000
		
		sla l		; -------- YYYY----
		rl h
		
		ld d,h		;value is in first bit position -add it
		ld e,l	
				; 00000000 01010000
		sla e		; -------Y YYY-----
		rl d		;	    
		sla e		; ------YY YY------
		rl d
		
		add hl,de	;value is in 2nd bit position - add it
		;We've now effectively multiplied by 80 (&50)

	;-----YYY	(0-7)  - this part needs to be multiplied by &0800 and added to the total
		ld a,C
		and %00000111	
		
		rlca		;X8
		rlca
		rlca

		ld d,a		;Load into top byte, and add as 16 bit
		ld e,0

		add hl,de
		;We've now effectively multiplied by 8

;Screen Base
		ld a,&C0	;Add the screen Base &C000
		ld d,a

;X position
		ld e,B		;Add the X pos 
		add hl,de
		ex de,hl
	pop hl
	ret 		;return memory location in DE
	
	
;Every 8 lines we need to jump back to the top of the memory range to get the correct line
	;The code below will check if we need to do this - yes it's annoying but that's just the way the CPC screen is!
GetNextLine:
	ld a,d		;Add &08 to H (each CPC line is &0800 bytes below the last
	add &08
	ld d,a
	bit 7,d		;Change this to bit 6,h if your screen is at &8000!
	ret nz
	
	ld a,e		;Wrap back to the top of the &C000 range
	add &50
	ld e,a
	ld a,d
	adc &C0
	ld d,a
	ret

WaitForFire:
	call DoRandom		;Reseed Random Numbers
	call &bb24 			; KM Get Joystick... Returns ---FRLDU
	and %00010000
	jr nz,WaitForFire

WaitForFireB:
	call DoRandom		;Reseed Random Numbers
	call &bb24 			; KM Get Joystick... Returns ---FRLDU
	and %00010000
	jr z,WaitForFireB
	ret
	

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
		
	read "YQ_DataDefs.asm"
	read "YQ_RamDefs.asm"
	read "YQ_Multiplatform.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

SpriteData:
	incbin "\ResALL\Yquest\CPC_YQuest.raw"
	incbin "\ResALL\Yquest\CPC_YQuest2.raw"
	incbin "\ResALL\Yquest\CPC_YQuest3.raw"
	incbin "\ResALL\Yquest\CPC_YQuest4.raw"
	
FontData:												;Bitmap Font (4 color)
	incbin "\ResALL\Yquest\FontCPC.raw"
	
Palette:
	db 0,5,19,26			;Palette in native format
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

