mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-06-18 10:24:04 +09:00
Compare commits
3 Commits
76011d4fa9
...
02c4f9590c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
02c4f9590c | ||
|
|
34afa95137 | ||
|
|
284108f07f |
@@ -146,7 +146,7 @@ const panFxNames = {
|
|||||||
3:"Fine slide",
|
3:"Fine slide",
|
||||||
30:"Fine slide L",
|
30:"Fine slide L",
|
||||||
31:"Fine slide R",
|
31:"Fine slide R",
|
||||||
999:"--",
|
999:"---",
|
||||||
}
|
}
|
||||||
const volFxNames = {
|
const volFxNames = {
|
||||||
0:"Set to",
|
0:"Set to",
|
||||||
@@ -155,7 +155,7 @@ const volFxNames = {
|
|||||||
3:"Fine slide",
|
3:"Fine slide",
|
||||||
30:"Fine slide DN",
|
30:"Fine slide DN",
|
||||||
31:"Fine slide UP",
|
31:"Fine slide UP",
|
||||||
999:"--",
|
999:"---",
|
||||||
}
|
}
|
||||||
|
|
||||||
const pitchTablePresets = {
|
const pitchTablePresets = {
|
||||||
@@ -564,8 +564,9 @@ const colVoiceHdr = 230
|
|||||||
const colSep = 252
|
const colSep = 252
|
||||||
const colPushBtnBack = 143
|
const colPushBtnBack = 143
|
||||||
const colTabBarBack = 187
|
const colTabBarBack = 187
|
||||||
const colTabBarOrn = 135
|
const colTabBarOrn = 91//135
|
||||||
const colBrand = 211
|
const colBrand = 211
|
||||||
|
const colPopupBack = 91
|
||||||
|
|
||||||
|
|
||||||
// protip: avoid using colour zero
|
// protip: avoid using colour zero
|
||||||
@@ -940,7 +941,7 @@ function drawVoiceDetail(isVerticalLayout = false, ptn = null, activeRow = -1, c
|
|||||||
|
|
||||||
const lines = []
|
const lines = []
|
||||||
lines.push({ label: 'Note ', value: `${noteToStr(note)} ($${note.hex04()})`, fg: colNote })
|
lines.push({ label: 'Note ', value: `${noteToStr(note)} ($${note.hex04()})`, fg: colNote })
|
||||||
lines.push({ label: 'Inst ', value: inst === 0 ? '--' : inst.hex02(), fg: colInst })
|
lines.push({ label: 'Inst ', value: inst === 0 ? '---' : ('$'+inst.hex02()), fg: colInst })
|
||||||
lines.push({ label: 'Vx ', value: `${volFxNames[voleffop1]} ${voleffarg1}`, fg: colVol })
|
lines.push({ label: 'Vx ', value: `${volFxNames[voleffop1]} ${voleffarg1}`, fg: colVol })
|
||||||
lines.push({ label: 'Px ', value: `${panFxNames[paneffop1]} ${paneffarg1}`, fg: colPan })
|
lines.push({ label: 'Px ', value: `${panFxNames[paneffop1]} ${paneffarg1}`, fg: colPan })
|
||||||
lines.push({ label: 'Fx ', value: fxName.trimEnd(), fg: colEffOp })
|
lines.push({ label: 'Fx ', value: fxName.trimEnd(), fg: colEffOp })
|
||||||
@@ -950,7 +951,7 @@ function drawVoiceDetail(isVerticalLayout = false, ptn = null, activeRow = -1, c
|
|||||||
if (cumState !== null) {
|
if (cumState !== null) {
|
||||||
lines.push({ label: '------', value: '', fg: colSep })
|
lines.push({ label: '------', value: '', fg: colSep })
|
||||||
lines.push({ label: 'L.Note', value: noteToStr(cumState.lastNote), fg: colNote })
|
lines.push({ label: 'L.Note', value: noteToStr(cumState.lastNote), fg: colNote })
|
||||||
lines.push({ label: 'L.Inst', value: cumState.lastInst === 0 ? '--' : cumState.lastInst.hex02(), fg: colInst })
|
lines.push({ label: 'L.Inst', value: cumState.lastInst === 0 ? '---' : ('$'+cumState.lastInst.hex02()), fg: colInst })
|
||||||
lines.push({ label: 'Vol ', value: `$${cumState.volAbs.hex02()}`, fg: colVol })
|
lines.push({ label: 'Vol ', value: `$${cumState.volAbs.hex02()}`, fg: colVol })
|
||||||
lines.push({ label: 'Pan ', value: `$${cumState.panAbs.hex02()}`, fg: colPan })
|
lines.push({ label: 'Pan ', value: `$${cumState.panAbs.hex02()}`, fg: colPan })
|
||||||
const _apo = Math.abs(cumState.pitchOff)
|
const _apo = Math.abs(cumState.pitchOff)
|
||||||
@@ -1112,6 +1113,8 @@ function setTimelineRowStyle(style) {
|
|||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
con.curs_set(0)
|
con.curs_set(0)
|
||||||
|
graphics.setBackground(34, 38, 51)
|
||||||
|
graphics.setGraphicsMode(0)
|
||||||
|
|
||||||
let currentPanel = VIEW_TIMELINE
|
let currentPanel = VIEW_TIMELINE
|
||||||
let cueIdx = 0
|
let cueIdx = 0
|
||||||
@@ -1438,7 +1441,7 @@ function simulateRowState(ptnDat, uptoRow) {
|
|||||||
let lastNote = 0xFFFF, lastInst = 0
|
let lastNote = 0xFFFF, lastInst = 0
|
||||||
let volAbs = 0x3F, panAbs = 0x20
|
let volAbs = 0x3F, panAbs = 0x20
|
||||||
let pitchOff = 0, portaTarget = -1
|
let pitchOff = 0, portaTarget = -1
|
||||||
let speed = 6
|
let speed = audio.getTickRate(PLAYHEAD) // not always going to be correct but it should be mostly
|
||||||
let memEF = 0, memG = 0
|
let memEF = 0, memG = 0
|
||||||
let memHU = { speed: 0, depth: 0 }
|
let memHU = { speed: 0, depth: 0 }
|
||||||
let memR = { speed: 0, depth: 0 }
|
let memR = { speed: 0, depth: 0 }
|
||||||
@@ -1470,10 +1473,10 @@ function simulateRowState(ptnDat, uptoRow) {
|
|||||||
}
|
}
|
||||||
if (inst !== 0) lastInst = inst
|
if (inst !== 0) lastInst = inst
|
||||||
|
|
||||||
// Volume column: set OR slide
|
// Volume column: set OR slide (0xC0 = 3.00 nop is the empty sentinel, not 0x00)
|
||||||
const volop = (voleff >>> 6) & 3
|
const volop = (voleff >>> 6) & 3
|
||||||
const volefarg = voleff & 63
|
const volefarg = voleff & 63
|
||||||
if (voleff !== 0) {
|
if (voleff !== 0xC0) {
|
||||||
if (volop === 0) {
|
if (volop === 0) {
|
||||||
volAbs = volefarg
|
volAbs = volefarg
|
||||||
} else if (volop === 1) {
|
} else if (volop === 1) {
|
||||||
@@ -1486,10 +1489,10 @@ function simulateRowState(ptnDat, uptoRow) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pan column: set OR slide
|
// Pan column: set OR slide (0xC0 = 3.00 nop is the empty sentinel, not 0x00)
|
||||||
const panop = (paneff >>> 6) & 3
|
const panop = (paneff >>> 6) & 3
|
||||||
const panefarg = paneff & 63
|
const panefarg = paneff & 63
|
||||||
if (paneff !== 0) {
|
if (paneff !== 0xC0) {
|
||||||
if (panop === 0) {
|
if (panop === 0) {
|
||||||
panAbs = panefarg
|
panAbs = panefarg
|
||||||
} else if (panop === 1) {
|
} else if (panop === 1) {
|
||||||
@@ -2001,6 +2004,146 @@ function clampOrdersHoriz() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// GOTO POPUP
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const GOTO_POPUP_W = 26
|
||||||
|
const GOTO_POPUP_H = 5
|
||||||
|
|
||||||
|
const popupDrawFrame = (wo) => {
|
||||||
|
// draw header
|
||||||
|
con.move(wo.y, wo.x)
|
||||||
|
con.color_pair(colTabBarOrn, colTabBarBack)
|
||||||
|
print(`\u00FB`.repeat(wo.width))
|
||||||
|
|
||||||
|
// imprint title
|
||||||
|
let titleWidth = wo.title.length
|
||||||
|
con.move(wo.y, wo.x + (((wo.width - titleWidth - 2) & 254) >>> 1))
|
||||||
|
let col = (wo.isHighlighted) ? 161 : 240
|
||||||
|
con.color_pair(col, colTabBarBack)
|
||||||
|
print(` ${wo.title} `)
|
||||||
|
|
||||||
|
// fill content area
|
||||||
|
for (let r = 1; r < wo.height - 1; r++) {
|
||||||
|
con.move(wo.y + r, wo.x)
|
||||||
|
con.color_pair(230, colPopupBack)
|
||||||
|
print(' '.repeat(wo.width))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawGotoPopup(popup, buf) {
|
||||||
|
con.color_pair(230, colPopupBack)
|
||||||
|
popup.drawFrame()
|
||||||
|
|
||||||
|
const prompts = ['Cue (hex):', 'Cue (hex):', 'Pattern (hex):']
|
||||||
|
const promptStr = prompts[currentPanel] || 'Number:'
|
||||||
|
|
||||||
|
con.move(popup.y + 2, popup.x + 2)
|
||||||
|
con.color_pair(colStatus, colPopupBack)
|
||||||
|
print(promptStr + ' ')
|
||||||
|
con.color_pair(230, 240)
|
||||||
|
print('[' + buf.padEnd(3, '_') + ']')
|
||||||
|
|
||||||
|
con.color_pair(colStatus, 255) // reset colour
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyGoto(num) {
|
||||||
|
if (currentPanel === 0) {
|
||||||
|
cueIdx = num; clampCue()
|
||||||
|
} else if (currentPanel === 1) {
|
||||||
|
const maxCue = song.lastActiveCue < 0 ? 0 : song.lastActiveCue
|
||||||
|
ordersCursor = Math.max(0, Math.min(maxCue, num))
|
||||||
|
if (ordersCursor < ordersScroll) ordersScroll = ordersCursor
|
||||||
|
if (ordersCursor >= ordersScroll + PTNVIEW_HEIGHT)
|
||||||
|
ordersScroll = Math.max(0, ordersCursor - PTNVIEW_HEIGHT + 1)
|
||||||
|
} else if (currentPanel === 2) {
|
||||||
|
patternIdx = num; clampPatternIdx()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function openConfirmQuit() {
|
||||||
|
const pw = 24
|
||||||
|
const ph = 5
|
||||||
|
const px = ((SCRW - pw) / 2 | 0) + 1
|
||||||
|
const py = ((SCRH - ph) / 2 | 0)
|
||||||
|
|
||||||
|
const popup = new win.WindowObject(px, py, pw, ph, ()=>{}, ()=>{}, 'Quit?', popupDrawFrame)
|
||||||
|
popup.isHighlighted = true
|
||||||
|
popup.titleBack = colPopupBack
|
||||||
|
|
||||||
|
con.color_pair(230, colPopupBack)
|
||||||
|
popup.drawFrame()
|
||||||
|
|
||||||
|
con.move(py + 2, px + 2)
|
||||||
|
con.color_pair(colStatus, colPopupBack)
|
||||||
|
print('Exit taut? ')
|
||||||
|
con.color_pair(230, 240)
|
||||||
|
print('[Y/N]')
|
||||||
|
|
||||||
|
con.color_pair(colStatus, 255) // reset colour
|
||||||
|
|
||||||
|
let result = false
|
||||||
|
let done = false
|
||||||
|
while (!done) {
|
||||||
|
input.withEvent(ev => {
|
||||||
|
if (ev[0] !== 'key_down') return
|
||||||
|
if (1 !== ev[2]) return
|
||||||
|
const ks = ev[1]
|
||||||
|
if (ks === 'y' || ks === 'Y' || ks === '\n') { result = true; done = true }
|
||||||
|
else if (ks === 'n' || ks === 'N' || ks === '<ESC>') { done = true }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!result) drawAll()
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
function openGotoPopup() {
|
||||||
|
const pw = GOTO_POPUP_W
|
||||||
|
const ph = GOTO_POPUP_H
|
||||||
|
const px = ((SCRW - pw) / 2 | 0) + 1
|
||||||
|
const py = ((SCRH - ph) / 2 | 0)
|
||||||
|
|
||||||
|
const popup = new win.WindowObject(px, py, pw, ph, ()=>{}, ()=>{}, 'Go To', popupDrawFrame)
|
||||||
|
popup.isHighlighted = true
|
||||||
|
popup.titleBack = colTabBarBack
|
||||||
|
|
||||||
|
let buf = ''
|
||||||
|
let done = false
|
||||||
|
drawGotoPopup(popup, buf)
|
||||||
|
|
||||||
|
let eventJustReceived = true
|
||||||
|
|
||||||
|
while (!done) {
|
||||||
|
input.withEvent(ev => {
|
||||||
|
if (ev[0] !== 'key_down') return
|
||||||
|
const ks = ev[1]
|
||||||
|
if (1 !== ev[2]) return // not key just hit
|
||||||
|
|
||||||
|
if (eventJustReceived) { // filter Shift-G input
|
||||||
|
eventJustReceived = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ks === '<ESC>') {
|
||||||
|
done = true
|
||||||
|
} else if (ks === '\n') {
|
||||||
|
if (buf.length > 0) applyGoto(parseInt(buf, 16))
|
||||||
|
done = true
|
||||||
|
} else if (ks === '\u0008') {
|
||||||
|
buf = buf.slice(0, -1)
|
||||||
|
drawGotoPopup(popup, buf)
|
||||||
|
} else if (ks.length === 1 && '0123456789abcdefABCDEF'.includes(ks) && buf.length < 3) {
|
||||||
|
buf += ks.toUpperCase()
|
||||||
|
drawGotoPopup(popup, buf)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
drawAll()
|
||||||
|
}
|
||||||
|
|
||||||
clampCursor(); clampVoice(); clampCue(); clampOrdersHoriz(); clampPatternIdx(); clampPatternGrid()
|
clampCursor(); clampVoice(); clampCue(); clampOrdersHoriz(); clampPatternIdx(); clampPatternGrid()
|
||||||
drawAll()
|
drawAll()
|
||||||
|
|
||||||
@@ -2017,8 +2160,8 @@ while (!exitFlag) {
|
|||||||
const keyJustHit = (1 == event[2])
|
const keyJustHit = (1 == event[2])
|
||||||
const shiftDown = (event.includes(59) || event.includes(60))
|
const shiftDown = (event.includes(59) || event.includes(60))
|
||||||
|
|
||||||
if (keysym === "<ESC>" || keysym === "q" || keysym === "Q") {
|
if (keyJustHit && keysym === "q") {
|
||||||
exitFlag = true
|
if (openConfirmQuit()) exitFlag = true
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2031,6 +2174,11 @@ while (!exitFlag) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (keyJustHit && shiftDown && event.includes(keys.G)) {
|
||||||
|
openGotoPopup()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
panels[currentPanel].processInput(event)
|
panels[currentPanel].processInput(event)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
1
assets/disk0/tvdos/bin/taut_fileop.js
Normal file
1
assets/disk0/tvdos/bin/taut_fileop.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
// filesystem navigator for Taut
|
||||||
0
assets/disk0/tvdos/bin/taut_instredit.js
Normal file
0
assets/disk0/tvdos/bin/taut_instredit.js
Normal file
0
assets/disk0/tvdos/bin/taut_notationedit.js
Normal file
0
assets/disk0/tvdos/bin/taut_notationedit.js
Normal file
0
assets/disk0/tvdos/bin/taut_sampleedit.js
Normal file
0
assets/disk0/tvdos/bin/taut_sampleedit.js
Normal file
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user