1 /*
2 * Copyright (C) 2003-2010 Neverball authors
3 *
4 * NEVERBALL is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published
6 * by the Free Software Foundation; either version 2 of the License,
7 * or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 */
14
15 #include "game_common.h"
16 #include "vec3.h"
17 #include "config.h"
18 #include "solid_vary.h"
19 #include "hmd.h"
20 #include "common.h"
21
22 /*---------------------------------------------------------------------------*/
23
status_to_str(int s)24 const char *status_to_str(int s)
25 {
26 switch (s)
27 {
28 case GAME_NONE: return _("Aborted");
29 case GAME_TIME: return _("Time-out");
30 case GAME_GOAL: return _("Success");
31 case GAME_FALL: return _("Fall-out");
32 default: return _("Unknown");
33 }
34 }
35
36 /*---------------------------------------------------------------------------*/
37
cam_to_str(int c)38 const char *cam_to_str(int c)
39 {
40 static char str[64];
41
42 int s = cam_speed(c);
43
44 if (s < 0) return _("Manual Camera");
45 if (s <= 100) return _("Lazy Camera");
46 if (s <= 500) return _("Chase Camera");
47
48 sprintf(str, _("Camera %d"), c + 1);
49
50 return str;
51 }
52
cam_speed(int c)53 int cam_speed(int c)
54 {
55 static const int *cfgs[] = {
56 &CONFIG_CAMERA_1_SPEED,
57 &CONFIG_CAMERA_2_SPEED,
58 &CONFIG_CAMERA_3_SPEED
59 };
60
61 if (c >= 0 && c < ARRAYSIZE(cfgs))
62 return config_get_d(*cfgs[c]);
63
64 return 250;
65 }
66
67 /*---------------------------------------------------------------------------*/
68
69 const float GRAVITY_UP[] = { 0.0f, +9.8f, 0.0f };
70 const float GRAVITY_DN[] = { 0.0f, -9.8f, 0.0f };
71
game_tilt_init(struct game_tilt * tilt)72 void game_tilt_init(struct game_tilt *tilt)
73 {
74 tilt->x[0] = 1.0f;
75 tilt->x[1] = 0.0f;
76 tilt->x[2] = 0.0f;
77
78 tilt->rx = 0.0f;
79
80 tilt->z[0] = 0.0f;
81 tilt->z[1] = 0.0f;
82 tilt->z[2] = 1.0f;
83
84 tilt->rz = 0.0f;
85 }
86
87 /*
88 * Compute appropriate tilt axes from the view basis.
89 */
game_tilt_axes(struct game_tilt * tilt,float view_e[3][3])90 void game_tilt_axes(struct game_tilt *tilt, float view_e[3][3])
91 {
92 v_cpy(tilt->x, view_e[0]);
93 v_cpy(tilt->z, view_e[2]);
94 }
95
game_tilt_grav(float h[3],const float g[3],const struct game_tilt * tilt)96 void game_tilt_grav(float h[3], const float g[3], const struct game_tilt *tilt)
97 {
98 float X[16];
99 float Z[16];
100 float M[16];
101
102 /* Compute the gravity vector from the given world rotations. */
103
104 m_rot (Z, tilt->z, V_RAD(tilt->rz));
105 m_rot (X, tilt->x, V_RAD(tilt->rx));
106 m_mult(M, Z, X);
107 m_vxfm(h, M, g);
108 }
109
110 /*---------------------------------------------------------------------------*/
111
game_view_init(struct game_view * view)112 void game_view_init(struct game_view *view)
113 {
114 /* In VR, ensure the default view is level. */
115
116 if (hmd_stat())
117 {
118 view->dp = config_get_d(CONFIG_VIEW_DP) / 100.0f;
119 view->dc = config_get_d(CONFIG_VIEW_DP) / 100.0f;
120 view->dz = config_get_d(CONFIG_VIEW_DZ) / 100.0f;
121 }
122 else
123 {
124 view->dp = config_get_d(CONFIG_VIEW_DP) / 100.0f;
125 view->dc = config_get_d(CONFIG_VIEW_DC) / 100.0f;
126 view->dz = config_get_d(CONFIG_VIEW_DZ) / 100.0f;
127 }
128
129 view->a = 0.0f;
130
131 view->c[0] = 0.0f;
132 view->c[1] = view->dc;
133 view->c[2] = 0.0f;
134
135 view->p[0] = 0.0f;
136 view->p[1] = view->dp;
137 view->p[2] = view->dz;
138
139 view->e[0][0] = 1.0f;
140 view->e[0][1] = 0.0f;
141 view->e[0][2] = 0.0f;
142 view->e[1][0] = 0.0f;
143 view->e[1][1] = 1.0f;
144 view->e[1][2] = 0.0f;
145 view->e[2][0] = 0.0f;
146 view->e[2][1] = 0.0f;
147 view->e[2][2] = 1.0f;
148 }
149
game_view_fly(struct game_view * view,const struct s_vary * vary,float k)150 void game_view_fly(struct game_view *view, const struct s_vary *vary, float k)
151 {
152 /* float x[3] = { 1.f, 0.f, 0.f }; */
153 float y[3] = { 0.f, 1.f, 0.f };
154 float z[3] = { 0.f, 0.f, 1.f };
155 float c0[3] = { 0.f, 0.f, 0.f };
156 float p0[3] = { 0.f, 0.f, 0.f };
157 float c1[3] = { 0.f, 0.f, 0.f };
158 float p1[3] = { 0.f, 0.f, 0.f };
159 float v[3];
160
161 game_view_init(view);
162
163 /* k = 0.0 view is at the ball. */
164
165 if (vary->uc > 0)
166 {
167 v_cpy(c0, vary->uv[0].p);
168 v_cpy(p0, vary->uv[0].p);
169 }
170
171 v_mad(p0, p0, y, view->dp);
172 v_mad(p0, p0, z, view->dz);
173 v_mad(c0, c0, y, view->dc);
174
175 /* k = +1.0 view is s_view 0 */
176
177 if (k >= 0 && vary->base->wc > 0)
178 {
179 v_cpy(p1, vary->base->wv[0].p);
180 v_cpy(c1, vary->base->wv[0].q);
181 }
182
183 /* k = -1.0 view is s_view 1 */
184
185 if (k <= 0 && vary->base->wc > 1)
186 {
187 v_cpy(p1, vary->base->wv[1].p);
188 v_cpy(c1, vary->base->wv[1].q);
189 }
190
191 /* Interpolate the views. */
192
193 v_sub(v, p1, p0);
194 v_mad(view->p, p0, v, k * k);
195
196 v_sub(v, c1, c0);
197 v_mad(view->c, c0, v, k * k);
198
199 /* Orthonormalize the view basis. */
200
201 v_sub(view->e[2], view->p, view->c);
202 v_crs(view->e[0], view->e[1], view->e[2]);
203 v_crs(view->e[2], view->e[0], view->e[1]);
204 v_nrm(view->e[0], view->e[0]);
205 v_nrm(view->e[2], view->e[2]);
206 }
207
208 /*---------------------------------------------------------------------------*/
209
lockstep_clr(struct lockstep * ls)210 void lockstep_clr(struct lockstep *ls)
211 {
212 ls->at = 0;
213 ls->ts = 1.0f;
214 }
215
lockstep_run(struct lockstep * ls,float dt)216 void lockstep_run(struct lockstep *ls, float dt)
217 {
218 ls->at += dt * ls->ts;
219
220 while (ls->at >= ls->dt)
221 {
222 ls->step(ls->dt);
223 ls->at -= ls->dt;
224 }
225 }
226
lockstep_scl(struct lockstep * ls,float ts)227 void lockstep_scl(struct lockstep *ls, float ts)
228 {
229 ls->ts = ts;
230 }
231
232 /*---------------------------------------------------------------------------*/
233
234 /* Poor man's cache. */
235
236 struct s_base game_base;
237 static char *base_path;
238
game_base_load(const char * path)239 int game_base_load(const char *path)
240 {
241 if (base_path)
242 {
243 if (strcmp(base_path, path) == 0)
244 return 1;
245
246 sol_free_base(&game_base);
247
248 free(base_path);
249 base_path = NULL;
250 }
251
252 if (sol_load_base(&game_base, path))
253 {
254 base_path = strdup(path);
255 return 1;
256 }
257
258 return 0;
259 }
260
261
game_base_free(const char * next)262 void game_base_free(const char *next)
263 {
264 if (base_path)
265 {
266 if (next && strcmp(base_path, next) == 0)
267 return;
268
269 sol_free_base(&game_base);
270
271 free(base_path);
272 base_path = NULL;
273 }
274 }
275
276 /*---------------------------------------------------------------------------*/
277
278 float SPEED_FACTORS[SPEED_MAX] = {
279 0.0f,
280 1.0f / 8,
281 1.0f / 4,
282 1.0f / 2,
283 1.0f,
284 1.0f * 2,
285 1.0f * 4,
286 1.0f * 8
287 };
288
289 /*---------------------------------------------------------------------------*/
290