aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--engine/slop_menu.asm69
1 files changed, 33 insertions, 36 deletions
diff --git a/engine/slop_menu.asm b/engine/slop_menu.asm
index 09650150..7e534015 100644
--- a/engine/slop_menu.asm
+++ b/engine/slop_menu.asm
@@ -874,45 +874,60 @@ SlopScrollUp:
SlopDirBits:
db PAD_UP, PAD_DOWN, PAD_LEFT, PAD_RIGHT
-; -> a = bitmask of currently-movable directions (same rule as the arrows)
+; -> a = bitmask of directions the screensaver can actually make progress in.
+; A direction is open if there are >= 2 coords of room that way (enough for one
+; even scroll step) OR a map connection to cross into. The >= 2 test matters
+; because moves round down to even coords, and a map's far edge (maxY/maxX =
+; wCurrentMap*2 - 1) is always odd -- so "coord != max" would never register the
+; edge as blocked and the wander would freeze one step short of it.
SlopValidDirMask:
ld c, 0
+; up: room upward = wYCoord
ld a, [wYCoord]
- and a
- jr nz, .up
+ cp 2
+ jr nc, .up
ld a, [wNorthConnectedMap]
inc a
jr z, .noUp
.up
set B_PAD_UP, c
.noUp
+; down: room downward = maxY - wYCoord
ld a, [wCurrentMapHeight2]
dec a
- ld b, a
+ ld b, a ; b = maxY
ld a, [wYCoord]
- cp b
- jr nz, .down
+ ld d, a
+ ld a, b
+ sub d ; a = maxY - wYCoord
+ cp 2
+ jr nc, .down
ld a, [wSouthConnectedMap]
inc a
jr z, .noDown
.down
set B_PAD_DOWN, c
.noDown
+; left: room leftward = wXCoord
ld a, [wXCoord]
- and a
- jr nz, .left
+ cp 2
+ jr nc, .left
ld a, [wWestConnectedMap]
inc a
jr z, .noLeft
.left
set B_PAD_LEFT, c
.noLeft
+; right: room rightward = maxX - wXCoord
ld a, [wCurrentMapWidth2]
dec a
- ld b, a
+ ld b, a ; b = maxX
ld a, [wXCoord]
- cp b
- jr nz, .right
+ ld d, a
+ ld a, b
+ sub d ; a = maxX - wXCoord
+ cp 2
+ jr nc, .right
ld a, [wEastConnectedMap]
inc a
jr z, .noRight
@@ -967,15 +982,9 @@ SlopRevDir:
ld a, PAD_LEFT ; was RIGHT
ret
-; a = dir bit -> a = mask of the two perpendicular directions
-SlopPerpMask:
- and PAD_UP | PAD_DOWN
- ld a, PAD_LEFT | PAD_RIGHT ; vertical dir -> horizontal perpendicular
- ret nz
- ld a, PAD_UP | PAD_DOWN
- ret
-
-; pick the next screensaver direction; store in wSlopSaverDir, return it in d
+; pick the next screensaver direction; store in wSlopSaverDir, return it in d.
+; Strategy: keep heading the same way until that direction gets blocked, then
+; turn onto a random still-open direction, preferring not to double back.
SlopSaverPickDir:
call SlopValidDirMask
ld e, a ; e = valid-direction mask
@@ -984,27 +993,15 @@ SlopSaverPickDir:
ld a, [wSlopSaverDir]
ld b, a ; b = current direction
and e
- jr z, .blocked ; current direction no longer valid -> turn
-; current direction still valid: mostly keep going, occasionally turn
- ldh a, [hRandomAdd]
- and $07
- jr nz, .keepCurrent ; 7/8: carry straight on
- ld a, b
- call SlopPerpMask
- and e ; valid perpendicular directions
- jr z, .keepCurrent ; none -> keep going
- call SlopRandomBit
- jr .store
-.blocked
+ jr nz, .keepCurrent ; still valid -> carry straight on
+; blocked at a bound: turn onto another open direction (avoid a U-turn if we can)
ld a, b
call SlopRevDir
cpl
and e ; valid directions excluding a U-turn
- jr z, .onlyReverse
- call SlopRandomBit
- jr .store
-.onlyReverse
+ jr nz, .turn
ld a, e ; only a U-turn is available
+.turn
call SlopRandomBit
jr .store
.keepCurrent