static void menu_input_key_bind_poll_bind_get_rested_axes( struct menu_bind_state *state, unsigned port) { unsigned a; const input_device_driver_t *joypad = input_driver_get_joypad_driver(); const input_device_driver_t *sec_joypad = input_driver_get_sec_joypad_driver(); if (!state || !joypad) return; /* poll only the relevant port */ for (a = 0; a < MENU_MAX_AXES; a++) state->axis_state[port].rested_axes[a] = input_joypad_axis_raw(joypad, port, a); if (sec_joypad) { /* poll only the relevant port */ for (a = 0; a < MENU_MAX_AXES; a++) state->axis_state[port].rested_axes[a] = input_joypad_axis_raw(sec_joypad, port, a); } }
static void menu_input_key_bind_poll_bind_state_internal(const input_device_driver_t *joypad, struct menu_bind_state *state, unsigned port, bool timed_out) { unsigned b, a, h; if (!joypad) return; if (joypad->poll) joypad->poll(); /* poll only the relevant port */ /* for (i = 0; i < settings->input.max_users; i++) */ for (b = 0; b < MENU_MAX_BUTTONS; b++) state->state[port].buttons[b] = input_joypad_button_raw(joypad, port, b); for (a = 0; a < MENU_MAX_AXES; a++) state->state[port].axes[a] = input_joypad_axis_raw(joypad, port, a); for (h = 0; h < MENU_MAX_HATS; h++) { if (input_joypad_hat_raw(joypad, port, HAT_UP_MASK, h)) state->state[port].hats[h] |= HAT_UP_MASK; if (input_joypad_hat_raw(joypad, port, HAT_DOWN_MASK, h)) state->state[port].hats[h] |= HAT_DOWN_MASK; if (input_joypad_hat_raw(joypad, port, HAT_LEFT_MASK, h)) state->state[port].hats[h] |= HAT_LEFT_MASK; if (input_joypad_hat_raw(joypad, port, HAT_RIGHT_MASK, h)) state->state[port].hats[h] |= HAT_RIGHT_MASK; } }
static void poll_joypad(const rarch_joypad_driver_t *driver, unsigned pad, struct poll_data *data) { unsigned i; if (driver) driver->poll(); for (i = 0; i < MAX_BUTTONS; i++) data->buttons[i] = input_joypad_button_raw(driver, pad, i); for (i = 0; i < MAX_AXES; i++) data->axes[i] = input_joypad_axis_raw(driver, pad, i); for (i = 0; i < MAX_HATS; i++) { uint16_t hat = 0; hat |= input_joypad_hat_raw(driver, pad, HAT_UP_MASK, i) << HAT_UP_SHIFT; hat |= input_joypad_hat_raw(driver, pad, HAT_DOWN_MASK, i) << HAT_DOWN_SHIFT; hat |= input_joypad_hat_raw(driver, pad, HAT_LEFT_MASK, i) << HAT_LEFT_SHIFT; hat |= input_joypad_hat_raw(driver, pad, HAT_RIGHT_MASK, i) << HAT_RIGHT_SHIFT; data->hats[i] = hat; } }
void menu_poll_bind_state(struct menu_bind_state *state) { if (!state) return; unsigned i, b, a, h; memset(state->state, 0, sizeof(state->state)); state->skip = input_input_state_func(NULL, 0, RETRO_DEVICE_KEYBOARD, 0, RETROK_RETURN); const rarch_joypad_driver_t *joypad = NULL; if (driver.input && driver.input_data && driver.input->get_joypad_driver) joypad = driver.input->get_joypad_driver(driver.input_data); if (!joypad) { RARCH_ERR("Cannot poll raw joypad state."); return; } input_joypad_poll(joypad); for (i = 0; i < MAX_PLAYERS; i++) { for (b = 0; b < MENU_MAX_BUTTONS; b++) state->state[i].buttons[b] = input_joypad_button_raw(joypad, i, b); for (a = 0; a < MENU_MAX_AXES; a++) state->state[i].axes[a] = input_joypad_axis_raw(joypad, i, a); for (h = 0; h < MENU_MAX_HATS; h++) { state->state[i].hats[h] |= input_joypad_hat_raw(joypad, i, HAT_UP_MASK, h) ? HAT_UP_MASK : 0; state->state[i].hats[h] |= input_joypad_hat_raw(joypad, i, HAT_DOWN_MASK, h) ? HAT_DOWN_MASK : 0; state->state[i].hats[h] |= input_joypad_hat_raw(joypad, i, HAT_LEFT_MASK, h) ? HAT_LEFT_MASK : 0; state->state[i].hats[h] |= input_joypad_hat_raw(joypad, i, HAT_RIGHT_MASK, h) ? HAT_RIGHT_MASK : 0; } } }
static void menu_input_poll_bind_get_rested_axes(struct menu_bind_state *state, unsigned port) { unsigned a; const input_device_driver_t *joypad = input_driver_get_joypad_driver(); if (!state || !joypad) return; /* poll only the relevant port */ /*for (i = 0; i < settings->input.max_users; i++)*/ for (a = 0; a < MENU_MAX_AXES; a++) state->axis_state[port].rested_axes[a] = input_joypad_axis_raw(joypad, port, a); }
void menu_poll_bind_get_rested_axes(struct rgui_bind_state *state) { unsigned i, a; const rarch_joypad_driver_t *joypad = NULL; if (driver.input && driver.input_data && driver.input->get_joypad_driver) joypad = driver.input->get_joypad_driver(driver.input_data); if (!joypad) { RARCH_ERR("Cannot poll raw joypad state."); return; } for (i = 0; i < MAX_PLAYERS; i++) for (a = 0; a < RGUI_MAX_AXES; a++) state->axis_state[i].rested_axes[a] = input_joypad_axis_raw(joypad, i, a); }
static void menu_input_poll_bind_state(struct menu_bind_state *state) { unsigned i, b, a, h; const input_device_driver_t *joypad = input_driver_get_joypad_driver(); settings_t *settings = config_get_ptr(); if (!state) return; memset(state->state, 0, sizeof(state->state)); state->skip = input_driver_state(NULL, 0, RETRO_DEVICE_KEYBOARD, 0, RETROK_RETURN); if (!joypad) { RARCH_ERR("Cannot poll raw joypad state."); return; } if (joypad->poll) joypad->poll(); for (i = 0; i < settings->input.max_users; i++) { for (b = 0; b < MENU_MAX_BUTTONS; b++) state->state[i].buttons[b] = input_joypad_button_raw(joypad, i, b); for (a = 0; a < MENU_MAX_AXES; a++) state->state[i].axes[a] = input_joypad_axis_raw(joypad, i, a); for (h = 0; h < MENU_MAX_HATS; h++) { if (input_joypad_hat_raw(joypad, i, HAT_UP_MASK, h)) state->state[i].hats[h] |= HAT_UP_MASK; if (input_joypad_hat_raw(joypad, i, HAT_DOWN_MASK, h)) state->state[i].hats[h] |= HAT_DOWN_MASK; if (input_joypad_hat_raw(joypad, i, HAT_LEFT_MASK, h)) state->state[i].hats[h] |= HAT_LEFT_MASK; if (input_joypad_hat_raw(joypad, i, HAT_RIGHT_MASK, h)) state->state[i].hats[h] |= HAT_RIGHT_MASK; } } }
static void menu_input_poll_bind_get_rested_axes(struct menu_bind_state *state) { unsigned i, a; const input_device_driver_t *joypad = input_driver_get_joypad_driver(); settings_t *settings = config_get_ptr(); if (!state) return; if (!joypad) { RARCH_ERR("Cannot poll raw joypad state."); return; } for (i = 0; i < settings->input.max_users; i++) for (a = 0; a < MENU_MAX_AXES; a++) state->axis_state[i].rested_axes[a] = input_joypad_axis_raw(joypad, i, a); }
void menu_input_poll_bind_get_rested_axes(struct menu_bind_state *state) { unsigned i, a; const rarch_joypad_driver_t *joypad = NULL; if (!state) return; if (driver.input && driver.input_data && driver.input->get_joypad_driver) joypad = driver.input->get_joypad_driver(driver.input_data); if (!joypad) { RARCH_ERR("Cannot poll raw joypad state."); return; } for (i = 0; i < g_settings.input.max_users; i++) for (a = 0; a < MENU_MAX_AXES; a++) state->axis_state[i].rested_axes[a] = input_joypad_axis_raw(joypad, i, a); }
static void menu_input_key_bind_poll_bind_state(struct menu_bind_state *state, unsigned port, bool timed_out) { unsigned b, a, h; const input_device_driver_t *joypad = input_driver_get_joypad_driver(); if (!state) return; memset(state->state, 0, sizeof(state->state)); state->skip = timed_out || input_driver_state(NULL, 0, RETRO_DEVICE_KEYBOARD, 0, RETROK_RETURN); if (!joypad) return; if (joypad->poll) joypad->poll(); /* poll only the relevant port */ /* for (i = 0; i < settings->input.max_users; i++) */ for (b = 0; b < MENU_MAX_BUTTONS; b++) state->state[port].buttons[b] = input_joypad_button_raw(joypad, port, b); for (a = 0; a < MENU_MAX_AXES; a++) state->state[port].axes[a] = input_joypad_axis_raw(joypad, port, a); for (h = 0; h < MENU_MAX_HATS; h++) { if (input_joypad_hat_raw(joypad, port, HAT_UP_MASK, h)) state->state[port].hats[h] |= HAT_UP_MASK; if (input_joypad_hat_raw(joypad, port, HAT_DOWN_MASK, h)) state->state[port].hats[h] |= HAT_DOWN_MASK; if (input_joypad_hat_raw(joypad, port, HAT_LEFT_MASK, h)) state->state[port].hats[h] |= HAT_LEFT_MASK; if (input_joypad_hat_raw(joypad, port, HAT_RIGHT_MASK, h)) state->state[port].hats[h] |= HAT_RIGHT_MASK; } }
static void get_binds(config_file_t *conf, config_file_t *auto_conf, int player, int joypad) { int i, timeout_cnt; const rarch_joypad_driver_t *driver = input_joypad_init_driver(g_driver); if (!driver) { fprintf(stderr, "Cannot find any valid input driver.\n"); exit(1); } if (!driver->query_pad(joypad)) { fprintf(stderr, "Couldn't open joystick #%d.\n", joypad); exit(1); } fprintf(stderr, "Found joypad driver: %s\n", driver->ident); const char *joypad_name = input_joypad_name(driver, joypad); fprintf(stderr, "Using joypad: %s\n", joypad_name ? joypad_name : "Unknown"); if (joypad_name && auto_conf) { config_set_string(auto_conf, "input_device", joypad_name); config_set_string(auto_conf, "input_driver", driver->ident); } int16_t initial_axes[MAX_AXES] = {0}; struct poll_data old_poll = {{0}}; struct poll_data new_poll = {{0}}; int last_axis = -1; bool block_axis = false; int timeout_ticks = g_timeout * 100; poll_joypad(driver, joypad, &old_poll); fprintf(stderr, "\nJoypads tend to have stale state after opened.\nPress some buttons and move some axes around to make sure joypad state is completely neutral before proceeding.\nWhen done, press Enter ... "); getchar(); poll_joypad(driver, joypad, &old_poll); for (i = 0; i < MAX_AXES; i++) { int16_t initial = input_joypad_axis_raw(driver, joypad, i); if (abs(initial) < 20000) initial = 0; /* Certain joypads (such as XBox360 controller on Linux) * has a default negative axis for shoulder triggers, * which makes configuration very awkward. * * If default negative, we can't trigger on the negative axis, * and similar with defaulted positive axes. */ if (initial) fprintf(stderr, "Axis %d is defaulted to %s axis value of %d.\n", i, initial > 0 ? "positive" : "negative", initial); initial_axes[i] = initial; } for (i = 0; i < MAX_BUTTONS; i++) { if (old_poll.buttons[i]) fprintf(stderr, "Button %d was initially pressed. This indicates broken initial state.\n", i); } fprintf(stderr, "Configuring binds for player #%d on joypad #%d.\n\n", player + 1, joypad); for (i = 0, timeout_cnt = 0; input_config_bind_map[i].valid; i++, timeout_cnt = 0) { int j; if (i == RARCH_TURBO_ENABLE) continue; unsigned meta_level = input_config_bind_map[i].meta; if (meta_level > g_meta_level) continue; fprintf(stderr, "%s\n", input_config_bind_map[i].desc); unsigned player_index = input_config_bind_map[i].meta ? 0 : player; for (;;) { old_poll = new_poll; /* To avoid pegging CPU. * Ideally use an event-based joypad scheme, * but it adds far more complexity, so, meh. */ rarch_sleep(10); if (timeout_ticks) { timeout_cnt++; if (timeout_cnt >= timeout_ticks) { fprintf(stderr, "\tTimed out ...\n"); break; } } poll_joypad(driver, joypad, &new_poll); for (j = 0; j < MAX_BUTTONS; j++) { if (new_poll.buttons[j] && !old_poll.buttons[j]) { fprintf(stderr, "\tJoybutton pressed: %d\n", j); char key[64]; snprintf(key, sizeof(key), "%s_%s_btn", input_config_get_prefix(player_index, input_config_bind_map[i].meta), input_config_bind_map[i].base); config_set_int(conf, key, j); if (auto_conf) { snprintf(key, sizeof(key), "input_%s_btn", input_config_bind_map[i].base); config_set_int(auto_conf, key, j); } goto out; } } for (j = 0; j < MAX_AXES; j++) { if (new_poll.axes[j] == old_poll.axes[j]) continue; int16_t value = new_poll.axes[j]; bool same_axis = last_axis == j; bool require_negative = initial_axes[j] > 0; bool require_positive = initial_axes[j] < 0; /* Block the axis config until we're sure * axes have returned to their neutral state. */ if (same_axis) { if (abs(value) < 10000 || (require_positive && value < 0) || (require_negative && value > 0)) block_axis = false; } /* If axes are in their neutral state, * we can't allow it. */ if (require_negative && value >= 0) continue; if (require_positive && value <= 0) continue; if (block_axis) continue; if (abs(value) > 20000) { last_axis = j; fprintf(stderr, "\tJoyaxis moved: Axis %d, Value %d\n", j, value); char buf[8]; snprintf(buf, sizeof(buf), value > 0 ? "+%d" : "-%d", j); char key[64]; snprintf(key, sizeof(key), "%s_%s_axis", input_config_get_prefix(player_index, input_config_bind_map[i].meta), input_config_bind_map[i].base); config_set_string(conf, key, buf); if (auto_conf) { snprintf(key, sizeof(key), "input_%s_axis", input_config_bind_map[i].base); config_set_string(auto_conf, key, buf); } block_axis = true; goto out; } } for (j = 0; j < MAX_HATS; j++) { const char *quark = NULL; uint16_t value = new_poll.hats[j]; uint16_t old_value = old_poll.hats[j]; if ((value & HAT_UP_MASK) && !(old_value & HAT_UP_MASK)) quark = "up"; else if ((value & HAT_LEFT_MASK) && !(old_value & HAT_LEFT_MASK)) quark = "left"; else if ((value & HAT_RIGHT_MASK) && !(old_value & HAT_RIGHT_MASK)) quark = "right"; else if ((value & HAT_DOWN_MASK) && !(old_value & HAT_DOWN_MASK)) quark = "down"; if (quark) { fprintf(stderr, "\tJoyhat moved: Hat %d, direction %s\n", j, quark); char buf[16]; snprintf(buf, sizeof(buf), "h%d%s", j, quark); char key[64]; snprintf(key, sizeof(key), "%s_%s_btn", input_config_get_prefix(player_index, input_config_bind_map[i].meta), input_config_bind_map[i].base); config_set_string(conf, key, buf); if (auto_conf) { snprintf(key, sizeof(key), "input_%s_btn", input_config_bind_map[i].base); config_set_string(auto_conf, key, buf); } goto out; } } } out: old_poll = new_poll; } }
static void get_binds(config_file_t *conf, int player, int joypad) { const rarch_joypad_driver_t *driver = input_joypad_init_first(); if (!driver) { fprintf(stderr, "Cannot find any valid input driver.\n"); exit(1); } if (!driver->query_pad(joypad)) { fprintf(stderr, "Couldn't open joystick #%u.\n", joypad); exit(1); } fprintf(stderr, "Found joypad driver: %s\n", driver->ident); int16_t initial_axes[MAX_AXES] = {0}; struct poll_data old_poll = {{0}}; struct poll_data new_poll = {{0}}; int last_axis = -1; bool block_axis = false; poll_joypad(driver, joypad, &old_poll); for (int i = 0; i < MAX_AXES; i++) { int16_t initial = input_joypad_axis_raw(driver, joypad, i); if (abs(initial) < 20000) initial = 0; // Certain joypads (such as XBox360 controller on Linux) has a default negative axis for shoulder triggers, // which makes configuration very awkward. // If default negative, we can't trigger on the negative axis, and similar with defaulted positive axes. if (initial) fprintf(stderr, "Axis %d is defaulted to %s axis value of %d\n", i, initial > 0 ? "positive" : "negative", initial); initial_axes[i] = initial; } fprintf(stderr, "Configuring binds for player #%d on joypad #%d.\n\n", player + 1, joypad); for (unsigned i = 0; i < sizeof(binds) / sizeof(binds[0]) && (g_use_misc || !binds[i].is_misc) ; i++) { fprintf(stderr, "%s\n", binds[i].keystr); unsigned player_index = binds[i].is_misc ? 0 : player; for (;;) { old_poll = new_poll; // To avoid pegging CPU. // Ideally use an event-based joypad scheme, // but it adds far more complexity, so, meh. rarch_sleep(10); poll_joypad(driver, joypad, &new_poll); for (int j = 0; j < MAX_BUTTONS; j++) { if (new_poll.buttons[j] && !old_poll.buttons[j]) { fprintf(stderr, "\tJoybutton pressed: %u\n", j); config_set_int(conf, binds[i].confbtn[player_index], j); goto out; } } for (int j = 0; j < MAX_AXES; j++) { if (new_poll.axes[j] != old_poll.axes[j]) { int16_t value = new_poll.axes[j]; bool same_axis = last_axis == j; bool require_negative = initial_axes[j] > 0; bool require_positive = initial_axes[j] < 0; // Block the axis config until we're sure axes have returned to their neutral state. if (same_axis) { if (abs(value) < 10000 || (require_positive && value < 0) || (require_negative && value > 0)) block_axis = false; } // If axes are in their neutral state, we can't allow it. if (require_negative && value >= 0) continue; if (require_positive && value <= 0) continue; if (block_axis) continue; if (abs(value) > 20000) { last_axis = j; fprintf(stderr, "\tJoyaxis moved: Axis %d, Value %d\n", j, value); char buf[8]; snprintf(buf, sizeof(buf), value > 0 ? "+%d" : "-%d", j); config_set_string(conf, binds[i].confaxis[player_index], buf); block_axis = true; goto out; } } } for (int j = 0; j < MAX_HATS; j++) { const char *quark = NULL; uint16_t value = new_poll.hats[j]; uint16_t old_value = old_poll.hats[j]; if ((value & HAT_UP_MASK) && !(old_value & HAT_UP_MASK)) quark = "up"; else if ((value & HAT_LEFT_MASK) && !(old_value & HAT_LEFT_MASK)) quark = "left"; else if ((value & HAT_RIGHT_MASK) && !(old_value & HAT_RIGHT_MASK)) quark = "right"; else if ((value & HAT_DOWN_MASK) && !(old_value & HAT_DOWN_MASK)) quark = "down"; if (quark) { fprintf(stderr, "\tJoyhat moved: Hat %d, direction %s\n", j, quark); char buf[16]; snprintf(buf, sizeof(buf), "h%d%s", j, quark); config_set_string(conf, binds[i].confbtn[player_index], buf); goto out; } } } out: old_poll = new_poll; } }