pokered/engine/overworld/oam.asm

190 lines
3.5 KiB
NASM
Raw Normal View History

2014-05-26 02:23:12 +00:00
PrepareOAMData:
; Determine OAM data for currently visible
; sprites and write it to wOAMBuffer.
2014-09-13 07:50:56 +00:00
ld a, [wUpdateSpritesEnabled]
2014-05-26 02:23:12 +00:00
dec a
2015-07-15 11:27:59 +00:00
jr z, .updateEnabled
2014-05-26 02:23:12 +00:00
cp 0 - 1
ret nz
2014-09-13 07:50:56 +00:00
ld [wUpdateSpritesEnabled], a
2014-05-26 02:23:12 +00:00
jp HideSprites
2015-07-15 11:27:59 +00:00
.updateEnabled
2014-05-26 02:23:12 +00:00
xor a
2015-07-15 11:27:59 +00:00
ld [hOAMBufferOffset], a
.spriteLoop
2015-07-15 20:58:21 +00:00
ld [hSpriteOffset2], a
2014-05-26 02:23:12 +00:00
ld d, wSpriteStateData1 / $100
2015-07-15 20:58:21 +00:00
ld a, [hSpriteOffset2]
2014-05-26 02:23:12 +00:00
ld e, a
ld a, [de] ; c1x0
and a
2015-07-15 11:27:59 +00:00
jp z, .nextSprite
2014-05-26 02:23:12 +00:00
inc e
inc e
ld a, [de] ; c1x2 (facing/anim)
ld [wd5cd], a
2014-05-26 02:23:12 +00:00
cp $ff ; off-screen (don't draw)
jr nz, .visible
2015-07-15 11:27:59 +00:00
call GetSpriteScreenXY
jr .nextSprite
2014-05-26 02:23:12 +00:00
.visible
2015-07-15 11:27:59 +00:00
cp $a0 ; is the sprite unchanging like an item ball or boulder?
2014-05-26 02:23:12 +00:00
jr c, .usefacing
2015-07-15 11:27:59 +00:00
; unchanging
2014-05-26 02:23:12 +00:00
and $f
2015-07-15 11:27:59 +00:00
add $10 ; skip to the second half of the table which doesn't account for facing direction
jr .next
2014-05-26 02:23:12 +00:00
.usefacing
and $f
2015-07-15 11:27:59 +00:00
.next
2014-05-26 02:23:12 +00:00
ld l, a
2015-07-15 11:27:59 +00:00
; get sprite priority
2014-05-26 02:23:12 +00:00
push de
inc d
ld a, e
add $5
ld e, a
ld a, [de] ; c2x7
and $80
2015-07-15 11:27:59 +00:00
ld [hSpritePriority], a ; temp store sprite priority
2014-05-26 02:23:12 +00:00
pop de
2015-07-15 11:27:59 +00:00
; read the entry from the table
2014-05-26 02:23:12 +00:00
ld h, 0
ld bc, SpriteFacingAndAnimationTable
add hl, hl
add hl, hl
add hl, bc
ld a, [hli]
ld c, a
ld a, [hli]
ld b, a
ld a, [hli]
ld h, [hl]
ld l, a
2015-07-15 11:27:59 +00:00
call GetSpriteScreenXY
2014-05-26 02:23:12 +00:00
2015-07-15 11:27:59 +00:00
ld a, [hOAMBufferOffset]
2014-05-26 02:23:12 +00:00
ld e, a
ld d, wOAMBuffer / $100
2015-07-15 11:27:59 +00:00
.tileLoop
ld a, [hSpriteScreenY] ; temp for sprite Y position
2014-05-26 02:23:12 +00:00
add $10 ; Y=16 is top of screen (Y=0 is invisible)
add [hl] ; add Y offset from table
ld [de], a ; write new sprite OAM Y position
inc hl
2015-07-15 11:27:59 +00:00
ld a, [hSpriteScreenX] ; temp for sprite X position
2014-05-26 02:23:12 +00:00
add $8 ; X=8 is left of screen (X=0 is invisible)
add [hl] ; add X offset from table
inc e
ld [de], a ; write new sprite OAM X position
inc e
2015-07-15 11:27:59 +00:00
ld a, [bc] ; read pattern number offset (accommodates orientation (offset 0,4 or 8) and animation (offset 0 or $80))
2014-05-26 02:23:12 +00:00
inc bc
push bc
ld b, a
ld a, [wd5cd] ; temp copy of c1x2
2014-05-26 02:23:12 +00:00
swap a ; high nybble determines sprite used (0 is always player sprite, next are some npcs)
and $f
; Sprites $a and $b have one face (and therefore 4 tiles instead of 12).
; As a result, sprite $b's tile offset is less than normal.
cp $b
2015-07-15 11:27:59 +00:00
jr nz, .notFourTileSprite
2014-05-26 02:23:12 +00:00
ld a, $a * 12 + 4
2015-07-15 11:27:59 +00:00
jr .next2
2014-05-26 02:23:12 +00:00
2015-07-15 11:27:59 +00:00
.notFourTileSprite
2014-05-26 02:23:12 +00:00
; a *= 12
sla a
sla a
ld c, a
sla a
add c
2015-07-15 11:27:59 +00:00
.next2
add b ; add the tile offset from the table (based on frame and facing direction)
2014-05-26 02:23:12 +00:00
pop bc
ld [de], a ; tile id
inc hl
inc e
ld a, [hl]
2015-07-15 11:27:59 +00:00
bit 1, a ; is the tile allowed to set the sprite priority bit?
jr z, .skipPriority
ld a, [hSpritePriority]
2014-05-26 02:23:12 +00:00
or [hl]
2015-07-15 11:27:59 +00:00
.skipPriority
2014-05-26 02:23:12 +00:00
inc hl
ld [de], a
inc e
bit 0, a ; OAMFLAG_ENDOFDATA
2015-07-15 11:27:59 +00:00
jr z, .tileLoop
2014-05-26 02:23:12 +00:00
ld a, e
2015-07-15 11:27:59 +00:00
ld [hOAMBufferOffset], a
2014-05-26 02:23:12 +00:00
2015-07-15 11:27:59 +00:00
.nextSprite
2015-07-15 20:58:21 +00:00
ld a, [hSpriteOffset2]
2014-05-26 02:23:12 +00:00
add $10
cp $100 % $100
2015-07-15 11:27:59 +00:00
jp nz, .spriteLoop
2014-05-26 02:23:12 +00:00
; Clear unused OAM.
2015-07-15 11:27:59 +00:00
ld a, [hOAMBufferOffset]
2014-05-26 02:23:12 +00:00
ld l, a
ld h, wOAMBuffer / $100
ld de, $4
ld b, $a0
ld a, [wd736]
bit 6, a ; jumping down ledge or fishing animation?
2014-05-26 02:23:12 +00:00
ld a, $a0
jr z, .clear
; Don't clear the last 4 entries because they are used for the shadow in the
; jumping down ledge animation and the rod in the fishing animation.
2014-05-26 02:23:12 +00:00
ld a, $90
2014-05-26 02:23:12 +00:00
.clear
cp l
ret z
ld [hl], b
add hl, de
jr .clear
2015-07-15 11:27:59 +00:00
GetSpriteScreenXY: ; 4bd1 (1:4bd1)
2014-05-26 02:23:12 +00:00
inc e
inc e
ld a, [de] ; c1x4
2015-07-15 11:27:59 +00:00
ld [hSpriteScreenY], a
2014-05-26 02:23:12 +00:00
inc e
inc e
ld a, [de] ; c1x6
2015-07-15 11:27:59 +00:00
ld [hSpriteScreenX], a
ld a, 4
2014-05-26 02:23:12 +00:00
add e
ld e, a
2015-07-15 11:27:59 +00:00
ld a, [hSpriteScreenY]
add 4
2014-05-26 02:23:12 +00:00
and $f0
ld [de], a ; c1xa (y)
inc e
2015-07-15 11:27:59 +00:00
ld a, [hSpriteScreenX]
2014-05-26 02:23:12 +00:00
and $f0
ld [de], a ; c1xb (x)
ret