From 49fdb2457dbb7705501264d519e840dd3ca60919 Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Sat, 23 Feb 2019 07:31:23 +0200 Subject: [PATCH] moving along --- Makefile | 3 +- src/game.c | 152 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--- src/game.h | 15 +++--- src/osd.c | 4 +- src/osd.h | 2 +- src/screen.c | 54 +++++++++++++++++++++ src/screen.h | 39 +++++++++++++++ 7 files changed, 250 insertions(+), 19 deletions(-) create mode 100644 src/screen.c create mode 100644 src/screen.h diff --git a/Makefile b/Makefile index a773a6e..3b1335d 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,8 @@ bin = vrtris CFLAGS = -pedantic -Wall -g `pkg-config --cflags sdl2` -LDFLAGS = $(libsys) $(libgl) `pkg-config --libs sdl2` -ldrawtext +LDFLAGS = $(libsys) $(libgl) `pkg-config --libs sdl2` -ldrawtext -lgoatvr \ + -limago -lm sys ?= $(shell uname -s | sed 's/MINGW.*/mingw/') diff --git a/src/game.c b/src/game.c index 399a5ea..00f81cc 100644 --- a/src/game.c +++ b/src/game.c @@ -1,8 +1,19 @@ #include +#include +#include #include "opengl.h" #include "game.h" +#include "screen.h" +#include "osd.h" #include "opt.h" +static void calc_framerate(void); +static void print_framerate(void); + +static float view_matrix[16], proj_matrix[16]; +static int should_swap; +static unsigned long framerate; + int game_init(int argc, char **argv) { if(init_opengl() == -1) { @@ -13,43 +24,150 @@ int game_init(int argc, char **argv) return -1; } + if(init_screens() == -1) { + return -1; + } + + if(opt.flags & OPT_VR) { + if(goatvr_init() == -1) { + return -1; + } + goatvr_set_origin_mode(GOATVR_HEAD); + + goatvr_startvr(); + should_swap = goatvr_should_swap(); + } return 0; } void game_cleanup() { + if(opt.flags & OPT_VR) { + goatvr_shutdown(); + } + cleanup_screens(); } -void game_display() +static void update(float dt) { - glClear(GL_COLOR_BUFFER_BIT); + 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_display(void) +{ + static long prev_msec; + int i; + float dt = (float)(time_msec - prev_msec) / 1000.0f; + prev_msec = time_msec; + + update(dt); + + if(opt.flags & OPT_VR) { + goatvr_draw_start(); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + for(i=0; i<2; i++) { + /* for each eye */ + goatvr_draw_eye(i); + + cgm_mcopy(proj_matrix, goatvr_projection_matrix(i, 0.5, 500.0)); + glMatrixMode(GL_PROJECTION); + glLoadMatrixf(proj_matrix); + + cgm_mcopy(view_matrix, goatvr_view_matrix(i)); + glMatrixMode(GL_MODELVIEW); + glLoadMatrixf(view_matrix); + + screen->draw(); + print_framerate(); + draw_osd(); + } + + goatvr_draw_done(); + + if(should_swap) { + game_swap_buffers(); + } + + } else { + /* non-VR mode */ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + cgm_mperspective(proj_matrix, cgm_deg_to_rad(50.0), win_aspect, 0.5, 500.0); + glMatrixMode(GL_PROJECTION); + glLoadMatrixf(proj_matrix); + + cgm_midentity(view_matrix); + glMatrixMode(GL_MODELVIEW); + glLoadMatrixf(view_matrix); + + screen->draw(); + print_framerate(); + draw_osd(); + + game_swap_buffers(); + } - game_swap_buffers(); assert(glGetError() == GL_NO_ERROR); + + calc_framerate(); } void game_reshape(int x, int y) { + glViewport(0, 0, x, y); + goatvr_set_fb_size(x, y, 1.0f); + + reshape_screens(x, y); } void game_keyboard(int key, int pressed) { + unsigned int mod = game_get_modifiers(); + + if(pressed) { + switch(key) { + case 27: + game_quit(); + return; + + case '\n': + case '\r': + if(mod & MOD_ALT) { + game_toggle_fullscreen(); + return; + } + break; + + default: + break; + } + } + + screen->keyboard(key, pressed); } void game_mouse_button(int bn, int pressed, int x, int y) { + screen->mouse(bn, pressed, x, y); } void game_mouse_motion(int x, int y) { -} - -void game_mouse_delta(int dx, int dy) -{ + screen->motion(x, y); } void game_mouse_wheel(int dir) { + screen->wheel(dir); } @@ -60,3 +178,23 @@ void game_gamepad_axis(int axis, float val) void game_gamepad_button(int bn, int pressed) { } + +static void calc_framerate(void) +{ + static unsigned long nframes; + static long prev_upd; + + long elapsed = time_msec - prev_upd; + if(elapsed >= 1000) { + framerate = nframes * 10000 / elapsed; + nframes = 1; + prev_upd = time_msec; + } else { + ++nframes; + } +} + +static void print_framerate(void) +{ + print_text(9 * win_width / 10, 20, 1, 1, 0, "fps: %d.%d", framerate / 10, framerate % 10); +} diff --git a/src/game.h b/src/game.h index a3455f0..0bcd229 100644 --- a/src/game.h +++ b/src/game.h @@ -58,28 +58,27 @@ enum { }; int game_init(int argc, char **argv); -void game_cleanup(); +void game_cleanup(void); -void game_display(); +void game_display(void); void game_reshape(int x, int y); void game_keyboard(int key, int pressed); void game_mouse_button(int bn, int pressed, int x, int y); void game_mouse_motion(int x, int y); -void game_mouse_delta(int dx, int dy); void game_mouse_wheel(int dir); void game_gamepad_axis(int axis, float val); void game_gamepad_button(int bn, int pressed); /* the following functions are implemented by the backend (main.c) */ -void game_quit(); -void game_swap_buffers(); -unsigned int game_get_modifiers(); +void game_quit(void); +void game_swap_buffers(void); +unsigned int game_get_modifiers(void); void game_resize(int x, int y); void game_fullscreen(int fs); -void game_toggle_fullscreen(); -int game_is_fullscreen(); +void game_toggle_fullscreen(void); +int game_is_fullscreen(void); #endif // GAME_H_ diff --git a/src/osd.c b/src/osd.c index b40424f..8b139bd 100644 --- a/src/osd.c +++ b/src/osd.c @@ -128,7 +128,7 @@ void print_textv(float x, float y, float r, float g, float b, const char *fmt, v txlist = tx; } -void draw_ui() +void draw_osd(void) { if(!ui_font) return; @@ -191,7 +191,7 @@ void draw_ui() glPopMatrix(); } -static int init() +static int init(void) { static int done_init; if(done_init) return 0; diff --git a/src/osd.h b/src/osd.h index dc0028b..c475150 100644 --- a/src/osd.h +++ b/src/osd.h @@ -16,6 +16,6 @@ void show_messagev(long timeout, float r, float g, float b, const char *fmt, va_ void print_text(float x, float y, float r, float g, float b, const char *fmt, ...); void print_textv(float x, float y, float r, float g, float b, const char *fmt, va_list ap); -void draw_ui(void); +void draw_osd(void); #endif /* OSD_H_ */ diff --git a/src/screen.c b/src/screen.c new file mode 100644 index 0000000..6638b4e --- /dev/null +++ b/src/screen.c @@ -0,0 +1,54 @@ +#include "screen.h" + +static struct game_screen *screens[16]; +static int num_screens; + +static struct game_screen *stack; + +int init_screens(void) +{ + int i; + + for(i=0; iinit() == -1) { + return -1; + } + } + return 0; +} + +void cleanup_screens(void) +{ + int i; + + for(i=0; icleanup(); + } +} + +void reshape_screens(int x, int y) +{ + struct game_screen *s = stack; + while(s) { + s->reshape(x, y); + s = s->next; + } +} + +void push_screen(struct game_screen *s) +{ + s->next = stack; + stack = s; + s->start(); +} + +int pop_screen(void) +{ + struct game_screen *s; + + if(!stack->next) return -1; + s = stack; + stack = stack->next; + s->stop(); + return 0; +} diff --git a/src/screen.h b/src/screen.h new file mode 100644 index 0000000..33897dc --- /dev/null +++ b/src/screen.h @@ -0,0 +1,39 @@ +#ifndef SCREEN_H_ +#define SCREEN_H_ + +struct game_screen { + const char *name; + int opaque; /* if 0, the next screen is visible, so keep update/drawing it */ + + struct game_screen *next; + + int (*init)(void); + void (*cleanup)(void); + + void (*start)(void); + void (*stop)(void); + + void (*update)(float dt); + void (*draw)(void); + void (*reshape)(int, int); + /* these functions return 1 if they handled the event, or 0 + * if it should propagate to the next screen in the stack */ + int (*keyboard)(int, int); + int (*mouse)(int, int, int, int); + int (*motion)(int, int); + int (*wheel)(int dir); +}; + +/* this always points to the top screen on the stack + * there's always at least one screen, this will never be null + */ +struct game_screen *screen; + +int init_screens(void); +void cleanup_screens(void); +void reshape_screens(int x, int y); + +void push_screen(struct game_screen *s); +int pop_screen(void); + +#endif /* SCREEN_H_ */ -- 1.7.10.4