RetroArch crashes when any joystick direction is pressed, EmulationStation fine.
-
I am writing an input driver for my device that talks to a pico to relay button presses and analog readings. I am having issues with RetroArch crashing on axis input, giving a not so detailed Floating Point Exception in /dev/shm/runcommand.log, or not recognizing DPAD input if I change it to button presses. Here is my relevant code for the driver. Everything responds in EmulationStation just fine, just RetroArch crashes. here are the relevant sections of my code:
void ControllerManager::setup_uinput_device(int joystick_id) { struct uinput_setup usetup; int fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK); if (fd < 0) { perror("Unable to open /dev/uinput"); exit(EXIT_FAILURE); } ioctl(fd, UI_SET_EVBIT, EV_KEY); ioctl(fd, UI_SET_KEYBIT, BTN_A); ioctl(fd, UI_SET_KEYBIT, BTN_B); ioctl(fd, UI_SET_KEYBIT, BTN_X); ioctl(fd, UI_SET_KEYBIT, BTN_Y); ioctl(fd, UI_SET_KEYBIT, BTN_START); ioctl(fd, UI_SET_KEYBIT, BTN_SELECT); ioctl(fd, UI_SET_KEYBIT, BTN_TL); ioctl(fd, UI_SET_KEYBIT, BTN_TR); ioctl(fd, UI_SET_EVBIT, EV_ABS); ioctl(fd, UI_SET_ABSBIT, ABS_X); ioctl(fd, UI_SET_ABSBIT, ABS_Y); memset(&usetup, 0, sizeof(usetup)); usetup.id.bustype = BUS_USB; usetup.id.vendor = 0x5348; // Sample Vendor usetup.id.product = 0x0100 + joystick_id; // Unique product ID for each joystick snprintf(usetup.name, UINPUT_MAX_NAME_SIZE, "Xemplar PicoTroller %d", joystick_id); ioctl(fd, UI_DEV_SETUP, &usetup); ioctl(fd, UI_DEV_CREATE); fds[fd_count++] = fd; } void ControllerManager::monitorJoystick(byte controller_index, byte button_count, const byte* button_values, byte axis_count, const int16_t* axis_values) { if(controller_index < 0 || controller_index > fd_count) return; // Invalid controller index if(controller_index == 0){ pluggedIn = (button_values[0] & 0x01) > 0; bool isFan = (button_values[0] & 0x02) > 0; if(isFan){ fanValue = axis_values[0]; } else { batteryValue = axis_values[0]; } return; } controller_index--; if(controllers[controller_index].button_count < button_count){ controllers[controller_index].button_count = button_count; controllers[controller_index].axis_count = axis_count; } for(int i = 0; i < button_count; i++){ byte byte_index = i / 8; byte bit_index = i % 8; byte button_state = (button_values[byte_index] >> bit_index) & 1; controllers[controller_index].button_states[i] = button_state == 1; } for (byte i = 0; i < axis_count; ++i) { controllers[controller_index].axis[i].x = axis_values[i * 2]; controllers[controller_index].axis[i].y = axis_values[i * 2 + 1]; } if(checkSpecial(controller_index)) return; controller_index++; emulateJoystick(controller_index, button_count, button_values, axis_count, axis_values); } void ControllerManager::emulateJoystick(byte controller_index, byte button_count, const byte* button_values, byte axis_count, const int16_t* axis_values) { int fd = fds[controller_index - 1]; // Convert to 0-based index sendEvent(fd, EV_SYN, SYN_REPORT, 0); for (byte i = 0; i < button_count; ++i) { int code; switch (i + 1) { case 1: code = BTN_A; break; case 2: code = BTN_B; break; case 3: code = BTN_X; break; case 4: code = BTN_Y; break; case 5: code = BTN_START; break; case 6: code = BTN_SELECT; break; case 7: code = BTN_TL; break; case 8: code = BTN_TR; break; default: continue; } sendEvent(fd, EV_KEY, code, controllers[controller_index - 1].button_states[i]); } sendEvent(fd, EV_SYN, SYN_REPORT, 0); sendEvent(fd, EV_ABS, ABS_X, controllers[controller_index - 1].axis[0].x); sendEvent(fd, EV_ABS, ABS_Y, controllers[controller_index - 1].axis[0].y); sendEvent(fd, EV_SYN, SYN_REPORT, 0); if (DEBUG) { std::cout << "\rAxes: "; for (byte i = 0; i < axis_count * 2; ++i) { std::cout << std::setw(3) << static_cast<int>(i) << ":" << std::setw(6) << controllers[controller_index - 1].axis[i].x << " " << controllers[controller_index - 1].axis[i].y << " "; } std::cout << "Buttons: "; for (byte i = 0; i < button_count; ++i) { std::cout << std::setw(2) << static_cast<int>(i) << ":" << (controllers[controller_index - 1].button_states[i] ? "on " : "off "); } std::cout << std::flush; if(!ONE_LINE) std::cout << std::endl; } }
-
RetroPie just packages RetroArch - you may want to report to the upstream project. You should add a way to reproduce the issue without relying on a specific device, so that any developer familiar with RetroArch's input system may be able to analyze and maybe fix your issue.
Contributions to the project are always appreciated, so if you would like to support us with a donation you can do so here.
Hosting provided by Mythic-Beasts. See the Hosting Information page for more information.