3 * Copyright (C) 2006 Exophase <exophase@gmail.com>
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.
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.
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
22 // Special thanks to psp298 for the analog->dpad code!
24 void trigger_key(u32 key)
26 u32 p1_cnt = io_registers[REG_P1CNT];
29 if((p1_cnt >> 14) & 0x01)
31 u32 key_intersection = (p1_cnt & key) & 0x3FF;
35 if(key_intersection == (p1_cnt & 0x3FF))
36 raise_interrupt(IRQ_KEYPAD);
41 raise_interrupt(IRQ_KEYPAD);
48 u32 global_enable_analog = 1;
49 u32 analog_sensitivity_level = 4;
56 } button_repeat_state_type;
59 // These define autorepeat values (in microseconds), tweak as necessary.
61 #define BUTTON_REPEAT_START 200000
62 #define BUTTON_REPEAT_CONTINUE 50000
64 button_repeat_state_type button_repeat_state = BUTTON_NOT_HELD;
65 u32 button_repeat = 0;
66 gui_action_type cursor_repeat = CURSOR_NONE;
71 u32 gamepad_config_map[16] =
73 BUTTON_ID_MENU, // Triangle
74 BUTTON_ID_A, // Circle
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
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
91 #define PSP_ALL_BUTTON_MASK 0xFFFF
93 gui_action_type get_gui_input()
95 SceCtrlData ctrl_data;
96 gui_action_type new_button = CURSOR_NONE;
99 static u32 last_buttons = 0;
100 static u64 button_repeat_timestamp;
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;
109 if(new_buttons & PSP_CTRL_LEFT)
110 new_button = CURSOR_LEFT;
112 if(new_buttons & PSP_CTRL_RIGHT)
113 new_button = CURSOR_RIGHT;
115 if(new_buttons & PSP_CTRL_UP)
116 new_button = CURSOR_UP;
118 if(new_buttons & PSP_CTRL_DOWN)
119 new_button = CURSOR_DOWN;
121 if(new_buttons & PSP_CTRL_START)
122 new_button = CURSOR_SELECT;
124 if(new_buttons & PSP_CTRL_CIRCLE)
125 new_button = CURSOR_SELECT;
127 if(new_buttons & PSP_CTRL_CROSS)
128 new_button = CURSOR_EXIT;
130 if(new_buttons & PSP_CTRL_SQUARE)
131 new_button = CURSOR_BACK;
133 if(new_button != CURSOR_NONE)
135 get_ticks_us(&button_repeat_timestamp);
136 button_repeat_state = BUTTON_HELD_INITIAL;
137 button_repeat = new_buttons;
138 cursor_repeat = new_button;
142 if(ctrl_data.Buttons & button_repeat)
145 get_ticks_us(&new_ticks);
147 if(button_repeat_state == BUTTON_HELD_INITIAL)
149 if((new_ticks - button_repeat_timestamp) >
152 new_button = cursor_repeat;
153 button_repeat_timestamp = new_ticks;
154 button_repeat_state = BUTTON_HELD_REPEAT;
158 if(button_repeat_state == BUTTON_HELD_REPEAT)
160 if((new_ticks - button_repeat_timestamp) >
161 BUTTON_REPEAT_CONTINUE)
163 new_button = cursor_repeat;
164 button_repeat_timestamp = new_ticks;
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)
178 u32 button_psp_mask_to_config[] =
193 PSP_CTRL_ANALOG_DOWN,
194 PSP_CTRL_ANALOG_LEFT,
195 PSP_CTRL_ANALOG_RIGHT
198 u32 button_id_to_gba_mask[] =
216 gui_action_type get_gui_input_fs_hold(u32 button_id)
218 gui_action_type new_button = get_gui_input();
219 if((last_buttons & button_psp_mask_to_config[button_id]) == 0)
225 u32 rapidfire_flag = 1;
229 SceCtrlData ctrl_data;
231 u32 non_repeat_buttons;
235 u32 analog_sensitivity = 92 - (analog_sensitivity_level * 4);
236 u32 inv_analog_sensitivity = 256 - analog_sensitivity;
238 sceCtrlPeekBufferPositive(&ctrl_data, 1);
240 buttons = ctrl_data.Buttons;
242 if(global_enable_analog)
244 if(ctrl_data.Lx < analog_sensitivity)
245 buttons |= PSP_CTRL_ANALOG_LEFT;
247 if(ctrl_data.Lx > inv_analog_sensitivity)
248 buttons |= PSP_CTRL_ANALOG_RIGHT;
250 if(ctrl_data.Ly < analog_sensitivity)
251 buttons |= PSP_CTRL_ANALOG_UP;
253 if(ctrl_data.Ly > inv_analog_sensitivity)
254 buttons |= PSP_CTRL_ANALOG_DOWN;
257 non_repeat_buttons = (last_buttons ^ buttons) & buttons;
258 last_buttons = buttons;
260 for(i = 0; i < 16; i++)
262 if(non_repeat_buttons & button_psp_mask_to_config[i])
263 button_id = gamepad_config_map[i];
265 button_id = BUTTON_ID_NONE;
271 u16 *screen_copy = copy_screen();
272 u32 ret_val = menu(screen_copy);
278 case BUTTON_ID_LOADSTATE:
280 u8 current_savestate_filename[512];
281 get_savestate_filename_noshot(savestate_slot,
282 current_savestate_filename);
283 load_state(current_savestate_filename);
287 case BUTTON_ID_SAVESTATE:
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);
298 case BUTTON_ID_FASTFORWARD:
299 print_string("FASTFORWARD", 0xFFFF, 0x0000, 0, 50);
300 synchronize_flag ^= 1;
304 if(buttons & button_psp_mask_to_config[i])
306 button_id = gamepad_config_map[i];
307 if(button_id < BUTTON_ID_MENU)
309 new_key |= button_id_to_gba_mask[button_id];
313 if((button_id >= BUTTON_ID_RAPIDFIRE_A) &&
314 (button_id <= BUTTON_ID_RAPIDFIRE_L))
319 new_key |= button_id_to_gba_mask[button_id -
320 BUTTON_ID_RAPIDFIRE_A + BUTTON_ID_A];
324 new_key &= ~button_id_to_gba_mask[button_id -
325 BUTTON_ID_RAPIDFIRE_A + BUTTON_ID_A];
331 if((new_key | key) != key)
332 trigger_key(new_key);
336 io_registers[REG_P1] = (~key) & 0x3FF;
343 sceCtrlSetSamplingCycle(0);
344 sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG);
352 // GP2X SDL requires a user made input method
353 #include <sys/mman.h>
354 #include <sys/ioctl.h>
355 #include "gp2x/gp2x.h"
357 u32 gamepad_config_map[16] =
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
371 BUTTON_ID_VOLDOWN, // Vol down
372 BUTTON_ID_VOLUP, // Vol up
373 BUTTON_ID_FPS, // Push
374 BUTTON_ID_MENU // Vol middle
377 extern u32 fps_debug;
378 extern u32 gpsp_gp2x_joystick_read(void);
380 gui_action_type get_gui_input()
382 gui_action_type new_button = CURSOR_NONE;
383 u32 buttons = gpsp_gp2x_joystick_read();
386 static u32 last_buttons = 0;
387 static u64 button_repeat_timestamp;
391 new_buttons = (last_buttons ^ buttons) & buttons;
392 last_buttons = buttons;
394 if(new_buttons & GP2X_A)
395 new_button = CURSOR_BACK;
397 if(new_buttons & GP2X_X)
398 new_button = CURSOR_EXIT;
400 if(new_buttons & GP2X_B)
401 new_button = CURSOR_SELECT;
403 if(new_buttons & GP2X_UP)
404 new_button = CURSOR_UP;
406 if(new_buttons & GP2X_DOWN)
407 new_button = CURSOR_DOWN;
409 if(new_buttons & GP2X_LEFT)
410 new_button = CURSOR_LEFT;
412 if(new_buttons & GP2X_RIGHT)
413 new_button = CURSOR_RIGHT;
415 if(new_buttons & GP2X_L)
416 new_button = CURSOR_L;
418 if(new_buttons & GP2X_R)
419 new_button = CURSOR_R;
422 if(new_button != CURSOR_NONE)
424 get_ticks_us(&button_repeat_timestamp);
425 button_repeat_state = BUTTON_HELD_INITIAL;
426 button_repeat = new_buttons;
427 cursor_repeat = new_button;
431 if(buttons & button_repeat)
434 get_ticks_us(&new_ticks);
436 if(button_repeat_state == BUTTON_HELD_INITIAL)
438 if((new_ticks - button_repeat_timestamp) >
441 new_button = cursor_repeat;
442 button_repeat_timestamp = new_ticks;
443 button_repeat_state = BUTTON_HELD_REPEAT;
447 if(button_repeat_state == BUTTON_HELD_REPEAT)
449 if((new_ticks - button_repeat_timestamp) >
450 BUTTON_REPEAT_CONTINUE)
452 new_button = cursor_repeat;
453 button_repeat_timestamp = new_ticks;
462 #define GP2X_VOL_MIDDLE (1 << 24)
464 u32 button_gp2x_mask_to_config[] =
484 u32 button_id_to_gba_mask[] =
504 static u32 rapidfire_flag = 1;
505 static u32 last_buttons;
509 u32 buttons = gpsp_gp2x_joystick_read();
512 if((buttons & GP2X_VOL_DOWN) && (buttons & GP2X_VOL_UP))
514 buttons &= ~(GP2X_VOL_DOWN | GP2X_VOL_UP);
515 buttons |= GP2X_VOL_MIDDLE;
519 if((buttons & GP2X_VOL_DOWN) && (buttons & GP2X_SELECT))
521 buttons &= ~(GP2X_VOL_DOWN | GP2X_SELECT);
522 buttons |= GP2X_VOL_MIDDLE;
525 handled_buttons = ((last_buttons ^ buttons) | GP2X_VOL_DOWN | GP2X_VOL_UP) & buttons;
526 last_buttons = buttons;
528 for(i = 0; i < 16; i++)
530 if(handled_buttons & button_gp2x_mask_to_config[i])
531 button_id = gamepad_config_map[i];
533 button_id = BUTTON_ID_NONE;
539 u16 *screen_copy = copy_screen();
540 u32 ret_val = menu(screen_copy);
546 case BUTTON_ID_LOADSTATE:
548 u8 current_savestate_filename[512];
549 get_savestate_filename_noshot(savestate_slot,
550 current_savestate_filename);
551 load_state(current_savestate_filename);
555 case BUTTON_ID_SAVESTATE:
557 u8 current_savestate_filename[512];
558 u16 *current_screen = copy_screen();
559 get_savestate_filename_noshot(savestate_slot,
560 current_savestate_filename);
561 save_state(current_savestate_filename, current_screen);
562 free(current_screen);
566 case BUTTON_ID_FASTFORWARD:
567 print_string("FASTFORWARD", 0xFFFF, 0x0000, 0, 50);
568 synchronize_flag ^= 1;
571 case BUTTON_ID_VOLUP:
572 gp2x_sound_volume(1);
575 case BUTTON_ID_VOLDOWN:
576 gp2x_sound_volume(0);
584 if(buttons & button_gp2x_mask_to_config[i])
586 button_id = gamepad_config_map[i];
587 if(button_id < BUTTON_ID_MENU)
589 new_key |= button_id_to_gba_mask[button_id];
593 if((button_id >= BUTTON_ID_RAPIDFIRE_A) &&
594 (button_id <= BUTTON_ID_RAPIDFIRE_L))
599 new_key |= button_id_to_gba_mask[button_id -
600 BUTTON_ID_RAPIDFIRE_A + BUTTON_ID_A];
604 new_key &= ~button_id_to_gba_mask[button_id -
605 BUTTON_ID_RAPIDFIRE_A + BUTTON_ID_A];
611 if((new_key | key) != key)
612 trigger_key(new_key);
616 io_registers[REG_P1] = (~key) & 0x3FF;
632 u32 key_map(SDLKey key_sym)
658 return BUTTON_SELECT;
671 u32 joy_map(u32 button)
685 return BUTTON_SELECT;
698 gui_action_type get_gui_input()
701 gui_action_type gui_action = CURSOR_NONE;
705 while(SDL_PollEvent(&event))
714 switch(event.key.keysym.sym)
717 gui_action = CURSOR_EXIT;
721 gui_action = CURSOR_DOWN;
725 gui_action = CURSOR_UP;
729 gui_action = CURSOR_LEFT;
733 gui_action = CURSOR_RIGHT;
737 gui_action = CURSOR_SELECT;
741 gui_action = CURSOR_BACK;
756 while(SDL_PollEvent(&event))
765 if(event.key.keysym.sym == SDLK_ESCAPE)
770 if(event.key.keysym.sym == SDLK_BACKSPACE)
772 u16 *screen_copy = copy_screen();
773 u32 ret_val = menu(screen_copy);
780 if(event.key.keysym.sym == SDLK_F1)
786 if(event.key.keysym.sym == SDLK_F2)
788 FILE *fp = fopen("palette_ram.bin", "wb");
789 printf("writing palette RAM\n");
790 fwrite(palette_ram, 1024, 1, fp);
792 printf("writing palette VRAM\n");
793 fp = fopen("vram.bin", "wb");
794 fwrite(vram, 1024 * 96, 1, fp);
796 printf("writing palette OAM RAM\n");
797 fp = fopen("oam_ram.bin", "wb");
798 fwrite(oam_ram, 1024, 1, fp);
800 printf("writing palette I/O registers\n");
801 fp = fopen("io_registers.bin", "wb");
802 fwrite(io_registers, 1024, 1, fp);
807 if(event.key.keysym.sym == SDLK_F3)
809 dump_translation_cache();
813 if(event.key.keysym.sym == SDLK_F5)
815 u8 current_savestate_filename[512];
816 u16 *current_screen = copy_screen();
817 get_savestate_filename_noshot(savestate_slot,
818 current_savestate_filename);
819 save_state(current_savestate_filename, current_screen);
820 free(current_screen);
824 if(event.key.keysym.sym == SDLK_F7)
826 u8 current_savestate_filename[512];
827 get_savestate_filename_noshot(savestate_slot,
828 current_savestate_filename);
829 load_state(current_savestate_filename);
835 if(event.key.keysym.sym == SDLK_BACKQUOTE)
837 synchronize_flag ^= 1;
841 key |= key_map(event.key.keysym.sym);
850 key &= ~(key_map(event.key.keysym.sym));
854 case SDL_JOYBUTTONDOWN:
856 key |= joy_map(event.jbutton.button);
861 case SDL_JOYBUTTONUP:
863 key &= ~(joy_map(event.jbutton.button));
869 io_registers[REG_P1] = (~key) & 0x3FF;
876 u32 joystick_count = SDL_NumJoysticks();
878 if(joystick_count > 0)
881 SDL_JoystickEventState(SDL_ENABLE);
888 #define input_savestate_builder(type) \
889 void input_##type##_savestate(file_tag_type savestate_file) \
891 file_##type##_variable(savestate_file, key); \
894 input_savestate_builder(read);
895 input_savestate_builder(write_mem);