gint GetJoy(guint js, guidata *gui) { //printf("Number of Axes: %d\n", SDL_JoystickNumAxes(gui->joy[js].sdljoy)); //printf("Number of Hats: %d\n", SDL_JoystickNumHats(gui->joy[js].sdljoy)); //printf("Number of Buttons: %d\n", SDL_JoystickNumButtons(gui->joy[js].sdljoy)); //printf("Number of Balls: %d\n", SDL_JoystickNumBalls(gui->joy[js].sdljoy)); gui->joy[js].id = CalcOldStyleID(SDL_JoystickNumAxes(gui->joy[js].sdljoy), 0, SDL_JoystickNumHats(gui->joy[js].sdljoy), SDL_JoystickNumButtons(gui->joy[js].sdljoy)); return 1; }
Joystick_Linux::Joystick_Linux(const char *jsdev_path, const char *evdev_path) : jsdev_fd(-1), evdev_fd(-1) { unsigned char tmp; //printf("%s %s\n", jsdev_path, evdev_path); jsdev_fd = open(jsdev_path, O_RDONLY); if(jsdev_fd == -1) { ErrnoHolder ene(errno); throw MDFN_Error(ene.Errno(), _("Error opening joystick device \"%s\": %s"), jsdev_path, ene.StrError()); } fcntl(jsdev_fd, F_SETFL, fcntl(jsdev_fd, F_GETFL) | O_NONBLOCK); if(evdev_path != NULL) { evdev_fd = open(evdev_path, O_RDWR); if(evdev_fd == -1) { ErrnoHolder ene(errno); if(ene.Errno() == EACCES) { evdev_fd = open(evdev_path, O_RDONLY); if(evdev_fd == -1) { ErrnoHolder ene2(errno); fprintf(stderr, _("WARNING: Failed to open event device \"%s\": %s --- !!!!! BASE JOYSTICK FUNCTIONALITY WILL BE AVAILABLE, BUT FORCE-FEEDBACK(E.G. RUMBLE) WILL BE UNAVAILABLE, AND THE CALCULATED JOYSTICK ID WILL BE DIFFERENT. !!!!!\n"), evdev_path, ene2.StrError()); } else { fprintf(stderr, _("WARNING: Could only open event device \"%s\" for reading, and not reading+writing: %s --- !!!!! FORCE-FEEDBACK(E.G. RUMBLE) WILL BE UNAVAILABLE. !!!!!\n"), evdev_path, ene.StrError()); } } else fprintf(stderr, _("WARNING: Failed to open event device \"%s\": %s --- !!!!! BASE JOYSTICK FUNCTIONALITY WILL BE AVAILABLE, BUT FORCE-FEEDBACK(E.G. RUMBLE) WILL BE UNAVAILABLE, AND THE CALCULATED JOYSTICK ID WILL BE DIFFERENT. !!!!!\n"), evdev_path, ene.StrError()); } } else fprintf(stderr, _("WARNING: Failed to find a valid corresponding event device to joystick device \"%s\" --- !!!!! BASE JOYSTICK FUNCTIONALITY WILL BE AVAILABLE, BUT FORCE-FEEDBACK(E.G. RUMBLE) WILL BE UNAVAILABLE, AND THE CALCULATED JOYSTICK ID WILL BE DIFFERENT. !!!!!\n"), jsdev_path); if(evdev_fd != -1) fcntl(evdev_fd, F_SETFL, fcntl(evdev_fd, F_GETFL) | O_NONBLOCK); num_rel_axes = 0; if(ioctl(jsdev_fd, JSIOCGAXES, &tmp) == -1) { ErrnoHolder ene(errno); throw MDFN_Error(ene.Errno(), _("Failed to get number of axes: %s"), ene.StrError()); } else num_axes = tmp; if(ioctl(jsdev_fd, JSIOCGBUTTONS, &tmp) == -1) { ErrnoHolder ene(errno); throw MDFN_Error(ene.Errno(), _("Failed to get number of buttons: %s"), ene.StrError()); } else num_buttons = tmp; axis_state.resize(num_axes); button_state.resize(num_buttons); memset(name, 0, sizeof(name)); ioctl(jsdev_fd, JSIOCGNAME(sizeof(name) - 1), name); if(name[0] == 0) snprintf(name, sizeof(name), _("%u-button, %u-axis controller"), num_buttons, num_axes); compat_hat_offs = ~0U; CalcOldStyleID(num_axes, 0, 0, num_buttons); if(evdev_fd != -1) { #if 0 uint8 keybits[(KEY_CNT + 7) / 8]; unsigned ev_button_count = 0; memset(keybits, 0, sizeof(keybits)); ioctl(evdev_fd, EVIOCGBIT(EV_KEY, sizeof(keybits)), keybits); for(unsigned kbt = 0; kbt < KEY_CNT; kbt++) { if(keybits[kbt >> 3] & (1 << (kbt & 0x7))) { ev_button_count++; } } printf("moo: %u\n", ev_button_count); #endif uint8 absaxbits[(ABS_CNT + 7) / 8]; unsigned ev_abs_count = 0; unsigned ev_hat_count = 0; memset(absaxbits, 0, sizeof(absaxbits)); ioctl(evdev_fd, EVIOCGBIT(EV_ABS, sizeof(absaxbits)), absaxbits); for(unsigned aat = 0; aat < ABS_CNT; aat++) { if(TestEVBit(absaxbits, aat)) { if(aat >= ABS_HAT0X && aat <= ABS_HAT3Y) { if(compat_hat_offs == ~0U) compat_hat_offs = ev_abs_count; ev_hat_count++; } ev_abs_count++; } } //printf("%u\n", compat_hat_offs); CalcOldStyleID(ev_abs_count - ev_hat_count, 0, ev_hat_count / 2, num_buttons); }
Joystick_DX5::Joystick_DX5(LPDIRECTINPUT dii, DIDEVICEINSTANCE *ddi) : dev(NULL), have_exclusive_access(-1) { LPDIRECTINPUTDEVICE tmp_dev = NULL; try { REQUIRE_DI_CALL( dii->CreateDevice(ddi->guidInstance, &tmp_dev, NULL) ); REQUIRE_DI_CALL( tmp_dev->QueryInterface(IID_IDirectInputDevice2, (LPVOID *)&dev) ); REQUIRE_DI_CALL( dev->SetDataFormat(&c_dfDIJoystick2) ); DevCaps.dwSize = sizeof(DevCaps); REQUIRE_DI_CALL( dev->GetCapabilities(&DevCaps) ); for(unsigned rax = 0; rax < 8; rax++) { DIPROPRANGE diprg; HRESULT hres; diprg.diph.dwSize = sizeof(diprg); diprg.diph.dwHeaderSize = sizeof(diprg.diph); diprg.diph.dwObj = rax * sizeof(LONG); diprg.diph.dwHow = DIPH_BYOFFSET; // TODO: Handle DIPROPRANGE_NOMIN and DIPROPRANGE_NOMAX hres = dev->GetProperty(DIPROP_RANGE, &diprg.diph); if(hres == DI_OK) { if(diprg.lMin < diprg.lMax) { di_axis_info dai; dai.jd_logical_offset = rax; dai.minimum = diprg.lMin; dai.maximum = diprg.lMax; DIAxisInfo.push_back(dai); } } //else if(hres != DIERR_OBJECTNOTFOUND) } num_rel_axes = 0; num_axes = DIAxisInfo.size() + DevCaps.dwPOVs * 2; num_buttons = DevCaps.dwButtons; axis_state.resize(num_axes); rel_axis_state.resize(num_rel_axes); button_state.resize(num_buttons); // id, guidinstance, etc. // // // #if 0 { DIEFFECTINFO eff_inf; eff_inf.dwSize = sizeof(eff_inf); if(dev->GetEffectInfo(&eff_inf, GUID_Square) == DI_OK || dev->GetEffectInfo(&eff_inf, GUID_Sine) == DI_OK) { } } #endif RequestExclusive(false); CalcOldStyleID(DIAxisInfo.size(), 0, DevCaps.dwPOVs, DevCaps.dwButtons); snprintf(name, sizeof(name), "%s", ddi->tszProductName); } catch(...) { if(tmp_dev != NULL) tmp_dev->Release(); if(dev != NULL) dev->Release(); throw; } }