void PERDXLoadDevices(char *inifilename) { char tempstr[MAX_PATH]; char string1[20]; char string2[20]; GUID guid; DIDEVCAPS didc; u32 i; int j, i2; int buttonid; DIPROPDWORD dipdw; int id; DWORD coopflags=DISCL_FOREGROUND | DISCL_NONEXCLUSIVE; BOOL loaddefault=TRUE; int numpads; HRESULT hr; if (!PERCore) return; PerPortReset(); memset(pad, 0, sizeof(pad)); // Check Connection Type if (GetPrivateProfileStringA("Input", "Port1Type", "", tempstr, MAX_PATH, inifilename) == 0) { // Check if it's using the old ini settings for peripherals if (GetPrivateProfileStringA("Peripheral1", "GUID", "", tempstr, MAX_PATH, inifilename) != 0) { // Convert to the newer type of settings for (i = 0; i < 2; i++) { sprintf(string1, "Port%dType", (int)i+1); WritePrivateProfileStringA("Input", string1, "1", inifilename); sprintf(string1, "Peripheral%d", (int)i+1); sprintf(string2, "Peripheral%dA", (int)i+1); if (GetPrivateProfileStringA(string1, "GUID", "", tempstr, MAX_PATH, inifilename)) WritePrivateProfileStringA(string2, "GUID", tempstr, inifilename); if (GetPrivateProfileStringA(string1, "EmulateType", "", tempstr, MAX_PATH, inifilename)) WritePrivateProfileStringA(string2, "EmulateType", tempstr, inifilename); for (i2 = 0; i2 < 13; i2++) { if (GetPrivateProfileStringA(string1, PerPadNames[i2], "", tempstr, MAX_PATH, inifilename)) WritePrivateProfileStringA(string2, PerPadNames[i2], tempstr, inifilename); } } // Remove old ini entries for (i = 0; i < 12; i++) { sprintf(string1, "Peripheral%d", (int)i+1); WritePrivateProfileStringA(string1, NULL, NULL, inifilename); } loaddefault = FALSE; } } else loaddefault = FALSE; if (loaddefault) { LoadDefaultPort1A(); return; } // Load new type settings for (i = 0; i < 2; i++) { sprintf(string1, "Port%dType", (int)i+1); if (GetPrivateProfileStringA("Input", string1, "", tempstr, MAX_PATH, inifilename) != 0) { porttype[i] = atoi(tempstr); switch(porttype[i]) { case 1: numpads = 1; break; case 2: numpads = 6; break; default: numpads = 0; break; } // Load new type settings for (j = 0; j < numpads; j++) { int padindex=(6*i)+j; padconf_struct *curdevice=&paddevice[padindex]; sprintf(string1, "Peripheral%d%C", (int)i+1, 'A' + j); // Let's first fetch the guid of the device if (GetPrivateProfileStringA(string1, "GUID", "", tempstr, MAX_PATH, inifilename) == 0) continue; if (GetPrivateProfileStringA(string1, "EmulateType", "0", string2, MAX_PATH, inifilename)) { curdevice->emulatetype = atoi(string2); if (curdevice->emulatetype == 0) continue; } if (curdevice->lpDIDevice) { // Free the default keyboard, etc. IDirectInputDevice8_Unacquire(curdevice->lpDIDevice); IDirectInputDevice8_Release(curdevice->lpDIDevice); } StringToGUID(tempstr, &guid); // Ok, now that we've got the GUID of the device, let's set it up if (FAILED(IDirectInput8_CreateDevice(lpDI8, &guid, &lpDIDevice[padindex], NULL) )) { curdevice->lpDIDevice = NULL; curdevice->emulatetype = 0; continue; } curdevice->lpDIDevice = lpDIDevice[padindex]; didc.dwSize = sizeof(DIDEVCAPS); if (FAILED(IDirectInputDevice8_GetCapabilities(lpDIDevice[padindex], &didc) )) continue; if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_KEYBOARD) { if (FAILED(IDirectInputDevice8_SetDataFormat(lpDIDevice[padindex], &c_dfDIKeyboard) )) continue; curdevice->type = TYPE_KEYBOARD; coopflags |= DISCL_NOWINKEY; } else if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_GAMEPAD || GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_JOYSTICK) { if (FAILED(IDirectInputDevice8_SetDataFormat(lpDIDevice[padindex], &c_dfDIJoystick2) )) continue; curdevice->type = TYPE_JOYSTICK; } else if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_MOUSE) { if (FAILED(IDirectInputDevice8_SetDataFormat(lpDIDevice[padindex], &c_dfDIMouse2) )) continue; curdevice->type = TYPE_MOUSE; coopflags = DISCL_FOREGROUND | DISCL_EXCLUSIVE; } hr = IDirectInputDevice8_SetCooperativeLevel(lpDIDevice[i], DXGetWindow(), coopflags); if (FAILED(hr)) continue; dipdw.diph.dwSize = sizeof(DIPROPDWORD); dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); dipdw.diph.dwObj = 0; dipdw.diph.dwHow = DIPH_DEVICE; dipdw.dwData = 8; // should be enough // Setup Buffered input if (FAILED(IDirectInputDevice8_SetProperty(lpDIDevice[padindex], DIPROP_BUFFERSIZE, &dipdw.diph))) continue; IDirectInputDevice8_Acquire(lpDIDevice[padindex]); switch(curdevice->emulatetype) { case 1: // Standard Pad id = PERPAD; break; case 2: // Analog Pad case 3: // Stunner case 5: // Keyboard id = 0; break; case 4: // Mouse id = PERMOUSE; break; default: break; } // Make sure we're added to the smpc list if (i == 0) pad[padindex] = PerAddPeripheral(&PORTDATA1, id); else pad[padindex] = PerAddPeripheral(&PORTDATA2, id); // Now that we're all setup, let's fetch the controls from the ini if (curdevice->emulatetype != 3 && curdevice->emulatetype != 4) { for (i2 = 0; i2 < 13; i2++) { buttonid = GetPrivateProfileIntA(string1, PerPadNames[i2], 0, inifilename); PerSetKey(buttonid, i2, pad[padindex]); } } else if (curdevice->emulatetype == 4) { for (i2 = 0; i2 < 4; i2++) { buttonid = GetPrivateProfileIntA(string1, mouse_names[i2], 0, inifilename); PerSetKey(buttonid, PERMOUSE_LEFT+i2, pad[padindex]); } } } } } }
/* * Opens the haptic device. * * Steps: * - Set cooperative level. * - Set data format. * - Acquire exclusiveness. * - Reset actuators. * - Get supported features. */ static int SDL_DINPUT_HapticOpenFromDevice(SDL_Haptic * haptic, LPDIRECTINPUTDEVICE8 device8, SDL_bool is_joystick) { HRESULT ret; DIPROPDWORD dipdw; /* Allocate the hwdata */ haptic->hwdata = (struct haptic_hwdata *)SDL_malloc(sizeof(*haptic->hwdata)); if (haptic->hwdata == NULL) { return SDL_OutOfMemory(); } SDL_memset(haptic->hwdata, 0, sizeof(*haptic->hwdata)); /* We'll use the device8 from now on. */ haptic->hwdata->device = device8; haptic->hwdata->is_joystick = is_joystick; /* !!! FIXME: opening a haptic device here first will make an attempt to !!! FIXME: SDL_JoystickOpen() that same device fail later, since we !!! FIXME: have it open in exclusive mode. But this will allow !!! FIXME: SDL_JoystickOpen() followed by SDL_HapticOpenFromJoystick() !!! FIXME: to work, and that's probably the common case. Still, !!! FIXME: ideally, We need to unify the opening code. */ if (!is_joystick) { /* if is_joystick, we already set this up elsewhere. */ /* Grab it exclusively to use force feedback stuff. */ ret = IDirectInputDevice8_SetCooperativeLevel(haptic->hwdata->device, SDL_HelperWindow, DISCL_EXCLUSIVE | DISCL_BACKGROUND); if (FAILED(ret)) { DI_SetError("Setting cooperative level to exclusive", ret); goto acquire_err; } /* Set data format. */ ret = IDirectInputDevice8_SetDataFormat(haptic->hwdata->device, &SDL_c_dfDIJoystick2); if (FAILED(ret)) { DI_SetError("Setting data format", ret); goto acquire_err; } /* Acquire the device. */ ret = IDirectInputDevice8_Acquire(haptic->hwdata->device); if (FAILED(ret)) { DI_SetError("Acquiring DirectInput device", ret); goto acquire_err; } } /* Get number of axes. */ ret = IDirectInputDevice8_EnumObjects(haptic->hwdata->device, DI_DeviceObjectCallback, haptic, DIDFT_AXIS); if (FAILED(ret)) { DI_SetError("Getting device axes", ret); goto acquire_err; } /* Reset all actuators - just in case. */ ret = IDirectInputDevice8_SendForceFeedbackCommand(haptic->hwdata->device, DISFFC_RESET); if (FAILED(ret)) { DI_SetError("Resetting device", ret); goto acquire_err; } /* Enabling actuators. */ ret = IDirectInputDevice8_SendForceFeedbackCommand(haptic->hwdata->device, DISFFC_SETACTUATORSON); if (FAILED(ret)) { DI_SetError("Enabling actuators", ret); goto acquire_err; } /* Get supported effects. */ ret = IDirectInputDevice8_EnumEffects(haptic->hwdata->device, DI_EffectCallback, haptic, DIEFT_ALL); if (FAILED(ret)) { DI_SetError("Enumerating supported effects", ret); goto acquire_err; } if (haptic->supported == 0) { /* Error since device supports nothing. */ SDL_SetError("Haptic: Internal error on finding supported effects."); goto acquire_err; } /* Check autogain and autocenter. */ dipdw.diph.dwSize = sizeof(DIPROPDWORD); dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); dipdw.diph.dwObj = 0; dipdw.diph.dwHow = DIPH_DEVICE; dipdw.dwData = 10000; ret = IDirectInputDevice8_SetProperty(haptic->hwdata->device, DIPROP_FFGAIN, &dipdw.diph); if (!FAILED(ret)) { /* Gain is supported. */ haptic->supported |= SDL_HAPTIC_GAIN; } dipdw.diph.dwObj = 0; dipdw.diph.dwHow = DIPH_DEVICE; dipdw.dwData = DIPROPAUTOCENTER_OFF; ret = IDirectInputDevice8_SetProperty(haptic->hwdata->device, DIPROP_AUTOCENTER, &dipdw.diph); if (!FAILED(ret)) { /* Autocenter is supported. */ haptic->supported |= SDL_HAPTIC_AUTOCENTER; } /* Status is always supported. */ haptic->supported |= SDL_HAPTIC_STATUS | SDL_HAPTIC_PAUSE; /* Check maximum effects. */ haptic->neffects = 128; /* This is not actually supported as thus under windows, there is no way to tell the number of EFFECTS that a device can hold, so we'll just use a "random" number instead and put warnings in SDL_haptic.h */ haptic->nplaying = 128; /* Even more impossible to get this then neffects. */ /* Prepare effects memory. */ haptic->effects = (struct haptic_effect *) SDL_malloc(sizeof(struct haptic_effect) * haptic->neffects); if (haptic->effects == NULL) { SDL_OutOfMemory(); goto acquire_err; } /* Clear the memory */ SDL_memset(haptic->effects, 0, sizeof(struct haptic_effect) * haptic->neffects); return 0; /* Error handling */ acquire_err: IDirectInputDevice8_Unacquire(haptic->hwdata->device); return -1; }
int PERDXInit(void) { DIPROPDWORD dipdw; char tempstr[512]; HRESULT ret; memset(pad, 0, sizeof(pad)); memset(paddevice, 0, sizeof(paddevice)); if (FAILED((ret = DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, &IID_IDirectInput8, (LPVOID *)&lpDI8, NULL)) )) { sprintf(tempstr, "DirectInput8Create error: %s - %s", DXGetErrorString8(ret), DXGetErrorDescription8(ret)); MessageBox (NULL, _16(tempstr), _16("Error"), MB_OK | MB_ICONINFORMATION); return -1; } IDirectInput8_EnumDevices(lpDI8, DI8DEVCLASS_ALL, EnumPeripheralsCallback, NULL, DIEDFL_ATTACHEDONLY); if (FAILED((ret = IDirectInput8_CreateDevice(lpDI8, &GUID_SysKeyboard, &lpDIDevice[0], NULL)) )) { sprintf(tempstr, "IDirectInput8_CreateDevice error: %s - %s", DXGetErrorString8(ret), DXGetErrorDescription8(ret)); MessageBox (NULL, _16(tempstr), _16("Error"), MB_OK | MB_ICONINFORMATION); return -1; } if (FAILED((ret = IDirectInputDevice8_SetDataFormat(lpDIDevice[0], &c_dfDIKeyboard)) )) { sprintf(tempstr, "IDirectInputDevice8_SetDataFormat error: %s - %s", DXGetErrorString8(ret), DXGetErrorDescription8(ret)); MessageBox (NULL, _16(tempstr), _16("Error"), MB_OK | MB_ICONINFORMATION); return -1; } if (FAILED((ret = IDirectInputDevice8_SetCooperativeLevel(lpDIDevice[0], DXGetWindow(), DISCL_FOREGROUND | DISCL_NONEXCLUSIVE | DISCL_NOWINKEY)) )) { sprintf(tempstr, "IDirectInputDevice8_SetCooperativeLevel error: %s - %s", DXGetErrorString8(ret), DXGetErrorDescription8(ret)); MessageBox (NULL, _16(tempstr), _16("Error"), MB_OK | MB_ICONINFORMATION); return -1; } dipdw.diph.dwSize = sizeof(DIPROPDWORD); dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); dipdw.diph.dwObj = 0; dipdw.diph.dwHow = DIPH_DEVICE; dipdw.dwData = 8; // should be enough // Setup Buffered input if (FAILED((ret = IDirectInputDevice8_SetProperty(lpDIDevice[0], DIPROP_BUFFERSIZE, &dipdw.diph)) )) { sprintf(tempstr, "IDirectInputDevice8_SetProperty error: %s - %s", DXGetErrorString8(ret), DXGetErrorDescription8(ret)); MessageBox (NULL, _16(tempstr), _16("Error"), MB_OK | MB_ICONINFORMATION); return -1; } // Make sure Keyboard is acquired already IDirectInputDevice8_Acquire(lpDIDevice[0]); paddevice[0].lpDIDevice = lpDIDevice[0]; paddevice[0].type = TYPE_KEYBOARD; paddevice[0].emulatetype = 1; PerPortReset(); LoadDefaultPort1A(); return 0; }
static BOOL CALLBACK enum_joypad_cb(const DIDEVICEINSTANCE *inst, void *p) { bool is_xinput_pad; LPDIRECTINPUTDEVICE8 *pad = NULL; (void)p; if (g_joypad_cnt == MAX_USERS) return DIENUM_STOP; pad = &g_pads[g_joypad_cnt].joypad; #ifdef __cplusplus if (FAILED(IDirectInput8_CreateDevice( g_ctx, inst->guidInstance, pad, NULL))) #else if (FAILED(IDirectInput8_CreateDevice( g_ctx, &inst->guidInstance, pad, NULL))) #endif return DIENUM_CONTINUE; g_pads[g_joypad_cnt].joy_name = strdup(inst->tszProductName); #ifdef HAVE_WINXINPUT #if 0 is_xinput_pad = g_xinput_block_pads && name_is_xinput_pad(inst->tszProductName); #endif is_xinput_pad = g_xinput_block_pads && guid_is_xinput_device(&inst->guidProduct); if (is_xinput_pad) { if (g_last_xinput_pad_idx < 4) g_xinput_pad_indexes[g_joypad_cnt] = g_last_xinput_pad_idx++; goto enum_iteration_done; } #endif IDirectInputDevice8_SetDataFormat(*pad, &c_dfDIJoystick2); IDirectInputDevice8_SetCooperativeLevel(*pad, (HWND)driver.video_window, DISCL_NONEXCLUSIVE | DISCL_BACKGROUND); IDirectInputDevice8_EnumObjects(*pad, enum_axes_cb, *pad, DIDFT_ABSAXIS); #ifdef HAVE_WINXINPUT if (!is_xinput_pad) #endif { strlcpy(g_settings.input.device_names[g_joypad_cnt], dinput_joypad_name(g_joypad_cnt), sizeof(g_settings.input.device_names[g_joypad_cnt])); /* TODO - implement VID/PID? */ input_config_autoconfigure_joypad(g_joypad_cnt, dinput_joypad_name(g_joypad_cnt), 0, 0, dinput_joypad.ident); } enum_iteration_done: g_joypad_cnt++; return DIENUM_CONTINUE; }
static BOOL CALLBACK enum_joypad_cb(const DIDEVICEINSTANCE *inst, void *p) { #ifdef HAVE_XINPUT bool is_xinput_pad; #endif LPDIRECTINPUTDEVICE8 *pad = NULL; (void)p; if (g_joypad_cnt == MAX_USERS) return DIENUM_STOP; pad = &g_pads[g_joypad_cnt].joypad; #ifdef __cplusplus if (FAILED(IDirectInput8_CreateDevice( g_dinput_ctx, inst->guidInstance, pad, NULL))) #else if (FAILED(IDirectInput8_CreateDevice( g_dinput_ctx, &inst->guidInstance, pad, NULL))) #endif return DIENUM_CONTINUE; g_pads[g_joypad_cnt].joy_name = strdup((const char*)inst->tszProductName); g_pads[g_joypad_cnt].joy_friendly_name = strdup((const char*)inst->tszInstanceName); /* there may be more useful info in the GUID so leave this here for a while */ #if 0 printf("Guid = {%08lX-%04hX-%04hX-%02hhX%02hhX-%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX}\n", inst->guidProduct.Data1, inst->guidProduct.Data2, inst->guidProduct.Data3, inst->guidProduct.Data4[0], inst->guidProduct.Data4[1], inst->guidProduct.Data4[2], inst->guidProduct.Data4[3], inst->guidProduct.Data4[4], inst->guidProduct.Data4[5], inst->guidProduct.Data4[6], inst->guidProduct.Data4[7]); #endif g_pads[g_joypad_cnt].vid = inst->guidProduct.Data1 % 0x10000; g_pads[g_joypad_cnt].pid = inst->guidProduct.Data1 / 0x10000; RARCH_LOG("[DINPUT]: Device #%u PID: {%04lX} VID:{%04lX}\n", g_joypad_cnt, g_pads[g_joypad_cnt].pid, g_pads[g_joypad_cnt].vid); #ifdef HAVE_XINPUT is_xinput_pad = g_xinput_block_pads && guid_is_xinput_device(&inst->guidProduct); if (is_xinput_pad) { if (g_last_xinput_pad_idx < 4) g_xinput_pad_indexes[g_joypad_cnt] = g_last_xinput_pad_idx++; goto enum_iteration_done; } #endif IDirectInputDevice8_SetDataFormat(*pad, &c_dfDIJoystick2); IDirectInputDevice8_SetCooperativeLevel(*pad, (HWND)video_driver_window_get(), DISCL_EXCLUSIVE | DISCL_BACKGROUND); IDirectInputDevice8_EnumObjects(*pad, enum_axes_cb, *pad, DIDFT_ABSAXIS); dinput_create_rumble_effects(&g_pads[g_joypad_cnt]); #ifdef HAVE_XINPUT if (!is_xinput_pad) #endif { if (!input_autoconfigure_connect( dinput_joypad_name(g_joypad_cnt), dinput_joypad_friendly_name(g_joypad_cnt), dinput_joypad.ident, g_joypad_cnt, dinput_joypad_vid(g_joypad_cnt), dinput_joypad_pid(g_joypad_cnt))) input_config_set_device_name(g_joypad_cnt, dinput_joypad_name(g_joypad_cnt)); } #ifdef HAVE_XINPUT enum_iteration_done: #endif g_joypad_cnt++; return DIENUM_CONTINUE; }
static void *dinput_init(void) { struct dinput_input *di = NULL; settings_t *settings = config_get_ptr(); if (!dinput_init_context()) { RARCH_ERR("Failed to start DirectInput driver.\n"); return NULL; } di = (struct dinput_input*)calloc(1, sizeof(*di)); if (!di) return NULL; #ifdef __cplusplus if (FAILED(IDirectInput8_CreateDevice(g_dinput_ctx, GUID_SysKeyboard, &di->keyboard, NULL))) { RARCH_ERR("Failed to create keyboard device.\n"); di->keyboard = NULL; } if (FAILED(IDirectInput8_CreateDevice(g_dinput_ctx, GUID_SysMouse, &di->mouse, NULL))) { RARCH_ERR("Failed to create mouse device.\n"); di->mouse = NULL; } #else if (FAILED(IDirectInput8_CreateDevice(g_dinput_ctx, &GUID_SysKeyboard, &di->keyboard, NULL))) { RARCH_ERR("Failed to create keyboard device.\n"); di->keyboard = NULL; } if (FAILED(IDirectInput8_CreateDevice(g_dinput_ctx, &GUID_SysMouse, &di->mouse, NULL))) { RARCH_ERR("Failed to create mouse device.\n"); di->mouse = NULL; } #endif if (di->keyboard) { IDirectInputDevice8_SetDataFormat(di->keyboard, &c_dfDIKeyboard); IDirectInputDevice8_SetCooperativeLevel(di->keyboard, (HWND)video_driver_window_get(), DISCL_NONEXCLUSIVE | DISCL_FOREGROUND); IDirectInputDevice8_Acquire(di->keyboard); } if (di->mouse) { DIDATAFORMAT c_dfDIMouse2_custom = c_dfDIMouse2; c_dfDIMouse2_custom.dwFlags = DIDF_ABSAXIS; IDirectInputDevice8_SetDataFormat(di->mouse, &c_dfDIMouse2_custom); IDirectInputDevice8_SetCooperativeLevel(di->mouse, (HWND)video_driver_window_get(), DISCL_NONEXCLUSIVE | DISCL_FOREGROUND); IDirectInputDevice8_Acquire(di->mouse); } input_keymaps_init_keyboard_lut(rarch_key_map_dinput); di->joypad = input_joypad_init_driver(settings->input.joypad_driver, di); return di; }
static gboolean dx_dinput_setup_events (ControllerDXDInput *controller, GError **error) { HRESULT hresult; DIPROPDWORD dword; gint i, k; DXDInputSource *source; if ((controller->event = CreateEvent (NULL, TRUE, FALSE, NULL)) == NULL) { g_set_error (error, GIMP_MODULE_ERROR, GIMP_MODULE_FAILED, "CreateEvent failed: %s", g_win32_error_message (GetLastError ())); return FALSE; } controller->format = g_new (DIDATAFORMAT, 1); controller->format->dwSize = sizeof (DIDATAFORMAT); controller->format->dwObjSize = sizeof (DIOBJECTDATAFORMAT); dword.diph.dwSize = sizeof (DIPROPDWORD); dword.diph.dwHeaderSize = sizeof (DIPROPHEADER); dword.diph.dwObj = 0; dword.diph.dwHow = DIPH_DEVICE; /* Get the axis mode so we can use the same in the format */ if (FAILED ((hresult = IDirectInputDevice8_GetProperty (controller->didevice8, DIPROP_AXISMODE, &dword.diph)))) { g_set_error (error, GIMP_MODULE_ERROR, GIMP_MODULE_FAILED, "IDirectInputDevice8::GetParameters failed: %s", g_win32_error_message (hresult)); goto fail0; } controller->format->dwFlags = dword.dwData + 1; controller->format->dwNumObjs = controller->num_buttons + controller->num_axes + controller->num_sliders + controller->num_povs; controller->format->rgodf = g_new (DIOBJECTDATAFORMAT, controller->format->dwNumObjs); k = 0; controller->format->dwDataSize = 0; for (i = 0; i < controller->num_buttons; i++) { controller->format->rgodf[k].pguid = NULL; controller->format->rgodf[k].dwOfs = controller->format->dwDataSize; controller->format->rgodf[k].dwType = DIDFT_BUTTON | DIDFT_MAKEINSTANCE (i); controller->format->rgodf[k].dwFlags = 0; controller->format->dwDataSize += 1; k++; } controller->format->dwDataSize = 4*((controller->format->dwDataSize + 3)/4); for (i = 0; i < controller->num_axes; i++) { controller->format->rgodf[k].pguid = NULL; controller->format->rgodf[k].dwOfs = controller->format->dwDataSize; controller->format->rgodf[k].dwType = DIDFT_AXIS | DIDFT_MAKEINSTANCE (i); controller->format->rgodf[k].dwFlags = DIDOI_ASPECTPOSITION; controller->format->dwDataSize += 4; k++; } for (i = 0; i < controller->num_sliders; i++) { controller->format->rgodf[k].pguid = NULL; controller->format->rgodf[k].dwOfs = controller->format->dwDataSize; controller->format->rgodf[k].dwType = DIDFT_AXIS | DIDFT_MAKEINSTANCE (i); controller->format->rgodf[k].dwFlags = DIDOI_ASPECTPOSITION; controller->format->dwDataSize += 4; k++; } for (i = 0; i < controller->num_povs; i++) { controller->format->rgodf[k].pguid = NULL; controller->format->rgodf[k].dwOfs = controller->format->dwDataSize; controller->format->rgodf[k].dwType = DIDFT_POV | DIDFT_MAKEINSTANCE (i); controller->format->rgodf[k].dwFlags = 0; controller->format->dwDataSize += 4; k++; } g_assert (k == controller->format->dwNumObjs); controller->format->dwDataSize = 4*((controller->format->dwDataSize + 3)/4); controller->prevdata = g_malloc (controller->format->dwDataSize); dump_data_format (controller->format); if (FAILED ((hresult = IDirectInputDevice8_SetDataFormat (controller->didevice8, controller->format)))) { g_set_error (error, GIMP_MODULE_ERROR, GIMP_MODULE_FAILED, "IDirectInputDevice8::SetDataFormat failed: %s", g_win32_error_message (hresult)); goto fail1; } if (FAILED ((hresult = IDirectInputDevice8_SetEventNotification (controller->didevice8, controller->event)))) { g_set_error (error, GIMP_MODULE_ERROR, GIMP_MODULE_FAILED, "IDirectInputDevice8::SetEventNotification failed: %s", g_win32_error_message (hresult)); goto fail2; } if (FAILED ((hresult = IDirectInputDevice8_Acquire (controller->didevice8)))) { g_set_error (error, GIMP_MODULE_ERROR, GIMP_MODULE_FAILED, "IDirectInputDevice8::Acquire failed: %s", g_win32_error_message (hresult)); goto fail2; } if (FAILED ((hresult = IDirectInputDevice8_GetDeviceState (controller->didevice8, controller->format->dwDataSize, controller->prevdata)))) { g_set_error (error, GIMP_MODULE_ERROR, GIMP_MODULE_FAILED, "IDirectInputDevice8::GetDeviceState failed: %s", g_win32_error_message (hresult)); goto fail2; } source = (DXDInputSource *) g_source_new (&dx_dinput_event_funcs, sizeof (DXDInputSource)); source->controller = controller; controller->source = (GSource *) source; controller->pollfd = g_new (GPollFD, 1); controller->pollfd->fd = (int) controller->event; controller->pollfd->events = G_IO_IN; g_source_add_poll (&source->source, controller->pollfd); g_source_attach (&source->source, NULL); return TRUE; fail2: IDirectInputDevice8_SetEventNotification (controller->didevice8, NULL); fail1: g_free (controller->format->rgodf); g_free (controller->format); controller->format = NULL; g_free (controller->prevdata); controller->prevdata = NULL; fail0: CloseHandle (controller->event); controller->event = 0; return FALSE; }
int SDL_DINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickdevice) { HRESULT result; LPDIRECTINPUTDEVICE8 device; DIPROPDWORD dipdw; joystick->hwdata->buffered = SDL_TRUE; joystick->hwdata->Capabilities.dwSize = sizeof(DIDEVCAPS); SDL_zero(dipdw); dipdw.diph.dwSize = sizeof(DIPROPDWORD); dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); result = IDirectInput8_CreateDevice(dinput, &(joystickdevice->dxdevice.guidInstance), &device, NULL); if (FAILED(result)) { return SetDIerror("IDirectInput::CreateDevice", result); } /* Now get the IDirectInputDevice8 interface, instead. */ result = IDirectInputDevice8_QueryInterface(device, &IID_IDirectInputDevice8, (LPVOID *)& joystick-> hwdata->InputDevice); /* We are done with this object. Use the stored one from now on. */ IDirectInputDevice8_Release(device); if (FAILED(result)) { return SetDIerror("IDirectInputDevice8::QueryInterface", result); } /* Acquire shared access. Exclusive access is required for forces, * though. */ result = IDirectInputDevice8_SetCooperativeLevel(joystick->hwdata-> InputDevice, SDL_HelperWindow, DISCL_EXCLUSIVE | DISCL_BACKGROUND); if (FAILED(result)) { return SetDIerror("IDirectInputDevice8::SetCooperativeLevel", result); } /* Use the extended data structure: DIJOYSTATE2. */ result = IDirectInputDevice8_SetDataFormat(joystick->hwdata->InputDevice, &SDL_c_dfDIJoystick2); if (FAILED(result)) { return SetDIerror("IDirectInputDevice8::SetDataFormat", result); } /* Get device capabilities */ result = IDirectInputDevice8_GetCapabilities(joystick->hwdata->InputDevice, &joystick->hwdata->Capabilities); if (FAILED(result)) { return SetDIerror("IDirectInputDevice8::GetCapabilities", result); } /* Force capable? */ if (joystick->hwdata->Capabilities.dwFlags & DIDC_FORCEFEEDBACK) { result = IDirectInputDevice8_Acquire(joystick->hwdata->InputDevice); if (FAILED(result)) { return SetDIerror("IDirectInputDevice8::Acquire", result); } /* reset all actuators. */ result = IDirectInputDevice8_SendForceFeedbackCommand(joystick->hwdata-> InputDevice, DISFFC_RESET); /* Not necessarily supported, ignore if not supported. if (FAILED(result)) { return SetDIerror("IDirectInputDevice8::SendForceFeedbackCommand", result); } */ result = IDirectInputDevice8_Unacquire(joystick->hwdata->InputDevice); if (FAILED(result)) { return SetDIerror("IDirectInputDevice8::Unacquire", result); } /* Turn on auto-centering for a ForceFeedback device (until told * otherwise). */ dipdw.diph.dwObj = 0; dipdw.diph.dwHow = DIPH_DEVICE; dipdw.dwData = DIPROPAUTOCENTER_ON; result = IDirectInputDevice8_SetProperty(joystick->hwdata->InputDevice, DIPROP_AUTOCENTER, &dipdw.diph); /* Not necessarily supported, ignore if not supported. if (FAILED(result)) { return SetDIerror("IDirectInputDevice8::SetProperty", result); } */ } /* What buttons and axes does it have? */ IDirectInputDevice8_EnumObjects(joystick->hwdata->InputDevice, EnumDevObjectsCallback, joystick, DIDFT_BUTTON | DIDFT_AXIS | DIDFT_POV); /* Reorder the input objects. Some devices do not report the X axis as * the first axis, for example. */ SortDevObjects(joystick); dipdw.diph.dwObj = 0; dipdw.diph.dwHow = DIPH_DEVICE; dipdw.dwData = INPUT_QSIZE; /* Set the buffer size */ result = IDirectInputDevice8_SetProperty(joystick->hwdata->InputDevice, DIPROP_BUFFERSIZE, &dipdw.diph); if (result == DI_POLLEDDEVICE) { /* This device doesn't support buffering, so we're forced * to use less reliable polling. */ joystick->hwdata->buffered = SDL_FALSE; } else if (FAILED(result)) { return SetDIerror("IDirectInputDevice8::SetProperty", result); } return 0; }