	
	;enemy defs
	
	.def	enStateMoving		0		;AAB (AA = 0 enemy not dead or explode)
	.def	enStateShoot		1
	.def	enStateExplode		2
	.def	enStateDead		4
	
	.def	enStateEnemyActiveMax	2	
	
	.def	enStateHeavenRShift	1
	
	.def	enAnimMaxDelay		3
	.def	enAnimExplosionMaxDelay	9
	
	.def	enMovingAnimMax		3	;0..3
	.def	enExplosionAnimMax	9	;0..9
	
	.def	enemySourceWidth		288
	
	;enemy struct

	.def	enPositionX		0	
	.def	enPositionY		1       
	.def	enSOURL			2       
	.def	enDirection		3       
	.def	enIsMoving		4       
	.def	enMoveCounter		5       
	.def	enAnimDelayCounter	6       
	.def	enShotDelayCounter	7       
	.def	enState			8       
	.def	enCurrentWay		9       
	.def	enMaxWay		10	
	.def	enPosInWay              11      
	.def	enEnemyType             12   
	.def	enDirectionToPlayer	13
	.def	enDistanceToPlayer	14
	.def	enMinDistanceToPlayer	15
	.def	enEnemySpeed		16
	.def	enBulletSpeed		17
	.def	enBulletLifeTime	18
	.def	enBulletShotCounterMax	19
	.def	enWaysStart		20
	
	;enemy way struct
	
	.def	enWayX			0
	.def	enWayY			1
	.def	enWayLength		2
	.def	enWaySX			3
	.def	enWaySY			4
	.def	enWayDirection		5
	.def	enWayStructSize		6
	
;******************************
;*
;* resetEnemys
;* 
;* r1 = map struct
;*	

resetEnemys	
	
	;prolog

	push	r1
	push	r2
	push	r3
	push	r4
	push	r5
	push	r6
	push	r7
		
	;get enemy and set address struct to esadr
	
	rqldi	r1,mapEnemysAdrLow
	rqldi	r1,mapEnemysAdrHigh
	nop
	ld	r2
	ld	r3
	nop
	
	esadr	r3,r2		;
	erqldi	0		; enemy count
	eld	r2
	movei	r0,0
	subi	r2,1
	
	movei	r7,0
	
resetEnemysCountLoop

	;r0 = enemy number
	;r1 = map struct
	;r2 = loop counter
	
	;get address from enemy
	
	rqldi	r1,mapEnemysAdrLow
	rqldi	r1,mapEnemysAdrHigh
	addqi	r4,r0,1
	ld	r5
	ld	r6
	nop
	
	esadr	r6,r5		;
	erqld	r4		; offset
	eld	r4		;get enemy offset
	
	nop
	add	r5,r5,r4
	addtqi	r6,r6,0			;got to current enemy struct
	nop
	esadr	r6,r5
	
	;set state to normal
	
	movei	r3,enStateMoving
	dexti	3>enState		;  3 bit extension
	est	r3,enState		; store state
	
	;set current way
	
	movei	r3,0
	dexti	3>enCurrentWay		;  3 bit extension
	est	r3,enCurrentWay		; store state
	
	;set pos in way
	
	movei	r3,0
	dexti	3>enPosInWay		;  3 bit extension
	est	r3,enPosInWay		; store state

	subi	r2,1
	brts	resetEnemysCountLoop
	addi	r0,1	;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	
	
;******************************
;*
;* calcEnemys
;* 
;* r1 = map struct
;*	

calcEnemys

	;prolog

	push	r1
	push	r2
	push	r3
	push	r4
	push	r5
	push	r6
	push	r7
	
	;get enemy count
	
	;get enemy and set address struct to esadr
	
	rqldi	r1,mapEnemysAdrLow
	rqldi	r1,mapEnemysAdrHigh
	nop
	ld	r2
	ld	r3
	nop
	
	esadr	r3,r2		;
	erqldi	0		; enemy count
	eld	r2
	movei	r0,0
	subi	r2,1
	
calcEnemyLoop

	gpci	r7,2
	br	calcEnemyPre
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot

	gpci	r7,2
	br	calcEnemy
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
	gpci	r7,2
	br	testEnemyShot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot

	subi	r2,1
	brts	calcEnemyLoop
	addi	r0,1	;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	

;******************************
;*
;* calcEnemyPre
;*
;* will calculated/store direction and distance to player
;* 
;* r0 = enemy number
;* r1 = map struct
;*	

calcEnemyPre	

	;prolog

	push	r0
	push	r1
	push	r2
	push	r3
	push	r4
	push	r5
	push	r6
	push	r7
	
	;get absolute player position
	
	dexti	>playerData	;delay slot
	movei	r2,playerData	;delay slot
	nop
	
	rqldi	r2,plState
	rqldi	r2,plPositionX
	rqldi	r2,plPositionY
	ld	r7		;player state
	ld	r2		;player position x
	ld	r3		;player position y
	
	rqldi	r1,mapPositionX
	rqldi	r1,mapPositionY
	nop
	ld	r5		;map pos x
	ld	r6		;map pos y
	
	sub	r5,r2,r5	;r5 = absolute player position x
	sub	r6,r3,r6	;r6 = absolute player position y

	;get current enemy adr
	
	rqldi	r1,mapEnemysAdrLow
	rqldi	r1,mapEnemysAdrHigh
	addi	r0,1
	ld	r2
	ld	r3
	nop
	
	esadr	r3,r2		;
	erqldi	0		; enemy count
	erqld	r0		; offset
	eld	r4		;get enemy count
	eld	r0		;get enemy offset
	
	nop
	add	r2,r2,r0
	addtqi	r3,r3,0		;got to current enemy struct
	nop
	esadr	r3,r2
	
	;check player state (dont shoot at explosion/dead player)
	
	cmpeqi	r7,plStateOk
	brtc	calcEnemyPrePlayerIsDead
	nop		;delay slot
	nop		;delay slot	
	nop		;delay slot
	nop		;delay slot	
	
	erqldi	enPositionX			
	erqldi	enPositionY		

	eld	r2		;r2 = enemy pos x
	eld	r3		;r3 = enemy pos y
	
	;get delta
	
	sub	r0,r2,r5	;dx		;delay slot
	sub	r1,r3,r6	;dy		;delay slot
	
	;calculate direction
	
	dexti	>dxyToDirection
	movei	r4,dxyToDirection
	gpci	r7,0
	jmpi	r4,0
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	;r2 = direction (store this)
	
	dexti	3>enDirectionToPlayer
	est	r2,enDirectionToPlayer
	
	;calc distance to player
	
	dexti	>dxyToLength
	movei	r4,dxyToLength
	gpci	r7,0
	jmpi	r4,0
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	dexti	3>enDistanceToPlayer
	est	r2,enDistanceToPlayer

calcEnemyPreEnd
	
	;epilog
	
	rqpop
	rqpop
	rqpop
	poparqp	r7
	poparqp	r6
	poparqp	r5
	poparqp	r4
	poparqp	r3
	pop	r2
	pop	r1
	pop	r0
	
	jmpi	r7,0
	nop		;delay slot
	nop		;delay slot	
	nop		;delay slot
	nop		;delay slot	
	
	
calcEnemyPrePlayerIsDead

	br	calcEnemyPreEnd
	dexti	$20			;delay slot	
	movei	r2,$0			;delay slot	set wide distance 8192 (so out of enemy view)
	dexti	3>enDistanceToPlayer	;delay slot	
	est	r2,enDistanceToPlayer	;delay slot	
	
;******************************
;*
;* drawEnemys
;* 
;* r1 = map struct
;*	

drawEnemys

	;prolog

	push	r1
	push	r2
	push	r3
	push	r4
	push	r5
	push	r6
	push	r7
	
	;get enemy count
	
	;get enemy and set address struct to esadr
	
	rqldi	r1,mapEnemysAdrLow
	rqldi	r1,mapEnemysAdrHigh
	addi	r0,1
	ld	r2
	ld	r3
	nop
	
	esadr	r3,r2		;
	erqldi	0		; enemy count
	eld	r2
	movei	r0,0
	subi	r2,1
	
drawEnemysLoop

	gpci	r7,2
	br	drawEnemy
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot


	subi	r2,1
	brts	drawEnemysLoop
	addi	r0,1	;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		
	
;******************************
;*
;* calcEnemy
;* 
;* r0 = enemy number
;* r1 = map struct
;*	

calcEnemy

	;prolog

	push	r0
	push	r1
	push	r2
	push	r3
	push	r4
	push	r5
	push	r6
	push	r7	
	
	;get enemy and set address struct to esadr
	
	rqldi	r1,mapEnemysAdrLow
	rqldi	r1,mapEnemysAdrHigh
	addi	r0,1
	ld	r2
	ld	r3
	nop
	
	esadr	r3,r2		;
	erqldi	0		; enemy count
	erqld	r0		; offset
	eld	r4		;get enemy count
	eld	r0		;get enemy offset
	
	nop
	add	r2,r2,r0
	addtqi	r3,r3,0		;got to current enemy struct
	nop
	esadr	r3,r2
	or	r7,r3,r3	;store also to r7:r6
	or	r6,r2,r2	
	
	;test state
	
	erqldi	enState
	eld	r0		;state -- no lut used .....
	nop
	
	cmpeqi	r0,enStateMoving
	brts	calcEnemyStateOk
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
	cmpeqi	r0,enStateShoot
	brts	calcEnemyStateShoot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
	cmpeqi	r0,enStateExplode
	brts	calcEnemyEnd
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot	
	
	cmpeqi	r0,enStateDead
	brts	calcEnemyEnd
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
	;----------------------------------------------------- 
	
calcEnemyStateShoot	

	;in shoot mode
	
	erqldi	enDistanceToPlayer
	erqldi	enMinDistanceToPlayer
	eld	r2			;distance
	eld	r3			;min distance
	
	nop
	addi	r3,16			;release distance (offset)
	
	movei	r4,enStateMoving
	cmplo	r2,r3			;in enemy out view so next state is ok
	movets	r0,r0,r4
		
	dexti	3>enState		;  3 bit extension
	est	r0,enState		; store state
	
	;set direction (to player -> direction)
	
	erqldi	enDirectionToPlayer
	eld	r4
	dexti	3>enDirection
	est	r4,enDirection
	
	
	
	br	calcEnemyEnd
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
	;----------------------------------------------------- 
	
calcEnemyStateOk	;r0 = state

	;in walking mode 
	
	erqldi	enDistanceToPlayer
	erqldi	enMinDistanceToPlayer
	eld	r2			;distance
	eld	r3			;min distance
	
	movei	r4,enStateShoot
	cmplo	r2,r3			;in enemy view so next state is shoot
	movets	r0,r4,r0
	
	dexti	3>enState		;  3 bit extension
	est	r0,enState		; store state
	
	;normal walking
	
	erqldi	enCurrentWay		
	erqldi	enMaxWay		
	eld	r2		;current way
	eld	r3		;max ways
	
	movei	r4,0
	cmpeq	r2,r3			;current way == max ways
	dexti	3>enCurrentWay		;  3 bit extension
	estts	r4,enCurrentWay		; then current way = 0
	movets	r4,r4,r2
	
	nop
	or	r3,r4,r4
	nop
	muli	r3,enWayStructSize
	nop	
	addi	r3,enWaysStart
	nop	
	
	add	r6,r6,r3
	addtqi	r7,r7,0			;r7:r6 = ways[current way]
	
	
	
	erqldi	enPosInWay
	edrqldi	r7,r6,enWayLength	
	eld	r2			;pos in way
	eld	r3			;way length
		
	nop
	cmplo	r2,r3			;pos in way < length
	brts	calcEnemyInWay
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
calcEnemyNotInWay	


	addi	r4,1			;current way ++
	movei	r3,0			;pos in way = 0
	dexti	3>enCurrentWay
	est	r4,enCurrentWay
	dexti	3>enPosInWay
	est	r3,enPosInWay
		
	br		calcEnemyEnd
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	   
calcEnemyInWay
	
	;r2 = pos in way
	
	edrqldi	r7,r6,enWaySX
	edrqldi	r7,r6,enWayX
	
	eld	r0	;way.sx [8:8]
	eld	r1	;way.x
	
	muls	r0,r0,r2	;		sx * enPosInWay
	gmulhi	r3	; r3:r0 = SSSS SSSS SSSS SSSS : SSSS SSSS XXXX XXXX
	
	nop
	moveih	r3,0	; r3:r0 = 0000 0000 SSSS SSSS : XXXX XXXX SSSS SSSS 
	lsri	r0,8	; r3:r0 = 0000 0000 SSSS SSSS : XXXX XXXX SSSS SSSS 
	swp	r3,r3   ; r3:r0 = SSSS SSSS 0000 0000 : XXXX XXXX SSSS SSSS 
	nop
	or	r0,r0,r3 ; r0 = SSSS SSSS SSSS SSSS
	nop
	add	r1,r1,r0	;x + sx * enPosInWay
	nop
	
	dexti	3>enPositionX
	est	r1,enPositionX	;pos x <- 
	
	edrqldi	r7,r6,enWaySY
	edrqldi	r7,r6,enWayY
	
	eld	r0	;way.sy [8:8]
	eld	r1	;way.y
	
	muls	r0,r0,r2	;		sy * enPosInWay
	gmulhi	r3	; r3:r0 = SSSS SSSS SSSS SSSS : SSSS SSSS XXXX XXXX
	
	nop
	moveih	r3,0	; r3:r0 = 0000 0000 SSSS SSSS : XXXX XXXX SSSS SSSS 
	lsri	r0,8	; r3:r0 = 0000 0000 SSSS SSSS : XXXX XXXX SSSS SSSS 
	swp	r3,r3   ; r3:r0 = SSSS SSSS 0000 0000 : XXXX XXXX SSSS SSSS 
	nop
	or	r0,r0,r3 ; r0 = SSSS SSSS SSSS SSSS
	nop
	add	r1,r1,r0	;y + sy * enPosInWay
	nop
	
	dexti	3>enPositionY
	est	r1,enPositionY	;pos y <-
	
	edrqldi	r7,r6,enWayDirection
	eld	r1
	dexti	3>enDirection
	est	r1,enDirection
	
	erqldi	enEnemySpeed
	eld	r1
	nop
	add	r2,r2,r1
	dexti	3>enPosInWay
	est	r2,enPosInWay
	

            ; else
            ; {
                ; bobPos.X = w.x + (w.sx * w.enPosInWay);
                ; bobPos.Y = w.y + (w.sy * w.enPosInWay);
                ; m_direction =  w.direction;

                ; enPosInWay += speed;
            ; }
	
	;
	
calcEnemyEnd	
	
	;epilog
	
	rqpop
	rqpop
	rqpop
	poparqp	r7
	poparqp	r6
	poparqp	r5
	poparqp	r4
	poparqp	r3
	pop	r2
	pop	r1
	pop	r0
	
	jmpi	r7,0
	nop		;delay slot
	nop		;delay slot	
	nop		;delay slot
	nop		;delay slot	

;******************************
;*
;* drawEnemy
;* 
;* r0 = enemy number
;* r1 = map struct
;*	
	
drawEnemy

	;prolog

	push	r0
	push	r1
	push	r2
	push	r3
	push	r4
	push	r5
	push	r6
	push	r7	
	
	rqldi	r1,mapEnemysAdrLow
	rqldi	r1,mapEnemysAdrHigh
	addi	r0,1
	ld	r2
	ld	r3
	nop
	
	esadr	r3,r2		;
	erqldi	0		; enemy count
	erqld	r0		; offset
	eld	r4		;get enemy count
	eld	r0		;get enemy offset
	
	nop
	add	r2,r2,r0
	addtqi	r3,r3,0		;got to current enemy struct
	
	dexti	>enemyBobData
	movei	r6,enemyBobData
	
	esadr	r3,r2
		
	;r2-r7 free / esadr is en data	r6 = bobTemp
		
	;-- store position of enemy
		
	rqldi	r1,mapPositionX
	rqldi	r1,mapPositionY
	nop
	ld	r4		;map pos x
	ld	r5		;map pos y
	
	nop
	erqldi	enPositionX
	erqldi	enPositionY
	erqldi	enDirection
	eld	r1		;pos x
	eld	r2		;pos y
	eld	r3		;direction
	
	add	r1,r1,r4
	add	r2,r2,r5
		
	ssto	csDestX		;store x y
	stwo	r6,r1
	ssto	csDestY
	stwo	r6,r2
	
	;-- check state
	
	erqldi	enState
	eld	r2
	nop
	
	cmpeqi	r2,enStateDead		; if dead no draw
	brts	drawEnemyEnd
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	cmpeqi	r2,enStateMoving	; if moving
	brts	drawEnemyMoving
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	cmpeqi	r2,enStateShoot		; enemy shoot
	brts	drawEnemyShoot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	cmpeqi	r2,enStateExplode	; enemy explode
	brts	drawEnemyExplode
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	;something is wrong
	.execm	stop
	
	;---- explode anim
	
drawEnemyExplode

	;anim delay
	
	erqldi	enAnimDelayCounter
	eld	r5		;anim delay counter
	nop
	
	cmploi	r5,enAnimExplosionMaxDelay		
	brts	noChangeExplosionEnemyAnim
	addi	r5,1			;delay slot
	nop				;delay slot
	est	r5,enAnimDelayCounter	;delay slot
	nop				;delay slot

	movei	r5,0	
	nop
	est	r5,enAnimDelayCounter	;clear anim counter


	
	;test/increase  anim count
	
	erqldi	enMoveCounter
	nop
	eld	r5		;move counter
	
	nop
	addi	r5,1		;next anim
	movei	r7,0
	cmploi	r5,enExplosionAnimMax	;		move counter < max expl ?
	movets	r5,r5,r7		;move counter =				  move counter : 0
	
	brts	enemyExplosionAnimInProgress
	est	r5,enMoveCounter	;delay slot
	nop				;delay slot
	nop				;delay slot
	nop				;delay slot
	
	;explosion anim is over so go to state dead
	
	movei	r0,enStateDead
	dexti	3>enState	;3 bit extension
	est	r0,enState	; store state
	
	
	br	drawEnemyEnd
	nop				;delay slot
	nop				;delay slot
	nop				;delay slot
	nop				;delay slot
	
	
	;
enemyExplosionAnimInProgress	
noChangeExplosionEnemyAnim


	;get source data (from effects)
		
	dexti	>bulletSourceWidth
	movei	r2,bulletSourceWidth
	dexti	>>>globalBullets
	movei	r1,>>globalBullets
	dexti	>globalBullets
	movei	r0,globalBullets
	
	ssto	csSourceWidth
	stwo	r6,r2
	ssto	csSourceAdrHigh	
	stwo	r6,r1
	ssto	csSourceAdrLow
	stwo	r6,r0	
	
	;get correct source position
	
	erqldi	enMoveCounter
	nop
	eld	r5		;move counter
	
	dexti	>enemyExplosionGFXPositions
	movei	r0,enemyExplosionGFXPositions
	add	r5,r5,r5	;move counter * 2
	nop
	add	r0,r0,r5
	nop
	rqldi	r0,0	;x
	rqldi	r0,1	;y
	nop
	ld	r1
	ld	r2
	
	ssto	csSourceX		;store source x y
	stwo	r6,r1
	ssto	csSourceY
	stwo	r6,r2
	
	br	drawEnemyNow
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	;---- shoot anim
	
drawEnemyShoot	

	movei	r4,enAnimMaxDelay	;draw now
	movei	r5,0			;no move stand still
	est	r4,enAnimDelayCounter
	est	r5,enMoveCounter
	
	br	drawEnemyMoving
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot

	
	;---- moving anim
	
drawEnemyMoving
	
	;-- make direction and run animation
	
	erqldi	enDirection
	erqldi	enAnimDelayCounter
	eld	r3		;old direction
	eld	r5		;anim delay counter
		
	;test anim delay counter
	
	nop
	cmploi	r5,enAnimMaxDelay		
	brts	noDrawEnemyAnim
	addi	r5,1			;delay slot
	nop				;delay slot
	est	r5,enAnimDelayCounter	;delay slot
	nop				;delay slot
	
	movei	r5,0	
	nop
	est	r5,enAnimDelayCounter	;clear anim counter	
	
	;test anim max

	erqldi	enMoveCounter
	nop
	eld	r5		;move counter
	
	
	movei	r4,enMovingAnimMax
	addi	r5,1		;next anim
	nop
	and	r5,r5,r4	;0..3
	nop
	
	est	r5,enMoveCounter
	
	;
	
noDrawEnemyAnim	

	;get source data (from enemy n) and width
		
	dexti	>enemySourceWidth
	movei	r2,enemySourceWidth
	dexti	>>>globalEnemy1
	movei	r1,>>globalEnemy1
	dexti	>globalEnemy1
	movei	r0,globalEnemy1
	
	ssto	csSourceWidth
	stwo	r6,r2
	ssto	csSourceAdrHigh	
	stwo	r6,r1
	ssto	csSourceAdrLow
	stwo	r6,r0	
	
	
	;get correct source position
	
	erqldi	enMoveCounter
	muli	r3,8		;direction * 8
	nop
	eld	r2		;move counter
	
	dexti	>enemy1MoveGFXPosition
	movei	r1,enemy1MoveGFXPosition
	muli	r2,2		;move counter * 2
	add	r1,r1,r3	;get direction
	nop
	add	r1,r1,r2	;+move counter
	nop
	rqldi	r1,0		;request source x
	rqldi	r1,1		;request source y
	nop
	ld	r1
	ld	r2
	
	ssto	csSourceX		;store source x y
	stwo	r6,r1
	ssto	csSourceY
	stwo	r6,r2
	
	;explosion jump in here
	
drawEnemyNow
	
	;
	
	dexti	>drawFrame
	movei	r7,drawFrame
	nop
	rqldi	r7,0
	rqldi	r7,1
	nop
	ld	r1	;high
	ld	r2	;low
	nop
	;addi	r0,16
	;addtqi	r1,r1,0
	
	ssto	csDestAdrLow
	stwo	r6,r2
	ssto	csDestAdrHigh
	stwo	r6,r1
	
	dexti	>drawBob
	movei	r5,drawBob
	gpci	r7,2		;next 4 + X
	jmpi	r5,0		;br	copySolid16xN
	or	r0,r6,r6	;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot	

drawEnemyEnd	

	;epilog
	
	rqpop
	rqpop
	rqpop
	poparqp	r7
	poparqp	r6
	poparqp	r5
	poparqp	r4
	poparqp	r3
	pop	r2
	pop	r1
	pop	r0
	
	jmpi	r7,0
	nop		;delay slot
	nop		;delay slot	
	nop		;delay slot
	nop		;delay slot	
	
	
;******************************
;*
;* testEnemyShot
;* 
;* r0 = enemy number
;* r1 = map struct
;*	
	
testEnemyShot	

	;prolog

	push	r0
	push	r1
	push	r2
	push	r3
	push	r4
	push	r5
	push	r6
	push	r7	
	
	;get address from enemy
	
	rqldi	r1,mapEnemysAdrLow
	rqldi	r1,mapEnemysAdrHigh
	addi	r0,1
	ld	r2
	ld	r3
	nop
	
	esadr	r3,r2		;
	erqldi	0		; enemy count
	erqld	r0		; offset
	eld	r4		;get enemy count
	eld	r0		;get enemy offset
	
	nop
	add	r2,r2,r0
	addtqi	r3,r3,0		;got to current enemy struct
	nop
	esadr	r3,r2
	
	;get shot counter
	
	erqldi	enShotDelayCounter
	erqldi	enState
	erqldi	enBulletShotCounterMax
	eld	r3		;shot counter
	eld	r4		;state
	eld	r7		;shot counter max
	
	;shot counter test
	
	addi	r3,1			
	nop
	cmpeq	r3,r7
	brtc	testEnemyShotNoShot	;no shot 
	xorts	r3,r3			;clear r2 if shot count max reached
	dexti	3>enShotDelayCounter	;delay slot
	est	r3,enShotDelayCounter	;delay slot
	nop				;delay slot
	
	cmpeqi	r4,enStateShoot		;in shoot state?
	brtc	testEnemyShotNoShot
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot
	nop	;delay slot
		
	;calc shot
	
	erqldi	enPositionX
	erqldi	enPositionY
	erqldi	enDirection
	eld	r3	;px
	eld	r4	;py
	eld	r2	;direction
		
	;add/sub xy center (from direction)
	
	dexti	>enemyShootCenterToDirection
	movei	r7,enemyShootCenterToDirection
	nop
	add	r7,r7,r2
	nop
	add	r7,r7,r2
	nop
	rqldi	r7,0	;x center
	rqldi	r7,1	;y center
	nop
	ld	r5
	ld	r6
	
	add	r3,r3,r5
	add	r4,r4,r6
	
	
	;r1 = type,r2 = direction r3 = x, r4 = y
	
	erqldi	enBulletSpeed	
	erqldi	enBulletLifeTime
	eld	r6
	eld	r5
	
	dexti	>addBullet
	movei	r0,addBullet
	gpci	r7,2
	jmpi	r0,0
	nop				;delay slot
	nop				;delay slot
	movei	r1,buEnemy		;type		delay slot
	nop				;delay slot
	
	;epilog
	
testEnemyShotNoShot	
	
	rqpop
	rqpop
	rqpop
	poparqp	r7
	poparqp	r6
	poparqp	r5
	poparqp	r4
	poparqp	r3
	pop	r2
	pop	r1
	pop	r0
	
	jmpi	r7,0
	nop		;delay slot
	nop		;delay slot	
	nop		;delay slot
	nop		;delay slot	
	
;******************************
;*
;* getNearestEnemy
;*
;* r1 = map struct
;* r2 = x
;* r3 = y
;*
;* return
;*
;* r4 = nearest enemy
;* r5 = distance 
;*

getNearestEnemy

	;prolog

	push	r1
	push	r2
	push	r3
	push	r6
	push	r7
	
	;clear stats
	
	movei	r7,$ff
	dexti	>nearestEnemyStaticData
	movei	r4,nearestEnemyStaticData
	moveih	r7,$ff
	ssto	nearestEnemyMinLength
	stwo	r4,r7
	ssto	nearestEnemyNumber
	stwo	r4,r7

	;get enemy and set address struct to esadr
	
	rqldi	r1,mapEnemysAdrLow
	rqldi	r1,mapEnemysAdrHigh
	addi	r0,1
	ld	r5
	ld	r6
	nop
	
	esadr	r6,r5		;
	erqldi	0		
	eld	r4		;r4 = enemy count
	movei	r0,0		;r0 = enemy selector
	subi	r4,1
	
	
getNearestEnemyLoop

	push	r0
	push	r1
	push	r2
	push	r3
	push	r4

	push	r0	;repush selector!
	
        ;r0 = enemy selector
	
	;get address from enemy
	
	rqldi	r1,mapEnemysAdrLow
	rqldi	r1,mapEnemysAdrHigh
	addi	r0,1
	ld	r5
	ld	r6
	nop
	
	esadr	r6,r5		;
	erqldi	0		; enemy count
	erqld	r0		; offset
	eld	r4		;get enemy count
	eld	r0		;get enemy offset
	
	nop
	add	r5,r5,r0
	addtqi	r6,r6,0		;got to current enemy struct
	nop
	esadr	r6,r5		;address of enemy[enemy selector (r0)]
	
	erqldi	enState		
	erqldi	enPositionX			
	erqldi	enPositionY
	eld	r4		;enemy state
	eld	r5		;enemy x
	lsri	r4,enStateHeavenRShift	;if there is a bit after this shift then enemy is dead
	eld	r6		;enemy y
	

	cmpeqi	r4,0
	brtc	getNearestEnemyRIP
	rqpop				;delay slot
	sub	r0,r5,r2		;dx 	delay slot
	sub	r1,r6,r3		;dy	delay slot
	pop	r5			;delay slot		;--repop selector
	
	dexti	>dxyToLength
	movei	r4,dxyToLength
	gpci	r7,2
	jmpi	r4,0
	dexti	>nearestEnemyStaticData		;delay slot
	movei	r4,nearestEnemyStaticData	;delay slot				
	nop					;delay slot
	nop					;delay slot
	
	;r2 = length,r4 = data, r5 = current enemy
	
	rqldi	r4,nearestEnemyMinLength
	rqldi	r4,nearestEnemyNumber
	nop
	ld	r3	;min length
	ld	r6	;enemy number
	
	cmplo	r2,r3		;		length < min_length?
	movets	r3,r2,r3	;min_length   =				length : min_length
	movets	r6,r5,r6	;enemy number =                         current enemy : enemy number
	
	ssto	nearestEnemyMinLength
	stwo	r4,r3
	ssto	nearestEnemyNumber
	stwo	r4,r6
	
		
getNearestEnemyRIP	
	
	;
	
	rqpop	
	rqpop
	rqpop	
	pop	r4
	pop	r3
	pop	r2
	
	rqpop	
	rqpop
	nop	
	pop	r1
	pop	r0
	
	
	subi	r4,1
	brts	getNearestEnemyLoop
	addi	r0,1	;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
	;store result
	
	dexti	>nearestEnemyStaticData		
	movei	r4,nearestEnemyStaticData				
	nop					
	
	rqldi	r4,nearestEnemyMinLength
	rqldi	r4,nearestEnemyNumber
	nop
	ld	r5	;distance
	ld	r4	;r4 = nearest enemy
	
	rqpop
	rqpop
	rqpop	
	pop	r7
	pop	r6
	pop	r3
	
	rqpop
	rqpop
	jmpi	r7,0
	pop	r2	;delay slot
	pop	r1	;delay slot
	nop		;delay slot
	nop		;delay slot
	
	.def	nearestEnemyMinLength	0
	.def	nearestEnemyNumber	1
	
nearestEnemyStaticData	
	.data	0,0
	
;******************************
;*
;* killEnemy
;*
;* r0 = enemy number
;* r1 = map struct
;*
	
killEnemy	

	;prolog

	push	r0
	push	r1
	push	r2
	push	r3
	push	r4
			
	;get address from enemy
	
	rqldi	r1,mapEnemysAdrLow
	rqldi	r1,mapEnemysAdrHigh
	addi	r0,1
	ld	r2
	ld	r3
	nop
	
	esadr	r3,r2		;
	erqldi	0		; enemy count
	erqld	r0		; offset
	eld	r4		;get enemy count
	eld	r0		;get enemy offset
	
	nop
	add	r2,r2,r0
	addtqi	r3,r3,0			;got to current enemy struct
	movei	r0,enStateExplode	;explode the asshole 
	esadr	r3,r2
	
	;set explode state
	
	dexti	3>enState	;3 bit extension
	est	r0,enState	; store state
	
	;set anim delay counter (fast update)
	
	movei	r0,enAnimExplosionMaxDelay
	dexti	3>enAnimDelayCounter
	est	r0,enAnimDelayCounter
	
	;set move counter -1 (anim) (+1 = 0 first frame)
	
	dexti	$ff
	movei	r0,$ff
	dexti	3>enMoveCounter
	est	r0,enMoveCounter

	rqpop
	rqpop
	rqpop	
	pop	r4
	pop	r3
	pop	r2
	
	rqpop
	rqpop
	jmpi	r7,0
	pop	r1	;delay slot
	pop	r0	;delay slot
	nop		;delay slot
	nop		;delay slot
	
	
;******************************
;*
;* getLivingEnemyCount
;* 
;* r1 = map struct
;*	
;* return
;*
;* r0 = living enemys
;*

getLivingEnemyCount

	;prolog

	push	r1
	push	r2
	push	r3
	push	r4
	push	r5
	push	r6
	push	r7
	
	;get enemy count
	
	;get enemy and set address struct to esadr
	
	rqldi	r1,mapEnemysAdrLow
	rqldi	r1,mapEnemysAdrHigh
	nop
	ld	r2
	ld	r3
	nop
	
	esadr	r3,r2		;
	erqldi	0		; enemy count
	eld	r2
	movei	r0,0
	subi	r2,1
	
	movei	r7,0
	
getLivingEnemyCountLoop

	;r0 = enemy number
	;r1 = map struct
	;r2 = loop counter
	
	;get address from enemy
	
	rqldi	r1,mapEnemysAdrLow
	rqldi	r1,mapEnemysAdrHigh
	addqi	r4,r0,1
	ld	r5
	ld	r6
	nop
	
	esadr	r6,r5		;
	erqld	r4		; offset
	eld	r4		;get enemy offset
	
	nop
	add	r5,r5,r4
	addtqi	r6,r6,0			;got to current enemy struct
	
	;get state of enemy
	
	dexti	3>enState
	edrqldi	r6,r5,enState
	movei	r3,enStateEnemyActiveMax
	eld	r4
	nop
	
	cmples	r4,r3	;active
	addtqi	r7,r7,0
	

	subi	r2,1
	brts	getLivingEnemyCountLoop
	addi	r0,1	;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
	;
	
	or	r0,r7,r7
	
	;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	
	
;*********************************************************************
;* data
;*********************************************************************	

enemyExplosionGFXPositions

	.data	345,2		;0
	.data	378,2           ;1
	.data	411,2           ;2
	.data	444,2           ;3
	.data	477,2           ;4
	.data	510,2           ;5
	.data	543,2           ;6
	.data	576,2           ;7
	.data	609,2	        ;8	
	
enemyShootCenterToDirection	
	
	.data	17,-14		;N	0		y-		ok
	.data	28,-4		;NO	1	x+      y-		ok
	.data	32,12		;O	2	x+      		ok
	.data	25,25		;SO	3	x+      y+		ok
	.data	2,29		;S	4	        y+		ok
	.data	-13,17		;SW	5	x-      y+		ok
	.data	-19,2		;W	6	x-      		ok
	.data	-6,-10		;NW	7	x-      y-		ok	
	
enemy1MoveGFXPosition

	;	3	2	1	0				OURL
	.data	11,44,	44,44,	77,44,	110,44	;N	0	O	1000
	.data	141,44,	174,44,	207,44,	240,44	;NO	1	OR	1010
	.data	11,77,	44,77,	77,77,	110,77	;O	2	R	0010
	.data	141,77,	174,77,	207,77,	240,77	;SO	3	UR	0110
	.data	11,110,	44,110,	77,110,	110,110	;S	4	U	0100
	.data	145,110,178,110,211,110,244,110 ;SW	5	UL	0101
	.data	11,143,	44,143,	77,143,	110,143	;W	6	L	0001
	.data	145,143,178,143,211,143,244,143	;NW	7	OL	1001	
	