Creation of physics project
[physics.git] / src / main.cpp
1 #include <GL/gl.h>
2 #include <GL/glu.h>
3 #include <SDL/SDL.h>
4
5 #include <iostream>
6 using std::cerr;
7 using std::cout;
8 using std::endl;
9
10 #include <vector>
11 using std::vector;
12
13 #include "game.h"
14 #include "ticks.h"
15 #include "graphics.h"
16
17
18 /// ***** Private Method Headers *****
19 void init();
20
21 void run();
22 void cleanUp();
23
24 void blockUpdate();
25 void updateFPSCounters();
26
27 void input();
28 void update(float);
29 void draw();
30
31
32 /// ***** MAIN Method *****
33 int main()
34 {
35     init();
36     run();
37     cleanUp();
38     return 0;
39 }
40
41
42 /// ***** Private Variables *****
43
44 // variable used to determine if it is time to shutdown
45 bool is_Running;
46
47 /* Values for the main game loop
48  * target_UPS := the amount of updates that is wanted in one second
49  * last_Update := stores the time of the last update
50  * update_Sum := used to determine the updates needs for this run
51
52  * ups := updates per second for the last second
53  * fps := frames per second for the last second
54  * update_Count := counts this seconds updates
55  * draw_Count  := counts this seconds draws
56  * last_Second := stores the time of the last second, used for ups and fps
57  */
58 int target_UPS = 250;
59 long int last_Block_Update;
60 float update_Sum = 0;
61
62 int ups, fps;
63 int update_Count, draw_Count;
64 long int last_Second;
65
66
67 /// ***** Private Methods *****
68 void init()
69 {
70     graphicsInit();
71
72     gameInit();
73
74     // TODO
75     // add a game state
76
77     cout << "Initialization Complete" << endl;
78
79     // create starting entities
80
81     cout << "World Created" << endl;
82 }
83
84 void run()
85 {
86     is_Running = true;
87     last_Block_Update = tickCountMicro();
88     last_Second = tickCountMicro();
89
90     while(is_Running)
91     {
92         blockUpdate();
93         updateFPSCounters();
94         draw();
95     }
96 }
97
98 void cleanUp()
99 {
100     gameClean();
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 }
145
146 void input()
147 {
148     gameInput();
149
150     /*
151     if(key[KEY_ESC])
152         is_Running = false;
153     */
154 }
155
156 void update(float time_step)
157 {
158     update_Count++;
159
160     gameUpdate(time_step);
161 }
162
163 void draw()
164 {
165     draw_Count++;
166
167     gameDraw();
168
169     SDL_GL_SwapBuffers();
170
171     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
172 }