From 325391b617a3f5a1f17e03598baa66d00715422d Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Wed, 13 Mar 2019 01:37:41 +0200 Subject: [PATCH] playable with a gamepad --- src/game.c | 15 ++++++------ src/game.h | 18 +++++++++++++- src/gameinp.c | 43 +++++++++++++++++++++++++++++++++ src/gameinp.h | 23 ++++++++++++++++++ src/gamescr.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 164 insertions(+), 9 deletions(-) create mode 100644 src/gameinp.c create mode 100644 src/gameinp.h diff --git a/src/game.c b/src/game.c index 05bdc95..68f6a23 100644 --- a/src/game.c +++ b/src/game.c @@ -15,6 +15,7 @@ static void print_framerate(void); static int should_swap; static unsigned long framerate; + int game_init(int argc, char **argv) { if(init_opengl() == -1) { @@ -58,14 +59,6 @@ void game_cleanup() static void update(float dt) { - int num_vr_sticks; - - if((num_vr_sticks = goatvr_num_sticks()) > 0) { - float p[2]; - goatvr_stick_pos(0, p); - /* TODO */ - } - screen->update(dt); } @@ -187,10 +180,16 @@ void game_mouse_wheel(int dir) void game_gamepad_axis(int axis, float val) { + joy_axis[axis] = val; } void game_gamepad_button(int bn, int pressed) { + if(pressed) { + joy_bnstate |= (1 << bn); + } else { + joy_bnstate &= ~(1 << bn); + } } static void calc_framerate(void) diff --git a/src/game.h b/src/game.h index 3ada420..2625f1a 100644 --- a/src/game.h +++ b/src/game.h @@ -7,6 +7,9 @@ int vp_width, vp_height; /* viewport size differs from win size during VR eye re float win_aspect; int fb_srgb; +float joy_axis[3]; +unsigned int joy_bnstate; + float view_matrix[16], proj_matrix[16]; enum { @@ -56,7 +59,17 @@ enum { GPAD_UP, GPAD_DOWN, GPAD_LEFT, - GPAD_RIGHT, + GPAD_RIGHT +}; + +/* XXX make sure these match with SDL_GameControllerAxis */ +enum { + GPAD_LSTICK_X, + GPAD_LSTICK_Y, + GPAD_RSTICK_X, + GPAD_RSTICK_Y, + GPAD_LTRIG, + GPAD_RTRIG }; int game_init(int argc, char **argv); @@ -83,4 +96,7 @@ void game_fullscreen(int fs); void game_toggle_fullscreen(void); int game_is_fullscreen(void); +int game_num_joy_axes(void); +int game_num_joy_buttons(void); + #endif // GAME_H_ diff --git a/src/gameinp.c b/src/gameinp.c new file mode 100644 index 0000000..2d0c52a --- /dev/null +++ b/src/gameinp.c @@ -0,0 +1,43 @@ +#include "gameinp.h" +#include "game.h" + +#define NUM_BN 6 + +static int rep_start, rep_rep; +static long first_press[16], last_press[16]; +static unsigned int repmask; + + +void ginp_repeat(int start, int rep, unsigned int mask) +{ + rep_start = start; + rep_rep = rep; + repmask = mask; +} + +void update_ginp(void) +{ + static unsigned int prevstate; + int i; + + ginp_bndelta = ginp_bnstate ^ prevstate; + prevstate = ginp_bnstate; + + for(i=0; i= rep_start && time_msec - last_press[i] >= rep_rep) { + ginp_bndelta |= bit; + last_press[i] = time_msec; + } + } + } + } +} diff --git a/src/gameinp.h b/src/gameinp.h new file mode 100644 index 0000000..ca8c63e --- /dev/null +++ b/src/gameinp.h @@ -0,0 +1,23 @@ +#ifndef GAMEINP_H_ +#define GAMEINP_H_ + +enum { + GINP_LEFT = 1, + GINP_RIGHT = 2, + GINP_UP = 4, + GINP_DOWN = 8, + GINP_ROTATE = 16, + GINP_PAUSE = 32 +}; + +#define GINP_PRESS(bn) ((ginp_bnstate & (bn)) && (ginp_bndelta & (bn))) +#define GINP_RELEASE(bn) ((ginp_bnstate & (bn)) == 0 && (ginp_bndelta & (bn))) + +unsigned int ginp_bnstate, ginp_bndelta; + +void ginp_repeat(int start, int rep, unsigned int mask); + +void update_ginp(void); + + +#endif /* GAMEINP_H_ */ diff --git a/src/gamescr.c b/src/gamescr.c index 66aa1fe..d2e0219 100644 --- a/src/gamescr.c +++ b/src/gamescr.c @@ -2,12 +2,14 @@ #include #include #include +#include #include "opengl.h" #include "game.h" #include "screen.h" #include "cmesh.h" #include "blocks.h" #include "logger.h" +#include "gameinp.h" int init_starfield(void); void draw_starfield(void); @@ -144,17 +146,89 @@ static void start(void) next_block = rand() % NUM_BLOCKS; memset(pfield, 0, PF_COLS * PF_ROWS * sizeof *pfield); + + ginp_repeat(500, 75, GINP_LEFT | GINP_RIGHT | GINP_DOWN); } static void stop(void) { } +#define JTHRES 0.6 + +#define CHECK_BUTTON(idx, gbn) \ + if(joy_bnstate & (1 << idx)) { \ + ginp_bnstate |= gbn; \ + } + +static void update_input(float dtsec) +{ + int num_vr_sticks; + + if((num_vr_sticks = goatvr_num_sticks()) > 0) { + float p[2]; + + goatvr_stick_pos(0, p); + + if(fabs(p[0]) > fabs(joy_axis[GPAD_LSTICK_X])) { + joy_axis[GPAD_LSTICK_X] = p[0]; + } + if(fabs(p[1]) > fabs(joy_axis[GPAD_LSTICK_Y])) { + joy_axis[GPAD_LSTICK_Y] = p[1]; + } + } + + ginp_bnstate = 0; + + /* joystick axis */ + if(joy_axis[GPAD_LSTICK_X] >= JTHRES) { + ginp_bnstate |= GINP_RIGHT; + } else if(joy_axis[GPAD_LSTICK_X] <= -JTHRES) { + ginp_bnstate |= GINP_LEFT; + } + + if(joy_axis[GPAD_LSTICK_Y] >= JTHRES) { + ginp_bnstate |= GINP_DOWN; + } else if(joy_axis[GPAD_LSTICK_Y] <= -JTHRES) { + ginp_bnstate |= GINP_UP; + } + + CHECK_BUTTON(GPAD_LEFT, GINP_LEFT); + CHECK_BUTTON(GPAD_RIGHT, GINP_RIGHT); + CHECK_BUTTON(GPAD_UP, GINP_UP); + CHECK_BUTTON(GPAD_DOWN, GINP_DOWN); + CHECK_BUTTON(GPAD_A, GINP_ROTATE); + CHECK_BUTTON(GPAD_START, GINP_PAUSE); + + update_ginp(); + + if(GINP_PRESS(GINP_LEFT)) { + game_keyboard('a', 1); + } + if(GINP_PRESS(GINP_RIGHT)) { + game_keyboard('d', 1); + } + if(GINP_PRESS(GINP_DOWN)) { + game_keyboard('s', 1); + } + if(GINP_PRESS(GINP_UP)) { + game_keyboard('\t', 1); + } + if(GINP_PRESS(GINP_ROTATE)) { + game_keyboard('w', 1); + } + if(GINP_PRESS(GINP_PAUSE)) { + game_keyboard('p', 1); + } +} + static void update(float dtsec) { static long prev_tick; long dt; + update_input(dtsec); + if(pause) { prev_tick = time_msec; return; -- 1.7.10.4