libretro_rs/
core_macro.rs

1#[macro_export]
2macro_rules! libretro_core {
3  ($core:path) => {
4    #[doc(hidden)]
5    mod libretro_rs_instance {
6      use super::{$core};
7      use libretro_rs::libc::*;
8      use libretro_rs::sys::*;
9      use libretro_rs::*;
10
11      static mut RETRO_INSTANCE: RetroInstance<$core> = RetroInstance {
12        environment: None,
13        audio_sample: None,
14        audio_sample_batch: None,
15        input_poll: None,
16        input_state: None,
17        video_refresh: None,
18        system: None,
19        system_info: None,
20        system_av_info: None,
21      };
22
23      #[no_mangle]
24      extern "C" fn retro_api_version() -> c_uint {
25        RETRO_API_VERSION
26      }
27
28      #[no_mangle]
29      extern "C" fn retro_get_system_info(info: &mut retro_system_info) {
30        instance_mut(|instance| instance.on_get_system_info(info))
31      }
32
33      #[no_mangle]
34      extern "C" fn retro_get_system_av_info(info: &mut retro_system_av_info) {
35        instance_ref(|instance| instance.on_get_system_av_info(info))
36      }
37
38      #[no_mangle]
39      extern "C" fn retro_init() {
40        instance_mut(|instance| instance.on_init())
41      }
42
43      #[no_mangle]
44      extern "C" fn retro_deinit() {
45        instance_mut(|instance| instance.on_deinit())
46      }
47
48      #[no_mangle]
49      extern "C" fn retro_set_environment(cb: retro_environment_t) {
50        instance_mut(|instance| instance.on_set_environment(cb))
51      }
52
53      #[no_mangle]
54      extern "C" fn retro_set_audio_sample(cb: retro_audio_sample_t) {
55        instance_mut(|instance| instance.on_set_audio_sample(cb))
56      }
57
58      #[no_mangle]
59      extern "C" fn retro_set_audio_sample_batch(cb: retro_audio_sample_batch_t) {
60        instance_mut(|instance| instance.on_set_audio_sample_batch(cb))
61      }
62
63      #[no_mangle]
64      extern "C" fn retro_set_input_poll(cb: retro_input_poll_t) {
65        instance_mut(|instance| instance.on_set_input_poll(cb))
66      }
67
68      #[no_mangle]
69      extern "C" fn retro_set_input_state(cb: retro_input_state_t) {
70        instance_mut(|instance| instance.on_set_input_state(cb))
71      }
72
73      #[no_mangle]
74      extern "C" fn retro_set_video_refresh(cb: retro_video_refresh_t) {
75        instance_mut(|instance| instance.on_set_video_refresh(cb))
76      }
77
78      #[no_mangle]
79      extern "C" fn retro_set_controller_port_device(port: c_uint, device: c_uint) {
80        instance_mut(|instance| instance.on_set_controller_port_device(port, device))
81      }
82
83      #[no_mangle]
84      extern "C" fn retro_reset() {
85        instance_mut(|instance| instance.on_reset())
86      }
87
88      #[no_mangle]
89      extern "C" fn retro_run() {
90        instance_mut(|instance| instance.on_run())
91      }
92
93      #[no_mangle]
94      extern "C" fn retro_serialize_size() -> size_t {
95        instance_ref(|instance| instance.on_serialize_size())
96      }
97
98      #[no_mangle]
99      extern "C" fn retro_serialize(data: *mut (), size: size_t) -> bool {
100        instance_ref(|instance| instance.on_serialize(data, size))
101      }
102
103      #[no_mangle]
104      extern "C" fn retro_unserialize(data: *const (), size: size_t) -> bool {
105        instance_mut(|instance| instance.on_unserialize(data, size))
106      }
107
108      #[no_mangle]
109      extern "C" fn retro_cheat_reset() {
110        instance_mut(|instance| instance.on_cheat_reset())
111      }
112
113      #[no_mangle]
114      extern "C" fn retro_cheat_set(index: c_uint, enabled: bool, code: *const c_char) {
115        instance_mut(|instance| instance.on_cheat_set(index, enabled, code))
116      }
117
118      #[no_mangle]
119      extern "C" fn retro_load_game(game: &retro_game_info) -> bool {
120        instance_mut(|instance| instance.on_load_game(game))
121      }
122
123      #[no_mangle]
124      extern "C" fn retro_load_game_special(game_type: c_uint, info: &retro_game_info, num_info: size_t) -> bool {
125        instance_mut(|instance| instance.on_load_game_special(game_type, info, num_info))
126      }
127
128      #[no_mangle]
129      extern "C" fn retro_unload_game() {
130        instance_mut(|instance| instance.on_unload_game())
131      }
132
133      #[no_mangle]
134      extern "C" fn retro_get_region() -> c_uint {
135        instance_ref(|instance| instance.on_get_region())
136      }
137
138      #[no_mangle]
139      extern "C" fn retro_get_memory_data(id: c_uint) -> *mut () {
140        instance_mut(|instance| instance.on_get_memory_data(id))
141      }
142
143      #[no_mangle]
144      extern "C" fn retro_get_memory_size(id: c_uint) -> size_t {
145        instance_mut(|instance| instance.on_get_memory_size(id))
146      }
147
148      #[inline]
149      fn instance_ref<T>(f: impl FnOnce(&RetroInstance<$core>) -> T) -> T {
150        unsafe { f(&RETRO_INSTANCE) }
151      }
152
153      #[inline]
154      fn instance_mut<T>(f: impl FnOnce(&mut RetroInstance<$core>) -> T) -> T {
155        unsafe { f(&mut RETRO_INSTANCE) }
156      }
157    }
158  };
159}