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