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