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