Skip to content

Commit 08f9542

Browse files
committed
add support for mame 0.243
1 parent 833235c commit 08f9542

3 files changed

Lines changed: 113 additions & 53 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Capturing data from bsnes works well, mame is getting there.
55

66
## Currently supported emulators:
77
bsnes v115
8-
mame 0.242
8+
mame 0.242 - 0.243
99

1010
## Currently supported games:
1111
Gradius III (snes / arcade)

src/game_data.rs

Lines changed: 51 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,57 @@ pub enum Emulator
55
Mame,
66
}
77

8+
impl Emulator
9+
{
10+
pub fn get_mame_version(module_size: u32) -> u16
11+
{
12+
match module_size
13+
{
14+
0x129FB000 => 242,
15+
0x12A82000 => 243,
16+
_ => 0, //unsupported version
17+
}
18+
}
19+
20+
pub fn get_mame_name_offset(version: u16) -> u32
21+
{
22+
match version
23+
{
24+
242 => 0x11EC4450,
25+
243 => 0x11F3C970,
26+
_ => todo!("unsupported mame version"),
27+
}
28+
}
29+
30+
pub fn mame_game_offset(version: u16, games: Games) -> Vec<u64>
31+
{
32+
match version
33+
{
34+
242 =>
35+
{
36+
match games
37+
{
38+
Games::GhoulsArcade => vec![0x11B72B48, 0x08, 0x10, 0x28, 0x38, 0x60, 0x18, 0x80, 0x18],
39+
Games::Gradius3Arcade => vec![0x11B72B48, 0x38, 0x150, 0x8, 0x10],
40+
_ => unreachable!(),
41+
}
42+
}
43+
44+
243 =>
45+
{
46+
match games
47+
{
48+
Games::GhoulsArcade => vec![0x11BF4390, 0x8, 0x10, 0x38, 0x40, 0x80, 0x18, 0x80, 0x18],
49+
Games::Gradius3Arcade => vec![0x11BF4390, 0x28, 0x150, 0x8, 0x10],
50+
_ => unreachable!(),
51+
}
52+
}
53+
54+
_ => todo!("unsupported mame version"),
55+
}
56+
}
57+
}
58+
859
pub struct GameData
960
{
1061
pub id: Games,
@@ -52,16 +103,6 @@ impl Games
52103
}
53104
}
54105

55-
pub fn mame_game_offset(&self) -> Vec<u64>
56-
{
57-
match self
58-
{
59-
Games::GhoulsArcade => vec![0x11B72B48, 0x08, 0x10, 0x28, 0x38, 0x60, 0x18, 0x80, 0x18],
60-
Games::Gradius3Arcade => vec![0x11B72B48, 0x38, 0x150, 0x8, 0x10],
61-
_ => unreachable!(),
62-
}
63-
}
64-
65106
pub fn game_info(&self) -> GameData
66107
{
67108
match self

src/main.rs

Lines changed: 61 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -210,37 +210,22 @@ fn find_game(gui_state: &mut GuiState)
210210

211211
if let Some((emu, handle)) = emu_info
212212
{
213-
let mut raw_str = [0; 22];
214-
let base = match emu
215-
{
216-
game_data::Emulator::Bsnes => 0xB151E8 as *const c_void,
217-
game_data::Emulator::Mame =>
218-
{
219-
let name_offset = vec![0x11B72B48];
220-
let offset = get_mame_offset(&handle, name_offset);
221-
(offset + 0xD8) as *const c_void
222-
}
223-
};
224-
225-
unsafe
226-
{
227-
let p_raw_str = raw_str.as_mut_ptr() as *mut _ as *mut c_void;
228-
let mut count = 0;
229-
ReadProcessMemory(handle, base, p_raw_str, raw_str.len() - 1, &mut count);
230-
}
213+
let mut first_module = HINSTANCE::default();
214+
let mut lpcb_needed = 0;
215+
unsafe{ K32EnumProcessModules(handle, &mut first_module, std::mem::size_of::<HINSTANCE>() as u32, &mut lpcb_needed); }
231216

232-
let terminator = raw_str.into_iter().position(|x| x == 0).unwrap();
217+
let mut info = MODULEINFO::default();
218+
unsafe{ K32GetModuleInformation(handle, first_module, &mut info, std::mem::size_of::<MODULEINFO>() as u32); }
233219

234-
let game_name = match std::str::from_utf8(&raw_str[0 .. terminator])
220+
if emu == game_data::Emulator::Mame
235221
{
236-
Ok(name) => match emu
222+
if game_data::Emulator::get_mame_version(info.SizeOfImage) == 0
237223
{
238-
game_data::Emulator::Bsnes => game_data::Games::bsnes_game_name(name),
239-
game_data::Emulator::Mame => game_data::Games::mame_game_name(name),
224+
return; //unsupported mame version. kinda bootleg way to do this
240225
}
226+
}
241227

242-
Err(e) => panic!("failed to get convert game name to string: {e}"),
243-
};
228+
let game_name = get_game_name(&handle, &info, &emu);
244229

245230
match game_name
246231
{
@@ -251,7 +236,12 @@ fn find_game(gui_state: &mut GuiState)
251236
gui_state.offset = match emu
252237
{
253238
game_data::Emulator::Bsnes => 0xB16D7C,
254-
game_data::Emulator::Mame => get_mame_offset(&handle, game.mame_game_offset()),
239+
game_data::Emulator::Mame =>
240+
{
241+
let version = game_data::Emulator::get_mame_version(info.SizeOfImage);
242+
let offset_list = game_data::Emulator::mame_game_offset(version, game);
243+
get_mame_offset(&handle, info.lpBaseOfDll as u64, offset_list)
244+
}
255245
};
256246
}
257247

@@ -263,31 +253,40 @@ fn find_game(gui_state: &mut GuiState)
263253
}
264254
}
265255

266-
fn get_mame_offset(handle: &HANDLE, offset_list: Vec<u64>) -> u64
256+
fn get_game_name(handle: &HANDLE, info: &MODULEINFO, emu: &game_data::Emulator) -> Option<game_data::Games>
267257
{
268-
//sleep because getting the offset while mame is loading the game can fail
269-
std::thread::sleep(std::time::Duration::from_secs(2));
258+
let mut raw_str = [0; 22];
270259

271-
unsafe
260+
let game_name_offset = match emu
272261
{
273-
let mut first_module = HINSTANCE::default();
274-
let mut lpcb_needed = 0;
275-
K32EnumProcessModules(handle, &mut first_module, std::mem::size_of::<HINSTANCE>() as u32, &mut lpcb_needed);
262+
game_data::Emulator::Bsnes => 0xB151E8 as *const c_void,
263+
game_data::Emulator::Mame =>
264+
{
265+
let version = game_data::Emulator::get_mame_version(info.SizeOfImage);
266+
let name_offset = game_data::Emulator::get_mame_name_offset(version);
276267

277-
let mut info = MODULEINFO::default();
278-
K32GetModuleInformation(handle, first_module, &mut info, std::mem::size_of::<MODULEINFO>() as u32);
268+
(info.lpBaseOfDll as u64 + name_offset as u64) as *const c_void
269+
}
270+
};
271+
272+
unsafe
273+
{
274+
let p_raw_str = raw_str.as_mut_ptr() as *mut _ as *mut c_void;
275+
let mut count = 0;
276+
ReadProcessMemory(handle, game_name_offset, p_raw_str, raw_str.len() - 1, &mut count);
277+
}
279278

280-
let mut address = info.lpBaseOfDll as u64;
279+
let terminator = raw_str.into_iter().position(|x| x == 0).unwrap();
281280

282-
for offset in offset_list
281+
match std::str::from_utf8(&raw_str[0 .. terminator])
282+
{
283+
Ok(name) => match emu
283284
{
284-
let base = (address + offset) as *const c_void;
285-
let p_address = &mut address as *mut _ as *mut c_void;
286-
let mut count = 0;
287-
ReadProcessMemory(handle, base, p_address, 8, &mut count);
285+
game_data::Emulator::Bsnes => game_data::Games::bsnes_game_name(name),
286+
game_data::Emulator::Mame => game_data::Games::mame_game_name(name),
288287
}
289288

290-
address
289+
Err(_) => None,
291290
}
292291
}
293292

@@ -300,6 +299,26 @@ fn enum_processes() -> ([u32; 384], u32)
300299
(pid_list, pid_size / 4)
301300
}
302301

302+
fn get_mame_offset(handle: &HANDLE, dll_base: u64, offset_list: Vec<u64>) -> u64
303+
{
304+
std::thread::sleep(std::time::Duration::from_secs(2)); //sleep because getting the offset while mame is loading the game can fail
305+
306+
unsafe
307+
{
308+
let mut address = dll_base;
309+
310+
for offset in offset_list
311+
{
312+
let base = (address + offset) as *const c_void;
313+
let p_address = &mut address as *mut _ as *mut c_void;
314+
let mut count = 0;
315+
ReadProcessMemory(handle, base, p_address, 8, &mut count);
316+
}
317+
318+
address
319+
}
320+
}
321+
303322
fn update(gui_state: &mut GuiState)
304323
{
305324
if gui_state.memory_read_timer > 0

0 commit comments

Comments
 (0)