Skip to content
Snippets Groups Projects
Verified Commit d6cf2aba authored by João Magalhães's avatar João Magalhães :rocket:
Browse files

chore: better genie code structure

parent 6cdbe262
No related branches found
No related tags found
1 merge request!25Game Genie support
Pipeline #2868 passed
...@@ -970,9 +970,8 @@ impl GameBoy { ...@@ -970,9 +970,8 @@ impl GameBoy {
pub fn load_rom(&mut self, data: &[u8]) -> &Cartridge { pub fn load_rom(&mut self, data: &[u8]) -> &Cartridge {
let mut rom = Cartridge::from_data(data); let mut rom = Cartridge::from_data(data);
//rom.add_genie_code("00A-17B-C49").unwrap(); // SML rom.add_genie_code("00A-17B-C49").unwrap(); // SML
//rom.add_genie_code("008-60A-E6E").unwrap(); // SML rom.add_genie_code("008-60A-E6E").unwrap(); // SML
rom.add_genie_code("001-40C-E6E").unwrap();
self.mmu().set_rom(rom); self.mmu().set_rom(rom);
self.mmu().rom() self.mmu().rom()
} }
......
...@@ -211,7 +211,7 @@ impl Display for ObjectData { ...@@ -211,7 +211,7 @@ impl Display for ObjectData {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!( write!(
f, f,
"Index => {}\nX => {}\nY => {}\nTile => {}", "Index: {}, X: {}, Y: {}, Tile: {}",
self.index, self.x, self.y, self.tile self.index, self.x, self.y, self.tile
) )
} }
...@@ -249,7 +249,7 @@ impl Display for TileData { ...@@ -249,7 +249,7 @@ impl Display for TileData {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!( write!(
f, f,
"Palette => {}\nVRAM Bank => {}\nX Flip => {}\nY Flip => {}", "Palette: {}, VRAM Bank: {}, X Flip: {}, Y Flip: {}",
self.palette, self.vram_bank, self.xflip, self.yflip self.palette, self.vram_bank, self.xflip, self.yflip
) )
} }
......
...@@ -218,6 +218,10 @@ pub struct GameGenieCode { ...@@ -218,6 +218,10 @@ pub struct GameGenieCode {
} }
impl GameGenieCode { impl GameGenieCode {
pub fn short_description(&self) -> String {
self.code.to_string()
}
pub fn description(&self) -> String { pub fn description(&self) -> String {
format!( format!(
"Code: {}, Address: 0x{:04x}, New Data: 0x{:04x}, Old Data: 0x{:04x}", "Code: {}, Address: 0x{:04x}, New Data: 0x{:04x}, Old Data: 0x{:04x}",
...@@ -228,7 +232,7 @@ impl GameGenieCode { ...@@ -228,7 +232,7 @@ impl GameGenieCode {
impl Display for GameGenieCode { impl Display for GameGenieCode {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.description()) write!(f, "{}", self.short_description())
} }
} }
...@@ -315,8 +319,15 @@ impl Cartridge { ...@@ -315,8 +319,15 @@ impl Cartridge {
pub fn read(&self, addr: u16) -> u8 { pub fn read(&self, addr: u16) -> u8 {
if self.genie_codes.contains_key(&addr) { if self.genie_codes.contains_key(&addr) {
let genie_code = self.genie_codes.get(&addr).unwrap(); let genie_code = self.genie_codes.get(&addr).unwrap();
debugln!("Applying Game Genie code: {}", game_genie_code);
return genie_code.new_data; // checks if the current data at the address is the same as the
// one that is expected by the Game Genie code, if that's the case
// applies the patch, otherwise returns the original strategy is
// going to be used
if genie_code.old_data == (self.mbc.read_rom)(self, addr) {
debugln!("Applying Game Genie code: {}", game_genie_code);
return genie_code.new_data;
}
} }
match addr & 0xf000 { match addr & 0xf000 {
...@@ -432,24 +443,28 @@ impl Cartridge { ...@@ -432,24 +443,28 @@ impl Cartridge {
return Err("Invalid Game Genie code length"); return Err("Invalid Game Genie code length");
} }
let new_data_slice = &code[0..=1]; let code_u = code.to_uppercase();
let new_data_slice = &code_u[0..=1];
let new_data = u8::from_str_radix(new_data_slice, 16).unwrap(); let new_data = u8::from_str_radix(new_data_slice, 16).unwrap();
let old_data_slice = format!("{}{}", &code[8..=8], &code[10..=10]); let old_data_slice = format!("{}{}", &code_u[8..=8], &code_u[10..=10]);
let old_data: u8 = (u8::from_str_radix(old_data_slice.as_str(), 16).unwrap() ^ 0xba) << 2; let old_data: u8 = u8::from_str_radix(old_data_slice.as_str(), 16)
.unwrap()
.rotate_right(2)
^ 0xba;
let address_slice = format!("{}{}{}", &code[6..=6], &code[2..=2], &code[4..=5]); let address_slice = format!("{}{}{}", &code_u[6..=6], &code_u[2..=2], &code_u[4..=5]);
let address = u16::from_str_radix(address_slice.as_str(), 16).unwrap() ^ 0xf000; let address = u16::from_str_radix(address_slice.as_str(), 16).unwrap() ^ 0xf000;
let game_genie_code = GameGenieCode { let genie_code = GameGenieCode {
code: String::from(code), code: code_u,
address, address,
new_data, new_data,
old_data, old_data,
}; };
self.genie_codes.insert(address, game_genie_code); self.genie_codes.insert(address, genie_code);
Ok(self.genie_codes.get(&address).unwrap()) Ok(self.genie_codes.get(&address).unwrap())
} }
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment