vrheights

changeset 7:0eca023ed909

- fixed the hmd-tracking / mouselook interaction - added game variable system
author John Tsiombikas <nuclear@member.fsf.org>
date Wed, 01 Oct 2014 01:06:55 +0300
parents 608e03b688f8
children 3f221bdc9bab
files src/game.cc src/game_var.cc src/game_var.h vrheights.vcxproj vrheights.vcxproj.filters
diffstat 5 files changed, 237 insertions(+), 18 deletions(-) [+]
line diff
     1.1 --- a/src/game.cc	Tue Sep 30 18:57:20 2014 +0300
     1.2 +++ b/src/game.cc	Wed Oct 01 01:06:55 2014 +0300
     1.3 @@ -9,6 +9,7 @@
     1.4  #include "teapot.h"
     1.5  #include "console.h"
     1.6  #include "drawtext.h"
     1.7 +#include "game_var.h"
     1.8  
     1.9  static void draw_scene();
    1.10  static void material(float r, float g, float b, float roughness);
    1.11 @@ -17,8 +18,6 @@
    1.12  static int next_pow2(int x);
    1.13  static void con_handle(const char *cmd);
    1.14  
    1.15 -bool opt_separate_walk_look;
    1.16 -
    1.17  static int win_width, win_height;
    1.18  static unsigned int fb_tex;
    1.19  static unsigned int fbo, fb_depth;
    1.20 @@ -34,6 +33,8 @@
    1.21  static Console con;
    1.22  static dtx_font *con_font;
    1.23  
    1.24 +#define OPT_LOOK_WALK	"look-walk"
    1.25 +
    1.26  bool game_init()
    1.27  {
    1.28  	init_opengl();
    1.29 @@ -61,9 +62,13 @@
    1.30  		return false;
    1.31  	}
    1.32  	con.set_font(con_font, 14);
    1.33 -	con.set_size(7, 40);
    1.34 +	con.set_size(7, 52);
    1.35  	con.set_position(0, 0, Console::CENTER);
    1.36  	con.set_command_func(con_handle);
    1.37 +	con.set_echo(false);
    1.38 +
    1.39 +	/* initialize all option variables */
    1.40 +	set_gvar_bool(OPT_LOOK_WALK, true);
    1.41  
    1.42  	return true;
    1.43  }
    1.44 @@ -100,18 +105,19 @@
    1.45  		dir += Vector3(0, 0, offs);
    1.46  	}
    1.47  
    1.48 +	if(get_gvar_bool(OPT_LOOK_WALK)) {
    1.49 +		float rot[4];
    1.50 +		vr_view_rotation(0, rot);
    1.51 +		Quaternion q(rot[3], rot[0], rot[1], rot[2]);
    1.52 +
    1.53 +		dir.transform(q);
    1.54 +	}
    1.55 +
    1.56  	float cos_theta = cos(DEG_TO_RAD(cam_theta));
    1.57  	float sin_theta = sin(DEG_TO_RAD(cam_theta));
    1.58  	cam_pos.x += dir.x * cos_theta - dir.z * sin_theta;
    1.59  	cam_pos.z += dir.x * sin_theta + dir.z * cos_theta;
    1.60  
    1.61 -	if(!opt_separate_walk_look) {
    1.62 -		float rot[4];
    1.63 -		vr_view_rotation(0, rot);
    1.64 -		Quaternion q(rot[3], rot[0], rot[1], rot[2]);
    1.65 -
    1.66 -		cam_pos.transform(q);
    1.67 -	}
    1.68  }
    1.69  
    1.70  void game_display()
    1.71 @@ -377,6 +383,13 @@
    1.72  	return str;
    1.73  }
    1.74  
    1.75 +struct Variable {
    1.76 +	const char *var;
    1.77 +	enum { BOOL, NUM } type;
    1.78 +	bool bool_val;
    1.79 +	float num_val;
    1.80 +};
    1.81 +
    1.82  static void con_handle(const char *cmd)
    1.83  {
    1.84  	std::vector<char*> argv;
    1.85 @@ -396,20 +409,45 @@
    1.86  
    1.87  	if(strcmp(argv[0], "set") == 0) {
    1.88  		if(argv.size() < 3) {
    1.89 -			fprintf(stderr, "set must be followed by 2 arguments\n");
    1.90 +			con.printf("set must be followed by 2 arguments\n");
    1.91  			return;
    1.92  		}
    1.93 -		if(strcmp(argv[1], "separate-walk") == 0) {
    1.94 -			if(strcmp(argv[2], "true") == 0) {
    1.95 -				opt_separate_walk_look = true;
    1.96 -			} else if(strcmp(argv[2], "false") == 0) {
    1.97 -				opt_separate_walk_look = false;
    1.98 -			}
    1.99 +		if(have_gvar(argv[1])) {
   1.100 +			GameVariable &gv = get_gvar(argv[1]);
   1.101 +			con.printf("%s->%s (prev: %s)\n", argv[1], argv[2], gv.to_str().c_str());
   1.102  		} else {
   1.103 -			con.printf("unknown option: %s\n", argv[1]);
   1.104 +			con.printf("%s->%s\n", argv[1], argv[2]);
   1.105  		}
   1.106 +		set_gvar_parse(argv[1], argv[2]);
   1.107 +
   1.108 +	} else if(strcmp(argv[0], "get") == 0) {
   1.109 +		if(argv.size() < 2) {
   1.110 +			con.printf("get must be followed by the variable name\n");
   1.111 +			return;
   1.112 +		}
   1.113 +		if(have_gvar(argv[1])) {
   1.114 +			GameVariable &gv = get_gvar(argv[1]);
   1.115 +			con.printf("%s: %s\n", argv[1], gv.to_str().c_str());
   1.116 +		}
   1.117 +
   1.118 +	} else if(strcmp(argv[0], "vars") == 0) {
   1.119 +		std::list<std::string> vars = get_gvar_list();
   1.120 +		std::list<std::string>::const_iterator it = vars.begin();
   1.121 +		while(it != vars.end()) {
   1.122 +			con.printf("  %s\n", it++->c_str());
   1.123 +		}
   1.124 +
   1.125  	} else if(strcmp(argv[0], "exit") == 0 || strcmp(argv[0], "quit") == 0) {
   1.126  		exit_game();
   1.127 +
   1.128 +	} else if(strcmp(argv[0], "help") == 0) {
   1.129 +		con.printf("available commands:\n");
   1.130 +		con.printf(" set <var> <val>  set value to a variable\n");
   1.131 +		con.printf(" get <var>        print the value of a variable\n");
   1.132 +		con.printf(" vars             print a list of all variables\n");
   1.133 +		con.printf(" help             print this help screen\n");
   1.134 +		con.printf(" exit or quit     quit the program\n");
   1.135 +
   1.136  	} else {
   1.137  		con.printf("invalid command: %s\n", argv[0]);
   1.138  	}
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/src/game_var.cc	Wed Oct 01 01:06:55 2014 +0300
     2.3 @@ -0,0 +1,141 @@
     2.4 +#include <map>
     2.5 +#include "game_var.h"
     2.6 +
     2.7 +static std::map<std::string, GameVariable> gvars;
     2.8 +
     2.9 +GameVariable::GameVariable()
    2.10 +{
    2.11 +	num_val = 0.0f;
    2.12 +	bool_val = false;
    2.13 +}
    2.14 +
    2.15 +std::string GameVariable::to_str() const
    2.16 +{
    2.17 +	char buf[128];
    2.18 +
    2.19 +	switch(type) {
    2.20 +	case GameVariable::STR:
    2.21 +		return val;
    2.22 +	case GameVariable::BOOL:
    2.23 +		return bool_val ? "true" : "false";
    2.24 +	case GameVariable::NUMBER:
    2.25 +		sprintf(buf, "%g", num_val);
    2.26 +		return buf;
    2.27 +	}
    2.28 +	return "<unknown>";
    2.29 +}
    2.30 +
    2.31 +void set_gvar(const GameVariable &var)
    2.32 +{
    2.33 +	gvars[var.name] = var;
    2.34 +}
    2.35 +
    2.36 +void set_gvar_str(const char *name, const char *val)
    2.37 +{
    2.38 +	GameVariable v;
    2.39 +	v.name = name;
    2.40 +	v.val = val;
    2.41 +	v.type = GameVariable::STR;
    2.42 +	set_gvar(v);
    2.43 +}
    2.44 +
    2.45 +void set_gvar_num(const char *name, float val)
    2.46 +{
    2.47 +	GameVariable v;
    2.48 +	v.name = name;
    2.49 +	v.num_val = val;
    2.50 +	v.type = GameVariable::NUMBER;
    2.51 +	set_gvar(v);
    2.52 +}
    2.53 +
    2.54 +void set_gvar_bool(const char *name, bool val)
    2.55 +{
    2.56 +	GameVariable v;
    2.57 +	v.name = name;
    2.58 +	v.bool_val = val;
    2.59 +	v.type = GameVariable::BOOL;
    2.60 +	set_gvar(v);
    2.61 +}
    2.62 +
    2.63 +static char *strip_whitespace(char *s)
    2.64 +{
    2.65 +	while(*s && isspace(*s)) ++s;
    2.66 +	if(*s == 0) return s;
    2.67 +
    2.68 +	char *endp = s + strlen(s) - 1;
    2.69 +	while(endp > s && isspace(*endp)) {
    2.70 +		*endp-- = 0;
    2.71 +	}
    2.72 +	return s;
    2.73 +}
    2.74 +
    2.75 +static int strccmp(const char *a, const char *b)
    2.76 +{
    2.77 +	while(*a && *b) {
    2.78 +		int diff = tolower(*a) - tolower(*b);
    2.79 +		if(diff != 0) return diff;
    2.80 +		++a;
    2.81 +		++b;
    2.82 +	}
    2.83 +	if(*a == 0 && *b == 0) return 0;
    2.84 +	return *a == 0 ? -1 : 1;
    2.85 +}
    2.86 +
    2.87 +void set_gvar_parse(const char *name, const char *val)
    2.88 +{
    2.89 +	char *endp, *valstr = (char*)alloca(strlen(val) + 1);
    2.90 +	strcpy(valstr, val);
    2.91 +	valstr = strip_whitespace(valstr);
    2.92 +
    2.93 +	float fval = strtod(valstr, &endp);
    2.94 +	if(endp != valstr && *endp == 0) {
    2.95 +		set_gvar_num(name, fval);
    2.96 +		return;
    2.97 +	}
    2.98 +
    2.99 +	if(strccmp(valstr, "true") == 0 || strccmp(valstr, "yes") == 0) {
   2.100 +		set_gvar_bool(name, true);
   2.101 +		return;
   2.102 +	}
   2.103 +	if(strccmp(valstr, "false") == 0 || strccmp(valstr, "no") == 0) {
   2.104 +		set_gvar_bool(name, false);
   2.105 +		return;
   2.106 +	}
   2.107 +	return set_gvar_str(name, val);
   2.108 +}
   2.109 +
   2.110 +GameVariable &get_gvar(const char *name)
   2.111 +{
   2.112 +	return gvars[name];
   2.113 +}
   2.114 +
   2.115 +const char *get_gvar_str(const char *name)
   2.116 +{
   2.117 +	return gvars[name].val.c_str();
   2.118 +}
   2.119 +
   2.120 +float get_gvar_num(const char *name)
   2.121 +{
   2.122 +	return gvars[name].num_val;
   2.123 +}
   2.124 +
   2.125 +bool get_gvar_bool(const char *name)
   2.126 +{
   2.127 +	return gvars[name].bool_val;
   2.128 +}
   2.129 +
   2.130 +bool have_gvar(const char *name)
   2.131 +{
   2.132 +	return gvars.find(std::string(name)) != gvars.end();
   2.133 +}
   2.134 +
   2.135 +std::list<std::string> get_gvar_list()
   2.136 +{
   2.137 +	std::list<std::string> res;
   2.138 +
   2.139 +	std::map<std::string, GameVariable>::const_iterator it = gvars.begin();
   2.140 +	while(it != gvars.end()) {
   2.141 +		res.push_back((it++)->first);
   2.142 +	}
   2.143 +	return res;
   2.144 +}
   2.145 \ No newline at end of file
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/src/game_var.h	Wed Oct 01 01:06:55 2014 +0300
     3.3 @@ -0,0 +1,32 @@
     3.4 +#ifndef GAME_VAR_H_
     3.5 +#define GAME_VAR_H_
     3.6 +
     3.7 +#include <string>
     3.8 +#include <list>
     3.9 +
    3.10 +struct GameVariable {
    3.11 +	enum { NUMBER, BOOL, STR } type;
    3.12 +	std::string name, val;
    3.13 +	float num_val;
    3.14 +	bool bool_val;
    3.15 +
    3.16 +	GameVariable();
    3.17 +	std::string to_str() const;
    3.18 +};
    3.19 +
    3.20 +void set_gvar(const GameVariable &var);
    3.21 +void set_gvar_str(const char *name, const char *val);
    3.22 +void set_gvar_num(const char *name, float val);
    3.23 +void set_gvar_bool(const char *name, bool val);
    3.24 +void set_gvar_parse(const char *name, const char *val);
    3.25 +
    3.26 +GameVariable &get_gvar(const char *name);
    3.27 +const char *get_gvar_str(const char *name);
    3.28 +float get_gvar_num(const char *name);
    3.29 +bool get_gvar_bool(const char *name);
    3.30 +
    3.31 +bool have_gvar(const char *name);
    3.32 +
    3.33 +std::list<std::string> get_gvar_list();
    3.34 +
    3.35 +#endif	// GAME_VAR_H_
    3.36 \ No newline at end of file
     4.1 --- a/vrheights.vcxproj	Tue Sep 30 18:57:20 2014 +0300
     4.2 +++ b/vrheights.vcxproj	Wed Oct 01 01:06:55 2014 +0300
     4.3 @@ -83,6 +83,7 @@
     4.4      <ClCompile Include="src\bezmath.c" />
     4.5      <ClCompile Include="src\console.cc" />
     4.6      <ClCompile Include="src\game.cc" />
     4.7 +    <ClCompile Include="src\game_var.cc" />
     4.8      <ClCompile Include="src\main.cc" />
     4.9      <ClCompile Include="src\opengl.cc" />
    4.10      <ClCompile Include="src\teapot.c" />
    4.11 @@ -91,6 +92,7 @@
    4.12      <ClInclude Include="src\bezmath.h" />
    4.13      <ClInclude Include="src\console.h" />
    4.14      <ClInclude Include="src\game.h" />
    4.15 +    <ClInclude Include="src\game_var.h" />
    4.16      <ClInclude Include="src\opengl.h" />
    4.17      <ClInclude Include="src\teapot.h" />
    4.18      <ClInclude Include="src\teapot_data.h" />
     5.1 --- a/vrheights.vcxproj.filters	Tue Sep 30 18:57:20 2014 +0300
     5.2 +++ b/vrheights.vcxproj.filters	Wed Oct 01 01:06:55 2014 +0300
     5.3 @@ -25,6 +25,9 @@
     5.4      <ClCompile Include="src\console.cc">
     5.5        <Filter>src</Filter>
     5.6      </ClCompile>
     5.7 +    <ClCompile Include="src\game_var.cc">
     5.8 +      <Filter>src</Filter>
     5.9 +    </ClCompile>
    5.10    </ItemGroup>
    5.11    <ItemGroup>
    5.12      <ClInclude Include="src\game.h">
    5.13 @@ -45,5 +48,8 @@
    5.14      <ClInclude Include="src\console.h">
    5.15        <Filter>src</Filter>
    5.16      </ClInclude>
    5.17 +    <ClInclude Include="src\game_var.h">
    5.18 +      <Filter>src</Filter>
    5.19 +    </ClInclude>
    5.20    </ItemGroup>
    5.21  </Project>
    5.22 \ No newline at end of file