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 xor a jr .next .usefacing and $f .next ; read the entry from the table add a ld c, a ld b, 0 ld hl, SpriteFacingAndAnimationTable add hl, bc ld a, [hli] ld h, [hl] ld l, a ; get sprite priority ld b, d ld c, e inc b ld a, c add $5 ld c, a ld a, [bc] ; c2x7 and $80 ld [hSpritePriority], a ; temp store sprite priority call GetSpriteScreenXY 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 .startTileLoop .notFourTileSprite ; a *= 12 add a add a ld c, a add a add c .startTileLoop ld b, a ld a, [hOAMBufferOffset] ld e, a ld d, wOAMBuffer / $100 ld c, $4 .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, [hli] add b ld [de], a ; tile id 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 ; uncomment the following range for pal conversion ; 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 jp nz, .spriteLoop ; Clear unused OAM. 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 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 ====================================================================== SpriteFacingAndAnimationTable: ; 4000 (1:4000) dw SpriteFacingDownAndStanding ; facing down, walk animation frame 0 dw SpriteFacingDownAndWalking ; facing down, walk animation frame 1 dw SpriteFacingDownAndStanding ; facing down, walk animation frame 2 dw SpriteFacingDownAndWalking2 ; facing down, walk animation frame 3 dw SpriteFacingUpAndStanding ; facing up, walk animation frame 0 dw SpriteFacingUpAndWalking ; facing up, walk animation frame 1 dw SpriteFacingUpAndStanding ; facing up, walk animation frame 2 dw SpriteFacingUpAndWalking2 ; facing up, walk animation frame 3 dw SpriteFacingLeftAndStanding ; facing left, walk animation frame 0 dw SpriteFacingLeftAndWalking ; facing left, walk animation frame 1 dw SpriteFacingLeftAndStanding ; facing left, walk animation frame 2 dw SpriteFacingLeftAndWalking ; facing left, walk animation frame 3 dw SpriteFacingRightAndStanding ; facing right, walk animation frame 0 dw SpriteFacingRightAndWalking ; facing right, walk animation frame 1 dw SpriteFacingRightAndStanding ; facing right, walk animation frame 2 dw SpriteFacingRightAndWalking ; facing right, walk animation frame 3 dw SpriteFacingDownAndStanding ; --- dw SpriteFacingDownAndStanding ; This table is used for sprites $a and $b. dw SpriteFacingDownAndStanding ; All orientation and animation parameters dw SpriteFacingDownAndStanding ; lead to the same result. Used for immobile dw SpriteFacingDownAndStanding ; sprites like items on the ground dw SpriteFacingDownAndStanding ; --- dw SpriteFacingDownAndStanding dw SpriteFacingDownAndStanding dw SpriteFacingDownAndStanding dw SpriteFacingDownAndStanding dw SpriteFacingDownAndStanding dw SpriteFacingDownAndStanding dw SpriteFacingDownAndStanding dw SpriteFacingDownAndStanding dw SpriteFacingDownAndStanding dw SpriteFacingDownAndStanding SpriteFacingDownAndStanding: ; 4042 (1:4042) ; Sprite OAM Parameters db $00,$00,$00,$00 ; top left db $00,$08,$01,$00 ; top right db $08,$00,$02,OAMFLAG_CANBEMASKED ; bottom left db $08,$08,$03,OAMFLAG_CANBEMASKED | OAMFLAG_ENDOFDATA ; bottom right SpriteFacingDownAndWalking: ; 4053 (1:4053) ; Sprite OAM Parameters db $00,$00,$80,$00 ; top left db $00,$08,$81,$00 ; top right db $08,$00,$82,OAMFLAG_CANBEMASKED ; bottom left db $08,$08,$83,OAMFLAG_CANBEMASKED | OAMFLAG_ENDOFDATA ; bottom right SpriteFacingDownAndWalking2: ; 4064 (1:4064) ; Sprite OAM Parameters db $00,$08,$80,OAMFLAG_VFLIPPED ; top left db $00,$00,$81,OAMFLAG_VFLIPPED ; top right db $08,$08,$82,OAMFLAG_VFLIPPED | OAMFLAG_CANBEMASKED ; bottom left db $08,$00,$83,OAMFLAG_VFLIPPED | OAMFLAG_CANBEMASKED | OAMFLAG_ENDOFDATA ; bottom right SpriteFacingUpAndStanding: ; 4075 (1:4075) ; Sprite OAM Parameters db $00,$00,$04,$00 ; top left db $00,$08,$05,$00 ; top right db $08,$00,$06,OAMFLAG_CANBEMASKED ; bottom left db $08,$08,$07,OAMFLAG_CANBEMASKED | OAMFLAG_ENDOFDATA ; bottom right SpriteFacingUpAndWalking: ; 4086 (1:4086) ; Sprite OAM Parameters db $00,$00,$84,$00 ; top left db $00,$08,$85,$00 ; top right db $08,$00,$86,OAMFLAG_CANBEMASKED ; bottom left db $08,$08,$87,OAMFLAG_CANBEMASKED | OAMFLAG_ENDOFDATA ; bottom right SpriteFacingUpAndWalking2: ; 4097 (1:4097) ; Sprite OAM Parameters db $00,$08,$84,OAMFLAG_VFLIPPED ; top left db $00,$00,$85,OAMFLAG_VFLIPPED ; top right db $08,$08,$86,OAMFLAG_VFLIPPED | OAMFLAG_CANBEMASKED ; bottom left db $08,$00,$87,OAMFLAG_VFLIPPED | OAMFLAG_CANBEMASKED | OAMFLAG_ENDOFDATA ; bottom right SpriteFacingLeftAndStanding: ; 40a8 (1:40a8) ; Sprite OAM Parameters db $00,$00,$08,$00 ; top left db $00,$08,$09,$00 ; top right db $08,$00,$0a,OAMFLAG_CANBEMASKED ; bottom left db $08,$08,$0b,OAMFLAG_CANBEMASKED | OAMFLAG_ENDOFDATA ; bottom right SpriteFacingLeftAndWalking: ; 40b9 (1:40b9) ; Sprite OAM Parameters db $00,$00,$88,$00 ; top left db $00,$08,$89,$00 ; top right db $08,$00,$8a,OAMFLAG_CANBEMASKED ; bottom left db $08,$08,$8b,OAMFLAG_CANBEMASKED | OAMFLAG_ENDOFDATA ; bottom right SpriteFacingRightAndStanding: ; 40ca (1:40ca) ; Sprite OAM Parameters db $00,$08,$08,OAMFLAG_VFLIPPED ; top left db $00,$00,$09,OAMFLAG_VFLIPPED ; top right db $08,$08,$0a,OAMFLAG_VFLIPPED | OAMFLAG_CANBEMASKED ; bottom left db $08,$00,$0b,OAMFLAG_VFLIPPED | OAMFLAG_CANBEMASKED | OAMFLAG_ENDOFDATA ; bottom right SpriteFacingRightAndWalking: ; 40db (1:40db) ; Sprite OAM Parameters db $00,$08,$88,OAMFLAG_VFLIPPED ; top left db $00,$00,$89,OAMFLAG_VFLIPPED ; top right db $08,$08,$8a,OAMFLAG_VFLIPPED | OAMFLAG_CANBEMASKED ; bottom left db $08,$00,$8b,OAMFLAG_VFLIPPED | OAMFLAG_CANBEMASKED | OAMFLAG_ENDOFDATA ; bottom right