change to SDLKey type
[physics.git] / src / main.cpp
... / ...
CommitLineData
1/*
2 * Copyright (C) 2008 Patrik Gornicz, Gornicz_P (at) hotmail (dot) com.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include <GL/gl.h>
19#include <GL/glu.h>
20#include <SDL/SDL.h>
21
22#include "debug.h"
23#include "handleSignal.h"
24
25#include "game.h"
26#include "ticks.h"
27
28#include "graphics/graphics.h"
29#include "input/inputManager.h"
30#include "config/config.h"
31
32/// ***** Private Method Headers *****
33
34void init();
35
36void sighandler( int sig );
37
38void run();
39void clean();
40
41void blockUpdate();
42void updateFPSCounters();
43
44void handleInput();
45void update(float);
46void draw();
47
48/// ***** Private Variables *****
49
50// variable used to determine if it is time to shutdown
51bool is_Running;
52
53/* Values for the main game loop
54 * target_UPS := the amount of updates that is wanted in one second
55 * last_Update := stores the time of the last update
56 * update_Sum := used to determine the updates needs for this run
57
58 * ups := updates per second for the last second
59 * fps := frames per second for the last second
60 * update_Count := counts this seconds updates
61 * draw_Count := counts this seconds draws
62 * last_Second := stores the time of the last second, used for ups and fps
63 */
64int target_UPS = 100;
65long int last_Block_Update;
66float update_Sum = 0;
67
68int ups=100, fps=100;
69int update_Count, draw_Count;
70long int last_Second;
71
72
73float target_time_steps_per_second = 1000;
74float times;
75float time_steps_Count;
76
77
78// experiment with rolling averages
79float rUpdate = 100;
80float rDraw = 100;
81float rInput = 100;
82float rRun = 100;
83
84float num = 10;
85
86float total = 0;
87
88/// ***** MAIN Method *****
89int main()
90{
91 init();
92 run();
93 clean();
94 return 0;
95}
96
97/// ***** Initializers/Cleaners *****
98
99void init()
100{
101 installSignal();
102
103 graphics::init();
104
105 game::init();
106
107 input::init();
108
109 cfg::init();
110
111#ifdef DEBUGGING
112 cout << "Initialization Complete" << endl;
113#endif
114}
115
116void clean()
117{
118#ifdef DEBUGGING
119 cout << "Cleaning up" << endl;
120#endif
121
122 cfg::clean();
123
124 input::clean();
125
126 game::clean();
127
128 graphics::clean();
129}
130
131/// ***** Private Methods *****
132
133void run()
134{
135 is_Running = true;
136 last_Block_Update = tickCountMicro();
137 last_Second = tickCountMicro();
138
139 while(is_Running)
140 {
141 long int time;
142
143 time = tickCountMicro();
144 blockUpdate();
145 updateFPSCounters();
146 draw();
147 time = tickCountMicro() - time;
148
149 rRun = (rRun * (num-1) + time) / num;
150
151 //cout << "total:\t" << total << endl;
152 //cout << "rR:\t" << rRun << endl;
153 //total = 0;
154 }
155}
156
157void blockUpdate()
158{
159 long int start = tickCountMicro();
160 long int diff = start - last_Block_Update;
161
162 //cout << "Block" << endl;
163
164 // Calculate the updates that should be run for the next draw
165 update_Sum += (float)(diff * target_UPS) / 1000000;
166
167 // insures the float to int cast is done once.
168 int iupdate_sum = (int)update_Sum;
169
170 // TODO the main run loop needs to be tested and pruned
171 if (iupdate_sum > 0)
172 {
173 // Calculate a time step that spreads the updates out as much as
174 // possible used because really quick updates are nearly wasted
175
176 //float time_step = ((float)diff) / iupdate_sum / 1000;
177 //float time_step = 1000 / (100000 / rUpdate) / iupdate_sum;
178 //float time_step = 1000 / ups / iupdate_sum;
179 float time_step = 10;
180
181 // run the updates
182 for (int i = 0; i < iupdate_sum; i++)
183 {
184 handleInput();
185 update(time_step);
186 }
187
188 // remove the updates that were run from the sum
189 update_Sum -= iupdate_sum;
190 last_Block_Update = tickCountMicro();
191 }
192}
193
194void updateFPSCounters()
195{
196 // Check if a second has passed to recalculate UPS and FPS
197 if (tickCountMicro() - last_Second >= 1000000)
198 {
199 ups = update_Count;
200 fps = draw_Count;
201 times = time_steps_Count;
202 update_Count = 0;
203 draw_Count = 0;
204 time_steps_Count = 0;
205
206 last_Second = tickCountMicro();
207
208#ifdef FPSUPS
209 cout << "ups:\t" << ups << endl;
210 cout << "fps:\t" << fps << endl;
211 cout << "times:\t" << times << endl;
212#endif
213 }
214}
215
216void handleInput()
217{
218 long int time;
219
220 time = tickCountMicro();
221 input::update();
222
223 game::handleInput();
224
225 if(cfg::endGame())
226 is_Running = false;
227 time = tickCountMicro() - time;
228
229 rInput = (rInput*(num-1) + time) /num;
230
231 total += rInput;
232}
233
234void update(float time_step)
235{
236 long int time;
237
238 update_Count++;
239 time_steps_Count += time_step;
240
241 time = tickCountMicro();
242 game::update(time_step);
243 time = tickCountMicro() - time;
244
245 rUpdate = (rUpdate * (num-1) + time) / num;
246
247 //cout << "ts:\t" << time_step << endl;
248 //cout << "ru:\t" << rUpdate << endl;
249
250 total += rUpdate;
251}
252
253void draw()
254{
255 long int time;
256
257 draw_Count++;
258
259 time = tickCountMicro();
260 game::draw();
261
262 SDL_GL_SwapBuffers();
263
264 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
265
266 //SDL_Delay(10);
267 time = tickCountMicro() - time;
268
269 rDraw = (rDraw*(num-1) + time) /num;
270
271 //cout << "rd:\t" << rDraw << endl;
272
273 total += rDraw;
274}