Treat angle values as floating point numbers
[neverball] / share / state.c
1 /*
2  * Copyright (C) 2003 Robert Kooima
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 "glext.h"
16 #include "state.h"
17 #include "config.h"
18 #include "video.h"
19 #include "common.h"
20
21 /*---------------------------------------------------------------------------*/
22
23 static float         state_time;
24 static int           state_drawn;
25 static struct state *state;
26
27 struct state *curr_state(void)
28 {
29     return state;
30 }
31
32 float time_state(void)
33 {
34     return state_time;
35 }
36
37 void init_state(struct state *st)
38 {
39     state = st;
40 }
41
42 int goto_state(struct state *st)
43 {
44     struct state *prev = state;
45
46     if (state && state->leave)
47         state->leave(state, st, state->gui_id);
48
49     state       = st;
50     state_time  = 0;
51     state_drawn = 0;
52
53     if (state && state->enter)
54         state->gui_id = state->enter(state, prev);
55
56     return 1;
57 }
58
59 /*---------------------------------------------------------------------------*/
60
61 void st_paint(float t)
62 {
63     state_drawn = 1;
64
65     if (state && state->paint)
66     {
67         /* TODO: reimplement stereo using LR instead of quad-buffer.
68
69         if (config_get_d(CONFIG_STEREO))
70         {
71             glDrawBuffer(GL_BACK_LEFT);
72             video_clear();
73             state->paint(state->gui_id, t);
74
75             glDrawBuffer(GL_BACK_RIGHT);
76             video_clear();
77             state->paint(state->gui_id, t);
78         }
79         else
80         */
81         {
82             video_clear();
83             state->paint(state->gui_id, t);
84         }
85     }
86 }
87
88 void st_timer(float dt)
89 {
90     if (!state_drawn)
91         return;
92
93     state_time += dt;
94
95     if (state && state->timer)
96         state->timer(state->gui_id, dt);
97 }
98
99 void st_point(int x, int y, int dx, int dy)
100 {
101     if (state && state->point)
102         state->point(state->gui_id, x, y, dx, dy);
103 }
104
105 void st_stick(int a, float v)
106 {
107     static struct
108     {
109         const int *num;
110         const int *inv;
111
112         float prev;
113     } axes[] = {
114         { &CONFIG_JOYSTICK_AXIS_X, &CONFIG_JOYSTICK_AXIS_X_INVERT },
115         { &CONFIG_JOYSTICK_AXIS_Y, &CONFIG_JOYSTICK_AXIS_Y_INVERT },
116         { &CONFIG_JOYSTICK_AXIS_U, &CONFIG_JOYSTICK_AXIS_U_INVERT }
117     };
118
119     int i, bump = 0;
120
121     for (i = 0; i < ARRAYSIZE(axes); i++)
122         if (config_tst_d(*axes[i].num, a))
123         {
124             float p = axes[i].prev;
125
126             /* Note the transition from centered to leaned position. */
127
128             bump = ((-0.5f <= p && p <= +0.5f) &&
129                     (v < -0.5f || +0.5f < v));
130
131             axes[i].prev = v;
132
133             if (config_get_d(*axes[i].inv))
134                 v = -v;
135
136             break;
137         }
138
139     if (state && state->stick)
140         state->stick(state->gui_id, a, v, bump);
141 }
142
143 void st_angle(float x, float z)
144 {
145     if (state && state->angle)
146         state->angle(state->gui_id, x, z);
147 }
148
149 /*---------------------------------------------------------------------------*/
150
151 int st_click(int b, int d)
152 {
153     return (state && state->click) ? state->click(b, d) : 1;
154 }
155
156 int st_keybd(int c, int d)
157 {
158     return (state && state->keybd) ? state->keybd(c, d) : 1;
159 }
160
161 int st_buttn(int b, int d)
162 {
163     return (state && state->buttn) ? state->buttn(b, d) : 1;
164 }
165
166 /*---------------------------------------------------------------------------*/