diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b21ddc4562aecc70fd031e3cf998f49542bcea3..fc4e4e9413917f44ce4203828cbca155191fb7c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * Support for true fullscreen at a browser level * Support for more flexible palette colors +* Support for setting palette colors using WASM ### Changed diff --git a/examples/web/index.ts b/examples/web/index.ts index 79836e4eb1f567ce98df45c3af2c3fed82c64ded..ebc456c915ce6f14c756e05eeebdc923d19ce3d0 100644 --- a/examples/web/index.ts +++ b/examples/web/index.ts @@ -286,6 +286,14 @@ class GameboyEmulator extends EmulatorBase implements Emulator { break; } + //Â @todo replace this with somethign more flexible + this.gameBoy.set_palette_colors_ws([ + "b6a571", + "8b7e56", + "554d35", + "201d13" + ]); + // resets the Game Boy engine to restore it into // a valid state ready to be used this.gameBoy.reset(); diff --git a/src/gb.rs b/src/gb.rs index 77691658d0104aba62197896f07a597d25bb05ac..27623252de1cb06440c94b0d0de9ff107a9e85df 100644 --- a/src/gb.rs +++ b/src/gb.rs @@ -10,6 +10,8 @@ use crate::{ }; #[cfg(feature = "wasm")] +use crate::ppu::Palette; +use std::convert::TryInto; use wasm_bindgen::prelude::*; #[cfg(feature = "wasm")] @@ -244,9 +246,34 @@ impl GameBoy { prev(info); })); } + pub fn load_rom_ws(&mut self, data: &[u8]) -> Cartridge { self.load_rom(data).clone() } + + pub fn set_palette_colors_ws(&mut self, value: Vec<JsValue>) { + let palette: Palette = value + .into_iter() + .map(|v| self.convert_value(&v)) + .collect::<Vec<[u8; 3]>>() + .try_into() + .unwrap(); + self.ppu().set_palette_colors(&palette); + } + + fn convert_value(&self, value: &JsValue) -> [u8; 3] { + value + .as_string() + .unwrap() + .chars() + .collect::<Vec<char>>() + .chunks(2) + .map(|s| s.iter().collect::<String>()) + .map(|s| u8::from_str_radix(&s, 16).unwrap()) + .collect::<Vec<u8>>() + .try_into() + .unwrap() + } } #[cfg(feature = "wasm")] diff --git a/src/ppu.rs b/src/ppu.rs index f74fd1aa60db000003f3b3222e3c74300a01827a..c871a4521f72d727a9bfb0d218da69be6deb2ca6 100644 --- a/src/ppu.rs +++ b/src/ppu.rs @@ -178,8 +178,8 @@ pub struct Ppu { /// The base colors that are going to be used in the registration /// of the concrete palettes, this value basically controls the /// colors that are going to be shown for each of the four base - /// values - 0x00, 0x01, 0x02, and 0x03 - pallette_colors: Palette, + /// values - 0x00, 0x01, 0x02, and 0x03. + palette_colors: Palette, /// The palette of colors that is currently loaded in Game Boy /// and used for background (tiles). @@ -308,7 +308,7 @@ impl Ppu { priority: false, index: 0, }; OBJ_COUNT], - pallette_colors: PALETTE_COLORS, + palette_colors: PALETTE_COLORS, palette: [[0u8; RGB_SIZE]; PALETTE_SIZE], palette_obj_0: [[0u8; RGB_SIZE]; PALETTE_SIZE], palette_obj_1: [[0u8; RGB_SIZE]; PALETTE_SIZE], @@ -518,7 +518,7 @@ impl Ppu { for index in 0..PALETTE_SIZE { let color_index: usize = (value as usize >> (index * 2)) & 3; match color_index { - 0..=3 => self.palette[index] = self.pallette_colors[color_index], + 0..=3 => self.palette[index] = self.palette_colors[color_index], color_index => panic!("Invalid palette color index {:04x}", color_index), } } @@ -528,7 +528,7 @@ impl Ppu { for index in 0..PALETTE_SIZE { let color_index: usize = (value as usize >> (index * 2)) & 3; match color_index { - 0..=3 => self.palette_obj_0[index] = self.pallette_colors[color_index], + 0..=3 => self.palette_obj_0[index] = self.palette_colors[color_index], color_index => panic!("Invalid palette color index {:04x}", color_index), } } @@ -538,7 +538,7 @@ impl Ppu { for index in 0..PALETTE_SIZE { let color_index: usize = (value as usize >> (index * 2)) & 3; match color_index { - 0..=3 => self.palette_obj_1[index] = self.pallette_colors[color_index], + 0..=3 => self.palette_obj_1[index] = self.palette_colors[color_index], color_index => panic!("Invalid palette color index {:04x}", color_index), } } @@ -565,6 +565,10 @@ impl Ppu { &self.tiles } + pub fn set_palette_colors(&mut self, value: &Palette) { + self.palette_colors = *value; + } + pub fn palette(&self) -> Palette { self.palette }