various mouse nav fixes, font rom update

This commit is contained in:
minjaesong
2026-05-26 04:38:41 +09:00
parent a716807b36
commit 15587a0d76
6 changed files with 153 additions and 23 deletions

View File

@@ -385,6 +385,10 @@ const ag_workMid = new Float32Array(AG_WORK_N)
const ag_workTmp = new Float32Array(AG_WORK_N >> 1)
const ag_bandEnergy = new Float32Array(AG_N_BANDS)
// Sub-500 Hz residual — drops out of the wavelet modulator set on purpose,
// but we keep its RMS around to drive the bass mark.
let ag_bassEnergy = 0
// Persistence buffer — float intensity per cell, plus the glyph last written
// there. Decay shrinks intensity each frame; new beam samples overwrite the
// glyph and bump intensity.
@@ -397,6 +401,7 @@ const ag_cellFg = new Int16Array(AG_VIS_H * AG_VIS_W).fill(-1)
const ag_waveGlyph = new Int16Array(AG_LANE_W * 3).fill(-1)
const ag_stereoGlyph = new Int16Array(AG_LANE_W).fill(-1)
const ag_stereoFg = new Int16Array(AG_LANE_W).fill(-1)
let ag_lastBassFg = -1
// Render rate-limiter — playmp2 spins ~32 Hz, playtad ~1 Hz, playwav ~100 Hz
// at decode time. Clamp visual refresh to 20 Hz so each caller can spam
@@ -579,6 +584,16 @@ function ag_analyseHaar() {
ag_bandEnergy[lv] = rms > 1 ? 1 : rms
len = half
}
// Residual approximation in ag_workMid[0..len-1] holds the sub-500 Hz
// energy that the modulator pipeline intentionally discards. Reuse it
// to drive the bass mark.
let bassSumSq = 0
for (let i = 0; i < len; i++) {
const v = ag_workMid[i]
bassSumSq += v * v
}
const bassRms = Math.sqrt(bassSumSq / len) * 1.8
ag_bassEnergy = bassRms > 1 ? 1 : bassRms
}
// ── Wavescope (rows 3..5) ──────────────────────────────────────────────────
@@ -652,6 +667,16 @@ const AG_XY_CY = AG_VIS_H >> 1 // centre row
const AG_XY_SX = 18 // (LR) → horizontal extent ±36 cells
const AG_XY_SY = 9 // (L+R) → vertical extent ±18 cells
// Bass mark: 2×2 cell indicator pinned to the centre of the vectorscope so
// the bass "subwoofer" sits underneath the beam's pivot point. Half-blocks
// form a compact 16×16-pixel "dot" centred in the 16×32-pixel 2×2 area.
const AG_BASS_VIS_R0 = AG_XY_CY - 1
const AG_BASS_VIS_C0 = AG_XY_CX - 1
const AG_BASS_VIS_R1 = AG_BASS_VIS_R0 + 1
const AG_BASS_VIS_C1 = AG_BASS_VIS_C0 + 1
const AG_BASS_SCR_R = AG_ROW_VIS_TOP + AG_BASS_VIS_R0
const AG_BASS_SCR_C = AG_COL_INSIDE_L + AG_BASS_VIS_C0
// Glyphs.
const AG_G_DOT = 0xFA // ·
const AG_G_BSL = 0x5C // \\
@@ -741,7 +766,10 @@ function ag_drawVisualiser() {
for (let r = 0; r < AG_VIS_H; r++) {
const rowOff = r * AG_VIS_W
const screenY = AG_ROW_VIS_TOP + r
const inBassRow = (r === AG_BASS_VIS_R0 || r === AG_BASS_VIS_R1)
for (let c = 0; c < AG_VIS_W; c++) {
// Bass mark owns its 2×2 cells — let ag_drawBassMark() paint them.
if (inBassRow && (c === AG_BASS_VIS_C0 || c === AG_BASS_VIS_C1)) continue
const idx = rowOff + c
const e = ag_persist[idx]
let levelIdx = (e * 5) | 0
@@ -758,6 +786,25 @@ function ag_drawVisualiser() {
}
}
// ── Bass mark (rows 29-30, cols 2-3) ───────────────────────────────────────
// Brightness-only indicator driven by the sub-500 Hz residual of the Haar
// pyramid. Uses indices 1..4 of the beam palette so the dot never falls all
// the way to background — a quiet track still shows a faint amber ember.
function ag_drawBassMark() {
let idx = (ag_bassEnergy * 4) | 0
if (idx > 3) idx = 3
if (idx < 0) idx = 0
const fg = AG_BEAM_PAL[idx + 1]
if (fg === ag_lastBassFg) return
ag_lastBassFg = fg
ag_color(fg, AG_COL_BG)
ag_mvprn(AG_BASS_SCR_R, AG_BASS_SCR_C, 0xDC)
ag_mvprn(AG_BASS_SCR_R, AG_BASS_SCR_C + 1, 0xDC)
ag_mvprn(AG_BASS_SCR_R + 1, AG_BASS_SCR_C, 0xDF)
ag_mvprn(AG_BASS_SCR_R + 1, AG_BASS_SCR_C + 1, 0xDF)
}
// ── Stereo energy bar (row 31) ─────────────────────────────────────────────
//
// Same idea as playtaud.drawStereo() but driven by raw PCM: for each sample,
@@ -840,6 +887,8 @@ function audioInit(params) {
ag_cellGlyph.fill(-1); ag_cellFg.fill(-1)
ag_waveGlyph.fill(-1)
ag_stereoGlyph.fill(-1); ag_stereoFg.fill(-1)
ag_bassEnergy = 0
ag_lastBassFg = -1
con.curs_set(0)
con.clear()
@@ -861,6 +910,7 @@ function audioRender() {
ag_updateXYScope()
ag_drawWavescope()
ag_drawVisualiser()
ag_drawBassMark()
ag_drawStereo()
}