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];
28 if((p1_cnt >> 14) & 0x01)
30 u32 key_intersection = (p1_cnt & key) & 0x3FF;
34 if(key_intersection == (p1_cnt & 0x3FF))
35 raise_interrupt(IRQ_KEYPAD);
40 raise_interrupt(IRQ_KEYPAD);
47 u32 global_enable_analog = 1;
48 u32 analog_sensitivity_level = 4;
55 } button_repeat_state_type;
58 // These define autorepeat values (in microseconds), tweak as necessary.
60 #define BUTTON_REPEAT_START 200000
61 #define BUTTON_REPEAT_CONTINUE 50000
63 button_repeat_state_type button_repeat_state = BUTTON_NOT_HELD;
64 u32 button_repeat = 0;
65 gui_action_type cursor_repeat = CURSOR_NONE;
70 u32 gamepad_config_map[16] =
72 BUTTON_ID_MENU, // Triangle
73 BUTTON_ID_A, // Circle
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
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
90 #define PSP_ALL_BUTTON_MASK 0xFFFF
92 gui_action_type get_gui_input()
94 SceCtrlData ctrl_data;
95 gui_action_type new_button = CURSOR_NONE;
98 static u32 last_buttons = 0;
99 static u64 button_repeat_timestamp;
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;
108 if(new_buttons & PSP_CTRL_LEFT)
109 new_button = CURSOR_LEFT;
111 if(new_buttons & PSP_CTRL_RIGHT)
112 new_button = CURSOR_RIGHT;
114 if(new_buttons & PSP_CTRL_UP)
115 new_button = CURSOR_UP;
117 if(new_buttons & PSP_CTRL_DOWN)
118 new_button = CURSOR_DOWN;
120 if(new_buttons & PSP_CTRL_START)
121 new_button = CURSOR_SELECT;
123 if(new_buttons & PSP_CTRL_CIRCLE)
124 new_button = CURSOR_SELECT;
126 if(new_buttons & PSP_CTRL_CROSS)
127 new_button = CURSOR_EXIT;
129 if(new_buttons & PSP_CTRL_SQUARE)
130 new_button = CURSOR_BACK;
132 if(new_button != CURSOR_NONE)
134 get_ticks_us(&button_repeat_timestamp);
135 button_repeat_state = BUTTON_HELD_INITIAL;
136 button_repeat = new_buttons;
137 cursor_repeat = new_button;
141 if(ctrl_data.Buttons & button_repeat)
144 get_ticks_us(&new_ticks);
146 if(button_repeat_state == BUTTON_HELD_INITIAL)
148 if((new_ticks - button_repeat_timestamp) >
151 new_button = cursor_repeat;
152 button_repeat_timestamp = new_ticks;
153 button_repeat_state = BUTTON_HELD_REPEAT;
157 if(button_repeat_state == BUTTON_HELD_REPEAT)
159 if((new_ticks - button_repeat_timestamp) >
160 BUTTON_REPEAT_CONTINUE)
162 new_button = cursor_repeat;
163 button_repeat_timestamp = new_ticks;
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)
177 u32 button_psp_mask_to_config[] =
192 PSP_CTRL_ANALOG_DOWN,
193 PSP_CTRL_ANALOG_LEFT,
194 PSP_CTRL_ANALOG_RIGHT
197 u32 button_id_to_gba_mask[] =
215 gui_action_type get_gui_input_fs_hold(u32 button_id)
217 gui_action_type new_button = get_gui_input();
218 if((last_buttons & button_psp_mask_to_config[button_id]) == 0)
224 u32 rapidfire_flag = 1;
228 SceCtrlData ctrl_data;
230 u32 non_repeat_buttons;
234 u32 analog_sensitivity = 92 - (analog_sensitivity_level * 4);
235 u32 inv_analog_sensitivity = 256 - analog_sensitivity;
237 sceCtrlPeekBufferPositive(&ctrl_data, 1);
239 buttons = ctrl_data.Buttons;
241 if(global_enable_analog)
243 if(ctrl_data.Lx < analog_sensitivity)
244 buttons |= PSP_CTRL_ANALOG_LEFT;
246 if(ctrl_data.Lx > inv_analog_sensitivity)
247 buttons |= PSP_CTRL_ANALOG_RIGHT;
249 if(ctrl_data.Ly < analog_sensitivity)
250 buttons |= PSP_CTRL_ANALOG_UP;
252 if(ctrl_data.Ly > inv_analog_sensitivity)
253 buttons |= PSP_CTRL_ANALOG_DOWN;
256 non_repeat_buttons = (last_buttons ^ buttons) & buttons;
257 last_buttons = buttons;
259 for(i = 0; i < 16; i++)
261 if(non_repeat_buttons & button_psp_mask_to_config[i])
262 button_id = gamepad_config_map[i];
264 button_id = BUTTON_ID_NONE;
270 u16 *screen_copy = copy_screen();
271 u32 ret_val = menu(screen_copy);
277 case BUTTON_ID_LOADSTATE:
279 u8 current_savestate_filename[512];
280 get_savestate_filename_noshot(savestate_slot,
281 current_savestate_filename);
282 load_state(current_savestate_filename);
286 case BUTTON_ID_SAVESTATE:
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);
297 case BUTTON_ID_FASTFORWARD:
298 print_string("FASTFORWARD", 0xFFFF, 0x0000, 0, 50);
299 synchronize_flag ^= 1;
303 if(buttons & button_psp_mask_to_config[i])
305 button_id = gamepad_config_map[i];
306 if(button_id < BUTTON_ID_MENU)
308 new_key |= button_id_to_gba_mask[button_id];
312 if((button_id >= BUTTON_ID_RAPIDFIRE_A) &&
313 (button_id <= BUTTON_ID_RAPIDFIRE_L))
318 new_key |= button_id_to_gba_mask[button_id -
319 BUTTON_ID_RAPIDFIRE_A + BUTTON_ID_A];
323 new_key &= ~button_id_to_gba_mask[button_id -
324 BUTTON_ID_RAPIDFIRE_A + BUTTON_ID_A];
330 if((new_key | key) != key)
331 trigger_key(new_key);
335 io_registers[REG_P1] = (~key) & 0x3FF;
342 sceCtrlSetSamplingCycle(0);
343 sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG);
349 #if defined(GP2X_BUILD) || defined(PND_BUILD)
351 extern u32 fps_debug;
353 gui_action_type get_gui_input()
355 gui_action_type new_button = CURSOR_NONE;
356 u32 buttons = gpsp_plat_joystick_read();
359 static u32 last_buttons = 0;
360 static u64 button_repeat_timestamp;
364 new_buttons = (last_buttons ^ buttons) & buttons;
365 last_buttons = buttons;
367 new_button = gpsp_plat_buttons_to_cursor(new_buttons);
368 if(new_button != CURSOR_NONE)
370 get_ticks_us(&button_repeat_timestamp);
371 button_repeat_state = BUTTON_HELD_INITIAL;
372 button_repeat = new_buttons;
373 cursor_repeat = new_button;
377 if(buttons & button_repeat)
380 get_ticks_us(&new_ticks);
382 if(button_repeat_state == BUTTON_HELD_INITIAL)
384 if((new_ticks - button_repeat_timestamp) >
387 new_button = cursor_repeat;
388 button_repeat_timestamp = new_ticks;
389 button_repeat_state = BUTTON_HELD_REPEAT;
393 if(button_repeat_state == BUTTON_HELD_REPEAT)
395 if((new_ticks - button_repeat_timestamp) >
396 BUTTON_REPEAT_CONTINUE)
398 new_button = cursor_repeat;
399 button_repeat_timestamp = new_ticks;
408 u32 button_id_to_gba_mask[] =
428 static u32 rapidfire_flag = 1;
429 static u32 last_buttons;
433 u32 buttons = gpsp_plat_joystick_read();
437 if((buttons & GP2X_VOL_DOWN) && (buttons & GP2X_VOL_UP))
439 buttons &= ~(GP2X_VOL_DOWN | GP2X_VOL_UP);
440 buttons |= GP2X_VOL_MIDDLE;
444 if((buttons & GP2X_VOL_DOWN) && (buttons & GP2X_SELECT))
446 buttons &= ~(GP2X_VOL_DOWN | GP2X_SELECT);
447 buttons |= GP2X_VOL_MIDDLE;
450 last_buttons &= ~(GP2X_VOL_DOWN | GP2X_VOL_UP);
453 handled_buttons = (last_buttons ^ buttons) & buttons;
454 last_buttons = buttons;
456 for(i = 0; i < PLAT_BUTTON_COUNT; i++)
458 if(handled_buttons & button_plat_mask_to_config[i])
459 button_id = gamepad_config_map[i];
461 button_id = BUTTON_ID_NONE;
467 u16 *screen_copy = copy_screen();
468 u32 ret_val = menu(screen_copy);
474 case BUTTON_ID_LOADSTATE:
476 char current_savestate_filename[512];
477 get_savestate_filename_noshot(savestate_slot,
478 current_savestate_filename);
479 load_state(current_savestate_filename);
483 case BUTTON_ID_SAVESTATE:
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);
494 case BUTTON_ID_FASTFORWARD:
495 synchronize_flag ^= 1;
499 case BUTTON_ID_VOLUP:
500 gp2x_sound_volume(1);
503 case BUTTON_ID_VOLDOWN:
504 gp2x_sound_volume(0);
513 if(buttons & button_plat_mask_to_config[i])
515 button_id = gamepad_config_map[i];
516 if(button_id < BUTTON_ID_MENU)
518 new_key |= button_id_to_gba_mask[button_id];
522 if((button_id >= BUTTON_ID_RAPIDFIRE_A) &&
523 (button_id <= BUTTON_ID_RAPIDFIRE_L))
528 new_key |= button_id_to_gba_mask[button_id -
529 BUTTON_ID_RAPIDFIRE_A + BUTTON_ID_A];
533 new_key &= ~button_id_to_gba_mask[button_id -
534 BUTTON_ID_RAPIDFIRE_A + BUTTON_ID_A];
540 if((new_key | key) != key)
541 trigger_key(new_key);
545 io_registers[REG_P1] = (~key) & 0x3FF;
561 u32 key_map(SDLKey key_sym)
587 return BUTTON_SELECT;
600 u32 joy_map(u32 button)
614 return BUTTON_SELECT;
627 gui_action_type get_gui_input()
630 gui_action_type gui_action = CURSOR_NONE;
634 while(SDL_PollEvent(&event))
643 switch(event.key.keysym.sym)
646 gui_action = CURSOR_EXIT;
650 gui_action = CURSOR_DOWN;
654 gui_action = CURSOR_UP;
658 gui_action = CURSOR_LEFT;
662 gui_action = CURSOR_RIGHT;
666 gui_action = CURSOR_SELECT;
670 gui_action = CURSOR_BACK;
688 while(SDL_PollEvent(&event))
697 if(event.key.keysym.sym == SDLK_ESCAPE)
702 if(event.key.keysym.sym == SDLK_BACKSPACE)
704 u16 *screen_copy = copy_screen();
705 u32 ret_val = menu(screen_copy);
712 if(event.key.keysym.sym == SDLK_F1)
718 if(event.key.keysym.sym == SDLK_F2)
720 FILE *fp = fopen("palette_ram.bin", "wb");
721 printf("writing palette RAM\n");
722 fwrite(palette_ram, 1024, 1, fp);
724 printf("writing palette VRAM\n");
725 fp = fopen("vram.bin", "wb");
726 fwrite(vram, 1024 * 96, 1, fp);
728 printf("writing palette OAM RAM\n");
729 fp = fopen("oam_ram.bin", "wb");
730 fwrite(oam_ram, 1024, 1, fp);
732 printf("writing palette I/O registers\n");
733 fp = fopen("io_registers.bin", "wb");
734 fwrite(io_registers, 1024, 1, fp);
739 if(event.key.keysym.sym == SDLK_F3)
741 dump_translation_cache();
745 if(event.key.keysym.sym == SDLK_F5)
747 char current_savestate_filename[512];
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);
756 if(event.key.keysym.sym == SDLK_F7)
758 char current_savestate_filename[512];
759 get_savestate_filename_noshot(savestate_slot,
760 current_savestate_filename);
761 load_state(current_savestate_filename);
767 if(event.key.keysym.sym == SDLK_BACKQUOTE)
769 synchronize_flag ^= 1;
773 key |= key_map(event.key.keysym.sym);
782 key &= ~(key_map(event.key.keysym.sym));
786 case SDL_JOYBUTTONDOWN:
788 key |= joy_map(event.jbutton.button);
793 case SDL_JOYBUTTONUP:
795 key &= ~(joy_map(event.jbutton.button));
801 io_registers[REG_P1] = (~key) & 0x3FF;
808 u32 joystick_count = SDL_NumJoysticks();
810 if(joystick_count > 0)
813 SDL_JoystickEventState(SDL_ENABLE);
820 #define input_savestate_builder(type) \
821 void input_##type##_savestate(file_tag_type savestate_file) \
823 file_##type##_variable(savestate_file, key); \
826 input_savestate_builder(read);
827 input_savestate_builder(write_mem);