aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoruser <user@clank>2026-07-16 16:40:45 +0200
committeruser <user@clank>2026-07-16 16:40:45 +0200
commit2f43a8851a89661b304edd9396677080dcb3e003 (patch)
treebf74d012a5646cb08e1c49fb9c5c107b154a11b5
parentterm/osk: scroll region so the OSK never hides the input line (diff)
downloadgbos-2f43a8851a89661b304edd9396677080dcb3e003.tar.gz
gbos-2f43a8851a89661b304edd9396677080dcb3e003.tar.xz
gbos-2f43a8851a89661b304edd9396677080dcb3e003.zip
term/osk: view-offset scroll region (lossless backlog on OSK toggle)
Replace the shrink-and-scroll region with a view offset. The terminal is always 18 logical rows; term_write_tilemap maps screen row -> logical row + wViewTop (rows the OSK covers clamp to the cursor line). Showing the OSK sets the offset to OSK_ROWS so the cursor line lands at row 14 (above the keyboard) and hiding it sets the offset back to 0 - now purely a remap, so nothing is scrolled off or destroyed. term_set_view replaces term_set_rows; term_scroll/cursor_down are back to plain 18-row scrolling. Result: full 18-row backlog when the OSK is hidden, a shifted 15-row window when shown, and toggling is lossless (verified: OSK-shown view == baseline rows 3..17, and toggle on+off == baseline exactly).
Diffstat (limited to '')
-rw-r--r--src/osk.asm10
-rw-r--r--src/term.asm87
2 files changed, 35 insertions, 62 deletions
diff --git a/src/osk.asm b/src/osk.asm
index a34a863..5e316e3 100644
--- a/src/osk.asm
+++ b/src/osk.asm
@@ -236,9 +236,9 @@ osk_toggle::
ld [wOskVisible], a
or a
jr z, .hide
- ; show: shrink the terminal to the rows above the keyboard, then enable window
- ld a, 18 - OSK_ROWS
- call term_set_rows
+ ; show: shift the view up so the cursor line clears the keyboard
+ ld a, OSK_ROWS
+ call term_set_view
ld a, [rLCDC]
or %00100000
ld [rLCDC], a
@@ -247,8 +247,8 @@ osk_toggle::
ld a, [rLCDC]
and %11011111
ld [rLCDC], a
- ld a, 18 ; restore full-height terminal
- call term_set_rows
+ xor a ; view unshifted -> full 18-row backlog
+ call term_set_view
ret
; movement with wrap-around; each moves the highlight
diff --git a/src/term.asm b/src/term.asm
index 8105285..fb6e870 100644
--- a/src/term.asm
+++ b/src/term.asm
@@ -36,7 +36,7 @@ DEF wRT_tcol EQU $D58B
DEF wRT_cL EQU $D58C
DEF wRT_cR EQU $D58D
DEF wScratch EQU $D58E
-DEF wTermRows EQU $D58F ; usable terminal rows (18 normally, fewer under the OSK)
+DEF wViewTop EQU $D58F ; view offset: screen row maps to logical row + this
DEF wAssign EQU $D590 ; assign[18]: screen row -> line-slot ($D590-$D5A1)
DEF CUR_L EQU $E0 ; cursor underline, left cell (3px)
@@ -82,8 +82,8 @@ term_init::
ld [wCurCol], a
ld a, 1
ld [wCursorOn], a
- ld a, TROWS
- ld [wTermRows], a ; full height until the OSK shrinks it
+ xor a
+ ld [wViewTop], a ; view starts unshifted (all 18 rows)
; clear the buffer (all slots) to spaces
ld hl, TERM_BUF
@@ -153,13 +153,18 @@ term_write_tilemap::
ret
; helper: C = screen row -> DE = assign[C]*20, HL = $9800 + C*32
.slot20
- ld a, c
+ ld a, [wViewTop]
+ add c ; logical row = screen row + view offset
+ cp TROWS
+ jr c, .lok
+ ld a, TROWS-1 ; rows the OSK covers clamp to the cursor line
+.lok
add LOW(wAssign)
ld l, a
ld a, HIGH(wAssign)
adc 0
ld h, a
- ld a, [hl] ; L = assign[row]
+ ld a, [hl] ; L = assign[logical row]
ld l, a
ld h, 0
add hl, hl
@@ -435,38 +440,24 @@ term_redraw::
; term_scroll - scroll up one line: rotate assign[], blank+build the new bottom
; line, rewrite the tilemap.
; -----------------------------------------------------------------------------
-; term_scroll scrolls only within the active region [0 .. wTermRows-1], so the
-; rows the OSK covers are left alone.
+; term_scroll - scroll all 18 logical rows up one; the new line becomes logical
+; row 17. The view offset decides where that lands on screen, so toggling the
+; OSK never destroys backlog.
term_scroll::
- ld a, [wTermRows]
- dec a
- ld [wScratch], a ; wScratch = bottom row of the region
ld a, [wAssign]
- ld b, a ; B = freed line-slot (assign[0])
- ; rotate assign[1..bottom] down into assign[0..bottom-1]
- ld a, [wScratch]
- or a
- jr z, .norot
- ld c, a ; count = bottom
+ ld [wScratch], a ; freed line-slot
ld hl, wAssign+1
ld de, wAssign
+ ld b, TROWS-1
.rot
ld a, [hl+]
ld [de], a
inc de
- dec c
+ dec b
jr nz, .rot
-.norot
- ; assign[bottom] = freed
ld a, [wScratch]
- add LOW(wAssign)
- ld l, a
- ld a, HIGH(wAssign)
- adc 0
- ld h, a
- ld [hl], b
+ ld [wAssign + TROWS-1], a
; clear buffer[freed] to spaces
- ld a, b
ld l, a
ld h, 0
add hl, hl
@@ -483,12 +474,11 @@ term_scroll::
ld [hl+], a
dec b
jr nz, .clr
- ; rebuild the region's bottom line
+ ; rebuild logical row 17
ld c, 0
.build
push bc
- ld a, [wScratch]
- ld b, a
+ ld b, TROWS-1
call render_tile
pop bc
inc c
@@ -498,41 +488,24 @@ term_scroll::
call term_write_tilemap
ret
-; cursor_down - advance the cursor row, scrolling the region if it overflows.
+; cursor_down - advance the cursor row, scrolling when it runs past the bottom.
cursor_down:
ld a, [wCurRow]
inc a
- ld b, a
- ld a, [wTermRows]
- cp b
- jr z, .scroll
- jr c, .scroll ; candidate >= wTermRows
- ld a, b
- ld [wCurRow], a
- ret
-.scroll
+ cp TROWS
+ jr c, .ok
call term_scroll
- ld a, [wTermRows]
- dec a
+ ld a, TROWS-1
+.ok
ld [wCurRow], a
ret
-; term_set_rows - A = new usable row count. Scrolls the cursor up into the new
-; region if it would fall outside, then applies the new height.
-term_set_rows::
- ld e, a
-.loop
- ld a, [wCurRow]
- cp e
- jr c, .done ; cursor already inside the new region
- call term_scroll ; scroll (old wTermRows still in effect)
- ld hl, wCurRow
- dec [hl]
- jr .loop
-.done
- ld a, e
- ld [wTermRows], a
- ret
+; 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::
+ ld [wViewTop], a
+ jp term_write_tilemap
; -----------------------------------------------------------------------------
; term_putc - A = character. Print at the cursor, advance, handle \n \r \b.