diff options
author | dannye <33dannye@gmail.com> | 2020-11-04 00:06:44 -0600 |
---|---|---|
committer | dannye <33dannye@gmail.com> | 2020-11-04 00:06:44 -0600 |
commit | 5647ca687b92954dcf37a6ea6bfbc9a341c32de4 (patch) | |
tree | dde1937a1bfdb3a835f4155e1c2eb8f1aaf86f63 /engine/gfx/sprite_oam.asm | |
parent | 53fcd05aa24693093d8af1dc8ec4fedd3957decc (diff) |
Sync with pokered
Diffstat (limited to 'engine/gfx/sprite_oam.asm')
-rw-r--r-- | engine/gfx/sprite_oam.asm | 232 |
1 files changed, 232 insertions, 0 deletions
diff --git a/engine/gfx/sprite_oam.asm b/engine/gfx/sprite_oam.asm new file mode 100644 index 00000000..01b2c412 --- /dev/null +++ b/engine/gfx/sprite_oam.asm @@ -0,0 +1,232 @@ +PrepareOAMData:: +; 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 -1 + ret nz + ld [wUpdateSpritesEnabled], a + jp HideSprites + +.updateEnabled + xor a + ldh [hOAMBufferOffset], a + +.spriteLoop + ldh [hSpriteOffset2], a + + ld e, a + ld d, HIGH(wSpriteStateData1) + + ld a, [de] ; [x#SPRITESTATEDATA1_PICTUREID] + and a + jp z, .nextSprite + + inc e + inc e + ld a, [de] ; [x#SPRITESTATEDATA1_IMAGEINDEX] + 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] ; [x#SPRITESTATEDATA2_GRASSPRIORITY] + and $80 + ldh [hSpritePriority], a ; temp store sprite priority + pop de + + + call GetSpriteScreenXY + + ldh a, [hOAMBufferOffset] + add [hl] + cp $a0 + jr z, .hidden + jr nc, .asm_4a41 +.hidden + call Func_4a7b + ld [wd5cd], a + ldh a, [hOAMBufferOffset] + + ld e, a + ld d, HIGH(wOAMBuffer) + +.tileLoop + ld a, [hli] + ld c, a +.loop + ldh 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 + ldh 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 + ldh a, [hFFFC] + 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 + ldh 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 + ldh [hOAMBufferOffset], a +.nextSprite + ldh a, [hSpriteOffset2] + add $10 + cp LOW($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 + ldh 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: + inc e + inc e + ld a, [de] ; [x#SPRITESTATEDATA1_YPIXELS] + ldh [hSpriteScreenY], a + inc e + inc e + ld a, [de] ; [x#SPRITESTATEDATA1_XPIXELS] + ldh [hSpriteScreenX], a + ld a, 4 + add e + ld e, a + ldh a, [hSpriteScreenY] + add 4 + and $f0 + ld [de], a ; [x#SPRITESTATEDATA1_YADJUSTED] + inc e + ldh a, [hSpriteScreenX] + and $f0 + ld [de], a ; [x#SPRITESTATEDATA1_XADJUSTED] + ret + +Func_4a7b: + push bc + ld a, [wd5cd] ; temp copy of [x#SPRITESTATEDATA1_IMAGEINDEX] + 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/gfx/oam_dma.asm" + +_IsTilePassable:: + 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/tilesets/collision_tile_ids.asm" |