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" |
19 | |
20 | #define MENU_X2 1 |
21 | #define array_size(x) (sizeof(x) / sizeof(x[0])) |
22 | |
23 | typedef 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 | |
45 | extern int ready_to_go; |
46 | |
47 | static int dummy, state_slot; |
48 | static char rom_fname_reload[MAXPATHLEN]; |
49 | static char last_selected_fname[MAXPATHLEN]; |
50 | |
51 | void 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 | |
63 | static int emu_check_save_file(int slot) |
64 | { |
65 | return 0; |
66 | } |
67 | |
68 | static int emu_save_load_game(int load, int sram) |
69 | { |
70 | return 0; |
71 | } |
72 | |
73 | static int emu_write_config(int is_game) |
74 | { |
75 | return 0; |
76 | } |
77 | |
78 | static void emu_set_defconfig(void) |
79 | { |
80 | } |
81 | |
82 | #include "common/menu.c" |
83 | |
84 | static void draw_savestate_bg(int slot) |
85 | { |
86 | } |
87 | |
88 | // -------------- key config -------------- |
89 | |
90 | me_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 | |
109 | me_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 | |
119 | static 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 | |
137 | static 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 | |
155 | static const char *mgn_saveloadcfg(int id, int *offs) |
156 | { |
157 | return ""; |
158 | } |
159 | |
160 | static 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 | |
177 | static 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 | |
196 | static 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 | |
207 | static menu_entry e_menu_adv_options[] = |
208 | { |
209 | mee_onoff ("captain placeholder", 0, dummy, 1), |
210 | mee_end, |
211 | }; |
212 | |
213 | static 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 | |
222 | static menu_entry e_menu_gfx_options[] = |
223 | { |
224 | mee_end, |
225 | }; |
226 | |
227 | static 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 | |
238 | static menu_entry e_menu_options[]; |
239 | |
240 | static int mh_restore_defaults(int id, int keys) |
241 | { |
242 | emu_set_defconfig(); |
243 | me_update_msg("defaults restored"); |
244 | return 1; |
245 | } |
246 | |
247 | static const char *men_confirm_save[] = { "OFF", "writes", "loads", "both", NULL }; |
248 | static const char h_confirm_save[] = "Ask for confirmation when overwriting save,\n" |
249 | "loading state or both"; |
250 | |
251 | static 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 | |
264 | static 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 | |
286 | static void draw_frame_debug(void) |
287 | { |
288 | smalltext_out16(4, 1, "build: "__DATE__ " " __TIME__ " " COMPILER, 0xffff); |
289 | } |
290 | |
291 | static 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 | |
310 | const 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 | |
322 | static 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 | |
361 | static 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 | |
398 | static 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 | |
414 | void 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 | |
425 | strcpy(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 | |
444 | void 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 | |