mirror of
https://github.com/thornAvery/kep-hack.git
synced 2026-02-06 15:45:24 +13:00
Add subdirectories to engine/ similar to pokecrystal
This commit is contained in:
parent
5559d51c86
commit
f275790aec
124 changed files with 342 additions and 346 deletions
270
engine/gfx/hp_bar.asm
Executable file
270
engine/gfx/hp_bar.asm
Executable file
|
|
@ -0,0 +1,270 @@
|
|||
HPBarLength:
|
||||
call GetPredefRegisters
|
||||
|
||||
; calculates bc * 48 / de, the number of pixels the HP bar has
|
||||
; the result is always at least 1
|
||||
GetHPBarLength:
|
||||
push hl
|
||||
xor a
|
||||
ld hl, H_MULTIPLICAND
|
||||
ld [hli], a
|
||||
ld a, b
|
||||
ld [hli], a
|
||||
ld a, c
|
||||
ld [hli], a
|
||||
ld [hl], $30
|
||||
call Multiply ; 48 * bc (hp bar is 48 pixels long)
|
||||
ld a, d
|
||||
and a
|
||||
jr z, .maxHPSmaller256
|
||||
srl d ; make HP in de fit into 1 byte by dividing by 4
|
||||
rr e
|
||||
srl d
|
||||
rr e
|
||||
ld a, [H_MULTIPLICAND+1]
|
||||
ld b, a
|
||||
ld a, [H_MULTIPLICAND+2]
|
||||
srl b ; divide multiplication result as well
|
||||
rr a
|
||||
srl b
|
||||
rr a
|
||||
ld [H_MULTIPLICAND+2], a
|
||||
ld a, b
|
||||
ld [H_MULTIPLICAND+1], a
|
||||
.maxHPSmaller256
|
||||
ld a, e
|
||||
ld [H_DIVISOR], a
|
||||
ld b, $4
|
||||
call Divide
|
||||
ld a, [H_MULTIPLICAND+2]
|
||||
ld e, a ; e = bc * 48 / de (num of pixels of HP bar)
|
||||
pop hl
|
||||
and a
|
||||
ret nz
|
||||
ld e, $1 ; make result at least 1
|
||||
ret
|
||||
|
||||
; predef $48
|
||||
UpdateHPBar:
|
||||
UpdateHPBar2:
|
||||
push hl
|
||||
ld hl, wHPBarOldHP
|
||||
ld a, [hli]
|
||||
ld c, a ; old HP into bc
|
||||
ld a, [hli]
|
||||
ld b, a
|
||||
ld a, [hli]
|
||||
ld e, a ; new HP into de
|
||||
ld d, [hl]
|
||||
pop hl
|
||||
push de
|
||||
push bc
|
||||
call UpdateHPBar_CalcHPDifference
|
||||
ld a, e
|
||||
ld [wHPBarHPDifference+1], a
|
||||
ld a, d
|
||||
ld [wHPBarHPDifference], a
|
||||
pop bc
|
||||
pop de
|
||||
call UpdateHPBar_CompareNewHPToOldHP
|
||||
ret z
|
||||
ld a, $ff
|
||||
jr c, .HPdecrease
|
||||
ld a, $1
|
||||
.HPdecrease
|
||||
ld [wHPBarDelta], a
|
||||
call GetPredefRegisters
|
||||
ld a, [wHPBarNewHP]
|
||||
ld e, a
|
||||
ld a, [wHPBarNewHP+1]
|
||||
ld d, a
|
||||
.animateHPBarLoop
|
||||
push de
|
||||
ld a, [wHPBarOldHP]
|
||||
ld c, a
|
||||
ld a, [wHPBarOldHP+1]
|
||||
ld b, a
|
||||
call UpdateHPBar_CompareNewHPToOldHP
|
||||
jr z, .animateHPBarDone
|
||||
jr nc, .HPIncrease
|
||||
; HP decrease
|
||||
dec bc ; subtract 1 HP
|
||||
ld a, c
|
||||
ld [wHPBarNewHP], a
|
||||
ld a, b
|
||||
ld [wHPBarNewHP+1], a
|
||||
call UpdateHPBar_CalcOldNewHPBarPixels
|
||||
ld a, e
|
||||
sub d ; calc pixel difference
|
||||
jr .ok
|
||||
.HPIncrease
|
||||
inc bc ; add 1 HP
|
||||
ld a, c
|
||||
ld [wHPBarNewHP], a
|
||||
ld a, b
|
||||
ld [wHPBarNewHP+1], a
|
||||
call UpdateHPBar_CalcOldNewHPBarPixels
|
||||
ld a, d
|
||||
sub e ; calc pixel difference
|
||||
.ok
|
||||
call UpdateHPBar_PrintHPNumber
|
||||
and a
|
||||
jr z, .noPixelDifference
|
||||
call UpdateHPBar_AnimateHPBar
|
||||
.noPixelDifference
|
||||
ld a, [wHPBarNewHP]
|
||||
ld [wHPBarOldHP], a
|
||||
ld a, [wHPBarNewHP+1]
|
||||
ld [wHPBarOldHP+1], a
|
||||
pop de
|
||||
jr .animateHPBarLoop
|
||||
.animateHPBarDone
|
||||
pop de
|
||||
ld a, e
|
||||
ld [wHPBarOldHP], a
|
||||
ld a, d
|
||||
ld [wHPBarOldHP+1], a
|
||||
or e
|
||||
jr z, .monFainted
|
||||
call UpdateHPBar_CalcOldNewHPBarPixels
|
||||
ld d, e
|
||||
.monFainted
|
||||
call UpdateHPBar_PrintHPNumber
|
||||
ld a, $1
|
||||
call UpdateHPBar_AnimateHPBar
|
||||
jp Delay3
|
||||
|
||||
; animates the HP bar going up or down for (a) ticks (two waiting frames each)
|
||||
; stops prematurely if bar is filled up
|
||||
; e: current health (in pixels) to start with
|
||||
UpdateHPBar_AnimateHPBar:
|
||||
push hl
|
||||
.barAnimationLoop
|
||||
push af
|
||||
push de
|
||||
ld d, $6
|
||||
call DrawHPBar
|
||||
ld c, 2
|
||||
call DelayFrames
|
||||
pop de
|
||||
ld a, [wHPBarDelta] ; +1 or -1
|
||||
add e
|
||||
cp $31
|
||||
jr nc, .barFilledUp
|
||||
ld e, a
|
||||
pop af
|
||||
dec a
|
||||
jr nz, .barAnimationLoop
|
||||
pop hl
|
||||
ret
|
||||
.barFilledUp
|
||||
pop af
|
||||
pop hl
|
||||
ret
|
||||
|
||||
; compares old HP and new HP and sets c and z flags accordingly
|
||||
UpdateHPBar_CompareNewHPToOldHP:
|
||||
ld a, d
|
||||
sub b
|
||||
ret nz
|
||||
ld a, e
|
||||
sub c
|
||||
ret
|
||||
|
||||
; calcs HP difference between bc and de (into de)
|
||||
UpdateHPBar_CalcHPDifference:
|
||||
ld a, d
|
||||
sub b
|
||||
jr c, .oldHPGreater
|
||||
jr z, .testLowerByte
|
||||
.newHPGreater
|
||||
ld a, e
|
||||
sub c
|
||||
ld e, a
|
||||
ld a, d
|
||||
sbc b
|
||||
ld d, a
|
||||
ret
|
||||
.oldHPGreater
|
||||
ld a, c
|
||||
sub e
|
||||
ld e, a
|
||||
ld a, b
|
||||
sbc d
|
||||
ld d, a
|
||||
ret
|
||||
.testLowerByte
|
||||
ld a, e
|
||||
sub c
|
||||
jr c, .oldHPGreater
|
||||
jr nz, .newHPGreater
|
||||
ld de, $0
|
||||
ret
|
||||
|
||||
UpdateHPBar_PrintHPNumber:
|
||||
push af
|
||||
push de
|
||||
ld a, [wHPBarType]
|
||||
and a
|
||||
jr z, .done ; don't print number in enemy HUD
|
||||
; convert from little-endian to big-endian for PrintNumber
|
||||
ld a, [wHPBarOldHP]
|
||||
ld [wHPBarTempHP + 1], a
|
||||
ld a, [wHPBarOldHP + 1]
|
||||
ld [wHPBarTempHP], a
|
||||
push hl
|
||||
ld a, [hFlags_0xFFF6]
|
||||
bit 0, a
|
||||
jr z, .asm_fb15
|
||||
ld de, $9
|
||||
jr .next
|
||||
.asm_fb15
|
||||
ld de, $15
|
||||
.next
|
||||
add hl, de
|
||||
push hl
|
||||
ld a, " "
|
||||
ld [hli], a
|
||||
ld [hli], a
|
||||
ld [hli], a
|
||||
pop hl
|
||||
ld de, wHPBarTempHP
|
||||
lb bc, 2, 3
|
||||
call PrintNumber
|
||||
call DelayFrame
|
||||
pop hl
|
||||
.done
|
||||
pop de
|
||||
pop af
|
||||
ret
|
||||
|
||||
; calcs number of HP bar pixels for old and new HP value
|
||||
; d: new pixels
|
||||
; e: old pixels
|
||||
UpdateHPBar_CalcOldNewHPBarPixels:
|
||||
push hl
|
||||
ld hl, wHPBarMaxHP
|
||||
ld a, [hli] ; max HP into de
|
||||
ld e, a
|
||||
ld a, [hli]
|
||||
ld d, a
|
||||
ld a, [hli] ; old HP into bc
|
||||
ld c, a
|
||||
ld a, [hli]
|
||||
ld b, a
|
||||
ld a, [hli] ; new HP into hl
|
||||
ld h, [hl]
|
||||
ld l, a
|
||||
push hl
|
||||
push de
|
||||
call GetHPBarLength ; calc num pixels for old HP
|
||||
ld a, e
|
||||
pop de
|
||||
pop bc
|
||||
push af
|
||||
call GetHPBarLength ; calc num pixels for new HP
|
||||
pop af
|
||||
ld d, e
|
||||
ld e, a
|
||||
pop hl
|
||||
ret
|
||||
11
engine/gfx/load_pokedex_tiles.asm
Executable file
11
engine/gfx/load_pokedex_tiles.asm
Executable file
|
|
@ -0,0 +1,11 @@
|
|||
; Loads tile patterns for tiles used in the pokedex.
|
||||
LoadPokedexTilePatterns:
|
||||
call LoadHpBarAndStatusTilePatterns
|
||||
ld de, PokedexTileGraphics
|
||||
ld hl, vChars2 + $600
|
||||
lb bc, BANK(PokedexTileGraphics), (PokedexTileGraphicsEnd - PokedexTileGraphics) / $10
|
||||
call CopyVideoData
|
||||
ld de, PokeballTileGraphics
|
||||
ld hl, vChars2 + $720
|
||||
lb bc, BANK(PokeballTileGraphics), $01
|
||||
jp CopyVideoData ; load pokeball tile for marking caught mons
|
||||
295
engine/gfx/mon_icons.asm
Executable file
295
engine/gfx/mon_icons.asm
Executable file
|
|
@ -0,0 +1,295 @@
|
|||
AnimatePartyMon_ForceSpeed1:
|
||||
xor a
|
||||
ld [wCurrentMenuItem], a
|
||||
ld b, a
|
||||
inc a
|
||||
jr GetAnimationSpeed
|
||||
|
||||
; wPartyMenuHPBarColors contains the party mon's health bar colors
|
||||
; 0: green
|
||||
; 1: yellow
|
||||
; 2: red
|
||||
AnimatePartyMon::
|
||||
ld hl, wPartyMenuHPBarColors
|
||||
ld a, [wCurrentMenuItem]
|
||||
ld c, a
|
||||
ld b, 0
|
||||
add hl, bc
|
||||
ld a, [hl]
|
||||
|
||||
GetAnimationSpeed:
|
||||
ld c, a
|
||||
ld hl, PartyMonSpeeds
|
||||
add hl, bc
|
||||
ld a, [wOnSGB]
|
||||
xor $1
|
||||
add [hl]
|
||||
ld c, a
|
||||
add a
|
||||
ld b, a
|
||||
ld a, [wAnimCounter]
|
||||
and a
|
||||
jr z, .resetSprites
|
||||
cp c
|
||||
jr z, .animateSprite
|
||||
.incTimer
|
||||
inc a
|
||||
cp b
|
||||
jr nz, .skipResetTimer
|
||||
xor a ; reset timer
|
||||
.skipResetTimer
|
||||
ld [wAnimCounter], a
|
||||
jp DelayFrame
|
||||
.resetSprites
|
||||
push bc
|
||||
ld hl, wMonPartySpritesSavedOAM
|
||||
ld de, wOAMBuffer
|
||||
ld bc, $60
|
||||
call CopyData
|
||||
pop bc
|
||||
xor a
|
||||
jr .incTimer
|
||||
.animateSprite
|
||||
push bc
|
||||
ld hl, wOAMBuffer + $02 ; OAM tile id
|
||||
ld bc, $10
|
||||
ld a, [wCurrentMenuItem]
|
||||
call AddNTimes
|
||||
ld c, $40 ; amount to increase the tile id by
|
||||
ld a, [hl]
|
||||
cp $4 ; tile ID for ICON_BALL
|
||||
jr z, .editCoords
|
||||
cp $8 ; tile ID for ICON_HELIX
|
||||
jr nz, .editTileIDS
|
||||
; ICON_BALL and ICON_HELIX only shake up and down
|
||||
.editCoords
|
||||
dec hl
|
||||
dec hl ; dec hl to the OAM y coord
|
||||
ld c, $1 ; amount to increase the y coord by
|
||||
; otherwise, load a second sprite frame
|
||||
.editTileIDS
|
||||
ld b, $4
|
||||
ld de, $4
|
||||
.loop
|
||||
ld a, [hl]
|
||||
add c
|
||||
ld [hl], a
|
||||
add hl, de
|
||||
dec b
|
||||
jr nz, .loop
|
||||
pop bc
|
||||
ld a, c
|
||||
jr .incTimer
|
||||
|
||||
; Party mon animations cycle between 2 frames.
|
||||
; The members of the PartyMonSpeeds array specify the number of V-blanks
|
||||
; that each frame lasts for green HP, yellow HP, and red HP in order.
|
||||
; On the naming screen, the yellow HP speed is always used.
|
||||
PartyMonSpeeds:
|
||||
db 5, 16, 32
|
||||
|
||||
LoadMonPartySpriteGfx:
|
||||
; Load mon party sprite tile patterns into VRAM during V-blank.
|
||||
ld hl, MonPartySpritePointers
|
||||
ld a, $1c
|
||||
|
||||
LoadAnimSpriteGfx:
|
||||
; Load animated sprite tile patterns into VRAM during V-blank. hl is the address
|
||||
; of an array of structures that contain arguments for CopyVideoData and a is
|
||||
; the number of structures in the array.
|
||||
ld bc, $0
|
||||
.loop
|
||||
push af
|
||||
push bc
|
||||
push hl
|
||||
add hl, bc
|
||||
ld a, [hli]
|
||||
ld e, a
|
||||
ld a, [hli]
|
||||
ld d, a
|
||||
ld a, [hli]
|
||||
ld c, a
|
||||
ld a, [hli]
|
||||
ld b, a
|
||||
ld a, [hli]
|
||||
ld h, [hl]
|
||||
ld l, a
|
||||
call CopyVideoData
|
||||
pop hl
|
||||
pop bc
|
||||
ld a, $6
|
||||
add c
|
||||
ld c, a
|
||||
pop af
|
||||
dec a
|
||||
jr nz, .loop
|
||||
ret
|
||||
|
||||
LoadMonPartySpriteGfxWithLCDDisabled:
|
||||
; Load mon party sprite tile patterns into VRAM immediately by disabling the
|
||||
; LCD.
|
||||
call DisableLCD
|
||||
ld hl, MonPartySpritePointers
|
||||
ld a, $1c
|
||||
ld bc, $0
|
||||
.loop
|
||||
push af
|
||||
push bc
|
||||
push hl
|
||||
add hl, bc
|
||||
ld a, [hli]
|
||||
ld e, a
|
||||
ld a, [hli]
|
||||
ld d, a
|
||||
push de
|
||||
ld a, [hli]
|
||||
ld c, a
|
||||
swap c
|
||||
ld b, $0
|
||||
ld a, [hli]
|
||||
ld e, [hl]
|
||||
inc hl
|
||||
ld d, [hl]
|
||||
pop hl
|
||||
call FarCopyData2
|
||||
pop hl
|
||||
pop bc
|
||||
ld a, $6
|
||||
add c
|
||||
ld c, a
|
||||
pop af
|
||||
dec a
|
||||
jr nz, .loop
|
||||
jp EnableLCD
|
||||
|
||||
INCLUDE "data/mon_party_sprite_pointers.asm"
|
||||
|
||||
WriteMonPartySpriteOAMByPartyIndex:
|
||||
; Write OAM blocks for the party mon in [hPartyMonIndex].
|
||||
push hl
|
||||
push de
|
||||
push bc
|
||||
ld a, [hPartyMonIndex]
|
||||
ld hl, wPartySpecies
|
||||
ld e, a
|
||||
ld d, 0
|
||||
add hl, de
|
||||
ld a, [hl]
|
||||
call GetPartyMonSpriteID
|
||||
ld [wOAMBaseTile], a
|
||||
call WriteMonPartySpriteOAM
|
||||
pop bc
|
||||
pop de
|
||||
pop hl
|
||||
ret
|
||||
|
||||
WriteMonPartySpriteOAMBySpecies:
|
||||
; Write OAM blocks for the party sprite of the species in
|
||||
; [wMonPartySpriteSpecies].
|
||||
xor a
|
||||
ld [hPartyMonIndex], a
|
||||
ld a, [wMonPartySpriteSpecies]
|
||||
call GetPartyMonSpriteID
|
||||
ld [wOAMBaseTile], a
|
||||
jr WriteMonPartySpriteOAM
|
||||
|
||||
UnusedPartyMonSpriteFunction:
|
||||
; This function is unused and doesn't appear to do anything useful. It looks
|
||||
; like it may have been intended to load the tile patterns and OAM data for
|
||||
; the mon party sprite associated with the species in [wcf91].
|
||||
; However, its calculations are off and it loads garbage data.
|
||||
ld a, [wcf91]
|
||||
call GetPartyMonSpriteID
|
||||
push af
|
||||
ld hl, vSprites
|
||||
call .LoadTilePatterns
|
||||
pop af
|
||||
add $54
|
||||
ld hl, vSprites + $40
|
||||
call .LoadTilePatterns
|
||||
xor a
|
||||
ld [wMonPartySpriteSpecies], a
|
||||
jr WriteMonPartySpriteOAMBySpecies
|
||||
|
||||
.LoadTilePatterns
|
||||
push hl
|
||||
add a
|
||||
ld c, a
|
||||
ld b, 0
|
||||
ld hl, MonPartySpritePointers
|
||||
add hl, bc
|
||||
add hl, bc
|
||||
add hl, bc
|
||||
ld a, [hli]
|
||||
ld e, a
|
||||
ld a, [hli]
|
||||
ld d, a
|
||||
ld a, [hli]
|
||||
ld c, a
|
||||
ld a, [hli]
|
||||
ld b, a
|
||||
pop hl
|
||||
jp CopyVideoData
|
||||
|
||||
WriteMonPartySpriteOAM:
|
||||
; Write the OAM blocks for the first animation frame into the OAM buffer and
|
||||
; make a copy at wMonPartySpritesSavedOAM.
|
||||
push af
|
||||
ld c, $10
|
||||
ld h, wOAMBuffer / $100
|
||||
ld a, [hPartyMonIndex]
|
||||
swap a
|
||||
ld l, a
|
||||
add $10
|
||||
ld b, a
|
||||
pop af
|
||||
cp ICON_HELIX << 2
|
||||
jr z, .helix
|
||||
call WriteSymmetricMonPartySpriteOAM
|
||||
jr .makeCopy
|
||||
.helix
|
||||
call WriteAsymmetricMonPartySpriteOAM
|
||||
; Make a copy of the OAM buffer with the first animation frame written so that
|
||||
; we can flip back to it from the second frame by copying it back.
|
||||
.makeCopy
|
||||
ld hl, wOAMBuffer
|
||||
ld de, wMonPartySpritesSavedOAM
|
||||
ld bc, $60
|
||||
jp CopyData
|
||||
|
||||
GetPartyMonSpriteID:
|
||||
ld [wd11e], a
|
||||
predef IndexToPokedex
|
||||
ld a, [wd11e]
|
||||
ld c, a
|
||||
dec a
|
||||
srl a
|
||||
ld hl, MonPartyData
|
||||
ld e, a
|
||||
ld d, 0
|
||||
add hl, de
|
||||
ld a, [hl]
|
||||
bit 0, c
|
||||
jr nz, .skipSwap
|
||||
swap a ; use lower nybble if pokedex num is even
|
||||
.skipSwap
|
||||
and $f0
|
||||
srl a
|
||||
srl a
|
||||
ret
|
||||
|
||||
INCLUDE "data/mon_party_sprites.asm"
|
||||
|
||||
INC_FRAME_1 EQUS "0, $20"
|
||||
INC_FRAME_2 EQUS "$20, $20"
|
||||
|
||||
BugIconFrame1: INCBIN "gfx/icons/bug.2bpp", INC_FRAME_1
|
||||
PlantIconFrame1: INCBIN "gfx/icons/plant.2bpp", INC_FRAME_1
|
||||
BugIconFrame2: INCBIN "gfx/icons/bug.2bpp", INC_FRAME_2
|
||||
PlantIconFrame2: INCBIN "gfx/icons/plant.2bpp", INC_FRAME_2
|
||||
SnakeIconFrame1: INCBIN "gfx/icons/snake.2bpp", INC_FRAME_1
|
||||
QuadrupedIconFrame1: INCBIN "gfx/icons/quadruped.2bpp", INC_FRAME_1
|
||||
SnakeIconFrame2: INCBIN "gfx/icons/snake.2bpp", INC_FRAME_2
|
||||
QuadrupedIconFrame2: INCBIN "gfx/icons/quadruped.2bpp", INC_FRAME_2
|
||||
|
||||
TradeBubbleIconGFX: INCBIN "gfx/trade/bubble.2bpp"
|
||||
26
engine/gfx/oam_dma.asm
Normal file
26
engine/gfx/oam_dma.asm
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
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, wOAMBuffer / $100
|
||||
ld [rDMA], a
|
||||
|
||||
; wait for DMA to finish
|
||||
ld a, $28
|
||||
.wait
|
||||
dec a
|
||||
jr nz, .wait
|
||||
ret
|
||||
DMARoutineEnd:
|
||||
641
engine/gfx/palettes.asm
Executable file
641
engine/gfx/palettes.asm
Executable file
|
|
@ -0,0 +1,641 @@
|
|||
_RunPaletteCommand:
|
||||
call GetPredefRegisters
|
||||
ld a, b
|
||||
cp $ff
|
||||
jr nz, .next
|
||||
ld a, [wDefaultPaletteCommand] ; use default command if command ID is $ff
|
||||
.next
|
||||
cp UPDATE_PARTY_MENU_BLK_PACKET
|
||||
jp z, UpdatePartyMenuBlkPacket
|
||||
ld l, a
|
||||
ld h, 0
|
||||
add hl, hl
|
||||
ld de, SetPalFunctions
|
||||
add hl, de
|
||||
ld a, [hli]
|
||||
ld h, [hl]
|
||||
ld l, a
|
||||
ld de, SendSGBPackets
|
||||
push de
|
||||
jp hl
|
||||
|
||||
SetPal_BattleBlack:
|
||||
ld hl, PalPacket_Black
|
||||
ld de, BlkPacket_Battle
|
||||
ret
|
||||
|
||||
; uses PalPacket_Empty to build a packet based on mon IDs and health color
|
||||
SetPal_Battle:
|
||||
ld hl, PalPacket_Empty
|
||||
ld de, wPalPacket
|
||||
ld bc, $10
|
||||
call CopyData
|
||||
ld a, [wPlayerBattleStatus3]
|
||||
ld hl, wBattleMonSpecies
|
||||
call DeterminePaletteID
|
||||
ld b, a
|
||||
ld a, [wEnemyBattleStatus3]
|
||||
ld hl, wEnemyMonSpecies2
|
||||
call DeterminePaletteID
|
||||
ld c, a
|
||||
ld hl, wPalPacket + 1
|
||||
ld a, [wPlayerHPBarColor]
|
||||
add PAL_GREENBAR
|
||||
ld [hli], a
|
||||
inc hl
|
||||
ld a, [wEnemyHPBarColor]
|
||||
add PAL_GREENBAR
|
||||
ld [hli], a
|
||||
inc hl
|
||||
ld a, b
|
||||
ld [hli], a
|
||||
inc hl
|
||||
ld a, c
|
||||
ld [hl], a
|
||||
ld hl, wPalPacket
|
||||
ld de, BlkPacket_Battle
|
||||
ld a, SET_PAL_BATTLE
|
||||
ld [wDefaultPaletteCommand], a
|
||||
ret
|
||||
|
||||
SetPal_TownMap:
|
||||
ld hl, PalPacket_TownMap
|
||||
ld de, BlkPacket_WholeScreen
|
||||
ret
|
||||
|
||||
; uses PalPacket_Empty to build a packet based the mon ID
|
||||
SetPal_StatusScreen:
|
||||
ld hl, PalPacket_Empty
|
||||
ld de, wPalPacket
|
||||
ld bc, $10
|
||||
call CopyData
|
||||
ld a, [wcf91]
|
||||
cp NUM_POKEMON_INDEXES + 1
|
||||
jr c, .pokemon
|
||||
ld a, $1 ; not pokemon
|
||||
.pokemon
|
||||
call DeterminePaletteIDOutOfBattle
|
||||
push af
|
||||
ld hl, wPalPacket + 1
|
||||
ld a, [wStatusScreenHPBarColor]
|
||||
add PAL_GREENBAR
|
||||
ld [hli], a
|
||||
inc hl
|
||||
pop af
|
||||
ld [hl], a
|
||||
ld hl, wPalPacket
|
||||
ld de, BlkPacket_StatusScreen
|
||||
ret
|
||||
|
||||
SetPal_PartyMenu:
|
||||
ld hl, PalPacket_PartyMenu
|
||||
ld de, wPartyMenuBlkPacket
|
||||
ret
|
||||
|
||||
SetPal_Pokedex:
|
||||
ld hl, PalPacket_Pokedex
|
||||
ld de, wPalPacket
|
||||
ld bc, $10
|
||||
call CopyData
|
||||
ld a, [wcf91]
|
||||
call DeterminePaletteIDOutOfBattle
|
||||
ld hl, wPalPacket + 3
|
||||
ld [hl], a
|
||||
ld hl, wPalPacket
|
||||
ld de, BlkPacket_Pokedex
|
||||
ret
|
||||
|
||||
SetPal_Slots:
|
||||
ld hl, PalPacket_Slots
|
||||
ld de, BlkPacket_Slots
|
||||
ret
|
||||
|
||||
SetPal_TitleScreen:
|
||||
ld hl, PalPacket_Titlescreen
|
||||
ld de, BlkPacket_Titlescreen
|
||||
ret
|
||||
|
||||
; used mostly for menus and the Oak intro
|
||||
SetPal_Generic:
|
||||
ld hl, PalPacket_Generic
|
||||
ld de, BlkPacket_WholeScreen
|
||||
ret
|
||||
|
||||
SetPal_NidorinoIntro:
|
||||
ld hl, PalPacket_NidorinoIntro
|
||||
ld de, BlkPacket_NidorinoIntro
|
||||
ret
|
||||
|
||||
SetPal_GameFreakIntro:
|
||||
ld hl, PalPacket_GameFreakIntro
|
||||
ld de, BlkPacket_GameFreakIntro
|
||||
ld a, SET_PAL_GENERIC
|
||||
ld [wDefaultPaletteCommand], a
|
||||
ret
|
||||
|
||||
; uses PalPacket_Empty to build a packet based on the current map
|
||||
SetPal_Overworld:
|
||||
ld hl, PalPacket_Empty
|
||||
ld de, wPalPacket
|
||||
ld bc, $10
|
||||
call CopyData
|
||||
ld a, [wCurMapTileset]
|
||||
cp CEMETERY
|
||||
jr z, .PokemonTowerOrAgatha
|
||||
cp CAVERN
|
||||
jr z, .caveOrBruno
|
||||
ld a, [wCurMap]
|
||||
cp REDS_HOUSE_1F
|
||||
jr c, .townOrRoute
|
||||
cp CERULEAN_CAVE_2F
|
||||
jr c, .normalDungeonOrBuilding
|
||||
cp NAME_RATERS_HOUSE
|
||||
jr c, .caveOrBruno
|
||||
cp LORELEIS_ROOM
|
||||
jr z, .Lorelei
|
||||
cp BRUNOS_ROOM
|
||||
jr z, .caveOrBruno
|
||||
.normalDungeonOrBuilding
|
||||
ld a, [wLastMap] ; town or route that current dungeon or building is located
|
||||
.townOrRoute
|
||||
cp SAFFRON_CITY + 1
|
||||
jr c, .town
|
||||
ld a, PAL_ROUTE - 1
|
||||
.town
|
||||
inc a ; a town's palette ID is its map ID + 1
|
||||
ld hl, wPalPacket + 1
|
||||
ld [hld], a
|
||||
ld de, BlkPacket_WholeScreen
|
||||
ld a, SET_PAL_OVERWORLD
|
||||
ld [wDefaultPaletteCommand], a
|
||||
ret
|
||||
.PokemonTowerOrAgatha
|
||||
ld a, PAL_GREYMON - 1
|
||||
jr .town
|
||||
.caveOrBruno
|
||||
ld a, PAL_CAVE - 1
|
||||
jr .town
|
||||
.Lorelei
|
||||
xor a
|
||||
jr .town
|
||||
|
||||
; used when a Pokemon is the only thing on the screen
|
||||
; such as evolution, trading and the Hall of Fame
|
||||
SetPal_PokemonWholeScreen:
|
||||
push bc
|
||||
ld hl, PalPacket_Empty
|
||||
ld de, wPalPacket
|
||||
ld bc, $10
|
||||
call CopyData
|
||||
pop bc
|
||||
ld a, c
|
||||
and a
|
||||
ld a, PAL_BLACK
|
||||
jr nz, .next
|
||||
ld a, [wWholeScreenPaletteMonSpecies]
|
||||
call DeterminePaletteIDOutOfBattle
|
||||
.next
|
||||
ld [wPalPacket + 1], a
|
||||
ld hl, wPalPacket
|
||||
ld de, BlkPacket_WholeScreen
|
||||
ret
|
||||
|
||||
SetPal_TrainerCard:
|
||||
ld hl, BlkPacket_TrainerCard
|
||||
ld de, wTrainerCardBlkPacket
|
||||
ld bc, $40
|
||||
call CopyData
|
||||
ld de, BadgeBlkDataLengths
|
||||
ld hl, wTrainerCardBlkPacket + 2
|
||||
ld a, [wObtainedBadges]
|
||||
ld c, 8
|
||||
.badgeLoop
|
||||
srl a
|
||||
push af
|
||||
jr c, .haveBadge
|
||||
; The player doens't have the badge, so zero the badge's blk data.
|
||||
push bc
|
||||
ld a, [de]
|
||||
ld c, a
|
||||
xor a
|
||||
.zeroBadgeDataLoop
|
||||
ld [hli], a
|
||||
dec c
|
||||
jr nz, .zeroBadgeDataLoop
|
||||
pop bc
|
||||
jr .nextBadge
|
||||
.haveBadge
|
||||
; The player does have the badge, so skip past the badge's blk data.
|
||||
ld a, [de]
|
||||
.skipBadgeDataLoop
|
||||
inc hl
|
||||
dec a
|
||||
jr nz, .skipBadgeDataLoop
|
||||
.nextBadge
|
||||
pop af
|
||||
inc de
|
||||
dec c
|
||||
jr nz, .badgeLoop
|
||||
ld hl, PalPacket_TrainerCard
|
||||
ld de, wTrainerCardBlkPacket
|
||||
ret
|
||||
|
||||
SetPalFunctions:
|
||||
dw SetPal_BattleBlack
|
||||
dw SetPal_Battle
|
||||
dw SetPal_TownMap
|
||||
dw SetPal_StatusScreen
|
||||
dw SetPal_Pokedex
|
||||
dw SetPal_Slots
|
||||
dw SetPal_TitleScreen
|
||||
dw SetPal_NidorinoIntro
|
||||
dw SetPal_Generic
|
||||
dw SetPal_Overworld
|
||||
dw SetPal_PartyMenu
|
||||
dw SetPal_PokemonWholeScreen
|
||||
dw SetPal_GameFreakIntro
|
||||
dw SetPal_TrainerCard
|
||||
|
||||
; The length of the blk data of each badge on the Trainer Card.
|
||||
; The Rainbow Badge has 3 entries because of its many colors.
|
||||
BadgeBlkDataLengths:
|
||||
db 6 ; Boulder Badge
|
||||
db 6 ; Cascade Badge
|
||||
db 6 ; Thunder Badge
|
||||
db 6 * 3 ; Rainbow Badge
|
||||
db 6 ; Soul Badge
|
||||
db 6 ; Marsh Badge
|
||||
db 6 ; Volcano Badge
|
||||
db 6 ; Earth Badge
|
||||
|
||||
DeterminePaletteID:
|
||||
bit TRANSFORMED, a ; a is battle status 3
|
||||
ld a, PAL_GREYMON ; if the mon has used Transform, use Ditto's palette
|
||||
ret nz
|
||||
ld a, [hl]
|
||||
DeterminePaletteIDOutOfBattle:
|
||||
ld [wd11e], a
|
||||
and a ; is the mon index 0?
|
||||
jr z, .skipDexNumConversion
|
||||
push bc
|
||||
predef IndexToPokedex
|
||||
pop bc
|
||||
ld a, [wd11e]
|
||||
.skipDexNumConversion
|
||||
ld e, a
|
||||
ld d, 0
|
||||
ld hl, MonsterPalettes ; not just for Pokemon, Trainers use it too
|
||||
add hl, de
|
||||
ld a, [hl]
|
||||
ret
|
||||
|
||||
InitPartyMenuBlkPacket:
|
||||
ld hl, BlkPacket_PartyMenu
|
||||
ld de, wPartyMenuBlkPacket
|
||||
ld bc, $30
|
||||
jp CopyData
|
||||
|
||||
UpdatePartyMenuBlkPacket:
|
||||
; Update the blk packet with the palette of the HP bar that is
|
||||
; specified in [wWhichPartyMenuHPBar].
|
||||
ld hl, wPartyMenuHPBarColors
|
||||
ld a, [wWhichPartyMenuHPBar]
|
||||
ld e, a
|
||||
ld d, 0
|
||||
add hl, de
|
||||
ld e, l
|
||||
ld d, h
|
||||
ld a, [de]
|
||||
and a
|
||||
ld e, (1 << 2) | 1 ; green
|
||||
jr z, .next
|
||||
dec a
|
||||
ld e, (2 << 2) | 2 ; yellow
|
||||
jr z, .next
|
||||
ld e, (3 << 2) | 3 ; red
|
||||
.next
|
||||
push de
|
||||
ld hl, wPartyMenuBlkPacket + 8 + 1
|
||||
ld bc, 6
|
||||
ld a, [wWhichPartyMenuHPBar]
|
||||
call AddNTimes
|
||||
pop de
|
||||
ld [hl], e
|
||||
ret
|
||||
|
||||
SendSGBPacket:
|
||||
;check number of packets
|
||||
ld a, [hl]
|
||||
and $07
|
||||
ret z
|
||||
; store number of packets in B
|
||||
ld b, a
|
||||
.loop2
|
||||
; save B for later use
|
||||
push bc
|
||||
; disable ReadJoypad to prevent it from interfering with sending the packet
|
||||
ld a, 1
|
||||
ld [hDisableJoypadPolling], a
|
||||
; send RESET signal (P14=LOW, P15=LOW)
|
||||
xor a
|
||||
ld [rJOYP], a
|
||||
; set P14=HIGH, P15=HIGH
|
||||
ld a, $30
|
||||
ld [rJOYP], a
|
||||
;load length of packets (16 bytes)
|
||||
ld b, $10
|
||||
.nextByte
|
||||
;set bit counter (8 bits per byte)
|
||||
ld e, $08
|
||||
; get next byte in the packet
|
||||
ld a, [hli]
|
||||
ld d, a
|
||||
.nextBit0
|
||||
bit 0, d
|
||||
; if 0th bit is not zero set P14=HIGH,P15=LOW (send bit 1)
|
||||
ld a, $10
|
||||
jr nz, .next0
|
||||
; else (if 0th bit is zero) set P14=LOW,P15=HIGH (send bit 0)
|
||||
ld a, $20
|
||||
.next0
|
||||
ld [rJOYP], a
|
||||
; must set P14=HIGH,P15=HIGH between each "pulse"
|
||||
ld a, $30
|
||||
ld [rJOYP], a
|
||||
; rotation will put next bit in 0th position (so we can always use command
|
||||
; "bit 0,d" to fetch the bit that has to be sent)
|
||||
rr d
|
||||
; decrease bit counter so we know when we have sent all 8 bits of current byte
|
||||
dec e
|
||||
jr nz, .nextBit0
|
||||
dec b
|
||||
jr nz, .nextByte
|
||||
; send bit 1 as a "stop bit" (end of parameter data)
|
||||
ld a, $20
|
||||
ld [rJOYP], a
|
||||
; set P14=HIGH,P15=HIGH
|
||||
ld a, $30
|
||||
ld [rJOYP], a
|
||||
xor a
|
||||
ld [hDisableJoypadPolling], a
|
||||
; wait for about 70000 cycles
|
||||
call Wait7000
|
||||
; restore (previously pushed) number of packets
|
||||
pop bc
|
||||
dec b
|
||||
; return if there are no more packets
|
||||
ret z
|
||||
; else send 16 more bytes
|
||||
jr .loop2
|
||||
|
||||
LoadSGB:
|
||||
xor a
|
||||
ld [wOnSGB], a
|
||||
call CheckSGB
|
||||
ret nc
|
||||
ld a, 1
|
||||
ld [wOnSGB], a
|
||||
ld a, [wGBC]
|
||||
and a
|
||||
jr z, .notGBC
|
||||
ret
|
||||
.notGBC
|
||||
di
|
||||
call PrepareSuperNintendoVRAMTransfer
|
||||
ei
|
||||
ld a, 1
|
||||
ld [wCopyingSGBTileData], a
|
||||
ld de, ChrTrnPacket
|
||||
ld hl, SGBBorderGraphics
|
||||
call CopyGfxToSuperNintendoVRAM
|
||||
xor a
|
||||
ld [wCopyingSGBTileData], a
|
||||
ld de, PctTrnPacket
|
||||
ld hl, BorderPalettes
|
||||
call CopyGfxToSuperNintendoVRAM
|
||||
xor a
|
||||
ld [wCopyingSGBTileData], a
|
||||
ld de, PalTrnPacket
|
||||
ld hl, SuperPalettes
|
||||
call CopyGfxToSuperNintendoVRAM
|
||||
call ClearVram
|
||||
ld hl, MaskEnCancelPacket
|
||||
jp SendSGBPacket
|
||||
|
||||
PrepareSuperNintendoVRAMTransfer:
|
||||
ld hl, .packetPointers
|
||||
ld c, 9
|
||||
.loop
|
||||
push bc
|
||||
ld a, [hli]
|
||||
push hl
|
||||
ld h, [hl]
|
||||
ld l, a
|
||||
call SendSGBPacket
|
||||
pop hl
|
||||
inc hl
|
||||
pop bc
|
||||
dec c
|
||||
jr nz, .loop
|
||||
ret
|
||||
|
||||
.packetPointers
|
||||
; Only the first packet is needed.
|
||||
dw MaskEnFreezePacket
|
||||
dw DataSnd_72548
|
||||
dw DataSnd_72558
|
||||
dw DataSnd_72568
|
||||
dw DataSnd_72578
|
||||
dw DataSnd_72588
|
||||
dw DataSnd_72598
|
||||
dw DataSnd_725a8
|
||||
dw DataSnd_725b8
|
||||
|
||||
CheckSGB:
|
||||
; Returns whether the game is running on an SGB in carry.
|
||||
ld hl, MltReq2Packet
|
||||
di
|
||||
call SendSGBPacket
|
||||
ld a, 1
|
||||
ld [hDisableJoypadPolling], a
|
||||
ei
|
||||
call Wait7000
|
||||
ld a, [rJOYP]
|
||||
and $3
|
||||
cp $3
|
||||
jr nz, .isSGB
|
||||
ld a, $20
|
||||
ld [rJOYP], a
|
||||
ld a, [rJOYP]
|
||||
ld a, [rJOYP]
|
||||
call Wait7000
|
||||
call Wait7000
|
||||
ld a, $30
|
||||
ld [rJOYP], a
|
||||
call Wait7000
|
||||
call Wait7000
|
||||
ld a, $10
|
||||
ld [rJOYP], a
|
||||
ld a, [rJOYP]
|
||||
ld a, [rJOYP]
|
||||
ld a, [rJOYP]
|
||||
ld a, [rJOYP]
|
||||
ld a, [rJOYP]
|
||||
ld a, [rJOYP]
|
||||
call Wait7000
|
||||
call Wait7000
|
||||
ld a, $30
|
||||
ld [rJOYP], a
|
||||
ld a, [rJOYP]
|
||||
ld a, [rJOYP]
|
||||
ld a, [rJOYP]
|
||||
call Wait7000
|
||||
call Wait7000
|
||||
ld a, [rJOYP]
|
||||
and $3
|
||||
cp $3
|
||||
jr nz, .isSGB
|
||||
call SendMltReq1Packet
|
||||
and a
|
||||
ret
|
||||
.isSGB
|
||||
call SendMltReq1Packet
|
||||
scf
|
||||
ret
|
||||
|
||||
SendMltReq1Packet:
|
||||
ld hl, MltReq1Packet
|
||||
call SendSGBPacket
|
||||
jp Wait7000
|
||||
|
||||
CopyGfxToSuperNintendoVRAM:
|
||||
di
|
||||
push de
|
||||
call DisableLCD
|
||||
ld a, $e4
|
||||
ld [rBGP], a
|
||||
ld de, vChars1
|
||||
ld a, [wCopyingSGBTileData]
|
||||
and a
|
||||
jr z, .notCopyingTileData
|
||||
call CopySGBBorderTiles
|
||||
jr .next
|
||||
.notCopyingTileData
|
||||
ld bc, $1000
|
||||
call CopyData
|
||||
.next
|
||||
ld hl, vBGMap0
|
||||
ld de, $c
|
||||
ld a, $80
|
||||
ld c, $d
|
||||
.loop
|
||||
ld b, $14
|
||||
.innerLoop
|
||||
ld [hli], a
|
||||
inc a
|
||||
dec b
|
||||
jr nz, .innerLoop
|
||||
add hl, de
|
||||
dec c
|
||||
jr nz, .loop
|
||||
ld a, $e3
|
||||
ld [rLCDC], a
|
||||
pop hl
|
||||
call SendSGBPacket
|
||||
xor a
|
||||
ld [rBGP], a
|
||||
ei
|
||||
ret
|
||||
|
||||
Wait7000:
|
||||
; Each loop takes 9 cycles so this routine actually waits 63000 cycles.
|
||||
ld de, 7000
|
||||
.loop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
dec de
|
||||
ld a, d
|
||||
or e
|
||||
jr nz, .loop
|
||||
ret
|
||||
|
||||
SendSGBPackets:
|
||||
ld a, [wGBC]
|
||||
and a
|
||||
jr z, .notGBC
|
||||
push de
|
||||
call InitGBCPalettes
|
||||
pop hl
|
||||
call EmptyFunc5
|
||||
ret
|
||||
.notGBC
|
||||
push de
|
||||
call SendSGBPacket
|
||||
pop hl
|
||||
jp SendSGBPacket
|
||||
|
||||
InitGBCPalettes:
|
||||
ld a, $80 ; index 0 with auto-increment
|
||||
ld [rBGPI], a
|
||||
inc hl
|
||||
ld c, $20
|
||||
.loop
|
||||
ld a, [hli]
|
||||
inc hl
|
||||
add a
|
||||
add a
|
||||
add a
|
||||
ld de, SuperPalettes
|
||||
add e
|
||||
jr nc, .noCarry
|
||||
inc d
|
||||
.noCarry
|
||||
ld a, [de]
|
||||
ld [rBGPD], a
|
||||
dec c
|
||||
jr nz, .loop
|
||||
ret
|
||||
|
||||
EmptyFunc5:
|
||||
ret
|
||||
|
||||
CopySGBBorderTiles:
|
||||
; SGB tile data is stored in a 4BPP planar format.
|
||||
; Each tile is 32 bytes. The first 16 bytes contain bit planes 1 and 2, while
|
||||
; the second 16 bytes contain bit planes 3 and 4.
|
||||
; This function converts 2BPP planar data into this format by mapping
|
||||
; 2BPP colors 0-3 to 4BPP colors 0-3. 4BPP colors 4-15 are not used.
|
||||
ld b, 128
|
||||
|
||||
.tileLoop
|
||||
|
||||
; Copy bit planes 1 and 2 of the tile data.
|
||||
ld c, 16
|
||||
.copyLoop
|
||||
ld a, [hli]
|
||||
ld [de], a
|
||||
inc de
|
||||
dec c
|
||||
jr nz, .copyLoop
|
||||
|
||||
; Zero bit planes 3 and 4.
|
||||
ld c, 16
|
||||
xor a
|
||||
.zeroLoop
|
||||
ld [de], a
|
||||
inc de
|
||||
dec c
|
||||
jr nz, .zeroLoop
|
||||
|
||||
dec b
|
||||
jr nz, .tileLoop
|
||||
ret
|
||||
|
||||
INCLUDE "data/sgb_packets.asm"
|
||||
|
||||
INCLUDE "data/mon_palettes.asm"
|
||||
|
||||
INCLUDE "data/super_palettes.asm"
|
||||
|
||||
INCLUDE "data/sgb_border.asm"
|
||||
71
engine/gfx/screen_effects.asm
Executable file
71
engine/gfx/screen_effects.asm
Executable file
|
|
@ -0,0 +1,71 @@
|
|||
; b = new colour for BG colour 0 (usually white) for 4 frames
|
||||
ChangeBGPalColor0_4Frames:
|
||||
call GetPredefRegisters
|
||||
ld a, [rBGP]
|
||||
or b
|
||||
ld [rBGP], a
|
||||
ld c, 4
|
||||
call DelayFrames
|
||||
ld a, [rBGP]
|
||||
and %11111100
|
||||
ld [rBGP], a
|
||||
ret
|
||||
|
||||
PredefShakeScreenVertically:
|
||||
; Moves the window down and then back in a sequence of progressively smaller
|
||||
; numbers of pixels, starting at b.
|
||||
call GetPredefRegisters
|
||||
ld a, 1
|
||||
ld [wDisableVBlankWYUpdate], a
|
||||
xor a
|
||||
.loop
|
||||
ld [$ff96], a
|
||||
call .MutateWY
|
||||
call .MutateWY
|
||||
dec b
|
||||
ld a, b
|
||||
jr nz, .loop
|
||||
xor a
|
||||
ld [wDisableVBlankWYUpdate], a
|
||||
ret
|
||||
|
||||
.MutateWY
|
||||
ld a, [$ff96]
|
||||
xor b
|
||||
ld [$ff96], a
|
||||
ld [rWY], a
|
||||
ld c, 3
|
||||
jp DelayFrames
|
||||
|
||||
PredefShakeScreenHorizontally:
|
||||
; Moves the window right and then back in a sequence of progressively smaller
|
||||
; numbers of pixels, starting at b.
|
||||
call GetPredefRegisters
|
||||
xor a
|
||||
.loop
|
||||
ld [$ff97], a
|
||||
call .MutateWX
|
||||
ld c, 1
|
||||
call DelayFrames
|
||||
call .MutateWX
|
||||
dec b
|
||||
ld a, b
|
||||
jr nz, .loop
|
||||
|
||||
; restore normal WX
|
||||
ld a, 7
|
||||
ld [rWX], a
|
||||
ret
|
||||
|
||||
.MutateWX
|
||||
ld a, [$ff97]
|
||||
xor b
|
||||
ld [$ff97], a
|
||||
bit 7, a
|
||||
jr z, .skipZeroing
|
||||
xor a ; zero a if it's negative
|
||||
.skipZeroing
|
||||
add 7
|
||||
ld [rWX], a
|
||||
ld c, 4
|
||||
jp DelayFrames
|
||||
189
engine/gfx/sprite_oam.asm
Normal file
189
engine/gfx/sprite_oam.asm
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
PrepareOAMData::
|
||||
; Determine OAM data for currently visible
|
||||
; sprites and write it to wOAMBuffer.
|
||||
|
||||
ld a, [wUpdateSpritesEnabled]
|
||||
dec a
|
||||
jr z, .updateEnabled
|
||||
|
||||
cp -1
|
||||
ret nz
|
||||
ld [wUpdateSpritesEnabled], a
|
||||
jp HideSprites
|
||||
|
||||
.updateEnabled
|
||||
xor a
|
||||
ld [hOAMBufferOffset], a
|
||||
|
||||
.spriteLoop
|
||||
ld [hSpriteOffset2], a
|
||||
|
||||
ld d, wSpriteStateData1 / $100
|
||||
ld a, [hSpriteOffset2]
|
||||
ld e, a
|
||||
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
|
||||
and $f
|
||||
add $10 ; skip to the second half of the table which doesn't account for facing direction
|
||||
jr .next
|
||||
|
||||
.usefacing
|
||||
and $f
|
||||
|
||||
.next
|
||||
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
|
||||
|
||||
; read the entry from the table
|
||||
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 GetSpriteScreenXY
|
||||
|
||||
ld a, [hOAMBufferOffset]
|
||||
ld e, a
|
||||
ld d, wOAMBuffer / $100
|
||||
|
||||
.tileLoop
|
||||
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
|
||||
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
|
||||
inc e
|
||||
ld [de], a ; write new sprite OAM X position
|
||||
inc e
|
||||
ld a, [bc] ; read pattern number offset (accommodates orientation (offset 0,4 or 8) and animation (offset 0 or $80))
|
||||
inc bc
|
||||
push bc
|
||||
ld b, a
|
||||
|
||||
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
|
||||
jr .next2
|
||||
|
||||
.notFourTileSprite
|
||||
; a *= 12
|
||||
sla a
|
||||
sla a
|
||||
ld c, a
|
||||
sla a
|
||||
add c
|
||||
|
||||
.next2
|
||||
add b ; add the tile offset from the table (based on frame and facing direction)
|
||||
pop bc
|
||||
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
|
||||
inc hl
|
||||
ld [de], a
|
||||
inc e
|
||||
bit 0, a ; OAMFLAG_ENDOFDATA
|
||||
jr z, .tileLoop
|
||||
|
||||
ld a, e
|
||||
ld [hOAMBufferOffset], a
|
||||
|
||||
.nextSprite
|
||||
ld a, [hSpriteOffset2]
|
||||
add $10
|
||||
cp $100 % $100
|
||||
jp nz, .spriteLoop
|
||||
|
||||
; Clear unused OAM.
|
||||
ld a, [hOAMBufferOffset]
|
||||
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?
|
||||
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.
|
||||
ld a, $90
|
||||
|
||||
.clear
|
||||
cp l
|
||||
ret z
|
||||
ld [hl], b
|
||||
add hl, de
|
||||
jr .clear
|
||||
|
||||
GetSpriteScreenXY:
|
||||
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
|
||||
Loading…
Add table
Add a link
Reference in a new issue