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