void SDL_SYS_JoystickUpdate(SDL_Joystick * joystick) { int i; Sint16 value; float values[3]; SDL_joylist_item *item = SDL_joylist; while (item) { if (item->is_accelerometer) { if (item->joystick) { if (Android_JNI_GetAccelerometerValues(values)) { for ( i = 0; i < 3; i++ ) { if (values[i] > 1.0f) { values[i] = 1.0f; } else if (values[i] < -1.0f) { values[i] = -1.0f; } value = (Sint16)(values[i] * 32767.0f); SDL_PrivateJoystickAxis(item->joystick, i, value); } } } break; } item = item->next; } }
/* 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 __inline__ void JS_HandleEvents(SDL_Joystick *joystick) { struct js_event events[32]; int i, len; Uint8 other_axis; #ifndef NO_LOGICAL_JOYSTICKS if (SDL_joylist[joystick->index].fname == NULL) { SDL_joylist_head(i, joystick->index); JS_HandleEvents(SDL_joylist[i].joy); return; } #endif while ((len=read(joystick->hwdata->fd, events, (sizeof events))) > 0) { len /= sizeof(events[0]); for ( i=0; i<len; ++i ) { switch (events[i].type & ~JS_EVENT_INIT) { case JS_EVENT_AXIS: if ( events[i].number < joystick->naxes ) { #ifndef NO_LOGICAL_JOYSTICKS if (!LogicalJoystickAxis(joystick, events[i].number, events[i].value)) #endif SDL_PrivateJoystickAxis(joystick, events[i].number, events[i].value); break; } events[i].number -= joystick->naxes; other_axis = (events[i].number / 2); if ( other_axis < joystick->nhats ) { HandleHat(joystick, other_axis, events[i].number%2, events[i].value); break; } events[i].number -= joystick->nhats*2; other_axis = (events[i].number / 2); if ( other_axis < joystick->nballs ) { HandleBall(joystick, other_axis, events[i].number%2, events[i].value); break; } break; case JS_EVENT_BUTTON: #ifndef NO_LOGICAL_JOYSTICKS if (!LogicalJoystickButton(joystick, events[i].number, events[i].value)) #endif SDL_PrivateJoystickButton(joystick, events[i].number, events[i].value); break; default: /* ?? */ break; } } } }
/* SDL_PrivateJoystick* doesn't discard duplicate events, so we need to * do it. */ static int SDL_PrivateJoystickAxis_Int(SDL_Joystick * joystick, Uint8 axis, Sint16 value) { if (joystick->axes[axis] != value) return SDL_PrivateJoystickAxis(joystick, axis, value); return 0; }
void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick) { //dc=keysd; //if (dc) //{ //fprintf(stderr,"heartbeat= %d\n",REG_VCOUNT); //swiWaitForVBlank(); //scanKeys(); //keysd = keysDown(); //keysu = keysUp(); //ldc=keysd; //} /*if (prevkey && prevbutton) { scanKeys(); } */ //scanKeys(); keysd = keysDown(); keysu = keysUp(); short ax=0,v=0,h=0; if((keysd&KEY_UP)) {ax=1;v=-10;SDL_PrivateJoystickAxis(joystick,ax,v);prevkey=KEY_UP;}//fprintf(stderr,"KEY_UP\n");} if((keysd&KEY_DOWN)) {ax=1;v=10;SDL_PrivateJoystickAxis(joystick,ax,v);prevkey=KEY_DOWN;}//fprintf(stderr,"KEY_DOWN\n");} if((keysd&KEY_LEFT)) {ax=0;h=-10;SDL_PrivateJoystickAxis(joystick,ax,h);prevkey=KEY_LEFT;}//fprintf(stderr,"KEY_LEFT\n");} if((keysd&KEY_RIGHT)) {ax=0;h=10;SDL_PrivateJoystickAxis(joystick,ax,h);prevkey=KEY_RIGHT;}//fprintf(stderr,"KEY_RIGHT\n");} if((keysu&KEY_UP)) {ax=1;v=0;SDL_PrivateJoystickAxis(joystick,ax,v);prevkey=0;}//fprintf(stderr,"KEY_UP\n");} if((keysu&KEY_DOWN)) {ax=1;v=0;SDL_PrivateJoystickAxis(joystick,ax,v);prevkey=0;}//fprintf(stderr,"KEY_DOWN\n");} if((keysu&KEY_LEFT)) {ax=0;h=0;SDL_PrivateJoystickAxis(joystick,ax,h);prevkey=0;}//fprintf(stderr,"KEY_LEFT\n");} if((keysu&KEY_RIGHT)) {ax=0;h=0;SDL_PrivateJoystickAxis(joystick,ax,h);prevkey=0;}//fprintf(stderr,"KEY_RIGHT\n");} if((keysd&KEY_A)) {SDL_PrivateJoystickButton(joystick,0,SDL_PRESSED);prevbutton=KEY_A;} if((keysd&KEY_B)) {SDL_PrivateJoystickButton(joystick,1,SDL_PRESSED);prevbutton=KEY_B;} if((keysd&KEY_X)) {SDL_PrivateJoystickButton(joystick,2,SDL_PRESSED);prevbutton=KEY_X;} if((keysd&KEY_Y)) {SDL_PrivateJoystickButton(joystick,3,SDL_PRESSED);prevbutton=KEY_Y;} if((keysd&KEY_SELECT)) {SDL_PrivateJoystickButton(joystick,6,SDL_PRESSED);prevbutton=KEY_SELECT;} if((keysd&KEY_START)) {SDL_PrivateJoystickButton(joystick,7,SDL_PRESSED);prevbutton=KEY_START;} if((keysd&KEY_L)) {SDL_PrivateJoystickButton(joystick,4,SDL_PRESSED);prevbutton=KEY_L;} if((keysd&KEY_R)) {SDL_PrivateJoystickButton(joystick,5,SDL_PRESSED);prevbutton=KEY_R;} if((keysu&KEY_A)) {SDL_PrivateJoystickButton(joystick,0,SDL_RELEASED);prevbutton=0;} if((keysu&KEY_B)) {SDL_PrivateJoystickButton(joystick,1,SDL_RELEASED);prevbutton=0;} if((keysu&KEY_X)) {SDL_PrivateJoystickButton(joystick,2,SDL_RELEASED);prevbutton=0;} if((keysu&KEY_Y)) {SDL_PrivateJoystickButton(joystick,3,SDL_RELEASED);prevbutton=0;} if((keysu&KEY_SELECT)) {SDL_PrivateJoystickButton(joystick,6,SDL_RELEASED);prevbutton=0;} if((keysu&KEY_START)) {SDL_PrivateJoystickButton(joystick,7,SDL_RELEASED);prevbutton=0;} if((keysu&KEY_L)) {SDL_PrivateJoystickButton(joystick,4,SDL_RELEASED);prevbutton=0;} if((keysu&KEY_R)) {SDL_PrivateJoystickButton(joystick,5,SDL_RELEASED);prevbutton=0;} }
int SDL_PrivateJoystickAxis(SDL_Joystick * joystick, Uint8 axis, Sint16 value) { int posted; /* Make sure we're not getting garbage or duplicate events */ if (axis >= joystick->naxes) { return 0; } if (!joystick->axes[axis].has_initial_value) { joystick->axes[axis].initial_value = value; joystick->axes[axis].value = value; joystick->axes[axis].zero = value; joystick->axes[axis].has_initial_value = SDL_TRUE; } if (value == joystick->axes[axis].value) { return 0; } if (!joystick->axes[axis].sent_initial_value) { /* Make sure we don't send motion until there's real activity on this axis */ const int MAX_ALLOWED_JITTER = SDL_JOYSTICK_AXIS_MAX / 80; /* ShanWan PS3 controller needed 96 */ if (SDL_abs(value - joystick->axes[axis].value) <= MAX_ALLOWED_JITTER) { return 0; } joystick->axes[axis].sent_initial_value = SDL_TRUE; joystick->axes[axis].value = value; /* Just so we pass the check above */ SDL_PrivateJoystickAxis(joystick, axis, joystick->axes[axis].initial_value); } /* We ignore events if we don't have keyboard focus, except for centering * events. */ if (SDL_PrivateJoystickShouldIgnoreEvent()) { if ((value > joystick->axes[axis].zero && value >= joystick->axes[axis].value) || (value < joystick->axes[axis].zero && value <= joystick->axes[axis].value)) { return 0; } } /* Update internal joystick state */ joystick->axes[axis].value = value; /* Post the event, if desired */ posted = 0; #if !SDL_EVENTS_DISABLED if (SDL_GetEventState(SDL_JOYAXISMOTION) == SDL_ENABLE) { SDL_Event event; event.type = SDL_JOYAXISMOTION; event.jaxis.which = joystick->instance_id; event.jaxis.axis = axis; event.jaxis.value = value; posted = SDL_PushEvent(&event) == 1; } #endif /* !SDL_EVENTS_DISABLED */ return (posted); }
static void UpdateDINPUTJoystickState_Buffered(SDL_Joystick * joystick) { int i; HRESULT result; DWORD numevents; DIDEVICEOBJECTDATA evtbuf[INPUT_QSIZE]; numevents = INPUT_QSIZE; result = IDirectInputDevice8_GetDeviceData(joystick->hwdata->InputDevice, sizeof(DIDEVICEOBJECTDATA), evtbuf, &numevents, 0); if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) { IDirectInputDevice8_Acquire(joystick->hwdata->InputDevice); result = IDirectInputDevice8_GetDeviceData(joystick->hwdata->InputDevice, sizeof(DIDEVICEOBJECTDATA), evtbuf, &numevents, 0); } /* Handle the events or punt */ if (FAILED(result)) { joystick->hwdata->send_remove_event = SDL_TRUE; joystick->hwdata->removed = SDL_TRUE; return; } for (i = 0; i < (int)numevents; ++i) { int j; for (j = 0; j < joystick->hwdata->NumInputs; ++j) { const input_t *in = &joystick->hwdata->Inputs[j]; if (evtbuf[i].dwOfs != in->ofs) continue; switch (in->type) { case AXIS: SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)evtbuf[i].dwData); break; case BUTTON: SDL_PrivateJoystickButton(joystick, in->num, (Uint8)(evtbuf[i].dwData ? SDL_PRESSED : SDL_RELEASED)); break; case HAT: { Uint8 pos = TranslatePOV(evtbuf[i].dwData); SDL_PrivateJoystickHat(joystick, in->num, pos); } break; } } } }
int Android_OnJoy(int device_id, int axis, float value) { /* Android gives joy info normalized as [-1.0, 1.0] or [0.0, 1.0] */ SDL_joylist_item *item = JoystickByDeviceId(device_id); if (item && item->joystick) { SDL_PrivateJoystickAxis(item->joystick, axis, (Sint16) (32767.*value) ); } return 0; }
/* 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. */ void SDL_SYS_JoystickUpdate(SDL_Joystick * joystick) { if(current_video->hidden->iJoystickStatus[EJoyLEFT]!= current_video->hidden->iLastJoystickStatus[EJoyLEFT]|| current_video->hidden->iJoystickStatus[EJoyRIGHT]!= current_video->hidden->iLastJoystickStatus[EJoyRIGHT]) { if(!current_video->hidden->iJoystickStatus[EJoyLEFT] && !current_video->hidden->iJoystickStatus[EJoyRIGHT]) SDL_PrivateJoystickAxis(joystick,0,0); else SDL_PrivateJoystickAxis(joystick,0,current_video->hidden->iJoystickStatus[EJoyLEFT]?-JOY_DEADZONE:JOY_DEADZONE); current_video->hidden->iLastJoystickStatus[EJoyLEFT] = current_video->hidden->iJoystickStatus[EJoyLEFT]; current_video->hidden->iLastJoystickStatus[EJoyRIGHT] = current_video->hidden->iJoystickStatus[EJoyRIGHT]; } if(current_video->hidden->iJoystickStatus[EJoyUP]!= current_video->hidden->iLastJoystickStatus[EJoyUP]|| current_video->hidden->iJoystickStatus[EJoyDOWN]!= current_video->hidden->iLastJoystickStatus[EJoyDOWN]) { if(!current_video->hidden->iJoystickStatus[EJoyUP] && !current_video->hidden->iJoystickStatus[EJoyDOWN]) SDL_PrivateJoystickAxis(joystick,1,0); else SDL_PrivateJoystickAxis(joystick,1,current_video->hidden->iJoystickStatus[EJoyUP]?-JOY_DEADZONE:JOY_DEADZONE); current_video->hidden->iLastJoystickStatus[EJoyUP] = current_video->hidden->iJoystickStatus[EJoyUP]; current_video->hidden->iLastJoystickStatus[EJoyDOWN] = current_video->hidden->iJoystickStatus[EJoyDOWN]; } if(current_video->hidden->iJoystickStatus[EJoyBUT1]!= current_video->hidden->iLastJoystickStatus[EJoyBUT1]) { SDL_PrivateJoystickButton(joystick,0,current_video->hidden->iJoystickStatus[EJoyBUT1]); current_video->hidden->iLastJoystickStatus[EJoyBUT1] = current_video->hidden->iJoystickStatus[EJoyBUT1]; } if(current_video->hidden->iJoystickStatus[EJoyBUT2]!= current_video->hidden->iLastJoystickStatus[EJoyBUT2]) { SDL_PrivateJoystickButton(joystick,1,current_video->hidden->iJoystickStatus[EJoyBUT2]); current_video->hidden->iLastJoystickStatus[EJoyBUT2] = current_video->hidden->iJoystickStatus[EJoyBUT2]; } if(current_video->hidden->iJoystickStatus[EJoyBUT3]!= current_video->hidden->iLastJoystickStatus[EJoyBUT3]) { SDL_PrivateJoystickButton(joystick,2,current_video->hidden->iJoystickStatus[6]); current_video->hidden->iLastJoystickStatus[EJoyBUT3] = current_video->hidden->iJoystickStatus[EJoyBUT3]; } }
void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick) { int i; enum PspCtrlButtons buttons; enum PspCtrlButtons changed; unsigned char x, y; static enum PspCtrlButtons old_buttons = 0; static unsigned char old_x = 0, old_y = 0; SDL_SemWait(pad_sem); buttons = pad.Buttons; x = pad.Lx; y = pad.Ly; SDL_SemPost(pad_sem); /* Axes */ if(old_x != x) { SDL_PrivateJoystickAxis(joystick, 0, analog_map[x]); old_x = x; } if(old_y != y) { SDL_PrivateJoystickAxis(joystick, 1, analog_map[y]); old_y = y; } /* Buttons */ changed = old_buttons ^ buttons; old_buttons = buttons; if(changed) { for(i=0; i<sizeof(button_map)/sizeof(button_map[0]); i++) { if(changed & button_map[i]) { SDL_PrivateJoystickButton( joystick, i, (buttons & button_map[i]) ? SDL_PRESSED : SDL_RELEASED); } } } sceKernelDelayThread(0); }
/* 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. */ void SDL_SYS_JoystickUpdate(SDL_Joystick * joystick) { int i; float values[3]; Android_JNI_GetAccelerometerValues(values); for ( i = 0; i < 3; i++ ) { SDL_PrivateJoystickAxis(joystick, i, values[i]); } }
static void UpdateXInputJoystickState_OLD(SDL_Joystick * joystick, XINPUT_STATE_EX *pXInputState, XINPUT_BATTERY_INFORMATION_EX *pBatteryInformation) { static WORD s_XInputButtons[] = { XINPUT_GAMEPAD_DPAD_UP, XINPUT_GAMEPAD_DPAD_DOWN, XINPUT_GAMEPAD_DPAD_LEFT, XINPUT_GAMEPAD_DPAD_RIGHT, XINPUT_GAMEPAD_START, XINPUT_GAMEPAD_BACK, XINPUT_GAMEPAD_LEFT_THUMB, XINPUT_GAMEPAD_RIGHT_THUMB, XINPUT_GAMEPAD_LEFT_SHOULDER, XINPUT_GAMEPAD_RIGHT_SHOULDER, XINPUT_GAMEPAD_A, XINPUT_GAMEPAD_B, XINPUT_GAMEPAD_X, XINPUT_GAMEPAD_Y, XINPUT_GAMEPAD_GUIDE }; WORD wButtons = pXInputState->Gamepad.wButtons; Uint8 button; SDL_PrivateJoystickAxis(joystick, 0, (Sint16)pXInputState->Gamepad.sThumbLX); SDL_PrivateJoystickAxis(joystick, 1, (Sint16)(-SDL_max(-32767, pXInputState->Gamepad.sThumbLY))); SDL_PrivateJoystickAxis(joystick, 2, (Sint16)pXInputState->Gamepad.sThumbRX); SDL_PrivateJoystickAxis(joystick, 3, (Sint16)(-SDL_max(-32767, pXInputState->Gamepad.sThumbRY))); SDL_PrivateJoystickAxis(joystick, 4, (Sint16)(((int)pXInputState->Gamepad.bLeftTrigger * 65535 / 255) - 32768)); SDL_PrivateJoystickAxis(joystick, 5, (Sint16)(((int)pXInputState->Gamepad.bRightTrigger * 65535 / 255) - 32768)); for (button = 0; button < SDL_arraysize(s_XInputButtons); ++button) { SDL_PrivateJoystickButton(joystick, button, (wButtons & s_XInputButtons[button]) ? SDL_PRESSED : SDL_RELEASED); } UpdateXInputJoystickBatteryInformation( joystick, pBatteryInformation ); }
/* 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. */ void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick) { _kernel_swi_regs regs; regs.r[0] = joystick->index; if (_kernel_swi(JOYSTICK_READ, ®s, ®s) == NULL) { int newstate = regs.r[0]; int oldstate = joystick->hwdata->joystate; if (newstate != oldstate) { if ((newstate & 0xFF) != (oldstate & 0xFF)) { int y = regs.r[0] & 0xFF; /* Convert to signed values */ if (y >= 128) y -= 256; SDL_PrivateJoystickAxis(joystick,1,-y * 256); /* Up and down opposite to result in SDL */ } if ((newstate & 0xFF00) != (oldstate & 0xFF00)) { int x = (regs.r[0] & 0xFF00) >> 8; if (x >= 128) x -= 256; SDL_PrivateJoystickAxis(joystick,0,x * 256); } if ((newstate & 0xFF0000) != (oldstate & 0xFF0000)) { int buttons = (regs.r[0] & 0xFF0000) >> 16; int oldbuttons = (oldstate & 0xFF0000) >> 16; int i; for (i = 0; i < joystick->nbuttons; i++) { if ((buttons & (1<<i)) != (oldbuttons & (1<<i))) { if (buttons & (1<<i)) SDL_PrivateJoystickButton(joystick,i,SDL_PRESSED); else SDL_PrivateJoystickButton(joystick,i,SDL_RELEASED); } } }
void SDL_JoystickUpdate(void) { SDL_Joystick *joystick; joystick = SDL_joysticks; while (joystick) { SDL_Joystick *joysticknext; /* save off the next pointer, the Update call may cause a joystick removed event * and cause our joystick pointer to be freed */ joysticknext = joystick->next; SDL_updating_joystick = joystick; SDL_SYS_JoystickUpdate(joystick); if (joystick->force_recentering) { int i; /* Tell the app that everything is centered/unpressed... */ for (i = 0; i < joystick->naxes; i++) { SDL_PrivateJoystickAxis(joystick, i, joystick->axes_zero[i]); } for (i = 0; i < joystick->nbuttons; i++) { SDL_PrivateJoystickButton(joystick, i, 0); } for (i = 0; i < joystick->nhats; i++) { SDL_PrivateJoystickHat(joystick, i, SDL_HAT_CENTERED); } joystick->force_recentering = SDL_FALSE; } SDL_updating_joystick = NULL; /* If the joystick was closed while updating, free it here */ if (joystick->ref_count <= 0) { SDL_JoystickClose(joystick); } joystick = joysticknext; } /* this needs to happen AFTER walking the joystick list above, so that any dangling hardware data from removed devices can be free'd */ SDL_SYS_JoystickDetect(); }
/* 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. */ void SDL_SYS_JoystickUpdate(SDL_Joystick * joystick) { int i; Sint16 value; float values[3]; if (Android_JNI_GetAccelerometerValues(values)) { for ( i = 0; i < 3; i++ ) { value = (Sint16)(values[i] * 32767.0f); SDL_PrivateJoystickAxis(joystick, i, value); } } }
/* Release all buttons*/ void CELL_PAD_JOYSTICK_Exit (enum PadMode aNewMode) { if(CELL_Video.Pads.Pads[0].Open && CELL_Video.Pads.Pads[0].Joystick) { for(int i = 0; i != NUM_BUTTONS; i ++) { ProcessJoystickButton(CELL_Video.Pads.Pads[0].Joystick, 0, i, 0, 1); } for(int i = 0; i != NUM_AXES; i ++) { SDL_PrivateJoystickAxis(CELL_Video.Pads.Pads[0].Joystick, i, 0); } } }
extern void SDL_ANDROID_MainThreadPushJoystickAxis(int joy, int axis, int value) { if( ! ( joy < MAX_MULTITOUCH_POINTERS+1 && SDL_ANDROID_CurrentJoysticks[joy] ) ) return; if( joystickEventsCount > 64 ) { //__android_log_print(ANDROID_LOG_INFO, "libSDL", "Too many joystick events in the queue - dropping some events"); return; } joystickEventsCount++; SDL_PrivateJoystickAxis( SDL_ANDROID_CurrentJoysticks[joy], axis, MAX( -32768, MIN( 32767, value ) ) ); }
/* Process all buttons and axes, called by SDL_Joystick code not by the SDL_Video */ void CELL_PAD_JOYSTICK_Process (SDL_Joystick* aJoystick, uint32_t aIndex) { #ifndef CELL_NO_SOFT_INPUT if(aIndex < NUM_PADS && CELL_Video.Pads.Pads[aIndex].Open && CELL_Video.Pads.Pads[aIndex].Mode == JOYSTICK) #else if(aIndex < NUM_PADS && CELL_Video.Pads.Pads[aIndex].Open) #endif { CellPadData newpadstate; if((CELL_OK == cellPadGetData(aIndex, &newpadstate)) && (newpadstate.len >= 8)) { uint32_t newbuttons = newpadstate.button[2] | (newpadstate.button[3] << 8); /* Process buttons */ if(newbuttons != CELL_Video.Pads.Pads[aIndex].OldButtons) { for(int i = 0; i != NUM_BUTTONS; i ++) { ProcessJoystickButton(aJoystick, aIndex, i, newbuttons & (1 << i), CELL_Video.Pads.Pads[aIndex].OldButtons & (1 << i)); } CELL_Video.Pads.Pads[aIndex].OldButtons = newbuttons; } /* Process Axes */ for(int i = 0; i != NUM_AXES; i ++) { if(CELL_Video.Pads.Pads[aIndex].OldAxes[i] != newpadstate.button[AxisIndex[i]]) { int16_t value = (newpadstate.button[AxisIndex[i]] - 0x80) * 256; SDL_PrivateJoystickAxis(aJoystick, i, value); } } for(int i = 0; i != NUM_AXES; i ++) { CELL_Video.Pads.Pads[aIndex].OldAxes[i] = newpadstate.button[AxisIndex[i]]; } } } return; }
/* 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. */ void SDL_SYS_JoystickUpdate(SDL_Joystick * joystick) { EmscriptenGamepadEvent gamepadState; SDL_joylist_item *item = (SDL_joylist_item *) joystick->hwdata; int i, result, buttonState; if (item) { result = emscripten_get_gamepad_status(item->index, &gamepadState); if( result == EMSCRIPTEN_RESULT_SUCCESS) { if(gamepadState.timestamp == 0 || gamepadState.timestamp != item->timestamp) { for(i = 0; i < item->nbuttons; i++) { if(item->digitalButton[i] != gamepadState.digitalButton[i]) { buttonState = gamepadState.digitalButton[i]? SDL_PRESSED: SDL_RELEASED; SDL_PrivateJoystickButton(item->joystick, i, buttonState); } /* store values to compare them in the next update */ item->analogButton[i] = gamepadState.analogButton[i]; item->digitalButton[i] = gamepadState.digitalButton[i]; } for(i = 0; i < item->naxes; i++) { if(item->axis[i] != gamepadState.axis[i]) { /* do we need to do conversion? */ SDL_PrivateJoystickAxis(item->joystick, i, (Sint16) (32767.*gamepadState.axis[i])); } /* store to compare in next update */ item->axis[i] = gamepadState.axis[i]; } item->timestamp = gamepadState.timestamp; } } } }
static int LogicalJoystickAxis( SDL_Joystick *joystick, Uint8 axis, Sint16 value) { struct joystick_logical_mapping* axes; SDL_Joystick *logicaljoy = NULL; /* if there's no map then this is just a regular joystick */ if (SDL_joylist[joystick->index].map == NULL) return 0; /* get the logical joystick that will receive the event */ axes = SDL_joylist[joystick->index].map->axismap+axis; logicaljoy = FindLogicalJoystick(joystick, axes); if (logicaljoy == NULL) return 1; SDL_PrivateJoystickAxis(logicaljoy, axes->nthing, value); return 1; }
static void UpdateXInputJoystickState(SDL_Joystick * joystick, XINPUT_STATE_EX *pXInputState, XINPUT_BATTERY_INFORMATION_EX *pBatteryInformation) { static WORD s_XInputButtons[] = { XINPUT_GAMEPAD_A, XINPUT_GAMEPAD_B, XINPUT_GAMEPAD_X, XINPUT_GAMEPAD_Y, XINPUT_GAMEPAD_LEFT_SHOULDER, XINPUT_GAMEPAD_RIGHT_SHOULDER, XINPUT_GAMEPAD_BACK, XINPUT_GAMEPAD_START, XINPUT_GAMEPAD_LEFT_THUMB, XINPUT_GAMEPAD_RIGHT_THUMB, XINPUT_GAMEPAD_GUIDE }; WORD wButtons = pXInputState->Gamepad.wButtons; Uint8 button; Uint8 hat = SDL_HAT_CENTERED; SDL_PrivateJoystickAxis(joystick, 0, pXInputState->Gamepad.sThumbLX); SDL_PrivateJoystickAxis(joystick, 1, ~pXInputState->Gamepad.sThumbLY); SDL_PrivateJoystickAxis(joystick, 2, ((int)pXInputState->Gamepad.bLeftTrigger * 257) - 32768); SDL_PrivateJoystickAxis(joystick, 3, pXInputState->Gamepad.sThumbRX); SDL_PrivateJoystickAxis(joystick, 4, ~pXInputState->Gamepad.sThumbRY); SDL_PrivateJoystickAxis(joystick, 5, ((int)pXInputState->Gamepad.bRightTrigger * 257) - 32768); for (button = 0; button < SDL_arraysize(s_XInputButtons); ++button) { SDL_PrivateJoystickButton(joystick, button, (wButtons & s_XInputButtons[button]) ? SDL_PRESSED : SDL_RELEASED); } if (wButtons & XINPUT_GAMEPAD_DPAD_UP) { hat |= SDL_HAT_UP; } if (wButtons & XINPUT_GAMEPAD_DPAD_DOWN) { hat |= SDL_HAT_DOWN; } if (wButtons & XINPUT_GAMEPAD_DPAD_LEFT) { hat |= SDL_HAT_LEFT; } if (wButtons & XINPUT_GAMEPAD_DPAD_RIGHT) { hat |= SDL_HAT_RIGHT; } SDL_PrivateJoystickHat(joystick, 0, hat); UpdateXInputJoystickBatteryInformation(joystick, pBatteryInformation); }
int SDL_SYS_JoystickOpen(SDL_Joystick *joy) { char *path = joynames[joy->index]; struct joystick_hwdata *hw; struct hid_item hitem; struct hid_data *hdata; struct report *rep; int fd; int i; fd = open(path, O_RDONLY); if (fd == -1) { SDL_SetError("%s: %s", path, strerror(errno)); return (-1); } hw = (struct joystick_hwdata *)SDL_malloc(sizeof(struct joystick_hwdata)); if (hw == NULL) { SDL_OutOfMemory(); close(fd); return (-1); } joy->hwdata = hw; hw->fd = fd; hw->path = strdup(path); hw->x = 0; hw->y = 0; hw->xmin = 0xffff; hw->ymin = 0xffff; hw->xmax = 0; hw->ymax = 0; if (! SDL_strncmp(path, "/dev/joy", 8)) { hw->type = BSDJOY_JOY; joy->naxes = 2; joy->nbuttons = 2; joy->nhats = 0; joy->nballs = 0; joydevnames[joy->index] = strdup("Gameport joystick"); goto usbend; } else { hw->type = BSDJOY_UHID; } { int ax; for (ax = 0; ax < JOYAXE_count; ax++) hw->axis_map[ax] = -1; } hw->repdesc = hid_get_report_desc(fd); if (hw->repdesc == NULL) { SDL_SetError("%s: USB_GET_REPORT_DESC: %s", hw->path, strerror(errno)); goto usberr; } #if defined(__FREEBSD__) && (__FreeBSD_kernel_version > 800063) rep->rid = hid_get_report_id(fd); if (rep->rid < 0) { #else rep = &hw->inreport; if (ioctl(fd, USB_GET_REPORT_ID, &rep->rid) < 0) { #endif rep->rid = -1; /* XXX */ } if (report_alloc(rep, hw->repdesc, REPORT_INPUT) < 0) { goto usberr; } if (rep->size <= 0) { SDL_SetError("%s: Input report descriptor has invalid length", hw->path); goto usberr; } #if defined(USBHID_NEW) || (defined(__FREEBSD__) && __FreeBSD_kernel_version >= 500111) hdata = hid_start_parse(hw->repdesc, 1 << hid_input, rep->rid); #else hdata = hid_start_parse(hw->repdesc, 1 << hid_input); #endif if (hdata == NULL) { SDL_SetError("%s: Cannot start HID parser", hw->path); goto usberr; } joy->naxes = 0; joy->nbuttons = 0; joy->nhats = 0; joy->nballs = 0; for (i=0; i<JOYAXE_count; i++) hw->axis_map[i] = -1; while (hid_get_item(hdata, &hitem) > 0) { char *sp; const char *s; switch (hitem.kind) { case hid_collection: switch (HID_PAGE(hitem.usage)) { case HUP_GENERIC_DESKTOP: switch (HID_USAGE(hitem.usage)) { case HUG_JOYSTICK: case HUG_GAME_PAD: s = hid_usage_in_page(hitem.usage); sp = SDL_malloc(SDL_strlen(s) + 5); SDL_snprintf(sp, SDL_strlen(s) + 5, "%s (%d)", s, joy->index); joydevnames[joy->index] = sp; } } break; case hid_input: switch (HID_PAGE(hitem.usage)) { case HUP_GENERIC_DESKTOP: { unsigned usage = HID_USAGE(hitem.usage); int joyaxe = usage_to_joyaxe(usage); if (joyaxe >= 0) { hw->axis_map[joyaxe] = 1; } else if (usage == HUG_HAT_SWITCH) { joy->nhats++; } break; } case HUP_BUTTON: joy->nbuttons++; break; default: break; } break; default: break; } } hid_end_parse(hdata); for (i=0; i<JOYAXE_count; i++) if (hw->axis_map[i] > 0) hw->axis_map[i] = joy->naxes++; usbend: /* The poll blocks the event thread. */ fcntl(fd, F_SETFL, O_NONBLOCK); return (0); usberr: close(hw->fd); SDL_free(hw->path); SDL_free(hw); return (-1); } void SDL_SYS_JoystickUpdate(SDL_Joystick *joy) { struct hid_item hitem; struct hid_data *hdata; struct report *rep; int nbutton, naxe = -1; Sint32 v; #if defined(__FREEBSD__) || SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H struct joystick gameport; if (joy->hwdata->type == BSDJOY_JOY) { if (read(joy->hwdata->fd, &gameport, sizeof gameport) != sizeof gameport) return; if (abs(joy->hwdata->x - gameport.x) > 8) { joy->hwdata->x = gameport.x; if (joy->hwdata->x < joy->hwdata->xmin) { joy->hwdata->xmin = joy->hwdata->x; } if (joy->hwdata->x > joy->hwdata->xmax) { joy->hwdata->xmax = joy->hwdata->x; } if (joy->hwdata->xmin == joy->hwdata->xmax) { joy->hwdata->xmin--; joy->hwdata->xmax++; } v = (Sint32)joy->hwdata->x; v -= (joy->hwdata->xmax + joy->hwdata->xmin + 1)/2; v *= 32768/((joy->hwdata->xmax - joy->hwdata->xmin + 1)/2); SDL_PrivateJoystickAxis(joy, 0, v); } if (abs(joy->hwdata->y - gameport.y) > 8) { joy->hwdata->y = gameport.y; if (joy->hwdata->y < joy->hwdata->ymin) { joy->hwdata->ymin = joy->hwdata->y; } if (joy->hwdata->y > joy->hwdata->ymax) { joy->hwdata->ymax = joy->hwdata->y; } if (joy->hwdata->ymin == joy->hwdata->ymax) { joy->hwdata->ymin--; joy->hwdata->ymax++; } v = (Sint32)joy->hwdata->y; v -= (joy->hwdata->ymax + joy->hwdata->ymin + 1)/2; v *= 32768/((joy->hwdata->ymax - joy->hwdata->ymin + 1)/2); SDL_PrivateJoystickAxis(joy, 1, v); } if (gameport.b1 != joy->buttons[0]) { SDL_PrivateJoystickButton(joy, 0, gameport.b1); } if (gameport.b2 != joy->buttons[1]) { SDL_PrivateJoystickButton(joy, 1, gameport.b2); } return; } #endif /* defined(__FREEBSD__) || SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H */ rep = &joy->hwdata->inreport; if (read(joy->hwdata->fd, REP_BUF_DATA(rep), rep->size) != rep->size) { return; } #if defined(USBHID_NEW) || (defined(__FREEBSD__) && __FreeBSD_kernel_version >= 500111) hdata = hid_start_parse(joy->hwdata->repdesc, 1 << hid_input, rep->rid); #else hdata = hid_start_parse(joy->hwdata->repdesc, 1 << hid_input); #endif if (hdata == NULL) { fprintf(stderr, "%s: Cannot start HID parser\n", joy->hwdata->path); return; } for (nbutton = 0; hid_get_item(hdata, &hitem) > 0;) { switch (hitem.kind) { case hid_input: switch (HID_PAGE(hitem.usage)) { case HUP_GENERIC_DESKTOP: { unsigned usage = HID_USAGE(hitem.usage); int joyaxe = usage_to_joyaxe(usage); if (joyaxe >= 0) { naxe = joy->hwdata->axis_map[joyaxe]; /* scaleaxe */ v = (Sint32)hid_get_data(REP_BUF_DATA(rep), &hitem); v -= (hitem.logical_maximum + hitem.logical_minimum + 1)/2; v *= 32768/((hitem.logical_maximum - hitem.logical_minimum + 1)/2); if (v != joy->axes[naxe]) { SDL_PrivateJoystickAxis(joy, naxe, v); } } else if (usage == HUG_HAT_SWITCH) { v = (Sint32)hid_get_data(REP_BUF_DATA(rep), &hitem); SDL_PrivateJoystickHat(joy, 0, hatval_to_sdl(v)-hitem.logical_minimum); } break; } case HUP_BUTTON: v = (Sint32)hid_get_data(REP_BUF_DATA(rep), &hitem); if (joy->buttons[nbutton] != v) { SDL_PrivateJoystickButton(joy, nbutton, v); } nbutton++; break; default: continue; } break; default: break; } } hid_end_parse(hdata); return; } /* Function to close a joystick after use */ void SDL_SYS_JoystickClose(SDL_Joystick *joy) { if (SDL_strncmp(joy->hwdata->path, "/dev/joy", 8)) { report_free(&joy->hwdata->inreport); hid_dispose_report_desc(joy->hwdata->repdesc); } close(joy->hwdata->fd); SDL_free(joy->hwdata->path); SDL_free(joy->hwdata); return; } void SDL_SYS_JoystickQuit(void) { int i; for (i = 0; i < MAX_JOYS; i++) { if (joynames[i] != NULL) SDL_free(joynames[i]); if (joydevnames[i] != NULL) SDL_free(joydevnames[i]); } return; }
void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick) { int i, ret; int port, slot; int rjoy_h, rjoy_v; int ljoy_h, ljoy_v; struct padButtonStatus buttons; u32 paddata; u32 old_pad; u32 new_pad; port = joystick->hwdata->port; slot = joystick->hwdata->slot; if (wait_pad(port, slot, 10) < 0) { /* no pad information available */ return; } if (joystick->hwdata->deviceid < 0) { int id; /* see if we can probe the MODECURID now */ id = padInfoMode(port, slot, PAD_MODECURID, 0); if (id != 0) { int ext; ext = padInfoMode(port, slot, PAD_MODECUREXID, 0); if (ext != 0) { id = ext; } if (id == PAD_TYPE_DIGITAL) { printf("SDL_Joystick: digital pad detected\n"); } else if (id == PAD_TYPE_DUALSHOCK) { printf("SDL_Joystick: dualshock detected\n"); } else { printf("SDL_Joystick: unknown identifier %d detected\n", id); } if (id == PAD_TYPE_DIGITAL || id == PAD_TYPE_DUALSHOCK) { ret = padSetMainMode(port, slot, PAD_MMODE_DUALSHOCK, PAD_MMODE_LOCK); if (ret == 1) { printf("JoystickInit: Request received\n"); } else { printf("JoystickInit: padSetMainMode failed\n"); } } joystick->hwdata->deviceid = id; if (wait_pad(port, slot, 10) < 0) { /* no pad information available */ return; } } } ret = padRead(port, slot, &buttons); if (ret != 0) { int changed, hat; old_pad = joystick->hwdata->prev_buttons; paddata = 0xffff ^ buttons.btns; new_pad = paddata; changed = paddata ^ old_pad; joystick->hwdata->prev_buttons = paddata; hat = SDL_HAT_CENTERED; if (new_pad & PAD_LEFT) { hat = hat | SDL_HAT_LEFT; } if (new_pad & PAD_RIGHT) { hat = hat | SDL_HAT_RIGHT; } if (new_pad & PAD_DOWN) { hat = hat | SDL_HAT_DOWN; } if (new_pad & PAD_UP) { hat = hat | SDL_HAT_UP; } for (i=0; i<MAX_BUTTONS; i++) { if (changed & sdl_buttons[i]) { int status = (new_pad & sdl_buttons[i]) ? SDL_PRESSED : SDL_RELEASED; SDL_PrivateJoystickButton(joystick, i, status); } } if (changed & (PAD_LEFT|PAD_RIGHT|PAD_UP|PAD_DOWN)) { SDL_PrivateJoystickHat(joystick, 0, hat); } /* now do axis */ ljoy_h = buttons.ljoy_h - 128; ljoy_v = buttons.ljoy_v - 128; rjoy_h = buttons.rjoy_h - 128; rjoy_v = buttons.rjoy_v - 128; /* printf("rjoy_h %d rjoy_v %d ljoy_h %d ljoy_v %d (%d, %d, %d, %d)\n", rjoy_h, rjoy_v, ljoy_h, ljoy_v, joystick->hwdata->prev_rjoy_h, joystick->hwdata->prev_rjoy_v, joystick->hwdata->prev_ljoy_h, joystick->hwdata->prev_ljoy_v); */ /* left analog stick */ if (abs(joystick->hwdata->prev_ljoy_h - ljoy_h) > AXIS_THRESHOLD) { SDL_PrivateJoystickAxis(joystick, 0, ljoy_h * 127); joystick->hwdata->prev_ljoy_h = ljoy_h; } if (abs(joystick->hwdata->prev_ljoy_v - ljoy_v) > AXIS_THRESHOLD) { SDL_PrivateJoystickAxis(joystick, 1, ljoy_v * 127); joystick->hwdata->prev_ljoy_v = ljoy_v; } /* right analog stick */ if (abs(joystick->hwdata->prev_rjoy_h - rjoy_h) > AXIS_THRESHOLD) { SDL_PrivateJoystickAxis(joystick, 2, rjoy_h * 127); joystick->hwdata->prev_rjoy_h = rjoy_h; } if (abs(joystick->hwdata->prev_rjoy_v - rjoy_v) > AXIS_THRESHOLD) { SDL_PrivateJoystickAxis(joystick, 3, rjoy_v * 127); joystick->hwdata->prev_rjoy_v = rjoy_v; } } }
/* 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. */ void SDL_SYS_JoystickUpdate(SDL_Joystick * joystick) { recDevice *device = joystick->hwdata; recElement *element; SInt32 value, range; int i; if (!device) { return; } if (device->removed) { /* device was unplugged; ignore it. */ joystick->closed = 1; joystick->uncentered = 1; joystick->hwdata = NULL; return; } element = device->firstAxis; i = 0; while (element) { value = GetHIDScaledCalibratedState(device, element, -32768, 32767); if (value != joystick->axes[i]) { SDL_PrivateJoystickAxis(joystick, i, value); } element = element->pNext; ++i; } element = device->firstButton; i = 0; while (element) { value = GetHIDElementState(device, element); if (value > 1) { /* handle pressure-sensitive buttons */ value = 1; } if (value != joystick->buttons[i]) { SDL_PrivateJoystickButton(joystick, i, value); } element = element->pNext; ++i; } element = device->firstHat; i = 0; while (element) { Uint8 pos = 0; range = (element->max - element->min + 1); value = GetHIDElementState(device, element) - element->min; if (range == 4) { /* 4 position hatswitch - scale up value */ value *= 2; } else if (range != 8) { /* Neither a 4 nor 8 positions - fall back to default position (centered) */ value = -1; } switch (value) { case 0: pos = SDL_HAT_UP; break; case 1: pos = SDL_HAT_RIGHTUP; break; case 2: pos = SDL_HAT_RIGHT; break; case 3: pos = SDL_HAT_RIGHTDOWN; break; case 4: pos = SDL_HAT_DOWN; break; case 5: pos = SDL_HAT_LEFTDOWN; break; case 6: pos = SDL_HAT_LEFT; break; case 7: pos = SDL_HAT_LEFTUP; break; default: /* Every other value is mapped to center. We do that because some * joysticks use 8 and some 15 for this value, and apparently * there are even more variants out there - so we try to be generous. */ pos = SDL_HAT_CENTERED; break; } if (pos != joystick->hats[i]) { SDL_PrivateJoystickHat(joystick, i, pos); } element = element->pNext; ++i; } }
/* 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. */ void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick) { int i, j; ISpAxisData a; ISpDPadData b; //ISpDeltaData c; ISpButtonData d; for(i = 0, j = 0; i < joystick->naxes; i++, j++) { Sint16 value; ISpElement_GetSimpleState( joystick->hwdata->refs[j], &a); value = (ISpSymmetricAxisToFloat(a)* 32767.0); if ( value != joystick->axes[i] ) { SDL_PrivateJoystickAxis(joystick, i, value); } } for(i = 0; i < joystick->nhats; i++, j++) { Uint8 pos; ISpElement_GetSimpleState( joystick->hwdata->refs[j], &b); switch(b) { case kISpPadIdle: pos = SDL_HAT_CENTERED; break; case kISpPadLeft: pos = SDL_HAT_LEFT; break; case kISpPadUpLeft: pos = SDL_HAT_LEFTUP; break; case kISpPadUp: pos = SDL_HAT_UP; break; case kISpPadUpRight: pos = SDL_HAT_RIGHTUP; break; case kISpPadRight: pos = SDL_HAT_RIGHT; break; case kISpPadDownRight: pos = SDL_HAT_RIGHTDOWN; break; case kISpPadDown: pos = SDL_HAT_DOWN; break; case kISpPadDownLeft: pos = SDL_HAT_LEFTDOWN; break; } if ( pos != joystick->hats[i] ) { SDL_PrivateJoystickHat(joystick, i, pos); } } for(i = 0; i < joystick->nballs; i++, j++) { /* ignore balls right now */ } for(i = 0; i < joystick->nbuttons; i++, j++) { ISpElement_GetSimpleState( joystick->hwdata->refs[j], &d); if ( d != joystick->buttons[i] ) { SDL_PrivateJoystickButton(joystick, i, d); } } }
void SDL_SYS_JoystickUpdate(SDL_Joystick *joy) { struct hid_item hitem; struct hid_data *hdata; struct report *rep; int nbutton, naxe = -1; Sint32 v; #if defined(__FREEBSD__) || SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H struct joystick gameport; if (joy->hwdata->type == BSDJOY_JOY) { if (read(joy->hwdata->fd, &gameport, sizeof gameport) != sizeof gameport) return; if (abs(joy->hwdata->x - gameport.x) > 8) { joy->hwdata->x = gameport.x; if (joy->hwdata->x < joy->hwdata->xmin) { joy->hwdata->xmin = joy->hwdata->x; } if (joy->hwdata->x > joy->hwdata->xmax) { joy->hwdata->xmax = joy->hwdata->x; } if (joy->hwdata->xmin == joy->hwdata->xmax) { joy->hwdata->xmin--; joy->hwdata->xmax++; } v = (Sint32)joy->hwdata->x; v -= (joy->hwdata->xmax + joy->hwdata->xmin + 1)/2; v *= 32768/((joy->hwdata->xmax - joy->hwdata->xmin + 1)/2); SDL_PrivateJoystickAxis(joy, 0, v); } if (abs(joy->hwdata->y - gameport.y) > 8) { joy->hwdata->y = gameport.y; if (joy->hwdata->y < joy->hwdata->ymin) { joy->hwdata->ymin = joy->hwdata->y; } if (joy->hwdata->y > joy->hwdata->ymax) { joy->hwdata->ymax = joy->hwdata->y; } if (joy->hwdata->ymin == joy->hwdata->ymax) { joy->hwdata->ymin--; joy->hwdata->ymax++; } v = (Sint32)joy->hwdata->y; v -= (joy->hwdata->ymax + joy->hwdata->ymin + 1)/2; v *= 32768/((joy->hwdata->ymax - joy->hwdata->ymin + 1)/2); SDL_PrivateJoystickAxis(joy, 1, v); } if (gameport.b1 != joy->buttons[0]) { SDL_PrivateJoystickButton(joy, 0, gameport.b1); } if (gameport.b2 != joy->buttons[1]) { SDL_PrivateJoystickButton(joy, 1, gameport.b2); } return; } #endif /* defined(__FREEBSD__) || SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H */ rep = &joy->hwdata->inreport; if (read(joy->hwdata->fd, REP_BUF_DATA(rep), rep->size) != rep->size) { return; } #if defined(USBHID_NEW) || (defined(__FREEBSD__) && __FreeBSD_version >= 500111) hdata = hid_start_parse(joy->hwdata->repdesc, 1 << hid_input, rep->rid); #else hdata = hid_start_parse(joy->hwdata->repdesc, 1 << hid_input); #endif if (hdata == NULL) { fprintf(stderr, "%s: Cannot start HID parser\n", joy->hwdata->path); return; } for (nbutton = 0; hid_get_item(hdata, &hitem) > 0;) { switch (hitem.kind) { case hid_input: switch (HID_PAGE(hitem.usage)) { case HUP_GENERIC_DESKTOP: { unsigned usage = HID_USAGE(hitem.usage); int joyaxe = usage_to_joyaxe(usage); if (joyaxe >= 0) { naxe = joy->hwdata->axis_map[joyaxe]; /* scaleaxe */ v = (Sint32)hid_get_data(REP_BUF_DATA(rep), &hitem); v -= (hitem.logical_maximum + hitem.logical_minimum + 1)/2; v *= 32768/((hitem.logical_maximum - hitem.logical_minimum + 1)/2); if (v != joy->axes[naxe]) { SDL_PrivateJoystickAxis(joy, naxe, v); } } else if (usage == HUG_HAT_SWITCH) { v = (Sint32)hid_get_data(REP_BUF_DATA(rep), &hitem); SDL_PrivateJoystickHat(joy, 0, hatval_to_sdl(v)-hitem.logical_minimum); } break; } case HUP_BUTTON: v = (Sint32)hid_get_data(REP_BUF_DATA(rep), &hitem); if (joy->buttons[nbutton] != v) { SDL_PrivateJoystickButton(joy, nbutton, v); } nbutton++; break; default: continue; } break; default: break; } } hid_end_parse(hdata); return; }
/* 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. */ void SDL_SYS_JoystickUpdate(SDL_Joystick * joystick) { MMRESULT result; int i; DWORD flags[MAX_AXES] = { JOY_RETURNX, JOY_RETURNY, JOY_RETURNZ, JOY_RETURNR, JOY_RETURNU, JOY_RETURNV }; DWORD pos[MAX_AXES]; struct _transaxis *transaxis; int value, change; JOYINFOEX joyinfo; joyinfo.dwSize = sizeof(joyinfo); joyinfo.dwFlags = JOY_RETURNALL | JOY_RETURNPOVCTS; if (!joystick->hats) { joyinfo.dwFlags &= ~(JOY_RETURNPOV | JOY_RETURNPOVCTS); } result = joyGetPosEx(joystick->hwdata->id, &joyinfo); if (result != JOYERR_NOERROR) { SetMMerror("joyGetPosEx", result); return; } /* joystick motion events */ pos[0] = joyinfo.dwXpos; pos[1] = joyinfo.dwYpos; pos[2] = joyinfo.dwZpos; pos[3] = joyinfo.dwRpos; pos[4] = joyinfo.dwUpos; pos[5] = joyinfo.dwVpos; transaxis = joystick->hwdata->transaxis; for (i = 0; i < joystick->naxes; i++) { if (joyinfo.dwFlags & flags[i]) { value = (int) (((float) pos[i] + transaxis[i].offset) * transaxis[i].scale); change = (value - joystick->axes[i]); if ((change < -JOY_AXIS_THRESHOLD) || (change > JOY_AXIS_THRESHOLD)) { SDL_PrivateJoystickAxis(joystick, (Uint8) i, (Sint16) value); } } } /* joystick button events */ if (joyinfo.dwFlags & JOY_RETURNBUTTONS) { for (i = 0; i < joystick->nbuttons; ++i) { if (joyinfo.dwButtons & JOY_BUTTON_FLAG(i)) { if (!joystick->buttons[i]) { SDL_PrivateJoystickButton(joystick, (Uint8) i, SDL_PRESSED); } } else { if (joystick->buttons[i]) { SDL_PrivateJoystickButton(joystick, (Uint8) i, SDL_RELEASED); } } } } /* joystick hat events */ if (joyinfo.dwFlags & JOY_RETURNPOV) { Uint8 pos; pos = TranslatePOV(joyinfo.dwPOV); if (pos != joystick->hats[0]) { SDL_PrivateJoystickHat(joystick, 0, pos); } } }
/* 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; } } } }
void SDL_JoystickUpdate(void) { SDL_Joystick *joystick; SDL_LockJoystickList(); if (SDL_updating_joystick) { /* The joysticks are already being updated */ SDL_UnlockJoystickList(); return; } SDL_updating_joystick = SDL_TRUE; /* Make sure the list is unlocked while dispatching events to prevent application deadlocks */ SDL_UnlockJoystickList(); for (joystick = SDL_joysticks; joystick; joystick = joystick->next) { SDL_SYS_JoystickUpdate(joystick); if (joystick->force_recentering) { int i; /* Tell the app that everything is centered/unpressed... */ for (i = 0; i < joystick->naxes; i++) { if (joystick->axes[i].has_initial_value) { SDL_PrivateJoystickAxis(joystick, i, joystick->axes[i].zero); } } for (i = 0; i < joystick->nbuttons; i++) { SDL_PrivateJoystickButton(joystick, i, 0); } for (i = 0; i < joystick->nhats; i++) { SDL_PrivateJoystickHat(joystick, i, SDL_HAT_CENTERED); } joystick->force_recentering = SDL_FALSE; } } SDL_LockJoystickList(); SDL_updating_joystick = SDL_FALSE; /* If any joysticks were closed while updating, free them here */ for (joystick = SDL_joysticks; joystick; joystick = joystick->next) { if (joystick->ref_count <= 0) { SDL_JoystickClose(joystick); } } /* this needs to happen AFTER walking the joystick list above, so that any dangling hardware data from removed devices can be free'd */ SDL_SYS_JoystickDetect(); SDL_UnlockJoystickList(); }
static __inline__ void EV_HandleEvents(SDL_Joystick *joystick) { struct input_event events[32]; int i, len; int code; #ifndef NO_LOGICAL_JOYSTICKS if (SDL_joylist[joystick->index].fname == NULL) { SDL_joylist_head(i, joystick->index); return EV_HandleEvents(SDL_joylist[i].joy); } #endif while ((len=read(joystick->hwdata->fd, events, (sizeof events))) > 0) { len /= sizeof(events[0]); for ( i=0; i<len; ++i ) { code = events[i].code; switch (events[i].type) { case EV_KEY: if ( code >= BTN_MISC ) { code -= BTN_MISC; #ifndef NO_LOGICAL_JOYSTICKS if (!LogicalJoystickButton(joystick, joystick->hwdata->key_map[code], events[i].value)) #endif SDL_PrivateJoystickButton(joystick, joystick->hwdata->key_map[code], events[i].value); } break; case EV_ABS: switch (code) { case ABS_HAT0X: case ABS_HAT0Y: case ABS_HAT1X: case ABS_HAT1Y: case ABS_HAT2X: case ABS_HAT2Y: case ABS_HAT3X: case ABS_HAT3Y: code -= ABS_HAT0X; HandleHat(joystick, code/2, code%2, events[i].value); break; default: events[i].value = EV_AxisCorrect(joystick, code, events[i].value); #ifndef NO_LOGICAL_JOYSTICKS if (!LogicalJoystickAxis(joystick, joystick->hwdata->abs_map[code], events[i].value)) #endif SDL_PrivateJoystickAxis(joystick, joystick->hwdata->abs_map[code], events[i].value); break; } break; case EV_REL: switch (code) { case REL_X: case REL_Y: code -= REL_X; HandleBall(joystick, code/2, code%2, events[i].value); break; default: break; } break; default: break; } } } }
/* 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. */ void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick) { recDevice *device = joystick->hwdata; recElement *element; SInt32 value; int i; if (device->removed) /* device was unplugged; ignore it. */ { if (device->uncentered) { device->uncentered = 0; /* Tell the app that everything is centered/unpressed... */ for (i = 0; i < device->axes; i++) SDL_PrivateJoystickAxis(joystick, i, 0); for (i = 0; i < device->buttons; i++) SDL_PrivateJoystickButton(joystick, i, 0); for (i = 0; i < device->hats; i++) SDL_PrivateJoystickHat(joystick, i, SDL_HAT_CENTERED); } return; } element = device->firstAxis; i = 0; while (element) { value = HIDScaledCalibratedValue(device, element, -32768, 32767); if ( value != joystick->axes[i] ) SDL_PrivateJoystickAxis(joystick, i, value); element = element->pNext; ++i; } element = device->firstButton; i = 0; while (element) { value = HIDGetElementValue(device, element); if (value > 1) /* handle pressure-sensitive buttons */ value = 1; if ( value != joystick->buttons[i] ) SDL_PrivateJoystickButton(joystick, i, value); element = element->pNext; ++i; } element = device->firstHat; i = 0; while (element) { Uint8 pos = 0; value = HIDGetElementValue(device, element); if (element->max == 3) /* 4 position hatswitch - scale up value */ value *= 2; else if (element->max != 7) /* Neither a 4 nor 8 positions - fall back to default position (centered) */ value = -1; switch(value) { case 0: pos = SDL_HAT_UP; break; case 1: pos = SDL_HAT_RIGHTUP; break; case 2: pos = SDL_HAT_RIGHT; break; case 3: pos = SDL_HAT_RIGHTDOWN; break; case 4: pos = SDL_HAT_DOWN; break; case 5: pos = SDL_HAT_LEFTDOWN; break; case 6: pos = SDL_HAT_LEFT; break; case 7: pos = SDL_HAT_LEFTUP; break; default: /* Every other value is mapped to center. We do that because some * joysticks use 8 and some 15 for this value, and apparently * there are even more variants out there - so we try to be generous. */ pos = SDL_HAT_CENTERED; break; } if ( pos != joystick->hats[i] ) SDL_PrivateJoystickHat(joystick, i, pos); element = element->pNext; ++i; } return; }