starting windows cross compiling
[physics.git] / src / main.cpp
CommitLineData
e68f847b
PG
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
ad9f1fb6
PG
18#include <GL/gl.h>
19#include <GL/glu.h>
20#include <SDL/SDL.h>
21
f7b3b2eb 22#include "debug.h"
7cbd4505 23#include "handleSignal.h"
f7b3b2eb 24
ad9f1fb6
PG
25#include "game.h"
26#include "ticks.h"
44b079f8
PG
27
28#include "graphics/graphics.h"
f7b3b2eb 29#include "input/inputManager.h"
b1d92c2f 30#include "config/config.h"
ad9f1fb6 31
ad9f1fb6 32/// ***** Private Method Headers *****
617dcc71 33
ad9f1fb6
PG
34void init();
35
7cbd4505
PG
36void sighandler( int sig );
37
ad9f1fb6 38void run();
617dcc71 39void clean();
ad9f1fb6
PG
40
41void blockUpdate();
42void updateFPSCounters();
43
68b2316d 44void handleInput();
ad9f1fb6
PG
45void update(float);
46void draw();
47
ad9f1fb6
PG
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 */
d279b77b 64int target_UPS = 100;
ad9f1fb6
PG
65long int last_Block_Update;
66float update_Sum = 0;
67
9bbcda11 68int ups=100, fps=100;
ad9f1fb6
PG
69int update_Count, draw_Count;
70long int last_Second;
71
72
25d84412
PG
73float target_time_steps_per_second = 1000;
74float times;
75float time_steps_Count;
d279b77b
PG
76
77
78// experiment with rolling averages
79float rUpdate = 100;
80float rDraw = 100;
25d84412 81float rInput = 100;
d279b77b 82float rRun = 100;
25d84412 83
d279b77b
PG
84float num = 10;
85
9bbcda11 86float total = 0;
d279b77b 87
617dcc71 88/// ***** MAIN Method *****
3c3c195d 89int main(int argc, char** args)
617dcc71
PG
90{
91 init();
92 run();
93 clean();
94 return 0;
95}
96
97/// ***** Initializers/Cleaners *****
98
ad9f1fb6
PG
99void init()
100{
7cbd4505
PG
101 installSignal();
102
68b2316d 103 graphics::init();
ad9f1fb6 104
3c3c195d
PG
105#ifdef DEBUGGING
106 cout << "Graphics initialized" << endl;
107 cout << "Graphics initialized2" << endl;
108#endif
109
68b2316d 110 game::init();
ad9f1fb6 111
3c3c195d
PG
112#ifdef DEBUGGING
113 cout << "Game initialized" << endl;
114#endif
115
68b2316d 116 input::init();
617dcc71 117
3c3c195d
PG
118#ifdef DEBUGGING
119 cout << "Input initialized" << endl;
120#endif
121
b1d92c2f
PG
122 cfg::init();
123
f7b3b2eb 124#ifdef DEBUGGING
3c3c195d
PG
125 cout << "Configs initialized" << endl;
126#endif
127
128#ifdef DEBUGGING
ad9f1fb6 129 cout << "Initialization Complete" << endl;
f7b3b2eb 130#endif
ad9f1fb6
PG
131}
132
617dcc71 133void clean()
44b079f8
PG
134{
135#ifdef DEBUGGING
136 cout << "Cleaning up" << endl;
137#endif
138
b1d92c2f
PG
139 cfg::clean();
140
68b2316d 141 input::clean();
617dcc71 142
68b2316d 143 game::clean();
44b079f8 144
68b2316d 145 graphics::clean();
44b079f8
PG
146}
147
617dcc71
PG
148/// ***** Private Methods *****
149
ad9f1fb6
PG
150void run()
151{
152 is_Running = true;
153 last_Block_Update = tickCountMicro();
154 last_Second = tickCountMicro();
155
156 while(is_Running)
157 {
d279b77b
PG
158 long int time;
159
160 time = tickCountMicro();
161 blockUpdate();
162 updateFPSCounters();
163 draw();
164 time = tickCountMicro() - time;
165
166 rRun = (rRun * (num-1) + time) / num;
167
25d84412
PG
168 //cout << "total:\t" << total << endl;
169 //cout << "rR:\t" << rRun << endl;
170 //total = 0;
ad9f1fb6
PG
171 }
172}
173
ad9f1fb6
PG
174void blockUpdate()
175{
176 long int start = tickCountMicro();
2ea1d2d4 177 long int diff = start - last_Block_Update;
ad9f1fb6 178
25d84412 179 //cout << "Block" << endl;
d279b77b 180
ad9f1fb6 181 // Calculate the updates that should be run for the next draw
9bbcda11 182 update_Sum += (float)(diff * target_UPS) / 1000000;
ad9f1fb6
PG
183
184 // insures the float to int cast is done once.
185 int iupdate_sum = (int)update_Sum;
186
187 // TODO the main run loop needs to be tested and pruned
188 if (iupdate_sum > 0)
189 {
9bbcda11
PG
190 // Calculate a time step that spreads the updates out as much as
191 // possible used because really quick updates are nearly wasted
2ea1d2d4
PG
192
193 //float time_step = ((float)diff) / iupdate_sum / 1000;
194 //float time_step = 1000 / (100000 / rUpdate) / iupdate_sum;
9bbcda11 195 //float time_step = 1000 / ups / iupdate_sum;
2ea1d2d4 196 float time_step = 10;
ad9f1fb6
PG
197
198 // run the updates
2ea1d2d4 199 for (int i = 0; i < iupdate_sum; i++)
ad9f1fb6 200 {
68b2316d 201 handleInput();
25d84412 202 update(time_step);
ad9f1fb6 203 }
9bbcda11
PG
204
205 // remove the updates that were run from the sum
ad9f1fb6
PG
206 update_Sum -= iupdate_sum;
207 last_Block_Update = tickCountMicro();
208 }
209}
210
211void updateFPSCounters()
212{
213 // Check if a second has passed to recalculate UPS and FPS
214 if (tickCountMicro() - last_Second >= 1000000)
215 {
216 ups = update_Count;
217 fps = draw_Count;
25d84412 218 times = time_steps_Count;
ad9f1fb6
PG
219 update_Count = 0;
220 draw_Count = 0;
25d84412 221 time_steps_Count = 0;
ad9f1fb6
PG
222
223 last_Second = tickCountMicro();
44b079f8 224
7adc59fe
PG
225#ifdef FPSUPS
226 cout << "ups:\t" << ups << endl;
227 cout << "fps:\t" << fps << endl;
25d84412 228 cout << "times:\t" << times << endl;
7adc59fe 229#endif
ad9f1fb6
PG
230 }
231}
232
68b2316d 233void handleInput()
ad9f1fb6 234{
25d84412
PG
235 long int time;
236
237 time = tickCountMicro();
238 input::update();
f7b3b2eb 239
25d84412 240 game::handleInput();
ad9f1fb6 241
25d84412
PG
242 if(cfg::endGame())
243 is_Running = false;
244 time = tickCountMicro() - time;
245
246 rInput = (rInput*(num-1) + time) /num;
247
248 total += rInput;
ad9f1fb6
PG
249}
250
251void update(float time_step)
252{
d279b77b
PG
253 long int time;
254
ad9f1fb6 255 update_Count++;
25d84412 256 time_steps_Count += time_step;
ad9f1fb6 257
d279b77b
PG
258 time = tickCountMicro();
259 game::update(time_step);
260 time = tickCountMicro() - time;
261
262 rUpdate = (rUpdate * (num-1) + time) / num;
263
25d84412
PG
264 //cout << "ts:\t" << time_step << endl;
265 //cout << "ru:\t" << rUpdate << endl;
266
267 total += rUpdate;
ad9f1fb6
PG
268}
269
270void draw()
271{
d279b77b
PG
272 long int time;
273
ad9f1fb6
PG
274 draw_Count++;
275
d279b77b
PG
276 time = tickCountMicro();
277 game::draw();
278
279 SDL_GL_SwapBuffers();
280
281 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
282
9bbcda11 283 //SDL_Delay(10);
d279b77b 284 time = tickCountMicro() - time;
ad9f1fb6 285
d279b77b 286 rDraw = (rDraw*(num-1) + time) /num;
ad9f1fb6 287
25d84412
PG
288 //cout << "rd:\t" << rDraw << endl;
289
290 total += rDraw;
ad9f1fb6 291}