int intake(struct world *mzx_world, char *string, int max_len, int x, int y, char color, int exit_type, int filter_type, int *return_x_pos, bool robo_intk, char *macro) { int currx, curr_len, macro_position = -1; int done = 0, place = 0; char cur_char = 0; char temp_char; int in_macro; int use_mask = mzx_world->conf.mask_midchars; int mouse_press; int key; if(macro != NULL) macro_position = 0; // Activate cursor if(insert_on) cursor_underline(); else cursor_solid(); // Put cursor at the end of the string... currx = curr_len = (int)strlen(string); // ...unless return_x_pos says not to. if((return_x_pos) && (*return_x_pos < currx)) currx = *return_x_pos; if(robo_intk && (currx > 75)) move_cursor(77, y); else move_cursor(x + currx, y); if(insert_on) cursor_underline(); else cursor_solid(); do { if(!robo_intk) { if(use_mask) write_string_mask(string, x, y, color, 0); else write_string_ext(string, x, y, color, 0, 0, 16); } else { draw_char('\x11', color, 79, y); if((curr_len < 76) || (currx < 76)) { draw_char('\x10', color, 0, y); if(curr_len < 76) { if(use_mask) write_line_mask(string, x, y, color, 0); else write_line_ext(string, x, y, color, 0, 0, 16); fill_line(76 - curr_len, x + curr_len, y, 32, color); } else { temp_char = string[76]; string[76] = 0; if(use_mask) write_line_mask(string, x, y, color, 0); else write_line_ext(string, x, y, color, 0, 0, 16); string[76] = temp_char; draw_char('\xaf', color, 79, y); } } else { draw_char('\x20', color, 77, y); if(strlen(string + currx - 75) > 78) { temp_char = string[currx + 1]; string[currx + 1] = 0; if(use_mask) { write_line_mask(string + currx - 75, x, y, color, 0); } else { write_line_ext(string + currx - 75, x, y, color, 0, 0, 16); } string[currx + 1] = temp_char; } else { if(use_mask) { write_line_mask(string + currx - 75, x, y, color, 0); } else { write_line_ext(string + currx - 75, x, y, color, 0, 0, 16); } } draw_char('\xae', color, 0, y); if(currx < curr_len) draw_char('\xaf', color, 79, y); } draw_char('\x20', color, 78, y); } if(!robo_intk) { fill_line(max_len + 1 - curr_len, x + curr_len, y, 32, color); } else { write_number(currx + 1, 79, 32, 0, 3, 0, 10); write_number(curr_len + 1, 79, 36, 0, 3, 0, 10); } in_macro = 0; // Get key if(macro_position != -1) { key = macro[macro_position]; cur_char = key; macro_position++; if(macro[macro_position] == 0) macro_position = -1; if(key == '^') key = IKEY_RETURN; } else { update_screen(); update_event_status_delay(); key = get_key(keycode_internal); place = 0; cur_char = get_key(keycode_unicode); } mouse_press = get_mouse_press_ext(); if(get_mouse_press_ext()) { int mouse_x, mouse_y; get_mouse_position(&mouse_x, &mouse_y); if((mouse_y == y) && (mouse_x >= x) && (mouse_x <= (x + max_len)) && (mouse_press <= MOUSE_BUTTON_RIGHT)) { // Yep, reposition cursor. currx = mouse_x - x; if(currx > curr_len) currx = curr_len; } else { key = -1; done = 1; } } // Handle key cases switch(key) { case IKEY_ESCAPE: { // ESC if(exit_type > 0) { done = 1; } break; } case IKEY_RETURN: { // Enter done = 1; break; } case IKEY_HOME: { if(get_alt_status(keycode_internal) && robo_intk) { done = 1; } else { // Home currx = 0; } break; } case IKEY_END: { if(get_alt_status(keycode_internal) && robo_intk) { done = 1; } else { // End currx = curr_len; } break; } case IKEY_LEFT: { if(get_ctrl_status(keycode_internal)) { // Find nearest space to the left if(currx) { char *current_position = string + currx; if(currx) current_position--; if(!isalnum((int)*current_position)) { while(currx && !isalnum((int)*current_position)) { current_position--; currx--; } } do { current_position--; currx--; } while(currx && isalnum((int)*current_position)); if(currx < 0) currx = 0; } } else { // Left if(currx > 0) currx--; } break; } case IKEY_RIGHT: { if(get_ctrl_status(keycode_internal)) { // Find nearest space to the right if(currx < curr_len) { char *current_position = string + currx; char current_char = *current_position; if(!isalnum((int)current_char)) { do { current_position++; currx++; current_char = *current_position; } while(current_char && !isalnum((int)current_char)); } while(current_char && isalnum((int)current_char)) { current_position++; currx++; current_char = *current_position; } } } else { // Right if(currx < curr_len) currx++; } break; } case IKEY_F1: case IKEY_F2: case IKEY_F3: case IKEY_F4: case IKEY_F5: case IKEY_F6: case IKEY_F7: case IKEY_F8: case IKEY_F9: case IKEY_F10: case IKEY_F11: case IKEY_F12: case IKEY_UP: case IKEY_DOWN: case IKEY_TAB: case IKEY_PAGEUP: case IKEY_PAGEDOWN: { done = 1; break; } case IKEY_INSERT: { if(get_alt_status(keycode_internal) && robo_intk) { done = 1; } else { // Insert if(insert_on) cursor_solid(); else cursor_underline(); insert_on ^= 1; } break; } case IKEY_BACKSPACE: { // Backspace, at 0 it might exit if(get_alt_status(keycode_internal)) { // Alt-backspace, erase input curr_len = currx = 0; string[0] = 0; } else if(get_ctrl_status(keycode_internal)) { // Find nearest space to the left if(currx) { int old_position = currx; if(!isalnum((int)string[currx])) { while(currx && !isalnum((int)string[currx])) { currx--; } } while(currx && isalnum((int)string[currx])) { currx--; } curr_len -= old_position - currx; memmove(string + currx, string + old_position, strlen(string + old_position) + 1); } } else if(currx == 0) { if(exit_type == 2) { done = 1; } } else { // Move all back 1, decreasing string length memmove(string + currx - 1, string + currx, curr_len - currx + 1); curr_len--; // Cursor back one currx--; } break; } case IKEY_DELETE: { // Delete, at the end might exit if(currx == curr_len) { if(exit_type == 2) done = 1; } else { if(curr_len) { // Move all back 1, decreasing string length memmove(string + currx, string + currx + 1, curr_len - currx); curr_len--; } } break; } case IKEY_c: { if(get_ctrl_status(keycode_internal) && robo_intk) { done = 1; } else if(get_alt_status(keycode_internal) && !filter_type) { // If alt - C is pressed, choose character int new_char = char_selection(last_char); if(new_char >= 32) { cur_char = new_char; last_char = new_char; place = 1; } else { place = 0; } } else { place = 1; } break; } case IKEY_t: { if(get_alt_status(keycode_internal)) { done = 1; } else { place = 1; } break; } case IKEY_l: case IKEY_g: case IKEY_d: case IKEY_f: case IKEY_r: { if(get_ctrl_status(keycode_internal) && robo_intk) { done = 1; } else { place = 1; } break; } case IKEY_i: { if((get_ctrl_status(keycode_internal) || get_alt_status(keycode_internal)) && robo_intk) { done = 1; } else { place = 1; } break; } case IKEY_u: case IKEY_o: case IKEY_x: case IKEY_b: case IKEY_s: case IKEY_e: case IKEY_v: case IKEY_p: case IKEY_h: case IKEY_m: { if(get_alt_status(keycode_internal) && robo_intk) { done = 1; } else { place = 1; } break; } case IKEY_LSHIFT: case IKEY_RSHIFT: case 0: { place = 0; break; } default: { // Place the char place = 1; break; } case -1: { break; } } if(place) { if((cur_char < 32) && (exit_type == 2)) { done = 1; key = cur_char; } else // Keycode.. Filter. if(filter_type & 1) { if((cur_char >= 'a') && (cur_char <= 'z')) cur_char -= 32; } if(filter_type & 2) { if((cur_char >= 'A') && (cur_char <= 'Z')) cur_char += 32; } // Block numbers if((filter_type & 4) && ((cur_char >= '0') && (cur_char <= '9'))) { place = 0; } // Block alpha if((filter_type & 8) && (((cur_char >= 'a') && (cur_char <= 'z')) || ((cur_char >= 'A') && (cur_char <= 'Z')))) { place = 0; } // Block spaces if((filter_type & 16) && (cur_char == ' ')) { place = 0; } // Block high-ASCII if((filter_type & 32) && (cur_char > 126)) { place = 0; } // Block these chars if((filter_type & 64) && ((cur_char == '*') || (cur_char == '[') || (cur_char == ']') || (cur_char == '>') || (cur_char == '<') || (cur_char == ',') || (cur_char == '|') || (cur_char == '?') || (cur_char == '=') || (cur_char == ';') || (cur_char == '\"') || (cur_char =='/'))) { place = 0; } // Block these chars if((filter_type & 128) && ((cur_char == ':') || (cur_char == '\\'))) { place = 0; } // Block these chars if((filter_type & 256) && (((cur_char > ' ') && (cur_char < '0')) || ((cur_char > '9') && (cur_char < 'A')) || ((cur_char > 'Z') && (cur_char < 'a')) || ((cur_char > 'z') && (cur_char < 127)))) { place = 0; } // Now, can it still be placed? if(place && (curr_len != max_len) && (!done) && cur_char) { // Overwrite or insert? if((insert_on) || (currx == curr_len)) { // Insert- Move all ahead 1, increasing string length curr_len++; memmove(string + currx + 1, string + currx, curr_len - currx); } // Add character and move forward one string[currx++] = cur_char; } } // Move cursor if(robo_intk && (currx > 75)) move_cursor(77, y); else move_cursor(x + currx, y); if(insert_on) cursor_underline(); else cursor_solid(); // Loop } while(!done); cursor_off(); if(return_x_pos) *return_x_pos = currx; return key; }
static bool process_event(union event *ev) { struct buffered_status *status = store_status(); bool rval = true; switch(ev->type) { case EVENT_BUTTON_DOWN: { Uint32 button = map_button(ev->button.pad, ev->button.button); rval = false; if((ev->button.pad == 0) && pointing) { Uint32 mousebutton; switch(ev->button.button) { case WPAD_BUTTON_A: mousebutton = MOUSE_BUTTON_LEFT; break; case WPAD_BUTTON_B: mousebutton = MOUSE_BUTTON_RIGHT; break; default: mousebutton = 0; break; } if(mousebutton) { status->mouse_button = mousebutton; status->mouse_repeat = mousebutton; status->mouse_button_state |= MOUSE_BUTTON(mousebutton); status->mouse_repeat_state = 1; status->mouse_drag_state = -1; status->mouse_time = get_ticks(); button = 256; rval = true; } } if((button < 256)) { enum keycode skey = input.joystick_button_map[ev->button.pad][button]; if(skey && (status->keymap[skey] == 0)) { key_press(status, skey, skey); rval = true; } } else { if((ev->button.pad < 4) && ((ev->button.button == WPAD_BUTTON_HOME) || ((ext_type[ev->button.pad] == WPAD_EXP_CLASSIC) && (ev->button.button == WPAD_CLASSIC_BUTTON_HOME)))) { status->keymap[IKEY_ESCAPE] = 1; status->key = IKEY_ESCAPE; status->keypress_time = get_ticks(); rval = true; break; } } break; } case EVENT_BUTTON_UP: { Uint32 button = map_button(ev->button.pad, ev->button.button); rval = false; if((ev->button.pad == 0) && status->mouse_button_state) { Uint32 mousebutton; switch(ev->button.button) { case WPAD_BUTTON_A: mousebutton = MOUSE_BUTTON_LEFT; break; case WPAD_BUTTON_B: mousebutton = MOUSE_BUTTON_RIGHT; break; default: mousebutton = 0; break; } if(mousebutton && (status->mouse_button_state & MOUSE_BUTTON(mousebutton))) { status->mouse_button_state &= ~MOUSE_BUTTON(mousebutton); status->mouse_repeat = 0; status->mouse_drag_state = 0; status->mouse_repeat_state = 0; button = 256; rval = true; } } if((button < 256)) { enum keycode skey = input.joystick_button_map[ev->button.pad][button]; if(skey) { key_release(status, skey); rval = true; } } break; } case EVENT_AXIS_MOVE: { int digital_value = -1; int axis = ev->axis.axis; int last_axis; enum keycode skey; if(ev->axis.pad < 4) { switch(ext_type[ev->axis.pad]) { case WPAD_EXP_NUNCHUK: break; case WPAD_EXP_CLASSIC: axis += 2; break; case WPAD_EXP_GUITARHERO3: axis += 6; break; default: axis = 256; break; // Not supposed to happen } } if(axis == 256) break; last_axis = status->axis[ev->axis.pad][axis]; if(ev->axis.pos > 10000) digital_value = 1; else if(ev->axis.pos < -10000) digital_value = 0; if(digital_value != -1) { skey = input.joystick_axis_map[ev->axis.pad][axis][digital_value]; if(skey) { if(status->keymap[skey] == 0) key_press(status, skey, skey); if(last_axis == (digital_value ^ 1)) { skey = input.joystick_axis_map[ev->axis.pad][axis][last_axis]; key_release(status, skey); } } } else { if(last_axis != -1) { skey = input.joystick_axis_map[ev->axis.pad][axis][last_axis]; if(skey) key_release(status, skey); } } status->axis[ev->axis.pad][axis] = digital_value; break; } case EVENT_CHANGE_EXT: { ext_type[ev->ext.pad] = ev->ext.ext; break; } case EVENT_POINTER_MOVE: { pointing = 1; status->mouse_moved = true; status->real_mouse_x = ev->pointer.x; status->real_mouse_y = ev->pointer.y; status->mouse_x = ev->pointer.x / 8; status->mouse_y = ev->pointer.y / 14; break; } case EVENT_POINTER_OUT: { pointing = 0; break; } case EVENT_KEY_DOWN: { enum keycode ckey = convert_USB_internal(ev->key.key); if(!ckey) { if(ev->key.unicode) ckey = IKEY_UNICODE; else { rval = false; break; } } if((ckey == IKEY_RETURN) && get_alt_status(keycode_internal) && get_ctrl_status(keycode_internal)) { toggle_fullscreen(); break; } if(ckey == IKEY_F12) { dump_screen(); break; } if(status->key_repeat && (status->key_repeat != IKEY_LSHIFT) && (status->key_repeat != IKEY_RSHIFT) && (status->key_repeat != IKEY_LALT) && (status->key_repeat != IKEY_RALT) && (status->key_repeat != IKEY_LCTRL) && (status->key_repeat != IKEY_RCTRL)) { // Stack current repeat key if it isn't shift, alt, or ctrl if(input.repeat_stack_pointer != KEY_REPEAT_STACK_SIZE) { input.key_repeat_stack[input.repeat_stack_pointer] = status->key_repeat; input.unicode_repeat_stack[input.repeat_stack_pointer] = status->unicode_repeat; input.repeat_stack_pointer++; } } key_press(status, ckey, ev->key.unicode); break; } case EVENT_KEY_UP: { enum keycode ckey = convert_USB_internal(ev->key.key); if(!ckey) { if(status->keymap[IKEY_UNICODE]) ckey = IKEY_UNICODE; else { rval = false; break; } } status->keymap[ckey] = 0; if(status->key_repeat == ckey) { status->key_repeat = IKEY_UNKNOWN; status->unicode_repeat = 0; } status->key_release = ckey; break; } case EVENT_KEY_LOCKS: { status->numlock_status = !!(ev->locks.locks & MOD_NUMLOCK); status->caps_status = !!(ev->locks.locks & MOD_CAPSLOCK); break; } case EVENT_MOUSE_MOVE: { int mx = status->real_mouse_x + ev->mmove.dx; int my = status->real_mouse_y + ev->mmove.dy; if(mx < 0) mx = 0; if(my < 0) my = 0; if(mx >= 640) mx = 639; if(my >= 350) my = 349; status->real_mouse_x = mx; status->real_mouse_y = my; status->mouse_x = mx / 8; status->mouse_y = my / 14; status->mouse_moved = true; break; } case EVENT_MOUSE_BUTTON_DOWN: { Uint32 button = 0; switch (ev->mbutton.button) { case USB_MOUSE_BTN_LEFT: button = MOUSE_BUTTON_LEFT; break; case USB_MOUSE_BTN_RIGHT: button = MOUSE_BUTTON_RIGHT; break; case USB_MOUSE_BTN_MIDDLE: button = MOUSE_BUTTON_MIDDLE; break; default: break; } if(!button) break; status->mouse_button = button; status->mouse_repeat = button; status->mouse_button_state |= MOUSE_BUTTON(button); status->mouse_repeat_state = 1; status->mouse_drag_state = -1; status->mouse_time = get_ticks(); break; } case EVENT_MOUSE_BUTTON_UP: { Uint32 button = 0; switch (ev->mbutton.button) { case USB_MOUSE_BTN_LEFT: button = MOUSE_BUTTON_LEFT; break; case USB_MOUSE_BTN_RIGHT: button = MOUSE_BUTTON_RIGHT; break; case USB_MOUSE_BTN_MIDDLE: button = MOUSE_BUTTON_MIDDLE; break; default: break; } if(!button) break; status->mouse_button_state &= ~MOUSE_BUTTON(button); status->mouse_repeat = 0; status->mouse_drag_state = 0; status->mouse_repeat_state = 0; break; } default: { rval = false; break; } } return rval; }
static bool process_event(SDL_Event *event) { struct buffered_status *status = store_status(); enum keycode ckey; /* SDL's numlock keyboard modifier handling seems to be broken on X11, * and it will only get numlock's status right on application init. We * can trust this value once, and then toggle based on user presses of * the numlock key. * * On Windows, KEYDOWN/KEYUP seem to be sent separately, to indicate * enabling or disabling of numlock. But on X11, both KEYDOWN/KEYUP are * sent for each toggle, so this must be handled differently. * * What a mess! */ if(!numlock_status_initialized) { status->numlock_status = !!(SDL_GetModState() & KMOD_NUM); numlock_status_initialized = true; } switch(event->type) { case SDL_QUIT: { // Stuff an escape status->key = IKEY_ESCAPE; status->keymap[IKEY_ESCAPE] = 1; status->keypress_time = get_ticks(); break; } #if SDL_VERSION_ATLEAST(2,0,0) case SDL_WINDOWEVENT: { switch(event->window.event) { case SDL_WINDOWEVENT_RESIZED: { resize_screen(event->window.data1, event->window.data2); break; } case SDL_WINDOWEVENT_FOCUS_LOST: { // Pause while minimized if(input.unfocus_pause) { while(1) { SDL_WaitEvent(event); if(event->type == SDL_WINDOWEVENT && event->window.event == SDL_WINDOWEVENT_FOCUS_GAINED) break; } } break; } } break; } #else // !SDL_VERSION_ATLEAST(2,0,0) case SDL_VIDEORESIZE: { resize_screen(event->resize.w, event->resize.h); break; } case SDL_ACTIVEEVENT: { if(input.unfocus_pause) { // Pause while minimized if(event->active.state & (SDL_APPACTIVE | SDL_APPINPUTFOCUS)) { // Wait for SDL_APPACTIVE with gain of 1 do { SDL_WaitEvent(event); } while((event->type != SDL_ACTIVEEVENT) || (event->active.state & ~(SDL_APPACTIVE | SDL_APPINPUTFOCUS))); } } break; } #endif // !SDL_VERSION_ATLEAST(2,0,0) case SDL_MOUSEMOTION: { SDL_Window *window = SDL_GetWindowFromID(sdl_window_id); int mx_real = event->motion.x; int my_real = event->motion.y; int mx, my, min_x, min_y, max_x, max_y; get_screen_coords(mx_real, my_real, &mx, &my, &min_x, &min_y, &max_x, &max_y); if(mx > 639) SDL_WarpMouseInWindow(window, max_x, my_real); if(mx < 0) SDL_WarpMouseInWindow(window, min_x, my_real); if(my > 349) SDL_WarpMouseInWindow(window, mx_real, max_y); if(my < 0) SDL_WarpMouseInWindow(window, mx_real, min_y); status->real_mouse_x = mx; status->real_mouse_y = my; status->mouse_x = mx / 8; status->mouse_y = my / 14; status->mouse_moved = true; break; } case SDL_MOUSEBUTTONDOWN: { status->mouse_button = event->button.button; status->mouse_repeat = event->button.button; status->mouse_button_state |= SDL_BUTTON(event->button.button); status->mouse_repeat_state = 1; status->mouse_drag_state = -1; status->mouse_time = SDL_GetTicks(); break; } case SDL_MOUSEBUTTONUP: { status->mouse_button_state &= ~SDL_BUTTON(event->button.button); status->mouse_repeat = 0; status->mouse_drag_state = 0; status->mouse_repeat_state = 0; break; } #if SDL_VERSION_ATLEAST(2,0,0) // emulate the X11-style "wheel is a button" that SDL 1.2 used case SDL_MOUSEWHEEL: { SDL_Event fake_event; fake_event.type = SDL_MOUSEBUTTONDOWN; fake_event.button.windowID = event->wheel.windowID; fake_event.button.which = event->wheel.which; fake_event.button.state = SDL_PRESSED; fake_event.button.x = 0; fake_event.button.y = 0; if(event->wheel.y < 0) fake_event.button.button = MOUSE_BUTTON_WHEELDOWN; else fake_event.button.button = MOUSE_BUTTON_WHEELUP; SDL_PushEvent(&fake_event); fake_event.type = SDL_MOUSEBUTTONUP; fake_event.button.state = SDL_RELEASED; SDL_PushEvent(&fake_event); break; } #endif // SDL_VERSION_ATLEAST(2,0,0) case SDL_KEYDOWN: { Uint16 unicode = 0; #if SDL_VERSION_ATLEAST(2,0,0) // FIXME: SDL 2.0 finally implements proper key repeat. // We should probably use it instead of our hand-rolled stuff. if(event->key.repeat) break; #endif ckey = convert_SDL_internal(event->key.keysym.sym); if(!ckey) { #if !SDL_VERSION_ATLEAST(2,0,0) if(!event->key.keysym.unicode) break; #endif ckey = IKEY_UNICODE; } #if SDL_VERSION_ATLEAST(2,0,0) // SDL 2.0 sends the raw key and translated 'text' as separate events. // There is no longer a UNICODE mode that sends both at once. // Because of the way the SDL 1.2 assumption is embedded deeply in // the MZX event queue processor, emulate the 1.2 behaviour by waiting // for a TEXTINPUT event after a KEYDOWN. if(SDL_WaitEventTimeout(event, 1)) { if(event->type == SDL_TEXTINPUT) unicode = event->text.text[0] | event->text.text[1] << 8; else SDL_PushEvent(event); } #else unicode = event->key.keysym.unicode; #endif if((ckey == IKEY_RETURN) && get_alt_status(keycode_internal) && get_ctrl_status(keycode_internal)) { toggle_fullscreen(); break; } if(ckey == IKEY_CAPSLOCK) { status->caps_status = true; } if(ckey == IKEY_NUMLOCK) { #if !SDL_VERSION_ATLEAST(2,0,0) && defined(__WIN32__) status->numlock_status = true; #endif break; } if(ckey == IKEY_F12) { dump_screen(); break; } // Ignore alt + tab if((ckey == IKEY_TAB) && get_alt_status(keycode_internal)) { break; } if(status->key_repeat && (status->key_repeat != IKEY_LSHIFT) && (status->key_repeat != IKEY_RSHIFT) && (status->key_repeat != IKEY_LALT) && (status->key_repeat != IKEY_RALT) && (status->key_repeat != IKEY_LCTRL) && (status->key_repeat != IKEY_RCTRL)) { // Stack current repeat key if it isn't shift, alt, or ctrl if(input.repeat_stack_pointer != KEY_REPEAT_STACK_SIZE) { input.key_repeat_stack[input.repeat_stack_pointer] = status->key_repeat; input.unicode_repeat_stack[input.repeat_stack_pointer] = status->unicode_repeat; input.repeat_stack_pointer++; } } key_press(status, ckey, unicode); break; } case SDL_KEYUP: { #if SDL_VERSION_ATLEAST(2,0,0) // FIXME: SDL 2.0 finally implements proper key repeat. // We should probably use it instead of our hand-rolled stuff. if(event->key.repeat) break; #endif ckey = convert_SDL_internal(event->key.keysym.sym); if(!ckey) { #if !SDL_VERSION_ATLEAST(2,0,0) if(!status->keymap[IKEY_UNICODE]) break; #endif ckey = IKEY_UNICODE; } if(ckey == IKEY_NUMLOCK) { #if !SDL_VERSION_ATLEAST(2,0,0) && defined(__WIN32__) status->numlock_status = false; #else status->numlock_status = !status->numlock_status; #endif break; } if(ckey == IKEY_CAPSLOCK) { status->caps_status = false; } status->keymap[ckey] = 0; if(status->key_repeat == ckey) { status->key_repeat = IKEY_UNKNOWN; status->unicode_repeat = 0; } status->key_release = ckey; break; } case SDL_JOYAXISMOTION: { int axis_value = event->jaxis.value; int digital_value = -1; int which = event->jaxis.which; int axis = event->jaxis.axis; Sint8 last_axis = status->axis[which][axis]; enum keycode stuffed_key; if(axis_value > 10000) digital_value = 1; else if(axis_value < -10000) digital_value = 0; if(digital_value != -1) { stuffed_key = input.joystick_axis_map[which][axis][digital_value]; if(stuffed_key) { joystick_key_press(status, stuffed_key, stuffed_key); if(last_axis == (digital_value ^ 1)) { joystick_key_release(status, input.joystick_axis_map[which][axis][last_axis]); } } } else if(last_axis != -1) { joystick_key_release(status, input.joystick_axis_map[which][axis][last_axis]); } status->axis[which][axis] = digital_value; break; } case SDL_JOYBUTTONDOWN: { int which = event->jbutton.which; int button = event->jbutton.button; enum keycode stuffed_key = input.joystick_button_map[which][button]; if(stuffed_key) joystick_key_press(status, stuffed_key, stuffed_key); break; } case SDL_JOYBUTTONUP: { int which = event->jbutton.which; int button = event->jbutton.button; enum keycode stuffed_key = input.joystick_button_map[which][button]; if(stuffed_key) joystick_key_release(status, stuffed_key); break; } case SDL_JOYHATMOTION: { int which = event->jhat.which; int dir = event->jhat.value; enum keycode key_up = input.joystick_hat_map[which][0]; enum keycode key_down = input.joystick_hat_map[which][1]; enum keycode key_left = input.joystick_hat_map[which][2]; enum keycode key_right = input.joystick_hat_map[which][3]; //if(dir & SDL_HAT_CENTERED) { joystick_key_release(status, key_up); joystick_key_release(status, key_down); joystick_key_release(status, key_left); joystick_key_release(status, key_right); } if(dir & SDL_HAT_UP) { if (key_up) joystick_key_press(status, key_up, key_up); } if(dir & SDL_HAT_DOWN) { if (key_down) joystick_key_press(status, key_down, key_down); } if(dir & SDL_HAT_LEFT) { if (key_left) joystick_key_press(status, key_left, key_left); } if(dir & SDL_HAT_RIGHT) { if (key_right) joystick_key_press(status, key_right, key_right); } break; } default: return false; } return true; }