aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAsh Ketchum <no-reply@sl0p.foo>2026-07-15 13:58:35 +0200
committerAsh Ketchum <no-reply@sl0p.foo>2026-07-15 13:58:35 +0200
commit76925904c16bef43eea7d8d08f864880695525fd (patch)
tree5bcd3d6d095ce2264995a09febd388f6e2ead46a
parentexplore: rewrite as an instant screen-paging camera (diff)
downloadpokeyellow-76925904c16bef43eea7d8d08f864880695525fd.tar.gz
pokeyellow-76925904c16bef43eea7d8d08f864880695525fd.tar.xz
pokeyellow-76925904c16bef43eea7d8d08f864880695525fd.zip
explore: direction arrows showing where you can move
Overlay real ▲▼◀▶ arrow sprites at the screen edges for every direction the camera can currently page: either there's more map that way, or the map has a connection that way. Arrows update live -- e.g. at a connectionless edge that direction's arrow disappears. Implementation: the font has only a down-arrow ($ee) and right-arrow ($ed), so up/left are made with CGB OBJ Y/X-flip (the emulator supports OBJ flips). Drawn as 4 sprites in wShadowOAM (8x8 OBJ mode, font loaded so $ed/$ee are OBJ- reachable at 0x8ed0/0x8ee0). Set wUpdateSpritesEnabled=$ff after building them so the vblank PrepareOAMData leaves shadow OAM alone instead of repopulating the player sprite over the arrows. Verified: Pallet mid-map shows all 4; Viridian shows N/S/W (no E); paging to a connectionless edge drops that arrow and it returns on the way back.
-rw-r--r--engine/slop_menu.asm81
1 files changed, 79 insertions, 2 deletions
diff --git a/engine/slop_menu.asm b/engine/slop_menu.asm
index 66a8a482..258770f5 100644
--- a/engine/slop_menu.asm
+++ b/engine/slop_menu.asm
@@ -280,8 +280,85 @@ SlopExplore:
call LoadCurrentMapView
ld b, HIGH(vBGMap0)
call CopyScreenTileBufferToVRAM
- ldh a, [rLCDC] ; hide sprites for a clean camera
- res B_LCDC_OBJS, a
+ call LoadFontTilePatterns ; arrow glyphs ($ed/$ee) into VRAM for the OBJ layer
+; draw a direction-arrow sprite for each direction the camera can currently move:
+; either there's more map that way, or the map has a connection that way.
+ call ClearSprites
+ ld hl, wShadowOAM
+; up: movable unless at the top edge (wYCoord == 0) with no north connection
+ ld a, [wYCoord]
+ and a
+ jr nz, .putUp
+ ld a, [wNorthConnectedMap]
+ inc a
+ jr z, .skipUp
+.putUp
+ ld de, .arrUp
+ call .putArrow
+.skipUp
+; down: movable unless at the bottom edge with no south connection
+ ld a, [wCurrentMapHeight2]
+ dec a
+ ld b, a
+ ld a, [wYCoord]
+ cp b
+ jr nz, .putDown
+ ld a, [wSouthConnectedMap]
+ inc a
+ jr z, .skipDown
+.putDown
+ ld de, .arrDown
+ call .putArrow
+.skipDown
+; left: movable unless at the left edge with no west connection
+ ld a, [wXCoord]
+ and a
+ jr nz, .putLeft
+ ld a, [wWestConnectedMap]
+ inc a
+ jr z, .skipLeft
+.putLeft
+ ld de, .arrLeft
+ call .putArrow
+.skipLeft
+; right: movable unless at the right edge with no east connection
+ ld a, [wCurrentMapWidth2]
+ dec a
+ ld b, a
+ ld a, [wXCoord]
+ cp b
+ jr nz, .putRight
+ ld a, [wEastConnectedMap]
+ inc a
+ jr z, .skipRight
+.putRight
+ ld de, .arrRight
+ call .putArrow
+.skipRight
+ jr .arrowsDone
+.putArrow ; de -> Y, X, tile, attr; write to [hl], advance hl
+ ld a, [de]
+ inc de
+ ld [hli], a
+ ld a, [de]
+ inc de
+ ld [hli], a
+ ld a, [de]
+ inc de
+ ld [hli], a
+ ld a, [de]
+ ld [hli], a
+ ret
+.arrUp db 18, 80, $ee, $40 ; down-arrow glyph, Y-flipped -> up
+.arrDown db 144, 80, $ee, $00
+.arrLeft db 80, 12, $ed, $20 ; right-arrow glyph, X-flipped -> left
+.arrRight db 80, 156, $ed, $00
+.arrowsDone
+ ld a, $ff
+ ld [wUpdateSpritesEnabled], a ; freeze shadow OAM so PrepareOAMData keeps our arrows
+ ldh a, [rLCDC]
+ res B_LCDC_OBJ_SIZE, a ; 8x8 sprites -> single-tile arrows
+ set B_LCDC_OBJS, a ; show the arrow sprites
ldh [rLCDC], a
ld a, $90
ldh [hWY], a