diff options
| -rw-r--r-- | engine/slop_menu.asm | 267 |
1 files changed, 248 insertions, 19 deletions
diff --git a/engine/slop_menu.asm b/engine/slop_menu.asm index 2e1adaaa..acad203c 100644 --- a/engine/slop_menu.asm +++ b/engine/slop_menu.asm @@ -225,6 +225,10 @@ WarpMapTable: ; =========================================================================== DEF SLOP_PAGE_X EQU 10 ; coords moved per horizontal page (~one screen) DEF SLOP_PAGE_Y EQU 8 ; coords moved per vertical page +; smooth-scroll animation speed. SLOP_SCROLL_PX must divide 16 (one coord-step +; is 16 px). Bigger = faster/steppier, smaller = slower/smoother. +DEF SLOP_SCROLL_PX EQU 8 +DEF SLOP_SCROLL_FRAMES EQU 16 / SLOP_SCROLL_PX SlopExplore: ; save origin (map, coords, block coords, view pointer) to restore on exit @@ -247,13 +251,8 @@ SlopExplore: push af call LoadMapData ; reload current map + tileset (menu clobbered VRAM) .renderView - xor a - ld [wYBlockCoord], a ; block-aligned camera centred on wYCoord/wXCoord - ld [wXBlockCoord], a - call SlopSetViewPtr - call LoadCurrentMapView - ld b, HIGH(vBGMap0) - call CopyScreenTileBufferToVRAM + call SlopExploreRenderBG ; fresh render to vBGMap0, hardware scroll reset +.renderArrows 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. @@ -349,7 +348,7 @@ SlopExplore: jr z, .ckDown ld a, [wYCoord] sub SLOP_PAGE_Y - jp nc, .setY + jp nc, .moveUp ld hl, wNorthConnectedMap ld de, wNorthConnectedMapYAlignment ld a, 0 ; clamp target = top @@ -363,8 +362,8 @@ SlopExplore: ld a, [wYCoord] add SLOP_PAGE_Y cp b - jp c, .setY - jp z, .setY + jp c, .moveDown + jp z, .moveDown ld hl, wSouthConnectedMap ld de, wSouthConnectedMapYAlignment ld a, b ; clamp target = max Y @@ -374,7 +373,7 @@ SlopExplore: jr z, .ckRight ld a, [wXCoord] sub SLOP_PAGE_X - jp nc, .setX + jp nc, .moveLeft ld hl, wWestConnectedMap ld de, wWestConnectedMapYAlignment ld a, 0 @@ -388,18 +387,30 @@ SlopExplore: ld a, [wXCoord] add SLOP_PAGE_X cp b - jp c, .setX - jp z, .setX + jp c, .moveRight + jp z, .moveRight ld hl, wEastConnectedMap ld de, wEastConnectedMapYAlignment ld a, b jp .crossH -.setY - ld [wYCoord], a - jp .renderView -.setX - ld [wXCoord], a - jp .renderView +; in-map page moves: smooth-scroll one screen, then just redraw the arrows +; (the scroll already left the destination view on screen in rotated VRAM). +.moveUp + ld c, SLOP_PAGE_Y + call SlopScrollUp + jp .renderArrows +.moveDown + ld c, SLOP_PAGE_Y + call SlopScrollDown + jp .renderArrows +.moveLeft + ld c, SLOP_PAGE_X + call SlopScrollLeft + jp .renderArrows +.moveRight + ld c, SLOP_PAGE_X + call SlopScrollRight + jp .renderArrows ; vertical cross (up/down): hl -> connected-map byte, de -> its YAlignment, ; a = Y to clamp to when there is no connection. .crossV @@ -566,6 +577,224 @@ SlopSetViewPtr: ld [wCurrentTileBlockMapViewPointer + 1], a ret +; render the current view freshly to vBGMap0 and reset the hardware scroll so +; the camera is block-aligned at SCX/SCY = 0. Used on entry, map-cross and +; clamp (i.e. everywhere except the animated in-map page moves). +SlopExploreRenderBG: + xor a + ld [wYBlockCoord], a ; block-aligned camera centred on wYCoord/wXCoord + ld [wXBlockCoord], a + ldh [hAutoBGTransferEnabled], a ; use RedrawRowOrColumn path, not AutoBgMapTransfer + ld [wMapViewVRAMPointer], a + ldh [hSCX], a + ldh [hSCY], a + ld a, HIGH(vBGMap0) + ld [wMapViewVRAMPointer + 1], a + call SlopSetViewPtr + call LoadCurrentMapView + ld b, HIGH(vBGMap0) + jp CopyScreenTileBufferToVRAM + +; --------------------------------------------------------------------------- +; Smooth EXPLORE scrolling. Each routine pans the camera `c` coords in one +; direction, 16 px per coord-step, reusing the walking engine's rotating-VRAM +; machinery: advance wMapViewVRAMPointer, re-render wTileMap for the new +; position, inject the freshly exposed 2-tile edge with a Schedule*Redraw +; (applied by RedrawRowOrColumn in VBlank), and ramp hSCX/hSCY SLOP_SCROLL_PX +; px per frame. After an even coord count it ends block-aligned exactly where +; SlopExploreRenderBG would have placed the view, so wTileMap / the block +; pointer / arrow logic / warp scan are all consistent afterwards. +; --------------------------------------------------------------------------- +SlopScrollRight: + xor a + ldh [hAutoBGTransferEnabled], a +.loop + push bc + ld a, [wXCoord] + inc a + ld [wXCoord], a + ld a, [wMapViewVRAMPointer] ; VRAM col +2 (wrap within the 32-tile row) + ld e, a + and $e0 + ld d, a + ld a, e + add 2 + and $1f + or d + ld [wMapViewVRAMPointer], a + ld hl, wXBlockCoord + inc [hl] + ld a, [hl] + cp 2 + jr nz, .go + ld [hl], 0 ; crossed a block east -> advance block pointer + ld hl, wCurrentTileBlockMapViewPointer + inc [hl] + jr nz, .go + inc hl + inc [hl] +.go + call LoadCurrentMapView + call ScheduleEastColumnRedraw + ld c, SLOP_SCROLL_FRAMES +.frames + ldh a, [hSCX] + add SLOP_SCROLL_PX + ldh [hSCX], a + call DelayFrame + dec c + jr nz, .frames + pop bc + dec c + jr nz, .loop + ret + +SlopScrollLeft: + xor a + ldh [hAutoBGTransferEnabled], a +.loop + push bc + ld a, [wXCoord] + dec a + ld [wXCoord], a + ld a, [wMapViewVRAMPointer] ; VRAM col -2 + ld e, a + and $e0 + ld d, a + ld a, e + sub 2 + and $1f + or d + ld [wMapViewVRAMPointer], a + ld hl, wXBlockCoord + dec [hl] + ld a, [hl] + inc a + jr nz, .go ; was 0 -> now $ff: crossed a block west + ld [hl], 1 + ld hl, wCurrentTileBlockMapViewPointer + ld a, [hl] + sub 1 + ld [hl], a + jr nc, .go + inc hl + dec [hl] +.go + call LoadCurrentMapView + call ScheduleWestColumnRedraw + ld c, SLOP_SCROLL_FRAMES +.frames + ldh a, [hSCX] + sub SLOP_SCROLL_PX + ldh [hSCX], a + call DelayFrame + dec c + jr nz, .frames + pop bc + dec c + jr nz, .loop + ret + +SlopScrollDown: + xor a + ldh [hAutoBGTransferEnabled], a +.loop + push bc + ld a, [wYCoord] + inc a + ld [wYCoord], a + ld a, [wMapViewVRAMPointer] ; VRAM row +1 (=+$40), wrap high byte into vBGMap0 + add $40 + ld [wMapViewVRAMPointer], a + jr nc, .vramDone + ld a, [wMapViewVRAMPointer + 1] + inc a + and $03 + or $98 + ld [wMapViewVRAMPointer + 1], a +.vramDone + ld hl, wYBlockCoord + inc [hl] + ld a, [hl] + cp 2 + jr nz, .go + ld [hl], 0 ; crossed a block south -> advance block pointer + ld a, [wCurMapWidth] + add MAP_BORDER * 2 + ld b, a + ld hl, wCurrentTileBlockMapViewPointer + ld a, [hl] + add b + ld [hl], a + jr nc, .go + inc hl + inc [hl] +.go + call LoadCurrentMapView + call ScheduleSouthRowRedraw + ld c, SLOP_SCROLL_FRAMES +.frames + ldh a, [hSCY] + add SLOP_SCROLL_PX + ldh [hSCY], a + call DelayFrame + dec c + jr nz, .frames + pop bc + dec c + jr nz, .loop + ret + +SlopScrollUp: + xor a + ldh [hAutoBGTransferEnabled], a +.loop + push bc + ld a, [wYCoord] + dec a + ld [wYCoord], a + ld a, [wMapViewVRAMPointer] ; VRAM row -1 (=-$40) + sub $40 + ld [wMapViewVRAMPointer], a + jr nc, .vramDone + ld a, [wMapViewVRAMPointer + 1] + dec a + and $03 + or $98 + ld [wMapViewVRAMPointer + 1], a +.vramDone + ld hl, wYBlockCoord + dec [hl] + ld a, [hl] + inc a + jr nz, .go ; was 0 -> now $ff: crossed a block north + ld [hl], 1 + ld a, [wCurMapWidth] + add MAP_BORDER * 2 + ld b, a + ld hl, wCurrentTileBlockMapViewPointer + ld a, [hl] + sub b + ld [hl], a + jr nc, .go + inc hl + dec [hl] +.go + call LoadCurrentMapView + call ScheduleNorthRowRedraw + ld c, SLOP_SCROLL_FRAMES +.frames + ldh a, [hSCY] + sub SLOP_SCROLL_PX + ldh [hSCY], a + call DelayFrame + dec c + jr nz, .frames + pop bc + dec c + jr nz, .loop + ret + ; (dy, dx) coord offsets scanned outward from the centre for a walkable tile SlopWarpOffsets: db 0, 0 |
