refactor OSD code and PCNT stuff
[pcsx_rearmed.git] / frontend / menu.c
... / ...
CommitLineData
1/*
2 * (C) GraÅžvydas "notaz" Ignotas, 2010
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 <string.h>
13
14#include "config.h"
15#include "plugin_lib.h"
16#include "omap.h"
17#include "common/plat.h"
18#include "../libpcsxcore/misc.h"
19#include "../libpcsxcore/new_dynarec/new_dynarec.h"
20
21#define MENU_X2 1
22#define array_size(x) (sizeof(x) / sizeof(x[0]))
23
24typedef enum
25{
26 MA_NONE = 1,
27 MA_MAIN_RESUME_GAME,
28 MA_MAIN_SAVE_STATE,
29 MA_MAIN_LOAD_STATE,
30 MA_MAIN_RESET_GAME,
31 MA_MAIN_LOAD_ROM,
32 MA_MAIN_CONTROLS,
33 MA_MAIN_CREDITS,
34 MA_MAIN_EXIT,
35 MA_CTRL_PLAYER1,
36 MA_CTRL_PLAYER2,
37 MA_CTRL_EMU,
38 MA_CTRL_DEV_FIRST,
39 MA_CTRL_DEV_NEXT,
40 MA_CTRL_DONE,
41 MA_OPT_SAVECFG,
42 MA_OPT_SAVECFG_GAME,
43 MA_OPT_CPU_CLOCKS,
44} menu_id;
45
46extern int ready_to_go;
47
48static int dummy, state_slot;
49static char rom_fname_reload[MAXPATHLEN];
50static char last_selected_fname[MAXPATHLEN];
51
52void emu_make_path(char *buff, const char *end, int size)
53{
54 int pos, end_len;
55
56 end_len = strlen(end);
57 pos = plat_get_root_dir(buff, size);
58 strncpy(buff + pos, end, size - pos);
59 buff[size - 1] = 0;
60 if (pos + end_len > size - 1)
61 printf("Warning: path truncated: %s\n", buff);
62}
63
64static int emu_check_save_file(int slot)
65{
66 return 0;
67}
68
69static int emu_save_load_game(int load, int sram)
70{
71 return 0;
72}
73
74static int emu_write_config(int is_game)
75{
76 return 0;
77}
78
79static void emu_set_defconfig(void)
80{
81}
82
83#include "common/menu.c"
84
85static void draw_savestate_bg(int slot)
86{
87}
88
89// -------------- key config --------------
90
91me_bind_action me_ctrl_actions[] =
92{
93 { "UP ", 1 << DKEY_UP},
94 { "DOWN ", 1 << DKEY_DOWN },
95 { "LEFT ", 1 << DKEY_LEFT },
96 { "RIGHT ", 1 << DKEY_RIGHT },
97 { "TRIANGLE", 1 << DKEY_TRIANGLE },
98 { "CIRCLE ", 1 << DKEY_SQUARE },
99 { "CROSS ", 1 << DKEY_CROSS },
100 { "SQUARE ", 1 << DKEY_SQUARE },
101 { "L1 ", 1 << DKEY_L1 },
102 { "R1 ", 1 << DKEY_R1 },
103 { "L2 ", 1 << DKEY_L2 },
104 { "R2 ", 1 << DKEY_R2 },
105 { "START ", 1 << DKEY_START },
106 { "SELECT ", 1 << DKEY_SELECT },
107 { NULL, 0 }
108};
109
110me_bind_action emuctrl_actions[] =
111{
112 { "Load State ", PEV_STATE_LOAD },
113 { "Save State ", PEV_STATE_SAVE },
114 { "Prev Save Slot ", PEV_SSLOT_PREV },
115 { "Next Save Slot ", PEV_SSLOT_NEXT },
116 { "Enter Menu ", PEV_MENU },
117 { NULL, 0 }
118};
119
120static int key_config_loop_wrap(int id, int keys)
121{
122 switch (id) {
123 case MA_CTRL_PLAYER1:
124 key_config_loop(me_ctrl_actions, array_size(me_ctrl_actions) - 1, 0);
125 break;
126 case MA_CTRL_PLAYER2:
127 key_config_loop(me_ctrl_actions, array_size(me_ctrl_actions) - 1, 1);
128 break;
129 case MA_CTRL_EMU:
130 key_config_loop(emuctrl_actions, array_size(emuctrl_actions) - 1, -1);
131 break;
132 default:
133 break;
134 }
135 return 0;
136}
137
138static const char *mgn_dev_name(int id, int *offs)
139{
140 const char *name = NULL;
141 static int it = 0;
142
143 if (id == MA_CTRL_DEV_FIRST)
144 it = 0;
145
146 for (; it < IN_MAX_DEVS; it++) {
147 name = in_get_dev_name(it, 1, 1);
148 if (name != NULL)
149 break;
150 }
151
152 it++;
153 return name;
154}
155
156static const char *mgn_saveloadcfg(int id, int *offs)
157{
158 return "";
159}
160
161static int mh_saveloadcfg(int id, int keys)
162{
163 switch (id) {
164 case MA_OPT_SAVECFG:
165 case MA_OPT_SAVECFG_GAME:
166 if (emu_write_config(id == MA_OPT_SAVECFG_GAME ? 1 : 0))
167 me_update_msg("config saved");
168 else
169 me_update_msg("failed to write config");
170 break;
171 default:
172 return 0;
173 }
174
175 return 1;
176}
177
178static menu_entry e_menu_keyconfig[] =
179{
180 mee_handler_id("Player 1", MA_CTRL_PLAYER1, key_config_loop_wrap),
181 mee_handler_id("Player 2", MA_CTRL_PLAYER2, key_config_loop_wrap),
182 mee_handler_id("Emulator controls", MA_CTRL_EMU, key_config_loop_wrap),
183 mee_cust_nosave("Save global config", MA_OPT_SAVECFG, mh_saveloadcfg, mgn_saveloadcfg),
184 mee_cust_nosave("Save cfg for loaded game", MA_OPT_SAVECFG_GAME, mh_saveloadcfg, mgn_saveloadcfg),
185 mee_label (""),
186 mee_label ("Input devices:"),
187 mee_label_mk (MA_CTRL_DEV_FIRST, mgn_dev_name),
188 mee_label_mk (MA_CTRL_DEV_NEXT, mgn_dev_name),
189 mee_label_mk (MA_CTRL_DEV_NEXT, mgn_dev_name),
190 mee_label_mk (MA_CTRL_DEV_NEXT, mgn_dev_name),
191 mee_label_mk (MA_CTRL_DEV_NEXT, mgn_dev_name),
192 mee_label_mk (MA_CTRL_DEV_NEXT, mgn_dev_name),
193 mee_label_mk (MA_CTRL_DEV_NEXT, mgn_dev_name),
194 mee_end,
195};
196
197static int menu_loop_keyconfig(int id, int keys)
198{
199 static int sel = 0;
200
201 me_enable(e_menu_keyconfig, MA_OPT_SAVECFG_GAME, ready_to_go);
202 me_loop(e_menu_keyconfig, &sel, NULL);
203 return 0;
204}
205
206// ------------ adv options menu ------------
207
208static menu_entry e_menu_adv_options[] =
209{
210 mee_onoff ("captain placeholder", 0, dummy, 1),
211 mee_end,
212};
213
214static int menu_loop_adv_options(int id, int keys)
215{
216 static int sel = 0;
217 me_loop(e_menu_adv_options, &sel, NULL);
218 return 0;
219}
220
221// ------------ gfx options menu ------------
222
223static menu_entry e_menu_gfx_options[] =
224{
225 mee_end,
226};
227
228static int menu_loop_gfx_options(int id, int keys)
229{
230 static int sel = 0;
231
232 me_loop(e_menu_gfx_options, &sel, NULL);
233
234 return 0;
235}
236
237// ------------ options menu ------------
238
239static menu_entry e_menu_options[];
240
241static int mh_restore_defaults(int id, int keys)
242{
243 emu_set_defconfig();
244 me_update_msg("defaults restored");
245 return 1;
246}
247
248static const char *men_confirm_save[] = { "OFF", "writes", "loads", "both", NULL };
249static const char h_confirm_save[] = "Ask for confirmation when overwriting save,\n"
250 "loading state or both";
251
252static menu_entry e_menu_options[] =
253{
254 mee_range ("Save slot", 0, state_slot, 0, 9),
255 mee_enum_h ("Confirm savestate", 0, dummy, men_confirm_save, h_confirm_save),
256 mee_range ("", MA_OPT_CPU_CLOCKS, dummy, 20, 5000),
257 mee_handler ("[Display]", menu_loop_gfx_options),
258 mee_handler ("[Advanced]", menu_loop_adv_options),
259 mee_cust_nosave("Save global config", MA_OPT_SAVECFG, mh_saveloadcfg, mgn_saveloadcfg),
260 mee_cust_nosave("Save cfg for loaded game",MA_OPT_SAVECFG_GAME, mh_saveloadcfg, mgn_saveloadcfg),
261 mee_handler ("Restore defaults", mh_restore_defaults),
262 mee_end,
263};
264
265static int menu_loop_options(int id, int keys)
266{
267 static int sel = 0;
268 int i;
269
270 i = me_id2offset(e_menu_options, MA_OPT_CPU_CLOCKS);
271 e_menu_options[i].enabled = e_menu_options[i].name[0] ? 1 : 0;
272 me_enable(e_menu_options, MA_OPT_SAVECFG_GAME, ready_to_go);
273
274 me_loop(e_menu_options, &sel, NULL);
275
276 return 0;
277}
278
279// ------------ debug menu ------------
280
281#ifdef __GNUC__
282#define COMPILER "gcc " __VERSION__
283#else
284#define COMPILER
285#endif
286
287static void draw_frame_debug(void)
288{
289 smalltext_out16(4, 1, "build: "__DATE__ " " __TIME__ " " COMPILER, 0xffff);
290}
291
292static void debug_menu_loop(void)
293{
294 int inp;
295
296 while (1)
297 {
298 menu_draw_begin(1);
299 draw_frame_debug();
300 menu_draw_end();
301
302 inp = in_menu_wait(PBTN_MOK|PBTN_MBACK|PBTN_MA2|PBTN_MA3|PBTN_L|PBTN_R |
303 PBTN_UP|PBTN_DOWN|PBTN_LEFT|PBTN_RIGHT, 70);
304 if (inp & PBTN_MBACK)
305 return;
306 }
307}
308
309// ------------ main menu ------------
310
311const char *plat_get_credits(void)
312{
313 return "(C) 1999-2003 PCSX Team\n"
314 "(C) 2005-2009 PCSX-df Team\n"
315 "(C) 2009-2010 PCSX-Reloaded Team\n\n"
316 "GPU and SPU code by Pete Bernert\n"
317 " and the P.E.Op.S. team\n"
318 "ARM recompiler by Ari64\n\n"
319 "integration, optimization and\n"
320 " frontend by (C) notaz, 2010\n";
321}
322
323static char *romsel_run(void)
324{
325 char *ret;
326
327 ret = menu_loop_romsel(last_selected_fname, sizeof(last_selected_fname));
328 if (ret == NULL)
329 return NULL;
330
331 lprintf("selected file: %s\n", ret);
332 ready_to_go = 0;
333
334 SetIsoFile(ret);
335 LoadPlugins();
336 NetOpened = 0;
337 if (OpenPlugins() == -1) {
338 me_update_msg("failed to open plugins");
339 return NULL;
340 }
341
342 SysReset();
343
344 if (CheckCdrom() == -1) {
345 // Only check the CD if we are starting the console with a CD
346 ClosePlugins();
347 me_update_msg("unsupported/invalid CD image");
348 return NULL;
349 }
350
351 // Read main executable directly from CDRom and start it
352 if (LoadCdrom() == -1) {
353 ClosePlugins();
354 me_update_msg("failed to load CD image");
355 return NULL;
356 }
357
358 ready_to_go = 1;
359 return ret;
360}
361
362static int main_menu_handler(int id, int keys)
363{
364 char *ret_name;
365
366 switch (id)
367 {
368 case MA_MAIN_RESUME_GAME:
369 break;
370 case MA_MAIN_SAVE_STATE:
371 if (ready_to_go)
372 return menu_loop_savestate(0);
373 break;
374 case MA_MAIN_LOAD_STATE:
375 if (ready_to_go)
376 return menu_loop_savestate(1);
377 break;
378 case MA_MAIN_RESET_GAME:
379 break;
380 case MA_MAIN_LOAD_ROM:
381 ret_name = romsel_run();
382 if (ret_name != NULL)
383 return 1;
384 break;
385 case MA_MAIN_CREDITS:
386 draw_menu_credits();
387 in_menu_wait(PBTN_MOK|PBTN_MBACK, 70);
388 break;
389 case MA_MAIN_EXIT:
390 exit(1); // FIXME
391 default:
392 lprintf("%s: something unknown selected\n", __FUNCTION__);
393 break;
394 }
395
396 return 0;
397}
398
399static menu_entry e_menu_main[] =
400{
401 mee_label (""),
402 mee_label (""),
403 mee_handler_id("Resume game", MA_MAIN_RESUME_GAME, main_menu_handler),
404 mee_handler_id("Save State", MA_MAIN_SAVE_STATE, main_menu_handler),
405 mee_handler_id("Load State", MA_MAIN_LOAD_STATE, main_menu_handler),
406 mee_handler_id("Reset game", MA_MAIN_RESET_GAME, main_menu_handler),
407 mee_handler_id("Load CD image", MA_MAIN_LOAD_ROM, main_menu_handler),
408 mee_handler ("Options", menu_loop_options),
409 mee_handler ("Controls", menu_loop_keyconfig),
410 mee_handler_id("Credits", MA_MAIN_CREDITS, main_menu_handler),
411 mee_handler_id("Exit", MA_MAIN_EXIT, main_menu_handler),
412 mee_end,
413};
414
415void menu_loop(void)
416{
417 static int sel = 0;
418
419 omap_enable_layer(0);
420
421 me_enable(e_menu_main, MA_MAIN_RESUME_GAME, ready_to_go);
422 me_enable(e_menu_main, MA_MAIN_SAVE_STATE, ready_to_go);
423 me_enable(e_menu_main, MA_MAIN_LOAD_STATE, ready_to_go);
424 me_enable(e_menu_main, MA_MAIN_RESET_GAME, ready_to_go);
425
426strcpy(last_selected_fname, "/mnt/ntz/stuff/psx");
427 menu_enter(ready_to_go);
428 in_set_config_int(0, IN_CFG_BLOCKING, 1);
429
430 do {
431 me_loop(e_menu_main, &sel, NULL);
432 } while (!ready_to_go);
433
434 /* wait until menu, ok, back is released */
435 while (in_menu_wait_any(50) & (PBTN_MENU|PBTN_MOK|PBTN_MBACK))
436 ;
437
438 in_set_config_int(0, IN_CFG_BLOCKING, 0);
439
440 memset(g_menuscreen_ptr, 0, g_menuscreen_w * g_menuscreen_h * 2);
441 menu_draw_end();
442 omap_enable_layer(1);
443 stop = 0;
444}
445
446void me_update_msg(const char *msg)
447{
448 strncpy(menu_error_msg, msg, sizeof(menu_error_msg));
449 menu_error_msg[sizeof(menu_error_msg) - 1] = 0;
450
451 menu_error_time = plat_get_ticks_ms();
452 lprintf("msg: %s\n", menu_error_msg);
453}
454