gb-tarot/CopyTilesSafe.inc

355 lines
8.5 KiB
PHP

CopyTilesToMap:
CopyTilesToMapUnsafe:
; copy tiles from where they are linearly packed at an origin (hl)
; to a rectangle in the tilemap in vram (de)
; assuming it has height in b and width in c.
ld a, b
or a, c
ret z
push bc
.copyTile
ld a, [hl] ; load from the tile map into a
ld [de], a ; load from a into the destination
inc hl ; this is slower than using hli but i'm trying to work with this here
inc de
dec c
; check if we've completed a line?
ld a, 0
or a, c ; check if c is zero, if it's not zero go back and copy more bytes
jp nz, .copyTile
.doneWithLine
pop bc
ld a, e
add a, 32
ld e, a
ld a, d
adc a, 0
ld d, a
ld a, e
sub a, c
ld e, a
ld a, d
sbc a, 0
ld d, a
dec b
ld a, b
cp a, 0
jp nz, CopyTilesToMap
ret
BuildMetaSprite:
; takkes similar args as copytilestomapunsafe but builds several sprites
; instead.
; location of source tile map: hl
; location in memory to write to: de
; y and x in b and c
; height and width in a & %11110000 and a & %00001111 ??? that's deranged
push hl
push de
pop hl ; want hl and de to be swapped just for the sake of consistent apis
pop de ; hl now holds the OAM location, de holds the sprite map
push af ; save to the stack so we can retrieve it for row-wise decrement
push bc ; hold onto the upper-left corner so we can update it each row
.writeRow
pop bc
pop af
push af
push bc ; refresh af and bc from their authoritative stack versions
and a, $0F ; take only the horizontal tile count
.buildSprite
;
ld [hl], b ; write y byte
inc hl
ld [hl], c ; write x byte
inc hl
push af ; save a before we use it for transferring de to hl
ld a, [de]
inc de ; move to the next sprite
ld [hl], a
inc hl
res OAMB_XFLIP, [hl] ; make sure xflip is turned off
inc hl ; skip the attributes byte
; we're going to wait to get our a value (number of tiles left to draw in this
; row) until after we've used a for changing c
;we've written a whole sprite. hl and de are in the right state, we need to
; update a and bc.
; update bc
ld a, c
add a, 8
ld c, a
pop af ; get back the number of tiles to draw in this row
dec a
jp nz, .buildSprite ; if there are still tiles left to draw in this row, do it!
; otherwise we have no more tiles to write this row bc needs to be updated
pop bc
ld a, b
add a, 8
ld b, a ; add 8 to the y coordinate
pop af
sub a, $10
push af
push bc
and a, $F0
; stakc has bc and af, ready for repeating from the top
jp nz, .writeRow ; last numerical operation was and a, $F0 so checking if upper byte is zero
pop bc
pop af
ret
BuildMetaSpriteHFlip:
; takkes similar args as copytilestomapunsafe but builds several sprites
; instead.
; location of source tile map: hl
; location in memory to write to: de
; y and x in b and c
; height and width in a & %11110000 and a & %00001111 ??? that's deranged
push hl
push de
pop hl ; want hl and de to be swapped just for the sake of consistent apis
pop de ; hl now holds the OAM location, de holds the sprite map
push af ; save to the stack so we can retrieve it for row-wise decrement
and a, $0F
;sla a ;times 2
;sla a ; times 4
;sla a ; times 8
;add a, c
;ld a, b
;adc a, 0
;ld b, a
pop af
push af
push bc ; hold onto the upper-left corner so we can update it each row
.writeRow
pop bc
pop af
push af
push bc ; refresh af and bc from their authoritative stack versions
and a, $0F ; take only the horizontal tile count
.buildSprite
;
ld [hl], b ; write y byte
inc hl
ld [hl], c ; write x byte
inc hl
push af ; save a before we use it for transferring de to hl
ld a, [de]
inc de ; move to the next sprite
ld [hl], a
inc hl
set OAMB_XFLIP, [hl] ; make sure xflip is turned on
inc hl ; skip the attributes byte
; we're going to wait to get our a value (number of tiles left to draw in this
; row) until after we've used a for changing c
;we've written a whole sprite. hl and de are in the right state, we need to
; update a and bc.
; update bc
ld a, c
sub a, 8
ld c, a
pop af ; get back the number of tiles to draw in this row
dec a
jp nz, .buildSprite ; if there are still tiles left to draw in this row, do it!
; otherwise we have no more tiles to write this row bc needs to be updated
pop bc
ld a, b
add a, 8
ld b, a ; add 8 to the y coordinate
pop af
sub a, $10
push af
push bc
and a, $F0
; stakc has bc and af, ready for repeating from the top
jp nz, .writeRow ; last numerical operation was and a, $F0 so checking if upper byte is zero
pop bc
pop af
ret
BuildMetaSpritePackedHflip:
; takkes similar args as copytilestomapunsafe but builds several sprites
; instead.
; location of source tile map: hl
; location in memory to write to: de
; y and x in b and c
; height and width in a & %11110000 and a & %00001111 ??? that's deranged
push hl
push de
pop hl ; want hl and de to be swapped just for the sake of consistent apis
pop de ; hl now holds the OAM location, de holds the sprite map
push af ; save to the stack so we can retrieve it for row-wise decrement
push bc ; hold onto the upper-left corner so we can update it each row
.writeRow
pop bc
pop af
push af
push bc ; refresh af and bc from their authoritative stack versions
and a, $0F ; take only the horizontal tile count
.buildSprite
;
ld [hl], b ; write y byte
inc hl
ld [hl], c ; write x byte
inc hl
push af ; save a before we use it for transferring de to hl
ld a, [de]
inc de ; move to the next sprite
ld [hl], a
cp a, 0
jp nz, :+
dec hl
dec hl
jp :++
:
inc hl
set OAMB_XFLIP, [hl] ; make sure xflip is turned off
inc hl ; skip the attributes byte
; we're going to wait to get our a value (number of tiles left to draw in this
; row) until after we've used a for changing c
;we've written a whole sprite. hl and de are in the right state, we need to
; update a and bc.
; update bc
: ld a, c
sub a, 8
ld c, a
pop af ; get back the number of tiles to draw in this row
dec a
jp nz, .buildSprite ; if there are still tiles left to draw in this row, do it!
; otherwise we have no more tiles to write this row bc needs to be updated
pop bc
ld a, b
add a, 8
ld b, a ; add 8 to the y coordinate
pop af
sub a, $10
push af
push bc
and a, $F0
; stakc has bc and af, ready for repeating from the top
jp nz, .writeRow ; last numerical operation was and a, $F0 so checking if upper byte is zero
pop bc
pop af
ret
BuildMetaSpritePacked:
; takkes similar args as copytilestomapunsafe but builds several sprites
; instead.
; location of source tile map: hl
; location in memory to write to: de
; y and x in b and c
; height and width in a & %11110000 and a & %00001111 ??? that's deranged
push hl
push de
pop hl ; want hl and de to be swapped just for the sake of consistent apis
pop de ; hl now holds the OAM location, de holds the sprite map
push af ; save to the stack so we can retrieve it for row-wise decrement
push bc ; hold onto the upper-left corner so we can update it each row
.writeRow
pop bc
pop af
push af
push bc ; refresh af and bc from their authoritative stack versions
and a, $0F ; take only the horizontal tile count
.buildSprite
;
ld [hl], b ; write y byte
inc hl
ld [hl], c ; write x byte
inc hl
push af ; save a before we use it for transferring de to hl
ld a, [de]
inc de ; move to the next sprite
ld [hl], a
cp a, 0
jp nz, :+
dec hl
dec hl
jp :++
:
inc hl
res OAMB_XFLIP, [hl] ; make sure xflip is turned off
inc hl ; skip the attributes byte
; we're going to wait to get our a value (number of tiles left to draw in this
; row) until after we've used a for changing c
;we've written a whole sprite. hl and de are in the right state, we need to
; update a and bc.
; update bc
: ld a, c
add a, 8
ld c, a
pop af ; get back the number of tiles to draw in this row
dec a
jp nz, .buildSprite ; if there are still tiles left to draw in this row, do it!
; otherwise we have no more tiles to write this row bc needs to be updated
pop bc
ld a, b
add a, 8
ld b, a ; add 8 to the y coordinate
pop af
sub a, $10
push af
push bc
and a, $F0
; stakc has bc and af, ready for repeating from the top
jp nz, .writeRow ; last numerical operation was and a, $F0 so checking if upper byte is zero
pop bc
pop af
ret