static void lr_input_poll_orbatak_trackball(const int port_) { freedo_pbus_orbatak_trackball_t tb; tb.x = (poll_analog_lx(port_) / (32768 / 24)); tb.y = (poll_analog_ly(port_) / (32768 / 24)); if(tb.x == 0) { if(poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_LEFT)) tb.x = -24; else if(poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_RIGHT)) tb.x = 24; } if(tb.y == 0) { if(poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_UP)) tb.y = -24; else if(poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_DOWN)) tb.y = 24; } tb.start_p1 = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_SELECT); tb.start_p2 = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_START); tb.coin_p1 = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_L); tb.coin_p2 = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_R); tb.service = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_R2); freedo_pbus_add_orbatak_trackball(&tb); }
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 lr_input_poll_flightstick(const int port_) { freedo_pbus_flightstick_t fs; fs.h_pos = poll_analog_lx(port_); fs.v_pos = poll_analog_ly(port_); fs.z_pos = poll_analog_ry(port_); fs.fire = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_R2); fs.a = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_Y); fs.b = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_B); fs.c = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_A); fs.u = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_UP); fs.d = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_DOWN); fs.l = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_LEFT); fs.r = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_RIGHT); fs.p = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_START); fs.x = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_SELECT); fs.lt = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_L); fs.rt = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_R); freedo_pbus_add_flightstick(&fs); }
static void lr_input_poll_joypad(const int port_) { freedo_pbus_joypad_t jp; jp.u = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_UP); jp.d = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_DOWN); jp.l = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_LEFT); jp.r = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_RIGHT); jp.lt = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_L); jp.rt = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_R); jp.x = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_SELECT); jp.p = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_START) | poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_X); jp.a = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_Y); jp.b = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_B); jp.c = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_A); freedo_pbus_add_joypad(&jp); }
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; } }