Added ball, touchpad, and sensor support for virtual joysticks
Fixes https://github.com/libsdl-org/SDL/issues/9542
This commit is contained in:
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user