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