Skip to content

Commit 93431c4

Browse files
authored
Merge pull request #13 from Rodrigodd/override-mbc
Add option for overriding MBC type
2 parents 1a17ea7 + 5bda6a1 commit 93431c4

File tree

12 files changed

+802
-206
lines changed

12 files changed

+802
-206
lines changed

Cargo.lock

Lines changed: 360 additions & 105 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

core/src/gameboy/cartridge.rs

Lines changed: 269 additions & 89 deletions
Large diffs are not rendered by default.

core/src/parser/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
use std::io::{Read, Seek, SeekFrom};
22

3+
mod size;
4+
5+
pub use size::{parse_number, parse_size};
6+
37
fn read_u32(file: &mut impl Read) -> Result<u32, std::io::Error> {
48
let mut value = [0; 4];
59
file.read_exact(&mut value)?;

core/src/parser/size.rs

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
use std::num::ParseIntError;
2+
3+
#[derive(Debug, PartialEq)]
4+
pub enum ParseSizeError {
5+
InvalidFormat,
6+
InvalidSuffix,
7+
NumberTooLarge,
8+
ParseError(ParseIntError),
9+
}
10+
11+
pub fn parse_number(input: &str) -> Result<u64, ParseIntError> {
12+
if let Some(stripped) = input.strip_prefix("0x") {
13+
u64::from_str_radix(stripped, 16)
14+
} else {
15+
input.parse()
16+
}
17+
}
18+
19+
pub fn parse_size(input: &str) -> Result<u64, ParseSizeError> {
20+
if input.is_empty() {
21+
return Err(ParseSizeError::InvalidFormat);
22+
}
23+
24+
let (num_part, suffix) = input.trim().split_at(
25+
input
26+
.find(|c: char| !c.is_ascii_digit() && c != 'x')
27+
.unwrap_or(input.len()),
28+
);
29+
30+
let num = parse_number(num_part).map_err(ParseSizeError::ParseError)?;
31+
32+
let multiplier = match suffix.trim() {
33+
"B" => 1,
34+
"kB" => 1_024,
35+
"MB" => 1_024 * 1_024,
36+
"GB" => 1_024 * 1_024 * 1_024,
37+
"" => return Err(ParseSizeError::InvalidFormat),
38+
_ => return Err(ParseSizeError::InvalidSuffix),
39+
};
40+
41+
let result = num
42+
.checked_mul(multiplier as u64)
43+
.ok_or(ParseSizeError::NumberTooLarge)?;
44+
45+
if result > u32::MAX as u64 {
46+
return Err(ParseSizeError::NumberTooLarge);
47+
}
48+
49+
Ok(result)
50+
}
51+
52+
#[cfg(test)]
53+
mod tests {
54+
use super::*;
55+
56+
#[test]
57+
fn test_parse_number_decimal() {
58+
assert_eq!(parse_number("123"), Ok(123));
59+
assert_eq!(parse_number("0"), Ok(0));
60+
}
61+
62+
#[test]
63+
fn test_parse_number_hexadecimal() {
64+
assert_eq!(parse_number("0x10"), Ok(16));
65+
assert_eq!(parse_number("0x1F4"), Ok(500));
66+
}
67+
68+
#[test]
69+
fn test_parse_number_invalid() {
70+
assert!(parse_number("not_a_number").is_err());
71+
assert!(parse_number("0xZZZ").is_err());
72+
}
73+
74+
#[test]
75+
fn test_parse_size_with_hexadecimal() {
76+
assert_eq!(parse_size("0x100B"), Ok(256));
77+
assert_eq!(parse_size("0x1kB"), Ok(1_024));
78+
assert_eq!(parse_size("0x2MB"), Ok(2 * 1_024 * 1_024));
79+
}
80+
81+
#[test]
82+
fn test_valid_sizes() {
83+
assert_eq!(parse_size("0B"), Ok(0));
84+
assert_eq!(parse_size("256B"), Ok(256));
85+
assert_eq!(parse_size("1kB"), Ok(1_024));
86+
assert_eq!(parse_size("2MB"), Ok(2 * 1_024 * 1_024));
87+
assert_eq!(parse_size("1GB"), Ok(1_024 * 1_024 * 1_024));
88+
}
89+
90+
#[test]
91+
fn test_invalid_formats() {
92+
assert_eq!(parse_size(""), Err(ParseSizeError::InvalidFormat));
93+
assert_eq!(parse_size("256"), Err(ParseSizeError::InvalidFormat));
94+
assert_eq!(parse_size("256MBExtra"), Err(ParseSizeError::InvalidSuffix));
95+
}
96+
97+
#[test]
98+
fn test_invalid_suffix() {
99+
assert_eq!(parse_size("256mB"), Err(ParseSizeError::InvalidSuffix));
100+
assert_eq!(parse_size("256TB"), Err(ParseSizeError::InvalidSuffix));
101+
}
102+
103+
#[test]
104+
fn test_parse_errors() {
105+
assert!(matches!(
106+
parse_size("not_a_numberMB"),
107+
Err(ParseSizeError::ParseError(_))
108+
));
109+
assert!(matches!(
110+
parse_size("0xnot_hexB"),
111+
Err(ParseSizeError::ParseError(_))
112+
));
113+
}
114+
}

core/tests/check_interrupt_prediction.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ fn test_interrupt_prediction(rom: &str, timeout: u64) -> bool {
100100
let rom = std::fs::read(rom_path).unwrap();
101101
let cartridge = match Cartridge::new(rom) {
102102
Ok(x) => x,
103-
Err(x) => {
103+
Err((x, _)) => {
104104
eprintln!("Error reading rom: {}", x);
105105
return true;
106106
}

jit/tests/check_jit_compilation.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ fn test_interrupt_prediction(rom: &str, timeout: u64) -> bool {
162162
};
163163
let cartridge = match Cartridge::new(rom) {
164164
Ok(x) => x,
165-
Err(x) => {
165+
Err((x, _)) => {
166166
eprintln!("Error reading rom: {}", x);
167167
return true;
168168
}

libretro/src/lib.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -174,12 +174,16 @@ extern "C" fn retro_load_game(info: Option<&retro_game_info>) -> bool {
174174
log::info!("retro load game");
175175

176176
// load rom data into core
177-
let Some(info) = info else { return false } ;
177+
let Some(info) = info else { return false };
178178

179179
let data = unsafe { std::slice::from_raw_parts(info.data as *const u8, info.size as usize) };
180180
let cartridge = match Cartridge::new(data.to_vec()) {
181-
Ok(x) => x,
182-
Err(err) => {
181+
Ok(rom) => rom,
182+
Err((err, Some(rom))) => {
183+
log::warn!("Warnings when loading rom: {}", err);
184+
rom
185+
}
186+
Err((err, None)) => {
183187
log::error!("Error loading rom: {}", err);
184188
return false;
185189
}
@@ -371,7 +375,10 @@ impl log::Log for RetroLogger {
371375
let Ok(mut file) = std::fs::OpenOptions::new()
372376
.create(true)
373377
.append(true)
374-
.open(path) else { return };
378+
.open(path)
379+
else {
380+
return;
381+
};
375382

376383
let _ = writeln!(
377384
&mut file,

license/about-android.toml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
ignore-dev-dependencies = true
22
ignore-build-dependencies = true
3-
accepted = ["Apache-2.0", "MIT", "Unicode-DFS-2016", "ISC", "BSD-3-Clause"]
3+
accepted = [
4+
"Apache-2.0",
5+
"MIT",
6+
"Unicode-DFS-2016",
7+
"Unicode-3.0",
8+
"ISC",
9+
"BSD-3-Clause",
10+
]
411

512
targets = ["aarch64-linux-android"]

license/about-linux.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ accepted = [
44
"Apache-2.0",
55
"MIT",
66
"Unicode-DFS-2016",
7+
"Unicode-3.0",
78
"BSD-2-Clause",
89
"BSD-3-Clause",
910
"ISC",

license/about-windows.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ accepted = [
44
"Apache-2.0",
55
"MIT",
66
"Unicode-DFS-2016",
7+
"Unicode-3.0",
78
"ISC",
89
"BSD-3-Clause",
910
"BSL-1.0",

0 commit comments

Comments
 (0)