diff --git a/examples/web/index.html b/examples/web/index.html index c66238ada7f1a561e7c6a3809b98c21e99d4866c..50bfe5e4e636b25fbe0716db134ead0d907e7357 100644 --- a/examples/web/index.html +++ b/examples/web/index.html @@ -20,7 +20,7 @@ <img class="large" src="res/minimise.svg" alt="minimise" /> </span> <div class="canvas-frame"> - <canvas id="chip-canvas" class="canvas" width="640" height="320"></canvas> + <canvas id="chip-canvas" class="canvas" width="160" height="144"></canvas> </div> </div> </div> diff --git a/examples/web/index.ts b/examples/web/index.ts index 08dfbbb1e60909beef81875b736eb1e90507e590..c25f67d196587ac0e9fce3a74f2d96dc25a000aa 100644 --- a/examples/web/index.ts +++ b/examples/web/index.ts @@ -1,7 +1,6 @@ import { default as wasm, GameBoy } from "./lib/boytacean.js"; import info from "./package.json"; -const PIXEL_SET_COLOR = 0x50cb93ff; const PIXEL_UNSET_COLOR = 0x1b1a17ff; const LOGIC_HZ = 600; @@ -11,8 +10,8 @@ const IDLE_HZ = 10; const FREQUENCY_DELTA = 60; -const DISPLAY_WIDTH = 64; -const DISPLAY_HEIGHT = 32; +const DISPLAY_WIDTH = 160; +const DISPLAY_HEIGHT = 144; const DISPLAY_RATIO = DISPLAY_WIDTH / DISPLAY_HEIGHT; const SAMPLE_RATE = 2; @@ -207,10 +206,6 @@ const tick = (currentTime: number) => { // reached the flush of the "tick" logic is skiped if (currentTime < state.nextTickTime) return; - // initializes the flag that is going to control is a beep - // is going to be issued - let beepFlag = false; - // calculates the number of ticks that have elapsed since the // last draw operation, this is critical to be able to properly // operate the clock of the CPU in frame drop situations @@ -221,14 +216,19 @@ const tick = (currentTime: number) => { ); ticks = Math.max(ticks, 1); - const ratioLogic = (state.logicFrequency / state.visualFrequency) * ticks; - for (let i = 0; i < ratioLogic; i++) { - state.gameBoy.clock(); - } + let counterTicks = 0; - // in case the beep flag is active issue a sound during a bried - // period, to notify the user about a certain event - if (beepFlag) beep(); + while (true) { + // limits the number of ticks to the typical number + // of ticks required to do a complete PPU draw + if (counterTicks >= 70224) { + break; + } + + // runs the Game Boy clock, this operations should + // include the advance of both the CPU and the PPU + counterTicks += state.gameBoy.clock(); + } // updates the canvas object with the new // visual information coming in @@ -662,11 +662,15 @@ const initCanvas = async () => { }; const updateCanvas = (pixels: Uint8Array) => { - for (let i = 0; i < pixels.length; i++) { - state.videoBuff.setUint32( - i * 4, - pixels[i] ? PIXEL_SET_COLOR : PIXEL_UNSET_COLOR - ); //@todo must take into consideration that these are RGB pixels + let offset = 0; + for (let index = 0; index < pixels.length; index += 3) { + const color = + (pixels[index] << 24) | + (pixels[index + 1] << 16) | + (pixels[index + 2] << 8) | + 0xff; + state.videoBuff.setUint32(offset, color); + offset += 4; } state.canvasCtx.putImageData(state.image, 0, 0); state.canvasScaledCtx.drawImage(state.canvas, 0, 0); @@ -887,11 +891,6 @@ const fetchRom = async (romPath: string): Promise<[string, Uint8Array]> => { return [romName, romData]; }; -const beep = async () => { - sound.muted = false; - await sound.play(); -}; - (async () => { await main(); })(); diff --git a/src/gb.rs b/src/gb.rs index 37463bc649e5664c44a16d7f61056a58cae354a2..67bafdbc76e5dbede6fb053547e5898f090013ed 100644 --- a/src/gb.rs +++ b/src/gb.rs @@ -5,13 +5,26 @@ use crate::{ util::read_file, }; -/// Static data corresponding to the DMG boot ROM -/// allows freely using the emulator without external dependency. -pub const BOOT_DATA: [u8; 256] = [49, 254, 255, 175, 33, 255, 159, 50, 203, 124, 32, 251, 33, 38, 255, 14, 17, 62, 128, 50, 226, 12, 62, 243, 226, 50, 62, 119, 119, 62, 252, 224, 71, 17, 4, 1, 33, 16, 128, 26, 205, 149, 0, 205, 150, 0, 19, 123, 254, 52, 32, 243, 17, 216, 0, 6, 8, 26, 19, 34, 35, 5, 32, 249, 62, 25, 234, 16, 153, 33, 47, 153, 14, 12, 61, 40, 8, 50, 13, 32, 249, 46, 15, 24, 243, 103, 62, 100, 87, 224, 66, 62, 145, 224, 64, 4, 30, 2, 14, 12, 240, 68, 254, 144, 32, 250, 13, 32, 247, 29, 32, 242, 14, 19, 36, 124, 30, 131, 254, 98, 40, 6, 30, 193, 254, 100, 32, 6, 123, 226, 12, 62, 135, 226, 240, 66, 144, 224, 66, 21, 32, 210, 5, 32, 79, 22, 32, 24, 203, 79, 6, 4, 197, 203, 17, 23, 193, 203, 17, 23, 5, 32, 245, 34, 35, 34, 35, 201, 206, 237, 102, 102, 204, 13, 0, 11, 3, 115, 0, 131, 0, 12, 0, 13, 0, 8, 17, 31, 136, 137, 0, 14, 220, 204, 110, 230, 221, 221, 217, 153, 187, 187, 103, 99, 110, 14, 236, 204, 221, 220, 153, 159, 187, 185, 51, 62, 60, 66, 185, 165, 185, 165, 66, 60, 33, 4, 1, 17, 168, 0, 26, 19, 190, 32, 254, 35, 125, 254, 52, 32, 245, 6, 25, 120, 134, 35, 5, 32, 251, 134, 32, 254, 62, 1, 224, 80]; - #[cfg(feature = "wasm")] use wasm_bindgen::prelude::*; +/// Static data corresponding to the DMG boot ROM +/// allows freely using the emulator without external dependency. +pub const BOOT_DATA: [u8; 256] = [ + 49, 254, 255, 175, 33, 255, 159, 50, 203, 124, 32, 251, 33, 38, 255, 14, 17, 62, 128, 50, 226, + 12, 62, 243, 226, 50, 62, 119, 119, 62, 252, 224, 71, 17, 4, 1, 33, 16, 128, 26, 205, 149, 0, + 205, 150, 0, 19, 123, 254, 52, 32, 243, 17, 216, 0, 6, 8, 26, 19, 34, 35, 5, 32, 249, 62, 25, + 234, 16, 153, 33, 47, 153, 14, 12, 61, 40, 8, 50, 13, 32, 249, 46, 15, 24, 243, 103, 62, 100, + 87, 224, 66, 62, 145, 224, 64, 4, 30, 2, 14, 12, 240, 68, 254, 144, 32, 250, 13, 32, 247, 29, + 32, 242, 14, 19, 36, 124, 30, 131, 254, 98, 40, 6, 30, 193, 254, 100, 32, 6, 123, 226, 12, 62, + 135, 226, 240, 66, 144, 224, 66, 21, 32, 210, 5, 32, 79, 22, 32, 24, 203, 79, 6, 4, 197, 203, + 17, 23, 193, 203, 17, 23, 5, 32, 245, 34, 35, 34, 35, 201, 206, 237, 102, 102, 204, 13, 0, 11, + 3, 115, 0, 131, 0, 12, 0, 13, 0, 8, 17, 31, 136, 137, 0, 14, 220, 204, 110, 230, 221, 221, 217, + 153, 187, 187, 103, 99, 110, 14, 236, 204, 221, 220, 153, 159, 187, 185, 51, 62, 60, 66, 185, + 165, 185, 165, 66, 60, 33, 4, 1, 17, 168, 0, 26, 19, 190, 32, 254, 35, 125, 254, 52, 32, 245, + 6, 25, 120, 134, 35, 5, 32, 251, 134, 32, 254, 62, 1, 224, 80, +]; + #[cfg_attr(feature = "wasm", wasm_bindgen)] pub struct GameBoy { cpu: Cpu,