2823a4c8 |
1 | /* gameplaySP |
2 | * |
3 | * Copyright (C) 2006 Exophase <exophase@gmail.com> |
4 | * |
5 | * This program is free software; you can redistribute it and/or |
6 | * modify it under the terms of the GNU General Public License as |
7 | * published by the Free Software Foundation; either version 2 of |
8 | * the License, or (at your option) any later version. |
9 | * |
10 | * This program is distributed in the hope that it will be useful, |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | * General Public License for more details. |
14 | * |
15 | * You should have received a copy of the GNU General Public License |
16 | * along with this program; if not, write to the Free Software |
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
18 | */ |
19 | |
20 | #include "common.h" |
21 | |
22 | // Special thanks to psp298 for the analog->dpad code! |
23 | |
24 | void trigger_key(u32 key) |
25 | { |
26 | u32 p1_cnt = io_registers[REG_P1CNT]; |
27 | u32 p1; |
28 | |
29 | if((p1_cnt >> 14) & 0x01) |
30 | { |
31 | u32 key_intersection = (p1_cnt & key) & 0x3FF; |
32 | |
33 | if(p1_cnt >> 15) |
34 | { |
35 | if(key_intersection == (p1_cnt & 0x3FF)) |
36 | raise_interrupt(IRQ_KEYPAD); |
37 | } |
38 | else |
39 | { |
40 | if(key_intersection) |
41 | raise_interrupt(IRQ_KEYPAD); |
42 | } |
43 | } |
44 | } |
45 | |
46 | u32 key = 0; |
47 | |
48 | u32 global_enable_analog = 1; |
49 | u32 analog_sensitivity_level = 4; |
50 | |
51 | typedef enum |
52 | { |
53 | BUTTON_NOT_HELD, |
54 | BUTTON_HELD_INITIAL, |
55 | BUTTON_HELD_REPEAT |
56 | } button_repeat_state_type; |
57 | |
58 | |
59 | // These define autorepeat values (in microseconds), tweak as necessary. |
60 | |
61 | #define BUTTON_REPEAT_START 200000 |
62 | #define BUTTON_REPEAT_CONTINUE 50000 |
63 | |
64 | button_repeat_state_type button_repeat_state = BUTTON_NOT_HELD; |
65 | u32 button_repeat = 0; |
66 | gui_action_type cursor_repeat = CURSOR_NONE; |
67 | |
68 | |
69 | #ifdef PSP_BUILD |
70 | |
71 | u32 gamepad_config_map[16] = |
72 | { |
73 | BUTTON_ID_MENU, // Triangle |
74 | BUTTON_ID_A, // Circle |
75 | BUTTON_ID_B, // Cross |
76 | BUTTON_ID_START, // Square |
77 | BUTTON_ID_L, // Ltrigger |
78 | BUTTON_ID_R, // Rtrigger |
79 | BUTTON_ID_DOWN, // Down |
80 | BUTTON_ID_LEFT, // Left |
81 | BUTTON_ID_UP, // Up |
82 | BUTTON_ID_RIGHT, // Right |
83 | BUTTON_ID_SELECT, // Select |
84 | BUTTON_ID_START, // Start |
85 | BUTTON_ID_UP, // Analog up |
86 | BUTTON_ID_DOWN, // Analog down |
87 | BUTTON_ID_LEFT, // Analog left |
88 | BUTTON_ID_RIGHT // Analog right |
89 | }; |
90 | |
91 | #define PSP_ALL_BUTTON_MASK 0xFFFF |
92 | |
93 | gui_action_type get_gui_input() |
94 | { |
95 | SceCtrlData ctrl_data; |
96 | gui_action_type new_button = CURSOR_NONE; |
97 | u32 new_buttons; |
98 | |
99 | static u32 last_buttons = 0; |
100 | static u64 button_repeat_timestamp; |
101 | |
102 | delay_us(25000); |
103 | |
104 | sceCtrlPeekBufferPositive(&ctrl_data, 1); |
105 | ctrl_data.Buttons &= PSP_ALL_BUTTON_MASK; |
106 | new_buttons = (last_buttons ^ ctrl_data.Buttons) & ctrl_data.Buttons; |
107 | last_buttons = ctrl_data.Buttons; |
108 | |
109 | if(new_buttons & PSP_CTRL_LEFT) |
110 | new_button = CURSOR_LEFT; |
111 | |
112 | if(new_buttons & PSP_CTRL_RIGHT) |
113 | new_button = CURSOR_RIGHT; |
114 | |
115 | if(new_buttons & PSP_CTRL_UP) |
116 | new_button = CURSOR_UP; |
117 | |
118 | if(new_buttons & PSP_CTRL_DOWN) |
119 | new_button = CURSOR_DOWN; |
120 | |
121 | if(new_buttons & PSP_CTRL_START) |
122 | new_button = CURSOR_SELECT; |
123 | |
124 | if(new_buttons & PSP_CTRL_CIRCLE) |
125 | new_button = CURSOR_SELECT; |
126 | |
127 | if(new_buttons & PSP_CTRL_CROSS) |
128 | new_button = CURSOR_EXIT; |
129 | |
130 | if(new_buttons & PSP_CTRL_SQUARE) |
131 | new_button = CURSOR_BACK; |
132 | |
133 | if(new_button != CURSOR_NONE) |
134 | { |
135 | get_ticks_us(&button_repeat_timestamp); |
136 | button_repeat_state = BUTTON_HELD_INITIAL; |
137 | button_repeat = new_buttons; |
138 | cursor_repeat = new_button; |
139 | } |
140 | else |
141 | { |
142 | if(ctrl_data.Buttons & button_repeat) |
143 | { |
144 | u64 new_ticks; |
145 | get_ticks_us(&new_ticks); |
146 | |
147 | if(button_repeat_state == BUTTON_HELD_INITIAL) |
148 | { |
149 | if((new_ticks - button_repeat_timestamp) > |
150 | BUTTON_REPEAT_START) |
151 | { |
152 | new_button = cursor_repeat; |
153 | button_repeat_timestamp = new_ticks; |
154 | button_repeat_state = BUTTON_HELD_REPEAT; |
155 | } |
156 | } |
157 | |
158 | if(button_repeat_state == BUTTON_HELD_REPEAT) |
159 | { |
160 | if((new_ticks - button_repeat_timestamp) > |
161 | BUTTON_REPEAT_CONTINUE) |
162 | { |
163 | new_button = cursor_repeat; |
164 | button_repeat_timestamp = new_ticks; |
165 | } |
166 | } |
167 | } |
168 | } |
169 | |
170 | return new_button; |
171 | } |
172 | |
173 | #define PSP_CTRL_ANALOG_UP (1 << 28) |
174 | #define PSP_CTRL_ANALOG_DOWN (1 << 29) |
175 | #define PSP_CTRL_ANALOG_LEFT (1 << 30) |
176 | #define PSP_CTRL_ANALOG_RIGHT (1 << 31) |
177 | |
178 | u32 button_psp_mask_to_config[] = |
179 | { |
180 | PSP_CTRL_TRIANGLE, |
181 | PSP_CTRL_CIRCLE, |
182 | PSP_CTRL_CROSS, |
183 | PSP_CTRL_SQUARE, |
184 | PSP_CTRL_LTRIGGER, |
185 | PSP_CTRL_RTRIGGER, |
186 | PSP_CTRL_DOWN, |
187 | PSP_CTRL_LEFT, |
188 | PSP_CTRL_UP, |
189 | PSP_CTRL_RIGHT, |
190 | PSP_CTRL_SELECT, |
191 | PSP_CTRL_START, |
192 | PSP_CTRL_ANALOG_UP, |
193 | PSP_CTRL_ANALOG_DOWN, |
194 | PSP_CTRL_ANALOG_LEFT, |
195 | PSP_CTRL_ANALOG_RIGHT |
196 | }; |
197 | |
198 | u32 button_id_to_gba_mask[] = |
199 | { |
200 | BUTTON_UP, |
201 | BUTTON_DOWN, |
202 | BUTTON_LEFT, |
203 | BUTTON_RIGHT, |
204 | BUTTON_A, |
205 | BUTTON_B, |
206 | BUTTON_L, |
207 | BUTTON_R, |
208 | BUTTON_START, |
209 | BUTTON_SELECT, |
210 | BUTTON_NONE, |
211 | BUTTON_NONE, |
212 | BUTTON_NONE, |
213 | BUTTON_NONE |
214 | }; |
215 | |
216 | gui_action_type get_gui_input_fs_hold(u32 button_id) |
217 | { |
218 | gui_action_type new_button = get_gui_input(); |
219 | if((last_buttons & button_psp_mask_to_config[button_id]) == 0) |
220 | return CURSOR_BACK; |
221 | |
222 | return new_button; |
223 | } |
224 | |
225 | u32 rapidfire_flag = 1; |
226 | |
227 | u32 update_input() |
228 | { |
229 | SceCtrlData ctrl_data; |
230 | u32 buttons; |
231 | u32 non_repeat_buttons; |
232 | u32 button_id; |
233 | u32 i; |
234 | u32 new_key = 0; |
235 | u32 analog_sensitivity = 92 - (analog_sensitivity_level * 4); |
236 | u32 inv_analog_sensitivity = 256 - analog_sensitivity; |
237 | |
238 | sceCtrlPeekBufferPositive(&ctrl_data, 1); |
239 | |
240 | buttons = ctrl_data.Buttons; |
241 | |
242 | if(global_enable_analog) |
243 | { |
244 | if(ctrl_data.Lx < analog_sensitivity) |
245 | buttons |= PSP_CTRL_ANALOG_LEFT; |
246 | |
247 | if(ctrl_data.Lx > inv_analog_sensitivity) |
248 | buttons |= PSP_CTRL_ANALOG_RIGHT; |
249 | |
250 | if(ctrl_data.Ly < analog_sensitivity) |
251 | buttons |= PSP_CTRL_ANALOG_UP; |
252 | |
253 | if(ctrl_data.Ly > inv_analog_sensitivity) |
254 | buttons |= PSP_CTRL_ANALOG_DOWN; |
255 | } |
256 | |
257 | non_repeat_buttons = (last_buttons ^ buttons) & buttons; |
258 | last_buttons = buttons; |
259 | |
260 | for(i = 0; i < 16; i++) |
261 | { |
262 | if(non_repeat_buttons & button_psp_mask_to_config[i]) |
263 | button_id = gamepad_config_map[i]; |
264 | else |
265 | button_id = BUTTON_ID_NONE; |
266 | |
267 | switch(button_id) |
268 | { |
269 | case BUTTON_ID_MENU: |
270 | { |
271 | u16 *screen_copy = copy_screen(); |
272 | u32 ret_val = menu(screen_copy); |
273 | free(screen_copy); |
274 | |
275 | return ret_val; |
276 | } |
277 | |
278 | case BUTTON_ID_LOADSTATE: |
279 | { |
280 | u8 current_savestate_filename[512]; |
281 | get_savestate_filename_noshot(savestate_slot, |
282 | current_savestate_filename); |
283 | load_state(current_savestate_filename); |
284 | return 1; |
285 | } |
286 | |
287 | case BUTTON_ID_SAVESTATE: |
288 | { |
289 | u8 current_savestate_filename[512]; |
290 | u16 *current_screen = copy_screen(); |
291 | get_savestate_filename_noshot(savestate_slot, |
292 | current_savestate_filename); |
293 | save_state(current_savestate_filename, current_screen); |
294 | free(current_screen); |
295 | return 0; |
296 | } |
297 | |
298 | case BUTTON_ID_FASTFORWARD: |
299 | print_string("FASTFORWARD", 0xFFFF, 0x0000, 0, 50); |
300 | synchronize_flag ^= 1; |
301 | return 0; |
302 | } |
303 | |
304 | if(buttons & button_psp_mask_to_config[i]) |
305 | { |
306 | button_id = gamepad_config_map[i]; |
307 | if(button_id < BUTTON_ID_MENU) |
308 | { |
309 | new_key |= button_id_to_gba_mask[button_id]; |
310 | } |
311 | else |
312 | |
313 | if((button_id >= BUTTON_ID_RAPIDFIRE_A) && |
314 | (button_id <= BUTTON_ID_RAPIDFIRE_L)) |
315 | { |
316 | rapidfire_flag ^= 1; |
317 | if(rapidfire_flag) |
318 | { |
319 | new_key |= button_id_to_gba_mask[button_id - |
320 | BUTTON_ID_RAPIDFIRE_A + BUTTON_ID_A]; |
321 | } |
322 | else |
323 | { |
324 | new_key &= ~button_id_to_gba_mask[button_id - |
325 | BUTTON_ID_RAPIDFIRE_A + BUTTON_ID_A]; |
326 | } |
327 | } |
328 | } |
329 | } |
330 | |
331 | if((new_key | key) != key) |
332 | trigger_key(new_key); |
333 | |
334 | key = new_key; |
335 | |
336 | io_registers[REG_P1] = (~key) & 0x3FF; |
337 | |
338 | return 0; |
339 | } |
340 | |
341 | void init_input() |
342 | { |
343 | sceCtrlSetSamplingCycle(0); |
344 | sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG); |
345 | } |
346 | |
347 | #endif |
348 | |
349 | |
350 | #ifdef GP2X_BUILD |
351 | |
352 | // GP2X SDL requires a user made input method |
353 | #include <sys/mman.h> |
354 | #include <sys/ioctl.h> |
355 | #include "gp2x/gp2x.h" |
356 | |
357 | u32 gamepad_config_map[16] = |
358 | { |
359 | BUTTON_ID_UP, // Up |
360 | BUTTON_ID_LEFT, // Left |
361 | BUTTON_ID_DOWN, // Down |
362 | BUTTON_ID_RIGHT, // Right |
363 | BUTTON_ID_START, // Start |
364 | BUTTON_ID_SELECT, // Select |
365 | BUTTON_ID_L, // Ltrigger |
366 | BUTTON_ID_R, // Rtrigger |
367 | BUTTON_ID_NONE, // A |
368 | BUTTON_ID_A, // B |
369 | BUTTON_ID_B, // X |
370 | BUTTON_ID_NONE, // Y |
371 | BUTTON_ID_VOLDOWN, // Vol down |
372 | BUTTON_ID_VOLUP, // Vol up |
373 | BUTTON_ID_FPS, // Push |
374 | BUTTON_ID_MENU // Vol middle |
375 | }; |
376 | |
377 | extern u32 gp2x_fps_debug; |
378 | |
379 | u32 gpsp_gp2x_joystick_read(void) |
380 | { |
381 | u32 value = (gpsp_gp2x_memregs[0x1198 >> 1] & 0x00FF); |
382 | |
383 | if(value == 0xFD) |
384 | value = 0xFA; |
385 | if(value == 0xF7) |
386 | value = 0xEB; |
387 | if(value == 0xDF) |
388 | value = 0xAF; |
389 | if(value == 0x7F) |
390 | value = 0xBE; |
391 | |
392 | return ~((gpsp_gp2x_memregs[0x1184 >> 1] & 0xFF00) | value | |
393 | (gpsp_gp2x_memregs[0x1186 >> 1] << 16)); |
394 | } |
395 | |
396 | gui_action_type get_gui_input() |
397 | { |
398 | gui_action_type new_button = CURSOR_NONE; |
399 | u32 buttons = gpsp_gp2x_joystick_read(); |
400 | u32 new_buttons; |
401 | |
402 | static u32 last_buttons = 0; |
403 | static u64 button_repeat_timestamp; |
404 | |
405 | delay_us(25000); |
406 | |
407 | new_buttons = (last_buttons ^ buttons) & buttons; |
408 | last_buttons = buttons; |
409 | |
410 | if(new_buttons & GP2X_A) |
411 | new_button = CURSOR_BACK; |
412 | |
413 | if(new_buttons & GP2X_X) |
414 | new_button = CURSOR_EXIT; |
415 | |
416 | if(new_buttons & GP2X_B) |
417 | new_button = CURSOR_SELECT; |
418 | |
419 | if(new_buttons & GP2X_UP) |
420 | new_button = CURSOR_UP; |
421 | |
422 | if(new_buttons & GP2X_DOWN) |
423 | new_button = CURSOR_DOWN; |
424 | |
425 | if(new_buttons & GP2X_LEFT) |
426 | new_button = CURSOR_LEFT; |
427 | |
428 | if(new_buttons & GP2X_RIGHT) |
429 | new_button = CURSOR_RIGHT; |
430 | |
431 | |
432 | if(new_button != CURSOR_NONE) |
433 | { |
434 | get_ticks_us(&button_repeat_timestamp); |
435 | button_repeat_state = BUTTON_HELD_INITIAL; |
436 | button_repeat = new_buttons; |
437 | cursor_repeat = new_button; |
438 | } |
439 | else |
440 | { |
441 | if(buttons & button_repeat) |
442 | { |
443 | u64 new_ticks; |
444 | get_ticks_us(&new_ticks); |
445 | |
446 | if(button_repeat_state == BUTTON_HELD_INITIAL) |
447 | { |
448 | if((new_ticks - button_repeat_timestamp) > |
449 | BUTTON_REPEAT_START) |
450 | { |
451 | new_button = cursor_repeat; |
452 | button_repeat_timestamp = new_ticks; |
453 | button_repeat_state = BUTTON_HELD_REPEAT; |
454 | } |
455 | } |
456 | |
457 | if(button_repeat_state == BUTTON_HELD_REPEAT) |
458 | { |
459 | if((new_ticks - button_repeat_timestamp) > |
460 | BUTTON_REPEAT_CONTINUE) |
461 | { |
462 | new_button = cursor_repeat; |
463 | button_repeat_timestamp = new_ticks; |
464 | } |
465 | } |
466 | } |
467 | } |
468 | |
469 | return new_button; |
470 | } |
471 | |
472 | #define GP2X_VOL_MIDDLE (1 << 24) |
473 | |
474 | u32 button_gp2x_mask_to_config[] = |
475 | { |
476 | GP2X_UP, |
477 | GP2X_LEFT, |
478 | GP2X_DOWN, |
479 | GP2X_RIGHT, |
480 | GP2X_START, |
481 | GP2X_SELECT, |
482 | GP2X_L, |
483 | GP2X_R, |
484 | GP2X_A, |
485 | GP2X_B, |
486 | GP2X_X, |
487 | GP2X_Y, |
488 | GP2X_VOL_DOWN, |
489 | GP2X_VOL_UP, |
490 | GP2X_PUSH, |
491 | GP2X_VOL_MIDDLE |
492 | }; |
493 | |
494 | u32 button_id_to_gba_mask[] = |
495 | { |
496 | BUTTON_UP, |
497 | BUTTON_DOWN, |
498 | BUTTON_LEFT, |
499 | BUTTON_RIGHT, |
500 | BUTTON_A, |
501 | BUTTON_B, |
502 | BUTTON_L, |
503 | BUTTON_R, |
504 | BUTTON_START, |
505 | BUTTON_SELECT, |
506 | BUTTON_NONE, |
507 | BUTTON_NONE, |
508 | BUTTON_NONE, |
509 | BUTTON_NONE |
510 | }; |
511 | |
512 | u32 update_input() |
513 | { |
514 | static u32 rapidfire_flag = 1; |
515 | static u32 last_buttons; |
516 | u32 non_repeat_buttons; |
517 | u32 button_id; |
518 | u32 new_key = 0; |
519 | u32 buttons = gpsp_gp2x_joystick_read(); |
520 | u32 i; |
521 | |
522 | if((buttons & GP2X_VOL_DOWN) && (buttons & GP2X_VOL_UP)) |
523 | { |
524 | buttons &= ~(GP2X_VOL_DOWN | GP2X_VOL_UP); |
525 | buttons |= GP2X_VOL_MIDDLE; |
526 | } |
527 | |
528 | non_repeat_buttons = (last_buttons ^ buttons) & buttons; |
529 | last_buttons = buttons; |
530 | |
531 | for(i = 0; i < 16; i++) |
532 | { |
533 | if(non_repeat_buttons & button_gp2x_mask_to_config[i]) |
534 | button_id = gamepad_config_map[i]; |
535 | else |
536 | button_id = BUTTON_ID_NONE; |
537 | |
538 | switch(button_id) |
539 | { |
540 | case BUTTON_ID_MENU: |
541 | { |
542 | u16 *screen_copy = copy_screen(); |
543 | u32 ret_val = menu(screen_copy); |
544 | free(screen_copy); |
545 | |
546 | return ret_val; |
547 | } |
548 | |
549 | case BUTTON_ID_LOADSTATE: |
550 | { |
551 | u8 current_savestate_filename[512]; |
552 | get_savestate_filename_noshot(savestate_slot, |
553 | current_savestate_filename); |
554 | load_state(current_savestate_filename); |
555 | return 1; |
556 | } |
557 | |
558 | case BUTTON_ID_SAVESTATE: |
559 | { |
560 | u8 current_savestate_filename[512]; |
561 | u16 *current_screen = copy_screen(); |
562 | get_savestate_filename_noshot(savestate_slot, |
563 | current_savestate_filename); |
564 | save_state(current_savestate_filename, current_screen); |
565 | free(current_screen); |
566 | return 0; |
567 | } |
568 | |
569 | case BUTTON_ID_FASTFORWARD: |
570 | print_string("FASTFORWARD", 0xFFFF, 0x0000, 0, 50); |
571 | synchronize_flag ^= 1; |
572 | return 0; |
573 | |
574 | case BUTTON_ID_VOLUP: |
575 | gp2x_sound_volume(1); |
576 | break; |
577 | |
578 | case BUTTON_ID_VOLDOWN: |
579 | gp2x_sound_volume(0); |
580 | break; |
581 | |
582 | case BUTTON_ID_FPS: |
583 | gp2x_fps_debug ^= 1; |
584 | break; |
585 | } |
586 | |
587 | if(buttons & button_gp2x_mask_to_config[i]) |
588 | { |
589 | button_id = gamepad_config_map[i]; |
590 | if(button_id < BUTTON_ID_MENU) |
591 | { |
592 | new_key |= button_id_to_gba_mask[button_id]; |
593 | } |
594 | else |
595 | |
596 | if((button_id >= BUTTON_ID_RAPIDFIRE_A) && |
597 | (button_id <= BUTTON_ID_RAPIDFIRE_L)) |
598 | { |
599 | rapidfire_flag ^= 1; |
600 | if(rapidfire_flag) |
601 | { |
602 | new_key |= button_id_to_gba_mask[button_id - |
603 | BUTTON_ID_RAPIDFIRE_A + BUTTON_ID_A]; |
604 | } |
605 | else |
606 | { |
607 | new_key &= ~button_id_to_gba_mask[button_id - |
608 | BUTTON_ID_RAPIDFIRE_A + BUTTON_ID_A]; |
609 | } |
610 | } |
611 | } |
612 | } |
613 | |
614 | if((new_key | key) != key) |
615 | trigger_key(new_key); |
616 | |
617 | key = new_key; |
618 | |
619 | io_registers[REG_P1] = (~key) & 0x3FF; |
620 | |
621 | return 0; |
622 | } |
623 | |
624 | void init_input() |
625 | { |
626 | |
627 | } |
628 | |
629 | #endif |
630 | |
631 | |
632 | |
633 | #ifdef PC_BUILD |
634 | |
635 | u32 key_map(SDLKey key_sym) |
636 | { |
637 | switch(key_sym) |
638 | { |
639 | case SDLK_LSHIFT: |
640 | return BUTTON_L; |
641 | |
642 | case SDLK_x: |
643 | return BUTTON_R; |
644 | |
645 | case SDLK_DOWN: |
646 | return BUTTON_DOWN; |
647 | |
648 | case SDLK_UP: |
649 | return BUTTON_UP; |
650 | |
651 | case SDLK_LEFT: |
652 | return BUTTON_LEFT; |
653 | |
654 | case SDLK_RIGHT: |
655 | return BUTTON_RIGHT; |
656 | |
657 | case SDLK_RETURN: |
658 | return BUTTON_START; |
659 | |
660 | case SDLK_RSHIFT: |
661 | return BUTTON_SELECT; |
662 | |
663 | case SDLK_LCTRL: |
664 | return BUTTON_B; |
665 | |
666 | case SDLK_LALT: |
667 | return BUTTON_A; |
668 | |
669 | default: |
670 | return BUTTON_NONE; |
671 | } |
672 | } |
673 | |
674 | u32 joy_map(u32 button) |
675 | { |
676 | switch(button) |
677 | { |
678 | case 4: |
679 | return BUTTON_L; |
680 | |
681 | case 5: |
682 | return BUTTON_R; |
683 | |
684 | case 9: |
685 | return BUTTON_START; |
686 | |
687 | case 8: |
688 | return BUTTON_SELECT; |
689 | |
690 | case 0: |
691 | return BUTTON_B; |
692 | |
693 | case 1: |
694 | return BUTTON_A; |
695 | |
696 | default: |
697 | return BUTTON_NONE; |
698 | } |
699 | } |
700 | |
701 | gui_action_type get_gui_input() |
702 | { |
703 | SDL_Event event; |
704 | gui_action_type gui_action = CURSOR_NONE; |
705 | |
706 | delay_us(30000); |
707 | |
708 | while(SDL_PollEvent(&event)) |
709 | { |
710 | switch(event.type) |
711 | { |
712 | case SDL_QUIT: |
713 | quit(); |
714 | |
715 | case SDL_KEYDOWN: |
716 | { |
717 | switch(event.key.keysym.sym) |
718 | { |
719 | case SDLK_ESCAPE: |
720 | gui_action = CURSOR_EXIT; |
721 | break; |
722 | |
723 | case SDLK_DOWN: |
724 | gui_action = CURSOR_DOWN; |
725 | break; |
726 | |
727 | case SDLK_UP: |
728 | gui_action = CURSOR_UP; |
729 | break; |
730 | |
731 | case SDLK_LEFT: |
732 | gui_action = CURSOR_LEFT; |
733 | break; |
734 | |
735 | case SDLK_RIGHT: |
736 | gui_action = CURSOR_RIGHT; |
737 | break; |
738 | |
739 | case SDLK_RETURN: |
740 | gui_action = CURSOR_SELECT; |
741 | break; |
742 | |
743 | case SDLK_BACKSPACE: |
744 | gui_action = CURSOR_BACK; |
745 | break; |
746 | } |
747 | break; |
748 | } |
749 | } |
750 | } |
751 | |
752 | return gui_action; |
753 | } |
754 | |
755 | u32 update_input() |
756 | { |
757 | SDL_Event event; |
758 | |
759 | while(SDL_PollEvent(&event)) |
760 | { |
761 | switch(event.type) |
762 | { |
763 | case SDL_QUIT: |
764 | quit(); |
765 | |
766 | case SDL_KEYDOWN: |
767 | { |
768 | if(event.key.keysym.sym == SDLK_ESCAPE) |
769 | { |
770 | quit(); |
771 | } |
772 | |
773 | if(event.key.keysym.sym == SDLK_BACKSPACE) |
774 | { |
775 | u16 *screen_copy = copy_screen(); |
776 | u32 ret_val = menu(screen_copy); |
777 | free(screen_copy); |
778 | |
779 | return ret_val; |
780 | } |
781 | else |
782 | |
783 | if(event.key.keysym.sym == SDLK_F1) |
784 | { |
785 | debug_on(); |
786 | } |
787 | else |
788 | |
789 | if(event.key.keysym.sym == SDLK_F2) |
790 | { |
791 | FILE *fp = fopen("palette_ram.bin", "wb"); |
792 | printf("writing palette RAM\n"); |
793 | fwrite(palette_ram, 1024, 1, fp); |
794 | fclose(fp); |
795 | printf("writing palette VRAM\n"); |
796 | fp = fopen("vram.bin", "wb"); |
797 | fwrite(vram, 1024 * 96, 1, fp); |
798 | fclose(fp); |
799 | printf("writing palette OAM RAM\n"); |
800 | fp = fopen("oam_ram.bin", "wb"); |
801 | fwrite(oam_ram, 1024, 1, fp); |
802 | fclose(fp); |
803 | printf("writing palette I/O registers\n"); |
804 | fp = fopen("io_registers.bin", "wb"); |
805 | fwrite(io_registers, 1024, 1, fp); |
806 | fclose(fp); |
807 | } |
808 | else |
809 | |
810 | if(event.key.keysym.sym == SDLK_F3) |
811 | { |
812 | dump_translation_cache(); |
813 | } |
814 | else |
815 | |
816 | if(event.key.keysym.sym == SDLK_F5) |
817 | { |
818 | u8 current_savestate_filename[512]; |
819 | u16 *current_screen = copy_screen(); |
820 | get_savestate_filename_noshot(savestate_slot, |
821 | current_savestate_filename); |
822 | save_state(current_savestate_filename, current_screen); |
823 | free(current_screen); |
824 | } |
825 | else |
826 | |
827 | if(event.key.keysym.sym == SDLK_F7) |
828 | { |
829 | u8 current_savestate_filename[512]; |
830 | get_savestate_filename_noshot(savestate_slot, |
831 | current_savestate_filename); |
832 | load_state(current_savestate_filename); |
833 | debug_on(); |
834 | return 1; |
835 | } |
836 | else |
837 | |
838 | if(event.key.keysym.sym == SDLK_BACKQUOTE) |
839 | { |
840 | synchronize_flag ^= 1; |
841 | } |
842 | else |
843 | { |
844 | key |= key_map(event.key.keysym.sym); |
845 | trigger_key(key); |
846 | } |
847 | |
848 | break; |
849 | } |
850 | |
851 | case SDL_KEYUP: |
852 | { |
853 | key &= ~(key_map(event.key.keysym.sym)); |
854 | break; |
855 | } |
856 | |
857 | case SDL_JOYBUTTONDOWN: |
858 | { |
859 | key |= joy_map(event.jbutton.button); |
860 | trigger_key(key); |
861 | break; |
862 | } |
863 | |
864 | case SDL_JOYBUTTONUP: |
865 | { |
866 | key &= ~(joy_map(event.jbutton.button)); |
867 | break; |
868 | } |
869 | } |
870 | } |
871 | |
872 | io_registers[REG_P1] = (~key) & 0x3FF; |
873 | |
874 | return 0; |
875 | } |
876 | |
877 | void init_input() |
878 | { |
879 | u32 joystick_count = SDL_NumJoysticks(); |
880 | |
881 | if(joystick_count > 0) |
882 | { |
883 | SDL_JoystickOpen(0); |
884 | SDL_JoystickEventState(SDL_ENABLE); |
885 | } |
886 | } |
887 | |
888 | #endif |
889 | |
890 | |
891 | #define input_savestate_builder(type) \ |
892 | void input_##type##_savestate(file_tag_type savestate_file) \ |
893 | { \ |
894 | file_##type##_variable(savestate_file, key); \ |
895 | } \ |
896 | |
897 | input_savestate_builder(read); |
898 | input_savestate_builder(write_mem); |
899 | |