;======================================================================================================================
;
; cryAEngine - a small gameengine for the Amiga
; 
; CHLUDENS.ch project
;
; Some Code from  Massimo Bonnucchi
;======================================================================================================================

; 68k
; flags: CCR 
; MOVE #$00,CCR

; signed values
; https://stackoverflow.com/questions/13615568/ccr-on-the-68000
; unsigned values
; 
; scc
; https://stackoverflow.com/questions/25035030/understanding-the-scc-instructions-of-68000-assembly
;

;For unsigned arithmetic use the following branches:

;>   BHI
;<=  BLS
;>=  BCC/BHS
;<   BCS/BLO
;For signed arithmetic use the following branches:

;>=  BGE
;<   BLT
;>   BGT
;<=  BLE


; demoscene - blk - default value for 

	section	GameCode,CODE_P

;======================================================================================================================
; Startup File
; Makes sure we take control of the OS the proper way
;======================================================================================================================

	include	"lib/startup.s"

;======================================================================================================================
; Which DMAs we will enable
;
; 15	SET/CLR	Set/Clear control bit.
;				Determines if bits written with a 1 get set or cleared
;			    Bits written with a zero are unchanged
; 14	BBUSY	Blitter busy status bit (read only)
; 13	BZERO	Blitter logic zero status bit (read only)
; 12	X	
; 11	X	
; 10	BLTPRI	Blitter DMA priority (also called "blitter nasty" for stealing from CPU)
; 09	DMAEN	Enable all DMA below (also UHRES DMA)
; 08	BPLEN	Bit plane DMA enable
; 07	COPEN	Coprocessor DMA enable
; 06	BLTEN	Blitter DMA enable
; 05	SPREN	Sprite DMA enable
; 04	DSKEN	Disk DMA enable
; 03	AUD3EN	Audio channel 3 DMA enable
; 02	AUD2EN	Audio channel 2 DMA enable
; 01	AUD1EN	Audio channel 1 DMA enable
; 00	AUD0EN	Audio channel 0 DMA enable
;======================================================================================================================

								;5432109876543210
DMASET					equ		%1000001110101111	; Enable Copper, Bitplane DMA, Sprite DMA, Sound DMA

WaitDisk				equ		30		; Defined in Startup.s : Time to wait 50-150 to save/load (50 = 1 second in Pal system)

;======================================================================================================================
; Game Source Files + Data Files
;======================================================================================================================

; Game Constants
		include	"Source/HWConstants.s"
		include	"Source/Constants.s"

; Game Core Files
		include	"Source/Utils.s"
		include	"Source/Player.s"
		include	"Source/Enemies.s"
		include	"Source/GameOver.s"
		include	"Source/Intro.s"
		include	"Source/Hud.s"
		include	"Source/GameCore.s"
		include	"Lib/music.s"

; Game Data Files
		include	"Source/VarTables.s"
		include	"Source/Data.s"





;======================================================================================================================
; Main Program Start
;======================================================================================================================

START:
		;--------------------------------------------------------------------------------------------------------------
		; Saving everything for startup file
		;--------------------------------------------------------------------------------------------------------------

		movem.l	d0-d7/a0-a6,-(SP)

		bsr.w	WaitForRaster

		;--------------------------------------------------------------------------------------------------------------
		; The following is more setup to complete the startup file 
		;--------------------------------------------------------------------------------------------------------------

		; Custom Chips HW Base Address
		lea		$dff000,a5

		; DMA Set / Enable
		move.w	#DMASET,$96(a5)		; DMACON - Enable Bitplane, Copper DMA, Sprties

		; Disable AGA for compatibility
		move.w	#0,$1fc(a5)			; Disable AGA
		move.w	#$c00,$106(a5)		; Disable AGA
		move.w	#$11,$10c(a5)		; Disable AGA

		;--------------------------------------------------------------------------------------------------------------
		; Init Music
		;--------------------------------------------------------------------------------------------------------------

	

		move.l	#GameScreenBitplanes,d0		; Source Image Address that is the address of Bitplane 1
		lea		GameBitplanePointers,a0		; Bitplane Pointers in the Copper
		moveq.l	#NoOfBpls-1,d1				; Number of Bitplanes
		move.l	#BitplaneSize,d2			; Add the bitplane size to the source start Image Address
		bsr.w	SetBitPlanes				; Set the Bitplane Pointers

;		bsr.w	CheckForJoystickFire

;		bsr.w	mt_init

	
		;--------------------------------------------------------------------------------------------------------------
		; Init Main Game Screen
		; This only need to be initialised once
		;--------------------------------------------------------------------------------------------------------------

		bsr.w	InitBitPlanes
		bsr.w	InitColours

		;--------------------------------------------------------------------------------------------------------------
		; Init the Intro Screen
		;--------------------------------------------------------------------------------------------------------------


	.Intro:
		; Init the Intro Screen Bitplanes and Colours
		bsr.w	InitIntroScr  ; wird nachträglich gemacht!
;		bsr.w	SetIntroCol	

		;--------------------------------------------------------------------------------------------------------------
		; The following is more setup to complete the startup file 
		;--------------------------------------------------------------------------------------------------------------

		; Custom Chips HW Base Address
		lea		$dff000,a5

		; Init Copper
		move.l	#GenericScreen,$80(a5)	; Point to our copper
		move.w	d0,$88(a5)			; Init our copper

		;--------------------------------------------------------------------------------------------------------------
		; Play Music while we wait for the user to press the fire button
		; and also till the player releases the fire button
		;--------------------------------------------------------------------------------------------------------------

;		bsr.w	mt_music

	jmp ingame

		;--------------------------------------------------------------------------------------------------------------
		; TITLESCREEN
		;--------------------------------------------------------------------------------------------------------------

xxx:

		bsr.w	WaitForRaster


  	    BTST   #6,$BFE001      ; Test left mouse button
   		BNE.S   xxx

xxxx:
  	    BTST   #6,$BFE001      ; Test left mouse button
   		BEQ.S   xxxx


		;--------------------------------------------------------------------------------------------------------------
		; GAMELOOP
		;--------------------------------------------------------------------------------------------------------------
ingame:

		; copy new background

		move.l	#GameOverScreen,d0			; Source Image Address that is the address of Bitplane 1
		lea		GenericBPL,a0				; Bitplane Pointers in the Copper

		moveq.l	#NoOfBpls-1,d1				; Number of Bitplanes
		move.l	#BitplaneSize,d2			; Add the bitplane size to the source start Image Address
		bsr.w	SetBitPlanes


		; Init Copper
		; move.l	#CopperList,$80(a5)	; Point to our copper
		; move.w	d0,$88(a5)			; Init our copper

		; init sprites
		bsr.w	InitSprite ; player
;		bsr.w   InitGameVars
;		bsr.w	ResetEnemies

		; ------------------------------
		; SPRITE INIT VISUAL POINTERS
		; ------------------------------		
		move.l	#Spr0,d0
		lea		SpritePointer0,a1
		move.w	d0,6(a1)
		swap	d0
		move.w	d0,2(a1)

		move.l	#Spr1,d0
		lea		SpritePointer1,a1
		move.w	d0,6(a1)
		swap	d0
		move.w	d0,2(a1)

		move.l	#Spr2,d0
		lea		SpritePointer2,a1
		move.w	d0,6(a1)
		swap	d0
		move.w	d0,2(a1)

		move.l	#Spr3,d0
		lea		SpritePointer3,a1
		move.w	d0,6(a1)
		swap	d0
		move.w	d0,2(a1)

		move.l	#Spr4,d0
		lea		SpritePointer4,a1
		move.w	d0,6(a1)
		swap	d0
		move.w	d0,2(a1)

		move.l	#Spr5,d0
		lea		SpritePointer5,a1
		move.w	d0,6(a1)
		swap	d0
		move.w	d0,2(a1)

		move.l	#Spr6,d0
		lea		SpritePointer6,a1
		move.w	d0,6(a1)
		swap	d0
		move.w	d0,2(a1)

		move.l	#Spr7,d0
		lea		SpritePointer7,a1
		move.w	d0,6(a1)
		swap	d0
		move.w	d0,2(a1)

		
		; move.l	#GenericScreen,$80(a5)	; Point to our copper
		; move.w	d0,$88(a5)			; Init our copper
		bsr.w	WaitForRaster
		move.l	#CopperList,$80(a5)	; Point to our copper
		move.w	d0,$88(a5)			; Init our copper

		; ----------------------------
		; setup
		; ----------------------------
		; behavior
		lea.l gameobjects,a6
		move.l #8,d5
bvx:
		move.w #behavior_4dir_random,gameobject_behaviour(a6)

		add.l #16*2,a6
		dbra d5,bvx
		
		; avatar
		lea.l gameobjects,a6
		add.l #3*16*2,a6
		move.w #behavior_mouse_direct,gameobject_behaviour(a6)

		
		; ----------------------------
		; snippets
		; ----------------------------
		; bsr.w	RndB						; Get a Random Number in D0
		; and.l	#$00000007,d0				; We are only interested in the first 8 (0 - 7)

		; ----------------------------
		; ingameloop
		; ----------------------------
ingameloop:

		; wait for the raster ... 
		bsr.w	WaitForRaster

		; ---------------------------
		; VISUALS & ANIM
		; ---------------------------
		; copy bitplanes
		lea		Diaper,a2		; Source Address
		lea		Spr0_Data,a1		; DESTINATION Address
		bsr.w   copyVisualSpriteData
		lea		Diaper,a2		; Source Address
		lea		Spr1_Data,a1		; DESTINATION Address
		bsr.w   copyVisualSpriteData
		lea		Diaper,a2		; Source Address
		lea		Spr2_Data,a1		; DESTINATION Address
		bsr.w   copyVisualSpriteData
		lea		Diaper,a2		; Source Address
		lea		Spr3_Data,a1		; DESTINATION Address
		bsr.w   copyVisualSpriteData
		lea		Diaper,a2		; Source Address
		lea		Spr4_Data,a1		; DESTINATION Address
		bsr.w   copyVisualSpriteData
		lea		Diaper,a2		; Source Address
		lea		Spr5_Data,a1		; DESTINATION Address
		bsr.w   copyVisualSpriteData
		lea		Diaper,a2		; Source Address
		lea		Spr6_Data,a1		; DESTINATION Address
		bsr.w   copyVisualSpriteData
		lea		Diaper,a2		; Source Address
		lea		Spr7_Data,a1		; DESTINATION Address
		bsr.w   copyVisualSpriteData


		; ---------------------------
		; BEHAVIOUR GAMEOBJECTS
		; ---------------------------

		; ---------------------------
		; MOVE SOMETHING
		; ---------------------------
;		lea		Spr3,a1
;		move.w	d5,d0
;		move.w	#90,d0
;		move.w	#90,d1
;		move.w	#$10,d2
;		bsr.w	MoveSprite


		move.l #8,d6 ; gameobjects_no
		lea.l gameobjects,a6
behave:		
		clr d0

		; mouse direct
		move.w #0,CCR 
		cmp.w #behavior_mouse_direct,gameobject_behaviour(a6)
		bne.w notmousedirect

		move.w mousex_direct,gameobject_x(a6)
		move.w mousey_direct,gameobject_y(a6)

		jmp notbehav_4dir_random
notmousedirect:

		; jmp nosquarez
		; -----------------------
		; squarez behavior
		; -----------------------
		clr.l d0	
		move.w gameobject_behaviour(a6),d0
		move.w #0,CCR 
		cmp.w #behavior_4dir_random,d0
		bne.w  notbehav_4dir_random

		bsr.w	RndB						; Get a Random Number in D0
		and.l	#$0000000ff,d0				; We are only interested in the first 8 (0 - 7)
		move.w d0,gameobject_y(a6)
		move.w #120,gameobject_x(a6)

		bsr.w	RndB						; Get a Random Number in D0
		and.l	#$00000007,d0				; We are only interested in the first 8 (0 - 7)

		move.w #0,CCR 
		cmp.w #0,d0
		bne.w ntrandom_left
		move.w #behavior_right,gameobject_behaviour(a6)

			bsr.w	RndB						; Get a Random Number in D0
			and.l	#$0000000ff,d0				; We are only interested in the first 8 (0 - 7)
			move.w d0,gameobject_y(a6)
			move.w #0,gameobject_x(a6)

		jmp notbehav_4dir_random
ntrandom_left:	

		move.w #0,CCR 
		cmp.w #1,d0
		bne.w ntrandom_right
		move.w #behavior_left,gameobject_behaviour(a6)

			bsr.w	RndB						; Get a Random Number in D0
			and.l	#$0000000ff,d0				; We are only interested in the first 8 (0 - 7)
			move.w d0,gameobject_y(a6)
			move.w #320,gameobject_x(a6)

		jmp notbehav_4dir_random
ntrandom_right:		

		move.w #0,CCR 
		cmp.w #2,d0
		bne.w ntrandom_down
		move.w #behavior_down,gameobject_behaviour(a6)

			bsr.w	RndB						; Get a Random Number in D0
			and.l	#$0000000ff,d0				; We are only interested in the first 8 (0 - 7)
			move.w d0,gameobject_x(a6)
			move.w #0,gameobject_y(a6)

		jmp notbehav_4dir_random
ntrandom_down:	

		move.w #0,CCR 
		cmp.w #3,d0
		bne.w ntrandom_up
		move.w #behavior_up,gameobject_behaviour(a6)

			bsr.w	RndB						; Get a Random Number in D0
			and.l	#$0000000ff,d0				; We are only interested in the first 8 (0 - 7)
			move.w d0,gameobject_x(a6)
			move.w #200,gameobject_y(a6)

		jmp notbehav_4dir_random
ntrandom_up:	




notbehav_4dir_random:

		
		; -------------------
		; 4 directions
		; -------------------
		; move left		
		move.w gameobject_behaviour(a6),d0
		move.w #0,CCR 
		cmp.w #behavior_right,d0
		bne.w nobehavior_right		
		add.w  #1,gameobject_x(a6)
		move.w gameobject_x(a6),d0
		cmp.w #320,gameobject_x(a6)
		blt.w xhigherend
		move.w #behavior_4dir_random,gameobject_behaviour(a6)
xhigherend:
		jmp end_behavior
nobehavior_right:

;		jmp end_behavior

		; move right	
		clr.l d0	
		move.w gameobject_behaviour(a6),d0
		move.w #0,CCR 
		cmp.w #behavior_left,d0
		bne.w nobehavior_left
		
		sub.w  #1,gameobject_x(a6)
		move.w gameobject_x(a6),d0
		cmp.w #10,d0
		bgt.w xlowerend
;		move.w #319,gameobject_x(a6)
		move.w #behavior_4dir_random,gameobject_behaviour(a6)
xlowerend:
		jmp end_behavior
nobehavior_left:

		; move down		
		move.w gameobject_behaviour(a6),d0
		move.w #0,CCR 
		cmp.w #behavior_down,d0
		bne.w nobehavior_down		
		add.w  #1,gameobject_y(a6)
		move.w gameobject_y(a6),d0
		cmp.w #320,gameobject_y(a6)
		blt.w yhigherend
		move.w #behavior_4dir_random,gameobject_behaviour(a6)
yhigherend:
		jmp end_behavior
nobehavior_down:


		; move up	
		clr.l d0	
		move.w gameobject_behaviour(a6),d0
		move.w #0,CCR 
		cmp.w #behavior_up,d0
		bne.w nobehavior_up
		
		sub.w  #1,gameobject_y(a6)
		move.w gameobject_y(a6),d0
		cmp.w #10,d0
		bgt.w ylowerend
;		move.w #319,gameobject_x(a6)
		move.w #behavior_4dir_random,gameobject_behaviour(a6)
ylowerend:
		jmp end_behavior
nobehavior_up:

		
nosquarez:



end_behavior:

		add.l  #16*2,a6 ; gameobject_size
		dbra d6,behave

;	------------------------
;	/END BEHVAVIOUR
;	------------------------

; ---------------------------
;  COLLISION
; ---------------------------
	 jmp nocollision

		move.l #8,d7 ; gameobjects_no
		lea.l gameobjects,a7
collision:		
		
		clr d5
		; innerCollision
		move.l #8,d6 ; gameobjects_no
		lea.l gameobjects,a6
innerCollision:		
		clr d4
		clr d3

		; no collision against the same object
		move.w #0,ccr
		cmp.w d6,d7
		bne.w notthesame
		jmp thesame
notthesame:

		; box collider
		;   ______ 
		;  | a7  _|___
		;  |_____|a6 |
		;        |___|
		;

		clr.l d5
		clr.l d4
		clr.l d3
		move.w gameobject_y(a7),d5
		move.w gameobject_y(a6),d4
		move.w gameobject_height(a6),d3
		move.w #0,CCR
		add.w d3,d4
		cmp.w d5,d4
		bhi.w yhigher
		;bgt.w yhigher	
		;  a7.y > a6.y+a6.height

		clr.l d5
		clr.l d4
		clr.l d3
		move.w gameobject_y(a7),d5
		move.w gameobject_y(a6),d4
		move.w gameobject_height(a7),d3
		move.w #0,CCR
		sub.w d3,d4
		cmp.w d5,d4
		bcs.w ylower	
;		blt.w ylower
		;  a7.y < a6.y-a7.height

		clr.l d5
		clr.l d4
		clr.l d3
		move.w gameobject_y(a7),d5
		move.w gameobject_x(a6),d4
		move.w gameobject_width(a6),d3
		add.w d3,d4
		move.w #0,CCR
		cmp.w d5,d4
		bhi.w xhigher
		;  a7.x > a6.x+a6.width

		clr.l d5
		clr.l d4
		clr.l d3
		move.w gameobject_y(a7),d5
		move.w gameobject_x(a6),d4
		move.w gameobject_width(a7),d3
		sub.w d3,d4
		move.w #0,CCR
		cmp.w d5,d4
		bcs.w xlower
		;  a7.x < a6.x-a7.width

		; ------------------------

		; --- 
;		move.w #0,gameobject_state(a6)
;		move.w #0,gameobject_state(a7)

		; move.w #behavior_4dir_random,gameobject_behaviour(a6)
		; move.w #behavior_4dir_random,gameobject_behaviour(a7)

		; jmp collision_done
;		move.w #0,gameobject_behaviour(a6)
;		move.w #0,gameobject_behaviour(a7)

xlower:
xhigher:

ylower: 
yhigher:		

thesame:

		add.l  #16*2,a6 ; gameobject_size
		dbra d6,innerCollision
		; / innerCollision

		; collision
		add.l  #16*2,a7 ; gameobject_size
		dbra d7,collision

collision_done:

nocollision:

; ---------------------------
; / END COLLISION
; ---------------------------




		; ---------------------------
		; RENDER GAMEOBJECTS
		; ---------------------------
		; TO SPRITES (if there is a sprite representation)
		;
		; jmp abc

		move.l #8,d6 ; gameobjects_no
		lea.l gameobjects,a6
render:		
		lea		Spr0,a1

		; dump switch
		cmp #1,d6
		bne not1
		lea		Spr1,a1
not1:
		cmp #2,d6
		bne not2
		lea		Spr2,a1
not2:
		cmp #3,d6
		bne not3
		lea		Spr3,a1
not3:
		cmp #4,d6
		bne not4
		lea		Spr4,a1
not4:
		cmp #5,d6
		bne not5
		lea		Spr5,a1
not5:
		cmp #6,d6
		bne not6
		lea		Spr6,a1
not6:
		cmp #7,d6
		bne not7
		lea		Spr7,a1
not7:
		move.w  gameobject_y(a6),d0
		move.w  gameobject_x(a6),d1
		move.w	#$10,d2
		bsr.w	MoveSprite

		add.l  #16*2,a6 ; gameobject_size
		dbra d6,render

		; ---------------------------
		; MUSIC
		; ---------------------------
;		bsr.w	mt_music

		; --------------------------
		; behavior service
		; --------------------------
		; --------------------------
		; mouse control
		; --------------------------
		bsr.w	mouse         ; 	branch to 	subroutine mouse
		lea.l	mousex,a1     ; move mousex 	address into a1
		lea.l	mousey,a2     ; move mousey 	address into a2
		move.w	(a1),d1       ; move value at mousex 	address into d1
		move.w	(a2),d0       ; move value at mousey 	address into d2
		move.w  d0,mousey_direct
		move.w  d1,mousex_direct

		;	    cmp.w #300,d1
		;		bcs   bxb319
		;		move.w #300,d1
		;	bxb319:
		;	    cmp.w #200,d0
		;		bcs   byb200
		;		move.w #199,d0
		;	byb200:
		;		; update the gameobject here
		;		lea		gameobject0_y,a1
		;		move.w  d0,(a1)
		;		lea		gameobject0_x,a1
		;		move.w  d1,(a1)

		; exit
  	    btst   #6,$BFE001      ; Test left mouse button
   		beq.s  exit

		jmp ingameloop ; gameloop
		; ---------------------------
		; INGAME LOOP ^
		; ---------------------------


exit:	
;		bsr.w	mt_end

		movem.l	(SP)+,d0-d7/a0-a6

		rts

tryout:

		rts 

;======================================================================================================================
; Prints a Character to the screen
;======================================================================================================================

DrawText:
	MOVE.L	StrCodingPtr(PC),A0			; Text Address in a0
	MOVEQ	#0,D2					; Clear d2
	MOVE.B	(A0)+,D2				; Next Char d2
	CMP.B	#$ff,d2					; End of text? ($FF)
	beq.s	XText_Exit				; Yes - Exit
	TST.B	d2						; End of Line? ($00)
	bne.s	XNotEOL					; No Not End Of Line

	ADD.L	#20*7,XBitplanePtr		; Screen is 40 byte wide and the font is 8 bytes high
	ADDQ.L	#1,StrCodingPtr				; Hold the column on the on the screen or where we are on the current line
									; hence reset it to 1 since we are starting a new line
	move.b	(a0)+,d2				; First character on the line skipping 0

XNotEOL:
	SUB.B	#$20,D2					; Subtract 32 from the char ASCII value 
									; so that we can transform for example
									; if it was a space which is $20 to a $00
									; the asterics $21 to $01 etc etc
	LSL.W	#3,D2					; Multiply the same number by 8,
									; since the font is 8 pixels high
	MOVE.L	D2,A2					; move the multiplication result to A2
	ADD.L	#XFont,A2				; Add the value in A2 to the font Base address

	; Display char on bitplanes
	MOVE.L	XBitplanePtr(PC),A3		; Bitplane Address in a3
	MOVE.B	(A2)+,40*0(A3)			; Print Line 1 of char
	MOVE.B	(A2)+,40*1(A3)			; Print Line 2 of char
	MOVE.B	(A2)+,40*2(A3)			; Print Line 3 of char
	MOVE.B	(A2)+,40*3(A3)			; Print Line 4 of char
	MOVE.B	(A2)+,40*4(A3)			; Print Line 5 of char
	MOVE.B	(A2)+,40*5(A3)			; Print Line 6 of char
	MOVE.B	(A2)+,40*6(A3)			; Print Line 7 of char
	MOVE.B	(A2)+,40*7(A3)			; Print Line 8 of char

	ADDQ.L	#1,XBitplanePtr	 		; We need to move 8 bits or 1 byte for next character
	ADDQ.L	#1,StrCodingPtr				; Next character to print

XBitplanePtr:
	dc.l	GameScreenBitplanes

XText_Exit:
	RTS

StrCodingPtr:
	dc.l	StrCoding
StrCoding:
    dc.b    "LA1n PRODUCTION"
    dc.b    $ff

XFont:
	incbin	"gfx/nice.fnt"

mouse:                    ; 	subroutine (mousex, mousey) = mouse()
	movem.l	d0-d7/a0-a6,-(a7) ; save registers on stack
	move.w	$dff00a,d0        ; move value in JOY0DAT to d0
	andi.l	#255,d0           ; keep lower byte in d0 (mouse x counter) using immidiate AND
	moveq	#0,d2             ; move 0 into d2 (lower bound on x)
	move.l	#639,d3           ; move 639 into d3 (upper bound on x)
	lea.l	oldx,a1           ; move oldx 	address into a1
	lea.l	mousex,a2         ; move mousex 	address into a2
	bsr.s	calcmouse         ; 	branch to 	subroutine calcmouse
	move.w	$dff00a,d0        ; move value in JOY0DAT to d0
	lsr.w	#8,d0             ; shift left 8 bits
	andi.l	#255,d0           ; keep lower byte in d0 (mouse y counter) using immidiate AND 
	moveq	#0,d2             ; move 0 into d2 (lower bound on y)
	move.l	#511,d3           ; move 511 into d3 (upper bound on y)
	lea.l	oldy,a1           ; move 	address of oldy into a1
	lea.l	mousey,a2         ; move 	address of mousey into a2
	bsr.s	calcmouse         ; 	branch to 	subroutine calcmouse
	movem.l	(a7)+,d0-d7/a0-a6 ; load registers from stack
	rts                       ; return from 	subroutine

calcmouse:                ; 	subroutine calcmouse(a1=ol	dcountPtr,a2=newCoordinatePtr,d0=newCount,d2=lowerBound,d3=upperBound)
	moveq	#0,d1             ; move 0 into d1
	move.w	(a1),d1           ; move value from 	address in a1 (ol	dcount) to d1
	move.w	d0,(a1)           ; move d0 (newCount) into 	address pointed to by a1
	move.l	d0,d5             ; move d0 (newCount) into d5
	move.l	d1,d6             ; move d1 (ol	dcount) into d6
	sub.w	d0,d1             ; 	subtract word d0 (newCount) from d1 (ol	dcount) and store result in d1 (countDiff)
	cmp.w	#-128,d1          ; compare -128 with d1 (countDiff)
	blt.s	mc_less           ; if d1 < -128 goto mc_less
	cmp.w	#127,d1           ; compare 127 with d1 (countDiff)
	bgt.s	mc_more           ; if d1 > 127 goto mc_more
	cmp.w	#0,d1             ; compare 0 with d1 (countDiff)
	blt.s	mc_chk2           ; if d1 < 0 goto mc_chk2
mc_chk1:                  ; label
	cmp.w	d5,d6             ; compare d5 (newCount) with d6 (ol	dcount)
	bge.s	mc_chk1ok         ; if d6 > d5 goto mc_chk1ok
	neg.w	d1                ; 	negate d1 (countDiff)
mc_chk1ok:                ; label
	bra.s	mc_storem         ; 	branch always to mc_storem
mc_chk2:                  ; label
	cmp.w	d5,d6             ; compare d5 (newCount) with d6 (ol	dcount)
	ble.s	mc_chk2ok         ; d6 < d5 goto mc_chk2ok
	neg.w	d1                ; 	negate d1 (countDiff)
mc_chk2ok:                ; label
	bra.s	mc_storem         ; 	branch always to mc_storem
mc_less:                  ; label
	add.w	#256,d1           ; 	add 256 to d1 and store in d1 (countDiff)
	bra.s	mc_storem         ; 	branch always to mc_storem
mc_more:                  ; label
	sub.w	#256,d1           ; 	subtract 256 from d1 and store in d1 (countDiff)
mc_storem:                ; label
	neg.w	d1                ; 	negate d1 (countDiff)
	add.w	d1,(a2)           ; 	add d1 (countDiff) to the value pointed to by a2 (newCoordinatePtr)
	move.w	(a2),d0           ; move value from 	address in a2 (newCoordinatePtr) to d0
	cmp.w	d2,d0             ; compare d2 (lowerBound) with d0
	blt.s	mc_toosmall       ; if d0 < d2 goto mc_toosmall
	cmp.w	d3,d0             ; compare d3 (upperBound) with d0
	bgt.s	mc_toolarge       ; if d0 > d3 goto mc_toolarge
	rts                       ; return from 	subroutine
mc_toosmall:              ; label
	move.w	d2,(a2)           ; move value in d2 (lowerBound) to 	address pointed to by a2 (newCoordinatePtr)
	rts                       ; return from 	subroutine
mc_toolarge:              ; label
	move.w	d3,(a2)           ; move value in d3 (upperBound) to 	address pointed to by a2 (newCoordinatePtr)
	rts                       ; return from 	subroutine
oldx:       
	dc.l	$0000             ; allocate space for oldx (mouse x counter)
oldy:       
	dc.l	$0000             ; allocate soace for oldy (mouse y counter)
mousex:       
	dc.w	$0000             ; allocate space for mousex (mouse x coordinate)
mousey:       
	dc.w	$0000  	
mousex_direct:       
	dc.w	$0000             ; allocate space for mousex (mouse x coordinate)
mousey_direct:       
	dc.w	$0000  	


;======================================================================================================================
;  cryAengine
;======================================================================================================================
	even

gameobjects_no equ 3 ; //  

gameobject_size equ 16 * 2 ; long 

gameobject_state equ 0
gameobject_x equ 1*2 
gameobject_y equ 2*2 
gameobject_width equ 3*2
gameobject_height equ 4*2 
gameobject_colwidth equ 5*2
gameobject_colheight equ 6*2 
gameobject_type equ 7*2
gameobject_typesub equ 8*2 
gameobject_art equ 9*2   ; 
gameobject_animmin equ 10*2  ; -- represented in a sprite
gameobject_animmax equ 11*2  ; 
gameobject_animmind equ 12*2 ;
gameobject_arg equ 13*2 ;
gameobject_behaviour equ 14*2 ;
gameobject_spr equ 15*2  ; -- represented in a sprite

; behavior
behavior_standstill equ 0 ; stand still
behavior_mouse_direct equ 1 ; 
behavior_mouse_relative equ 2 ; 

; squarez behaviors
behavior_left equ 3 ; 
behavior_right equ 4 ; 
behavior_up equ 5 ; 
behavior_down equ 6 ; 
behavior_4dir_random equ 7 ; generates left>down and creates 



; gameobjects
gameobjects:

gameobject0:
	dc.w 1    ; state
	gameobject0_x:
	dc.w 50   ; x
	gameobject0_y:
	dc.w 50   ; y
	dc.w 16   ; width
	dc.w 16   ; height
	dc.w 16   ; col width
	dc.w 16   ; col height
	dc.w 0   ; type
	dc.w 0   ; typesub
	dc.w 0   ; art
	dc.w 0   ; animmin
	dc.w 0   ; animmax
	dc.w 0   ; animind
	dc.w 0   ; arg
	dc.w 0   ; behavior
	dc.w 0   ; spr

gameobject1:
	dc.w 1    ; state
	dc.w 70   ; x
	dc.w 70   ; y
	dc.w 16   ; width
	dc.w 16   ; height
	dc.w 16   ; col width
	dc.w 16   ; col height
	dc.w 0   ; type
	dc.w 0   ; typesub
	dc.w 0   ; art
	dc.w 0   ; animmin
	dc.w 0   ; animmax
	dc.w 0   ; animind
	dc.w 0   ; arg
	dc.w 0   ; behavior
	dc.w 1   ; spr

gameobject2:
	dc.w 1    ; state
	dc.w 90   ; x
	dc.w 90   ; y
	dc.w 16   ; width
	dc.w 16   ; height
	dc.w 16   ; col width
	dc.w 16   ; col height
	dc.w 0   ; type
	dc.w 0   ; typesub
	dc.w 0   ; art
	dc.w 0   ; animmin
	dc.w 0   ; animmax
	dc.w 0   ; animind
	dc.w 0   ; arg
	dc.w 0   ; behavior
	dc.w 2   ; spr

gameobject3:
	dc.w 1    ; state
	dc.w 110   ; x
	dc.w 110   ; y
	dc.w 16   ; width
	dc.w 16   ; height
	dc.w 16   ; col width
	dc.w 16   ; col height
	dc.w 0   ; type
	dc.w 0   ; typesub
	dc.w 0   ; art
	dc.w 0   ; animmin
	dc.w 0   ; animmax
	dc.w 0   ; animind
	dc.w 0   ; arg
	dc.w 0   ; behavior
	dc.w 3   ; spr

gameobject4:
	dc.w 1    ; state
	dc.w 130   ; x
	dc.w 130   ; y
	dc.w 16   ; width
	dc.w 16   ; height
	dc.w 16   ; col width
	dc.w 16   ; col height
	dc.w 0   ; type
	dc.w 0   ; typesub
	dc.w 0   ; art
	dc.w 0   ; animmin
	dc.w 0   ; animmax
	dc.w 0   ; animind
	dc.w 0   ; arg
	dc.w 0   ; behavior
	dc.w 4   ; spr

gameobject5:
	dc.w 1    ; state
	dc.w 150   ; x
	dc.w 150   ; y
	dc.w 16   ; width
	dc.w 16   ; height
	dc.w 16   ; col width
	dc.w 16   ; col height
	dc.w 0   ; type
	dc.w 0   ; typesub
	dc.w 0   ; art
	dc.w 0   ; animmin
	dc.w 0   ; animmax
	dc.w 0   ; animind
	dc.w 0   ; arg
	dc.w 0   ; behavior
	dc.w 5   ; spr

gameobject6:
	dc.w 1    ; state
	dc.w 170   ; x
	dc.w 170   ; y
	dc.w 16   ; width
	dc.w 16   ; height
	dc.w 16   ; col width
	dc.w 16   ; col height
	dc.w 0   ; type
	dc.w 0   ; typesub
	dc.w 0   ; art
	dc.w 0   ; animmin
	dc.w 0   ; animmax
	dc.w 0   ; animind
	dc.w 0   ; arg
	dc.w 0   ; behavior
	dc.w 6   ; spr

gameobject7:
	dc.w 1    ; state
	dc.w 190   ; x
	dc.w 190   ; y
	dc.w 16   ; width
	dc.w 16   ; height
	dc.w 16   ; col width
	dc.w 16   ; col height
	dc.w 0   ; type
	dc.w 0   ; typesub
	dc.w 0   ; art
	dc.w 0   ; animmin
	dc.w 0   ; animmax
	dc.w 0   ; animind
	dc.w 0   ; arg
	dc.w 0   ; behavior
	dc.w 7   ; spr

gameobject8:
	dc.w 1    ; state
	dc.w 210   ; x
	dc.w 210   ; y
	dc.w 16   ; width
	dc.w 16   ; height
	dc.w 16   ; col width
	dc.w 16   ; col height
	dc.w 0   ; type
	dc.w 0   ; typesub
	dc.w 0   ; art
	dc.w 0   ; animmin
	dc.w 0   ; animmax
	dc.w 0   ; animind
	dc.w 0   ; arg
	dc.w 0   ; behavior
	dc.w 0   ; spr
	dcb.w	20*16*4,0

;======================================================================================================================
;  cryAengine: visual data 
;======================================================================================================================

		lea		Diaper,a2		; Source Address
		lea		Spr0_Data,a1		; DESTINATION Address
		; bsr.w   copyVisualSpriteData

	; image data
	; sprx_data

copyVisualSpriteData:
		add.l   #2,a1
		moveq.l	#16-1,d2					; Sprite Image Data Lenght in Long Words
	XCopyImgSprDatax:
		move.l	(a2)+,(a1)+					; Copy from Source to destination in Long Words
		dbra	d2,XCopyImgSprDatax			; Loop Till we Copy
	rts


;======================================================================================================================
;  Chip Data Section
;======================================================================================================================

		include	"Source/C_SpriteStructs.s"
		include	"Source/C_Copper.s"
		include	"Source/C_Data.s"





ChkMouse:			;gives border-checked x & y in D0/D1 & [X]/[Y]
	move.w $a-2(a6),d3		;new state
	lea OldMs(PC),a0
	move.w (a0),d2
	move.w d3,(a0)+
	sub.b d2,d3			;X diff
	move.b d3,d0
	ext.w d0
	add.w (a0),d0
	bmi.s .L
	moveq #0,d0
.L:	cmp.w #Wid,d0
	blt.s .R
	move.w #Wid-1,d0
.R:	move.w d0,(a0)+
	lsr.w #8,d2
	lsr.w #8,d3
	sub.b d2,d3			;Y diff
	move.b d3,d1
	ext.w d1
	add.w (a0),d1
	bmi.s .U
	moveq #0,d1
.U:	cmp.w #Hgt,d1
	blt.s .D
	move.w #Hgt-1,d1
.D:	move.w d1,(a0)+
	RTS


ChkKey:		;read ext. ASCII key code-->d0.0=no key!auto-fixes shift etc.
	moveq #0,d0
	lea Key(PC),a1
	btst #3,$1f-2(a6)
	beq.s .End
	lea $bfed01,a0
	btst #3,(a0)
	beq.s .End			;key pressed down?
	clr.b (a0)			;nec?
	moveq #0,d1
	move.b -$100(a0),d1		;read key
	move.b #$50,$100(a0)		;output+force load (start handshake)
	lea 6-2(a6),a2			;<-for spd/Size only
	move.b (a2),d2			;wait for 75 microsecs=60 or so cycles
	not.b d1
	lsr.b #1,d1
	bcc.s .Pres
	moveq #-1,d0			;neg=released!
.Pres:	move.w Shift(PC),d3
	bpl.s .Shift
	move.w Caps(PC),d3
	bmi.s .NoSh
.Shift:	add.w #KeyTblS-KeyTbl,d1
.NoSh:	move.b KeyTbl-Key(a1,d1.w),d0	;fetch ASCII equivalent
	moveq #0,d1
	move.b d0,d1
	bpl.s .WLup1			;special key is neg!
	addq.b #5,d1			;less than -5?
	bmi.s .WLup1			;then no special key
	add.w d1,d1
	move.w d0,2(a1,d1.w)		;put state in corr. key-slot (-=OFF!)
.WLup1:	cmp.b (a2),d2			;QikFix:wait AT LEAST 1 scanline
	beq.s .WLup1
	move.b (a2),d2			;make this into an int later!
.WLup2:	cmp.b (a2),d2
	beq.s .WLup2

	move.b #$10,$100(a0)		;input+force load (handshake done)
	move.w #8,$9c-2(a6)		;clear lev2-intreq
.End:	move.w d0,(a1)
	RTS				;d0/[key]=Ascii key
Key:	dc.w 0
Caps:	dc.w -1
Amiga:	dc.w -1				;special keys state
Alt:	dc.w -1				;-=OFF(!)
Shift:	dc.w -1
Ctrl:	dc.w -1				;DONT SEP ^5!
KeyTbl:					;clr unused keybytes for final opti.
dc.b "`1234567890-=\",0,"0"
dc.b "qwertyuiop[]",0,"123"
dc.b "asdfghjkl;'",0,0,"456"
dc.b 0,"zxcvbnm,./",0,".789"
dc.b " ",8,9,13,13,27,127,0,0,0,"-",0,31,30,29,28	;28-31=cursor keys
dc.b -7,-8,-9,-10,-11,-12,-13,-14,-15,-16,"()/*+",-6	;F-keys,Help
dc.b -2,-2,-5,-1,-3,-3,-4,-4				;Shift,Ctrl,Alt,<A>
dc.b 128,129,130,131,132,133,134,135
dc.b 136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151
KeyTblS:				;SHIFTED
dc.b "~!@#$%^&*()_+|",0,"0"
dc.b "QWERTYUIOP{}",0,"123"
dc.b "ASDFGHJKL:",34,0,0,"456"
dc.b 0,"ZXCVBNM<>?",0,".789"
dc.b " ",8,9,13,13,27,127,0,0,0,"-",0,31,30,29,28	;28-31=cursor keys
dc.b -7,-8,-9,-10,-11,-12,-13,-14,-15,-16,"()/*+",-6	;F-keys,Help
dc.b -2,-2,-5,-1,-3,-3,-4,-4				;Shift,Ctrl,Alt,<A>
dc.b 128,129,130,131,132,133,134,135
dc.b 136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151	


 


