1 #include <stdint.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <stdarg.h>
6 #include <audio.h>
7 #include <cmdline.h>
8 #include <libretro.h>
9 #include <log.h>
10 #include <machine.h>
11 #include <video.h>
12
13 /* Package definitions */
14 #define PACKAGE_NAME "emux"
15 #define PACKAGE_VERSION "0.1"
16
17 /* Retro frontends functions */
18 void retro_audio_fill_timing(struct retro_system_timing *timing);
19 void retro_video_fill_timing(struct retro_system_timing *timing);
20 void retro_video_fill_geometry(struct retro_game_geometry *geometry);
21 bool retro_video_updated();
22
23 retro_environment_t retro_environment_cb;
24 static bool machine_initialized;
25
retro_init(void)26 void retro_init(void)
27 {
28 char *system_dir;
29 char *config_dir;
30 char *save_dir;
31 struct retro_log_callback log_callback;
32
33 /* Get system directory from frontend */
34 retro_environment_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY,
35 &system_dir);
36
37 /* Get config directory from frontend (currently equal to system dir) */
38 retro_environment_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY,
39 &config_dir);
40
41 /* Get save directory from frontend */
42 retro_environment_cb(RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY, &save_dir);
43
44 /* Override log callback if supported by frontend */
45 if (retro_environment_cb(RETRO_ENVIRONMENT_GET_LOG_INTERFACE,
46 &log_callback))
47 log_cb = (log_print_t)log_callback.log;
48
49 /* Set system/config/save directories */
50 cmdline_set_param("system-dir", NULL, system_dir);
51 cmdline_set_param("config-dir", NULL, config_dir);
52 cmdline_set_param("save-dir", NULL, save_dir);
53
54 /* Set machine to be run */
55 cmdline_set_param("machine", NULL, MACHINE);
56
57 /* Set retro frontends */
58 cmdline_set_param("audio", NULL, "retro");
59 cmdline_set_param("video", NULL, "retro");
60 }
61
retro_deinit(void)62 void retro_deinit(void)
63 {
64 }
65
retro_api_version(void)66 unsigned int retro_api_version(void)
67 {
68 return RETRO_API_VERSION;
69 }
70
retro_set_controller_port_device(unsigned int port,unsigned int device)71 void retro_set_controller_port_device(unsigned int port, unsigned int device)
72 {
73 (void)port;
74 (void)device;
75 }
76
retro_get_system_info(struct retro_system_info * info)77 void retro_get_system_info(struct retro_system_info *info)
78 {
79 memset(info, 0, sizeof(*info));
80 info->library_name = PACKAGE_NAME " (" MACHINE ")";
81 info->library_version = PACKAGE_VERSION;
82 info->need_fullpath = true;
83 info->valid_extensions = VALID_EXTS;
84 }
85
retro_get_system_av_info(struct retro_system_av_info * info)86 void retro_get_system_av_info(struct retro_system_av_info *info)
87 {
88 /* Let frontends fill timing and geometry */
89 retro_audio_fill_timing(&info->timing);
90 retro_video_fill_timing(&info->timing);
91 retro_video_fill_geometry(&info->geometry);
92 }
93
retro_set_environment(retro_environment_t cb)94 void retro_set_environment(retro_environment_t cb)
95 {
96 /* Set retro environment callback */
97 retro_environment_cb = cb;
98 }
99
retro_reset(void)100 void retro_reset(void)
101 {
102 /* Reset machine */
103 machine_reset();
104 }
105
retro_run(void)106 void retro_run(void)
107 {
108 /* Run until screen is updated */
109 while (!video_updated())
110 machine_step();
111 }
112
retro_load_game(const struct retro_game_info * info)113 bool retro_load_game(const struct retro_game_info *info)
114 {
115 /* Set data path */
116 cmdline_set_param(NULL, NULL, (char *)info->path);
117
118 /* Initialize machine */
119 if (!machine_init()) {
120 LOG_E("Failed to initialize machine!\n");
121 return false;
122 }
123
124 /* Flag machine as initialized */
125 machine_initialized = true;
126
127 /* Start audio processing */
128 audio_start();
129
130 return true;
131 }
132
retro_unload_game(void)133 void retro_unload_game(void)
134 {
135 /* Return already if machine was not initialized */
136 if (!machine_initialized)
137 return;
138
139 /* Stop audio processing */
140 audio_stop();
141
142 /* Deinitialize machine */
143 machine_deinit();
144 machine_initialized = false;
145 }
146
retro_get_region(void)147 unsigned int retro_get_region(void)
148 {
149 return RETRO_REGION_NTSC;
150 }
151
retro_load_game_special(unsigned int type,const struct retro_game_info * info,size_t num)152 bool retro_load_game_special(unsigned int type,
153 const struct retro_game_info *info, size_t num)
154 {
155 (void)type;
156 (void)info;
157 (void)num;
158 return false;
159 }
160
retro_serialize_size(void)161 size_t retro_serialize_size(void)
162 {
163 return 0;
164 }
165
retro_serialize(void * data_,size_t size)166 bool retro_serialize(void *data_, size_t size)
167 {
168 return false;
169 }
170
retro_unserialize(const void * data_,size_t size)171 bool retro_unserialize(const void *data_, size_t size)
172 {
173 return false;
174 }
175
retro_get_memory_data(unsigned int id)176 void *retro_get_memory_data(unsigned int id)
177 {
178 if ( id == RETRO_MEMORY_SYSTEM_RAM )
179 return g_ram_data;
180 return NULL;
181 }
182
retro_get_memory_size(unsigned int id)183 size_t retro_get_memory_size(unsigned int id)
184 {
185 if ( id == RETRO_MEMORY_SYSTEM_RAM )
186 return g_ram_size;
187 return 0;
188 }
189
retro_cheat_reset(void)190 void retro_cheat_reset(void)
191 {
192 }
193
retro_cheat_set(unsigned int index,bool enabled,const char * code)194 void retro_cheat_set(unsigned int index, bool enabled, const char *code)
195 {
196 (void)index;
197 (void)enabled;
198 (void)code;
199 }
200
201