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