aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authoruser <user@clank>2026-07-16 16:46:21 +0200
committeruser <user@clank>2026-07-16 16:46:21 +0200
commit0db949c3a3ab07b264c21c3a15efea6b6055be0d (patch)
tree2d6cdae9ee9983d53838d29a6d7041d26cfab58c /src
parentterm/osk: view-offset scroll region (lossless backlog on OSK toggle) (diff)
downloadgbos-0db949c3a3ab07b264c21c3a15efea6b6055be0d.tar.gz
gbos-0db949c3a3ab07b264c21c3a15efea6b6055be0d.tar.xz
gbos-0db949c3a3ab07b264c21c3a15efea6b6055be0d.zip
term: compute the OSK view offset from the cursor row (keep input visible)
A fixed offset of OSK_ROWS pushed the cursor off the top of the screen when there was little backlog (e.g. a fresh terminal: cursor at logical row 0 -> screen row -3, hidden). Now the offset is max(0, wCurRow - 14): 0 when the cursor is within the visible area, growing only enough to keep the cursor line at the bottom visible row (14) once the terminal has filled past it. compute_offset (from wOskVisible + wCurRow) runs at the top of term_write_tilemap; cursor_down re-runs the tilemap when the cursor changes rows while the OSK is up; osk_toggle just re-runs it. Shared OSK_DOCK constant in gbos.inc keeps term.asm and osk.asm in sync. Verified: fresh terminal + OSK shows the input at row 0; filling past row 14 shifts the view to hold the input at row 14; full screen + OSK puts it at row 14; toggle on+off is still lossless.
Diffstat (limited to 'src')
-rw-r--r--src/osk.asm12
-rw-r--r--src/term.asm38
2 files changed, 33 insertions, 17 deletions
diff --git a/src/osk.asm b/src/osk.asm
index 5e316e3..609f6be 100644
--- a/src/osk.asm
+++ b/src/osk.asm
@@ -16,7 +16,7 @@ DEF rBCPD EQU $FF69
DEF rWY EQU $FF4A
DEF rWX EQU $FF4B
-DEF OSK_ROWS EQU 3
+DEF OSK_ROWS EQU OSK_DOCK
DEF OSK_COLS EQU 20
DEF OSK_KEYS EQU OSK_ROWS * OSK_COLS
DEF OSK_TILE0 EQU 104 ; first OSK tile index (bank 1; terminal uses 0-103)
@@ -236,20 +236,16 @@ osk_toggle::
ld [wOskVisible], a
or a
jr z, .hide
- ; show: shift the view up so the cursor line clears the keyboard
- ld a, OSK_ROWS
- call term_set_view
+ ; show: enable window, then recompute the view so the cursor clears the keys
ld a, [rLCDC]
or %00100000
ld [rLCDC], a
- ret
+ jp term_write_tilemap
.hide
ld a, [rLCDC]
and %11011111
ld [rLCDC], a
- xor a ; view unshifted -> full 18-row backlog
- call term_set_view
- ret
+ jp term_write_tilemap ; offset recomputes to 0 -> full backlog
; movement with wrap-around; each moves the highlight
osk_up:
diff --git a/src/term.asm b/src/term.asm
index fb6e870..64e45aa 100644
--- a/src/term.asm
+++ b/src/term.asm
@@ -80,10 +80,10 @@ term_init::
xor a
ld [wCurRow], a
ld [wCurCol], a
+ ld [wViewTop], a ; view starts unshifted (all 18 rows)
+ ld [wOskVisible], a ; OSK hidden until toggled
ld a, 1
ld [wCursorOn], a
- xor a
- ld [wViewTop], a ; view starts unshifted (all 18 rows)
; clear the buffer (all slots) to spaces
ld hl, TERM_BUF
@@ -108,6 +108,7 @@ term_init::
; line-slot tiles. Pass 1 = indices (bank 0), pass 2 = attributes (bank 1).
; -----------------------------------------------------------------------------
term_write_tilemap::
+ call compute_offset
xor a
ld [rVBK], a
ld c, 0 ; screen row
@@ -494,18 +495,37 @@ cursor_down:
inc a
cp TROWS
jr c, .ok
- call term_scroll
+ call term_scroll ; rewrites the tilemap (offset recomputed)
ld a, TROWS-1
-.ok
ld [wCurRow], a
ret
+.ok
+ ld [wCurRow], a
+ ; the cursor changed rows; if the OSK is up the view offset may need to move
+ ld a, [wOskVisible]
+ or a
+ ret z
+ jp term_write_tilemap
-; term_set_view - A = view-top offset. screen row -> logical row + A. 0 shows all
-; 18 rows; OSK_ROWS shifts the view up so the cursor line clears the keyboard.
-; No content is scrolled/lost - just remapped.
-term_set_view::
+; compute_offset - set wViewTop so the cursor line is always on screen: 0 when
+; the OSK is hidden; otherwise max(0, wCurRow - 14) so the cursor sits at the
+; bottom visible row (14) once the terminal has filled past it, but stays put
+; while there is little content (no shifting the cursor off the top).
+compute_offset::
+ ld a, [wOskVisible]
+ or a
+ jr nz, .osk
+ xor a
ld [wViewTop], a
- jp term_write_tilemap
+ ret
+.osk
+ ld a, [wCurRow]
+ sub TROWS - OSK_DOCK - 1 ; wCurRow - 14
+ jr nc, .store
+ xor a ; cursor above row 14 -> no shift
+.store
+ ld [wViewTop], a
+ ret
; -----------------------------------------------------------------------------
; term_putc - A = character. Print at the cursor, advance, handle \n \r \b.