📄 sdl_sysjoystick.c
字号:
++joystick->nbuttons; } } for ( i=0; i<ABS_MAX; ++i ) { /* Skip hats */ if ( i == ABS_HAT0X ) { i = ABS_HAT3Y; continue; } if ( test_bit(i, absbit) ) { int values[5]; ioctl(fd, EVIOCGABS(i), values);#ifdef DEBUG_INPUT_EVENTS printf("Joystick has absolute axis: %x\n", i); printf("Values = { %d, %d, %d, %d, %d }\n", values[0], values[1], values[2], values[3], values[4]);#endif /* DEBUG_INPUT_EVENTS */ joystick->hwdata->abs_map[i] = joystick->naxes; if ( values[1] == values[2] ) { joystick->hwdata->abs_correct[i].used = 0; } else { joystick->hwdata->abs_correct[i].used = 1; joystick->hwdata->abs_correct[i].coef[0] = (values[2] + values[1]) / 2 - values[4]; joystick->hwdata->abs_correct[i].coef[1] = (values[2] + values[1]) / 2 + values[4]; joystick->hwdata->abs_correct[i].coef[2] = (1 << 29) / ((values[2] - values[1]) / 2 - 2 * values[4]); } ++joystick->naxes; } } for ( i=ABS_HAT0X; i <= ABS_HAT3Y; i += 2 ) { if ( test_bit(i, absbit) || test_bit(i+1, absbit) ) {#ifdef DEBUG_INPUT_EVENTS printf("Joystick has hat %d\n",(i-ABS_HAT0X)/2);#endif ++joystick->nhats; } } if ( test_bit(REL_X, relbit) || test_bit(REL_Y, relbit) ) { ++joystick->nballs; } /* Allocate data to keep track of these thingamajigs */ if ( joystick->nhats > 0 ) { if ( allocate_hatdata(joystick) < 0 ) { joystick->nhats = 0; } } if ( joystick->nballs > 0 ) { if ( allocate_balldata(joystick) < 0 ) { joystick->nballs = 0; } } } return(joystick->hwdata->is_hid);}#endif /* USE_INPUT_EVENTS */#endif /* FANCY_HATS_AND_BALLS *//* Function to open a joystick for use. The joystick to open is specified by the index field of the joystick. This should fill the nbuttons and naxes fields of the joystick structure. It returns 0, or -1 if there is an error. */int SDL_SYS_JoystickOpen(SDL_Joystick *joystick){#ifdef FANCY_HATS_AND_BALLS const char *name; int i;#endif int fd; unsigned char n; /* Open the joystick and set the joystick file descriptor */ fd = open(SDL_joylist[joystick->index], O_RDONLY, 0); if ( fd < 0 ) { SDL_SetError("Unable to open %s\n", SDL_joylist[joystick->index]); return(-1); } joystick->hwdata = (struct joystick_hwdata *) malloc(sizeof(*joystick->hwdata)); if ( joystick->hwdata == NULL ) { SDL_OutOfMemory(); close(fd); return(-1); } 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 */#ifdef USE_INPUT_EVENTS if ( ! EV_ConfigJoystick(joystick, fd) )#endif { if ( ioctl(fd, JSIOCGAXES, &n) < 0 ) { joystick->naxes = 2; } else { joystick->naxes = n; } if ( ioctl(fd, JSIOCGBUTTONS, &n) < 0 ) { joystick->nbuttons = 2; } else { joystick->nbuttons = n; }#ifdef FANCY_HATS_AND_BALLS /* Check for special joystick support */ name = SDL_SYS_JoystickName(joystick->index); for ( i=0; special_joysticks[i]; ++i ) { if (ConfigJoystick(joystick,name,special_joysticks[i])){ break; } } if ( special_joysticks[i] == NULL ) { ConfigJoystick(joystick, name, getenv("SDL_LINUX_JOYSTICK")); }#endif /* FANCY_HATS_AND_BALLS */ } return(0);}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 } }; 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; SDL_PrivateJoystickHat(stick, hat, position_map[the_hat->axis[1]][the_hat->axis[0]]); }}/* This was necessary for the Wingman Extreme Analog joystick */static __inline__void HandleAnalogHat(SDL_Joystick *stick, Uint8 hat, int value){ const Uint8 position_map[] = { SDL_HAT_UP, SDL_HAT_RIGHT, SDL_HAT_DOWN, SDL_HAT_LEFT, SDL_HAT_CENTERED }; SDL_PrivateJoystickHat(stick, hat, position_map[(value/16000)+2]);}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; 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 ) { SDL_PrivateJoystickAxis(joystick, events[i].number, events[i].value); break; } events[i].number -= joystick->naxes; if ( joystick->hwdata->analog_hat ) { other_axis = events[i].number; if ( other_axis < joystick->nhats ) { HandleAnalogHat(joystick, other_axis, events[i].value); break; } } else { 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: SDL_PrivateJoystickButton(joystick, events[i].number, events[i].value); break; default: /* ?? */ break; } } }}#ifdef USE_INPUT_EVENTSstatic __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 < -32767 ) { value = -32767; } else if ( value > 32767 ) { value = 32767; } return value;}static __inline__ void EV_HandleEvents(SDL_Joystick *joystick){ struct input_event events[32]; int i, len; int code; 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; 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); 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 /* USE_INPUT_EVENTS */void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick){ int i; #ifdef USE_INPUT_EVENTS 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){ if ( joystick->hwdata ) { close(joystick->hwdata->fd); if ( joystick->hwdata->hats ) { free(joystick->hwdata->hats); } if ( joystick->hwdata->balls ) { free(joystick->hwdata->balls); } 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]; ++i ) { free(SDL_joylist[i]); } SDL_joylist[0] = NULL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -