Add copyright message to gles_video
[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
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
45 u32 key = 0;
46
47 u32 global_enable_analog = 1;
48 u32 analog_sensitivity_level = 4;
49
50 typedef 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
63 button_repeat_state_type button_repeat_state = BUTTON_NOT_HELD;
64 u32 button_repeat = 0;
65 gui_action_type cursor_repeat = CURSOR_NONE;
66
67
68 #ifdef PSP_BUILD
69
70 u32 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
92 gui_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
177 u32 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
197 u32 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
215 gui_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
224 u32 rapidfire_flag = 1;
225
226 u32 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
340 void init_input()
341 {
342   sceCtrlSetSamplingCycle(0);
343   sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG);
344 }
345
346 #endif
347
348
349 #if defined(GP2X_BUILD) || defined(PND_BUILD)
350
351 extern u32 fps_debug;
352
353 gui_action_type get_gui_input()
354 {
355   gui_action_type new_button = CURSOR_NONE;
356   u32 buttons = gpsp_plat_joystick_read();
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
367   new_button = gpsp_plat_buttons_to_cursor(new_buttons);
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
408 u32 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
426 u32 update_input()
427 {
428   static u32 rapidfire_flag = 1;
429   static u32 last_buttons;
430   u32 handled_buttons;
431   u32 button_id;
432   u32 new_key = 0;
433   u32 buttons = gpsp_plat_joystick_read();
434   u32 i;
435
436 #ifdef GP2X_BUILD
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
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
450   last_buttons &= ~(GP2X_VOL_DOWN | GP2X_VOL_UP);
451 #endif
452
453   handled_buttons = (last_buttons ^ buttons) & buttons;
454   last_buttons = buttons;
455
456   for(i = 0; i < PLAT_BUTTON_COUNT; i++)
457   {
458     if(handled_buttons & button_plat_mask_to_config[i])
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       {
476         char current_savestate_filename[512];
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       {
485         char current_savestate_filename[512];
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:
495         synchronize_flag ^= 1;
496         return 0;
497
498 #ifdef GP2X_BUILD
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;
506 #endif
507
508       case BUTTON_ID_FPS:
509         fps_debug ^= 1;
510         break;
511     }
512
513     if(buttons & button_plat_mask_to_config[i])
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
550 void init_input()
551 {
552
553 }
554
555 #endif
556
557
558 #if defined(RPI_BUILD)
559
560 u32 key_map(SDLKey key_sym)
561 {
562   switch(key_sym)
563   {
564     case SDLK_a:
565       return BUTTON_L;
566
567     case SDLK_s:
568       return BUTTON_R;
569
570     case SDLK_DOWN:
571       return BUTTON_DOWN;
572
573     case SDLK_UP:
574       return BUTTON_UP;
575
576     case SDLK_LEFT:
577       return BUTTON_LEFT;
578
579     case SDLK_RIGHT:
580       return BUTTON_RIGHT;
581
582     case SDLK_RETURN:
583       return BUTTON_START;
584
585     case SDLK_BACKSPACE:
586       return BUTTON_SELECT;
587
588     case SDLK_x:
589       return BUTTON_B;
590
591     case SDLK_z:
592       return BUTTON_A;
593
594     default:
595       return BUTTON_NONE;
596   }
597 }
598 #endif
599
600 #if defined(PC_BUILD)
601
602 u32 key_map(SDLKey key_sym)
603 {
604   switch(key_sym)
605   {
606     case SDLK_LSHIFT:
607       return BUTTON_L;
608
609     case SDLK_x:
610       return BUTTON_R;
611
612     case SDLK_DOWN:
613       return BUTTON_DOWN;
614
615     case SDLK_UP:
616       return BUTTON_UP;
617
618     case SDLK_LEFT:
619       return BUTTON_LEFT;
620
621     case SDLK_RIGHT:
622       return BUTTON_RIGHT;
623
624     case SDLK_RETURN:
625       return BUTTON_START;
626
627     case SDLK_RSHIFT:
628       return BUTTON_SELECT;
629
630     case SDLK_LCTRL:
631       return BUTTON_B;
632
633     case SDLK_LALT:
634       return BUTTON_A;
635
636     default:
637       return BUTTON_NONE;
638   }
639 }
640 #endif
641 #if defined(PC_BUILD) || defined(RPI_BUILD)
642
643 u32 joy_map(u32 button)
644 {
645   switch(button)
646   {
647     case 4:
648       return BUTTON_L;
649
650     case 5:
651       return BUTTON_R;
652
653     case 2:
654       return BUTTON_START;
655
656     case 3:
657       return BUTTON_SELECT;
658
659     case 1:
660       return BUTTON_B;
661
662     case 0:
663       return BUTTON_A;
664
665     default:
666       return BUTTON_NONE;
667   }
668 }
669
670 gui_action_type get_gui_input()
671 {
672   SDL_Event event;
673   gui_action_type gui_action = CURSOR_NONE;
674
675   delay_us(30000);
676
677   while(SDL_PollEvent(&event))
678   { 
679     switch(event.type)
680     {
681       case SDL_QUIT:
682         quit();
683
684       case SDL_KEYDOWN:
685       {
686         switch(event.key.keysym.sym)
687         {
688           case SDLK_ESCAPE:
689             gui_action = CURSOR_EXIT;
690             break;
691
692           case SDLK_DOWN:
693             gui_action = CURSOR_DOWN;
694             break;
695
696           case SDLK_UP:
697             gui_action = CURSOR_UP;
698             break;
699
700           case SDLK_LEFT:
701             gui_action = CURSOR_LEFT;
702             break;
703
704           case SDLK_RIGHT:
705             gui_action = CURSOR_RIGHT;
706             break;
707
708           case SDLK_RETURN:
709             gui_action = CURSOR_SELECT;
710             break;
711
712           case SDLK_BACKSPACE:
713             gui_action = CURSOR_BACK;
714             break;
715          default:
716             break;
717       }
718     }
719     break;
720 #ifdef RPI_BUILD
721     case SDL_JOYBUTTONDOWN:
722     {
723       switch (event.jbutton.button)
724       {
725         case 2:
726             gui_action = CURSOR_BACK;
727             break;
728
729         case 1:
730             gui_action = CURSOR_EXIT;
731             break;
732
733         case 0:
734             gui_action = CURSOR_SELECT;
735             break;
736         }
737      }
738      break;
739
740      case SDL_JOYAXISMOTION:
741      {
742          if (event.jaxis.axis==0) { //Left-Right
743             if (event.jaxis.value < -3200) gui_action = CURSOR_LEFT;
744                 else if (event.jaxis.value > 3200) gui_action = CURSOR_RIGHT;
745          }
746          if (event.jaxis.axis==1) {  //Up-Down
747             if (event.jaxis.value < -3200) gui_action = CURSOR_UP;
748                 else if (event.jaxis.value > 3200) gui_action = CURSOR_DOWN;
749          }
750     }
751     break;
752
753 #endif
754     default:
755         break;
756     }
757   }
758   return gui_action;
759 }
760
761 u32 update_input()
762 {
763   SDL_Event event;
764
765   while(SDL_PollEvent(&event))
766   {
767     switch(event.type)
768     {
769       case SDL_QUIT:
770         quit();
771
772       case SDL_KEYDOWN:
773       {
774         if(event.key.keysym.sym == SDLK_ESCAPE)
775         {
776           quit();
777         }
778 #ifdef PC_BUILD
779         if(event.key.keysym.sym == SDLK_BACKSPACE)
780 #else
781         if(event.key.keysym.sym == SDLK_F10)
782 #endif
783         {
784           u16 *screen_copy = copy_screen();
785           u32 ret_val = menu(screen_copy);
786           free(screen_copy);
787
788           return ret_val;
789         }
790         else
791 #ifdef PC_BUILD
792         if(event.key.keysym.sym == SDLK_F1)
793         {
794           debug_on();
795         }
796         else
797
798         if(event.key.keysym.sym == SDLK_F2)
799         {
800           FILE *fp = fopen("palette_ram.bin", "wb");
801           printf("writing palette RAM\n");
802           fwrite(palette_ram, 1024, 1, fp);
803           fclose(fp);
804           printf("writing palette VRAM\n");
805           fp = fopen("vram.bin", "wb");
806           fwrite(vram, 1024 * 96, 1, fp);
807           fclose(fp);
808           printf("writing palette OAM RAM\n");
809           fp = fopen("oam_ram.bin", "wb");
810           fwrite(oam_ram, 1024, 1, fp);
811           fclose(fp);
812           printf("writing palette I/O registers\n");
813           fp = fopen("io_registers.bin", "wb");
814           fwrite(io_registers, 1024, 1, fp);
815           fclose(fp);
816         }
817         else
818
819         if(event.key.keysym.sym == SDLK_F3)
820         {
821           dump_translation_cache();
822         }
823         else
824 #endif
825         if(event.key.keysym.sym == SDLK_F5)
826         {
827           char current_savestate_filename[512];
828           u16 *current_screen = copy_screen();
829           get_savestate_filename_noshot(savestate_slot,
830            current_savestate_filename);
831           save_state(current_savestate_filename, current_screen);
832           free(current_screen);
833         }
834         else
835
836         if(event.key.keysym.sym == SDLK_F7)
837         {
838           char current_savestate_filename[512];
839           get_savestate_filename_noshot(savestate_slot,
840            current_savestate_filename);
841           load_state(current_savestate_filename);
842           debug_on();
843           return 1;
844         }
845         else
846
847         if(event.key.keysym.sym == SDLK_BACKQUOTE)
848         {
849           synchronize_flag ^= 1;
850         }
851         else
852         {
853           key |= key_map(event.key.keysym.sym);
854           trigger_key(key);
855         }
856
857         break;
858       }
859
860       case SDL_KEYUP:
861       {
862         key &= ~(key_map(event.key.keysym.sym));
863         break;
864       }
865
866       case SDL_JOYBUTTONDOWN:
867       {
868         key |= joy_map(event.jbutton.button);
869         trigger_key(key);
870         break;
871       }
872
873       case SDL_JOYBUTTONUP:
874       {
875         key &= ~(joy_map(event.jbutton.button));
876         break;
877       }
878 #ifdef RPI_BUILD
879       case SDL_JOYAXISMOTION:
880       {
881          if (event.jaxis.axis==0) { //Left-Right
882             key &= ~(BUTTON_LEFT|BUTTON_RIGHT);
883          if (event.jaxis.value < -3200)  key |= BUTTON_LEFT;
884            else if (event.jaxis.value > 3200)  key |= BUTTON_RIGHT;
885        } 
886          if (event.jaxis.axis==1) {  //Up-Down
887             key &= ~(BUTTON_UP|BUTTON_DOWN);
888          if (event.jaxis.value < -3200)  key |= BUTTON_UP;
889            else if (event.jaxis.value > 3200)  key |= BUTTON_DOWN;
890        }
891        break;
892 #endif
893       }
894     }
895   }
896
897   io_registers[REG_P1] = (~key) & 0x3FF;
898
899   return 0;
900 }
901
902 void init_input()
903 {
904   u32 joystick_count = SDL_NumJoysticks();
905
906   if(joystick_count > 0)
907   {
908     SDL_JoystickOpen(0);
909     SDL_JoystickEventState(SDL_ENABLE);
910   }
911 }
912
913 #endif
914
915
916 #define input_savestate_builder(type)                                         \
917 void input_##type##_savestate(file_tag_type savestate_file)                   \
918 {                                                                             \
919   file_##type##_variable(savestate_file, key);                                \
920 }                                                                             \
921
922 input_savestate_builder(read);
923 input_savestate_builder(write_mem);
924