# HG changeset patch # User John Tsiombikas # Date 1412114815 -10800 # Node ID 0eca023ed9095f8d0728db919eb53a15fc0a81e7 # Parent 608e03b688f88dfbb4eafbf1bfdebae4cd9b49b3 - fixed the hmd-tracking / mouselook interaction - added game variable system diff -r 608e03b688f8 -r 0eca023ed909 src/game.cc --- a/src/game.cc Tue Sep 30 18:57:20 2014 +0300 +++ b/src/game.cc Wed Oct 01 01:06:55 2014 +0300 @@ -9,6 +9,7 @@ #include "teapot.h" #include "console.h" #include "drawtext.h" +#include "game_var.h" static void draw_scene(); static void material(float r, float g, float b, float roughness); @@ -17,8 +18,6 @@ static int next_pow2(int x); static void con_handle(const char *cmd); -bool opt_separate_walk_look; - static int win_width, win_height; static unsigned int fb_tex; static unsigned int fbo, fb_depth; @@ -34,6 +33,8 @@ static Console con; static dtx_font *con_font; +#define OPT_LOOK_WALK "look-walk" + bool game_init() { init_opengl(); @@ -61,9 +62,13 @@ return false; } con.set_font(con_font, 14); - con.set_size(7, 40); + con.set_size(7, 52); con.set_position(0, 0, Console::CENTER); con.set_command_func(con_handle); + con.set_echo(false); + + /* initialize all option variables */ + set_gvar_bool(OPT_LOOK_WALK, true); return true; } @@ -100,18 +105,19 @@ dir += Vector3(0, 0, offs); } + if(get_gvar_bool(OPT_LOOK_WALK)) { + float rot[4]; + vr_view_rotation(0, rot); + Quaternion q(rot[3], rot[0], rot[1], rot[2]); + + dir.transform(q); + } + float cos_theta = cos(DEG_TO_RAD(cam_theta)); float sin_theta = sin(DEG_TO_RAD(cam_theta)); cam_pos.x += dir.x * cos_theta - dir.z * sin_theta; cam_pos.z += dir.x * sin_theta + dir.z * cos_theta; - if(!opt_separate_walk_look) { - float rot[4]; - vr_view_rotation(0, rot); - Quaternion q(rot[3], rot[0], rot[1], rot[2]); - - cam_pos.transform(q); - } } void game_display() @@ -377,6 +383,13 @@ return str; } +struct Variable { + const char *var; + enum { BOOL, NUM } type; + bool bool_val; + float num_val; +}; + static void con_handle(const char *cmd) { std::vector argv; @@ -396,20 +409,45 @@ if(strcmp(argv[0], "set") == 0) { if(argv.size() < 3) { - fprintf(stderr, "set must be followed by 2 arguments\n"); + con.printf("set must be followed by 2 arguments\n"); return; } - if(strcmp(argv[1], "separate-walk") == 0) { - if(strcmp(argv[2], "true") == 0) { - opt_separate_walk_look = true; - } else if(strcmp(argv[2], "false") == 0) { - opt_separate_walk_look = false; - } + if(have_gvar(argv[1])) { + GameVariable &gv = get_gvar(argv[1]); + con.printf("%s->%s (prev: %s)\n", argv[1], argv[2], gv.to_str().c_str()); } else { - con.printf("unknown option: %s\n", argv[1]); + con.printf("%s->%s\n", argv[1], argv[2]); } + set_gvar_parse(argv[1], argv[2]); + + } else if(strcmp(argv[0], "get") == 0) { + if(argv.size() < 2) { + con.printf("get must be followed by the variable name\n"); + return; + } + if(have_gvar(argv[1])) { + GameVariable &gv = get_gvar(argv[1]); + con.printf("%s: %s\n", argv[1], gv.to_str().c_str()); + } + + } else if(strcmp(argv[0], "vars") == 0) { + std::list vars = get_gvar_list(); + std::list::const_iterator it = vars.begin(); + while(it != vars.end()) { + con.printf(" %s\n", it++->c_str()); + } + } else if(strcmp(argv[0], "exit") == 0 || strcmp(argv[0], "quit") == 0) { exit_game(); + + } else if(strcmp(argv[0], "help") == 0) { + con.printf("available commands:\n"); + con.printf(" set set value to a variable\n"); + con.printf(" get print the value of a variable\n"); + con.printf(" vars print a list of all variables\n"); + con.printf(" help print this help screen\n"); + con.printf(" exit or quit quit the program\n"); + } else { con.printf("invalid command: %s\n", argv[0]); } diff -r 608e03b688f8 -r 0eca023ed909 src/game_var.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/game_var.cc Wed Oct 01 01:06:55 2014 +0300 @@ -0,0 +1,141 @@ +#include +#include "game_var.h" + +static std::map gvars; + +GameVariable::GameVariable() +{ + num_val = 0.0f; + bool_val = false; +} + +std::string GameVariable::to_str() const +{ + char buf[128]; + + switch(type) { + case GameVariable::STR: + return val; + case GameVariable::BOOL: + return bool_val ? "true" : "false"; + case GameVariable::NUMBER: + sprintf(buf, "%g", num_val); + return buf; + } + return ""; +} + +void set_gvar(const GameVariable &var) +{ + gvars[var.name] = var; +} + +void set_gvar_str(const char *name, const char *val) +{ + GameVariable v; + v.name = name; + v.val = val; + v.type = GameVariable::STR; + set_gvar(v); +} + +void set_gvar_num(const char *name, float val) +{ + GameVariable v; + v.name = name; + v.num_val = val; + v.type = GameVariable::NUMBER; + set_gvar(v); +} + +void set_gvar_bool(const char *name, bool val) +{ + GameVariable v; + v.name = name; + v.bool_val = val; + v.type = GameVariable::BOOL; + set_gvar(v); +} + +static char *strip_whitespace(char *s) +{ + while(*s && isspace(*s)) ++s; + if(*s == 0) return s; + + char *endp = s + strlen(s) - 1; + while(endp > s && isspace(*endp)) { + *endp-- = 0; + } + return s; +} + +static int strccmp(const char *a, const char *b) +{ + while(*a && *b) { + int diff = tolower(*a) - tolower(*b); + if(diff != 0) return diff; + ++a; + ++b; + } + if(*a == 0 && *b == 0) return 0; + return *a == 0 ? -1 : 1; +} + +void set_gvar_parse(const char *name, const char *val) +{ + char *endp, *valstr = (char*)alloca(strlen(val) + 1); + strcpy(valstr, val); + valstr = strip_whitespace(valstr); + + float fval = strtod(valstr, &endp); + if(endp != valstr && *endp == 0) { + set_gvar_num(name, fval); + return; + } + + if(strccmp(valstr, "true") == 0 || strccmp(valstr, "yes") == 0) { + set_gvar_bool(name, true); + return; + } + if(strccmp(valstr, "false") == 0 || strccmp(valstr, "no") == 0) { + set_gvar_bool(name, false); + return; + } + return set_gvar_str(name, val); +} + +GameVariable &get_gvar(const char *name) +{ + return gvars[name]; +} + +const char *get_gvar_str(const char *name) +{ + return gvars[name].val.c_str(); +} + +float get_gvar_num(const char *name) +{ + return gvars[name].num_val; +} + +bool get_gvar_bool(const char *name) +{ + return gvars[name].bool_val; +} + +bool have_gvar(const char *name) +{ + return gvars.find(std::string(name)) != gvars.end(); +} + +std::list get_gvar_list() +{ + std::list res; + + std::map::const_iterator it = gvars.begin(); + while(it != gvars.end()) { + res.push_back((it++)->first); + } + return res; +} \ No newline at end of file diff -r 608e03b688f8 -r 0eca023ed909 src/game_var.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/game_var.h Wed Oct 01 01:06:55 2014 +0300 @@ -0,0 +1,32 @@ +#ifndef GAME_VAR_H_ +#define GAME_VAR_H_ + +#include +#include + +struct GameVariable { + enum { NUMBER, BOOL, STR } type; + std::string name, val; + float num_val; + bool bool_val; + + GameVariable(); + std::string to_str() const; +}; + +void set_gvar(const GameVariable &var); +void set_gvar_str(const char *name, const char *val); +void set_gvar_num(const char *name, float val); +void set_gvar_bool(const char *name, bool val); +void set_gvar_parse(const char *name, const char *val); + +GameVariable &get_gvar(const char *name); +const char *get_gvar_str(const char *name); +float get_gvar_num(const char *name); +bool get_gvar_bool(const char *name); + +bool have_gvar(const char *name); + +std::list get_gvar_list(); + +#endif // GAME_VAR_H_ \ No newline at end of file diff -r 608e03b688f8 -r 0eca023ed909 vrheights.vcxproj --- a/vrheights.vcxproj Tue Sep 30 18:57:20 2014 +0300 +++ b/vrheights.vcxproj Wed Oct 01 01:06:55 2014 +0300 @@ -83,6 +83,7 @@ + @@ -91,6 +92,7 @@ + diff -r 608e03b688f8 -r 0eca023ed909 vrheights.vcxproj.filters --- a/vrheights.vcxproj.filters Tue Sep 30 18:57:20 2014 +0300 +++ b/vrheights.vcxproj.filters Wed Oct 01 01:06:55 2014 +0300 @@ -25,6 +25,9 @@ src + + src + @@ -45,5 +48,8 @@ src + + src + \ No newline at end of file