1 /*
2  * Viewer.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 "Constants.h"
22 #include "Viewer.h"
23 
24 Animation animation[30];
25 Model skeletonmodels[10];
26 Model gunmodels[11];
27 Costume costume[10];
28 Person person; //just the one model to view
29 Sprites sprites;
30 Decals decals;
31 Camera camera;
32 //Skeleton testskeleton;
33 Config config;
34 Environment environment;
35 
36 Fog fog;
37 
38 //#define setupSkel(skel, model)
39 
setup()40 Viewer::setup()
41 {
42   if(!initialized) {
43 
44     //Foggy env settings
45     environment.viewdistance = 500;
46     environment.fogcolor.setColor(0.5, 0.5, 0.5);
47 
48     if(!azertykeyboard) {
49       forwardskey = MAC_W_KEY;
50       backwardskey = MAC_S_KEY;
51       leftkey = MAC_A_KEY;
52       rightkey = MAC_D_KEY;
53       aimkey = MAC_Q_KEY;
54       psychicaimkey = MAC_E_KEY;
55       psychickey = MAC_Z_KEY;
56       helpkey = MAC_F1_KEY;
57     } else if(azertykeyboard) {
58       forwardskey = MAC_Z_KEY;
59       backwardskey = MAC_S_KEY;
60       leftkey = MAC_Q_KEY;
61       rightkey = MAC_D_KEY;
62       aimkey = MAC_A_KEY;
63       psychicaimkey = MAC_E_KEY;
64       psychickey = MAC_W_KEY;
65       helpkey = MAC_F1_KEY;
66     }
67 
68     //Setup camera
69     camera.position = 0;
70     camera.position.x = num_blocks / 2 * block_spacing + block_spacing / 2;
71     camera.position.z = num_blocks / 2 * block_spacing + block_spacing / 2;
72     camera.position.y = 30;
73     camera.oldposition = camera.position;
74 
75     street.load((unsigned char *)":Data:Models:streetsubdivided2.solid");
76     street.Rotate(90, 0, 0);
77     street.Scale(.01, .01, .01);
78     street.CalculateNormals();
79 
80     Bigstreet = street;
81     Bigstreet.Scale(10000, 10000, 10000);
82 
83     //Load player model
84     skeletonmodels[0].load((unsigned char *)":Data:Models:Head.solid");
85     skeletonmodels[0].Rotate(90, 0, 0);
86     skeletonmodels[0].Scale(.02, .02, .02);
87     skeletonmodels[0].CalculateNormals();
88 
89     skeletonmodels[1].load((unsigned char *)":Data:Models:Chest.solid");
90     skeletonmodels[1].Rotate(90, 0, 0);
91     skeletonmodels[1].Scale(.02, .02, .02);
92     skeletonmodels[1].CalculateNormals();
93 
94     skeletonmodels[2].load((unsigned char *)":Data:Models:Abdomen.solid");
95     skeletonmodels[2].Rotate(90, 0, 0);
96     skeletonmodels[2].Scale(.02, .02, .02);
97     skeletonmodels[2].CalculateNormals();
98 
99     skeletonmodels[3].load((unsigned char *)":Data:Models:Upper arm.solid");
100     skeletonmodels[3].Rotate(90, 0, 0);
101     skeletonmodels[3].Scale(.02, .02, .02);
102     skeletonmodels[3].CalculateNormals();
103 
104     skeletonmodels[4].load((unsigned char *)":Data:Models:Lower arm.solid");
105     skeletonmodels[4].Rotate(90, 0, 0);
106     skeletonmodels[4].Scale(.02, .02, .02);
107     skeletonmodels[4].CalculateNormals();
108 
109     skeletonmodels[5].load((unsigned char *)":Data:Models:Hand.solid");
110     skeletonmodels[5].Rotate(90, 0, 0);
111     skeletonmodels[5].Scale(.02, .02, .02);
112     skeletonmodels[5].CalculateNormals();
113 
114     skeletonmodels[6].load((unsigned char *)":Data:Models:Upper leg.solid");
115     skeletonmodels[6].Rotate(90, 0, 0);
116     skeletonmodels[6].Scale(.02, .02, .02);
117     skeletonmodels[6].CalculateNormals();
118 
119     skeletonmodels[7].load((unsigned char *)":Data:Models:Lower leg.solid");
120     skeletonmodels[7].Rotate(90, 0, 0);
121     skeletonmodels[7].Scale(.02, .02, .02);
122     skeletonmodels[7].CalculateNormals();
123 
124     skeletonmodels[8].load((unsigned char *)":Data:Models:Foot.solid");
125     skeletonmodels[8].Rotate(90, 0, 0);
126     skeletonmodels[8].Scale(.02, .02, .02);
127     skeletonmodels[8].CalculateNormals();
128 
129     skeletonmodels[9].load((unsigned char *)":Data:Models:Shades.solid");
130     skeletonmodels[9].Rotate(90, 0, 0);
131     skeletonmodels[9].Scale(.02, .02, .02);
132     skeletonmodels[9].CalculateNormals();
133 
134     //Load gun models
135     gunmodels[sniperriflemodel].
136         load((unsigned char *)":Data:Models:sniperrifle.solid");
137     gunmodels[sniperriflemodel].Rotate(0, 0, 90);
138     gunmodels[sniperriflemodel].Scale(.001, .001, .001);
139     gunmodels[sniperriflemodel].CalculateNormals();
140 
141     gunmodels[assaultriflemodel].
142         load((unsigned char *)":Data:Models:assaultrifle.solid");
143     gunmodels[assaultriflemodel].Rotate(0, 0, 90);
144     gunmodels[assaultriflemodel].Scale(.01, .01, .01);
145     gunmodels[assaultriflemodel].CalculateNormals();
146 
147     gunmodels[handgunbasemodel].
148         load((unsigned char *)":Data:Models:Handgunbase.solid");
149     gunmodels[handgunbasemodel].Rotate(0, 0, 90);
150     gunmodels[handgunbasemodel].Rotate(180, 0, 0);
151     gunmodels[handgunbasemodel].Scale(.014, .014, .014);
152     gunmodels[handgunbasemodel].CalculateNormals();
153     gunmodels[handgunbasemodel].MultColor(.6);
154 
155     gunmodels[handgunslidemodel].
156         load((unsigned char *)":Data:Models:Handgunslide.solid");
157     gunmodels[handgunslidemodel].Rotate(0, 0, 90);
158     gunmodels[handgunslidemodel].Rotate(180, 0, 0);
159     gunmodels[handgunslidemodel].Scale(.014, .014, .014);
160     gunmodels[handgunslidemodel].CalculateNormals();
161     gunmodels[handgunslidemodel].MultColor(.6);
162 
163     gunmodels[handgun2basemodel].
164         load((unsigned char *)":Data:Models:glockbase.solid");
165     gunmodels[handgun2basemodel].Rotate(0, 0, 90);
166     gunmodels[handgun2basemodel].Rotate(180, 0, 0);
167     gunmodels[handgun2basemodel].Scale(.014, .014, .014);
168     gunmodels[handgun2basemodel].CalculateNormals();
169     gunmodels[handgun2basemodel].MultColor(.6);
170 
171     gunmodels[handgun2slidemodel].
172         load((unsigned char *)":Data:Models:glockslide.solid");
173     gunmodels[handgun2slidemodel].Rotate(0, 0, 90);
174     gunmodels[handgun2slidemodel].Rotate(180, 0, 0);
175     gunmodels[handgun2slidemodel].Scale(.014, .014, .014);
176     gunmodels[handgun2slidemodel].CalculateNormals();
177     gunmodels[handgun2slidemodel].MultColor(.6);
178 
179     gunmodels[grenadebasemodel].
180         load((unsigned char *)":Data:Models:grenadebase.solid");
181     gunmodels[grenadebasemodel].Rotate(0, 0, 90);
182     gunmodels[grenadebasemodel].Rotate(180, 0, 0);
183     gunmodels[grenadebasemodel].Scale(.014, .014, .014);
184     gunmodels[grenadebasemodel].CalculateNormals();
185 
186     gunmodels[grenadepinmodel].
187         load((unsigned char *)":Data:Models:grenadepin.solid");
188     gunmodels[grenadepinmodel].Rotate(0, 0, 90);
189     gunmodels[grenadepinmodel].Rotate(180, 0, 0);
190     gunmodels[grenadepinmodel].Scale(.014, .014, .014);
191     gunmodels[grenadepinmodel].CalculateNormals();
192 
193     gunmodels[grenadespoonmodel].
194         load((unsigned char *)":Data:Models:grenadespoon.solid");
195     gunmodels[grenadespoonmodel].Rotate(0, 0, 90);
196     gunmodels[grenadespoonmodel].Rotate(180, 0, 0);
197     gunmodels[grenadespoonmodel].Scale(.014, .014, .014);
198     gunmodels[grenadespoonmodel].CalculateNormals();
199 
200     gunmodels[knifemodel].load((unsigned char *)":Data:Models:Knife.solid");
201     gunmodels[knifemodel].Rotate(0, 0, 90);
202     gunmodels[knifemodel].Rotate(180, 0, 0);
203     gunmodels[knifemodel].Scale(.014, .014, .014);
204     gunmodels[knifemodel].CalculateNormals();
205 
206     gunmodels[shotgunmodel].load((unsigned char *)":Data:Models:shotgun.solid");
207     gunmodels[shotgunmodel].Rotate(0, 0, 90);
208     gunmodels[shotgunmodel].Scale(.001, .001, .001);
209     gunmodels[shotgunmodel].CalculateNormals();
210     gunmodels[shotgunmodel].MultColor(.6);
211 
212     testskeleton.Load((char *)":Data:Skeleton:Basic Figure");
213     animation[idleanim].Load((char *)":Data:Animations:Breathe");
214     animation[joganim].Load((char *)":Data:Animations:Run");
215     animation[pistolaimanim].Load((char *)":Data:Animations:PistolAim");
216 
217     animation[walkanim].Load((char *)":Data:Animations:Walk");
218     animation[rifleholdanim].Load((char *)":Data:Animations:Riflehold");
219     animation[rifleaimanim].Load((char *)":Data:Animations:Rifleaim");
220     animation[assaultrifleaimanim].
221         Load((char *)":Data:Animations:AssaultRifleaim");
222 
223     animation[crouchanim].Load((char *)":Data:Animations:Crouch");
224 
225     animation[headpainanim].Load((char *)":Data:Animations:Headshot");
226     animation[chestpainanim].Load((char *)":Data:Animations:Chestshot");
227     animation[stomachpainanim].Load((char *)":Data:Animations:Stomachshot");
228     animation[rightarmpainanim].Load((char *)":Data:Animations:Rightarmshot");
229     animation[leftarmpainanim].Load((char *)":Data:Animations:Leftarmshot");
230 
231     animation[rightlegpainanim].Load((char *)":Data:Animations:Rightlegshot");
232     animation[leftlegpainanim].Load((char *)":Data:Animations:Leftlegshot");
233     animation[riflehitanim].Load((char *)":Data:Animations:Riflehit");
234     animation[grenadeaimanim].Load((char *)":Data:Animations:grenadeaim");
235     animation[grenadechargeanim].Load((char *)":Data:Animations:grenadecharge");
236 
237     animation[grenadethrowanim].Load((char *)":Data:Animations:grenadethrow");
238     animation[zombieeatanim].Load((char *)":Data:Animations:Zombiemunch");
239     animation[zombiejoganim].Load((char *)":Data:Animations:ZombieRun");
240     animation[zombiewalkanim].Load((char *)":Data:Animations:Zombiewalk");
241 
242     animation[getupfrontanim].Load((char *)":Data:Animations:Getupfromfront");
243     animation[getupbackanim].Load((char *)":Data:Animations:Getupfromback",
244                                   180);
245     animation[diveanim].Load((char *)":Data:Animations:Dive");
246     animation[throwanim].Load((char *)":Data:Animations:Aikidothrow");
247     animation[thrownanim].Load((char *)":Data:Animations:Aikidothrown");
248 
249     person.skeleton.Load((char *)":Data:Skeleton:Basic Figure");
250   }
251 }
252 
Tick()253 void Viewer::Tick()
254 {
255     //Mouse look
256     //if((person[0].aimamount <= 0)) {
257       camera.rotation = camera.visrotation;
258       camera.rotation2 = camera.visrotation2;
259 
260       mousesensitivity = config.usermousesensitivity;
261     //}
262 
263     GetMouseRel(&mouseloc);
264 
265     mouserotation = (mouseloc.h / 1.3888) * mousesensitivity;
266     mouserotation2 = (mouseloc.v / 1.3888) * mousesensitivity;
267 
268 }
269 
DrawGLScene()270 void Viewer::DrawGLScene()
271 {
272   glLoadIdentity();
273 
274   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
275 
276   glEnable(GL_DEPTH_TEST);
277 
278   glDisable(GL_CLIP_PLANE0);
279 
280   //Visions
281   sinefluct = sin(sinefluctprog);
282   sinefluctprog += multiplier * 3;
283 
284   int visions = config.visions;
285   viewdistance = environment.viewdistance;
286 
287     fog.fogcolor.setColor(environment.fogcolor);
288     fog.SetFog(environment.fogcolor, 0, viewdistance * .8, .2);
289 
290     glClearColor(fog.fogcolor.r, fog.fogcolor.g, fog.fogcolor.b, 1);
291 
292     if(environment.type == sunny_environment) {
293 
294       GLfloat LightAmbient[] =
295           { fog.fogcolor.r / 4, fog.fogcolor.g / 4, fog.fogcolor.b / 4, 1.0f };
296       GLfloat LightDiffuse[] =
297           { fog.fogcolor.r * 1.6, fog.fogcolor.g * 1.6, fog.fogcolor.r * 1.6,
298 1.0f };
299 
300       glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmbient);
301       glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDiffuse);
302     } else {
303 
304       GLfloat LightAmbient[] =
305           { fog.fogcolor.r * .8, fog.fogcolor.g * .8, fog.fogcolor.b * .8,
306 1.0f };
307       GLfloat LightDiffuse[] =
308           { fog.fogcolor.r * .8, fog.fogcolor.g * .8, fog.fogcolor.r * .8,
309 1.0f };
310 
311       glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmbient);
312       glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDiffuse);
313     }
314 
315     glEnable(GL_LIGHT0);
316 
317     //Don't think this needs to be done every time
318     ReSizeGLScene(90, .1, viewdistance);
319 
320     config.nocolors = 0;
321 
322   //Camera
323   camera.Apply();
324 
325   glPushMatrix();
326   glClipPlane(GL_CLIP_PLANE0, eqn);
327   glDisable(GL_CLIP_PLANE0);
328   glPopMatrix();
329 
330   frustum.GetFrustum();
331 
332   GLfloat LightPosition[] = { -.5, 1, -.8, 0.0f };
333 
334   glLightfv(GL_LIGHT0, GL_POSITION, LightPosition);
335 
336   glDisable(GL_TEXTURE_2D);
337 
338   glEnable(GL_FOG);
339   glEnable(GL_COLOR_MATERIAL);
340   glEnable(GL_CULL_FACE);
341 
342   glDepthMask(1);
343 
344   //Draw street
345   glPushMatrix();
346 
347   glDepthMask(0);
348 
349   glDisable(GL_DEPTH_TEST);
350 
351   glEnable(GL_LIGHTING);
352 
353   glTranslatef(camera.position.x, 0, camera.position.z);
354 
355   glScalef(viewdistance * 0.05, 1, viewdistance * 0.05);
356 
357   if(visions == 0)
358     street.draw(.22, .22, .22);
359 
360   if(visions == 1)
361     street.draw(0, 0, 0);
362 
363   glEnable(GL_DEPTH_TEST);
364 
365   glDepthMask(1);
366 
367   glPopMatrix();
368 
369   ///Draw person
370   glPushMatrix();
371 
372   glTranslatef(person.playercoords.x,
373                person.playercoords.y, person.playercoords.z);
374 
375   glRotatef(person.playerrotation, 0, 1, 0);
376 
377   person.DoAnimations(1);
378 
379   person.DrawSkeleton(1);
380 
381   glPopMatrix();
382 }
383 
EventLoop()384 void Viewer::EventLoop()
385 {
386   unsigned char theKeyMap[16];
387 
388   ///Frame limiting
389   maxfps = 90;
390   int interval = 1000/maxfps, sleep;
391   float last_calc = SDL_GetTicks();
392 
393   float sps = 90; //needed?
394   float sps_interval = 1000/sps;
395   float last_tick = SDL_GetTicks();
396   float diff_tick = 0;
397   int cur_tick;
398 
399   GLfloat oldmult;
400   gQuit = false;
401   int step = 1, framecount = 0, spscount = 0;
402 
403   init_sdlkeymap();
404 
405   while(!gQuit) {
406     start = SDL_GetTicks();
407 
408     ProcessSDLEvents();
409     //Tick() changes the value of "multiplier"
410     oldmult = multiplier;
411 
412     /** This regulates ticks (separate from FPS)
413      * Should be about 80-90 per second.
414      */
415     cur_tick = SDL_GetTicks();
416     diff_tick += (float)(cur_tick - last_tick);
417     while(diff_tick >= sps_interval) {
418       Tick();
419       diff_tick -= sps_interval;
420       spscount++;
421     }
422     last_tick = cur_tick;
423 
424     multiplier = oldmult;
425 
426     if(DrawGLScene())
427       SDL_GL_SwapBuffers();
428     else
429       gQuit = true;
430 
431     oldmult = multiplier;
432 
433     GetKeys((unsigned long *)theKeyMap);
434 
435     if(IsKeyDown(theKeyMap, MAC_Q_KEY) || IsKeyDown(theKeyMap, MAC_ESCAPE_KEY)) {
436       gQuit = true;
437     }
438 
439     framecount++;
440 
441     end = SDL_GetTicks();
442     sleep = (int)(interval - (end - start)) + step;
443     if (sleep > 0) {
444       SDL_Delay(sleep);
445     }
446 
447     if(end > last_calc + 1000) {
448       if(framecount < maxfps) {
449         step--;
450       } else {
451         step++;
452       }
453 
454       framespersecond = framecount;
455       std::cout << "fps: " << framespersecond << std::endl;
456       framecount = 0;
457       std::cout << "sps: " << spscount << std::endl;
458       spscount = 0;
459       last_calc = end;
460     }
461 
462     multiplier = 0.0110f; //bizarely correct
463 
464     if(multiplier > 1)
465       multiplier = 1;
466 
467     if(multiplier < .00001)
468       multiplier = .00001;
469 
470     if(paused)
471       multiplier = 0;
472   }
473 }
474 
getInstance()475 Viewer &Viewer::getInstance()
476 {
477   MutexLocker obtain_lock(m);
478   if(instance.get() == 0)
479     instance.reset(new Viewer);
480   return *instance;
481 }
482 
483 std::auto_ptr <Viewer> Viewer::instance;
484 Mutex Viewer::m;
485 
486