You've already forked pokecrystal-board
mirror of
https://gitlab.com/xCrystal/pokecrystal-board.git
synced 2025-04-09 05:44:44 -07:00
Overworld HUD implementation (#15)
This commit is contained in:
122
home/hud.asm
Executable file
122
home/hud.asm
Executable file
@@ -0,0 +1,122 @@
|
||||
OVERWORLD_HUD_HEIGHT EQU 8
|
||||
|
||||
EnableOverworldHUD::
|
||||
ld a, HUD_OVERWORLD
|
||||
ld [wWhichHUD], a
|
||||
ld a, OVERWORLD_HUD_HEIGHT - 1
|
||||
; fallthrough
|
||||
|
||||
EnableWindowHUD:
|
||||
ldh [hWindowHUDLY], a
|
||||
; configure LCD interrupt
|
||||
ldh [rLYC], a
|
||||
; make window hidden this frame to prevent graphical glitches
|
||||
ld a, $90
|
||||
ldh [hWY], a
|
||||
; configure LCD interrupt
|
||||
ld a, 1 << rSTAT_INT_LYC ; LYC=LC
|
||||
ldh [rSTAT], a
|
||||
ret
|
||||
|
||||
DisableOverworldHUD::
|
||||
xor a
|
||||
ld [wWhichHUD], a
|
||||
; fallthrough
|
||||
|
||||
DisableWindowHUD::
|
||||
xor a
|
||||
ldh [hWindowHUDLY], a
|
||||
; configure LCD interrupt
|
||||
xor a
|
||||
ldh [rLYC], a
|
||||
ld a, 1 << rSTAT_INT_HBLANK ; hblank (default)
|
||||
ldh [rSTAT], a
|
||||
; leave window in default state (hidden with WY=$90)
|
||||
; rLCDC[rLCDC_WINDOW_ENABLE] will be set during next vblank
|
||||
ld a, $90
|
||||
ldh [hWY], a
|
||||
ret
|
||||
|
||||
LoadWindowHUD::
|
||||
; like LoadHUD, but for HUDs that require a Window overlay
|
||||
ldh a, [hWindowHUDLY]
|
||||
and a
|
||||
ret z
|
||||
; fallthrough
|
||||
|
||||
LoadHUD::
|
||||
; load the HUD at wWhichHUD to the top of wTilemap and wAttrmap
|
||||
ld a, [wWhichHUD]
|
||||
and a
|
||||
ret z
|
||||
farcall _LoadHUD
|
||||
ret
|
||||
|
||||
ConstructOverworldHUDTilemap::
|
||||
; draw the overworld HUD's tilemap into wOverworldHUDTiles
|
||||
ld hl, .Tilemap
|
||||
ld de, wOverworldHUDTiles
|
||||
ld bc, .TilemapEnd - .Tilemap ; SCREEN_WIDTH
|
||||
call CopyBytes
|
||||
ret
|
||||
|
||||
.Tilemap:
|
||||
db "▶- ▶- ▶ ▶ "
|
||||
.TilemapEnd:
|
||||
assert .TilemapEnd - .Tilemap == wOverworldHUDTilesEnd - wOverworldHUDTiles
|
||||
|
||||
TransferOverworldHUDToBGMap::
|
||||
; transfer overworld HUD to vBGMap1/vBGMap3 during v/hblank(s)
|
||||
; tilemap is read from wOverworldHUDTiles, attrmap is all PAL_BG_TEXT | PRIORITY
|
||||
ldh a, [rVBK]
|
||||
push af
|
||||
|
||||
; Tilemap
|
||||
ld a, BANK(vBGMap1)
|
||||
ldh [rVBK], a
|
||||
ld de, vBGMap1
|
||||
ld hl, wOverworldHUDTiles
|
||||
|
||||
ld b, 1 << rSTAT_BUSY ; not in v/hblank
|
||||
ld c, LOW(rSTAT)
|
||||
|
||||
rept SCREEN_WIDTH / 2
|
||||
; if not in v/hblank, wait until in v/hblank
|
||||
.loop\@
|
||||
ldh a, [c]
|
||||
and b
|
||||
jr nz, .loop\@
|
||||
; copy
|
||||
; we have at least a margin of 16 cycles of Mode2 left
|
||||
ld a, [hli]
|
||||
ld [de], a
|
||||
inc de
|
||||
ld a, [hli]
|
||||
ld [de], a
|
||||
inc de
|
||||
endr
|
||||
|
||||
; Attrmap
|
||||
ld a, BANK(vBGMap3)
|
||||
ldh [rVBK], a
|
||||
ld hl, vBGMap3
|
||||
|
||||
rept SCREEN_WIDTH / 5
|
||||
; if not in v/hblank, wait until in v/hblank
|
||||
.loop\@
|
||||
ldh a, [c]
|
||||
and b
|
||||
jr nz, .loop\@
|
||||
; fill
|
||||
; we have at least a margin of 16 cycles of Mode2 left
|
||||
ld a, PAL_BG_TEXT | PRIORITY
|
||||
ld [hli], a
|
||||
ld [hli], a
|
||||
ld [hli], a
|
||||
ld [hli], a
|
||||
ld [hli], a
|
||||
endr
|
||||
|
||||
pop af
|
||||
ld [rVBK], a
|
||||
ret
|
@@ -4,7 +4,7 @@ LCD::
|
||||
push af
|
||||
|
||||
; hLCDCPointer is used in battle transition, battle anims, and movies (crystal intro, credits, etc.)
|
||||
; uses rSTAT_INT_HBLANK and doesn't overlap with hWindowHUD.
|
||||
; uses rSTAT_INT_HBLANK and doesn't overlap with hWindowHUDLY.
|
||||
ldh a, [hLCDCPointer]
|
||||
and a
|
||||
jr z, .next
|
||||
@@ -23,8 +23,8 @@ LCD::
|
||||
pop bc
|
||||
|
||||
.next
|
||||
; hWindowHUD uses rSTAT_INT_LYC
|
||||
ldh a, [hWindowHUD]
|
||||
; hWindowHUDLY uses rSTAT_INT_LYC
|
||||
ldh a, [hWindowHUDLY]
|
||||
and a
|
||||
jr z, .done
|
||||
|
||||
|
@@ -1,12 +1,5 @@
|
||||
; Functions dealing with rendering and interacting with maps.
|
||||
|
||||
ClearUnusedMapBuffer::
|
||||
ld hl, wUnusedMapBuffer
|
||||
ld bc, wUnusedMapBufferEnd - wUnusedMapBuffer
|
||||
ld a, 0
|
||||
call ByteFill
|
||||
ret
|
||||
|
||||
CheckScenes::
|
||||
; Checks wCurMapSceneScriptPointer. If it's empty, returns -1 in a. Otherwise, returns the active scene ID in a.
|
||||
push hl
|
||||
@@ -146,7 +139,6 @@ LoadMetatiles::
|
||||
ld e, l
|
||||
ld d, h
|
||||
; Set hl to the address of the current metatile data ([wTilesetBlocksAddress] + (a) tiles).
|
||||
; BUG: LoadMetatiles wraps around past 128 blocks (see docs/bugs_and_glitches.md)
|
||||
ld l, a
|
||||
ld h, 0
|
||||
add hl, hl
|
||||
|
@@ -49,20 +49,15 @@ CopyTilemapAtOnce::
|
||||
xor a
|
||||
ldh [hMapAnims], a
|
||||
|
||||
; .wait
|
||||
; ldh a, [rLY]
|
||||
; cp $80 - 1
|
||||
; jr c, .wait
|
||||
|
||||
call DelayFrame
|
||||
|
||||
ldh a, [hWindowHUD]
|
||||
ldh a, [hWindowHUDLY]
|
||||
and a
|
||||
jr z, .go
|
||||
|
||||
; wait until LCD interrupt has ocurred this frame ([rLY] - [hWindowHUD] >= 0)
|
||||
; wait until LCD interrupt has ocurred this frame ([rLY] - [hWindowHUDLY] >= 0)
|
||||
.wait_lcd
|
||||
; ldh a, [hWindowHUD]
|
||||
; ldh a, [hWindowHUDLY]
|
||||
ld b, a
|
||||
ldh a, [rLY]
|
||||
sub b
|
||||
@@ -78,11 +73,6 @@ CopyTilemapAtOnce::
|
||||
ldh [rVBK], a
|
||||
hlcoord 0, 0
|
||||
call .CopyBGMapViaStack
|
||||
|
||||
; .wait2
|
||||
; ldh a, [rLY]
|
||||
; cp $80 - 1
|
||||
; jr c, .wait2
|
||||
ei
|
||||
|
||||
pop af
|
||||
|
@@ -65,12 +65,12 @@ VBlank0::
|
||||
ldh a, [hROMBank]
|
||||
ldh [hROMBankBackup], a
|
||||
|
||||
; enable window back in case LCD interrupt disabled it mid-frame due to hWindowHUD
|
||||
; enable window back in case LCD interrupt disabled it mid-frame due to hWindowHUDLY
|
||||
ldh a, [rLCDC]
|
||||
set rLCDC_WINDOW_ENABLE, a
|
||||
ldh [rLCDC], a
|
||||
|
||||
ld a, [hWindowHUD]
|
||||
ld a, [hWindowHUDLY]
|
||||
and a
|
||||
jr z, .next
|
||||
|
||||
@@ -117,8 +117,8 @@ VBlank0::
|
||||
xor a
|
||||
ld [wVBlankOccurred], a
|
||||
|
||||
; if hWindowHUD is active, enable interrupts so the LCD interrupt can trigger
|
||||
ldh a, [hWindowHUD]
|
||||
; if hWindowHUDLY is active, enable interrupts so the LCD interrupt can trigger
|
||||
ldh a, [hWindowHUDLY]
|
||||
and a
|
||||
jr z, .next2
|
||||
|
||||
@@ -163,17 +163,17 @@ VBlank0::
|
||||
ldh a, [hROMBankBackup]
|
||||
rst Bankswitch
|
||||
|
||||
; if hWindowHUD is not active, we're done
|
||||
ldh a, [hWindowHUD]
|
||||
; if hWindowHUDLY is not active, we're done
|
||||
ldh a, [hWindowHUDLY]
|
||||
and a
|
||||
ret z
|
||||
|
||||
; interrupts must be enabled in the cycle that rLY becomes [hWindowHUD] to prevent flickering
|
||||
; wait until [hWindowHUD] - [rLY] is NOT between 0 and 2 before disabling interrupts
|
||||
; interrupts must be enabled in the cycle that rLY becomes [hWindowHUDLY] to prevent flickering
|
||||
; wait until [hWindowHUDLY] - [rLY] is NOT between 0 and 2 before disabling interrupts
|
||||
.wait_loop
|
||||
ldh a, [rLY]
|
||||
ld b, a
|
||||
ldh a, [hWindowHUD]
|
||||
ldh a, [hWindowHUDLY]
|
||||
sub b
|
||||
cp 2 + 1
|
||||
jr c, .wait_loop
|
||||
|
@@ -110,7 +110,7 @@ SafeUpdateSprites::
|
||||
HideWindow_EnableLCDInt::
|
||||
ld a, $90
|
||||
ldh [hWY], a
|
||||
ldh a, [hWindowHUD]
|
||||
ldh a, [hWindowHUDLY]
|
||||
and a
|
||||
ld a, 1 << rSTAT_INT_HBLANK
|
||||
jr z, .ok
|
||||
@@ -118,35 +118,3 @@ HideWindow_EnableLCDInt::
|
||||
.ok
|
||||
ldh [rSTAT], a
|
||||
ret
|
||||
|
||||
OVERWORLD_HUD_HEIGHT EQU 8
|
||||
|
||||
EnableOverworldWindowHUD::
|
||||
ld a, OVERWORLD_HUD_HEIGHT - 1
|
||||
; fallthrough
|
||||
|
||||
EnableWindowHUD:
|
||||
ldh [hWindowHUD], a
|
||||
; configure LCD interrupt
|
||||
ldh [rLYC], a
|
||||
; make window hidden this frame to prevent graphical glitches
|
||||
ld a, $90
|
||||
ldh [hWY], a
|
||||
; configure LCD interrupt
|
||||
ld a, 1 << rSTAT_INT_LYC ; LYC=LC
|
||||
ldh [rSTAT], a
|
||||
ret
|
||||
|
||||
DisableWindowHUD::
|
||||
xor a
|
||||
ldh [hWindowHUD], a
|
||||
; configure LCD interrupt
|
||||
xor a
|
||||
ldh [rLYC], a
|
||||
ld a, 1 << rSTAT_INT_HBLANK ; hblank (default)
|
||||
ldh [rSTAT], a
|
||||
; leave window in default state (hidden with WY=$90)
|
||||
; rLCDC[rLCDC_WINDOW_ENABLE] will be set during next vblank
|
||||
ld a, $90
|
||||
ldh [hWY], a
|
||||
ret
|
||||
|
Reference in New Issue
Block a user