spr_tile equ 0

spr_patt equ 4

spr_width equ 8
spr_height equ 9

spr_xpos equ 10
spr_ypos equ 11

spr_refreshtile equ 12
spr_refreshsprite equ 13

spr_oldxpos equ 14
spr_oldypos equ 15

spr_flags equ 16
spr_pattREV equ 18


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

; ;draw a flipped tilemap
drawtilemaprev:
; ;                                     	ld a,ixh			;width of tilemap
	clr.l d0
	move.b d3,d0
	subq.l #1,d0
	add.l d0,a2


	move.b #1,(striproutine)
	 jsr drawtilemap
	 clr.b (striproutine)
	rts


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



drawsprite:
	tst.b (spr_refreshsprite,a4)	;check if we need to do redeaw
	bne lbl14451
	rts
lbl14451
	clr.b (spr_refreshsprite,a4)

drawspritealways:			;force redraw
	
	move.l (spr_tile,a4),a2	;tilemap source

	clr.l d1
	clr.l d4
	;sprite position
	move.b (spr_xpos,a4),d1
	move.b (spr_ypos,a4),d4
	
	;update lastpos	
	move.b d1,(spr_oldxpos,a4)
	move.b d4,(spr_oldypos,a4)
	
	move.l (spr_patt,a4),a5	;sprite pattern data
	
	ifd BuildAMI
	
		btst #0,(spr_flags,a4)
		beq NotReversedPatterns
			move.l (spr_pattREV,a4),a5	;sprite pattern data
NotReversedPatterns:
	endif
	
		
	ifd BuildNEO
	
		btst #0,(spr_flags,a4)
		beq NotReversedPatterns
			move.l (spr_pattREV,a4),a5	;sprite pattern data
NotReversedPatterns:
	endif
	
	
	
	clr.l d3
	clr.l d6
	move.b (spr_width,a4),d3
	move.b (spr_height,a4),d6

	move.b (spr_flags,a4),d0
	
	jsr docrop		;crop the sprite bc/D1.D4=xy pos D3.D6/hl=widthheigh, A2=source data
	
	bcs drawabort	;nothing to draw
	
	lsr.l #2,d3		;convert to tile width
	lsr.l #2,d6		;convert to tile height
	
	
	jsr getscreenpos
			; pop ix		;width height
			; push iy	;tilemap source
	move.b (spr_width,a4),d7	;tilemap width
	lsr.l #2,d7		;convert to tile width
	
	btst #0,(spr_flags,a4)
	 beq drawtilemap
	 jmp drawtilemaprev
drawabort:
	rts

; ;DE/A2=tilemap de'/A5=pattern data D6,D5/ix=wh D7/iyh=tilemap width hl/A3=vram dest

drawtilemap:

nextline:
	movem.l A2/A6/D5-D7,-(sp)
	
	move.l d3,d7

		tst.b (StripRoutine)		;Draw type?
		
		bne DoStripRevver		;Reverse
		ifd DoStripSprite
			jsr DoStripSprite
		else
			jsr dostrip 	;A2=Tilemap A5=TileBitmap A6=Vram dest D7=Width
		endif
		jmp DoStripDone
DoStripRevver:		
		ifd DoStripSprite
			jsr DoStripSpriteRev
		else
			jsr DoStripRev
		endif
DoStripDone:
	
		
	
	movem.l (sp)+,A2/A6/D5-D7
	ifd BuildNEO
		add #1,a6
	endif
	ifd BuildX68
		add #1024*8,a6
	endif
	ifd BuildAST
		add #40*4*8,a6
	endif
	ifd BuildAMI
		add #40*4*8,a6
	endif
	ifd BuildGEN
		add.l #2*64,a6
	endif
	ifd BuildSQL
		add #128*8,a6
	endif
	
	add.l d7,a2

	subq.b #1,d6
	bne nextline		;repeat for next line
	rts

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



;DE/A2=tilemap de'/A5=pattern data D6,D5/ix=wh D7/iyh=tilemap width hl/A6=vram dest

cls:

	move.l #$18,d7		;draw height (IXL)
	ifd BuildNEO
		clr.l d1
		clr.l d4
	endif
	
	ifd BuildAST
		move.l (screenbase),a6	;vram destination (HL)
		add.l #4*4,a6
	else
		move.l #screenbase,a6	;vram destination (HL)
	endif
	
	ifd buildAMI
		clr.l d1	;For BLIT routine
	endif
	
nextlinef:
	move.l d7,-(sp)
		move.l #32,d7		;draw width (IYL)
	
		jsr dostrip
	
		ifd BuildX68
			add.l #(1024*8)-512,a6	
		endif
		ifd BuildAMI
			add.l #(160*8)-40+8,a6	
		endif
		ifd BuildAST
			add.l #(160*7)+4*8,a6	
		endif
		ifd BuildSQL
			add.l #(128*8)-128,a6	
		endif
		ifd BuildGEN
			add.l #2*32,a6
		endif
	move.l (sp)+,d7
	
	subq.b #1,d7
	bne nextlinef

	rts


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

; ;                                     ;x,y pos = bc / width+height = hl   iy=source

; ;                                     ;a= sprite flags

; ;                                     

; ;                                     docrop:
docrop:
; ;                                     	bit 0,a
	btst #0,d0
; ;                                     	jr z,docropnorev
	beq docropnorev
; ;                                     

;the source recalc routine won't work right for flipped sprites

;so we flip the xpos before running the crop routine	

; ;                                     	

; ;                                     	ld a,h
	
; ;                                     	add b
	add.b d3,d1
; ;                                     	neg						;flip xpos
	neg.b d1
; ;                                     	ld b,a			
	; move.b d0,d1
; ;                                     

; ;                                     	call docropnorev
	jsr docropnorev
; ;                                     	ret c
	bcc lbl19121
	rts
lbl19121
; ;                                     	

; ;                                     	ld a,vscreenwid+1
	move.l #vscreenwid+1,d0
	ifd BuildX68
		move.l #vscreenwid+1,d0
	endif
; 

; ;                                     	sub h			;flip to opposite side of screen.
	sub.b d3,d0
; ;                                     	sub b
	sub.b d1,d0
; ;                                     	ld b,a
	move.b d0,d1
	
	
; ;                                     

; ;                                     	or a			;clear carry
	; ;nop
; ;                                     	ret
	andi #%11111110,ccr		;Clear carry
	rts
; ;                                     docropnorev:
docropnorev:
	clr.l d2
	move.b d2,(spritehclip)
	clr.l d2
	clr.l d5
;crop top side

	clr.l d0
	move.b d4,d0
	
;logical top of the screen
	sub.b #vscreenminy,d0
	bcc notcrop
	neg.b d0

	addq.b #2,d0
	
	cmp.b d6,d0					;no pixels onscreen?

	bcc docrop_alloffscreen		;all offscreen
	move.b d0,d5				;top crop
	and.l #%00000011,d0
	eor.l #%00000011,d0
notcrop:

;crop bottom hand side
	move.b d0,d4
	add.b d6,d0
	sub.b #vscreenhei-vscreenheiclip,d0	;logical height of screen
	bcs nobcrop
	and.l #%11111100,d0
	cmp.b d6,d0					;no pixels onscreen?

	bcc docrop_alloffscreen		;all offscreen
	move.b d0,d2				;bottom crop
nobcrop:

	move.b d5,d0
	
	add.b d2,d0
	and.l #%11111100,d0
	beq novclip
	neg.b d0
	add.b d0,d6					;height
	
	clr.l d2
	move.b d5,d2

	move.b d3,d5				;bytes per line	
	and.l #$FF,d5
	lsr.b #2,d5					;2 lines per unit
	
	
	and.l #$FF,d2				;lines to remove from top
	lsr.b #2,d2					;2 lines per unit
	mulu d5,d2

	add.l d2,a2
	
NoVClip:
	clr.l d2
	clr.l d5

;crop left hand side


	move.b d1,d0
 	
	sub.b #vscreenminx,d0		;64 = leftmost visible tile
	bcc nolcrop
	neg.b d0
	
	addq.b #2,d0
	
	cmp.b d3,d0					;no pixels onscreen?
	bcc docrop_alloffscreen		;offscreen

	move.b d0,d5
	
	and.l #%00000011,d0
	eor.l #%00000011,d0
	
nolcrop:
;crop right hand side
	move.b d0,d1
	add.b d3,d0

	sub.b #vscreenwid-vscreenwidclip,d0		;logical width of screen
	bcs norcrop
	cmp.b d3,d0				;no pixels onscreen?
	bcc docrop_alloffscreen	;offscreen
	move.b d0,d2

norcrop:
	move.b d2,d0
	add.b d5,d0
	lsr.b #2,d0
	beq nohclip

	move.b d0,(spritehclip)
	
	lsl.b #2,d0

	sub.b d0,d3			;amount to subtract from width (right)

	and.l #$FF,d5			;amount to subtract from left
	lsr.b #2,d5					;2 lines per unit
;update start byte
	add.l d5,a2				;move across 
	
nohclip:
	andi #%11111110,ccr		;Clear carry
	rts

docrop_alloffscreen:
	ori #%00000001,ccr		;set carry (nothing to draw)
	rts

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

flagspriteforrefresh:
	move.b #1,(spr_refreshtile,a4)
	move.b #1,(spr_refreshsprite,a4)
	 rts
	 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;redraw the background under a sprite

removesprite:
	tst.b (spr_refreshtile,a4)
	bne lbl30960
		rts
lbl30960:

	clr.l d1
	clr.l d4
	clr.l d3
	clr.l d6
	
	move.b (spr_oldxpos,a4),d1
	move.b (spr_oldypos,a4),d4
	
	move.b (spr_width,a4),d3	;do we allow 2/4 pixel moves?
	ifd tilesmoothxmove
		addq.b #4,d3
   	endif
	
	move.b (spr_height,a4),d6
	ifd tilesmoothymove
		addq.b #4,d6
	endif
	
	;crop the sprite bc=xy pos hl=widthheigh, iy=source data
	jsr docropnorev
	bcc lbl49532
	rts		;nothing to draw
lbl49532:

	jsr docroplogicaltotile	;convert to tile co-ords
	bne lbl43027
	rts
lbl43027:
	

	movem.l D3/D6,-(sp)
		move.l #$20,d7	;tilemap width
		move.l #tilecache,a2
		jsr shifttilemap
		move.l a3,-(sp)
		
			move.l #$24,d7	;tilemap width
			move.l #tilemap2,a2
			move.b (offset1),d0
			and.l #%00000011,d0
			add.l d0,a2			;shift source tilemap by offset
			
			;alter tilemap pos for current sprite position
			jsr shifttilemap
		move.l (sp)+,a2
		
		move.l d7,d3
		move.l #$20,d7	;tile cache width	
	movem.l (sp)+,D1/D4
	
;updatetilecache
updatetilecacheb:
	move.l a3,-(sp)
		move.l a2,-(sp)
			move.b d1,d0
updatetilecachec:
			move.b (a3)+,(a2)+		;copy bytes of tilemap to cache
			
			subq.b #1,d0
			bne updatetilecachec

		move.l (sp)+,a2
		add.l d7,a2
	move.l (sp)+,a3

	add.l d3,a3		;width of tilemap
	subq.b #1,d4
	bne updatetilecacheb
	rts
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;




; ;                                     ;remove a sprite from the cache (stops sprite flickering)

; ;                                     

; ;                                     zerospriteincache:	;bc= x,y pos   ix=sprite source
zerospriteincache:
; ;                                     	

; ;                                     	ld a,(ix+spr_refreshtile)
	tst.b (spr_refreshtile,a4)
	bne lbl27807
		rts
lbl27807:
	clr.b (spr_refreshtile,a4)
	
	move.b (spr_xpos,a4),d1
	move.b (spr_ypos,a4),d4
	
; ;                                     

; ;                                     	ifdef lowresx
	ifd lowresx
		and.b #%11111100,d1
	endif

	ifd lowresy
		and.b #%11111100,d4
	endif

	move.b (spr_width,a4),d3
	move.b (spr_height,a4),d6

	ifd tilesmoothxmove
		btst #1,d1
		beq nohalf

		addq.b #2,d1
		and.b #%11111100,d1
		bne lbl14907
			rts
lbl14907
		subq.b #2,d3
nohalf:
	endif
	
	
	
	ifd tilesmoothymove
		btst #1,d4
		beq nohalf2

		addq.b #2,d4
		and.b #%11111100,d4
		bne lbl149072
			rts
lbl149072
		subq.b #2,d6
nohalf2:
	endif
	

	;crop the sprite bc=xy pos hl=widthheigh, iy=source data
	move.b (Spr_Flags,a4),d0
	jsr DoCrop	;Crop the sprite BC=XY pos HL=WidthHeigh, IY=source data
	bcc lbl49532z
	rts		;nothing to draw
lbl49532z:

	jsr docroplogicaltotile	;convert to tile co-ords
	bne lbl43027z
	rts
lbl43027z:
	btst #0,(Spr_Flags,a4)
	beq DoCropLogicalToTileB
	;addq.b #2,d1
DoCropLogicalToTileB:	
	

	movem.l D3/D6,-(sp)
		;move.l #$20,d7	;tilemap width
		
		
		;move.l a3,-(sp)
		
			move.l #$20,d7	;tilemap width
			move.l #tileCache,a2
			
			;alter tilemap pos for current sprite position
			jsr shifttilemap
			exg a3,a2
		;move.l (sp)+,a2
		move.l (Spr_Tile,a4),a3
		
		
	movem.l (sp)+,D1/D4
	
	btst #0,(Spr_Flags,a4)
	beq ZeroTileCache
	
	move.b d1,d0		;Flip Width
	subq.b #1,d0
	and.l #$FF,d0
	add.l d0,a3
	
	move.b #1,(ZeroTileCacheRev)

	jsr ZeroTileCache

	clr.b (ZeroTileCacheRev)

	rts
	
ZeroTileCache:	
	
;updatetilecache
Zeroupdatetilecacheb:
	move.l a3,-(sp)
		move.l a2,-(sp)
			move.b d1,d0
Zeroupdatetilecachec:
			tst.b (a3)+
			beq zeroCacheb
			clr.b (a2)		;copy bytes of tilemap to cache
			
zeroCacheb:	
			addq.l #1,a2
			
			tst.b (ZeroTileCacheRev)
			beq ZeroTileCacheRevJ
				subq.l #2,a3
ZeroTileCacheRevJ:		
			subq.b #1,d0
			bne Zeroupdatetilecachec

		move.l (sp)+,a2
		add.l d7,a2
	move.l (sp)+,a3

	add.l d3,a3		;width of tilemap
	subq.b #1,d4
	bne Zeroupdatetilecacheb
	rts
	

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

;de/A2=tilemap			bc(D1/D4)=xy pos	iyh/D7=width

;returns:

;hl/A3=new tilemap pos

shifttilemap:
	exg A2,A3
	
	and.l #$FF,d7		;tilemap width
	
	move.b d4,d0
	beq NoAdd
readd:	
	add.l d7,a3			;move down c lines 
	
	subq.b #1,d0
	bne readd
NoAdd:	
	and.l #$FF,d1
	
	add.l d1,a3
	rts
	

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

; convert logical pos to tilemap tile pos 
; z=true if size is zero
;z= invalid width/height

docroplogicaltotile:
	lsr.b #2,d1			;xpos /4
	lsr.b #2,d4			;ypos /4

	lsr.b #2,d3			;width /4
	lsr.b #2,d6			;height /4

	tst.b d3			;is width or height zero?
	beq lbl60519
	tst.b d6
lbl60519:
	rts


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

;compare tilemap bc to hl and copy tiles to cache de if different

;bc/a1 and hl/a3 must be &24 tiles wilde... de/a2 must be &20

 ;ixh/d7 = width    ixl/d6 =height

changescroll:

; ;                                     		push ix
		; push ix
	move.b d7,d5
; ;                                     changescrollagain:
changescrollagain:
	move.b (a1)+,d0	;get source tile
	cmp.b (a3)+,d0			;is dest correct?
	beq changescrollok
	move.b d0,(a2)			;no! request an update
changescrollok:
	addq.l #1,a2

	subq.b #1,d5
	bne changescrollagain

	addq.l #4,a3		;skip 4 unused tiles in tilemap
	addq.l #4,a1
	
	subq.b #1,d6
	bne changescroll

	rts
; ;                                     