Split SOL data structures into base, varying and rendering parts
[neverball] / ball / game_common.c
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
20 /*---------------------------------------------------------------------------*/
21
22 const char *status_to_str(int s)
23 {
24     switch (s)
25     {
26     case GAME_NONE:    return _("Aborted");
27     case GAME_TIME:    return _("Time-out");
28     case GAME_GOAL:    return _("Success");
29     case GAME_FALL:    return _("Fall-out");
30     default:           return _("Unknown");
31     }
32 }
33
34 const char *view_to_str(int v)
35 {
36     switch (v)
37     {
38     case VIEW_CHASE:   return _("Chase");
39     case VIEW_LAZY:    return _("Lazy");
40     case VIEW_MANUAL:  return _("Manual");
41     default:           return _("Unknown");
42     }
43 }
44
45 /*---------------------------------------------------------------------------*/
46
47 const float GRAVITY_UP[] = { 0.0f, +9.8f, 0.0f };
48 const float GRAVITY_DN[] = { 0.0f, -9.8f, 0.0f };
49
50 void game_tilt_init(struct game_tilt *tilt)
51 {
52     tilt->x[0] = 1.0f;
53     tilt->x[1] = 0.0f;
54     tilt->x[2] = 0.0f;
55
56     tilt->rx = 0.0f;
57
58     tilt->z[0] = 0.0f;
59     tilt->z[1] = 0.0f;
60     tilt->z[2] = 1.0f;
61
62     tilt->rz = 0.0f;
63 }
64
65 /*
66  * Compute appropriate tilt axes from the view basis.
67  */
68 void game_tilt_axes(struct game_tilt *tilt, float view_e[3][3])
69 {
70     v_cpy(tilt->x, view_e[0]);
71     v_cpy(tilt->z, view_e[2]);
72 }
73
74 void game_tilt_grav(float h[3], const float g[3], const struct game_tilt *tilt)
75 {
76     float X[16];
77     float Z[16];
78     float M[16];
79
80     /* Compute the gravity vector from the given world rotations. */
81
82     m_rot (Z, tilt->z, V_RAD(tilt->rz));
83     m_rot (X, tilt->x, V_RAD(tilt->rx));
84     m_mult(M, Z, X);
85     m_vxfm(h, M, g);
86 }
87
88 /*---------------------------------------------------------------------------*/
89
90 void game_view_init(struct game_view *view)
91 {
92     view->dp  = config_get_d(CONFIG_VIEW_DP) / 100.0f;
93     view->dc  = config_get_d(CONFIG_VIEW_DC) / 100.0f;
94     view->dz  = config_get_d(CONFIG_VIEW_DZ) / 100.0f;
95     view->a   = 0.0f;
96
97     view->c[0] = 0.0f;
98     view->c[1] = view->dc;
99     view->c[2] = 0.0f;
100
101     view->p[0] =     0.0f;
102     view->p[1] = view->dp;
103     view->p[2] = view->dz;
104
105     view->e[0][0] = 1.0f;
106     view->e[0][1] = 0.0f;
107     view->e[0][2] = 0.0f;
108     view->e[1][0] = 0.0f;
109     view->e[1][1] = 1.0f;
110     view->e[1][2] = 0.0f;
111     view->e[2][0] = 0.0f;
112     view->e[2][1] = 0.0f;
113     view->e[2][2] = 1.0f;
114 }
115
116 void game_view_fly(struct game_view *view, const struct s_vary *vary, float k)
117 {
118     /* float  x[3] = { 1.f, 0.f, 0.f }; */
119     float  y[3] = { 0.f, 1.f, 0.f };
120     float  z[3] = { 0.f, 0.f, 1.f };
121     float c0[3] = { 0.f, 0.f, 0.f };
122     float p0[3] = { 0.f, 0.f, 0.f };
123     float c1[3] = { 0.f, 0.f, 0.f };
124     float p1[3] = { 0.f, 0.f, 0.f };
125     float  v[3];
126
127     game_view_init(view);
128
129     /* k = 0.0 view is at the ball. */
130
131     if (vary->uc > 0)
132     {
133         v_cpy(c0, vary->uv[0].p);
134         v_cpy(p0, vary->uv[0].p);
135     }
136
137     v_mad(p0, p0, y, view->dp);
138     v_mad(p0, p0, z, view->dz);
139     v_mad(c0, c0, y, view->dc);
140
141     /* k = +1.0 view is s_view 0 */
142
143     if (k >= 0 && vary->base->wc > 0)
144     {
145         v_cpy(p1, vary->base->wv[0].p);
146         v_cpy(c1, vary->base->wv[0].q);
147     }
148
149     /* k = -1.0 view is s_view 1 */
150
151     if (k <= 0 && vary->base->wc > 1)
152     {
153         v_cpy(p1, vary->base->wv[1].p);
154         v_cpy(c1, vary->base->wv[1].q);
155     }
156
157     /* Interpolate the views. */
158
159     v_sub(v, p1, p0);
160     v_mad(view->p, p0, v, k * k);
161
162     v_sub(v, c1, c0);
163     v_mad(view->c, c0, v, k * k);
164
165     /* Orthonormalize the view basis. */
166
167     v_sub(view->e[2], view->p, view->c);
168     v_crs(view->e[0], view->e[1], view->e[2]);
169     v_crs(view->e[2], view->e[0], view->e[1]);
170     v_nrm(view->e[0], view->e[0]);
171     v_nrm(view->e[2], view->e[2]);
172 }
173
174 /*---------------------------------------------------------------------------*/
175
176 void lockstep_clr(struct lockstep *ls)
177 {
178     ls->at = 0;
179     ls->ts = 1.0f;
180 }
181
182 void lockstep_run(struct lockstep *ls, float dt)
183 {
184     ls->at += dt * ls->ts;
185
186     while (ls->at >= ls->dt)
187     {
188         ls->step(ls->dt);
189         ls->at -= ls->dt;
190     }
191 }
192
193 void lockstep_scl(struct lockstep *ls, float ts)
194 {
195     ls->ts = ts;
196 }
197
198 /*---------------------------------------------------------------------------*/