]> git.jsancho.org Git - lugaru.git/blob - Source/GameDraw.cpp
Added braces to all statements with clang-tidy and ran clang-format again
[lugaru.git] / Source / GameDraw.cpp
1 /*
2 Copyright (C) 2003, 2010 - Wolfire Games
3 Copyright (C) 2010-2016 - 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((int)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             if (Dialog::inDialog() && !mainmenu) {
668                 glDisable(GL_DEPTH_TEST);
669                 glDisable(GL_CULL_FACE);
670                 glDisable(GL_LIGHTING);
671                 glDisable(GL_TEXTURE_2D);
672                 glDepthMask(0);
673                 glMatrixMode(GL_PROJECTION);
674                 glPushMatrix();
675                 glLoadIdentity();
676                 glOrtho(0, screenwidth, 0, screenheight, -100, 100);
677                 glMatrixMode(GL_MODELVIEW);
678                 glPushMatrix();
679                 glLoadIdentity();
680                 if (Dialog::currentScene().location == 1) {
681                     glTranslatef(0, screenheight * 3 / 4, 0);
682                 }
683                 glScalef(screenwidth, screenheight / 4, 1);
684                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
685                 glEnable(GL_BLEND);
686
687                 glColor4f(Dialog::currentScene().color[0], Dialog::currentScene().color[1], Dialog::currentScene().color[2], 0.7);
688                 glBegin(GL_QUADS);
689                 glVertex3f(0, 0, 0.0f);
690                 glVertex3f(1, 0, 0.0f);
691                 glVertex3f(1, 1, 0.0f);
692                 glVertex3f(0, 1, 0.0f);
693                 glEnd();
694                 glMatrixMode(GL_PROJECTION);
695                 glPopMatrix();
696                 glMatrixMode(GL_MODELVIEW);
697                 glPopMatrix();
698                 glEnable(GL_DEPTH_TEST);
699                 glEnable(GL_CULL_FACE);
700                 glDisable(GL_BLEND);
701                 glDepthMask(1);
702                 glEnable(GL_TEXTURE_2D);
703
704                 tutorialopac = 1;
705
706                 float startx;
707                 float starty;
708
709                 startx = screenwidth * 1 / 5;
710                 if (Dialog::currentScene().location == 1) {
711                     starty = screenheight / 16 + screenheight * 4 / 5;
712                 } else {
713                     starty = screenheight * 1 / 5 - screenheight / 16;
714                 }
715
716                 // FIXME - What is that char[] building for?
717                 char tempname[264];
718                 int tempnum = 0;
719                 for (int i = 0; i < 264; i++) {
720                     tempname[i] = '\0';
721                 }
722
723                 for (unsigned i = 0; i < Dialog::currentScene().name.size(); i++) {
724                     tempname[tempnum] = Dialog::currentScene().name[i];
725                     if (tempname[tempnum] == '#' || tempname[tempnum] == '\0') {
726                         tempname[tempnum] = '\0';
727                     } else {
728                         tempnum++;
729                     }
730                 }
731
732                 string = std::string(tempname) + ": ";
733
734                 if (Dialog::currentScene().color[0] + Dialog::currentScene().color[1] + Dialog::currentScene().color[2] < 1.5) {
735                     text->glPrintOutlined(0.7, 0.7, 0.7, tutorialopac, startx - 2 * 7.6 * string.size() * screenwidth / 1024, starty, string, 1, 1.5 * screenwidth / 1024, screenwidth, screenheight);
736                 } else {
737                     glColor4f(0, 0, 0, tutorialopac);
738                     text->glPrintOutline(startx - 2 * 7.6 * string.size() * screenwidth / 1024 - 4, starty - 4, string, 1, 1.5 * 1.25 * screenwidth / 1024, screenwidth, screenheight);
739                 }
740
741                 tempnum = 0;
742                 for (unsigned i = 0; i < Dialog::currentScene().text.size() + 1; i++) {
743                     tempname[tempnum] = Dialog::currentScene().text[i];
744                     if (Dialog::currentScene().text[i] != '#') {
745                         tempnum++;
746                     }
747                 }
748
749                 string = tempname;
750
751                 int lastline = 0;
752                 int line = 0;
753                 bool done = false;
754                 int i = 0;
755                 while (!done) {
756                     if (string[i] == '\n' || string[i] > 'z' || string[i] < ' ' || string[i] == '\0') {
757                         if (Dialog::currentScene().color[0] + Dialog::currentScene().color[1] + Dialog::currentScene().color[2] < 1.5) {
758                             text->glPrintOutlined(1, 1, 1, tutorialopac, startx, starty - 20 * screenwidth / 1024 * line, string, 1, 1.5 * screenwidth / 1024, screenwidth, screenheight, lastline, i);
759                         } else {
760                             glColor4f(0, 0, 0, tutorialopac);
761                             text->glPrint(startx, starty - 20 * screenwidth / 1024 * line, string, 1, 1.5 * screenwidth / 1024, screenwidth, screenheight, lastline, i);
762                         }
763                         lastline = i + 1;
764                         line++;
765                         if (string[i] == '\0') {
766                             done = 1;
767                         }
768                     }
769                     if (i >= 255) {
770                         done = 1;
771                     }
772                     i++;
773                 }
774             }
775
776             if (!Tutorial::active && !winfreeze && !Dialog::inDialog() && !mainmenu) {
777                 if (campaign) {
778                     if (scoreadded) {
779                         string = "Score: " + to_string(int(Account::active().getCampaignScore()));
780                     } else {
781                         string = "Score: " + to_string(int(Account::active().getCampaignScore() + bonustotal));
782                     }
783                 } else {
784                     string = "Score: " + to_string(int(bonustotal));
785                 }
786                 text->glPrintOutlined(1, 0, 0, 1, 1024 / 40, 768 / 16 + 768 * 14 / 16, string, 1, 1.5, 1024, 768);
787                 if (showdamagebar) {
788                     glDisable(GL_DEPTH_TEST);
789                     glDisable(GL_CULL_FACE);
790                     glDisable(GL_LIGHTING);
791                     glDisable(GL_TEXTURE_2D);
792                     glDepthMask(0);
793                     glMatrixMode(GL_PROJECTION);
794                     glPushMatrix();
795                     glLoadIdentity();
796                     glOrtho(0, screenwidth, 0, screenheight, -100, 100);
797                     glMatrixMode(GL_MODELVIEW);
798                     glPushMatrix();
799                     glLoadIdentity();
800                     glTranslatef(15, screenheight * 17.5 / 20, 0);
801                     glScalef(screenwidth / 3 + 20, screenheight / 20, 1);
802                     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
803                     glEnable(GL_BLEND);
804                     glColor4f(0.0, 0.4, 0.0, 0.7);
805                     float bar = ((float)Person::players[0]->damage) / Person::players[0]->damagetolerance;
806                     glBegin(GL_QUADS);
807                     glVertex3f((bar < 1 ? bar : 1), 0, 0.0f);
808                     glVertex3f(1, 0, 0.0f);
809                     glVertex3f(1, 1, 0.0f);
810                     glVertex3f((bar < 1 ? bar : 1), 1, 0.0f);
811                     glEnd();
812                     glColor4f(0.1, 0.0, 0.0, 1);
813                     bar = ((float)Person::players[0]->bloodloss) / Person::players[0]->damagetolerance;
814                     glBegin(GL_QUADS);
815                     glVertex3f(0, 0, 0.0f);
816                     glVertex3f((bar < 1 ? bar : 1), 0, 0.0f);
817                     glVertex3f((bar < 1 ? bar : 1), 1, 0.0f);
818                     glVertex3f(0, 1, 0.0f);
819                     glEnd();
820                     glColor4f(0.4, 0.0, 0.0, 0.7);
821                     bar = ((float)Person::players[0]->damage) / Person::players[0]->damagetolerance;
822                     glBegin(GL_QUADS);
823                     glVertex3f(0, 0, 0.0f);
824                     glVertex3f((bar < 1 ? bar : 1), 0, 0.0f);
825                     glVertex3f((bar < 1 ? bar : 1), 1, 0.0f);
826                     glVertex3f(0, 1, 0.0f);
827                     glEnd();
828                     glColor4f(0.4, 0.0, 0.0, 0.7);
829                     bar = ((float)Person::players[0]->permanentdamage) / Person::players[0]->damagetolerance;
830                     glBegin(GL_QUADS);
831                     glVertex3f(0, 0, 0.0f);
832                     glVertex3f((bar < 1 ? bar : 1), 0, 0.0f);
833                     glVertex3f((bar < 1 ? bar : 1), 1, 0.0f);
834                     glVertex3f(0, 1, 0.0f);
835                     glEnd();
836                     glColor4f(0.4, 0.0, 0.0, 0.7);
837                     bar = ((float)Person::players[0]->superpermanentdamage) / Person::players[0]->damagetolerance;
838                     glBegin(GL_QUADS);
839                     glVertex3f(0, 0, 0.0f);
840                     glVertex3f((bar < 1 ? bar : 1), 0, 0.0f);
841                     glVertex3f((bar < 1 ? bar : 1), 1, 0.0f);
842                     glVertex3f(0, 1, 0.0f);
843                     glEnd();
844                     glColor4f(0.0, 0.0, 0.0, 0.7);
845                     glLineWidth(2.0);
846                     glBegin(GL_LINE_STRIP);
847                     glVertex3f(0, 0, 0.0f);
848                     glVertex3f(1, 0, 0.0f);
849                     glVertex3f(1, 1, 0.0f);
850                     glVertex3f(0, 1, 0.0f);
851                     glVertex3f(0, 0, 0.0f);
852                     glEnd();
853
854                     glMatrixMode(GL_PROJECTION);
855                     glPopMatrix();
856                     glMatrixMode(GL_MODELVIEW);
857                     glPopMatrix();
858                     glEnable(GL_DEPTH_TEST);
859                     glEnable(GL_CULL_FACE);
860                     glDisable(GL_BLEND);
861                     glDepthMask(1);
862                     glEnable(GL_TEXTURE_2D);
863
864                     // writing the numbers :
865                     string = "Damages : " + to_string(int(Person::players[0]->damage)) + "/" + to_string(int(Person::players[0]->damagetolerance)) + " (" + to_string(int(Person::players[0]->bloodloss)) + ")";
866                     text->glPrintOutlined(1, 0, 0, 1, 1024 / 40, 768 / 16 + 768 * 14 / 16 - 40, string, 1, 1.5, 1024, 768);
867                 }
868             }
869
870             glColor4f(.5, .5, .5, 1);
871
872             if ((texttoggle || editorenabled) && devtools && !mainmenu) {
873                 string = "The framespersecond is " + to_string(int(fps));
874                 text->glPrint(10, 30, string, 0, .8, 1024, 768);
875
876                 if (editorenabled) {
877                     string = "Map editor enabled.";
878                 } else {
879                     string = "Map editor disabled.";
880                 }
881                 text->glPrint(10, 60, string, 0, .8, 1024, 768);
882                 if (editorenabled) {
883                     string = "Object size: " + to_string(editorsize);
884                     text->glPrint(10, 75, string, 0, .8, 1024, 768);
885                     if (editoryaw >= 0) {
886                         string = "Object yaw: " + to_string(editoryaw);
887                     } else {
888                         string = "Object yaw: Random";
889                     }
890                     text->glPrint(10, 90, string, 0, .8, 1024, 768);
891                     if (editorpitch >= 0) {
892                         string = "Object pitch: " + to_string(editorpitch);
893                     } else {
894                         string = "Object pitch: Random";
895                     }
896                     text->glPrint(10, 105, string, 0, .8, 1024, 768);
897                     string = "Object type: " + to_string(editortype);
898                     text->glPrint(10, 120, string, 0, .8, 1024, 768);
899                     switch (editortype) {
900                         case boxtype:
901                             string = "(box)";
902                             break;
903                         case treetrunktype:
904                             string = "(tree)";
905                             break;
906                         case walltype:
907                             string = "(wall)";
908                             break;
909                         case weirdtype:
910                             string = "(weird)";
911                             break;
912                         case spiketype:
913                             string = "(spike)";
914                             break;
915                         case rocktype:
916                             string = "(rock)";
917                             break;
918                         case bushtype:
919                             string = "(bush)";
920                             break;
921                         case tunneltype:
922                             string = "(tunnel)";
923                             break;
924                         case chimneytype:
925                             string = "(chimney)";
926                             break;
927                         case platformtype:
928                             string = "(platform)";
929                             break;
930                         case cooltype:
931                             string = "(cool)";
932                             break;
933                         case firetype:
934                             string = "(fire)";
935                             break;
936                     }
937                     text->glPrint(130, 120, string, 0, .8, 1024, 768);
938
939                     string = "Numplayers: " + to_string(Person::players.size());
940                     text->glPrint(10, 155, string, 0, .8, 1024, 768);
941                     string = "Player " + to_string(int(Person::players.size()) - 1) + ": numwaypoints: " + to_string(Person::players.back()->numwaypoints);
942                     text->glPrint(10, 140, string, 0, .8, 1024, 768);
943                 }
944                 string = "Difficulty: " + to_string(difficulty);
945                 text->glPrint(10, 240, string, 0, .8, 1024, 768);
946             }
947         }
948
949         if (drawmode == glowmode) {
950             glDisable(GL_DEPTH_TEST);
951             glDisable(GL_CULL_FACE);
952             glDisable(GL_LIGHTING);
953             glDisable(GL_TEXTURE_2D);
954             glDepthMask(0);
955             glMatrixMode(GL_PROJECTION);
956             glPushMatrix();
957             glLoadIdentity();
958             glOrtho(0, screenwidth, 0, screenheight, -100, 100);
959             glMatrixMode(GL_MODELVIEW);
960             glPushMatrix();
961             glLoadIdentity();
962             glScalef(screenwidth, screenheight, 1);
963             glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
964             glEnable(GL_BLEND);
965             glColor4f(0, 0, 0, .5);
966             glBegin(GL_QUADS);
967             glVertex3f(0, 0, 0.0f);
968             glVertex3f(256, 0, 0.0f);
969             glVertex3f(256, 256, 0.0f);
970             glVertex3f(0, 256, 0.0f);
971             glEnd();
972             glMatrixMode(GL_PROJECTION);
973             glPopMatrix();
974             glMatrixMode(GL_MODELVIEW);
975             glPopMatrix();
976             glEnable(GL_DEPTH_TEST);
977             glEnable(GL_CULL_FACE);
978             glDisable(GL_BLEND);
979             glDepthMask(1);
980         }
981
982         if ((((blackout && damageeffects) || (Person::players[0]->bloodloss > 0 && damageeffects && Person::players[0]->blooddimamount > 0) || Person::players[0]->dead) && !cameramode) || console) {
983             glDisable(GL_DEPTH_TEST);
984             glDisable(GL_CULL_FACE);
985             glDisable(GL_LIGHTING);
986             glDisable(GL_TEXTURE_2D);
987             glDepthMask(0);
988             glMatrixMode(GL_PROJECTION);
989             glPushMatrix();
990             glLoadIdentity();
991             glOrtho(0, screenwidth, 0, screenheight, -100, 100);
992             glMatrixMode(GL_MODELVIEW);
993             glPushMatrix();
994             glLoadIdentity();
995             glScalef(screenwidth, screenheight, 1);
996             glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
997             glEnable(GL_BLEND);
998             if (Person::players[0]->dead) {
999                 blackout += multiplier * 3;
1000             }
1001             if (Person::players[0]->dead == 1) {
1002                 blackout = .4f;
1003             }
1004             if (Person::players[0]->dead == 2 && blackout > .6) {
1005                 blackout = .6;
1006             }
1007             glColor4f(0, 0, 0, blackout);
1008             if (!Person::players[0]->dead) {
1009                 if ((Person::players[0]->bloodloss / Person::players[0]->damagetolerance * (sin(woozy) / 4 + .5)) * .3 < .3) {
1010                     glColor4f(0, 0, 0, Person::players[0]->blooddimamount * Person::players[0]->bloodloss / Person::players[0]->damagetolerance * (sin(woozy) / 4 + .5) * .3);
1011                     blackout = Person::players[0]->blooddimamount * Person::players[0]->bloodloss / Person::players[0]->damagetolerance * (sin(woozy) / 4 + .5) * .3;
1012                 } else {
1013                     glColor4f(0, 0, 0, Person::players[0]->blooddimamount * .3);
1014                     blackout = Person::players[0]->blooddimamount * .3;
1015                 }
1016             }
1017             if (console) {
1018                 glColor4f(.7, 0, 0, .2);
1019             }
1020             glBegin(GL_QUADS);
1021             glVertex3f(0, 0, 0.0f);
1022             glVertex3f(256, 0, 0.0f);
1023             glVertex3f(256, 256, 0.0f);
1024             glVertex3f(0, 256, 0.0f);
1025             glEnd();
1026             glMatrixMode(GL_PROJECTION);
1027             glPopMatrix();
1028             glMatrixMode(GL_MODELVIEW);
1029             glPopMatrix();
1030             glEnable(GL_DEPTH_TEST);
1031             glEnable(GL_CULL_FACE);
1032             glDisable(GL_BLEND);
1033             glDepthMask(1);
1034         }
1035
1036         if (flashamount > 0 && damageeffects) {
1037             if (flashamount > 1) {
1038                 flashamount = 1;
1039             }
1040             if (flashdelay <= 0) {
1041                 flashamount -= multiplier;
1042             }
1043             flashdelay--;
1044             if (flashamount < 0) {
1045                 flashamount = 0;
1046             }
1047             glDisable(GL_DEPTH_TEST);
1048             glDisable(GL_CULL_FACE);
1049             glDisable(GL_LIGHTING);
1050             glDepthMask(0);
1051             glMatrixMode(GL_PROJECTION);
1052             glPushMatrix();
1053             glLoadIdentity();
1054             glOrtho(0, screenwidth, 0, screenheight, -100, 100);
1055             glMatrixMode(GL_MODELVIEW);
1056             glPushMatrix();
1057             glLoadIdentity();
1058             glScalef(screenwidth, screenheight, 1);
1059             glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1060             glEnable(GL_BLEND);
1061             glColor4f(flashr, flashg, flashb, flashamount);
1062             glBegin(GL_QUADS);
1063             glVertex3f(0, 0, 0.0f);
1064             glVertex3f(256, 0, 0.0f);
1065             glVertex3f(256, 256, 0.0f);
1066             glVertex3f(0, 256, 0.0f);
1067             glEnd();
1068             glMatrixMode(GL_PROJECTION);
1069             glPopMatrix();
1070             glMatrixMode(GL_MODELVIEW);
1071             glPopMatrix();
1072             glEnable(GL_DEPTH_TEST);
1073             glEnable(GL_CULL_FACE);
1074             glDisable(GL_BLEND);
1075             glDepthMask(1);
1076         }
1077
1078         if (difficulty < 2 && !Dialog::inDialog()) { // minimap
1079             float mapviewdist = 20000;
1080
1081             glDisable(GL_DEPTH_TEST);
1082             glColor3f(1.0, 1.0, 1.0); // no coloring
1083
1084             glEnable(GL_TEXTURE_2D);
1085             glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1086             glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1087             glDisable(GL_DEPTH_TEST);
1088             glDisable(GL_CULL_FACE);
1089             glDisable(GL_LIGHTING);
1090             glDepthMask(0);
1091             glMatrixMode(GL_PROJECTION);
1092             glPushMatrix();
1093             glLoadIdentity();
1094             glOrtho(0, screenwidth, 0, screenheight, -100, 100);
1095             glMatrixMode(GL_MODELVIEW);
1096             glPushMatrix();
1097             glLoadIdentity();
1098             glScalef((float)screenwidth / 2, (float)screenwidth / 2, 1);
1099             glTranslatef(1.75, .25, 0);
1100             glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1101             glEnable(GL_BLEND);
1102             glColor4f(1, 1, 1, 1);
1103             glPushMatrix();
1104             float opac = .7;
1105             XYZ center;
1106             float radius;
1107             float distcheck;
1108
1109             center = Person::players[0]->coords;
1110
1111             radius = 110;
1112
1113             glScalef(.25 / radius * 256 * terrain.scale * .4, .25 / radius * 256 * terrain.scale * .4, 1);
1114             glPushMatrix();
1115             glScalef(1 / (1 / radius * 256 * terrain.scale * .4), 1 / (1 / radius * 256 * terrain.scale * .4), 1);
1116             glPopMatrix();
1117             glRotatef(Person::players[0]->lookyaw * -1 + 180, 0, 0, 1);
1118             glTranslatef(-(center.x / terrain.scale / 256 * -2 + 1), (center.z / terrain.scale / 256 * -2 + 1), 0);
1119             for (unsigned int i = 0; i < Object::objects.size(); i++) {
1120                 if (Object::objects[i]->type == treetrunktype) {
1121                     distcheck = distsq(&Person::players[0]->coords, &Object::objects[i]->position);
1122                     if (distcheck < mapviewdist) {
1123                         Mapcircletexture.bind();
1124                         glColor4f(0, .3, 0, opac * (1 - distcheck / mapviewdist));
1125                         glPushMatrix();
1126                         glTranslatef(Object::objects[i]->position.x / terrain.scale / 256 * -2 + 1, Object::objects[i]->position.z / terrain.scale / 256 * 2 - 1, 0);
1127                         glRotatef(Object::objects[i]->yaw, 0, 0, 1);
1128                         glScalef(.003, .003, .003);
1129                         glBegin(GL_QUADS);
1130                         glTexCoord2f(0, 0);
1131                         glVertex3f(-1, -1, 0.0f);
1132                         glTexCoord2f(1, 0);
1133                         glVertex3f(1, -1, 0.0f);
1134                         glTexCoord2f(1, 1);
1135                         glVertex3f(1, 1, 0.0f);
1136                         glTexCoord2f(0, 1);
1137                         glVertex3f(-1, 1, 0.0f);
1138                         glEnd();
1139                         glPopMatrix();
1140                     }
1141                 }
1142                 if (Object::objects[i]->type == boxtype) {
1143                     distcheck = distsq(&Person::players[0]->coords, &Object::objects[i]->position);
1144                     if (distcheck < mapviewdist) {
1145                         Mapboxtexture.bind();
1146                         glColor4f(.4, .4, .4, opac * (1 - distcheck / mapviewdist));
1147                         glPushMatrix();
1148                         glTranslatef(Object::objects[i]->position.x / terrain.scale / 256 * -2 + 1, Object::objects[i]->position.z / terrain.scale / 256 * 2 - 1, 0);
1149                         glRotatef(Object::objects[i]->yaw, 0, 0, 1);
1150                         glScalef(.01 * Object::objects[i]->scale, .01 * Object::objects[i]->scale, .01 * Object::objects[i]->scale);
1151                         glBegin(GL_QUADS);
1152                         glTexCoord2f(0, 0);
1153                         glVertex3f(-1, -1, 0.0f);
1154                         glTexCoord2f(1, 0);
1155                         glVertex3f(1, -1, 0.0f);
1156                         glTexCoord2f(1, 1);
1157                         glVertex3f(1, 1, 0.0f);
1158                         glTexCoord2f(0, 1);
1159                         glVertex3f(-1, 1, 0.0f);
1160                         glEnd();
1161                         glPopMatrix();
1162                     }
1163                 }
1164             }
1165             if (editorenabled) {
1166                 Mapcircletexture.bind();
1167                 for (int i = 0; i < numboundaries; i++) {
1168                     glColor4f(0, 0, 0, opac / 3);
1169                     glPushMatrix();
1170                     glTranslatef(boundary[i].x / terrain.scale / 256 * -2 + 1, boundary[i].z / terrain.scale / 256 * 2 - 1, 0);
1171                     glScalef(.002, .002, .002);
1172                     glBegin(GL_QUADS);
1173                     glTexCoord2f(0, 0);
1174                     glVertex3f(-1, -1, 0.0f);
1175                     glTexCoord2f(1, 0);
1176                     glVertex3f(1, -1, 0.0f);
1177                     glTexCoord2f(1, 1);
1178                     glVertex3f(1, 1, 0.0f);
1179                     glTexCoord2f(0, 1);
1180                     glVertex3f(-1, 1, 0.0f);
1181                     glEnd();
1182                     glPopMatrix();
1183                 }
1184             }
1185             for (unsigned i = 0; i < Person::players.size(); i++) {
1186                 distcheck = distsq(&Person::players[0]->coords, &Person::players[i]->coords);
1187                 if (distcheck < mapviewdist) {
1188                     glPushMatrix();
1189                     Maparrowtexture.bind();
1190                     if (i == 0) {
1191                         glColor4f(1, 1, 1, opac);
1192                     } else if (Person::players[i]->dead == 2 || Person::players[i]->howactive > typesleeping) {
1193                         glColor4f(0, 0, 0, opac * (1 - distcheck / mapviewdist));
1194                     } else if (Person::players[i]->dead) {
1195                         glColor4f(.3, .3, .3, opac * (1 - distcheck / mapviewdist));
1196                     } else if (Person::players[i]->aitype == attacktypecutoff) {
1197                         glColor4f(1, 0, 0, opac * (1 - distcheck / mapviewdist));
1198                     } else if (Person::players[i]->aitype == passivetype) {
1199                         glColor4f(0, 1, 0, opac * (1 - distcheck / mapviewdist));
1200                     } else {
1201                         glColor4f(1, 1, 0, 1);
1202                     }
1203                     glTranslatef(Person::players[i]->coords.x / terrain.scale / 256 * -2 + 1, Person::players[i]->coords.z / terrain.scale / 256 * 2 - 1, 0);
1204                     glRotatef(Person::players[i]->yaw + 180, 0, 0, 1);
1205                     glScalef(.005, .005, .005);
1206                     glBegin(GL_QUADS);
1207                     glTexCoord2f(0, 0);
1208                     glVertex3f(-1, -1, 0.0f);
1209                     glTexCoord2f(1, 0);
1210                     glVertex3f(1, -1, 0.0f);
1211                     glTexCoord2f(1, 1);
1212                     glVertex3f(1, 1, 0.0f);
1213                     glTexCoord2f(0, 1);
1214                     glVertex3f(-1, 1, 0.0f);
1215                     glEnd();
1216                     glPopMatrix();
1217                 }
1218             }
1219             glPopMatrix();
1220             glDisable(GL_TEXTURE_2D);
1221             glMatrixMode(GL_PROJECTION);
1222             glPopMatrix();
1223             glMatrixMode(GL_MODELVIEW);
1224             glPopMatrix();
1225             glEnable(GL_DEPTH_TEST);
1226             glEnable(GL_CULL_FACE);
1227             glDisable(GL_BLEND);
1228             glDepthMask(1);
1229         }
1230
1231         if (loading && !stealthloading && (!campaign || Person::players[0]->dead)) {
1232             glDisable(GL_DEPTH_TEST);
1233             glDisable(GL_CULL_FACE);
1234             glDisable(GL_LIGHTING);
1235             glDisable(GL_TEXTURE_2D);
1236             glDepthMask(0);
1237             glMatrixMode(GL_PROJECTION);
1238             glPushMatrix();
1239             glLoadIdentity();
1240             glOrtho(0, screenwidth, 0, screenheight, -100, 100);
1241             glMatrixMode(GL_MODELVIEW);
1242             glPushMatrix();
1243             glLoadIdentity();
1244             glScalef(screenwidth, screenheight, 1);
1245             glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1246             glEnable(GL_BLEND);
1247             glColor4f(0, 0, 0, .7);
1248             glBegin(GL_QUADS);
1249             glVertex3f(0, 0, 0.0f);
1250             glVertex3f(256, 0, 0.0f);
1251             glVertex3f(256, 256, 0.0f);
1252             glVertex3f(0, 256, 0.0f);
1253             glEnd();
1254             glMatrixMode(GL_PROJECTION);
1255             glPopMatrix();
1256             glMatrixMode(GL_MODELVIEW);
1257             glPopMatrix();
1258             glEnable(GL_DEPTH_TEST);
1259             glEnable(GL_CULL_FACE);
1260             glDisable(GL_BLEND);
1261             glDepthMask(1);
1262
1263             //logo
1264             glDisable(GL_DEPTH_TEST);
1265             glColor3f(1.0, 1.0, 1.0); // no coloring
1266
1267             glEnable(GL_TEXTURE_2D);
1268
1269             //Minimap
1270
1271             if (loading != 4) {
1272                 glEnable(GL_TEXTURE_2D);
1273                 glColor4f(1, 1, 1, 1);
1274                 string = "Loading...";
1275                 text->glPrint(1024 / 2 - 90, 768 / 2, string, 1, 2, 1024, 768);
1276             }
1277             loading = 2;
1278             drawmode = normalmode;
1279         }
1280
1281         if (winfreeze && !campaign) {
1282             glDisable(GL_DEPTH_TEST);
1283             glDisable(GL_CULL_FACE);
1284             glDisable(GL_LIGHTING);
1285             glDisable(GL_TEXTURE_2D);
1286             glDepthMask(0);
1287             glMatrixMode(GL_PROJECTION);
1288             glPushMatrix();
1289             glLoadIdentity();
1290             glOrtho(0, screenwidth, 0, screenheight, -100, 100);
1291             glMatrixMode(GL_MODELVIEW);
1292             glPushMatrix();
1293             glLoadIdentity();
1294             glScalef(screenwidth, screenheight, 1);
1295             glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1296             glEnable(GL_BLEND);
1297             glColor4f(0, 0, 0, .4);
1298             glBegin(GL_QUADS);
1299             glVertex3f(0, 0, 0.0f);
1300             glVertex3f(256, 0, 0.0f);
1301             glVertex3f(256, 256, 0.0f);
1302             glVertex3f(0, 256, 0.0f);
1303             glEnd();
1304             glMatrixMode(GL_PROJECTION);
1305             glPopMatrix();
1306             glMatrixMode(GL_MODELVIEW);
1307             glPopMatrix();
1308             glEnable(GL_DEPTH_TEST);
1309             glEnable(GL_CULL_FACE);
1310             glDisable(GL_BLEND);
1311             glDepthMask(1);
1312
1313             //logo
1314             glDisable(GL_DEPTH_TEST);
1315             glColor3f(1.0, 1.0, 1.0); // no coloring
1316
1317             glEnable(GL_TEXTURE_2D);
1318
1319             //Win Screen Won Victory
1320
1321             glEnable(GL_TEXTURE_2D);
1322             glColor4f(1, 1, 1, 1);
1323             string = "Level Cleared!";
1324             text->glPrintOutlined(1024 / 2 - string.size() * 10, 768 * 7 / 8, string, 1, 2, 1024, 768);
1325
1326             string = "Score:     " + to_string(int(bonustotal - startbonustotal));
1327             text->glPrintOutlined(1024 / 30, 768 * 6 / 8, string, 1, 2, 1024, 768);
1328
1329             string = "Press Escape to return to menu or Space to continue";
1330             text->glPrintOutlined(640 / 2 - string.size() * 5, 480 * 1 / 16, string, 1, 1, 640, 480);
1331
1332             int wontime = (int)round(wonleveltime);
1333             string = "Time:      " + to_string(int((wontime - wontime % 60) / 60));
1334             if (wontime % 60 < 10) {
1335                 string += "0";
1336             }
1337             string += to_string(int(wontime % 60));
1338             text->glPrintOutlined(1024 / 30, 768 * 6 / 8 - 40, string, 1, 2, 1024, 768);
1339
1340             //Awards
1341             int awards[award_count];
1342             int numawards = award_awards(awards);
1343
1344             for (int i = 0; i < numawards && i < 6; i++) {
1345                 text->glPrintOutlined(1024 / 30, 768 * 6 / 8 - 90 - 40 * i, award_names[awards[i]], 1, 2, 1024, 768);
1346             }
1347         }
1348
1349         if (drawmode != normalmode) {
1350             glEnable(GL_TEXTURE_2D);
1351             glFinish();
1352             if (!drawtoggle || drawmode != realmotionblurmode || (drawtoggle == 2 || change == 1)) {
1353                 if (screentexture) {
1354
1355                     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
1356                     GLfloat subtractColor[4] = { 0.5, 0.5, 0.5, 0.0 };
1357                     glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, subtractColor);
1358                     glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE);
1359                     glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_CONSTANT);
1360                     glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE, 2.0f);
1361
1362                     glBindTexture(GL_TEXTURE_2D, screentexture);
1363                     glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, texviewwidth, texviewheight);
1364                 }
1365             }
1366             if ((drawtoggle || change == 1) && drawmode == realmotionblurmode) {
1367                 if (screentexture2) {
1368                     glBindTexture(GL_TEXTURE_2D, screentexture2);
1369                     glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, texviewwidth, texviewheight);
1370                 }
1371                 if (!screentexture2) {
1372                     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1373
1374                     glGenTextures(1, &screentexture2);
1375                     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
1376
1377                     glEnable(GL_TEXTURE_2D);
1378                     glBindTexture(GL_TEXTURE_2D, screentexture2);
1379                     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1380                     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1381
1382                     glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, kTextureSize, kTextureSize, 0);
1383                 }
1384             }
1385         }
1386
1387         glClear(GL_DEPTH_BUFFER_BIT);
1388         Game::ReSizeGLScene(90, .1f);
1389         glViewport(0, 0, screenwidth, screenheight);
1390
1391         if (drawmode != normalmode) {
1392             glDisable(GL_DEPTH_TEST);
1393             if (drawmode == motionblurmode) {
1394                 glDrawBuffer(GL_FRONT);
1395                 glReadBuffer(GL_BACK);
1396             }
1397             glColor3f(1.0, 1.0, 1.0); // no coloring
1398
1399             glEnable(GL_TEXTURE_2D);
1400             glBindTexture(GL_TEXTURE_2D, screentexture);
1401             glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1402             glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1403             glDisable(GL_DEPTH_TEST);
1404             glDisable(GL_CULL_FACE);
1405             glDisable(GL_LIGHTING);
1406             glDepthMask(0);
1407             glMatrixMode(GL_PROJECTION);
1408             glPushMatrix();
1409             glLoadIdentity();
1410             glOrtho(0, screenwidth, 0, screenheight, -100, 100);
1411             glMatrixMode(GL_MODELVIEW);
1412             glPushMatrix();
1413             glLoadIdentity();
1414             glScalef((float)screenwidth / 2, (float)screenheight / 2, 1);
1415             glTranslatef(1, 1, 0);
1416             glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1417             glEnable(GL_BLEND);
1418             if (drawmode == motionblurmode) {
1419                 if (motionbluramount < .2) {
1420                     motionbluramount = .2;
1421                 }
1422                 glColor4f(1, 1, 1, motionbluramount);
1423                 glPushMatrix();
1424                 glBegin(GL_QUADS);
1425                 glTexCoord2f(0, 0);
1426                 glVertex3f(-1, -1, 0.0f);
1427                 glTexCoord2f(texcoordwidth, 0);
1428                 glVertex3f(1, -1, 0.0f);
1429                 glTexCoord2f(texcoordwidth, texcoordheight);
1430                 glVertex3f(1, 1, 0.0f);
1431                 glTexCoord2f(0, texcoordheight);
1432                 glVertex3f(-1, 1, 0.0f);
1433                 glEnd();
1434                 glPopMatrix();
1435             }
1436             if (drawmode == realmotionblurmode) {
1437                 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
1438                 glClear(GL_COLOR_BUFFER_BIT);
1439                 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
1440                 glBindTexture(GL_TEXTURE_2D, screentexture);
1441                 glColor4f(1, 1, 1, .5);
1442                 glPushMatrix();
1443                 glBegin(GL_QUADS);
1444                 glTexCoord2f(0, 0);
1445                 glVertex3f(-1, -1, 0.0f);
1446                 glTexCoord2f(texcoordwidth, 0);
1447                 glVertex3f(1, -1, 0.0f);
1448                 glTexCoord2f(texcoordwidth, texcoordheight);
1449                 glVertex3f(1, 1, 0.0f);
1450                 glTexCoord2f(0, texcoordheight);
1451                 glVertex3f(-1, 1, 0.0f);
1452                 glEnd();
1453                 glPopMatrix();
1454                 glBindTexture(GL_TEXTURE_2D, screentexture2);
1455                 glColor4f(1, 1, 1, .5);
1456                 glPushMatrix();
1457                 glBegin(GL_QUADS);
1458                 glTexCoord2f(0, 0);
1459                 glVertex3f(-1, -1, 0.0f);
1460                 glTexCoord2f(texcoordwidth, 0);
1461                 glVertex3f(1, -1, 0.0f);
1462                 glTexCoord2f(texcoordwidth, texcoordheight);
1463                 glVertex3f(1, 1, 0.0f);
1464                 glTexCoord2f(0, texcoordheight);
1465                 glVertex3f(-1, 1, 0.0f);
1466                 glEnd();
1467                 glPopMatrix();
1468                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1469             }
1470             if (drawmode == doublevisionmode) {
1471                 static float crosseyedness;
1472                 crosseyedness = abs(Person::players[0]->damage - Person::players[0]->superpermanentdamage - (Person::players[0]->damagetolerance - Person::players[0]->superpermanentdamage) * 1 / 2) / 30;
1473                 if (crosseyedness > 1) {
1474                     crosseyedness = 1;
1475                 }
1476                 if (crosseyedness < 0) {
1477                     crosseyedness = 0;
1478                 }
1479                 glColor4f(1, 1, 1, 1);
1480                 glDisable(GL_BLEND);
1481                 glPushMatrix();
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                 if (crosseyedness) {
1495                     glColor4f(1, 1, 1, .5);
1496                     glEnable(GL_BLEND);
1497                     glPushMatrix();
1498                     glTranslatef(.015 * crosseyedness, 0, 0);
1499                     glScalef(1, 1, 1);
1500                     glBegin(GL_QUADS);
1501                     glTexCoord2f(0, 0);
1502                     glVertex3f(-1, -1, 0.0f);
1503                     glTexCoord2f(texcoordwidth, 0);
1504                     glVertex3f(1, -1, 0.0f);
1505                     glTexCoord2f(texcoordwidth, texcoordheight);
1506                     glVertex3f(1, 1, 0.0f);
1507                     glTexCoord2f(0, texcoordheight);
1508                     glVertex3f(-1, 1, 0.0f);
1509                     glEnd();
1510                     glPopMatrix();
1511                 }
1512             }
1513             if (drawmode == glowmode) {
1514                 glColor4f(.5, .5, .5, .5);
1515                 glEnable(GL_BLEND);
1516                 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
1517                 glPushMatrix();
1518                 glTranslatef(.01, 0, 0);
1519                 glBegin(GL_QUADS);
1520                 glTexCoord2f(0, 0);
1521                 glVertex3f(-1, -1, 0.0f);
1522                 glTexCoord2f(texcoordwidth, 0);
1523                 glVertex3f(1, -1, 0.0f);
1524                 glTexCoord2f(texcoordwidth, texcoordheight);
1525                 glVertex3f(1, 1, 0.0f);
1526                 glTexCoord2f(0, texcoordheight);
1527                 glVertex3f(-1, 1, 0.0f);
1528                 glEnd();
1529                 glPopMatrix();
1530                 glPushMatrix();
1531                 glTranslatef(-.01, 0, 0);
1532                 glBegin(GL_QUADS);
1533                 glTexCoord2f(0, 0);
1534                 glVertex3f(-1, -1, 0.0f);
1535                 glTexCoord2f(texcoordwidth, 0);
1536                 glVertex3f(1, -1, 0.0f);
1537                 glTexCoord2f(texcoordwidth, texcoordheight);
1538                 glVertex3f(1, 1, 0.0f);
1539                 glTexCoord2f(0, texcoordheight);
1540                 glVertex3f(-1, 1, 0.0f);
1541                 glEnd();
1542                 glPopMatrix();
1543                 glPushMatrix();
1544                 glTranslatef(.0, .01, 0);
1545                 glBegin(GL_QUADS);
1546                 glTexCoord2f(0, 0);
1547                 glVertex3f(-1, -1, 0.0f);
1548                 glTexCoord2f(texcoordwidth, 0);
1549                 glVertex3f(1, -1, 0.0f);
1550                 glTexCoord2f(texcoordwidth, texcoordheight);
1551                 glVertex3f(1, 1, 0.0f);
1552                 glTexCoord2f(0, texcoordheight);
1553                 glVertex3f(-1, 1, 0.0f);
1554                 glEnd();
1555                 glPopMatrix();
1556                 glPushMatrix();
1557                 glTranslatef(0, -.01, 0);
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             if (drawmode == radialzoommode) {
1571                 for (int i = 0; i < 3; i++) {
1572                     glColor4f(1, 1, 1, 1 / ((float)i + 1));
1573                     glPushMatrix();
1574                     glScalef(1 + (float)i * .01, 1 + (float)i * .01, 1);
1575                     glBegin(GL_QUADS);
1576                     glTexCoord2f(0, 0);
1577                     glVertex3f(-1, -1, 0.0f);
1578                     glTexCoord2f(texcoordwidth, 0);
1579                     glVertex3f(1, -1, 0.0f);
1580                     glTexCoord2f(texcoordwidth, texcoordheight);
1581                     glVertex3f(1, 1, 0.0f);
1582                     glTexCoord2f(0, texcoordheight);
1583                     glVertex3f(-1, 1, 0.0f);
1584                     glEnd();
1585                     glPopMatrix();
1586                 }
1587             }
1588             glDisable(GL_TEXTURE_2D);
1589             glMatrixMode(GL_PROJECTION);
1590             glPopMatrix();
1591             glMatrixMode(GL_MODELVIEW);
1592             glPopMatrix();
1593             glEnable(GL_DEPTH_TEST);
1594             glEnable(GL_CULL_FACE);
1595             glDisable(GL_BLEND);
1596             glDepthMask(1);
1597         }
1598
1599         if (console) {
1600             glEnable(GL_TEXTURE_2D);
1601             glColor4f(1, 1, 1, 1);
1602             int offset = 0;
1603             if (consoleselected >= 60) {
1604                 offset = consoleselected - 60;
1605             }
1606             textmono->glPrint(10, 30, " ]", 0, 1, 1024, 768);
1607             if (consoleblink) {
1608                 textmono->glPrint(30 + (float)consoleselected * 10 - offset * 10, 30, "_", 0, 1, 1024, 768);
1609             }
1610             for (unsigned i = 0; i < 15; i++) {
1611                 textmono->glPrint(30 - offset * 10, 30 + i * 20, consoletext[i], 0, 1, 1024, 768);
1612             }
1613         }
1614     }
1615
1616     if (freeze || winfreeze || (mainmenu && gameon) || (!gameon && gamestarted)) {
1617         multiplier = tempmult;
1618     }
1619
1620     if (mainmenu) {
1621         DrawMenu();
1622     }
1623
1624     if (freeze || winfreeze || (mainmenu && gameon) || (!gameon && gamestarted)) {
1625         tempmult = multiplier;
1626         multiplier = 0;
1627     }
1628
1629     if (side == stereoRight || side == stereoCenter) {
1630         if (drawmode != motionblurmode || mainmenu) {
1631             swap_gl_buffers();
1632         }
1633     }
1634
1635     glDrawBuffer(GL_BACK);
1636     glReadBuffer(GL_BACK);
1637
1638     weapons.DoStuff();
1639
1640     if (drawtoggle == 2) {
1641         drawtoggle = 0;
1642     }
1643
1644     if (freeze || winfreeze || (mainmenu && gameon) || (!gameon && gamestarted)) {
1645         multiplier = tempmult;
1646     }
1647     //Jordan fixed your warning!
1648     return 0;
1649 }
1650
1651 void DrawMenu()
1652 {
1653     // !!! FIXME: hack: clamp framerate in menu so text input works correctly on fast systems.
1654     SDL_Delay(15);
1655
1656     glDrawBuffer(GL_BACK);
1657     glReadBuffer(GL_BACK);
1658     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
1659     Game::ReSizeGLScene(90, .1f);
1660
1661     //draw menu background
1662     glClear(GL_DEPTH_BUFFER_BIT);
1663     glEnable(GL_ALPHA_TEST);
1664     glAlphaFunc(GL_GREATER, 0.001f);
1665     glEnable(GL_TEXTURE_2D);
1666     glDisable(GL_DEPTH_TEST);
1667     glDisable(GL_CULL_FACE);
1668     glDisable(GL_LIGHTING);
1669     glDepthMask(0);
1670     glMatrixMode(GL_PROJECTION);
1671     glPushMatrix();
1672     glLoadIdentity();
1673     glOrtho(0, screenwidth, 0, screenheight, -100, 100);
1674     glMatrixMode(GL_MODELVIEW);
1675     glPushMatrix();
1676     glLoadIdentity();
1677     glTranslatef(screenwidth / 2, screenheight / 2, 0);
1678     glPushMatrix();
1679     glScalef((float)screenwidth / 2, (float)screenheight / 2, 1);
1680     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1681     glDisable(GL_BLEND);
1682     glColor4f(0, 0, 0, 1.0);
1683     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1684     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1685     glDisable(GL_TEXTURE_2D);
1686     glBegin(GL_QUADS);
1687     glVertex3f(-1, -1, 0);
1688     glVertex3f(+1, -1, 0);
1689     glVertex3f(+1, +1, 0);
1690     glVertex3f(-1, +1, 0);
1691     glEnd();
1692     glEnable(GL_BLEND);
1693     glColor4f(0.4, 0.4, 0.4, 1.0);
1694     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1695     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1696     glEnable(GL_TEXTURE_2D);
1697     Game::Mainmenuitems[4].bind();
1698     glBegin(GL_QUADS);
1699     glTexCoord2f(0, 0);
1700     glVertex3f(-1, -1, 0);
1701     glTexCoord2f(1, 0);
1702     glVertex3f(+1, -1, 0);
1703     glTexCoord2f(1, 1);
1704     glVertex3f(+1, +1, 0);
1705     glTexCoord2f(0, 1);
1706     glVertex3f(-1, +1, 0);
1707     glEnd();
1708     glPopMatrix();
1709     glPopMatrix();
1710     glMatrixMode(GL_PROJECTION);
1711     glPopMatrix();
1712     glMatrixMode(GL_MODELVIEW);
1713
1714     glMatrixMode(GL_PROJECTION);
1715     glPushMatrix();
1716     glLoadIdentity();
1717     glOrtho(0, 640, 0, 480, -100, 100);
1718     glMatrixMode(GL_MODELVIEW);
1719     glPushMatrix();
1720     glLoadIdentity();
1721     glEnable(GL_TEXTURE_2D);
1722
1723     Menu::drawItems();
1724
1725     //draw mouse cursor
1726     glMatrixMode(GL_PROJECTION);
1727     glPopMatrix();
1728     glMatrixMode(GL_MODELVIEW);
1729     glPopMatrix();
1730
1731     glMatrixMode(GL_PROJECTION);
1732     glPushMatrix();
1733     glLoadIdentity();
1734     glOrtho(0, screenwidth, 0, screenheight, -100, 100);
1735     glMatrixMode(GL_MODELVIEW);
1736     glPushMatrix();
1737     glLoadIdentity();
1738     glTranslatef(screenwidth / 2, screenheight / 2, 0);
1739     glPushMatrix();
1740     glScalef((float)screenwidth / 2, (float)screenheight / 2, 1);
1741     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1742     glEnable(GL_BLEND);
1743     glEnable(GL_TEXTURE_2D);
1744     glColor4f(1, 1, 1, 1);
1745     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1746     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1747     glPopMatrix();
1748     if (!Game::waiting) { // hide the cursor while waiting for a key
1749         glPushMatrix();
1750         glTranslatef(Game::mousecoordh - screenwidth / 2, Game::mousecoordv * -1 + screenheight / 2, 0);
1751         glScalef((float)screenwidth / 64, (float)screenwidth / 64, 1);
1752         glTranslatef(1, -1, 0);
1753         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1754         glColor4f(1, 1, 1, 1);
1755         Game::cursortexture.bind();
1756         glPushMatrix();
1757         glBegin(GL_QUADS);
1758         glTexCoord2f(0, 0);
1759         glVertex3f(-1, -1, 0.0f);
1760         glTexCoord2f(1, 0);
1761         glVertex3f(1, -1, 0.0f);
1762         glTexCoord2f(1, 1);
1763         glVertex3f(1, 1, 0.0f);
1764         glTexCoord2f(0, 1);
1765         glVertex3f(-1, 1, 0.0f);
1766         glEnd();
1767         glPopMatrix();
1768         glPopMatrix();
1769     }
1770     glPopMatrix();
1771     glMatrixMode(GL_PROJECTION);
1772     glPopMatrix();
1773
1774     //draw screen flash
1775     if (flashamount > 0) {
1776         if (flashamount > 1) {
1777             flashamount = 1;
1778         }
1779         if (flashdelay <= 0) {
1780             flashamount -= multiplier;
1781         }
1782         flashdelay--;
1783         if (flashamount < 0) {
1784             flashamount = 0;
1785         }
1786         glDisable(GL_DEPTH_TEST);
1787         glDisable(GL_CULL_FACE);
1788         glDisable(GL_LIGHTING);
1789         glDisable(GL_TEXTURE_2D);
1790         glDepthMask(0);
1791         glMatrixMode(GL_PROJECTION);
1792         glPushMatrix();
1793         glLoadIdentity();
1794         glOrtho(0, screenwidth, 0, screenheight, -100, 100);
1795         glMatrixMode(GL_MODELVIEW);
1796         glPushMatrix();
1797         glLoadIdentity();
1798         glScalef(screenwidth, screenheight, 1);
1799         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1800         glEnable(GL_BLEND);
1801         glColor4f(flashr, flashg, flashb, flashamount);
1802         glBegin(GL_QUADS);
1803         glVertex3f(0, 0, 0.0f);
1804         glVertex3f(256, 0, 0.0f);
1805         glVertex3f(256, 256, 0.0f);
1806         glVertex3f(0, 256, 0.0f);
1807         glEnd();
1808         glMatrixMode(GL_PROJECTION);
1809         glPopMatrix();
1810         glMatrixMode(GL_MODELVIEW);
1811         glPopMatrix();
1812         glEnable(GL_DEPTH_TEST);
1813         glEnable(GL_CULL_FACE);
1814         glDisable(GL_BLEND);
1815         glDepthMask(1);
1816     }
1817 }