Support ZUIKI MasconPro (#13770)

* Add ZUIKI controller

Support version:
MasconPro

Enable rumble
Disable sensors
This commit is contained in:
zuiki_inn
2025-09-22 15:38:28 +09:00
committed by GitHub
parent 34b09be6a5
commit fc648e5546
10 changed files with 332 additions and 6 deletions

View File

@@ -734,6 +734,7 @@
<ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_xbox360w.c" /> <ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_xbox360w.c" />
<ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_xboxone.c" /> <ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_xboxone.c" />
<ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_lg4ff.c" /> <ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_lg4ff.c" />
<ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_zuiki.c" />
<ClCompile Include="..\..\src\joystick\SDL_gamepad.c" /> <ClCompile Include="..\..\src\joystick\SDL_gamepad.c" />
<ClCompile Include="..\..\src\joystick\SDL_joystick.c" /> <ClCompile Include="..\..\src\joystick\SDL_joystick.c" />
<ClCompile Include="..\..\src\joystick\SDL_steam_virtual_gamepad.c" /> <ClCompile Include="..\..\src\joystick\SDL_steam_virtual_gamepad.c" />

View File

@@ -86,6 +86,7 @@
<ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_xbox360w.c" /> <ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_xbox360w.c" />
<ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_xboxone.c" /> <ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_xboxone.c" />
<ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_lg4ff.c" /> <ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_lg4ff.c" />
<ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_zuiki.c" />
<ClCompile Include="..\..\src\joystick\SDL_gamepad.c" /> <ClCompile Include="..\..\src\joystick\SDL_gamepad.c" />
<ClCompile Include="..\..\src\joystick\SDL_joystick.c" /> <ClCompile Include="..\..\src\joystick\SDL_joystick.c" />
<ClCompile Include="..\..\src\joystick\SDL_steam_virtual_gamepad.c" /> <ClCompile Include="..\..\src\joystick\SDL_steam_virtual_gamepad.c" />

View File

@@ -624,6 +624,7 @@
<ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_xbox360w.c" /> <ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_xbox360w.c" />
<ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_xboxone.c" /> <ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_xboxone.c" />
<ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_lg4ff.c" /> <ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_lg4ff.c" />
<ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_zuiki.c" />
<ClCompile Include="..\..\src\joystick\SDL_gamepad.c" /> <ClCompile Include="..\..\src\joystick\SDL_gamepad.c" />
<ClCompile Include="..\..\src\joystick\SDL_joystick.c" /> <ClCompile Include="..\..\src\joystick\SDL_joystick.c" />
<ClCompile Include="..\..\src\joystick\SDL_steam_virtual_gamepad.c" /> <ClCompile Include="..\..\src\joystick\SDL_steam_virtual_gamepad.c" />

View File

@@ -1254,6 +1254,9 @@
<ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_lg4ff.c"> <ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_lg4ff.c">
<Filter>joystick\hidapi</Filter> <Filter>joystick\hidapi</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_zuiki.c">
<Filter>joystick\hidapi</Filter>
</ClCompile>
<ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapijoystick.c"> <ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapijoystick.c">
<Filter>joystick\hidapi</Filter> <Filter>joystick\hidapi</Filter>
</ClCompile> </ClCompile>

View File

@@ -66,6 +66,7 @@
566E26D8246274CC00718109 /* SDL_locale.c in Sources */ = {isa = PBXBuildFile; fileRef = 566E26CD246274CB00718109 /* SDL_locale.c */; }; 566E26D8246274CC00718109 /* SDL_locale.c in Sources */ = {isa = PBXBuildFile; fileRef = 566E26CD246274CB00718109 /* SDL_locale.c */; };
566E26E1246274CC00718109 /* SDL_syslocale.h in Headers */ = {isa = PBXBuildFile; fileRef = 566E26CE246274CC00718109 /* SDL_syslocale.h */; }; 566E26E1246274CC00718109 /* SDL_syslocale.h in Headers */ = {isa = PBXBuildFile; fileRef = 566E26CE246274CC00718109 /* SDL_syslocale.h */; };
56A2373329F9C113003CCA5F /* SDL_sysrwlock.c in Sources */ = {isa = PBXBuildFile; fileRef = 56A2373229F9C113003CCA5F /* SDL_sysrwlock.c */; }; 56A2373329F9C113003CCA5F /* SDL_sysrwlock.c in Sources */ = {isa = PBXBuildFile; fileRef = 56A2373229F9C113003CCA5F /* SDL_sysrwlock.c */; };
63124A422E5C357500A53610 /* SDL_hidapi_zuiki.c in Sources */ = {isa = PBXBuildFile; fileRef = 63124A412E5C357500A53610 /* SDL_hidapi_zuiki.c */; };
6312C66D2B42341400A7BB00 /* SDL_murmur3.c in Sources */ = {isa = PBXBuildFile; fileRef = 6312C66C2B42341400A7BB00 /* SDL_murmur3.c */; }; 6312C66D2B42341400A7BB00 /* SDL_murmur3.c in Sources */ = {isa = PBXBuildFile; fileRef = 6312C66C2B42341400A7BB00 /* SDL_murmur3.c */; };
63134A252A7902FD0021E9A6 /* SDL_pen_c.h in Headers */ = {isa = PBXBuildFile; fileRef = 63134A232A7902FD0021E9A6 /* SDL_pen_c.h */; }; 63134A252A7902FD0021E9A6 /* SDL_pen_c.h in Headers */ = {isa = PBXBuildFile; fileRef = 63134A232A7902FD0021E9A6 /* SDL_pen_c.h */; };
63134A262A7902FD0021E9A6 /* SDL_pen.c in Sources */ = {isa = PBXBuildFile; fileRef = 63134A242A7902FD0021E9A6 /* SDL_pen.c */; }; 63134A262A7902FD0021E9A6 /* SDL_pen.c in Sources */ = {isa = PBXBuildFile; fileRef = 63134A242A7902FD0021E9A6 /* SDL_pen.c */; };
@@ -614,6 +615,7 @@
566E26CD246274CB00718109 /* SDL_locale.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_locale.c; path = locale/SDL_locale.c; sourceTree = "<group>"; }; 566E26CD246274CB00718109 /* SDL_locale.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_locale.c; path = locale/SDL_locale.c; sourceTree = "<group>"; };
566E26CE246274CC00718109 /* SDL_syslocale.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_syslocale.h; path = locale/SDL_syslocale.h; sourceTree = "<group>"; }; 566E26CE246274CC00718109 /* SDL_syslocale.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_syslocale.h; path = locale/SDL_syslocale.h; sourceTree = "<group>"; };
56A2373229F9C113003CCA5F /* SDL_sysrwlock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_sysrwlock.c; sourceTree = "<group>"; }; 56A2373229F9C113003CCA5F /* SDL_sysrwlock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_sysrwlock.c; sourceTree = "<group>"; };
63124A412E5C357500A53610 /* SDL_hidapi_zuiki.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_hidapi_zuiki.c; sourceTree = "<group>"; };
6312C66C2B42341400A7BB00 /* SDL_murmur3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_murmur3.c; sourceTree = "<group>"; }; 6312C66C2B42341400A7BB00 /* SDL_murmur3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_murmur3.c; sourceTree = "<group>"; };
63134A232A7902FD0021E9A6 /* SDL_pen_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_pen_c.h; sourceTree = "<group>"; }; 63134A232A7902FD0021E9A6 /* SDL_pen_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_pen_c.h; sourceTree = "<group>"; };
63134A242A7902FD0021E9A6 /* SDL_pen.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_pen.c; sourceTree = "<group>"; }; 63134A242A7902FD0021E9A6 /* SDL_pen.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_pen.c; sourceTree = "<group>"; };
@@ -1964,6 +1966,7 @@
A7D8A7C223E2513E00DCD162 /* SDL_hidapi_xbox360.c */, A7D8A7C223E2513E00DCD162 /* SDL_hidapi_xbox360.c */,
A7D8A7C823E2513E00DCD162 /* SDL_hidapi_xbox360w.c */, A7D8A7C823E2513E00DCD162 /* SDL_hidapi_xbox360w.c */,
A7D8A7C523E2513E00DCD162 /* SDL_hidapi_xboxone.c */, A7D8A7C523E2513E00DCD162 /* SDL_hidapi_xboxone.c */,
63124A412E5C357500A53610 /* SDL_hidapi_zuiki.c */,
A7D8A7C423E2513E00DCD162 /* SDL_hidapijoystick.c */, A7D8A7C423E2513E00DCD162 /* SDL_hidapijoystick.c */,
A7D8A7C723E2513E00DCD162 /* SDL_hidapijoystick_c.h */, A7D8A7C723E2513E00DCD162 /* SDL_hidapijoystick_c.h */,
); );
@@ -3116,6 +3119,7 @@
00004D0B73767647AD550000 /* SDL_asyncio_generic.c in Sources */, 00004D0B73767647AD550000 /* SDL_asyncio_generic.c in Sources */,
0000A03C0F32C43816F40000 /* SDL_asyncio_windows_ioring.c in Sources */, 0000A03C0F32C43816F40000 /* SDL_asyncio_windows_ioring.c in Sources */,
0000A877C7DB9FA935FC0000 /* SDL_uikitpen.m in Sources */, 0000A877C7DB9FA935FC0000 /* SDL_uikitpen.m in Sources */,
63124A422E5C357500A53610 /* SDL_hidapi_zuiki.c in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };

View File

@@ -1776,6 +1776,18 @@ extern "C" {
*/ */
#define SDL_HINT_JOYSTICK_HIDAPI_SINPUT "SDL_JOYSTICK_HIDAPI_SINPUT" #define SDL_HINT_JOYSTICK_HIDAPI_SINPUT "SDL_JOYSTICK_HIDAPI_SINPUT"
/**
* A variable controlling whether the HIDAPI driver for ZUIKI controllers
* should be used.
*
* This variable can be set to the following values:
*
* "0" - HIDAPI driver is not used. "1" - HIDAPI driver is used.
*
* The default is the value of SDL_HINT_JOYSTICK_HIDAPI
*/
#define SDL_HINT_JOYSTICK_HIDAPI_ZUIKI "SDL_JOYSTICK_HIDAPI_ZUIKI"
/** /**
* A variable controlling whether the HIDAPI driver for Flydigi controllers * A variable controlling whether the HIDAPI driver for Flydigi controllers
* should be used. * should be used.
@@ -4264,7 +4276,7 @@ extern "C" {
* *
* \since This hint is available since SDL 3.2.0. * \since This hint is available since SDL 3.2.0.
*/ */
#define SDL_HINT_WINDOWS_GAMEINPUT "SDL_WINDOWS_GAMEINPUT" #define SDL_HINT_WINDOWS_GAMEINPUT "SDL_WINDOWS_GAMEINPUT"
/** /**
* A variable controlling whether raw keyboard events are used on Windows. * A variable controlling whether raw keyboard events are used on Windows.
@@ -4309,7 +4321,7 @@ extern "C" {
* *
* \since This hint is available since SDL 3.2.0. * \since This hint is available since SDL 3.2.0.
*/ */
#define SDL_HINT_WINDOWS_INTRESOURCE_ICON "SDL_WINDOWS_INTRESOURCE_ICON" #define SDL_HINT_WINDOWS_INTRESOURCE_ICON "SDL_WINDOWS_INTRESOURCE_ICON"
/** /**
* A variable to specify custom icon resource id from RC file on Windows * A variable to specify custom icon resource id from RC file on Windows
@@ -4612,7 +4624,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_ResetHints(void);
* \sa SDL_SetHint * \sa SDL_SetHint
* \sa SDL_SetHintWithPriority * \sa SDL_SetHintWithPriority
*/ */
extern SDL_DECLSPEC const char * SDLCALL SDL_GetHint(const char *name); extern SDL_DECLSPEC const char *SDLCALL SDL_GetHint(const char *name);
/** /**
* Get the boolean value of a hint variable. * Get the boolean value of a hint variable.
@@ -4688,8 +4700,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_AddHintCallback(const char *name, SDL_HintC
* \sa SDL_AddHintCallback * \sa SDL_AddHintCallback
*/ */
extern SDL_DECLSPEC void SDLCALL SDL_RemoveHintCallback(const char *name, extern SDL_DECLSPEC void SDLCALL SDL_RemoveHintCallback(const char *name,
SDL_HintCallback callback, SDL_HintCallback callback,
void *userdata); void *userdata);
/* Ends C function definitions when using C++ */ /* Ends C function definitions when using C++ */
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -0,0 +1,297 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 2025 Zuiki Inc.
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifdef SDL_JOYSTICK_HIDAPI
#include "../SDL_sysjoystick.h"
#include "SDL_hidapijoystick_c.h"
#include "SDL_hidapi_rumble.h"
#ifdef SDL_JOYSTICK_HIDAPI_ZUIKI
// Define this if you want to log all packets from the controller
#if 0
#define DEBUG_ZUIKI_PROTOCOL
#endif
typedef struct
{
Uint8 last_state[USB_PACKET_LENGTH];
} SDL_DriverZUIKI_Context;
static void HIDAPI_DriverZUIKI_RegisterHints(SDL_HintCallback callback, void *userdata)
{
SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_ZUIKI, callback, userdata);
}
static void HIDAPI_DriverZUIKI_UnregisterHints(SDL_HintCallback callback, void *userdata)
{
SDL_RemoveHintCallback(SDL_HINT_JOYSTICK_HIDAPI_ZUIKI, callback, userdata);
}
static bool HIDAPI_DriverZUIKI_IsEnabled(void)
{
return SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_ZUIKI, SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI, SDL_HIDAPI_DEFAULT));
}
static bool HIDAPI_DriverZUIKI_IsSupportedDevice(SDL_HIDAPI_Device *device, const char *name, SDL_GamepadType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol)
{
if (vendor_id == USB_VENDOR_ZUIKI) {
switch (product_id) {
case USB_PRODUCT_ZUIKI_MASCON_PRO:
return true;
default:
break;
}
}
return false;
}
static bool HIDAPI_DriverZUIKI_InitDevice(SDL_HIDAPI_Device *device)
{
SDL_DriverZUIKI_Context *ctx = (SDL_DriverZUIKI_Context *)SDL_calloc(1, sizeof(*ctx));
if (!ctx) {
return false;
}
device->context = ctx;
if (device->product_id == USB_PRODUCT_ZUIKI_MASCON_PRO) {
HIDAPI_SetDeviceName(device, "ZUIKI MASCON PRO");
}
return HIDAPI_JoystickConnected(device, NULL);
}
static int HIDAPI_DriverZUIKI_GetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id)
{
return -1;
}
static void HIDAPI_DriverZUIKI_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index)
{
}
#ifndef DEG2RAD
#define DEG2RAD(x) ((float)(x) * (float)(SDL_PI_F / 180.f))
#endif
static bool HIDAPI_DriverZUIKI_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
{
SDL_DriverZUIKI_Context *ctx = (SDL_DriverZUIKI_Context *)device->context;
SDL_AssertJoysticksLocked();
SDL_zeroa(ctx->last_state);
joystick->nbuttons = 11;
joystick->naxes = SDL_GAMEPAD_AXIS_COUNT;
joystick->nhats = 1;
return true;
}
static bool HIDAPI_DriverZUIKI_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
{
Uint8 rumble_packet[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
rumble_packet[4] = low_frequency_rumble >> 8;
rumble_packet[5] = high_frequency_rumble >> 8;
if (SDL_HIDAPI_SendRumble(device, rumble_packet, sizeof(rumble_packet)) != sizeof(rumble_packet)) {
return SDL_SetError("Couldn't send rumble packet");
}
return true;
}
static bool HIDAPI_DriverZUIKI_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble)
{
return SDL_Unsupported();
}
static Uint32 HIDAPI_DriverZUIKI_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
{
Uint32 caps = 0;
caps |= SDL_JOYSTICK_CAP_RUMBLE;
return caps;
}
static bool HIDAPI_DriverZUIKI_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
{
return SDL_Unsupported();
}
static bool HIDAPI_DriverZUIKI_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size)
{
if (SDL_HIDAPI_SendRumble(device, data, size) != size) {
return SDL_SetError("Couldn't send rumble packet");
}
return true;
}
static bool HIDAPI_DriverZUIKI_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, bool enabled)
{
return SDL_Unsupported();
}
static void HIDAPI_DriverZUIKI_HandleOldStatePacket(SDL_Joystick *joystick, SDL_DriverZUIKI_Context *ctx, Uint8 *data, int size)
{
Sint16 axis;
Uint64 timestamp = SDL_GetTicksNS();
if (ctx->last_state[2] != data[2]) {
Uint8 hat;
switch (data[2]) {
case 0:
hat = SDL_HAT_UP;
break;
case 1:
hat = SDL_HAT_RIGHTUP;
break;
case 2:
hat = SDL_HAT_RIGHT;
break;
case 3:
hat = SDL_HAT_RIGHTDOWN;
break;
case 4:
hat = SDL_HAT_DOWN;
break;
case 5:
hat = SDL_HAT_LEFTDOWN;
break;
case 6:
hat = SDL_HAT_LEFT;
break;
case 7:
hat = SDL_HAT_LEFTUP;
break;
default:
hat = SDL_HAT_CENTERED;
break;
}
SDL_SendJoystickHat(timestamp, joystick, 0, hat);
}
if (ctx->last_state[0] != data[0]) {
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_NORTH, ((data[0] & 0x01) != 0));
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_EAST, ((data[0] & 0x02) != 0));
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SOUTH, ((data[0] & 0x04) != 0));
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_WEST, ((data[0] & 0x08) != 0));
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_SHOULDER, ((data[0] & 0x10) != 0));
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER, ((data[0] & 0x20) != 0));
SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFT_TRIGGER, (data[0] & 0x40) ? SDL_MAX_SINT16 : SDL_MIN_SINT16);
SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER, (data[0] & 0x80) ? SDL_MAX_SINT16 : SDL_MIN_SINT16);
}
if (ctx->last_state[1] != data[1]) {
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_BACK, ((data[1] & 0x01) != 0));
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_START, ((data[1] & 0x02) != 0));
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_STICK, ((data[1] & 0x04) != 0));
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_STICK, ((data[1] & 0x08) != 0));
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_GUIDE, ((data[1] & 0x10) != 0));
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_MISC1, ((data[1] & 0x20) != 0));
/* todo for switch C key */
}
#define READ_STICK_AXIS(offset) \
(data[offset] == 0x7f ? 0 : (Sint16)HIDAPI_RemapVal((float)((int)data[offset] - 0x7f), -0x7f, 0xff - 0x7f, SDL_MIN_SINT16, SDL_MAX_SINT16))
{
axis = READ_STICK_AXIS(3);
SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFTX, axis);
axis = READ_STICK_AXIS(4);
SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFTY, axis);
axis = READ_STICK_AXIS(5);
SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHTX, axis);
axis = READ_STICK_AXIS(6);
SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHTY, axis);
}
#undef READ_STICK_AXIS
SDL_memcpy(ctx->last_state, data, SDL_min(size, sizeof(ctx->last_state)));
}
static bool HIDAPI_DriverZUIKI_UpdateDevice(SDL_HIDAPI_Device *device)
{
SDL_DriverZUIKI_Context *ctx = (SDL_DriverZUIKI_Context *)device->context;
SDL_Joystick *joystick = NULL;
Uint8 data[USB_PACKET_LENGTH];
int size = 0;
if (device->num_joysticks > 0) {
joystick = SDL_GetJoystickFromID(device->joysticks[0]);
} else {
return false;
}
while ((size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) {
#ifdef DEBUG_ZUIKI_PROTOCOL
HIDAPI_DumpPacket("ZUIKI packet: size = %d", data, size);
#endif
if (!joystick) {
continue;
}
if (size == 8) {
HIDAPI_DriverZUIKI_HandleOldStatePacket(joystick, ctx, data, size);
}
}
if (size < 0) {
// Read error, device is disconnected
HIDAPI_JoystickDisconnected(device, device->joysticks[0]);
}
return (size >= 0);
}
static void HIDAPI_DriverZUIKI_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
{
}
static void HIDAPI_DriverZUIKI_FreeDevice(SDL_HIDAPI_Device *device)
{
}
SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverZUIKI = {
SDL_HINT_JOYSTICK_HIDAPI_ZUIKI,
true,
HIDAPI_DriverZUIKI_RegisterHints,
HIDAPI_DriverZUIKI_UnregisterHints,
HIDAPI_DriverZUIKI_IsEnabled,
HIDAPI_DriverZUIKI_IsSupportedDevice,
HIDAPI_DriverZUIKI_InitDevice,
HIDAPI_DriverZUIKI_GetDevicePlayerIndex,
HIDAPI_DriverZUIKI_SetDevicePlayerIndex,
HIDAPI_DriverZUIKI_UpdateDevice,
HIDAPI_DriverZUIKI_OpenJoystick,
HIDAPI_DriverZUIKI_RumbleJoystick,
HIDAPI_DriverZUIKI_RumbleJoystickTriggers,
HIDAPI_DriverZUIKI_GetJoystickCapabilities,
HIDAPI_DriverZUIKI_SetJoystickLED,
HIDAPI_DriverZUIKI_SendJoystickEffect,
HIDAPI_DriverZUIKI_SetJoystickSensorsEnabled,
HIDAPI_DriverZUIKI_CloseJoystick,
HIDAPI_DriverZUIKI_FreeDevice,
};
#endif // SDL_JOYSTICK_HIDAPI_ZUIKI
#endif // SDL_JOYSTICK_HIDAPI

View File

@@ -103,6 +103,9 @@ static SDL_HIDAPI_DeviceDriver *SDL_HIDAPI_drivers[] = {
#ifdef SDL_JOYSTICK_HIDAPI_SINPUT #ifdef SDL_JOYSTICK_HIDAPI_SINPUT
&SDL_HIDAPI_DriverSInput, &SDL_HIDAPI_DriverSInput,
#endif #endif
#ifdef SDL_JOYSTICK_HIDAPI_ZUIKI
&SDL_HIDAPI_DriverZUIKI,
#endif
}; };
static int SDL_HIDAPI_numdrivers = 0; static int SDL_HIDAPI_numdrivers = 0;
static SDL_AtomicInt SDL_HIDAPI_updating_devices; static SDL_AtomicInt SDL_HIDAPI_updating_devices;

View File

@@ -48,6 +48,7 @@
#define SDL_JOYSTICK_HIDAPI_FLYDIGI #define SDL_JOYSTICK_HIDAPI_FLYDIGI
#define SDL_JOYSTICK_HIDAPI_GIP #define SDL_JOYSTICK_HIDAPI_GIP
#define SDL_JOYSTICK_HIDAPI_SINPUT #define SDL_JOYSTICK_HIDAPI_SINPUT
#define SDL_JOYSTICK_HIDAPI_ZUIKI
// Joystick capability definitions // Joystick capability definitions
#define SDL_JOYSTICK_CAP_MONO_LED 0x00000001 #define SDL_JOYSTICK_CAP_MONO_LED 0x00000001
@@ -171,6 +172,7 @@ extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverLg4ff;
extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_Driver8BitDo; extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_Driver8BitDo;
extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverFlydigi; extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverFlydigi;
extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSInput; extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSInput;
extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverZUIKI;
// Return true if a HID device is present and supported as a joystick of the given type // Return true if a HID device is present and supported as a joystick of the given type
extern bool HIDAPI_IsDeviceTypePresent(SDL_GamepadType type); extern bool HIDAPI_IsDeviceTypePresent(SDL_GamepadType type);

View File

@@ -60,6 +60,7 @@
#define USB_VENDOR_VALVE 0x28de #define USB_VENDOR_VALVE 0x28de
#define USB_VENDOR_ZEROPLUS 0x0c12 #define USB_VENDOR_ZEROPLUS 0x0c12
#define USB_VENDOR_RASPBERRYPI 0x2e8a // Commercial hardware from various companies are registered under this VID #define USB_VENDOR_RASPBERRYPI 0x2e8a // Commercial hardware from various companies are registered under this VID
#define USB_VENDOR_ZUIKI 0x33dd
#define USB_PRODUCT_8BITDO_SF30_PRO 0x6000 // B + START #define USB_PRODUCT_8BITDO_SF30_PRO 0x6000 // B + START
#define USB_PRODUCT_8BITDO_SF30_PRO_BT 0x6100 // B + START #define USB_PRODUCT_8BITDO_SF30_PRO_BT 0x6100 // B + START
@@ -170,7 +171,8 @@
#define USB_PRODUCT_HANDHELDLEGEND_SINPUT_GENERIC 0x10c6 #define USB_PRODUCT_HANDHELDLEGEND_SINPUT_GENERIC 0x10c6
#define USB_PRODUCT_HANDHELDLEGEND_PROGCC 0x10df #define USB_PRODUCT_HANDHELDLEGEND_PROGCC 0x10df
#define USB_PRODUCT_HANDHELDLEGEND_GCULTIMATE 0x10dd #define USB_PRODUCT_HANDHELDLEGEND_GCULTIMATE 0x10dd
#define USB_PRODUCT_BONZIRICHANNEL_FIREBIRD 0x10e0 #define USB_PRODUCT_BONZIRICHANNEL_FIREBIRD 0x10e0
#define USB_PRODUCT_ZUIKI_MASCON_PRO 0x0006
#define USB_PRODUCT_VOIDGAMING_PS4FIREBIRD 0x10e5 #define USB_PRODUCT_VOIDGAMING_PS4FIREBIRD 0x10e5
// USB usage pages // USB usage pages