libretro_rs/
core_macro.rs1#[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}