race condition fix from 2007 (gpsp09-2xb_1)
[gpsp.git] / input.c
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