SearchA-ZW › WASM-4

WASM-4

2021 Open source · ISC Online & downloadable

WASM-4 is a low-level fantasy console by Bruno Garcia where games are built as WebAssembly modules within tight memory and display limits. Cartridges can be written in any language that targets WebAssembly and run in the browser runtime or the native player.

Visit the official site ↗

Runs on: Web browser, Windows, macOS, Linux

WASM-4 Online Emulator

Play WASM-4 using JavaScript directly in your browser.

Configurations

ConfigurationEmulatorMachineOSLegal
Sound DemoWASM-4WASM-4openOpen ⛶
WatrisWASM-4WASM-4openOpen ⛶

Machines emulated

Chips

Notes

Sound

Sound uses Pattern V-native: the vendored WASM-4 runtime already emulates the console’s APU in JavaScript and plays it through its own AudioContext, so we drive that pipeline directly rather than rerouting through the shared EmuAudio sink.

The APU is the runtime’s class Kt (reachable at app.runtime.apu). It owns one AudioContext at 44100 Hz and renders the four voices — two pulse, one triangle, one noise — inside an AudioWorkletNode named wasm4-apu (with a ScriptProcessor fallback). The cart’s tone() calls post note events to the worklet, which synthesises the ADSR-shaped waveforms and writes interleaved stereo. That worklet used to connect straight to audioCtx.destination.

Mute gate. The runtime auto-resumes its AudioContext on any keydown or pointerup (via runtime.unlockAudio()), so suspending the context alone cannot hold it silent while a game is being driven. We splice a master GainNode (apu.masterGain, created in apu._ensureGain()) between the worklet/ScriptProcessor output and the destination. apu.setMute(m) sets that gain to 0 or 1 and suspends/resumes the context, and unlockAudio() is gated to no-op while muted. The APU boots with _muted = true and gain = 0, so nothing is audible until a gesture.

Contract. window.EMU_BOOT.transport.isMuted() / setMute(bool) delegate to apu.setMute(). It starts muted; the on-page Sound button unmutes it from a real click, which resumes the context and opens the gain.

Default and mute. The default cartridge is Watris, a real game. Sound is fully supported and plays when the cart drives the APU; the page starts muted, so click Sound to hear it. A tiny self-authored Sound Demo cartridge config is also available (sound-demo.wasm, a 150-byte hand-assembled WASM-4 module): it imports env.tone and, on every frame in its exported update(), draws a moving block and every twelfth frame calls tone() to play a repeating eight-note melody on the pulse channel.