-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
API to hook in external tooling #215
Comments
Hi TTP, there is no official API for full procedural control of Mupen. However, depending on your requirements, you might be able to get away with generating hotkey presses via SendInput to trigger various actions. If you only need control over the game input, you can write a custom input plugin in Rust. |
Thanks for your reply. I'll have to think about what I want to do. I've always wanted to experiment with machine learning in something like SM64, but I don't really want to use vision as the primary input, so I may need to work out how to monitor memory. If I do get around to this project, I may pop into Discord sometime after November if I need help. Is there any reference or documentation for Mupen? Edit: the Discord link in the readme is invalid |
To read Mupen's memory, you can do it externally via ReadProcessMemory like STROOP, or internally by writing to Mupen currently has no comprehensive docs so feel free to ask anytime in the discord. |
Just for fun, here's a proof of concept of reading Mario's speed in Rust using the [dependencies]
winapi = { version = "0.3.9", features = ["memoryapi", "processthreadsapi", "handleapi"] } use winapi::{
ctypes::c_void,
um::{
handleapi::CloseHandle, memoryapi::ReadProcessMemory, processthreadsapi::OpenProcess,
winnt::PROCESS_VM_READ,
},
};
fn read_float(pid: u32, address: u32) -> f32 {
let handle = unsafe { OpenProcess(PROCESS_VM_READ, 0, pid) };
if handle.is_null() {
panic!("Handle was null");
}
let mut buffer = [0u8; 4]; // float is 4 bytes
let read_result = unsafe {
ReadProcessMemory(
handle,
address as *const c_void,
buffer.as_mut_ptr() as *mut c_void,
4, // float is 4 bytes
&mut 0,
)
};
let close_handle_result = unsafe { CloseHandle(handle) };
if close_handle_result == 0 {
eprintln!("Handle didn't close correctly"); // don't panic, we may still have something in read_result
}
if read_result == 0 {
panic!("Read failed");
}
f32::from_le_bytes(buffer)
}
fn main() {
let pid = 9820;
let address = 0x00BFB184;
let speed = read_float(pid, address);
println!("{:?}", speed);
} Ofc this could be improved with better rust error handling or maybe a generic read function that can read different types (float, s16, etc...), but in my opinion it's better to use C/C++ when using windows apis because you don't have to do any type gymnastics or deal with unsafe. |
While this is cool, I don't really see the point of hooking into mupen when there is wafel as a library 🤨 |
Oh, interesting. I have never seen this. However, I don't want to be limited to only SM64. This will be a good place to start, though! |
Is there currently support for hooking in an external tool that can control user input? I have been learning Rust and would like to get into playing with algorithms that can perform optimised searches.
I am not sure if this would even be possible as this kind of lower-level systems programming is not my typical domain of interest, so I am not entirely certain how you would typically go about doing it.
As such, I was wondering if it were possible to allow for external tools to connect and serve as a controller, being able to monitor memory, savestates, etc., allowing for autonomous control of Mupen by a 3rd party tool.
Depending on the complexity of Mupen, I assume it would be possible, perhaps through a plugin interface, where the external app would be fed state and would return controller/application input.
If something like this can already be done, I would love to know more about where to look.
Thanks
The text was updated successfully, but these errors were encountered: