Add support for SDL_GameControllerDB

This adds support for importing and applying mappings from the
SDL_GameControllerDB database.

Related to #900.
This commit is contained in:
Camilla Löwy
2017-06-18 15:13:25 +02:00
parent 07bf2b166b
commit 953106e74d
19 changed files with 1186 additions and 80 deletions
+91 -47
View File
@@ -92,6 +92,55 @@ static const char* joystick_label(int jid)
return label;
}
static void hat_widget(struct nk_context* nk, unsigned char state)
{
float radius;
struct nk_rect area;
struct nk_vec2 center;
if (nk_widget(&area, nk) != NK_WIDGET_VALID)
return;
center = nk_vec2(area.x + area.w / 2.f, area.y + area.h / 2.f);
radius = NK_MIN(area.w, area.h) / 2.f;
nk_stroke_circle(nk_window_get_canvas(nk),
nk_rect(center.x - radius,
center.y - radius,
radius * 2.f,
radius * 2.f),
1.f,
nk_rgb(175, 175, 175));
if (state)
{
const float angles[] =
{
0.f, 0.f,
NK_PI * 1.5f, NK_PI * 1.75f,
NK_PI, 0.f,
NK_PI * 1.25f, 0.f,
NK_PI * 0.5f, NK_PI * 0.25f,
0.f, 0.f,
NK_PI * 0.75f, 0.f,
};
const float cosa = nk_cos(angles[state]);
const float sina = nk_sin(angles[state]);
const struct nk_vec2 p0 = nk_vec2(0.f, -radius);
const struct nk_vec2 p1 = nk_vec2( radius / 2.f, -radius / 3.f);
const struct nk_vec2 p2 = nk_vec2(-radius / 2.f, -radius / 3.f);
nk_fill_triangle(nk_window_get_canvas(nk),
center.x + cosa * p0.x + sina * p0.y,
center.y + cosa * p0.y - sina * p0.x,
center.x + cosa * p1.x + sina * p1.y,
center.y + cosa * p1.y - sina * p1.x,
center.x + cosa * p2.x + sina * p2.y,
center.y + cosa * p2.y - sina * p2.x,
nk_rgb(175, 175, 175));
}
}
int main(void)
{
int jid, hat_buttons = GLFW_FALSE;
@@ -105,7 +154,7 @@ int main(void)
if (!glfwInit())
exit(EXIT_FAILURE);
window = glfwCreateWindow(640, 480, "Joystick Test", NULL, NULL);
window = glfwCreateWindow(800, 600, "Joystick Test", NULL, NULL);
if (!window)
{
glfwTerminate();
@@ -165,7 +214,7 @@ int main(void)
{
if (nk_begin(nk,
joystick_label(joysticks[i]),
nk_rect(i * 20.f, i * 20.f, 400.f, 400.f),
nk_rect(i * 20.f, i * 20.f, 550.f, 570.f),
NK_WINDOW_BORDER |
NK_WINDOW_MOVABLE |
NK_WINDOW_SCALABLE |
@@ -176,8 +225,10 @@ int main(void)
const float* axes;
const unsigned char* buttons;
const unsigned char* hats;
GLFWgamepadstate state;
nk_layout_row_dynamic(nk, 30, 1);
nk_label(nk, "Joystick state", NK_TEXT_LEFT);
axes = glfwGetJoystickAxes(joysticks[i], &axis_count);
buttons = glfwGetJoystickButtons(joysticks[i], &button_count);
@@ -189,7 +240,7 @@ int main(void)
for (j = 0; j < axis_count; j++)
nk_slide_float(nk, -1.f, axes[j], 1.f, 0.1f);
nk_layout_row_dynamic(nk, 30, 8);
nk_layout_row_dynamic(nk, 30, 12);
for (j = 0; j < button_count; j++)
{
@@ -201,54 +252,47 @@ int main(void)
nk_layout_row_dynamic(nk, 30, 8);
for (j = 0; j < hat_count; j++)
hat_widget(nk, hats[j]);
nk_layout_row_dynamic(nk, 30, 1);
if (glfwGetGamepadState(joysticks[i], &state))
{
float radius;
struct nk_rect area;
struct nk_vec2 center;
if (nk_widget(&area, nk) != NK_WIDGET_VALID)
continue;
center = nk_vec2(area.x + area.w / 2.f,
area.y + area.h / 2.f);
radius = NK_MIN(area.w, area.h) / 2.f;
nk_stroke_circle(nk_window_get_canvas(nk),
nk_rect(center.x - radius,
center.y - radius,
radius * 2.f,
radius * 2.f),
1.f,
nk_rgb(175, 175, 175));
if (hats[j])
int hat = 0;
const char* names[GLFW_GAMEPAD_BUTTON_LAST + 1 - 4] =
{
const float angles[] =
{
0.f, 0.f,
NK_PI * 1.5f, NK_PI * 1.75f,
NK_PI, 0.f,
NK_PI * 1.25f, 0.f,
NK_PI * 0.5f, NK_PI * 0.25f,
0.f, 0.f,
NK_PI * 0.75f, 0.f,
};
const float cosa = nk_cos(angles[hats[j]]);
const float sina = nk_sin(angles[hats[j]]);
const struct nk_vec2 p0 = nk_vec2(0.f, -radius);
const struct nk_vec2 p1 = nk_vec2( radius / 2.f, -radius / 3.f);
const struct nk_vec2 p2 = nk_vec2(-radius / 2.f, -radius / 3.f);
"A", "B", "X", "Y",
"LB", "RB",
"Back", "Start", "Guide",
"LT", "RT",
};
nk_fill_triangle(nk_window_get_canvas(nk),
center.x + cosa * p0.x + sina * p0.y,
center.y + cosa * p0.y - sina * p0.x,
center.x + cosa * p1.x + sina * p1.y,
center.y + cosa * p1.y - sina * p1.x,
center.x + cosa * p2.x + sina * p2.y,
center.y + cosa * p2.y - sina * p2.x,
nk_rgb(175, 175, 175));
}
nk_label(nk, "Gamepad state", NK_TEXT_LEFT);
nk_layout_row_dynamic(nk, 30, 2);
for (j = 0; j <= GLFW_GAMEPAD_AXIS_LAST; j++)
nk_slide_float(nk, -1.f, state.axes[j], 1.f, 0.1f);
nk_layout_row_dynamic(nk, 30, GLFW_GAMEPAD_BUTTON_LAST + 1 - 4);
for (j = 0; j <= GLFW_GAMEPAD_BUTTON_LAST - 4; j++)
nk_select_label(nk, names[j], NK_TEXT_CENTERED, state.buttons[j]);
if (state.buttons[GLFW_GAMEPAD_BUTTON_DPAD_UP])
hat |= GLFW_HAT_UP;
if (state.buttons[GLFW_GAMEPAD_BUTTON_DPAD_RIGHT])
hat |= GLFW_HAT_RIGHT;
if (state.buttons[GLFW_GAMEPAD_BUTTON_DPAD_DOWN])
hat |= GLFW_HAT_DOWN;
if (state.buttons[GLFW_GAMEPAD_BUTTON_DPAD_LEFT])
hat |= GLFW_HAT_LEFT;
nk_layout_row_dynamic(nk, 30, 8);
hat_widget(nk, hat);
}
else
nk_label(nk, "Joystick has no gamepad mapping", NK_TEXT_LEFT);
}
nk_end(nk);