Finalize webiste for Jon
Some checks failed
Cargo Build & Test / Rust project - latest (stable) (push) Failing after 37s

This commit is contained in:
2026-04-09 08:26:31 -05:00
parent ce3b197d52
commit 9a1d5b04a4
2 changed files with 44 additions and 16 deletions

View File

@@ -11,7 +11,7 @@ use web_sys::{
AudioBuffer, AudioBufferOptions, AudioContext, AudioContextOptions, AudioContextState, AudioBuffer, AudioBufferOptions, AudioContext, AudioContextOptions, AudioContextState,
CanvasRenderingContext2d, HtmlButtonElement, HtmlCanvasElement, HtmlInputElement, ImageBitmap, CanvasRenderingContext2d, HtmlButtonElement, HtmlCanvasElement, HtmlInputElement, ImageBitmap,
ImageData, KeyboardEvent, ImageData, KeyboardEvent,
js_sys::{Function, Uint8Array}, js_sys::{Function, Reflect, Uint8Array},
wasm_bindgen::{Clamped, JsValue, UnwrapThrowExt, closure::Closure}, wasm_bindgen::{Clamped, JsValue, UnwrapThrowExt, closure::Closure},
window, window,
}; };
@@ -54,7 +54,7 @@ pub fn main() {
let _ = audio.suspend().expect_throw("Failed to suspend AudioCtx"); let _ = audio.suspend().expect_throw("Failed to suspend AudioCtx");
const BUFFER_SIZE: usize = 1 << 10; const BUFFER_SIZE: usize = 1 << 10;
const SAMPLE_RATE: f64 = 60. * 3723.; const SAMPLE_RATE: f64 = 60. * 3722.;
let audio_buffer_opts = AudioBufferOptions::new(BUFFER_SIZE as u32, SAMPLE_RATE as f32); let audio_buffer_opts = AudioBufferOptions::new(BUFFER_SIZE as u32, SAMPLE_RATE as f32);
audio_buffer_opts.set_number_of_channels(1); audio_buffer_opts.set_number_of_channels(1);
// let audio_buffer = // let audio_buffer =
@@ -70,21 +70,21 @@ pub fn main() {
.create_gain() .create_gain()
.expect_throw("Failed to create gain node"); .expect_throw("Failed to create gain node");
gain_node.set_channel_count(1); gain_node.set_channel_count(1);
gain_node.gain().set_value(0.01); gain_node.gain().set_value(0.1);
gain_node gain_node
.connect_with_audio_node_and_output(&audio.destination(), 0) .connect_with_audio_node_and_output(&audio.destination(), 0)
.expect_throw("Failed to connect to audio destination"); .expect_throw("Failed to connect to audio destination");
// gain_node // gain_node
// .connect_with_audio_node_and_output(&audio.destination(), 1) // .connect_with_audio_node_and_output(&audio.destination(), 1)
// .expect_throw("Failed to connect to audio destination 2"); // .expect_throw("Failed to connect to audio destination 2");
let delay_node = audio // let delay_node = audio
.create_delay() // .create_delay()
.expect_throw("Failed to create delay node"); // .expect_throw("Failed to create delay node");
delay_node.set_channel_count(1); // delay_node.set_channel_count(1);
delay_node.delay_time().set_value(0.); // delay_node.delay_time().set_value(0.);
delay_node // delay_node
.connect_with_audio_node(&gain_node) // .connect_with_audio_node(&gain_node)
.expect_throw("Failed to connect to audio destination"); // .expect_throw("Failed to connect to audio destination");
// source_node.start_with_when(when) // source_node.start_with_when(when)
let nes = Arc::new(Mutex::new({ let nes = Arc::new(Mutex::new({
@@ -139,6 +139,25 @@ pub fn main() {
.add_event_listener_with_callback("click", &Function::from(f.into_js_value())) .add_event_listener_with_callback("click", &Function::from(f.into_js_value()))
.expect_throw("Failed to setup pause callback"); .expect_throw("Failed to setup pause callback");
} }
doc.get_element_by_id("mute")
.unwrap()
.add_event_listener_with_callback(
"click",
&Function::from(
Closure::<dyn Fn()>::new(move || {
let win = window().expect_throw("Failed to get window");
let v = win.get("play_audio").is_none_or(|v| v.is_falsy());
Reflect::set(
&win,
&JsValue::from_str("play_audio"),
&JsValue::from_bool(!v),
)
.expect_throw("Failed to update audio mute");
})
.into_js_value(),
),
)
.expect_throw("Failed to setup pause callback");
{ {
let nes = nes.clone(); let nes = nes.clone();
let poisoned = poisoned.clone(); let poisoned = poisoned.clone();
@@ -204,7 +223,7 @@ pub fn main() {
let mut last_frame = audio.current_time(); let mut last_frame = audio.current_time();
let mut raw_audio_buffer = [0f32; BUFFER_SIZE]; let mut raw_audio_buffer = [0f32; BUFFER_SIZE];
let mut cur_pos = 0; let mut cur_pos = 0;
let mut cur_total = BUFFER_SIZE; // Start time in samples, set to buffer size... let mut cur_total = 3722 * 5; // Start time in samples, set to buffer size...
let period = Arc::new(Mutex::new(None as Option<Function>)); let period = Arc::new(Mutex::new(None as Option<Function>));
let period_cl = period.clone(); let period_cl = period.clone();
let periodic: Closure<dyn FnMut(JsValue)> = Closure::new(move |_v| { let periodic: Closure<dyn FnMut(JsValue)> = Closure::new(move |_v| {
@@ -235,14 +254,17 @@ pub fn main() {
} }
} }
// info!("New samples: {}", n.apu().get_frame_samples().len()); // info!("New samples: {}", n.apu().get_frame_samples().len());
for s in n.apu().get_frame_samples() { for s in
&n.apu().get_frame_samples()[..n.apu().get_frame_samples().len().min(3722)]
{
// raw_audio_buffer[cur_pos] = ((*s as f32) - 127.5) / 128.; // raw_audio_buffer[cur_pos] = ((*s as f32) - 127.5) / 128.;
raw_audio_buffer[cur_pos] = (*s as f32) / 256.; raw_audio_buffer[cur_pos] = (*s as f32) / 256.;
cur_pos += 1; cur_pos += 1;
if cur_pos == BUFFER_SIZE { if cur_pos == BUFFER_SIZE {
cur_pos = 0; cur_pos = 0;
cur_total += BUFFER_SIZE; cur_total += BUFFER_SIZE;
if win.get("play_audio").is_some_and(|v| v.is_truthy()) { if win.get("play_audio").is_none_or(|v| v.is_falsy()) {
// info!("{:?}", &raw_audio_buffer[..50]);
let audio_buffer = AudioBuffer::new(&audio_buffer_opts) let audio_buffer = AudioBuffer::new(&audio_buffer_opts)
.expect_throw("Failed to create audio buffer"); .expect_throw("Failed to create audio buffer");
audio_buffer audio_buffer
@@ -265,9 +287,14 @@ pub fn main() {
// "At {cur_total} samples, {:02.04}s ahead !loop", // "At {cur_total} samples, {:02.04}s ahead !loop",
// (cur_total as f64) / SAMPLE_RATE - audio.current_time() // (cur_total as f64) / SAMPLE_RATE - audio.current_time()
// ); // );
if (cur_total as f64) / SAMPLE_RATE - audio.current_time() < 0. {
info!("Bumping audio playback");
cur_total += BUFFER_SIZE;
} }
} }
} }
}
// info!("New samples: {}", n.apu().get_frame_samples().len());
n.apu_mut().reset_frame_samples(); // Discard audio samples n.apu_mut().reset_frame_samples(); // Discard audio samples
// info!("Completed Frame in {} cycles", count); // info!("Completed Frame in {} cycles", count);
let data = Clamped(n.ppu().render_buffer.raw_image()); let data = Clamped(n.ppu().render_buffer.raw_image());

View File

@@ -31,6 +31,7 @@
<p>Start: Q key</p> <p>Start: Q key</p>
<p>Select: W key</p> <p>Select: W key</p>
<button id="pause">Play</button> <button id="pause">Play</button>
<button id="mute">Mute</button>
</div> </div>
<div class="flex col"> <div class="flex col">
<h4>Load new ROM:</h4> <h4>Load new ROM:</h4>
@@ -46,8 +47,8 @@
<a href="https://gitea.loadingm.xyz/the10thwiz/nes-emu">Source is available for those interested.</a> <a href="https://gitea.loadingm.xyz/the10thwiz/nes-emu">Source is available for those interested.</a>
</p> </p>
<p> <p>
The APU isn't fully emulated yet, and many of the features implemented don't work properly yet. Audio The APU isn't fully emulated yet, and many of the features implemented don't work properly yet.
is disabled. <!-- Audio is disabled to protect your ears. -->
<!-- Run `window.play_audio = true;` in the dev console to enable audio --> <!-- Run `window.play_audio = true;` in the dev console to enable audio -->
</p> </p>
<p> <p>