static int should_swap;
static unsigned long framerate;
+
int game_init(int argc, char **argv)
{
if(init_opengl() == -1) {
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);
}
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)
float win_aspect;
int fb_srgb;
+float joy_axis[3];
+unsigned int joy_bnstate;
+
float view_matrix[16], proj_matrix[16];
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);
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_
--- /dev/null
+#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<NUM_BN; i++) {
+ unsigned int bit = 1 << i;
+ if(!(bit & repmask)) {
+ continue;
+ }
+
+ if(ginp_bnstate & bit) {
+ if(ginp_bndelta & bit) {
+ first_press[i] = time_msec;
+ } else {
+ if(time_msec - first_press[i] >= rep_start && time_msec - last_press[i] >= rep_rep) {
+ ginp_bndelta |= bit;
+ last_press[i] = time_msec;
+ }
+ }
+ }
+ }
+}
--- /dev/null
+#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_ */
#include <time.h>
#include <assert.h>
#include <imago2.h>
+#include <goatvr.h>
#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);
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;