taut: better fil8l

This commit is contained in:
minjaesong
2026-05-27 11:33:01 +09:00
parent 051177f7f7
commit 01cc5c90ee
2 changed files with 93 additions and 21 deletions

View File

@@ -3356,7 +3356,7 @@ function sampleWaveformRect() {
function clearSampleWaveformArea() {
const r = sampleWaveformRect()
graphics.plotRect(r.x, r.y, r.w, r.h, 255) // 255 = transparent
graphics.plotRect(r.x-1, r.y-1, r.w+1, r.h+1, 255) // 255 = transparent
}
function drawSampleWaveform() {
@@ -3364,7 +3364,7 @@ function drawSampleWaveform() {
const wx0 = r.x, wy0 = r.y, wW = r.w, wH = r.h
// Clear waveform area to transparent (255 = transparent against text bg)
graphics.plotRect(wx0, wy0, wW, wH, 255)
clearSampleWaveformArea()
const s = (samplesCache && samplesCache[smpListCursor]) || null
if (!s || s.len === 0) return
@@ -3931,7 +3931,7 @@ function instEnvelopeRect() {
// the instrument viewer (mirrors clearSampleWaveformArea for the same reason).
function clearInstrumentsEnvelopeArea() {
const r = instEnvelopeRect()
graphics.plotRect(r.x, r.y, r.w, r.h, 255)
graphics.plotRect(r.x-1, r.y-1, r.w+1, r.h+1, 255)
// Also clear the row of text that the graph overlays would otherwise visually
// smudge — the body redraw paints these rows blank anyway, but switchToPanel
// bypasses the body redraw on exit.
@@ -3962,7 +3962,7 @@ function envPlotLine(x0, y0, x1, y1, col) {
// Value axis: 0 at bottom, env.valueMax at top.
function drawEnvelopeGraph(env) {
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
// first so the solid axis line / loop bands / polyline can stack on top.
@@ -4026,13 +4026,13 @@ function drawEnvelopeGraph(env) {
const x0 = pxX(xs[env.loopStart])
const x1 = pxX(xs[env.loopEnd])
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)
}
if (env.sustEnable && env.sustStart <= lastIdx && env.sustEnd <= lastIdx) {
const x0 = pxX(xs[env.sustStart])
const x1 = pxX(xs[env.sustEnd])
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)
}
// Polyline through the envelope.

View File

@@ -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 xe = max(x, x+w).toLong()
val ys = min(y, y+h).toLong()
val ye = max(y, y+h).toLong()
getFirstGPU()?.let {
for (py in ys until ye) {
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())
val forYcond = if (eff == 2) (ys until ye step 2) else (ys until ye)
for (py in forYcond) {
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 xe = max(x, x+w).toLong()
val ys = min(y, y+h).toLong()
val ye = max(y, y+h).toLong()
getFirstGPU()?.let {
for (py in ys until ye) {
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())
val forYcond = if (eff == 2) (ys until ye step 2) else (ys until ye)
for (py in forYcond) {
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 xe = max(x, x+w).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 halfH = it.config.height / 2
val planesize = it.config.width * it.config.height / 4
for (py in ys until ye) {
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())
val forYcond = if (eff == 2) (ys until ye step 2) else (ys until ye)
for (py in forYcond) {
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())
}
}
}
}