mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-09-06 03:18:13 +00:00
Added binding mode to testcontroller
This commit is contained in:
@@ -114,9 +114,9 @@ struct GamepadImage
|
|||||||
int x;
|
int x;
|
||||||
int y;
|
int y;
|
||||||
SDL_bool showing_front;
|
SDL_bool showing_front;
|
||||||
SDL_bool showing_battery;
|
|
||||||
SDL_bool showing_touchpad;
|
SDL_bool showing_touchpad;
|
||||||
GamepadImageFaceStyle face_style;
|
GamepadImageFaceStyle face_style;
|
||||||
|
ControllerDisplayMode display_mode;
|
||||||
|
|
||||||
SDL_bool buttons[SDL_GAMEPAD_BUTTON_MAX];
|
SDL_bool buttons[SDL_GAMEPAD_BUTTON_MAX];
|
||||||
int axes[SDL_GAMEPAD_AXIS_MAX];
|
int axes[SDL_GAMEPAD_AXIS_MAX];
|
||||||
@@ -231,57 +231,13 @@ void SetGamepadImageFaceStyle(GamepadImage *ctx, GamepadImageFaceStyle face_styl
|
|||||||
ctx->face_style = face_style;
|
ctx->face_style = face_style;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetGamepadImageShowingBattery(GamepadImage *ctx, SDL_bool showing_battery)
|
void SetGamepadImageDisplayMode(GamepadImage *ctx, ControllerDisplayMode display_mode)
|
||||||
{
|
{
|
||||||
if (!ctx) {
|
if (!ctx) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->showing_battery = showing_battery;
|
ctx->display_mode = display_mode;
|
||||||
}
|
|
||||||
|
|
||||||
void SetGamepadImageShowingTouchpad(GamepadImage *ctx, SDL_bool showing_touchpad)
|
|
||||||
{
|
|
||||||
if (!ctx) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx->showing_touchpad = showing_touchpad;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GetGamepadImageArea(GamepadImage *ctx, int *x, int *y, int *width, int *height)
|
|
||||||
{
|
|
||||||
if (!ctx) {
|
|
||||||
if (x) {
|
|
||||||
*x = 0;
|
|
||||||
}
|
|
||||||
if (y) {
|
|
||||||
*y = 0;
|
|
||||||
}
|
|
||||||
if (width) {
|
|
||||||
*width = 0;
|
|
||||||
}
|
|
||||||
if (height) {
|
|
||||||
*height = 0;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (x) {
|
|
||||||
*x = ctx->x;
|
|
||||||
}
|
|
||||||
if (y) {
|
|
||||||
*y = ctx->y;
|
|
||||||
}
|
|
||||||
if (width) {
|
|
||||||
*width = ctx->gamepad_width;
|
|
||||||
}
|
|
||||||
if (height) {
|
|
||||||
*height = ctx->gamepad_height;
|
|
||||||
if (ctx->showing_touchpad) {
|
|
||||||
*height += ctx->touchpad_height;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetGamepadImageButtonWidth(GamepadImage *ctx)
|
int GetGamepadImageButtonWidth(GamepadImage *ctx)
|
||||||
@@ -482,12 +438,14 @@ void UpdateGamepadImageFromGamepad(GamepadImage *ctx, SDL_Gamepad *gamepad)
|
|||||||
|
|
||||||
SDL_GetGamepadTouchpadFinger(gamepad, 0, i, &finger->state, &finger->x, &finger->y, &finger->pressure);
|
SDL_GetGamepadTouchpadFinger(gamepad, 0, i, &finger->state, &finger->x, &finger->y, &finger->pressure);
|
||||||
}
|
}
|
||||||
|
ctx->showing_touchpad = SDL_TRUE;
|
||||||
} else {
|
} else {
|
||||||
if (ctx->fingers) {
|
if (ctx->fingers) {
|
||||||
SDL_free(ctx->fingers);
|
SDL_free(ctx->fingers);
|
||||||
ctx->fingers = NULL;
|
ctx->fingers = NULL;
|
||||||
ctx->num_fingers = 0;
|
ctx->num_fingers = 0;
|
||||||
}
|
}
|
||||||
|
ctx->showing_touchpad = SDL_FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -568,7 +526,7 @@ void RenderGamepadImage(GamepadImage *ctx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->showing_battery) {
|
if (ctx->display_mode == CONTROLLER_MODE_TESTING && ctx->battery_level != SDL_JOYSTICK_POWER_UNKNOWN) {
|
||||||
dst.x = (float)ctx->x + ctx->gamepad_width - ctx->battery_width;
|
dst.x = (float)ctx->x + ctx->gamepad_width - ctx->battery_width;
|
||||||
dst.y = (float)ctx->y;
|
dst.y = (float)ctx->y;
|
||||||
dst.w = (float)ctx->battery_width;
|
dst.w = (float)ctx->battery_width;
|
||||||
@@ -576,7 +534,7 @@ void RenderGamepadImage(GamepadImage *ctx)
|
|||||||
SDL_RenderTexture(ctx->renderer, ctx->battery_texture[1 + ctx->battery_level], NULL, &dst);
|
SDL_RenderTexture(ctx->renderer, ctx->battery_texture[1 + ctx->battery_level], NULL, &dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->showing_touchpad) {
|
if (ctx->display_mode == CONTROLLER_MODE_TESTING && ctx->showing_touchpad) {
|
||||||
dst.x = (float)ctx->x + (ctx->gamepad_width - ctx->touchpad_width) / 2;
|
dst.x = (float)ctx->x + (ctx->gamepad_width - ctx->touchpad_width) / 2;
|
||||||
dst.y = (float)ctx->y + ctx->gamepad_height;
|
dst.y = (float)ctx->y + ctx->gamepad_height;
|
||||||
dst.w = (float)ctx->touchpad_width;
|
dst.w = (float)ctx->touchpad_width;
|
||||||
@@ -673,6 +631,8 @@ struct GamepadDisplay
|
|||||||
float gyro_data[3];
|
float gyro_data[3];
|
||||||
Uint64 last_sensor_update;
|
Uint64 last_sensor_update;
|
||||||
|
|
||||||
|
ControllerDisplayMode display_mode;
|
||||||
|
|
||||||
SDL_Rect area;
|
SDL_Rect area;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -691,16 +651,22 @@ GamepadDisplay *CreateGamepadDisplay(SDL_Renderer *renderer)
|
|||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetGamepadDisplayArea(GamepadDisplay *ctx, int x, int y, int w, int h)
|
void SetGamepadDisplayDisplayMode(GamepadDisplay *ctx, ControllerDisplayMode display_mode)
|
||||||
{
|
{
|
||||||
if (!ctx) {
|
if (!ctx) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->area.x = x;
|
ctx->display_mode = display_mode;
|
||||||
ctx->area.y = y;
|
}
|
||||||
ctx->area.w = w;
|
|
||||||
ctx->area.h = h;
|
void SetGamepadDisplayArea(GamepadDisplay *ctx, const SDL_Rect *area)
|
||||||
|
{
|
||||||
|
if (!ctx) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_copyp(&ctx->area, area);
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_bool GetBindingString(const char *label, char *mapping, char *text, size_t size)
|
static SDL_bool GetBindingString(const char *label, char *mapping, char *text, size_t size)
|
||||||
@@ -794,7 +760,7 @@ void RenderGamepadDisplay(GamepadDisplay *ctx, SDL_Gamepad *gamepad)
|
|||||||
const float arrow_extent = 48.0f;
|
const float arrow_extent = 48.0f;
|
||||||
SDL_FRect dst, rect;
|
SDL_FRect dst, rect;
|
||||||
Uint8 r, g, b, a;
|
Uint8 r, g, b, a;
|
||||||
char *mapping;
|
char *mapping = NULL;
|
||||||
SDL_bool has_accel;
|
SDL_bool has_accel;
|
||||||
SDL_bool has_gyro;
|
SDL_bool has_gyro;
|
||||||
|
|
||||||
@@ -812,6 +778,11 @@ void RenderGamepadDisplay(GamepadDisplay *ctx, SDL_Gamepad *gamepad)
|
|||||||
for (i = 0; i < SDL_GAMEPAD_BUTTON_MAX; ++i) {
|
for (i = 0; i < SDL_GAMEPAD_BUTTON_MAX; ++i) {
|
||||||
SDL_GamepadButton button = (SDL_GamepadButton)i;
|
SDL_GamepadButton button = (SDL_GamepadButton)i;
|
||||||
|
|
||||||
|
if (ctx->display_mode == CONTROLLER_MODE_TESTING &&
|
||||||
|
!SDL_GamepadHasButton(gamepad, button)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
SDL_snprintf(text, sizeof(text), "%s:", gamepad_button_names[i]);
|
SDL_snprintf(text, sizeof(text), "%s:", gamepad_button_names[i]);
|
||||||
SDLTest_DrawString(ctx->renderer, x + center - SDL_strlen(text) * FONT_CHARACTER_SIZE, y, text);
|
SDLTest_DrawString(ctx->renderer, x + center - SDL_strlen(text) * FONT_CHARACTER_SIZE, y, text);
|
||||||
|
|
||||||
@@ -827,9 +798,11 @@ void RenderGamepadDisplay(GamepadDisplay *ctx, SDL_Gamepad *gamepad)
|
|||||||
dst.h = (float)ctx->button_height;
|
dst.h = (float)ctx->button_height;
|
||||||
SDL_RenderTexture(ctx->renderer, ctx->button_texture, NULL, &dst);
|
SDL_RenderTexture(ctx->renderer, ctx->button_texture, NULL, &dst);
|
||||||
|
|
||||||
if (GetButtonBindingString(button, mapping, binding, sizeof(binding))) {
|
if (ctx->display_mode == CONTROLLER_MODE_BINDING) {
|
||||||
dst.x += dst.w + 2 * margin;
|
if (GetButtonBindingString(button, mapping, binding, sizeof(binding))) {
|
||||||
SDLTest_DrawString(ctx->renderer, dst.x, y, binding);
|
dst.x += dst.w + 2 * margin;
|
||||||
|
SDLTest_DrawString(ctx->renderer, dst.x, y, binding);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
y += ctx->button_height + 2.0f;
|
y += ctx->button_height + 2.0f;
|
||||||
@@ -838,7 +811,14 @@ void RenderGamepadDisplay(GamepadDisplay *ctx, SDL_Gamepad *gamepad)
|
|||||||
for (i = 0; i < SDL_GAMEPAD_AXIS_MAX; ++i) {
|
for (i = 0; i < SDL_GAMEPAD_AXIS_MAX; ++i) {
|
||||||
SDL_GamepadAxis axis = (SDL_GamepadAxis)i;
|
SDL_GamepadAxis axis = (SDL_GamepadAxis)i;
|
||||||
SDL_bool has_negative = (axis != SDL_GAMEPAD_AXIS_LEFT_TRIGGER && axis != SDL_GAMEPAD_AXIS_RIGHT_TRIGGER);
|
SDL_bool has_negative = (axis != SDL_GAMEPAD_AXIS_LEFT_TRIGGER && axis != SDL_GAMEPAD_AXIS_RIGHT_TRIGGER);
|
||||||
Sint16 value = SDL_GetGamepadAxis(gamepad, axis);
|
Sint16 value;
|
||||||
|
|
||||||
|
if (ctx->display_mode == CONTROLLER_MODE_TESTING &&
|
||||||
|
!SDL_GamepadHasAxis(gamepad, axis)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
value = SDL_GetGamepadAxis(gamepad, axis);
|
||||||
|
|
||||||
SDL_snprintf(text, sizeof(text), "%s:", gamepad_axis_names[i]);
|
SDL_snprintf(text, sizeof(text), "%s:", gamepad_axis_names[i]);
|
||||||
SDLTest_DrawString(ctx->renderer, x + center - SDL_strlen(text) * FONT_CHARACTER_SIZE, y, text);
|
SDLTest_DrawString(ctx->renderer, x + center - SDL_strlen(text) * FONT_CHARACTER_SIZE, y, text);
|
||||||
@@ -875,12 +855,14 @@ void RenderGamepadDisplay(GamepadDisplay *ctx, SDL_Gamepad *gamepad)
|
|||||||
SDL_RenderFillRect(ctx->renderer, &rect);
|
SDL_RenderFillRect(ctx->renderer, &rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (has_negative && GetAxisBindingString(axis, -1, mapping, binding, sizeof(binding))) {
|
if (ctx->display_mode == CONTROLLER_MODE_BINDING && has_negative) {
|
||||||
float text_x;
|
if (GetAxisBindingString(axis, -1, mapping, binding, sizeof(binding))) {
|
||||||
|
float text_x;
|
||||||
|
|
||||||
SDL_SetRenderDrawColor(ctx->renderer, r, g, b, a);
|
SDL_SetRenderDrawColor(ctx->renderer, r, g, b, a);
|
||||||
text_x = dst.x + arrow_extent / 2 - ((float)FONT_CHARACTER_SIZE * SDL_strlen(binding)) / 2;
|
text_x = dst.x + arrow_extent / 2 - ((float)FONT_CHARACTER_SIZE * SDL_strlen(binding)) / 2;
|
||||||
SDLTest_DrawString(ctx->renderer, text_x, y, binding);
|
SDLTest_DrawString(ctx->renderer, text_x, y, binding);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dst.x += arrow_extent;
|
dst.x += arrow_extent;
|
||||||
@@ -894,12 +876,14 @@ void RenderGamepadDisplay(GamepadDisplay *ctx, SDL_Gamepad *gamepad)
|
|||||||
SDL_RenderFillRect(ctx->renderer, &rect);
|
SDL_RenderFillRect(ctx->renderer, &rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetAxisBindingString(axis, 1, mapping, binding, sizeof(binding))) {
|
if (ctx->display_mode == CONTROLLER_MODE_BINDING) {
|
||||||
float text_x;
|
if (GetAxisBindingString(axis, 1, mapping, binding, sizeof(binding))) {
|
||||||
|
float text_x;
|
||||||
|
|
||||||
SDL_SetRenderDrawColor(ctx->renderer, r, g, b, a);
|
SDL_SetRenderDrawColor(ctx->renderer, r, g, b, a);
|
||||||
text_x = dst.x + arrow_extent / 2 - ((float)FONT_CHARACTER_SIZE * SDL_strlen(binding)) / 2;
|
text_x = dst.x + arrow_extent / 2 - ((float)FONT_CHARACTER_SIZE * SDL_strlen(binding)) / 2;
|
||||||
SDLTest_DrawString(ctx->renderer, text_x, y, binding);
|
SDLTest_DrawString(ctx->renderer, text_x, y, binding);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dst.x += arrow_extent;
|
dst.x += arrow_extent;
|
||||||
@@ -916,72 +900,74 @@ void RenderGamepadDisplay(GamepadDisplay *ctx, SDL_Gamepad *gamepad)
|
|||||||
y += ctx->button_height + 2;
|
y += ctx->button_height + 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SDL_GetNumGamepadTouchpads(gamepad) > 0) {
|
if (ctx->display_mode == CONTROLLER_MODE_TESTING) {
|
||||||
int num_fingers = SDL_GetNumGamepadTouchpadFingers(gamepad, 0);
|
if (SDL_GetNumGamepadTouchpads(gamepad) > 0) {
|
||||||
for (i = 0; i < num_fingers; ++i) {
|
int num_fingers = SDL_GetNumGamepadTouchpadFingers(gamepad, 0);
|
||||||
Uint8 state;
|
for (i = 0; i < num_fingers; ++i) {
|
||||||
float finger_x, finger_y, finger_pressure;
|
Uint8 state;
|
||||||
|
float finger_x, finger_y, finger_pressure;
|
||||||
|
|
||||||
if (SDL_GetGamepadTouchpadFinger(gamepad, 0, i, &state, &finger_x, &finger_y, &finger_pressure) < 0) {
|
if (SDL_GetGamepadTouchpadFinger(gamepad, 0, i, &state, &finger_x, &finger_y, &finger_pressure) < 0) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_snprintf(text, sizeof(text), "Touch finger %d:", i);
|
||||||
|
SDLTest_DrawString(ctx->renderer, x + center - SDL_strlen(text) * FONT_CHARACTER_SIZE, y, text);
|
||||||
|
|
||||||
|
if (state) {
|
||||||
|
SDL_SetTextureColorMod(ctx->button_texture, 10, 255, 21);
|
||||||
|
} else {
|
||||||
|
SDL_SetTextureColorMod(ctx->button_texture, 255, 255, 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
dst.x = x + center + 2.0f;
|
||||||
|
dst.y = y + FONT_CHARACTER_SIZE / 2 - ctx->button_height / 2;
|
||||||
|
dst.w = (float)ctx->button_width;
|
||||||
|
dst.h = (float)ctx->button_height;
|
||||||
|
SDL_RenderTexture(ctx->renderer, ctx->button_texture, NULL, &dst);
|
||||||
|
|
||||||
|
if (state) {
|
||||||
|
SDL_snprintf(text, sizeof(text), "(%.2f,%.2f)", finger_x, finger_y);
|
||||||
|
SDLTest_DrawString(ctx->renderer, x + center + ctx->button_width + 4.0f, y, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
y += ctx->button_height + 2.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_snprintf(text, sizeof(text), "Touch finger %d:", i);
|
|
||||||
SDLTest_DrawString(ctx->renderer, x + center - SDL_strlen(text) * FONT_CHARACTER_SIZE, y, text);
|
|
||||||
|
|
||||||
if (state) {
|
|
||||||
SDL_SetTextureColorMod(ctx->button_texture, 10, 255, 21);
|
|
||||||
} else {
|
|
||||||
SDL_SetTextureColorMod(ctx->button_texture, 255, 255, 255);
|
|
||||||
}
|
|
||||||
|
|
||||||
dst.x = x + center + 2.0f;
|
|
||||||
dst.y = y + FONT_CHARACTER_SIZE / 2 - ctx->button_height / 2;
|
|
||||||
dst.w = (float)ctx->button_width;
|
|
||||||
dst.h = (float)ctx->button_height;
|
|
||||||
SDL_RenderTexture(ctx->renderer, ctx->button_texture, NULL, &dst);
|
|
||||||
|
|
||||||
if (state) {
|
|
||||||
SDL_snprintf(text, sizeof(text), "(%.2f,%.2f)", finger_x, finger_y);
|
|
||||||
SDLTest_DrawString(ctx->renderer, x + center + ctx->button_width + 4.0f, y, text);
|
|
||||||
}
|
|
||||||
|
|
||||||
y += ctx->button_height + 2.0f;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
has_accel = SDL_GamepadHasSensor(gamepad, SDL_SENSOR_ACCEL);
|
has_accel = SDL_GamepadHasSensor(gamepad, SDL_SENSOR_ACCEL);
|
||||||
has_gyro = SDL_GamepadHasSensor(gamepad, SDL_SENSOR_GYRO);
|
has_gyro = SDL_GamepadHasSensor(gamepad, SDL_SENSOR_GYRO);
|
||||||
if (has_accel || has_gyro) {
|
if (has_accel || has_gyro) {
|
||||||
const int SENSOR_UPDATE_INTERVAL_MS = 100;
|
const int SENSOR_UPDATE_INTERVAL_MS = 100;
|
||||||
Uint64 now = SDL_GetTicks();
|
Uint64 now = SDL_GetTicks();
|
||||||
|
|
||||||
|
if (now >= ctx->last_sensor_update + SENSOR_UPDATE_INTERVAL_MS) {
|
||||||
|
if (has_accel) {
|
||||||
|
SDL_GetGamepadSensorData(gamepad, SDL_SENSOR_ACCEL, ctx->accel_data, SDL_arraysize(ctx->accel_data));
|
||||||
|
}
|
||||||
|
if (has_gyro) {
|
||||||
|
SDL_GetGamepadSensorData(gamepad, SDL_SENSOR_GYRO, ctx->gyro_data, SDL_arraysize(ctx->gyro_data));
|
||||||
|
}
|
||||||
|
ctx->last_sensor_update = now;
|
||||||
|
}
|
||||||
|
|
||||||
if (now >= ctx->last_sensor_update + SENSOR_UPDATE_INTERVAL_MS) {
|
|
||||||
if (has_accel) {
|
if (has_accel) {
|
||||||
SDL_GetGamepadSensorData(gamepad, SDL_SENSOR_ACCEL, ctx->accel_data, SDL_arraysize(ctx->accel_data));
|
SDL_strlcpy(text, "Accelerometer:", sizeof(text));
|
||||||
|
SDLTest_DrawString(ctx->renderer, x + center - SDL_strlen(text) * FONT_CHARACTER_SIZE, y, text);
|
||||||
|
SDL_snprintf(text, sizeof(text), "(%.2f,%.2f,%.2f)", ctx->accel_data[0], ctx->accel_data[1], ctx->accel_data[2]);
|
||||||
|
SDLTest_DrawString(ctx->renderer, x + center + 2.0f, y, text);
|
||||||
|
|
||||||
|
y += ctx->button_height + 2.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (has_gyro) {
|
if (has_gyro) {
|
||||||
SDL_GetGamepadSensorData(gamepad, SDL_SENSOR_GYRO, ctx->gyro_data, SDL_arraysize(ctx->gyro_data));
|
SDL_strlcpy(text, "Gyro:", sizeof(text));
|
||||||
|
SDLTest_DrawString(ctx->renderer, x + center - SDL_strlen(text) * FONT_CHARACTER_SIZE, y, text);
|
||||||
|
SDL_snprintf(text, sizeof(text), "(%.2f,%.2f,%.2f)", ctx->gyro_data[0], ctx->gyro_data[1], ctx->gyro_data[2]);
|
||||||
|
SDLTest_DrawString(ctx->renderer, x + center + 2.0f, y, text);
|
||||||
|
|
||||||
|
y += ctx->button_height + 2.0f;
|
||||||
}
|
}
|
||||||
ctx->last_sensor_update = now;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (has_accel) {
|
|
||||||
SDL_strlcpy(text, "Accelerometer:", sizeof(text));
|
|
||||||
SDLTest_DrawString(ctx->renderer, x + center - SDL_strlen(text) * FONT_CHARACTER_SIZE, y, text);
|
|
||||||
SDL_snprintf(text, sizeof(text), "(%.2f,%.2f,%.2f)", ctx->accel_data[0], ctx->accel_data[1], ctx->accel_data[2]);
|
|
||||||
SDLTest_DrawString(ctx->renderer, x + center + 2.0f, y, text);
|
|
||||||
|
|
||||||
y += ctx->button_height + 2.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (has_gyro) {
|
|
||||||
SDL_strlcpy(text, "Gyro:", sizeof(text));
|
|
||||||
SDLTest_DrawString(ctx->renderer, x + center - SDL_strlen(text) * FONT_CHARACTER_SIZE, y, text);
|
|
||||||
SDL_snprintf(text, sizeof(text), "(%.2f,%.2f,%.2f)", ctx->gyro_data[0], ctx->gyro_data[1], ctx->gyro_data[2]);
|
|
||||||
SDLTest_DrawString(ctx->renderer, x + center + 2.0f, y, text);
|
|
||||||
|
|
||||||
y += ctx->button_height + 2.0f;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1028,16 +1014,13 @@ JoystickDisplay *CreateJoystickDisplay(SDL_Renderer *renderer)
|
|||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetJoystickDisplayArea(JoystickDisplay *ctx, int x, int y, int w, int h)
|
void SetJoystickDisplayArea(JoystickDisplay *ctx, const SDL_Rect *area)
|
||||||
{
|
{
|
||||||
if (!ctx) {
|
if (!ctx) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->area.x = x;
|
SDL_copyp(&ctx->area, area);
|
||||||
ctx->area.y = y;
|
|
||||||
ctx->area.w = w;
|
|
||||||
ctx->area.h = h;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderJoystickDisplay(JoystickDisplay *ctx, SDL_Joystick *joystick)
|
void RenderJoystickDisplay(JoystickDisplay *ctx, SDL_Joystick *joystick)
|
||||||
@@ -1259,16 +1242,16 @@ GamepadButton *CreateGamepadButton(SDL_Renderer *renderer, const char *label)
|
|||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetGamepadButtonArea(GamepadButton *ctx, int x, int y, int w, int h)
|
void SetGamepadButtonArea(GamepadButton *ctx, const SDL_Rect *area)
|
||||||
{
|
{
|
||||||
if (!ctx) {
|
if (!ctx) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->area.x = (float)x;
|
ctx->area.x = (float)area->x;
|
||||||
ctx->area.y = (float)y;
|
ctx->area.y = (float)area->y;
|
||||||
ctx->area.w = (float)w;
|
ctx->area.w = (float)area->w;
|
||||||
ctx->area.h = (float)h;
|
ctx->area.h = (float)area->h;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetGamepadButtonHighlight(GamepadButton *ctx, SDL_bool highlight)
|
void SetGamepadButtonHighlight(GamepadButton *ctx, SDL_bool highlight)
|
||||||
|
@@ -14,6 +14,12 @@
|
|||||||
|
|
||||||
typedef struct GamepadImage GamepadImage;
|
typedef struct GamepadImage GamepadImage;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
CONTROLLER_MODE_TESTING,
|
||||||
|
CONTROLLER_MODE_BINDING,
|
||||||
|
} ControllerDisplayMode;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
GAMEPAD_IMAGE_FACE_BLANK,
|
GAMEPAD_IMAGE_FACE_BLANK,
|
||||||
@@ -26,9 +32,7 @@ extern GamepadImage *CreateGamepadImage(SDL_Renderer *renderer);
|
|||||||
extern void SetGamepadImagePosition(GamepadImage *ctx, int x, int y);
|
extern void SetGamepadImagePosition(GamepadImage *ctx, int x, int y);
|
||||||
extern void SetGamepadImageShowingFront(GamepadImage *ctx, SDL_bool showing_front);
|
extern void SetGamepadImageShowingFront(GamepadImage *ctx, SDL_bool showing_front);
|
||||||
extern void SetGamepadImageFaceStyle(GamepadImage *ctx, GamepadImageFaceStyle face_style);
|
extern void SetGamepadImageFaceStyle(GamepadImage *ctx, GamepadImageFaceStyle face_style);
|
||||||
extern void SetGamepadImageShowingBattery(GamepadImage *ctx, SDL_bool showing_battery);
|
extern void SetGamepadImageDisplayMode(GamepadImage *ctx, ControllerDisplayMode display_mode);
|
||||||
extern void SetGamepadImageShowingTouchpad(GamepadImage *ctx, SDL_bool showing_touchpad);
|
|
||||||
extern void GetGamepadImageArea(GamepadImage *ctx, int *x, int *y, int *width, int *height);
|
|
||||||
extern int GetGamepadImageButtonWidth(GamepadImage *ctx);
|
extern int GetGamepadImageButtonWidth(GamepadImage *ctx);
|
||||||
extern int GetGamepadImageButtonHeight(GamepadImage *ctx);
|
extern int GetGamepadImageButtonHeight(GamepadImage *ctx);
|
||||||
extern int GetGamepadImageAxisWidth(GamepadImage *ctx);
|
extern int GetGamepadImageAxisWidth(GamepadImage *ctx);
|
||||||
@@ -50,7 +54,8 @@ extern void DestroyGamepadImage(GamepadImage *ctx);
|
|||||||
typedef struct GamepadDisplay GamepadDisplay;
|
typedef struct GamepadDisplay GamepadDisplay;
|
||||||
|
|
||||||
extern GamepadDisplay *CreateGamepadDisplay(SDL_Renderer *renderer);
|
extern GamepadDisplay *CreateGamepadDisplay(SDL_Renderer *renderer);
|
||||||
extern void SetGamepadDisplayArea(GamepadDisplay *ctx, int x, int y, int w, int h);
|
extern void SetGamepadDisplayDisplayMode(GamepadDisplay *ctx, ControllerDisplayMode display_mode);
|
||||||
|
extern void SetGamepadDisplayArea(GamepadDisplay *ctx, const SDL_Rect *area);
|
||||||
extern void RenderGamepadDisplay(GamepadDisplay *ctx, SDL_Gamepad *gamepad);
|
extern void RenderGamepadDisplay(GamepadDisplay *ctx, SDL_Gamepad *gamepad);
|
||||||
extern void DestroyGamepadDisplay(GamepadDisplay *ctx);
|
extern void DestroyGamepadDisplay(GamepadDisplay *ctx);
|
||||||
|
|
||||||
@@ -59,7 +64,7 @@ extern void DestroyGamepadDisplay(GamepadDisplay *ctx);
|
|||||||
typedef struct JoystickDisplay JoystickDisplay;
|
typedef struct JoystickDisplay JoystickDisplay;
|
||||||
|
|
||||||
extern JoystickDisplay *CreateJoystickDisplay(SDL_Renderer *renderer);
|
extern JoystickDisplay *CreateJoystickDisplay(SDL_Renderer *renderer);
|
||||||
extern void SetJoystickDisplayArea(JoystickDisplay *ctx, int x, int y, int w, int h);
|
extern void SetJoystickDisplayArea(JoystickDisplay *ctx, const SDL_Rect *area);
|
||||||
extern void RenderJoystickDisplay(JoystickDisplay *ctx, SDL_Joystick *joystick);
|
extern void RenderJoystickDisplay(JoystickDisplay *ctx, SDL_Joystick *joystick);
|
||||||
extern void DestroyJoystickDisplay(JoystickDisplay *ctx);
|
extern void DestroyJoystickDisplay(JoystickDisplay *ctx);
|
||||||
|
|
||||||
@@ -68,7 +73,7 @@ extern void DestroyJoystickDisplay(JoystickDisplay *ctx);
|
|||||||
typedef struct GamepadButton GamepadButton;
|
typedef struct GamepadButton GamepadButton;
|
||||||
|
|
||||||
extern GamepadButton *CreateGamepadButton(SDL_Renderer *renderer, const char *label);
|
extern GamepadButton *CreateGamepadButton(SDL_Renderer *renderer, const char *label);
|
||||||
extern void SetGamepadButtonArea(GamepadButton *ctx, int x, int y, int w, int h);
|
extern void SetGamepadButtonArea(GamepadButton *ctx, const SDL_Rect *area);
|
||||||
extern void SetGamepadButtonHighlight(GamepadButton *ctx, SDL_bool highlight);
|
extern void SetGamepadButtonHighlight(GamepadButton *ctx, SDL_bool highlight);
|
||||||
extern int GetGamepadButtonLabelWidth(GamepadButton *ctx);
|
extern int GetGamepadButtonLabelWidth(GamepadButton *ctx);
|
||||||
extern int GetGamepadButtonLabelHeight(GamepadButton *ctx);
|
extern int GetGamepadButtonLabelHeight(GamepadButton *ctx);
|
||||||
|
@@ -27,7 +27,8 @@
|
|||||||
#define TITLE_HEIGHT 48
|
#define TITLE_HEIGHT 48
|
||||||
#define PANEL_SPACING 25
|
#define PANEL_SPACING 25
|
||||||
#define PANEL_WIDTH 250
|
#define PANEL_WIDTH 250
|
||||||
#define BUTTON_MARGIN 8
|
#define MINIMUM_BUTTON_WIDTH 96
|
||||||
|
#define BUTTON_MARGIN 16
|
||||||
#define BUTTON_PADDING 12
|
#define BUTTON_PADDING 12
|
||||||
#define GAMEPAD_WIDTH 512
|
#define GAMEPAD_WIDTH 512
|
||||||
#define GAMEPAD_HEIGHT 480
|
#define GAMEPAD_HEIGHT 480
|
||||||
@@ -56,10 +57,17 @@ typedef struct
|
|||||||
|
|
||||||
static SDL_Window *window = NULL;
|
static SDL_Window *window = NULL;
|
||||||
static SDL_Renderer *screen = NULL;
|
static SDL_Renderer *screen = NULL;
|
||||||
|
static ControllerDisplayMode display_mode = CONTROLLER_MODE_TESTING;
|
||||||
static GamepadImage *image = NULL;
|
static GamepadImage *image = NULL;
|
||||||
static GamepadDisplay *gamepad_elements = NULL;
|
static GamepadDisplay *gamepad_elements = NULL;
|
||||||
static JoystickDisplay *joystick_elements = NULL;
|
static JoystickDisplay *joystick_elements = NULL;
|
||||||
|
static GamepadButton *setup_mapping_button = NULL;
|
||||||
|
static GamepadButton *test_mapping_button = NULL;
|
||||||
|
static GamepadButton *cancel_button = NULL;
|
||||||
|
static GamepadButton *clear_button = NULL;
|
||||||
static GamepadButton *copy_button = NULL;
|
static GamepadButton *copy_button = NULL;
|
||||||
|
static GamepadButton *paste_button = NULL;
|
||||||
|
static char *backup_mapping = NULL;
|
||||||
static SDL_bool retval = SDL_FALSE;
|
static SDL_bool retval = SDL_FALSE;
|
||||||
static SDL_bool done = SDL_FALSE;
|
static SDL_bool done = SDL_FALSE;
|
||||||
static SDL_bool set_LED = SDL_FALSE;
|
static SDL_bool set_LED = SDL_FALSE;
|
||||||
@@ -209,6 +217,104 @@ static void CyclePS5TriggerEffect(Controller *device)
|
|||||||
SDL_SendGamepadEffect(device->gamepad, &state, sizeof(state));
|
SDL_SendGamepadEffect(device->gamepad, &state, sizeof(state));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ClearButtonHighlights()
|
||||||
|
{
|
||||||
|
SetGamepadButtonHighlight(setup_mapping_button, SDL_FALSE);
|
||||||
|
SetGamepadButtonHighlight(test_mapping_button, SDL_FALSE);
|
||||||
|
SetGamepadButtonHighlight(cancel_button, SDL_FALSE);
|
||||||
|
SetGamepadButtonHighlight(clear_button, SDL_FALSE);
|
||||||
|
SetGamepadButtonHighlight(copy_button, SDL_FALSE);
|
||||||
|
SetGamepadButtonHighlight(paste_button, SDL_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void UpdateButtonHighlights(float x, float y)
|
||||||
|
{
|
||||||
|
ClearButtonHighlights();
|
||||||
|
|
||||||
|
if (display_mode == CONTROLLER_MODE_TESTING) {
|
||||||
|
SetGamepadButtonHighlight(setup_mapping_button, GamepadButtonContains(setup_mapping_button, x, y));
|
||||||
|
} else if (display_mode == CONTROLLER_MODE_BINDING) {
|
||||||
|
SetGamepadButtonHighlight(test_mapping_button, GamepadButtonContains(test_mapping_button, x, y));
|
||||||
|
SetGamepadButtonHighlight(cancel_button, GamepadButtonContains(cancel_button, x, y));
|
||||||
|
SetGamepadButtonHighlight(clear_button, GamepadButtonContains(clear_button, x, y));
|
||||||
|
SetGamepadButtonHighlight(copy_button, GamepadButtonContains(copy_button, x, y));
|
||||||
|
SetGamepadButtonHighlight(paste_button, GamepadButtonContains(paste_button, x, y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetDisplayMode(ControllerDisplayMode mode)
|
||||||
|
{
|
||||||
|
float x, y;
|
||||||
|
|
||||||
|
if (mode == CONTROLLER_MODE_BINDING) {
|
||||||
|
/* Make a backup of the current mapping */
|
||||||
|
backup_mapping = SDL_GetGamepadMapping(controller->gamepad);
|
||||||
|
}
|
||||||
|
|
||||||
|
display_mode = mode;
|
||||||
|
SetGamepadImageDisplayMode(image, mode);
|
||||||
|
SetGamepadDisplayDisplayMode(gamepad_elements, mode);
|
||||||
|
|
||||||
|
SDL_GetMouseState(&x, &y);
|
||||||
|
SDL_RenderCoordinatesFromWindow(screen, x, y, &x, &y);
|
||||||
|
UpdateButtonHighlights(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CancelMapping(void)
|
||||||
|
{
|
||||||
|
if (backup_mapping) {
|
||||||
|
SDL_SetGamepadMapping(controller->id, backup_mapping);
|
||||||
|
SDL_free(backup_mapping);
|
||||||
|
backup_mapping = NULL;
|
||||||
|
}
|
||||||
|
SetDisplayMode(CONTROLLER_MODE_TESTING);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ClearMapping(void)
|
||||||
|
{
|
||||||
|
SDL_SetGamepadMapping(controller->id, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CopyMapping(void)
|
||||||
|
{
|
||||||
|
if (controller && controller->gamepad) {
|
||||||
|
char *mapping = SDL_GetGamepadMapping(controller->gamepad);
|
||||||
|
if (mapping) {
|
||||||
|
const char *name = SDL_GetGamepadName(controller->gamepad);
|
||||||
|
char *wildcard = SDL_strchr(mapping, '*');
|
||||||
|
if (wildcard && name && *name) {
|
||||||
|
char *text;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
/* Personalize the mapping for this controller */
|
||||||
|
*wildcard++ = '\0';
|
||||||
|
size = SDL_strlen(mapping) + SDL_strlen(name) + SDL_strlen(wildcard) + 1;
|
||||||
|
text = SDL_malloc(size);
|
||||||
|
if (!text) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SDL_snprintf(text, size, "%s%s%s", mapping, name, wildcard);
|
||||||
|
SDL_SetClipboardText(text);
|
||||||
|
SDL_free(text);
|
||||||
|
} else {
|
||||||
|
SDL_SetClipboardText(mapping);
|
||||||
|
}
|
||||||
|
SDL_free(mapping);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PasteMapping(void)
|
||||||
|
{
|
||||||
|
if (controller) {
|
||||||
|
char *mapping = SDL_GetClipboardText();
|
||||||
|
if (*mapping) {
|
||||||
|
SDL_SetGamepadMapping(controller->id, mapping);
|
||||||
|
}
|
||||||
|
SDL_free(mapping);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int FindController(SDL_JoystickID id)
|
static int FindController(SDL_JoystickID id)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@@ -225,29 +331,21 @@ static void SetController(SDL_JoystickID id)
|
|||||||
{
|
{
|
||||||
int i = FindController(id);
|
int i = FindController(id);
|
||||||
|
|
||||||
|
if (i >= 0 && display_mode == CONTROLLER_MODE_BINDING) {
|
||||||
|
/* Don't change controllers while binding */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (i < 0 && num_controllers > 0) {
|
if (i < 0 && num_controllers > 0) {
|
||||||
i = 0;
|
i = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i >= 0) {
|
if (i >= 0) {
|
||||||
controller = &controllers[i];
|
controller = &controllers[i];
|
||||||
|
|
||||||
if (controller->gamepad) {
|
|
||||||
SetGamepadImageShowingBattery(image, SDL_TRUE);
|
|
||||||
} else {
|
|
||||||
SetGamepadImageShowingBattery(image, SDL_FALSE);
|
|
||||||
}
|
|
||||||
if (SDL_GetNumGamepadTouchpads(controller->gamepad) > 0) {
|
|
||||||
SetGamepadImageShowingTouchpad(image, SDL_TRUE);
|
|
||||||
} else {
|
|
||||||
SetGamepadImageShowingTouchpad(image, SDL_FALSE);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
controller = NULL;
|
controller = NULL;
|
||||||
|
|
||||||
SetGamepadImageShowingBattery(image, SDL_FALSE);
|
|
||||||
SetGamepadImageShowingTouchpad(image, SDL_FALSE);
|
|
||||||
}
|
}
|
||||||
|
SetDisplayMode(CONTROLLER_MODE_TESTING);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AddController(SDL_JoystickID id, SDL_bool verbose)
|
static void AddController(SDL_JoystickID id, SDL_bool verbose)
|
||||||
@@ -354,6 +452,19 @@ static void DelController(SDL_JoystickID id)
|
|||||||
SetController(0);
|
SetController(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void HandleGamepadRemapped(SDL_JoystickID id)
|
||||||
|
{
|
||||||
|
int i = FindController(id);
|
||||||
|
|
||||||
|
if (i < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!controllers[i].gamepad) {
|
||||||
|
controllers[i].gamepad = SDL_OpenGamepad(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static Uint16 ConvertAxisToRumble(Sint16 axisval)
|
static Uint16 ConvertAxisToRumble(Sint16 axisval)
|
||||||
{
|
{
|
||||||
/* Only start rumbling if the axis is past the halfway point */
|
/* Only start rumbling if the axis is past the halfway point */
|
||||||
@@ -413,6 +524,10 @@ static void OpenVirtualGamepad(void)
|
|||||||
SDL_VirtualJoystickDesc desc;
|
SDL_VirtualJoystickDesc desc;
|
||||||
SDL_JoystickID virtual_id;
|
SDL_JoystickID virtual_id;
|
||||||
|
|
||||||
|
if (virtual_joystick) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
SDL_zero(desc);
|
SDL_zero(desc);
|
||||||
desc.version = SDL_VIRTUAL_JOYSTICK_DESC_VERSION;
|
desc.version = SDL_VIRTUAL_JOYSTICK_DESC_VERSION;
|
||||||
desc.type = SDL_JOYSTICK_TYPE_GAMEPAD;
|
desc.type = SDL_JOYSTICK_TYPE_GAMEPAD;
|
||||||
@@ -578,47 +693,76 @@ static void DrawGamepadInfo(SDL_Renderer *renderer)
|
|||||||
SDLTest_DrawString(renderer, x, y, text);
|
SDLTest_DrawString(renderer, x, y, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_snprintf(text, SDL_arraysize(text), "VID: 0x%.4x PID: 0x%.4x",
|
if (display_mode == CONTROLLER_MODE_TESTING) {
|
||||||
SDL_GetJoystickVendor(controller->joystick),
|
SDL_snprintf(text, SDL_arraysize(text), "VID: 0x%.4x PID: 0x%.4x",
|
||||||
SDL_GetJoystickProduct(controller->joystick));
|
SDL_GetJoystickVendor(controller->joystick),
|
||||||
y = (float)SCREEN_HEIGHT - 8.0f - FONT_LINE_HEIGHT;
|
SDL_GetJoystickProduct(controller->joystick));
|
||||||
x = (float)SCREEN_WIDTH - 8.0f - (FONT_CHARACTER_SIZE * SDL_strlen(text));
|
|
||||||
SDLTest_DrawString(renderer, x, y, text);
|
|
||||||
|
|
||||||
serial = SDL_GetJoystickSerial(controller->joystick);
|
|
||||||
if (serial && *serial) {
|
|
||||||
SDL_snprintf(text, SDL_arraysize(text), "Serial: %s", serial);
|
|
||||||
x = (float)SCREEN_WIDTH / 2 - (FONT_CHARACTER_SIZE * SDL_strlen(text)) / 2;
|
|
||||||
y = (float)SCREEN_HEIGHT - 8.0f - FONT_LINE_HEIGHT;
|
y = (float)SCREEN_HEIGHT - 8.0f - FONT_LINE_HEIGHT;
|
||||||
|
x = (float)SCREEN_WIDTH - 8.0f - (FONT_CHARACTER_SIZE * SDL_strlen(text));
|
||||||
SDLTest_DrawString(renderer, x, y, text);
|
SDLTest_DrawString(renderer, x, y, text);
|
||||||
|
|
||||||
|
serial = SDL_GetJoystickSerial(controller->joystick);
|
||||||
|
if (serial && *serial) {
|
||||||
|
SDL_snprintf(text, SDL_arraysize(text), "Serial: %s", serial);
|
||||||
|
x = (float)SCREEN_WIDTH / 2 - (FONT_CHARACTER_SIZE * SDL_strlen(text)) / 2;
|
||||||
|
y = (float)SCREEN_HEIGHT - 8.0f - FONT_LINE_HEIGHT;
|
||||||
|
SDLTest_DrawString(renderer, x, y, text);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CopyMappingToClipboard()
|
static void UpdateGamepadEffects(void)
|
||||||
{
|
{
|
||||||
if (controller && controller->gamepad) {
|
if (display_mode != CONTROLLER_MODE_TESTING || !controller->gamepad) {
|
||||||
char *mapping = SDL_GetGamepadMapping(controller->gamepad);
|
return;
|
||||||
if (mapping) {
|
}
|
||||||
const char *name = SDL_GetGamepadName(controller->gamepad);
|
|
||||||
char *wildcard = SDL_strchr(mapping, '*');
|
|
||||||
if (wildcard && name && *name) {
|
|
||||||
char *text;
|
|
||||||
size_t size;
|
|
||||||
|
|
||||||
/* Personalize the mapping for this controller */
|
/* Update LED based on left thumbstick position */
|
||||||
*wildcard++ = '\0';
|
{
|
||||||
size = SDL_strlen(mapping) + SDL_strlen(name) + SDL_strlen(wildcard) + 1;
|
Sint16 x = SDL_GetGamepadAxis(controller->gamepad, SDL_GAMEPAD_AXIS_LEFTX);
|
||||||
text = SDL_malloc(size);
|
Sint16 y = SDL_GetGamepadAxis(controller->gamepad, SDL_GAMEPAD_AXIS_LEFTY);
|
||||||
if (!text) {
|
|
||||||
return;
|
if (!set_LED) {
|
||||||
}
|
set_LED = (x < -8000 || x > 8000 || y > 8000);
|
||||||
SDL_snprintf(text, size, "%s%s%s", mapping, name, wildcard);
|
}
|
||||||
SDL_SetClipboardText(text);
|
if (set_LED) {
|
||||||
SDL_free(text);
|
Uint8 r, g, b;
|
||||||
|
|
||||||
|
if (x < 0) {
|
||||||
|
r = (Uint8)(((~x) * 255) / 32767);
|
||||||
|
b = 0;
|
||||||
} else {
|
} else {
|
||||||
SDL_SetClipboardText(mapping);
|
r = 0;
|
||||||
|
b = (Uint8)(((int)(x)*255) / 32767);
|
||||||
}
|
}
|
||||||
SDL_free(mapping);
|
if (y > 0) {
|
||||||
|
g = (Uint8)(((int)(y)*255) / 32767);
|
||||||
|
} else {
|
||||||
|
g = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_SetGamepadLED(controller->gamepad, r, g, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (controller->trigger_effect == 0) {
|
||||||
|
/* Update rumble based on trigger state */
|
||||||
|
{
|
||||||
|
Sint16 left = SDL_GetGamepadAxis(controller->gamepad, SDL_GAMEPAD_AXIS_LEFT_TRIGGER);
|
||||||
|
Sint16 right = SDL_GetGamepadAxis(controller->gamepad, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER);
|
||||||
|
Uint16 low_frequency_rumble = ConvertAxisToRumble(left);
|
||||||
|
Uint16 high_frequency_rumble = ConvertAxisToRumble(right);
|
||||||
|
SDL_RumbleGamepad(controller->gamepad, low_frequency_rumble, high_frequency_rumble, 250);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update trigger rumble based on thumbstick state */
|
||||||
|
{
|
||||||
|
Sint16 left = SDL_GetGamepadAxis(controller->gamepad, SDL_GAMEPAD_AXIS_LEFTY);
|
||||||
|
Sint16 right = SDL_GetGamepadAxis(controller->gamepad, SDL_GAMEPAD_AXIS_RIGHTY);
|
||||||
|
Uint16 left_rumble = ConvertAxisToRumble(~left);
|
||||||
|
Uint16 right_rumble = ConvertAxisToRumble(~right);
|
||||||
|
|
||||||
|
SDL_RumbleGamepadTriggers(controller->gamepad, left_rumble, right_rumble, 250);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -653,6 +797,10 @@ static void loop(void *arg)
|
|||||||
SetController(event.jbutton.which);
|
SetController(event.jbutton.which);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SDL_EVENT_GAMEPAD_REMAPPED:
|
||||||
|
HandleGamepadRemapped(event.gdevice.which);
|
||||||
|
break;
|
||||||
|
|
||||||
case SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN:
|
case SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN:
|
||||||
case SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION:
|
case SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION:
|
||||||
case SDL_EVENT_GAMEPAD_TOUCHPAD_UP:
|
case SDL_EVENT_GAMEPAD_TOUCHPAD_UP:
|
||||||
@@ -702,11 +850,13 @@ static void loop(void *arg)
|
|||||||
SDL_GetGamepadStringForButton((SDL_GamepadButton) event.gbutton.button),
|
SDL_GetGamepadStringForButton((SDL_GamepadButton) event.gbutton.button),
|
||||||
event.gbutton.state ? "pressed" : "released");
|
event.gbutton.state ? "pressed" : "released");
|
||||||
|
|
||||||
/* Cycle PS5 trigger effects when the microphone button is pressed */
|
if (display_mode == CONTROLLER_MODE_TESTING) {
|
||||||
if (event.type == SDL_EVENT_GAMEPAD_BUTTON_DOWN &&
|
/* Cycle PS5 trigger effects when the microphone button is pressed */
|
||||||
controller && SDL_GetGamepadType(controller->gamepad) == SDL_GAMEPAD_TYPE_PS5 &&
|
if (event.type == SDL_EVENT_GAMEPAD_BUTTON_DOWN &&
|
||||||
event.gbutton.button == SDL_GAMEPAD_BUTTON_MISC1) {
|
controller && SDL_GetGamepadType(controller->gamepad) == SDL_GAMEPAD_TYPE_PS5 &&
|
||||||
CyclePS5TriggerEffect(controller);
|
event.gbutton.button == SDL_GAMEPAD_BUTTON_MISC1) {
|
||||||
|
CyclePS5TriggerEffect(controller);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -715,48 +865,72 @@ static void loop(void *arg)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SDL_EVENT_MOUSE_BUTTON_DOWN:
|
case SDL_EVENT_MOUSE_BUTTON_DOWN:
|
||||||
if (virtual_joystick) {
|
if (virtual_joystick && controller->joystick == virtual_joystick) {
|
||||||
VirtualGamepadMouseDown(event.button.x, event.button.y);
|
VirtualGamepadMouseDown(event.button.x, event.button.y);
|
||||||
}
|
}
|
||||||
SetGamepadButtonHighlight(copy_button, GamepadButtonContains(copy_button, event.button.x, event.button.y));
|
UpdateButtonHighlights(event.button.x, event.button.y);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDL_EVENT_MOUSE_BUTTON_UP:
|
case SDL_EVENT_MOUSE_BUTTON_UP:
|
||||||
if (virtual_joystick) {
|
if (virtual_joystick && controller->joystick == virtual_joystick) {
|
||||||
VirtualGamepadMouseUp(event.button.x, event.button.y);
|
VirtualGamepadMouseUp(event.button.x, event.button.y);
|
||||||
}
|
}
|
||||||
if (GamepadButtonContains(copy_button, event.button.x, event.button.y)) {
|
|
||||||
CopyMappingToClipboard();
|
ClearButtonHighlights();
|
||||||
|
|
||||||
|
if (display_mode == CONTROLLER_MODE_TESTING) {
|
||||||
|
if (GamepadButtonContains(setup_mapping_button, event.button.x, event.button.y)) {
|
||||||
|
SetDisplayMode(CONTROLLER_MODE_BINDING);
|
||||||
|
}
|
||||||
|
} else if (display_mode == CONTROLLER_MODE_BINDING) {
|
||||||
|
if (GamepadButtonContains(test_mapping_button, event.button.x, event.button.y)) {
|
||||||
|
SetDisplayMode(CONTROLLER_MODE_TESTING);
|
||||||
|
} else if (GamepadButtonContains(cancel_button, event.button.x, event.button.y)) {
|
||||||
|
CancelMapping();
|
||||||
|
} else if (GamepadButtonContains(clear_button, event.button.x, event.button.y)) {
|
||||||
|
ClearMapping();
|
||||||
|
} else if (GamepadButtonContains(copy_button, event.button.x, event.button.y)) {
|
||||||
|
CopyMapping();
|
||||||
|
} else if (GamepadButtonContains(paste_button, event.button.x, event.button.y)) {
|
||||||
|
PasteMapping();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
SetGamepadButtonHighlight(copy_button, SDL_FALSE);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDL_EVENT_MOUSE_MOTION:
|
case SDL_EVENT_MOUSE_MOTION:
|
||||||
if (virtual_joystick) {
|
if (virtual_joystick && controller->joystick == virtual_joystick) {
|
||||||
VirtualGamepadMouseMotion(event.motion.x, event.motion.y);
|
VirtualGamepadMouseMotion(event.motion.x, event.motion.y);
|
||||||
}
|
}
|
||||||
SetGamepadButtonHighlight(copy_button, event.motion.state && GamepadButtonContains(copy_button, event.motion.x, event.motion.y));
|
UpdateButtonHighlights(event.motion.x, event.motion.y);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDL_EVENT_KEY_DOWN:
|
case SDL_EVENT_KEY_DOWN:
|
||||||
if (event.key.keysym.sym >= SDLK_0 && event.key.keysym.sym <= SDLK_9) {
|
if (display_mode == CONTROLLER_MODE_TESTING) {
|
||||||
if (controller && controller->gamepad) {
|
if (event.key.keysym.sym >= SDLK_0 && event.key.keysym.sym <= SDLK_9) {
|
||||||
int player_index = (event.key.keysym.sym - SDLK_0);
|
if (controller && controller->gamepad) {
|
||||||
|
int player_index = (event.key.keysym.sym - SDLK_0);
|
||||||
|
|
||||||
SDL_SetGamepadPlayerIndex(controller->gamepad, player_index);
|
SDL_SetGamepadPlayerIndex(controller->gamepad, player_index);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} else if (event.key.keysym.sym == SDLK_a) {
|
||||||
|
OpenVirtualGamepad();
|
||||||
|
} else if (event.key.keysym.sym == SDLK_d) {
|
||||||
|
CloseVirtualGamepad();
|
||||||
|
} else if (event.key.keysym.sym == SDLK_ESCAPE) {
|
||||||
|
done = SDL_TRUE;
|
||||||
|
}
|
||||||
|
} else if (display_mode == CONTROLLER_MODE_BINDING) {
|
||||||
|
if (event.key.keysym.sym == SDLK_c && (event.key.keysym.mod & SDL_KMOD_CTRL)) {
|
||||||
|
CopyMapping();
|
||||||
|
} else if (event.key.keysym.sym == SDLK_v && (event.key.keysym.mod & SDL_KMOD_CTRL)) {
|
||||||
|
PasteMapping();
|
||||||
|
} else if (event.key.keysym.sym == SDLK_x && (event.key.keysym.mod & SDL_KMOD_CTRL)) {
|
||||||
|
CopyMapping();
|
||||||
|
ClearMapping();
|
||||||
|
} else if (event.key.keysym.sym == SDLK_ESCAPE) {
|
||||||
|
CancelMapping();
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (event.key.keysym.sym == SDLK_a) {
|
|
||||||
OpenVirtualGamepad();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (event.key.keysym.sym == SDLK_d) {
|
|
||||||
CloseVirtualGamepad();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (event.key.keysym.sym == SDLK_ESCAPE) {
|
|
||||||
done = SDL_TRUE;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SDL_EVENT_QUIT:
|
case SDL_EVENT_QUIT:
|
||||||
@@ -780,62 +954,21 @@ static void loop(void *arg)
|
|||||||
RenderGamepadDisplay(gamepad_elements, controller->gamepad);
|
RenderGamepadDisplay(gamepad_elements, controller->gamepad);
|
||||||
RenderJoystickDisplay(joystick_elements, controller->joystick);
|
RenderJoystickDisplay(joystick_elements, controller->joystick);
|
||||||
|
|
||||||
if (controller->gamepad) {
|
if (display_mode == CONTROLLER_MODE_TESTING) {
|
||||||
RenderGamepadButton(copy_button);
|
RenderGamepadButton(setup_mapping_button);
|
||||||
|
} else if (display_mode == CONTROLLER_MODE_BINDING) {
|
||||||
|
RenderGamepadButton(test_mapping_button);
|
||||||
|
RenderGamepadButton(cancel_button);
|
||||||
|
RenderGamepadButton(clear_button);
|
||||||
|
if (controller->gamepad) {
|
||||||
|
RenderGamepadButton(copy_button);
|
||||||
|
}
|
||||||
|
RenderGamepadButton(paste_button);
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawGamepadInfo(screen);
|
DrawGamepadInfo(screen);
|
||||||
|
|
||||||
if (controller->gamepad) {
|
UpdateGamepadEffects();
|
||||||
/* Update LED based on left thumbstick position */
|
|
||||||
{
|
|
||||||
Sint16 x = SDL_GetGamepadAxis(controller->gamepad, SDL_GAMEPAD_AXIS_LEFTX);
|
|
||||||
Sint16 y = SDL_GetGamepadAxis(controller->gamepad, SDL_GAMEPAD_AXIS_LEFTY);
|
|
||||||
|
|
||||||
if (!set_LED) {
|
|
||||||
set_LED = (x < -8000 || x > 8000 || y > 8000);
|
|
||||||
}
|
|
||||||
if (set_LED) {
|
|
||||||
Uint8 r, g, b;
|
|
||||||
|
|
||||||
if (x < 0) {
|
|
||||||
r = (Uint8)(((~x) * 255) / 32767);
|
|
||||||
b = 0;
|
|
||||||
} else {
|
|
||||||
r = 0;
|
|
||||||
b = (Uint8)(((int)(x)*255) / 32767);
|
|
||||||
}
|
|
||||||
if (y > 0) {
|
|
||||||
g = (Uint8)(((int)(y)*255) / 32767);
|
|
||||||
} else {
|
|
||||||
g = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_SetGamepadLED(controller->gamepad, r, g, b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (controller->trigger_effect == 0) {
|
|
||||||
/* Update rumble based on trigger state */
|
|
||||||
{
|
|
||||||
Sint16 left = SDL_GetGamepadAxis(controller->gamepad, SDL_GAMEPAD_AXIS_LEFT_TRIGGER);
|
|
||||||
Sint16 right = SDL_GetGamepadAxis(controller->gamepad, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER);
|
|
||||||
Uint16 low_frequency_rumble = ConvertAxisToRumble(left);
|
|
||||||
Uint16 high_frequency_rumble = ConvertAxisToRumble(right);
|
|
||||||
SDL_RumbleGamepad(controller->gamepad, low_frequency_rumble, high_frequency_rumble, 250);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Update trigger rumble based on thumbstick state */
|
|
||||||
{
|
|
||||||
Sint16 left = SDL_GetGamepadAxis(controller->gamepad, SDL_GAMEPAD_AXIS_LEFTY);
|
|
||||||
Sint16 right = SDL_GetGamepadAxis(controller->gamepad, SDL_GAMEPAD_AXIS_RIGHTY);
|
|
||||||
Uint16 left_rumble = ConvertAxisToRumble(~left);
|
|
||||||
Uint16 right_rumble = ConvertAxisToRumble(~right);
|
|
||||||
|
|
||||||
SDL_RumbleGamepadTriggers(controller->gamepad, left_rumble, right_rumble, 250);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
DrawGamepadWaiting(screen);
|
DrawGamepadWaiting(screen);
|
||||||
}
|
}
|
||||||
@@ -854,7 +987,7 @@ int main(int argc, char *argv[])
|
|||||||
int i;
|
int i;
|
||||||
float content_scale;
|
float content_scale;
|
||||||
int screen_width, screen_height;
|
int screen_width, screen_height;
|
||||||
int button_width, button_height;
|
SDL_Rect area;
|
||||||
int gamepad_index = -1;
|
int gamepad_index = -1;
|
||||||
SDLTest_CommonState *state;
|
SDLTest_CommonState *state;
|
||||||
|
|
||||||
@@ -960,18 +1093,62 @@ int main(int argc, char *argv[])
|
|||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
SetGamepadImagePosition(image, PANEL_WIDTH + PANEL_SPACING, TITLE_HEIGHT);
|
SetGamepadImagePosition(image, PANEL_WIDTH + PANEL_SPACING, TITLE_HEIGHT);
|
||||||
SetGamepadImageShowingBattery(image, SDL_TRUE);
|
|
||||||
|
|
||||||
gamepad_elements = CreateGamepadDisplay(screen);
|
gamepad_elements = CreateGamepadDisplay(screen);
|
||||||
SetGamepadDisplayArea(gamepad_elements, 0, TITLE_HEIGHT, PANEL_WIDTH, GAMEPAD_HEIGHT);
|
area.x = 0;
|
||||||
|
area.y = TITLE_HEIGHT;
|
||||||
|
area.w = PANEL_WIDTH;
|
||||||
|
area.h = GAMEPAD_HEIGHT;
|
||||||
|
SetGamepadDisplayArea(gamepad_elements, &area);
|
||||||
|
|
||||||
joystick_elements = CreateJoystickDisplay(screen);
|
joystick_elements = CreateJoystickDisplay(screen);
|
||||||
SetJoystickDisplayArea(joystick_elements, PANEL_WIDTH + PANEL_SPACING + GAMEPAD_WIDTH + PANEL_SPACING, TITLE_HEIGHT, PANEL_WIDTH, GAMEPAD_HEIGHT);
|
area.x = PANEL_WIDTH + PANEL_SPACING + GAMEPAD_WIDTH + PANEL_SPACING;
|
||||||
|
area.y = TITLE_HEIGHT;
|
||||||
|
area.w = PANEL_WIDTH;
|
||||||
|
area.h = GAMEPAD_HEIGHT;
|
||||||
|
SetJoystickDisplayArea(joystick_elements, &area);
|
||||||
|
|
||||||
copy_button = CreateGamepadButton(screen, "Copy to Clipboard");
|
setup_mapping_button = CreateGamepadButton(screen, "Setup Mapping");
|
||||||
button_width = GetGamepadButtonLabelWidth(copy_button) + 2 * BUTTON_PADDING;
|
area.w = SDL_max(MINIMUM_BUTTON_WIDTH, GetGamepadButtonLabelWidth(setup_mapping_button) + 2 * BUTTON_PADDING);
|
||||||
button_height = GetGamepadButtonLabelHeight(copy_button) + 2 * BUTTON_PADDING;
|
area.h = GetGamepadButtonLabelHeight(setup_mapping_button) + 2 * BUTTON_PADDING;
|
||||||
SetGamepadButtonArea(copy_button, BUTTON_MARGIN, SCREEN_HEIGHT - BUTTON_MARGIN - button_height, button_width, button_height);
|
area.x = BUTTON_MARGIN;
|
||||||
|
area.y = SCREEN_HEIGHT - BUTTON_MARGIN - area.h;
|
||||||
|
SetGamepadButtonArea(setup_mapping_button, &area);
|
||||||
|
|
||||||
|
cancel_button = CreateGamepadButton(screen, "Cancel");
|
||||||
|
area.w = SDL_max(MINIMUM_BUTTON_WIDTH, GetGamepadButtonLabelWidth(cancel_button) + 2 * BUTTON_PADDING);
|
||||||
|
area.h = GetGamepadButtonLabelHeight(cancel_button) + 2 * BUTTON_PADDING;
|
||||||
|
area.x = BUTTON_MARGIN;
|
||||||
|
area.y = SCREEN_HEIGHT - BUTTON_MARGIN - area.h;
|
||||||
|
SetGamepadButtonArea(cancel_button, &area);
|
||||||
|
|
||||||
|
clear_button = CreateGamepadButton(screen, "Clear");
|
||||||
|
area.x += area.w + BUTTON_PADDING;
|
||||||
|
area.w = SDL_max(MINIMUM_BUTTON_WIDTH, GetGamepadButtonLabelWidth(clear_button) + 2 * BUTTON_PADDING);
|
||||||
|
area.h = GetGamepadButtonLabelHeight(clear_button) + 2 * BUTTON_PADDING;
|
||||||
|
area.y = SCREEN_HEIGHT - BUTTON_MARGIN - area.h;
|
||||||
|
SetGamepadButtonArea(clear_button, &area);
|
||||||
|
|
||||||
|
copy_button = CreateGamepadButton(screen, "Copy");
|
||||||
|
area.x += area.w + BUTTON_PADDING;
|
||||||
|
area.w = SDL_max(MINIMUM_BUTTON_WIDTH, GetGamepadButtonLabelWidth(copy_button) + 2 * BUTTON_PADDING);
|
||||||
|
area.h = GetGamepadButtonLabelHeight(copy_button) + 2 * BUTTON_PADDING;
|
||||||
|
area.y = SCREEN_HEIGHT - BUTTON_MARGIN - area.h;
|
||||||
|
SetGamepadButtonArea(copy_button, &area);
|
||||||
|
|
||||||
|
paste_button = CreateGamepadButton(screen, "Paste");
|
||||||
|
area.x += area.w + BUTTON_PADDING;
|
||||||
|
area.w = SDL_max(MINIMUM_BUTTON_WIDTH, GetGamepadButtonLabelWidth(paste_button) + 2 * BUTTON_PADDING);
|
||||||
|
area.h = GetGamepadButtonLabelHeight(paste_button) + 2 * BUTTON_PADDING;
|
||||||
|
area.y = SCREEN_HEIGHT - BUTTON_MARGIN - area.h;
|
||||||
|
SetGamepadButtonArea(paste_button, &area);
|
||||||
|
|
||||||
|
test_mapping_button = CreateGamepadButton(screen, "Done");
|
||||||
|
area.w = SDL_max(MINIMUM_BUTTON_WIDTH, GetGamepadButtonLabelWidth(test_mapping_button) + 2 * BUTTON_PADDING);
|
||||||
|
area.h = GetGamepadButtonLabelHeight(test_mapping_button) + 2 * BUTTON_PADDING;
|
||||||
|
area.x = SCREEN_WIDTH / 2 - area.w / 2;
|
||||||
|
area.y = SCREEN_HEIGHT - BUTTON_MARGIN - area.h;
|
||||||
|
SetGamepadButtonArea(test_mapping_button, &area);
|
||||||
|
|
||||||
/* Process the initial gamepad list */
|
/* Process the initial gamepad list */
|
||||||
loop(NULL);
|
loop(NULL);
|
||||||
|
Reference in New Issue
Block a user