Skip to content
Snippets Groups Projects

Support for Libretro

Merged João Magalhães requested to merge joamag/libretro into master
Files
2
@@ -10,9 +10,10 @@ use std::{
};
use boytacean::{
debugln,
gb::{AudioProvider, GameBoy},
pad::PadKey,
ppu::{PpuMode, DISPLAY_HEIGHT, DISPLAY_WIDTH, FRAME_BUFFER_RGB155_SIZE, RGB1555_SIZE},
ppu::{DISPLAY_HEIGHT, DISPLAY_WIDTH, FRAME_BUFFER_RGB155_SIZE, RGB1555_SIZE},
rom::Cartridge,
};
use consts::{
@@ -29,6 +30,7 @@ use crate::consts::{REGION_NTSC, RETRO_API_VERSION};
static mut EMULATOR: Option<GameBoy> = None;
static mut KEY_STATES: Option<HashMap<RetroJoypad, bool>> = None;
static mut FRAME_BUFFER: [u8; FRAME_BUFFER_RGB155_SIZE] = [0x00; FRAME_BUFFER_RGB155_SIZE];
static mut PENDING_CYCLES: u32 = 0_u32;
static mut ENVIRONMENT_CALLBACK: Option<extern "C" fn(u32, *const c_void) -> bool> = None;
static mut VIDEO_REFRESH_CALLBACK: Option<extern "C" fn(*const u8, c_uint, c_uint, usize)> = None;
@@ -139,13 +141,13 @@ pub struct RetroSystemTiming {
#[no_mangle]
pub extern "C" fn retro_api_version() -> c_uint {
println!("retro_api_version()");
debugln!("retro_api_version()");
RETRO_API_VERSION
}
#[no_mangle]
pub extern "C" fn retro_init() {
println!("retro_init()");
debugln!("retro_init()");
unsafe {
EMULATOR = Some(GameBoy::new(None));
KEY_STATES = Some(HashMap::new());
@@ -154,12 +156,12 @@ pub extern "C" fn retro_init() {
#[no_mangle]
pub extern "C" fn retro_deinit() {
println!("retro_deinit()");
debugln!("retro_deinit()");
}
#[no_mangle]
pub extern "C" fn retro_reset() {
println!("retro_reset()");
debugln!("retro_reset()");
let emulator = unsafe { EMULATOR.as_mut().unwrap() };
emulator.reload();
}
@@ -169,7 +171,7 @@ pub extern "C" fn retro_reset() {
/// This function should not be called only within Lib Retro context.
#[no_mangle]
pub unsafe extern "C" fn retro_get_system_info(info: *mut RetroSystemInfo) {
println!("retro_get_system_info()");
debugln!("retro_get_system_info()");
(*info).library_name = "Boytacean\0".as_ptr() as *const c_char;
(*info).library_version = "v0.9.6\0".as_ptr() as *const c_char;
(*info).valid_extensions = "gb|gbc\0".as_ptr() as *const c_char;
@@ -182,7 +184,7 @@ pub unsafe extern "C" fn retro_get_system_info(info: *mut RetroSystemInfo) {
/// This function should not be called only within Lib Retro context.
#[no_mangle]
pub unsafe extern "C" fn retro_get_system_av_info(info: *mut RetroSystemAvInfo) {
println!("retro_get_system_av_info()");
debugln!("retro_get_system_av_info()");
(*info).geometry.base_width = DISPLAY_WIDTH as u32;
(*info).geometry.base_height = DISPLAY_HEIGHT as u32;
(*info).geometry.max_width = DISPLAY_WIDTH as u32 * 64;
@@ -196,7 +198,7 @@ pub unsafe extern "C" fn retro_get_system_av_info(info: *mut RetroSystemAvInfo)
pub extern "C" fn retro_set_environment(
callback: Option<extern "C" fn(u32, *const c_void) -> bool>,
) {
println!("retro_set_environment()");
debugln!("retro_set_environment()");
unsafe {
ENVIRONMENT_CALLBACK = callback;
}
@@ -204,7 +206,7 @@ pub extern "C" fn retro_set_environment(
#[no_mangle]
pub extern "C" fn retro_set_controller_port_device() {
println!("retro_set_controller_port_device()");
debugln!("retro_set_controller_port_device()");
}
#[no_mangle]
@@ -219,7 +221,7 @@ pub extern "C" fn retro_run() {
let mut last_frame = emulator.ppu_frame();
let mut counter_cycles = 0_u32;
let mut counter_cycles = unsafe { PENDING_CYCLES };
let cycle_limit = (GameBoy::CPU_FREQ as f32 * emulator.multiplier() as f32
/ GameBoy::VISUAL_FREQ)
.round() as u32;
@@ -228,7 +230,7 @@ pub extern "C" fn retro_run() {
// limits the number of ticks to the typical number
// of cycles expected for the current logic cycle
if counter_cycles >= cycle_limit {
//pending_cycles = counter_cycles - cycle_limit;
unsafe { PENDING_CYCLES = counter_cycles - cycle_limit };
break;
}
@@ -291,7 +293,7 @@ pub extern "C" fn retro_run() {
#[no_mangle]
pub extern "C" fn retro_get_region() -> u32 {
println!("retro_get_region()");
debugln!("retro_get_region()");
REGION_NTSC
}
@@ -300,7 +302,7 @@ pub extern "C" fn retro_get_region() -> u32 {
/// This function should not be called only within Lib Retro context.
#[no_mangle]
pub unsafe extern "C" fn retro_load_game(game: *const RetroGameInfo) -> bool {
println!("retro_load_game()");
debugln!("retro_load_game()");
let instance = EMULATOR.as_mut().unwrap();
let data_buffer = from_raw_parts((*game).data as *const u8, (*game).size);
let rom = Cartridge::from_data(data_buffer);
@@ -318,57 +320,57 @@ pub extern "C" fn retro_load_game_special(
_info: *const RetroGameInfo,
_num_info: usize,
) -> bool {
println!("retro_load_game_special()");
debugln!("retro_load_game_special()");
false
}
#[no_mangle]
pub extern "C" fn retro_unload_game() {
println!("retro_unload_game()");
debugln!("retro_unload_game()");
}
#[no_mangle]
pub extern "C" fn retro_get_memory_data(_memory_id: u32) -> *mut c_void {
println!("retro_get_memory_data()");
debugln!("retro_get_memory_data()");
std::ptr::null_mut()
}
#[no_mangle]
pub extern "C" fn retro_get_memory_size(_memory_id: u32) -> usize {
println!("retro_get_memory_size()");
debugln!("retro_get_memory_size()");
0
}
#[no_mangle]
pub extern "C" fn retro_serialize_size() {
println!("retro_serialize_size()");
debugln!("retro_serialize_size()");
}
#[no_mangle]
pub extern "C" fn retro_serialize() {
println!("retro_serialize()");
debugln!("retro_serialize()");
}
#[no_mangle]
pub extern "C" fn retro_unserialize() {
println!("retro_unserialize()");
debugln!("retro_unserialize()");
}
#[no_mangle]
pub extern "C" fn retro_cheat_reset() {
println!("retro_cheat_reset()");
debugln!("retro_cheat_reset()");
}
#[no_mangle]
pub extern "C" fn retro_cheat_set() {
println!("retro_cheat_set()");
debugln!("retro_cheat_set()");
}
#[no_mangle]
pub extern "C" fn retro_set_video_refresh(
callback: Option<extern "C" fn(*const u8, c_uint, c_uint, usize)>,
) {
println!("retro_set_video_refresh()");
debugln!("retro_set_video_refresh()");
unsafe {
VIDEO_REFRESH_CALLBACK = callback;
}
@@ -376,7 +378,7 @@ pub extern "C" fn retro_set_video_refresh(
#[no_mangle]
pub extern "C" fn retro_set_audio_sample(callback: Option<extern "C" fn(i16, i16)>) {
println!("retro_set_audio_sample()");
debugln!("retro_set_audio_sample()");
unsafe {
AUDIO_SAMPLE_CALLBACK = callback;
}
@@ -384,7 +386,7 @@ pub extern "C" fn retro_set_audio_sample(callback: Option<extern "C" fn(i16, i16
#[no_mangle]
pub extern "C" fn retro_set_audio_sample_batch(callback: Option<extern "C" fn(*const i16, usize)>) {
println!("retro_set_audio_sample_batch()");
debugln!("retro_set_audio_sample_batch()");
unsafe {
AUDIO_SAMPLE_BATCH_CALLBACK = callback;
}
@@ -392,7 +394,7 @@ pub extern "C" fn retro_set_audio_sample_batch(callback: Option<extern "C" fn(*c
#[no_mangle]
pub extern "C" fn retro_set_input_poll(callback: Option<extern "C" fn()>) {
println!("retro_set_input_poll()");
debugln!("retro_set_input_poll()");
unsafe {
INPUT_POLL_CALLBACK = callback;
}
@@ -402,7 +404,7 @@ pub extern "C" fn retro_set_input_poll(callback: Option<extern "C" fn()>) {
pub extern "C" fn retro_set_input_state(
callback: Option<extern "C" fn(port: u32, device: u32, index: u32, id: u32) -> i16>,
) {
println!("retro_set_input_state()");
debugln!("retro_set_input_state()");
unsafe {
INPUT_STATE_CALLBACK = callback;
}
Loading