mirror of
https://github.com/thornAvery/kep-hack.git
synced 2025-12-21 01:51:36 +13:00
Try to clean up PrepareOAMData.
This commit is contained in:
parent
5a14234b49
commit
f6038a3d52
25
engine/oam_dma.asm
Normal file
25
engine/oam_dma.asm
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
WriteDMACodeToHRAM:
|
||||||
|
; Since no other memory is available during OAM DMA,
|
||||||
|
; DMARoutine is copied to HRAM and executed there.
|
||||||
|
ld c, $ff80 % $100
|
||||||
|
ld b, DMARoutineEnd - DMARoutine
|
||||||
|
ld hl, DMARoutine
|
||||||
|
.copy
|
||||||
|
ld a, [hli]
|
||||||
|
ld [$ff00+c], a
|
||||||
|
inc c
|
||||||
|
dec b
|
||||||
|
jr nz, .copy
|
||||||
|
ret
|
||||||
|
|
||||||
|
DMARoutine:
|
||||||
|
; initiate DMA
|
||||||
|
ld a, $c3
|
||||||
|
ld [$ff46], a
|
||||||
|
|
||||||
|
; wait for DMA to finish
|
||||||
|
ld a, $28
|
||||||
|
.wait dec a
|
||||||
|
jr nz, .wait
|
||||||
|
ret
|
||||||
|
DMARoutineEnd:
|
||||||
178
engine/overworld/oam.asm
Normal file
178
engine/overworld/oam.asm
Normal file
|
|
@ -0,0 +1,178 @@
|
||||||
|
PrepareOAMData:
|
||||||
|
; Determine OAM data for currently visible
|
||||||
|
; sprites and write it to wOAMBuffer.
|
||||||
|
|
||||||
|
ld a, [$cfcb]
|
||||||
|
dec a
|
||||||
|
jr z, .asm_4b1e
|
||||||
|
|
||||||
|
cp 0 - 1
|
||||||
|
ret nz
|
||||||
|
ld [$cfcb], a
|
||||||
|
jp HideSprites
|
||||||
|
|
||||||
|
.asm_4b1e
|
||||||
|
xor a
|
||||||
|
ld [$ff90], a
|
||||||
|
.asm_4b21
|
||||||
|
ld [$ff8f], a
|
||||||
|
|
||||||
|
ld d, wSpriteStateData1 / $100
|
||||||
|
ld a, [$ff8f]
|
||||||
|
ld e, a
|
||||||
|
ld a, [de] ; c1x0
|
||||||
|
and a
|
||||||
|
jp z, .asm_4bad
|
||||||
|
|
||||||
|
inc e
|
||||||
|
inc e
|
||||||
|
ld a, [de] ; c1x2 (facing/anim)
|
||||||
|
ld [$d5cd], a
|
||||||
|
cp $ff ; off-screen (don't draw)
|
||||||
|
jr nz, .visible
|
||||||
|
|
||||||
|
call Func_4bd1
|
||||||
|
jr .asm_4bad
|
||||||
|
|
||||||
|
.visible
|
||||||
|
cp $a0
|
||||||
|
jr c, .usefacing
|
||||||
|
and $f
|
||||||
|
add $10
|
||||||
|
jr .asm_4b48
|
||||||
|
|
||||||
|
.usefacing
|
||||||
|
and $f
|
||||||
|
.asm_4b48
|
||||||
|
ld l, a
|
||||||
|
|
||||||
|
push de
|
||||||
|
inc d
|
||||||
|
ld a, e
|
||||||
|
add $5
|
||||||
|
ld e, a
|
||||||
|
ld a, [de] ; c2x7
|
||||||
|
and $80
|
||||||
|
ld [$ff94], a ; temp store sprite priority
|
||||||
|
pop de
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
call Func_4bd1
|
||||||
|
|
||||||
|
ld a, [$ff90]
|
||||||
|
ld e, a
|
||||||
|
ld d, wOAMBuffer / $100
|
||||||
|
.tile
|
||||||
|
ld a, [$ff92] ; 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
|
||||||
|
ld a, [$ff91] ; temp for sprite X position
|
||||||
|
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
|
||||||
|
ld a, [bc] ; read pattern number offset (accomodates orientation (offset 0,4 or 8) and animation (offset 0 or $80))
|
||||||
|
inc bc
|
||||||
|
push bc
|
||||||
|
ld b, a
|
||||||
|
|
||||||
|
ld a, [$d5cd] ; 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, .offset
|
||||||
|
ld a, $a * 12 + 4
|
||||||
|
jr .gotoffset
|
||||||
|
|
||||||
|
.offset
|
||||||
|
; a *= 12
|
||||||
|
sla a
|
||||||
|
sla a
|
||||||
|
ld c, a
|
||||||
|
sla a
|
||||||
|
add c
|
||||||
|
.gotoffset
|
||||||
|
add b ; which frame
|
||||||
|
pop bc
|
||||||
|
ld [de], a ; tile id
|
||||||
|
inc hl
|
||||||
|
inc e
|
||||||
|
ld a, [hl]
|
||||||
|
bit 1, a ; sprite priority
|
||||||
|
jr z, .fg
|
||||||
|
ld a, [$ff94] ; facing priority
|
||||||
|
or [hl]
|
||||||
|
.fg
|
||||||
|
inc hl
|
||||||
|
ld [de], a
|
||||||
|
inc e
|
||||||
|
bit 0, a ; OAMFLAG_ENDOFDATA
|
||||||
|
jr z, .tile
|
||||||
|
|
||||||
|
ld a, e
|
||||||
|
ld [$ff90], a
|
||||||
|
|
||||||
|
.asm_4bad
|
||||||
|
ld a, [$ff8f]
|
||||||
|
add $10
|
||||||
|
cp $100 % $100
|
||||||
|
jp nz, .asm_4b21
|
||||||
|
|
||||||
|
; Clear unused OAM.
|
||||||
|
ld a, [$ff90]
|
||||||
|
ld l, a
|
||||||
|
ld h, wOAMBuffer / $100
|
||||||
|
ld de, $4
|
||||||
|
ld b, $a0
|
||||||
|
ld a, [$d736]
|
||||||
|
bit 6, a
|
||||||
|
ld a, $a0
|
||||||
|
jr z, .clear
|
||||||
|
ld a, $90
|
||||||
|
.clear
|
||||||
|
cp l
|
||||||
|
ret z
|
||||||
|
ld [hl], b
|
||||||
|
add hl, de
|
||||||
|
jr .clear
|
||||||
|
|
||||||
|
Func_4bd1: ; 4bd1 (1:4bd1)
|
||||||
|
inc e
|
||||||
|
inc e
|
||||||
|
ld a, [de] ; c1x4
|
||||||
|
ld [$ff92], a
|
||||||
|
inc e
|
||||||
|
inc e
|
||||||
|
ld a, [de] ; c1x6
|
||||||
|
ld [$ff91], a
|
||||||
|
ld a, $4
|
||||||
|
add e
|
||||||
|
ld e, a
|
||||||
|
ld a, [$ff92]
|
||||||
|
add $4
|
||||||
|
and $f0
|
||||||
|
ld [de], a ; c1xa (y)
|
||||||
|
inc e
|
||||||
|
ld a, [$ff91]
|
||||||
|
and $f0
|
||||||
|
ld [de], a ; c1xb (x)
|
||||||
|
ret
|
||||||
180
main.asm
180
main.asm
|
|
@ -139,184 +139,8 @@ UnusedNames: ; 4a92 (1:4a92)
|
||||||
db "マスター@"
|
db "マスター@"
|
||||||
db "エクセレント"
|
db "エクセレント"
|
||||||
|
|
||||||
; calculates the OAM data for all currently visible sprites and writes it to wOAMBuffer
|
INCLUDE "engine/overworld/oam.asm"
|
||||||
PrepareOAMData: ; 4b0f (1:4b0f)
|
INCLUDE "engine/oam_dma.asm"
|
||||||
ld a, [$cfcb]
|
|
||||||
dec a
|
|
||||||
jr z, .asm_4b1e
|
|
||||||
cp $ff
|
|
||||||
ret nz
|
|
||||||
ld [$cfcb], a
|
|
||||||
jp HideSprites
|
|
||||||
.asm_4b1e
|
|
||||||
xor a
|
|
||||||
ld [$ff90], a
|
|
||||||
.asm_4b21
|
|
||||||
ld [$ff8f], a
|
|
||||||
ld d, $c1
|
|
||||||
ld a, [$ff8f]
|
|
||||||
ld e, a
|
|
||||||
ld a, [de] ; c1x0
|
|
||||||
and a
|
|
||||||
jp z, .asm_4bad
|
|
||||||
inc e
|
|
||||||
inc e
|
|
||||||
ld a, [de] ; c1x2 read combined orientation and animation info
|
|
||||||
ld [$d5cd], a
|
|
||||||
cp $ff
|
|
||||||
jr nz, .spriteVisible ; $ff -> offscreen, don't draw
|
|
||||||
call Func_4bd1
|
|
||||||
jr .asm_4bad
|
|
||||||
.spriteVisible
|
|
||||||
cp $a0
|
|
||||||
jr c, .considerOrientation ; if >= $a0, ignore the sprite orientation and animation (by using a different conversion table)
|
|
||||||
and $f
|
|
||||||
add $10
|
|
||||||
jr .asm_4b48
|
|
||||||
.considerOrientation
|
|
||||||
and $f ; the lower nybble contains orientation and animation info
|
|
||||||
.asm_4b48
|
|
||||||
ld l, a
|
|
||||||
push de
|
|
||||||
inc d
|
|
||||||
ld a, e
|
|
||||||
add $5
|
|
||||||
ld e, a
|
|
||||||
ld a, [de] ; c2x7
|
|
||||||
and $80
|
|
||||||
ld [$ff94], a ; temp store bit 7 for later use in OAM flags (draws sprite behind background (used for grass))
|
|
||||||
pop de
|
|
||||||
ld h, $0
|
|
||||||
ld bc, SpriteFacingAndAnimationTable
|
|
||||||
add hl, hl
|
|
||||||
add hl, hl
|
|
||||||
add hl, bc ; skip to the table location determined by orientation and animation
|
|
||||||
ld a, [hli]
|
|
||||||
ld c, a
|
|
||||||
ld a, [hli]
|
|
||||||
ld b, a
|
|
||||||
ld a, [hli]
|
|
||||||
ld h, [hl]
|
|
||||||
ld l, a
|
|
||||||
call Func_4bd1
|
|
||||||
ld a, [$ff90]
|
|
||||||
ld e, a
|
|
||||||
ld d, $c3 ; wOAMBuffer+x is buffer for OAM data
|
|
||||||
.spriteTilesLoop ; loops 4 times for the 4 tiles a sprite consists of
|
|
||||||
ld a, [$ff92] ; 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
|
|
||||||
ld a, [$ff91] ; temp for sprite X position
|
|
||||||
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
|
|
||||||
ld a, [bc] ; read pattern number offset (accomodates orientation (offset 0,4 or 8) and animation (offset 0 or $80))
|
|
||||||
inc bc
|
|
||||||
push bc
|
|
||||||
ld b, a
|
|
||||||
ld a, [$d5cd] ; temp copy of c1x2
|
|
||||||
swap a ; high nybble determines sprite used (0 is always player sprite, next are some npcs)
|
|
||||||
and $f
|
|
||||||
cp $b ; sprites $a and $b have no orientation or animation and therefore only 4 tiles
|
|
||||||
jr nz, .calcTileOffset ; (instead of 12), so tile b's offset is a special case
|
|
||||||
ld a, $7c ; = $a * 12 + 4
|
|
||||||
jr .doneCalcTileOffset
|
|
||||||
.calcTileOffset
|
|
||||||
sla a
|
|
||||||
sla a
|
|
||||||
ld c, a
|
|
||||||
sla a
|
|
||||||
add c ; a *= 12 (each sprite consists of 12 tiles)
|
|
||||||
.doneCalcTileOffset
|
|
||||||
add b ; add orientation and animation offset
|
|
||||||
pop bc
|
|
||||||
ld [de], a ; write OAM sprite pattern number
|
|
||||||
inc hl
|
|
||||||
inc e
|
|
||||||
ld a, [hl]
|
|
||||||
bit 1, a ; bit 1 is ignored for OAM, it's used here as an "always in foregroud" flag.
|
|
||||||
jr z, .alwaysInForeground
|
|
||||||
ld a, [$ff94] ; load bit 7 (set to $80 if sprite is in grass and should be drawn behind it)
|
|
||||||
or [hl]
|
|
||||||
.alwaysInForeground
|
|
||||||
inc hl
|
|
||||||
ld [de], a ; write OAM sprite flags
|
|
||||||
inc e
|
|
||||||
bit 0, a ; test for OAMFLAG_ENDOFDATA
|
|
||||||
jr z, .spriteTilesLoop
|
|
||||||
ld a, e
|
|
||||||
ld [$ff90], a
|
|
||||||
.asm_4bad
|
|
||||||
ld a, [$ff8f]
|
|
||||||
add $10
|
|
||||||
cp $0
|
|
||||||
jp nz, .asm_4b21
|
|
||||||
ld a, [$ff90]
|
|
||||||
ld l, a
|
|
||||||
ld h, $c3
|
|
||||||
ld de, $4
|
|
||||||
ld b, $a0
|
|
||||||
ld a, [$d736]
|
|
||||||
bit 6, a
|
|
||||||
ld a, $a0
|
|
||||||
jr z, .clearUnusedOAMEntriesLoop
|
|
||||||
ld a, $90
|
|
||||||
.clearUnusedOAMEntriesLoop
|
|
||||||
cp l
|
|
||||||
ret z
|
|
||||||
ld [hl], b
|
|
||||||
add hl, de
|
|
||||||
jr .clearUnusedOAMEntriesLoop
|
|
||||||
|
|
||||||
Func_4bd1: ; 4bd1 (1:4bd1)
|
|
||||||
inc e
|
|
||||||
inc e
|
|
||||||
ld a, [de] ; c1x4
|
|
||||||
ld [$ff92], a
|
|
||||||
inc e
|
|
||||||
inc e
|
|
||||||
ld a, [de] ; c1x6
|
|
||||||
ld [$ff91], a
|
|
||||||
ld a, $4
|
|
||||||
add e
|
|
||||||
ld e, a
|
|
||||||
ld a, [$ff92]
|
|
||||||
add $4
|
|
||||||
and $f0
|
|
||||||
ld [de], a ; c1xa (sprite Y pos (snapped to whole steps (?))
|
|
||||||
inc e
|
|
||||||
ld a, [$ff91]
|
|
||||||
and $f0
|
|
||||||
ld [de], a ; c1xb (sprite X pos (snapped to whole steps (?))
|
|
||||||
ret
|
|
||||||
|
|
||||||
; copies DMA routine to HRAM. By GB specifications, all DMA needs to be done in HRAM (no other memory section is available during DMA)
|
|
||||||
WriteDMACodeToHRAM: ; 4bed (1:4bed)
|
|
||||||
ld c, $80
|
|
||||||
ld b, $a
|
|
||||||
ld hl, DMARoutine
|
|
||||||
.copyLoop
|
|
||||||
ld a, [hli]
|
|
||||||
ld [$ff00+c], a
|
|
||||||
inc c
|
|
||||||
dec b
|
|
||||||
jr nz, .copyLoop
|
|
||||||
ret
|
|
||||||
|
|
||||||
; this routine is copied to HRAM and executed there on every VBlank
|
|
||||||
DMARoutine: ; 4bfb (1:4bfb)
|
|
||||||
ld a, $c3
|
|
||||||
ld [$ff46], a ; start DMA
|
|
||||||
ld a, $28
|
|
||||||
.waitLoop ; wait for DMA to finish
|
|
||||||
dec a
|
|
||||||
jr nz, .waitLoop
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|
||||||
PrintWaitingText:
|
PrintWaitingText:
|
||||||
FuncCoord 3, 10
|
FuncCoord 3, 10
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue