drc: handle upto 64k page size
[pcsx_rearmed.git] / deps / libretro-common / samples / core_options / example_hide_option / libretro_core_options.h
CommitLineData
3719602c
PC
1#ifndef LIBRETRO_CORE_OPTIONS_H__
2#define LIBRETRO_CORE_OPTIONS_H__
3
4#include <stdlib.h>
5#include <string.h>
6
7#include <libretro.h>
8#include <retro_inline.h>
9
10#ifndef HAVE_NO_LANGEXTRA
11#include "libretro_core_options_intl.h"
12#endif
13
14/*
15 ********************************
16 * VERSION: 1.3
17 ********************************
18 *
19 * - 1.3: Move translations to libretro_core_options_intl.h
20 * - libretro_core_options_intl.h includes BOM and utf-8
21 * fix for MSVC 2010-2013
22 * - Added HAVE_NO_LANGEXTRA flag to disable translations
23 * on platforms/compilers without BOM support
24 * - 1.2: Use core options v1 interface when
25 * RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION is >= 1
26 * (previously required RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION == 1)
27 * - 1.1: Support generation of core options v0 retro_core_option_value
28 * arrays containing options with a single value
29 * - 1.0: First commit
30*/
31
32#ifdef __cplusplus
33extern "C" {
34#endif
35
36/*
37 ********************************
38 * Core Option Definitions
39 ********************************
40*/
41
42/* RETRO_LANGUAGE_ENGLISH */
43
44/* Default language:
45 * - All other languages must include the same keys and values
46 * - Will be used as a fallback in the event that frontend language
47 * is not available
48 * - Will be used as a fallback for any missing entries in
49 * frontend language definition */
50
51struct retro_core_option_definition option_defs_us[] = {
52 {
53 "mycore_region", /* key (option name) */
54 "Console Region", /* description (label) */
55 "Specify which region the system is from.", /* sublabel */
56 {
57 { "auto", "Auto" }, /* value_1, value_1_label */
58 { "ntsc-j", "Japan" }, /* value_2, value_2_label */
59 { "ntsc-u", "America" }, /* value_3, value_3_label */
60 { "pal", "Europe" }, /* value_4, value_4_label */
61 { NULL, NULL },
62 },
63 "auto" /* default_value */
64 },
65 {
66 "mycore_video_scale",
67 "Video Scale",
68 "Set internal video scale factor.",
69 {
70 { "1x", NULL }, /* If value itself is human-readable (e.g. a number) */
71 { "2x", NULL }, /* and can displayed directly, the value_label should */
72 { "3x", NULL }, /* be set to NULL */
73 { "4x", NULL },
74 { NULL, NULL },
75 },
76 "3x"
77 },
78 /* This 'mycore_show_speedhacks' option will only be shown
79 * if the frontend supports core options API v1.
80 * It will be hidden on older frontends.
81 * See line 227 */
82 {
83 "mycore_show_speedhacks",
84 "Show Unsafe Settings",
85 "Enable configuration of emulation speed hacks.",
86 {
87 { "enabled", NULL },
88 { "disabled", NULL },
89 { NULL, NULL},
90 },
91 "disabled"
92 },
93 {
94 "mycore_overclock",
95 "Reduce Slowdown",
96 "Enable CPU overclock (unsafe).",
97 {
98 { "enabled", NULL }, /* If value is equal to 'enabled' or 'disabled', */
99 { "disabled", NULL }, /* value_label should be set to NULL */
100 { NULL, NULL },
101 },
102 "disabled"
103 },
104 { NULL, NULL, NULL, {{0}}, NULL },
105};
106
107/*
108 ********************************
109 * Language Mapping
110 ********************************
111*/
112
113#ifndef HAVE_NO_LANGEXTRA
114struct retro_core_option_definition *option_defs_intl[RETRO_LANGUAGE_LAST] = {
115 option_defs_us, /* RETRO_LANGUAGE_ENGLISH */
116 NULL, /* RETRO_LANGUAGE_JAPANESE */
117 NULL, /* RETRO_LANGUAGE_FRENCH */
118 NULL, /* RETRO_LANGUAGE_SPANISH */
119 NULL, /* RETRO_LANGUAGE_GERMAN */
120 NULL, /* RETRO_LANGUAGE_ITALIAN */
121 NULL, /* RETRO_LANGUAGE_DUTCH */
122 NULL, /* RETRO_LANGUAGE_PORTUGUESE_BRAZIL */
123 NULL, /* RETRO_LANGUAGE_PORTUGUESE_PORTUGAL */
124 NULL, /* RETRO_LANGUAGE_RUSSIAN */
125 NULL, /* RETRO_LANGUAGE_KOREAN */
126 NULL, /* RETRO_LANGUAGE_CHINESE_TRADITIONAL */
127 NULL, /* RETRO_LANGUAGE_CHINESE_SIMPLIFIED */
128 NULL, /* RETRO_LANGUAGE_ESPERANTO */
129 NULL, /* RETRO_LANGUAGE_POLISH */
130 NULL, /* RETRO_LANGUAGE_VIETNAMESE */
131 NULL, /* RETRO_LANGUAGE_ARABIC */
132 NULL, /* RETRO_LANGUAGE_GREEK */
133 NULL, /* RETRO_LANGUAGE_TURKISH */
134 NULL, /* RETRO_LANGUAGE_SLOVAK */
135 NULL, /* RETRO_LANGUAGE_PERSIAN */
136 NULL, /* RETRO_LANGUAGE_HEBREW */
137 NULL, /* RETRO_LANGUAGE_ASTURIAN */
138 NULL, /* RETRO_LANGUAGE_FINNISH */
139 NULL, /* RETRO_LANGUAGE_INDONESIAN */
140 NULL, /* RETRO_LANGUAGE_SWEDISH */
141 NULL, /* RETRO_LANGUAGE_UKRAINIAN */
142 NULL, /* RETRO_LANGUAGE_CZECH */
143};
144#endif
145
146/*
147 ********************************
148 * Functions
149 ********************************
150*/
151
152/* Handles configuration/setting of core options.
153 * Should be called as early as possible - ideally inside
154 * retro_set_environment(), and no later than retro_load_game()
155 * > We place the function body in the header to avoid the
156 * necessity of adding more .c files (i.e. want this to
157 * be as painless as possible for core devs)
158 */
159
160static INLINE void libretro_set_core_options(retro_environment_t environ_cb)
161{
162 unsigned version = 0;
163
164 if (!environ_cb)
165 return;
166
167 if (environ_cb(RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION, &version) && (version >= 1))
168 {
169#ifndef HAVE_NO_LANGEXTRA
170 struct retro_core_options_intl core_options_intl;
171 unsigned language = 0;
172
173 core_options_intl.us = option_defs_us;
174 core_options_intl.local = NULL;
175
176 if (environ_cb(RETRO_ENVIRONMENT_GET_LANGUAGE, &language) &&
177 (language < RETRO_LANGUAGE_LAST) && (language != RETRO_LANGUAGE_ENGLISH))
178 core_options_intl.local = option_defs_intl[language];
179
180 environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_INTL, &core_options_intl);
181#else
182 environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS, &option_defs_us);
183#endif
184 }
185 else
186 {
187 size_t i;
188 size_t option_index = 0;
189 size_t num_options = 0;
190 struct retro_variable *variables = NULL;
191 char **values_buf = NULL;
192
193 /* Determine number of options
194 * > Note: We are going to skip a number of irrelevant
195 * core options when building the retro_variable array,
196 * but we'll allocate space for all of them. The difference
197 * in resource usage is negligible, and this allows us to
198 * keep the code 'cleaner' */
199 for (;;)
200 {
201 if (!option_defs_us[num_options].key)
202 break;
203 num_options++;
204 }
205
206 /* Allocate arrays */
207 variables = (struct retro_variable *)calloc(num_options + 1, sizeof(struct retro_variable));
208 values_buf = (char **)calloc(num_options, sizeof(char *));
209
210 if (!variables || !values_buf)
211 goto error;
212
213 /* Copy parameters from option_defs_us array */
214 for (i = 0; i < num_options; i++)
215 {
216 const char *key = option_defs_us[i].key;
217 const char *desc = option_defs_us[i].desc;
218 const char *default_value = option_defs_us[i].default_value;
219 struct retro_core_option_value *values = option_defs_us[i].values;
220 size_t buf_len = 3;
221 size_t default_index = 0;
222
223 values_buf[i] = NULL;
224
225 /* Skip options that are irrelevant when using the
226 * old style core options interface */
227 if (strcmp(key, "mycore_show_speedhacks") == 0)
228 continue;
229
230 if (desc)
231 {
232 size_t num_values = 0;
233
234 /* Determine number of values */
235 for (;;)
236 {
237 if (!values[num_values].value)
238 break;
239
240 /* Check if this is the default value */
241 if (default_value)
242 if (strcmp(values[num_values].value, default_value) == 0)
243 default_index = num_values;
244
245 buf_len += strlen(values[num_values].value);
246 num_values++;
247 }
248
249 /* Build values string */
250 if (num_values > 0)
251 {
252 size_t j;
253
254 buf_len += num_values - 1;
255 buf_len += strlen(desc);
256
257 values_buf[i] = (char *)calloc(buf_len, sizeof(char));
258 if (!values_buf[i])
259 goto error;
260
261 strcpy(values_buf[i], desc);
262 strcat(values_buf[i], "; ");
263
264 /* Default value goes first */
265 strcat(values_buf[i], values[default_index].value);
266
267 /* Add remaining values */
268 for (j = 0; j < num_values; j++)
269 {
270 if (j != default_index)
271 {
272 strcat(values_buf[i], "|");
273 strcat(values_buf[i], values[j].value);
274 }
275 }
276 }
277 }
278
279 variables[option_index].key = key;
280 variables[option_index].value = values_buf[i];
281 option_index++;
282 }
283
284 /* Set variables */
285 environ_cb(RETRO_ENVIRONMENT_SET_VARIABLES, variables);
286
287error:
288
289 /* Clean up */
290 if (values_buf)
291 {
292 for (i = 0; i < num_options; i++)
293 {
294 if (values_buf[i])
295 {
296 free(values_buf[i]);
297 values_buf[i] = NULL;
298 }
299 }
300
301 free(values_buf);
302 values_buf = NULL;
303 }
304
305 if (variables)
306 {
307 free(variables);
308 variables = NULL;
309 }
310 }
311}
312
313#ifdef __cplusplus
314}
315#endif
316
317#endif