Add game specific overrides file (like vba-over.ini)

Former-commit-id: c5084bd191fcc91d9caa5f2c0f89a9803706d0b2
Former-commit-id: a80f747b6199679c74a25505a7893afe4b3b05e1
This commit is contained in:
Michel Heily 2020-05-21 01:01:23 +03:00 committed by MishMish
parent 8e1ba1117c
commit a99a1499fd
5 changed files with 112 additions and 5 deletions

View file

@ -38,6 +38,8 @@ ringbuf = "0.2.1"
goblin = { version = "0.2", optional = true } goblin = { version = "0.2", optional = true }
fuzzy-matcher = { version = "0.3.4", optional = true } fuzzy-matcher = { version = "0.3.4", optional = true }
bit_reverse = "0.1.8" bit_reverse = "0.1.8"
yaml-rust = "0.4"
lazy_static = "1.4.0"
[target.'cfg(target_arch="wasm32")'.dependencies] [target.'cfg(target_arch="wasm32")'.dependencies]
instant = { version = "0.1.2", features = ["wasm-bindgen"] } instant = { version = "0.1.2", features = ["wasm-bindgen"] }

View file

@ -0,0 +1,13 @@
# Game specific overrides
# TODO - complete the list
- code: ALFP
name: Dragon Ball Z - The Legacy of Goku II (Europe)(En,Fr,De,Es,It)
save_type: eeprom
- code: AZJE
name: Dragon Ball Z - Supersonic Warriors (USA)
- code: BPEE
name: Pokemon - Emerald Version (USA, Europe)
rtc: true

View file

@ -3,6 +3,7 @@ use std::path::{Path, PathBuf};
use memmem::{Searcher, TwoWaySearcher}; use memmem::{Searcher, TwoWaySearcher};
use num::FromPrimitive; use num::FromPrimitive;
use super::super::overrides;
use super::super::{GBAError, GBAResult}; use super::super::{GBAError, GBAResult};
use super::backup::eeprom::*; use super::backup::eeprom::*;
use super::backup::flash::*; use super::backup::flash::*;
@ -131,24 +132,53 @@ impl GamepakBuilder {
} }
} }
if self.save_type == BackupType::AutoDetect { let mut save_type = self.save_type;
let mut gpio_device = self.gpio_device;
if let Some(overrides) = overrides::get_game_overrides(&header.game_code) {
info!("Found game overrides for {}: {:#?}", header.game_code, overrides);
if let Some(override_save_type) = overrides.save_type() {
if override_save_type != save_type && save_type != BackupType::AutoDetect {
warn!(
"Forced save type {:?} takes priority of {:?}",
save_type, override_save_type
);
}
save_type = override_save_type;
}
if overrides.force_rtc() {
match gpio_device {
GpioDeviceType::None => gpio_device = GpioDeviceType::Rtc,
GpioDeviceType::Rtc => {},
_ => {
warn!(
"Can't use RTC due to forced gpio device type {:?}",
gpio_device
);
}
}
}
}
if save_type == BackupType::AutoDetect {
if let Some(detected) = detect_backup_type(&bytes) { if let Some(detected) = detect_backup_type(&bytes) {
info!("Detected Backup: {:?}", detected); info!("Detected Backup: {:?}", detected);
self.save_type = detected; save_type = detected;
} else { } else {
warn!("could not detect backup save type"); warn!("could not detect backup save type");
} }
} }
let backup = create_backup(self.save_type, self.save_path); let backup = create_backup(save_type, self.save_path);
let gpio = match self.gpio_device { let gpio = match gpio_device {
GpioDeviceType::None => Gpio::new_none(), GpioDeviceType::None => Gpio::new_none(),
GpioDeviceType::Rtc => { GpioDeviceType::Rtc => {
info!("Emulating RTC!"); info!("Emulating RTC!");
Gpio::new_rtc() Gpio::new_rtc()
} }
_ => unimplemented!("Gpio device {:?} not implemented", self.gpio_device), _ => unimplemented!("Gpio device {:?} not implemented", gpio_device),
}; };
let size = bytes.len(); let size = bytes.len();

View file

@ -1,6 +1,9 @@
#[macro_use] #[macro_use]
extern crate serde; extern crate serde;
#[macro_use]
extern crate lazy_static;
#[macro_use] #[macro_use]
extern crate debug_stub_derive; extern crate debug_stub_derive;
@ -48,6 +51,7 @@ pub mod dma;
pub mod keypad; pub mod keypad;
pub mod timer; pub mod timer;
pub use bus::*; pub use bus::*;
pub(crate) mod overrides;
#[cfg(feature = "gdb")] #[cfg(feature = "gdb")]
pub mod gdb; pub mod gdb;

View file

@ -0,0 +1,58 @@
use std::collections::HashMap;
use std::convert::TryFrom;
use yaml_rust::YamlLoader;
use super::cartridge::BackupType;
#[derive(Debug)]
pub struct GameOverride {
force_rtc: bool,
save_type: Option<BackupType>,
}
impl GameOverride {
pub fn force_rtc(&self) -> bool {
self.force_rtc
}
pub fn save_type(&self) -> Option<BackupType> {
self.save_type
}
}
lazy_static! {
static ref GAME_OVERRIDES: HashMap<String, GameOverride> = {
let mut m = HashMap::new();
let docs = YamlLoader::load_from_str(include_str!("../overrides.yaml"))
.expect("failed to load overrides file");
let doc = &docs[0];
let games = doc.as_vec().unwrap();
for game in games {
let game_code = String::from(game["code"].as_str().unwrap());
let force_rtc = game["rtc"].as_bool().unwrap_or(false);
let save_type = if let Some(save_type) = game["save_type"].as_str() {
match BackupType::try_from(save_type) {
Ok(x) => Some(x),
_ => panic!("{}: invalid save type {:#}", game_code, save_type),
}
} else {
None
};
let game_overrride = GameOverride {
force_rtc,
save_type,
};
m.insert(game_code, game_overrride);
}
m
};
}
pub fn get_game_overrides(game_code: &str) -> Option<&GameOverride> {
GAME_OVERRIDES.get(game_code)
}