]> git.jsancho.org Git - lugaru.git/blob - Source/GameDraw.cpp
Fix feedback on prev commits from MCMic
[lugaru.git] / Source / GameDraw.cpp
1 /*
2 Copyright (C) 2003, 2010 - Wolfire Games
3 Copyright (C) 2010-2017 - Lugaru contributors (see AUTHORS file)
4
5 This file is part of Lugaru.
6
7 Lugaru is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 Lugaru is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Lugaru.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "Game.hpp"
22
23 #include "Audio/openal_wrapper.hpp"
24 #include "Level/Awards.hpp"
25 #include "Level/Dialog.hpp"
26 #include "Level/Hotspot.hpp"
27 #include "Menu/Menu.hpp"
28 #include "Tutorial.hpp"
29 #include "Utils/Input.hpp"
30
31 extern XYZ viewer;
32 extern int environment;
33 extern float texscale;
34 extern Light light;
35 extern Terrain terrain;
36 extern float multiplier;
37 extern float viewdistance;
38 extern float fadestart;
39 extern float screenwidth, screenheight;
40 extern int kTextureSize;
41 extern FRUSTUM frustum;
42 extern Light light;
43 extern int detail;
44 extern float usermousesensitivity;
45 extern float camerashake;
46 extern int slomo;
47 extern float slomodelay;
48 extern bool ismotionblur;
49 extern float woozy;
50 extern float blackout;
51 extern bool damageeffects;
52 extern float volume;
53 extern bool texttoggle;
54 extern float blurness;
55 extern float targetblurness;
56 extern float playerdist;
57 extern bool cellophane;
58 extern bool freeze;
59 extern float flashamount, flashr, flashg, flashb;
60 extern int flashdelay;
61 extern int netstate;
62 extern float motionbluramount;
63 extern bool isclient;
64 extern bool alwaysblur;
65 extern bool velocityblur;
66 extern bool devtools;
67 extern int mainmenu;
68 extern int bloodtoggle;
69 extern int difficulty;
70 extern bool decalstoggle;
71 extern float texdetail;
72 extern bool musictoggle;
73 extern float smoketex;
74 extern bool againbonus;
75 extern float damagedealt;
76 extern bool invertmouse;
77
78 extern bool campaign;
79 extern bool winfreeze;
80
81 extern bool gamestart;
82
83 extern bool gamestarted;
84
85 extern bool showdamagebar;
86
87 int drawtoggle = 0;
88 int numboundaries = 0;
89 XYZ boundary[360];
90 int change = 0;
91
92 enum drawmodes
93 {
94     normalmode,
95     motionblurmode,
96     radialzoommode,
97     realmotionblurmode,
98     doublevisionmode,
99     glowmode,
100 };
101
102 void Game::flash(float amount, int delay) // shouldn't be that way, these should be attributes and Person class should not change rendering.
103 {
104     flashr = 1;
105     flashg = 0;
106     flashb = 0;
107     flashamount = amount;
108     flashdelay = delay;
109 }
110
111 void DrawMenu();
112
113 /*********************> DrawGLScene() <*****/
114 int Game::DrawGLScene(StereoSide side)
115 {
116     static float texcoordwidth, texcoordheight;
117     static float texviewwidth, texviewheight;
118     static XYZ checkpoint;
119     static float tempmult;
120     float tutorialopac;
121     std::string string;
122     static int drawmode = 0;
123
124     if (stereomode == stereoAnaglyph) {
125         switch (side) {
126             case stereoLeft:
127                 glColorMask(0.0, 1.0, 1.0, 1.0);
128                 break;
129             case stereoRight:
130                 glColorMask(1.0, 0.0, 0.0, 1.0);
131                 break;
132             default:
133                 break;
134         }
135     } else {
136         glColorMask(1.0, 1.0, 1.0, 1.0);
137
138         if (stereomode == stereoHorizontalInterlaced ||
139             stereomode == stereoVerticalInterlaced) {
140             glStencilFunc(side == stereoLeft ? GL_NOTEQUAL : GL_EQUAL, 0x01, 0x01);
141         }
142     }
143
144     if (freeze || winfreeze || (mainmenu && gameon) || (!gameon && gamestarted)) {
145         tempmult = multiplier;
146         multiplier = 0;
147     }
148
149     if (!mainmenu) {
150         if (editorenabled) {
151             numboundaries = mapradius * 2;
152             if (numboundaries > 360) {
153                 numboundaries = 360;
154             }
155             for (int i = 0; i < numboundaries; i++) {
156                 boundary[i] = 0;
157                 boundary[i].z = 1;
158                 boundary[i] = mapcenter + DoRotation(boundary[i] * mapradius, 0, i * (360 / ((float)(numboundaries))), 0);
159             }
160         }
161
162         SetUpLighting();
163
164         static int changed;
165         changed = 0;
166
167         int olddrawmode = drawmode;
168         if (ismotionblur && !loading) {
169             if ((findLengthfast(&Person::players[0]->velocity) > 200) && velocityblur && !cameramode) {
170                 drawmode = motionblurmode;
171                 motionbluramount = 200 / (findLengthfast(&Person::players[0]->velocity));
172                 changed = 1;
173             }
174             if (Person::players[0]->damage - Person::players[0]->superpermanentdamage > (Person::players[0]->damagetolerance - Person::players[0]->superpermanentdamage) * 1 / 2 && damageeffects && !cameramode) {
175                 drawmode = doublevisionmode;
176                 changed = 1;
177             }
178         }
179
180         if (slomo && !loading) {
181             if (ismotionblur) {
182                 drawmode = motionblurmode;
183             }
184             motionbluramount = .2;
185             slomodelay -= multiplier;
186             if (slomodelay < 0) {
187                 slomo = 0;
188             }
189             camerashake = 0;
190             changed = 1;
191         }
192         if ((!changed && !slomo) || loading) {
193             drawmode = normalmode;
194             if (ismotionblur && (/*fps>100||*/ alwaysblur)) {
195                 if (olddrawmode != realmotionblurmode) {
196                     change = 1;
197                 } else {
198                     change = 0;
199                 }
200                 drawmode = realmotionblurmode;
201             } else if (olddrawmode == realmotionblurmode) {
202                 change = 2;
203             } else {
204                 change = 0;
205             }
206         }
207
208         if (freeze || winfreeze || (mainmenu && gameon) || (!gameon && gamestarted)) {
209             drawmode = normalmode;
210         }
211         if ((freeze || winfreeze) && ismotionblur && !mainmenu) {
212             drawmode = radialzoommode;
213         }
214
215         if (winfreeze || mainmenu) {
216             drawmode = normalmode;
217         }
218
219         if (drawtoggle != 2) {
220             drawtoggle = 1 - drawtoggle;
221         }
222
223         if (!texcoordwidth) {
224             texviewwidth = kTextureSize;
225             if (texviewwidth > screenwidth) {
226                 texviewwidth = screenwidth;
227             }
228             texviewheight = kTextureSize;
229             if (texviewheight > screenheight) {
230                 texviewheight = screenheight;
231             }
232
233             texcoordwidth = screenwidth / kTextureSize;
234             texcoordheight = screenheight / kTextureSize;
235             if (texcoordwidth > 1) {
236                 texcoordwidth = 1;
237             }
238             if (texcoordheight > 1) {
239                 texcoordheight = 1;
240             }
241         }
242
243         glDrawBuffer(GL_BACK);
244         glReadBuffer(GL_BACK);
245
246         static XYZ terrainlight;
247         static float distance;
248         if (drawmode == normalmode) {
249             Game::ReSizeGLScene(90, .1f);
250         } else {
251             glViewport(0, 0, texviewwidth, texviewheight);
252         }
253         glDepthFunc(GL_LEQUAL);
254         glDepthMask(1);
255         glAlphaFunc(GL_GREATER, 0.0001f);
256         glEnable(GL_ALPHA_TEST);
257         glClearColor(0.25f, 0.25f, 0.25f, 1.0f);
258         glClear(GL_DEPTH_BUFFER_BIT);
259
260         glMatrixMode(GL_MODELVIEW);
261         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
262         glLoadIdentity();
263
264         // Move the camera for the current eye's point of view.
265         // Reverse the movement if we're reversing stereo
266         glTranslatef((stereoseparation / 2) * side * (stereoreverse ? -1 : 1), 0, 0);
267
268         //camera effects
269         if (!cameramode && !freeze && !winfreeze) {
270             //shake
271             glRotatef(float(Random() % 100) / 10 * camerashake /*+(woozy*woozy)/10*/, 0, 0, 1);
272             //sway
273             glRotatef(pitch + sin(woozy / 2) * (Person::players[0]->damage / Person::players[0]->damagetolerance) * 5, 1, 0, 0);
274             glRotatef(yaw + sin(woozy) * (Person::players[0]->damage / Person::players[0]->damagetolerance) * 5, 0, 1, 0);
275         }
276         if (cameramode || freeze || winfreeze) {
277             glRotatef(pitch, 1, 0, 0);
278             glRotatef(yaw, 0, 1, 0);
279         }
280
281         if (environment == desertenvironment) {
282             glRotatef((float)(abs(Random() % 100)) / 3000 - 1, 1, 0, 0);
283             glRotatef((float)(abs(Random() % 100)) / 3000 - 1, 0, 1, 0);
284         }
285         SetUpLight(&light, 0);
286         glPushMatrix();
287
288         //heat blur effect in desert
289         if (abs(blurness - targetblurness) < multiplier * 10 || abs(blurness - targetblurness) > 2) {
290             blurness = targetblurness;
291             targetblurness = (float)(abs(Random() % 100)) / 40;
292         }
293         if (blurness < targetblurness) {
294             blurness += multiplier * 5;
295         } else {
296             blurness -= multiplier * 5;
297         }
298
299         if (environment == desertenvironment) {
300             if (detail == 2) {
301                 glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, blurness + .4);
302             }
303             glRotatef((float)(abs(Random() % 100)) / 1000, 1, 0, 0);
304             glRotatef((float)(abs(Random() % 100)) / 1000, 0, 1, 0);
305         }
306         skybox->draw();
307         glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, 0);
308         glPopMatrix();
309         glTranslatef(-viewer.x, -viewer.y, -viewer.z);
310         frustum.GetFrustum();
311
312         //make shadow decals on terrain and Object::objects
313         static XYZ point;
314         static float size, opacity, rotation;
315         rotation = 0;
316         for (unsigned int k = 0; k < Person::players.size(); k++) {
317             if (!Person::players[k]->skeleton.free && Person::players[k]->playerdetail && Person::players[k]->howactive < typesleeping) {
318                 if (frustum.SphereInFrustum(Person::players[k]->coords.x, Person::players[k]->coords.y + Person::players[k]->scale * 3, Person::players[k]->coords.z, Person::players[k]->scale * 7) && Person::players[k]->occluded < 25) {
319                     for (unsigned int i = 0; i < Person::players[k]->skeleton.joints.size(); i++) {
320                         if (Person::players[k]->skeleton.joints[i].label == leftknee || Person::players[k]->skeleton.joints[i].label == rightknee || Person::players[k]->skeleton.joints[i].label == groin) {
321                             point = DoRotation(Person::players[k]->skeleton.joints[i].position, 0, Person::players[k]->yaw, 0) * Person::players[k]->scale + Person::players[k]->coords;
322                             size = .4f;
323                             opacity = .4 - Person::players[k]->skeleton.joints[i].position.y * Person::players[k]->scale / 5 - (Person::players[k]->coords.y - terrain.getHeight(Person::players[k]->coords.x, Person::players[k]->coords.z)) / 10;
324                             if (k != 0 && Tutorial::active) {
325                                 opacity = .2 + .2 * sin(smoketex * 6 + i) - Person::players[k]->skeleton.joints[i].position.y * Person::players[k]->scale / 5 - (Person::players[k]->coords.y - terrain.getHeight(Person::players[k]->coords.x, Person::players[k]->coords.z)) / 10;
326                             }
327                             terrain.MakeDecal(shadowdecal, point, size, opacity, rotation);
328                             for (unsigned int l = 0; l < terrain.patchobjects[Person::players[k]->whichpatchx][Person::players[k]->whichpatchz].size(); l++) {
329                                 unsigned int j = terrain.patchobjects[Person::players[k]->whichpatchx][Person::players[k]->whichpatchz][l];
330                                 if (Object::objects[j]->position.y < Person::players[k]->coords.y || Object::objects[j]->type == tunneltype || Object::objects[j]->type == weirdtype) {
331                                     point = DoRotation(DoRotation(Person::players[k]->skeleton.joints[i].position, 0, Person::players[k]->yaw, 0) * Person::players[k]->scale + Person::players[k]->coords - Object::objects[j]->position, 0, -Object::objects[j]->yaw, 0);
332                                     size = .4f;
333                                     opacity = .4f;
334                                     if (k != 0 && Tutorial::active) {
335                                         opacity = .2 + .2 * sin(smoketex * 6 + i);
336                                     }
337                                     Object::objects[j]->model.MakeDecal(shadowdecal, &point, &size, &opacity, &rotation);
338                                 }
339                             }
340                         }
341                     }
342                 }
343             }
344             if ((Person::players[k]->skeleton.free || Person::players[k]->howactive >= typesleeping) && Person::players[k]->playerdetail) {
345                 if (frustum.SphereInFrustum(Person::players[k]->coords.x, Person::players[k]->coords.y, Person::players[k]->coords.z, Person::players[k]->scale * 5) && Person::players[k]->occluded < 25) {
346                     for (unsigned i = 0; i < Person::players[k]->skeleton.joints.size(); i++) {
347                         if (Person::players[k]->skeleton.joints[i].label == leftknee || Person::players[k]->skeleton.joints[i].label == rightknee || Person::players[k]->skeleton.joints[i].label == groin || Person::players[k]->skeleton.joints[i].label == leftelbow || Person::players[k]->skeleton.joints[i].label == rightelbow || Person::players[k]->skeleton.joints[i].label == neck) {
348                             if (Person::players[k]->skeleton.free) {
349                                 point = Person::players[k]->skeleton.joints[i].position * Person::players[k]->scale + Person::players[k]->coords;
350                             } else {
351                                 point = DoRotation(Person::players[k]->skeleton.joints[i].position, 0, Person::players[k]->yaw, 0) * Person::players[k]->scale + Person::players[k]->coords;
352                             }
353                             size = .4f;
354                             opacity = .4 - Person::players[k]->skeleton.joints[i].position.y * Person::players[k]->scale / 5 - (Person::players[k]->coords.y - terrain.getHeight(Person::players[k]->coords.x, Person::players[k]->coords.z)) / 5;
355                             if (k != 0 && Tutorial::active) {
356                                 opacity = .2 + .2 * sin(smoketex * 6 + i) - Person::players[k]->skeleton.joints[i].position.y * Person::players[k]->scale / 5 - (Person::players[k]->coords.y - terrain.getHeight(Person::players[k]->coords.x, Person::players[k]->coords.z)) / 10;
357                             }
358                             terrain.MakeDecal(shadowdecal, point, size, opacity * .7, rotation);
359                             for (unsigned int l = 0; l < terrain.patchobjects[Person::players[k]->whichpatchx][Person::players[k]->whichpatchz].size(); l++) {
360                                 unsigned int j = terrain.patchobjects[Person::players[k]->whichpatchx][Person::players[k]->whichpatchz][l];
361                                 if (Object::objects[j]->position.y < Person::players[k]->coords.y || Object::objects[j]->type == tunneltype || Object::objects[j]->type == weirdtype) {
362                                     if (Person::players[k]->skeleton.free) {
363                                         point = DoRotation(Person::players[k]->skeleton.joints[i].position * Person::players[k]->scale + Person::players[k]->coords - Object::objects[j]->position, 0, -Object::objects[j]->yaw, 0);
364                                     } else {
365                                         point = DoRotation(DoRotation(Person::players[k]->skeleton.joints[i].position, 0, Person::players[k]->yaw, 0) * Person::players[k]->scale + Person::players[k]->coords - Object::objects[j]->position, 0, -Object::objects[j]->yaw, 0);
366                                     }
367                                     size = .4f;
368                                     opacity = .4f;
369                                     if (k != 0 && Tutorial::active) {
370                                         opacity = .2 + .2 * sin(smoketex * 6 + i);
371                                     }
372                                     Object::objects[j]->model.MakeDecal(shadowdecal, &point, &size, &opacity, &rotation);
373                                 }
374                             }
375                         }
376                     }
377                 }
378             }
379
380             if (!Person::players[k]->playerdetail) {
381                 if (frustum.SphereInFrustum(Person::players[k]->coords.x, Person::players[k]->coords.y, Person::players[k]->coords.z, Person::players[k]->scale * 5)) {
382                     point = Person::players[k]->coords;
383                     size = .7;
384                     opacity = .4 - (Person::players[k]->coords.y - terrain.getHeight(Person::players[k]->coords.x, Person::players[k]->coords.z)) / 5;
385                     terrain.MakeDecal(shadowdecal, point, size, opacity * .7, rotation);
386                     for (unsigned int l = 0; l < terrain.patchobjects[Person::players[k]->whichpatchx][Person::players[k]->whichpatchz].size(); l++) {
387                         unsigned int j = terrain.patchobjects[Person::players[k]->whichpatchx][Person::players[k]->whichpatchz][l];
388                         point = DoRotation(Person::players[k]->coords - Object::objects[j]->position, 0, -Object::objects[j]->yaw, 0);
389                         size = .7;
390                         opacity = .4f;
391                         Object::objects[j]->model.MakeDecal(shadowdecal, &point, &size, &opacity, &rotation);
392                     }
393                 }
394             }
395         }
396
397         //Terrain
398         glEnable(GL_TEXTURE_2D);
399         glDepthMask(1);
400         glEnable(GL_DEPTH_TEST);
401         glEnable(GL_CULL_FACE);
402         glDisable(GL_BLEND);
403         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
404         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
405         terraintexture.bind();
406         terrain.draw(0);
407         terraintexture2.bind();
408         terrain.draw(1);
409
410         terrain.drawdecals();
411
412         //Model
413         glEnable(GL_CULL_FACE);
414         glEnable(GL_LIGHTING);
415         glDisable(GL_BLEND);
416         glEnable(GL_TEXTURE_2D);
417         glDepthMask(1);
418
419         glEnable(GL_COLOR_MATERIAL);
420
421         if (!cellophane) {
422             glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
423             glEnable(GL_CULL_FACE);
424             glCullFace(GL_FRONT);
425             glDepthMask(1);
426             for (unsigned k = 0; k < Person::players.size(); k++) {
427                 if (k == 0 || !Tutorial::active) {
428                     glEnable(GL_BLEND);
429                     glEnable(GL_LIGHTING);
430                     terrainlight = terrain.getLighting(Person::players[k]->coords.x, Person::players[k]->coords.z);
431                     distance = distsq(&viewer, &Person::players[k]->coords);
432                     distance = (viewdistance * viewdistance - (distance - (viewdistance * viewdistance * fadestart)) * (1 / (1 - fadestart))) / viewdistance / viewdistance;
433                     glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, distance);
434                     if (distance >= 1) {
435                         glDisable(GL_BLEND);
436                     }
437                     if (distance >= .5) {
438                         checkpoint = DoRotation(Person::players[k]->skeleton.joints[fabs(Random() % Person::players[k]->skeleton.joints.size())].position, 0, Person::players[k]->yaw, 0) * Person::players[k]->scale + Person::players[k]->coords;
439                         checkpoint.y += 1;
440                         int i = -1;
441                         if (Person::players[k]->occluded != 0) {
442                             i = Object::checkcollide(viewer, checkpoint, Person::players[k]->lastoccluded);
443                         }
444                         if (i == -1) {
445                             i = Object::checkcollide(viewer, checkpoint);
446                         }
447                         if (i != -1) {
448                             Person::players[k]->occluded += 1;
449                             Person::players[k]->lastoccluded = i;
450                         } else {
451                             Person::players[k]->occluded = 0;
452                         }
453                         if (Person::players[k]->occluded < 25) {
454                             Person::players[k]->DrawSkeleton();
455                         }
456                     }
457                 }
458             }
459         }
460
461         if (!cameramode && musictype == stream_fighttheme) {
462             playerdist = distsqflat(&Person::players[0]->coords, &viewer);
463         } else {
464             playerdist = -100;
465         }
466         glPushMatrix();
467         glCullFace(GL_BACK);
468         glEnable(GL_TEXTURE_2D);
469         Object::Draw();
470         glPopMatrix();
471
472         //draw hawk
473         glPushMatrix();
474         if (frustum.SphereInFrustum(realhawkcoords.x + hawk.boundingspherecenter.x, realhawkcoords.y + hawk.boundingspherecenter.y, realhawkcoords.z + hawk.boundingspherecenter.z, 2)) {
475             glAlphaFunc(GL_GREATER, 0.0001f);
476             glDepthMask(1);
477             glDisable(GL_CULL_FACE);
478             glDisable(GL_LIGHTING);
479             glEnable(GL_BLEND);
480             glTranslatef(hawkcoords.x, hawkcoords.y, hawkcoords.z);
481             glRotatef(hawkyaw, 0, 1, 0);
482             glTranslatef(25, 0, 0);
483             distance = distsq(&viewer, &realhawkcoords) * 1.2;
484             glColor4f(light.color[0], light.color[1], light.color[2], (viewdistance * viewdistance - (distance - (viewdistance * viewdistance * fadestart)) * (1 / (1 - fadestart))) / viewdistance / viewdistance);
485             if ((viewdistance * viewdistance - (distance - (viewdistance * viewdistance * fadestart)) * (1 / (1 - fadestart))) / viewdistance / viewdistance > 1) {
486                 glColor4f(light.color[0], light.color[1], light.color[2], 1);
487             }
488             if ((viewdistance * viewdistance - (distance - (viewdistance * viewdistance * fadestart)) * (1 / (1 - fadestart))) / viewdistance / viewdistance > 0) {
489                 hawk.drawdifftex(hawktexture);
490             }
491         }
492         glPopMatrix();
493
494         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
495         glEnable(GL_CULL_FACE);
496         glCullFace(GL_FRONT);
497         glDepthMask(1);
498         for (unsigned k = 0; k < Person::players.size(); k++) {
499             if (!(k == 0 || !Tutorial::active)) {
500                 glEnable(GL_BLEND);
501                 glEnable(GL_LIGHTING);
502                 terrainlight = terrain.getLighting(Person::players[k]->coords.x, Person::players[k]->coords.z);
503                 distance = distsq(&viewer, &Person::players[k]->coords);
504                 distance = (viewdistance * viewdistance - (distance - (viewdistance * viewdistance * fadestart)) * (1 / (1 - fadestart))) / viewdistance / viewdistance;
505                 glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, distance);
506                 if (distance >= 1) {
507                     glDisable(GL_BLEND);
508                 }
509                 if (distance >= .5) {
510                     checkpoint = DoRotation(Person::players[k]->skeleton.joints[fabs(Random() % Person::players[k]->skeleton.joints.size())].position, 0, Person::players[k]->yaw, 0) * Person::players[k]->scale + Person::players[k]->coords;
511                     checkpoint.y += 1;
512                     int i = -1;
513                     if (Person::players[k]->occluded != 0) {
514                         i = Object::checkcollide(viewer, checkpoint, Person::players[k]->lastoccluded);
515                     }
516                     if (i == -1) {
517                         i = Object::checkcollide(viewer, checkpoint);
518                     }
519                     if (i != -1) {
520                         Person::players[k]->occluded += 1;
521                         Person::players[k]->lastoccluded = i;
522                     } else {
523                         Person::players[k]->occluded = 0;
524                     }
525                     if (Person::players[k]->occluded < 25) {
526                         Person::players[k]->DrawSkeleton();
527                     }
528                 }
529             }
530         }
531
532         glPushMatrix();
533         glEnable(GL_TEXTURE_2D);
534         weapons.Draw();
535         glPopMatrix();
536         glCullFace(GL_BACK);
537
538         glDisable(GL_COLOR_MATERIAL);
539
540         glDisable(GL_LIGHTING);
541         glDisable(GL_TEXTURE_2D);
542
543         glDepthMask(0);
544
545         Sprite::Draw();
546
547         //waypoints, pathpoints in editor
548         if (editorenabled) {
549             glEnable(GL_BLEND);
550             glDisable(GL_LIGHTING);
551             glDisable(GL_TEXTURE_2D);
552             glDisable(GL_COLOR_MATERIAL);
553             glColor4f(1, 1, 0, 1);
554
555             for (unsigned k = 0; k < Person::players.size(); k++) {
556                 if (Person::players[k]->numwaypoints > 1) {
557                     glBegin(GL_LINE_LOOP);
558                     for (int i = 0; i < Person::players[k]->numwaypoints; i++) {
559                         glVertex3f(Person::players[k]->waypoints[i].x, Person::players[k]->waypoints[i].y + .5, Person::players[k]->waypoints[i].z);
560                     }
561                     glEnd();
562                 }
563             }
564
565             if (numpathpoints > 1) {
566                 glColor4f(0, 1, 0, 1);
567                 for (unsigned k = 0; int(k) < numpathpoints; k++) {
568                     if (numpathpointconnect[k]) {
569                         for (int i = 0; i < numpathpointconnect[k]; i++) {
570                             glBegin(GL_LINE_LOOP);
571                             glVertex3f(pathpoint[k].x, pathpoint[k].y + .5, pathpoint[k].z);
572                             glVertex3f(pathpoint[pathpointconnect[k][i]].x, pathpoint[pathpointconnect[k][i]].y + .5, pathpoint[pathpointconnect[k][i]].z);
573                             glEnd();
574                         }
575                     }
576                 }
577                 glColor4f(1, 1, 1, 1);
578                 glPointSize(4);
579                 glBegin(GL_POINTS);
580                 glVertex3f(pathpoint[pathpointselected].x, pathpoint[pathpointselected].y + .5, pathpoint[pathpointselected].z);
581                 glEnd();
582             }
583         }
584
585         //Text
586
587         glEnable(GL_TEXTURE_2D);
588         glColor4f(.5, .5, .5, 1);
589         if (!console) {
590             if (!Tutorial::active) {
591                 if (bonus > 0 && bonustime < 1 && !winfreeze && !Dialog::inDialog()) {
592                     const char* bonus_name;
593                     if (bonus < bonus_count) {
594                         bonus_name = bonus_names[bonus];
595                     } else {
596                         bonus_name = "Excellent!"; // When does this happen?
597                     }
598                     text->glPrintOutlined(1, 0, 0, 1 - bonustime, 1024 / 2 - 10 * strlen(bonus_name), 768 / 16 + 768 * 4 / 5, bonus_name, 1, 2, 1024, 768);
599
600                     string = to_string(bonusvalue);
601                     text->glPrintOutlined(1, 0, 0, 1 - bonustime, 1024 / 2 - 10 * string.size(), 768 / 16 - 20 + 768 * 4 / 5, string, 1, 2 * .8, 1024, 768);
602
603                     glColor4f(.5, .5, .5, 1);
604                 }
605             }
606
607             if (Tutorial::active) {
608                 Tutorial::DrawTextInfo();
609             }
610
611             //Hot spots
612             if (Hotspot::hotspots.size() && (bonustime >= 1 || bonus <= 0 || bonustime < 0) && !Tutorial::active) {
613                 float closestdist = -1;
614                 int closest = Hotspot::current;
615                 for (unsigned i = 0; i < Hotspot::hotspots.size(); i++) {
616                     float distance = distsq(&Person::players[0]->coords, &Hotspot::hotspots[i].position);
617                     if (closestdist == -1 || distance < closestdist) {
618                         if (distsq(&Person::players[0]->coords, &Hotspot::hotspots[i].position) < Hotspot::hotspots[i].size && ((Hotspot::hotspots[i].type <= 10 && Hotspot::hotspots[i].type >= 0) || (Hotspot::hotspots[i].type <= 40 && Hotspot::hotspots[i].type >= 20))) {
619                             closestdist = distance;
620                             closest = i;
621                         }
622                     }
623                 }
624                 if (closest != -1) {
625                     Hotspot::current = closest;
626                     if (Hotspot::hotspots[closest].type <= 10) {
627                         if (distsq(&Person::players[0]->coords, &Hotspot::hotspots[closest].position) < Hotspot::hotspots[closest].size) {
628                             Tutorial::stagetime = 0;
629                         }
630                         Tutorial::maxtime = 1;
631                         tutorialopac = Tutorial::maxtime - Tutorial::stagetime;
632                         if (tutorialopac > 1) {
633                             tutorialopac = 1;
634                         }
635                         if (tutorialopac < 0) {
636                             tutorialopac = 0;
637                         }
638
639                         string = Hotspot::hotspots[closest].text;
640
641                         int lastline = 0;
642                         int line = 0;
643                         bool done = false;
644                         int i = 0;
645                         while (!done) {
646                             if (string[i] == '\n' || string[i] > 'z' || string[i] < ' ' || string[i] == '\0') {
647                                 text->glPrintOutlined(1, 1, 1, tutorialopac, screenwidth / 2 - 7.6 * (i - lastline) * screenwidth / 1024, screenheight / 16 + screenheight * 4 / 5 - 20 * screenwidth / 1024 * line, string, 1, 1.5 * screenwidth / 1024, screenwidth, screenheight, lastline, i);
648                                 lastline = i + 1;
649                                 line++;
650                                 if (string[i] == '\0') {
651                                     done = 1;
652                                 }
653                             }
654                             if (i >= 255) {
655                                 done = 1;
656                             }
657                             i++;
658                         }
659                     } else if ((Hotspot::hotspots[closest].type >= 20) && (Dialog::dialogs[Hotspot::hotspots[closest].type - 20].gonethrough == 0)) {
660                         Dialog::whichdialogue = Hotspot::hotspots[closest].type - 20;
661                         Dialog::currentDialog().play();
662                         Dialog::currentDialog().gonethrough++;
663                     }
664                 }
665             }
666
667             /* Drawing dialogs */
668             if (Dialog::inDialog() && !mainmenu) {
669                 glDisable(GL_DEPTH_TEST);
670                 glDisable(GL_CULL_FACE);
671                 glDisable(GL_LIGHTING);
672                 glDisable(GL_TEXTURE_2D);
673                 glDepthMask(0);
674                 glMatrixMode(GL_PROJECTION);
675                 glPushMatrix();
676                 glLoadIdentity();
677                 glOrtho(0, screenwidth, 0, screenheight, -100, 100);
678                 glMatrixMode(GL_MODELVIEW);
679                 glPushMatrix();
680                 glLoadIdentity();
681                 if (Dialog::currentScene().location == 1) {
682                     glTranslatef(0, screenheight * 3 / 4, 0);
683                 }
684                 glScalef(screenwidth, screenheight / 4, 1);
685                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
686                 glEnable(GL_BLEND);
687
688                 glColor4f(Dialog::currentScene().color[0], Dialog::currentScene().color[1], Dialog::currentScene().color[2], 0.7);
689                 glBegin(GL_QUADS);
690                 glVertex3f(0, 0, 0.0f);
691                 glVertex3f(1, 0, 0.0f);
692                 glVertex3f(1, 1, 0.0f);
693                 glVertex3f(0, 1, 0.0f);
694                 glEnd();
695                 glMatrixMode(GL_PROJECTION);
696                 glPopMatrix();
697                 glMatrixMode(GL_MODELVIEW);
698                 glPopMatrix();
699                 glEnable(GL_DEPTH_TEST);
700                 glEnable(GL_CULL_FACE);
701                 glDisable(GL_BLEND);
702                 glDepthMask(1);
703                 glEnable(GL_TEXTURE_2D);
704
705                 tutorialopac = 1;
706
707                 float startx;
708                 float starty;
709
710                 startx = screenwidth * 1 / 5;
711                 if (Dialog::currentScene().location == 1) {
712                     starty = screenheight / 16 + screenheight * 4 / 5;
713                 } else {
714                     starty = screenheight * 1 / 5 - screenheight / 16;
715                 }
716
717                 /* Get speaker name, and remove potential '#' chars hardcoded in it. */
718                 string = Dialog::currentScene().name + ": ";
719                 string.erase(std::remove(string.begin(), string.end(), '#'), string.end());
720
721                 /* Print speaker name in dialog box. */
722                 if (Dialog::currentScene().color[0] + Dialog::currentScene().color[1] + Dialog::currentScene().color[2] < 1.5) {
723                     text->glPrintOutlined(0.7, 0.7, 0.7, tutorialopac, startx - 2 * 7.6 * string.size() * screenwidth / 1024, starty, string, 1, 1.4 * screenwidth / 1024, screenwidth, screenheight);
724                 } else {
725                     glColor4f(0, 0, 0, tutorialopac);
726                     text->glPrintOutline(startx - 2 * 7.6 * string.size() * screenwidth / 1024 - 4, starty - 4, string, 1, 1.4 * 1.25 * screenwidth / 1024, screenwidth, screenheight);
727                 }
728
729                 /* Get dialog text, and remove potential '#' chars hardcoded in it.' */
730                 string = Dialog::currentScene().text;
731                 string.erase(std::remove(string.begin(), string.end(), '#'), string.end());
732
733                 /* Print dialog text in dialog box. */
734                 int lastline = 0;
735                 int line = 0;
736                 bool done = false;
737                 int i = 0;
738                 while (!done) {
739                     if (string[i] == '\n' || string[i] > 'z' || string[i] < ' ' || string[i] == '\0') {
740                         if (Dialog::currentScene().color[0] + Dialog::currentScene().color[1] + Dialog::currentScene().color[2] < 1.5) {
741                             text->glPrintOutlined(1, 1, 1, tutorialopac, startx, starty - 20 * screenwidth / 1024 * line, string, 1, 1.4 * screenwidth / 1024, screenwidth, screenheight, lastline, i);
742                         } else {
743                             glColor4f(0, 0, 0, tutorialopac);
744                             text->glPrint(startx, starty - 20 * screenwidth / 1024 * line, string, 1, 1.4 * screenwidth / 1024, screenwidth, screenheight, lastline, i);
745                         }
746                         lastline = i + 1;
747                         line++;
748                         if (string[i] == '\0') {
749                             done = 1;
750                         }
751                     }
752                     if (i >= 255) {
753                         done = 1;
754                     }
755                     i++;
756                 }
757             }
758
759             if (!Tutorial::active && !winfreeze && !Dialog::inDialog() && !mainmenu) {
760                 if (campaign) {
761                     if (scoreadded) {
762                         string = "Score: " + to_string(int(Account::active().getCampaignScore()));
763                     } else {
764                         string = "Score: " + to_string(int(Account::active().getCampaignScore() + bonustotal));
765                     }
766                 } else {
767                     string = "Score: " + to_string(int(bonustotal));
768                 }
769                 text->glPrintOutlined(1, 0, 0, 1, 1024 / 40, 768 / 16 + 768 * 14 / 16, string, 1, 1.5, 1024, 768);
770                 if (showdamagebar) {
771                     glDisable(GL_DEPTH_TEST);
772                     glDisable(GL_CULL_FACE);
773                     glDisable(GL_LIGHTING);
774                     glDisable(GL_TEXTURE_2D);
775                     glDepthMask(0);
776                     glMatrixMode(GL_PROJECTION);
777                     glPushMatrix();
778                     glLoadIdentity();
779                     glOrtho(0, screenwidth, 0, screenheight, -100, 100);
780                     glMatrixMode(GL_MODELVIEW);
781                     glPushMatrix();
782                     glLoadIdentity();
783                     glTranslatef(15, screenheight * 17.5 / 20, 0);
784                     glScalef(screenwidth / 3 + 20, screenheight / 20, 1);
785                     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
786                     glEnable(GL_BLEND);
787                     glColor4f(0.0, 0.4, 0.0, 0.7);
788                     float bar = ((float)Person::players[0]->damage) / Person::players[0]->damagetolerance;
789                     glBegin(GL_QUADS);
790                     glVertex3f((bar < 1 ? bar : 1), 0, 0.0f);
791                     glVertex3f(1, 0, 0.0f);
792                     glVertex3f(1, 1, 0.0f);
793                     glVertex3f((bar < 1 ? bar : 1), 1, 0.0f);
794                     glEnd();
795                     glColor4f(0.1, 0.0, 0.0, 1);
796                     bar = ((float)Person::players[0]->bloodloss) / Person::players[0]->damagetolerance;
797                     glBegin(GL_QUADS);
798                     glVertex3f(0, 0, 0.0f);
799                     glVertex3f((bar < 1 ? bar : 1), 0, 0.0f);
800                     glVertex3f((bar < 1 ? bar : 1), 1, 0.0f);
801                     glVertex3f(0, 1, 0.0f);
802                     glEnd();
803                     glColor4f(0.4, 0.0, 0.0, 0.7);
804                     bar = ((float)Person::players[0]->damage) / Person::players[0]->damagetolerance;
805                     glBegin(GL_QUADS);
806                     glVertex3f(0, 0, 0.0f);
807                     glVertex3f((bar < 1 ? bar : 1), 0, 0.0f);
808                     glVertex3f((bar < 1 ? bar : 1), 1, 0.0f);
809                     glVertex3f(0, 1, 0.0f);
810                     glEnd();
811                     glColor4f(0.4, 0.0, 0.0, 0.7);
812                     bar = ((float)Person::players[0]->permanentdamage) / Person::players[0]->damagetolerance;
813                     glBegin(GL_QUADS);
814                     glVertex3f(0, 0, 0.0f);
815                     glVertex3f((bar < 1 ? bar : 1), 0, 0.0f);
816                     glVertex3f((bar < 1 ? bar : 1), 1, 0.0f);
817                     glVertex3f(0, 1, 0.0f);
818                     glEnd();
819                     glColor4f(0.4, 0.0, 0.0, 0.7);
820                     bar = ((float)Person::players[0]->superpermanentdamage) / Person::players[0]->damagetolerance;
821                     glBegin(GL_QUADS);
822                     glVertex3f(0, 0, 0.0f);
823                     glVertex3f((bar < 1 ? bar : 1), 0, 0.0f);
824                     glVertex3f((bar < 1 ? bar : 1), 1, 0.0f);
825                     glVertex3f(0, 1, 0.0f);
826                     glEnd();
827                     glColor4f(0.0, 0.0, 0.0, 0.7);
828                     glLineWidth(2.0);
829                     glBegin(GL_LINE_STRIP);
830                     glVertex3f(0, 0, 0.0f);
831                     glVertex3f(1, 0, 0.0f);
832                     glVertex3f(1, 1, 0.0f);
833                     glVertex3f(0, 1, 0.0f);
834                     glVertex3f(0, 0, 0.0f);
835                     glEnd();
836
837                     glMatrixMode(GL_PROJECTION);
838                     glPopMatrix();
839                     glMatrixMode(GL_MODELVIEW);
840                     glPopMatrix();
841                     glEnable(GL_DEPTH_TEST);
842                     glEnable(GL_CULL_FACE);
843                     glDisable(GL_BLEND);
844                     glDepthMask(1);
845                     glEnable(GL_TEXTURE_2D);
846
847                     // writing the numbers :
848                     string = "Damages : " + to_string(int(Person::players[0]->damage)) + "/" + to_string(int(Person::players[0]->damagetolerance)) + " (" + to_string(int(Person::players[0]->bloodloss)) + ")";
849                     text->glPrintOutlined(1, 0, 0, 1, 1024 / 40, 768 / 16 + 768 * 14 / 16 - 40, string, 1, 1.5, 1024, 768);
850                 }
851             }
852
853             glColor4f(.5, .5, .5, 1);
854
855             if ((texttoggle || editorenabled) && devtools && !mainmenu) {
856                 string = "The framespersecond is " + to_string(int(fps));
857                 text->glPrint(10, 30, string, 0, .8, 1024, 768);
858
859                 if (editorenabled) {
860                     string = "Map editor enabled.";
861                 } else {
862                     string = "Map editor disabled.";
863                 }
864                 text->glPrint(10, 60, string, 0, .8, 1024, 768);
865                 if (editorenabled) {
866                     string = "Object size: " + to_string(editorsize);
867                     text->glPrint(10, 75, string, 0, .8, 1024, 768);
868                     if (editoryaw >= 0) {
869                         string = "Object yaw: " + to_string(editoryaw);
870                     } else {
871                         string = "Object yaw: Random";
872                     }
873                     text->glPrint(10, 90, string, 0, .8, 1024, 768);
874                     if (editorpitch >= 0) {
875                         string = "Object pitch: " + to_string(editorpitch);
876                     } else {
877                         string = "Object pitch: Random";
878                     }
879                     text->glPrint(10, 105, string, 0, .8, 1024, 768);
880                     string = "Object type: " + to_string(editortype);
881                     text->glPrint(10, 120, string, 0, .8, 1024, 768);
882                     switch (editortype) {
883                         case boxtype:
884                             string = "(box)";
885                             break;
886                         case treetrunktype:
887                             string = "(tree)";
888                             break;
889                         case walltype:
890                             string = "(wall)";
891                             break;
892                         case weirdtype:
893                             string = "(weird)";
894                             break;
895                         case spiketype:
896                             string = "(spike)";
897                             break;
898                         case rocktype:
899                             string = "(rock)";
900                             break;
901                         case bushtype:
902                             string = "(bush)";
903                             break;
904                         case tunneltype:
905                             string = "(tunnel)";
906                             break;
907                         case chimneytype:
908                             string = "(chimney)";
909                             break;
910                         case platformtype:
911                             string = "(platform)";
912                             break;
913                         case cooltype:
914                             string = "(cool)";
915                             break;
916                         case firetype:
917                             string = "(fire)";
918                             break;
919                     }
920                     text->glPrint(130, 120, string, 0, .8, 1024, 768);
921
922                     string = "Numplayers: " + to_string(Person::players.size());
923                     text->glPrint(10, 155, string, 0, .8, 1024, 768);
924                     string = "Player " + to_string(int(Person::players.size()) - 1) + ": numwaypoints: " + to_string(Person::players.back()->numwaypoints);
925                     text->glPrint(10, 140, string, 0, .8, 1024, 768);
926                 }
927                 string = "Difficulty: " + to_string(difficulty);
928                 text->glPrint(10, 240, string, 0, .8, 1024, 768);
929             }
930         }
931
932         if (drawmode == glowmode) {
933             glDisable(GL_DEPTH_TEST);
934             glDisable(GL_CULL_FACE);
935             glDisable(GL_LIGHTING);
936             glDisable(GL_TEXTURE_2D);
937             glDepthMask(0);
938             glMatrixMode(GL_PROJECTION);
939             glPushMatrix();
940             glLoadIdentity();
941             glOrtho(0, screenwidth, 0, screenheight, -100, 100);
942             glMatrixMode(GL_MODELVIEW);
943             glPushMatrix();
944             glLoadIdentity();
945             glScalef(screenwidth, screenheight, 1);
946             glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
947             glEnable(GL_BLEND);
948             glColor4f(0, 0, 0, .5);
949             glBegin(GL_QUADS);
950             glVertex3f(0, 0, 0.0f);
951             glVertex3f(256, 0, 0.0f);
952             glVertex3f(256, 256, 0.0f);
953             glVertex3f(0, 256, 0.0f);
954             glEnd();
955             glMatrixMode(GL_PROJECTION);
956             glPopMatrix();
957             glMatrixMode(GL_MODELVIEW);
958             glPopMatrix();
959             glEnable(GL_DEPTH_TEST);
960             glEnable(GL_CULL_FACE);
961             glDisable(GL_BLEND);
962             glDepthMask(1);
963         }
964
965         if ((((blackout && damageeffects) || (Person::players[0]->bloodloss > 0 && damageeffects && Person::players[0]->blooddimamount > 0) || Person::players[0]->dead) && !cameramode) || console) {
966             glDisable(GL_DEPTH_TEST);
967             glDisable(GL_CULL_FACE);
968             glDisable(GL_LIGHTING);
969             glDisable(GL_TEXTURE_2D);
970             glDepthMask(0);
971             glMatrixMode(GL_PROJECTION);
972             glPushMatrix();
973             glLoadIdentity();
974             glOrtho(0, screenwidth, 0, screenheight, -100, 100);
975             glMatrixMode(GL_MODELVIEW);
976             glPushMatrix();
977             glLoadIdentity();
978             glScalef(screenwidth, screenheight, 1);
979             glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
980             glEnable(GL_BLEND);
981             if (Person::players[0]->dead) {
982                 blackout += multiplier * 3;
983             }
984             if (Person::players[0]->dead == 1) {
985                 blackout = .4f;
986             }
987             if (Person::players[0]->dead == 2 && blackout > .6) {
988                 blackout = .6;
989             }
990             glColor4f(0, 0, 0, blackout);
991             if (!Person::players[0]->dead) {
992                 if ((Person::players[0]->bloodloss / Person::players[0]->damagetolerance * (sin(woozy) / 4 + .5)) * .3 < .3) {
993                     glColor4f(0, 0, 0, Person::players[0]->blooddimamount * Person::players[0]->bloodloss / Person::players[0]->damagetolerance * (sin(woozy) / 4 + .5) * .3);
994                     blackout = Person::players[0]->blooddimamount * Person::players[0]->bloodloss / Person::players[0]->damagetolerance * (sin(woozy) / 4 + .5) * .3;
995                 } else {
996                     glColor4f(0, 0, 0, Person::players[0]->blooddimamount * .3);
997                     blackout = Person::players[0]->blooddimamount * .3;
998                 }
999             }
1000             if (console) {
1001                 glColor4f(.7, 0, 0, .2);
1002             }
1003             glBegin(GL_QUADS);
1004             glVertex3f(0, 0, 0.0f);
1005             glVertex3f(256, 0, 0.0f);
1006             glVertex3f(256, 256, 0.0f);
1007             glVertex3f(0, 256, 0.0f);
1008             glEnd();
1009             glMatrixMode(GL_PROJECTION);
1010             glPopMatrix();
1011             glMatrixMode(GL_MODELVIEW);
1012             glPopMatrix();
1013             glEnable(GL_DEPTH_TEST);
1014             glEnable(GL_CULL_FACE);
1015             glDisable(GL_BLEND);
1016             glDepthMask(1);
1017         }
1018
1019         if (flashamount > 0 && damageeffects) {
1020             if (flashamount > 1) {
1021                 flashamount = 1;
1022             }
1023             if (flashdelay <= 0) {
1024                 flashamount -= multiplier;
1025             }
1026             flashdelay--;
1027             if (flashamount < 0) {
1028                 flashamount = 0;
1029             }
1030             glDisable(GL_DEPTH_TEST);
1031             glDisable(GL_CULL_FACE);
1032             glDisable(GL_LIGHTING);
1033             glDepthMask(0);
1034             glMatrixMode(GL_PROJECTION);
1035             glPushMatrix();
1036             glLoadIdentity();
1037             glOrtho(0, screenwidth, 0, screenheight, -100, 100);
1038             glMatrixMode(GL_MODELVIEW);
1039             glPushMatrix();
1040             glLoadIdentity();
1041             glScalef(screenwidth, screenheight, 1);
1042             glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1043             glEnable(GL_BLEND);
1044             glColor4f(flashr, flashg, flashb, flashamount);
1045             glBegin(GL_QUADS);
1046             glVertex3f(0, 0, 0.0f);
1047             glVertex3f(256, 0, 0.0f);
1048             glVertex3f(256, 256, 0.0f);
1049             glVertex3f(0, 256, 0.0f);
1050             glEnd();
1051             glMatrixMode(GL_PROJECTION);
1052             glPopMatrix();
1053             glMatrixMode(GL_MODELVIEW);
1054             glPopMatrix();
1055             glEnable(GL_DEPTH_TEST);
1056             glEnable(GL_CULL_FACE);
1057             glDisable(GL_BLEND);
1058             glDepthMask(1);
1059         }
1060
1061         if (difficulty < 2 && !Dialog::inDialog()) { // minimap
1062             float mapviewdist = 20000;
1063
1064             glDisable(GL_DEPTH_TEST);
1065             glColor3f(1.0, 1.0, 1.0); // no coloring
1066
1067             glEnable(GL_TEXTURE_2D);
1068             glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1069             glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1070             glDisable(GL_DEPTH_TEST);
1071             glDisable(GL_CULL_FACE);
1072             glDisable(GL_LIGHTING);
1073             glDepthMask(0);
1074             glMatrixMode(GL_PROJECTION);
1075             glPushMatrix();
1076             glLoadIdentity();
1077             glOrtho(0, screenwidth, 0, screenheight, -100, 100);
1078             glMatrixMode(GL_MODELVIEW);
1079             glPushMatrix();
1080             glLoadIdentity();
1081             glScalef((float)screenwidth / 2, (float)screenwidth / 2, 1);
1082             glTranslatef(1.75, .25, 0);
1083             glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1084             glEnable(GL_BLEND);
1085             glColor4f(1, 1, 1, 1);
1086             glPushMatrix();
1087             float opac = .7;
1088             XYZ center;
1089             float radius;
1090             float distcheck;
1091
1092             center = Person::players[0]->coords;
1093
1094             radius = 110;
1095
1096             glScalef(.25 / radius * 256 * terrain.scale * .4, .25 / radius * 256 * terrain.scale * .4, 1);
1097             glPushMatrix();
1098             glScalef(1 / (1 / radius * 256 * terrain.scale * .4), 1 / (1 / radius * 256 * terrain.scale * .4), 1);
1099             glPopMatrix();
1100             glRotatef(Person::players[0]->lookyaw * -1 + 180, 0, 0, 1);
1101             glTranslatef(-(center.x / terrain.scale / 256 * -2 + 1), (center.z / terrain.scale / 256 * -2 + 1), 0);
1102             for (unsigned int i = 0; i < Object::objects.size(); i++) {
1103                 if (Object::objects[i]->type == treetrunktype) {
1104                     distcheck = distsq(&Person::players[0]->coords, &Object::objects[i]->position);
1105                     if (distcheck < mapviewdist) {
1106                         Mapcircletexture.bind();
1107                         glColor4f(0, .3, 0, opac * (1 - distcheck / mapviewdist));
1108                         glPushMatrix();
1109                         glTranslatef(Object::objects[i]->position.x / terrain.scale / 256 * -2 + 1, Object::objects[i]->position.z / terrain.scale / 256 * 2 - 1, 0);
1110                         glRotatef(Object::objects[i]->yaw, 0, 0, 1);
1111                         glScalef(.003, .003, .003);
1112                         glBegin(GL_QUADS);
1113                         glTexCoord2f(0, 0);
1114                         glVertex3f(-1, -1, 0.0f);
1115                         glTexCoord2f(1, 0);
1116                         glVertex3f(1, -1, 0.0f);
1117                         glTexCoord2f(1, 1);
1118                         glVertex3f(1, 1, 0.0f);
1119                         glTexCoord2f(0, 1);
1120                         glVertex3f(-1, 1, 0.0f);
1121                         glEnd();
1122                         glPopMatrix();
1123                     }
1124                 }
1125                 if (Object::objects[i]->type == boxtype) {
1126                     distcheck = distsq(&Person::players[0]->coords, &Object::objects[i]->position);
1127                     if (distcheck < mapviewdist) {
1128                         Mapboxtexture.bind();
1129                         glColor4f(.4, .4, .4, opac * (1 - distcheck / mapviewdist));
1130                         glPushMatrix();
1131                         glTranslatef(Object::objects[i]->position.x / terrain.scale / 256 * -2 + 1, Object::objects[i]->position.z / terrain.scale / 256 * 2 - 1, 0);
1132                         glRotatef(Object::objects[i]->yaw, 0, 0, 1);
1133                         glScalef(.01 * Object::objects[i]->scale, .01 * Object::objects[i]->scale, .01 * Object::objects[i]->scale);
1134                         glBegin(GL_QUADS);
1135                         glTexCoord2f(0, 0);
1136                         glVertex3f(-1, -1, 0.0f);
1137                         glTexCoord2f(1, 0);
1138                         glVertex3f(1, -1, 0.0f);
1139                         glTexCoord2f(1, 1);
1140                         glVertex3f(1, 1, 0.0f);
1141                         glTexCoord2f(0, 1);
1142                         glVertex3f(-1, 1, 0.0f);
1143                         glEnd();
1144                         glPopMatrix();
1145                     }
1146                 }
1147             }
1148             if (editorenabled) {
1149                 Mapcircletexture.bind();
1150                 for (int i = 0; i < numboundaries; i++) {
1151                     glColor4f(0, 0, 0, opac / 3);
1152                     glPushMatrix();
1153                     glTranslatef(boundary[i].x / terrain.scale / 256 * -2 + 1, boundary[i].z / terrain.scale / 256 * 2 - 1, 0);
1154                     glScalef(.002, .002, .002);
1155                     glBegin(GL_QUADS);
1156                     glTexCoord2f(0, 0);
1157                     glVertex3f(-1, -1, 0.0f);
1158                     glTexCoord2f(1, 0);
1159                     glVertex3f(1, -1, 0.0f);
1160                     glTexCoord2f(1, 1);
1161                     glVertex3f(1, 1, 0.0f);
1162                     glTexCoord2f(0, 1);
1163                     glVertex3f(-1, 1, 0.0f);
1164                     glEnd();
1165                     glPopMatrix();
1166                 }
1167             }
1168             for (unsigned i = 0; i < Person::players.size(); i++) {
1169                 distcheck = distsq(&Person::players[0]->coords, &Person::players[i]->coords);
1170                 if (distcheck < mapviewdist) {
1171                     glPushMatrix();
1172                     Maparrowtexture.bind();
1173                     if (i == 0) {
1174                         glColor4f(1, 1, 1, opac);
1175                     } else if (Person::players[i]->dead == 2 || Person::players[i]->howactive > typesleeping) {
1176                         glColor4f(0, 0, 0, opac * (1 - distcheck / mapviewdist));
1177                     } else if (Person::players[i]->dead) {
1178                         glColor4f(.3, .3, .3, opac * (1 - distcheck / mapviewdist));
1179                     } else if (Person::players[i]->aitype == attacktypecutoff) {
1180                         glColor4f(1, 0, 0, opac * (1 - distcheck / mapviewdist));
1181                     } else if (Person::players[i]->aitype == passivetype) {
1182                         glColor4f(0, 1, 0, opac * (1 - distcheck / mapviewdist));
1183                     } else {
1184                         glColor4f(1, 1, 0, 1);
1185                     }
1186                     glTranslatef(Person::players[i]->coords.x / terrain.scale / 256 * -2 + 1, Person::players[i]->coords.z / terrain.scale / 256 * 2 - 1, 0);
1187                     glRotatef(Person::players[i]->yaw + 180, 0, 0, 1);
1188                     glScalef(.005, .005, .005);
1189                     glBegin(GL_QUADS);
1190                     glTexCoord2f(0, 0);
1191                     glVertex3f(-1, -1, 0.0f);
1192                     glTexCoord2f(1, 0);
1193                     glVertex3f(1, -1, 0.0f);
1194                     glTexCoord2f(1, 1);
1195                     glVertex3f(1, 1, 0.0f);
1196                     glTexCoord2f(0, 1);
1197                     glVertex3f(-1, 1, 0.0f);
1198                     glEnd();
1199                     glPopMatrix();
1200                 }
1201             }
1202             glPopMatrix();
1203             glDisable(GL_TEXTURE_2D);
1204             glMatrixMode(GL_PROJECTION);
1205             glPopMatrix();
1206             glMatrixMode(GL_MODELVIEW);
1207             glPopMatrix();
1208             glEnable(GL_DEPTH_TEST);
1209             glEnable(GL_CULL_FACE);
1210             glDisable(GL_BLEND);
1211             glDepthMask(1);
1212         }
1213
1214         if (loading && !stealthloading && (!campaign || Person::players[0]->dead)) {
1215             glDisable(GL_DEPTH_TEST);
1216             glDisable(GL_CULL_FACE);
1217             glDisable(GL_LIGHTING);
1218             glDisable(GL_TEXTURE_2D);
1219             glDepthMask(0);
1220             glMatrixMode(GL_PROJECTION);
1221             glPushMatrix();
1222             glLoadIdentity();
1223             glOrtho(0, screenwidth, 0, screenheight, -100, 100);
1224             glMatrixMode(GL_MODELVIEW);
1225             glPushMatrix();
1226             glLoadIdentity();
1227             glScalef(screenwidth, screenheight, 1);
1228             glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1229             glEnable(GL_BLEND);
1230             glColor4f(0, 0, 0, .7);
1231             glBegin(GL_QUADS);
1232             glVertex3f(0, 0, 0.0f);
1233             glVertex3f(256, 0, 0.0f);
1234             glVertex3f(256, 256, 0.0f);
1235             glVertex3f(0, 256, 0.0f);
1236             glEnd();
1237             glMatrixMode(GL_PROJECTION);
1238             glPopMatrix();
1239             glMatrixMode(GL_MODELVIEW);
1240             glPopMatrix();
1241             glEnable(GL_DEPTH_TEST);
1242             glEnable(GL_CULL_FACE);
1243             glDisable(GL_BLEND);
1244             glDepthMask(1);
1245
1246             //logo
1247             glDisable(GL_DEPTH_TEST);
1248             glColor3f(1.0, 1.0, 1.0); // no coloring
1249
1250             glEnable(GL_TEXTURE_2D);
1251
1252             //Minimap
1253
1254             if (loading != 4) {
1255                 glEnable(GL_TEXTURE_2D);
1256                 glColor4f(1, 1, 1, 1);
1257                 string = "Loading...";
1258                 text->glPrint(1024 / 2 - 90, 768 / 2, string, 1, 2, 1024, 768);
1259             }
1260             loading = 2;
1261             drawmode = normalmode;
1262         }
1263
1264         if (winfreeze && !campaign) {
1265             glDisable(GL_DEPTH_TEST);
1266             glDisable(GL_CULL_FACE);
1267             glDisable(GL_LIGHTING);
1268             glDisable(GL_TEXTURE_2D);
1269             glDepthMask(0);
1270             glMatrixMode(GL_PROJECTION);
1271             glPushMatrix();
1272             glLoadIdentity();
1273             glOrtho(0, screenwidth, 0, screenheight, -100, 100);
1274             glMatrixMode(GL_MODELVIEW);
1275             glPushMatrix();
1276             glLoadIdentity();
1277             glScalef(screenwidth, screenheight, 1);
1278             glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1279             glEnable(GL_BLEND);
1280             glColor4f(0, 0, 0, .4);
1281             glBegin(GL_QUADS);
1282             glVertex3f(0, 0, 0.0f);
1283             glVertex3f(256, 0, 0.0f);
1284             glVertex3f(256, 256, 0.0f);
1285             glVertex3f(0, 256, 0.0f);
1286             glEnd();
1287             glMatrixMode(GL_PROJECTION);
1288             glPopMatrix();
1289             glMatrixMode(GL_MODELVIEW);
1290             glPopMatrix();
1291             glEnable(GL_DEPTH_TEST);
1292             glEnable(GL_CULL_FACE);
1293             glDisable(GL_BLEND);
1294             glDepthMask(1);
1295
1296             //logo
1297             glDisable(GL_DEPTH_TEST);
1298             glColor3f(1.0, 1.0, 1.0); // no coloring
1299
1300             glEnable(GL_TEXTURE_2D);
1301
1302             //Win Screen Won Victory
1303
1304             glEnable(GL_TEXTURE_2D);
1305             glColor4f(1, 1, 1, 1);
1306             string = "Level Cleared!";
1307             text->glPrintOutlined(1024 / 2 - string.size() * 10, 768 * 7 / 8, string, 1, 2, 1024, 768);
1308
1309             string = "Score:     " + to_string(int(bonustotal - startbonustotal));
1310             text->glPrintOutlined(1024 / 30, 768 * 6 / 8, string, 1, 2, 1024, 768);
1311
1312             string = "Press Escape to return to menu or Space to continue";
1313             text->glPrintOutlined(640 / 2 - string.size() * 5, 480 * 1 / 16, string, 1, 1, 640, 480);
1314
1315             int wontime = (int)round(wonleveltime);
1316             string = "Time:      " + to_string(int((wontime - wontime % 60) / 60));
1317             if (wontime % 60 < 10) {
1318                 string += "0";
1319             }
1320             string += to_string(int(wontime % 60));
1321             text->glPrintOutlined(1024 / 30, 768 * 6 / 8 - 40, string, 1, 2, 1024, 768);
1322
1323             //Awards
1324             int awards[award_count];
1325             int numawards = award_awards(awards);
1326
1327             for (int i = 0; i < numawards && i < 6; i++) {
1328                 text->glPrintOutlined(1024 / 30, 768 * 6 / 8 - 90 - 40 * i, award_names[awards[i]], 1, 2, 1024, 768);
1329             }
1330         }
1331
1332         if (drawmode != normalmode) {
1333             glEnable(GL_TEXTURE_2D);
1334             glFinish();
1335             if (!drawtoggle || drawmode != realmotionblurmode || (drawtoggle == 2 || change == 1)) {
1336                 if (screentexture) {
1337
1338                     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
1339                     GLfloat subtractColor[4] = { 0.5, 0.5, 0.5, 0.0 };
1340                     glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, subtractColor);
1341                     glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE);
1342                     glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_CONSTANT);
1343                     glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE, 2.0f);
1344
1345                     glBindTexture(GL_TEXTURE_2D, screentexture);
1346                     glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, texviewwidth, texviewheight);
1347                 }
1348             }
1349             if ((drawtoggle || change == 1) && drawmode == realmotionblurmode) {
1350                 if (screentexture2) {
1351                     glBindTexture(GL_TEXTURE_2D, screentexture2);
1352                     glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, texviewwidth, texviewheight);
1353                 }
1354                 if (!screentexture2) {
1355                     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1356
1357                     glGenTextures(1, &screentexture2);
1358                     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
1359
1360                     glEnable(GL_TEXTURE_2D);
1361                     glBindTexture(GL_TEXTURE_2D, screentexture2);
1362                     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1363                     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1364
1365                     glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, kTextureSize, kTextureSize, 0);
1366                 }
1367             }
1368         }
1369
1370         glClear(GL_DEPTH_BUFFER_BIT);
1371         Game::ReSizeGLScene(90, .1f);
1372         glViewport(0, 0, screenwidth, screenheight);
1373
1374         if (drawmode != normalmode) {
1375             glDisable(GL_DEPTH_TEST);
1376             if (drawmode == motionblurmode) {
1377                 glDrawBuffer(GL_FRONT);
1378                 glReadBuffer(GL_BACK);
1379             }
1380             glColor3f(1.0, 1.0, 1.0); // no coloring
1381
1382             glEnable(GL_TEXTURE_2D);
1383             glBindTexture(GL_TEXTURE_2D, screentexture);
1384             glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1385             glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1386             glDisable(GL_DEPTH_TEST);
1387             glDisable(GL_CULL_FACE);
1388             glDisable(GL_LIGHTING);
1389             glDepthMask(0);
1390             glMatrixMode(GL_PROJECTION);
1391             glPushMatrix();
1392             glLoadIdentity();
1393             glOrtho(0, screenwidth, 0, screenheight, -100, 100);
1394             glMatrixMode(GL_MODELVIEW);
1395             glPushMatrix();
1396             glLoadIdentity();
1397             glScalef((float)screenwidth / 2, (float)screenheight / 2, 1);
1398             glTranslatef(1, 1, 0);
1399             glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1400             glEnable(GL_BLEND);
1401             if (drawmode == motionblurmode) {
1402                 if (motionbluramount < .2) {
1403                     motionbluramount = .2;
1404                 }
1405                 glColor4f(1, 1, 1, motionbluramount);
1406                 glPushMatrix();
1407                 glBegin(GL_QUADS);
1408                 glTexCoord2f(0, 0);
1409                 glVertex3f(-1, -1, 0.0f);
1410                 glTexCoord2f(texcoordwidth, 0);
1411                 glVertex3f(1, -1, 0.0f);
1412                 glTexCoord2f(texcoordwidth, texcoordheight);
1413                 glVertex3f(1, 1, 0.0f);
1414                 glTexCoord2f(0, texcoordheight);
1415                 glVertex3f(-1, 1, 0.0f);
1416                 glEnd();
1417                 glPopMatrix();
1418             }
1419             if (drawmode == realmotionblurmode) {
1420                 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
1421                 glClear(GL_COLOR_BUFFER_BIT);
1422                 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
1423                 glBindTexture(GL_TEXTURE_2D, screentexture);
1424                 glColor4f(1, 1, 1, .5);
1425                 glPushMatrix();
1426                 glBegin(GL_QUADS);
1427                 glTexCoord2f(0, 0);
1428                 glVertex3f(-1, -1, 0.0f);
1429                 glTexCoord2f(texcoordwidth, 0);
1430                 glVertex3f(1, -1, 0.0f);
1431                 glTexCoord2f(texcoordwidth, texcoordheight);
1432                 glVertex3f(1, 1, 0.0f);
1433                 glTexCoord2f(0, texcoordheight);
1434                 glVertex3f(-1, 1, 0.0f);
1435                 glEnd();
1436                 glPopMatrix();
1437                 glBindTexture(GL_TEXTURE_2D, screentexture2);
1438                 glColor4f(1, 1, 1, .5);
1439                 glPushMatrix();
1440                 glBegin(GL_QUADS);
1441                 glTexCoord2f(0, 0);
1442                 glVertex3f(-1, -1, 0.0f);
1443                 glTexCoord2f(texcoordwidth, 0);
1444                 glVertex3f(1, -1, 0.0f);
1445                 glTexCoord2f(texcoordwidth, texcoordheight);
1446                 glVertex3f(1, 1, 0.0f);
1447                 glTexCoord2f(0, texcoordheight);
1448                 glVertex3f(-1, 1, 0.0f);
1449                 glEnd();
1450                 glPopMatrix();
1451                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1452             }
1453             if (drawmode == doublevisionmode) {
1454                 static float crosseyedness;
1455                 crosseyedness = abs(Person::players[0]->damage - Person::players[0]->superpermanentdamage - (Person::players[0]->damagetolerance - Person::players[0]->superpermanentdamage) * 1 / 2) / 30;
1456                 if (crosseyedness > 1) {
1457                     crosseyedness = 1;
1458                 }
1459                 if (crosseyedness < 0) {
1460                     crosseyedness = 0;
1461                 }
1462                 glColor4f(1, 1, 1, 1);
1463                 glDisable(GL_BLEND);
1464                 glPushMatrix();
1465                 glScalef(1, 1, 1);
1466                 glBegin(GL_QUADS);
1467                 glTexCoord2f(0, 0);
1468                 glVertex3f(-1, -1, 0.0f);
1469                 glTexCoord2f(texcoordwidth, 0);
1470                 glVertex3f(1, -1, 0.0f);
1471                 glTexCoord2f(texcoordwidth, texcoordheight);
1472                 glVertex3f(1, 1, 0.0f);
1473                 glTexCoord2f(0, texcoordheight);
1474                 glVertex3f(-1, 1, 0.0f);
1475                 glEnd();
1476                 glPopMatrix();
1477                 if (crosseyedness) {
1478                     glColor4f(1, 1, 1, .5);
1479                     glEnable(GL_BLEND);
1480                     glPushMatrix();
1481                     glTranslatef(.015 * crosseyedness, 0, 0);
1482                     glScalef(1, 1, 1);
1483                     glBegin(GL_QUADS);
1484                     glTexCoord2f(0, 0);
1485                     glVertex3f(-1, -1, 0.0f);
1486                     glTexCoord2f(texcoordwidth, 0);
1487                     glVertex3f(1, -1, 0.0f);
1488                     glTexCoord2f(texcoordwidth, texcoordheight);
1489                     glVertex3f(1, 1, 0.0f);
1490                     glTexCoord2f(0, texcoordheight);
1491                     glVertex3f(-1, 1, 0.0f);
1492                     glEnd();
1493                     glPopMatrix();
1494                 }
1495             }
1496             if (drawmode == glowmode) {
1497                 glColor4f(.5, .5, .5, .5);
1498                 glEnable(GL_BLEND);
1499                 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
1500                 glPushMatrix();
1501                 glTranslatef(.01, 0, 0);
1502                 glBegin(GL_QUADS);
1503                 glTexCoord2f(0, 0);
1504                 glVertex3f(-1, -1, 0.0f);
1505                 glTexCoord2f(texcoordwidth, 0);
1506                 glVertex3f(1, -1, 0.0f);
1507                 glTexCoord2f(texcoordwidth, texcoordheight);
1508                 glVertex3f(1, 1, 0.0f);
1509                 glTexCoord2f(0, texcoordheight);
1510                 glVertex3f(-1, 1, 0.0f);
1511                 glEnd();
1512                 glPopMatrix();
1513                 glPushMatrix();
1514                 glTranslatef(-.01, 0, 0);
1515                 glBegin(GL_QUADS);
1516                 glTexCoord2f(0, 0);
1517                 glVertex3f(-1, -1, 0.0f);
1518                 glTexCoord2f(texcoordwidth, 0);
1519                 glVertex3f(1, -1, 0.0f);
1520                 glTexCoord2f(texcoordwidth, texcoordheight);
1521                 glVertex3f(1, 1, 0.0f);
1522                 glTexCoord2f(0, texcoordheight);
1523                 glVertex3f(-1, 1, 0.0f);
1524                 glEnd();
1525                 glPopMatrix();
1526                 glPushMatrix();
1527                 glTranslatef(.0, .01, 0);
1528                 glBegin(GL_QUADS);
1529                 glTexCoord2f(0, 0);
1530                 glVertex3f(-1, -1, 0.0f);
1531                 glTexCoord2f(texcoordwidth, 0);
1532                 glVertex3f(1, -1, 0.0f);
1533                 glTexCoord2f(texcoordwidth, texcoordheight);
1534                 glVertex3f(1, 1, 0.0f);
1535                 glTexCoord2f(0, texcoordheight);
1536                 glVertex3f(-1, 1, 0.0f);
1537                 glEnd();
1538                 glPopMatrix();
1539                 glPushMatrix();
1540                 glTranslatef(0, -.01, 0);
1541                 glBegin(GL_QUADS);
1542                 glTexCoord2f(0, 0);
1543                 glVertex3f(-1, -1, 0.0f);
1544                 glTexCoord2f(texcoordwidth, 0);
1545                 glVertex3f(1, -1, 0.0f);
1546                 glTexCoord2f(texcoordwidth, texcoordheight);
1547                 glVertex3f(1, 1, 0.0f);
1548                 glTexCoord2f(0, texcoordheight);
1549                 glVertex3f(-1, 1, 0.0f);
1550                 glEnd();
1551                 glPopMatrix();
1552             }
1553             if (drawmode == radialzoommode) {
1554                 for (int i = 0; i < 3; i++) {
1555                     glColor4f(1, 1, 1, 1 / ((float)i + 1));
1556                     glPushMatrix();
1557                     glScalef(1 + (float)i * .01, 1 + (float)i * .01, 1);
1558                     glBegin(GL_QUADS);
1559                     glTexCoord2f(0, 0);
1560                     glVertex3f(-1, -1, 0.0f);
1561                     glTexCoord2f(texcoordwidth, 0);
1562                     glVertex3f(1, -1, 0.0f);
1563                     glTexCoord2f(texcoordwidth, texcoordheight);
1564                     glVertex3f(1, 1, 0.0f);
1565                     glTexCoord2f(0, texcoordheight);
1566                     glVertex3f(-1, 1, 0.0f);
1567                     glEnd();
1568                     glPopMatrix();
1569                 }
1570             }
1571             glDisable(GL_TEXTURE_2D);
1572             glMatrixMode(GL_PROJECTION);
1573             glPopMatrix();
1574             glMatrixMode(GL_MODELVIEW);
1575             glPopMatrix();
1576             glEnable(GL_DEPTH_TEST);
1577             glEnable(GL_CULL_FACE);
1578             glDisable(GL_BLEND);
1579             glDepthMask(1);
1580         }
1581
1582         if (console) {
1583             glEnable(GL_TEXTURE_2D);
1584             glColor4f(1, 1, 1, 1);
1585             int offset = 0;
1586             if (consoleselected >= 60) {
1587                 offset = consoleselected - 60;
1588             }
1589             textmono->glPrint(10, 30, " ]", 0, 1, 1024, 768);
1590             if (consoleblink) {
1591                 textmono->glPrint(30 + (float)consoleselected * 10 - offset * 10, 30, "_", 0, 1, 1024, 768);
1592             }
1593             for (unsigned i = 0; i < 15; i++) {
1594                 textmono->glPrint(30 - offset * 10, 30 + i * 20, consoletext[i], 0, 1, 1024, 768);
1595             }
1596         }
1597     }
1598
1599     if (freeze || winfreeze || (mainmenu && gameon) || (!gameon && gamestarted)) {
1600         multiplier = tempmult;
1601     }
1602
1603     if (mainmenu) {
1604         DrawMenu();
1605     }
1606
1607     if (freeze || winfreeze || (mainmenu && gameon) || (!gameon && gamestarted)) {
1608         tempmult = multiplier;
1609         multiplier = 0;
1610     }
1611
1612     if (side == stereoRight || side == stereoCenter) {
1613         if (drawmode != motionblurmode || mainmenu) {
1614             swap_gl_buffers();
1615         }
1616     }
1617
1618     glDrawBuffer(GL_BACK);
1619     glReadBuffer(GL_BACK);
1620
1621     weapons.DoStuff();
1622
1623     if (drawtoggle == 2) {
1624         drawtoggle = 0;
1625     }
1626
1627     if (freeze || winfreeze || (mainmenu && gameon) || (!gameon && gamestarted)) {
1628         multiplier = tempmult;
1629     }
1630     //Jordan fixed your warning!
1631     return 0;
1632 }
1633
1634 void DrawMenu()
1635 {
1636     // !!! FIXME: hack: clamp framerate in menu so text input works correctly on fast systems.
1637     SDL_Delay(15);
1638
1639     glDrawBuffer(GL_BACK);
1640     glReadBuffer(GL_BACK);
1641     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
1642     Game::ReSizeGLScene(90, .1f);
1643
1644     //draw menu background
1645     glClear(GL_DEPTH_BUFFER_BIT);
1646     glEnable(GL_ALPHA_TEST);
1647     glAlphaFunc(GL_GREATER, 0.001f);
1648     glEnable(GL_TEXTURE_2D);
1649     glDisable(GL_DEPTH_TEST);
1650     glDisable(GL_CULL_FACE);
1651     glDisable(GL_LIGHTING);
1652     glDepthMask(0);
1653     glMatrixMode(GL_PROJECTION);
1654     glPushMatrix();
1655     glLoadIdentity();
1656     glOrtho(0, screenwidth, 0, screenheight, -100, 100);
1657     glMatrixMode(GL_MODELVIEW);
1658     glPushMatrix();
1659     glLoadIdentity();
1660     glTranslatef(screenwidth / 2, screenheight / 2, 0);
1661     glPushMatrix();
1662     glScalef((float)screenwidth / 2, (float)screenheight / 2, 1);
1663     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1664     glDisable(GL_BLEND);
1665     glColor4f(0, 0, 0, 1.0);
1666     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1667     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1668     glDisable(GL_TEXTURE_2D);
1669     glBegin(GL_QUADS);
1670     glVertex3f(-1, -1, 0);
1671     glVertex3f(+1, -1, 0);
1672     glVertex3f(+1, +1, 0);
1673     glVertex3f(-1, +1, 0);
1674     glEnd();
1675     glEnable(GL_BLEND);
1676     glColor4f(0.4, 0.4, 0.4, 1.0);
1677     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1678     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1679     glEnable(GL_TEXTURE_2D);
1680     Game::Mainmenuitems[4].bind();
1681     glBegin(GL_QUADS);
1682     glTexCoord2f(0, 0);
1683     glVertex3f(-1, -1, 0);
1684     glTexCoord2f(1, 0);
1685     glVertex3f(+1, -1, 0);
1686     glTexCoord2f(1, 1);
1687     glVertex3f(+1, +1, 0);
1688     glTexCoord2f(0, 1);
1689     glVertex3f(-1, +1, 0);
1690     glEnd();
1691     glPopMatrix();
1692     glPopMatrix();
1693     glMatrixMode(GL_PROJECTION);
1694     glPopMatrix();
1695     glMatrixMode(GL_MODELVIEW);
1696
1697     glMatrixMode(GL_PROJECTION);
1698     glPushMatrix();
1699     glLoadIdentity();
1700     glOrtho(0, 640, 0, 480, -100, 100);
1701     glMatrixMode(GL_MODELVIEW);
1702     glPushMatrix();
1703     glLoadIdentity();
1704     glEnable(GL_TEXTURE_2D);
1705
1706     Menu::drawItems();
1707
1708     //draw mouse cursor
1709     glMatrixMode(GL_PROJECTION);
1710     glPopMatrix();
1711     glMatrixMode(GL_MODELVIEW);
1712     glPopMatrix();
1713
1714     glMatrixMode(GL_PROJECTION);
1715     glPushMatrix();
1716     glLoadIdentity();
1717     glOrtho(0, screenwidth, 0, screenheight, -100, 100);
1718     glMatrixMode(GL_MODELVIEW);
1719     glPushMatrix();
1720     glLoadIdentity();
1721     glTranslatef(screenwidth / 2, screenheight / 2, 0);
1722     glPushMatrix();
1723     glScalef((float)screenwidth / 2, (float)screenheight / 2, 1);
1724     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1725     glEnable(GL_BLEND);
1726     glEnable(GL_TEXTURE_2D);
1727     glColor4f(1, 1, 1, 1);
1728     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1729     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1730     glPopMatrix();
1731     if (!Game::waiting) { // hide the cursor while waiting for a key
1732         glPushMatrix();
1733         glTranslatef(Game::mousecoordh - screenwidth / 2, Game::mousecoordv * -1 + screenheight / 2, 0);
1734         glScalef((float)screenwidth / 64, (float)screenwidth / 64, 1);
1735         glTranslatef(1, -1, 0);
1736         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1737         glColor4f(1, 1, 1, 1);
1738         Game::cursortexture.bind();
1739         glPushMatrix();
1740         glBegin(GL_QUADS);
1741         glTexCoord2f(0, 0);
1742         glVertex3f(-1, -1, 0.0f);
1743         glTexCoord2f(1, 0);
1744         glVertex3f(1, -1, 0.0f);
1745         glTexCoord2f(1, 1);
1746         glVertex3f(1, 1, 0.0f);
1747         glTexCoord2f(0, 1);
1748         glVertex3f(-1, 1, 0.0f);
1749         glEnd();
1750         glPopMatrix();
1751         glPopMatrix();
1752     }
1753     glPopMatrix();
1754     glMatrixMode(GL_PROJECTION);
1755     glPopMatrix();
1756
1757     //draw screen flash
1758     if (flashamount > 0) {
1759         if (flashamount > 1) {
1760             flashamount = 1;
1761         }
1762         if (flashdelay <= 0) {
1763             flashamount -= multiplier;
1764         }
1765         flashdelay--;
1766         if (flashamount < 0) {
1767             flashamount = 0;
1768         }
1769         glDisable(GL_DEPTH_TEST);
1770         glDisable(GL_CULL_FACE);
1771         glDisable(GL_LIGHTING);
1772         glDisable(GL_TEXTURE_2D);
1773         glDepthMask(0);
1774         glMatrixMode(GL_PROJECTION);
1775         glPushMatrix();
1776         glLoadIdentity();
1777         glOrtho(0, screenwidth, 0, screenheight, -100, 100);
1778         glMatrixMode(GL_MODELVIEW);
1779         glPushMatrix();
1780         glLoadIdentity();
1781         glScalef(screenwidth, screenheight, 1);
1782         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1783         glEnable(GL_BLEND);
1784         glColor4f(flashr, flashg, flashb, flashamount);
1785         glBegin(GL_QUADS);
1786         glVertex3f(0, 0, 0.0f);
1787         glVertex3f(256, 0, 0.0f);
1788         glVertex3f(256, 256, 0.0f);
1789         glVertex3f(0, 256, 0.0f);
1790         glEnd();
1791         glMatrixMode(GL_PROJECTION);
1792         glPopMatrix();
1793         glMatrixMode(GL_MODELVIEW);
1794         glPopMatrix();
1795         glEnable(GL_DEPTH_TEST);
1796         glEnable(GL_CULL_FACE);
1797         glDisable(GL_BLEND);
1798         glDepthMask(1);
1799     }
1800 }