setup config to be one file
[physics.git] / src / main.cpp
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
34 void init();
35
36 void sighandler( int sig );
37
38 void run();
39 void clean();
40
41 void blockUpdate();
42 void updateFPSCounters();
43
44 void handleInput();
45 void update(float);
46 void draw();
47
48 /// ***** Private Variables *****
49
50 // variable used to determine if it is time to shutdown
51 bool 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  */
64 int target_UPS = 250;
65 long int last_Block_Update;
66 float update_Sum = 0;
67
68 int ups, fps;
69 int update_Count, draw_Count;
70 long int last_Second;
71
72
73 /// ***** MAIN Method *****
74 int main()
75 {
76     init();
77     run();
78     clean();
79     return 0;
80 }
81
82 /// ***** Initializers/Cleaners *****
83
84 void init()
85 {
86     installSignal();
87
88     graphics::init();
89
90     game::init();
91
92     input::init();
93
94     cfg::init();
95
96 #ifdef DEBUGGING
97     cout << "Initialization Complete" << endl;
98 #endif
99 }
100
101 void clean()
102 {
103 #ifdef DEBUGGING
104     cout << "Cleaning up" << endl;
105 #endif
106
107     cfg::clean();
108
109     input::clean();
110
111     game::clean();
112
113     graphics::clean();
114 }
115
116 /// ***** Private Methods *****
117
118 void run()
119 {
120     is_Running = true;
121     last_Block_Update = tickCountMicro();
122     last_Second = tickCountMicro();
123
124     while(is_Running)
125     {
126         blockUpdate();
127         updateFPSCounters();
128         draw();
129     }
130 }
131
132 void blockUpdate()
133 {
134     long int start = tickCountMicro();
135
136     // Calculate the updates that should be run for the next draw
137     update_Sum += (start - last_Block_Update) / (1000000 / (float)target_UPS);
138
139     // insures the float to int cast is done once.
140     int iupdate_sum = (int)update_Sum;
141
142     // TODO the main run loop needs to be tested and pruned
143     if (iupdate_sum > 0)
144     {
145         // Calculate a time step that spreads the updates out as much as possible
146         // used because really quick updates are nearly wasted
147         float time_step = ((float)(start - last_Block_Update)) / iupdate_sum;
148
149         // run the updates
150         for (int i = 1; i <= iupdate_sum; i++)
151         {
152             handleInput();
153             update(time_step*i / 1000);
154         }
155         // remove the updates that where run from the sum
156         update_Sum -= iupdate_sum;
157         last_Block_Update = tickCountMicro();
158     }
159 }
160
161 void updateFPSCounters()
162 {
163     // Check if a second has passed to recalculate UPS and FPS
164     if (tickCountMicro() - last_Second >= 1000000)
165     {
166         ups = update_Count;
167         fps = draw_Count;
168         update_Count = 0;
169         draw_Count = 0;
170
171         last_Second = tickCountMicro();
172
173 #ifdef FPSUPS
174         cout << "ups:\t" << ups << endl;
175         cout << "fps:\t" << fps << endl;
176 #endif
177     }
178 }
179
180 void handleInput()
181 {
182     input::update();
183
184     game::input();
185
186     if(cfg::endGame())
187         is_Running = false;
188 }
189
190 void update(float time_step)
191 {
192     update_Count++;
193
194     game::update(time_step);
195 }
196
197 void draw()
198 {
199     draw_Count++;
200
201     game::draw();
202
203     SDL_GL_SwapBuffers();
204
205     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
206 }