4a2a617a |
1 | /* |
2 | * (C) GraÅžvydas "notaz" Ignotas, 2010-2011 |
3 | * |
4 | * This work is licensed under the terms of any of these licenses |
5 | * (at your option): |
6 | * - GNU GPL, version 2 or later. |
7 | * - GNU LGPL, version 2.1 or later. |
8 | * See the COPYING file in the top-level directory. |
9 | */ |
10 | |
11 | #include <stdio.h> |
12 | #include <stdlib.h> |
13 | #include <string.h> |
14 | #include <errno.h> |
15 | #include <sys/stat.h> |
16 | |
17 | #include "main.h" |
18 | #include "menu.h" |
19 | #include "input.h" |
20 | #include "settings.h" |
21 | #include "config.h" |
22 | #include "args.h" |
23 | #include "dface.h" |
24 | #include "../libpicofe/plat.h" |
25 | #include "../libpicofe/input.h" |
26 | #include "../../state.h" |
27 | #include "../../general.h" |
28 | #include "../../input.h" |
29 | #include "../../palette.h" |
30 | #include "revision.h" |
31 | |
32 | #define array_size(x) (sizeof(x) / sizeof(x[0])) |
33 | |
34 | #define state_slot CurrentState |
35 | extern uint8 Exit; |
36 | |
37 | typedef enum |
38 | { |
39 | MA_NONE = 1, |
40 | MA_CTRL_PLAYER1, |
41 | MA_CTRL_PLAYER2, |
42 | MA_CTRL_EMU, |
43 | MA_CTRL_DEADZONE, |
44 | MA_OPT_SAVECFG, |
45 | MA_OPT_SAVECFG_GAME, |
46 | MA_CTRL_DEV_FIRST, |
47 | MA_CTRL_DEV_NEXT, |
48 | MA_OPT_NTSC_COLOR, |
49 | MA_OPT_NTSC_TINT, |
50 | MA_OPT_NTSC_HUE, |
51 | MA_OPT_SREND_N, |
52 | MA_OPT_EREND_N, |
53 | MA_OPT_SREND_P, |
54 | MA_OPT_EREND_P, |
55 | MA_OPT_CLIP, |
56 | MA_OPT_NO8LIM, |
57 | MA_OPT_GG, |
58 | MA_OPT_SHOWFPS, |
59 | MA_OPT_FSKIP, |
88e59df3 |
60 | MA_OPT_SWFILTER, |
44343b87 |
61 | MA_OPT_HWFILTER, |
88e59df3 |
62 | MA_OPT_SCALING, |
4a2a617a |
63 | MA_OPT_RENDERER, |
64 | MA_OPT_SOUNDON, |
65 | MA_OPT_SOUNDRATE, |
66 | MA_OPT_REGION, |
67 | MA_OPT_TURBO, |
68 | MA_OPT_SSTATE, |
69 | MA_OPT_SSLOT, |
70 | MA_OPT_GAMMA, |
71 | MA_MAIN_RESUME_GAME, |
72 | MA_MAIN_SAVE_STATE, |
73 | MA_MAIN_LOAD_STATE, |
74 | MA_MAIN_RESET_GAME, |
75 | MA_MAIN_LOAD_ROM, |
76 | MA_MAIN_CHEATS, |
77 | MA_MAIN_CREDITS, |
78 | MA_MAIN_EXIT, |
79 | } menu_id; |
80 | |
81 | void emu_make_path(char *buff, const char *end, int size) |
82 | { |
83 | int pos, end_len; |
84 | |
85 | end_len = strlen(end); |
86 | pos = plat_get_root_dir(buff, size); |
87 | strncpy(buff + pos, end, size - pos); |
88 | buff[size - 1] = 0; |
89 | if (pos + end_len > size - 1) |
90 | printf("Warning: path truncated: %s\n", buff); |
91 | } |
92 | |
93 | static int emu_check_save_file(int slot, int *time) |
94 | { |
95 | struct stat status; |
96 | char *fname; |
97 | FILE *st; |
98 | int retval = 0; |
99 | int ret; |
100 | |
7a938870 |
101 | fname = FCEU_MakeFName(FCEUMKF_STATE, slot, 0); |
4a2a617a |
102 | st = fopen(fname,"rb"); |
103 | if (st == NULL) |
104 | goto out; |
105 | fclose(st); |
106 | |
107 | retval = 1; |
108 | if (time == NULL) |
109 | goto out; |
110 | |
111 | ret = stat(fname, &status); |
112 | if (ret != 0) |
113 | goto out; |
114 | |
115 | if (status.st_mtime < 1347000000) |
116 | goto out; // probably bad rtc like on some Caanoos |
117 | |
118 | *time = status.st_mtime; |
119 | |
120 | out: |
121 | free(fname); |
122 | return retval; |
123 | } |
124 | |
125 | static int emu_save_load_game(int load, int unused) |
126 | { |
127 | if (load) |
128 | FCEUI_LoadState(); |
129 | else |
130 | FCEUI_SaveState(); |
131 | |
132 | return 0; |
133 | } |
134 | |
135 | // rrrr rggg gggb bbbb |
136 | static unsigned short fname2color(const char *fname) |
137 | { |
138 | static const char *rom_exts[] = { ".zip", ".nes", ".fds", ".unf", |
139 | ".nez", ".unif" }; |
140 | static const char *other_exts[] = { ".nsf", ".ips", ".fcm" }; |
141 | const char *ext = strrchr(fname, '.'); |
142 | int i; |
143 | |
144 | if (ext == NULL) |
145 | return 0xffff; |
146 | for (i = 0; i < array_size(rom_exts); i++) |
147 | if (strcasecmp(ext, rom_exts[i]) == 0) |
148 | return 0xbdff; |
149 | for (i = 0; i < array_size(other_exts); i++) |
150 | if (strcasecmp(ext, other_exts[i]) == 0) |
151 | return 0xaff5; |
152 | return 0xffff; |
153 | } |
154 | |
155 | static const char *filter_exts[] = { |
156 | ".txt", ".srm", ".pnd" |
157 | }; |
158 | |
159 | #define MENU_ALIGN_LEFT |
160 | #ifdef __ARM_ARCH_7A__ // assume hires device |
161 | #define MENU_X2 1 |
162 | #else |
163 | #define MENU_X2 0 |
164 | #endif |
165 | |
166 | #include "../libpicofe/menu.c" |
167 | |
168 | static void draw_savestate_bg(int slot) |
169 | { |
170 | } |
171 | |
172 | static void debug_menu_loop(void) |
173 | { |
174 | } |
175 | |
176 | // ------------ patch/gg menu ------------ |
177 | |
178 | extern void *cheats; |
179 | static int cheat_count, cheat_start, cheat_pos; |
180 | |
181 | static int countcallb(char *name, uint32 a, uint8 v, int compare, int s, int type, void *data) |
182 | { |
183 | cheat_count++; |
184 | return 1; |
185 | } |
186 | |
187 | static int clistcallb(char *name, uint32 a, uint8 v, int compare, int s, int type, void *data) |
188 | { |
189 | int pos; |
190 | |
191 | pos = cheat_start + cheat_pos; |
192 | cheat_pos++; |
193 | if (pos < 0) return 1; |
194 | if (pos >= g_menuscreen_h / me_sfont_h) return 0; |
195 | |
196 | smalltext_out16(14, pos * me_sfont_h, s ? "ON " : "OFF", 0xffff); |
197 | smalltext_out16(14 + me_sfont_w*4, pos * me_sfont_h, type ? "S" : "R", 0xffff); |
198 | smalltext_out16(14 + me_sfont_w*6, pos * me_sfont_h, name, 0xffff); |
199 | |
200 | return 1; |
201 | } |
202 | |
203 | static void draw_patchlist(int sel) |
204 | { |
205 | int pos, max_cnt; |
206 | |
207 | menu_draw_begin(1, 1); |
208 | |
209 | max_cnt = g_menuscreen_h / me_sfont_h; |
210 | cheat_start = max_cnt / 2 - sel; |
211 | cheat_pos = 0; |
212 | FCEUI_ListCheats(clistcallb, 0); |
213 | |
214 | pos = cheat_start + cheat_pos; |
215 | if (pos < max_cnt) |
216 | smalltext_out16(14, pos * me_sfont_h, "done", 0xffff); |
217 | |
218 | text_out16(5, max_cnt / 2 * me_sfont_h, ">"); |
219 | menu_draw_end(); |
220 | } |
221 | |
222 | void patches_menu_loop(void) |
223 | { |
224 | static int menu_sel = 0; |
225 | int inp; |
226 | |
227 | cheat_count = 0; |
228 | FCEUI_ListCheats(countcallb, 0); |
229 | |
230 | for (;;) |
231 | { |
232 | draw_patchlist(menu_sel); |
233 | inp = in_menu_wait(PBTN_UP|PBTN_DOWN|PBTN_LEFT|PBTN_RIGHT|PBTN_L|PBTN_R |
234 | |PBTN_MOK|PBTN_MBACK, NULL, 33); |
235 | if (inp & PBTN_UP ) { menu_sel--; if (menu_sel < 0) menu_sel = cheat_count; } |
236 | if (inp & PBTN_DOWN) { menu_sel++; if (menu_sel > cheat_count) menu_sel = 0; } |
237 | if (inp &(PBTN_LEFT|PBTN_L)) { menu_sel-=10; if (menu_sel < 0) menu_sel = 0; } |
238 | if (inp &(PBTN_RIGHT|PBTN_R)) { menu_sel+=10; if (menu_sel > cheat_count) menu_sel = cheat_count; } |
239 | if (inp & PBTN_MOK) { // action |
240 | if (menu_sel < cheat_count) |
241 | FCEUI_ToggleCheat(menu_sel); |
242 | else break; |
243 | } |
244 | if (inp & PBTN_MBACK) |
245 | break; |
246 | } |
247 | } |
248 | |
249 | // -------------- key config -------------- |
250 | |
251 | // b_turbo,a_turbo RLDU SEBA |
252 | me_bind_action me_ctrl_actions[] = |
253 | { |
254 | { "UP ", NKEY_UP }, |
255 | { "DOWN ", NKEY_DOWN }, |
256 | { "LEFT ", NKEY_LEFT }, |
257 | { "RIGHT ", NKEY_RIGHT }, |
258 | { "A ", NKEY_A }, |
259 | { "B ", NKEY_B }, |
260 | { "A TURBO", NKEY_A_TURBO }, |
261 | { "B TURBO", NKEY_B_TURBO }, |
262 | { "START ", NKEY_START }, |
263 | { "SELECT ", NKEY_SELECT }, |
264 | { NULL, 0 } |
265 | }; |
266 | |
267 | me_bind_action emuctrl_actions[] = |
268 | { |
269 | { "Save State ", EACT_SAVE_STATE }, |
270 | { "Load State ", EACT_LOAD_STATE }, |
271 | { "Next State Slot ", EACT_NEXT_SLOT }, |
272 | { "Prev State Slot ", EACT_PREV_SLOT }, |
273 | { "FDS Insert/Eject ", EACT_FDS_INSERT }, |
274 | { "FDS Select Disk ", EACT_FDS_SELECT }, |
275 | { "VSUni Insert Coin", EACT_INSERT_COIN }, |
276 | { "Enter Menu ", EACT_ENTER_MENU }, |
277 | { NULL, 0 } |
278 | }; |
279 | |
280 | static int key_config_loop_wrap(int id, int keys) |
281 | { |
282 | switch (id) { |
283 | case MA_CTRL_PLAYER1: |
284 | key_config_loop(me_ctrl_actions, array_size(me_ctrl_actions) - 1, 0); |
285 | break; |
286 | case MA_CTRL_PLAYER2: |
287 | key_config_loop(me_ctrl_actions, array_size(me_ctrl_actions) - 1, 1); |
288 | break; |
289 | case MA_CTRL_EMU: |
290 | key_config_loop(emuctrl_actions, array_size(emuctrl_actions) - 1, -1); |
291 | break; |
292 | default: |
293 | break; |
294 | } |
295 | return 0; |
296 | } |
297 | |
298 | static const char *mgn_dev_name(int id, int *offs) |
299 | { |
300 | const char *name = NULL; |
301 | static int it = 0; |
302 | |
303 | if (id == MA_CTRL_DEV_FIRST) |
304 | it = 0; |
305 | |
306 | for (; it < IN_MAX_DEVS; it++) { |
307 | name = in_get_dev_name(it, 1, 1); |
308 | if (name != NULL) |
309 | break; |
310 | } |
311 | |
312 | it++; |
313 | return name; |
314 | } |
315 | |
316 | static const char *mgn_saveloadcfg(int id, int *offs) |
317 | { |
318 | return ""; |
319 | } |
320 | |
321 | static void config_commit(void); |
322 | |
323 | static int mh_savecfg(int id, int keys) |
324 | { |
325 | const char *fname = NULL; |
326 | if (id == MA_OPT_SAVECFG_GAME) |
327 | fname = lastLoadedGameName; |
328 | |
329 | config_commit(); |
330 | if (SaveConfig(fname) == 0) |
331 | menu_update_msg("config saved"); |
332 | else |
333 | menu_update_msg("failed to write config"); |
334 | |
335 | return 1; |
336 | } |
337 | |
338 | static int mh_input_rescan(int id, int keys) |
339 | { |
340 | //menu_sync_config(); |
341 | in_probe(); |
342 | menu_update_msg("rescan complete."); |
343 | |
344 | return 0; |
345 | } |
346 | |
347 | static menu_entry e_menu_keyconfig[] = |
348 | { |
349 | mee_handler_id("Player 1", MA_CTRL_PLAYER1, key_config_loop_wrap), |
350 | mee_handler_id("Player 2", MA_CTRL_PLAYER2, key_config_loop_wrap), |
351 | mee_handler_id("Emulator controls", MA_CTRL_EMU, key_config_loop_wrap), |
352 | mee_label (""), |
353 | // mee_range ("Analog deadzone", MA_CTRL_DEADZONE, analog_deadzone, 1, 99), |
354 | mee_cust_nosave("Save global config", MA_OPT_SAVECFG, mh_savecfg, mgn_saveloadcfg), |
355 | mee_cust_nosave("Save cfg for loaded game", MA_OPT_SAVECFG_GAME, mh_savecfg, mgn_saveloadcfg), |
356 | mee_handler ("Rescan devices:", mh_input_rescan), |
357 | mee_label (""), |
358 | mee_label_mk (MA_CTRL_DEV_FIRST, mgn_dev_name), |
359 | mee_label_mk (MA_CTRL_DEV_NEXT, mgn_dev_name), |
360 | mee_label_mk (MA_CTRL_DEV_NEXT, mgn_dev_name), |
361 | mee_label_mk (MA_CTRL_DEV_NEXT, mgn_dev_name), |
362 | mee_label_mk (MA_CTRL_DEV_NEXT, mgn_dev_name), |
363 | mee_label_mk (MA_CTRL_DEV_NEXT, mgn_dev_name), |
364 | mee_label_mk (MA_CTRL_DEV_NEXT, mgn_dev_name), |
365 | mee_end, |
366 | }; |
367 | |
368 | static int menu_loop_keyconfig(int id, int keys) |
369 | { |
370 | static int sel = 0; |
371 | |
372 | me_loop(e_menu_keyconfig, &sel); |
373 | return 0; |
374 | } |
375 | |
376 | // --------- FCEU options ---------- |
377 | |
378 | extern int ntsccol,ntschue,ntsctint; |
379 | extern int srendlinev[2]; |
380 | extern int erendlinev[2]; |
381 | extern int eoptions; |
382 | extern char *cpalette; |
383 | extern void LoadCPalette(void); |
384 | |
385 | static menu_entry e_menu_fceu_options[] = |
386 | { |
387 | //gp2x_text_out15(tl_x, y, "Custom palette: %s", cpal); |
388 | mee_onoff ("NTSC Color Emulation", MA_OPT_NTSC_COLOR, ntsccol, 1), |
389 | mee_range (" Tint (default: 56)", MA_OPT_NTSC_TINT, ntsctint, 0, 128), |
390 | mee_range (" Hue (default: 72)", MA_OPT_NTSC_HUE, ntschue, 0, 128), |
391 | mee_range ("First visible line (NTSC)", MA_OPT_SREND_N, srendlinev[0], 0, 239), |
392 | mee_range ("Last visible line (NTSC)", MA_OPT_EREND_N, erendlinev[0], 0, 239), |
393 | mee_range ("First visible line (PAL)", MA_OPT_SREND_P, srendlinev[1], 0, 239), |
394 | mee_range ("Last visible line (PAL)", MA_OPT_EREND_P, erendlinev[1], 0, 239), |
395 | mee_onoff ("Clip 8 left/right columns", MA_OPT_CLIP, eoptions, EO_CLIPSIDES), |
396 | mee_onoff ("Disable 8 sprite limit", MA_OPT_NO8LIM, eoptions, EO_NO8LIM), |
397 | mee_onoff ("Enable authentic GameGenie",MA_OPT_GG, eoptions, EO_GG), |
398 | mee_end, |
399 | }; |
400 | |
401 | static int menu_loop_fceu_options(int id, int keys) |
402 | { |
403 | static int sel = 0; |
404 | int i; |
405 | |
406 | FCEUI_GetNTSCTH(&ntsctint, &ntschue); |
407 | |
408 | me_loop(e_menu_fceu_options, &sel); |
409 | |
410 | for(i = 0; i < 2; i++) |
411 | { |
412 | if (srendlinev[i] < 0 || srendlinev[i] > 239) |
413 | srendlinev[i] = 0; |
414 | if (erendlinev[i] < srendlinev[i] || erendlinev[i] > 239) |
415 | erendlinev[i] = 239; |
416 | } |
417 | FCEUI_SetNTSCTH(ntsccol, ntsctint, ntschue); |
418 | FCEUI_SetRenderedLines(srendlinev[0],erendlinev[0],srendlinev[1],erendlinev[1]); |
419 | FCEUI_DisableSpriteLimitation(eoptions&EO_NO8LIM); |
420 | FCEUI_SetGameGenie(eoptions&EO_GG); |
421 | //if (cpalette) LoadCPalette(); |
422 | //else |
423 | FCEUI_SetPaletteArray(0); // set to default |
424 | FCEU_ResetPalette(); |
425 | |
426 | return 0; |
427 | } |
428 | |
429 | // -------------- options -------------- |
430 | |
431 | static const char *men_frameskip[] = { "Auto", "0", "1", "2", "3", "4", NULL }; |
88e59df3 |
432 | static const char *men_swfilter[] = { "none", "Scale2x", "Eagle2x", NULL }; |
44343b87 |
433 | static const char *men_scaling[] = { "1x", "proportional", "4:3 scaled", "fullscreen", NULL }; |
4a2a617a |
434 | static const char *men_rates[] = { "8000", "11025", "16000", "22050", "44100", NULL }; |
435 | static const int men_rates_i[] = { 8000 , 11025 , 16000 , 22050 , 44100 }; |
436 | static const char *men_region[] = { "Auto", "NTSC", "PAL", NULL }; |
437 | static const char *men_sstate[] = { "OFF", "writes", "loads", "both", NULL }; |
438 | static const char h_renderer[] = "ROM reload required for this\n" |
439 | "setting to take effect"; |
440 | |
441 | static int sndrate_i; |
442 | static int sndon; |
443 | static int turbo_i; |
7a938870 |
444 | static int frameskip_i; |
4a2a617a |
445 | |
446 | static void config_commit(void) |
447 | { |
448 | Settings.sound_rate = men_rates_i[sndrate_i]; |
b054fd77 |
449 | soundvol = sndon ? 50 : 0; |
4a2a617a |
450 | Settings.turbo_rate_add = (turbo_i * 2 << 24) / 60 + 1; |
7a938870 |
451 | Settings.frameskip = frameskip_i - 1; |
4a2a617a |
452 | |
453 | if (Settings.region_force) |
454 | FCEUI_SetVidSystem(Settings.region_force - 1); |
455 | } |
456 | |
457 | static menu_entry e_menu_options[] = |
458 | { |
44343b87 |
459 | // mee_onoff ("Show FPS", MA_OPT_SHOWFPS, Settings.showfps, 1), |
7a938870 |
460 | mee_enum ("Frameskip", MA_OPT_FSKIP, frameskip_i, men_frameskip), |
88e59df3 |
461 | mee_enum ("Softwere filter", MA_OPT_SWFILTER, Settings.sw_filter, men_swfilter), |
462 | mee_enum ("Hardware filter", MA_OPT_HWFILTER, Settings.hw_filter, NULL), |
44343b87 |
463 | mee_enum ("Scaling", MA_OPT_SCALING, Settings.scaling, men_scaling), |
4a2a617a |
464 | mee_onoff_h ("Accurate renderer (slow)",MA_OPT_RENDERER, Settings.accurate_mode, 1, h_renderer), |
465 | mee_onoff ("Enable sound", MA_OPT_SOUNDON, sndon, 1), |
466 | mee_enum ("Sound Rate", MA_OPT_SOUNDRATE, sndrate_i, men_rates), |
467 | mee_enum ("Region", MA_OPT_REGION, Settings.region_force, men_region), |
468 | mee_range ("Turbo rate (Hz)", MA_OPT_TURBO, turbo_i, 1, 30), |
469 | mee_enum ("Confirm savestate", MA_OPT_SSTATE, Settings.sstate_confirm, men_sstate), |
470 | mee_range ("Save slot", MA_OPT_SSLOT, CurrentState, 0, 9), |
44343b87 |
471 | // mee_range ("Gamma correction", MA_OPT_GAMMA, Settings.gamma, 0, 300), |
4a2a617a |
472 | mee_handler ("[FCE Ultra options]", menu_loop_fceu_options), |
473 | mee_cust_nosave("Save global config", MA_OPT_SAVECFG, mh_savecfg, mgn_saveloadcfg), |
474 | mee_cust_nosave("Save cfg for loaded game",MA_OPT_SAVECFG_GAME, mh_savecfg, mgn_saveloadcfg), |
475 | mee_end, |
476 | }; |
477 | |
478 | static int menu_loop_options(int id, int keys) |
479 | { |
480 | static int sel = 0; |
481 | int oldrate; |
482 | int i; |
483 | |
44343b87 |
484 | i = me_id2offset(e_menu_options, MA_OPT_HWFILTER); |
485 | e_menu_options[i].data = plat_target.filters; |
486 | me_enable(e_menu_options, MA_OPT_HWFILTER, plat_target.filters != NULL); |
487 | |
4a2a617a |
488 | oldrate = Settings.sound_rate; |
489 | for (i = 0; i < array_size(men_rates_i); i++) { |
490 | if (Settings.sound_rate == men_rates_i[i]) { |
491 | sndrate_i = i; |
492 | break; |
493 | } |
494 | } |
495 | sndon = soundvol != 0; |
496 | turbo_i = (Settings.turbo_rate_add * 60 / 2) >> 24; |
7a938870 |
497 | frameskip_i = Settings.frameskip + 1; |
4a2a617a |
498 | |
499 | me_loop(e_menu_options, &sel); |
500 | |
501 | config_commit(); |
502 | if (oldrate != Settings.sound_rate) |
503 | InitSound(); |
504 | |
505 | return 0; |
506 | } |
507 | |
508 | // -------------- root menu -------------- |
509 | |
510 | static const char credits_text[] = |
511 | "GPFCE " REV "\n" |
512 | "(c) notaz, 2007,2012\n\n" |
513 | "Based on FCE Ultra versions\n" |
514 | "0.81 and 0.98.1x\n\n" |
515 | " - Credits -\n" |
516 | "Bero: FCE\n" |
517 | "Xodnizel: FCE Ultra\n" |
88e59df3 |
518 | "FCA author: 6502 core\n" |
519 | "M-HT: NEON scalers\n"; |
4a2a617a |
520 | |
521 | static void draw_frame_credits(void) |
522 | { |
523 | smalltext_out16(4, 1, "build: " __DATE__ " " __TIME__ " " REV, 0xe7fc); |
524 | } |
525 | |
526 | static int romsel_run(void) |
527 | { |
528 | const char *fname; |
529 | |
530 | fname = menu_loop_romsel(lastLoadedGameName, sizeof(lastLoadedGameName)); |
531 | if (fname == NULL) |
532 | return -1; |
533 | |
534 | printf("selected file: %s\n", fname); |
535 | //keys_load_all(cfg); |
536 | |
537 | strcpy(lastLoadedGameName, rom_fname_reload); |
538 | return 0; |
539 | } |
540 | |
541 | static int menu_loop_ret; |
542 | |
543 | static int main_menu_handler(int id, int keys) |
544 | { |
545 | switch (id) |
546 | { |
547 | case MA_MAIN_RESUME_GAME: |
548 | if (fceugi) |
549 | return 1; |
550 | break; |
551 | case MA_MAIN_SAVE_STATE: |
552 | if (fceugi) { |
4a2a617a |
553 | return menu_loop_savestate(0); |
554 | } |
555 | break; |
556 | case MA_MAIN_LOAD_STATE: |
557 | if (fceugi) { |
4a2a617a |
558 | return menu_loop_savestate(1); |
559 | } |
560 | break; |
561 | case MA_MAIN_RESET_GAME: |
562 | if (fceugi) { |
563 | FCEU_DoSimpleCommand(FCEUNPCMD_RESET); |
7a938870 |
564 | return 1; |
4a2a617a |
565 | } |
566 | break; |
567 | case MA_MAIN_LOAD_ROM: |
568 | if (romsel_run() == 0) { |
569 | menu_loop_ret = 2; |
570 | return 1; |
571 | } |
572 | break; |
573 | case MA_MAIN_CREDITS: |
574 | draw_menu_message(credits_text, draw_frame_credits); |
575 | in_menu_wait(PBTN_MOK|PBTN_MBACK, NULL, 70); |
576 | break; |
577 | case MA_MAIN_EXIT: |
578 | menu_loop_ret = 1; |
579 | return 1; |
580 | default: |
581 | lprintf("%s: something unknown selected\n", __FUNCTION__); |
582 | break; |
583 | } |
584 | |
585 | return 0; |
586 | } |
587 | |
588 | static menu_entry e_menu_main[] = |
589 | { |
590 | mee_handler_id("Resume game", MA_MAIN_RESUME_GAME, main_menu_handler), |
591 | mee_handler_id("Save State", MA_MAIN_SAVE_STATE, main_menu_handler), |
592 | mee_handler_id("Load State", MA_MAIN_LOAD_STATE, main_menu_handler), |
593 | mee_handler_id("Reset game", MA_MAIN_RESET_GAME, main_menu_handler), |
594 | mee_handler_id("Load ROM", MA_MAIN_LOAD_ROM, main_menu_handler), |
595 | mee_handler ("Options", menu_loop_options), |
596 | mee_handler ("Controls", menu_loop_keyconfig), |
597 | mee_handler_id("Cheats", MA_MAIN_CHEATS, main_menu_handler), |
598 | mee_handler_id("Credits", MA_MAIN_CREDITS, main_menu_handler), |
599 | mee_handler_id("Exit", MA_MAIN_EXIT, main_menu_handler), |
600 | mee_end, |
601 | }; |
602 | |
603 | // ---------------------------- |
604 | |
605 | int menu_loop(void) |
606 | { |
607 | static int sel = 0; |
608 | |
609 | menu_loop_ret = 0; |
610 | |
611 | me_enable(e_menu_main, MA_MAIN_RESUME_GAME, fceugi != NULL); |
612 | me_enable(e_menu_main, MA_MAIN_SAVE_STATE, fceugi != NULL); |
613 | me_enable(e_menu_main, MA_MAIN_LOAD_STATE, fceugi != NULL); |
614 | me_enable(e_menu_main, MA_MAIN_RESET_GAME, fceugi != NULL); |
615 | me_enable(e_menu_main, MA_MAIN_CHEATS, fceugi && cheats); |
616 | |
617 | plat_video_menu_enter(fceugi != NULL); |
44343b87 |
618 | memcpy(g_menubg_ptr, g_menubg_src_ptr, g_menuscreen_w * g_menuscreen_h * 2); |
4a2a617a |
619 | in_set_config_int(0, IN_CFG_BLOCKING, 1); |
620 | |
621 | do { |
622 | me_loop_d(e_menu_main, &sel, NULL, NULL); |
b054fd77 |
623 | } while (!fceugi && menu_loop_ret == 0); |
4a2a617a |
624 | |
625 | /* wait until menu, ok, back is released */ |
626 | while (in_menu_wait_any(NULL, 50) & (PBTN_MENU|PBTN_MOK|PBTN_MBACK)) |
627 | ; |
628 | |
629 | in_set_config_int(0, IN_CFG_BLOCKING, 0); |
630 | plat_video_menu_leave(); |
631 | |
7a938870 |
632 | Exit = 0; |
4a2a617a |
633 | return menu_loop_ret; |
634 | } |
635 | |
636 | void menu_init(void) |
637 | { |
638 | char buff[256]; |
639 | |
640 | g_border_style = 1; |
641 | menu_init_base(); |
642 | |
643 | //menu_load_config(0); |
644 | |
645 | g_menubg_src_ptr = calloc(g_menuscreen_w * g_menuscreen_h * 2, 1); |
646 | g_menubg_ptr = calloc(g_menuscreen_w * g_menuscreen_h * 2, 1); |
647 | if (g_menubg_src_ptr == NULL || g_menubg_ptr == NULL) { |
648 | fprintf(stderr, "OOM\n"); |
649 | exit(1); |
650 | } |
651 | |
652 | emu_make_path(buff, "skin/background.png", sizeof(buff)); |
653 | readpng(g_menubg_src_ptr, buff, READPNG_BG, g_menuscreen_w, g_menuscreen_h); |
654 | } |
655 | |
656 | void menu_update_msg(const char *msg) |
657 | { |
658 | strncpy(menu_error_msg, msg, sizeof(menu_error_msg)); |
659 | menu_error_msg[sizeof(menu_error_msg) - 1] = 0; |
660 | |
661 | menu_error_time = plat_get_ticks_ms(); |
662 | lprintf("msg: %s\n", menu_error_msg); |
663 | } |
664 | |