spikes/KniWeb (outside LittleSim.sln): a kni-blazor-gl template project (KNI 4.2.9001, net8.0) referencing MrGameEng.Core directly. A mini-host in the GameHost mold drives EngineContext/GameClock/Scene phases over KNI's Game; the scene moves 300 Friflo entities in the update phase and draws them with SpriteBatch (WebGL). Verified in a real browser: sprites render and animate, browser console is clean. Decision (docs/web-client.md): path A — KNI — is the primary route for the web client; the core runs in Blazor WASM unchanged thanks to the Core/Host split. Known follow-ups: per-platform compilation of the graphics libraries against nkast.* packages, shader compatibility for Renderer2D, HTTP-served content instead of the filesystem. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
87 lines
2.3 KiB
JavaScript
87 lines
2.3 KiB
JavaScript
// streamProcessor.js
|
|
class StreamProcessor extends AudioWorkletProcessor
|
|
{
|
|
constructor()
|
|
{
|
|
super();
|
|
this.queue = [];
|
|
|
|
this.port.onmessage = (event) =>
|
|
{
|
|
var data = event.data;
|
|
|
|
if (typeof data === 'number')
|
|
{
|
|
if (data === 2)
|
|
{
|
|
this.queue = [];
|
|
}
|
|
}
|
|
if (data instanceof Uint8Array)
|
|
{
|
|
const buffer = new Int16Array(data.buffer, data.byteOffset, data.length / 2);
|
|
buffer.offset = 0;
|
|
this.queue.push(buffer);
|
|
}
|
|
};
|
|
}
|
|
|
|
|
|
process(inputs, outputs, parameters)
|
|
{
|
|
const output = outputs[0];
|
|
|
|
const channelCount = output.length;
|
|
const sampleCount = output[0].length;
|
|
|
|
let written = 0;
|
|
|
|
while (written < sampleCount && this.queue.length > 0)
|
|
{
|
|
const buffer = this.queue[0];
|
|
const offset = buffer.offset;
|
|
|
|
const available = buffer.length - offset;
|
|
const needed = sampleCount - written;
|
|
const copyCount = Math.min(available, needed);
|
|
|
|
for (let i = 0; i < copyCount; i++)
|
|
{
|
|
for (let c = 0; c < channelCount; c++)
|
|
{
|
|
const channel = output[c];
|
|
let value = (buffer[offset+i] / 32767);
|
|
channel[written+i] = value;
|
|
}
|
|
}
|
|
|
|
written += copyCount;
|
|
buffer.offset += copyCount;
|
|
|
|
if (buffer.offset >= buffer.length)
|
|
{
|
|
this.queue.shift();
|
|
this.port.postMessage(1);
|
|
}
|
|
}
|
|
|
|
// Fill remaining samples with silence
|
|
if (written < sampleCount)
|
|
{
|
|
for (let c = 0; c < channelCount; c++)
|
|
{
|
|
const channel = output[c];
|
|
|
|
for (let i = written; i < sampleCount; i++)
|
|
{
|
|
let value = 0;
|
|
channel[i] = value;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
registerProcessor("stream-processor", StreamProcessor); |