aboutsummaryrefslogtreecommitdiffstats
path: root/engine/slop_menu.asm
diff options
context:
space:
mode:
authorAsh Ketchum <no-reply@sl0p.foo>2026-07-15 15:46:49 +0200
committerAsh Ketchum <no-reply@sl0p.foo>2026-07-15 15:46:49 +0200
commit92856fd4b4908939ff4998a84369d4b9ac097b7a (patch)
tree371eb1bd39053eddca367cabaebbeaefc52d396a /engine/slop_menu.asm
parentSAVER: wander straight until blocked, and fix the edge-freeze (diff)
downloadpokeyellow-92856fd4b4908939ff4998a84369d4b9ac097b7a.tar.gz
pokeyellow-92856fd4b4908939ff4998a84369d4b9ac097b7a.tar.xz
pokeyellow-92856fd4b4908939ff4998a84369d4b9ac097b7a.zip
EXPLORE/SAVER: clamp camera into map bounds after a connection cross
Crossing a map connection applies the connection's alignment offset blindly. At an edge position the connection doesn't span, the resulting coord lands outside the neighbour (e.g. Y = -8 = $f8), and since the bounds checks then operate on the wrapped value the camera roams far outside the map, rendering whatever WRAM lies past wOverworldMap as on-screen garbage. SlopClampCoords (run in .renderView, i.e. after every entry/cross LoadMapData) clamps wYCoord to [0,maxY] and wXCoord to [0,maxX] of the freshly-loaded map. Verified: 120-sample saver soak across 19 maps -> 0 out-of-bounds; manual EXPLORE crossing unaffected.
Diffstat (limited to 'engine/slop_menu.asm')
-rw-r--r--engine/slop_menu.asm33
1 files changed, 33 insertions, 0 deletions
diff --git a/engine/slop_menu.asm b/engine/slop_menu.asm
index 7e534015..4c93e2ed 100644
--- a/engine/slop_menu.asm
+++ b/engine/slop_menu.asm
@@ -275,6 +275,7 @@ SlopExploreShared:
ld a, $ff
ld [wUpdateSpritesEnabled], a
call ClearSprites
+ call SlopClampCoords ; a cross can land outside the new map -> clamp
call SlopExploreRenderBG ; fresh render to vBGMap0, hardware scroll reset
.renderArrows
call LoadFontTilePatterns ; arrow glyphs ($ed/$ee) into VRAM for the OBJ layer
@@ -616,6 +617,38 @@ SlopExploreShared:
and a ; carry clear -> back to SL0P menu
ret
+; Clamp wYCoord to [0,maxY] and wXCoord to [0,maxX] of the current map. Crossing a
+; connection applies its alignment offset blindly, so at an edge position the
+; connection doesn't span the camera can land outside the neighbour; rendering
+; that reads past wOverworldMap into other WRAM = on-screen garbage.
+SlopClampCoords:
+ ld a, [wCurrentMapHeight2]
+ dec a
+ ld b, a ; maxY
+ ld a, [wYCoord]
+ call .clamp
+ ld [wYCoord], a
+ ld a, [wCurrentMapWidth2]
+ dec a
+ ld b, a ; maxX
+ ld a, [wXCoord]
+ call .clamp
+ ld [wXCoord], a
+ ret
+; a = coord, b = max -> a clamped to [0,max]. Out-of-range values >= $80 are
+; treated as "past the near edge" (negative) and clamped to 0, otherwise to max.
+.clamp
+ cp b
+ ret c
+ ret z
+ bit 7, a
+ jr nz, .zero
+ ld a, b
+ ret
+.zero
+ xor a
+ ret
+
; wCurrentTileBlockMapViewPointer = wOverworldMap + (wYCoord/2 + 1)*stride + wXCoord/2
SlopSetViewPtr:
ld a, [wCurMapWidth]