1 /* RetroArch - A frontend for libretro.
2 * Copyright (C) 2010-2014 - Hans-Kristian Arntzen
3 * Copyright (C) 2011-2017 - Daniel De Matteis
4 * Copyright (C) 2012-2015 - Michael Lelli
5 *
6 * RetroArch is free software: you can redistribute it and/or modify it under the terms
7 * of the GNU General Public License as published by the Free Software Found-
8 * ation, either version 3 of the License, or (at your option) any later version.
9 *
10 * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
11 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12 * PURPOSE. See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with RetroArch.
15 * If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include <stdint.h>
19 #include <stdlib.h>
20 #include <string.h>
21
22 #include <libretro.h>
23
24 #if defined(HAVE_MENU) && defined(HAVE_RGUI)
25 #include <string/stdstring.h>
26 #include "../configuration.h"
27 #include "../menu/menu_defines.h"
28 #endif
29
30 #include "internal_cores.h"
31
32 static uint16_t *dummy_frame_buf;
33
34 static uint16_t frame_buf_width;
35 static uint16_t frame_buf_height;
36
37 #if defined(HAVE_LIBNX) && defined(HAVE_STATIC_DUMMY)
retro_init(void)38 void retro_init(void) { libretro_dummy_retro_init(); }
retro_deinit(void)39 void retro_deinit(void) { libretro_dummy_retro_deinit(); }
retro_api_version(void)40 unsigned retro_api_version(void) { return libretro_dummy_retro_api_version(); }
retro_set_controller_port_device(unsigned port,unsigned device)41 void retro_set_controller_port_device(unsigned port, unsigned device) { libretro_dummy_retro_set_controller_port_device(port, device); }
retro_get_system_info(struct retro_system_info * info)42 void retro_get_system_info(struct retro_system_info *info) { libretro_dummy_retro_get_system_info(info); }
retro_get_system_av_info(struct retro_system_av_info * info)43 void retro_get_system_av_info(struct retro_system_av_info *info) { retro_get_system_av_info(info); }
retro_set_environment(retro_environment_t cb)44 void retro_set_environment(retro_environment_t cb) { libretro_dummy_retro_set_environment(cb); }
retro_set_audio_sample(retro_audio_sample_t cb)45 void retro_set_audio_sample(retro_audio_sample_t cb) { libretro_dummy_retro_set_audio_sample(cb); }
retro_set_audio_sample_batch(retro_audio_sample_batch_t cb)46 void retro_set_audio_sample_batch(retro_audio_sample_batch_t cb) { libretro_dummy_retro_set_audio_sample_batch(cb); }
retro_set_input_poll(retro_input_poll_t cb)47 void retro_set_input_poll(retro_input_poll_t cb) { libretro_dummy_retro_set_input_poll(cb); }
retro_set_input_state(retro_input_state_t cb)48 void retro_set_input_state(retro_input_state_t cb) { libretro_dummy_retro_set_input_state(cb); }
retro_set_video_refresh(retro_video_refresh_t cb)49 void retro_set_video_refresh(retro_video_refresh_t cb) { libretro_dummy_retro_set_video_refresh(cb); }
retro_reset(void)50 void retro_reset(void) { libretro_dummy_retro_reset(); }
retro_run(void)51 void retro_run(void) { libretro_dummy_retro_run(); }
retro_load_game(const struct retro_game_info * info)52 bool retro_load_game(const struct retro_game_info *info) { return libretro_dummy_retro_load_game(info); }
retro_unload_game(void)53 void retro_unload_game(void) { libretro_dummy_retro_unload_game(); }
retro_get_region(void)54 unsigned retro_get_region(void) { return libretro_dummy_retro_get_region(); }
retro_load_game_special(unsigned type,const struct retro_game_info * info,size_t num)55 bool retro_load_game_special(unsigned type, const struct retro_game_info *info, size_t num) { return libretro_dummy_retro_load_game_special(type, info, num); }
retro_serialize_size(void)56 size_t retro_serialize_size(void) { return libretro_dummy_retro_serialize_size(); }
retro_serialize(void * data,size_t size)57 bool retro_serialize(void *data, size_t size) { return libretro_dummy_retro_serialize(data, size); }
retro_unserialize(const void * data,size_t size)58 bool retro_unserialize(const void *data, size_t size) { return libretro_dummy_retro_unserialize(data, size); }
retro_get_memory_data(unsigned id)59 void *retro_get_memory_data(unsigned id) { return libretro_dummy_retro_get_memory_data(id); }
retro_get_memory_size(unsigned id)60 size_t retro_get_memory_size(unsigned id) { return libretro_dummy_retro_get_memory_size(id); }
retro_cheat_reset(void)61 void retro_cheat_reset(void) { libretro_dummy_retro_cheat_reset(); }
retro_cheat_set(unsigned idx,bool enabled,const char * code)62 void retro_cheat_set(unsigned idx, bool enabled, const char *code) { libretro_dummy_retro_cheat_set(idx, enabled, code); }
63 #endif
64
libretro_dummy_retro_init(void)65 void libretro_dummy_retro_init(void)
66 {
67 #if defined(HAVE_MENU) && defined(HAVE_RGUI)
68 settings_t *settings = config_get_ptr();
69 #endif
70 unsigned i;
71
72 /* Sensible defaults */
73 frame_buf_width = 320;
74 frame_buf_height = 240;
75
76 #if defined(HAVE_MENU) && defined(HAVE_RGUI)
77 if (string_is_equal(settings->arrays.menu_driver, "rgui"))
78 {
79 switch (settings->uints.menu_rgui_aspect_ratio)
80 {
81 case RGUI_ASPECT_RATIO_16_9:
82 case RGUI_ASPECT_RATIO_16_9_CENTRE:
83 frame_buf_width = 426;
84 break;
85 case RGUI_ASPECT_RATIO_16_10:
86 case RGUI_ASPECT_RATIO_16_10_CENTRE:
87 frame_buf_width = 384;
88 break;
89 default:
90 /* 4:3 */
91 frame_buf_width = 320;
92 break;
93 }
94 }
95 #endif
96
97 dummy_frame_buf = (uint16_t*)calloc(frame_buf_width * frame_buf_height, sizeof(uint16_t));
98 for (i = 0; i < (unsigned)(frame_buf_width * frame_buf_height); i++)
99 dummy_frame_buf[i] = 4 << 5;
100 }
101
libretro_dummy_retro_deinit(void)102 void libretro_dummy_retro_deinit(void)
103 {
104 if (dummy_frame_buf)
105 free(dummy_frame_buf);
106 dummy_frame_buf = NULL;
107 }
108
libretro_dummy_retro_api_version(void)109 unsigned libretro_dummy_retro_api_version(void)
110 {
111 return RETRO_API_VERSION;
112 }
113
libretro_dummy_retro_set_controller_port_device(unsigned port,unsigned device)114 void libretro_dummy_retro_set_controller_port_device(
115 unsigned port, unsigned device)
116 {
117 (void)port;
118 (void)device;
119 }
120
libretro_dummy_retro_get_system_info(struct retro_system_info * info)121 void libretro_dummy_retro_get_system_info(
122 struct retro_system_info *info)
123 {
124 memset(info, 0, sizeof(*info));
125 info->library_name = "";
126 info->library_version = "";
127 info->need_fullpath = false;
128 info->valid_extensions = ""; /* Nothing. */
129 }
130
131 static retro_video_refresh_t dummy_video_cb;
132 static retro_audio_sample_t dummy_audio_cb;
133 static retro_audio_sample_batch_t dummy_audio_batch_cb;
134 static retro_environment_t dummy_environ_cb;
135 static retro_input_poll_t dummy_input_poll_cb;
136 static retro_input_state_t dummy_input_state_cb;
137
138 /* Doesn't really matter, but need something sane. */
libretro_dummy_retro_get_system_av_info(struct retro_system_av_info * info)139 void libretro_dummy_retro_get_system_av_info(
140 struct retro_system_av_info *info)
141 {
142 float refresh_rate = 0.0;
143 if (!dummy_environ_cb(RETRO_ENVIRONMENT_GET_TARGET_REFRESH_RATE, &refresh_rate))
144 refresh_rate = 60.0;
145
146 info->timing.fps = refresh_rate;
147 info->timing.sample_rate = 48000.0;
148
149 info->geometry.base_width = frame_buf_width;
150 info->geometry.base_height = frame_buf_height;
151 info->geometry.max_width = frame_buf_width;
152 info->geometry.max_height = frame_buf_height;
153 info->geometry.aspect_ratio = (float)frame_buf_width / (float)frame_buf_height;
154 }
155
libretro_dummy_retro_set_environment(retro_environment_t cb)156 void libretro_dummy_retro_set_environment(retro_environment_t cb)
157 {
158 enum retro_pixel_format fmt = RETRO_PIXEL_FORMAT_RGB565;
159
160 dummy_environ_cb = cb;
161
162 /* We know it's supported, it's internal to RetroArch. */
163 dummy_environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &fmt);
164 }
165
libretro_dummy_retro_set_audio_sample(retro_audio_sample_t cb)166 void libretro_dummy_retro_set_audio_sample(retro_audio_sample_t cb)
167 {
168 dummy_audio_cb = cb;
169 }
170
libretro_dummy_retro_set_audio_sample_batch(retro_audio_sample_batch_t cb)171 void libretro_dummy_retro_set_audio_sample_batch(
172 retro_audio_sample_batch_t cb)
173 {
174 dummy_audio_batch_cb = cb;
175 }
176
libretro_dummy_retro_set_input_poll(retro_input_poll_t cb)177 void libretro_dummy_retro_set_input_poll(retro_input_poll_t cb)
178 {
179 dummy_input_poll_cb = cb;
180 }
181
libretro_dummy_retro_set_input_state(retro_input_state_t cb)182 void libretro_dummy_retro_set_input_state(retro_input_state_t cb)
183 {
184 dummy_input_state_cb = cb;
185 }
186
libretro_dummy_retro_set_video_refresh(retro_video_refresh_t cb)187 void libretro_dummy_retro_set_video_refresh(retro_video_refresh_t cb)
188 {
189 dummy_video_cb = cb;
190 }
191
libretro_dummy_retro_reset(void)192 void libretro_dummy_retro_reset(void)
193 {}
194
libretro_dummy_retro_run(void)195 void libretro_dummy_retro_run(void)
196 {
197 dummy_input_poll_cb();
198 dummy_video_cb(dummy_frame_buf, frame_buf_width, frame_buf_height, 2 * frame_buf_width);
199 }
200
201 /* This should never be called, it's only used as a placeholder. */
libretro_dummy_retro_load_game(const struct retro_game_info * info)202 bool libretro_dummy_retro_load_game(const struct retro_game_info *info)
203 {
204 (void)info;
205 return false;
206 }
207
libretro_dummy_retro_unload_game(void)208 void libretro_dummy_retro_unload_game(void)
209 {}
210
libretro_dummy_retro_get_region(void)211 unsigned libretro_dummy_retro_get_region(void)
212 {
213 return RETRO_REGION_NTSC;
214 }
215
libretro_dummy_retro_load_game_special(unsigned type,const struct retro_game_info * info,size_t num)216 bool libretro_dummy_retro_load_game_special(unsigned type,
217 const struct retro_game_info *info, size_t num)
218 {
219 (void)type;
220 (void)info;
221 (void)num;
222 return false;
223 }
224
libretro_dummy_retro_serialize_size(void)225 size_t libretro_dummy_retro_serialize_size(void)
226 {
227 return 0;
228 }
229
libretro_dummy_retro_serialize(void * data,size_t size)230 bool libretro_dummy_retro_serialize(void *data, size_t size)
231 {
232 (void)data;
233 (void)size;
234 return false;
235 }
236
libretro_dummy_retro_unserialize(const void * data,size_t size)237 bool libretro_dummy_retro_unserialize(const void *data,
238 size_t size)
239 {
240 (void)data;
241 (void)size;
242 return false;
243 }
244
libretro_dummy_retro_get_memory_data(unsigned id)245 void *libretro_dummy_retro_get_memory_data(unsigned id)
246 {
247 (void)id;
248 return NULL;
249 }
250
libretro_dummy_retro_get_memory_size(unsigned id)251 size_t libretro_dummy_retro_get_memory_size(unsigned id)
252 {
253 (void)id;
254 return 0;
255 }
256
libretro_dummy_retro_cheat_reset(void)257 void libretro_dummy_retro_cheat_reset(void)
258 {}
259
libretro_dummy_retro_cheat_set(unsigned idx,bool enabled,const char * code)260 void libretro_dummy_retro_cheat_set(unsigned idx,
261 bool enabled, const char *code)
262 {
263 (void)idx;
264 (void)enabled;
265 (void)code;
266 }
267