aboutsummaryrefslogtreecommitdiffstats
path: root/engine/slop_menu.asm
diff options
context:
space:
mode:
Diffstat (limited to 'engine/slop_menu.asm')
-rw-r--r--engine/slop_menu.asm218
1 files changed, 197 insertions, 21 deletions
diff --git a/engine/slop_menu.asm b/engine/slop_menu.asm
index b4b7f78e..66a8a482 100644
--- a/engine/slop_menu.asm
+++ b/engine/slop_menu.asm
@@ -216,30 +216,206 @@ WarpMapTable:
; ===========================================================================
-; EXPLORE (P1): overworld map-connection browser. Renders the current map (no
-; NPCs), and U/D/L/R jump to the connected map in that direction if one exists
-; (via wCurMapConnections + the connection headers). B restores the original
-; map and returns to the SL0P menu. No warping yet - read-only browse.
-; ===========================================================================
-; ===========================================================================
-; EXPLORE: toggle noclip free-roam. With noclip on, CollisionCheckOnLand is
-; bypassed, so you glide through walls / NPCs / ledges and cross map connection
-; seams exactly as the world data defines them. Closes the menu so you drop
-; straight back into the overworld to roam. Pick it again to turn it off.
+; EXPLORE: a screen-paging overworld camera. Each d-pad press INSTANTLY redraws
+; the next screenful of the world -- no character walking. At a map edge it hops
+; to the connected map using that connection's alignment offset (or clamps if
+; there's none). B restores the origin view and returns to the SL0P menu. It is
+; self-contained: it renders straight from the map block buffer (wOverworldMap)
+; and never touches the walk engine.
; ===========================================================================
+DEF SLOP_PAGE_X EQU 10 ; coords moved per horizontal page (~one screen)
+DEF SLOP_PAGE_Y EQU 8 ; coords moved per vertical page
+
SlopExplore:
- ld a, [wSlopNoclip]
- xor $01
- ld [wSlopNoclip], a
-; close the menu the same way the B button does (rebuild the overworld) instead
-; of .exitProceed, which only bare-returns and assumes a warp will redraw.
- pop hl ; drop the pushed .afterHandler return address
- call SlopMenuRestoreFlags
- ld a, $01
- ld [wUpdateSpritesEnabled], a
- ldh a, [hLoadedROMBank]
+; save origin (map, coords, block coords, view pointer) to restore on exit
+ ld a, [wYCoord]
+ ld b, a
+ ld a, [wXCoord]
+ ld c, a
+ push bc
+ ld a, [wYBlockCoord]
+ ld b, a
+ ld a, [wXBlockCoord]
+ ld c, a
+ push bc
+ ld a, [wCurrentTileBlockMapViewPointer]
+ ld b, a
+ ld a, [wCurrentTileBlockMapViewPointer + 1]
+ ld c, a
+ push bc
+ ld a, [wCurMap]
push af
- jp CloseTextDisplay
+ call LoadMapData ; reload current map + tileset (menu clobbered VRAM)
+.renderView
+; block-aligned camera; view pointer = wOverworldMap + (by+1)*stride + bx,
+; where by = wYCoord/2, bx = wXCoord/2, stride = wCurMapWidth + 2*MAP_BORDER.
+ xor a
+ ld [wYBlockCoord], a
+ ld [wXBlockCoord], a
+ ld a, [wCurMapWidth]
+ add MAP_BORDER * 2
+ ld c, a
+ ld b, 0
+ ld a, [wYCoord]
+ srl a
+ inc a
+ ld hl, 0
+.mulRow
+ add hl, bc
+ dec a
+ jr nz, .mulRow
+ ld a, [wXCoord]
+ srl a
+ add l
+ ld l, a
+ jr nc, .noCarry
+ inc h
+.noCarry
+ ld bc, wOverworldMap
+ add hl, bc
+ ld a, l
+ ld [wCurrentTileBlockMapViewPointer], a
+ ld a, h
+ ld [wCurrentTileBlockMapViewPointer + 1], a
+ call LoadCurrentMapView
+ ld b, HIGH(vBGMap0)
+ call CopyScreenTileBufferToVRAM
+ ldh a, [rLCDC] ; hide sprites for a clean camera
+ res B_LCDC_OBJS, a
+ ldh [rLCDC], a
+ ld a, $90
+ ldh [hWY], a
+.input
+ call DelayFrame
+ call JoypadLowSensitivity
+ ldh a, [hJoyPressed]
+ ld d, a
+ bit B_PAD_B, d
+ jp nz, .exit
+ bit B_PAD_UP, d
+ jr z, .ckDown
+ ld a, [wYCoord]
+ sub SLOP_PAGE_Y
+ jp nc, .setY
+ ld hl, wNorthConnectedMap
+ ld de, wNorthConnectedMapYAlignment
+ ld a, 0 ; clamp target = top
+ jp .crossV
+.ckDown
+ bit B_PAD_DOWN, d
+ jr z, .ckLeft
+ ld a, [wCurrentMapHeight2]
+ dec a
+ ld b, a ; b = max Y
+ ld a, [wYCoord]
+ add SLOP_PAGE_Y
+ cp b
+ jp c, .setY
+ jp z, .setY
+ ld hl, wSouthConnectedMap
+ ld de, wSouthConnectedMapYAlignment
+ ld a, b ; clamp target = max Y
+ jp .crossV
+.ckLeft
+ bit B_PAD_LEFT, d
+ jr z, .ckRight
+ ld a, [wXCoord]
+ sub SLOP_PAGE_X
+ jp nc, .setX
+ ld hl, wWestConnectedMap
+ ld de, wWestConnectedMapYAlignment
+ ld a, 0
+ jp .crossH
+.ckRight
+ bit B_PAD_RIGHT, d
+ jp z, .input
+ ld a, [wCurrentMapWidth2]
+ dec a
+ ld b, a ; b = max X
+ ld a, [wXCoord]
+ add SLOP_PAGE_X
+ cp b
+ jp c, .setX
+ jp z, .setX
+ ld hl, wEastConnectedMap
+ ld de, wEastConnectedMapYAlignment
+ ld a, b
+ jp .crossH
+.setY
+ ld [wYCoord], a
+ jp .renderView
+.setX
+ ld [wXCoord], a
+ jp .renderView
+; vertical cross (up/down): hl -> connected-map byte, de -> its YAlignment,
+; a = Y to clamp to when there is no connection.
+.crossV
+ ld b, a
+ ld a, [hl]
+ inc a
+ jr z, .clampY ; $ff -> no connection
+ ld a, [de] ; YAlignment -> new Y (absolute)
+ ld c, a
+ inc de
+ ld a, [de] ; XAlignment -> added to X
+ ld b, a
+ ld a, [wXCoord]
+ add b
+ ld [wXCoord], a
+ ld a, c
+ ld [wYCoord], a
+ ld a, [hl]
+ ld [wCurMap], a
+ call LoadMapData
+ jp .renderView
+.clampY
+ ld a, b
+ ld [wYCoord], a
+ jp .renderView
+; horizontal cross (left/right): hl -> connected-map byte, de -> its YAlignment,
+; a = X to clamp to when there is no connection.
+.crossH
+ ld b, a
+ ld a, [hl]
+ inc a
+ jr z, .clampX
+ ld a, [de] ; YAlignment -> added to Y
+ ld c, a
+ inc de
+ ld a, [de] ; XAlignment -> new X (absolute)
+ ld [wXCoord], a
+ ld a, [wYCoord]
+ add c
+ ld [wYCoord], a
+ ld a, [hl]
+ ld [wCurMap], a
+ call LoadMapData
+ jp .renderView
+.clampX
+ ld a, b
+ ld [wXCoord], a
+ jp .renderView
+.exit
+ pop af
+ ld [wCurMap], a
+ pop bc
+ ld a, b
+ ld [wCurrentTileBlockMapViewPointer], a
+ ld a, c
+ ld [wCurrentTileBlockMapViewPointer + 1], a
+ pop bc
+ ld a, b
+ ld [wYBlockCoord], a
+ ld a, c
+ ld [wXBlockCoord], a
+ pop bc
+ ld a, b
+ ld [wYCoord], a
+ ld a, c
+ ld [wXCoord], a
+ call LoadMapData ; restore origin view (renders from restored pointer)
+ and a ; carry clear -> back to SL0P menu
+ ret
; ===========================================================================
; ITEMS submenu: give 99 of the chosen item (stacks via GiveItem)