diff options
| -rw-r--r-- | engine/slop_menu.asm | 69 |
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 |
