mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-06-06 05:28:31 +09:00
Compare commits
2 Commits
051177f7f7
...
10e577699f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
10e577699f | ||
|
|
01cc5c90ee |
@@ -3356,7 +3356,7 @@ function sampleWaveformRect() {
|
|||||||
|
|
||||||
function clearSampleWaveformArea() {
|
function clearSampleWaveformArea() {
|
||||||
const r = sampleWaveformRect()
|
const r = sampleWaveformRect()
|
||||||
graphics.plotRect(r.x, r.y, r.w, r.h, 255) // 255 = transparent
|
graphics.plotRect(r.x-2, r.y-2, r.w+4, r.h+4, 255) // 255 = transparent
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawSampleWaveform() {
|
function drawSampleWaveform() {
|
||||||
@@ -3364,7 +3364,7 @@ function drawSampleWaveform() {
|
|||||||
const wx0 = r.x, wy0 = r.y, wW = r.w, wH = r.h
|
const wx0 = r.x, wy0 = r.y, wW = r.w, wH = r.h
|
||||||
|
|
||||||
// Clear waveform area to transparent (255 = transparent against text bg)
|
// Clear waveform area to transparent (255 = transparent against text bg)
|
||||||
graphics.plotRect(wx0, wy0, wW, wH, 255)
|
clearSampleWaveformArea()
|
||||||
|
|
||||||
const s = (samplesCache && samplesCache[smpListCursor]) || null
|
const s = (samplesCache && samplesCache[smpListCursor]) || null
|
||||||
if (!s || s.len === 0) return
|
if (!s || s.len === 0) return
|
||||||
@@ -3665,7 +3665,9 @@ const colInstEnvNode = 198 // pink-ish — node markers stand out f
|
|||||||
const colInstEnvAxis = 246 // dim grey for zero/center line
|
const colInstEnvAxis = 246 // dim grey for zero/center line
|
||||||
const colInstEnvHair = 251 // darker grey — quarter-point hairlines (dashed)
|
const colInstEnvHair = 251 // darker grey — quarter-point hairlines (dashed)
|
||||||
const colInstEnvLoop = 220 // muted yellow-orange — loop range band
|
const colInstEnvLoop = 220 // muted yellow-orange — loop range band
|
||||||
const colInstEnvSust = 161 // muted red — sustain range band
|
const colInstEnvSust = 145 // muted yellow-green — loop range band
|
||||||
|
const colInstEnvLoopSuper= 230 // muted yellow-orange — loop range band
|
||||||
|
const colInstEnvSustSuper= 155 // muted yellow-green — loop range band
|
||||||
|
|
||||||
let instListScroll = 0
|
let instListScroll = 0
|
||||||
let instListCursor = 0
|
let instListCursor = 0
|
||||||
@@ -3931,7 +3933,7 @@ function instEnvelopeRect() {
|
|||||||
// the instrument viewer (mirrors clearSampleWaveformArea for the same reason).
|
// the instrument viewer (mirrors clearSampleWaveformArea for the same reason).
|
||||||
function clearInstrumentsEnvelopeArea() {
|
function clearInstrumentsEnvelopeArea() {
|
||||||
const r = instEnvelopeRect()
|
const r = instEnvelopeRect()
|
||||||
graphics.plotRect(r.x, r.y, r.w, r.h, 255)
|
graphics.plotRect(r.x-2, r.y-2, r.w+4, r.h+4, 255)
|
||||||
// Also clear the row of text that the graph overlays would otherwise visually
|
// Also clear the row of text that the graph overlays would otherwise visually
|
||||||
// smudge — the body redraw paints these rows blank anyway, but switchToPanel
|
// smudge — the body redraw paints these rows blank anyway, but switchToPanel
|
||||||
// bypasses the body redraw on exit.
|
// bypasses the body redraw on exit.
|
||||||
@@ -3962,7 +3964,7 @@ function envPlotLine(x0, y0, x1, y1, col) {
|
|||||||
// Value axis: 0 at bottom, env.valueMax at top.
|
// Value axis: 0 at bottom, env.valueMax at top.
|
||||||
function drawEnvelopeGraph(env) {
|
function drawEnvelopeGraph(env) {
|
||||||
const r = instEnvelopeRect()
|
const r = instEnvelopeRect()
|
||||||
graphics.plotRect(r.x, r.y, r.w, r.h, 255) // clear
|
clearInstrumentsEnvelopeArea() // clear
|
||||||
|
|
||||||
// Dashed reference hairlines at quarter points of the value range. Drawn
|
// Dashed reference hairlines at quarter points of the value range. Drawn
|
||||||
// first so the solid axis line / loop bands / polyline can stack on top.
|
// first so the solid axis line / loop bands / polyline can stack on top.
|
||||||
@@ -4026,13 +4028,19 @@ function drawEnvelopeGraph(env) {
|
|||||||
const x0 = pxX(xs[env.loopStart])
|
const x0 = pxX(xs[env.loopStart])
|
||||||
const x1 = pxX(xs[env.loopEnd])
|
const x1 = pxX(xs[env.loopEnd])
|
||||||
const bw = Math.max(1, x1 - x0)
|
const bw = Math.max(1, x1 - x0)
|
||||||
graphics.plotRect(x0, r.y, bw, r.h, colInstEnvLoop)
|
graphics.plotRect(x0, r.y, bw, r.h, colInstEnvLoop, 2)
|
||||||
|
// start & end hairline
|
||||||
|
graphics.plotRect(x0, r.y, 1, r.h, colInstEnvLoopSuper)
|
||||||
|
graphics.plotRect(x1, r.y, 1, r.h, colInstEnvLoopSuper)
|
||||||
}
|
}
|
||||||
if (env.sustEnable && env.sustStart <= lastIdx && env.sustEnd <= lastIdx) {
|
if (env.sustEnable && env.sustStart <= lastIdx && env.sustEnd <= lastIdx) {
|
||||||
const x0 = pxX(xs[env.sustStart])
|
const x0 = pxX(xs[env.sustStart])
|
||||||
const x1 = pxX(xs[env.sustEnd])
|
const x1 = pxX(xs[env.sustEnd])
|
||||||
const bw = Math.max(1, x1 - x0)
|
const bw = Math.max(1, x1 - x0)
|
||||||
graphics.plotRect(x0, r.y, bw, r.h, colInstEnvSust)
|
graphics.plotRect(x0, r.y, bw, r.h, colInstEnvSust, 2)
|
||||||
|
// start & end hairline
|
||||||
|
graphics.plotRect(x0, r.y, 1, r.h, colInstEnvSustSuper)
|
||||||
|
graphics.plotRect(x1, r.y, 1, r.h, colInstEnvSustSuper)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Polyline through the envelope.
|
// Polyline through the envelope.
|
||||||
@@ -4621,8 +4629,8 @@ function openConfirmQuit() {
|
|||||||
colours: popupColours,
|
colours: popupColours,
|
||||||
message: messageLines,
|
message: messageLines,
|
||||||
buttons: [
|
buttons: [
|
||||||
{ label: 'Yes', action: 'yes', default: true },
|
{ label: 'Yes', action: 'yes' },
|
||||||
{ label: 'No', action: 'no' },
|
{ label: 'No', action: 'no', default: true },
|
||||||
],
|
],
|
||||||
onKey: (ks, _shift, ctx) => {
|
onKey: (ks, _shift, ctx) => {
|
||||||
if (ks === 'y' || ks === 'Y') { ctx.close({ action: 'yes' }); return true }
|
if (ks === 'y' || ks === 'Y') { ctx.close({ action: 'yes' }); return true }
|
||||||
@@ -4644,9 +4652,9 @@ function openGotoPopup() {
|
|||||||
title: 'Go To',
|
title: 'Go To',
|
||||||
drawFrame: popupDrawFrame,
|
drawFrame: popupDrawFrame,
|
||||||
colours: popupColours,
|
colours: popupColours,
|
||||||
fields: [{ label: promptStr, width: 3, maxLength: 3 }],
|
fields: [{ label: promptStr, width: 4, maxLength: 3 }],
|
||||||
buttons: [
|
buttons: [
|
||||||
{ label: 'OK', action: 'ok', default: true },
|
{ label: 'OK', action: 'ok' },
|
||||||
{ label: 'Cancel', action: 'cancel' },
|
{ label: 'Cancel', action: 'cancel' },
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
@@ -4714,7 +4722,7 @@ function openRetunePopup() {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
buttons: [
|
buttons: [
|
||||||
{ label: 'OK', action: 'ok', default: true },
|
{ label: 'OK', action: 'ok' },
|
||||||
{ label: 'Cancel', action: 'cancel' },
|
{ label: 'Cancel', action: 'cancel' },
|
||||||
],
|
],
|
||||||
onKey: (ks, _shift, ctx) => {
|
onKey: (ks, _shift, ctx) => {
|
||||||
@@ -4803,7 +4811,7 @@ function openFlagsPopup() {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
buttons: [
|
buttons: [
|
||||||
{ label: 'OK', action: 'ok', default: true },
|
{ label: 'OK', action: 'ok' },
|
||||||
{ label: 'Cancel', action: 'cancel' },
|
{ label: 'Cancel', action: 'cancel' },
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -336,7 +336,7 @@ function showDialog(opts) {
|
|||||||
const listMinW = hasList
|
const listMinW = hasList
|
||||||
? (list.width != null ? list.width + 4 : longestItem + 6)
|
? (list.width != null ? list.width + 4 : longestItem + 6)
|
||||||
: 0
|
: 0
|
||||||
const w = Math.max(maxFieldW + 6, titleW + 4, longestMsg + 6, btnRowW + 4, listMinW, 24)
|
const w = 2+Math.max(maxFieldW + 6, titleW + 4, longestMsg + 6, btnRowW + 4, listMinW, 22)
|
||||||
|
|
||||||
const msgRows = messageLines.length + (messageLines.length > 0 ? 1 : 0)
|
const msgRows = messageLines.length + (messageLines.length > 0 ? 1 : 0)
|
||||||
const fieldsBlockH = fields.length * 4
|
const fieldsBlockH = fields.length * 4
|
||||||
|
|||||||
@@ -149,17 +149,41 @@ class GraphicsJSR223Delegate(private val vm: VM) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun plotRect(x: Int, y: Int, w: Int, h: Int, colour: Int) {
|
fun plotRect(x: Int, y: Int, w: Int, h: Int, colour: Int) = plotRect(x, y, w, h, colour, 0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param eff plot effect. 0 — solid, 1 — 50% checkerboard, 2 — 25% checkerboard
|
||||||
|
*/
|
||||||
|
fun plotRect(x: Int, y: Int, w: Int, h: Int, colour: Int, eff: Int) {
|
||||||
val xs = min(x, x+w).toLong()
|
val xs = min(x, x+w).toLong()
|
||||||
val xe = max(x, x+w).toLong()
|
val xe = max(x, x+w).toLong()
|
||||||
val ys = min(y, y+h).toLong()
|
val ys = min(y, y+h).toLong()
|
||||||
val ye = max(y, y+h).toLong()
|
val ye = max(y, y+h).toLong()
|
||||||
|
|
||||||
getFirstGPU()?.let {
|
getFirstGPU()?.let {
|
||||||
for (py in ys until ye) {
|
val forYcond = if (eff == 2) (ys until ye step 2) else (ys until ye)
|
||||||
for (px in xs until xe) {
|
|
||||||
if (px in 0 until it.config.width && py in 0 until it.config.height) {
|
for (py in forYcond) {
|
||||||
it.poke(py * it.config.width + px, colour.toByte())
|
when (eff) {
|
||||||
|
0 -> for (px in xs until xe) {
|
||||||
|
if (px in 0 until it.config.width && py in 0 until it.config.height) {
|
||||||
|
it.poke(py * it.config.width + px, colour.toByte())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
1 -> {
|
||||||
|
val parity = py % 2
|
||||||
|
val forXcond = if (parity == 0L) (xs until xe step 2) else ((xs+1) until xe step 2)
|
||||||
|
|
||||||
|
for (px in forXcond) {
|
||||||
|
if (px in 0 until it.config.width && py in 0 until it.config.height) {
|
||||||
|
it.poke(py * it.config.width + px, colour.toByte())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
2 -> for (px in xs until xe step 2) {
|
||||||
|
if (px in 0 until it.config.width && py in 0 until it.config.height) {
|
||||||
|
it.poke(py * it.config.width + px, colour.toByte())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -167,17 +191,41 @@ class GraphicsJSR223Delegate(private val vm: VM) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun plotRect2(x: Int, y: Int, w: Int, h: Int, colour: Int) {
|
fun plotRect2(x: Int, y: Int, w: Int, h: Int, colour: Int) = plotRect2(x, y, w, h, colour, 0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param eff plot effect. 0 — solid, 1 — 50% checkerboard, 2 — 25% checkerboard
|
||||||
|
*/
|
||||||
|
fun plotRect2(x: Int, y: Int, w: Int, h: Int, colour: Int, eff: Int) {
|
||||||
val xs = min(x, x+w).toLong()
|
val xs = min(x, x+w).toLong()
|
||||||
val xe = max(x, x+w).toLong()
|
val xe = max(x, x+w).toLong()
|
||||||
val ys = min(y, y+h).toLong()
|
val ys = min(y, y+h).toLong()
|
||||||
val ye = max(y, y+h).toLong()
|
val ye = max(y, y+h).toLong()
|
||||||
|
|
||||||
getFirstGPU()?.let {
|
getFirstGPU()?.let {
|
||||||
for (py in ys until ye) {
|
val forYcond = if (eff == 2) (ys until ye step 2) else (ys until ye)
|
||||||
for (px in xs until xe) {
|
|
||||||
if (px in 0 until it.config.width && py in 0 until it.config.height) {
|
for (py in forYcond) {
|
||||||
it.poke(262144 + py * it.config.width + px, colour.toByte())
|
when (eff) {
|
||||||
|
0 -> for (px in xs until xe) {
|
||||||
|
if (px in 0 until it.config.width && py in 0 until it.config.height) {
|
||||||
|
it.poke(262144 + py * it.config.width + px, colour.toByte())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
1 -> {
|
||||||
|
val parity = py % 2
|
||||||
|
val forXcond = if (parity == 0L) (xs until xe step 2) else ((xs+1) until xe step 2)
|
||||||
|
|
||||||
|
for (px in forXcond) {
|
||||||
|
if (px in 0 until it.config.width && py in 0 until it.config.height) {
|
||||||
|
it.poke(py * it.config.width + px, colour.toByte())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
2 -> for (px in xs until xe step 2) {
|
||||||
|
if (px in 0 until it.config.width && py in 0 until it.config.height) {
|
||||||
|
it.poke(py * it.config.width + px, colour.toByte())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -195,7 +243,12 @@ class GraphicsJSR223Delegate(private val vm: VM) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun plotRectMode1(x: Int, y: Int, w: Int, h: Int, colour: Int, plane: Int) {
|
fun plotRectMode1(x: Int, y: Int, w: Int, h: Int, colour: Int, plane: Int) = plotRectMode1(x, y, w, h, colour, plane, 0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param eff plot effect. 0 — solid, 1 — 50% checkerboard, 2 — 25% checkerboard
|
||||||
|
*/
|
||||||
|
fun plotRectMode1(x: Int, y: Int, w: Int, h: Int, colour: Int, plane: Int, eff: Int) {
|
||||||
val xs = min(x, x+w).toLong()
|
val xs = min(x, x+w).toLong()
|
||||||
val xe = max(x, x+w).toLong()
|
val xe = max(x, x+w).toLong()
|
||||||
val ys = min(y, y+h).toLong()
|
val ys = min(y, y+h).toLong()
|
||||||
@@ -205,10 +258,29 @@ class GraphicsJSR223Delegate(private val vm: VM) {
|
|||||||
val halfW = it.config.width / 2
|
val halfW = it.config.width / 2
|
||||||
val halfH = it.config.height / 2
|
val halfH = it.config.height / 2
|
||||||
val planesize = it.config.width * it.config.height / 4
|
val planesize = it.config.width * it.config.height / 4
|
||||||
for (py in ys until ye) {
|
val forYcond = if (eff == 2) (ys until ye step 2) else (ys until ye)
|
||||||
for (px in xs until xe) {
|
|
||||||
if (px in 0 until halfW && py in 0 until halfH) {
|
for (py in forYcond) {
|
||||||
it.poke(py * halfW + px + planesize * plane, colour.toByte())
|
when (eff) {
|
||||||
|
0 -> for (px in xs until xe) {
|
||||||
|
if (px in 0 until halfW && py in 0 until halfH) {
|
||||||
|
it.poke(py * halfW + px + planesize * plane, colour.toByte())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
1 -> {
|
||||||
|
val parity = py % 2
|
||||||
|
val forXcond = if (parity == 0L) (xs until xe step 2) else ((xs+1) until xe step 2)
|
||||||
|
|
||||||
|
for (px in forXcond) {
|
||||||
|
if (px in 0 until halfW && py in 0 until halfH) {
|
||||||
|
it.poke(py * halfW + px + planesize * plane, colour.toByte())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
2 -> for (px in xs until xe step 2) {
|
||||||
|
if (px in 0 until halfW && py in 0 until halfH) {
|
||||||
|
it.poke(py * halfW + px + planesize * plane, colour.toByte())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user