created input, graphics and game namespaces
[physics.git] / src / main.cpp
1 #include <GL/gl.h>
2 #include <GL/glu.h>
3 #include <SDL/SDL.h>
4
5 #include "debug.h"
6 #include "handleSignal.h"
7
8 #include "game.h"
9 #include "ticks.h"
10
11 #include "graphics/graphics.h"
12 #include "input/inputManager.h"
13
14 /// ***** Private Method Headers *****
15
16 void init();
17
18 void sighandler( int sig );
19
20 void run();
21 void clean();
22
23 void blockUpdate();
24 void updateFPSCounters();
25
26 void handleInput();
27 void update(float);
28 void draw();
29
30 /// ***** Private Variables *****
31
32 // variable used to determine if it is time to shutdown
33 bool is_Running;
34
35 /* Values for the main game loop
36  * target_UPS := the amount of updates that is wanted in one second
37  * last_Update := stores the time of the last update
38  * update_Sum := used to determine the updates needs for this run
39
40  * ups := updates per second for the last second
41  * fps := frames per second for the last second
42  * update_Count := counts this seconds updates
43  * draw_Count  := counts this seconds draws
44  * last_Second := stores the time of the last second, used for ups and fps
45  */
46 int target_UPS = 250;
47 long int last_Block_Update;
48 float update_Sum = 0;
49
50 int ups, fps;
51 int update_Count, draw_Count;
52 long int last_Second;
53
54
55 /// ***** MAIN Method *****
56 int main()
57 {
58     init();
59     run();
60     clean();
61     return 0;
62 }
63
64 /// ***** Initializers/Cleaners *****
65
66 void init()
67 {
68     installSignal();
69
70     graphics::init();
71
72     game::init();
73
74     input::init();
75
76 #ifdef DEBUGGING
77     cout << "Initialization Complete" << endl;
78 #endif
79 }
80
81 void clean()
82 {
83 #ifdef DEBUGGING
84     cout << "Cleaning up" << endl;
85 #endif
86
87     input::clean();
88
89     game::clean();
90
91     graphics::clean();
92 }
93
94 /// ***** Private Methods *****
95
96 void run()
97 {
98     is_Running = true;
99     last_Block_Update = tickCountMicro();
100     last_Second = tickCountMicro();
101
102     while(is_Running)
103     {
104         blockUpdate();
105         updateFPSCounters();
106         draw();
107     }
108 }
109
110 void blockUpdate()
111 {
112     long int start = tickCountMicro();
113
114     // Calculate the updates that should be run for the next draw
115     update_Sum += (start - last_Block_Update) / (1000000 / (float)target_UPS);
116
117     // insures the float to int cast is done once.
118     int iupdate_sum = (int)update_Sum;
119
120     // TODO the main run loop needs to be tested and pruned
121     if (iupdate_sum > 0)
122     {
123         // Calculate a time step that spreads the updates out as much as possible
124         // used because really quick updates are nearly wasted
125         float time_step = ((float)(start - last_Block_Update)) / iupdate_sum;
126
127         // run the updates
128         for (int i = 1; i <= iupdate_sum; i++)
129         {
130             handleInput();
131             update(time_step*i / 1000);
132         }
133         // remove the updates that where run from the sum
134         update_Sum -= iupdate_sum;
135         last_Block_Update = tickCountMicro();
136     }
137 }
138
139 void updateFPSCounters()
140 {
141     // Check if a second has passed to recalculate UPS and FPS
142     if (tickCountMicro() - last_Second >= 1000000)
143     {
144         ups = update_Count;
145         fps = draw_Count;
146         update_Count = 0;
147         draw_Count = 0;
148
149         last_Second = tickCountMicro();
150
151 #ifdef FPSUPS
152         cout << "ups:\t" << ups << endl;
153         cout << "fps:\t" << fps << endl;
154 #endif
155     }
156 }
157
158 void handleInput()
159 {
160     input::update();
161
162     game::input();
163
164     if(input::wasReleased(SDLK_ESCAPE))
165         is_Running = false;
166 }
167
168 void update(float time_step)
169 {
170     update_Count++;
171
172     game::update(time_step);
173 }
174
175 void draw()
176 {
177     draw_Count++;
178
179     game::draw();
180
181     SDL_GL_SwapBuffers();
182
183     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
184 }