
; nicht überschiessbar
; querschläger ...
; raufzählen = am leben erhalten 
; an - ab
; mousepointer explodiert ... 
; klicken unten - zerstören der minen
; abwechselnd beschuss auf die protection ...
; movable target - protect a train or something !!! 2002
; protect vs shooting different
; movable protectings - one?
; roboter oder so ... 
; minen in der nähe etc.
; tamagotchi und bahn frei machen
; ziel klar nach 'hause' bringen
; vgl. filme etc.
; auf ihn schiessen bringt ihn irgendwohin
; etwas wirft wieder panzer ab ... raumschiff - evtl. unabschiessbar ! 
; bad things to protect 
; on/off ... tiles ... 
; seitenschuss anlage ... einfacher mechanismus
; you are not allowed to play this game, if you are against the liberalest thing at all: erbschaftssteuer
; OK - RESET COMPUTER
; böse crabbler 
;

; adventure - sprayen auf die wand ...
;
;
;

;======================================================================================================================
;                         _____                        .__               
;    ___________ ___.__. /  _  \   ____   ____    ____ |__| ____   ____  
;  _/ ___\_  __ <   |  |/  /_\  \_/ __ \ /    \  / ___\|  |/    \_/ __ \ 
;  \  \___|  | \/\___  /    |    \  ___/|   |  \/ /_/  >  |   |  \  ___/ 
;   \___  >__|   / ____\____|__  /\___  >___|  /\___  /|__|___|  /\___  >
;       \/       \/            \/     \/     \//_____/         \/     \/
;
; cryAmigaGameEngine - a small (assembler) gameengine for the amiga 
; 
; you need only 68000er assembler knowhow for this gameengine
; no amiga custom chips knowledge needed :-)
;
;  Version 0.77b
;
; GameObjects, LevelPlayfields, Structure with Title,Menu,About and Ingame 
; 
; part of the CHLUDENS.ch project by gamelab.zhdk.ch
; code by rene.bauer AT zhdk.ch
;
; including atan2 and sincos from dansalvato https://gist.github.com/dansalvato
;
; Some Code from  Massimo Bonnucchi
;======================================================================================================================

;======================================================================================================================
; made with and for VisualStudioCode and Amiga-Assembly-Modul 
;======================================================================================================================

;======================================================================================================================
; FS-UAE (Emulator):
;
; (FS-LUAE: Ctrl+w > fast forward)
; Ctrl+return > fullscrren
; Ctrl+A > several times > real fullscreen
; Command: pause/resum
;
;======================================================================================================================


;======================================================================================================================
; Features:
;
; Frame with
; - Titlescreen
; - Menuscreen
; - About etc.
; All editable in a BlockLevelEditor (Processing)
;
; Blocks (Raster):
; - LevelField 16x16 Blocks = 20X16 Blocks
; - drawLevel
; - setBlock
; - getBlock (xy) > block16x etc
; - BlockLevelEditor in Processing (Export to your System)
;   Exports .json & .asm (direct integretable)
;
;  - setdrawLevelBlockDoubleBuffering
;
; SmallBlocks (Only Rendering):
; drawSmallBlock
; 
; Text (Raster):
; - Integrated Font (16x16 & 8x8)
; - drawBlockText
; - drawText
;
; Sprites
; - Support for Amiga Hardware sprites
; - Spriteeditor in Processing
;
; Bobs (16x16 - 16C-4Planes)
; - Support
; - Editor for Bobs in Processing
;
;======================================================================================================================

;======================================================================================================================
; ScreenSize
; LevelSize
; ------------------
;
;    border      screen                               border
;    [0-32px]  [ 32-352px                         ] [ 352-384px ]
;              [                                  ]
;              [  level                           ]
;              [  [20x * 16y]                     ]
;              [  [levelWidth*levelHeight ]       ]
;              [                                  ]
;              [                                  ]
;              [                                  ]
;              [                                  ]
;              [                                  ]
;              [                                  ]
;
;======================================================================================================================


;======================================================================================================================
; DoubleBuffering
; ------------------
;
;         [BACKOFFICESCREEN]
;
;                  0|1
;
;     [INTROSCREEN] OR [GAMESCREEN]
;
;======================================================================================================================

;======================================================================================================================
;  HISTORY
;  20240910 init/update for levelblocks > too slow (jsr + rts)
;======================================================================================================================

; ATTENTION:
; INCBIN ONLY IN C_DATA.s	

; Blitter: memory-schleuder (blocks)
;          you can move areas ... in all x/y 
;          only bobs are a problem ... with roll right/left
;          ; https://codetapper.com/amiga/diary-of-a-game/menace/part-5-aliens-2/
;          tool:
;          ; http://deadliners.net/BLTCONCheatSheet/index.html
;

; ---------------------
; TITLE-SCREEN
; ---------------------
; Image-Data
; C_DATA.s
; - exported by https://www.stef.be/dpaint/ > Save as > planes
; colors:
; colors.S (automatic)
; - exported by https://www.stef.be/dpaint/ > Save as > planes > .palette.xt
; > colorsTitle.s update manual!!! 


; ---------------------
; BLOCKS
; ---------------------
; use Processing-Tool

; ---------------------
; SPRITE
; ---------------------
; use Processing-Tool

; ---------------------
; CODING
; ---------------------
; ATTENTION: DONT USE D7,D6,A7,A& 
; IS SOMEHOW NEEDED BY MUSIC AND MOUSE

; ------------------------------
; 68000 KNOWHOW
; ------------------------------

; 68k online ausprobieren
; https://asm-editor.specy.app/projects/GuILvBB

; CLR.[B/W/L]
; ADD.[B/W/L]
; SUB.[B/W/L]
; MOVE.[B/W/L]
; SWAP.[B/W/L]

; WITHOUT .B/W/L > WORD
; MOVE #4,d0 MEANS MOVE.W #4,d0!!!

; MULTIPLY:
; ROL ETC 
; DIV[U|S] / (int)   W1: RESULT  W2: REST %
; MUL[U|S] * (int)
;
; Data-Register: d0-d7
; Adress-Register: a0-a7
; 
; CMP.[B/W/L]
; BNE/BEQ etc.
;
; UNSIGMED
; BHI.w >
; BCS.w <
;
; SIGNED
; BGT.w >
; BLT.w <
;

;         even
; label:  must be even for 68k!

; DBRA: FOR-NEXT
;    move.l #10
; lab:
;    dbra d0,lab


;
; COPPER - graphic processor binded to crt-raster
;
; If you install a copper list, this will be executed forever! 
; but you can put labels and write direct there !
;
; commands WAIT,MOVE,SKIP
;  
;
; water ... 
;		; data, command
;		; will be always executed
;		DC.W    $9601,$FF00 	; wait for line 150
;		dc.w	$0180,$0fff   ; set color

; ---------------------------------
; GAMEENGINE PRESETS
; ---------------------------------

; debug - no go to black
ModeBlack equ 1 ; debug set to 0


copperListColoerOn equ 0

; shows red to next vsync
debugSpeed equ 0

; more VSYNCS
debugSlowDownGame equ 0

; debug gameobjects
debugGameObjects equ 0

; show 0/1/2
debugDoubleBuffering equ 0 

debugCollision equ 0


; music
musicMode equ 0 ; music on 1 off 0

; menu active in menu?
MouseMenuActive equ 0

; screenfactor
screenFactorWidth = 1
screenFactorHeight = 2

; default level size ...
levelWidth = 20*screenFactorWidth
levelHeight = 16*screenFactorHeight ;  can be changed for scrolling etc.. 
; > scrollY (now 0 )

; if you wanna use scrolling in y direction use levelHeight = 32 etc ... 
; and of course load some content 

; menu
blockMenuPointInactive = 0
blockMenuPointActive = 49


; ingame
maxGameObjects = 20

gui_score_x equ 16
gui_hscore_x equ 5


; grenade game
avatar_y equ 235

; ---------------------------------
; GAMEENGINE DOUBLE BUFFERING
; ---------------------------------

; simple version without bobs: experiment
;
; double-buffering-version:
; idea: change playfield > update playfield-change-map or two! 
;       repaint then before next
;       perhaps a version behind always up to date - render to frontend   
;       1 change     playfield
;       2 change bob remove again           
;

	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

		IF musicMode
			bsr.w	mt_init
		ENDIF

		; ----------------------
		; BLITTER ENABLING
		; ----------------------
		move.w #$8040,$dff096 ; enable blitter
		; move.w #$87e0,$dff096
		
		;--------------------------------------------------------------------------------------------------------------
		; Init Main Game Screen
		; This only need to be initialised once
		;--------------------------------------------------------------------------------------------------------------

		; bsr.w	InitBitPlanes
		; bsr.w	InitColours

	

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

		; 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 Intro Copper
		;--------------------------------------------------------------------------------------------------------------
;		move.l	#GenericScreen,$80(a5)	; Point to our copper
;		move.w	d0,$88(a5)			; Init our copper

		;--------------------------------------------------------------------------------------------------------------
		; Colors
		;--------------------------------------------------------------------------------------------------------------
		; jsr colorsToGameColorsIntroScreen

		;--------------------------------------------------------------------------------------------------------------
		; Playfield example ...  320x200
		;--------------------------------------------------------------------------------------------------------------

; BitplaneSizeWide =(320/8)*256	; 256!			; Size of 1 Bitplanes

; SIMPLE PLAYFIELD
;BitplaneSizeSimple =((320+2*32)/8)*256	; 256!			; Size of 1 Bitplanes
;
;	    move.l	#IntroScreen,d0		; Source Image Address that is the address of Bitplane 1
;		; add.l   #8*40,d0  ; border
;		lea		GameBitplanePointers,a0		; Bitplane Pointers in the Copper
;		lea		$dff000,a5
;		moveq.l	#NoOfBpls-1,d1				; Number of Bitplanes
;		move.l	#BitplaneSizeSimple,d2			; Add the bitplane size to the source start Image Address
;		bsr.w	SetBitPlanes 
;ht:
;		jsr rainbow
;		jmp ht

  	    ;--------------------------------------------------------------------------------------------------------------
		; Init SPRITES
		;--------------------------------------------------------------------------------------------------------------

		; setSpritesUp 
		jsr setupSprites


		;--------------------------------------------------------------------------------------------------------------
		; ENABLE COPPER
		;--------------------------------------------------------------------------------------------------------------
		lea		$dff000,a5
		move.l	#CopperList,$80(a5)	; Point to our copper
		move.w	d0,$88(a5)			; Init our copper

		; jsr colorsToGameColors

		;--------------------------------------------------------------------------------------------------------------
		; setup borders & co
		;--------------------------------------------------------------------------------------------------------------
		; https://www.amigarealm.com/computing/knowledge/hardref/ch3.htm#:~:text=The%20register%20DIWSTRT%20(for%20%22Display,DIWSTRT%20for%20a%20basic%20playfield.
		; display area
		; 
		; []
		; low-resolution:
		; playfield 320x200 

		; 32 x 32
border_offset = 32 ; border around ...
; border_offset_blt1 = border_offset/4
border_offset_byte = border_offset/8
border_offset_word = border_offset/16 ; tiles

; 
address_screen_addframe =  border_offset_byte;  + 8*(320/8);  +  +border_offset_byte*(320+2*border_offset)/8 

		move.w #border_offset_byte*2,screenoffset_x_borderleft ; odd  ; border_offset_byte
		move.w #border_offset_byte*2,screenoffset_x_borderright ; even

		; drawLevel
;		move.l #0,actualLevelIndex      ; draw where? 
;		jsr loadActualLevel 
		; todo: blendin/out
		; level to gameobjects (if needed)
		; jsr parseLevel 
;		move.l #GameScreenBitplanes,blockscreen
;		jsr drawLevel

;		move.l #GameScreenBitplanes,bob1616_screen
;		move.w #5,bob1616_id
;		move.w #320+16+8,bob1616_x
;		move.w #0,bob1616_y
;		jsr renderBob1616

;		move.l #GameScreenBitplanes,blockscreen
;		move.w #10+2,blockx
;		move.w #8,blocky
;		move.w #1,blockno
;		jsr renderBlockRasterBlitter

;		move.l #GameScreenBitplanes,blockscreen
;		move.w #2,bob1616raster_id
;		move.w #2,bob1616raster_x
;		move.w #0,bob1616raster_y
;		jsr renderBob1616ToRaster

		; let's copy introscreen image data to gamescreen ...
;		move.l #IntroScreen,a5
;		move.l #GameScreenBitplanes,a4
;		add.l  #4,a4
;		jsr copyImageDataToScreenDirect

		; update camera
;		move.w #23,scrollX
;		move.w #50,scrollY
;		jsr updateCameraAndScrolling

;htx:
;		jsr vsync
		
		;jsr rainbow

		; add.w #1,scrollY
		; jsr updateCameraAndScrolling
; 		jmp htx

		;--------------------------------------------------------------------------------------------------------------
		; SET UP CAMERA
		;--------------------------------------------------------------------------------------------------------------

		move.w #0,scrollX
		move.w #0,scrollY
		jsr updateCameraAndScrolling

		;--------------------------------------------------------------------------------------------------------------
		; TITLE SCREEN
		;--------------------------------------------------------------------------------------------------------------
	; jmp menustart

		; copy screen
		move.l #IntroScreen,a5
		move.l #GameScreenBitplanes,a4
		add.l  #4,a4
		jsr copyImageDataToScreenDirect

		; colors
		jsr colorsToGameColorsIntroScreen
	
		; ------------------
		; scrolling text
		; ------------------

		move.l #0,text_title_counter
		lea.l text_title_screen,a4
		move.l a4,text_title_address


; ------------------
titleloop:
; ------------------

		bsr.w	WaitForRaster
		IF musicMode
			bsr.w	mt_music
		ENDIF

		; display a bob (blitterobject)
		jsr BlitWait

		; ------------------
		; blinking-scroll-text
		; ------------------
		add.l #1,text_title_counter
		cmp.l #100,text_title_counter
		bne   title_text
			move.l #0,text_title_counter
			; find next 0 
			move.l text_title_address,a4
			move.w #6+2,text_x
			move.w #30,text_y
			; move.w #1,smallblockscreentarget
			jsr drawText

			move.w #0,smallblockscreentarget
			add.l #text_title_size,text_title_address
			clr.l d0
			move.b (a4),d0
			cmp.b #42,d0
			bne.b   allis42
			lea.l  text_title_screen,a4
			move.l a4,text_title_address
allis42:		
title_text:		


		; mouse click?
  	    BTST   #6,$BFE001      
   		BNE   titleloop

		; waiting for next 
		jsr WaitForMouseUp
;		jsr colorsTitleToBlack
;		jsr colorsToBlack

;--------------------------------------------------------------------------------------------------------------
; MENU ... TITLE
;--------------------------------------------------------------------------------------------------------------
		; Menu/Colors
		jsr colorsToGameColors




; ------------------------
menustart:
; ------------------------

		; setupSpritesMouseMode
		; jsr  setupSpritesMouseMode

		; -----------------------------------------------
		; MENU & SUBMENU
		; -----------------------------------------------
		move.l #0,actualLevelIndex
;		jsr loadActualLevel 
		; todo: blendin/out
		; todo: use backoffice ... 
;		move.l #GameScreenBitplanes,blockscreen
;	 	jsr drawLevel

		move.w #0,scrollX
		move.w #0,scrollY
		jsr updateCameraAndScrolling

ttx: 
;		jsr rainbow
;		jmp ttx 



		move.l #statesub_play,menupoint_game_state_sub
		move.l #42,menupoint_game_state_sub_old

menu:   
		move.l #state_menu,game_state
		move.l #statesub_main,game_state_sub
		 
		; display mainmenu and submenus
submenu: 
		move.l game_state_sub,actualLevelIndex
		; move.l #1,actualLevelIndex
		
		cmp #statesub_main,game_state_sub
		beq notmain		
		; move.l game_state_sub,actualLevelIndex
notmain:
		; move.l #8,actualLevelIndex

		; jsr colorsToBlack

		; move.l #0,actualLevelIndex
		jsr loadActualLevel 
		; todo: blendin/out
		move.l #ScreenBase,blockscreen
		jsr drawLevel

		jsr updateCameraAndScrolling

		; disable all sprites from 1-7
		; set it to transparent

		; add some text here
		cmp.l #statesub_main,game_state_sub
		bne notmainx					
			; a text
			lea.l text_menu_main,a4
			move.w #8+2,text_x
			move.w #5,text_y
			move.l #ScreenBase,smallblockscreen
			jsr drawText	

			move.l #9+border_offset_word,number_x
			move.l #10,number_y
			move.l hscore,number_no
			jsr drawNumbers

notmainx:

		cmp.l #statesub_story,game_state_sub
		bne notmainxxx				
			; a text
			lea.l text_menusub_story,a4
			move.w #8+2,text_x
			move.w #5,text_y
			move.l #ScreenBase,smallblockscreen
			jsr drawText	
notmainxxx:

		cmp.l #statesub_howto,game_state_sub
		bne notmainxx				
			; a text
			lea.l text_menusub_howto,a4
			move.w #8+2,text_x
			move.w #5,text_y
			move.l #ScreenBase,smallblockscreen
			jsr drawText	
notmainxx:

		cmp.l #statesub_about,game_state_sub
		bne notmainxxxz			
			; a text
			lea.l text_menusub_about,a4
			move.w #8+2,text_x
			move.w #5,text_y
			move.l #ScreenBase,smallblockscreen
			jsr drawText	


notmainxxxz:

skipmenudef:

		; debug it
		;move.w #1,levelBlockIndex
		;move.w #4,levelBlock16X
		;move.w #4,levelBlock16Y
		;jsr setdrawLevelBlockDoubleBuffering
		;jsr showProductionScreen

		; copy screen to double buffering screens ... 
		jsr copyProductionToBuffering
		; renderBothSwapScreens

		; reset
		jsr resetAllGameObjects

		; bring it to light
		jsr colorsToGameColors



		jsr findNextFreeGameObject
		cmp.l #0,a0
		beq   crisshair
			move.w #objectstate_awake,gameobject_state(a0)
			move.w #type_avatar_mouse_crosshair,gameobject_type(a0)					
			move.w #100,gameobject_x(a0)
			move.w #200,gameobject_y(a0)
crisshair:


; -------------
menuloop:
; -------------

;		jmp nosmallblocks_test

;		move.w #4,smallblockx
;		move.w #1,smallblocky
;		move.w #8,smallblockno
;		jsr drawSmallBlockXY

;nosmallblocks_test:

		; -------------------------
		; init gameobject types
		; -------------------------
		jsr serviceInitGameObjectTypes

		; -------------------------------
		; update visuals / animate gameobjects
		; -------------------------------
		jsr updateVisualsGameObjects

		; -------------------------------
		; update gameobjects
		; -------------------------------
		jsr gameobjectsBehaviors


		; --------------------------
		; VSYNC
		; --------------------------
		bsr.w	WaitForRaster

		; -------------------------
		; screen swap
		; -------------------------
		jsr screenSwap

		; --------------------------
		; render now
		; --------------------------
		jsr renderScreenDoubleBuffered		

		; jsr rainbow

		; --------------------------
		; MUSIC
		; --------------------------
		; music 'thread'
		IF musicMode
			bsr.w	mt_music
		ENDIF


		


		; --------------------------
		; SHOW MENU POINT HERE
		; --------------------------
		; statesub_main

				; highscore
				;move.l #3,number_x
				;move.l #0,number_y
				;move.l menupoint_game_state_sub,d0
				;move.l d0,number_no
				;jsr drawNumbers

				cmp.l #statesub_main,game_state_sub
				bne  new_state

				move.l menupoint_game_state_sub,d0
				cmp.w menupoint_game_state_sub_old,d0
				beq new_state
				; cmp.w #42,d0
				; beq new_state
				
					; ok remove old one
					move.l menupoint_game_state_sub_old,d0
					cmp.w #42,d0
					beq new_state_oxt

						clr.l d0
						move.l menupoint_game_state_sub_old,d0
						add.l  #4,d0 ; y-pos
						move.w #75,blockno 
						move.w #4+border_offset_word,blockx
						move.w d0,blocky

						move.w #blockMenuPointInactive,levelBlockIndex
						move.w blockx,levelBlock16X
						move.w blocky,levelBlock16Y
						jsr setdrawLevelBlockDoubleBuffering
		

						
		new_state_oxt:

					; add new one 
					clr.l d0
					move.l menupoint_game_state_sub,d0
					add.l  #4,d0 ; y-pos
					move.w #52,blockno 
					move.w #4+border_offset_word,blockx
					move.w d0,blocky

						move.w #blockMenuPointActive,levelBlockIndex
						move.w blockx,levelBlock16X
						move.w blocky,levelBlock16Y
						jsr setdrawLevelBlockDoubleBuffering


		new_state:
				move.l menupoint_game_state_sub,menupoint_game_state_sub_old


				; debug
				jmp no_menudebug 
				clr.l d0
				move.w game_state_sub,d0
				move.w d0,number
				move.w #10,blockx
				move.w #7,blocky
				jsr displayBlockNumber 

				move.l game_state_sub,d0
		;		swap   d0
		;		move.w d0,number
		;		move.w #39,d0
				add.l  #39,d0
				move.w d0,blockno 
				move.w #10,blockx
				move.w #9,blocky
				jsr drawBlockXY
				; jsr displayBlockNumber 
		no_menudebug:

		; some block animations? 

		; --------------------------
		; "water simulation"
		; --------------------------
		; manipulate waves ...
		; effect_wave
;		jsr WaterEffect

		; ------------------------------
		; block animations & behavior
		; ------------------------------
		jsr updateBlockAnimationBehavior


		; --------------------------
		; random block animations
		; --------------------------
		; jsr RandomBlockAnimation

		; mouse 
		jsr serviceKeyJoystickAndMouseUpdate



		IF MouseMenuActive

		ENDIF
		


		; -------------------------
		; BACK FROM SUBMENU
		; -------------------------
		; not main menu 
		; back ... 
		cmp.l #statesub_main,game_state_sub		
		beq   not_main_main		
;txt:
		; move.w    $DFF006,$DFF180 ; background
		btst   #6,$BFE001      ;  left mouse button ?
   		bne.s  not_main_main
		move.l #statesub_main,game_state_sub				
		jmp submenu	
not_main_main:

		; ----------------------
		; INTERACTION MENU
		; ----------------------

        ; ---------------------
		; MENU PRESS KEY
		; ---------------------
		; mainmenu: select game 
				move.w #0,keyPressed

				bsr _keyboard

				; get keys
				jmp no_keysx
				move.l #5,number_x
				move.l #5,number_y
				clr.l d1
				move.w keyPressed,d1
				move.l d1,number_no
				jsr drawNumbers
		no_keysx:

				; 
				; 69 escape
				; 64 space
				; 68 return
				;
				; cursors?
				;
				;
				;


				; mainmenu
				cmp.l #statesub_main,game_state_sub
				bne n_mainmenu_menu

		; space
				clr.l d1
				move.w keyPressed,d1
				cmp.w #64,d1
				bne.w n_spacex_t
				; move.w    $DFF006,$DFF180 ; background
				cmp.l #statesub_play,menupoint_game_state_sub
				bne   startgame_now_x
				jmp startgame
		startgame_now_x:
				move.l menupoint_game_state_sub,game_state_sub	
				jmp submenu	
		n_spacex_t:

				; cursor
				clr.l d1
				move.w keyPressed,d1
				cmp.w #68,d1
				bne.w n_cursorup
				add.l #1,menupoint_game_state_sub
				; jsr showProductionScreen
		n_cursorup:

				jmp menu_keyboarddone
		n_mainmenu_menu:

				; space
				clr.l d1
				move.w keyPressed,d1
				cmp.w #64,d1
				bne.w menu_keyboarddone

				; MENU: ALL OTHERS
				move.l menupoint_game_state_sub,game_state_sub

		menu_keyboarddone:

		; ---------------------
		; MENU JOYSTICK
		; ---------------------
		jsr ReadJoystickDirect

				; mainmenu
				cmp.l #statesub_main,game_state_sub
				bne n_mainmenu_joystick

				cmp.w #1,joystick_Up_Clicked
				bne   j_up_y
				sub.l #1,menupoint_game_state_sub
		j_up_y:		

				cmp.w #1,joystick_Down_Clicked
				bne   j_down_x
				add.l #1,menupoint_game_state_sub
		j_down_x:	

				; all around the world
				cmp.l #0,menupoint_game_state_sub
				bne  awox
				move.l #4,menupoint_game_state_sub
		awox:

				; all around the world
				cmp.l #5,menupoint_game_state_sub
				bne  awoxy
				move.l #1,menupoint_game_state_sub
		awoxy:

				jmp no_mainmenu_sub
		n_mainmenu_joystick:

				; main menu sub
				; about etc.



no_mainmenu_sub:

		; ---------------------
		; MENU MOUSE DOWN
		; ---------------------
		btst   #6,$BFE001      ;  left mouse button ?
   		bne.s  no_mouse_button_pressedx
		jmp    no_mouse_button_pressedt
no_mouse_button_pressedx:
		jmp no_mouse_button_pressed
no_mouse_button_pressedt:

		jsr WaitForMouseUp

		; ---------------------
		; CLICK IN MAIN MENU
		; ---------------------
		; mainmenu: select game 
		cmp #statesub_main,game_state_sub
		bne not_mainmenu
		; wait for mouse up
yyyy:
		IF musicMode
			bsr.w	mt_music
		ENDIF 
  	    BTST   #6,$BFE001      ; Test left mouse button
   		BEQ.S   yyyy

		cmp.l #statesub_play,menupoint_game_state_sub
		bne   startgame_now_xy
		jmp startgame
startgame_now_xy:

		; MENU: ALL OTHERS
		move.l menupoint_game_state_sub,game_state_sub
		
		jmp submenu
notplay_howto:



		jmp not_submenu
not_mainmenu:
		; ---------------------
		; SUBMENU BACK
		; ---------------------
		move.l #statesub_main,game_state_sub				
;txt:
		move.w    $DFF006,$DFF180 ; background
;		jmp txt

		jmp submenu
not_submenu:

no_mouse_button_pressed:

		; < MENU LOOP
		jmp menuloop



;--------------------------------------------------------------------------------------------------------------
; GAME START
;--------------------------------------------------------------------------------------------------------------


startgame:

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

		IF musicMode
			bsr.w	mt_music
		ENDIF

		; -------------------------
		; reset all gameobjects
		; -------------------------
		jsr resetAllGameObjects

		move.l #0,level
		; repaint
		move.l #1,level_old

		move.l #0,score

		move.l #0,timer
		move.l #0,timercounter

		jmp next_level
died_level:
				; add score
		add.l #1,score

next_level:

		; jsr colorsToBlack


		jsr resetAllGameObjects
		
		; -------------------------------------
		; level title
		; -------------------------------------
		; show text for this level ....

	; jmp no_leveltitles

		move.l #6,actualLevelIndex
		jsr loadActualLevel 
		move.l #BackofficeBitplanes,blockscreen
		jsr drawLevel

		; add title 
		; todo: more text ...

		move.l #screenProduction,blockscreen
		move.l #levelTitles,a4
		move.l level,d0
		mulu #21,d0
		add.l d0,a4
		move.w #2,text_x ; offset!
		move.w #6,text_y
		jsr drawBlockText

		; copy in foreground double ... 
		jsr copyProductionToBuffering	

		; no double buffering just a screen!
		move.w #100,anykeyjoystick
		jsr pressAnyKeyJoystickOrMouseOrTime

	no_leveltitles:

		jsr resetAllGameObjects

		; next level ... 
;		move.l level,actualLevelIndex
;		add.l  #8,actualLevelIndex

		; load actual level
;		jsr loadActualLevel

		; gameobjects reset all 
		; jmp noresetall_sprites
;		lea.l gameobjects,a6
;		move.l #8,d3
resetall:	


		; ------------------------
		; add some objects
		; -------------------------
		; gameobject 0
;		jsr findNextFreeGameObject
;		cmp.l #0,a0
;		beq  foundnoobject
;		move.w #objectstate_awake,gameobject_state(a0)
;		move.w #160,gameobject_x(a0)
;		move.w #40,gameobject_y(a0)
;		move.w #art_type_bob1616,gameobject_art(a0)		
;		move.w #atype_noanim,gameobject_animtype(a0)
;		move.w #5,gameobject_animind(a0)
;		; move.w #type_avatar,gameobject_type(a0)


;		; gameobject 1
;		jsr findNextFreeGameObject
;		cmp.l #0,a0
;		beq  foundnoobject
;		; objectstate_awake
;		move.w #objectstate_awake,gameobject_state(a0)
;		move.w #40,gameobject_x(a0)
;		move.w #40,gameobject_y(a0)
;		move.w #type_ball,gameobject_type(a0)

;		; gameobject 2
;		jsr findNextFreeGameObject
;		cmp.l #0,a0
;		beq  foundnoobject
;		; objectstate_awake
;		move.w #objectstate_awake,gameobject_state(a0)
;		move.w #140,gameobject_x(a0)
;		move.w #140,gameobject_y(a0)
;		move.w #type_explosion,gameobject_type(a0)

		; gameobject 3
;		jsr findNextFreeGameObject
;		cmp.l #0,a0
;		beq  foundnoobject
;		; objectstate_awake
;		move.w #objectstate_awake,gameobject_state(a0)
;		move.w #70,gameobject_x(a0)
;		move.w #140,gameobject_y(a0)
;		move.w #type_explosion,gameobject_type(a0)


;		jsr findNextFreeGameObject
;		cmp.l #0,a0
;		beq  foundnoobject
;		; objectstate_awake
;		move.w #objectstate_awake,gameobject_state(a0)
;		move.w #70,gameobject_x(a0)
;		move.w #140,gameobject_y(a0)		
;		move.w #type_mouse,gameobject_type(a0)

foundnoobject:



	 	; jmp ingame
		; ------------------------------
		; Load & parse Level
		; ------------------------------
		move.l level,d0
		add.l  #8,d0
		move.l d0,actualLevelIndex
		jsr loadActualLevel 
		; todo: blendin/out

		; level to gameobjects (if needed)
		jsr parseLevel 


		move.l #BackofficeBitplanes,blockscreen
		jsr drawLevel
			;move.l #IntroScreen,blockscreen
			;jsr drawLevel
			; move.l #GameScreenBitplanes,blockscreen
			;;jsr drawLevel
		; copy in foreground double ... 
		jsr copyProductionToBuffering
		; renderBothSwapScreens

		; debug A/B | C=Backoffice
		IF debugDoubleBuffering
			; 0
			move.l #ScreenA,blockscreen
			move.w #2,blockx
			move.w #0,blocky
			move.w #39,blockno
			jsr drawBlockXY			
			; 1
			move.l #ScreenB,blockscreen
			move.w #3,blockx
			move.w #0,blocky
			move.w #40,blockno
			jsr drawBlockXY
			; 2
			move.l #ScreenC,blockscreen
			move.w #4,blockx
			move.w #0,blocky
			move.w #41,blockno
			jsr drawBlockXY
		ENDIF

;hx:
;		bsr WaitForRaster
;		; swap screens
;		; -------------------------
;		jsr screenSwap
;		jmp hx

;		; test2: show screenC
;		move.l #ScreenC,scrollCameraAddress
;		jsr updateCameraAndScrolling
;xt:
;		jmp xt


		; ------------------------
		; populate with sprites
		; ------------------------
;		jsr findNextFreeSprite
		

		; the game



		; player 
		jsr findNextFreeSprite
		cmp.l #0,a0
		beq   nothingfound
			move.w #objectstate_awake,gameobject_state(a0)
			move.w #type_avatar_mouse_ground,gameobject_type(a0)	
			move.w #3,gameobject_health(a0) ; lifes 
			move.w #100,gameobject_x(a0)
			move.w #avatar_y,gameobject_y(a0)
			move.l a0,playerAdress

		jsr findLastFreeGameObject
		cmp.l #0,a0
		beq   nothingfound
			move.w #objectstate_awake,gameobject_state(a0)
			move.w #type_avatar_mouse_crosshair,gameobject_type(a0)					
			move.w #100,gameobject_x(a0)
			move.w #200,gameobject_y(a0)

		; some sprites	
		;		move.l #3,d4
		;sprites_zlr:
		;		jsr findNextFreeGameObject
		;		cmp.l #0,a0
		;		beq   nothingfound
		;	
		;			move.w #objectstate_active,gameobject_state(a0)
		;			move.w #art_type_sprite,gameobject_art(a0)		
		;			cmp.l #4,d4
		;			bne nixdix
		;			;move.w #behavior_mouse_direct,gameobject_behaviour(a0)	
		;nixdix:
		;			move.l d4,d0
		;			mulu   #16,d0	
		;			add.l  #30,d0
		;			move.w d0,gameobject_x(a0)
		;			move.w #140,gameobject_y(a0)
		;			move.w d4,gameobject_spr(a0)
		;			; move.w #1,gameobject_animmin(a0)
		;			move.w d4,gameobject_animind(a0)
		;			add.w  #3,gameobject_animind(a0)
		;			; move.w #3,gameobject_animmax(a0)
		;			move.w #atype_noanim,gameobject_animtype(a0)
		;		dbra d4,sprites_zlr

				
nothingfound:


; -------------------------
ingameLoop:
; -------------------------

		; -------------------------
		; music
		; -------------------------
		IF musicMode
			bsr.w	mt_music
		ENDIF

		IF debugGameObjects
				; show here ...
				lea.l gameobjects,a6
				move.l #maxGameObjects,d3
				move.l #0,d4
			resetalltx:	
				cmp.w #objectstate_active,gameobject_state(a6)
				bne.w cdall 
				add.l #1,d4
			cdall:	
				add.l #gameobject_size_bytes,a6		
				dbra d3,resetalltx
		
				move.l #ScreenA,blockscreen

				move.l #1+border_offset_word,number_x
				move.l #3,number_y
				move.l d4,number_no

				; move.l protectIndex,number_no

				jsr drawNumbers
		ENDIF

		; -------------------------
		; init gameobject types
		; -------------------------
		jsr serviceInitGameObjectTypes

		; show red
		IF debugSpeed
		  jsr work_stop
		ENDIF



		; show black
		IF debugSpeed
		  jsr work_start
		ENDIF


	

		; swap screens
		; -------------------------
		jsr screenSwap
		; -------------------------


	; -------------------------
		; Wait for the raster	
		; -------------------------
		; jsr BlitWait      ; wait for last blit done
		bsr WaitForRaster
		IF debugSlowDownGame
			bsr WaitForRaster
			bsr WaitForRaster
			bsr WaitForRaster
			bsr WaitForRaster
			bsr WaitForRaster
			bsr WaitForRaster
			bsr WaitForRaster
			bsr WaitForRaster
			bsr WaitForRaster
			bsr WaitForRaster
		ENDIF

		; test
		; do the mechanics
		cmp.l #0,shownScreen
		bne   xyz
		; jsr rainbow
xyz:

		; ------------------------------
		; block animations & behavior
		; ------------------------------
		jsr updateBlockAnimationBehavior				

		; -------------------------
		; mechanics overall
		; -------------------------

		; count some objects
			move.l #0,gocounter
			move.l #maxGameObjects,d6 ; gameobjects_no
			lea.l gameobjects,a6
		counting:
			; gameobject_state
			cmp.w #objectstate_inactive,gameobject_state(a6)
			beq.w doncount_this

			cmp.w #type_a_shootflyup,gameobject_type(a6)
			beq.w count_this
			cmp.w #type_a_shootup,gameobject_type(a6)
			beq.w count_this
			jmp doncount_this
	count_this:
				add.l #1,gocounter
		doncount_this:

			add.l #gameobject_size_bytes,a6
			dbra d6,counting
		
		; -------------------------
		; mechanics specific
		; -------------------------
		; collision and co
		; specific code
		jsr gamemechanics

		cmp.w #254,scrollY
		bgt noscrollY
		; add.w #1,scrollY
		jmp scrollend
noscrollY:
		move.w #0,scrollY
scrollend:

		; ---------------------------
		; level based on time
		; ---------------------------
		; in game mode?
;		cmp.l #state_gameover,game_state_sub
;		beq gameover_nonewlevel
;
;		move.l level,d0
;		move.l d0,level_old
;
;		; primitive counter
;		add.l #1,timercounter
;		move.l timercounter,d0
;		cmp.l timestep,d0
;		bcs lowerthantimer 
;
;		move.l #0,timercounter
;		add.l  #1,timer
;
;		add.l #1,level
;not_nextlevel:
;lowerthantimer:
;gameover_nonewlevel:

			; -------------------
			; level finished?
			; -------------------
			; check if level is finished!

;			move.l #20*16-1,d1
;			move.l #0,d2
;			lea.l actualLevel,a0
;tlevel:
;			clr.l d0
;			move.b (a0)+,d0
;			cmp.w #block_collect_start,d0
;			blt.w nenotf
;			cmp.w #block_collect_stop+1,d0
;			bgt.w nenotf
;			add.l #1,d2
;nenotf:
;			dbra d1,tlevel


		; -------------------------
		; behviours 
		; -------------------------
		; collision and co
		; specific code
		jsr gameobjectsBehaviors


		; add to double buffering				
		;move.w #3,dbManagementX
		;move.w #0,dbManagementY
		;jsr managementDoubleBufferingAddBlock
		;move.w #4,dbManagementX
		;move.w #0,dbManagementY
		;jsr managementDoubleBufferingAddBlock
		;move.w #2,dbManagementX
		;move.w #0,dbManagementY
		;jsr managementDoubleBufferingAddBlock


		; copy from backoffice to screens
			; overwrite source screen
			; move.l #GameScreenBitplanes,cpScreenSource	
		;move.l #GameScreenBitplanes,cpScreen
		;move.w #4,cpRasterX
		;move.w #0,cpRasterY
		;jsr copyBlockRasterBackofficeToScreen
		;move.l #IntroScreen,cpScreen
		;move.w #4,cpRasterX
		;move.w #0,cpRasterY
		;jsr copyBlockRasterBackofficeToScreen

		; 2*16x16 pix
		;move.l #IntroScreen,cpBobScreen
		;move.w #2,cpBobRasterX
		;move.w #0,cpBobY
		;jsr copyBlockBobRasterBackofficeToScreen
		;move.l #GameScreenBitplanes,cpBobScreen
		;move.w #2,cpBobRasterX
		;move.w #0,cpBobY
		;jsr copyBlockBobRasterBackofficeToScreen

		; debug
		;move.l #IntroScreen,blockscreen
		;move.l listManagementABobsIndex,number_no
		;move.l #2,number_x
		;move.l #3,number_y
		;jsr drawNumbers
		;move.l #IntroScreen,blockscreen
		;move.l listManagementBBobsIndex,number_no
		;move.l #2,number_x
		;move.l #4,number_y
		;jsr drawNumbers


		; -------------------------------
		; animate gameobjects
		; -------------------------------
		jsr updateVisualsGameObjects

		; -------------------------------
		; key, joystickMouse
		; -------------------------------
		jsr serviceKeyJoystickAndMouseUpdate

		; -------------------------------
		; key & co handling
		; -------------------------------
		; 69 escape
		; 64 space
		; 68 return

key_escape = 69
key_space = 64
key_return = 68

		;
		; cursors?
	
		; escape
		clr.l d1
		move.w keyPressed,d1
		cmp.w #key_escape,d1
		bne.w n_escapex
		; move.w    $DFF006,$DFF180 ; background
		jmp menu
n_escapex:

		; space
		clr.l d1
		move.w keyPressed,d1
		cmp.w #key_space,d1
		bne.w n_spacex
		; move.w    $DFF006,$DFF180 ; background
		add.l #1,level
		jmp next_level

n_spacex:

		; escape
		clr.l d1
		move.w keyPressed,d1
		cmp.w #key_return,d1 ; $44
		bne.w n_return
		; move.w    $DFF006,$DFF180 ; background
n_return:


		; -------------------------------
		; render screen: game objects 
		; -------------------------------
		jsr renderScreenDoubleBuffered ; wait for raster inclusive


; ----------------------
		jmp ingameLoop
; ----------------------

exit:	
		bsr.w	mt_end
		; ---------------------------
		; BACK TO AMIGADOS
		; ---------------------------

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

		rts


	even
demoCounterCount: 	dc.w 0
demoCounter:	 	dc.w 0


ww 		=320

bltx	=20
blty    =0
bltoffs =blty*(ww/8)+bltx/8

; position
bltxd	=20
bltyd    =130
bltoffsd =bltyd*(ww/8)+bltxd/8
; size
bltw	=224/16
blth 	=100
bltskip =(320-224)/8

bcorner  = (blth-1)*(ww/8)+bltw*2-1



		
		; ---------------------------
		; BACK TO AMIGADOS
		; ---------------------------

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

		rts

	even
cloudx:
	dc.w 0



;======================================================================================================================
; 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    "sq"
    dc.b    $ff

XFont:
	incbin	"gfx/nice.fnt"


;======================================================================================================================
;  demoSCENE
;======================================================================================================================
	even

offsetY: dc.l 0
offsetYCounter: dc.l 0

blockerrunnerx: dc.w 0
blockerrunnery: dc.w 0

;======================================================================================================================
;  cryAengine: gamemechanics
;======================================================================================================================

gamemechanics:

		; ---------------------------
		;  COLLISIONS
		; ---------------------------
			; jmp nocollision


		; not game over!
		cmp.l #state_gameover,game_state_sub
		beq nocollision


				move.l #maxGameObjects,d5 ; gameobjects_no
				lea.l gameobjects,a3
		collision:		
				
				clr d3
				; innerCollision
				move.l #maxGameObjects,d4 ; gameobjects_no
				lea.l gameobjects,a2
		innerCollision:		
				clr d2
				clr d1

				; is one object not active?
				; gameobject_state
				move.w gameobject_state(a2),d0
				cmp.w #objectstate_inactive,d0
				beq.w thesame

				move.w gameobject_state(a3),d0
				cmp.w #objectstate_inactive,d0
				beq.w thesame


				; is collision active?
				cmp.w #collision_no,gameobject_collision(a2)
				beq.w thesame
				cmp.w #collision_no,gameobject_collision(a3)
				beq.w thesame

				; no collision against the same object
				cmp.l d4,d5
				bne notthesame
				jmp thesame
		notthesame:

				; box collision
				; with box colliders
				;   ______ 
				;  | a3  _|___
				;  |_____|a2 |
				;        |___|
				;

				clr.l d3
				clr.l d2
				clr.l d1
				move.w gameobject_y(a3),d3
				move.w gameobject_y(a2),d2
				move.w gameobject_height(a2),d1
				move.w #0,CCR
				add.w d1,d2
				cmp.w d2,d3
				bgt.w yhigher ; signed!
				;  a3.y > a2.y+a2.height

				clr.l d3
				clr.l d2
				clr.l d1
				move.w gameobject_y(a3),d3
				move.w gameobject_y(a2),d2
				move.w gameobject_height(a3),d1
				move.w #0,CCR
				sub.w d1,d2
				cmp.w d2,d3
				blt.w ylower ; signed <0
				;  a3.y < a2.y-a3.height

				clr.l d3
				clr.l d2
				clr.l d1
				move.w gameobject_x(a3),d3
				move.w gameobject_x(a2),d2
				move.w gameobject_width(a2),d1
				add.w d1,d2
				move.w #0,CCR
				cmp.w d2,d3
				bgt.w xhigher ; signed 
				;  a3.x > a2.x+a2.width

				clr.l d3
				clr.l d2
				clr.l d1
				move.w gameobject_x(a3),d3
				move.w gameobject_x(a2),d2
				move.w gameobject_width(a3),d1
				sub.w d1,d2
				move.w #0,CCR
				cmp.w d2,d3
				blt.w xlower
				;  a3.x < a2.x-a3.width

				; ------------------------
				; do the collision
				; ------------------------
					; debug it
					IF debugCollision
						move.w #1,gameobject_animind(a5)
						move.w #1,gameobject_animind(a6)
					ENDIF 

					; do it
					move.l a3,a6
					move.l a2,a5
					move.w #handle_collision,handleState
					jsr handleGameObject
				; ------------------------
				; / do the collision
				; ------------------------
				
				; rainbow
				; move.w    $DFF006,$DFF180 ; background

		xlower:
		xhigher:

		ylower: 
		yhigher:		

		thesame:

				add.l  #gameobject_size_bytes,a2 ; gameobject_size
				dbra d4,innerCollision
				; / innerCollision

				; collision
				add.l  #gameobject_size_bytes,a3 ; gameobject_size
				dbra d5,collision

		collision_done:

		nocollision:

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

		rts

;======================================================================================================================
; cryAengine: Waiting function
;======================================================================================================================

anykeyjoystick: dc.w 0
;		move.w #100,anykeyjoystick
anykeyjoystick_counter: dc.w 0


; no double buffering etc
pressAnyKeyJoystickOrMouseOrTime:

	move.w #0,anykeyjoystick_counter

	pressAnyKeyJoystickOrMouseOrTime_loop:

		jsr	WaitForRaster
		
		IF musicMode
			bsr.w	mt_music
		ENDIF
	
		BTST   #6,$BFE001      ; Test left mouse button
   		BEQ.S   end_pressAnyKeyJoystickOrMouseOrTime_loop

		add.w #1,anykeyjoystick_counter
		move.w anykeyjoystick,d0
		cmp.w anykeyjoystick_counter,d0
		blt  end_pressAnyKeyJoystickOrMouseOrTime_loop
		jmp pressAnyKeyJoystickOrMouseOrTime_loop

	end_pressAnyKeyJoystickOrMouseOrTime_loop:

		rts


;======================================================================================================================
;  cryAengine: gameobjectBehaviours
;======================================================================================================================

resetAllGameObjects:

		; -------------------------
		; reset all gameobjects
		; -------------------------
		; gameobjects reset all 
		; jmp noresetall_sprites
		lea.l gameobjects,a6
		move.l #maxGameObjects,d3
resetallt:	

		move.w #objectstate_inactive,gameobject_state(a6)
		move.l d3,d0
		mulu  #4,d0
		move.w #32,gameobject_x(a6)
		add.w d0,gameobject_x(a6)
		move.w #32,gameobject_y(a6)
		; move.w #behavior_standstill,gameobject_behaviour(a6)		

		move.w #0,gameobject_arg(a6)		

		add.l #gameobject_size_bytes,a6
		dbra d3,resetallt		
noresetall_sprites:

		rts


;======================================================================================================================
;  cryAengine: gameobjectBehaviours
;======================================================================================================================

gameobjectsBehaviors:

		; ---------------------------
		; 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 #maxGameObjects,d6 ; gameobjects_no
		lea.l gameobjects,a6
behave:		

		; object state?
		cmp.w #objectstate_active,gameobject_state(a6)
		bne.w end_behaviorx

			; move.l a6,a0
			move.w #handle_update,handleState
			jsr handleGameObject
 
end_behaviorx:

		add.l  #gameobject_size_bytes,a6 ; gameobject_size
		dbra d6,behave

nobehavior:

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

		rts

;======================================================================================================================
;  cryAengine: Admin Double Buffering 
;======================================================================================================================
; BackofficeBitplanes
; shownScreen: 		 dc.l 0 	; 0: Screen A
; actualHiddenScreenAddress: dc.l 0

; actualManagement: dc.l 1

; ------------------------
managementScreen:
; ------------------------

shownScreen: 		 dc.l 0 	; 0: Screen A
					      		; 1: Screen B
actualHiddenScreenAddress: dc.l 0

dbManagementX: dc.w 1
dbManagementY: dc.w 1

	even

managementDoubleBufferingAddBlock:

	; add to both management for the screen
	; screen a
	move.l #listManagementABlocks,a0
	cmp.l #0,listManagementABlocksIndex
	beq   mdnocounta
		move.l listManagementABlocksIndex,d0
		mulu   #blockManagementSize,d0
		add.l d0,a0	
mdnocounta:
	; add now
	move.w managementBlockType_1616,managementBlockType(a0)
	move.w dbManagementX,managementBlockX(a0)
	move.w dbManagementY,managementBlockY(a0)
	add.l #1,listManagementABlocksIndex
	cmp.l #10,listManagementABlocksIndex
	blt   ablocksIndexMax
	move.l #10,listManagementABlocksIndex
ablocksIndexMax:		

	; screen b
	move.l #listManagementBBlocks,a0
	cmp.l #0,listManagementBBlocksIndex
	beq   mdnocountb
		move.l listManagementBBlocksIndex,d0
		mulu   #blockManagementSize,d0
		add.l d0,a0	
mdnocountb:
	; add now
	move.w managementBlockType_1616,managementBlockType(a0)
	move.w dbManagementX,managementBlockX(a0)
	move.w dbManagementY,managementBlockY(a0)
	add.l #1,listManagementBBlocksIndex
	cmp.l #listManagementAmountOfBlocks,listManagementBBlocksIndex
	blt   abblocksIndexMaxX
	move.l #listManagementAmountOfBlocks,listManagementBBlocksIndex
abblocksIndexMaxX:		

	rts 

; -----------------
; BlockManagement
; -----------------
blockManagementSize = 5*2; listManagementABlockEnd-listManagementABlocks

; blockindizes
managementBlockType = 0
managementBlockX = 2
managementBlockY = 4
managementBlockWidth = 8
managementBlockHeight = 10

; blocktypes
managementBlockType_1616 = 0


; ---------------------
; BobRemoveManagement
; ---------------------
bobManagementSize = 12; listManagementABobs - listManagementABobs

; indexies
managementScreen_BobType = 0
managementScreen_BobX = 2
managementScreen_BobY = 4
managementScreen_BobWidth = 6 
managementScreen_BobHeight = 8
managementScreen_BobOrder = 10

; ------------
; A
; ------------
			  even

listManagementAmountOfBlocks = 40			  

listManagementABlocks: ; type,x,y,optwith,optheight %16
					   ; 0 16x16
			  dc.w 0,10,0,0,0
listManagementABlockEnd:
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0

			  even
listManagementABlocksIndex: dc.l 0

			  even
listManagementABobs:   ; dc.w	type (block1616: 0 / bob1616:1 / bob3232:2), sizex, sizey, order x
			  dc.w 0,10,10,16,16,1
listManagementABobEnd:
			  even

			  dc.w 0,10,10,16,16,0
			  dc.w 0,10,10,16,16,0
			  dc.w 0,10,10,16,16,0
			  dc.w 0,10,10,16,16,0
			  dc.w 0,10,10,16,16,0
			  dc.w 0,10,10,16,16,0
			  dc.w 0,10,10,16,16,0
			  dc.w 0,10,10,16,16,0
			  dc.w 0,10,10,16,16,0
			  dc.w 0,10,10,16,16,0
			  dc.w 0,10,10,16,16,0
			  dc.w 0,10,10,16,16,0
			  dc.w 0,10,10,16,16,0
			  dc.w 0,10,10,16,16,0
			  dc.w 0,10,10,16,16,0
			  dc.w 0,10,10,16,16,0
			  dc.w 0,10,10,16,16,0
			  dc.w 0,10,10,16,16,0
			  dc.w 0,10,10,16,16,0
			  dc.w 0,10,10,16,16,0
			  dc.w 0,10,10,16,16,0
			  dc.w 0,10,10,16,16,0
			  dc.w 0,10,10,16,16,0
			  dc.w 0,10,10,16,16,0
			  dc.w 0,10,10,16,16,0
			  dc.w 0,10,10,16,16,0
			  dc.w 0,10,10,16,16,0
			  dc.w 0,10,10,16,16,0
			  dc.w 0,10,10,16,16,0
			  dc.w 0,10,10,16,16,0
			  dc.w 0,10,10,16,16,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  even

listManagementABobsIndex: dc.l 0



; ------------
; B
; ------------
			  even

listManagementBBlocks: ; type,x,y,optwith,optheight %16
					   ; 0 16x16
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0			  
	even
listManagementBBlocksIndex: dc.l 0

			  even
listManagementBBobs:   ; dc.w	type (block1616: 0 / bob1616:1 / bob3232:2), sizex, sizey, order x
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0
			  dc.w 0,10,0,0,0

	even

listManagementBBobsIndex: dc.l 0


;======================================================================================================================
;  cryAengine: Render Double Buffering ..
;======================================================================================================================

; update both SwapScreen
copyProductionToBuffering:

	; copy backoffice screen to the two swapscreens (no bobs etc)

		lea BackofficeBitplanes,a5
		move.l #IntroScreen,a4
		jsr copyScreenDirect

		lea BackofficeBitplanes,a5
		move.l #GameScreenBitplanes,a4
		jsr copyScreenDirect

	rts



;  Double Bufferin in action:
; 
;   for each screen:
;   1. overwrite affected areas by bobs
;   2. update blocks
;   3. render actual actual blocks
;

	even
; shownScreen: 		 dc.l 0 	; 0: Screen A
					      		; 1: Screen B
; actualHiddenScreenAddress: dc.l 0


	even

; production screen?
showProductionScreen:
		move.l #ScreenC,scrollCameraAddress
		jsr updateCameraAndScrolling
xt:
		jmp xt
		rts

; screenSwap:
screenSwap:


	cmp.l #0,shownScreen
	bne   swapAScreen
		move.l #1,shownScreen


	    move.l	#ScreenB,d0		; Source Image Address that is the address of Bitplane 1
		add.l   #address_screen_addframe,d0  ; border
		; yscroll
		clr.l   d5
		move.w scrollY,d5
		mulu    #40*screenFactorWidth+2*border_offset_byte,d5
		add.l   d5,d0
		lea		GameBitplanePointers,a0		; Bitplane Pointers in the Copper
		lea		$dff000,a5
		moveq.l	#NoOfBpls-1,d1				; Number of Bitplanes
		move.l	#BitplaneSizeWide,d2			; Add the bitplane size to the source start Image Address
		bsr.w	SetBitPlanes 


;		move.l #IntroScreen,actualHiddenScreenAddress
		move.l #ScreenA,actualHiddenScreenAddress


		jmp swapBScreen
swapAScreen:
		;jsr rainbow yscroll
		move.l #0,shownScreen

	    move.l	#ScreenA,d0		; Source Image Address that is the address of Bitplane 1
		add.l   #address_screen_addframe,d0  ; border
		; yscroll
		clr.l   d5
		move.w scrollY,d5
		mulu    #40*screenFactorWidth+2*border_offset_byte,d5
		add.l   d5,d0
		lea		GameBitplanePointers,a0		; Bitplane Pointers in the Copper
		lea		$dff000,a5
		moveq.l	#NoOfBpls-1,d1				; Number of Bitplanes
		move.l	#BitplaneSizeWide,d2			; Add the bitplane size to the source start Image Address
		bsr.w	SetBitPlanes 


;		move.l #GameScreenBitplanes,actualHiddenScreenAddress
		move.l #ScreenB,actualHiddenScreenAddress



swapBScreen:



	rts 

; the concrete rendering
renderScreenDoubleBuffered:

	; shownScreen: 0 > introscreen shown
	;                > gamescreen hidden < paint
	; 				   > BlockB, BobsB
	; shownScreen: 1 > gamescreen shown
	;                > introscreen hidden < paint
	; 				   > BlockA, BobsB
	; actualHiddenScreenAddress


;	move.l #0,listManagementABobsIndex
;	move.l #0,listManagementBBobsIndex

;	jmp jumpxyz

	; reverse it
	; work on 



	; ----------------
	; RENDER HIDDEN
	; SCREEN
	; ----------------


	; ----------------
	; 1. CLEAN BOBS
	; ----------------
		; copy whole screen
		; dirty
		; one screen only
		;cmp.l #1,shownScreen
		;bne   screenBActiveX
		;	lea BackofficeBitplanes,a5
		;	move.l actualHiddenScreenAddress,a4
		;	jsr copyScreenDirect
; screenBActiveX:
	; shownScreen
	; -----------------
	; REMOVE BOBS B
	; -----------------
	cmp.l #0,shownScreen
	bne  endBobsB
		; go through the whole ... 
		; listManagementBBobsIndex: dc.l 1
		;listManagementBBobs
		move.l listManagementBBobsIndex,d5
		move.l #listManagementBBobs,a5
		cmp.l  #0,d5
		beq    endBobsB
ebe:
		; delete 
			; copy now the 16+16 pixels	
			clr.l d0
			move.w managementScreen_BobX(a5),d0 ; %16
			divu  #16,d0
			swap d0
			clr.w d0
			swap  d0	
			move.l actualHiddenScreenAddress,cpBobScreen
			move.w d0,cpBobRasterX
			move.w managementScreen_BobY(a5),cpBobY
			jsr copyBlockBobRasterBackofficeToScreen

		add.l #bobManagementSize,a5
		dbra d5,ebe			
		move.l #0,listManagementBBobsIndex
endBobsB:
	; -----------------
	; REMOVE BOBS A
	; -----------------
	cmp.l #1,shownScreen
	bne endBobsA
		; go through the whole ... 
		; listManagementABobsIndex: dc.l 1
		;listManagementABobs
				move.l listManagementABobsIndex,d5
				move.l #listManagementABobs,a5
				cmp.l  #0,d5
				beq    endBobsA
		eber:
				; delete 
					; copy now the 16+16 pixels	
					clr.l d0
					move.w managementScreen_BobX(a5),d0 ; %16
					divu  #16,d0
					swap d0
					clr.w d0
					swap  d0	
					move.l actualHiddenScreenAddress,cpBobScreen
					move.w d0,cpBobRasterX
					move.w managementScreen_BobY(a5),cpBobY
					jsr copyBlockBobRasterBackofficeToScreen
				add.l #bobManagementSize,a5
				dbra d5,eber			
		move.l #0,listManagementABobsIndex
endBobsA:


	; ------------------
	; 2. UPDATE NEW BLOCKS
	; ------------------
	
			move.l listManagementABlocksIndex,d5
			move.l #listManagementABlocks,a6
			; screen b
			move.l #screenProduction,blockscreen
			cmp.l #1,shownScreen
			bne   updateBlocksB
				move.l listManagementBBlocksIndex,d5
				move.l #listManagementBBlocks,a6
updateBlocksB:			
			; let's copy them now ...
			cmp.l #0,d5
			beq   noBlockUpdate
			
updateBlocks:
			; copy now ... backoffice to background-screen
			move.l actualHiddenScreenAddress,cpScreen
			move.w managementBlockX(a6),cpRasterX ; managementBlockX(a6)
			move.w managementBlockY(a6),cpRasterY ; managementBlockY(a6)
			; move.w #4,cpRasterX ; managementBlockX(a6)
			; move.w #0,cpRasterY ; managementBlockY(a6)
			jsr copyBlockRasterBackofficeToScreen
 
			add.l #blockManagementSize,a6
			dbra d5,updateBlocks
noBlockUpdate:

			; reset the blocks
			cmp.l #1,shownScreen
			bne updateResetB
				move.l #0,listManagementBBlocksIndex
				jmp updateResetA
updateResetB:
				move.l #0,listManagementABlocksIndex
updateResetA:


	; --------------------------------------
	; 3. RENDER ACTUAL BOBS IN GAMEOBJECTS
	; --------------------------------------

	; jmp norenderx
;	cmp.l #1,shownScreen
;	bne  norenderx

		lea.l gameobjects,a6
		move.l #maxGameObjects,d6
renderGameObjectBobs:	

		cmp.w #objectstate_active,gameobject_state(a6)
		bne   notactive

				; the bobs ...
				cmp.w #art_type_bob1616,gameobject_art(a6)
				bne   no_artbob

					move.l actualHiddenScreenAddress,bob1616_screen
					move.w gameobject_animind(a6),bob1616_id

					move.w gameobject_x(a6),bob1616_x
					move.w gameobject_y(a6),bob1616_y
					jsr renderBob1616

					; add bob ...
					; managementAddBob
					move.w bob1616_x,managementRemoveBobX
					move.w bob1616_y,managementRemoveBobY
					jsr managementRemoveAddBob
no_artbob:

				; the sprites ... 
				cmp.w #art_type_sprite,gameobject_art(a6)
				bne   no_artsprite

					clr.l d5
					move.w gameobject_spr(a6),d5
					cmp.l #7,d5
					bgt   nullto7

						; get address
						move.l #Spr0,a1
						mulu   #SpriteData_End-Spr0,d5
						add    d5,a1

						move.w  gameobject_y(a6),d0
						sub.w   #0,d0 ; offset
						move.w  gameobject_x(a6),d1
						sub.w   #-32,d1 ; offset
						move.w	#$10,d2
						bsr.w	MoveSprite

nullto7:

no_artsprite:


notactive:


		add.l #gameobject_size_bytes,a6
		dbra d6,renderGameObjectBobs

norenderx:




jumpxyz:

	; ------------------------------------------
	; 4. REMOVE ALL NOT USED SPRITES (HARDWARE)
	; ------------------------------------------

			move.l #8-1,d3
			move.l #spritesnoarr,a0
	rsprno2: 
			move.b #0,(a0)+
			dbra d3,rsprno2

			; find all occupied sprites ... 
			lea.l gameobjects,a0
			add.l #maxGameObjects*gameobject_size_bytes,a0
			move.l #maxGameObjects,d3
	zfnfgt2:	
			cmp.w #objectstate_active,gameobject_state(a0)
			bne.w   zactivespritet2
			cmp.w #art_type_sprite,gameobject_art(a0)
			bne.w   zactivespritet2
				move.l #spritesnoarr,a3
				move.w gameobject_spr(a0),d0
				cmp.w #0,d0
				blt   zactivespritet2
				cmp.w #7,d0
				bgt   zactivespritet2
					add.l d0,a3
					move.b #1,(a3)
	zactivespritet2:
			sub.l #gameobject_size_bytes,a0
			dbra d3,zfnfgt2

			; find now a not used sprite
			move.l #8,d3
			move.l #spritesnoarr,a4
			move.l #0,d4
	rsprno2t2: 
			cmp.b #0,(a4)
			bne.b   tilt2 
			  ; disable - means 
			  ; move it to 0/0 out of visible
			  ; todo: better version with transparent

			; get address
				move.l #Spr0,a1
				move.l d4,d2
				mulu   #SpriteData_End-Spr0,d2
				add    d2,a1
				; move to 0/0
				; move.w  d4,d0
				; move.w  d4,d1
				move.w #-16,d0
				move.w #-16,d1
				move.w	#$10,d2
				bsr.w	MoveSprite 		

   
	tilt2:	
			add.l #1,d4 		
			add.l #1,a4
			dbra d3,rsprno2t2	
 



		


		; render bobs ....
		;move.l actualHiddenScreenAddress,bob1616_screen
		;move.w #19,bob1616_id
		;move.w #271,bob1616_x
		;move.w #200,bob1616_y
		;jsr renderBob1616

		;move.l actualHiddenScreenAddress,bob1616_screen
		;move.w #1,bob1616_id
		;move.w #161,bob1616_x
		;move.w #180,bob1616_y
		;move.w  demoCounterCount,d0
		;add.w   d0,bob1616_y
		;jsr renderBob1616

		; draw a horde
;		move.l actualHiddenScreenAddress,bob1616_screen
;		add.w   #1,demoCounterCount
;		cmp.w   #40,demoCounterCount
;		bne.w     maxCount
;		move.w  #0,demoCounterCount
;maxCount:

;		move.l #19,d7
;bobcrowd:
;		move.l d7,d0
;		mulu   #10,d0
;		move.l #200,d1
;		sub.l  d0,d1
;		move.w d7,bob1616_id
;		move.w d0,bob1616_x
;		move.w demoCounterCount,d2
;		add.w  d2,d1
;		move.w d1,bob1616_y
;		jsr renderBob1616

		; add bob ...
		; managementAddBob
;		managementAddBob
;		move.w bob1616_x,managementRemoveBobX
;		move.w bob1616_y,managementRemoveBobY
;		jsr managementRemoveAddBob
;		dbra d7,bobcrowd



	rts


;======================================================================================================================
;  cryAengine: managementAddBob
;======================================================================================================================
	even

managementRemoveBobX: dc.w 0
managementRemoveBobY: dc.w 0

managementRemoveAddBob:

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

	; ----------------------
	; REMOVE ALL BBOBS
	; ----------------------
	cmp.l #0,shownScreen
	bne   screenBRemove
		move.l listManagementBBobsIndex,d4		
 		move.l #listManagementBBobs,a4
		mulu   #bobManagementSize,d4
		add.l  d4,a4
		move.w managementRemoveBobX,managementScreen_BobX(a4)		
		move.w managementRemoveBobY,managementScreen_BobY(a4)		
	 	add.l #1,listManagementBBobsIndex
screenBRemove:

	; ----------------------
	; REMOVE ALL ABOBS
	; ----------------------
	cmp.l #1,shownScreen
	bne   screenARemove
		move.l listManagementABobsIndex,d4		
 		move.l #listManagementABobs,a4
		mulu   #bobManagementSize,d4
		add.l  d4,a4
		move.w managementRemoveBobX,managementScreen_BobX(a4)		
		move.w managementRemoveBobY,managementScreen_BobY(a4)		
	 	add.l #1,listManagementABobsIndex
screenARemove:



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

	rts

;======================================================================================================================
;  cryAengine: GameObjects
;======================================================================================================================
; gameobjects all objects
; triggers, sprites (0-7), bob1616 (10) ...



; find next free gameobject - all gameobjects
findNextFreeGameObject:
		; returns address in a0
		lea.l gameobjects,a0
		move.l #maxGameObjects,d0
fnfg:	
	    cmp.w #objectstate_inactive,gameobject_state(a0)
		bne   activesprite
	    jmp fffnfg
activesprite:
		add.l #gameobject_size_bytes,a0
		dbra d0,fnfg
		move.l #0,a0
fffnfg:

	rts 

; find last free gameobject
findLastFreeGameObject:
		; returns address in a0
		lea.l gameobjects,a0
		add.l #maxGameObjects*gameobject_size_bytes,a0
		move.l #maxGameObjects,d3
fnfgt:	
	    cmp.w #objectstate_inactive,gameobject_state(a0)
		bne   activespritet
	    jmp fffnfgt
activespritet:
		sub.l #gameobject_size_bytes,a0
		dbra d3,fnfgt
		move.l #0,a0
fffnfgt:

	rts 

; find next free sprite - sprites only!
findNextFreeSprite:

	jsr findNextFreeGameObject

	cmp.l #0,a0
	beq   sorrynotfound
			move.l a0,a5

			; reset spritenoarr
			move.l #7,d3
			move.l #spritesnoarr,a0
	rsprno: 
			move.b #0,(a0)+
			dbra d3,rsprno


			; find all occupied sprites ... 
			lea.l gameobjects,a0
			add.l #maxGameObjects*gameobject_size_bytes,a0
			move.l #maxGameObjects,d3
	zfnfgt:	
			cmp.w #objectstate_active,gameobject_state(a0)
			bne   zactivespritet
			cmp.w #art_type_sprite,gameobject_art(a0)
			bne   zactivespritet
				move.l #spritesnoarr,a3
				move.w gameobject_spr(a0),d0
				cmp.w #0,d0
				blt   zactivespritet
				cmp.w #7,d0
				bgt   zactivespritet
					add.l d0,a3
					move.b #1,(a3)
	zactivespritet:
			sub.l #gameobject_size_bytes,a0
			dbra d3,fnfgt

			; find now a not used sprite
			move.l #7,d3
			move.l #spritesnoarr,a0
	rsprnot: 
			cmp.b #0,(a0)
			bne   tilt 
			  move.l a5,a0
			  move.w d3,gameobject_spr(a0)
			  jmp sorrynotfound
tilt:			
			add.l #1,a0
			dbra d3,rsprnot	

			move.l #0,a0

sorrynotfound:
	rts

	even



gameobject_size = 26 ; members 
gameobject_size_bytes = gameobject_size*2 ; gameobject_size * 2 ; word


gameobject_state equ 0
gameobject_x equ 1*2 
gameobject_y equ 2*2 
gameobject_x_expanded equ 3*2  ; expanded *3 etc for double or tripple precision
gameobject_y_expanded equ 4*2
gameobject_width equ 5*2
gameobject_height equ 6*2 
gameobject_colwidth equ 7*2
gameobject_colheight equ 8*2 
gameobject_type equ 9*2
gameobject_typesub equ 10*2  
gameobject_art equ 11*2   ; ; 1: sprite | 2 bob1616  - representations
gameobject_animtype equ 12*2  ; -- represented in a sprite
gameobject_animmin equ 13*2  ; -- represented in a sprite
gameobject_animmax equ 14*2  ; 
gameobject_animind equ 15*2 ;
gameobject_animindold equ 16*2 ;
gameobject_arg equ 17*2 ;
gameobject_behaviour equ 18*2 ;
gameobject_spr equ 19*2  ; -- represented in a sprite - use for orders!!!
gameobject_cat0 equ 20*2  ; -- represented in a sprite - use for orders!!! - often used for enemy/neutral
gameobject_cat1 equ 21*2  ; -- represented in a sprite - use for orders!!! - often used for health
gameobject_cat2 equ 22*2  ; -- represented in a sprite - use for orders!!! - example - speedx
gameobject_health equ 23*2  ; -- represented in a sprite - use for orders!!! - example - speedy
gameobject_argsub equ 24*2  ; -- represented in a sprite - use for orders!!!
gameobject_collision equ 25*2  ; -- represented in a sprite - use for orders!!!



; > update also length of a gameobject ^ up 

; object states 
objectstate_awake equ 2    ; init in awake 
objectstate_active equ 1
objectstate_inactive equ 0 ; moved to -16,-16 !

; gameobject_art type
art_type_neutral equ 0
art_type_sprite equ 1
art_type_bob1616 equ 2

; collision - gameobject to gameobject
collision_no equ 0
collision_yes equ 1

; cats
; cat0 used for friend enemy 
cat0_neutral equ 0
cat0_friend equ 1
cat0_enemy equ 2
cat0_bonus equ 3

; anim 
anim_indold_default equ 42000

atype_noanim equ 0
atype_loop equ 1
atype_once equ 2
atype_once_destroy equ 3



; sub
type_enemysub_leftright equ 0
type_enemysub_updown equ 1

; ------------------------
; block constants
; ------------------------
undestroyableBlockStart equ 72
undestroyableBlockStop equ 77
destroyBlockStart equ 84
destroyBlockStop equ 119

destroyableGrenadeFlyBlockStart equ 78
destroyableGrenadeFlyBlockStop equ 83

onestepDestroyedStart = 132
onestepDestroyedStop = 143


; ------------------------
; service types
; ------------------------
serviceInitGameObjectTypes:

		; jmp no_initspritetypes
		; objectstate_awake
		lea.l gameobjects,a6
		move.l #maxGameObjects,d7
abvxt:	
		move.l a6,a0	; pointers forever
		cmp.w  #objectstate_awake,gameobject_state(a6)
		bne.w    no_initspritetypes
		move.w #handle_init,handleState
		jsr handleGameObject

no_initspritetypes:
		add.l #gameobject_size_bytes,a6
		dbra d7,abvxt

	rts


; ------------------------
; type & handling
; ------------------------

	even

; move.w #handle_init,handleState
; move.l objextxyz,a0

handle_init = 0
handle_update = 1
handle_collision = 2

;	include "inc_gameobject_types.s"

; types
type_neutral = 0

type_transparent_animind = 1; transparent

type_avatar = 1

; avatar_mouse
type_avatar_mouse_atype = atype_noanim

; avatar
type_avatar_atype = atype_loop


; bonus
type_bonus = 2

; enemy
type_enemy = 3

; ball
type_ball = 4

; explosion
type_explosion = 5

; mouse
type_mouse = 6

; avatar 
type_avatar_mouse_ground = 7

; type_avatar_shootup
type_a_shootup = 8

; type_avatar_mouse_crosshair
type_avatar_mouse_crosshair = 9

type_a_shootflyup = 10

type_e_shootdown = 11

type_e_missile = 12 

type_unknown = 13

type_a_protect = 14

type_e_bouncer = 15

type_e_runner = 16

; explosion
type_explosion_defended = 17

; come from outside
type_e_outsider = 18

; explosion air
type_explosion_air = 19

; block_anim_startblock

type_e_airplane = 20

; ------------------------
handleGameObject:
; ------------------------



; in a0 pointer to the gameobject


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

	; ----------------------
	; default values!
	; ----------------------
	; default objects
	cmp.w #handle_init,handleState
	bne h_initall
	;	move.w #objectstate_active,gameobject_state(a6)		
		move.w #anim_indold_default,gameobject_animindold(a6)
		move.w #collision_no,gameobject_collision(a6)
		move.w #16,gameobject_width(a6)	
		move.w #16,gameobject_height(a6)	
		move.w #cat0_neutral,gameobject_cat0(a6)	
h_initall:

	; ----------------------
	; avatar 
	; ----------------------
	cmp.w #type_avatar_mouse_ground,gameobject_type(a6)
	bne.w h_avatar

		; init
		cmp.w #handle_init,handleState
		bne.w h_init_avatar
			move.w #objectstate_active,gameobject_state(a6)			
			move.w #cat0_friend,gameobject_cat0(a6)	
			move.w #1,gameobject_health(a6)
			move.w #collision_yes,gameobject_collision(a6)
			move.w #art_type_bob1616,gameobject_art(a6)
			move.w #atype_noanim,gameobject_animtype(a6)
			move.w #50,gameobject_animmin(a6)	
			move.w #50,gameobject_animind(a6)	
			move.w #51,gameobject_animmax(a6)	
			move.w #atype_loop,gameobject_animtype(a0)	

			jmp  end_handle		
	h_init_avatar:

		; update
		cmp.w #handle_update,handleState
		bne.w h_update_avatar_mouse_ground

			move.w MouseX,gameobject_x(a6)
			add.w  #32,gameobject_x(a6)

			; mouse clicked? (not mouse down)
			cmp.w  #1,mouseClicked
			bne.w    mouseclickedhere

				cmp.l  #2-1,gocounter
				bgt no_shooting_crosshair

					; jsr findNextFreeGameObject
					jsr findLastFreeGameObject
					cmp.l #0,a0
					beq   spawn_shoot

                        move.w #type_a_shootflyup,gameobject_type(a0)
        				move.w #objectstate_awake,gameobject_state(a0)
                        move.w gameobject_x(a6),gameobject_x(a0)
                        move.w gameobject_y(a6),gameobject_y(a0)
;                        move.l a6,a2
 ;                       add.l #gameobject_size,a2
  ;                      move.w gameobject_y(a2),gameobject_arg(a0)
                        move.w MouseY,gameobject_arg(a0)
                        ; add.w  #8,gameobject_arg(a0)		
                        ; add 
			spawn_shoot:
			mouseclickedhere:		
			
			jmp end_handle

		h_update_avatar_mouse_ground:
		
		cmp.w #handle_collision,handleState
		bne.w h_collision_avatar_mouse_ground

			cmp.w #cat0_enemy,gameobject_cat0(a5)
			bne.w   h_collision_avatar_mouse_ground

				sub.w #1,gameobject_health(a6)
				; move.w #3,gameobject_health(a0) ; lifes 
				; update lifes
				;move.l #18,number_x
				;move.l #0,number_y
				;move.l gameobject_health(a6),number_no
				;jsr drawNumbers
				
				move.w #type_explosion,gameobject_type(a6)
				move.w #objectstate_awake,gameobject_state(a6)

				move.w #type_explosion_air,gameobject_type(a5)
				move.w #objectstate_awake,gameobject_state(a5)

				; show it ... 

		h_collision_avatar_mouse_ground:

; ----------------------
h_avatar:
; ----------------------

; ----------------------
;  crosshair
; ----------------------
	cmp.w #type_avatar_mouse_crosshair,gameobject_type(a6)
	bne.w h_crosshair

		; init
		cmp.w #handle_init,handleState
		bne h_init_crosshair
			move.w #objectstate_active,gameobject_state(a6)			
			move.w #art_type_bob1616,gameobject_art(a6)
			move.w #atype_noanim,gameobject_animtype(a6)
			move.w #13,gameobject_animind(a6)	
			jmp  end_handle		
		h_init_crosshair:

		; update
		cmp.w #handle_update,handleState
		bne.w h_crosshair
			; no special thing

			move.w MouseX,gameobject_x(a6)
			add.w  #32,gameobject_x(a6)
			move.w MouseY,gameobject_y(a6)

			move.w #13,gameobject_animind(a6)	
			cmp.l  #2,gocounter
			blt no_shooting_crosshair
				move.w #5,gameobject_animind(a6)	
		no_shooting_crosshair:

; ----------------------
h_crosshair:
; ----------------------



; ----------------------
;  explosion
; ----------------------
	cmp.w #type_explosion,gameobject_type(a6)
	bne.w h_explosion

		; init
		cmp.w #handle_init,handleState,
		bne.w h_init_explosion
			move.w #objectstate_active,gameobject_state(a6)			
			move.w #art_type_bob1616,gameobject_art(a6)
			move.w #atype_once_destroy,gameobject_animtype(a6)
			move.w #24,gameobject_animmin(a6)
			move.w #24,gameobject_animind(a6)
			move.w #27,gameobject_animmax(a6)
			jmp  end_handle		
		h_init_explosion:

		; update
		cmp.w #handle_update,handleState,
		bne.w h_explosion

			; no special thing

; ----------------------
h_explosion:
; ----------------------

; ----------------------
;  explosion_defended
; ----------------------
	cmp.w #type_explosion_defended,gameobject_type(a6)
	bne.w h_explosion_defended

		; init
		cmp.w #handle_init,handleState,
		bne.w h_init_explosion_defended
			move.w #objectstate_active,gameobject_state(a6)			
			move.w #art_type_bob1616,gameobject_art(a6)
			move.w #atype_once_destroy,gameobject_animtype(a6)
			move.w #32,gameobject_animmin(a6)
			move.w #32,gameobject_animind(a6)
			move.w #35,gameobject_animmax(a6)
			jmp  end_handle		
		h_init_explosion_defended:

		; update
		cmp.w #handle_update,handleState,
		bne.w h_explosion_defended

			; no special thing
			sub.w  #1,gameobject_y(a6)

; ----------------------
h_explosion_defended:
; ----------------------

; ----------------------
;  explosion_air
; ----------------------
	cmp.w #type_explosion_air,gameobject_type(a6)
	bne.w h_explosion_air

		; init
		cmp.w #handle_init,handleState,
		bne.w h_init_explosion_air
			move.w #objectstate_active,gameobject_state(a6)			
			move.w #art_type_bob1616,gameobject_art(a6)
			move.w #atype_once_destroy,gameobject_animtype(a6)
			move.w #44,gameobject_animmin(a6)
			move.w #44,gameobject_animind(a6)
			move.w #47,gameobject_animmax(a6)
			jmp  end_handle		
		h_init_explosion_air:

		; update
		cmp.w #handle_update,handleState,
		bne.w h_explosion_air

			; no special thing

; ----------------------
h_explosion_air:
; ----------------------


; ----------------------
;  avatar shoot;
;  fly up
; ----------------------
	cmp.w #type_a_shootflyup,gameobject_type(a6)
	bne.w h_ashootflyup

		; init
		cmp.w #handle_init,handleState,
		bne.w h_init_ashootflyup

			move.w #objectstate_active,gameobject_state(a6)			
			move.w #art_type_bob1616,gameobject_art(a6)
			move.w #atype_once,gameobject_animtype(a6)
			move.w #19,gameobject_animmin(a6)	
			move.w #19,gameobject_animind(a6)	
			move.w #23,gameobject_animmax(a6)			
			jmp  end_handle		
		h_init_ashootflyup:

		; update
		cmp.w #handle_update,handleState
		bne h_ashootflyup

			sub.w #3,gameobject_y(a6)

			; stop fly blocks
			move.w gameobject_x(a6),levelBlockX
			move.w gameobject_y(a6),levelBlockY
			add.w  #8,levelBlockX
			add.w  #8,levelBlockY
			jsr getLevelBlock		
			; check if there is something
			; stop
			cmp.w #destroyableGrenadeFlyBlockStart-1,levelBlockIndex
			blt.w block_fly_stopable
			cmp.w #destroyableGrenadeFlyBlockStop+1,levelBlockIndex
			bgt.w block_fly_stopable				
				move.w #type_explosion_defended,gameobject_type(a6)
				move.w #objectstate_awake,gameobject_state(a6)


				; move.w #10,levelBlockIndex
				; jsr setdrawLevelBlockDoubleBuffering	
				jmp end_handle
            block_fly_stopable:


			clr.l d0
			move.w gameobject_y(a6),d0
			cmp.w gameobject_arg(a6),d0
			; cmp.w #50,d0
			bgt.w h_ashootflyup
				; change to explosion
				move.w #type_a_shootup,gameobject_type(a6)
				move.w #objectstate_awake,gameobject_state(a6)
				move.w #20,gameobject_arg(a6)

		jmp end_handle

; ----------------------
h_ashootflyup:
; ----------------------

; ----------------------
;  avatar shoot up
; destroyer
; ----------------------
	cmp.w #type_a_shootup,gameobject_type(a6)
	bne.w h_ashootup

		; init
		cmp.w #handle_init,handleState,
		bne.w h_init_ashootup

			move.w #objectstate_active,gameobject_state(a6)			
			move.w #cat0_friend,gameobject_cat0(a6)	
			move.w #collision_yes,gameobject_collision(a6)
            move.w #art_type_bob1616,gameobject_art(a0)
            move.w #atype_once,gameobject_animtype(a0)
            move.w #2,gameobject_animmin(a0)	
            move.w #2,gameobject_animind(a0)	
            move.w #4,gameobject_animmax(a0)	
			
			jmp  end_handle		
	
    	h_init_ashootup:

		; update
		cmp.w #handle_update,handleState
		bne h_update_ashootup

                    sub.w #2,gameobject_y(a6)
					
                    sub.w #1,gameobject_arg(a6)

                    cmp.w #1,gameobject_y(a6)
                    bgt.w supea
                        move.w #objectstate_inactive,gameobject_state(a6)
                        jmp end_handle
            supea:


                    cmp.w #1,gameobject_arg(a6)
                    bgt.w supe
                        ; change to explosion
                        move.w #objectstate_inactive,gameobject_state(a6)
                        jmp end_handle
            		supe:
                    ;move.w gameobject_x(a6),levelBlockX
                    ;add.w #8,levelBlockX
                    ;move.w gameobject_y(a6),levelBlockY
                    ;add.w #8,levelBlockY
                    ;jsr getLevelBlock
                    ;move.w #10,levelBlockIndex
                    ; jsr setdrawLevelBlockDoubleBuffering		

                    ; check destroy something on the ground ...
                    move.w gameobject_x(a6),levelBlockX
                    move.w gameobject_y(a6),levelBlockY
                    add.w  #8,levelBlockX
                    add.w  #8,levelBlockY
                    jsr getLevelBlock		

					; on/off switch barriere
					cmp.w #73,levelBlockIndex
					bne.w toggle_field
						move.w #229,levelBlockIndex
						jsr setdrawLevelBlockDoubleBuffering
						; disable ...
						move.w #type_explosion,gameobject_type(a6)
						move.w #objectstate_awake,gameobject_state(a6)
						jmp end_handle
					toggle_field:
					cmp.w #229,levelBlockIndex
					bne.w toggle_field_x
						move.w #73,levelBlockIndex
						jsr setdrawLevelBlockDoubleBuffering
						; disable ...
						move.w #type_explosion,gameobject_type(a6)
						move.w #objectstate_awake,gameobject_state(a6)
						jmp end_handle
					toggle_field_x:

                    ; set levelblock to something to debug
                    ; debug
                    ; move.w #10,levelBlockIndex
                    ; jsr setdrawLevelBlockDoubleBuffering		
                    
                    ; check if there is something
                    ; stop
                    cmp.w #undestroyableBlockStart-1,levelBlockIndex
                    blt.w block_stopable
                    cmp.w #undestroyableBlockStop+1,levelBlockIndex
                    bgt.w block_stopable
;                        move.w #objectstate_inactive,gameobject_state(a6)
						move.w #type_explosion_defended,gameobject_type(a6)
						move.w #objectstate_awake,gameobject_state(a6)

                        ; move.w #10,levelBlockIndex
                        ; jsr setdrawLevelBlockDoubleBuffering	
                        jmp end_handle
            block_stopable:
                    ; destroy ... 
                    cmp.w #objectstate_active,gameobject_state(a6)
                    bne.w block_destroyable
                        cmp.w #destroyBlockStart,levelBlockIndex
                        blt.w block_destroyable
                        cmp.w #destroyBlockStop,levelBlockIndex
                        bgt.w block_destroyable
                            
							add.w #12,levelBlockIndex
                            ; move.w #10,levelBlockIndex
                            ; add.w #8,levelBlockIndex
                            jsr setdrawLevelBlockDoubleBuffering	

							; explosion in grid?
							clr.l d0
							move.w levelBlock16X,d0
							mulu   #16,d0
							move.w d0,gameobject_x(a6)
							clr.l d0
							move.w levelBlock16Y,d0
							mulu   #16,d0
							move.w d0,gameobject_y(a6)


                            move.w #type_explosion,gameobject_type(a6)
                            move.w #objectstate_awake,gameobject_state(a6)


                            ;jsr findNextFreeGameObject
                            ;cmp.l #0,a0
                            ;beq   block_destroyablex
                          	;  move.w #objectstate_awake,gameobject_state(a0)
                          	;  move.w #type_e_shootdown,gameobject_type(a0)					
                          	;  move.w gameobject_x(a6),gameobject_x(a0)
                          	;  move.w gameobject_y(a6),gameobject_y(a0)

							; type_e_missile
                            ;jsr findNextFreeGameObject
                            ;cmp.l #0,a0
                            ;beq   block_destroyablex
                          	;  move.w #objectstate_awake,gameobject_state(a0)
                          	;  move.w #type_e_missile,gameobject_type(a0)					
                          	;  move.w gameobject_x(a6),gameobject_x(a0)
                          	;  move.w gameobject_y(a6),gameobject_y(a0)

						jmp end_handle
            block_destroyablex:
			block_destroyable:

				; destroy in one step
				cmp.w #onestepDestroyedStart,levelBlockIndex
				blt.w onstepdestroy
				cmp.w #onestepDestroyedStop,levelBlockIndex
				bgt.w onstepdestroy
					add.w #12,levelBlockIndex
                    jsr setdrawLevelBlockDoubleBuffering
					; disable ...
					move.w #type_explosion,gameobject_type(a6)
                    move.w #objectstate_awake,gameobject_state(a6)
					jmp end_handle
			onstepdestroy:


				

				; check for movable objects

				; -------------------
				; MOVABLE OBJECTS
				; -------------------
				; shoot next to the object moves it (stone)

;movable_block = 135		
;movable_block_replace = 132				

				
;				move.w gameobject_x(a6),levelBlockX
;				move.w gameobject_y(a6),levelBlockY
;				add.w  #8+16,levelBlockX
;				add.w  #8,levelBlockY
;				jsr getLevelBlock						
;				cmp.w #movable_block,levelBlockIndex
 ;               bne h_movableblocks_down_ashootup
;					add.l #1,d4
;					move.w #movable_block_replace,levelBlockIndex
;					jsr setdrawLevelBlockDoubleBuffering						
;					add.w #1,levelBlock16X
;					move.w #movable_block,levelBlockIndex
;					jsr setdrawLevelBlockDoubleBuffering						
;			    h_movableblocks_down_ashootup:

;				cmp.l #0,d4
;				bne h_movableblocks_ashootup
					;move.w #type_explosion,gameobject_type(a6)
	                ;move.w #objectstate_awake,gameobject_state(a6)
;					jmp end_handle							
;				h_movableblocks_ashootup:


				; move.w gameobject_x(a6),levelBlockX
				; move.w gameobject_y(a6),levelBlockY
				; add.w  #8,levelBlockX
				; add.w  #8,levelBlockY
				; jsr getLevelBlock
				; jsr setdrawLevelBlockDoubleBuffering	

		h_update_ashootup:

		; collision
		cmp.w #handle_collision,handleState
		bne.w h_ashootup

			cmp.w #type_a_protect,gameobject_type(a5)
			beq dothecollision

			; collision 
			cmp.w #cat0_enemy,gameobject_cat0(a5)
			bne.w   h_ne_ashootup

		dothecollision:

			move.w #1,gameobject_animind(a5)
			move.w #1,gameobject_animind(a6)



				move.w #objectstate_inactive,gameobject_state(a6)	

				move.w #type_explosion_air,gameobject_type(a5)
                move.w #objectstate_awake,gameobject_state(a5)

			h_ne_ashootup:

			jmp end_handle

		h_collision_ashootup:
		
		jmp end_handle

; ----------------------
h_ashootup:
; ----------------------


; ----------------------
; enemy
; ----------------------


; ----------------------
;  e shoot down
; ----------------------
	cmp.w #type_e_shootdown,gameobject_type(a6)
	bne.w h_eshootdown

		; init
		cmp.w #handle_init,handleState,
		bne.w h_init_h_eshootdown

			move.w #objectstate_active,gameobject_state(a6)			            
			move.w #cat0_enemy,gameobject_cat0(a6)
			move.w #collision_yes,gameobject_collision(a6)	
            move.w #art_type_bob1616,gameobject_art(a0)
            move.w #atype_noanim,gameobject_animtype(a0)
            move.w #9,gameobject_animind(a0)	
                        
			jmp  end_handle		
		h_init_h_eshootdown:

		; update
		cmp.w #handle_update,handleState
		bne h_eshootdown

            add.w #2,gameobject_y(a6)
            move.w gameobject_y(a6),d0
            cmp.w #avatar_y,gameobject_y(a6)
            blt.w supee
                ; change to explosion
                move.w #objectstate_awake,gameobject_state(a6)
                move.w #type_explosion,gameobject_type(a6)
                jmp end_handle
    supee:

		jmp end_handle

; ----------------------
h_eshootdown:
; ----------------------

; ----------------------
;  e missile
; ----------------------
	cmp.w #type_e_missile,gameobject_type(a6)
	bne.w h_emissile

		; init
		cmp.w #handle_init,handleState,
		bne.w h_init_h_emisslie

			move.w #objectstate_active,gameobject_state(a6)	
			move.w #cat0_enemy,gameobject_cat0(a6)	
			move.w #collision_yes,gameobject_collision(a6)
			move.w #art_type_bob1616,gameobject_art(a0)
			move.w #atype_noanim,gameobject_animtype(a0)
			move.w #16,gameobject_animind(a0)	

			jmp  end_handle		
		h_init_h_emisslie:

		; update
		cmp.w #handle_update,handleState
		bne h_emissile

				add.w #2,gameobject_y(a6)
				move.w gameobject_y(a6),d0
				cmp.w #avatar_y,gameobject_y(a6)
				blt.w supeee
					; change to explosion
					move.w #objectstate_awake,gameobject_state(a6)
					move.w #type_explosion,gameobject_type(a6)
					jmp end_handle
			supeee:	

				move.l playerAdress,a0
				; player
				move.w gameobject_x(a0),d0
				cmp.w gameobject_x(a6),d0
				blt.w h_emis_bigger
					add.w #1,gameobject_x(a6)
			h_emis_bigger:
				move.w gameobject_x(a0),d0
				cmp.w gameobject_x(a6),d0
				bgt.w h_emis_lower
					sub.w #1,gameobject_x(a6)
			h_emis_lower:

		jmp end_handle

; ----------------------
h_emissile:
; ----------------------


; ----------------------
;  e_airplane
; ----------------------
	cmp.w #type_e_airplane,gameobject_type(a6)
	bne.w h_airplane

		; init
		cmp.w #handle_init,handleState,
		bne.w h_init_h_airplane

			move.w #objectstate_active,gameobject_state(a6)	
			move.w #collision_yes,gameobject_collision(a6)
			move.w #cat0_enemy,gameobject_cat0(a6)	
            
			move.w #art_type_bob1616,gameobject_art(a0)
			move.w #atype_noanim,gameobject_animtype(a0)
			move.w #28,gameobject_animind(a0)	

			jmp  end_handle		
		h_init_h_airplane:

		; update
		cmp.w #handle_update,handleState
		bne h_airplane

				add.w #2,gameobject_y(a6)
				move.w gameobject_y(a6),d0
				
				; check under something ...
				
				move.w gameobject_x(a6),levelBlockX
				move.w gameobject_y(a6),levelBlockY
				add.w  #8,levelBlockX
				add.w  #2,levelBlockY
				jsr getLevelBlock	

				cmp.w #destroyableGrenadeFlyBlockStart-1,levelBlockIndex
				blt.w h_e_under_airplane
				cmp.w #destroyBlockStop+1,levelBlockIndex
				bgt.w h_e_under_airplane 
					move.w #36,gameobject_animind(a6)						
					jmp h_end_airplane
				h_e_under_airplane:
					move.w #28,gameobject_animind(a6)						
				h_end_airplane:

				; frame
				cmp.w #avatar_y,gameobject_y(a6)
				blt.w supeee_airplane
					; change to explosion
					move.w #objectstate_awake,gameobject_state(a6)
					move.w #type_explosion,gameobject_type(a6)
					jmp end_handle
			supeee_airplane:	




		jmp end_handle

; ----------------------
h_airplane:
; ----------------------

; ----------------------
;  a_protect
; ----------------------
	cmp.w #type_a_protect,gameobject_type(a6)
	bne.w h_protect

		; init
		cmp.w #handle_init,handleState,
		bne.w h_init_h_protect

			move.w #objectstate_active,gameobject_state(a6)	
			move.w #collision_yes,gameobject_collision(a6)
			move.w #cat0_friend,gameobject_cat0(a6)	

			move.w #0,gameobject_cat1(a6)	
			move.w #0,gameobject_cat2(a6)	

			move.w #art_type_bob1616,gameobject_art(a0)
			move.w #atype_noanim,gameobject_animtype(a0)
			move.w #atype_loop,gameobject_animtype(a0)	
			move.w #48,gameobject_animmin(a0)	
			move.w #48,gameobject_animind(a0)	
			move.w #49,gameobject_animmax(a0)	

			; *10
			clr.l d0
			move.w gameobject_x(a6),d0	
			mulu   #10,d0
			move.w  d0,gameobject_x_expanded(a6)
			clr.l  d0
			move.w gameobject_y(a6),d0	
			mulu   #10,d0
			move.w d0,gameobject_y_expanded(a6)

			jmp  end_handle		
		h_init_h_protect:

		; update
		cmp.w #handle_update,handleState
		bne h_protect

						; field before
						; create a line here ...
						; todo: better ! no so many updates
						; simple: get number of the tile
						; > same no > setup
					;	move.w gameobject_x(a6),levelBlockX
					;	move.w gameobject_y(a6),levelBlockY
					;	add.w  #8,levelBlockX
					;	add.w  #2,levelBlockY
					;	jsr getLevelBlock	
					;	clr.l d3
					;	move.w levelblockAbsFieldIndex,d3

												

				; expanded ... 
				move.w gameobject_cat1(a6),d0
				add.w d0,gameobject_x_expanded(a6)
				move.w gameobject_cat2(a6),d1
				add.w d1,gameobject_y_expanded(a6)
				
					
				
				; expanded to x,y
				clr.l d0
				move.w  gameobject_x_expanded(a6),d0
				divu   #10,d0
				move.w d0,gameobject_x(a6)
				clr.l d0
				move.w  gameobject_y_expanded(a6),d0
				divu   #10,d0
				move.w d0,gameobject_y(a6)	



						; field afterwards
					;	move.w gameobject_x(a6),levelBlockX
					;	move.w gameobject_y(a6),levelBlockY
					;	add.w  #8,levelBlockX
					;	add.w  #8,levelBlockY
					;	jsr getLevelBlock	

					;	cmp.w levelBlockIndex,d3
					;	beq   u_notanewfield_protect
					;		move.w #241,levelBlockIndex
					;		jsr setdrawLevelBlockDoubleBuffering	
					;	u_notanewfield_protect:

				; mine 
					move.w gameobject_x(a6),levelBlockX
					move.w gameobject_y(a6),levelBlockY
					add.w  #8,levelBlockX
					add.w  #8,levelBlockY
					jsr getLevelBlock	

					cmp.w #139,levelBlockIndex
					beq   mine_there
					cmp.w #140,levelBlockIndex
					beq   mine_there					
					jmp no_mine
					mine_there:
					
						add.w #12,levelBlockIndex
						jsr setdrawLevelBlockDoubleBuffering	
						move.w #objectstate_awake,gameobject_state(a6)	
						move.w #type_explosion,gameobject_type(a6)
					no_mine: 

					cmp.w #230,levelBlockIndex
					beq   mine_there_die
					cmp.w #140,levelBlockIndex
					beq   mine_there					
					jmp no_mine_die
					mine_there_die:					
						move.w #objectstate_awake,gameobject_state(a6)	
						move.w #type_explosion,gameobject_type(a6)
					no_mine_die: 


				; ... 
				cmp.w #avatar_y,gameobject_y(a6)
				blt.w h_notdown_protect
					move.w #objectstate_awake,gameobject_state(a6)
					move.w #type_explosion,gameobject_type(a6)
				h_notdown_protect:


				


				; stop and think
				clr.l d0
				move.w gameobject_x(a6),d0
				clr.l d1
				move.w gameobject_y(a6),d1

				; x%16==0 && y%16==0
				divu #16,d0
				swap d0
				ext.w d0
				cmp.w  #0,d0
				bne.w  h_nodecision_protect
				divu #16,d1
				ext.w d1
				swap d1
				cmp.w  #0,d1
				bne.w  h_nodecision_protect
					

							; check going down as often as possible
					; overwrite the rest
					move.w gameobject_x(a6),levelBlockX
					move.w gameobject_y(a6),levelBlockY
					add.w  #8,levelBlockX
					add.w  #16,levelBlockY
					jsr getLevelBlock		

					; LEFT
					cmp.w #0,gameobject_cat1(a6)
					bgt   h_tripleft_protect
					beq   h_tripleft_protect
					  	move.w gameobject_x(a6),levelBlockX
						move.w gameobject_y(a6),levelBlockY
						sub.w  #8,levelBlockX
						add.w  #8,levelBlockY
						jsr getLevelBlock	
						cmp.w #undestroyableBlockStart,levelBlockIndex
						blt.w h_tripleft_protect
						cmp.w #destroyBlockStop,levelBlockIndex
						bgt.w h_tripleft_protect
							move.w #3,gameobject_cat1(a6)
							move.w #0,gameobject_cat2(a6)
							jmp h_tripleftright_protect
					h_tripleft_protect:

					; RIGHT
					cmp.w #0,gameobject_cat1(a6)
					blt   h_tripright_protect
					beq   h_tripright_protect
					  	move.w gameobject_x(a6),levelBlockX
						move.w gameobject_y(a6),levelBlockY
						add.w  #16,levelBlockX
						add.w  #8,levelBlockY
						jsr getLevelBlock	
						cmp.w #undestroyableBlockStart,levelBlockIndex
						blt.w h_tripright_protect
						cmp.w #destroyBlockStop,levelBlockIndex
						bgt.w h_tripright_protect
							move.w #-3,gameobject_cat1(a6)
							move.w #0,gameobject_cat2(a6)
							jmp h_tripleftright_protect
					h_tripright_protect:

					h_tripleftright_protect:

					; AN OPEN FIELD DOWN?
					move.w gameobject_x(a6),levelBlockX
					move.w gameobject_y(a6),levelBlockY
					add.w  #8,levelBlockX
					add.w  #16,levelBlockY
					jsr getLevelBlock
					cmp.w #undestroyableBlockStart,levelBlockIndex
					blt.w h_nodecision_downfree_protect
					cmp.w #destroyBlockStop,levelBlockIndex
					bgt.w h_nodecision_downfree_protect	
						jmp h_nodecision_down_protect
					h_nodecision_downfree_protect:			
						; check left or right
						move.w #0,gameobject_cat1(a6)
						move.w #3,gameobject_cat2(a6)
						jmp end_handle
					h_nodecision_down_protect:

						; let's think about
						; move.w #0,gameobject_cat1(a6)
						; move.w #0,gameobject_cat2(a6)

					cmp.w #0,gameobject_cat1(a6)
					bne   h_nodecision_protect

						; rand left or right!
						jsr RndA 
						cmp.w #128,d0
						blt rand_right
						

						; left?
						move.w gameobject_x(a6),levelBlockX
						move.w gameobject_y(a6),levelBlockY
						sub.w  #8,levelBlockX
						add.w  #8,levelBlockY
						jsr getLevelBlock	
						cmp.w #undestroyableBlockStart,levelBlockIndex
						blt.w h_nodecision_leftfree_protect
						cmp.w #destroyBlockStop,levelBlockIndex
						bgt.w h_nodecision_leftfree_protect	
							jmp h_nodecision_leftf_protect
						h_nodecision_leftfree_protect:						
							; something else
							move.w #-3,gameobject_cat1(a6)
							move.w #0,gameobject_cat2(a6)
							jmp end_handle
						h_nodecision_leftf_protect:

						rand_right:

						; right?
						move.w gameobject_x(a6),levelBlockX
						move.w gameobject_y(a6),levelBlockY
						add.w  #16,levelBlockX
						add.w  #8,levelBlockY
						jsr getLevelBlock	
						cmp.w #undestroyableBlockStart,levelBlockIndex
						blt.w h_nodecision_rightfree_protect
						cmp.w #destroyBlockStop,levelBlockIndex
						bgt.w h_nodecision_rightfree_protect	
							jmp h_nodecision_rightf_protect
						h_nodecision_rightfree_protect:						
							; something else
							move.w #3,gameobject_cat1(a6)
							move.w #0,gameobject_cat2(a6)
							jmp end_handle
						h_nodecision_rightf_protect:
				


				h_nodecision_protect:

				; or in the middle? 

		jmp end_handle

; ----------------------
h_protect:
; ----------------------



; ----------------------
;  e_runner
; ----------------------
	cmp.w #type_e_runner,gameobject_type(a6)
	bne.w h_e_runner

		; init
		cmp.w #handle_init,handleState,
		bne.w ht_e_runner

			move.w #objectstate_active,gameobject_state(a6)	
			move.w #collision_yes,gameobject_collision(a6)
			move.w #cat0_enemy,gameobject_cat0(a6)	
            move.w #art_type_bob1616,gameobject_art(a0)
			move.w #atype_noanim,gameobject_animtype(a0)
			move.w #29,gameobject_animind(a0)	
			move.w #0,gameobject_arg(a0)	

			jmp  end_handle		
		ht_e_runner:

		; update
		cmp.w #handle_update,handleState
		bne h_e_runner

				add.w #1,gameobject_y(a6)

				; left <-> right
				; left
				cmp.w #0,gameobject_arg(a6)
				bne.w h_left_e_runner
					add.w #2,gameobject_x(a6)

					cmp.w #310,gameobject_x(a6)
					blt.w h_left_e_runner
						move.w #1,gameobject_arg(a6)					
					h_left_e_runner:
					
					move.w gameobject_x(a6),levelBlockX
					move.w gameobject_y(a6),levelBlockY
					add.w  #16,levelBlockX
					add.w  #8,levelBlockY
					jsr getLevelBlock	

					cmp.w #undestroyableBlockStart,levelBlockIndex
					blt.w h_left_ext_e_runner
					cmp.w #undestroyableBlockStop+1,levelBlockIndex
					bgt.w h_left_ext_e_runner
						move.w #1,gameobject_arg(a6)								
				h_left_ext_e_runner:

				; right
				cmp.w #1,gameobject_arg(a6)
				bne.w h_right_e_runner
					sub.w #2,gameobject_x(a6)
					cmp.w #10,gameobject_x(a6)
					bgt.w h_right_e_runner
						move.w #0,gameobject_arg(a6)					
					h_right_e_runner:
					
					move.w gameobject_x(a6),levelBlockX
					move.w gameobject_y(a6),levelBlockY
					add.w  #0,levelBlockX
					add.w  #8,levelBlockY
					jsr getLevelBlock	

					cmp.w #undestroyableBlockStart,levelBlockIndex
					blt.w h_right_ext_e_runner
					cmp.w #undestroyableBlockStop+1,levelBlockIndex
					bgt.w h_right_ext_e_runner
						move.w #0,gameobject_arg(a6)								
				h_right_ext_e_runner:


				move.w gameobject_y(a6),d0
				cmp.w #avatar_y,gameobject_y(a6)
				blt.w supeee_runner
					; change to explosion
					move.w #objectstate_awake,gameobject_state(a6)
					move.w #type_explosion,gameobject_type(a6)
					jmp end_handle
			supeee_runner:	




		jmp end_handle

; ----------------------
h_e_runner:
; ----------------------

; ----------------------
;  e_bouncer
; ----------------------
	cmp.w #type_e_bouncer,gameobject_type(a6)
	bne.w h_e_bouncer

		; init
		cmp.w #handle_init,handleState,
		bne.w ht_e_bouncer

			move.w #objectstate_active,gameobject_state(a6)	
			move.w #collision_yes,gameobject_collision(a6)
			move.w #cat0_enemy,gameobject_cat0(a6)	
            move.w #art_type_bob1616,gameobject_art(a0)
			move.w #atype_noanim,gameobject_animtype(a0)
			move.w #17,gameobject_animind(a0)	
			move.w #0,gameobject_arg(a0)	

			jmp  end_handle		
		ht_e_bouncer:

		; update
		cmp.w #handle_update,handleState
		bne h_e_bouncer

				; add.w #1,gameobject_y(a6)

				; left <-> right
				; left
				cmp.w #0,gameobject_arg(a6)
				bne.w h_left_e_bouncer
					add.w #2,gameobject_x(a6)

					cmp.w #310,gameobject_x(a6)
					blt.w h_left_e_bouncer
						move.w #1,gameobject_arg(a6)					
					h_left_e_bouncer:
					
					move.w gameobject_x(a6),levelBlockX
					move.w gameobject_y(a6),levelBlockY
					add.w  #16,levelBlockX
					add.w  #8,levelBlockY
					jsr getLevelBlock	

					cmp.w #undestroyableBlockStart-1,levelBlockIndex
					blt.w h_left_ext_e_bouncer
					cmp.w #destroyBlockStop+1,levelBlockIndex
					bgt.w h_left_ext_e_bouncer
						move.w #1,gameobject_arg(a6)								
						jsr checkLevelBlockAndDestroyBehaviour						
				h_left_ext_e_bouncer:

				; right
				cmp.w #1,gameobject_arg(a6)
				bne.w h_right_e_bouncer
					sub.w #2,gameobject_x(a6)
					cmp.w #10,gameobject_x(a6)
					bgt.w h_right_e_bouncer
						move.w #0,gameobject_arg(a6)					
					h_right_e_bouncer:
					
					move.w gameobject_x(a6),levelBlockX
					move.w gameobject_y(a6),levelBlockY
					add.w  #0,levelBlockX
					add.w  #8,levelBlockY
					jsr getLevelBlock	

					cmp.w #undestroyableBlockStart-1,levelBlockIndex
					blt.w h_right_ext_e_bouncer
					cmp.w #undestroyableBlockStop+1,levelBlockIndex
					bgt.w h_right_ext_e_bouncer
						jsr checkLevelBlockAndDestroyBehaviour						
						move.w #0,gameobject_arg(a6)								
				h_right_ext_e_bouncer:


				move.w gameobject_y(a6),d0
				cmp.w #avatar_y,gameobject_y(a6)
				blt.w supeee_bouncer
					; change to explosion
					move.w #objectstate_awake,gameobject_state(a6)
					move.w #type_explosion,gameobject_type(a6)
					jmp end_handle
			supeee_bouncer:	




		jmp end_handle

; ----------------------
h_e_bouncer:
; ----------------------

; ----------------------
;  e_outsider
; ----------------------
	cmp.w #type_e_outsider,gameobject_type(a6)
	bne.w h_outsider

		; init
		cmp.w #handle_init,handleState,
		bne.w h_init_h_outsider

			move.w #objectstate_active,gameobject_state(a6)	
			move.w #collision_yes,gameobject_collision(a6)
			move.w #cat0_enemy,gameobject_cat0(a6)	

			move.w #1,gameobject_health(a6)	

			; *5
			clr.l d0
			move.w gameobject_x(a6),d0	
			mulu   #5,d0
			move.w  d0,gameobject_x_expanded(a6)
			clr.l  d0
			move.w gameobject_y(a6),d0	
			mulu   #5,d0
			move.w d0,gameobject_y_expanded(a6)

			move.w #art_type_bob1616,gameobject_art(a0)
			move.w #atype_noanim,gameobject_animtype(a0)
			move.w #40,gameobject_animind(a0)	

			jmp  end_handle		
		h_init_h_outsider:

		; update
		cmp.w #handle_update,handleState
		bne h_outsider

		; jmp supeee_outsider

				; expanded ... 
				move.w gameobject_cat1(a6),d0
				add.w d0,gameobject_x_expanded(a6)
				move.w gameobject_cat2(a6),d1
				add.w d1,gameobject_y_expanded(a6)
				
				; check under something ...
				add.w d0,gameobject_x_expanded(a6)
				
				; expanded to x,y
				clr.l d0
				move.w  gameobject_x_expanded(a6),d0
				divu   #5,d0
				move.w d0,gameobject_x(a6)
				clr.l d0
				move.w  gameobject_y_expanded(a6),d0
				divu   #5,d0
				move.w d0,gameobject_y(a6)

				; create a line here ...
				

				; check here ... 

				; check area
				cmp.w #16,gameobject_x(a6)
				blt.w h_disable_h_outsider
				cmp.w #320,gameobject_x(a6)
				bgt.w h_disable_h_outsider
				cmp.w #5,gameobject_y(a6)
				blt.w h_disable_h_outsider
				cmp.w #256,gameobject_y(a6)
				bgt.w h_disable_h_outsider
				jmp h_disablenot_h_outsider
			h_disable_h_outsider:
					move.w #objectstate_inactive,gameobject_state(a6)
					jmp end_handle
			h_disablenot_h_outsider:

				; blockxy
				move.w gameobject_y(a6),d0
				
				move.w gameobject_x(a6),levelBlockX
				move.w gameobject_y(a6),levelBlockY
				add.w  #8,levelBlockX
				add.w  #2,levelBlockY
				jsr getLevelBlock	

				cmp.w #destroyableGrenadeFlyBlockStart-1,levelBlockIndex
				blt.w h_e_under_outsider
				cmp.w #destroyBlockStop+1,levelBlockIndex
				bgt.w h_e_under_outsider 
					move.w #41,gameobject_animind(a6)						
					jmp h_end_outsider
				h_e_under_outsider:
					move.w #40,gameobject_animind(a6)						
				h_end_outsider:

				; destroy ...
				cmp.w #objectstate_active,gameobject_state(a6)
                    bne.w block_outsider_destroyablex
                        cmp.w #destroyBlockStart,levelBlockIndex
                        blt.w block_outsider_destroyablex
                        cmp.w #destroyBlockStop,levelBlockIndex
                        bgt.w block_outsider_destroyablex
                            
							add.w #12,levelBlockIndex
                            ; move.w #10,levelBlockIndex
                            ; add.w #8,levelBlockIndex
                            jsr setdrawLevelBlockDoubleBuffering	

							; explosion in grid?
							clr.l d0
							move.w levelBlock16X,d0
							mulu   #16,d0
							move.w d0,gameobject_x(a6)
							clr.l d0
							move.w levelBlock16Y,d0
							mulu   #16,d0
							move.w d0,gameobject_y(a6)


                            move.w #type_explosion_air,gameobject_type(a6)
                            move.w #objectstate_awake,gameobject_state(a6)


                            ;jsr findNextFreeGameObject
                            ;cmp.l #0,a0
                            ;beq   block_destroyablex
                          	;  move.w #objectstate_awake,gameobject_state(a0)
                          	;  move.w #type_e_shootdown,gameobject_type(a0)					
                          	;  move.w gameobject_x(a6),gameobject_x(a0)
                          	;  move.w gameobject_y(a6),gameobject_y(a0)

							; type_e_missile
                            ;jsr findNextFreeGameObject
                            ;cmp.l #0,a0
                            ;beq   block_destroyablex
                          	;  move.w #objectstate_awake,gameobject_state(a0)
                          	;  move.w #type_e_missile,gameobject_type(a0)					
                          	;  move.w gameobject_x(a6),gameobject_x(a0)
                          	;  move.w gameobject_y(a6),gameobject_y(a0)


    	        block_outsider_destroyablex:
				block_outsider_destroyable:


				; frame
				cmp.w #avatar_y,gameobject_y(a6)
				blt.w supeee_outsider
					; change to explosion
					move.w #objectstate_awake,gameobject_state(a6)
					move.w #type_explosion,gameobject_type(a6)
					jmp end_handle
			supeee_outsider:	



		jmp end_handle

; ----------------------
h_outsider:
; ----------------------




; ----------------------
; init_not found
; ----------------------
	cmp.w #handle_init,handleState
	bne h_init_notfound
		
			move.w #type_unknown,gameobject_type(a6)
			move.w #art_type_bob1616,gameobject_art(a6)
			move.w #atype_noanim,gameobject_animtype(a6)
			move.w #1,gameobject_animind(a6)	

			move.w #20,gameobject_x(a6)	
			move.w #10,gameobject_y(a6)	
h_init_notfound:

; ----------------------
end_handle:
; ----------------------


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

	rts

; ------------------------
; behaviours
; ------------------------

checkLevelBlockAndDestroyBehaviour:

	; levelBlock16X
	cmp.w #destroyBlockStart,levelBlockIndex
	blt.w b_cdest
	cmp.w #destroyBlockStop,levelBlockIndex
	bgt.w b_cdest
		add.w #12,levelBlockIndex			
		jsr setdrawLevelBlockDoubleBuffering								
	b_cdest:

	rts

; ------------------------
; important vars
; ------------------------
	even
game_state dc.l 0
game_state_sub dc.l 0
game_state_sub_old dc.l 0

state_intro equ 0  ; title too
state_menu equ 1
state_ingame equ 2
state_gameover equ 3

; menu
menupoint_game_state_sub dc.l 1
menupoint_game_state_sub_old dc.l 42

statesub_main equ 0
statesub_story equ 1
statesub_howto equ 2
statesub_play equ 3
statesub_about equ 4 ; or credits
statesub_higscore equ 5

statesub_gameover equ 7
statesub_won equ 8

timer dc.l   0

; for counts timer + 1
timercounter:
	 dc.l 0
timestep:
 dc.l 400


level: 	dc.l 	0
level_old: 	dc.l 	0
level_maxbonus: dc.l 4

parselevel_address: dc.l 1

score: 	dc.l 	1
old_score: dc.l  0
hscore: dc.l 	50
lifes: 	dc.l 	3
health: dc.l 	100

scoredefault: 	dc.l 	0
hscoredefault: dc.l 	100
lifesdefault: 	dc.l 	3
healthdefault: dc.l 	100

animation: dc.l 0
animation_step: dc.l 5

handleState: dc.w 0

; playerAdress
playerAdress: dc.l  0

; gocounter
gocounter: dc.l 0

; targets

; protector game
protectsMax = 12
protectBlockStart = 84
protectBlockStop = 135 ; not used
even
protectIndex: dc.l 0

protectTargets:
	dc.w 2,10
	dc.w 10,12
	dc.w 5,5
	dc.w 20,5
	dc.w 0,0
	dc.w 0,0
	dc.w 0,0
	dc.w 0,0
	dc.w 0,0
	dc.w 0,0
	dc.w 0,0
	dc.w 0,0
	dc.w 0,0
	dc.w 0,0
	dc.w 0,0
	dc.w 0,0
	dc.w 0,0
	dc.w 0,0
	dc.w 0,0
	dc.w 0,0
	dc.w 0,0
	dc.w 0,0
	dc.w 0,0

; on platform
avatar_onplatform:
			dc.w  0			

; some bytes to jump ... 
jump_algo:      
    dc.b 0,6,6,5,5,5,5,3,3,3,3,2,2,2,2,2,2,1,1,1,1,0,0,0,0,0,0,0,42
    dc.b 0,6,5,5,3,3,2,2,2,1,1,0,0,0,0,0,0,0,42

; findsprite
spritesnoarr: dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

; ------------------------
; debug effect
; ------------------------
rainbow: 
		move.w    $DFF006,$DFF180 ; background
		rts

work_start: 
		move.w    $0,$DFF180 ; background
		rts

work_stop: 
		move.w    $DFF002,$DFF180 ; background
		rts

;======================================================================================================================
;  cryAengine: animate gameobjects
;======================================================================================================================

updateVisualsGameObjects:

		add.l #1,animation
		move.l animation,d0
		cmp.l animation_step,d0
		blt.w no_newanimstep
		move.l #0,animation

		; animate all of them
		move.l #maxGameObjects,d6 ; gameobjects_no
		lea.l gameobjects,a6
animfor:

		; is one object not active?
		; gameobject_state
		move.w gameobject_state(a6),d0
		cmp.w #objectstate_inactive,d0
		beq.w fanim_loop

		; no anim
		cmp.w #atype_noanim,gameobject_animtype(a6)
		bne.w fanim_no
fanim_no:

		; animloop
		cmp.w #atype_loop,gameobject_animtype(a6)
		bne.w fanim_loop
		; move.w #type_avatar_animind,gameobject_animind(a0)
		add.w #1,gameobject_animind(a6)
		move.w gameobject_animind(a6),d0
		sub.w #1,d0
		cmp.w gameobject_animmax(a6),d0
		blt.w fanim_loop 
		move.w gameobject_animmin(a6),d0
		move.w d0,gameobject_animind(a6)
fanim_loop:

; animonce
		cmp.w #atype_once,gameobject_animtype(a6)
		bne.w fanim_once
			add.w #1,gameobject_animind(a6)
			move.w gameobject_animind(a6),d0
			cmp.w gameobject_animmax(a6),d0
			blt.w fanim_once 
				move.w #atype_noanim,gameobject_animtype(a6)
fanim_once:

; animonce_destroy
		cmp.w #atype_once_destroy,gameobject_animtype(a6)
		bne.w fanim_once_destroy
		; move.w #type_avatar_animind,gameobject_animind(a0)
		add.w #1,gameobject_animind(a6)
		move.w gameobject_animind(a6),d0
		cmp.w gameobject_animmax(a6),d0
		blt.w fanim_once_destroy 
		move.w #objectstate_inactive,gameobject_state(a6)
fanim_once_destroy:


		add.l #gameobject_size_bytes,a6
		dbra d6,animfor

no_newanimstep:

		; ----------------------------
		; sprite animations & co
		; ----------------------------
		; render animation to sprite if needed!
		; check all sprites ... 


		move.l #maxGameObjects,d6 ; gameobjects_no
		lea.l gameobjects,a6
animspritefor:

		; is one object not active?
		; gameobject_state
		move.w gameobject_state(a6),d0
		cmp.w #objectstate_inactive,d0
		beq.w fanim_loop_sprite
		cmp.w #art_type_sprite,gameobject_art(a6)
		bne.w fanim_loop_sprite

		; find destination
			clr.l   d0
			move.w gameobject_animind(a6),d0		
			mulu   #sprite1-sprite0,d0
			move.l	#sprite0,a2		; destination
			add.l  d0,a2
			move.l a2,a4

		; data
			move.l #Spr0,a1
			move.w gameobject_spr(a6),d0 ; sprite number
			mulu   #SpriteData_End-Spr0,d0
			add.l  d0,a1			
			add.l  #4,a1
			moveq.l	#16-1,d2					; Sprite Image Data Lenght in Long Words
		directDataX:
			move.l	(a2)+,(a1)+					; Copy from Source to destination in Long Words
			dbra	d2,directDataX			; Loop Till we Copy

		;  copy colors

			add.l #spritevisualdata_object_bytes,a4
			move.l a4,a1 

			clr.l d5
			move.w gameobject_spr(a6),d5
			cmp.w #0,d5
			bne.w vnot0
			lea.l spritecolor_01_0,a4
			jmp vdoit
	vnot0:
			cmp.w #1,d5
			bne.w vnot1
			lea.l spritecolor_01_0,a4
			jmp vdoit
	vnot1:
			cmp.w #2,d5
			bne.w vnot2
			lea.l spritecolor_23_0,a4
			jmp vdoit
	vnot2:
			cmp.w #3,d5
			bne.w vnot3
			lea.l spritecolor_23_0,a4
			jmp vdoit
	vnot3:
			cmp.w #4,d5
			bne.w vnot4
			lea.l spritecolor_45_0,a4
			jmp vdoit
	vnot4:
			cmp.w #5,d5
			bne.w vnot5
			lea.l spritecolor_45_0,a4
			jmp vdoit
	vnot5:
			cmp.w #6,d5
			bne.w vnot6
			lea.l spritecolor_67_0,a4
			jmp vdoit
	vnot6:
			cmp.w #7,d5
			bne.w vnot7
			lea.l spritecolor_67_0,a4
			jmp vdoit
	vnot7:
			jmp vedoit

	vdoit:
			; copy colors
;			add.l #1,a2

			move.w (a2)+,(a4)
			add.l #4,a4
			move.w (a2)+,(a4)
			add.l #4,a4
			move.w (a2)+,(a4)
			add.l #4,a4
			move.w (a2)+,(a4)
	vedoit:

fanim_loop_sprite:
		add.l #gameobject_size_bytes,a6
		dbra d6,animspritefor

		; not anymore active? 
		; set to 0,0 or make it transparent ...


		
		rts


;======================================================================================================================
;  cryAengine: gameobjects array/list
;======================================================================================================================

	even
gameobjects:

gameobject0:
	dc.w 1    ; state
	gameobject0_x:
	dc.w 20   ; x
	gameobject0_y:
	dc.w 100   ; 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   ; animtype
	dc.w 0   ; animmin
	dc.w 0   ; animmax
	dc.w 0   ; animind
	dc.w 21000   ; animindold
	dc.w 1   ; arg
	dc.w 0   ; behavior
	dc.w 0   ; spr
	dc.w 0   ; cat0
	dc.w 0   ; cat1
	dc.w 0   ; cat2
	dc.w 0   ; argsub
	dc.w 1   ; collision


	; space for more gameobjects

	dcb.w	80*24*2,0


;======================================================================================================================
;  cryAengine: colors
;======================================================================================================================

		; --------------------------
		; behavior service
		; --------------------------

		; --------------------------
		; keys
		; --------------------------
		; http://www.whdload.de/docs/en/rawkey.html

		; https://www.stashofcode.fr/code/routines-pour-demomaker-sur-amiga/keyboard%20(polling).s


serviceKeyJoystickAndMouseUpdate:


		; check mouse and click
		
				move.w #0,mouseDown 
				move.w #0,mouseClicked

				; check mouse down & co
				btst   #6,$BFE001      ;  left mouse button ?
   				bne.s  c_mouseNotDown

					move.w #1,mouseDown

					cmp.w #0,mouseClickedHistory
					bne.w c_mouseNotDown
					move.w #1,mouseClicked
c_mouseNotDown:
				
				move.w mouseDown,mouseClickedHistory


		; use this not for debugging
		move.w #0,keyPressed

		bsr _keyboard

		; get keys
		jmp no_keysy
	 	move.l #5,number_x
		move.l #5,number_y
		clr.l d1
		move.w keyPressed,d1
		move.l d1,number_no
		jsr drawNumbers
no_keysy:


		; --------------------------
		; mouse control
		; --------------------------
	    jsr ReadMouse


		rts

;======================================================================================================================
;  cryAengine: colors
;======================================================================================================================

colorsTitleToBlack:

		IF ModeBlack

		move.l #15,d1
		lea.l InGameColors,a0

colsTo:		
		move.w (a0)+,d0
		move.w #$0,(a0)
		move.w (a0)+,d0
		dbra d1,colsTo

		ENDIF

		rts

colorsToBlack:

		IF ModeBlack

		move.l #15,d1
		lea.l InGameColors,a0
colsToB:		
		move.w (a0)+,d0
		move.w #$0,(a0)
		move.w (a0)+,d0
		dbra d1,colsToB

		ENDIF 

		rts		


colorsToGameColors:

		; a list 
		lea.l colors,a0						; Move to A0 since we will work with Address Register

		lea		InGameColors,a1			; Get the Address of where the colours are in the Copper list
		moveq	#15,d1						; Number of Colours
		addq.l	#2,a1							; Add 4 to the Copper list Address
nextcol:
		; move.w	d1,(a1)						; Copy the Word to teh Copper list Address Word
		move.w	(a0),(a1)						; Copy the Word to teh Copper list Address Word
		add.l	#2,a0							; Add 4 to the Copper list Address
		add.l	#4,a1							; Add 4 to the Copper list Address
		dbra	d1,nextcol					; Loop
nocopycolors:

		rts


colorsToGameColorsIntroScreen:

		; a list 
		lea.l IntroColors,a0						; Move to A0 since we will work with Address Register

		lea		InGameColors,a1			; Get the Address of where the colours are in the Copper list
		moveq	#15,d1						; Number of Colours
		addq.l	#2,a1							; Add 4 to the Copper list Address
nextcol2:
		; move.w	d1,(a1)						; Copy the Word to teh Copper list Address Word
		move.w	(a0),(a1)						; Copy the Word to teh Copper list Address Word
		add.l	#2,a0							; Add 4 to the Copper list Address
		add.l	#4,a1							; Add 4 to the Copper list Address
		dbra	d1,nextcol2					; Loop

		rts

;======================================================================================================================
;  cryAengine: sprites
;======================================================================================================================

; sorry for just copy and paste
; but i am tired of counting addresses

; setup addresses 

setupSprites
	

				; Sprite 0
				move.l	#Spr0,d0
				lea		SpritePointer0,a1
				move.w	d0,6(a1)
				swap	d0
				move.w	d0,2(a1)

				lea		sprite0,a2		; Source Address		
				add.l   #spritevisualdata_object_bytes,a2
				lea		Spr0_Data,a1		; DESTINATION Address
				bsr.w   copyVisualSpriteData			

				; colors
				lea	sprite0,a3		; Source Address		
				add.l #64,a3 
		;		add.l #spritevisualdata_object_bytes,a3
				lea.l spritecolor_01_0,a1 		
				move.w (a3)+,(a1)
				add.l #4,a1
				move.w (a3)+,(a1)
				add.l #4,a1
				move.w (a3)+,(a1)
				add.l #4,a1
				move.w (a3)+,(a1)

				lea		Spr0,a1
				move.w  #32,d0
				move.w  #32,d1
				move.w	#$10,d2
				bsr.w	MoveSprite


				; Sprite 1
				move.l	#Spr1,d0
				lea		SpritePointer1,a1
				move.w	d0,6(a1)
				swap	d0
				move.w	d0,2(a1)
				lea		sprite1,a2		; Source Address		
				add.l   #spritevisualdata_object_bytes,a2
				lea		Spr1_Data,a1		; DESTINATION Address
				bsr.w   copyVisualSpriteData			
				; colors
				lea	sprite1,a3		; Source Address		
				add.l #64,a3 
		;		add.l #spritevisualdata_object_bytes,a3
				lea.l spritecolor_01_0,a1 		
				move.w (a3)+,(a1)
				add.l #4,a1
				move.w (a3)+,(a1)
				add.l #4,a1
				move.w (a3)+,(a1)
				add.l #4,a1
				move.w (a3)+,(a1)
				lea		Spr1,a1
				move.w  #50,d0
				move.w  #50,d1
				move.w	#$10,d2
				bsr.w	MoveSprite

				; Sprite 2
				move.l	#Spr2,d0
				lea		SpritePointer2,a1
				move.w	d0,6(a1)
				swap	d0
				move.w	d0,2(a1)
				lea		sprite2,a2		; Source Address		
				add.l   #spritevisualdata_object_bytes,a2
				lea		Spr2_Data,a1		; DESTINATION Address
				bsr.w   copyVisualSpriteData			
				; colors
				lea	sprite2,a3		; Source Address		
				add.l #64,a3 
		;		add.l #spritevisualdata_object_bytes,a3
				lea.l spritecolor_01_0,a1 		
				move.w (a3)+,(a1)
				add.l #4,a1
				move.w (a3)+,(a1)
				add.l #4,a1
				move.w (a3)+,(a1)
				add.l #4,a1
				move.w (a3)+,(a1)
				lea		Spr2,a1
				move.w  #60,d0
				move.w  #60,d1
				move.w	#$10,d2
				bsr.w	MoveSprite

				; Sprite 3
				move.l	#Spr3,d0
				lea		SpritePointer3,a1
				move.w	d0,6(a1)
				swap	d0
				move.w	d0,2(a1)
				lea		sprite3,a2		; Source Address		
				add.l   #spritevisualdata_object_bytes,a2
				lea		Spr3_Data,a1		; DESTINATION Address
				bsr.w   copyVisualSpriteData			
				; colors
				lea	sprite3,a3		; Source Address		
				add.l #64,a3 
		;		add.l #spritevisualdata_object_bytes,a3
				lea.l spritecolor_01_0,a1 		
				move.w (a3)+,(a1)
				add.l #4,a1
				move.w (a3)+,(a1)
				add.l #4,a1
				move.w (a3)+,(a1)
				add.l #4,a1
				move.w (a3)+,(a1)
				lea		Spr3,a1
				move.w  #70,d0
				move.w  #70,d1
				move.w	#$10,d2
				bsr.w	MoveSprite			

				; Sprite 4
				move.l	#Spr4,d0
				lea		SpritePointer4,a1
				move.w	d0,6(a1)
				swap	d0
				move.w	d0,2(a1)
				lea		sprite4,a2		; Source Address		
				add.l   #spritevisualdata_object_bytes,a2
				lea		Spr4_Data,a1		; DESTINATION Address
				bsr.w   copyVisualSpriteData			
				; colors
				lea	sprite4,a3		; Source Address		
				add.l #64,a3 
		;		add.l #spritevisualdata_object_bytes,a3
				lea.l spritecolor_01_0,a1 		
				move.w (a3)+,(a1)
				add.l #4,a1
				move.w (a3)+,(a1)
				add.l #4,a1
				move.w (a3)+,(a1)
				add.l #4,a1
				move.w (a3)+,(a1)
				lea		Spr4,a1
				move.w  #80,d0
				move.w  #80,d1
				move.w	#$10,d2
				bsr.w	MoveSprite	

				; Sprite 5
				move.l	#Spr5,d0
				lea		SpritePointer5,a1
				move.w	d0,6(a1)
				swap	d0
				move.w	d0,2(a1)
				lea		sprite5,a2		; Source Address		
				add.l   #spritevisualdata_object_bytes,a2
				lea		Spr5_Data,a1		; DESTINATION Address
				bsr.w   copyVisualSpriteData			
				; colors
				lea	sprite5,a3		; Source Address		
				add.l #64,a3 
		;		add.l #spritevisualdata_object_bytes,a3
				lea.l spritecolor_01_0,a1 		
				move.w (a3)+,(a1)
				add.l #4,a1
				move.w (a3)+,(a1)
				add.l #4,a1
				move.w (a3)+,(a1)
				add.l #4,a1
				move.w (a3)+,(a1)
				lea		Spr5,a1
				move.w  #90,d0
				move.w  #90,d1
				move.w	#$10,d2
				bsr.w	MoveSprite	

				; Sprite 6
				move.l	#Spr6,d0
				lea		SpritePointer6,a1
				move.w	d0,6(a1)
				swap	d0
				move.w	d0,2(a1)
				lea		sprite6,a2		; Source Address		
				add.l   #spritevisualdata_object_bytes,a2
				lea		Spr6_Data,a1		; DESTINATION Address
				bsr.w   copyVisualSpriteData			
				; colors
				lea	sprite6,a3		; Source Address		
				add.l #64,a3 
		;		add.l #spritevisualdata_object_bytes,a3
				lea.l spritecolor_01_0,a1 		
				move.w (a3)+,(a1)
				add.l #4,a1
				move.w (a3)+,(a1)
				add.l #4,a1
				move.w (a3)+,(a1)
				add.l #4,a1
				move.w (a3)+,(a1)
				lea		Spr6,a1
				move.w  #100,d0
				move.w  #100,d1
				move.w	#$10,d2
				bsr.w	MoveSprite	

 				; Sprite 7
				move.l	#Spr7,d0
				lea		SpritePointer7,a1
				move.w	d0,6(a1)
				swap	d0
				move.w	d0,2(a1)
				lea		sprite7,a2		; Source Address		
				add.l   #spritevisualdata_object_bytes,a2
				lea		Spr7_Data,a1		; DESTINATION Address
				bsr.w   copyVisualSpriteData			
				; colors
				lea	sprite7,a3		; Source Address		
				add.l #64,a3 
		;		add.l #spritevisualdata_object_bytes,a3
				lea.l spritecolor_01_0,a1 		
				move.w (a3)+,(a1)
				add.l #4,a1
				move.w (a3)+,(a1)
				add.l #4,a1
				move.w (a3)+,(a1)
				add.l #4,a1
				move.w (a3)+,(a1)
				lea		Spr7,a1
				move.w  #110,d0
				move.w  #110,d1
				move.w	#$10,d2
				bsr.w	MoveSprite	

				; make transparent now ...


			rts

;======================================================================================================================
;  cryAengine: BOBs und BLOBS (copy into memory and redo)
;======================================================================================================================


BLTDDAT	=0	;result of the last word. used for bob collision detection and 
		;MFM decoding
DMACONR	=2	;bit 14=blitter busy flag

BLTCON0	=$40	;blitter operation setup
BLTCON1	=$42
BLTAFWM	=$44
BLTALWM	=$46

BLTCPTH	=$48	;sources, destination, and size
BLTCPTL	=$4a
BLTBPTH	=$4c
BLTBPTL	=$4e
BLTAPTH	=$50
BLTAPTL	=$52
BLTDPTH	=$54
BLTDPTL	=$56

BLTSIZE	=$58

BLTCON0L=$5a	;ECS/AGA registers
BLTSIZV	=$5c
BLTSIZH	=$5e

BLTCMOD	=$60	;modulos
BLTBMOD	=$62
BLTAMOD	=$64
BLTDMOD	=$66

BLTCDAT	=$70	;data to replace sources
BLTBDAT	=$72
BLTADAT	=$74

DMACON	=$96	;bit 6: enable blitter DMA. bit 10: give blitter priority over
		;the CPU.


BlitWait:
	
	movem.l	d0-d7/a0-a7,-(SP)

	lea $dff000,a6  ; blitter base 			

	tst DMACONR(a6)			;for compatibility
wait_blit:
	btst #6,DMACONR(a6)
	bne.s wait_blit

;	movem.l	d0-d7/a0-a7,-(SP)
	movem.l	(SP)+,d0-d7/a0-a7
	rts

; https://www.youtube.com/watch?v=OLhhgfnNo9A

; solve a puzzle
 
w	=320 ; 352?
h	=256


;======================================================================================================================
; cryAEngine: copyBlock1616BlockToScreen
;======================================================================================================================

cpScreen: dc.l 1
cpRasterX: dc.w 1 ; %16 
cpRasterY: dc.w 1 ; -- direct %16
cpRasterWidth: dc.w 16 ; %16 
cpRasterHeight: dc.w 16 ; %16 

cpScreenSource: dc.l 0


; copy now direct ... 
copyBlockRasterBackofficeToScreen:

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

		; source
		move.l #screenProduction,a5
		cmp.l #0,cpScreenSource
		beq usedefaultscreen
			move.l cpScreenSource,a5
usedefaultscreen:
		; destination
		move.l cpScreen,a4
		; offset
		clr.l  d0
		clr.l  d1
		move.w cpRasterX,d0		
		move.w cpRasterY,d1
		mulu   #(40+2*border_offset_byte)*screenFactorWidth*16,d1
		add.l  d0,d1 ; * 2
		add.l  d0,d1
		add.l d1,a5
		add.l d1,a4

		move.l #3,d7
cpblock:

		jsr BlitWait

		lea $dff000,a6  ; blitter base 			

		move.l #$09f00000,BLTCON0(a6); copy
		move.l #$ffffffff,BLTAFWM(a6) ; mask 

		move.l a5,BLTAPTH(a6); $dff054  ; high & low
		move.l a4,BLTDPTH(a6); $dff054  ; high & low
		move.w #(320*screenFactorWidth+2*border_offset-16)/8,BLTAMOD(a6); $dff066
		move.w #(320*screenFactorWidth+2*border_offset-16)/8,BLTDMOD(a6)
		; x. end
		move.w #16*64+16/16,BLTSIZE(a6) ; $dff058 ; set size		
		; *64 highword: height, lowword: width

		; all planes
		add.l #(40+2*border_offset_byte)*screenFactorWidth*256*screenFactorHeight,a5
		add.l #(40+2*border_offset_byte)*screenFactorWidth*256*screenFactorHeight,a4
		dbra d7,cpblock

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

		rts

;======================================================================================================================
; cryAEngine: copyBlockBob3216BlockToScreen
;======================================================================================================================

cpBobScreen: dc.l 1
cpBobRasterX: dc.w 1 ; %16 
cpBobY: dc.w 1 ; y-position
cpBobRasterWidth: dc.w 16 ; *16 2=(1+1)
cpBobRasterHeight: dc.w 16 ; %16 

cpBobScreenSource: dc.l 0


; copy now direct ... 
copyBlockBobRasterBackofficeToScreen:

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

		; source
		move.l #BackofficeBitplanes,a5
;		cmp.l #0,cpBobScreenSource
;		beq usedefaultscreenbob
;			move.l cpBobScreenSource,a5
;usedefaultscreenbob:
		; destination
		move.l cpBobScreen,a4
		; offset
		clr.l  d0
		clr.l  d1
		move.w cpBobRasterX,d0		
		move.w cpBobY,d1
		mulu   #2*border_offset_byte+40*screenFactorWidth,d1
		add.l  d0,d1 ; * 2
		add.l  d0,d1
		add.l d1,a5
		add.l d1,a4

		move.l #3,d7
cpblockbob:

		jsr BlitWait

		lea $dff000,a6  ; blitter base 			

		move.l #$09f00000,BLTCON0(a6); copy
		move.l #$ffffffff,BLTAFWM(a6) ; mask 

		move.l a5,BLTAPTH(a6); $dff054  ; high & low
		move.l a4,BLTDPTH(a6); $dff054  ; high & low
		move.w #(2*border_offset+320*screenFactorWidth-32)/8,BLTAMOD(a6); $dff066
		move.w #(2*border_offset+320*screenFactorWidth-32)/8,BLTDMOD(a6)
		; x. end
		move.w #16*64+32/16,BLTSIZE(a6) ; $dff058 ; set size		
		; *64 highword: height, lowword: width

		; all planes
		add.l #(2*border_offset_byte+40*screenFactorWidth)*256*screenFactorHeight,a5
		add.l #(2*border_offset_byte+40*screenFactorWidth)*256*screenFactorHeight,a4
		dbra d7,cpblockbob

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

		rts

;======================================================================================================================
; cryAEngine: copyImageDataToScreenDirect (320px > Border) 
;======================================================================================================================

; ressource
		lea GameScreenBitplanes,a5
		; target
		lea IntroScreen,a4
		; add offset! 

copyImageDataToScreenDirect:

		move.l #3,d7
copyscreen_aplanes_scr:

		jsr waitForBlitter

		; 1 - destination
		;         3210  
		; sources ABCD
		;         1001
		;         > 9 
		; copy from A pointer to D pointer!
		; move.l #$09000000,BLTCON0(a6);$dff040	mode	
		;          ^^ locial combination
		; https://www.youtube.com/watch?v=Iuxu3o8FZ-0 
		; MINDTERM
		;       ABCD  > D 
		;	0	000     0  
		;   1   001		0
		;   2   010		0
		;   3   011		0
		;   4   100 	1
		;   5   101		1
		;   6   110		1
		;   7   111 	1 < first bit
		;               ^ 8 bits
		;               > %111100000 > f0
		;       1001 > combine => 9
		;   A - SOURCE
		;   D - 
		move.l #$09f00000,BLTCON0(a6);$dff040 mode : combination + XORETC	
		move.l #$ffffffff,BLTAFWM(a6) ; mask 
		move.l a5,BLTAPTH(a6); $dff054  ; high & low
		; add.l  #0/8,BLTDPTH(a6) 
		move.l a4,BLTDPTH(a6); $dff054  ; high & low
		; add.l  #32/8,BLTDPTH(a6) 
		move.w #0,BLTAMOD(a6); $dff066
		move.w #4+4,BLTDMOD(a6) ; todo: add skip factor !!!
		; x. end
		; size the same ... not with border! 
		move.w #256*64+(320)/16,BLTSIZE(a6) ; $dff058 ; set size		
		; *64 highword: height, lowword: width

		; all planes
		add.l #40*256,a5
		add.l #(40+2*4)*screenFactorWidth*(256)*screenFactorHeight,a4

		dbra d7,copyscreen_aplanes_scr

		rts

;======================================================================================================================
; cryAEngine: copyScreen
;======================================================================================================================

; ressource
		lea GameScreenBitplanes,a5
		; target
		lea IntroScreen,a4

copyScreenDirect:

		move.l #3,d7
copyscreen_aplanes:

		jsr waitForBlitter

		; 1 - destination
		;         3210  
		; sources ABCD
		;         1001
		;         > 9 
		; copy from A pointer to D pointer!
		; move.l #$09000000,BLTCON0(a6);$dff040	mode	
		;          ^^ locial combination
		; https://www.youtube.com/watch?v=Iuxu3o8FZ-0 
		; MINDTERM
		;       ABCD  > D 
		;	0	000     0  
		;   1   001		0
		;   2   010		0
		;   3   011		0
		;   4   100 	1
		;   5   101		1
		;   6   110		1
		;   7   111 	1 < first bit
		;               ^ 8 bits
		;               > %111100000 > f0
		;       1001 > combine => 9
		;   A - SOURCE
		;   D - 
		move.l #$09f00000,BLTCON0(a6);$dff040 mode : combination + XORETC	
		move.l #$ffffffff,BLTAFWM(a6) ; mask 
		move.l a5,BLTAPTH(a6); $dff054  ; high & low
		move.l a4,BLTDPTH(a6); $dff054  ; high & low
		move.w #0,BLTAMOD(a6); $dff066
		move.w #0,BLTDMOD(a6)
		; x. end
		move.w #256*screenFactorHeight*64+(320*screenFactorWidth+2*border_offset)/16,BLTSIZE(a6) ; $dff058 ; set size		
		; *64 highword: height, lowword: width

		; all planes
		add.l #(40*screenFactorWidth+2*border_offset_byte)*256*screenFactorHeight,a5
		add.l #(40*screenFactorWidth+2*border_offset_byte)*256*screenFactorHeight,a4

		dbra d7,copyscreen_aplanes

		rts

nocopyscreen:


; copy data to 




;======================================================================================================================
;  cryAengine: bobs to raster (part of gameobjects!)
;======================================================================================================================
			even

bob1616raster_screen: dc.l 1
bob1616raster_id:	dc.w 0
bob1616raster_x:	dc.w 3   
bob1616raster_y:	dc.W 5 

renderBob1616ToRaster:

		movem.l	d0-d7/a0-a6,-(SP)
	
		move.l #3,d6
		move.l #bobs1616,a4 ; source
		clr.l  d0
		move.w bob1616raster_id,d0
;		mulu   #4*2*16,d0 ; size 16x 16 x planex= 2*3 *4 
		mulu   #5*(2+2)*16,d0 ; size 16x 16 x planex= 2*3 *4 
		add.l  d0,a4
		move.l bob1616raster_screen,a5 ; destination/target
allplanes:

		jsr waitForBlitter
		
		move.l #$09f00000,BLTCON0(a6) ; copy command a>d (zero shifting < > ) 
		move.l #$ffffffff,BLTAFWM(a6) ; mask 
		move.l a4,BLTAPTH(a6); $dff054  ; source
		; pos = 200*(320/8)+15/8
		clr.l  d0
		move.w bob1616raster_y,d0
		mulu   #16,d0
		; +2*border_offset_byte
		mulu   #40+2*border_offset_byte,d0
		add.w  bob1616raster_x,d0
		add.w  bob1616raster_x,d0
		move.l a5,d1
		add.l  d0,d1
		move.l d1,BLTDPTH(a6); target - screen
		
		move.w #2,BLTAMOD(a6); skip source (in bytes)
		; +2
		move.w #(320+2*border_offset-16)/8,BLTDMOD(a6); ; skip destination (in bytes)
		move.w #16*64+16/16,BLTSIZE(a6) ; size of the block (height*64 + wdith/16)		

; add.l #16*2,a4 ; next plane 
		add.l #16*(2+2),a4 ; next plane 
		add.l #(40+2*border_offset_byte)*256,a5 ; next plane destination

		dbra d6,allplanes


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

		rts 

;======================================================================================================================
;  cryAengine: bobs  (part of gameobjects!)
;======================================================================================================================

; https://www.stashofcode.fr/afficher-sprites-et-bobs-sur-amiga-2/
; https://eab.abime.net/showthread.php?t=68011
; https://www.stashofcode.fr/afficher-sprites-et-bobs-sur-amiga-2/
; https://www.markwrobel.dk/post/amiga-machine-code-letter7/
; https://codetapper.com/amiga/diary-of-a-game/menace/part-5-aliens-2/

			even

bob1616_screen: dc.l 0

bob1616_id:	dc.w 0
bob1616_x:	dc.w 10   
bob1616_y:	dc.W 10  

bob1616_x_raster: dc.w 10
bob1616_x_rest: dc.w 0



; two cases: %16==0
;            %16!=0 > shifting

renderBob1616:

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

	; debug
	;move.w #34,bob1616_y
	;move.w #17,bob1616_x
	move.w #0,bob1616_x_raster
	move.w #0,bob1616_x_rest

		; bob1616_x_raster
		clr.l  d0
		move.w bob1616_x,d0
; 		divu   #8,d0
		divu   #16,d0
		swap.w   d0
		move.w d0,bob1616_x_rest
		clr.w  d0
		swap.w   d0
		move.w d0,bob1616_x_raster

		; -----------------------
		; ... 
		; -----------------------
;		cmp.w #0,bob1616_x_rest
;		bne.w noCaseRest0

		
			; bob version
			; bobs
			move.l #3,d6

			; ...
			move.l #bobs1616,a4 ; source
			clr.l  d0
			move.w bob1616_id,d0
	;		mulu   #4*2*16,d0 ; size 16x 16 x planex= 2*3 *4 
			mulu   #5*(2+2)*16,d0 ; size 16x 16 x planex= 2*3 *4 
			add.l  d0,a4
			; mask .. 
			move.l a4,d0
			add.l  #4*(2+2)*16,d0
			move.l d0,a3
	
	; debug
	; move.l #bob1616_2,a4
	; move.l #bob1616_2_mask,a3

			move.l bob1616_screen,a5 ; destination/target
			; pos = 200*(320/8)+15/8
			clr.l  d0
			move.w bob1616_y,d0
			; mulu   #16,d0
			mulu   #40*screenFactorWidth+2*border_offset_byte,d0
			add.w  bob1616_x_raster,d0
			add.w  bob1616_x_raster,d0
			add.l  d0,a5

allplanes_1:

			jsr waitForBlitter

;			move.l #$01f00000,BLTCON0(a6) ; copy command a>d (zero shifting < > ) 
;			move.l #$1fca0000,BLTCON0(a6) ; copy command ba>cd (zero shifting < > ) 

			move.l #$ffff0000,BLTAFWM(a6) ; mask 

			clr.l d1
			move.w  bob1616_x_rest,d1 
			ror.w	#4,d1
			move.w	d1,BLTCON1(a6) ;  set up the B scroll value !!!! (forgotten)   --- was not set!!!! 4 
			or.w	#$0fca,d1	; 	set up the A scroll value and the
			move.w	d1,BLTCON0(a6)	;	minterm for D = notA.C + B
			
;		move.l #bob1616_1_mask,BLTAPTH(a6) ; source maske
			move.l a3,BLTAPTH(a6); ; source bitplane
		
			move.l a4,BLTBPTH(a6); ; source bitplane
		
			move.l a5,BLTCPTH(a6); target - screen - xor screen
			move.l a5,BLTDPTH(a6); target - screen
			
			move.w #0,BLTBMOD(a6); skip source (in bytes)			
			move.w #0,BLTAMOD(a6); skip source (in bytes)
			move.w #(320*screenFactorWidth+2*border_offset-(16+16))/8,BLTCMOD(a6); ; skip destination (in bytes)
			move.w #(320*screenFactorWidth+2*border_offset-(16+16))/8,BLTDMOD(a6); ; skip destination (in bytes)
			
			move.w #16*64+(16+16)/16,BLTSIZE(a6) ; size of the block (height*64 + wdith/16)		

	; add.l #16*2,a4 ; next plane 
			add.l #16*(2+2),a4 ; next plane  source
			add.l #(40+2*border_offset_byte)*screenFactorWidth*256*screenFactorHeight,a5 ; next plane destination

			dbra d6,allplanes_1

endCases:

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

		rts 







;======================================================================================================================
;  cryAengine: levels
;======================================================================================================================

actualLevelIndex: dc.l 0


; load into the actual level
loadActualLevel:


	; needed? > do it in the init

;	; clear all vars 
;	move.l #0,d4
;	move.l #10,d4
;clvarlay: 	
;	move.l #16*screenFactorHeight,d6
;clvarsy: 	
;	move.l #16*screenFactorHeight,d5
;clvarsx: 	

;	move.w d4,levelBlockVarLayer	
;	move.w d5,levelBlock16X
;	move.w d6,levelBlock16Y
;	jsr setLevelBlockVar
;
;	dbra d5,clvarsx
;	dbra d6,clvarsy
;	dbra d4,clvarlay


	; ---------------------
	; load concrete level
	; ---------------------
	lea.l levels,a1
	move.l actualLevelIndex,d0
	cmp.l #0,d0
	beq nocounting_levelsx
	sub.l #1,d0
adac_countingx:
	add.l #20*screenFactorWidth*16*screenFactorHeight+2,a1
	dbra d0,adac_countingx 	
nocounting_levelsx:

	; copy to 0,0, xyz ,0,0
	move.l #levelHeight-1,d1
	lea.l actualLevel,a2 
dcpy:
	; start new ... 
	move.b #0,(a2)+
	move.b #0,(a2)+

	move.l #20*screenFactorWidth-1,d2		
dcpx: 	
	move.b (a1)+,(a2)+
	dbra d2,dcpx

	; end
	move.b #0,(a2)+ ; i don't understand this! 
	move.b #0,(a2)+

	
	dbra d1,dcpy

	rts

; parse level .. 
parseLevel:

	; protectgame
	move.l #0,protectIndex

	move.l #(4+levelWidth)*levelHeight,d6
	move.l #0,d5
	move.l #0,d4
	move.l #0,d3
	move.l #0,d2 
	lea.l actualLevel,a6	
plevel:
	move.l #0,d4
	move.b (a6),d4

	

	; create objects
	; 56:0 - 71 - 15
	cmp.b #56,d4
	blt.b  foundnoobjectgameobject
	cmp.b #71,d4
	bgt.b  foundnoobjectgameobject

		; todo fix here ... 
		move.b 1(a6),(a6)
;		move.b #2,(a6)

		; search next free ... 
		jsr findNextFreeGameObject
		cmp.l #0,a0
		beq  foundnoobjectgameobject

			sub.l  #56,d4
			move.w d4,gameobject_type(a0)
			move.w #objectstate_awake,gameobject_state(a0)
			
			move.l d5,d0
			divu #2*border_offset_word+20*screenFactorWidth,d0
			swap d0
			clr.w d0
			swap d0
			mulu #16,d0
			move.w d0,gameobject_y(a0)

			move.l d5,d0
			divu #2*border_offset_word+20*screenFactorWidth,d0
			clr.w d0
			swap d0
			mulu #16,d0
;			add.w #16,d0
			move.w d0,gameobject_x(a0)


foundnoobjectgameobject:

		; reset
		cmp.w #252,d4
		bne   i_protect_house
				move.w d2,levelBlock16X
				move.w d3,levelBlock16Y
				move.w #0,levelBlockVarLayer
				move.w #0,levelBlockVar
				jsr setLevelBlockVar
i_protect_house:

		; count protection areas .. 
		; parse game
	; jmp nousedthis
		cmp.w #protectBlockStart,d4
		beq  protect_it
		cmp.w #protectBlockStart+12,d4
		beq  protect_it
		cmp.w #protectBlockStart+24,d4
		beq  protect_it
		jmp nothingtoprotect
protect_it:
			move.l #protectTargets,a1
			move.l protectIndex,d0
	; move.l #0,d0			
			mulu #4,d0
			add.l d0,a1

			move.w d2,(a1)
			move.w d3,2(a1)

			add.l #1,protectIndex			
		nothingtoprotect:		
nousedthis:


		; create 16x,16y 
		add.l #1,d2
		cmp.l #border_offset_word*2+20*screenFactorWidth,d2
		bne   nnextline
			move.l #0,d2
			add.l #1,d3
		nnextline:

	add.l #1,d5
	add.l #1,a6
	dbra d6,plevel

	rts

; draw the actual level
drawLevel:

	move.l #levelHeight-1,d7
	
	lea.l actualLevel,a4

	move.l #0,d5
ly:
	move.w d5,blocky
	move.l #(4+levelWidth)-1,d6
	move.l #0,d4
lx:
	move.w d4,blockx
	; add.w  #border_offset_word,blockx ; +border
	clr.l  d0
	move.b (a4)+,d0
	move.w d0,blockno
	; jsr drawBlockXY ; 68k version
	jsr renderBlockRasterBlitter
	add.l #1,d4
	dbra d6,lx

	add.l #1,d5	
	dbra d7,ly

	rts


	even

;======================================================================================================================
;  cryAengine: get Level Block (XY) etc
;======================================================================================================================
	even

; input
levelBlockX:
	dc.w 0
levelBlockY:
	dc.w 0

; input/output
levelBlockIndex:
	dc.w 0

levelBlock16X:
	dc.w 0
levelBlock16XRest:
	dc.w 0

levelBlock16Y:
	dc.w 0
levelBlock16YRest:
	dc.w 0

levelBlockAddress:
	dc.l 0

; setLevelBlockDoubleBuffering
setdrawLevelBlockDoubleBuffering:
	
	movem.l	d1-d7/a1-a7,-(SP)


	move.l #screenProduction,blockscreen

	move.w levelBlockIndex,blockno
	move.w levelBlock16X,blockx
	move.w levelBlock16Y,blocky

	jsr setLevelBlock

	
	move.w levelBlock16X,blockx
	move.w levelBlock16Y,blocky
	jsr drawBlockXY

	move.w levelBlock16X,dbManagementX
	move.w levelBlock16Y,dbManagementY
	jsr managementDoubleBufferingAddBlock

		movem.l	(SP)+,d1-d7/a1-a7

	rts


; must not be double buffered
; direct ... 
; should be input levelBlock16X and levelBlock16Y !!! 

; levelBlock16X
; levelBlock16Y

setLevelBlock:

	lea.l actualLevel,a0
	clr.l d0
	move.w levelBlock16Y,d0
	mulu #2*border_offset_word+20*screenFactorWidth,d0
	clr.l d1
	move.w levelBlock16X,d1
	add.l d1,d0
	add.l d0,a0
	clr.l d0
	move.w levelBlockIndex,d0
	move.b d0,(a0)

	rts
	
; x pos and y pos like 121 etc 

; input levelBlockX,levelBlockY

levelblockAbsFieldIndex: dc.w 0

getLevelBlock:

		movem.l	d1-d7/a0-a7,-(SP)


		clr.l d0
		move.w levelBlockX,d0
		divu #16,d0
		move.w d0,levelBlock16X
		swap d0
		move.w d0,levelBlock16XRest

		clr.l d0
		move.w levelBlockY,d0
		divu #16,d0
		move.w d0,levelBlock16Y
		swap d0
		move.w d0,levelBlock16YRest

		; levelblockAbsField


		; now create the address
		clr.l d0
		move.w levelBlock16Y,d0
		mulu #(2*border_offset_word)+20*screenFactorWidth,d0
		add.w levelBlock16X,d0

		move.w d0,levelblockAbsFieldIndex

		lea.l actualLevel,a0
		add.l d0,a0

		clr.l d0
		move.b (a0),d0
		move.w d0,levelBlockIndex

		move.l a0,levelBlockAddress

		movem.l	(SP)+,d1-d7/a0-a7


		rts

getLevelBlock16:

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


		; now create the address
		clr.l d0
		move.w levelBlock16Y,d0
		mulu #(2*border_offset_word)+20*screenFactorWidth,d0
		add.w levelBlock16X,d0

		move.w d0,levelblockAbsFieldIndex

		lea.l actualLevel,a0
		add.l d0,a0

		clr.l d0
		move.b (a0),d0
		move.w d0,levelBlockIndex

		move.l a0,levelBlockAddress

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


		rts

;======================================================================================================================
;  cryAengine: block animations
;======================================================================================================================

				
activateMousePointer:


	rts

;======================================================================================================================
;  cryAengine: block animations
;======================================================================================================================
; animate actual level 
; one animation 4 blocks
					even
block_anim_index: dc.l 0
block_anim_speed: dc.l 6

block_anim_startblock: dc.l 156 ; -1
block_anim_stopblock: dc.l 179 ;+1

block_bounce_start equ 80
block_bounce_stop equ 119

block_platform_start equ 79
block_platform_stop equ 87

block_collect_start equ 104
block_collect_stop equ 111
block_collect_replace equ 66 


; todo: xscroll
updateBlockAnimationBehavior:

	add.l  #1,block_anim_index
	move.l block_anim_speed,d0
	cmp.l  block_anim_index,d0
	bne no_blockanimation
	move.l #0,block_anim_index	

	; move.l #16*screenFactorHeight-1,d7
	move.l #16,d7

	lea.l actualLevel,a4

	; add here ...
	clr.l d0
	move.w scrollX,d0
	divu #16,d0
	clr.w d0
	mulu #2*border_offset_word+20*screenFactorWidth,d0
	add.l d0,a4

; scrollX: dc.w 0
; scrollY: dc.w 0
; hscrollX: dc.w 2001
; hscrollY: dc.w 2001   
 
	; d6
	; d7

	move.l #0,d5
bly:
	move.w d5,blocky
	move.l #(2*border_offset_word+20*screenFactorWidth)-1,d6

	move.l #0,d4
blx:
	move.w d4,blockx
	clr.l  d0
	move.b (a4)+,d0
	
	move.l block_anim_startblock,d1
	cmp.b d0,d1
	bhi.b notimp
	move.l block_anim_stopblock,d1
	cmp.b d0,d1
	bcs.b notimp

	; animate now ...
	add.b #1,d0

	; %4 
	clr.l d1
	move.b d0,d1
	divu #4,d1
	swap d1 ; %
	cmp.w #0,d1
	bne.w not_4
	
	clr.l d0
	move.b -1(a4),d0
	divu #4,d0
	mulu #4,d0
	; move.b #120,d0

not_4: 
	move.b d0,-1(a4)
	move.w d0,blockno

	;jsr drawBlockXY
	; set block
	move.w blockno,levelBlockIndex
	move.w blockx,levelBlock16X
	move.w blocky,levelBlock16Y
	jsr setdrawLevelBlockDoubleBuffering

notimp:

	; --------------------------------------
	; BLOCK BEHAVIOR
	; --------------------------------------
	; update behaviors
	; d4,d5,a4
	; jsr updateBlockBehavior

		move.b (a4),d0

		move.w d4,levelBlock16X
		move.w d5,levelBlock16Y

		; --------------------------------------
		; SIMPLE SPAWNER
		; --------------------------------------
		cmp.b #93,d0
		bne.b no_spawner
			; spawner
			;move.w blockx,levelBlock16X
			;move.w blocky,levelBlock16Y
			;move.w #1,levelBlockIndex
			;jsr setdrawLevelBlockDoubleBuffering
			
			move.w d4,levelBlock16X
			move.w d5,levelBlock16Y
			

			move.w #0,levelBlockVarLayer
			jsr getLevelBlockVar
			add.w #1,levelBlockVar
			jsr setLevelBlockVar

			cmp.w #90,levelBlockVar
			blt.w noshot
				move.w #0,levelBlockVar
				move.w #0,levelBlockVarLayer
				jsr setLevelBlockVar
				
				jsr findNextFreeGameObject
				cmp.l #0,a0
				beq   noshot
					move.w #type_e_airplane,gameobject_type(a0)
					move.w #objectstate_awake,gameobject_state(a0)
					clr.l d0
					move.w blockx,d0
					add.w  #1,d0
					mulu #16,d0
					move.w d0,gameobject_x(a0)
					clr.l d0
					move.w blocky,d0
					mulu #16,d0
					move.w d0,gameobject_y(a0)
		noshot:
		jmp end_blockbehavior
		no_spawner:

		; --------------------------------------
		; SIMPLE SPAWNER
		; --------------------------------------
		cmp.b #89,d0
		bne no_spawner_m
			; spawner
			;move.w blockx,levelBlock16X
			;move.w blocky,levelBlock16Y
			;move.w #1,levelBlockIndex
			;jsr setdrawLevelBlockDoubleBuffering

			move.w #0,levelBlockVarLayer
			jsr getLevelBlockVar
			add.w #1,levelBlockVar
			jsr setLevelBlockVar

			cmp.w #40,levelBlockVar
			blt.w noshot_no_spawner_m
				move.w #0,levelBlockVar
				jsr setLevelBlockVar
				
				jsr findNextFreeGameObject
				cmp.l #0,a0
				beq   noshot_no_spawner_m
					move.w #type_e_runner,gameobject_type(a0)
					move.w #objectstate_awake,gameobject_state(a0)
					clr.l d0
					move.w blockx,d0
					add.w  #1,d0
					mulu #16,d0
					move.w d0,gameobject_x(a0)
					clr.l d0
					move.w blocky,d0
					mulu #16,d0
					move.w d0,gameobject_y(a0)
		noshot_no_spawner_m:
	jmp end_blockbehavior
	no_spawner_m:


			; --------------------------------------
			; homebase
			; --------------------------------------
			cmp.b #84,d0
			beq no_homebase_m_do
			cmp.b #96,d0
			beq no_homebase_m_do
			cmp.b #108,d0
			beq no_homebase_m_do

			jmp no_homebase_m
			no_homebase_m_do:

				; homebase
				;move.w blockx,levelBlock16X
				;move.w blocky,levelBlock16Y
				;move.w #1,levelBlockIndex
				;jsr setdrawLevelBlockDoubleBuffering

				move.w #0,levelBlockVarLayer
				jsr getLevelBlockVar
				add.w #1,levelBlockVar
				jsr setLevelBlockVar

				; todo: random
				; 
				cmp.w #20,levelBlockVar
				blt.w noshot_no_homebase_m
					move.w #0,levelBlockVar
					jsr setLevelBlockVar

	; jmp no_homebase_m					

					jsr findNextFreeGameObject
					cmp.l #0,a0
					beq   noshot_no_homebase_m
						move.w #type_a_protect,gameobject_type(a0)
						move.w #objectstate_awake,gameobject_state(a0)
						clr.l d0
						move.w blockx,d0
						add.w  #1,d0
						mulu #16,d0
						move.w d0,gameobject_x(a0)
						clr.l d0
						move.w blocky,d0
						mulu #16,d0
						add.w #16,d0
						move.w d0,gameobject_y(a0)
			noshot_no_homebase_m:
			jmp end_blockbehavior
			no_homebase_m:


		; --------------------------------------
		; FROM OUTSIDE
		; --------------------------------------
		cmp.b #252,d0
		bne no_outsider
			; spawner
			;move.w blockx,levelBlock16X
			;move.w blocky,levelBlock16Y
			;move.w #1,levelBlockIndex
			;jsr setdrawLevelBlockDoubleBuffering
			
			move.w d4,levelBlock16X
			move.w d5,levelBlock16Y
			move.w #0,levelBlockVarLayer
			jsr getLevelBlockVar
			add.w #1,levelBlockVar
			jsr setLevelBlockVar

			cmp.w #20,levelBlockVar
			blt.w noshot_outsider
				move.w #0,levelBlockVar
				jsr setLevelBlockVar
				
				jsr findNextFreeGameObject
				cmp.l #0,a0 
				beq   noshot_outsider
					; type_e_outsider / type_explosion
					move.w #type_e_outsider,gameobject_type(a0)
					move.w #objectstate_awake,gameobject_state(a0)
					clr.l d0
					move.w blockx,d0
					add.w  #1,d0
					mulu #16,d0
					move.w d0,gameobject_x(a0)
					clr.l d0
					move.w blocky,d0
					mulu #16,d0
					move.w d0,gameobject_y(a0)

					; random x
					jsr RndA 
					cmp.w #128,d0
					blt b_outsider_lower
						jsr RndA ; 0-255 in d0
							; ext.w d0
							; sub.w #128,d0
							divu.w #8,d0
							clr.w d0
							swap d0
							muls   #-1,d0
							move.w d0,gameobject_cat1(a0)
						jmp b_outsider_higher
					b_outsider_lower:
						jsr RndA ; 0-255 in d0
							; ext.w d0
							; sub.w #128,d0
							divu.w #8,d0
							clr.w d0
							swap d0
							move.w d0,gameobject_cat1(a0)
					b_outsider_higher:
					; random y
					jsr RndA ; 0-255 in d0
						; ext.w d0
						divu.w #7,d0
						clr.w d0
						swap d0
						move.w d0,d1
						add.w #2,d1
						move.w d1,gameobject_cat2(a0)
					; move.w #5,gameobject_cat2(a0)

					; move.l protectIndex,d0

;					move.w #1,levelBlockVarLayer
;					jsr getLevelBlockVar
;					add.w #1,levelBlockVar
;					jsr setLevelBlockVar
;
;					cmp.w #protectsMax,levelBlockVar
;					blt   b_startnew_outsider_higher
;						add.w #1,levelBlockVar
;						jsr setLevelBlockVar
;			b_startnew_outsider_higher:
;					; move.l protectIndex,d0
;					clr.l d0
;					move.w levelBlockVar,d0
;					; move.w #0,d0 ; area - actual ... index
;					;
					
					move.l #protectTargets,a1

					; use random
					clr.l d0
				;	move.w  #0,d0
					
					jsr RndA
					move.l protectIndex,d1
					; add.l #1,d1
					divu d1,d0
					clr.w d0
					swap d0

					mulu #4,d0
					add.l d0,a1

					move.w (a1),d0
					move.w  d0,levelBlock16X
					mulu #16,d0
					; add.l #8,d0
					move.w 2(a1),d1
					move.w  d1,levelBlock16Y
					mulu #16,d1
					; add.l #16,d1

					; check if there ...
					; otherwise throw it on the player
					; check them
					jsr getLevelBlock16		

						cmp.w #protectBlockStart,levelBlockIndex
						beq  protect_it_now
						cmp.w #protectBlockStart+12,levelBlockIndex
						beq  protect_it_now
						cmp.w #protectBlockStart+24,levelBlockIndex
						beq  protect_it_now
							move.w #type_e_shootdown,gameobject_type(a0)
							move.l playerAdress,a1
							move.w gameobject_x(a1),gameobject_x(a0)
							move.w #0,gameobject_y(a0)
						jmp end_blockbehavior
						protect_it_now:						
					nothing_more_toprotect:	

				; target point
			; move.w #200,d0
			; move.w #100,d1

					mulu.w #5,d0
					mulu.w #5,d1
					; go back
					move.l #0,d2
				goback:
					sub.w gameobject_cat1(a0),d0
					sub.w gameobject_cat2(a0),d1
					

					; x
					cmp.w #32*5,d0
					blt.w  found_outside
					cmp.w #(320+32)*5,d0
					bgt.w  found_outside
					; y
					cmp.w #16*5,d1
					blt.w  found_outside
					cmp.w #240*5,d1
					bgt.w  found_outside

					; break 
					add.l #1,d2
					;cmp.l #5*10,d2    ; size around 5*300
					cmp.l #5*200,d2    ; size around 5*300
					beq   some_fail

					jmp goback

				some_fail:
					; take default values !!! 

				found_outside:



				; compute position
				; mulu 5
				move.w d0,gameobject_x_expanded(a0)
				divu #5,d0
				move.w d0,gameobject_x(a0)

				move.w d1,gameobject_y_expanded(a0)
				divu #5,d1
				move.w d1,gameobject_y(a0)

			; move.w #150,gameobject_x(a4)
			; move.w #100,gameobject_y(a4)


		noshot_outsider:
		jmp end_blockbehavior
		no_outsider:


	; --------------------------------------
	; / BLOCK BEHAVIOR
	; --------------------------------------

	end_blockbehavior:

	add.l #1,d4
	dbra d6,blx

	add.l #1,d5	
	dbra d7,bly

no_blockanimation:

		rts 

;======================================================================================================================
;  cryAengine: block behaviour
;======================================================================================================================

updateBlockBehavior:

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

			; update behaviors
			; d4,d5,a4
		

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

		rts

; set ...
	even
levelBlockVarLayer: dc.w 0 ; 0-10
levelBlockVar: dc.w 0

	even

; levelBlock16X
; levelBlock16Y
; get level var 0 at x,y


getLevelBlockVar:

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

		move.l #actualLevelVals,a0

		clr.l d0
		move.w levelBlockVarLayer,d0
		mulu #(4+20)*screenFactorWidth*levelHeight*screenFactorHeight*2,d0
		add.l d0,a0

		clr.l d0
		move.w levelBlock16Y,d0
		mulu   #2*(2*border_offset_word+20*screenFactorWidth),d0
		add.l d0,a0
		add.l d0,a0
		
		clr.l d1
		move.w levelBlock16X,d1
		add.l d1,a0
		add.l d1,a0

		move.w (a0),levelBlockVar

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

; get ...
setLevelBlockVar:

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

  
		move.l #actualLevelVals,a0

		clr.l d0
		move.w levelBlockVarLayer,d0
		mulu #(4+20)*screenFactorWidth*levelHeight*screenFactorHeight*2,d0
		add.l d0,a0

		clr.l d0
		move.w levelBlock16Y,d0
		mulu   #2*(2*border_offset_word+20*screenFactorWidth),d0
		add.l d0,a0
		add.l d0,a0
		
		clr.l d1
		move.w levelBlock16X,d1
		add.l d1,a0
		add.l d1,a0

		move.w levelBlockVar,(a0)

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

		rts 

;======================================================================================================================
;  cryAengine: numbers
;======================================================================================================================

number_no: dc.l 0
number_x: dc.l 0
number_y: dc.l 0
number_size: dc.l 2

number_showzero: dc.l 1 ; 1: show 001 or 1

; tmp
number_tmp_x: dc.l 0
number_tmp: dc.l 0

; print it revers    <-startx
drawNumbers:

		move.l number_size,d4
		move.l number_no,number_tmp 
		; move.l #123,number_tmp
		move.l number_y,d0
		move.w d0,blocky
		move.l number_x,number_tmp_x
dn:		

		move.l number_tmp_x,d0
		move.w d0,blockx
		move.l  number_tmp,d3
		divu #10,d3
		clr d0
		move.w d3,d0
		move.l d0,number_tmp
		clr d0
		swap d3
		move.w d3,d0
		add.l #39,d0
		move.w d0,blockno

		jsr drawBlockXY

		cmp.l #0,number_showzero
		bne   nnn
		cmp.l #0,number_tmp
		bne   nnn
		jmp   dna
nnn:

		sub.l #1,number_tmp_x
		dbra d4,dn

dna:    ; for all the false dna metaphorisms

		rts


;======================================================================================================================
;  cryAengine: blocks
;======================================================================================================================
			even

blockscreen: dc.l 1

blockx: 	; * 16
	dc.w	5
blocky: 	; * 16
	dc.w    3
blockno:
	dc.w	1	


; not anymore updated!!!
; drawBlockXY
drawBlockXY:
	; 2**16

	jmp renderBlockRasterBlitter

	rts

	; old 68k only routine
	lea.l  blocks,a0
	; add.l  #(2*16)*12,a0 ; (2*16)*4 = 1line (2byte) * 16 *4  planes
	clr.l d0
	move.w blockno,d0
	cmp.w #0,d0
	beq   ncd
	sub.w #1,d0
cd: 
	add.l  #(2*16)*4,a0
	dbra d0,cd
ncd:
	; screen
	move.l blockscreen,a1
	; lea.l  GameScreenBitplanes,a1

	; + y*16*40
	clr.l d0
	move.w blocky,d0
	cmp.w #0,d0
	beq   yncd
	sub.w #1,d0
ycd: 
	add.l  #40*16,a1
	dbra d0,ycd
yncd:

	; x
	clr.l d0
	move.w blockx,d0
	cmp.w #0,d0
	beq   xncd
	sub.w #1,d0

xcd: 
	add.l  #2,a1
	dbra d0,xcd
xncd:


	; simpler
	move.l  a1,a2 ; backup

	; plane 0 
	move.l #16-1,d0
for_plane0:
	move.b (a0)+,(a1)+
	move.b (a0)+,(a1)+
	add.l #40-2,a1
;	move.b #255,(a1)+
;	move.b #255,(a1)+
;	add.l #20-2,a1
	dbra d0,for_plane0

	move.l a2,a1
	add.l #40*256,a1 ; a line 40b * 256 = screen	
	move.l #16-1,d0
for_plane1:
	move.b (a0)+,(a1)+
	move.b (a0)+,(a1)+
	add.l #40-2,a1
	dbra d0,for_plane1

	move.l a2,a1
	add.l #2*40*256,a1 ; a line 40b * 256 = screen	
	move.l #16-1,d0
for_plane2:
	move.b (a0)+,(a1)+
	move.b (a0)+,(a1)+
	add.l #40-2,a1
	dbra d0,for_plane2

	move.l a2,a1
	add.l #3*40*256,a1 ; a line 40b * 256 = screen	
	move.l #16-1,d0
for_plane3:
	move.b (a0)+,(a1)+
	move.b (a0)+,(a1)+
	add.l #40-2,a1
	dbra d0,for_plane3



	rts


; displayBlock
	even
number: 
	dc.l    1 

; display Block No > 1,2,4,5, 
displayBlockNumber:

		move.l number,d0
		add.l #39,d0	 
		move.w d0,blockno
		jsr drawBlockXY		

		rts

		even


;======================================================================================================================
;  cryAengine: blitter blocks (render with blitter power)
;======================================================================================================================

; defintion - use block

; blockx: dc.w
; blocky:   dc.w
; blockno: dc.w
;
; blockscreen

renderBlockRasterBlitter:

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

		move.l #3,d6
		move.l #blocks,a4 ; source
		clr.l  d0
		move.w blockno,d0
		mulu   #4*2*16,d0 ; size 16x 16 x planex= 2*3 *4 
		add.l  d0,a4
		move.l blockscreen,a5 ; destination/target
allplanes_x:

		jsr waitForBlitter
		
		move.l #$09f00000,BLTCON0(a6) ; copy command a>d (zero shifting < > ) 
		move.l #$ffffffff,BLTAFWM(a6) ; mask 
		move.l a4,BLTAPTH(a6); $dff054  ; source
		; pos = 200*(320/8)+15/8

		clr.l  d0
		move.w blocky,d0
		mulu   #16,d0
		mulu   #(40+2*border_offset_byte)*screenFactorWidth,d0
		add.w  blockx,d0
		add.w  blockx,d0
		move.l a5,d1
		add.l  d0,d1 
		move.l d1,BLTDPTH(a6); target - screen
		move.w #0,BLTAMOD(a6); skip source (in bytes) 
		move.w #((320*screenFactorWidth)+2*border_offset-16)/8,BLTDMOD(a6); ; skip destination (in bytes)
		move.w #16*64+16/16,BLTSIZE(a6) ; size of the block (height*64 + wdith/16)		

		add.l #16*2,a4 ; next plane 
		add.l #(40*screenFactorWidth+2*border_offset_byte)*256*screenFactorHeight,a5 ; next plane destination

		dbra d6,allplanes_x

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

		rts 


;======================================================================================================================
;  cryAengine: camera (playfield) setup
;======================================================================================================================


;       move.l #IntroScreen,scrollCameraAddress
;		move.w #0,scrollX
;		move.w #0,scrollY
;		jsr updateCameraAndScrolling

	even

scrollX: dc.w 0
scrollY: dc.w 0
hscrollX: dc.w 2001
hscrollY: dc.w 2001

scrollCameraAddress: dc.l 0

updateCameraAndScrolling: 

		; check if something changed
		move.w  scrollX,d0
		cmp.w hscrollX,d0
		bne   updateCamera
		move.w  scrollY,d0
		cmp.w hscrollY,d0
		bne   updateCamera
		jmp   nocameraupdate
updateCamera:

BitplaneSizeWide =((320*screenFactorWidth+2*32)/8)*256*screenFactorHeight	; 256!			; Size of 1 Bitplanes

	    move.l	#GameScreenBitplanes,d0		; Source Image Address that is the address of Bitplane 1
		cmp.l #0,scrollCameraAddress
		beq    noextracamera
		move.l scrollCameraAddress,d0
noextracamera:		

	add.l   #address_screen_addframe,d0  ; border

;
;		clr.l   d5
;		move.w  scrollY,d5
;		divu    #16,d5
;		ext.l   d5
;		add.l   d5,d0
		
		; yscroll
		clr.l   d5
		move.w scrollY,d5
		mulu    #40*screenFactorWidth+2*border_offset_byte,d5
		add.l   d5,d0
		lea		GameBitplanePointers,a0		; Bitplane Pointers in the Copper
		lea		$dff000,a5
		moveq.l	#NoOfBpls-1,d1				; Number of Bitplanes
		move.l	#BitplaneSizeWide,d2			; Add the bitplane size to the source start Image Address
		bsr.w	SetBitPlanes 



nocameraupdate:

		rts

; -------------------------
; texts
; -------------------------

text_menu_main: dc.b "SHOOT BEHIND THE LINES!+++++++++++++++++++++++++THE STRATEGIC SHOOTEMUP",0

text_menusub_story: dc.b "...",0

text_menusub_howto: dc.b "ATTENTION: YOU SHOOT TO A AREA. IT IS A GRANADE. IT FLIES THROUGH THE AIR ++BACK TO MENU. PRESS ESC",0

text_menusub_about: dc.b "BASED ON THE IDEAS OF +MISSILE COMMAND BALLERBURG +LEMMINGS WORMS+BLACK SHADOWS++CONTACT: INFO AT LA1N.CH++RELEASE: 2024++DEVELOPMENT:+AMIGA ASSEMBLY WITH CRYAENGINE++CODE.GRAPHICS:T00CG ++LEVELS:T00CG.NULL00.HE02++MUSIC: BORROWED O. KLAEWER++GREETINGS:+R.WERNER SCA DEPECHE HALLER JESPERSEN",0

text_gameover: dc.b "GAME OVER",0
 
		even

		even



; ----------------------
; drawBlockText
; ----------------------
; text in a4
;

demo_text: dc.b "CODE FOREVER",0
	even

text_x: dc.w 0
text_y: dc.w 0
text_x_max: dc.w 22

text_tmp_x: dc.w 0
text_tmp_y: dc.w 0

; usage:
; move.w #5,text_x
; move.w #,text_y
; ; move.lw text_x_max
; lea.l demo_text,a4
; jsr drawBlockText

drawBlockText:
	move.w text_x,text_tmp_x
	move.w text_y,text_tmp_y

;	lea.l demo_text,a4
while_text:

	clr.l d0
	move.b (a4),d0
	add.l  #1,a4

	cmp.b #0,d0
	beq.b drawEnd_def

	cmp.b #32,d0
	bne.b n_space
	move.b #12,d0
	jmp   drawNowDirect
n_space:

	cmp.b #33,d0
	bne.b n_exclaim
	move.b #20,d0
	jmp   drawNowDirect
n_exclaim:


	sub.b #65,d0
	add.b #13,d0

drawNowDirect:

	move.w text_tmp_x,blockx
	move.w text_tmp_y,blocky
	move.w d0,blockno
	jsr drawBlockXY

	add.w #1,text_tmp_x
	move.w text_x_max,d1
	cmp.w text_tmp_x,d1
	bne.w text_x_maxtttt
	move.w text_x,text_tmp_x
	add.w  #1,text_tmp_y
text_x_maxtttt:

	jmp while_text

drawEnd_def:	

	rts




; ----------------------
; drawSmallBlockText
; ----------------------
; text in a4
;

demo_small_text: dc.b "THE WOLF IS GOING AROUND. HE WEARS A RED CAP",0

	even

; text_x: dc.w 0
; text_y: dc.w 0
; text_x_max: dc.w 20

; text_tmp_x: dc.w 0
; text_tmp_y: dc.w 0

; usage:
; move.w #5,text_x
; move.w #,text_y
; ; move.lw text_x_max
; lea.l demo_text,a4
; jsr drawText

textsmall_x_max: dc.w 40

drawText:

	move.w text_x,text_tmp_x
	move.w text_y,text_tmp_y

;	lea.l demo_text,a4
while_text_small:

	clr.l d0
	move.b (a4),d0
	add.l  #1,a4

	cmp.b #58,d0
	bne.b n_double
	move.b #47,d0
	jmp   drawNowDirect_small
n_double:

; check numbers ... 
	cmp.b #48,d0
	blt.b nonumber
	cmp.b #57,d0
	bgt.b nonumber
	sub.b #48,d0
	add.b #8,d0

	jmp   drawNowDirect_small
nonumber:

	cmp.b #0,d0
	beq drawEnd_def_small

	; return + 
	cmp.b #43,d0 ; 13 return
	bne.b n_returnit
	
	move.w text_x,text_tmp_x
	add.w  #1,text_tmp_y
	; add.l  #1,a4

	jmp   norendering_smtext
n_returnit:

	cmp.b #32,d0
	bne.b n_space_small
	move.b #20,d0
	jmp   drawNowDirect_small
n_space_small:

	cmp.b #46,d0
	bne.b n_bindes
	move.b #18,d0
	jmp   drawNowDirect_small
n_bindes:

	cmp.b #45,d0
	bne.b n_point
	move.b #19,d0
	jmp   drawNowDirect_small
n_point:

	cmp.b #33,d0
	bne.b n_pointx
	move.b #18,d0
	jmp   drawNowDirect_small
n_pointx:

	


; 9 / 10

	sub.b #65,d0
	add.b #21,d0

drawNowDirect_small:

	move.w text_tmp_x,smallblockx
	move.w text_tmp_y,smallblocky
	move.w d0,smallblockno
	jsr drawSmallBlockXY 

	add.w #1,text_tmp_x
	move.w textsmall_x_max,d1
	cmp.w text_tmp_x,d1
	bne.w text_x_maxtttt_small
	move.w text_x,text_tmp_x
	add.w  #1,text_tmp_y
text_x_maxtttt_small:

norendering_smtext:

	jmp while_text_small

drawEnd_def_small:	

	rts




;======================================================================================================================
;  cryAengine: draw changing/blinking text intro
;======================================================================================================================


			even
text_title_counter: dc.l 0
text_title_address: dc.l 0

text_title_size equ 31

			even
text_title_screen:
			; length clear
			; overwritting!
			dc.b "  PRODUCED BY CHLUDENS NORTH  ",0
			dc.b "                              ",0
			dc.b "    A VISUAL ABSTRACT GAME    ",0
			dc.b " NOT MANY ABSTRACT GAMES TILL ",0
			dc.b "          TODAY               ",0
			dc.b "                              ",0
			dc.b "    GAMEDEVS LOVE SETTINGS    ",0
			dc.b "   HELPS THEM AND THE GAMERS  ",0
			dc.b "  TO UNDERSTAND GAMEMECHANICS ",0
			dc.b "                              ",0
			dc.b "      PRESS MOUSE BUTTON      ",0
			dc.b "         TO CONTINUE          ",0
			dc.b "                              ",0
			dc.b 42


;======================================================================================================================
;  cryAengine: smallblocks (8x8)
;======================================================================================================================
			even

smallblockx: 	; * 16
	dc.w	5
smallblocky: 	; * 16
	dc.w    3
smallblockno:
	dc.w	1	

smallblockscreen:
	dc.l    0

smallblockno_big: dc.w 1
smallblockno_rest: dc.w 1

smallblockscreentarget: dc.w 0 ; 0 ingame screen 1: titlescreen

; drawsmallblockxY


; 68k version only 
drawSmallBlockXY: 
	; 2**16

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


	lea.l  blocks,a0
	; add.l  #(2*16)*12,a0 ; (2*16)*4 = 1line (2byte) * 16 *4  planes

	clr.l d0
	move.w smallblockno,d0
	divu.w #4,d0 
	; 4
	move.w d0,smallblockno_big
	swap d0
	; 4 rest xyz
	move.w d0,smallblockno_rest

	clr.l d0
	move.w smallblockno_big,d0
	cmp.w #0,d0
	beq   s_ncd
	sub.w #1,d0
s_cd: 
	add.l  #(2*16)*4,a0
	dbra d0,s_cd
s_ncd:

;
; p0
;  1 2  8+8  
;  3 4  8+8
; + 2*16
;
; p1
;  1 2  8+8  
;  3 4  8+8

	; now add rest
	; 0-3
	; 8 8 8 8 
	; 16 16 16 
	; 320 = 40 * 8bits
	; 20*16
	; 40*8
	; jmp end_cell
	; add rest * 8		
	clr.l d0
	move.w smallblockno_rest,d0
;	mulu.w #8,d0
;	add.l  d0,a0
	; add for 0,1,2,3
	cmp.w #0,d0
	bne cell0
	jmp end_cell
cell0:	
	cmp.w #1,d0
	bne cell1
	add.l #1,a0
	jmp end_cell
cell1:	
	cmp.w #2,d0
	bne cell2
	add.l #8*2,a0
	jmp end_cell
cell2:	
	cmp.w #3,d0
	bne cell3
	add.l #8*2+1,a0
	jmp end_cell
cell3:	


end_cell:
	

	; destination
	; draw to screen
	lea.l  GameScreenBitplanes,a1

	; smallblcokscreentarget
	cmp.w #1,smallblockscreentarget
	bne.w ntt
	lea.l  TitleScreenBitmap,a1
ntt:

	cmp.l #0,smallblockscreen
	beq   usespecialblock
		move.l smallblockscreen,a1
usespecialblock:

	; + y*8*40
	clr.l d0
	move.w smallblocky,d0
	cmp.w #0,d0
	beq   s_yncdx
	sub.w #1,d0
s_ycdx: 
	add.l  #(2*border_offset_byte+40*screenFactorWidth)*8,a1
	dbra d0,s_ycdx
s_yncdx:

	; x
	clr.l d0
	move.w smallblockx,d0
	add.l  d0,a1


	; -----------------------
	; now copy it all 
	; -----------------------
	; simpler
	move.l  a1,a2 ; backup

	move.l #3,d4
all_p:
	move.l a2,a1	

	; plane x
	move.l #8-1,d0
s_for_planex:
	move.b (a0)+,(a1)+
	;move.b #$ff,(a1)+
	add.l #1,a0 ; xy 
	add.l #2*border_offset_byte+40*screenFactorWidth-1,a1
	dbra d0,s_for_planex

	add.l #16,a0
	add.l #(2*border_offset_byte+40*screenFactorWidth)*256*screenFactorHeight,a2

    dbra d4,all_p



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


	rts

; ----------------------
; draw changing text
; ----------------------


;======================================================================================================================
;  cryAengine: sprites mode 
;======================================================================================================================

waitForBlitter:
			lea $dff000,a6  ; blitter base 
					move.w #$8040,DMACON(a6) ; enable blitter with offset
					tst DMACONR(a6); $dff002
			.waitblittingbob16:
					btst #6,DMACONR(a6); $dff002
					bne .waitblittingbob16:

			rts 

;======================================================================================================================
;  cryAengine: sprites mode 
;======================================================================================================================

setupSpritesMouseMode:

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

		; colors
		lea	sprite0,a3		; Source Address		
		add.l #64,a3 
;		add.l #spritevisualdata_object_bytes,a3
		lea.l spritecolor_01_0,a1 		
		move.w (a3)+,(a1)
		add.l #4,a1
		move.w (a3)+,(a1)
		add.l #4,a1
		move.w (a3)+,(a1)
		add.l #4,a1
		move.w (a3)+,(a1)


		lea		sprite0,a2		; Source Address		
		add.l   #spritevisualdata_object_bytes,a2
		lea		Spr1_Data,a1		; DESTINATION Address
		bsr.w   copyVisualSpriteData

		lea		sprite0,a2		; Source Address
		add.l  #spritevisualdata_object_bytes,a2
		lea		Spr2_Data,a1		; DESTINATION Address
		bsr.w   copyVisualSpriteData

		lea		sprite0,a2		; Source Address
		add.l #spritevisualdata_object_bytes,a2
		lea		Spr3_Data,a1		; DESTINATION Address
		bsr.w   copyVisualSpriteData

		lea		sprite0,a2		; Source Address
		add.l #spritevisualdata_object_bytes,a2
		lea		Spr4_Data,a1		; DESTINATION Address
		bsr.w   copyVisualSpriteData

		lea		sprite0,a2		; Source Address
		add.l   #spritevisualdata_object_bytes,a2
		lea		Spr5_Data,a1		; DESTINATION Address
		bsr.w   copyVisualSpriteData

		lea		sprite0,a2		; Source Address
		add.l   #spritevisualdata_object_bytes,a2
		lea		Spr6_Data,a1		; DESTINATION Address
		bsr.w   copyVisualSpriteData

		lea		sprite0,a2		; Source Address
		add.l   #spritevisualdata_object_bytes,a2
		lea		Spr7_Data,a1		; DESTINATION Address
		bsr.w   copyVisualSpriteData



		rts

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

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

	; image data
	; sprx_data

	copyVisualSpriteData:
		moveq.l	#16,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



;======================================================================================================================
;  cryAengine: game objects
;======================================================================================================================

; disable gameobjects
; - sprite - inactive and will be on -16,-16 (offscreen)

; gets the pointer / address of the object
getGameObject:

		rts

; no more collision, animation, behavior
disableGameObject:

		rts

 		; object state?
;		move.w gameobject_state(a6),d0
;		cmp.w #objectstate_inactive,d0
;		beq.w end_behavior

enableGameObject:

		rts 

;======================================================================================================================
;  cryAengine: WAVE-EFFECT
;======================================================================================================================
	even


WaterEffect:

		; version 1.0 
 	   ; plane 0
  	   lea.l effect_wave,a2
;	   move.l a2,effect_wave_pointer	   
	   lea.l GameScreenBitplanes,a0 ; start screen
	   lea.l GameScreenBitplanes,a1 ; start screen
	   add.l #40*(256-41),a0	   
	   add.l #40*(256-40),a1
	   move.l #38,d1
	   move.l #19,d1
cpy:	
		move.l (a2),d0
		mulu #40,d0
		sub.l d0,a0
	   move.l #19,d2
cpxor: 
		move.w (a0)+,(a1)+
		dbra d2,cpxor
	    sub.l #120,a0
	    add.l #40,a1
		dbra d1,cpy
		; /plane 0

	   ; plane 1
  	   lea.l effect_wave,a2
;	   move.l a2,effect_wave_pointer	   
	   lea.l GameScreenBitplanes,a0 ; start screen
	   lea.l GameScreenBitplanes,a1 ; start screen
	   add.l #40*(256-41),a0	   
	   add.l #40*(256-40),a1
	   add.l #40*256,a0
	   add.l #40*256,a1
	   move.l #38,d1
	   move.l #19,d1
cpy1:	
		move.l (a2),d0
		mulu #40,d0
		sub.l d0,a0
	   move.l #19,d2
cpxor1: 
		move.w (a0)+,(a1)+
		dbra d2,cpxor1
	    sub.l #120,a0
	    add.l #40,a1
		dbra d1,cpy1
		; /plane 1

		; plane 2
  	   lea.l effect_wave,a2
;	   move.l a2,effect_wave_pointer	   
	   lea.l GameScreenBitplanes,a0 ; start screen
	   lea.l GameScreenBitplanes,a1 ; start screen
	   add.l #40*(256-41),a0	   
	   add.l #40*(256-40),a1
	   add.l #80*256,a0
	   add.l #80*256,a1
	   move.l #38,d1
	   move.l #19,d1
cpy2:	
		move.l (a2),d0
		mulu #40,d0
		sub.l d0,a0
	   move.l #19,d2
cpxor2: 
		move.w (a0)+,(a1)+
		dbra d2,cpxor2
	    sub.l #120,a0
	    add.l #40,a1
		dbra d1,cpy2
		; /plane 2
		
	   ; -----------------------
	   ; move waves now
	   ; -----------------------
	   jmp nomore_x
	   add.l #1,effect_water_counter_uber
	   cmp.l #3,effect_water_counter_uber
	   bne effect_water_nolo_ost_tox
	   move.l #0,effect_water_counter_uber	

	   add.l #1,effect_water_counter
	   cmp.l #3,effect_water_counter
	   bne effect_water_nolo_ost
	   move.l #0,effect_water_counter	   
effect_water_nolo_ost:
effect_water_nolo_ost_tox:
nomore_x:


	   lea.l effect_wave,a2
  	   move.l #20,d4
	   move.l #0,d3
wavecontrol:
		move.l  #2,(a2)+
		dbra d4,wavecontrol
effect_water_nolo:

		rts

effect_water_counter: dc.l 0

effect_water_counter_uber: dc.l 0

effect_wave_pointer: dc.l 1

effect_wave: 
	dc.l 1
	dc.l 1
	dc.l 2
	dc.l 3
	dc.l 2
	dc.l 2
	dc.l 1
	dc.l 3
	dc.l 1
	dc.l 2
	dc.l 3
	dc.l 4
	dc.l 5
	dc.l 3
	dc.l 3
	dc.l 2
	dc.l 1
	dc.l 1
	dc.l 2
	dc.l 1
	dc.l 1
	dc.l 1
	dc.l 2
	dc.l 3
	dc.l 2
	dc.l 2
	dc.l 1
	dc.l 3
	dc.l 1
	dc.l 2
	dc.l 3
	dc.l 4
	dc.l 5
	dc.l 3
	dc.l 3
	dc.l 2
	dc.l 1
	dc.l 1
	dc.l 2
	dc.l 1
	dc.l 1
	dc.l 1
	dc.l 2
	dc.l 3
	dc.l 2
	dc.l 2
	dc.l 1
	dc.l 3
	dc.l 1
	dc.l 2
	dc.l 3
	dc.l 4
	dc.l 5
	dc.l 3
	dc.l 3
	dc.l 2
	dc.l 1
	dc.l 1
	dc.l 2
	dc.l 1
	dc.l 1
	dc.l 1
	dc.l 2
	dc.l 3
	dc.l 2
	dc.l 2
	dc.l 1
	dc.l 3
	dc.l 1
	dc.l 2
	dc.l 3
	dc.l 4
	dc.l 5
	dc.l 3
	dc.l 3
	dc.l 2
	dc.l 1
	dc.l 1
	dc.l 2
	dc.l 1
; -----------------------------
; COLORS
; -----------------------------
		even
colors: 
	include	"colors.s"

IntroColors:
	include	"colorsTitle.s"


; -----------------------------
; LEVEL
; -----------------------------
levelTitles:			
			;   ---------|---------
			;  8+
			dc.b "   PLANET COWARDS   ",0 ; 0
			dc.b "   DUTCH MOUTAINS   ",0 ; 0
			dc.b "    BEVERLY HILLS   ",0 ; 0
			dc.b "                    ",0 ; 0
			dc.b "                    ",0 ; 0
			dc.b "                    ",0 ; 0
			dc.b "                    ",0 ; 0
			dc.b "                    ",0 ; 0
			dc.b "                    ",0 ; 0
			dc.b "                    ",0 ; 0
			dc.b "                    ",0 ; 0
			dc.b "                    ",0 ; 0
			dc.b "                    ",0 ; 0
			dc.b "                    ",0 ; 0
			dc.b "                    ",0 ; 0
			dc.b "                    ",0 ; 0
			dc.b "                    ",0 ; 0
			dc.b "                    ",0 ; 0
			dc.b "                    ",0 ; 0
			dc.b "                    ",0 ; 0
			dc.b "                    ",0 ; 0
			dc.b "                    ",0 ; 0


; -----------------------------
; LEVELS
; -----------------------------
; levels from blockeditor
		even

			 ; buffer
             dc.b 0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0  ,0,0
             dc.b 0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0  ,0,0
             dc.b 0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0  ,0,0
             dc.b 0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0  ,0,0
             dc.b 0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0  ,0,0
             dc.b 0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0  ,0,0 

		even
actualLevel:

	; do it
	blk.b (4+levelWidth)*levelHeight,0 ; 256 y coords

actualLevelVals:

	; do it
	blk.b 10*(4+levelWidth)*levelHeight*2,0 ; 256 y coords


	; demo level 
             dc.b 0,0, 1,1,49,49,4,5,1,1,4,0,0,0,0,0,0,0,0,0,0,0  ,0,0
             dc.b 0,0, 0,0,2,4,1,4,1,3,4,1,3,3,3,3,0,5,0,0,0,0  ,0,0
             dc.b 0,0, 49,5,2,4,1,4,1,3,4,1,1,1,1,3,3,5,0,0,0,0  ,0,0
             dc.b 0,0, 49,5,2,4,4,4,1,3,4,1,3,3,3,3,0,5,0,0,0,0  ,0,0
             dc.b 0,0, 4,3,2,3,4,4,1,3,4,1,3,0,0,0,0,5,0,0,0,0  ,0,0
             dc.b 0,0, 4,3,5,3,3,3,1,3,4,0,3,0,0,0,0,0,0,0,0,0  ,0,0
             dc.b 0,0, 4,3,1,3,1,1,1,3,4,0,0,0,4,4,4,0,0,0,0,0  ,0,0
             dc.b 0,0, 3,3,3,3,3,4,4,4,4,0,0,0,0,0,4,4,0,0,0,0  ,0,0
             dc.b 0,0, 0,3,0,0,0,0,0,3,0,4,4,0,0,0,0,4,0,0,0,0  ,0,0
             dc.b 0,0, 0,3,0,4,0,0,0,3,0,0,4,0,0,0,0,4,0,0,0,0  ,0,0
             dc.b 0,0, 0,3,0,4,0,0,4,0,0,0,0,0,0,4,4,0,0,0,0,0  ,0,0
             dc.b 0,0, 0,0,0,4,0,4,4,0,0,0,0,0,4,4,0,0,0,0,0,0  ,0,0
             dc.b 0,0, 0,0,0,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0  ,0,0
             dc.b 0,0, 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0  ,0,0
             dc.b 0,0, 1,0,0,0,0,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0  ,0,0
             dc.b 0,0, 1,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0  ,0,0


			 ; buffer
             dc.b 0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0  ,0,0
             dc.b 0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0  ,0,0
             dc.b 0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0  ,0,0
             dc.b 0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0  ,0,0
             dc.b 0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0  ,0,0
             dc.b 0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0  ,0,0



	even
levels:
	include	"level0.s"
	include	"level1.s"
	include	"level2.s"
	include	"level3.s"
	include	"level4.s"
	include	"level5.s"
	include	"level6.s"
	include	"level7.s"
	include	"level8.s"
	include	"level9.s"
	include	"level10.s"
	include	"level11.s"
	include	"level12.s"
	include	"level13.s"
	include	"level14.s"
	include	"level15.s"
	include	"level16.s"
	include	"level17.s"
	; include	"level18.s"
	include	"level19.s"
	include	"level20.s"
	include	"level21.s"
	include	"level22.s"
	include	"level23.s"
	include	"level24.s"
	include	"level25.s"
	include	"level26.s"



; -----------------------------
; MOUSE HANDLING
; -----------------------------
WaitForMouseUp
xxxx:
		jsr WaitForRaster
		IF musicMode
			jsr 	mt_music
		ENDIF
  	    BTST   #6,$BFE001      ; Test left mouse button
   		BEQ.S   xxxx

		rts

		even 

; -----------------------------
 ; KEYBOARD
 ; -----------------------------

		even
keyPressed:
	dc.w 1

_keyboard:
	movem.l d0-d2,-(sp)

	;Vérifier dans ICR que la requête est bien générée par le CIA A aur l'événement SP (bascule des 8 bits reçus du clavier dans SDR)

	btst #3,$BFED01
	beq _keyboardNotKeyboard

	;Lire les 8 bits dans SDR et détecter s'il s'agit de la pression ou du relâchement d'une touche

	move.b $BFEC01,d0
	btst #0,d0
	bne _keyboardKeyDown
	move.w #$00F0,d1		;Touche relâchée : couleur vert
	bra _keyboardKeyUp
_keyboardKeyDown:
	move.w #$0F00,d1		;Touche pressée : couleur rouge
_keyboardKeyUp:

	;Changer la couleur de fond si la touche pressée est celle attendue (ESC)

	not.b d0
	lsr.b #1,d0

	; key pressed
	clr.l d2
	move.b d0,d2
	move.w d2,keyPressed

	cmpi.b #$45,d0
	bne _keyboardNotESC
	; move.w d1,COLOR00(a5)
	; move.w    $DFF006,$DFF180 ; background
_keyboardNotESC:

	;Acquitter auprès du clavier en maintenant à 0 le signal sur sa ligne KDAT durant 85 us, ce qui s'effectue en positionnant SPMODE à 1 dans CRA ("software must pulse the line low for 85 microseconds to ensure compatibility with all keyboard models" et "the KDAT line is active low [...] a low level (0V) is interpreted as 1"). Pour rappel, une ligne raster, c'est 227,5 cycles de 280 ns, donc 63,7 us, ce qui signifie qu'il faut attendre que le raster ait parcouru deux lignes. Maintenant, ce n'est pas très élégant d'attendre que le raster se balade en se tournant les pouces...

	bset #6,$BFEE01
	
	move.l $DFF004,d0
	lsr.l #8,d0
	and.w #$01FF,d0
	moveq #2-1,d1
_keyboardWait85us:
	move.l $DFF004,d2
	lsr.l #8,d2
	and.w #$01FF,d2
	cmp.w d0,d2
	beq _keyboardWait85us
	move.w d2,d0
	dbf d1,_keyboardWait85us

	bclr #6,$BFEE01

_keyboardNotKeyboard:
	movem.l (sp)+,d0-d2
	rts
 
; -----------------------------
 ; MOUSE CHECK
 ; -----------------------------
	even

; pressed
joystick_Left: 	dc.w 0
joystick_Right: 	dc.w 0
joystick_Down: 	dc.w 0
joystick_Up: 	dc.w 0
joystick_Pressed: dc.w 0

; clicked
joystick_Left_Clicked: 	dc.w 0
joystick_Right_Clicked: 	dc.w 0
joystick_Down_Clicked: 	dc.w 0
joystick_Up_Clicked: 	dc.w 0
joystick_Pressed_Clicked: dc.w 0

; tmp
joystick_Left_old: 	dc.w 0
joystick_Right_old: 	dc.w 0
joystick_Down_old: 	dc.w 0
joystick_Up_old: 	dc.w 0
joystick_Pressed_old: dc.w 0


ReadJoystickDirect:

		move.w #0,joystick_Left_Clicked
		move.w #0,joystick_Right_Clicked
		move.w #0,joystick_Up_Clicked
		move.w #0,joystick_Down_Clicked
		move.w #0,joystick_Pressed_Clicked

		move.w #0,joystick_Left
		move.w #0,joystick_Right
		move.w #0,joystick_Up
		move.w #0,joystick_Down
		move.w #0,joystick_Pressed

		move.w	$dff00c,d3	; Read Joy1dat
		btst.l	#1,d3		; If bit 1 is 1 we move to the Right
		beq.s	j_right		; else check for left
		move.w #1,joystick_Right
j_right:
		btst.l	#9,d3		; If bit 9 is 1 then we so to the left
		beq.s	j_left		; If the bit is 0 then we don't go to the left
		move.w #1,joystick_Left
j_left:

		move.w	d3,d2		; Make a copy of D3 in D2
		lsr.w	#1,d2		; Shift word to the right by 1
		eor.w	d2,d3		; Xor the number
		btst.l	#8,d3		; Is bit 8 set
		beq.s	j_up			; If not check for going down
		move.w #1,joystick_Up
j_up:
		btst.l	#0,d3		; Test if we go Down
		beq.s	j_down		; End Joy routine if not
		move.w #1,joystick_Down

j_down:

		; clicked?

		; check now ...

		cmp.w #0,joystick_Left_old
		bne   cl_left
		cmp.w #1,joystick_Left
		bne   cl_left
		move.w #1,joystick_Left_Clicked
cl_left:		

		cmp.w #0,joystick_Right_old
		bne   cl_right
		cmp.w #1,joystick_Right
		bne   cl_right
		move.w #1,joystick_Right_Clicked
cl_right:		


		cmp.w #0,joystick_Up_old
		bne   cl_up
		cmp.w #1,joystick_Up
		bne   cl_up
		move.w #1,joystick_Up_Clicked
cl_up:

		cmp.w #0,joystick_Down_old
		bne   cl_down
		cmp.w #1,joystick_Down
		bne   cl_down
		move.w #1,joystick_Down_Clicked
cl_down:


		; back in history
		move.w joystick_Left,joystick_Left_old
		move.w joystick_Right,joystick_Right_old
		move.w joystick_Up,joystick_Up_old
		move.w joystick_Down,joystick_Down_old
		move.w joystick_Pressed,joystick_Pressed_old

		rts


; -----------------------------
 ; MOUSE CHECK
 ; -----------------------------
 ; https://www.ikod.se/reading-the-mouse/

XScreenWidth             equ     320-16
XScreenHeight            equ     256-16
 
        IFND MouseLimit
                ; 0 = Mouse Limit InActive
                ; 1 = Mouse Limit Active (Default)
MouseLimit                      equ     1
        ENDC

mouseClicked: dc.w 0
mouseClickedHistory: dc.w 0

mouseDown: dc.w 0

ReadMouse:



                ; **** SOF Read Mouse Routine ****
         
                movem.l d0-d2/a0-a1,-(sp)
                lea.l   OldDeltaY,a0
                lea.l   $dff00a,a1
 
                moveq   #0,d0
                move.b  (a1),d0         ; Get New Y Mouse
                move.w  (a0),d1         ; Get Old Y Mouse
                move.w  d0,(a0)         ; Save New Y Mouse
                sub.w   d1,d0           ; Delta Y
 
                moveq   #0,d1
                move.b  1(a1),d1        ; Get New X Mouse
                move.w  2(a0),d2        ; Get Old X Mouse
                move.w  d1,2(a0)        ; Save New X Mouse
                sub.w   d2,d1           ; Delta X
                 
                ; **** Check Y Delta ****
 
                cmp.w   #-127,d0
                bge     noUnderFlowY
                move.w  #-255,d2
                sub.w   d0,d2           ; Delta Y = -255 - Delta Y
                bpl     noYPos
                moveq   #0,d2
 
noYPos:        move.w  d2,d0
                bra     rmSkipY
 
noUnderFlowY:  cmp.w   #127,d0
                ble     rmSkipY
                move.w  #255,d2
                sub.w   d0,d2           ; Delta X = 255 - Delta Y
                bmi     noYNeg
                moveq   #0,d2
noYNeg:        move.w  d2,d0
 
rmSkipY:
 
                ; **** Check X Delta ****
 
                cmp.w   #-127,d1
                bge     NoUnderFlowX
                move.w  #-255,d2
                sub.w   d1,d2           ; Delta X = -255 - Delta X
                bpl     noXPos
                moveq   #0,d2
 
noXPos:        move.w  d2,d1
                bra     rmSkipX
 
NoUnderFlowX:  cmp.w   #127,d1
                ble     rmSkipX
                move.w  #255,d2
                sub.w   d1,d2           ; Delta X = 255 - Delta X
                bmi     noXNeg
                moveq   #0,d2
noXNeg:        move.w  d2,d1
 
rmSkipX:
 
                lea.l   MouseY,a0
 
                move.w  (a0),d2         ; D2.W = Old Y Mouse 
                add.w   d0,d2           ; Y Mouse = Y Mouse + Y Delta
 
        IF MouseLimit
                bpl     yPositive
 
                moveq   #0,d2
yPositive:     cmp.w   #XScreenHeight-1,d2      ; Y Mouse > Screen Height?
                ble     yBelow
                move.w  #XScreenHeight-1,d2
yBelow:       
        ENDC
                move.w  d2,(a0)+        ; Save Y Mouse
 
                move.w  (a0),d2         ; D2.W = Old X Mouse
                add.w   d1,d2           ; X Mouse = X Mouse + X Delta
        IF MouseLimit
                bpl     xPositive
 
                moveq   #0,d2
xPositive:     cmp.w   #XScreenWidth-1,d2       ; X Mouse > Screen Width?
                ble     xBelow
                move.w  #XScreenWidth-1,d2
xBelow:       
        ENDC
                move.w  d2,(a0)+
 
                movem.l (sp)+,d0-d2/a0-a1
                rts
 
                ; **** EOF Read Mouse Routine ****
				EVEN
OldDeltaY:      dc.w    0
OldDeltaX:      dc.w    0
MouseY:         dc.w    0
MouseX:         dc.w    0


; ------------------------
; random
; ------------------------

;======================================================================================================================
;  Chip Data Section / Chipmemory
;======================================================================================================================

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



; SOME CODE

; resetBobList
;
; RenderBob1616 > add 16x16 bob
; 

; renderAwayBobList
; Start again ...

; render a 16x16 bob
; with id from BOB1616Editor

; screen


		even



; screenTarget
screenTarget: dc.w 0 ; 0 or 1/2
					 ; 0 base					 

even


; render bob 1616
renderBob1616_No:		;d0-d3/a0-a2=x,y,word-width,h,src,dest,mask,BLTCON0+1.l

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

; https://www.stashofcode.fr/afficher-sprites-et-bobs-sur-amiga-2/




; https://eab.abime.net/showthread.php?t=68011

	
		



		; https://www.stashofcode.fr/afficher-sprites-et-bobs-sur-amiga-2/

DISPLAY_DX=320
DISPLAY_DY=256

DISPLAY_X=$81
DISPLAY_Y=$2C

DISPLAY_DEPTH=4
COPPERLIST=10*4+DISPLAY_DEPTH*2*4+(1<<DISPLAY_DEPTH)*4+4
	;10*4					Configuration de l'affichage
	;DISPLAY_DEPTH*2*4		Adresses des bitplanes
	;(1<<DISPLAY_DEPTH)*4	Palette
	;4						$FFFFFFFE
BOB_X=DISPLAY_DX>>1
BOB_Y=DISPLAY_DY>>1
BOB_DX=16
BOB_DY=16
BOB_DEPTH=DISPLAY_DEPTH
DEBUG=1

		lea $dff000,a5  ; blitter base 
		
		move.w #$8040,DMACON(a6) ; enable blitter with offset
		tst DMACONR(a6); $dff002
.waitbliting1616_b:
		btst #6,DMACONR(a6); $dff002
		bne .waitbliting1616_b:

    moveq #0,d1
	move.w #BOB_X,d0
	subi.w #BOB_DX>>1,d0
	move.w d0,d1
	and.w #$F,d0
	ror.w #4,d0
	move.w d0,BLTCON1(a5)
	or.w #$0FF2,d0
	move.w d0,BLTCON0(a5)
	lsr.w #3,d1
	and.b #$FE,d1
	move.w #BOB_Y,d0
	subi.w #BOB_DY>>1,d0
	mulu #DISPLAY_DEPTH*(DISPLAY_DX>>2),d0
	add.l d1,d0
	;; backBuffer
	move.l #IntroScreen,d1
	add.l d1,d0
	move.w #$FFFF,BLTAFWM(a5)
	move.w #$0000,BLTALWM(a5)
	move.w #-2,BLTAMOD(a5)
	move.w #0,BLTBMOD(a5)
	move.w #(DISPLAY_DX-(BOB_DX+16))>>2,BLTCMOD(a5)
	move.w #(DISPLAY_DX-(BOB_DX+16))>>2,BLTDMOD(a5)
	move.l #bob1616_1,BLTAPTH(a5)
	move.l #bob1616_1_mask,BLTBPTH(a5)
	move.l d0,BLTCPTH(a5)
	move.l d0,BLTDPTH(a5)
;	move.w #(DISPLAY_DEPTH*(BOB_DY<<6))!((BOB_DX+16)>>4),BLTSIZE(a5)

;	move.w #(DISPLAY_DEPTH*(BOB_DY<<6))!((BOB_DX+16)>>4),BLTSIZE(a5)
	move.w #(DISPLAY_DEPTH*(BOB_DY<<6))!((BOB_DX+16)>>4),BLTSIZE(a5)

;	move.w #16*64+1,BLTSIZE(a5)


		
		
		jmp nono

			move.w #$8040,DMACON(a6) ; enable blitter with offset
					tst DMACONR(a6); $dff002
			.waitbliting1616_13:
					btst #6,DMACONR(a6); $dff002
					bne .waitbliting1616_13:


					; 1 - destination
					;         3210  
					; sources ABCD
					;         1001
					;         > 9 
					; copy from A pointer to D pointer!
					; move.l #$09000000,BLTCON0(a6);$dff040	mode	
					;          ^^ locial combination
					; https://www.youtube.com/watch?v=Iuxu3o8FZ-0 
					; MINDTERM
					;       ABCD  > D 
					;	0	000     0  
					;   1   001		0
					;   2   010		0
					;   3   011		0
					;   4   100 	1
					;   5   101		1
					;   6   110		1
					;   7   111 	1 < first bit
					;               ^ 8 bits
					;               > %111100000 > f0
					;       1001 > combine => 9
					;  
					; several channels
					; > combine to create a new
					; >> A ~ B > D
					; 
					; https://www.youtube.com/watch?v=Iuxu3o8FZ-0
					; add xor...
					;       ABCD  > D 
					;	0	000     0  
					;   1   001		0
					;   2   010		1
					;   3   011		1
					;   4   100 	1
					;   5   101		1
					;   6   110		1
					;   7   111 	1 < first bit
					;   
					;               %11111100 > FC
					;       1101  >>>>> D		
					;               TOTAL DFC 
					;               xor
					; 
					; BOB
					; https://www.youtube.com/watch?v=OLhhgfnNo9A&t=1215s
					; A cloud mask
					; B cloud
					; C destination playfield
					; D destination playfield
					; 1.0
					; xor
					move.l #0,d2
					move.w bob1616_x,d2
				
					; move.l #$1fca0000,d2

					move.l #$0fca0000,BLTCON0(a6);$dff040 mode : combination + XORETC	
					
					move.l d2,BLTCON0(a6)

			;		move.l #$09f00000,BLTCON0(a6);$dff040 mode : combination + XORETC	
					;        ^ shift!   
					; 2.0
					; mask
					move.l #$ffffffff,BLTAFWM(a6) ; mask 
			;		move.l #$01000000,BLTCON0(a6);$dff040	mode	
					; move.l #$01fff000,$dff040	
					; start/ressource	
					; ressource
					move.l a5,a2
					add.l #4*(16/8+0)*16,a2					
			;		lea testblockone,a0		
					move.l a5,a0
					move.l #bob1616_1_mask,a2 
					move.l #bob1616_1,a0
					move.l a2,BLTAPTH(a6); $dff054  ; high & low
					move.l a0,BLTBPTH(a6); $dff054  ; high & low
					; target
					lea IntroScreen,a3	
					; bltyd*(ww/8)+bltxd/8
					; add.l d6,a3
					move.l a3,BLTCPTH(a6); $dff054  ; high & low
					move.l a3,BLTDPTH(a6); $dff054  ; high & low
					; same target
					move.w #0,BLTAMOD(a6); $dff066
					move.w #0,BLTBMOD(a6); $dff066	

					move.w #(320-16-16)/8,BLTCMOD(a6)
					move.w #(320-16-16)/8,BLTDMOD(a6)
					; x. end
					move.w #32*64+(16+16)/16,BLTSIZE(a6) ; $dff058 ; set size		
					; *64 highword: height, lowword: width

	jmp nono
					; plane1
					tst DMACONR(a6); $dff002
			.waitbliting1616_1:
					btst #6,DMACONR(a6); $dff002
					bne .waitbliting1616_1
					move.l #$0fca0000,BLTCON0(a6);$dff040 mode : combination + XORETC	
					move.l #$ffffffff,BLTAFWM(a6) ; mask 
					move.l a5,a2
					add.l #4*(16/8+0)*16,a2				
			;		lea testblockdouble,a0		
					move.l a5,a0
					add.l #(16/8+0)*16,a0
					move.l a2,BLTAPTH(a6); $dff054  ; high & low
					move.l a0,BLTBPTH(a6); $dff054  ; high & low
					lea IntroScreen,a3
					add.l d6,a3
					add.l  #40*256,a3	
					move.l a3,BLTCPTH(a6); $dff054  ; high & low
					move.l a3,BLTDPTH(a6); $dff054  ; high & low
					move.w #0,BLTAMOD(a6); $dff066
					move.w #0,BLTBMOD(a6); $dff066	
					move.w #(320-16)/8,BLTCMOD(a6)
					move.w #(320-16)/8,BLTDMOD(a6)
					move.w #16*64+16/16,BLTSIZE(a6) ; $dff058 ; set size		

					; plane2
					tst DMACONR(a6); $dff002
			.waitbliting1616_2:
					btst #6,DMACONR(a6); $dff002
					bne .waitbliting1616_2
					move.l #$0fca0000,BLTCON0(a6);$dff040 mode : combination + XORETC	
					move.l #$ffffffff,BLTAFWM(a6) ; mask 
					move.l a5,a2
					add.l #4*(16/8+0)*16,a2					
			;		lea testblockdouble,a0		
					move.l a5,a0
					add.l #2*(16/8+0)*16,a0
					move.l a2,BLTAPTH(a6); $dff054  ; high & low
					move.l a0,BLTBPTH(a6); $dff054  ; high & low
					lea IntroScreen,a3
					add.l d6,a3
					add.l  #2*40*256,a3	
					move.l a3,BLTCPTH(a6); $dff054  ; high & low
					move.l a3,BLTDPTH(a6); $dff054  ; high & low
					move.w #0,BLTAMOD(a6); $dff066
					move.w #0,BLTBMOD(a6); $dff066	
					move.w #(320-16)/8,BLTCMOD(a6)
					move.w #(320-16)/8,BLTDMOD(a6)
					move.w #16*64+16/16,BLTSIZE(a6) ; $dff058 ; set size		

					; plane3
					tst DMACONR(a6); $dff002
			.waitbliting1616_3:
					btst #6,DMACONR(a6); $dff002
					bne .waitbliting1616_3
					move.l #$0fca0000,BLTCON0(a6);$dff040 mode : combination + XORETC	
					move.l #$ffffffff,BLTAFWM(a6) ; mask 
					move.l a5,a2
					add.l #4*(16/8+0)*16,a2				
			;		lea testblockdouble,a0		
					move.l a5,a0
					add.l #3*(16/8+0)*16,a0
					move.l a2,BLTAPTH(a6); $dff054  ; high & low
					move.l a0,BLTBPTH(a6); $dff054  ; high & low
					lea IntroScreen,a3
					add.l d6,a3
					add.l  #3*40*256,a3	
					move.l a3,BLTCPTH(a6); $dff054  ; high & low
					move.l a3,BLTDPTH(a6); $dff054  ; high & low
					move.w #0,BLTAMOD(a6); $dff066
					move.w #0,BLTBMOD(a6); $dff066	
					move.w #(320-16)/8,BLTCMOD(a6)
					move.w #(320-16)/8,BLTDMOD(a6)
					move.w #16*64+16/16,BLTSIZE(a6) ; $dff058 ; set size		

nono:

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

notthese:

; 	movem.l (sp)+,d2-d3/d5/a1

	rts



	include	"sincos.s"
	include	"atan2.s"

	even








  