98565a6afa682eacb4cdd551e6782e3b052e43d6
[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 #ifdef DEBUGGING
74     cout << "Initialization Complete" << endl;
75 #endif
76 }
77
78 void cleanUp()
79 {
80 #ifdef DEBUGGING
81     cout << "Cleaning up" << endl;
82 #endif
83
84     gameClean();
85
86     graphicsCleanUp();
87 }
88
89 void run()
90 {
91     is_Running = true;
92     last_Block_Update = tickCountMicro();
93     last_Second = tickCountMicro();
94
95     while(is_Running)
96     {
97         blockUpdate();
98         updateFPSCounters();
99         draw();
100     }
101 }
102
103 void blockUpdate()
104 {
105     long int start = tickCountMicro();
106
107     // Calculate the updates that should be run for the next draw
108     update_Sum += (start - last_Block_Update) / (1000000 / (float)target_UPS);
109
110     // insures the float to int cast is done once.
111     int iupdate_sum = (int)update_Sum;
112
113     // TODO the main run loop needs to be tested and pruned
114     if (iupdate_sum > 0)
115     {
116         // Calculate a time step that spreads the updates out as much as possible
117         // used because really quick updates are nearly wasted
118         float time_step = ((float)(start - last_Block_Update)) / iupdate_sum;
119
120         // run the updates
121         for (int i = 1; i <= iupdate_sum; i++)
122         {
123             input();
124             update(time_step*i / 1000);
125         }
126         // remove the updates that where run from the sum
127         update_Sum -= iupdate_sum;
128         last_Block_Update = tickCountMicro();
129     }
130 }
131
132 void updateFPSCounters()
133 {
134     // Check if a second has passed to recalculate UPS and FPS
135     if (tickCountMicro() - last_Second >= 1000000)
136     {
137         ups = update_Count;
138         fps = draw_Count;
139         update_Count = 0;
140         draw_Count = 0;
141
142         last_Second = tickCountMicro();
143
144         //cout << "ups:\t" << ups << endl;
145         //cout << "fps:\t" << fps << endl;
146     }
147 }
148
149 void input()
150 {
151     inputUpdate();
152
153     gameInput();
154
155     if(wasReleased(SDLK_ESCAPE))
156         is_Running = false;
157 }
158
159 void update(float time_step)
160 {
161     update_Count++;
162
163     gameUpdate(time_step);
164 }
165
166 void draw()
167 {
168     draw_Count++;
169
170     gameDraw();
171
172     SDL_GL_SwapBuffers();
173
174     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
175 }