mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-05-25 22:19:10 +00:00
Added ball, touchpad, and sensor support for virtual joysticks
Fixes https://github.com/libsdl-org/SDL/issues/9542
This commit is contained in:
parent
d231edd2ad
commit
c1ba31118b
12 changed files with 494 additions and 41 deletions
|
@ -1240,8 +1240,8 @@ extern DECLSPEC int SDLCALL SDL_GetNumGamepadTouchpadFingers(SDL_Gamepad *gamepa
|
|||
* \param touchpad a touchpad
|
||||
* \param finger a finger
|
||||
* \param state filled with state
|
||||
* \param x filled with x position
|
||||
* \param y filled with y position
|
||||
* \param x filled with x position, normalized 0 to 1, with the origin in the upper left
|
||||
* \param y filled with y position, normalized 0 to 1, with the origin in the upper left
|
||||
* \param pressure filled with pressure value
|
||||
* \returns 0 on success or a negative error code on failure; call
|
||||
* SDL_GetError() for more information.
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include <SDL3/SDL_mutex.h>
|
||||
#include <SDL3/SDL_power.h>
|
||||
#include <SDL3/SDL_properties.h>
|
||||
#include <SDL3/SDL_sensor.h>
|
||||
|
||||
#include <SDL3/SDL_begin_code.h>
|
||||
/* Set up for C function definitions, even when using C++ */
|
||||
|
@ -391,28 +392,62 @@ extern DECLSPEC SDL_Joystick *SDLCALL SDL_GetJoystickFromInstanceID(SDL_Joystick
|
|||
extern DECLSPEC SDL_Joystick *SDLCALL SDL_GetJoystickFromPlayerIndex(int player_index);
|
||||
|
||||
/**
|
||||
* The structure that defines an extended virtual joystick description
|
||||
* The structure that describes a virtual joystick touchpad.
|
||||
*
|
||||
* \since This struct is available since SDL 3.0.0.
|
||||
*
|
||||
* \sa SDL_VirtualJoystickDesc
|
||||
*/
|
||||
typedef struct SDL_VirtualJoystickTouchpadDesc
|
||||
{
|
||||
Uint16 nfingers; /**< the number of simultaneous fingers on this touchpad */
|
||||
Uint16 padding[3];
|
||||
} SDL_VirtualJoystickTouchpadDesc;
|
||||
|
||||
/**
|
||||
* The structure that describes a virtual joystick sensor.
|
||||
*
|
||||
* \since This struct is available since SDL 3.0.0.
|
||||
*
|
||||
* \sa SDL_VirtualJoystickDesc
|
||||
*/
|
||||
typedef struct SDL_VirtualJoystickSensorDesc
|
||||
{
|
||||
SDL_SensorType type; /**< the type of this sensor */
|
||||
float rate; /**< the update frequency of this sensor, may be 0.0f */
|
||||
} SDL_VirtualJoystickSensorDesc;
|
||||
|
||||
/**
|
||||
* The structure that describes a virtual joystick.
|
||||
*
|
||||
* All elements of this structure are optional and can be left 0.
|
||||
*
|
||||
* \since This struct is available since SDL 3.0.0.
|
||||
*
|
||||
* \sa SDL_AttachVirtualJoystick
|
||||
* \sa SDL_VirtualJoystickSensorDesc
|
||||
* \sa SDL_VirtualJoystickTouchpadDesc
|
||||
*/
|
||||
typedef struct SDL_VirtualJoystickDesc
|
||||
{
|
||||
Uint16 type; /**< `SDL_JoystickType` */
|
||||
Uint16 naxes; /**< the number of axes on this joystick */
|
||||
Uint16 nbuttons; /**< the number of buttons on this joystick */
|
||||
Uint16 nhats; /**< the number of hats on this joystick */
|
||||
Uint16 padding; /**< unused */
|
||||
Uint16 vendor_id; /**< the USB vendor ID of this joystick */
|
||||
Uint16 product_id; /**< the USB product ID of this joystick */
|
||||
Uint16 padding; /**< unused */
|
||||
Uint16 naxes; /**< the number of axes on this joystick */
|
||||
Uint16 nbuttons; /**< the number of buttons on this joystick */
|
||||
Uint16 nballs; /**< the number of balls on this joystick */
|
||||
Uint16 nhats; /**< the number of hats on this joystick */
|
||||
Uint16 ntouchpads; /**< the number of touchpads on this joystick, requires `touchpads` to point at valid descriptions */
|
||||
Uint16 nsensors; /**< the number of sensors on this joystick, requires `sensors` to point at valid descriptions */
|
||||
Uint16 padding2[2]; /**< unused */
|
||||
Uint32 button_mask; /**< A mask of which buttons are valid for this controller
|
||||
e.g. (1u << SDL_GAMEPAD_BUTTON_SOUTH) */
|
||||
e.g. (1 << SDL_GAMEPAD_BUTTON_SOUTH) */
|
||||
Uint32 axis_mask; /**< A mask of which axes are valid for this controller
|
||||
e.g. (1u << SDL_GAMEPAD_AXIS_LEFTX) */
|
||||
e.g. (1 << SDL_GAMEPAD_AXIS_LEFTX) */
|
||||
const char *name; /**< the name of the joystick */
|
||||
const SDL_VirtualJoystickTouchpadDesc *touchpads; /**< A pointer to an array of touchpad descriptions, required if `ntouchpads` is > 0 */
|
||||
const SDL_VirtualJoystickSensorDesc *sensors; /**< A pointer to an array of sensor descriptions, required if `nsensors` is > 0 */
|
||||
|
||||
void *userdata; /**< User data pointer passed to callbacks */
|
||||
void (SDLCALL *Update)(void *userdata); /**< Called when the joystick state should be updated */
|
||||
|
@ -421,6 +456,7 @@ typedef struct SDL_VirtualJoystickDesc
|
|||
int (SDLCALL *RumbleTriggers)(void *userdata, Uint16 left_rumble, Uint16 right_rumble); /**< Implements SDL_RumbleJoystickTriggers() */
|
||||
int (SDLCALL *SetLED)(void *userdata, Uint8 red, Uint8 green, Uint8 blue); /**< Implements SDL_SetJoystickLED() */
|
||||
int (SDLCALL *SendEffect)(void *userdata, const void *data, int size); /**< Implements SDL_SendJoystickEffect() */
|
||||
int (SDLCALL *SetSensorsEnabled)(void *userdata, SDL_bool enabled); /**< Implements SDL_SetGamepadSensorEnabled() */
|
||||
} SDL_VirtualJoystickDesc;
|
||||
|
||||
/**
|
||||
|
@ -461,7 +497,7 @@ extern DECLSPEC int SDLCALL SDL_DetachVirtualJoystick(SDL_JoystickID instance_id
|
|||
extern DECLSPEC SDL_bool SDLCALL SDL_IsJoystickVirtual(SDL_JoystickID instance_id);
|
||||
|
||||
/**
|
||||
* Set values on an opened, virtual-joystick's axis.
|
||||
* Set the state of an axis on an opened virtual joystick.
|
||||
*
|
||||
* Please note that values set here will not be applied until the next call to
|
||||
* SDL_UpdateJoysticks, which can either be called directly, or can be called
|
||||
|
@ -474,7 +510,7 @@ extern DECLSPEC SDL_bool SDLCALL SDL_IsJoystickVirtual(SDL_JoystickID instance_i
|
|||
* `SDL_JOYSTICK_AXIS_MIN`.
|
||||
*
|
||||
* \param joystick the virtual joystick on which to set state.
|
||||
* \param axis the specific axis on the virtual joystick to set.
|
||||
* \param axis the index of the axis on the virtual joystick to update.
|
||||
* \param value the new value for the specified axis.
|
||||
* \returns 0 on success or a negative error code on failure; call
|
||||
* SDL_GetError() for more information.
|
||||
|
@ -484,7 +520,7 @@ extern DECLSPEC SDL_bool SDLCALL SDL_IsJoystickVirtual(SDL_JoystickID instance_i
|
|||
extern DECLSPEC int SDLCALL SDL_SetJoystickVirtualAxis(SDL_Joystick *joystick, int axis, Sint16 value);
|
||||
|
||||
/**
|
||||
* Set values on an opened, virtual-joystick's button.
|
||||
* Generate ball motion on an opened virtual joystick.
|
||||
*
|
||||
* Please note that values set here will not be applied until the next call to
|
||||
* SDL_UpdateJoysticks, which can either be called directly, or can be called
|
||||
|
@ -493,7 +529,27 @@ extern DECLSPEC int SDLCALL SDL_SetJoystickVirtualAxis(SDL_Joystick *joystick, i
|
|||
* SDL_WaitEvent.
|
||||
*
|
||||
* \param joystick the virtual joystick on which to set state.
|
||||
* \param button the specific button on the virtual joystick to set.
|
||||
* \param ball the index of the ball on the virtual joystick to update.
|
||||
* \param xrel the relative motion on the X axis.
|
||||
* \param yrel the relative motion on the Y axis.
|
||||
* \returns 0 on success or a negative error code on failure; call
|
||||
* SDL_GetError() for more information.
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*/
|
||||
extern DECLSPEC int SDLCALL SDL_SetJoystickVirtualBall(SDL_Joystick *joystick, int ball, Sint16 xrel, Sint16 yrel);
|
||||
|
||||
/**
|
||||
* Set the state of a button on an opened virtual joystick.
|
||||
*
|
||||
* Please note that values set here will not be applied until the next call to
|
||||
* SDL_UpdateJoysticks, which can either be called directly, or can be called
|
||||
* indirectly through various other SDL APIs, including, but not limited to
|
||||
* the following: SDL_PollEvent, SDL_PumpEvents, SDL_WaitEventTimeout,
|
||||
* SDL_WaitEvent.
|
||||
*
|
||||
* \param joystick the virtual joystick on which to set state.
|
||||
* \param button the index of the button on the virtual joystick to update.
|
||||
* \param value the new value for the specified button.
|
||||
* \returns 0 on success or a negative error code on failure; call
|
||||
* SDL_GetError() for more information.
|
||||
|
@ -503,7 +559,7 @@ extern DECLSPEC int SDLCALL SDL_SetJoystickVirtualAxis(SDL_Joystick *joystick, i
|
|||
extern DECLSPEC int SDLCALL SDL_SetJoystickVirtualButton(SDL_Joystick *joystick, int button, Uint8 value);
|
||||
|
||||
/**
|
||||
* Set values on an opened, virtual-joystick's hat.
|
||||
* Set the state of a hat on an opened virtual joystick.
|
||||
*
|
||||
* Please note that values set here will not be applied until the next call to
|
||||
* SDL_UpdateJoysticks, which can either be called directly, or can be called
|
||||
|
@ -512,7 +568,7 @@ extern DECLSPEC int SDLCALL SDL_SetJoystickVirtualButton(SDL_Joystick *joystick,
|
|||
* SDL_WaitEvent.
|
||||
*
|
||||
* \param joystick the virtual joystick on which to set state.
|
||||
* \param hat the specific hat on the virtual joystick to set.
|
||||
* \param hat the index of the hat on the virtual joystick to update.
|
||||
* \param value the new value for the specified hat.
|
||||
* \returns 0 on success or a negative error code on failure; call
|
||||
* SDL_GetError() for more information.
|
||||
|
@ -521,6 +577,50 @@ extern DECLSPEC int SDLCALL SDL_SetJoystickVirtualButton(SDL_Joystick *joystick,
|
|||
*/
|
||||
extern DECLSPEC int SDLCALL SDL_SetJoystickVirtualHat(SDL_Joystick *joystick, int hat, Uint8 value);
|
||||
|
||||
/**
|
||||
* Set touchpad finger state on an opened virtual joystick.
|
||||
*
|
||||
* Please note that values set here will not be applied until the next call to
|
||||
* SDL_UpdateJoysticks, which can either be called directly, or can be called
|
||||
* indirectly through various other SDL APIs, including, but not limited to
|
||||
* the following: SDL_PollEvent, SDL_PumpEvents, SDL_WaitEventTimeout,
|
||||
* SDL_WaitEvent.
|
||||
*
|
||||
* \param joystick the virtual joystick on which to set state.
|
||||
* \param touchpad the index of the touchpad on the virtual joystick to update.
|
||||
* \param finger the index of the finger on the touchpad to set.
|
||||
* \param state `SDL_PRESSED` if the finger is pressed, `SDL_RELEASED` if the finger is released
|
||||
* \param x the x coordinate of the finger on the touchpad, normalized 0 to 1, with the origin in the upper left
|
||||
* \param y the y coordinate of the finger on the touchpad, normalized 0 to 1, with the origin in the upper left
|
||||
* \param pressure the pressure of the finger
|
||||
* \returns 0 on success or a negative error code on failure; call
|
||||
* SDL_GetError() for more information.
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*/
|
||||
extern DECLSPEC int SDLCALL SDL_SetJoystickVirtualTouchpad(SDL_Joystick *joystick, int touchpad, int finger, Uint8 state, float x, float y, float pressure);
|
||||
|
||||
/**
|
||||
* Send a sensor update for an opened virtual joystick.
|
||||
*
|
||||
* Please note that values set here will not be applied until the next call to
|
||||
* SDL_UpdateJoysticks, which can either be called directly, or can be called
|
||||
* indirectly through various other SDL APIs, including, but not limited to
|
||||
* the following: SDL_PollEvent, SDL_PumpEvents, SDL_WaitEventTimeout,
|
||||
* SDL_WaitEvent.
|
||||
*
|
||||
* \param joystick the virtual joystick on which to set state.
|
||||
* \param type the type of the sensor on the virtual joystick to update.
|
||||
* \param sensor_timestamp a 64-bit timestamp in nanoseconds associated with the sensor reading
|
||||
* \param data the data associated with the sensor reading
|
||||
* \param num_values the number of values pointed to by `data`
|
||||
* \returns 0 on success or a negative error code on failure; call
|
||||
* SDL_GetError() for more information.
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*/
|
||||
extern DECLSPEC int SDLCALL SDL_SendJoystickVirtualSensorData(SDL_Joystick *joystick, SDL_SensorType type, Uint64 sensor_timestamp, const float *data, int num_values);
|
||||
|
||||
/**
|
||||
* Get the properties associated with a joystick.
|
||||
*
|
||||
|
|
|
@ -680,6 +680,7 @@ SDL3_0.0.0 {
|
|||
SDL_SeekIO;
|
||||
SDL_SendGamepadEffect;
|
||||
SDL_SendJoystickEffect;
|
||||
SDL_SendJoystickVirtualSensorData;
|
||||
SDL_SetAssertionHandler;
|
||||
SDL_SetAudioPostmixCallback;
|
||||
SDL_SetAudioStreamFormat;
|
||||
|
@ -708,8 +709,10 @@ SDL3_0.0.0 {
|
|||
SDL_SetJoystickLED;
|
||||
SDL_SetJoystickPlayerIndex;
|
||||
SDL_SetJoystickVirtualAxis;
|
||||
SDL_SetJoystickVirtualBall;
|
||||
SDL_SetJoystickVirtualButton;
|
||||
SDL_SetJoystickVirtualHat;
|
||||
SDL_SetJoystickVirtualTouchpad;
|
||||
SDL_SetLogOutputFunction;
|
||||
SDL_SetMainReady;
|
||||
SDL_SetMemoryFunctions;
|
||||
|
|
|
@ -705,6 +705,7 @@
|
|||
#define SDL_SeekIO SDL_SeekIO_REAL
|
||||
#define SDL_SendGamepadEffect SDL_SendGamepadEffect_REAL
|
||||
#define SDL_SendJoystickEffect SDL_SendJoystickEffect_REAL
|
||||
#define SDL_SendJoystickVirtualSensorData SDL_SendJoystickVirtualSensorData_REAL
|
||||
#define SDL_SetAssertionHandler SDL_SetAssertionHandler_REAL
|
||||
#define SDL_SetAudioPostmixCallback SDL_SetAudioPostmixCallback_REAL
|
||||
#define SDL_SetAudioStreamFormat SDL_SetAudioStreamFormat_REAL
|
||||
|
@ -732,8 +733,10 @@
|
|||
#define SDL_SetJoystickLED SDL_SetJoystickLED_REAL
|
||||
#define SDL_SetJoystickPlayerIndex SDL_SetJoystickPlayerIndex_REAL
|
||||
#define SDL_SetJoystickVirtualAxis SDL_SetJoystickVirtualAxis_REAL
|
||||
#define SDL_SetJoystickVirtualBall SDL_SetJoystickVirtualBall_REAL
|
||||
#define SDL_SetJoystickVirtualButton SDL_SetJoystickVirtualButton_REAL
|
||||
#define SDL_SetJoystickVirtualHat SDL_SetJoystickVirtualHat_REAL
|
||||
#define SDL_SetJoystickVirtualTouchpad SDL_SetJoystickVirtualTouchpad_REAL
|
||||
#define SDL_SetLogOutputFunction SDL_SetLogOutputFunction_REAL
|
||||
#define SDL_SetMainReady SDL_SetMainReady_REAL
|
||||
#define SDL_SetMemoryFunctions SDL_SetMemoryFunctions_REAL
|
||||
|
|
|
@ -726,6 +726,7 @@ SDL_DYNAPI_PROC(SDL_bool,SDL_ScreenSaverEnabled,(void),(),return)
|
|||
SDL_DYNAPI_PROC(Sint64,SDL_SeekIO,(SDL_IOStream *a, Sint64 b, int c),(a,b,c),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_SendGamepadEffect,(SDL_Gamepad *a, const void *b, int c),(a,b,c),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_SendJoystickEffect,(SDL_Joystick *a, const void *b, int c),(a,b,c),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_SendJoystickVirtualSensorData,(SDL_Joystick *a, SDL_SensorType b, Uint64 c, const float *d, int e),(a,b,c,d,e),return)
|
||||
SDL_DYNAPI_PROC(void,SDL_SetAssertionHandler,(SDL_AssertionHandler a, void *b),(a,b),)
|
||||
SDL_DYNAPI_PROC(int,SDL_SetAudioPostmixCallback,(SDL_AudioDeviceID a, SDL_AudioPostmixCallback b, void *c),(a,b,c),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_SetAudioStreamFormat,(SDL_AudioStream *a, const SDL_AudioSpec *b, const SDL_AudioSpec *c),(a,b,c),return)
|
||||
|
@ -752,8 +753,10 @@ SDL_DYNAPI_PROC(void,SDL_SetJoystickEventsEnabled,(SDL_bool a),(a),)
|
|||
SDL_DYNAPI_PROC(int,SDL_SetJoystickLED,(SDL_Joystick *a, Uint8 b, Uint8 c, Uint8 d),(a,b,c,d),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_SetJoystickPlayerIndex,(SDL_Joystick *a, int b),(a,b),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_SetJoystickVirtualAxis,(SDL_Joystick *a, int b, Sint16 c),(a,b,c),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_SetJoystickVirtualBall,(SDL_Joystick *a, int b, Sint16 c, Sint16 d),(a,b,c,d),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_SetJoystickVirtualButton,(SDL_Joystick *a, int b, Uint8 c),(a,b,c),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_SetJoystickVirtualHat,(SDL_Joystick *a, int b, Uint8 c),(a,b,c),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_SetJoystickVirtualTouchpad,(SDL_Joystick *a, int b, int c, Uint8 d, float e, float f, float g),(a,b,c,d,e,f,g),return)
|
||||
SDL_DYNAPI_PROC(void,SDL_SetLogOutputFunction,(SDL_LogOutputFunction a, void *b),(a,b),)
|
||||
SDL_DYNAPI_PROC(void,SDL_SetMainReady,(void),(),)
|
||||
SDL_DYNAPI_PROC(int,SDL_SetMemoryFunctions,(SDL_malloc_func a, SDL_calloc_func b, SDL_realloc_func c, SDL_free_func d),(a,b,c,d),return)
|
||||
|
|
|
@ -1235,6 +1235,25 @@ int SDL_SetJoystickVirtualAxis(SDL_Joystick *joystick, int axis, Sint16 value)
|
|||
return retval;
|
||||
}
|
||||
|
||||
int SDL_SetJoystickVirtualBall(SDL_Joystick *joystick, int ball, Sint16 xrel, Sint16 yrel)
|
||||
{
|
||||
int retval;
|
||||
|
||||
SDL_LockJoysticks();
|
||||
{
|
||||
CHECK_JOYSTICK_MAGIC(joystick, -1);
|
||||
|
||||
#ifdef SDL_JOYSTICK_VIRTUAL
|
||||
retval = SDL_SetJoystickVirtualBallInner(joystick, ball, xrel, yrel);
|
||||
#else
|
||||
retval = SDL_SetError("SDL not built with virtual-joystick support");
|
||||
#endif
|
||||
}
|
||||
SDL_UnlockJoysticks();
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int SDL_SetJoystickVirtualButton(SDL_Joystick *joystick, int button, Uint8 value)
|
||||
{
|
||||
int retval;
|
||||
|
@ -1273,6 +1292,44 @@ int SDL_SetJoystickVirtualHat(SDL_Joystick *joystick, int hat, Uint8 value)
|
|||
return retval;
|
||||
}
|
||||
|
||||
int SDL_SetJoystickVirtualTouchpad(SDL_Joystick *joystick, int touchpad, int finger, Uint8 state, float x, float y, float pressure)
|
||||
{
|
||||
int retval;
|
||||
|
||||
SDL_LockJoysticks();
|
||||
{
|
||||
CHECK_JOYSTICK_MAGIC(joystick, -1);
|
||||
|
||||
#ifdef SDL_JOYSTICK_VIRTUAL
|
||||
retval = SDL_SetJoystickVirtualTouchpadInner(joystick, touchpad, finger, state, x, y, pressure);
|
||||
#else
|
||||
retval = SDL_SetError("SDL not built with virtual-joystick support");
|
||||
#endif
|
||||
}
|
||||
SDL_UnlockJoysticks();
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int SDL_SendJoystickVirtualSensorData(SDL_Joystick *joystick, SDL_SensorType type, Uint64 sensor_timestamp, const float *data, int num_values)
|
||||
{
|
||||
int retval;
|
||||
|
||||
SDL_LockJoysticks();
|
||||
{
|
||||
CHECK_JOYSTICK_MAGIC(joystick, -1);
|
||||
|
||||
#ifdef SDL_JOYSTICK_VIRTUAL
|
||||
retval = SDL_SendJoystickVirtualSensorDataInner(joystick, type, sensor_timestamp, data, num_values);
|
||||
#else
|
||||
retval = SDL_SetError("SDL not built with virtual-joystick support");
|
||||
#endif
|
||||
}
|
||||
SDL_UnlockJoysticks();
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks to make sure the joystick is valid.
|
||||
*/
|
||||
|
|
|
@ -102,6 +102,26 @@ static void VIRTUAL_FreeHWData(joystick_hwdata *hwdata)
|
|||
SDL_free(hwdata->hats);
|
||||
hwdata->hats = NULL;
|
||||
}
|
||||
if (hwdata->balls) {
|
||||
SDL_free(hwdata->balls);
|
||||
hwdata->balls = NULL;
|
||||
}
|
||||
if (hwdata->touchpads) {
|
||||
for (Uint16 i = 0; i < hwdata->desc.ntouchpads; ++i) {
|
||||
SDL_free(hwdata->touchpads[i].fingers);
|
||||
hwdata->touchpads[i].fingers = NULL;
|
||||
}
|
||||
SDL_free(hwdata->touchpads);
|
||||
hwdata->touchpads = NULL;
|
||||
}
|
||||
if (hwdata->sensors) {
|
||||
SDL_free(hwdata->sensors);
|
||||
hwdata->sensors = NULL;
|
||||
}
|
||||
if (hwdata->sensor_events) {
|
||||
SDL_free(hwdata->sensor_events);
|
||||
hwdata->sensor_events = NULL;
|
||||
}
|
||||
SDL_free(hwdata);
|
||||
}
|
||||
|
||||
|
@ -123,7 +143,9 @@ SDL_JoystickID SDL_JoystickAttachVirtualInner(const SDL_VirtualJoystickDesc *des
|
|||
VIRTUAL_FreeHWData(hwdata);
|
||||
return 0;
|
||||
}
|
||||
SDL_memcpy(&hwdata->desc, desc, sizeof(*desc));
|
||||
SDL_copyp(&hwdata->desc, desc);
|
||||
hwdata->desc.touchpads = NULL;
|
||||
hwdata->desc.sensors = NULL;
|
||||
|
||||
if (hwdata->desc.name) {
|
||||
name = hwdata->desc.name;
|
||||
|
@ -203,7 +225,7 @@ SDL_JoystickID SDL_JoystickAttachVirtualInner(const SDL_VirtualJoystickDesc *des
|
|||
|
||||
/* Allocate fields for different control-types */
|
||||
if (hwdata->desc.naxes > 0) {
|
||||
hwdata->axes = (Sint16 *)SDL_calloc(hwdata->desc.naxes, sizeof(Sint16));
|
||||
hwdata->axes = (Sint16 *)SDL_calloc(hwdata->desc.naxes, sizeof(*hwdata->axes));
|
||||
if (!hwdata->axes) {
|
||||
VIRTUAL_FreeHWData(hwdata);
|
||||
return 0;
|
||||
|
@ -218,19 +240,64 @@ SDL_JoystickID SDL_JoystickAttachVirtualInner(const SDL_VirtualJoystickDesc *des
|
|||
}
|
||||
}
|
||||
if (hwdata->desc.nbuttons > 0) {
|
||||
hwdata->buttons = (Uint8 *)SDL_calloc(hwdata->desc.nbuttons, sizeof(Uint8));
|
||||
hwdata->buttons = (Uint8 *)SDL_calloc(hwdata->desc.nbuttons, sizeof(*hwdata->buttons));
|
||||
if (!hwdata->buttons) {
|
||||
VIRTUAL_FreeHWData(hwdata);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (hwdata->desc.nhats > 0) {
|
||||
hwdata->hats = (Uint8 *)SDL_calloc(hwdata->desc.nhats, sizeof(Uint8));
|
||||
hwdata->hats = (Uint8 *)SDL_calloc(hwdata->desc.nhats, sizeof(*hwdata->hats));
|
||||
if (!hwdata->hats) {
|
||||
VIRTUAL_FreeHWData(hwdata);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (hwdata->desc.nballs > 0) {
|
||||
hwdata->balls = (SDL_JoystickBallData *)SDL_calloc(hwdata->desc.nballs, sizeof(*hwdata->balls));
|
||||
if (!hwdata->balls) {
|
||||
VIRTUAL_FreeHWData(hwdata);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (hwdata->desc.ntouchpads > 0) {
|
||||
if (!desc->touchpads) {
|
||||
VIRTUAL_FreeHWData(hwdata);
|
||||
SDL_SetError("desc missing touchpad descriptions");
|
||||
return 0;
|
||||
}
|
||||
hwdata->touchpads = (SDL_JoystickTouchpadInfo *)SDL_calloc(hwdata->desc.ntouchpads, sizeof(*hwdata->touchpads));
|
||||
if (!hwdata->touchpads) {
|
||||
VIRTUAL_FreeHWData(hwdata);
|
||||
return 0;
|
||||
}
|
||||
for (Uint16 i = 0; i < hwdata->desc.ntouchpads; ++i) {
|
||||
const SDL_VirtualJoystickTouchpadDesc *touchpad_desc = &desc->touchpads[i];
|
||||
hwdata->touchpads[i].nfingers = touchpad_desc->nfingers;
|
||||
hwdata->touchpads[i].fingers = (SDL_JoystickTouchpadFingerInfo *)SDL_calloc(touchpad_desc->nfingers, sizeof(*hwdata->touchpads[i].fingers));
|
||||
if (!hwdata->touchpads[i].fingers) {
|
||||
VIRTUAL_FreeHWData(hwdata);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hwdata->desc.nsensors > 0) {
|
||||
if (!desc->sensors) {
|
||||
VIRTUAL_FreeHWData(hwdata);
|
||||
SDL_SetError("desc missing sensor descriptions");
|
||||
return 0;
|
||||
}
|
||||
hwdata->sensors = (SDL_JoystickSensorInfo *)SDL_calloc(hwdata->desc.nsensors, sizeof(*hwdata->sensors));
|
||||
if (!hwdata->sensors) {
|
||||
VIRTUAL_FreeHWData(hwdata);
|
||||
return 0;
|
||||
}
|
||||
for (Uint16 i = 0; i < hwdata->desc.nsensors; ++i) {
|
||||
const SDL_VirtualJoystickSensorDesc *sensor_desc = &desc->sensors[i];
|
||||
hwdata->sensors[i].type = sensor_desc->type;
|
||||
hwdata->sensors[i].rate = sensor_desc->rate;
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate an instance ID for this device */
|
||||
hwdata->instance_id = SDL_GetNextObjectID();
|
||||
|
@ -268,17 +335,40 @@ int SDL_SetJoystickVirtualAxisInner(SDL_Joystick *joystick, int axis, Sint16 val
|
|||
SDL_AssertJoysticksLocked();
|
||||
|
||||
if (!joystick || !joystick->hwdata) {
|
||||
SDL_UnlockJoysticks();
|
||||
return SDL_SetError("Invalid joystick");
|
||||
}
|
||||
|
||||
hwdata = (joystick_hwdata *)joystick->hwdata;
|
||||
if (axis < 0 || axis >= hwdata->desc.naxes) {
|
||||
SDL_UnlockJoysticks();
|
||||
return SDL_SetError("Invalid axis index");
|
||||
}
|
||||
|
||||
hwdata->axes[axis] = value;
|
||||
hwdata->changes |= AXES_CHANGED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SDL_SetJoystickVirtualBallInner(SDL_Joystick *joystick, int ball, Sint16 xrel, Sint16 yrel)
|
||||
{
|
||||
joystick_hwdata *hwdata;
|
||||
|
||||
SDL_AssertJoysticksLocked();
|
||||
|
||||
if (!joystick || !joystick->hwdata) {
|
||||
return SDL_SetError("Invalid joystick");
|
||||
}
|
||||
|
||||
hwdata = (joystick_hwdata *)joystick->hwdata;
|
||||
if (ball < 0 || ball >= hwdata->desc.nballs) {
|
||||
return SDL_SetError("Invalid ball index");
|
||||
}
|
||||
|
||||
hwdata->balls[ball].dx += xrel;
|
||||
hwdata->balls[ball].dx = SDL_clamp(hwdata->balls[ball].dx, SDL_MIN_SINT16, SDL_MAX_SINT16);
|
||||
hwdata->balls[ball].dy += yrel;
|
||||
hwdata->balls[ball].dy = SDL_clamp(hwdata->balls[ball].dy, SDL_MIN_SINT16, SDL_MAX_SINT16);
|
||||
hwdata->changes |= BALLS_CHANGED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -290,17 +380,16 @@ int SDL_SetJoystickVirtualButtonInner(SDL_Joystick *joystick, int button, Uint8
|
|||
SDL_AssertJoysticksLocked();
|
||||
|
||||
if (!joystick || !joystick->hwdata) {
|
||||
SDL_UnlockJoysticks();
|
||||
return SDL_SetError("Invalid joystick");
|
||||
}
|
||||
|
||||
hwdata = (joystick_hwdata *)joystick->hwdata;
|
||||
if (button < 0 || button >= hwdata->desc.nbuttons) {
|
||||
SDL_UnlockJoysticks();
|
||||
return SDL_SetError("Invalid button index");
|
||||
}
|
||||
|
||||
hwdata->buttons[button] = value;
|
||||
hwdata->changes |= BUTTONS_CHANGED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -312,17 +401,74 @@ int SDL_SetJoystickVirtualHatInner(SDL_Joystick *joystick, int hat, Uint8 value)
|
|||
SDL_AssertJoysticksLocked();
|
||||
|
||||
if (!joystick || !joystick->hwdata) {
|
||||
SDL_UnlockJoysticks();
|
||||
return SDL_SetError("Invalid joystick");
|
||||
}
|
||||
|
||||
hwdata = (joystick_hwdata *)joystick->hwdata;
|
||||
if (hat < 0 || hat >= hwdata->desc.nhats) {
|
||||
SDL_UnlockJoysticks();
|
||||
return SDL_SetError("Invalid hat index");
|
||||
}
|
||||
|
||||
hwdata->hats[hat] = value;
|
||||
hwdata->changes |= HATS_CHANGED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SDL_SetJoystickVirtualTouchpadInner(SDL_Joystick *joystick, int touchpad, int finger, Uint8 state, float x, float y, float pressure)
|
||||
{
|
||||
joystick_hwdata *hwdata;
|
||||
|
||||
SDL_AssertJoysticksLocked();
|
||||
|
||||
if (!joystick || !joystick->hwdata) {
|
||||
return SDL_SetError("Invalid joystick");
|
||||
}
|
||||
|
||||
hwdata = (joystick_hwdata *)joystick->hwdata;
|
||||
if (touchpad < 0 || touchpad >= hwdata->desc.ntouchpads) {
|
||||
return SDL_SetError("Invalid touchpad index");
|
||||
}
|
||||
if (finger < 0 || finger >= hwdata->touchpads[touchpad].nfingers) {
|
||||
return SDL_SetError("Invalid finger index");
|
||||
}
|
||||
|
||||
SDL_JoystickTouchpadFingerInfo *info = &hwdata->touchpads[touchpad].fingers[finger];
|
||||
info->state = state;
|
||||
info->x = x;
|
||||
info->y = y;
|
||||
info->pressure = pressure;
|
||||
hwdata->changes |= TOUCHPADS_CHANGED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SDL_SendJoystickVirtualSensorDataInner(SDL_Joystick *joystick, SDL_SensorType type, Uint64 sensor_timestamp, const float *data, int num_values)
|
||||
{
|
||||
joystick_hwdata *hwdata;
|
||||
|
||||
SDL_AssertJoysticksLocked();
|
||||
|
||||
if (!joystick || !joystick->hwdata) {
|
||||
return SDL_SetError("Invalid joystick");
|
||||
}
|
||||
|
||||
hwdata = (joystick_hwdata *)joystick->hwdata;
|
||||
if (hwdata->num_sensor_events == hwdata->max_sensor_events) {
|
||||
int new_max_sensor_events = (hwdata->max_sensor_events + 1);
|
||||
VirtualSensorEvent *sensor_events = (VirtualSensorEvent *)SDL_realloc(hwdata->sensor_events, new_max_sensor_events * sizeof(*sensor_events));
|
||||
if (!sensor_events) {
|
||||
return -1;
|
||||
}
|
||||
hwdata->sensor_events = sensor_events;
|
||||
hwdata->max_sensor_events = hwdata->max_sensor_events;
|
||||
}
|
||||
|
||||
VirtualSensorEvent *event = &hwdata->sensor_events[hwdata->num_sensor_events++];
|
||||
event->type = type;
|
||||
event->sensor_timestamp = sensor_timestamp;
|
||||
event->num_values = SDL_min(num_values, SDL_arraysize(event->data));
|
||||
SDL_memcpy(event->data, data, (event->num_values * sizeof(*event->data)));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -424,6 +570,15 @@ static int VIRTUAL_JoystickOpen(SDL_Joystick *joystick, int device_index)
|
|||
joystick->nhats = hwdata->desc.nhats;
|
||||
hwdata->joystick = joystick;
|
||||
|
||||
for (Uint16 i = 0; i < hwdata->desc.ntouchpads; ++i) {
|
||||
const SDL_JoystickTouchpadInfo *touchpad = &hwdata->touchpads[i];
|
||||
SDL_PrivateJoystickAddTouchpad(joystick, touchpad->nfingers);
|
||||
}
|
||||
for (Uint16 i = 0; i < hwdata->desc.nsensors; ++i) {
|
||||
const SDL_JoystickSensorInfo *sensor = &hwdata->sensors[i];
|
||||
SDL_PrivateJoystickAddSensor(joystick, sensor->type, sensor->rate);
|
||||
}
|
||||
|
||||
if (hwdata->desc.SetLED) {
|
||||
SDL_SetBooleanProperty(SDL_GetJoystickProperties(joystick), SDL_PROP_JOYSTICK_CAP_RGB_LED_BOOLEAN, SDL_TRUE);
|
||||
}
|
||||
|
@ -518,13 +673,30 @@ static int VIRTUAL_JoystickSendEffect(SDL_Joystick *joystick, const void *data,
|
|||
|
||||
static int VIRTUAL_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
int result;
|
||||
|
||||
SDL_AssertJoysticksLocked();
|
||||
|
||||
if (joystick->hwdata) {
|
||||
joystick_hwdata *hwdata = joystick->hwdata;
|
||||
if (hwdata->desc.SetSensorsEnabled) {
|
||||
result = hwdata->desc.SetSensorsEnabled(hwdata->desc.userdata, enabled);
|
||||
} else {
|
||||
result = 0;
|
||||
}
|
||||
if (result == 0) {
|
||||
hwdata->sensors_enabled = enabled;
|
||||
}
|
||||
} else {
|
||||
result = SDL_SetError("SetSensorsEnabled failed, device disconnected");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void VIRTUAL_JoystickUpdate(SDL_Joystick *joystick)
|
||||
{
|
||||
joystick_hwdata *hwdata;
|
||||
Uint8 i;
|
||||
Uint64 timestamp = SDL_GetTicksNS();
|
||||
|
||||
SDL_AssertJoysticksLocked();
|
||||
|
@ -542,16 +714,51 @@ static void VIRTUAL_JoystickUpdate(SDL_Joystick *joystick)
|
|||
hwdata->desc.Update(hwdata->desc.userdata);
|
||||
}
|
||||
|
||||
for (i = 0; i < hwdata->desc.naxes; ++i) {
|
||||
if (hwdata->changes & AXES_CHANGED) {
|
||||
for (Uint16 i = 0; i < hwdata->desc.naxes; ++i) {
|
||||
SDL_SendJoystickAxis(timestamp, joystick, i, hwdata->axes[i]);
|
||||
}
|
||||
for (i = 0; i < hwdata->desc.nbuttons; ++i) {
|
||||
}
|
||||
if (hwdata->changes & BALLS_CHANGED) {
|
||||
for (Uint16 i = 0; i < hwdata->desc.nballs; ++i) {
|
||||
SDL_JoystickBallData *ball = &hwdata->balls[i];
|
||||
if (ball->dx || ball->dy) {
|
||||
SDL_SendJoystickBall(timestamp, joystick, i, ball->dx, ball->dy);
|
||||
ball->dx = 0;
|
||||
ball->dy = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hwdata->changes & BUTTONS_CHANGED) {
|
||||
for (Uint16 i = 0; i < hwdata->desc.nbuttons; ++i) {
|
||||
SDL_SendJoystickButton(timestamp, joystick, i, hwdata->buttons[i]);
|
||||
}
|
||||
for (i = 0; i < hwdata->desc.nhats; ++i) {
|
||||
}
|
||||
if (hwdata->changes & HATS_CHANGED) {
|
||||
for (Uint16 i = 0; i < hwdata->desc.nhats; ++i) {
|
||||
SDL_SendJoystickHat(timestamp, joystick, i, hwdata->hats[i]);
|
||||
}
|
||||
}
|
||||
if (hwdata->changes & TOUCHPADS_CHANGED) {
|
||||
for (Uint16 i = 0; i < hwdata->desc.ntouchpads; ++i) {
|
||||
const SDL_JoystickTouchpadInfo *touchpad = &hwdata->touchpads[i];
|
||||
for (int j = 0; j < touchpad->nfingers; ++j) {
|
||||
const SDL_JoystickTouchpadFingerInfo *finger = &touchpad->fingers[j];
|
||||
SDL_SendJoystickTouchpad(timestamp, joystick, i, j, finger->state, finger->x, finger->y, finger->pressure);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hwdata->num_sensor_events > 0) {
|
||||
if (hwdata->sensors_enabled) {
|
||||
for (int i = 0; i < hwdata->num_sensor_events; ++i) {
|
||||
const VirtualSensorEvent *event = &hwdata->sensor_events[i];
|
||||
SDL_SendJoystickSensor(timestamp, joystick, event->type, event->sensor_timestamp, event->data, event->num_values);
|
||||
}
|
||||
}
|
||||
hwdata->num_sensor_events = 0;
|
||||
}
|
||||
hwdata->changes = 0;
|
||||
}
|
||||
|
||||
static void VIRTUAL_JoystickClose(SDL_Joystick *joystick)
|
||||
{
|
||||
|
|
|
@ -25,31 +25,59 @@
|
|||
|
||||
#ifdef SDL_JOYSTICK_VIRTUAL
|
||||
|
||||
#include "../SDL_sysjoystick.h"
|
||||
|
||||
#define AXES_CHANGED 0x00000001
|
||||
#define BALLS_CHANGED 0x00000002
|
||||
#define BUTTONS_CHANGED 0x00000004
|
||||
#define HATS_CHANGED 0x00000008
|
||||
#define TOUCHPADS_CHANGED 0x00000010
|
||||
|
||||
/**
|
||||
* Data for a virtual, software-only joystick.
|
||||
*/
|
||||
typedef struct VirtualSensorEvent
|
||||
{
|
||||
SDL_SensorType type;
|
||||
Uint64 sensor_timestamp;
|
||||
float data[3];
|
||||
int num_values;
|
||||
} VirtualSensorEvent;
|
||||
|
||||
typedef struct joystick_hwdata
|
||||
{
|
||||
SDL_JoystickType type;
|
||||
SDL_JoystickID instance_id;
|
||||
SDL_bool attached;
|
||||
char *name;
|
||||
SDL_JoystickType type;
|
||||
SDL_JoystickGUID guid;
|
||||
SDL_VirtualJoystickDesc desc;
|
||||
Uint32 changes;
|
||||
Sint16 *axes;
|
||||
Uint8 *buttons;
|
||||
Uint8 *hats;
|
||||
SDL_JoystickID instance_id;
|
||||
SDL_JoystickBallData *balls;
|
||||
SDL_JoystickTouchpadInfo *touchpads;
|
||||
SDL_JoystickSensorInfo *sensors;
|
||||
SDL_bool sensors_enabled;
|
||||
int num_sensor_events;
|
||||
int max_sensor_events;
|
||||
VirtualSensorEvent *sensor_events;
|
||||
|
||||
SDL_Joystick *joystick;
|
||||
|
||||
struct joystick_hwdata *next;
|
||||
} joystick_hwdata;
|
||||
|
||||
SDL_JoystickID SDL_JoystickAttachVirtualInner(const SDL_VirtualJoystickDesc *desc);
|
||||
int SDL_JoystickDetachVirtualInner(SDL_JoystickID instance_id);
|
||||
extern SDL_JoystickID SDL_JoystickAttachVirtualInner(const SDL_VirtualJoystickDesc *desc);
|
||||
extern int SDL_JoystickDetachVirtualInner(SDL_JoystickID instance_id);
|
||||
|
||||
int SDL_SetJoystickVirtualAxisInner(SDL_Joystick *joystick, int axis, Sint16 value);
|
||||
int SDL_SetJoystickVirtualButtonInner(SDL_Joystick *joystick, int button, Uint8 value);
|
||||
int SDL_SetJoystickVirtualHatInner(SDL_Joystick *joystick, int hat, Uint8 value);
|
||||
extern int SDL_SetJoystickVirtualAxisInner(SDL_Joystick *joystick, int axis, Sint16 value);
|
||||
extern int SDL_SetJoystickVirtualBallInner(SDL_Joystick *joystick, int ball, Sint16 xrel, Sint16 yrel);
|
||||
extern int SDL_SetJoystickVirtualButtonInner(SDL_Joystick *joystick, int button, Uint8 value);
|
||||
extern int SDL_SetJoystickVirtualHatInner(SDL_Joystick *joystick, int hat, Uint8 value);
|
||||
extern int SDL_SetJoystickVirtualTouchpadInner(SDL_Joystick *joystick, int touchpad, int finger, Uint8 state, float x, float y, float pressure);
|
||||
extern int SDL_SendJoystickVirtualSensorDataInner(SDL_Joystick *joystick, SDL_SensorType type, Uint64 sensor_timestamp, const float *data, int num_values);
|
||||
|
||||
#endif /* SDL_JOYSTICK_VIRTUAL */
|
||||
|
||||
|
|
|
@ -191,6 +191,7 @@ void GetGamepadImageArea(GamepadImage *ctx, SDL_Rect *area)
|
|||
{
|
||||
if (!ctx) {
|
||||
SDL_zerop(area);
|
||||
return;
|
||||
}
|
||||
|
||||
area->x = ctx->x;
|
||||
|
@ -202,6 +203,19 @@ void GetGamepadImageArea(GamepadImage *ctx, SDL_Rect *area)
|
|||
}
|
||||
}
|
||||
|
||||
void GetGamepadTouchpadArea(GamepadImage *ctx, SDL_Rect *area)
|
||||
{
|
||||
if (!ctx) {
|
||||
SDL_zerop(area);
|
||||
return;
|
||||
}
|
||||
|
||||
area->x = (float)ctx->x + (ctx->gamepad_width - ctx->touchpad_width) / 2 + touchpad_area.x;
|
||||
area->y = (float)ctx->y + ctx->gamepad_height + touchpad_area.y;
|
||||
area->w = (float)touchpad_area.w;
|
||||
area->h = (float)touchpad_area.h;
|
||||
}
|
||||
|
||||
void SetGamepadImageShowingFront(GamepadImage *ctx, SDL_bool showing_front)
|
||||
{
|
||||
if (!ctx) {
|
||||
|
|
|
@ -54,6 +54,7 @@ enum
|
|||
extern GamepadImage *CreateGamepadImage(SDL_Renderer *renderer);
|
||||
extern void SetGamepadImagePosition(GamepadImage *ctx, int x, int y);
|
||||
extern void GetGamepadImageArea(GamepadImage *ctx, SDL_Rect *area);
|
||||
extern void GetGamepadTouchpadArea(GamepadImage *ctx, SDL_Rect *area);
|
||||
extern void SetGamepadImageShowingFront(GamepadImage *ctx, SDL_bool showing_front);
|
||||
extern void SetGamepadImageType(GamepadImage *ctx, SDL_GamepadType type);
|
||||
extern SDL_GamepadType GetGamepadImageType(GamepadImage *ctx);
|
||||
|
|
|
@ -100,6 +100,9 @@ static SDL_GamepadAxis virtual_axis_active = SDL_GAMEPAD_AXIS_INVALID;
|
|||
static float virtual_axis_start_x;
|
||||
static float virtual_axis_start_y;
|
||||
static SDL_GamepadButton virtual_button_active = SDL_GAMEPAD_BUTTON_INVALID;
|
||||
static SDL_bool virtual_touchpad_active = SDL_FALSE;
|
||||
static float virtual_touchpad_x;
|
||||
static float virtual_touchpad_y;
|
||||
|
||||
static int s_arrBindingOrder[] = {
|
||||
/* Standard sequence */
|
||||
|
@ -1109,6 +1112,8 @@ static int SDLCALL VirtualGamepadSetLED(void *userdata, Uint8 red, Uint8 green,
|
|||
|
||||
static void OpenVirtualGamepad(void)
|
||||
{
|
||||
SDL_VirtualJoystickTouchpadDesc virtual_touchpad = { 1, { 0, 0, 0 } };
|
||||
SDL_VirtualJoystickSensorDesc virtual_sensor = { SDL_SENSOR_ACCEL, 0.0f };
|
||||
SDL_VirtualJoystickDesc desc;
|
||||
SDL_JoystickID virtual_id;
|
||||
|
||||
|
@ -1120,6 +1125,10 @@ static void OpenVirtualGamepad(void)
|
|||
desc.type = SDL_JOYSTICK_TYPE_GAMEPAD;
|
||||
desc.naxes = SDL_GAMEPAD_AXIS_MAX;
|
||||
desc.nbuttons = SDL_GAMEPAD_BUTTON_MAX;
|
||||
desc.ntouchpads = 1;
|
||||
desc.touchpads = &virtual_touchpad;
|
||||
desc.nsensors = 1;
|
||||
desc.sensors = &virtual_sensor;
|
||||
desc.SetPlayerIndex = VirtualGamepadSetPlayerIndex;
|
||||
desc.Rumble = VirtualGamepadRumble;
|
||||
desc.RumbleTriggers = VirtualGamepadRumbleTriggers;
|
||||
|
@ -1195,6 +1204,14 @@ static void VirtualGamepadMouseMotion(float x, float y)
|
|||
SDL_SetJoystickVirtualAxis(virtual_joystick, virtual_axis_active + 1, valueY);
|
||||
}
|
||||
}
|
||||
|
||||
if (virtual_touchpad_active) {
|
||||
SDL_Rect touchpad;
|
||||
GetGamepadTouchpadArea(image, &touchpad);
|
||||
virtual_touchpad_x = (x - touchpad.x) / touchpad.w;
|
||||
virtual_touchpad_y = (y - touchpad.y) / touchpad.h;
|
||||
SDL_SetJoystickVirtualTouchpad(virtual_joystick, 0, 0, SDL_PRESSED, virtual_touchpad_x, virtual_touchpad_y, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
static void VirtualGamepadMouseDown(float x, float y)
|
||||
|
@ -1202,6 +1219,15 @@ static void VirtualGamepadMouseDown(float x, float y)
|
|||
int element = GetGamepadImageElementAt(image, x, y);
|
||||
|
||||
if (element == SDL_GAMEPAD_ELEMENT_INVALID) {
|
||||
SDL_Point point = { (int)x, (int)y };
|
||||
SDL_Rect touchpad;
|
||||
GetGamepadTouchpadArea(image, &touchpad);
|
||||
if (SDL_PointInRect(&point, &touchpad)) {
|
||||
virtual_touchpad_active = SDL_TRUE;
|
||||
virtual_touchpad_x = (x - touchpad.x) / touchpad.w;
|
||||
virtual_touchpad_y = (y - touchpad.y) / touchpad.h;
|
||||
SDL_SetJoystickVirtualTouchpad(virtual_joystick, 0, 0, SDL_PRESSED, virtual_touchpad_x, virtual_touchpad_y, 1.0f);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1251,6 +1277,11 @@ static void VirtualGamepadMouseUp(float x, float y)
|
|||
}
|
||||
virtual_axis_active = SDL_GAMEPAD_AXIS_INVALID;
|
||||
}
|
||||
|
||||
if (virtual_touchpad_active) {
|
||||
SDL_SetJoystickVirtualTouchpad(virtual_joystick, 0, 0, SDL_RELEASED, virtual_touchpad_x, virtual_touchpad_y, 0.0f);
|
||||
virtual_touchpad_active = SDL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void DrawGamepadWaiting(SDL_Renderer *renderer)
|
||||
|
@ -1500,6 +1531,12 @@ static void loop(void *arg)
|
|||
{
|
||||
SDL_Event event;
|
||||
|
||||
/* If we have a virtual controller, send a virtual accelerometer sensor reading */
|
||||
if (virtual_joystick) {
|
||||
float data[3] = { 0.0f, SDL_STANDARD_GRAVITY, 0.0f };
|
||||
SDL_SendJoystickVirtualSensorData(virtual_joystick, SDL_SENSOR_ACCEL, SDL_GetTicksNS(), data, SDL_arraysize(data));
|
||||
}
|
||||
|
||||
/* Update to get the current event state */
|
||||
SDL_PumpEvents();
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue