commit d412dad2a013993ae5a714107c4db327ec79d27c
parent 3fed33a8a0f682c28fcba1c3788c03aefed6b933
Author: amin <dev@aminmesbah.com>
Date: Wed, 25 Oct 2017 03:26:50 +0000
Get controller input through SDL event API
FossilOrigin-Name: 35e4ec6f7e7d86754023244baeb87b4b4516a6259f6a4d7d20c4250285314b56
Diffstat:
5 files changed, 117 insertions(+), 64 deletions(-)
diff --git a/Makefile b/Makefile
@@ -7,7 +7,7 @@ SDL_LDFLAGS := $(shell sdl2-config --libs)
override CFLAGS += $(SDL_CFLAGS)
-SRC_FILES = platform_sdl.c game.c
+SRC_FILES = platform_sdl.c game.c entity.c
SRC = $(addprefix src/, $(SRC_FILES))
EXE = ohsp
diff --git a/src/game.c b/src/game.c
@@ -1,6 +1,7 @@
#include "game.h"
#include <stdbool.h>
+#include <stdio.h>
bool PAUSED = false;
@@ -22,11 +23,11 @@ void game_init(struct GameState *game_state, int field_width, int field_height)
game_state->player.size = 100;
game_state->player.x = field_width / 2;
game_state->player.y = field_height / 2;
- game_state->player.color = 0xFFFFFF;
+ game_state->player.color = 0x888888;
}
-void game_update(struct GameState *game_state, int field_width, int field_height)
+void game_update(struct GameState *game_state, struct GameControllerInput game_input, int field_width, int field_height)
{
if (!game_state)
{
diff --git a/src/game.h b/src/game.h
@@ -29,6 +29,15 @@ struct GameBounds
float side_length_y;
};
+struct GameControllerInput
+{
+ uint8_t controller_index;
+ float left_stick_x;
+ float left_stick_y;
+ float right_stick_x;
+ float right_stick_y;
+};
+
struct GameView
{
float dx;
@@ -52,7 +61,7 @@ struct OffscreenBuffer
};
void game_init(struct GameState *game_state, int field_width, int field_height);
-void game_update(struct GameState *game_state, int field_width, int field_height);
+void game_update(struct GameState *game_state, struct GameControllerInput game_input, int field_width, int field_height);
void game_render(struct OffscreenBuffer *buffer, float dt, struct GameState *game_state);
void game_render_circle(struct OffscreenBuffer *buffer, float x, float y, float radius, uint32_t color);
float game_calc_render_offset(float zoom, float delta, float pos, float center);
diff --git a/src/platform_sdl.c b/src/platform_sdl.c
@@ -69,8 +69,28 @@ void clear_screen(struct SDLOffscreenBuffer *buffer, uint32_t pixel_value)
}
-bool handle_event(SDL_Event *event)
+float sdl_process_controller_axis_value(int16_t value, int16_t deadzone_threshold)
{
+ float result = 0.0;
+ if (value < -deadzone_threshold)
+ {
+ result = (float)(value + deadzone_threshold) / (32768.0f - deadzone_threshold);
+ }
+ else if (value > deadzone_threshold)
+ {
+ result = (float)(value - deadzone_threshold) / (32767.0f - deadzone_threshold);
+ }
+ return result;
+}
+
+
+bool sdl_handle_event(SDL_Event *event, struct GameControllerInput *controller_input)
+{
+ if (!event || !controller_input)
+ {
+ return true;
+ }
+
bool should_quit = false;
switch(event->type)
@@ -94,6 +114,43 @@ bool handle_event(SDL_Event *event)
}
}
} break;
+
+ case SDL_CONTROLLERAXISMOTION:
+ {
+ // down and right are positive
+ float normalized_axis_value = sdl_process_controller_axis_value(event->caxis.value, DEADZONE_THRESHOLD);
+
+ printf("SDL_CONTROLLERAXISMOTION (%d, %s, %d, %f)\n",
+ event->caxis.which,
+ SDL_GameControllerGetStringForAxis(event->caxis.axis),
+ event->caxis.value,
+ normalized_axis_value);
+
+ switch(event->caxis.axis)
+ {
+ case SDL_CONTROLLER_AXIS_LEFTX:
+ {
+ controller_input->left_stick_x = normalized_axis_value;
+ } break;
+ case SDL_CONTROLLER_AXIS_LEFTY:
+ {
+ controller_input->left_stick_y = normalized_axis_value;
+ } break;
+ case SDL_CONTROLLER_AXIS_RIGHTX:
+ {
+ controller_input->right_stick_x = normalized_axis_value;
+ } break;
+ case SDL_CONTROLLER_AXIS_RIGHTY:
+ {
+ controller_input->right_stick_y = normalized_axis_value;
+ } break;
+ default:
+ {
+ printf("Unhandled axis input\n");
+ }
+ }
+ } break;
+
case SDL_WINDOWEVENT:
{
switch(event->window.event)
@@ -126,7 +183,7 @@ bool handle_event(SDL_Event *event)
int main(int argc, char *argv[])
{
- if (SDL_Init(SDL_INIT_VIDEO))
+ if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER))
{
// TODO(amin): log SDL_Init error
}
@@ -160,12 +217,36 @@ int main(int argc, char *argv[])
srand((uint32_t)time(NULL));
#endif
+ int num_joysticks = SDL_NumJoysticks();
+ SDL_GameController *controller_handles[MAX_CONTROLLERS];
+ for (int controller_index = 0; controller_index < num_joysticks; ++controller_index)
+ {
+ if (!SDL_IsGameController(controller_index))
+ {
+ continue;
+ }
+
+ if (controller_index >= MAX_CONTROLLERS)
+ {
+ break;
+ }
+
+ controller_handles[controller_index] = SDL_GameControllerOpen(controller_index);
+ }
+
uint64_t lag = 0;
uint64_t previous_ms = (SDL_GetPerformanceCounter() * SECOND) / SDL_GetPerformanceFrequency();
struct GameState game_state;
game_init(&game_state, dimension.width, dimension.height);
+ struct GameControllerInput controller_input;
+ controller_input.controller_index = 0;
+ controller_input.left_stick_x = 0;
+ controller_input.right_stick_y = 0;
+ controller_input.left_stick_x = 0;
+ controller_input.right_stick_y = 0;
+
while (running)
{
uint64_t current_ms = (SDL_GetPerformanceCounter() * SECOND) / SDL_GetPerformanceFrequency();
@@ -175,70 +256,14 @@ int main(int argc, char *argv[])
//printf("%" PRIu64 ", %" PRIu64 ", %f\n", elapsed_ms, lag, MS_PER_UPDATE);
SDL_Event event;
-
while (SDL_PollEvent(&event))
{
- running = !handle_event(&event);
+ running = !sdl_handle_event(&event, &controller_input);
}
-
SDL_PumpEvents();
dimension = sdl_get_window_dimension(window);
- const uint8_t *keystate = SDL_GetKeyboardState(0);
-
- // TODO: move this to a function
- if (keystate[SDL_SCANCODE_A] || keystate[SDL_SCANCODE_H])
- {
- game_state.player.x -= 5 / game_state.view.zoom;
- }
- if (keystate[SDL_SCANCODE_D] || keystate[SDL_SCANCODE_L])
- {
- game_state.player.x += 5 / game_state.view.zoom;
- }
- if (keystate[SDL_SCANCODE_W] || keystate[SDL_SCANCODE_K])
- {
- game_state.player.y -= 5 / game_state.view.zoom;
- }
- if (keystate[SDL_SCANCODE_S] || keystate[SDL_SCANCODE_J])
- {
- game_state.player.y += 5 / game_state.view.zoom;
- }
- if (keystate[SDL_SCANCODE_LEFT])
- {
- game_state.player.x -= 1 / game_state.view.zoom;
- }
- if (keystate[SDL_SCANCODE_RIGHT])
- {
- game_state.player.x += 1 / game_state.view.zoom;
- }
- if (keystate[SDL_SCANCODE_UP])
- {
- game_state.player.y -= 1 / game_state.view.zoom;
- }
- if (keystate[SDL_SCANCODE_DOWN])
- {
- game_state.player.y += 1 / game_state.view.zoom;
- }
- if (keystate[SDL_SCANCODE_EQUALS])
- {
- game_state.view.zoom *= 1.01;
- }
- if (keystate[SDL_SCANCODE_MINUS])
- {
- game_state.view.zoom *= 0.99;
- }
- if (keystate[SDL_SCANCODE_0])
- {
- game_state.view.zoom = 1;
- }
- if (keystate[SDL_SCANCODE_HOME])
- {
- game_state.player.x = 0;
- game_state.player.y = 0;
- game_state.view.zoom = 1;
- }
-
struct OffscreenBuffer buffer;
// WARNING: these pointers are aliased until the end of the
// loop
@@ -255,7 +280,7 @@ int main(int argc, char *argv[])
{
while (lag >= MS_PER_UPDATE)
{
- game_update(&game_state, buffer.width, buffer.height);
+ game_update(&game_state, controller_input, buffer.width, buffer.height);
//printf("\t%" PRIu64 ", %f\n", lag, MS_PER_UPDATE);
lag -= MS_PER_UPDATE;
}
@@ -271,6 +296,21 @@ int main(int argc, char *argv[])
}
game_cleanup(&game_state);
+
+ for (int controller_index = 0; controller_index < num_joysticks; ++controller_index)
+ {
+ if (!SDL_IsGameController(controller_index))
+ {
+ continue;
+ }
+
+ if (controller_index >= MAX_CONTROLLERS)
+ {
+ break;
+ }
+
+ SDL_GameControllerClose(controller_handles[controller_index]);
+ }
}
else
{
diff --git a/src/platform_sdl.h b/src/platform_sdl.h
@@ -2,6 +2,9 @@
#include "SDL.h"
+#define MAX_CONTROLLERS 4
+#define DEADZONE_THRESHOLD 1000
+
struct SDLOffscreenBuffer
{
// NOTE(amin): pixels are always 32-bits wide. Memory order: BB GG RR XX.