
	.def	lvPlayerOk	0
	.def	lvLiveDecrease	0
	.def	lvGameOver	1
	.def	lvNextLevel	2

;******************************
;*
;* initLevel
;* 
;* r6 = level data
;*

initLevel

	;prolog

	push	r1
	push	r2
	push	r3
	push	r4
	push	r5
	push	r6
	push	r7

	;reset start position
	
	gpci	r7,2
	br	setStartPosition
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
	;enable all enemys
	
	dexti	>resetEnemys
	movei	r2,resetEnemys
	gpci	r7,2		
	jmpi	r2,0
	rqldi	r6,lvMapAddress	;delay slot
	nop			;delay slot
	nop			;delay slot
	ld	r1		;delay slot
	
	;reset energy of player
	
	dexti	>resetEnergy
	movei	r2,resetEnergy
	gpci	r7,2		
	jmpi	r2,0
	dexti	>playerData	;delay slot
	movei	r0,playerData	;delay slot
	nop			;delay slot
	nop			;delay slot
	
initLevelLoop

	;wait vpos (930)

	dexti	>waitVPos
	movei	r4,waitVPos
	gpci	r7,2	
	jmpi	r4,0
	movei	r3,$a1	;delay slot
	nop		;delay slot
	moveih	r3,$3	;delay slot
	nop		;delay slot	
		
	;frame switch
	
	dexti	>switchFrames
	movei	r4,switchFrames
	gpci	r7,2
	jmpi	r4,0
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
	;process ps2 keys
	
	dexti	>PS2Process
	movei	r4,PS2Process
	gpci	r7,2		
	jmpi	r4,0
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	;testKeys
	
	dexti	>testKeys
	movei	r4,testKeys
	gpci	r7,2
	jmpi	r4,0
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot	
		
	;clear draw frame
	
	dexti	>drawFrame
	movei	r4,drawFrame
	nop
	rqldi	r4,1
	rqldi	r4,0
	nop
	ld	r2	;low
	ld	r3	;high
	
	dexti	>efill8
	movei	r4,efill8
	gpci	r7,2
	jmpi	r4,0
	dexti	$2b		;delay slot
	movei	r0,$10		;delay slot
	movei	r1,0		;delay slot
	nop			;delay slot
	
	;setup char drawer
	
	dexti	>drawChar16x16
	movei	r2,drawChar16x16
	
	dexti	>setCharDrawer
	movei	r3,setCharDrawer
	gpci	r7,2
	jmpi	r3,0
	movei	r0,globalFont16x16	;delay slot
	movei	r1,>>globalFont16x16	;delay slot
	moveih	r0,>globalFont16x16	;delay slot
	moveih	r1,>>>globalFont16x16	;delay slot
		
	;draw text 1	
		
	rqldi	r6,lvNumber
	nop
	nop
	ld	r0
	nop
	
	push	r0	;store levelnumber
		
	dexti	>drawTextFormated
	movei	r3,drawTextFormated
	gpci	r7,2		;next 4 + X
	jmpi	r3,0
	movei	r0,levelInitText1	;delay slot
	movei	r1,4			;delay slot
	moveih	r0,>levelInitText1	;delay slot
	movei	r2,4			;delay slot
	
	rqpop
	nop
	nop
	nop
	
	;draw text 2	
		
	rqldi	r6,lvNameAddress
	nop
	nop
	ld	r0
	nop
	
	push	r0	;store level name
		
	dexti	>drawTextFormated
	movei	r3,drawTextFormated
	gpci	r7,2		;next 4 + X
	jmpi	r3,0
	movei	r0,levelInitText2	;delay slot
	movei	r1,0			;delay slot
	moveih	r0,>levelInitText2	;delay slot
	movei	r2,5			;delay slot
	
	rqpop
	nop
	nop
	nop
	
	;draw text 3
	
	dexti	>levelFlickerCounter
	movei	r3,levelFlickerCounter
	nop
	rqldi	r3,0
	nop
	nop
	ld	r0
	nop
	addi	r0,1
	nop
	st	r3,r0

	nop
	extri	r0,4
	brts	skipText3
	nop				;delay slot
	nop				;delay slot
	dexti	>drawTextFormated	;delay slot
	movei	r3,drawTextFormated	;delay slot

	gpci	r7,2		;next 4 + X
	jmpi	r3,0
	movei	r0,levelInitText3	;delay slot
	movei	r1,2			;delay slot
	moveih	r0,>levelInitText3	;delay slot
	movei	r2,7			;delay slot
	
skipText3	
	
	;test against space
	
	dexti	>OURL
	movei	r4,OURL
	nop
	rqldi	r4,0
	nop
	nop
	ld	r4
	nop
	
	extri	r4,4	;space??
	brtc	initLevelLoop
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
	
	;epilog
	
	rqpop
	rqpop
	rqpop
	poparqp	r7
	poparqp	r6
	poparqp	r5
	poparqp	r4
	pop	r3
	pop	r2
	pop	r1
	
	jmpi	r7,0
	nop		;delay slot
	nop		;delay slot	
	nop		;delay slot
	nop		;delay slot
	
;******************************
;*
;* playLevel
;* 
;* r6 = level data
;*	
;* return
;*
;* r0 = lvGameOver is game over no lives left
;*	lvNextLevel is goto next level
;*

playLevel

	;prolog

	push	r1
	push	r2
	push	r3
	push	r4
	push	r5
	push	r6
	push	r7

	;init module
	
	rqldi	r6,lvMusicAddressHigh
	rqldi	r6,lvMusicAddressLow
	nop
	ld	r1
	ld	r0

	
	dexti	>modInit
	movei	r2,modInit
	gpci	r7,2		;next 4 + X
	jmpi	r2,0
	dexti	>modChannels
	movei	r4,modChannels
	nop			;delay slot
	nop			;delay slot
	
	;start music
	
	dexti	>modStart
	movei	r1,modStart
	gpci	r7,2		;next 4 + X
	jmpi	r1,0		;start
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	;------------------------------ LEVEL LOOP (skip at dead or next level) -----------------------------
	
playLevelLoop	

	;wait vpos (930)

	dexti	>waitVPos
	movei	r4,waitVPos
	gpci	r7,2	
	jmpi	r4,0
	movei	r3,$a1	;delay slot
	nop		;delay slot
	moveih	r3,$3	;delay slot
	nop		;delay slot	
		
	;frame switch
	
	dexti	>switchFrames
	movei	r4,switchFrames
	gpci	r7,2
	jmpi	r4,0
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
	;process ps2 keys
	
	dexti	>PS2Process
	movei	r4,PS2Process
	gpci	r7,2		
	jmpi	r4,0
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	;testKeys
	
	dexti	>testKeys
	movei	r4,testKeys
	gpci	r7,2
	jmpi	r4,0
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot	
	
	;update counters (used for map anim)

	dexti	>updateCounters
	movei	r4,updateCounters
	gpci	r7,2
	jmpi	r4,0
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot	
	
	;anim map

	dexti	>animMap
	movei	r4,animMap
	gpci	r7,2		
	jmpi	r4,0
	rqldi	r6,lvMapAddress	;		delay slot
	nop			;		delay slot
	nop			;		delay slot
	ld	r0		;map address	delay slot

		
	;calcPlayer

	dexti	>calcPlayer
	movei	r2,calcPlayer
	gpci	r7,2		
	jmpi	r2,0
	rqldi	r6,lvMapAddress	;delay slot
	dexti	>playerData	;delay slot
	movei	r0,playerData	;delay slot
	ld	r1		;map address	delay slot
	
	;draw map
	
	dexti	>drawMap
	movei	r0,drawMap
	gpci	r7,2		
	jmpi	r0,0
	rqldi	r6,lvMapAddress	;		delay slot
	nop			;		delay slot
	nop			;		delay slot
	ld	r0		;map address	delay slot
	
	;calcEnemys
	
	dexti	>calcEnemys
	movei	r0,calcEnemys
	gpci	r7,2
	jmpi	r0,0
	rqldi	r6,lvMapAddress	;		delay slot
	nop			;		delay slot
	nop			;		delay slot
	ld	r1		;map address	delay slot
	
	;drawEnemy
	
	dexti	>drawEnemys
	movei	r0,drawEnemys
	gpci	r7,2
	jmpi	r0,0
	rqldi	r6,lvMapAddress	;		delay slot
	nop			;		delay slot
	nop			;		delay slot
	ld	r1		;map address	delay slot
	
	;draw player
	
	dexti	>drawPlayer
	movei	r0,drawPlayer
	gpci	r7,2
	jmpi	r0,0
	rqldi	r6,lvMapAddress	;		delay slot
	dexti	>playerData	;delay slot
	movei	r0,playerData	;delay slot	
	ld	r1		;map address	delay slot
	

	;test player shot
	
	dexti	>testPlayerShot
	movei	r0,testPlayerShot
	gpci	r7,2
	jmpi	r0,0
	rqldi	r6,lvMapAddress	;		delay slot
	dexti	>playerData	;delay slot
	movei	r0,playerData	;delay slot	
	ld	r1		;map address	delay slot	
	
	;draw bullets
	
	dexti	>drawAndCalcBullets
	movei	r0,drawAndCalcBullets
	gpci	r7,2
	jmpi	r0,0
	rqldi	r6,lvMapAddress	;		delay slot
	nop			;		delay slot
	nop			;		delay slot
	ld	r0		;map address	delay slot
	
	;draw hud
	
	dexti	>drawHUD
	movei	r0,drawHUD
	gpci	r7,2
	jmpi	r0,0
	rqldi	r6,lvMapAddress	;		delay slot
	dexti	>playerData	;delay slot
	movei	r0,playerData	;delay slot	
	ld	r1		;map address	delay slot
		
	;check enemy count
	
	dexti	>getLivingEnemyCount
	movei	r4,getLivingEnemyCount
	gpci	r7,2
	jmpi	r4,0
	rqldi	r6,lvMapAddress	;		delay slot
	nop			;		delay slot
	nop			;		delay slot
	ld	r1		;map address	delay slot
	
	nop
	cmpeqi	r0,0		;all enemys are dead
	brts	playLevelEnd
	movei	r0,lvNextLevel	;return next level delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	;check is player live
	
	dexti	>isPlayerDead
	movei	r4,isPlayerDead	
	gpci	r7,2
	jmpi	r4,0
	dexti	>playerData	;delay slot
	movei	r0,playerData	;delay slot	
	nop			;delay slot
	nop			;delay slot
	
	cmpeqi	r0,0	;0 = player ok
	gpci	r7,2
	brtc	playLevelPlayerIsDead
	movei	r0,lvPlayerOk	;set ok if no jump	delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	cmpeqi	r0,lvGameOver	;if game over go out
	brtc	playLevelLoop	
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	
playLevelEnd

	;stop music
	
	dexti	>modStop
	movei	r1,modStop
	gpci	r7,2		;next 4 + X
	jmpi	r1,0		;start
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	;epilog
	
	rqpop
	rqpop
	rqpop
	poparqp	r7
	poparqp	r6
	poparqp	r5
	poparqp	r4
	pop	r3
	pop	r2
	pop	r1
	
	jmpi	r7,0
	nop		;delay slot
	nop		;delay slot	
	nop		;delay slot
	nop		;delay slot

;******************************
;*
;* playLevelPlayerIsDead
;* 
;* r6 = level data
;*
;* return
;*
;* r0 = lvLiveDecrease is only live decrease
;*	lvGameOver is game over no lives left
;*

playLevelPlayerIsDead

	push	r7

	;reset start position
	
	gpci	r7,2
	br	setStartPosition
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
	;increase live
	
	dexti	>increaseLife
	movei	r4,increaseLife
	gpci	r7,2
	jmpi	r4,0
	dexti	>playerData	;delay slot
	movei	r0,playerData	;delay slot
	nop			;delay slot
	nop			;delay slot
	
	;get live count
	
	dexti	>getLiveCount
	movei	r3,getLiveCount	
	gpci	r7,2
	jmpi	r3,0
	dexti	>playerData	;delay slot
	movei	r0,playerData	;delay slot
	nop			;delay slot
	nop			;delay slot
	
	cmpeqi	r0,0		;game over?
	brts	playerGameOverLoop	
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
playerDeadLoop

	;wait vpos (930)

	dexti	>waitVPos
	movei	r4,waitVPos
	gpci	r7,2	
	jmpi	r4,0
	movei	r3,$a1	;delay slot
	nop		;delay slot
	moveih	r3,$3	;delay slot
	nop		;delay slot	
		
	;frame switch
	
	dexti	>switchFrames
	movei	r4,switchFrames
	gpci	r7,2
	jmpi	r4,0
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
	;process ps2 keys
	
	dexti	>PS2Process
	movei	r4,PS2Process
	gpci	r7,2		
	jmpi	r4,0
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	;testKeys
	
	dexti	>testKeys
	movei	r4,testKeys
	gpci	r7,2
	jmpi	r4,0
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot	
		
	;clear draw frame
	
	dexti	>drawFrame
	movei	r4,drawFrame
	nop
	rqldi	r4,1
	rqldi	r4,0
	nop
	ld	r2	;low
	ld	r3	;high
	
	dexti	>efill8
	movei	r4,efill8
	gpci	r7,2
	jmpi	r4,0
	dexti	$2b		;delay slot
	movei	r0,$10		;delay slot
	movei	r1,0		;delay slot
	nop			;delay slot
	
	;setup char drawer
	
	dexti	>drawChar16x16
	movei	r2,drawChar16x16
	
	dexti	>setCharDrawer
	movei	r3,setCharDrawer
	gpci	r7,2
	jmpi	r3,0
	movei	r0,globalFont16x16	;delay slot
	movei	r1,>>globalFont16x16	;delay slot
	moveih	r0,>globalFont16x16	;delay slot
	moveih	r1,>>>globalFont16x16	;delay slot
	
	;draw text 1	
		
	dexti	>getLiveCount
	movei	r3,getLiveCount	
	gpci	r7,2
	jmpi	r3,0
	dexti	>playerData	;delay slot
	movei	r0,playerData	;delay slot
	nop			;delay slot
	nop			;delay slot
	
	push	r0	;store live count
		
	dexti	>drawTextFormated
	movei	r3,drawTextFormated
	gpci	r7,2		;next 4 + X
	jmpi	r3,0
	movei	r0,levelDeadText1	;delay slot
	movei	r1,1			;delay slot
	moveih	r0,>levelDeadText1	;delay slot
	movei	r2,5			;delay slot
	
	rqpop
	nop
	nop
	nop
	
	;draw text 2
	
	dexti	>levelFlickerCounter
	movei	r3,levelFlickerCounter
	nop
	rqldi	r3,0
	nop
	nop
	ld	r0
	nop
	addi	r0,1
	nop
	st	r3,r0

	nop
	extri	r0,4
	brts	DeadSkipText3
	nop				;delay slot
	nop				;delay slot
	dexti	>drawTextFormated	;delay slot
	movei	r3,drawTextFormated	;delay slot

	gpci	r7,2		;next 4 + X
	jmpi	r3,0
	movei	r0,levelInitText3	;delay slot
	movei	r1,2			;delay slot
	moveih	r0,>levelInitText3	;delay slot
	movei	r2,7			;delay slot
	
DeadSkipText3	
	
	;test against space
	
	dexti	>OURL
	movei	r4,OURL
	nop
	rqldi	r4,0
	nop
	nop
	ld	r4
	nop
	
	extri	r4,4	;space??
	brtc	playerDeadLoop
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
	movei	r0,lvLiveDecrease
	
playerDeadEnd	
	
	;epliog
	
	rqpop
	nop
	nop
	pop	r7
	nop
	
	jmpi	r7,0
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
	;_____________________ GAME OVER _________________________
	
playerGameOverLoop	

	;wait vpos (930)

	dexti	>waitVPos
	movei	r4,waitVPos
	gpci	r7,2	
	jmpi	r4,0
	movei	r3,$a1	;delay slot
	nop		;delay slot
	moveih	r3,$3	;delay slot
	nop		;delay slot	
		
	;frame switch
	
	dexti	>switchFrames
	movei	r4,switchFrames
	gpci	r7,2
	jmpi	r4,0
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
	;process ps2 keys
	
	dexti	>PS2Process
	movei	r4,PS2Process
	gpci	r7,2		
	jmpi	r4,0
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	;testKeys
	
	dexti	>testKeys
	movei	r4,testKeys
	gpci	r7,2
	jmpi	r4,0
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot	
		
	;draw image	
	
	dexti	>gameOverBobData	
	movei	r6,gameOverBobData	
	
	dexti	>drawFrame
	movei	r7,drawFrame
	nop
	rqldi	r7,0
	rqldi	r7,1
	nop
	ld	r1	;high
	ld	r2	;low
	nop
	
	ssto	csDestAdrLow
	stwo	r6,r2
	ssto	csDestAdrHigh
	stwo	r6,r1
	
	dexti	>drawBob
	movei	r4,drawBob
	gpci	r7,2		;
	jmpi	r4,0		;
	or	r0,r6,r6	;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	;setup char drawer
	
	dexti	>drawChar16x16
	movei	r2,drawChar16x16
	
	dexti	>setCharDrawer
	movei	r3,setCharDrawer
	gpci	r7,2
	jmpi	r3,0
	movei	r0,globalFont16x16	;delay slot
	movei	r1,>>globalFont16x16	;delay slot
	moveih	r0,>globalFont16x16	;delay slot
	moveih	r1,>>>globalFont16x16	;delay slot
	
	;draw text 1	
				
	dexti	>drawTextFormated
	movei	r3,drawTextFormated
	gpci	r7,2		;next 4 + X
	jmpi	r3,0
	movei	r0,gameOverText1	;delay slot
	movei	r1,7			;delay slot
	moveih	r0,>gameOverText1	;delay slot
	movei	r2,6			;delay slot
	
	;draw text 2
	
	dexti	>levelFlickerCounter
	movei	r3,levelFlickerCounter
	nop
	rqldi	r3,0
	nop
	nop
	ld	r0
	nop
	addi	r0,1
	nop
	st	r3,r0

	nop
	extri	r0,4
	brts	GameOverSkipText3
	nop				;delay slot
	nop				;delay slot
	dexti	>drawTextFormated	;delay slot
	movei	r3,drawTextFormated	;delay slot

	gpci	r7,2		;next 4 + X
	jmpi	r3,0
	movei	r0,gameOverText2	;delay slot
	movei	r1,6			;delay slot
	moveih	r0,>gameOverText2	;delay slot
	movei	r2,8			;delay slot
	
GameOverSkipText3	
	
	;test against space
	
	dexti	>OURL
	movei	r4,OURL
	nop
	rqldi	r4,0
	nop
	nop
	ld	r4
	nop
	
	extri	r4,4	;space??
	brtc	playerGameOverLoop
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
	br	playerDeadEnd
	movei	r0,lvGameOver	;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	
levelInitText1
	.stringz	"ENTERING LEVEL %u"

levelInitText2
	.stringz	"%z"
	
levelInitText3
	.stringz	"PRESS SPACE TO START"
	
levelDeadText1
	.stringz	"YOU HAVE %u LIVES LEFT!"
	
gameOverText1
	.stringz	"GAME OVER"

gameOverText2
	.stringz	"PRESS SPACE"
	
;******************************
;*
;* initLevel
;* 
;* r6 = level data
;*
	
setStartPosition

	;prolog
	
	push	r1
	push	r2
	push	r3
	push	r4
	push	r7

	;reset start position
	
	rqldi	r6,lvPlayerStartPositionX
	rqldi	r6,lvPlayerStartPositionY
	rqldi	r6,lvMapAddress		
	ld	r1
	ld	r2
	ld	r3
	
	dexti	>playerData		;get player struct
	movei	r4,playerData
	
	ssto	plPositionX
	stwo	r4,r1
	ssto	plPositionY
	stwo	r4,r2
	
	rqldi	r6,lvMapStartPositionX
	rqldi	r6,lvMapStartPositionY
	nop
	ld	r1
	ld	r2
	
	ssto	mapPositionX
	stwo	r3,r1
	ssto	mapPositionY
	stwo	r3,r2
	
	;epilog
	
	rqpop	
	rqpop
	rqpop
	poparqp	r7
	poparqp	r4
	pop	r3
	pop	r2
	pop	r1
	
	jmpi	r7,0
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
	
;*********************************************************************
;* data
;*********************************************************************	
	
levelFlickerCounter
	
	word	0	
	
	