wip: main testing
[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
68int ups, fps;
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
86
617dcc71
PG
87/// ***** MAIN Method *****
88int main()
89{
90 init();
91 run();
92 clean();
93 return 0;
94}
95
96/// ***** Initializers/Cleaners *****
97
ad9f1fb6
PG
98void init()
99{
7cbd4505
PG
100 installSignal();
101
68b2316d 102 graphics::init();
ad9f1fb6 103
68b2316d 104 game::init();
ad9f1fb6 105
68b2316d 106 input::init();
617dcc71 107
b1d92c2f
PG
108 cfg::init();
109
f7b3b2eb 110#ifdef DEBUGGING
ad9f1fb6 111 cout << "Initialization Complete" << endl;
f7b3b2eb 112#endif
ad9f1fb6
PG
113}
114
617dcc71 115void clean()
44b079f8
PG
116{
117#ifdef DEBUGGING
118 cout << "Cleaning up" << endl;
119#endif
120
b1d92c2f
PG
121 cfg::clean();
122
68b2316d 123 input::clean();
617dcc71 124
68b2316d 125 game::clean();
44b079f8 126
68b2316d 127 graphics::clean();
44b079f8
PG
128}
129
617dcc71
PG
130/// ***** Private Methods *****
131
25d84412
PG
132float total = 0;
133
ad9f1fb6
PG
134void run()
135{
136 is_Running = true;
137 last_Block_Update = tickCountMicro();
138 last_Second = tickCountMicro();
139
140 while(is_Running)
141 {
d279b77b
PG
142 long int time;
143
144 time = tickCountMicro();
145 blockUpdate();
146 updateFPSCounters();
147 draw();
148 time = tickCountMicro() - time;
149
150 rRun = (rRun * (num-1) + time) / num;
151
25d84412
PG
152 //cout << "total:\t" << total << endl;
153 //cout << "rR:\t" << rRun << endl;
154 //total = 0;
ad9f1fb6
PG
155 }
156}
157
ad9f1fb6
PG
158void blockUpdate()
159{
160 long int start = tickCountMicro();
161
25d84412 162 //cout << "Block" << endl;
d279b77b 163
ad9f1fb6
PG
164 // Calculate the updates that should be run for the next draw
165 update_Sum += (start - last_Block_Update) / (1000000 / (float)target_UPS);
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 possible
174 // used because really quick updates are nearly wasted
25d84412 175 float time_step = ((float)(start - last_Block_Update)) / iupdate_sum / 1000;
ad9f1fb6
PG
176
177 // run the updates
178 for (int i = 1; i <= iupdate_sum; i++)
179 {
68b2316d 180 handleInput();
25d84412 181 update(time_step);
ad9f1fb6
PG
182 }
183 // remove the updates that where run from the sum
184 update_Sum -= iupdate_sum;
185 last_Block_Update = tickCountMicro();
186 }
187}
188
189void updateFPSCounters()
190{
191 // Check if a second has passed to recalculate UPS and FPS
192 if (tickCountMicro() - last_Second >= 1000000)
193 {
194 ups = update_Count;
195 fps = draw_Count;
25d84412 196 times = time_steps_Count;
ad9f1fb6
PG
197 update_Count = 0;
198 draw_Count = 0;
25d84412 199 time_steps_Count = 0;
ad9f1fb6
PG
200
201 last_Second = tickCountMicro();
44b079f8 202
7adc59fe
PG
203#ifdef FPSUPS
204 cout << "ups:\t" << ups << endl;
205 cout << "fps:\t" << fps << endl;
25d84412 206 cout << "times:\t" << times << endl;
7adc59fe 207#endif
ad9f1fb6
PG
208 }
209}
210
68b2316d 211void handleInput()
ad9f1fb6 212{
25d84412
PG
213 long int time;
214
215 time = tickCountMicro();
216 input::update();
f7b3b2eb 217
25d84412 218 game::handleInput();
ad9f1fb6 219
25d84412
PG
220 if(cfg::endGame())
221 is_Running = false;
222 time = tickCountMicro() - time;
223
224 rInput = (rInput*(num-1) + time) /num;
225
226 total += rInput;
ad9f1fb6
PG
227}
228
229void update(float time_step)
230{
d279b77b
PG
231 long int time;
232
ad9f1fb6 233 update_Count++;
25d84412 234 time_steps_Count += time_step;
ad9f1fb6 235
d279b77b
PG
236 time = tickCountMicro();
237 game::update(time_step);
238 time = tickCountMicro() - time;
239
240 rUpdate = (rUpdate * (num-1) + time) / num;
241
25d84412
PG
242 //cout << "ts:\t" << time_step << endl;
243 //cout << "ru:\t" << rUpdate << endl;
244
245 total += rUpdate;
ad9f1fb6
PG
246}
247
248void draw()
249{
d279b77b
PG
250 long int time;
251
ad9f1fb6
PG
252 draw_Count++;
253
d279b77b
PG
254 time = tickCountMicro();
255 game::draw();
256
257 SDL_GL_SwapBuffers();
258
259 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
260
25d84412 261// SDL_Delay(20);
d279b77b 262 time = tickCountMicro() - time;
ad9f1fb6 263
d279b77b 264 rDraw = (rDraw*(num-1) + time) /num;
ad9f1fb6 265
25d84412
PG
266 //cout << "rd:\t" << rDraw << endl;
267
268 total += rDraw;
ad9f1fb6 269}