diff --git a/src/run-web.html b/src/run-web.html
index e88a403..088401f 100644
--- a/src/run-web.html
+++ b/src/run-web.html
@@ -1 +1 @@
-
uw8-run
\ No newline at end of file
+uw8-run
\ No newline at end of file
diff --git a/src/run_native.rs b/src/run_native.rs
index eb96463..342a4fd 100644
--- a/src/run_native.rs
+++ b/src/run_native.rs
@@ -91,6 +91,7 @@ impl MicroW8 {
struct Uw8Sound {
stream: cpal::Stream,
tx: mpsc::SyncSender<[u8; 32]>,
+ rx: mpsc::Receiver<[u8; 32]>,
}
impl super::Runtime for MicroW8 {
@@ -260,15 +261,27 @@ impl super::Runtime for MicroW8 {
};
let (tx, rx) = mpsc::sync_channel::<[u8; 32]>(1);
+ let (back_tx, back_rx) = mpsc::sync_channel::<[u8; 32]>(2);
+
+ let start_time = Instant::now();
let mut sample_index = 0;
let stream = {
device.build_output_stream(
&config,
move |buffer: &mut [f32], _| {
- if let Ok(regs) = rx.try_recv() {
+ if let Ok(mut regs) = rx.try_recv() {
memory.write(&mut store, 80, ®s).unwrap();
+ memory.read(&mut store, 0x12c80, &mut regs).unwrap();
+ back_tx.send(regs).unwrap();
}
+
+ {
+ let time = start_time.elapsed().as_millis() as i32;
+ let mem = memory.data_mut(&mut store);
+ mem[64..68].copy_from_slice(&time.to_le_bytes());
+ }
+
for v in buffer {
*v = snd.call(&mut store, (sample_index,)).unwrap_or(0.0);
sample_index = sample_index.wrapping_add(1);
@@ -280,7 +293,11 @@ impl super::Runtime for MicroW8 {
)?
};
- Uw8Sound { stream, tx }
+ Uw8Sound {
+ stream,
+ tx,
+ rx: back_rx,
+ }
};
sound.stream.play()?;
@@ -302,6 +319,13 @@ impl super::Runtime for MicroW8 {
fn run_frame(&mut self) -> Result<()> {
let mut result = Ok(());
if let Some(mut instance) = self.instance.take() {
+ while let Ok(regs) = instance.sound.rx.try_recv() {
+ instance
+ .memory
+ .write(&mut instance.store, 0x12c80, ®s)
+ .unwrap();
+ }
+
{
let time = instance.start_time.elapsed().as_millis() as i32;
let mut gamepad: u32 = 0;
diff --git a/web/src/audiolet.js b/web/src/audiolet.js
index 662fc76..6fb5fb0 100644
--- a/web/src/audiolet.js
+++ b/web/src/audiolet.js
@@ -5,7 +5,14 @@ class APU extends AudioWorkletProcessor {
this.sampleIndex = 0;
this.port.onmessage = (ev) => {
if(this.memory) {
- U8(this.memory.buffer, 80, 32).set(U8(ev.data));
+ if(isNaN(ev.data)) {
+ let data = U8(ev.data);
+ U8(this.memory.buffer, 80, 32).set(data);
+ data.set(U8(this.memory.buffer, 0x12c80, 32));
+ this.port.postMessage(ev.data);
+ } else {
+ this.startTime = ev.data;
+ }
} else {
this.load(ev.data[0], ev.data[1]);
}
@@ -51,7 +58,9 @@ class APU extends AudioWorkletProcessor {
}
process(inputs, outputs, parameters) {
- if(this.snd) {
+ if(this.snd && this.startTime) {
+ let u32Mem = new Uint32Array(this.memory.buffer);
+ u32Mem[16] = Date.now() - this.startTime;
let channels = outputs[0];
let index = this.sampleIndex;
let numSamples = channels[0].length;
diff --git a/web/src/microw8.js b/web/src/microw8.js
index 0c80e38..0e471eb 100644
--- a/web/src/microw8.js
+++ b/web/src/microw8.js
@@ -126,7 +126,6 @@ export default function MicroW8(screen, config = {}) {
audioReadyResolve = null;
}
};
- audioNode.port.onmessage = (e) => updateAudioReady(e.data);
let audioStateChange = () => {
if(audioContext.state == 'suspended') {
if(config.startButton) {
@@ -211,6 +210,14 @@ export default function MicroW8(screen, config = {}) {
data = loadModuleData(data);
let platform_data = await loadModuleURL(platformUrl);
+
+ audioNode.port.onmessage = (e) => {
+ if(isNaN(e.data)) {
+ U8(memory.buffer, 0x12c80, 32).set(U8(e.data));
+ } else {
+ updateAudioReady(e.data);
+ }
+ };
audioNode.port.postMessage([platform_data, data]);
let platform_instance = await instantiate(platform_data);
@@ -240,10 +247,12 @@ export default function MicroW8(screen, config = {}) {
isPaused = false;
audioContext.resume();
startTime += now - pauseTime;
+ audioNode.port.postMessage(startTime);
} else {
isPaused = true;
audioContext.suspend();
pauseTime = now;
+ audioNode.port.postMessage(0);
}
};
window.addEventListener('focus', () => updateVisibility(true), { signal: abortController.signal });