OpenCDi browser adaptation, upstream https://github.com/sigsantilio/opencdi c9886fb. MIT and dependency notices included. No game or proprietary firmware in the source archive. Rust 1.99.1; target wasm32-unknown-emscripten; Emscripten 4.0.20. From the source directory, after sourcing emsdk_env.sh: cargo build --offline --lib --release --target wasm32-unknown-emscripten -j2 em++ target/wasm32-unknown-emscripten/release/libopencdi_b2og.a -o core.js -O2 --no-entry -sMODULARIZE=1 -sEXPORT_NAME=OpenCdi -sENVIRONMENT=worker -sFORCE_FILESYSTEM=1 -sALLOW_MEMORY_GROWTH=1 -sINITIAL_MEMORY=134217728 -sMAXIMUM_MEMORY=1073741824 -sSTACK_SIZE=8388608 -sEXPORTED_RUNTIME_METHODS='["ccall","FS","HEAPU8","HEAPU32","HEAP16"]' -sEXPORTED_FUNCTIONS='["_b2og_pointer_x","_b2og_pointer_y","_b2og_pointer_warp","_b2og_load","_b2og_frame","_b2og_picture","_b2og_frames","_b2og_pc","_b2og_mouse","_b2og_close","_b2og_audio","_b2og_samples","_b2og_nvram","_b2og_launched","_malloc","_free"]' The worker reads CHD in bounded lazy ranges, PAL video, stereo PCM, pointer/controller input, and per-game NVRAM. The player automatically loads owner-supplied firmware from a separate package. Full save states are not supported. No firmware selector is required. Pointer recenter commands from the CD-i are synchronized back to keyboard/gamepad coordinates.