📄 sdl_sysjoystick.c
字号:
#endif if ( fd < 0 ) { SDL_SetError("Unable to open %s\n", SDL_joylist[joystick->index]); return(-1); } joystick->hwdata = (struct joystick_hwdata *) SDL_malloc(sizeof(*joystick->hwdata)); if ( joystick->hwdata == NULL ) { SDL_OutOfMemory(); close(fd); return(-1); } SDL_memset(joystick->hwdata, 0, sizeof(*joystick->hwdata)); joystick->hwdata->fd = fd; /* Set the joystick to non-blocking read mode */ fcntl(fd, F_SETFL, O_NONBLOCK); /* Get the number of buttons and axes on the joystick */#ifndef NO_LOGICAL_JOYSTICKS if (realjoy) ConfigLogicalJoystick(joystick); else#endif#if SDL_INPUT_LINUXEV if ( ! EV_ConfigJoystick(joystick, fd) )#endif JS_ConfigJoystick(joystick, fd); return(0);}#ifndef NO_LOGICAL_JOYSTICKSstatic SDL_Joystick* FindLogicalJoystick( SDL_Joystick *joystick, struct joystick_logical_mapping* v){ SDL_Joystick *logicaljoy; register int i; i = joystick->index; logicaljoy = NULL; /* get the fake joystick that will receive the event */ for(;;) { if (SDL_joylist[i].logicalno == v->njoy) { logicaljoy = SDL_joylist[i].joy; break; } if (SDL_joylist[i].next == 0) break; i = SDL_joylist[i].next; } return logicaljoy;}static int LogicalJoystickButton( SDL_Joystick *joystick, Uint8 button, Uint8 state){ struct joystick_logical_mapping* buttons; 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 */ buttons = SDL_joylist[joystick->index].map->buttonmap+button; logicaljoy = FindLogicalJoystick(joystick, buttons); if (logicaljoy == NULL) return 1; SDL_PrivateJoystickButton(logicaljoy, buttons->nthing, state); return 1;}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;}#endif /* USE_LOGICAL_JOYSTICKS */static __inline__void HandleHat(SDL_Joystick *stick, Uint8 hat, int axis, int value){ struct hwdata_hat *the_hat; const Uint8 position_map[3][3] = { { SDL_HAT_LEFTUP, SDL_HAT_UP, SDL_HAT_RIGHTUP }, { SDL_HAT_LEFT, SDL_HAT_CENTERED, SDL_HAT_RIGHT }, { SDL_HAT_LEFTDOWN, SDL_HAT_DOWN, SDL_HAT_RIGHTDOWN } }; SDL_logical_joydecl(SDL_Joystick *logicaljoy = NULL); SDL_logical_joydecl(struct joystick_logical_mapping* hats = NULL); the_hat = &stick->hwdata->hats[hat]; if ( value < 0 ) { value = 0; } else if ( value == 0 ) { value = 1; } else if ( value > 0 ) { value = 2; } if ( value != the_hat->axis[axis] ) { the_hat->axis[axis] = value;#ifndef NO_LOGICAL_JOYSTICKS /* if there's no map then this is just a regular joystick */ if (SDL_joylist[stick->index].map != NULL) { /* get the fake joystick that will receive the event */ hats = SDL_joylist[stick->index].map->hatmap+hat; logicaljoy = FindLogicalJoystick(stick, hats); } if (logicaljoy) { stick = logicaljoy; hat = hats->nthing; }#endif /* USE_LOGICAL_JOYSTICKS */ SDL_PrivateJoystickHat(stick, hat, position_map[the_hat->axis[1]][the_hat->axis[0]]); }}static __inline__void HandleBall(SDL_Joystick *stick, Uint8 ball, int axis, int value){ stick->hwdata->balls[ball].axis[axis] += value;}/* 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; } } }}#if SDL_INPUT_LINUXEVstatic __inline__ int EV_AxisCorrect(SDL_Joystick *joystick, int which, int value){ struct axis_correct *correct; correct = &joystick->hwdata->abs_correct[which]; if ( correct->used ) { if ( value > correct->coef[0] ) { if ( value < correct->coef[1] ) { return 0; } value -= correct->coef[1]; } else { value -= correct->coef[0]; } value *= correct->coef[2]; value >>= 14; } /* Clamp and return */ if ( value < -32768 ) return -32768; if ( value > 32767 ) return 32767; return value;}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; } } }}#endif /* SDL_INPUT_LINUXEV */void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick){ int i; #if SDL_INPUT_LINUXEV if ( joystick->hwdata->is_hid ) EV_HandleEvents(joystick); else#endif JS_HandleEvents(joystick); /* Deliver ball motion updates */ for ( i=0; i<joystick->nballs; ++i ) { int xrel, yrel; xrel = joystick->hwdata->balls[i].axis[0]; yrel = joystick->hwdata->balls[i].axis[1]; if ( xrel || yrel ) { joystick->hwdata->balls[i].axis[0] = 0; joystick->hwdata->balls[i].axis[1] = 0; SDL_PrivateJoystickBall(joystick, (Uint8)i, xrel, yrel); } }}/* Function to close a joystick after use */void SDL_SYS_JoystickClose(SDL_Joystick *joystick){#ifndef NO_LOGICAL_JOYSTICKS register int i; if (SDL_joylist[joystick->index].fname == NULL) { SDL_joylist_head(i, joystick->index); SDL_JoystickClose(SDL_joylist[i].joy); }#endif if ( joystick->hwdata ) {#ifndef NO_LOGICAL_JOYSTICKS if (SDL_joylist[joystick->index].fname != NULL)#endif close(joystick->hwdata->fd); if ( joystick->hwdata->hats ) { SDL_free(joystick->hwdata->hats); } if ( joystick->hwdata->balls ) { SDL_free(joystick->hwdata->balls); } SDL_free(joystick->hwdata); joystick->hwdata = NULL; }}/* Function to perform any system-specific joystick related cleanup */void SDL_SYS_JoystickQuit(void){ int i; for ( i=0; SDL_joylist[i].fname; ++i ) { SDL_free(SDL_joylist[i].fname); } SDL_joylist[0].fname = NULL;}#endif /* SDL_JOYSTICK_LINUX */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -