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