u4 release
[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];
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
46u32 key = 0;
47
48u32 global_enable_analog = 1;
49u32 analog_sensitivity_level = 4;
50
51typedef 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
64button_repeat_state_type button_repeat_state = BUTTON_NOT_HELD;
65u32 button_repeat = 0;
66gui_action_type cursor_repeat = CURSOR_NONE;
67
68
69#ifdef PSP_BUILD
70
71u32 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
93gui_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
178u32 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
198u32 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
216gui_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
225u32 rapidfire_flag = 1;
226
227u32 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
341void 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
357u32 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
5a01fba6 367 BUTTON_ID_FPS, // A
2823a4c8 368 BUTTON_ID_A, // B
369 BUTTON_ID_B, // X
5a01fba6 370 BUTTON_ID_MENU, // Y
2823a4c8 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
377extern u32 gp2x_fps_debug;
4742480d 378extern u32 gpsp_gp2x_joystick_read(void);
2823a4c8 379
380gui_action_type get_gui_input()
381{
382 gui_action_type new_button = CURSOR_NONE;
383 u32 buttons = gpsp_gp2x_joystick_read();
384 u32 new_buttons;
385
386 static u32 last_buttons = 0;
387 static u64 button_repeat_timestamp;
388
389 delay_us(25000);
390
391 new_buttons = (last_buttons ^ buttons) & buttons;
392 last_buttons = buttons;
393
394 if(new_buttons & GP2X_A)
395 new_button = CURSOR_BACK;
396
397 if(new_buttons & GP2X_X)
398 new_button = CURSOR_EXIT;
399
400 if(new_buttons & GP2X_B)
401 new_button = CURSOR_SELECT;
402
403 if(new_buttons & GP2X_UP)
404 new_button = CURSOR_UP;
405
406 if(new_buttons & GP2X_DOWN)
407 new_button = CURSOR_DOWN;
408
409 if(new_buttons & GP2X_LEFT)
410 new_button = CURSOR_LEFT;
411
412 if(new_buttons & GP2X_RIGHT)
413 new_button = CURSOR_RIGHT;
414
415
416 if(new_button != CURSOR_NONE)
417 {
418 get_ticks_us(&button_repeat_timestamp);
419 button_repeat_state = BUTTON_HELD_INITIAL;
420 button_repeat = new_buttons;
421 cursor_repeat = new_button;
422 }
423 else
424 {
425 if(buttons & button_repeat)
426 {
427 u64 new_ticks;
428 get_ticks_us(&new_ticks);
429
430 if(button_repeat_state == BUTTON_HELD_INITIAL)
431 {
432 if((new_ticks - button_repeat_timestamp) >
433 BUTTON_REPEAT_START)
434 {
435 new_button = cursor_repeat;
436 button_repeat_timestamp = new_ticks;
437 button_repeat_state = BUTTON_HELD_REPEAT;
438 }
439 }
440
441 if(button_repeat_state == BUTTON_HELD_REPEAT)
442 {
443 if((new_ticks - button_repeat_timestamp) >
444 BUTTON_REPEAT_CONTINUE)
445 {
446 new_button = cursor_repeat;
447 button_repeat_timestamp = new_ticks;
448 }
449 }
450 }
451 }
452
453 return new_button;
454}
455
456#define GP2X_VOL_MIDDLE (1 << 24)
457
458u32 button_gp2x_mask_to_config[] =
459{
460 GP2X_UP,
461 GP2X_LEFT,
462 GP2X_DOWN,
463 GP2X_RIGHT,
464 GP2X_START,
465 GP2X_SELECT,
466 GP2X_L,
467 GP2X_R,
468 GP2X_A,
469 GP2X_B,
470 GP2X_X,
471 GP2X_Y,
472 GP2X_VOL_DOWN,
473 GP2X_VOL_UP,
474 GP2X_PUSH,
475 GP2X_VOL_MIDDLE
476};
477
478u32 button_id_to_gba_mask[] =
479{
480 BUTTON_UP,
481 BUTTON_DOWN,
482 BUTTON_LEFT,
483 BUTTON_RIGHT,
484 BUTTON_A,
485 BUTTON_B,
486 BUTTON_L,
487 BUTTON_R,
488 BUTTON_START,
489 BUTTON_SELECT,
490 BUTTON_NONE,
491 BUTTON_NONE,
492 BUTTON_NONE,
493 BUTTON_NONE
494};
495
496u32 update_input()
497{
498 static u32 rapidfire_flag = 1;
499 static u32 last_buttons;
90206450 500 u32 handled_buttons;
2823a4c8 501 u32 button_id;
502 u32 new_key = 0;
503 u32 buttons = gpsp_gp2x_joystick_read();
504 u32 i;
505
506 if((buttons & GP2X_VOL_DOWN) && (buttons & GP2X_VOL_UP))
507 {
508 buttons &= ~(GP2X_VOL_DOWN | GP2X_VOL_UP);
509 buttons |= GP2X_VOL_MIDDLE;
510 }
511
4cdfc0bc 512 /* for Wiz */
513 if((buttons & GP2X_VOL_DOWN) && (buttons & GP2X_SELECT))
514 {
515 buttons &= ~(GP2X_VOL_DOWN | GP2X_SELECT);
516 buttons |= GP2X_VOL_MIDDLE;
517 }
518
90206450 519 handled_buttons = ((last_buttons ^ buttons) | GP2X_VOL_DOWN | GP2X_VOL_UP) & buttons;
2823a4c8 520 last_buttons = buttons;
521
522 for(i = 0; i < 16; i++)
523 {
90206450 524 if(handled_buttons & button_gp2x_mask_to_config[i])
2823a4c8 525 button_id = gamepad_config_map[i];
526 else
527 button_id = BUTTON_ID_NONE;
528
529 switch(button_id)
530 {
531 case BUTTON_ID_MENU:
532 {
533 u16 *screen_copy = copy_screen();
534 u32 ret_val = menu(screen_copy);
535 free(screen_copy);
536
537 return ret_val;
538 }
539
540 case BUTTON_ID_LOADSTATE:
541 {
542 u8 current_savestate_filename[512];
543 get_savestate_filename_noshot(savestate_slot,
544 current_savestate_filename);
545 load_state(current_savestate_filename);
546 return 1;
547 }
548
549 case BUTTON_ID_SAVESTATE:
550 {
551 u8 current_savestate_filename[512];
552 u16 *current_screen = copy_screen();
553 get_savestate_filename_noshot(savestate_slot,
554 current_savestate_filename);
555 save_state(current_savestate_filename, current_screen);
556 free(current_screen);
557 return 0;
558 }
559
560 case BUTTON_ID_FASTFORWARD:
561 print_string("FASTFORWARD", 0xFFFF, 0x0000, 0, 50);
562 synchronize_flag ^= 1;
563 return 0;
564
565 case BUTTON_ID_VOLUP:
566 gp2x_sound_volume(1);
567 break;
568
569 case BUTTON_ID_VOLDOWN:
570 gp2x_sound_volume(0);
571 break;
572
573 case BUTTON_ID_FPS:
574 gp2x_fps_debug ^= 1;
575 break;
576 }
577
578 if(buttons & button_gp2x_mask_to_config[i])
579 {
580 button_id = gamepad_config_map[i];
581 if(button_id < BUTTON_ID_MENU)
582 {
583 new_key |= button_id_to_gba_mask[button_id];
584 }
585 else
586
587 if((button_id >= BUTTON_ID_RAPIDFIRE_A) &&
588 (button_id <= BUTTON_ID_RAPIDFIRE_L))
589 {
590 rapidfire_flag ^= 1;
591 if(rapidfire_flag)
592 {
593 new_key |= button_id_to_gba_mask[button_id -
594 BUTTON_ID_RAPIDFIRE_A + BUTTON_ID_A];
595 }
596 else
597 {
598 new_key &= ~button_id_to_gba_mask[button_id -
599 BUTTON_ID_RAPIDFIRE_A + BUTTON_ID_A];
600 }
601 }
602 }
603 }
604
605 if((new_key | key) != key)
606 trigger_key(new_key);
607
608 key = new_key;
609
610 io_registers[REG_P1] = (~key) & 0x3FF;
611
612 return 0;
613}
614
615void init_input()
616{
617
618}
619
620#endif
621
622
623
624#ifdef PC_BUILD
625
626u32 key_map(SDLKey key_sym)
627{
628 switch(key_sym)
629 {
630 case SDLK_LSHIFT:
631 return BUTTON_L;
632
633 case SDLK_x:
634 return BUTTON_R;
635
636 case SDLK_DOWN:
637 return BUTTON_DOWN;
638
639 case SDLK_UP:
640 return BUTTON_UP;
641
642 case SDLK_LEFT:
643 return BUTTON_LEFT;
644
645 case SDLK_RIGHT:
646 return BUTTON_RIGHT;
647
648 case SDLK_RETURN:
649 return BUTTON_START;
650
651 case SDLK_RSHIFT:
652 return BUTTON_SELECT;
653
654 case SDLK_LCTRL:
655 return BUTTON_B;
656
657 case SDLK_LALT:
658 return BUTTON_A;
659
660 default:
661 return BUTTON_NONE;
662 }
663}
664
665u32 joy_map(u32 button)
666{
667 switch(button)
668 {
669 case 4:
670 return BUTTON_L;
671
672 case 5:
673 return BUTTON_R;
674
675 case 9:
676 return BUTTON_START;
677
678 case 8:
679 return BUTTON_SELECT;
680
681 case 0:
682 return BUTTON_B;
683
684 case 1:
685 return BUTTON_A;
686
687 default:
688 return BUTTON_NONE;
689 }
690}
691
692gui_action_type get_gui_input()
693{
694 SDL_Event event;
695 gui_action_type gui_action = CURSOR_NONE;
696
697 delay_us(30000);
698
699 while(SDL_PollEvent(&event))
700 {
701 switch(event.type)
702 {
703 case SDL_QUIT:
704 quit();
705
706 case SDL_KEYDOWN:
707 {
708 switch(event.key.keysym.sym)
709 {
710 case SDLK_ESCAPE:
711 gui_action = CURSOR_EXIT;
712 break;
713
714 case SDLK_DOWN:
715 gui_action = CURSOR_DOWN;
716 break;
717
718 case SDLK_UP:
719 gui_action = CURSOR_UP;
720 break;
721
722 case SDLK_LEFT:
723 gui_action = CURSOR_LEFT;
724 break;
725
726 case SDLK_RIGHT:
727 gui_action = CURSOR_RIGHT;
728 break;
729
730 case SDLK_RETURN:
731 gui_action = CURSOR_SELECT;
732 break;
733
734 case SDLK_BACKSPACE:
735 gui_action = CURSOR_BACK;
736 break;
737 }
738 break;
739 }
740 }
741 }
742
743 return gui_action;
744}
745
746u32 update_input()
747{
748 SDL_Event event;
749
750 while(SDL_PollEvent(&event))
751 {
752 switch(event.type)
753 {
754 case SDL_QUIT:
755 quit();
756
757 case SDL_KEYDOWN:
758 {
759 if(event.key.keysym.sym == SDLK_ESCAPE)
760 {
761 quit();
762 }
763
764 if(event.key.keysym.sym == SDLK_BACKSPACE)
765 {
766 u16 *screen_copy = copy_screen();
767 u32 ret_val = menu(screen_copy);
768 free(screen_copy);
769
770 return ret_val;
771 }
772 else
773
774 if(event.key.keysym.sym == SDLK_F1)
775 {
776 debug_on();
777 }
778 else
779
780 if(event.key.keysym.sym == SDLK_F2)
781 {
782 FILE *fp = fopen("palette_ram.bin", "wb");
783 printf("writing palette RAM\n");
784 fwrite(palette_ram, 1024, 1, fp);
785 fclose(fp);
786 printf("writing palette VRAM\n");
787 fp = fopen("vram.bin", "wb");
788 fwrite(vram, 1024 * 96, 1, fp);
789 fclose(fp);
790 printf("writing palette OAM RAM\n");
791 fp = fopen("oam_ram.bin", "wb");
792 fwrite(oam_ram, 1024, 1, fp);
793 fclose(fp);
794 printf("writing palette I/O registers\n");
795 fp = fopen("io_registers.bin", "wb");
796 fwrite(io_registers, 1024, 1, fp);
797 fclose(fp);
798 }
799 else
800
801 if(event.key.keysym.sym == SDLK_F3)
802 {
803 dump_translation_cache();
804 }
805 else
806
807 if(event.key.keysym.sym == SDLK_F5)
808 {
809 u8 current_savestate_filename[512];
810 u16 *current_screen = copy_screen();
811 get_savestate_filename_noshot(savestate_slot,
812 current_savestate_filename);
813 save_state(current_savestate_filename, current_screen);
814 free(current_screen);
815 }
816 else
817
818 if(event.key.keysym.sym == SDLK_F7)
819 {
820 u8 current_savestate_filename[512];
821 get_savestate_filename_noshot(savestate_slot,
822 current_savestate_filename);
823 load_state(current_savestate_filename);
824 debug_on();
825 return 1;
826 }
827 else
828
829 if(event.key.keysym.sym == SDLK_BACKQUOTE)
830 {
831 synchronize_flag ^= 1;
832 }
833 else
834 {
835 key |= key_map(event.key.keysym.sym);
836 trigger_key(key);
837 }
838
839 break;
840 }
841
842 case SDL_KEYUP:
843 {
844 key &= ~(key_map(event.key.keysym.sym));
845 break;
846 }
847
848 case SDL_JOYBUTTONDOWN:
849 {
850 key |= joy_map(event.jbutton.button);
851 trigger_key(key);
852 break;
853 }
854
855 case SDL_JOYBUTTONUP:
856 {
857 key &= ~(joy_map(event.jbutton.button));
858 break;
859 }
860 }
861 }
862
863 io_registers[REG_P1] = (~key) & 0x3FF;
864
865 return 0;
866}
867
868void init_input()
869{
870 u32 joystick_count = SDL_NumJoysticks();
871
872 if(joystick_count > 0)
873 {
874 SDL_JoystickOpen(0);
875 SDL_JoystickEventState(SDL_ENABLE);
876 }
877}
878
879#endif
880
881
882#define input_savestate_builder(type) \
883void input_##type##_savestate(file_tag_type savestate_file) \
884{ \
885 file_##type##_variable(savestate_file, key); \
886} \
887
888input_savestate_builder(read);
889input_savestate_builder(write_mem);
890