diff --git a/js/waveform.js b/js/waveform.js index 6911c7f..0f6514d 100644 --- a/js/waveform.js +++ b/js/waveform.js @@ -31,8 +31,8 @@ export function recordSample() { if (!changed && state.timeStep > 0) return; - // Each tick = 1 step (visual width determined by waveZoom px/step) - state.timeStep += 1; + // Manual toggles advance by simSpeed too for consistency + state.timeStep += state.simSpeed; gates.forEach(g => { if (!waveData[g.id]) waveData[g.id] = []; const arr = waveData[g.id]; @@ -44,8 +44,8 @@ export function recordSample() { } export function forceRecordSample() { - // Each tick = 1 step - state.timeStep += 1; + // Advance time by the current simSpeed (in ms) to reflect real time + state.timeStep += state.simSpeed; state.gates.forEach(g => { if (!state.waveData[g.id]) state.waveData[g.id] = []; state.waveData[g.id].push({ t: state.timeStep, value: g.value }); @@ -73,7 +73,10 @@ export function setEvaluateAll(fn) { export function updateWaveInfo() { const totalSamples = Object.values(state.waveData).reduce((sum, arr) => sum + arr.length, 0); - document.getElementById('wave-info').textContent = `T=${state.timeStep} | ${totalSamples} samples`; + const timeLabel = state.timeStep >= 1000 + ? `${(state.timeStep/1000).toFixed(1)}s` + : `${state.timeStep}ms`; + document.getElementById('wave-info').textContent = `T=${timeLabel} | ${totalSamples} samples`; } export function clearWaveData() { @@ -123,33 +126,32 @@ export function drawWaveforms() { return; } - // pxPerStep: how many pixels per simulation step - const pxPerStep = state.waveZoom; + // pxPerMs: how many pixels per millisecond of simulation time + const pxPerMs = state.waveZoom / 100; // waveZoom=20 → 0.2 px/ms // Total width in pixels for all recorded time - const totalPx = state.timeStep * pxPerStep; + const totalPx = state.timeStep * pxPerMs; - // Visible width in steps - const visibleSteps = wc.width / pxPerStep; + // Visible width in ms + const visibleMs = wc.width / pxPerMs; // Auto-scroll: always follow the latest data, keep cursor at right edge - state.waveScroll = Math.max(0, state.timeStep - visibleSteps); + state.waveScroll = Math.max(0, state.timeStep - visibleMs); - // Helper: convert simulation step to pixel X - const tToX = (t) => (t - state.waveScroll) * pxPerStep; + // Helper: convert simulation time (ms) to pixel X + const tToX = (t) => (t - state.waveScroll) * pxPerMs; - // Draw time grid (every gridStep steps) - let gridStep = 5; - if (pxPerStep * gridStep < 30) gridStep = 10; - if (pxPerStep * gridStep < 30) gridStep = 20; - if (pxPerStep * gridStep < 30) gridStep = 50; - if (pxPerStep * gridStep > 200) gridStep = 2; - if (pxPerStep * gridStep > 200) gridStep = 1; + // Draw time grid (every gridMs milliseconds) + let gridMs = 500; + if (pxPerMs * gridMs < 30) gridMs = 1000; + if (pxPerMs * gridMs < 30) gridMs = 2000; + if (pxPerMs * gridMs > 200) gridMs = 200; + if (pxPerMs * gridMs > 200) gridMs = 100; wctx.strokeStyle = '#151520'; wctx.lineWidth = 1; - const startT = Math.floor(state.waveScroll / gridStep) * gridStep; - for (let t = startT; t <= state.timeStep; t += gridStep) { + const startT = Math.floor(state.waveScroll / gridMs) * gridMs; + for (let t = startT; t <= state.timeStep; t += gridMs) { const x = tToX(t); if (x < 0 || x > wc.width) continue; wctx.beginPath(); @@ -160,7 +162,8 @@ export function drawWaveforms() { wctx.fillStyle = '#333'; wctx.font = '9px monospace'; wctx.textAlign = 'center'; - wctx.fillText(`${t}`, x, 10); + const label = t >= 1000 ? `${(t/1000).toFixed(1)}s` : `${t}ms`; + wctx.fillText(label, x, 10); } // Row dividers