Add game specific overrides file (like vba-over.ini)
Former-commit-id: c5084bd191fcc91d9caa5f2c0f89a9803706d0b2 Former-commit-id: a80f747b6199679c74a25505a7893afe4b3b05e1
This commit is contained in:
parent
8e1ba1117c
commit
a99a1499fd
|
@ -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"] }
|
||||||
|
|
13
rustboyadvance-core/overrides.yaml
Normal file
13
rustboyadvance-core/overrides.yaml
Normal 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
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
58
rustboyadvance-core/src/overrides.rs
Normal file
58
rustboyadvance-core/src/overrides.rs
Normal 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)
|
||||||
|
}
|
Reference in a new issue