void PollXInputButtons(u32 pad, XINPUT_STATE *state) { int i; // Check buttons for ( i = 0; i < 16; i++ ) { WORD mask = 1 << i; if ( (state->Gamepad.wButtons & mask) == mask ) DX_PerKeyDown( pad, 0, DIJOFS_BUTTON(i) ); else DX_PerKeyUp( pad, 0, DIJOFS_BUTTON(i) ); } }
int CL_InputDeviceProvider_DirectInput::get_button_count() const { throw_if_disposed(); int count=0; for ( int x = 0; x < 32; x++ ) { count += check_axis(DIJOFS_BUTTON( x )); } return count; }
/* * Converts an SDL trigger button to an DIEFFECT trigger button. */ static DWORD DIGetTriggerButton(Uint16 button) { DWORD dwTriggerButton; dwTriggerButton = DIEB_NOTRIGGER; if (button != 0) { dwTriggerButton = DIJOFS_BUTTON(button - 1); } return dwTriggerButton; }
static BOOL CALLBACK DIJoystick_EnumDevObjectsProc(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID data) { DIDevice *device = (DIDevice *) data; HRESULT hr; input_t in; const int SupportedMask = DIDFT_BUTTON | DIDFT_POV | DIDFT_AXIS; if(!(dev->dwType & SupportedMask)) return DIENUM_CONTINUE; // unsupported if(dev->dwType & DIDFT_BUTTON) { if( device->buttons == 24 ) return DIENUM_CONTINUE; // too many buttons in.ofs = DIJOFS_BUTTON(device->buttons); in.type = in.BUTTON; in.num = device->buttons; } else if(dev->dwType & DIDFT_POV) { in.ofs = DIJOFS_POV(device->hats); in.type = in.HAT; in.num = device->hats; } else { // dev->dwType & DIDFT_AXIS DIPROPRANGE diprg; DIPROPDWORD dilong; // Figure out which axis we're looking at and store the correct DIJOFS_* value. if( dev->guidType == GUID_XAxis ) { in.ofs = DIJOFS_X; } else if( dev->guidType == GUID_YAxis ) { in.ofs = DIJOFS_Y; } else if( dev->guidType == GUID_ZAxis ) { in.ofs = DIJOFS_Z; } else if( dev->guidType == GUID_RxAxis ) { in.ofs = DIJOFS_RX; } else if( dev->guidType == GUID_RyAxis ) { in.ofs = DIJOFS_RY; } else if( dev->guidType == GUID_RzAxis ) { in.ofs = DIJOFS_RZ; } else { // No idea what this is so ignore it. return DIENUM_CONTINUE; } in.type = in.AXIS; in.num = device->axes; diprg.diph.dwSize = sizeof(diprg); diprg.diph.dwHeaderSize = sizeof(diprg.diph); diprg.diph.dwObj = dev->dwType; diprg.diph.dwHow = DIPH_BYID; diprg.lMin = -100; diprg.lMax = 100; hr = device->Device->SetProperty( DIPROP_RANGE, &diprg.diph ); if ( hr != DI_OK ) return DIENUM_CONTINUE; // don't use this axis // Set dead zone to 0. dilong.diph.dwSize = sizeof(dilong); dilong.diph.dwHeaderSize = sizeof(dilong.diph); dilong.diph.dwObj = dev->dwType; dilong.diph.dwHow = DIPH_BYID; dilong.dwData = 0; hr = device->Device->SetProperty( DIPROP_DEADZONE, &dilong.diph ); if ( hr != DI_OK ) return DIENUM_CONTINUE; // don't use this axis } /* For some devices it's possible to find multiple objects of the same type. When trying to * figure out which device caused an event it doesn't matter which one it finds so there's * no need to include a duplicate if one has already been added. */ if( std::find_if( device->Inputs.begin(), device->Inputs.end(), input_t::Compare( in.ofs ) ) == device->Inputs.end() ) { device->Inputs.push_back(in); // Increment the number of buttons/axes/hats only after it has been added. switch ( in.type ) { case input_t::BUTTON: ++device->buttons; break; case input_t::AXIS: ++device->axes; break; case input_t::HAT: ++device->hats; break; } } return DIENUM_CONTINUE; }
#define numObjects(x) (sizeof(x) / sizeof(x[0])) typedef struct tagUserData { IDirectInputA *pDI; DWORD version; } UserData; static const DIOBJECTDATAFORMAT dfDIJoystickTest[] = { { &GUID_XAxis,DIJOFS_X,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, { &GUID_YAxis,DIJOFS_Y,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, { &GUID_ZAxis,DIJOFS_Z,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, { &GUID_RxAxis,DIJOFS_RX,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, { &GUID_RyAxis,DIJOFS_RY,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, { &GUID_RzAxis,DIJOFS_RZ,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, { &GUID_Button,DIJOFS_BUTTON(0),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, { &GUID_Button,DIJOFS_BUTTON(1),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, { &GUID_Button,DIJOFS_BUTTON(2),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, { &GUID_Button,DIJOFS_BUTTON(3),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, { &GUID_Button,DIJOFS_BUTTON(4),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, { &GUID_Button,DIJOFS_BUTTON(5),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, { &GUID_Button,DIJOFS_BUTTON(6),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, { &GUID_Button,DIJOFS_BUTTON(7),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, { &GUID_Button,DIJOFS_BUTTON(8),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, { &GUID_Button,DIJOFS_BUTTON(9),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, { &GUID_Button,DIJOFS_BUTTON(10),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, }; static const DIDATAFORMAT c_dfDIJoystickTest = { sizeof(DIDATAFORMAT), sizeof(DIOBJECTDATAFORMAT),
#define numObjects(x) (sizeof(x) / sizeof(x[0])) static const DIOBJECTDATAFORMAT dfDIJoystick[] = { { &GUID_XAxis,DIJOFS_X,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, { &GUID_YAxis,DIJOFS_Y,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, { &GUID_ZAxis,DIJOFS_Z,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, { &GUID_RxAxis,DIJOFS_RX,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, { &GUID_RyAxis,DIJOFS_RY,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, { &GUID_RzAxis,DIJOFS_RZ,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, { &GUID_Slider,DIJOFS_SLIDER(0),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, { &GUID_Slider,DIJOFS_SLIDER(1),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, { &GUID_POV,DIJOFS_POV(0),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0}, { &GUID_POV,DIJOFS_POV(1),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0}, { &GUID_POV,DIJOFS_POV(2),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0}, { &GUID_POV,DIJOFS_POV(3),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0}, { NULL,DIJOFS_BUTTON(0),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, { NULL,DIJOFS_BUTTON(1),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, { NULL,DIJOFS_BUTTON(2),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, { NULL,DIJOFS_BUTTON(3),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, { NULL,DIJOFS_BUTTON(4),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, { NULL,DIJOFS_BUTTON(5),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, { NULL,DIJOFS_BUTTON(6),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, { NULL,DIJOFS_BUTTON(7),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, { NULL,DIJOFS_BUTTON(8),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, { NULL,DIJOFS_BUTTON(9),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, { NULL,DIJOFS_BUTTON(10),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, { NULL,DIJOFS_BUTTON(11),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, { NULL,DIJOFS_BUTTON(12),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, { NULL,DIJOFS_BUTTON(13),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, { NULL,DIJOFS_BUTTON(14),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, { NULL,DIJOFS_BUTTON(15),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
/* update_joystick: [joystick thread] * Reads in data for a single DirectInput joystick device, updates * the internal ALLEGRO_JOYSTICK_STATE structure, and generates any Allegro * events required. */ static void update_joystick(ALLEGRO_JOYSTICK_DIRECTX *joy) { DIDEVICEOBJECTDATA buffer[DEVICE_BUFFER_SIZE]; DWORD num_items = DEVICE_BUFFER_SIZE; HRESULT hr; ALLEGRO_EVENT_SOURCE *es = al_get_joystick_event_source(); /* some devices require polling */ IDirectInputDevice8_Poll(joy->device); /* get device data into buffer */ hr = IDirectInputDevice8_GetDeviceData(joy->device, sizeof(DIDEVICEOBJECTDATA), buffer, &num_items, 0); if (hr != DI_OK && hr != DI_BUFFEROVERFLOW) { if ((hr == DIERR_NOTACQUIRED) || (hr == DIERR_INPUTLOST)) { ALLEGRO_WARN("joystick device not acquired or lost\n"); } else { ALLEGRO_ERROR("unexpected error while polling the joystick\n"); } return; } /* don't bother locking the event source if there's no work to do */ /* this happens a lot for polled devices */ if (num_items == 0) return; _al_event_source_lock(es); { unsigned int i; for (i = 0; i < num_items; i++) { const DIDEVICEOBJECTDATA *item = &buffer[i]; const int dwOfs = item->dwOfs; const DWORD dwData = item->dwData; switch (dwOfs) { case DIJOFS_X: handle_axis_event(joy, &joy->x_mapping, dwData); break; case DIJOFS_Y: handle_axis_event(joy, &joy->y_mapping, dwData); break; case DIJOFS_Z: handle_axis_event(joy, &joy->z_mapping, dwData); break; case DIJOFS_RX: handle_axis_event(joy, &joy->rx_mapping, dwData); break; case DIJOFS_RY: handle_axis_event(joy, &joy->ry_mapping, dwData); break; case DIJOFS_RZ: handle_axis_event(joy, &joy->rz_mapping, dwData); break; case DIJOFS_SLIDER(0): handle_axis_event(joy, &joy->slider_mapping[0], dwData); break; case DIJOFS_SLIDER(1): handle_axis_event(joy, &joy->slider_mapping[1], dwData); break; case DIJOFS_POV(0): handle_pov_event(joy, joy->pov_mapping_stick[0], dwData); break; case DIJOFS_POV(1): handle_pov_event(joy, joy->pov_mapping_stick[1], dwData); break; case DIJOFS_POV(2): handle_pov_event(joy, joy->pov_mapping_stick[2], dwData); break; case DIJOFS_POV(3): handle_pov_event(joy, joy->pov_mapping_stick[3], dwData); break; default: /* buttons */ if ((dwOfs >= DIJOFS_BUTTON0) && (dwOfs < DIJOFS_BUTTON(joy->parent.info.num_buttons))) { int num = (dwOfs - DIJOFS_BUTTON0) / (DIJOFS_BUTTON1 - DIJOFS_BUTTON0); handle_button_event(joy, num, (dwData & 0x80)); } break; } } } _al_event_source_unlock(es); }
#define DIDFT_OPTIONAL 0x80000000 static const DIOBJECTDATAFORMAT __al_dfDIJoystick[] = { { &__al_GUID_XAxis, DIJOFS_X, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0}, { &__al_GUID_YAxis, DIJOFS_Y, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0}, { &__al_GUID_ZAxis, DIJOFS_Z, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0}, { &__al_GUID_RxAxis, DIJOFS_RX, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0}, { &__al_GUID_RyAxis, DIJOFS_RY, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0}, { &__al_GUID_RzAxis, DIJOFS_RZ, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0}, { &__al_GUID_Slider, DIJOFS_SLIDER(0), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0}, { &__al_GUID_Slider, DIJOFS_SLIDER(1), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0}, { &__al_GUID_POV, DIJOFS_POV(0), DIDFT_OPTIONAL | DIDFT_POV | DIDFT_ANYINSTANCE, 0}, { &__al_GUID_POV, DIJOFS_POV(1), DIDFT_OPTIONAL | DIDFT_POV | DIDFT_ANYINSTANCE, 0}, { &__al_GUID_POV, DIJOFS_POV(2), DIDFT_OPTIONAL | DIDFT_POV | DIDFT_ANYINSTANCE, 0}, { &__al_GUID_POV, DIJOFS_POV(3), DIDFT_OPTIONAL | DIDFT_POV | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(0), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(1), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(2), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(3), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(4), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(5), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(6), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(7), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(8), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(9), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(10), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(11), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(12), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(13), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(14), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(15), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0},
static BOOL CALLBACK EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID pvRef) { SDL_Joystick *joystick = (SDL_Joystick *)pvRef; HRESULT result; input_t *in = &joystick->hwdata->Inputs[joystick->hwdata->NumInputs]; if (dev->dwType & DIDFT_BUTTON) { in->type = BUTTON; in->num = joystick->nbuttons; in->ofs = DIJOFS_BUTTON(in->num); joystick->nbuttons++; } else if (dev->dwType & DIDFT_POV) { in->type = HAT; in->num = joystick->nhats; in->ofs = DIJOFS_POV(in->num); joystick->nhats++; } else if (dev->dwType & DIDFT_AXIS) { DIPROPRANGE diprg; DIPROPDWORD dilong; in->type = AXIS; in->num = joystick->naxes; if (!SDL_memcmp(&dev->guidType, &GUID_XAxis, sizeof(dev->guidType))) in->ofs = DIJOFS_X; else if (!SDL_memcmp(&dev->guidType, &GUID_YAxis, sizeof(dev->guidType))) in->ofs = DIJOFS_Y; else if (!SDL_memcmp(&dev->guidType, &GUID_ZAxis, sizeof(dev->guidType))) in->ofs = DIJOFS_Z; else if (!SDL_memcmp(&dev->guidType, &GUID_RxAxis, sizeof(dev->guidType))) in->ofs = DIJOFS_RX; else if (!SDL_memcmp(&dev->guidType, &GUID_RyAxis, sizeof(dev->guidType))) in->ofs = DIJOFS_RY; else if (!SDL_memcmp(&dev->guidType, &GUID_RzAxis, sizeof(dev->guidType))) in->ofs = DIJOFS_RZ; else if (!SDL_memcmp(&dev->guidType, &GUID_Slider, sizeof(dev->guidType))) { in->ofs = DIJOFS_SLIDER(joystick->hwdata->NumSliders); ++joystick->hwdata->NumSliders; } else { return DIENUM_CONTINUE; /* not an axis we can grok */ } diprg.diph.dwSize = sizeof(diprg); diprg.diph.dwHeaderSize = sizeof(diprg.diph); diprg.diph.dwObj = dev->dwType; diprg.diph.dwHow = DIPH_BYID; diprg.lMin = SDL_JOYSTICK_AXIS_MIN; diprg.lMax = SDL_JOYSTICK_AXIS_MAX; result = IDirectInputDevice8_SetProperty(joystick->hwdata->InputDevice, DIPROP_RANGE, &diprg.diph); if (FAILED(result)) { return DIENUM_CONTINUE; /* don't use this axis */ } /* Set dead zone to 0. */ dilong.diph.dwSize = sizeof(dilong); dilong.diph.dwHeaderSize = sizeof(dilong.diph); dilong.diph.dwObj = dev->dwType; dilong.diph.dwHow = DIPH_BYID; dilong.dwData = 0; result = IDirectInputDevice8_SetProperty(joystick->hwdata->InputDevice, DIPROP_DEADZONE, &dilong.diph); if (FAILED(result)) { return DIENUM_CONTINUE; /* don't use this axis */ } joystick->naxes++; } else { /* not supported at this time */ return DIENUM_CONTINUE; } joystick->hwdata->NumInputs++; if (joystick->hwdata->NumInputs == MAX_INPUTS) { return DIENUM_STOP; /* too many */ } return DIENUM_CONTINUE; }
static HRESULT WINAPI LinuxInputEffectImpl_GetParameters( LPDIRECTINPUTEFFECT iface, LPDIEFFECT peff, DWORD dwFlags) { HRESULT diErr = DI_OK; LinuxInputEffectImpl *This = impl_from_IDirectInputEffect(iface); TRACE("(this=%p,%p,%d)\n", This, peff, dwFlags); /* Major conversion factors are: * times: millisecond (linux) -> microsecond (windows) (x * 1000) * forces: scale 0x7FFF (linux) -> scale 10000 (windows) approx ((x / 33) * 10) * angles: scale 0x7FFF (linux) -> scale 35999 (windows) approx ((x / 33) * 36) * angle bases: 0 -> -y (down) (linux) -> 0 -> +x (right) (windows) */ if (dwFlags & DIEP_AXES) { if (peff->cAxes < 2 /* linuxinput effects always use 2 axes, x and y */) diErr = DIERR_MOREDATA; peff->cAxes = 2; if (diErr) return diErr; else { peff->rgdwAxes[0] = DIJOFS_X; peff->rgdwAxes[1] = DIJOFS_Y; } } if (dwFlags & DIEP_DIRECTION) { if (peff->cAxes < 2) diErr = DIERR_MOREDATA; peff->cAxes = 2; if (diErr) return diErr; else { if (peff->dwFlags & DIEFF_CARTESIAN) { peff->rglDirection[0] = sin(M_PI * 3 * This->effect.direction / 0x7FFF) * 1000; peff->rglDirection[1] = cos(M_PI * 3 * This->effect.direction / 0x7FFF) * 1000; } else { /* Polar and spherical coordinates are the same for two or less * axes. * Note that we also use this case if NO flags are marked. * According to MSDN, we should return the direction in the * format that it was specified in, if no flags are marked. */ peff->rglDirection[0] = (This->effect.direction / 33) * 36 + 9000; if (peff->rglDirection[0] > 35999) peff->rglDirection[0] -= 35999; } } } if (dwFlags & DIEP_DURATION) { peff->dwDuration = (DWORD)This->effect.replay.length * 1000; } if (dwFlags & DIEP_ENVELOPE) { struct ff_envelope* env; if (This->effect.type == FF_CONSTANT) env = &This->effect.u.constant.envelope; else if (This->effect.type == FF_PERIODIC) env = &This->effect.u.periodic.envelope; else if (This->effect.type == FF_RAMP) env = &This->effect.u.ramp.envelope; else env = NULL; if (env == NULL) { peff->lpEnvelope = NULL; } else if (peff->lpEnvelope == NULL) { return DIERR_INVALIDPARAM; } else { peff->lpEnvelope->dwAttackLevel = (env->attack_level / 33) * 10; peff->lpEnvelope->dwAttackTime = env->attack_length * 1000; peff->lpEnvelope->dwFadeLevel = (env->fade_level / 33) * 10; peff->lpEnvelope->dwFadeTime = env->fade_length * 1000; } } if (dwFlags & DIEP_GAIN) { peff->dwGain = This->gain * 10000 / 0xFFFF; } if (dwFlags & DIEP_SAMPLEPERIOD) { /* the linux input ff driver has no support for setting * the playback sample period. 0 means default. */ peff->dwSamplePeriod = 0; } if (dwFlags & DIEP_STARTDELAY) { peff->dwStartDelay = This->effect.replay.delay * 1000; } if (dwFlags & DIEP_TRIGGERBUTTON) { FIXME("LinuxInput button mapping needs redoing; for now, assuming we're using an actual joystick.\n"); peff->dwTriggerButton = DIJOFS_BUTTON(This->effect.trigger.button - BTN_JOYSTICK); } if (dwFlags & DIEP_TRIGGERREPEATINTERVAL) { peff->dwTriggerRepeatInterval = This->effect.trigger.interval * 1000; } if (dwFlags & DIEP_TYPESPECIFICPARAMS) { DWORD expectedsize = 0; if (This->effect.type == FF_PERIODIC) { expectedsize = sizeof(DIPERIODIC); } else if (This->effect.type == FF_CONSTANT) { expectedsize = sizeof(DICONSTANTFORCE); } else if (This->effect.type == FF_SPRING || This->effect.type == FF_FRICTION || This->effect.type == FF_INERTIA || This->effect.type == FF_DAMPER) { expectedsize = sizeof(DICONDITION) * 2; } else if (This->effect.type == FF_RAMP) { expectedsize = sizeof(DIRAMPFORCE); } if (expectedsize > peff->cbTypeSpecificParams) diErr = DIERR_MOREDATA; peff->cbTypeSpecificParams = expectedsize; if (diErr) return diErr; else { if (This->effect.type == FF_PERIODIC) { LPDIPERIODIC tsp = peff->lpvTypeSpecificParams; tsp->dwMagnitude = (This->effect.u.periodic.magnitude / 33) * 10; tsp->lOffset = (This->effect.u.periodic.offset / 33) * 10; tsp->dwPhase = (This->effect.u.periodic.phase / 33) * 36; tsp->dwPeriod = (This->effect.u.periodic.period * 1000); } else if (This->effect.type == FF_CONSTANT) { LPDICONSTANTFORCE tsp = peff->lpvTypeSpecificParams; tsp->lMagnitude = (This->effect.u.constant.level / 33) * 10; } else if (This->effect.type == FF_SPRING || This->effect.type == FF_FRICTION || This->effect.type == FF_INERTIA || This->effect.type == FF_DAMPER) { LPDICONDITION tsp = peff->lpvTypeSpecificParams; int i; for (i = 0; i < 2; ++i) { tsp[i].lOffset = (This->effect.u.condition[i].center / 33) * 10; tsp[i].lPositiveCoefficient = (This->effect.u.condition[i].right_coeff / 33) * 10; tsp[i].lNegativeCoefficient = (This->effect.u.condition[i].left_coeff / 33) * 10; tsp[i].dwPositiveSaturation = (This->effect.u.condition[i].right_saturation / 33) * 10; tsp[i].dwNegativeSaturation = (This->effect.u.condition[i].left_saturation / 33) * 10; tsp[i].lDeadBand = (This->effect.u.condition[i].deadband / 33) * 10; } } else if (This->effect.type == FF_RAMP) { LPDIRAMPFORCE tsp = peff->lpvTypeSpecificParams; tsp->lStart = (This->effect.u.ramp.start_level / 33) * 10; tsp->lEnd = (This->effect.u.ramp.end_level / 33) * 10; } } } return diErr; }
int PERDXFetchNextPress(HWND hWnd, u32 guidnum, char *buttonname) { LPDIRECTINPUT8 lpDI8temp = NULL; LPDIRECTINPUTDEVICE8 lpDIDevicetemp; DIDEVCAPS didc; int buttonid=-1; if (FAILED(DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, &IID_IDirectInput8, (LPVOID *)&lpDI8temp, NULL))) return -1; if (FAILED(IDirectInput8_CreateDevice(lpDI8temp, &GUIDDevice[guidnum], &lpDIDevicetemp, NULL))) { IDirectInput8_Release(lpDI8temp); return -1; } didc.dwSize = sizeof(DIDEVCAPS); if (FAILED(IDirectInputDevice8_GetCapabilities(lpDIDevicetemp, &didc))) { IDirectInputDevice8_Release(lpDIDevicetemp); IDirectInput8_Release(lpDI8temp); return -1; } if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_KEYBOARD) { if (FAILED(IDirectInputDevice8_SetDataFormat(lpDIDevicetemp, &c_dfDIKeyboard))) { IDirectInputDevice8_Release(lpDIDevicetemp); IDirectInput8_Release(lpDI8temp); return -1; } } else if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_GAMEPAD || GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_JOYSTICK) { if (FAILED(IDirectInputDevice8_SetDataFormat(lpDIDevicetemp, &c_dfDIJoystick))) { IDirectInputDevice8_Release(lpDIDevicetemp); IDirectInput8_Release(lpDI8temp); return -1; } } else if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_MOUSE) { if (FAILED(IDirectInputDevice8_SetDataFormat(lpDIDevicetemp, &c_dfDIMouse2))) { IDirectInputDevice8_Release(lpDIDevicetemp); IDirectInput8_Release(lpDI8temp); return -1; } } if (DialogBoxParam(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_BUTTONCONFIG), hWnd, (DLGPROC)ButtonConfigDlgProc, (LPARAM)lpDIDevicetemp) == TRUE) { // Figure out what kind of code to generate if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_KEYBOARD) { memset(buttonname, 0, MAX_PATH); buttonid = nextpress.dwOfs; // This fixes some strange inconsistencies if (buttonid == DIK_PAUSE) buttonid = DIK_NUMLOCK; else if (buttonid == DIK_NUMLOCK) buttonid = DIK_PAUSE; if (buttonid & 0x80) buttonid += 0x80; GetKeyNameTextA(buttonid << 16, buttonname, MAX_PATH); buttonid = nextpress.dwOfs; } else if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_GAMEPAD || GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_JOYSTICK) { if (nextpress.dwOfs == DIJOFS_X) { if (nextpress.dwData <= 0x8000) { sprintf(buttonname, "Axis Left"); buttonid = 0x00; } else { sprintf(buttonname, "Axis Right"); buttonid = 0x01; } } else if (nextpress.dwOfs == DIJOFS_Y) { if (nextpress.dwData <= 0x8000) { sprintf(buttonname, "Axis Up"); buttonid = 0x02; } else { sprintf(buttonname, "Axis Down"); buttonid = 0x03; } } else if (nextpress.dwOfs == DIJOFS_POV(0)) { if (nextpress.dwData < 9000) { sprintf(buttonname, "POV Up"); buttonid = 0x04; } else if (nextpress.dwData < 18000) { sprintf(buttonname, "POV Right"); buttonid = 0x05; } else if (nextpress.dwData < 27000) { sprintf(buttonname, "POV Down"); buttonid = 0x06; } else { sprintf(buttonname, "POV Left"); buttonid = 0x07; } } else if (nextpress.dwOfs >= DIJOFS_BUTTON(0) && nextpress.dwOfs <= DIJOFS_BUTTON(127)) { sprintf(buttonname, "Button %d", (int)(nextpress.dwOfs - 0x2F)); buttonid = nextpress.dwOfs; } } else if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_MOUSE) { buttonid = nextpress.dwOfs-DIMOFS_BUTTON0; sprintf(buttonname, "Button %d", buttonid+1); } } IDirectInputDevice8_Unacquire(lpDIDevicetemp); IDirectInputDevice8_Release(lpDIDevicetemp); IDirectInput8_Release(lpDI8temp); return buttonid; }
void PollKeys(void) { u32 i; DWORD i2; DWORD size=8; DIDEVICEOBJECTDATA didod[8]; HRESULT hr; for (i = 0; i < numpads; i++) { if (paddevice[i].lpDIDevice == NULL) continue; hr = IDirectInputDevice8_Poll(paddevice[i].lpDIDevice); if (FAILED(hr)) { if (hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED) { // Make sure device is acquired while(IDirectInputDevice8_Acquire(paddevice[i].lpDIDevice) == DIERR_INPUTLOST) {} continue; } } size = 8; // Poll events if (FAILED(IDirectInputDevice8_GetDeviceData(paddevice[i].lpDIDevice, sizeof(DIDEVICEOBJECTDATA), didod, &size, 0))) { if (hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED) { // Make sure device is acquired while(IDirectInputDevice8_Acquire(paddevice[i].lpDIDevice) == DIERR_INPUTLOST) {} continue; } } if (size == 0) continue; switch (paddevice[i].type) { case TYPE_KEYBOARD: // This probably could be optimized for (i2 = 0; i2 < size; i2++) { if (didod[i2].dwData & 0x80) PerKeyDown(didod[i2].dwOfs); else PerKeyUp(didod[i2].dwOfs); } break; case TYPE_JOYSTICK: { // This probably could be optimized for (i2 = 0; i2 < size; i2++) { // X Axis if (didod[i2].dwOfs == DIJOFS_X) { if (didod[i2].dwData < 0x3FFF) { PerKeyDown(PAD_DIR_AXISLEFT); PerKeyUp(PAD_DIR_AXISRIGHT); } else if (didod[i2].dwData > 0xBFFF) { PerKeyDown(PAD_DIR_AXISRIGHT); PerKeyUp(PAD_DIR_AXISLEFT); } else { PerKeyUp(PAD_DIR_AXISLEFT); PerKeyUp(PAD_DIR_AXISRIGHT); } } // Y Axis else if (didod[i2].dwOfs == DIJOFS_Y) { if (didod[i2].dwData < 0x3FFF) { PerKeyDown(PAD_DIR_AXISUP); PerKeyUp(PAD_DIR_AXISDOWN); } else if (didod[i2].dwData > 0xBFFF) { PerKeyDown(PAD_DIR_AXISDOWN); PerKeyUp(PAD_DIR_AXISUP); } else { PerKeyUp(PAD_DIR_AXISUP); PerKeyUp(PAD_DIR_AXISDOWN); } } else if (didod[i2].dwOfs == DIJOFS_POV(0)) { // POV Center if (LOWORD(didod[i2].dwData) == 0xFFFF) { PerKeyUp(PAD_DIR_POVUP); PerKeyUp(PAD_DIR_POVRIGHT); PerKeyUp(PAD_DIR_POVDOWN); PerKeyUp(PAD_DIR_POVLEFT); } // POV Up else if (didod[i2].dwData < 4500) { PerKeyDown(PAD_DIR_POVUP); PerKeyUp(PAD_DIR_POVRIGHT); PerKeyUp(PAD_DIR_POVLEFT); } // POV Up-right else if (didod[i2].dwData < 9000) { PerKeyDown(PAD_DIR_POVUP); PerKeyDown(PAD_DIR_POVRIGHT); } // POV Right else if (didod[i2].dwData < 13500) { PerKeyDown(PAD_DIR_POVRIGHT); PerKeyUp(PAD_DIR_POVDOWN); PerKeyUp(PAD_DIR_POVUP); } // POV Right-down else if (didod[i2].dwData < 18000) { PerKeyDown(PAD_DIR_POVRIGHT); PerKeyDown(PAD_DIR_POVDOWN); } // POV Down else if (didod[i2].dwData < 22500) { PerKeyDown(PAD_DIR_POVDOWN); PerKeyUp(PAD_DIR_POVLEFT); PerKeyUp(PAD_DIR_POVRIGHT); } // POV Down-left else if (didod[i2].dwData < 27000) { PerKeyDown(PAD_DIR_POVDOWN); PerKeyDown(PAD_DIR_POVLEFT); } // POV Left else if (didod[i2].dwData < 31500) { PerKeyDown(PAD_DIR_POVLEFT); PerKeyUp(PAD_DIR_POVUP); PerKeyUp(PAD_DIR_POVDOWN); } // POV Left-up else if (didod[i2].dwData < 36000) { PerKeyDown(PAD_DIR_POVLEFT); PerKeyDown(PAD_DIR_POVUP); } } else if (didod[i2].dwOfs >= DIJOFS_BUTTON(0) && didod[i2].dwOfs <= DIJOFS_BUTTON(127)) { if (didod[i2].dwData & 0x80) PerKeyDown(didod[i2].dwOfs); else PerKeyUp(didod[i2].dwOfs); } } break; } case TYPE_MOUSE: for (i2 = 0; i2 < size; i2++) { if (didod[i2].dwOfs == DIMOFS_X) // X Axis PerMouseMove((PerMouse_struct *)pad[i], (s32)didod[i2].dwData, 0); else if (didod[i2].dwOfs == DIMOFS_Y) // Y Axis PerMouseMove((PerMouse_struct *)pad[i], 0, 0-(s32)didod[i2].dwData); else if (didod[i2].dwOfs >= DIMOFS_BUTTON0 && didod[i2].dwOfs <= DIMOFS_BUTTON7) { // Mouse Buttons if (didod[i2].dwData & 0x80) PerKeyDown(didod[i2].dwOfs-DIMOFS_BUTTON0); else PerKeyUp(didod[i2].dwOfs-DIMOFS_BUTTON0); } } break; default: break; } } }