input: Add support for OpenFIRE lightguns (#964)

* Add OpenFIRE lightguns to guns whitelist

* Add preliminary OpenFIRE support

Guns are detected as light guns based on static VID and OpenFIRE name prefix, as the PID can be any number of different values depending on the user.

Because OpenFIRE guns can be polled through serial devices, a basic (read: hacky) heuristic is used to poll for serial port paths and send a signal to compatible guns to enable their MiSTer compatible mode.

* Tabbbbbs

* Directly open and write to file rather than rely on system echo
This commit is contained in:
That One Seong
2025-02-05 13:07:13 +00:00
committed by GitHub
parent e5269b06c1
commit e484d703f7

View File

@@ -4191,6 +4191,43 @@ static int vcs_proc(int dev, input_event *ev)
return 1;
}
void openfire_signal()
{
for (int i = 0; i < NUMDEV; i++)
{
if (input[i].vid == 0xf143 && strstr(input[i].name, "OpenFIRE ") &&
strstr(input[i].devname, "mouse") == NULL)
{
// OF generates 3 devices, so just focus on the one actual gamepad slot.
char *nameInit = input[i].name;
if (memcmp(nameInit+strlen(input[i].name)-5, "Mouse", 5) != 0 && memcmp(nameInit+strlen(input[i].name)-8, "Keyboard", 8) != 0)
{
char mname[strlen(input[i].name)];
strcpy(mname, input[i].name);
// Cleanup mname to replace offending characters not used in device filepath.
char *p;
while ((p = strchr(mname, '/'))) *p = '_';
while ((p = strchr(mname, ' '))) *p = '_';
while ((p = strchr(mname, '*'))) *p = '_';
while ((p = strchr(mname, ':'))) *p = '_';
char devicePath[29+strlen(mname)+strlen(strrchr(input[i].id, '/')+1)];
sprintf(devicePath, "/dev/serial/by-id/usb-%s_%s-if00", mname, strrchr(input[i].id, '/')+1);
FILE *deviceFile = fopen(devicePath, "r+");
if(deviceFile == NULL) {
printf("Failed to send command to %s: device path doesn't exist?\n", input[i].name);
} else {
fprintf(deviceFile, "M0x9");
printf("%s (device no. %i) set to MiSTer-compatible mode.\n", input[i].name, i);
fclose(deviceFile);
}
}
}
}
}
void check_joycon()
{
while (1)
@@ -4890,17 +4927,35 @@ int input_test(int getchar)
input_lightgun_load(n);
}
//Blamcon Lightgun
if (input[n].vid == 0x3673 && ((input[n].pid >= 0x0100 && input[n].pid <= 0x0103) || (input[n].pid >= 0x0200 && input[n].pid <= 0x0203)))
{
input[n].quirk = QUIRK_LIGHTGUN;
input[n].lightgun = 1;
input[n].guncal[0] = 0;
input[n].guncal[1] = 32767;
input[n].guncal[2] = 0;
input[n].guncal[3] = 32767;
input_lightgun_load(n);
}
//OpenFIRE Lightgun
//!Note that OF has a user-configurable PID, but the VID is reserved and every device name has the prefix "OpenFIRE"
if (input[n].vid == 0xf143 && strstr(input[n].name, "OpenFIRE "))
{
// OF generates 3 devices, so just focus on the one actual gamepad slot.
char *nameInit = input[n].name;
if(memcmp(nameInit+strlen(input[n].name)-5, "Mouse", 5) != 0 && memcmp(nameInit+strlen(input[n].name)-8, "Keyboard", 8) != 0)
{
input[n].quirk = QUIRK_LIGHTGUN;
input[n].lightgun = 1;
input[n].guncal[0] = -32767;
input[n].guncal[1] = 32767;
input[n].guncal[2] = -32767;
input[n].guncal[3] = 32767;
input_lightgun_load(n);
}
}
//Blamcon Lightgun
if (input[n].vid == 0x3673 && ((input[n].pid >= 0x0100 && input[n].pid <= 0x0103) || (input[n].pid >= 0x0200 && input[n].pid <= 0x0203)))
{
input[n].quirk = QUIRK_LIGHTGUN;
input[n].lightgun = 1;
input[n].guncal[0] = 0;
input[n].guncal[1] = 32767;
input[n].guncal[2] = 0;
input[n].guncal[3] = 32767;
input_lightgun_load(n);
}
//Retroshooter
if (input[n].vid == 0x0483 && input[n].pid >= 0x5750 && input[n].pid <= 0x5753)
@@ -4991,6 +5046,7 @@ int input_test(int getchar)
mergedevs();
check_joycon();
openfire_signal();
setup_wheels();
for (int i = 0; i < n; i++)
{