1 /*
2  * GameLoop.cpp
3  * Copyright (C) 2007 by Bryan Duff <duff0097@gmail.com>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
18  * USA
19  */
20 
21 #include "SDL_funcs.h"
22 #include "Game.h"
23 
24 extern unsigned int gSourceID[100];
25 extern unsigned int gSampleSet[100];
26 
27 extern Camera camera;
28 extern Fog fog;
29 extern Config config;
30 extern Environment environment;
31 
32 extern double multiplier;
33 extern int slomo;
34 
35 enum game_state prev_state = INIT;
36 
HandleKeyDown(char theChar)37 void Game::HandleKeyDown(char theChar)
38 {
39   XYZ facing;
40   bool debug = config.debug;
41 
42   if(state == GAME) {
43 
44     switch (theChar) {
45 
46       case 'l':
47         if(!lasersight == 1) {
48           lasersight = 1;
49         } else {
50           lasersight = 0;
51         }
52 
53         break;
54 
55       case 'k':
56         if(debug)
57           timeremaining = 0;
58 
59         break;
60 
61       case 'b':
62 
63         if(debug) {
64 
65           alSourcePlay(gSourceID[soulinsound]);
66 
67           if(!slomo)
68             slomo = 1;
69           else
70             slomo = 0;
71         }
72 
73         if(slomo) {
74           alSourcef(gSourceID[knifesong], AL_PITCH, (ALfloat) (.5));
75           alSourcef(gSourceID[shootsong], AL_PITCH, (ALfloat) (.5));
76           alSourcef(gSourceID[zombiesong], AL_PITCH, (ALfloat) (.5));
77         } else {
78           alSourcef(gSourceID[knifesong], AL_PITCH, (ALfloat) (1));
79           alSourcef(gSourceID[shootsong], AL_PITCH, (ALfloat) (1));
80           alSourcef(gSourceID[zombiesong], AL_PITCH, (ALfloat) (1));
81         }
82 
83         break;
84 
85       case 'B':
86 
87         if(debug) {
88           alSourcePlay(gSourceID[soulinsound]);
89           paused = 1 - paused;
90         }
91 
92         break;
93 
94       case 'f':
95 
96         if(debug) {
97           alSourcePlay(gSourceID[souloutsound]);
98 
99           //Facing
100           facing = 0;
101           facing.z = -1;
102           facing = DoRotation(facing, -camera.rotation2, 0, 0);
103           facing = DoRotation(facing, 0, 0 - camera.rotation, 0);
104 
105           for(int i = 1; i < numpeople; i++) {
106 
107             if(person[i].skeleton.free != 1) {
108 
109               if(findDistancefast
110                  (person[i].playercoords, person[0].playercoords) < 1000) {
111 
112                 person[i].skeleton.free = 1;
113                 person[i].longdead = 1;
114 
115                 for(int j = 0; j < person[i].skeleton.num_joints; j++) {
116 
117                   person[i].skeleton.joints[j].position =
118                       DoRotation(person[i].skeleton.joints[j].position, 0,
119                                  person[i].playerrotation, 0);
120 
121                   person[i].skeleton.joints[j].position +=
122                       person[i].playercoords;
123 
124                   person[i].skeleton.joints[j].realoldposition =
125                       person[i].skeleton.joints[j].position;
126 
127                   person[i].skeleton.joints[j].velocity =
128                       DoRotation(person[i].skeleton.joints[j].velocity, 0,
129                                  person[i].playerrotation, 0);
130 
131                   person[i].skeleton.joints[j].velocity += person[i].velocity;
132 
133                   person[i].skeleton.joints[j].velocity += facing * 50;
134 
135                   person[i].skeleton.joints[j].velocity.x +=
136                       abs(Random() % 20) - 10;
137 
138                   person[i].skeleton.joints[j].velocity.y +=
139                       abs(Random() % 20) - 10;
140 
141                   person[i].skeleton.joints[j].velocity.z +=
142                       abs(Random() % 20) - 10;
143 
144                 }
145               }
146             }
147           }
148         }
149 
150         break;
151 
152       case 'X':
153 
154         if(debug) {
155 
156           if(person[0].grenphase == 0) {
157             person[0].weapon.ammo = -1;
158             person[0].weapon.type++;
159             person[0].grenphase = 0;
160             person[0].reloads[person[0].weapon.type] = 3;
161 
162             if(person[0].weapon.type > 7)
163               person[0].weapon.type = 0;
164           }
165         }
166 
167         break;
168     }
169   }
170 }
171 
EventLoop(void)172 void Game::EventLoop(void)
173 {
174   unsigned char theKeyMap[16];
175 
176   ///Frame limiting
177   maxfps = 90;
178   int interval = 1000/maxfps, sleep;
179   float last_calc = SDL_GetTicks();
180 
181   float sps = 90.0; //needed?
182   float sps_interval = 1000/sps;
183   float last_tick = SDL_GetTicks();
184   float diff_tick = 0;
185   int cur_tick;
186 
187   GLfloat oldmult;
188   gQuit = false;
189   int step = 1, framecount = 0, spscount = 0;
190 
191   init_sdlkeymap();
192 
193   while(!gQuit) {
194     start = SDL_GetTicks();
195 
196     ProcessSDLEvents();
197     //Tick() changes the value of "multiplier"
198     oldmult = multiplier;
199 
200     /** This regulates ticks (separate from FPS)
201      * Should be about 90 per second.
202      */
203     cur_tick = SDL_GetTicks();
204     diff_tick += (float)(cur_tick - last_tick);
205     while(diff_tick >= sps_interval) {
206       Tick();
207       diff_tick -= sps_interval;
208       spscount++;
209     }
210     last_tick = cur_tick;
211 
212     multiplier = oldmult;
213 
214     if(DrawGLScene()) {
215       SDL_GL_SwapBuffers();
216     } else {
217       printf("Eventloop(): couldn't draw scene, exiting...");
218       gQuit = true;
219     }
220 
221     oldmult = multiplier;
222 
223     GetKeys((unsigned long *)theKeyMap);
224 
225     if(IsKeyDown(theKeyMap, MAC_COMMAND_KEY) && IsKeyDown(theKeyMap, MAC_Q_KEY)) {
226       gQuit = true;
227 
228       config.WriteHighScore(score);
229     }
230 
231     if(IsKeyDown(theKeyMap, MAC_ESCAPE_KEY)) {
232       alSourcePause(gSourceID[rainsound]);
233 
234       state = MAINMENU;
235 
236       alSourcePlay(gSourceID[souloutsound]);
237 
238       flashamount = 1;
239 
240       flashr = 1;
241       flashg = 1;
242       flashb = 1;
243 
244       alSourceStop(gSourceID[visionsound]);
245 
246       whichsong = mainmenusong;
247 
248       alSourceStop(gSourceID[knifesong]);
249       alSourceStop(gSourceID[shootsong]);
250       alSourceStop(gSourceID[zombiesong]);
251       alSourceStop(gSourceID[mainmenusong]);
252 
253       alSourcef(gSourceID[knifesong], AL_MIN_GAIN, 0);
254       alSourcef(gSourceID[shootsong], AL_MIN_GAIN, 0);
255       alSourcef(gSourceID[zombiesong], AL_MIN_GAIN, 0);
256       alSourcef(gSourceID[mainmenusong], AL_MIN_GAIN, 0);
257 
258       alSourcePlay(gSourceID[whichsong]);
259 
260       alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 1);
261     }
262 
263     if(IsKeyDown(theKeyMap, MAC_F1_KEY)) { //Help screen
264       if(state != HELP) {
265         prev_state = state;
266         state = HELP;
267 
268         alSourcePause(gSourceID[rainsound]);
269 
270         alSourcePlay(gSourceID[souloutsound]);
271 
272         alSourceStop(gSourceID[visionsound]);
273 
274         whichsong = mainmenusong;
275 
276         alSourceStop(gSourceID[knifesong]);
277         alSourceStop(gSourceID[shootsong]);
278         alSourceStop(gSourceID[zombiesong]);
279         alSourceStop(gSourceID[mainmenusong]);
280 
281         alSourcef(gSourceID[knifesong], AL_MIN_GAIN, 0);
282         alSourcef(gSourceID[shootsong], AL_MIN_GAIN, 0);
283         alSourcef(gSourceID[zombiesong], AL_MIN_GAIN, 0);
284         alSourcef(gSourceID[mainmenusong], AL_MIN_GAIN, 0);
285 
286         alSourcePlay(gSourceID[whichsong]);
287 
288         alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 1);
289 
290       } else { //Back to game or mainmenu
291         state = prev_state;
292 
293         if(state == GAME) {
294           MoveMouse(oldmouseloc.h, oldmouseloc.v, &mouseloc);
295 
296           if(environment.type == rainy_environment)
297             alSourcePlay(gSourceID[rainsound]);
298 
299           if(environment.type != rainy_environment)
300             alSourcePause(gSourceID[rainsound]);
301 
302           alSourceStop(gSourceID[whichsong]);
303 
304           alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 0);
305           alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 0);
306 
307           if(person[0].weapon.type == knife)
308             whichsong = knifesong;
309           else
310             whichsong = shootsong;
311 
312           if(type == zombie_type)
313             whichsong = zombiesong;
314 
315           alSourcePlay(gSourceID[whichsong]);
316 
317           alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 1);
318           alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 1);
319 
320           alSourcePlay(gSourceID[soulinsound]);
321 
322           if(config.visions)
323             alSourcePlay(gSourceID[visionsound]);
324         }
325       }
326       //FIXME: this probably isn't the best way to do this...
327       SDL_Delay(200); //fix key press issue
328     }
329 
330     if(IsKeyDown(theKeyMap, MAC_F12_KEY)) {
331       char file[20];
332       sprintf(file, "screenshot%d.tga", shotcount); //TODO: timestamp
333       printf("Saving screenshot: %s\n", file);
334       shotcount++;
335       SaveScreenshot(file);
336       SDL_Delay(100); //FIXME: hack - so only one shot per key press
337     }
338 
339     framecount++;
340 
341     end = SDL_GetTicks();
342     sleep = (int)(interval - (end - start)) + step;
343     if (sleep > 0) {
344       SDL_Delay(sleep);
345     }
346 
347     if(end > last_calc + 1000) {
348       if(framecount < maxfps) {
349         step--;
350       } else {
351         step++;
352       }
353 
354       framespersecond = framecount;
355       std::cout << "fps: " << framespersecond << std::endl;
356       framecount = 0;
357       //std::cout << "sps: " << spscount << std::endl;
358       spscount = 0;
359       last_calc = end;
360     }
361 
362     multiplier = 0.0110f; //bizarely correct
363 
364     if(multiplier > 1)
365       multiplier = 1;
366 
367     if(multiplier < .00001)
368       multiplier = .00001;
369 
370     if(config.visions == 1 && state == GAME)
371       multiplier /= 3;
372 
373     if(slomo)
374       multiplier *= .2;
375 
376     if(paused)
377       multiplier = 0;
378   }
379 }
380