diff --git a/src/lindbergh/evdevinput.c b/src/lindbergh/evdevinput.c index 6301fd4..4dfa26d 100644 --- a/src/lindbergh/evdevinput.c +++ b/src/lindbergh/evdevinput.c @@ -862,7 +862,7 @@ static ControllerStatus listControllers(Controllers *controllers) int controller = open(controllers->controller[i].path, O_RDONLY); if (controller < 0) { - strcpy(controllers->controller[i].name, "Unknown"); + strncpy(controllers->controller[i].name, "Unknown", SIZE); continue; } @@ -912,16 +912,26 @@ static ControllerStatus listControllers(Controllers *controllers) { if (test_bit(code, bit[EV_KEY])) { + if(controllers->controller[i].inputCount >= MAX_INPUTS) { // the number of input is limited + fprintf(stderr, "warning, maximum number of inputs reached !\n"); + break; + } + controllers->controller[i].enabled = 1; ControllerInput *controllerInput = &controllers->controller[i].inputs[controllers->controller[i].inputCount++]; controllerInput->evType = EV_KEY; controllerInput->evCode = code; controllerInput->specialFunction = NO_SPECIAL_FUNCTION; - strcpy(controllerInput->inputName, controllers->controller[i].name); + strncpy(controllerInput->inputName, controllers->controller[i].name, SIZE); strcat(controllerInput->inputName, "_"); strcat(controllerInput->inputName, codename(EV_KEY, code)); normaliseName(controllerInput->inputName); + if (snprintf(controllerInput->inputTechName, SIZE, "%s:KEY:%i", controllers->controller[i].path, code) >= 1024) + { + // hum ok, truncated value + } + strncpy(controllerInput->inputTechNegName, "-", SIZE); // unassignable value (not "" while some conf are empty) } } } @@ -939,31 +949,70 @@ static ControllerStatus listControllers(Controllers *controllers) controllerInput->evType = EV_ABS; controllerInput->evCode = code; controllerInput->specialFunction = NO_SPECIAL_FUNCTION; - strcpy(controllerInput->inputName, controllers->controller[i].name); + strncpy(controllerInput->inputName, controllers->controller[i].name, SIZE); strcat(controllerInput->inputName, "_"); strcat(controllerInput->inputName, codename(EV_ABS, code)); normaliseName(controllerInput->inputName); + if (snprintf(controllerInput->inputTechName, SIZE, "%s:ABS:%i", controllers->controller[i].path, code) >= 1024) + { + // hum ok, truncated value + } + if (snprintf(controllerInput->inputTechNegName, SIZE, "%s:ABS_NEG:%i", controllers->controller[i].path, code) >= 1024) + { + // hum ok, truncated value + } ControllerInput *minControllerInput = &controllers->controller[i].inputs[controllers->controller[i].inputCount++]; minControllerInput->evType = EV_ABS; minControllerInput->evCode = code; minControllerInput->specialFunction = ANALOGUE_TO_DIGITAL_MIN; - strcpy(minControllerInput->inputName, controllerInput->inputName); + strncpy(minControllerInput->inputName, controllerInput->inputName, SIZE); strcat(minControllerInput->inputName, "_MIN"); + if (snprintf(minControllerInput->inputTechName, SIZE, "%s:ABS:%i:MIN", controllers->controller[i].path, code) >= 1024) + { + // hum ok, truncated value + } + if (snprintf(minControllerInput->inputTechNegName, SIZE, "%s:ABS_NEG:%i:MIN", controllers->controller[i].path, code) >= + 1024) + { + // hum ok, truncated value + } ControllerInput *maxControllerInput = &controllers->controller[i].inputs[controllers->controller[i].inputCount++]; maxControllerInput->evType = EV_ABS; maxControllerInput->evCode = code; maxControllerInput->specialFunction = ANALOGUE_TO_DIGITAL_MAX; - strcpy(maxControllerInput->inputName, controllerInput->inputName); + strncpy(maxControllerInput->inputName, controllerInput->inputName, SIZE); strcat(maxControllerInput->inputName, "_MAX"); + if (snprintf(maxControllerInput->inputTechName, SIZE, "%s:ABS:%i:MAX", controllers->controller[i].path, code) >= 1024) + { + // hum ok, truncated value + } + if (snprintf(maxControllerInput->inputTechNegName, SIZE, "%s:ABS_NEG:%i:MAX", controllers->controller[i].path, code) >= + 1024) + { + // hum ok, truncated value + } + + ControllerInput *shakeControllerInput = &controllers->controller[i].inputs[controllers->controller[i].inputCount++]; + shakeControllerInput->evType = EV_ABS; + shakeControllerInput->evCode = code; + shakeControllerInput->specialFunction = ANALOGUE_SHAKE; + strncpy(shakeControllerInput->inputName, controllerInput->inputName, SIZE); + strcat(shakeControllerInput->inputName, "_SHAKE"); + if (snprintf(shakeControllerInput->inputTechName, SIZE, "%s:ABS:%i:SHAKE", controllers->controller[i].path, code) >= + 1024) + { + // hum ok, truncated value + } struct input_absinfo absoluteFeatures; ioctl(controller, EVIOCGABS(code), &absoluteFeatures); controllers->controller[i].absMin[code] = absoluteFeatures.minimum; controllers->controller[i].absMax[code] = absoluteFeatures.maximum; + } } } @@ -1066,31 +1115,67 @@ void *controllerThread(void *_args) ((double)event.value - (double)args->controller->absMin[event.code]) / ((double)args->controller->absMax[event.code] - (double)args->controller->absMin[event.code]); + if(args->controller->absTriggers[event.code].isNeg == 1) { + scaled = 1.0 - scaled; + } + if (args->controller->absTriggers[event.code].enabled) { int channel = args->controller->absTriggers[event.code].channel; - // Deadzone handling - if (scaled < analogue_deadzones[channel].start_max) + + if (args->controller->absTriggers[event.code].isAnalogue) { + // Deadzone handling + if (scaled < analogue_deadzones[channel].start_max) scaled = 0.0; - if (scaled > analogue_deadzones[channel].middle_min && scaled < analogue_deadzones[channel].middle_max) + if (scaled > analogue_deadzones[channel].middle_min && scaled < analogue_deadzones[channel].middle_max) scaled = 0.5; - if (scaled > analogue_deadzones[channel].end_min) + if (scaled > analogue_deadzones[channel].end_min) scaled = 1.0; - - setAnalogue(channel, scaled * (pow(2, jvsBits) - 1)); + setAnalogue(channel, scaled * (pow(2, jvsBits) - 1)); + } else { + setSwitch(args->controller->absTriggers[event.code].player, + args->controller->absTriggers[event.code].channel, scaled < 0.8 ? 0 : 1); + } } - if (args->controller->absTriggers[event.code].minEnabled) - { - setSwitch(args->controller->absTriggers[event.code].minPlayer, - args->controller->absTriggers[event.code].minChannel, scaled < 0.2); + if(event.value <= ((args->controller->absMin[event.code] + args->controller->absMax[event.code]) / 2)) { + if (args->controller->absTriggers[event.code].minEnabled) + { + int channel = args->controller->absTriggers[event.code].minChannel; + + if (args->controller->absTriggers[event.code].isAnalogue) { + setAnalogue(channel, scaled < 0.2 ? 0.0 : pow(2, jvsBits) * 1.0); + } else { + setSwitch(args->controller->absTriggers[event.code].minPlayer, + args->controller->absTriggers[event.code].minChannel, scaled < 0.2 ? 1 : 0); + } + } } - if (args->controller->absTriggers[event.code].maxEnabled) - { - setSwitch(args->controller->absTriggers[event.code].maxPlayer, - args->controller->absTriggers[event.code].maxChannel, scaled > 0.8); + if(event.value >= ((args->controller->absMin[event.code] + args->controller->absMax[event.code]) / 2)) { + if (args->controller->absTriggers[event.code].maxEnabled) + { + int channel = args->controller->absTriggers[event.code].maxChannel; + + if (args->controller->absTriggers[event.code].isAnalogue) { + setAnalogue(channel, scaled > 0.8 ? pow(2, jvsBits) : 0.0); + } else { + setSwitch(args->controller->absTriggers[event.code].maxPlayer, + args->controller->absTriggers[event.code].maxChannel, scaled > 0.8 ? 1 : 0); + } + } } + if (args->controller->absTriggers[event.code].shakeEnabled) + { + int channel = args->controller->absTriggers[event.code].shakeChannel; + if( (scaled > args->controller->absTriggers[event.code].shakePreviousScaled && scaled - args->controller->absTriggers[event.code].shakePreviousScaled > 0.1) || + (scaled < args->controller->absTriggers[event.code].shakePreviousScaled && -scaled + args->controller->absTriggers[event.code].shakePreviousScaled > 0.1)) { + setAnalogue(channel, 0); + } else { + setAnalogue(channel, pow(2, jvsBits) / 2); + } + args->controller->absTriggers[event.code].shakePreviousScaled = scaled; + } } break; @@ -1215,7 +1300,7 @@ ControllerStatus getArcadeInputByName(char *name, ArcadeInput *input) { if (strcmp(tempName, name) == 0) { - strcpy(input->name, arcadeInputs[index].name); + strncpy(input->name, arcadeInputs[index].name, SIZE); input->channel = arcadeInputs[index].channel; input->player = arcadeInputs[index].player; return CONTROLLER_STATUS_SUCCESS; @@ -1243,6 +1328,9 @@ ControllerStatus startControllerThreads(Controllers *controllers) controllers->controller[i].absTriggers[j].enabled = 0; controllers->controller[i].absTriggers[j].minEnabled = 0; controllers->controller[i].absTriggers[j].maxEnabled = 0; + controllers->controller[i].absTriggers[j].shakeEnabled = 0; + controllers->controller[i].absTriggers[j].isNeg = 0; + controllers->controller[i].absTriggers[j].isAnalogue = 1; } for (int j = 0; j < KEY_MAX; j++) @@ -1255,8 +1343,20 @@ ControllerStatus startControllerThreads(Controllers *controllers) for (int j = 0; j < controllers->controller[i].inputCount; j++) { char *mapping = getMapping(controllers->controller[i].inputs[j].inputName); - if (mapping == NULL) - continue; + int negabs = 0; + + if (mapping == NULL) { + // give a 2nd chance with a techninal mapping + mapping = getMapping(controllers->controller[i].inputs[j].inputTechName); + if (mapping == NULL) { + // give a 3rd change with negativ technical mapping + mapping = getMapping(controllers->controller[i].inputs[j].inputTechNegName); + negabs = 1; + if (mapping == NULL) { + continue; + } + } + } ArcadeInput input = {0}; ControllerStatus status = getArcadeInputByName(mapping, &input); @@ -1277,10 +1377,13 @@ ControllerStatus startControllerThreads(Controllers *controllers) controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].enabled = 1; controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].channel = input.channel; - strcpy(controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].name, - input.name); + strncpy(controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].name, + input.name, SIZE); controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].player = input.player; + controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].isNeg = negabs; + if (strstr(input.name, "ANALOGUE") == NULL) + controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].isAnalogue = 0; } break; @@ -1289,10 +1392,13 @@ ControllerStatus startControllerThreads(Controllers *controllers) controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].maxEnabled = 1; controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].maxChannel = input.channel; - strcpy(controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].maxName, - input.name); + strncpy(controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].maxName, + input.name, SIZE); controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].maxPlayer = input.player; + controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].isNeg = negabs; + if (strstr(input.name, "ANALOGUE") == NULL) + controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].isAnalogue = 0; } break; @@ -1301,10 +1407,25 @@ ControllerStatus startControllerThreads(Controllers *controllers) controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].minEnabled = 1; controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].minChannel = input.channel; - strcpy(controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].minName, - input.name); + strncpy(controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].minName, + input.name, SIZE); controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].minPlayer = input.player; + controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].isNeg = negabs; + if (strstr(input.name, "ANALOGUE") == NULL) + controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].isAnalogue = 0; + } + break; + + case ANALOGUE_SHAKE: + { + controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].shakeEnabled = 1; + controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].shakeChannel = + input.channel; + strncpy(controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].shakeName, + input.name, SIZE); + controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].shakePlayer = + input.player; } break; @@ -1319,8 +1440,8 @@ ControllerStatus startControllerThreads(Controllers *controllers) controllers->controller[i].keyTriggers[controllers->controller[i].inputs[j].evCode].enabled = 1; controllers->controller[i].keyTriggers[controllers->controller[i].inputs[j].evCode].channel = input.channel; - strcpy(controllers->controller[i].keyTriggers[controllers->controller[i].inputs[j].evCode].name, - input.name); + strncpy(controllers->controller[i].keyTriggers[controllers->controller[i].inputs[j].evCode].name, + input.name, SIZE); controllers->controller[i].keyTriggers[controllers->controller[i].inputs[j].evCode].player = input.player; diff --git a/src/lindbergh/evdevinput.h b/src/lindbergh/evdevinput.h index bcf30ee..bd80be6 100644 --- a/src/lindbergh/evdevinput.h +++ b/src/lindbergh/evdevinput.h @@ -2,9 +2,9 @@ #include -#define SIZE 1024 +#define SIZE 300 #define CONTROLLER_THREAD_MAX 256 - +#define MAX_INPUTS 512 typedef struct { @@ -31,6 +31,14 @@ typedef struct int maxEnabled; int isAnalogue; + int isNeg; // reversed axis + + char shakeName[SIZE]; + int shakeChannel; + int shakeEnabled; + int shakePlayer; + double shakePreviousScaled; + int isCoin; } ArcadeInput; @@ -44,12 +52,15 @@ typedef enum { NO_SPECIAL_FUNCTION = 0, ANALOGUE_TO_DIGITAL_MAX, ANALOGUE_TO_DIGITAL_MIN, - DIGITAL_TO_ANALOGUE + DIGITAL_TO_ANALOGUE, + ANALOGUE_SHAKE } SpecialFunction; typedef struct { char inputName[SIZE]; + char inputTechName[SIZE]; + char inputTechNegName[SIZE]; int evType; int evCode; SpecialFunction specialFunction; @@ -63,7 +74,7 @@ typedef struct int absMax[ABS_MAX]; int absMin[ABS_MAX]; - ControllerInput inputs[SIZE]; + ControllerInput inputs[MAX_INPUTS]; int inputCount; ArcadeInput keyTriggers[KEY_MAX]; diff --git a/src/lindbergh/lindbergh.c b/src/lindbergh/lindbergh.c index cc900ed..e143b1b 100644 --- a/src/lindbergh/lindbergh.c +++ b/src/lindbergh/lindbergh.c @@ -444,7 +444,7 @@ int main(int argc, char *argv[]) continue; } - if (strcmp(argv[i], "-z") == 0 || strcmp(argv[i], "--zink") == 0) + if (strcmp(argv[i], "-z") == 0 || strcmp(argv[i], "--ziink") == 0) { zink = 1; continue;