static unsigned menu_input_frame_pointer(unsigned *data) { unsigned ret = *data; settings_t *settings = config_get_ptr(); menu_input_t *menu_input = menu_input_get_ptr(); bool mouse_enabled = settings->menu.mouse.enable; #ifdef HAVE_OVERLAY if (!mouse_enabled) mouse_enabled = !(settings->input.overlay_enable && input_overlay_is_alive(NULL)); #endif if (!mouse_enabled) menu_input->mouse.ptr = 0; if (settings->menu.pointer.enable) menu_input_pointer(&ret); else memset(&menu_input->pointer, 0, sizeof(menu_input->pointer)); return ret; }
static int menu_input_mouse_post_iterate(uint64_t *input_mouse, menu_file_list_cbs_t *cbs, unsigned action) { size_t selection; unsigned header_height; settings_t *settings = config_get_ptr(); menu_input_t *menu_input = menu_input_get_ptr(); *input_mouse = MOUSE_ACTION_NONE; menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SELECTION, &selection); if (!settings->menu.mouse.enable #ifdef HAVE_OVERLAY || (settings->input.overlay_enable && input_overlay_is_alive()) #endif ) { menu_input->mouse.wheeldown = false; menu_input->mouse.wheelup = false; menu_input->mouse.oldleft = false; menu_input->mouse.oldright = false; return 0; } if (menu_input_mouse_state(MENU_MOUSE_LEFT_BUTTON)) { if (!menu_input->mouse.oldleft) { menu_display_ctl(MENU_DISPLAY_CTL_HEADER_HEIGHT, &header_height); BIT64_SET(*input_mouse, MOUSE_ACTION_BUTTON_L); menu_input->mouse.oldleft = true; if ((unsigned)menu_input->mouse.y < header_height) { menu_entries_pop_stack(&selection, 0); menu_navigation_ctl(MENU_NAVIGATION_CTL_SET_SELECTION, &selection); return 0; } if ((menu_input->mouse.ptr == selection) && cbs && cbs->action_select) { BIT64_SET(*input_mouse, MOUSE_ACTION_BUTTON_L_TOGGLE); } else if (menu_input->mouse.ptr <= (menu_entries_get_size() - 1)) { BIT64_SET(*input_mouse, MOUSE_ACTION_BUTTON_L_SET_NAVIGATION); } } } else menu_input->mouse.oldleft = false; if (menu_input_mouse_state(MENU_MOUSE_RIGHT_BUTTON)) { if (!menu_input->mouse.oldright) { menu_input->mouse.oldright = true; BIT64_SET(*input_mouse, MOUSE_ACTION_BUTTON_R); } } else menu_input->mouse.oldright = false; if (menu_input->mouse.wheeldown) { BIT64_SET(*input_mouse, MOUSE_ACTION_WHEEL_DOWN); } if (menu_input->mouse.wheelup) { BIT64_SET(*input_mouse, MOUSE_ACTION_WHEEL_UP); } return 0; }
static int menu_input_pointer_post_iterate(menu_file_list_cbs_t *cbs, menu_entry_t *entry, unsigned action) { unsigned header_height; size_t selection; int ret = 0; menu_input_t *menu_input = menu_input_get_ptr(); settings_t *settings = config_get_ptr(); if (!menu_input) return -1; if (!menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SELECTION, &selection)) return -1; menu_display_ctl(MENU_DISPLAY_CTL_HEADER_HEIGHT, &header_height); if (!settings->menu.pointer.enable #ifdef HAVE_OVERLAY || (settings->input.overlay_enable && input_overlay_is_alive()) #endif ) return 0; if (menu_input->pointer.pressed[0]) { int16_t pointer_x = menu_input_pointer_state(MENU_POINTER_X_AXIS); int16_t pointer_y = menu_input_pointer_state(MENU_POINTER_Y_AXIS); if (!menu_input->pointer.oldpressed[0]) { menu_input->pointer.accel = 0; menu_input->pointer.accel0 = 0; menu_input->pointer.accel1 = 0; menu_input->pointer.start_x = pointer_x; menu_input->pointer.start_y = pointer_y; menu_input->pointer.old_x = pointer_x; menu_input->pointer.old_y = pointer_y; menu_input->pointer.oldpressed[0] = true; } else if (abs(pointer_x - menu_input->pointer.start_x) > 3 || abs(pointer_y - menu_input->pointer.start_y) > 3) { float s, delta_time; menu_input->pointer.dragging = true; menu_input->pointer.dx = pointer_x - menu_input->pointer.old_x; menu_input->pointer.dy = pointer_y - menu_input->pointer.old_y; menu_input->pointer.old_x = pointer_x; menu_input->pointer.old_y = pointer_y; menu_animation_ctl(MENU_ANIMATION_CTL_DELTA_TIME, &delta_time); s = menu_input->pointer.dy / delta_time * 1000000.0; menu_input->pointer.accel = (menu_input->pointer.accel0 + menu_input->pointer.accel1 + s) / 3; menu_input->pointer.accel0 = menu_input->pointer.accel1; menu_input->pointer.accel1 = menu_input->pointer.accel; } } else { if (menu_input->pointer.oldpressed[0]) { if (!menu_input->pointer.dragging) ret = menu_driver_pointer_tap(menu_input->pointer.start_x, menu_input->pointer.start_y, menu_input->pointer.ptr, cbs, entry, action); menu_input->pointer.oldpressed[0] = false; menu_input->pointer.start_x = 0; menu_input->pointer.start_y = 0; menu_input->pointer.old_x = 0; menu_input->pointer.old_y = 0; menu_input->pointer.dx = 0; menu_input->pointer.dy = 0; menu_input->pointer.dragging = false; } } if (menu_input->pointer.back) { if (!menu_input->pointer.oldback) { menu_input->pointer.oldback = true; menu_entries_pop_stack(&selection, 0); menu_navigation_ctl(MENU_NAVIGATION_CTL_SET_SELECTION, &selection); } } menu_input->pointer.oldback = menu_input->pointer.back; return ret; }
static int menu_input_pointer_post_iterate( menu_file_list_cbs_t *cbs, menu_entry_t *entry, unsigned action) { static bool pointer_oldpressed[2]; static bool pointer_oldback = false; static int16_t start_x = 0; static int16_t start_y = 0; static int16_t pointer_old_x = 0; static int16_t pointer_old_y = 0; int ret = 0; bool check_overlay = false; menu_input_t *menu_input = menu_input_get_ptr(); settings_t *settings = config_get_ptr(); if (!menu_input || !settings) return -1; check_overlay = !settings->menu.pointer.enable; #ifdef HAVE_OVERLAY if (!check_overlay) check_overlay = (settings->input.overlay_enable && input_overlay_is_alive(NULL)); #endif if (check_overlay) return 0; if (menu_input->pointer.pressed[0]) { gfx_ctx_metrics_t metrics; float dpi; static float accel0 = 0.0f; static float accel1 = 0.0f; int16_t pointer_x = menu_input_pointer_state(MENU_POINTER_X_AXIS); int16_t pointer_y = menu_input_pointer_state(MENU_POINTER_Y_AXIS); metrics.type = DISPLAY_METRIC_DPI; metrics.value = &dpi; video_context_driver_get_metrics(&metrics); if (!pointer_oldpressed[0]) { menu_input->pointer.accel = 0; accel0 = 0; accel1 = 0; start_x = pointer_x; start_y = pointer_y; pointer_old_x = pointer_x; pointer_old_y = pointer_y; pointer_oldpressed[0] = true; } else if (abs(pointer_x - start_x) > (dpi / 10) || abs(pointer_y - start_y) > (dpi / 10)) { float s, delta_time; menu_input_ctl(MENU_INPUT_CTL_SET_POINTER_DRAGGED, NULL); menu_input->pointer.dx = pointer_x - pointer_old_x; menu_input->pointer.dy = pointer_y - pointer_old_y; pointer_old_x = pointer_x; pointer_old_y = pointer_y; menu_animation_ctl(MENU_ANIMATION_CTL_DELTA_TIME, &delta_time); s = (menu_input->pointer.dy * 550000000.0 ) / ( dpi * delta_time ); menu_input->pointer.accel = (accel0 + accel1 + s) / 3; accel0 = accel1; accel1 = menu_input->pointer.accel; } } else { if (pointer_oldpressed[0]) { if (!menu_input_ctl(MENU_INPUT_CTL_IS_POINTER_DRAGGED, NULL)) { menu_ctx_pointer_t point; point.x = start_x; point.y = start_y; point.ptr = menu_input->pointer.ptr; point.cbs = cbs; point.entry = entry; point.action = action; menu_driver_ctl(RARCH_MENU_CTL_POINTER_TAP, &point); ret = point.retcode; } pointer_oldpressed[0] = false; start_x = 0; start_y = 0; pointer_old_x = 0; pointer_old_y = 0; menu_input->pointer.dx = 0; menu_input->pointer.dy = 0; menu_input_ctl(MENU_INPUT_CTL_UNSET_POINTER_DRAGGED, NULL); } } if (menu_input->pointer.back) { if (!pointer_oldback) { size_t selection; pointer_oldback = true; menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SELECTION, &selection); menu_entry_action(entry, selection, MENU_ACTION_CANCEL); } } pointer_oldback = menu_input->pointer.back; return ret; }
static int menu_input_mouse_post_iterate(uint64_t *input_mouse, menu_file_list_cbs_t *cbs, unsigned action) { settings_t *settings = config_get_ptr(); static bool mouse_oldleft = false; static bool mouse_oldright = false; if ( !settings->menu.mouse.enable #ifdef HAVE_OVERLAY || (settings->input.overlay_enable && input_overlay_is_alive(NULL)) #endif ) { /* HACK: Need to lie to avoid false hits if mouse is held * when entering the RetroArch window. */ /* This happens if, for example, someone double clicks the * window border to maximize it. * * The proper fix is, of course, triggering on WM_LBUTTONDOWN * rather than this state change. */ mouse_oldleft = true; mouse_oldright = true; return 0; } if (menu_input_mouse_state(MENU_MOUSE_LEFT_BUTTON)) { if (!mouse_oldleft) { size_t selection; menu_input_t *menu_input = menu_input_get_ptr(); menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SELECTION, &selection); BIT64_SET(*input_mouse, MENU_MOUSE_ACTION_BUTTON_L); mouse_oldleft = true; if ((menu_input->mouse.ptr == selection) && cbs && cbs->action_select) { BIT64_SET(*input_mouse, MENU_MOUSE_ACTION_BUTTON_L_TOGGLE); } else if (menu_input->mouse.ptr <= (menu_entries_get_size() - 1)) { BIT64_SET(*input_mouse, MENU_MOUSE_ACTION_BUTTON_L_SET_NAVIGATION); } } } else mouse_oldleft = false; if (menu_input_mouse_state(MENU_MOUSE_RIGHT_BUTTON)) { if (!mouse_oldright) { mouse_oldright = true; BIT64_SET(*input_mouse, MENU_MOUSE_ACTION_BUTTON_R); } } else mouse_oldright = false; if (menu_input_mouse_state(MENU_MOUSE_WHEEL_DOWN)) { BIT64_SET(*input_mouse, MENU_MOUSE_ACTION_WHEEL_DOWN); } if (menu_input_mouse_state(MENU_MOUSE_WHEEL_UP)) { BIT64_SET(*input_mouse, MENU_MOUSE_ACTION_WHEEL_UP); } if (menu_input_mouse_state(MENU_MOUSE_HORIZ_WHEEL_DOWN)) { BIT64_SET(*input_mouse, MENU_MOUSE_ACTION_HORIZ_WHEEL_DOWN); } if (menu_input_mouse_state(MENU_MOUSE_HORIZ_WHEEL_UP)) { BIT64_SET(*input_mouse, MENU_MOUSE_ACTION_HORIZ_WHEEL_UP); } return 0; }
static int menu_input_mouse_post_iterate(uint64_t *input_mouse, menu_file_list_cbs_t *cbs, unsigned action) { settings_t *settings = config_get_ptr(); static bool mouse_oldleft = false; static bool mouse_oldright = false; *input_mouse = MENU_MOUSE_ACTION_NONE; if ( !settings->menu.mouse.enable #ifdef HAVE_OVERLAY || (settings->input.overlay_enable && input_overlay_is_alive(NULL)) #endif ) { mouse_oldleft = false; mouse_oldright = false; return 0; } if (menu_input_mouse_state(MENU_MOUSE_LEFT_BUTTON)) { if (!mouse_oldleft) { size_t selection; unsigned header_height; menu_input_t *menu_input = menu_input_get_ptr(); menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SELECTION, &selection); header_height = menu_display_get_header_height(); BIT64_SET(*input_mouse, MENU_MOUSE_ACTION_BUTTON_L); mouse_oldleft = true; /* Back button */ if ((unsigned)menu_input_mouse_state(MENU_MOUSE_X_AXIS) < header_height) { menu_entries_pop_stack(&selection, 0, 1); menu_navigation_ctl(MENU_NAVIGATION_CTL_SET_SELECTION, &selection); return 0; } if ((menu_input->mouse.ptr == selection) && cbs && cbs->action_select) { BIT64_SET(*input_mouse, MENU_MOUSE_ACTION_BUTTON_L_TOGGLE); } else if (menu_input->mouse.ptr <= (menu_entries_get_size() - 1)) { BIT64_SET(*input_mouse, MENU_MOUSE_ACTION_BUTTON_L_SET_NAVIGATION); } } } else mouse_oldleft = false; if (menu_input_mouse_state(MENU_MOUSE_RIGHT_BUTTON)) { if (!mouse_oldright) { mouse_oldright = true; BIT64_SET(*input_mouse, MENU_MOUSE_ACTION_BUTTON_R); } } else mouse_oldright = false; if (menu_input_mouse_state(MENU_MOUSE_WHEEL_DOWN)) { BIT64_SET(*input_mouse, MENU_MOUSE_ACTION_WHEEL_DOWN); } if (menu_input_mouse_state(MENU_MOUSE_WHEEL_UP)) { BIT64_SET(*input_mouse, MENU_MOUSE_ACTION_WHEEL_UP); } if (menu_input_mouse_state(MENU_MOUSE_HORIZ_WHEEL_DOWN)) { BIT64_SET(*input_mouse, MENU_MOUSE_ACTION_HORIZ_WHEEL_DOWN); } if (menu_input_mouse_state(MENU_MOUSE_HORIZ_WHEEL_UP)) { BIT64_SET(*input_mouse, MENU_MOUSE_ACTION_HORIZ_WHEEL_UP); } return 0; }
unsigned menu_event(retro_input_t input, retro_input_t trigger_input) { menu_animation_ctx_delta_t delta; float delta_time; /* Used for key repeat */ static float delay_timer = 0.0f; static float delay_count = 0.0f; unsigned ret = MENU_ACTION_NOOP; static bool initial_held = true; static bool first_held = false; bool set_scroll = false; bool mouse_enabled = false; size_t new_scroll_accel = 0; menu_input_t *menu_input = NULL; settings_t *settings = config_get_ptr(); if (input.state) { if (!first_held) { /* don't run anything first frame, only capture held inputs * for old_input_state. */ first_held = true; delay_timer = initial_held ? 12 : 6; delay_count = 0; } if (delay_count >= delay_timer) { retro_input_t input_repeat = {0}; BIT32_SET(input_repeat.state, RETRO_DEVICE_ID_JOYPAD_UP); BIT32_SET(input_repeat.state, RETRO_DEVICE_ID_JOYPAD_DOWN); BIT32_SET(input_repeat.state, RETRO_DEVICE_ID_JOYPAD_LEFT); BIT32_SET(input_repeat.state, RETRO_DEVICE_ID_JOYPAD_RIGHT); BIT32_SET(input_repeat.state, RETRO_DEVICE_ID_JOYPAD_B); BIT32_SET(input_repeat.state, RETRO_DEVICE_ID_JOYPAD_A); BIT32_SET(input_repeat.state, RETRO_DEVICE_ID_JOYPAD_L); BIT32_SET(input_repeat.state, RETRO_DEVICE_ID_JOYPAD_R); set_scroll = true; first_held = false; trigger_input.state |= input.state & input_repeat.state; menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SCROLL_ACCEL, &new_scroll_accel); new_scroll_accel = MIN(new_scroll_accel + 1, 64); } initial_held = false; } else { set_scroll = true; first_held = false; initial_held = true; } if (set_scroll) menu_navigation_ctl(MENU_NAVIGATION_CTL_SET_SCROLL_ACCEL, &new_scroll_accel); menu_animation_ctl(MENU_ANIMATION_CTL_DELTA_TIME, &delta_time); delta.current = delta_time; if (menu_animation_ctl(MENU_ANIMATION_CTL_IDEAL_DELTA_TIME_GET, &delta)) delay_count += delta.ideal; if (menu_input_dialog_get_display_kb()) { static unsigned ti_char = 64; static bool ti_next = false; if (trigger_input.state & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_DOWN)) { if (ti_char > 32) ti_char--; if (! ti_next) input_keyboard_event(true, '\x7f', '\x7f', 0, RETRO_DEVICE_KEYBOARD); input_keyboard_event(true, ti_char, ti_char, 0, RETRO_DEVICE_KEYBOARD); ti_next = false; } if (trigger_input.state & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_UP)) { if (ti_char < 125) ti_char++; if (! ti_next) input_keyboard_event(true, '\x7f', '\x7f', 0, RETRO_DEVICE_KEYBOARD); input_keyboard_event(true, ti_char, ti_char, 0, RETRO_DEVICE_KEYBOARD); ti_next = false; } if (trigger_input.state & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_A)) { ti_char = 64; ti_next = true; } if (trigger_input.state & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_B)) { input_keyboard_event(true, '\x7f', '\x7f', 0, RETRO_DEVICE_KEYBOARD); ti_char = 64; ti_next = false; } /* send return key to close keyboard input window */ if (trigger_input.state & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_START)) input_keyboard_event(true, '\n', '\n', 0, RETRO_DEVICE_KEYBOARD); trigger_input.state = 0; } if (trigger_input.state & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_UP)) ret = MENU_ACTION_UP; else if (trigger_input.state & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_DOWN)) ret = MENU_ACTION_DOWN; else if (trigger_input.state & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_LEFT)) ret = MENU_ACTION_LEFT; else if (trigger_input.state & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_RIGHT)) ret = MENU_ACTION_RIGHT; else if (trigger_input.state & (UINT64_C(1) << settings->menu_scroll_up_btn)) ret = MENU_ACTION_SCROLL_UP; else if (trigger_input.state & (UINT64_C(1) << settings->menu_scroll_down_btn)) ret = MENU_ACTION_SCROLL_DOWN; else if (trigger_input.state & (UINT64_C(1) << settings->menu_cancel_btn)) ret = MENU_ACTION_CANCEL; else if (trigger_input.state & (UINT64_C(1) << settings->menu_ok_btn)) ret = MENU_ACTION_OK; else if (trigger_input.state & (UINT64_C(1) << settings->menu_search_btn)) ret = MENU_ACTION_SEARCH; else if (trigger_input.state & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_Y)) ret = MENU_ACTION_SCAN; else if (trigger_input.state & (UINT64_C(1) << settings->menu_default_btn)) ret = MENU_ACTION_START; else if (trigger_input.state & (UINT64_C(1) << settings->menu_info_btn)) ret = MENU_ACTION_INFO; else if (trigger_input.state & (UINT64_C(1) << RARCH_MENU_TOGGLE)) ret = MENU_ACTION_TOGGLE; mouse_enabled = settings->menu.mouse.enable; #ifdef HAVE_OVERLAY if (!mouse_enabled) mouse_enabled = !(settings->input.overlay_enable && input_overlay_is_alive(NULL)); #endif if (!(menu_input = menu_input_get_ptr())) return 0; if (!mouse_enabled) menu_input->mouse.ptr = 0; if (settings->menu.pointer.enable) menu_event_pointer(&ret); else memset(&menu_input->pointer, 0, sizeof(menu_input->pointer)); return ret; }
unsigned menu_event(uint64_t input, uint64_t trigger_input) { menu_animation_ctx_delta_t delta; float delta_time; /* Used for key repeat */ static float delay_timer = 0.0f; static float delay_count = 0.0f; unsigned ret = MENU_ACTION_NOOP; static bool initial_held = true; static bool first_held = false; bool set_scroll = false; bool mouse_enabled = false; size_t new_scroll_accel = 0; menu_input_t *menu_input = NULL; settings_t *settings = config_get_ptr(); if (input) { if (!first_held) { /* don't run anything first frame, only capture held inputs * for old_input_state. */ first_held = true; delay_timer = initial_held ? 12 : 6; delay_count = 0; } if (delay_count >= delay_timer) { uint64_t input_repeat = 0; BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_UP); BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_DOWN); BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_LEFT); BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_RIGHT); BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_L); BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_R); set_scroll = true; first_held = false; trigger_input |= input & input_repeat; menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SCROLL_ACCEL, &new_scroll_accel); new_scroll_accel = MIN(new_scroll_accel + 1, 64); } initial_held = false; } else { set_scroll = true; first_held = false; initial_held = true; } if (set_scroll) menu_navigation_ctl(MENU_NAVIGATION_CTL_SET_SCROLL_ACCEL, &new_scroll_accel); menu_animation_ctl(MENU_ANIMATION_CTL_DELTA_TIME, &delta_time); delta.current = delta_time; if (menu_animation_ctl(MENU_ANIMATION_CTL_IDEAL_DELTA_TIME_GET, &delta)) delay_count += delta.ideal; if (menu_input_dialog_get_display_kb()) { if (kbd_upper) strlcpy(kbd_grid, "!@#$%^&*()QWERTYUIOPASDFGHJKL:ZXCVBNM <>?", sizeof(kbd_grid)); else strlcpy(kbd_grid, "1234567890qwertyuiopasdfghjkl:zxcvbnm ,./", sizeof(kbd_grid)); if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_DOWN)) { if (kbd_index < 30) kbd_index = kbd_index + 10; } if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_UP)) { if (kbd_index >= 10) kbd_index = kbd_index - 10; } if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_RIGHT)) { if (kbd_index < 39) kbd_index = kbd_index + 1; } if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_LEFT)) { if (kbd_index >= 1) kbd_index = kbd_index - 1; } if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_Y)) { kbd_upper = ! kbd_upper; } if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_A)) { input_keyboard_event(true, kbd_grid[kbd_index], kbd_grid[kbd_index], 0, RETRO_DEVICE_KEYBOARD); } if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_B)) { input_keyboard_event(true, '\x7f', '\x7f', 0, RETRO_DEVICE_KEYBOARD); } /* send return key to close keyboard input window */ if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_START)) input_keyboard_event(true, '\n', '\n', 0, RETRO_DEVICE_KEYBOARD); trigger_input = 0; } if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_UP)) ret = MENU_ACTION_UP; else if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_DOWN)) ret = MENU_ACTION_DOWN; else if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_LEFT)) ret = MENU_ACTION_LEFT; else if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_RIGHT)) ret = MENU_ACTION_RIGHT; else if (trigger_input & (UINT64_C(1) << settings->menu_scroll_up_btn)) ret = MENU_ACTION_SCROLL_UP; else if (trigger_input & (UINT64_C(1) << settings->menu_scroll_down_btn)) ret = MENU_ACTION_SCROLL_DOWN; else if (trigger_input & (UINT64_C(1) << settings->menu_cancel_btn)) ret = MENU_ACTION_CANCEL; else if (trigger_input & (UINT64_C(1) << settings->menu_ok_btn)) ret = MENU_ACTION_OK; else if (trigger_input & (UINT64_C(1) << settings->menu_search_btn)) ret = MENU_ACTION_SEARCH; else if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_Y)) ret = MENU_ACTION_SCAN; else if (trigger_input & (UINT64_C(1) << settings->menu_default_btn)) ret = MENU_ACTION_START; else if (trigger_input & (UINT64_C(1) << settings->menu_info_btn)) ret = MENU_ACTION_INFO; else if (trigger_input & (UINT64_C(1) << RARCH_MENU_TOGGLE)) ret = MENU_ACTION_TOGGLE; mouse_enabled = settings->menu.mouse.enable; #ifdef HAVE_OVERLAY if (!mouse_enabled) mouse_enabled = !(settings->input.overlay_enable && input_overlay_is_alive(NULL)); #endif if (!(menu_input = menu_input_get_ptr())) return 0; if (!mouse_enabled) menu_input->mouse.ptr = 0; if (settings->menu.pointer.enable) menu_event_pointer(&ret); else { menu_input->pointer.x = 0; menu_input->pointer.y = 0; menu_input->pointer.dx = 0; menu_input->pointer.dy = 0; menu_input->pointer.accel = 0; menu_input->pointer.pressed[0] = false; menu_input->pointer.pressed[1] = false; menu_input->pointer.back = false; menu_input->pointer.ptr = 0; } return ret; }
unsigned menu_event(uint64_t input, uint64_t trigger_input) { menu_animation_ctx_delta_t delta; float delta_time; /* Used for key repeat */ static float delay_timer = 0.0f; static float delay_count = 0.0f; unsigned ret = MENU_ACTION_NOOP; static bool initial_held = true; static bool first_held = false; bool set_scroll = false; bool mouse_enabled = false; size_t new_scroll_accel = 0; menu_input_t *menu_input = NULL; settings_t *settings = config_get_ptr(); static unsigned ok_old = 0; unsigned menu_ok_btn = settings->input.menu_swap_ok_cancel_buttons ? RETRO_DEVICE_ID_JOYPAD_B : RETRO_DEVICE_ID_JOYPAD_A; unsigned menu_cancel_btn = settings->input.menu_swap_ok_cancel_buttons ? RETRO_DEVICE_ID_JOYPAD_A : RETRO_DEVICE_ID_JOYPAD_B; unsigned ok_current = input & UINT64_C(1) << menu_ok_btn; unsigned ok_trigger = ok_current & ~ok_old; ok_old = ok_current; if (input) { if (!first_held) { /* don't run anything first frame, only capture held inputs * for old_input_state. */ first_held = true; delay_timer = initial_held ? 12 : 6; delay_count = 0; } if (delay_count >= delay_timer) { uint64_t input_repeat = 0; BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_UP); BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_DOWN); BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_LEFT); BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_RIGHT); BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_L); BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_R); set_scroll = true; first_held = false; trigger_input |= input & input_repeat; menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SCROLL_ACCEL, &new_scroll_accel); new_scroll_accel = MIN(new_scroll_accel + 1, 64); } initial_held = false; } else { set_scroll = true; first_held = false; initial_held = true; } if (set_scroll) menu_navigation_ctl(MENU_NAVIGATION_CTL_SET_SCROLL_ACCEL, &new_scroll_accel); menu_animation_ctl(MENU_ANIMATION_CTL_DELTA_TIME, &delta_time); delta.current = delta_time; if (menu_animation_ctl(MENU_ANIMATION_CTL_IDEAL_DELTA_TIME_GET, &delta)) delay_count += delta.ideal; if (menu_input_dialog_get_display_kb()) { switch (osk_idx) { case OSK_HIRAGANA_PAGE1: { memcpy(osk_grid, hiragana_page1_grid, sizeof(hiragana_page1_grid)); break; } case OSK_HIRAGANA_PAGE2: { memcpy(osk_grid, hiragana_page2_grid, sizeof(hiragana_page2_grid)); break; } case OSK_KATAKANA_PAGE1: { memcpy(osk_grid, katakana_page1_grid, sizeof(katakana_page1_grid)); break; } case OSK_KATAKANA_PAGE2: { memcpy(osk_grid, katakana_page2_grid, sizeof(katakana_page2_grid)); break; } case OSK_UPPERCASE_LATIN: { memcpy(osk_grid, uppercase_grid, sizeof(uppercase_grid)); break; } case OSK_LOWERCASE_LATIN: default: { memcpy(osk_grid, lowercase_grid, sizeof(lowercase_grid)); break; } } if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_DOWN)) { if (osk_ptr < 33) osk_ptr = osk_ptr + OSK_CHARS_PER_LINE; } if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_UP)) { if (osk_ptr >= OSK_CHARS_PER_LINE) osk_ptr = osk_ptr - OSK_CHARS_PER_LINE; } if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_RIGHT)) { if (osk_ptr < 43) osk_ptr = osk_ptr + 1; } if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_LEFT)) { if (osk_ptr >= 1) osk_ptr = osk_ptr - 1; } if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_L)) { if (osk_idx > OSK_TYPE_UNKNOWN + 1) osk_idx = (enum osk_type)(osk_idx - 1); else osk_idx = (enum osk_type)(OSK_TYPE_LAST - 1); } if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_R)) { if (osk_idx < OSK_TYPE_LAST - 1) osk_idx = (enum osk_type)(osk_idx + 1); else osk_idx = (enum osk_type)(OSK_TYPE_UNKNOWN + 1); } if (trigger_input & (UINT64_C(1) << menu_ok_btn)) { if (osk_ptr >= 0) { menu_event_osk_append(osk_ptr); } } if (trigger_input & (UINT64_C(1) << menu_cancel_btn)) { input_keyboard_event(true, '\x7f', '\x7f', 0, RETRO_DEVICE_KEYBOARD); } /* send return key to close keyboard input window */ if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_START)) input_keyboard_event(true, '\n', '\n', 0, RETRO_DEVICE_KEYBOARD); trigger_input = 0; ok_trigger = 0; } if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_UP)) ret = MENU_ACTION_UP; else if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_DOWN)) ret = MENU_ACTION_DOWN; else if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_LEFT)) ret = MENU_ACTION_LEFT; else if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_RIGHT)) ret = MENU_ACTION_RIGHT; else if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_L)) ret = MENU_ACTION_SCROLL_UP; else if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_R)) ret = MENU_ACTION_SCROLL_DOWN; else if (ok_trigger) ret = MENU_ACTION_OK; else if (trigger_input & (UINT64_C(1) << menu_cancel_btn)) ret = MENU_ACTION_CANCEL; else if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_X)) ret = MENU_ACTION_SEARCH; else if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_Y)) ret = MENU_ACTION_SCAN; else if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_START)) ret = MENU_ACTION_START; else if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_SELECT)) ret = MENU_ACTION_INFO; else if (trigger_input & (UINT64_C(1) << RARCH_MENU_TOGGLE)) ret = MENU_ACTION_TOGGLE; if (menu_keyboard_key_state[RETROK_F11]) { command_event(CMD_EVENT_GRAB_MOUSE_TOGGLE, NULL); menu_keyboard_key_state[RETROK_F11] = false; } if (runloop_cmd_press(trigger_input, RARCH_QUIT_KEY)) return MENU_ACTION_QUIT; mouse_enabled = settings->menu.mouse.enable; #ifdef HAVE_OVERLAY if (!mouse_enabled) mouse_enabled = !(settings->input.overlay_enable && input_overlay_is_alive(overlay_ptr)); #endif if (!(menu_input = menu_input_get_ptr())) return 0; if (!mouse_enabled) menu_input->mouse.ptr = 0; if (settings->menu.pointer.enable) menu_event_pointer(&ret); else { menu_input->pointer.x = 0; menu_input->pointer.y = 0; menu_input->pointer.dx = 0; menu_input->pointer.dy = 0; menu_input->pointer.accel = 0; menu_input->pointer.pressed[0] = false; menu_input->pointer.pressed[1] = false; menu_input->pointer.back = false; menu_input->pointer.ptr = 0; } return ret; }
static int menu_input_pointer_post_iterate( menu_file_list_cbs_t *cbs, menu_entry_t *entry, unsigned action) { static bool pointer_oldpressed[2]; static bool pointer_oldback = false; static int16_t start_x = 0; static int16_t start_y = 0; static int16_t pointer_old_x = 0; static int16_t pointer_old_y = 0; int ret = 0; menu_input_t *menu_input = &menu_input_state; settings_t *settings = config_get_ptr(); if (!menu_input || !settings) return -1; #ifdef HAVE_OVERLAY /* If we have overlays enabled, overlay controls take * precedence and we don't want regular menu * pointer controls to be handled */ if (( settings->bools.input_overlay_enable && input_overlay_is_alive(overlay_ptr))) return 0; #endif if (menu_input->pointer.pressed[0]) { gfx_ctx_metrics_t metrics; float dpi; static float accel0 = 0.0f; static float accel1 = 0.0f; int16_t pointer_x = menu_input_pointer_state(MENU_POINTER_X_AXIS); int16_t pointer_y = menu_input_pointer_state(MENU_POINTER_Y_AXIS); metrics.type = DISPLAY_METRIC_DPI; metrics.value = &dpi; menu_input->pointer.counter++; if (menu_input->pointer.counter == 1 && !menu_input_ctl(MENU_INPUT_CTL_IS_POINTER_DRAGGED, NULL)) { menu_ctx_pointer_t point; point.x = pointer_x; point.y = pointer_y; point.ptr = menu_input->pointer.ptr; point.cbs = cbs; point.entry = entry; point.action = action; menu_driver_ctl(RARCH_MENU_CTL_POINTER_DOWN, &point); } if (!pointer_oldpressed[0]) { menu_input->pointer.accel = 0; accel0 = 0; accel1 = 0; start_x = pointer_x; start_y = pointer_y; pointer_old_x = pointer_x; pointer_old_y = pointer_y; pointer_oldpressed[0] = true; } else if (video_context_driver_get_metrics(&metrics)) { if (abs(pointer_x - start_x) > (dpi / 10) || abs(pointer_y - start_y) > (dpi / 10)) { float s; menu_input_ctl(MENU_INPUT_CTL_SET_POINTER_DRAGGED, NULL); menu_input->pointer.dx = pointer_x - pointer_old_x; menu_input->pointer.dy = pointer_y - pointer_old_y; pointer_old_x = pointer_x; pointer_old_y = pointer_y; s = menu_input->pointer.dy; menu_input->pointer.accel = (accel0 + accel1 + s) / 3; accel0 = accel1; accel1 = menu_input->pointer.accel; } } } else { if (pointer_oldpressed[0]) { if (!menu_input_ctl(MENU_INPUT_CTL_IS_POINTER_DRAGGED, NULL)) { menu_ctx_pointer_t point; point.x = start_x; point.y = start_y; point.ptr = menu_input->pointer.ptr; point.cbs = cbs; point.entry = entry; point.action = action; if (menu_input_dialog_get_display_kb()) { menu_driver_ctl(RARCH_MENU_CTL_OSK_PTR_AT_POS, &point); if (point.retcode > -1) { menu_event_set_osk_ptr(point.retcode); menu_event_osk_append(point.retcode); } } else { if (menu_input->pointer.counter > 32) { size_t selection = menu_navigation_get_selection(); if (cbs && cbs->action_start) return menu_entry_action(entry, (unsigned)selection, MENU_ACTION_START); } else { menu_driver_ctl(RARCH_MENU_CTL_POINTER_UP, &point); menu_driver_ctl(RARCH_MENU_CTL_POINTER_TAP, &point); ret = point.retcode; } } } pointer_oldpressed[0] = false; start_x = 0; start_y = 0; pointer_old_x = 0; pointer_old_y = 0; menu_input->pointer.dx = 0; menu_input->pointer.dy = 0; menu_input->pointer.counter = 0; menu_input_ctl(MENU_INPUT_CTL_UNSET_POINTER_DRAGGED, NULL); } } if (menu_input->pointer.back) { if (!pointer_oldback) { pointer_oldback = true; menu_entry_action(entry, (unsigned)menu_navigation_get_selection(), MENU_ACTION_CANCEL); } } pointer_oldback = menu_input->pointer.back; return ret; }
/* * input_poll_overlay: * * Poll pressed buttons/keys on currently active overlay. **/ void input_poll_overlay(float opacity) { input_overlay_state_t old_key_state; unsigned i, j, device; uint16_t key_mod = 0; bool polled = false; settings_t *settings = config_get_ptr(); input_overlay_state_t *ol_state = &overlay_st_ptr; if (!input_overlay_is_alive() || !ol_state) return; memcpy(old_key_state.keys, ol_state->keys, sizeof(ol_state->keys)); memset(ol_state, 0, sizeof(*ol_state)); device = input_overlay_full_screen() ? RARCH_DEVICE_POINTER_SCREEN : RETRO_DEVICE_POINTER; for (i = 0; input_driver_state(NULL, 0, device, i, RETRO_DEVICE_ID_POINTER_PRESSED); i++) { input_overlay_state_t polled_data; int16_t x = input_driver_state(NULL, 0, device, i, RETRO_DEVICE_ID_POINTER_X); int16_t y = input_driver_state(NULL, 0, device, i, RETRO_DEVICE_ID_POINTER_Y); input_overlay_poll(&polled_data, x, y); ol_state->buttons |= polled_data.buttons; for (j = 0; j < ARRAY_SIZE(ol_state->keys); j++) ol_state->keys[j] |= polled_data.keys[j]; /* Fingers pressed later take prio and matched up * with overlay poll priorities. */ for (j = 0; j < 4; j++) if (polled_data.analog[j]) ol_state->analog[j] = polled_data.analog[j]; polled = true; } if (OVERLAY_GET_KEY(ol_state, RETROK_LSHIFT) || OVERLAY_GET_KEY(ol_state, RETROK_RSHIFT)) key_mod |= RETROKMOD_SHIFT; if (OVERLAY_GET_KEY(ol_state, RETROK_LCTRL) || OVERLAY_GET_KEY(ol_state, RETROK_RCTRL)) key_mod |= RETROKMOD_CTRL; if (OVERLAY_GET_KEY(ol_state, RETROK_LALT) || OVERLAY_GET_KEY(ol_state, RETROK_RALT)) key_mod |= RETROKMOD_ALT; if (OVERLAY_GET_KEY(ol_state, RETROK_LMETA) || OVERLAY_GET_KEY(ol_state, RETROK_RMETA)) key_mod |= RETROKMOD_META; /* CAPSLOCK SCROLLOCK NUMLOCK */ for (i = 0; i < ARRAY_SIZE(ol_state->keys); i++) { if (ol_state->keys[i] != old_key_state.keys[i]) { uint32_t orig_bits = old_key_state.keys[i]; uint32_t new_bits = ol_state->keys[i]; for (j = 0; j < 32; j++) if ((orig_bits & (1 << j)) != (new_bits & (1 << j))) input_keyboard_event(new_bits & (1 << j), i * 32 + j, 0, key_mod, RETRO_DEVICE_POINTER); } } /* Map "analog" buttons to analog axes like regular input drivers do. */ for (j = 0; j < 4; j++) { unsigned bind_plus = RARCH_ANALOG_LEFT_X_PLUS + 2 * j; unsigned bind_minus = bind_plus + 1; if (ol_state->analog[j]) continue; if (input_overlay_key_pressed(bind_plus)) ol_state->analog[j] += 0x7fff; if (input_overlay_key_pressed(bind_minus)) ol_state->analog[j] -= 0x7fff; } /* Check for analog_dpad_mode. * Map analogs to d-pad buttons when configured. */ switch (settings->input.analog_dpad_mode[0]) { case ANALOG_DPAD_LSTICK: case ANALOG_DPAD_RSTICK: { float analog_x, analog_y; unsigned analog_base = 2; if (settings->input.analog_dpad_mode[0] == ANALOG_DPAD_LSTICK) analog_base = 0; analog_x = (float)ol_state->analog[analog_base + 0] / 0x7fff; analog_y = (float)ol_state->analog[analog_base + 1] / 0x7fff; if (analog_x <= -settings->input.axis_threshold) ol_state->buttons |= (1UL << RETRO_DEVICE_ID_JOYPAD_LEFT); if (analog_x >= settings->input.axis_threshold) ol_state->buttons |= (1UL << RETRO_DEVICE_ID_JOYPAD_RIGHT); if (analog_y <= -settings->input.axis_threshold) ol_state->buttons |= (1UL << RETRO_DEVICE_ID_JOYPAD_UP); if (analog_y >= settings->input.axis_threshold) ol_state->buttons |= (1UL << RETRO_DEVICE_ID_JOYPAD_DOWN); break; } default: break; } if (polled) input_overlay_post_poll(opacity); else input_overlay_poll_clear(opacity); }
/* * This function gets called in order to process all input events * for the current frame. * * Sends input code to menu for one frame. * * It uses as input the local variables' input' and 'trigger_input'. * * Mouse and touch input events get processed inside this function. * * NOTE: 'input' and 'trigger_input' is sourced from the keyboard and/or * the gamepad. It does not contain input state derived from the mouse * and/or touch - this gets dealt with separately within this function. * * TODO/FIXME - maybe needs to be overhauled so we can send multiple * events per frame if we want to, and we shouldn't send the * entire button state either but do a separate event per button * state. */ unsigned menu_event(input_bits_t *p_input, input_bits_t *p_trigger_input) { /* Used for key repeat */ static float delay_timer = 0.0f; static float delay_count = 0.0f; static unsigned ok_old = 0; unsigned ret = MENU_ACTION_NOOP; static bool initial_held = true; static bool first_held = false; bool set_scroll = false; bool mouse_enabled = false; size_t new_scroll_accel = 0; menu_input_t *menu_input = NULL; settings_t *settings = config_get_ptr(); bool swap_ok_cancel_btns = settings->bools.input_menu_swap_ok_cancel_buttons; bool input_swap_override = input_autoconfigure_get_swap_override(); unsigned menu_ok_btn = (!input_swap_override && swap_ok_cancel_btns) ? RETRO_DEVICE_ID_JOYPAD_B : RETRO_DEVICE_ID_JOYPAD_A; unsigned menu_cancel_btn = (!input_swap_override && swap_ok_cancel_btns) ? RETRO_DEVICE_ID_JOYPAD_A : RETRO_DEVICE_ID_JOYPAD_B; unsigned ok_current = BIT256_GET_PTR(p_input, menu_ok_btn ); unsigned ok_trigger = ok_current & ~ok_old; ok_old = ok_current; if (bits_any_set(p_input->data, ARRAY_SIZE(p_input->data))) { if (!first_held) { /* don't run anything first frame, only capture held inputs * for old_input_state. */ first_held = true; delay_timer = initial_held ? 200 : 100; delay_count = 0; } if (delay_count >= delay_timer) { uint32_t input_repeat = 0; BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_UP); BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_DOWN); BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_LEFT); BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_RIGHT); BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_L); BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_R); set_scroll = true; first_held = false; p_trigger_input->data[0] |= p_input->data[0] & input_repeat; menu_driver_ctl(MENU_NAVIGATION_CTL_GET_SCROLL_ACCEL, &new_scroll_accel); new_scroll_accel = MIN(new_scroll_accel + 1, 64); } initial_held = false; } else { set_scroll = true; first_held = false; initial_held = true; } if (set_scroll) menu_driver_ctl(MENU_NAVIGATION_CTL_SET_SCROLL_ACCEL, &new_scroll_accel); delay_count += menu_animation_get_delta_time(); if (menu_input_dialog_get_display_kb()) { menu_event_osk_iterate(); if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_DOWN)) { if (menu_event_get_osk_ptr() < 33) menu_event_set_osk_ptr(menu_event_get_osk_ptr() + OSK_CHARS_PER_LINE); } if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_UP)) { if (menu_event_get_osk_ptr() >= OSK_CHARS_PER_LINE) menu_event_set_osk_ptr(menu_event_get_osk_ptr() - OSK_CHARS_PER_LINE); } if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_RIGHT)) { if (menu_event_get_osk_ptr() < 43) menu_event_set_osk_ptr(menu_event_get_osk_ptr() + 1); } if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_LEFT)) { if (menu_event_get_osk_ptr() >= 1) menu_event_set_osk_ptr(menu_event_get_osk_ptr() - 1); } if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_L)) { if (menu_event_get_osk_idx() > OSK_TYPE_UNKNOWN + 1) menu_event_set_osk_idx((enum osk_type)( menu_event_get_osk_idx() - 1)); else menu_event_set_osk_idx((enum osk_type)(OSK_TYPE_LAST - 1)); } if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_R)) { if (menu_event_get_osk_idx() < OSK_TYPE_LAST - 1) menu_event_set_osk_idx((enum osk_type)( menu_event_get_osk_idx() + 1)); else menu_event_set_osk_idx((enum osk_type)(OSK_TYPE_UNKNOWN + 1)); } if (BIT256_GET_PTR(p_trigger_input, menu_ok_btn)) { if (menu_event_get_osk_ptr() >= 0) menu_event_osk_append(menu_event_get_osk_ptr()); } if (BIT256_GET_PTR(p_trigger_input, menu_cancel_btn)) input_keyboard_event(true, '\x7f', '\x7f', 0, RETRO_DEVICE_KEYBOARD); /* send return key to close keyboard input window */ if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_START)) input_keyboard_event(true, '\n', '\n', 0, RETRO_DEVICE_KEYBOARD); BIT256_CLEAR_ALL_PTR(p_trigger_input); } else { if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_UP)) ret = MENU_ACTION_UP; else if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_DOWN)) ret = MENU_ACTION_DOWN; else if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_LEFT)) ret = MENU_ACTION_LEFT; else if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_RIGHT)) ret = MENU_ACTION_RIGHT; else if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_L)) ret = MENU_ACTION_SCROLL_UP; else if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_R)) ret = MENU_ACTION_SCROLL_DOWN; else if (ok_trigger) ret = MENU_ACTION_OK; else if (BIT256_GET_PTR(p_trigger_input, menu_cancel_btn)) ret = MENU_ACTION_CANCEL; else if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_X)) ret = MENU_ACTION_SEARCH; else if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_Y)) ret = MENU_ACTION_SCAN; else if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_START)) ret = MENU_ACTION_START; else if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_SELECT)) ret = MENU_ACTION_INFO; else if (BIT256_GET_PTR(p_trigger_input, RARCH_MENU_TOGGLE)) ret = MENU_ACTION_TOGGLE; } if (menu_event_kb_is_set(RETROK_F11)) { command_event(CMD_EVENT_GRAB_MOUSE_TOGGLE, NULL); menu_event_kb_set_internal(RETROK_F11, 0); } mouse_enabled = settings->bools.menu_mouse_enable; #ifdef HAVE_OVERLAY if (!mouse_enabled) mouse_enabled = !(settings->bools.input_overlay_enable && input_overlay_is_alive(overlay_ptr)); #endif menu_input = &menu_input_state; if (!mouse_enabled) menu_input->mouse.ptr = 0; if (settings->bools.menu_pointer_enable) menu_event_pointer(&ret); else { menu_input->pointer.x = 0; menu_input->pointer.y = 0; menu_input->pointer.dx = 0; menu_input->pointer.dy = 0; menu_input->pointer.accel = 0; menu_input->pointer.pressed[0] = false; menu_input->pointer.pressed[1] = false; menu_input->pointer.back = false; menu_input->pointer.ptr = 0; } return ret; }
static int menu_input_pointer_post_iterate(menu_file_list_cbs_t *cbs, menu_entry_t *entry, unsigned action) { int ret = 0; menu_display_t *disp = menu_display_get_ptr(); menu_navigation_t *nav = menu_navigation_get_ptr(); menu_list_t *menu_list = menu_list_get_ptr(); menu_input_t *menu_input = menu_input_get_ptr(); settings_t *settings = config_get_ptr(); if (!menu_input) return -1; if (!settings->menu.pointer.enable #ifdef HAVE_OVERLAY || (settings->input.overlay_enable && input_overlay_is_alive()) #endif ) return 0; if (menu_input->pointer.pressed[0]) { if (!menu_input->pointer.oldpressed[0]) { menu_input->pointer.accel = 0; menu_input->pointer.accel0 = 0; menu_input->pointer.accel1 = 0; menu_input->pointer.start_x = menu_input->pointer.x; menu_input->pointer.start_y = menu_input->pointer.y; menu_input->pointer.old_x = menu_input->pointer.x; menu_input->pointer.old_y = menu_input->pointer.y; menu_input->pointer.oldpressed[0] = true; } else if (abs(menu_input->pointer.x - menu_input->pointer.start_x) > 3 || abs(menu_input->pointer.y - menu_input->pointer.start_y) > 3) { float s; menu_input->pointer.dragging = true; menu_input->pointer.dx = menu_input->pointer.x - menu_input->pointer.old_x; menu_input->pointer.dy = menu_input->pointer.y - menu_input->pointer.old_y; menu_input->pointer.old_x = menu_input->pointer.x; menu_input->pointer.old_y = menu_input->pointer.y; s = menu_input->pointer.dy / menu_animation_get_delta_time(disp->animation) * 1000000.0; menu_input->pointer.accel = (menu_input->pointer.accel0 + menu_input->pointer.accel1 + s) / 3; menu_input->pointer.accel0 = menu_input->pointer.accel1; menu_input->pointer.accel1 = menu_input->pointer.accel; } } else { if (menu_input->pointer.oldpressed[0]) { if (!menu_input->pointer.dragging) { if ((unsigned)menu_input->pointer.start_y < disp->header_height) menu_list_pop_stack(menu_list, &nav->selection_ptr); else if (menu_input->pointer.ptr <= menu_list_get_size(menu_list)-1) { menu_input->pointer.oldpressed[0] = false; ret = pointer_tap(cbs, entry, action); } } menu_input->pointer.oldpressed[0] = false; menu_input->pointer.start_x = 0; menu_input->pointer.start_y = 0; menu_input->pointer.old_x = 0; menu_input->pointer.old_y = 0; menu_input->pointer.dx = 0; menu_input->pointer.dy = 0; menu_input->pointer.dragging = false; } } if (menu_input->pointer.back) { if (!menu_input->pointer.oldback) { menu_input->pointer.oldback = true; menu_list_pop_stack(menu_list, &nav->selection_ptr); } } menu_input->pointer.oldback = menu_input->pointer.back; return ret; }
static int menu_input_mouse_post_iterate(uint64_t *input_mouse, menu_file_list_cbs_t *cbs, unsigned action) { settings_t *settings = config_get_ptr(); menu_display_t *disp = menu_display_get_ptr(); menu_input_t *menu_input = menu_input_get_ptr(); menu_list_t *menu_list = menu_list_get_ptr(); menu_navigation_t *nav = menu_navigation_get_ptr(); *input_mouse = MOUSE_ACTION_NONE; if (!settings->menu.mouse.enable #ifdef HAVE_OVERLAY || (settings->input.overlay_enable && input_overlay_is_alive()) #endif ) { menu_input->mouse.wheeldown = false; menu_input->mouse.wheelup = false; menu_input->mouse.oldleft = false; menu_input->mouse.oldright = false; return 0; } if (menu_input->mouse.left) { if (!menu_input->mouse.oldleft) { BIT64_SET(*input_mouse, MOUSE_ACTION_BUTTON_L); menu_input->mouse.oldleft = true; if ((unsigned)menu_input->mouse.y < disp->header_height) { menu_list_pop_stack(menu_list, &nav->selection_ptr); return 0; } if ( (menu_input->mouse.ptr == nav->selection_ptr) && cbs && cbs->action_select ) { BIT64_SET(*input_mouse, MOUSE_ACTION_BUTTON_L_TOGGLE); } else if (menu_input->mouse.ptr <= menu_list_get_size(menu_list)-1) { BIT64_SET(*input_mouse, MOUSE_ACTION_BUTTON_L_SET_NAVIGATION); } } } else menu_input->mouse.oldleft = false; if (menu_input->mouse.right) { if (!menu_input->mouse.oldright) { menu_input->mouse.oldright = true; BIT64_SET(*input_mouse, MOUSE_ACTION_BUTTON_R); } } else menu_input->mouse.oldright = false; if (menu_input->mouse.wheeldown) { BIT64_SET(*input_mouse, MOUSE_ACTION_WHEEL_DOWN); } if (menu_input->mouse.wheelup) { BIT64_SET(*input_mouse, MOUSE_ACTION_WHEEL_UP); } return 0; }
static int menu_input_mouse(unsigned *action) { video_viewport_t vp; const struct retro_keybind *binds[MAX_USERS]; menu_animation_t *anim = menu_animation_get_ptr(); menu_input_t *menu_input = menu_input_get_ptr(); menu_framebuf_t *frame_buf= menu_display_fb_get_ptr(); settings_t *settings = config_get_ptr(); if (!settings->menu.mouse.enable #ifdef HAVE_OVERLAY || (settings->input.overlay_enable && input_overlay_is_alive()) #endif ) { memset(&menu_input->mouse, 0, sizeof(menu_input->mouse)); return 0; } if (!video_driver_viewport_info(&vp)) return -1; if (menu_input->mouse.hwheeldown) { *action = MENU_ACTION_LEFT; menu_input->mouse.hwheeldown = false; return 0; } if (menu_input->mouse.hwheelup) { *action = MENU_ACTION_RIGHT; menu_input->mouse.hwheelup = false; return 0; } menu_input->mouse.left = input_driver_state(binds, 0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_LEFT); menu_input->mouse.right = input_driver_state(binds, 0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_RIGHT); menu_input->mouse.wheelup = input_driver_state(binds, 0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_WHEELUP); menu_input->mouse.wheeldown = input_driver_state(binds, 0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_WHEELDOWN); menu_input->mouse.hwheelup = input_driver_state(binds, 0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_HORIZ_WHEELUP); menu_input->mouse.hwheeldown = input_driver_state(binds, 0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_HORIZ_WHEELDOWN); menu_input->mouse.dx = input_driver_state(binds, 0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_X); menu_input->mouse.dy = input_driver_state(binds, 0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_Y); menu_input->mouse.screen_x += menu_input->mouse.dx; menu_input->mouse.screen_y += menu_input->mouse.dy; menu_input->mouse.x = ((int)menu_input->mouse.screen_x * (int)frame_buf->width) / (int)vp.width; menu_input->mouse.y = ((int)menu_input->mouse.screen_y * (int)frame_buf->height) / (int)vp.height; if (menu_input->mouse.x < 5) menu_input->mouse.x = 5; if (menu_input->mouse.y < 5) menu_input->mouse.y = 5; if (menu_input->mouse.x > (int)frame_buf->width - 5) menu_input->mouse.x = frame_buf->width - 5; if (menu_input->mouse.y > (int)frame_buf->height - 5) menu_input->mouse.y = frame_buf->height - 5; menu_input->mouse.scrollup = (menu_input->mouse.y == 5); menu_input->mouse.scrolldown = (menu_input->mouse.y == (int)frame_buf->height - 5); if ( (menu_input->mouse.dx != 0) || (menu_input->mouse.dy !=0) || menu_input->mouse.left || menu_input->mouse.wheelup || menu_input->mouse.wheeldown || menu_input->mouse.hwheelup || menu_input->mouse.hwheeldown || menu_input->mouse.scrollup || menu_input->mouse.scrolldown ) menu_animation_set_active(anim); return 0; }
void input_mapper_poll(input_mapper_t *handle) { unsigned i, j; input_bits_t current_input; settings_t *settings = config_get_ptr(); unsigned max_users = *(input_driver_get_uint(INPUT_ACTION_MAX_USERS)); bool key_event[RARCH_CUSTOM_BIND_LIST_END] = { false }; #ifdef HAVE_OVERLAY bool poll_overlay = input_overlay_is_alive(overlay_ptr) ? true : false; #endif #ifdef HAVE_MENU if (menu_driver_is_alive()) return; #endif memset(handle->keys, 0, sizeof(handle->keys)); for (i = 0; i < max_users; i++) { unsigned device = settings->uints.input_libretro_device[i]; device &= RETRO_DEVICE_MASK; switch (device) { /* keyboard to gamepad remapping */ case RETRO_DEVICE_KEYBOARD: BIT256_CLEAR_ALL_PTR(¤t_input); input_get_state_for_port(settings, i, ¤t_input); for (j = 0; j < RARCH_CUSTOM_BIND_LIST_END; j++) { unsigned remap_button = settings->uints.input_keymapper_ids[i][j]; bool remap_valid = remap_button != RETROK_UNKNOWN; if (remap_valid) { unsigned current_button_value = BIT256_GET(current_input, j); if ((current_button_value == 1) && (j != remap_button)) { MAPPER_SET_KEY (handle, remap_button); input_keyboard_event(true, remap_button, 0, 0, RETRO_DEVICE_KEYBOARD); key_event[j] = true; } /* key_event tracks if a key is pressed for ANY PLAYER, so we must check if the key was used by any player before releasing */ else if (!key_event[j]) { input_keyboard_event(false, remap_button, 0, 0, RETRO_DEVICE_KEYBOARD); } } } break; /* gamepad remapping */ case RETRO_DEVICE_JOYPAD: case RETRO_DEVICE_ANALOG: /* this loop iterates on all users and all buttons, * and checks if a pressed button is assigned to any * other button than the default one, then it sets * the bit on the mapper input bitmap, later on the * original input is cleared in input_state */ BIT256_CLEAR_ALL(handle->buttons[i]); BIT256_CLEAR_ALL_PTR(¤t_input); for (j = 0; j < 8; j++) handle->analog_value[i][j] = 0; input_get_state_for_port(settings, i, ¤t_input); for (j = 0; j < RARCH_FIRST_CUSTOM_BIND; j++) { bool remap_valid; unsigned remap_button; unsigned current_button_value = BIT256_GET(current_input, j); #ifdef HAVE_OVERLAY if (poll_overlay && i == 0) current_button_value |= input_overlay_key_pressed(overlay_ptr, j); #endif remap_button = settings->uints.input_remap_ids[i][j]; remap_valid = (current_button_value == 1) && (j != remap_button) && (remap_button != RARCH_UNMAPPED); if (remap_valid) { if (remap_button < RARCH_FIRST_CUSTOM_BIND) { BIT256_SET(handle->buttons[i], remap_button); } else if (remap_button >= RARCH_FIRST_CUSTOM_BIND) { int invert = 1; if (remap_button % 2 != 0) invert = -1; handle->analog_value[i][ remap_button - RARCH_FIRST_CUSTOM_BIND] = 32767 * invert; } } } for (j = 0; j < 8; j++) { unsigned k = j + RARCH_FIRST_CUSTOM_BIND; int16_t current_axis_value = current_input.analogs[j]; unsigned remap_axis = settings->uints.input_remap_ids[i][k]; if ( (abs(current_axis_value) > *input_driver_get_float(INPUT_ACTION_AXIS_THRESHOLD) * 32767) && (k != remap_axis) && (remap_axis != RARCH_UNMAPPED) ) { if (remap_axis < RARCH_FIRST_CUSTOM_BIND) { BIT256_SET(handle->buttons[i], remap_axis); } else { int invert = 1; if ( (k % 2 == 0 && remap_axis % 2 != 0) || (k % 2 != 0 && remap_axis % 2 == 0) ) invert = -1; handle->analog_value[i][ remap_axis - RARCH_FIRST_CUSTOM_BIND] = current_axis_value * invert; #if 0 RARCH_LOG("axis %d(%d) remapped to axis %d val %d\n", j, k, remap_axis - RARCH_FIRST_CUSTOM_BIND, current_axis_value); #endif } } } break; default: break; } } }