69af03a2 |
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" |
7eda34c1 |
19 | #include "../libpcsxcore/new_dynarec/new_dynarec.h" |
69af03a2 |
20 | |
21 | #define MENU_X2 1 |
22 | #define array_size(x) (sizeof(x) / sizeof(x[0])) |
23 | |
24 | typedef 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 | |
46 | extern int ready_to_go; |
47 | |
48 | static int dummy, state_slot; |
49 | static char rom_fname_reload[MAXPATHLEN]; |
50 | static char last_selected_fname[MAXPATHLEN]; |
51 | |
52 | void 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 | |
64 | static int emu_check_save_file(int slot) |
65 | { |
66 | return 0; |
67 | } |
68 | |
69 | static int emu_save_load_game(int load, int sram) |
70 | { |
71 | return 0; |
72 | } |
73 | |
74 | static int emu_write_config(int is_game) |
75 | { |
76 | return 0; |
77 | } |
78 | |
79 | static void emu_set_defconfig(void) |
80 | { |
81 | } |
82 | |
83 | #include "common/menu.c" |
84 | |
85 | static void draw_savestate_bg(int slot) |
86 | { |
87 | } |
88 | |
89 | // -------------- key config -------------- |
90 | |
91 | me_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 | |
110 | me_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 | |
120 | static 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 | |
138 | static 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 | |
156 | static const char *mgn_saveloadcfg(int id, int *offs) |
157 | { |
158 | return ""; |
159 | } |
160 | |
161 | static 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 | |
178 | static 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 | |
197 | static 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 | |
208 | static menu_entry e_menu_adv_options[] = |
209 | { |
210 | mee_onoff ("captain placeholder", 0, dummy, 1), |
211 | mee_end, |
212 | }; |
213 | |
214 | static 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 | |
223 | static menu_entry e_menu_gfx_options[] = |
224 | { |
225 | mee_end, |
226 | }; |
227 | |
228 | static 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 | |
239 | static menu_entry e_menu_options[]; |
240 | |
241 | static int mh_restore_defaults(int id, int keys) |
242 | { |
243 | emu_set_defconfig(); |
244 | me_update_msg("defaults restored"); |
245 | return 1; |
246 | } |
247 | |
248 | static const char *men_confirm_save[] = { "OFF", "writes", "loads", "both", NULL }; |
249 | static const char h_confirm_save[] = "Ask for confirmation when overwriting save,\n" |
250 | "loading state or both"; |
251 | |
252 | static 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 | |
265 | static 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 | |
287 | static void draw_frame_debug(void) |
288 | { |
289 | smalltext_out16(4, 1, "build: "__DATE__ " " __TIME__ " " COMPILER, 0xffff); |
290 | } |
291 | |
292 | static 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 | |
311 | const 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 | |
323 | static 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 | |
362 | static 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 | |
399 | static 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 | |
415 | void 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 | |
426 | strcpy(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); |
7eda34c1 |
443 | stop = 0; |
69af03a2 |
444 | } |
445 | |
446 | void 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 | |