From 74d94b350c13d21f612239378751c1fb2b83afad Mon Sep 17 00:00:00 2001 From: minjaesong Date: Thu, 23 Apr 2026 01:32:44 +0900 Subject: [PATCH] taut: always scroll to centre --- assets/disk0/tvdos/bin/taut.js | 44 ++++++++++++------ .../src/net/torvald/tsvm/rom/FontROM7x14.png | Bin 3699 -> 3330 bytes 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/assets/disk0/tvdos/bin/taut.js b/assets/disk0/tvdos/bin/taut.js index 7eaf39a..3581a41 100644 --- a/assets/disk0/tvdos/bin/taut.js +++ b/assets/disk0/tvdos/bin/taut.js @@ -136,8 +136,8 @@ function buildRowCell(patternData, row) { else if (note == 0xFFFE) sNote = sym.notecut else if (note == 0x0000) sNote = sym.keyoff - let sInst = inst.toString(16).toUpperCase().padStart(3, sym.middot) - if (inst == 0) sInst = sym.middot.repeat(3) + let sInst = inst.toString(16).toUpperCase().padStart(2, sym.middot) + if (inst == 0) sInst = sym.middot.repeat(2) let sVolEff = volEffSym[voleff >>> 6] let sVolArg = voleffarg.toString().padStart(2, sym.middot) @@ -314,8 +314,8 @@ function loadTaud(filePath, songIndex) { ///////////////////////////////////////////////////////////////////////////////////////////////////////////// const [SCRH, SCRW] = con.getmaxyx() -const PTNVIEW_OFFSET_X = 8 -const PTNVIEW_OFFSET_Y = 10 +const PTNVIEW_OFFSET_X = 5 +const PTNVIEW_OFFSET_Y = 9 const PTNVIEW_HEIGHT = SCRH - PTNVIEW_OFFSET_Y const COLSIZE = 18 const VOCSIZE = 4 @@ -349,6 +349,14 @@ function drawStatusBar() { print(txt) } +function drawSeparators(posY, col_size) { + con.color_pair(colSep, 255) + for (let c = 0; c < VOCSIZE - 1; c++) { + con.move(posY, PTNVIEW_OFFSET_X + col_size * (c+1) - 1) + con.prnch(0xB3) + } +} + function drawVoiceHeaders() { fillLine(PTNVIEW_OFFSET_Y - 1, colVoiceHdr, 255) con.color_pair(colVoiceHdr, 255) @@ -363,10 +371,12 @@ function drawVoiceHeaders() { const patIdx = cue.pats[voice] const vlabel = `V${(voice+1).toString().padStart(2,'0')}` const plabel = (patIdx === CUE_EMPTY) ? '---' : patIdx.toString(16).toUpperCase().padStart(3,'0') - const label = `${vlabel} ptn ${plabel}` + const label = ` ${vlabel} ptn ${plabel} ` print((label + ' ').substring(0, COLSIZE - 1)) } } + + drawSeparators(PTNVIEW_OFFSET_Y - 1, COLSIZE) } function drawPatternRowAt(viewRow) { @@ -376,14 +386,17 @@ function drawPatternRowAt(viewRow) { const back = highlight ? colHighlight : colBackPtn const cue = song.cues[cueIdx] - con.move(y, 1) con.color_pair(colRowNum, back) if (actualRow < ROWS_PER_PAT) { if (actualRow % 4 == 0) {con.color_pair(colRowNumEmph1, back)} - print(' ' + actualRow.toString().toUpperCase().padStart(2, '0') + ' ') - } else { + let rowstr = actualRow.toString().toUpperCase().padStart(2, '0') + con.move(y, 1); con.prnch(rowstr.charCodeAt(0)); con.move(y, 2); con.prnch(rowstr.charCodeAt(1)) + con.move(y, SCRW-2); con.prnch(rowstr.charCodeAt(0)); con.move(y, SCRW-1); con.prnch(rowstr.charCodeAt(1)) + } + else { print(' ') } + // TODO scroll indicator on x=SCRW? for (let c = 0; c < VOCSIZE; c++) { const voice = voiceOff + c @@ -398,11 +411,7 @@ function drawPatternRowAt(viewRow) { drawCellAt(y, x, cell, back) } - con.color_pair(colSep, 255) - for (let c = 0; c < VOCSIZE - 1; c++) { - con.move(y, PTNVIEW_OFFSET_X + COLSIZE * (c+1) - 1) - con.prnch(0xB3) - } + drawSeparators(y, COLSIZE) } function drawPatternView() { @@ -413,7 +422,7 @@ function drawControlHint() { con.move(SCRH, 1) print(' '.repeat(SCRW-1)) con.move(SCRH, 1) - print(`\u008424u\u008425u Move rows ${MIDDOT} \u008427u\u008426u Move vox ${MIDDOT} Pg\u008424u\u008425u Move Ptns ${MIDDOT} Hm/Ed Init/Last row ${MIDDOT} q Quit`) + print(`\u008424u\u008425u Move rows ${MIDDOT} \u008427u\u008426u Move vox ${MIDDOT} Pg\u008424u\u008425u Move Ptns ${MIDDOT} Hm/Ed Init/Last row ${MIDDOT} q Quit ----`) } function drawAll() { @@ -472,6 +481,8 @@ function shiftPatternArea(dy) { // APPLICATION STUB ///////////////////////////////////////////////////////////////////////////////////////////////////////////// +con.curs_set(0) + let currentPanel = VIEW_TIMELINE let cueIdx = 0 let cursorRow = 0 @@ -495,7 +506,9 @@ function clampCursor() { if (cursorRow < 0) cursorRow = 0 if (cursorRow >= ROWS_PER_PAT) cursorRow = ROWS_PER_PAT - 1 if (cursorRow < scrollRow) scrollRow = cursorRow - if (cursorRow >= scrollRow + PTNVIEW_HEIGHT) scrollRow = cursorRow - PTNVIEW_HEIGHT + 1 + // bottom two IF statements will keep the cursor at the centre until viewpoint scroll edge has reached + if (cursorRow < scrollRow + (PTNVIEW_HEIGHT>>>1) && scrollRow > 0) scrollRow = cursorRow - (PTNVIEW_HEIGHT>>>1) + if (cursorRow >= scrollRow + ((PTNVIEW_HEIGHT+1)>>>1)) scrollRow = cursorRow - ((PTNVIEW_HEIGHT+1)>>>1) + 1 if (scrollRow < 0) scrollRow = 0 if (scrollRow + PTNVIEW_HEIGHT > ROWS_PER_PAT) scrollRow = Math.max(0, ROWS_PER_PAT - PTNVIEW_HEIGHT) @@ -584,4 +597,5 @@ while (!exitFlag) { sys.free(SCRATCH_PTR) con.clear() con.move(1, 1) +con.curs_set(1) return 0 \ No newline at end of file diff --git a/tsvm_core/src/net/torvald/tsvm/rom/FontROM7x14.png b/tsvm_core/src/net/torvald/tsvm/rom/FontROM7x14.png index f864a62ba34e730723bb55780af22e70fabec446..2cafa42b73d8b3005aed357dd16c8d9d028e73d0 100644 GIT binary patch delta 3327 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 JPDHLkV1h3)V@Lo1 delta 3684 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