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