int CL_InputDeviceProvider_DirectInput::get_axis_count() const { throw_if_disposed(); int count=0; // Struct DIJOYSTATE contains maximums count += check_axis(DIJOFS_SLIDER(0)); count += check_axis(DIJOFS_SLIDER(1)); // Should the hat be classified as an axis? count += check_axis(DIJOFS_POV(0)); count += check_axis(DIJOFS_POV(1)); count += check_axis(DIJOFS_POV(2)); count += check_axis(DIJOFS_POV(3)); count += check_axis(DIJOFS_RX); count += check_axis(DIJOFS_RY); count += check_axis(DIJOFS_RZ); count += check_axis(DIJOFS_X); count += check_axis(DIJOFS_Y); count += check_axis(DIJOFS_Z); return count; }
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; }
#include "windef.h" #include "dinput.h" #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},
/* 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); }
/* Function to update the state of a joystick - called as a device poll. * This function shouldn't update the joystick structure directly, * but instead should call SDL_PrivateJoystick*() to deliver events * and update joystick device state. */ static void UpdateDINPUTJoystickState_Polled(SDL_Joystick * joystick) { DIJOYSTATE2 state; HRESULT result; int i; result = IDirectInputDevice8_GetDeviceState(joystick->hwdata->InputDevice, sizeof(DIJOYSTATE2), &state); if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) { IDirectInputDevice8_Acquire(joystick->hwdata->InputDevice); result = IDirectInputDevice8_GetDeviceState(joystick->hwdata->InputDevice, sizeof(DIJOYSTATE2), &state); } if (result != DI_OK) { joystick->hwdata->send_remove_event = SDL_TRUE; joystick->hwdata->removed = SDL_TRUE; return; } /* Set each known axis, button and POV. */ for (i = 0; i < joystick->hwdata->NumInputs; ++i) { const input_t *in = &joystick->hwdata->Inputs[i]; switch (in->type) { case AXIS: switch (in->ofs) { case DIJOFS_X: SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)state.lX); break; case DIJOFS_Y: SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)state.lY); break; case DIJOFS_Z: SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)state.lZ); break; case DIJOFS_RX: SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)state.lRx); break; case DIJOFS_RY: SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)state.lRy); break; case DIJOFS_RZ: SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)state.lRz); break; case DIJOFS_SLIDER(0): SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)state.rglSlider[0]); break; case DIJOFS_SLIDER(1): SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)state.rglSlider[1]); break; } break; case BUTTON: SDL_PrivateJoystickButton(joystick, in->num, (Uint8)(state.rgbButtons[in->ofs - DIJOFS_BUTTON0] ? SDL_PRESSED : SDL_RELEASED)); break; case HAT: { Uint8 pos = TranslatePOV(state.rgdwPOV[in->ofs - DIJOFS_POV(0)]); SDL_PrivateJoystickHat(joystick, in->num, pos); break; } } } }
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; }
/* * Set default inputdevice config for SDL joysticks */ int32_t input_get_default_joystick (struct uae_input_device *uid, int32_t num, int32_t port, int32_t af, int32_t mode, bool gp, bool joymouseswap) { int32_t h,v; // uint32_t j; // struct didata *did; SDL_Joystick *joy; joy = joys[num].joy; if (num >= get_joystick_num ()) return 0; if (mode == JSEM_MODE_MOUSE_CDTV) { h = INPUTEVENT_MOUSE_CDTV_HORIZ; v = INPUTEVENT_MOUSE_CDTV_VERT; } else if (port >= 2) { h = port == 3 ? INPUTEVENT_PAR_JOY2_HORIZ : INPUTEVENT_PAR_JOY1_HORIZ; v = port == 3 ? INPUTEVENT_PAR_JOY2_VERT : INPUTEVENT_PAR_JOY1_VERT; } else { h = port ? INPUTEVENT_JOY2_HORIZ : INPUTEVENT_JOY1_HORIZ;; v = port ? INPUTEVENT_JOY2_VERT : INPUTEVENT_JOY1_VERT; } setid (uid, num, ID_AXIS_OFFSET + 0, 0, port, h); setid (uid, num, ID_AXIS_OFFSET + 1, 0, port, v); if (port >= 2) { setid_af (uid, num, ID_BUTTON_OFFSET + 0, 0, port, port == 3 ? INPUTEVENT_PAR_JOY2_FIRE_BUTTON : INPUTEVENT_PAR_JOY1_FIRE_BUTTON, af); } else { setid_af (uid, num, ID_BUTTON_OFFSET + 0, 0, port, port ? INPUTEVENT_JOY2_FIRE_BUTTON : INPUTEVENT_JOY1_FIRE_BUTTON, af); if (SDL_JoystickNumButtons(joy) > 0) setid (uid, num, ID_BUTTON_OFFSET + 1, 0, port, port ? INPUTEVENT_JOY2_2ND_BUTTON : INPUTEVENT_JOY1_2ND_BUTTON); if (SDL_JoystickNumButtons(joy) > 1) setid (uid, num, ID_BUTTON_OFFSET + 2, 0, port, port ? INPUTEVENT_JOY2_3RD_BUTTON : INPUTEVENT_JOY1_3RD_BUTTON); } #if 0 for (int32_t j = 2; j < MAX_MAPPINGS - 1; j++) { int32_t am = did->axismappings[j]; if (am == DIJOFS_POV(0) || am == DIJOFS_POV(1) || am == DIJOFS_POV(2) || am == DIJOFS_POV(3)) { setid (uid, num, ID_AXIS_OFFSET + j + 0, 0, port, h); setid (uid, num, ID_AXIS_OFFSET + j + 1, 0, port, v); j++; } } #endif if (mode == JSEM_MODE_JOYSTICK_CD32) { setid_af (uid, num, ID_BUTTON_OFFSET + 0, 0, port, port ? INPUTEVENT_JOY2_CD32_RED : INPUTEVENT_JOY1_CD32_RED, af); setid_af (uid, num, ID_BUTTON_OFFSET + 0, 1, port, port ? INPUTEVENT_JOY2_FIRE_BUTTON : INPUTEVENT_JOY1_FIRE_BUTTON, af); if (SDL_JoystickNumButtons(joy) > 0) { setid (uid, num, ID_BUTTON_OFFSET + 1, 0, port, port ? INPUTEVENT_JOY2_CD32_BLUE : INPUTEVENT_JOY1_CD32_BLUE); setid (uid, num, ID_BUTTON_OFFSET + 1, 1, port, port ? INPUTEVENT_JOY2_2ND_BUTTON : INPUTEVENT_JOY1_2ND_BUTTON); } if (SDL_JoystickNumButtons(joy) > 1) setid (uid, num, ID_BUTTON_OFFSET + 2, 0, port, port ? INPUTEVENT_JOY2_CD32_GREEN : INPUTEVENT_JOY1_CD32_GREEN); if (SDL_JoystickNumButtons(joy) > 2) setid (uid, num, ID_BUTTON_OFFSET + 3, 0, port, port ? INPUTEVENT_JOY2_CD32_YELLOW : INPUTEVENT_JOY1_CD32_YELLOW); if (SDL_JoystickNumButtons(joy) > 3) setid (uid, num, ID_BUTTON_OFFSET + 4, 0, port, port ? INPUTEVENT_JOY2_CD32_RWD : INPUTEVENT_JOY1_CD32_RWD); if (SDL_JoystickNumButtons(joy) > 4) setid (uid, num, ID_BUTTON_OFFSET + 5, 0, port, port ? INPUTEVENT_JOY2_CD32_FFW : INPUTEVENT_JOY1_CD32_FFW); if (SDL_JoystickNumButtons(joy) > 5) setid (uid, num, ID_BUTTON_OFFSET + 6, 0, port, port ? INPUTEVENT_JOY2_CD32_PLAY : INPUTEVENT_JOY1_CD32_PLAY); } if (num == 0) return 1; return 0; }
void DIInitJoysticks() { HRESULT hr; hr=CoCreateInstance(CLSID_DirectInput,NULL,CLSCTX_ALL,IID_IDirectInput,(void**)&DIObj); if (FAILED(hr)) return; hr=DIObj->Initialize(GetModuleHandle(NULL),DIRECTINPUT_VERSION); if (FAILED(hr)){ DIFreeJoysticks();return; } hr=DIObj->EnumDevices(DIDEVTYPE_JOYSTICK,DIEnumJoysticksCallback,NULL,DIEDFL_ALLDEVICES); if (FAILED(hr) || NumJoysticks==0){ DIFreeJoysticks();return; } // Set up data format const GUID* AxisList[]={&GUID_XAxis,&GUID_YAxis,&GUID_ZAxis,&GUID_RxAxis,&GUID_RyAxis, &GUID_RzAxis,&GUID_Slider,&GUID_Slider,NULL}; int Offset=FIELD_OFFSET(DIJOYSTATE,lX); int i=0; while (AxisList[i]){ DIJoyDataFormatObjects[i].pguid=AxisList[i]; DIJoyDataFormatObjects[i].dwOfs=Offset; DIJoyDataFormatObjects[i].dwType=DIDFT_AXIS | DIFT_ALLOWNOTEXIST | DIDFT_ANYINSTANCE; DIJoyDataFormatObjects[i].dwFlags=DIDOI_ASPECTPOSITION; Offset+=sizeof(LONG); i++; } for (int n=0;n<4;n++){ DIJoyDataFormatObjects[i].pguid=&GUID_POV; DIJoyDataFormatObjects[i].dwOfs=FIELD_OFFSET(DIJOYSTATE,rgdwPOV[n]); DIJoyDataFormatObjects[i].dwType=DIDFT_POV | DIFT_ALLOWNOTEXIST | DIDFT_ANYINSTANCE; DIJoyDataFormatObjects[i].dwFlags=0; i++; } for (int n=0;n<32;n++){ DIJoyDataFormatObjects[i].pguid=NULL; DIJoyDataFormatObjects[i].dwOfs=FIELD_OFFSET(DIJOYSTATE,rgbButtons[n]); DIJoyDataFormatObjects[i].dwType=DIDFT_BUTTON | DIFT_ALLOWNOTEXIST | DIDFT_ANYINSTANCE; DIJoyDataFormatObjects[i].dwFlags=0; i++; if (i>DIJOY_MAX_DATAOBJECT) break; } DIJoyDataFormat.dwNumObjs=i; for (int j=0;j<MAX_PC_JOYS;j++){ if (DIJoy[j]){ JoyExists[j]=true; DIJoy[j]->SetDataFormat(&DIJoyDataFormat); DIJoy[j]->SetCooperativeLevel(StemWin,DISCL_NONEXCLUSIVE | DISCL_BACKGROUND); // Set device wide options DIPROPDWORD dip={{sizeof(DIPROPDWORD),sizeof(DIPROPHEADER),0,DIPH_DEVICE},0}; dip.dwData=DIPROPAXISMODE_ABS; DIJoy[j]->SetProperty(DIPROP_AXISMODE,&dip.diph); dip.dwData=0; DIJoy[j]->SetProperty(DIPROP_DEADZONE,&dip.diph); dip.dwData=10000; DIJoy[j]->SetProperty(DIPROP_SATURATION,&dip.diph); for (int a=0;a<7;a++) JoyInfo[j].AxisExists[a]=0; DIGetAxisInfo(j,DIJOFS_X,AXIS_X); DIGetAxisInfo(j,DIJOFS_Y,AXIS_Y); DIGetAxisInfo(j,DIJOFS_Z,AXIS_Z); DIGetAxisInfo(j,DIJOFS_SLIDER(0),AXIS_U); DIGetAxisInfo(j,DIJOFS_SLIDER(1),AXIS_V); int rofs[3]={DIJOFS_RZ,DIJOFS_RX,DIJOFS_RY}; DI_RnMap[j][0]=-1, DI_RnMap[j][1]=-1, DI_RnMap[j][2]=-1; for (int i=0;i<3;i++){ int axnum=-1; for (int a=0;a<AXIS_POV;a++){ if (JoyInfo[j].AxisExists[a]==0){ axnum=a; break; } } if (axnum<0) break; DIGetAxisInfo(j,rofs[i],axnum); if (JoyInfo[j].AxisExists[axnum]) DI_RnMap[j][i]=axnum; } DIPOVNum=-1; for (int i=0;i<4;i++){ DIDEVICEOBJECTINSTANCE didoi; didoi.dwSize=sizeof(DIDEVICEOBJECTINSTANCE); if (DIJoy[j]->GetObjectInfo(&didoi,DIJOFS_POV(i),DIPH_BYOFFSET)==DI_OK){ DIPOVNum=i; JoyInfo[j].AxisExists[AXIS_POV]=true; break; } } // This is just in case getting positions fails silently somehow. DIJoyPos[j].lX=JoyInfo[j].AxisMid[AXIS_X]; DIJoyPos[j].lY=JoyInfo[j].AxisMid[AXIS_Y]; DIJoyPos[j].lZ=JoyInfo[j].AxisMid[AXIS_Z]; DIJoyPos[j].rglSlider[0]=JoyInfo[j].AxisMid[AXIS_U]; DIJoyPos[j].rglSlider[1]=JoyInfo[j].AxisMid[AXIS_V]; for (int p=0;p<4;p++) DIJoyPos[j].rgdwPOV[p]=0xffffffff; if (DI_RnMap[j][0]>=0) DIJoyPos[j].lRz=JoyInfo[j].AxisMid[DI_RnMap[j][0]]; if (DI_RnMap[j][1]>=0) DIJoyPos[j].lRx=JoyInfo[j].AxisMid[DI_RnMap[j][1]]; if (DI_RnMap[j][2]>=0) DIJoyPos[j].lRy=JoyInfo[j].AxisMid[DI_RnMap[j][2]]; JoyInfo[j].NumButtons=31; ZeroMemory(DIJoyPos[j].rgbButtons,sizeof(DIJoyPos[j].rgbButtons)); DIDisconnected[j]=50; DIJoy[j]->Acquire(); } } }
/* This doesn't take a timestamp; instead, we let InputHandler::ButtonPressed figure * it out. Be sure to call InputHandler::Update() between each poll. */ void InputHandler_DInput::UpdatePolled(DIDevice &device, const RageTimer &tm) { if( device.type == device.KEYBOARD ) { unsigned char keys[256]; HRESULT hr = GetDeviceState(device.Device, 256, keys); if ( hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED ) return; if ( hr != DI_OK ) { LOG->MapLog( "UpdatePolled", hr_ssprintf(hr, "Failures on polled keyboard update") ); return; } for( int k = 0; k < 256; ++k ) { const int key = device.Inputs[k].num; ButtonPressed(DeviceInput(device.dev, key), !!(keys[k] & 0x80)); } return; } DIJOYSTATE state; HRESULT hr = GetDeviceState(device.Device, sizeof(state), &state); if ( hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED ) return; /* Set each known axis, button and POV. */ for(unsigned i = 0; i < device.Inputs.size(); ++i) { const input_t &in = device.Inputs[i]; const InputDevice dev = device.dev; switch(in.type) { case in.BUTTON: { DeviceInput di(dev, JOY_1 + in.num, -1, tm); ButtonPressed(di, !!state.rgbButtons[in.ofs - DIJOFS_BUTTON0]); break; } case in.AXIS: { JoystickButton neg = NUM_JOYSTICK_BUTTONS, pos = NUM_JOYSTICK_BUTTONS; int val = 0; switch(in.ofs) { case DIJOFS_X: neg = JOY_LEFT; pos = JOY_RIGHT; val = state.lX; break; case DIJOFS_Y: neg = JOY_UP; pos = JOY_DOWN; val = state.lY; break; case DIJOFS_Z: neg = JOY_Z_UP; pos = JOY_Z_DOWN; val = state.lZ; break; case DIJOFS_RX: neg = JOY_ROT_LEFT; pos = JOY_ROT_RIGHT; val = state.lRx; break; case DIJOFS_RY: neg = JOY_ROT_UP; pos = JOY_ROT_DOWN; val = state.lRy; break; case DIJOFS_RZ: neg = JOY_ROT_Z_UP; pos = JOY_ROT_Z_DOWN; val = state.lRz; break; case DIJOFS_SLIDER(0): neg = JOY_AUX_1; pos = JOY_AUX_2; val = state.rglSlider[0]; break; case DIJOFS_SLIDER(1): neg = JOY_AUX_3; pos = JOY_AUX_4; val = state.rglSlider[1]; break; default: LOG->MapLog("unknown input", "Controller '%s' is returning an unknown joystick offset, %i", device.JoystickInst.tszProductName, in.ofs ); continue; } if( neg != NUM_JOYSTICK_BUTTONS ) { float l = SCALE( int(val), 0.0f, 100.0f, 0.0f, 1.0f ); ButtonPressed(DeviceInput(dev, neg, max(-l,0), tm), val < -50); ButtonPressed(DeviceInput(dev, pos, max(+l,0), tm), val > 50); } break; } case in.HAT: if( in.num == 0 ) { const int pos = TranslatePOV(state.rgdwPOV[in.ofs - DIJOFS_POV(0)]); ButtonPressed(DeviceInput(dev, JOY_HAT_UP, -1, tm), !!(pos & HAT_UP_MASK)); ButtonPressed(DeviceInput(dev, JOY_HAT_DOWN, -1, tm), !!(pos & HAT_DOWN_MASK)); ButtonPressed(DeviceInput(dev, JOY_HAT_LEFT, -1, tm), !!(pos & HAT_LEFT_MASK)); ButtonPressed(DeviceInput(dev, JOY_HAT_RIGHT, -1, tm), !!(pos & HAT_RIGHT_MASK)); } break; } } }
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; } } }
fResult f2dInputJoystickImpl::UpdateState() { DIDEVICEOBJECTDATA tRawData[BufferSize]; DWORD tSize = BufferSize; HRESULT tHR = m_pDev->GetDeviceData( sizeof(DIDEVICEOBJECTDATA), tRawData, &tSize, 0); if(FAILED(tHR)) { tHR = m_pDev->Acquire(); if(FAILED(tHR)) return FCYERR_INTERNALERR; else { tSize = BufferSize; tHR = m_pDev->GetDeviceData( sizeof(DIDEVICEOBJECTDATA), tRawData, &tSize, 0); if(FAILED(tHR)) return FCYERR_INTERNALERR; } } for(fuInt i = 0; i<tSize; ++i) { float tValue = 0.f; switch(tRawData[i].dwOfs) { case DIJOFS_X: tValue = ((int)tRawData[i].dwData - m_lXHalf) / (float)(m_lXHalfLen); m_lX = tValue; if(m_pListener) m_pListener->OnJoystickXAxisPosChange(tValue); break; case DIJOFS_Y: tValue = ((int)tRawData[i].dwData - m_lYHalf) / (float)(m_lYHalfLen); m_lY = tValue; if(m_pListener) m_pListener->OnJoystickYAxisPosChange(tValue); break; case DIJOFS_Z: tValue = ((int)tRawData[i].dwData - m_lZHalf) / (float)(m_lZHalfLen); m_lZ = tValue; if(m_pListener) m_pListener->OnJoystickZAxisPosChange(tValue); break; case DIJOFS_RX: tValue = ((int)tRawData[i].dwData - m_lRxHalf) / (float)(m_lRxHalfLen); m_lRx = tValue; if(m_pListener) m_pListener->OnJoystickXAxisRotationChange(tValue); break; case DIJOFS_RY: tValue = ((int)tRawData[i].dwData - m_lRyHalf) / (float)(m_lRyHalfLen); m_lRy = tValue; if(m_pListener) m_pListener->OnJoystickYAxisRotationChange(tValue); break; case DIJOFS_RZ: tValue = ((int)tRawData[i].dwData - m_lRzHalf) / (float)(m_lRzHalfLen); m_lRz = tValue; if(m_pListener) m_pListener->OnJoystickZAxisRotationChange(tValue); break; case DIJOFS_SLIDER(0): m_Slider[0] = tRawData[i].dwData; break; case DIJOFS_SLIDER(1): m_Slider[1] = tRawData[i].dwData; break; case DIJOFS_POV(0): m_POV[0] = tRawData[i].dwData; break; case DIJOFS_POV(1): m_POV[1] = tRawData[i].dwData; break; case DIJOFS_POV(2): m_POV[2] = tRawData[i].dwData; break; case DIJOFS_POV(3): m_POV[3] = tRawData[i].dwData; break; default: if(tRawData[i].dwOfs>=DIJOFS_BUTTON0 && tRawData[i].dwOfs<=DIJOFS_BUTTON31) { bool tDown = (LOWORD(tRawData[i].dwData)&0x80) != 0; m_ButtonDown[tRawData[i].dwOfs - DIJOFS_BUTTON0] = tDown; if(m_pListener) if(tDown) m_pListener->OnJoystickBtnDown(tRawData[i].dwOfs - DIJOFS_BUTTON0); else m_pListener->OnJoystickBtnUp(tRawData[i].dwOfs - DIJOFS_BUTTON0); } } } return FCYERR_OK; }