@@ -238,15 +238,18 @@ fn fs(in: VertexOut) -> @location(0) vec4<f32> {
238238 let effCmd = (in . packedB >> 8 ) & 255u ;
239239 let effVal = in . packedB & 255u ;
240240
241- let hasNote = (note > 0u );
241+ // OpenMPT numeric encoding: 1-120 = regular notes, 121 = OFF, 122 = CUT, 123 = FADE
242+ let hasNote = (note > 0u ) && (note <= 120u );
243+ let isNoteOff = (note == 121u );
244+ let isNoteCut = (note == 122u ) || (note == 123u );
242245 let hasExpression = (volCmd > 0u ) || (effCmd > 0u );
243246 let ch = channels [in . channel ];
244247 let isMuted = (ch . isMuted == 1u );
245248
246249 let topUV = btnUV - vec2 (0 .5 , 0 .16 );
247250 let topSize = vec2 (0 .20 , 0 .20 );
248251 let isDataPresent = hasExpression && ! isMuted ;
249- let topColorBase = vec3 (0 .0 , 0 .9 , 1 .0 );
252+ let topColorBase = vec3 (1 .0 , 0 .65 , 0 .10 ); // amber = volume/expression indicator
250253 let topColor = topColorBase * select (0 .0 , 1 .5 + bloom , isDataPresent );
251254 let topLed = drawChromeIndicator (topUV , topSize , topColor , isDataPresent , aa );
252255 finalColor = mix (finalColor , topLed . rgb , topLed . a );
@@ -257,7 +260,14 @@ fn fs(in: VertexOut) -> @location(0) vec4<f32> {
257260 var noteColor = vec3 (0 .2 );
258261 var lightAmount = 0 .0 ;
259262
260- if (hasNote ) {
263+ // Note-off / note-cut: show as dim red/orange main indicator
264+ if (isNoteOff ) {
265+ noteColor = vec3 (0 .45 , 0 .05 , 0 .05 );
266+ lightAmount = 0 .6 ;
267+ } else if (isNoteCut ) {
268+ noteColor = vec3 (0 .60 , 0 .20 , 0 .02 );
269+ lightAmount = 0 .5 ;
270+ } else if (hasNote ) {
261271 let pitchHue = pitchClassFromIndex (note );
262272 let baseColor = neonPalette (pitchHue );
263273 let instBand = inst & 15u ;
0 commit comments