pokeyellow/engine/overworld/oam.asm
2015-10-29 14:23:30 -04:00

232 lines
3.9 KiB
NASM

PrepareOAMData: ; 499b (1:499b)
; Determine OAM data for currently visible
; sprites and write it to wOAMBuffer.
; Yellow code has been changed to use registers more efficiently
; as well as tweaking the code to show gbc palettes
ld a, [wUpdateSpritesEnabled]
dec a
jr z, .updateEnabled
cp $ff
ret nz
ld [wUpdateSpritesEnabled], a
jp HideSprites
.updateEnabled
xor a
ld [hOAMBufferOffset], a
.spriteLoop
ld [hSpriteOffset2], a
ld e, a
ld d, wSpriteStateData1 / $100
ld a, [de] ; c1x0
and a
jp z, .nextSprite
inc e
inc e
ld a, [de] ; c1x2 (facing/anim)
ld [wd5cd], a
cp $ff ; off-screen (don't draw)
jr nz, .visible
call GetSpriteScreenXY
jr .nextSprite
.visible
cp $a0 ; is the sprite unchanging like an item ball or boulder?
jr c, .usefacing
; unchanging
ld a, $0
jr .next
.usefacing
and $f
.next
; read the entry from the table
ld c, a
ld b, 0
ld hl, SpriteFacingAndAnimationTable
add hl, bc
add hl, bc
ld a, [hli]
ld h, [hl]
ld l, a
; get sprite priority
push de
inc d
ld a, e
add $5
ld e, a
ld a, [de] ; c2x7
and $80
ld [hSpritePriority], a ; temp store sprite priority
pop de
call GetSpriteScreenXY
ld a, [hOAMBufferOffset]
add [hl]
cp $a0
jr z, .hidden
jr nc, .asm_4a41
.hidden
call Func_4a7b
ld [wd5cd], a
ld a, [hOAMBufferOffset]
ld e, a
ld d, wOAMBuffer / $100
.tileLoop
ld a, [hli]
ld c, a
.loop
ld a, [hSpriteScreenY] ; temp for sprite Y position
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
inc e
ld a, [hSpriteScreenX] ; temp for sprite X position
add $8 ; X=8 is left of screen (X=0 is invisible)
add [hl] ; add X offset from table
ld [de], a
inc hl
inc e
ld a, [wd5cd]
add [hl]
cp $80
jr c, .asm_4a1c
ld b, a
ld a, [$fffc]
add b
.asm_4a1c
ld [de], a ; tile id
inc hl
inc e
ld a, [hl]
bit 1, a ; is the tile allowed to set the sprite priority bit?
jr z, .skipPriority
ld a, [hSpritePriority]
or [hl]
.skipPriority
and $f0
bit 4, a ; OBP0 or OBP1
jr z, .spriteusesOBP0
or %100 ; palettes 4-7 are OBP1
.spriteusesOBP0
ld [de], a
inc hl
inc e
dec c
jr nz, .loop
ld a, e
ld [hOAMBufferOffset], a
.nextSprite
ld a, [hSpriteOffset2]
add $10
cp $100 % $100
jp nz, .spriteLoop
; Clear unused OAM.
.asm_4a41
ld a, [wd736]
bit 6, a ; jumping down ledge or fishing animation?
ld c, $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.
ld c, $90
.clear
ld a, [hOAMBufferOffset]
cp c
ret nc
ld l, a
ld h, wOAMBuffer / $100
ld a, c
ld de, $4 ; entry size
ld b, $a0
.clearLoop
ld [hl], b
add hl, de
cp l
jr nz, .clearLoop
ret
GetSpriteScreenXY: ; 4a5f (1:4a5f)
inc e
inc e
ld a, [de] ; c1x4
ld [hSpriteScreenY], a
inc e
inc e
ld a, [de] ; c1x6
ld [hSpriteScreenX], a
ld a, 4
add e
ld e, a
ld a, [hSpriteScreenY]
add 4
and $f0
ld [de], a ; c1xa (y)
inc e
ld a, [hSpriteScreenX]
and $f0
ld [de], a ; c1xb (x)
ret
Func_4a7b: ; 4a7b (1:4a7b)
push bc
ld a, [wd5cd] ; temp copy of c1x2
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
jr nz, .notFourTileSprite
ld a, $a * 12 + 4 ; $7c
jr .done
.notFourTileSprite
; a *= 12
add a
add a
ld c, a
add a
add c
.done
pop bc
ret
INCLUDE "engine/oam_dma.asm"
_IsTilePassable:: ; 4aaa (1:4aaa)
ld hl,wTilesetCollisionPtr ; pointer to list of passable tiles
ld a,[hli]
ld h,[hl]
ld l,a ; hl now points to passable tiles
.loop
ld a,[hli]
cp a,$ff
jr z,.tileNotPassable
cp c
jr nz,.loop
xor a
ret
.tileNotPassable
scf
ret
INCLUDE "data/collision.asm" ; probably