]> git.jsancho.org Git - lugaru.git/blob - Source/GameDraw.cpp
Cleaned up Objects handling
[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 "Utils/Input.hpp"
29
30 extern XYZ viewer;
31 extern int environment;
32 extern float texscale;
33 extern Light light;
34 extern Terrain terrain;
35 extern float multiplier;
36 extern float viewdistance;
37 extern float fadestart;
38 extern float screenwidth, screenheight;
39 extern int kTextureSize;
40 extern FRUSTUM frustum;
41 extern Light light;
42 extern int detail;
43 extern float usermousesensitivity;
44 extern float camerashake;
45 extern int slomo;
46 extern float slomodelay;
47 extern bool ismotionblur;
48 extern float woozy;
49 extern float blackout;
50 extern bool damageeffects;
51 extern float volume;
52 extern bool texttoggle;
53 extern float blurness;
54 extern float targetblurness;
55 extern float playerdist;
56 extern bool cellophane;
57 extern bool freeze;
58 extern float flashamount, flashr, flashg, flashb;
59 extern int flashdelay;
60 extern int netstate;
61 extern float motionbluramount;
62 extern bool isclient;
63 extern bool alwaysblur;
64 extern bool velocityblur;
65 extern bool devtools;
66 extern int mainmenu;
67 extern int bloodtoggle;
68 extern int difficulty;
69 extern bool decals;
70 extern float texdetail;
71 extern bool musictoggle;
72 extern int tutoriallevel;
73 extern float smoketex;
74 extern float tutorialstagetime;
75 extern float tutorialmaxtime;
76 extern int tutorialstage;
77 extern bool againbonus;
78 extern float damagedealt;
79 extern bool invertmouse;
80
81 extern bool campaign;
82 extern bool winfreeze;
83
84 extern bool gamestart;
85
86 extern bool gamestarted;
87
88 extern bool showdamagebar;
89
90
91
92 int drawtoggle = 0;
93 int numboundaries = 0;
94 XYZ boundary[360];
95 int change = 0;
96
97
98
99 enum drawmodes {
100     normalmode, motionblurmode, radialzoommode,
101     realmotionblurmode, doublevisionmode, glowmode,
102 };
103
104 void Game::flash(float amount, int delay)   // shouldn't be that way, these should be attributes and Person class should not change rendering.
105 {
106     flashr = 1;
107     flashg = 0;
108     flashb = 0;
109     flashamount = amount;
110     flashdelay = delay;
111 }
112
113 void DrawMenu();
114
115 /*********************> DrawGLScene() <*****/
116 int Game::DrawGLScene(StereoSide side)
117 {
118     static float texcoordwidth, texcoordheight;
119     static float texviewwidth, texviewheight;
120     static int l;
121     static XYZ checkpoint;
122     static float tempmult;
123     float tutorialopac;
124     std::string string;
125     std::string string2;
126     std::string string3;
127     static int drawmode = 0;
128
129     if ( stereomode == stereoAnaglyph ) {
130         switch (side) {
131         case stereoLeft:
132             glColorMask( 0.0, 1.0, 1.0, 1.0 );
133             break;
134         case stereoRight:
135             glColorMask( 1.0, 0.0, 0.0, 1.0 );
136             break;
137         default:
138             break;
139         }
140     } else {
141         glColorMask( 1.0, 1.0, 1.0, 1.0 );
142
143         if ( stereomode == stereoHorizontalInterlaced || stereomode == stereoVerticalInterlaced ) {
144             glStencilFunc(side == stereoLeft ? GL_NOTEQUAL : GL_EQUAL, 0x01, 0x01);
145         }
146     }
147
148     if (freeze || winfreeze || (mainmenu && gameon) || (!gameon && gamestarted)) {
149         tempmult = multiplier;
150         multiplier = 0;
151     }
152
153     if (!mainmenu) {
154         if (editorenabled) {
155             numboundaries = mapradius * 2;
156             if (numboundaries > 360)
157                 numboundaries = 360;
158             for (int i = 0; i < numboundaries; i++) {
159                 boundary[i] = 0;
160                 boundary[i].z = 1;
161                 boundary[i] = mapcenter + DoRotation(boundary[i] * mapradius, 0, i * (360 / ((float)(numboundaries))), 0);
162             }
163         }
164
165         SetUpLighting();
166
167         static int changed;
168         changed = 0;
169
170         int olddrawmode = drawmode;
171         if (ismotionblur && !loading) {
172             if ((findLengthfast(&Person::players[0]->velocity) > 200) && velocityblur && !cameramode) {
173                 drawmode = motionblurmode;
174                 motionbluramount = 200 / (findLengthfast(&Person::players[0]->velocity));
175                 changed = 1;
176             }
177             if (Person::players[0]->damage - Person::players[0]->superpermanentdamage > (Person::players[0]->damagetolerance - Person::players[0]->superpermanentdamage) * 1 / 2 && damageeffects && !cameramode) {
178                 drawmode = doublevisionmode;
179                 changed = 1;
180             }
181         }
182
183         if (slomo && !loading) {
184             if (ismotionblur)
185                 drawmode = motionblurmode;
186             motionbluramount = .2;
187             slomodelay -= multiplier;
188             if (slomodelay < 0)
189                 slomo = 0;
190             camerashake = 0;
191             changed = 1;
192         }
193         if ((!changed && !slomo) || loading) {
194             drawmode = normalmode;
195             if (ismotionblur && (/*fps>100||*/alwaysblur)) {
196                 if (olddrawmode != realmotionblurmode)
197                     change = 1;
198                 else
199                     change = 0;
200                 drawmode = realmotionblurmode;
201             } else if (olddrawmode == realmotionblurmode)
202                 change = 2;
203             else
204                 change = 0;
205         }
206
207         if (freeze || winfreeze || (mainmenu && gameon) || (!gameon && gamestarted))
208             drawmode = normalmode;
209         if ((freeze || winfreeze) && ismotionblur && !mainmenu)
210             drawmode = radialzoommode;
211
212         if (winfreeze || mainmenu)
213             drawmode = normalmode;
214
215         if (drawtoggle != 2)
216             drawtoggle = 1 - drawtoggle;
217
218         if (!texcoordwidth) {
219             texviewwidth = kTextureSize;
220             if (texviewwidth > screenwidth)
221                 texviewwidth = screenwidth;
222             texviewheight = kTextureSize;
223             if (texviewheight > screenheight)
224                 texviewheight = screenheight;
225
226             texcoordwidth = screenwidth / kTextureSize;
227             texcoordheight = screenheight / kTextureSize;
228             if (texcoordwidth > 1)
229                 texcoordwidth = 1;
230             if (texcoordheight > 1)
231                 texcoordheight = 1;
232         }
233
234         glDrawBuffer(GL_BACK);
235         glReadBuffer(GL_BACK);
236
237         static XYZ terrainlight;
238         static float distance;
239         if (drawmode == normalmode) {
240             Game::ReSizeGLScene(90, .1f);
241         } else {
242             glViewport(0, 0, texviewwidth, texviewheight);
243         }
244         glDepthFunc(GL_LEQUAL);
245         glDepthMask(1);
246         glAlphaFunc(GL_GREATER, 0.0001f);
247         glEnable(GL_ALPHA_TEST);
248         glClearColor(0.25f, 0.25f, 0.25f, 1.0f);
249         glClear(GL_DEPTH_BUFFER_BIT);
250
251         glMatrixMode (GL_MODELVIEW);
252         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
253         glLoadIdentity ();
254
255         // Move the camera for the current eye's point of view.
256         // Reverse the movement if we're reversing stereo
257         glTranslatef((stereoseparation / 2) * side * (stereoreverse  ? -1 : 1), 0, 0);
258
259         //camera effects
260         if (!cameramode && !freeze && !winfreeze) {
261             //shake
262             glRotatef(float(Random() % 100) / 10 * camerashake/*+(woozy*woozy)/10*/, 0, 0, 1);
263             //sway
264             glRotatef(pitch + sin(woozy / 2) * (Person::players[0]->damage / Person::players[0]->damagetolerance) * 5, 1, 0, 0);
265             glRotatef(yaw + sin(woozy) * (Person::players[0]->damage / Person::players[0]->damagetolerance) * 5, 0, 1, 0);
266         }
267         if (cameramode || freeze || winfreeze) {
268             glRotatef(pitch, 1, 0, 0);
269             glRotatef(yaw, 0, 1, 0);
270         }
271
272         if (environment == desertenvironment) {
273             glRotatef((float)(abs(Random() % 100)) / 3000 - 1, 1, 0, 0);
274             glRotatef((float)(abs(Random() % 100)) / 3000 - 1, 0, 1, 0);
275         }
276         SetUpLight(&light, 0);
277         glPushMatrix();
278
279         //heat blur effect in desert
280         if (abs(blurness - targetblurness) < multiplier * 10 || abs(blurness - targetblurness) > 2) {
281             blurness = targetblurness;
282             targetblurness = (float)(abs(Random() % 100)) / 40;
283         }
284         if (blurness < targetblurness)
285             blurness += multiplier * 5;
286         else
287             blurness -= multiplier * 5;
288
289         if (environment == desertenvironment) {
290             if (detail == 2) {
291                 glTexEnvf( GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, blurness + .4 );
292             }
293             glRotatef((float)(abs(Random() % 100)) / 1000, 1, 0, 0);
294             glRotatef((float)(abs(Random() % 100)) / 1000, 0, 1, 0);
295         }
296         skybox->draw();
297         glTexEnvf( GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, 0);
298         glPopMatrix();
299         glTranslatef(-viewer.x, -viewer.y, -viewer.z);
300         frustum.GetFrustum();
301
302         //make shadow decals on terrain and Object::objects
303         static XYZ point;
304         static float size, opacity, rotation;
305         rotation = 0;
306         for (unsigned k = 0; k < Person::players.size(); k++) {
307             if (!Person::players[k]->skeleton.free && Person::players[k]->playerdetail && Person::players[k]->howactive < typesleeping)
308                 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)
309                     for (unsigned i = 0; i < Person::players[k]->skeleton.joints.size(); i++) {
310                         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) {
311                             point = DoRotation(Person::players[k]->skeleton.joints[i].position, 0, Person::players[k]->yaw, 0) * Person::players[k]->scale + Person::players[k]->coords;
312                             size = .4f;
313                             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;
314                             if (k != 0 && tutoriallevel == 1) {
315                                 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;
316                             }
317                             terrain.MakeDecal(shadowdecal, point, size, opacity, rotation);
318                             for (l = 0; l < terrain.patchobjectnum[Person::players[k]->whichpatchx][Person::players[k]->whichpatchz]; l++) {
319                                 int j = terrain.patchobjects[Person::players[k]->whichpatchx][Person::players[k]->whichpatchz][l];
320                                 if (Object::objects[j]->position.y < Person::players[k]->coords.y || Object::objects[j]->type == tunneltype || Object::objects[j]->type == weirdtype) {
321                                     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);
322                                     size = .4f;
323                                     opacity = .4f;
324                                     if (k != 0 && tutoriallevel == 1) {
325                                         opacity = .2 + .2 * sin(smoketex * 6 + i);
326                                     }
327                                     Object::objects[j]->model.MakeDecal(shadowdecal, &point, &size, &opacity, &rotation);
328                                 }
329                             }
330                         }
331                     }
332             if ((Person::players[k]->skeleton.free || Person::players[k]->howactive >= typesleeping) && Person::players[k]->playerdetail)
333                 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)
334                     for (unsigned i = 0; i < Person::players[k]->skeleton.joints.size(); i++) {
335                         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) {
336                             if (Person::players[k]->skeleton.free)
337                                 point = Person::players[k]->skeleton.joints[i].position * Person::players[k]->scale + Person::players[k]->coords;
338                             else
339                                 point = DoRotation(Person::players[k]->skeleton.joints[i].position, 0, Person::players[k]->yaw, 0) * Person::players[k]->scale + Person::players[k]->coords;
340                             size = .4f;
341                             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;
342                             if (k != 0 && tutoriallevel == 1) {
343                                 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;
344                             }
345                             terrain.MakeDecal(shadowdecal, point, size, opacity * .7, rotation);
346                             for (l = 0; l < terrain.patchobjectnum[Person::players[k]->whichpatchx][Person::players[k]->whichpatchz]; l++) {
347                                 int j = terrain.patchobjects[Person::players[k]->whichpatchx][Person::players[k]->whichpatchz][l];
348                                 if (Object::objects[j]->position.y < Person::players[k]->coords.y || Object::objects[j]->type == tunneltype || Object::objects[j]->type == weirdtype) {
349                                     if (Person::players[k]->skeleton.free)
350                                         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);
351                                     else
352                                         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);
353                                     size = .4f;
354                                     opacity = .4f;
355                                     if (k != 0 && tutoriallevel == 1) {
356                                         opacity = .2 + .2 * sin(smoketex * 6 + i);
357                                     }
358                                     Object::objects[j]->model.MakeDecal(shadowdecal, &point, &size, &opacity, &rotation);
359                                 }
360                             }
361                         }
362                     }
363
364             if (!Person::players[k]->playerdetail)
365                 if (frustum.SphereInFrustum(Person::players[k]->coords.x, Person::players[k]->coords.y, Person::players[k]->coords.z, Person::players[k]->scale * 5)) {
366                     point = Person::players[k]->coords;
367                     size = .7;
368                     opacity = .4 - (Person::players[k]->coords.y - terrain.getHeight(Person::players[k]->coords.x, Person::players[k]->coords.z)) / 5;
369                     terrain.MakeDecal(shadowdecal, point, size, opacity * .7, rotation);
370                     for (l = 0; l < terrain.patchobjectnum[Person::players[k]->whichpatchx][Person::players[k]->whichpatchz]; l++) {
371                         int j = terrain.patchobjects[Person::players[k]->whichpatchx][Person::players[k]->whichpatchz][l];
372                         point = DoRotation(Person::players[k]->coords - Object::objects[j]->position, 0, -Object::objects[j]->yaw, 0);
373                         size = .7;
374                         opacity = .4f;
375                         Object::objects[j]->model.MakeDecal(shadowdecal, &point, &size, &opacity, &rotation);
376                     }
377                 }
378         }
379
380         //Terrain
381         glEnable(GL_TEXTURE_2D);
382         glDepthMask(1);
383         glEnable(GL_DEPTH_TEST);
384         glEnable(GL_CULL_FACE);
385         glDisable(GL_BLEND);
386         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
387         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
388         terraintexture.bind();
389         terrain.draw(0);
390         terraintexture2.bind();
391         terrain.draw(1);
392
393         terrain.drawdecals();
394
395         //Model
396         glEnable(GL_CULL_FACE);
397         glEnable(GL_LIGHTING);
398         glDisable(GL_BLEND);
399         glEnable(GL_TEXTURE_2D);
400         glDepthMask(1);
401
402         glEnable(GL_COLOR_MATERIAL);
403
404         if (!cellophane) {
405             glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
406             glEnable(GL_CULL_FACE);
407             glCullFace(GL_FRONT);
408             glDepthMask(1);
409             for (unsigned k = 0; k < Person::players.size(); k++) {
410                 if (k == 0 || tutoriallevel != 1) {
411                     glEnable(GL_BLEND);
412                     glEnable(GL_LIGHTING);
413                     terrainlight = terrain.getLighting(Person::players[k]->coords.x, Person::players[k]->coords.z);
414                     distance = distsq(&viewer, &Person::players[k]->coords);
415                     distance = (viewdistance * viewdistance - (distance - (viewdistance * viewdistance * fadestart)) * (1 / (1 - fadestart))) / viewdistance / viewdistance;
416                     glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, distance);
417                     if (distance >= 1)
418                         glDisable(GL_BLEND);
419                     if (distance >= .5) {
420                         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;
421                         checkpoint.y += 1;
422                         int i = -1;
423                         if (Person::players[k]->occluded != 0)
424                             i = checkcollide(viewer, checkpoint, Person::players[k]->lastoccluded);
425                         if (i == -1)
426                             i = checkcollide(viewer, checkpoint);
427                         if (i != -1) {
428                             Person::players[k]->occluded += 1;
429                             Person::players[k]->lastoccluded = i;
430                         } else {
431                             Person::players[k]->occluded = 0;
432                         }
433                         if (Person::players[k]->occluded < 25)
434                             Person::players[k]->DrawSkeleton();
435                     }
436                 }
437             }
438         }
439
440         if (!cameramode && musictype == stream_fighttheme)
441             playerdist = distsqflat(&Person::players[0]->coords, &viewer);
442         else
443             playerdist = -100;
444         glPushMatrix();
445         glCullFace(GL_BACK);
446         glEnable(GL_TEXTURE_2D);
447         Object::Draw();
448         glPopMatrix();
449
450         //draw hawk
451         glPushMatrix();
452         if (frustum.SphereInFrustum(realhawkcoords.x + hawk.boundingspherecenter.x, realhawkcoords.y + hawk.boundingspherecenter.y, realhawkcoords.z + hawk.boundingspherecenter.z, 2)) {
453             glAlphaFunc(GL_GREATER, 0.0001f);
454             glDepthMask(1);
455             glDisable(GL_CULL_FACE);
456             glDisable(GL_LIGHTING);
457             glEnable(GL_BLEND);
458             glTranslatef(hawkcoords.x, hawkcoords.y, hawkcoords.z);
459             glRotatef(hawkyaw, 0, 1, 0);
460             glTranslatef(25, 0, 0);
461             distance = distsq(&viewer, &realhawkcoords) * 1.2;
462             glColor4f(light.color[0], light.color[1], light.color[2], (viewdistance * viewdistance - (distance - (viewdistance * viewdistance * fadestart)) * (1 / (1 - fadestart))) / viewdistance / viewdistance);
463             if ((viewdistance * viewdistance - (distance - (viewdistance * viewdistance * fadestart)) * (1 / (1 - fadestart))) / viewdistance / viewdistance > 1)
464                 glColor4f(light.color[0], light.color[1], light.color[2], 1);
465             if ((viewdistance * viewdistance - (distance - (viewdistance * viewdistance * fadestart)) * (1 / (1 - fadestart))) / viewdistance / viewdistance > 0)
466                 hawk.drawdifftex(hawktexture);
467         }
468         glPopMatrix();
469
470         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
471         glEnable(GL_CULL_FACE);
472         glCullFace(GL_FRONT);
473         glDepthMask(1);
474         for (unsigned k = 0; k < Person::players.size(); k++) {
475             if (!(k == 0 || tutoriallevel != 1)) {
476                 glEnable(GL_BLEND);
477                 glEnable(GL_LIGHTING);
478                 terrainlight = terrain.getLighting(Person::players[k]->coords.x, Person::players[k]->coords.z);
479                 distance = distsq(&viewer, &Person::players[k]->coords);
480                 distance = (viewdistance * viewdistance - (distance - (viewdistance * viewdistance * fadestart)) * (1 / (1 - fadestart))) / viewdistance / viewdistance;
481                 glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, distance);
482                 if (distance >= 1)
483                     glDisable(GL_BLEND);
484                 if (distance >= .5) {
485                     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;
486                     checkpoint.y += 1;
487                     int i = -1;
488                     if (Person::players[k]->occluded != 0)
489                         i = checkcollide(viewer, checkpoint, Person::players[k]->lastoccluded);
490                     if (i == -1)
491                         i = checkcollide(viewer, checkpoint);
492                     if (i != -1) {
493                         Person::players[k]->occluded += 1;
494                         Person::players[k]->lastoccluded = i;
495                     } else {
496                         Person::players[k]->occluded = 0;
497                     }
498                     if (Person::players[k]->occluded < 25)
499                         Person::players[k]->DrawSkeleton();
500                 }
501             }
502         }
503
504         glPushMatrix();
505         glEnable(GL_TEXTURE_2D);
506         weapons.Draw();
507         glPopMatrix();
508         glCullFace(GL_BACK);
509
510         glDisable(GL_COLOR_MATERIAL);
511
512         glDisable(GL_LIGHTING);
513         glDisable(GL_TEXTURE_2D);
514
515         glDepthMask(0);
516
517         Sprite::Draw();
518
519         //waypoints, pathpoints in editor
520         if (editorenabled) {
521             glEnable(GL_BLEND);
522             glDisable(GL_LIGHTING);
523             glDisable(GL_TEXTURE_2D);
524             glDisable(GL_COLOR_MATERIAL);
525             glColor4f(1, 1, 0, 1);
526
527             for (unsigned k = 0; k < Person::players.size(); k++) {
528                 if (Person::players[k]->numwaypoints > 1) {
529                     glBegin(GL_LINE_LOOP);
530                     for (int i = 0; i < Person::players[k]->numwaypoints; i++) {
531                         glVertex3f(Person::players[k]->waypoints[i].x, Person::players[k]->waypoints[i].y + .5, Person::players[k]->waypoints[i].z);
532                     }
533                     glEnd();
534                 }
535             }
536
537
538             if (numpathpoints > 1) {
539                 glColor4f(0, 1, 0, 1);
540                 for (unsigned k = 0; int(k) < numpathpoints; k++) {
541                     if (numpathpointconnect[k]) {
542                         for (int i = 0; i < numpathpointconnect[k]; i++) {
543                             glBegin(GL_LINE_LOOP);
544                             glVertex3f(pathpoint[k].x, pathpoint[k].y + .5, pathpoint[k].z);
545                             glVertex3f(pathpoint[pathpointconnect[k][i]].x, pathpoint[pathpointconnect[k][i]].y + .5, pathpoint[pathpointconnect[k][i]].z);
546                             glEnd();
547                         }
548                     }
549                 }
550                 glColor4f(1, 1, 1, 1);
551                 glPointSize(4);
552                 glBegin(GL_POINTS);
553                 glVertex3f(pathpoint[pathpointselected].x, pathpoint[pathpointselected].y + .5, pathpoint[pathpointselected].z);
554                 glEnd();
555             }
556         }
557
558         //Text
559
560         glEnable(GL_TEXTURE_2D);
561         glColor4f(.5, .5, .5, 1);
562         if (!console) {
563             if (!tutoriallevel)
564                 if (bonus > 0 && bonustime < 1 && !winfreeze && !Dialog::inDialog()) {
565                     const char *bonus_name;
566                     if (bonus < bonus_count)
567                         bonus_name = bonus_names[bonus];
568                     else
569                         bonus_name = "Excellent!"; // When does this happen?
570
571                     text->glPrintOutlined(1, 0, 0, 1 - bonustime, 1024 / 2 - 10 * strlen(bonus_name), 768 / 16 + 768 * 4 / 5, bonus_name, 1, 2, 1024, 768);
572
573                     string = to_string((int)bonusvalue);
574                     text->glPrintOutlined(1, 0, 0, 1 - bonustime, 1024 / 2 - 10 * string.size(), 768 / 16 - 20 + 768 * 4 / 5, string, 1, 2 * .8, 1024, 768);
575
576                     glColor4f(.5, .5, .5, 1);
577                 }
578
579             if (tutoriallevel == 1) {
580                 tutorialopac = tutorialmaxtime - tutorialstagetime;
581                 if (tutorialopac > 1)
582                     tutorialopac = 1;
583                 if (tutorialopac < 0)
584                     tutorialopac = 0;
585
586                 string = " ";
587                 string2 = " ";
588                 string3 = " ";
589                 if (tutorialstage == 0) {
590                     string = " ";
591                     string2 = " ";
592                     string3 = " ";
593                 }
594                 if (tutorialstage == 1) {
595                     string = "Welcome to the Lugaru training level!";
596                     string2 = " ";
597                     string3 = " ";
598                 }
599                 if (tutorialstage == 2) {
600                     string = "BASIC MOVEMENT:";
601                     string2 = " ";
602                     string3 = " ";
603                 }
604                 if (tutorialstage == 3) {
605                     string = "You can move the mouse to rotate the camera.";
606                     string2 = " ";
607                     string3 = " ";
608                 }
609                 if (tutorialstage == 4) {
610                     string = std::string("Try using the ") +
611                             Input::keyToChar(forwardkey) + ", " +
612                             Input::keyToChar(leftkey) + ", " +
613                             Input::keyToChar(backkey) + " and " +
614                             Input::keyToChar(rightkey) + " keys to move around.";
615                     string2 = "All movement is relative to the camera.";
616                     string3 = " ";
617                 }
618                 if (tutorialstage == 5) {
619                     string = std::string("Please press ") + Input::keyToChar(jumpkey) + " to jump.";
620                     string2 = "You can hold it longer to jump higher.";
621                     string3 = " ";
622                 }
623                 if (tutorialstage == 6) {
624                     string = std::string("You can press ") + Input::keyToChar(crouchkey) + " to crouch.";
625                     string2 = "You can jump higher from a crouching position.";
626                     string3 = " ";
627                 }
628                 if (tutorialstage == 7) {
629                     string = std::string("While running, you can press ") + Input::keyToChar(crouchkey) + " to roll.";
630                     string2 = " ";
631                     string3 = " ";
632                 }
633                 if (tutorialstage == 8) {
634                     string = "While crouching, you can sneak around silently";
635                     string2 = "using the movement keys.";
636                     string3 = " ";
637                 }
638                 if (tutorialstage == 9) {
639                     string = "Release the crouch key while sneaking and hold the movement keys";
640                     string2 = "to run animal-style.";
641                     string3 = " ";
642                 }
643                 if (tutorialstage == 10) {
644                     string = "ADVANCED MOVEMENT:";
645                     string2 = " ";
646                     string3 = " ";
647                 }
648                 if (tutorialstage == 11) {
649                     string = std::string("When you jump at a wall, you can hold ") + Input::keyToChar(jumpkey) + " again";
650                     string2 = "during impact to perform a walljump.";
651                     string3 = "Be sure to use the movement keys to press against the wall";
652                 }
653                 if (tutorialstage == 12) {
654                     string = "While in the air, you can press crouch to flip.";
655                     string2 = "Walljumps and flips confuse enemies and give you more control.";
656                     string3 = " ";
657                 }
658                 if (tutorialstage == 13) {
659                     string = "BASIC COMBAT:";
660                     string2 = " ";
661                     string3 = " ";
662                 }
663                 if (tutorialstage == 14) {
664                     string = "There is now an imaginary enemy";
665                     string2 = "in the middle of the training area.";
666                     string3 = " ";
667                 }
668                 if (tutorialstage == 15) {
669                     if (attackkey == MOUSEBUTTON1) {
670                         string = "Click to attack when you are near an enemy.";
671                     } else {
672                         string = std::string("Press ") + Input::keyToChar(attackkey) + " to attack when you are near an enemy.";
673                     }
674                     string2 = "You can punch by standing still near an enemy and attacking.";
675                     string3 = " ";
676                 }
677                 if (tutorialstage == 16) {
678                     string = "If you are close, you will perform a weak punch.";
679                     string2 = "The weak punch is excellent for starting attack combinations.";
680                     string3 = " ";
681                 }
682                 if (tutorialstage == 17) {
683                     string = "Attacking while running results in a spin kick.";
684                     string2 = "This is one of your most powerful ground attacks.";
685                     string3 = " ";
686                 }
687                 if (tutorialstage == 18) {
688                     string = "Sweep the enemy's legs out by attacking while crouched.";
689                     string2 = "This is a very fast attack, and easy to follow up.";
690                     string3 = " ";
691                 }
692                 if (tutorialstage == 19) {
693                     string = "When an enemy is on the ground, you can deal some extra";
694                     string2 = "damage by running up and drop-kicking him.";
695                     string3 = "(Try knocking them down with a sweep first)";
696                 }
697                 if (tutorialstage == 20) {
698                     string = "Your most powerful individual attack is the rabbit kick.";
699                     if (attackkey == MOUSEBUTTON1) {
700                         string2 = "Run at the enemy while holding the mouse button, and press";
701                     } else {
702                         string2 = std::string("Run at the enemy while holding ") + Input::keyToChar(attackkey) + ", and press";
703                     }
704                     string3 = std::string("the jump key (") + Input::keyToChar(jumpkey) + ") to attack.";
705                 }
706                 if (tutorialstage == 21) {
707                     string = "This attack is devastating if timed correctly.";
708                     string2 = "Even if timed incorrectly, it will knock the enemy over.";
709                     if (againbonus)
710                         string3 = "Try rabbit-kicking the imaginary enemy again.";
711                     else
712                         string3 = "Try rabbit-kicking the imaginary enemy.";
713                 }
714                 if (tutorialstage == 22) {
715                     string = "If you sneak behind an enemy unnoticed, you can kill";
716                     string2 = "him instantly. Move close behind this enemy";
717                     string3 = "and attack.";
718                 }
719                 if (tutorialstage == 23) {
720                     string = "Another important attack is the wall kick. When an enemy";
721                     string2 = "is near a wall, perform a walljump nearby and hold";
722                     string3 = "the attack key during impact with the wall.";
723                 }
724                 if (tutorialstage == 24) {
725                     string = "You can tackle enemies by running at them animal-style";
726                     if (attackkey == MOUSEBUTTON1) {
727                         string2 = std::string("and pressing jump (") + Input::keyToChar(jumpkey) + ") or attack(mouse button).";
728                     } else {
729                         string2 = std::string("and pressing jump (") + Input::keyToChar(jumpkey) + ") or attack(" + Input::keyToChar(attackkey) + ").";
730                     }
731                     string3 = "This is especially useful when they are running away.";
732                 }
733                 if (tutorialstage == 25) {
734                     string = "Dodge by pressing back and attack. Dodging is essential";
735                     string2 = "against enemies with swords or other long weapons.";
736                     string3 = " ";
737                 }
738                 if (tutorialstage == 26) {
739                     string = "REVERSALS AND COUNTER-REVERSALS";
740                     string2 = " ";
741                     string3 = " ";
742                 }
743                 if (tutorialstage == 27) {
744                     string = "The enemy can now reverse your attacks.";
745                     string2 = " ";
746                     string3 = " ";
747                 }
748                 if (tutorialstage == 28) {
749                     string = "If you attack, you will notice that the enemy now sometimes";
750                     string2 = "catches your attack and uses it against you. Hold";
751                     string3 = std::string("crouch (") + Input::keyToChar(crouchkey) + ") after attacking to escape from reversals.";
752                 }
753                 if (tutorialstage == 29) {
754                     string = "Try escaping from two more reversals in a row.";
755                     string2 = " ";
756                     string3 = " ";
757                 }
758                 if (tutorialstage == 30) {
759                     string = "Good!";
760                     string2 = " ";
761                     string3 = " ";
762                 }
763                 if (tutorialstage == 31) {
764                     string = std::string("To reverse an attack, you must tap crouch (") + Input::keyToChar(crouchkey) + ") during the";
765                     string2 = "enemy's attack. You must also be close to the enemy;";
766                     string3 = "this is especially important against armed opponents.";
767                 }
768                 if (tutorialstage == 32) {
769                     string = "The enemy can attack in " + to_string(int(tutorialmaxtime - tutorialstagetime)) + " seconds.";
770                     string2 = "This imaginary opponents attacks will be highlighted";
771                     string3 = "to make this easier.";
772                 }
773                 if (tutorialstage == 33) {
774                     string = "Reverse three enemy attacks!";
775                     string2 = " ";
776                     string3 = " ";
777                 }
778                 if (tutorialstage == 34) {
779                     string = "Reverse two more enemy attacks!";
780                     string2 = " ";
781                     string3 = " ";
782                 }
783                 if (tutorialstage == 35) {
784                     string = "Reverse one more enemy attack!";
785                     string2 = " ";
786                     string3 = " ";
787                 }
788                 if (tutorialstage == 36) {
789                     string = "Excellent!";
790                     string2 = " ";
791                     string3 = " ";
792                 }
793                 if (tutorialstage == 37) {
794                     string = "Now spar with the enemy for " + to_string(int(tutorialmaxtime - tutorialstagetime)) + " more seconds.";
795                     string2 = "Damage dealt: " + to_string(int(damagedealt));
796                     string3 = "Damage taken: " + to_string(int(damagetaken));
797                 }
798                 if (tutorialstage == 38) {
799                     string = "WEAPONS:";
800                     string2 = " ";
801                     string3 = " ";
802                 }
803                 if (tutorialstage == 39) {
804                     string = "There is now an imaginary knife";
805                     string2 = "in the center of the training area.";
806                     string3 = " ";
807                 }
808                 if (tutorialstage == 40) {
809                     string = "Stand, roll or handspring over the knife";
810                     string2 = std::string("while pressing ") + Input::keyToChar(throwkey) + " to pick it up.";
811                     string3 = "You can crouch and press the same key to drop it again.";
812                 }
813                 if (tutorialstage == 41) {
814                     string = std::string("You can equip and unequip weapons using the ") + Input::keyToChar(drawkey) + " key.";
815                     string2 = "Sometimes it is best to keep them unequipped to";
816                     string3 = "prevent enemies from taking them. ";
817                 }
818                 if (tutorialstage == 42) {
819                     string = "The knife is the smallest weapon and the least encumbering.";
820                     string2 = "You can equip or unequip it while standing, crouching,";
821                     string3 = "running or flipping.";
822                 }
823                 if (tutorialstage == 43) {
824                     string = "You perform weapon attacks the same way as unarmed attacks,";
825                     string2 = "but sharp weapons cause permanent damage, instead of the";
826                     string3 = "temporary trauma from blunt weapons, fists and feet.";
827                 }
828                 if (tutorialstage == 44) {
829                     string = "The enemy now has your knife!";
830                     string2 = "Please reverse two of his knife attacks.";
831                     string3 = " ";
832                 }
833                 if (tutorialstage == 45) {
834                     string = "Please reverse one more of his knife attacks.";
835                     string2 = " ";
836                     string3 = " ";
837                 }
838                 if (tutorialstage == 46) {
839                     string = "Now he has a sword!";
840                     string2 = "The sword has longer reach than your arms, so you";
841                     string3 = "must move close to reverse the sword slash.";
842                 }
843                 if (tutorialstage == 47) {
844                     string = "Long weapons like the sword and staff are also useful for defense;";
845                     string2 = "you can parry enemy weapon attacks by pressing the attack key";
846                     string3 = "at the right time. Please try parrying the enemy's attacks!";
847                 }
848                 if (tutorialstage == 48) {
849                     string = "The staff is like the sword, but has two main attacks.";
850                     string2 = "The standing smash is fast and effective, and the running";
851                     string3 = "spin smash is slower and more powerful.";
852                 }
853                 if (tutorialstage == 49) {
854                     string = std::string("When facing an enemy, you can throw the knife with ") + Input::keyToChar(throwkey) + ".";
855                     string2 = "It is possible to throw the knife while flipping,";
856                     string3 = "but it is very inaccurate.";
857                 }
858                 if (tutorialstage == 50) {
859                     string = "You now know everything you can learn from training.";
860                     string2 = "Everything else you must learn from experience!";
861                     string3 = " ";
862                 }
863                 if (tutorialstage == 51) {
864                     string = "Walk out of the training area to return to the main menu.";
865                     string2 = " ";
866                     string3 = " ";
867                 }
868
869                 text->glPrintOutlined(1, 1, 1, tutorialopac, screenwidth / 2 - 7.6 * string.size()*screenwidth / 1024, screenheight / 16 + screenheight * 4 / 5, string, 1, 1.5 * screenwidth / 1024, screenwidth, screenheight);
870                 text->glPrintOutlined(1, 1, 1, tutorialopac, screenwidth / 2 - 7.6 * string2.size()*screenwidth / 1024, screenheight / 16 + screenheight * 4 / 5 - 20 * screenwidth / 1024, string2, 1, 1.5 * screenwidth / 1024, screenwidth, screenheight);
871                 text->glPrintOutlined(1, 1, 1, tutorialopac, screenwidth / 2 - 7.6 * string3.size()*screenwidth / 1024, screenheight / 16 + screenheight * 4 / 5 - 40 * screenwidth / 1024, string3, 1, 1.5 * screenwidth / 1024, screenwidth, screenheight);
872
873                 string = "Press 'tab' to skip to the next item.";
874                 string2 = "Press escape at any time to";
875                 string3 = "pause or exit the tutorial.";
876
877                 text->glPrintOutlined(0.5, 0.5, 0.5, 1, screenwidth / 2 - 7.6 * string.size()*screenwidth / 1024 * .8, 0 + screenheight * 1 / 10, string, 1, 1.5 * screenwidth / 1024 * .8, screenwidth, screenheight);
878                 text->glPrintOutlined(0.5, 0.5, 0.5, 1, screenwidth / 2 - 7.6 * string2.size()*screenwidth / 1024 * .8, 0 + screenheight * 1 / 10 - 20 * .8 * screenwidth / 1024, string2, 1, 1.5 * screenwidth / 1024 * .8, screenwidth, screenheight);
879                 text->glPrintOutlined(0.5, 0.5, 0.5, 1, screenwidth / 2 - 7.6 * string3.size()*screenwidth / 1024 * .8, 0 + screenheight * 1 / 10 - 40 * .8 * screenwidth / 1024, string3, 1, 1.5 * screenwidth / 1024 * .8, screenwidth, screenheight);
880             }
881
882             //Hot spots
883             if (Hotspot::hotspots.size() && (bonustime >= 1 || bonus <= 0 || bonustime < 0) && !tutoriallevel) {
884                 float closestdist = -1;
885                 float distance = 0;
886                 int closest = Hotspot::current;
887                 for (unsigned i = 0; i < Hotspot::hotspots.size(); i++) {
888                     distance = distsq(&Person::players[0]->coords, &Hotspot::hotspots[i].position);
889                     if (closestdist == -1 || distance < closestdist) {
890                         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))) {
891                             closestdist = distance;
892                             closest = i;
893                         }
894                     }
895                 }
896                 if (closest != -1) {
897                     Hotspot::current = closest;
898                     if (Hotspot::hotspots[closest].type <= 10) {
899                         if (distsq(&Person::players[0]->coords, &Hotspot::hotspots[closest].position) < Hotspot::hotspots[closest].size)
900                             tutorialstagetime = 0;
901                         tutorialmaxtime = 1;
902                         tutorialopac = tutorialmaxtime - tutorialstagetime;
903                         if (tutorialopac > 1)
904                             tutorialopac = 1;
905                         if (tutorialopac < 0)
906                             tutorialopac = 0;
907
908                         string = Hotspot::hotspots[closest].text;
909
910                         int lastline = 0;
911                         int line = 0;
912                         bool done = false;
913                         int i = 0;
914                         while (!done) {
915                             if (string[i] == '\n' || string[i] > 'z' || string[i] < ' ' || string[i] == '\0') {
916                                 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);
917                                 lastline = i + 1;
918                                 line++;
919                                 if (string[i] == '\0')
920                                     done = 1;
921                             }
922                             if (i >= 255)
923                                 done = 1;
924                             i++;
925                         }
926                     } else if ((Hotspot::hotspots[closest].type >= 20) && (Dialog::dialogs[Hotspot::hotspots[closest].type - 20].gonethrough == 0)) {
927                         Dialog::whichdialogue = Hotspot::hotspots[closest].type - 20;
928                         Dialog::currentDialog().play();
929                         Dialog::currentDialog().gonethrough++;
930                     }
931                 }
932             }
933
934             if (Dialog::inDialog() && !mainmenu) {
935                 glDisable(GL_DEPTH_TEST);
936                 glDisable(GL_CULL_FACE);
937                 glDisable(GL_LIGHTING);
938                 glDisable(GL_TEXTURE_2D);
939                 glDepthMask(0);
940                 glMatrixMode(GL_PROJECTION);
941                 glPushMatrix();
942                 glLoadIdentity();
943                 glOrtho(0, screenwidth, 0, screenheight, -100, 100);
944                 glMatrixMode(GL_MODELVIEW);
945                 glPushMatrix();
946                 glLoadIdentity();
947                 if (Dialog::currentScene().location == 1)
948                     glTranslatef(0, screenheight * 3 / 4, 0);
949                 glScalef(screenwidth, screenheight / 4, 1);
950                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
951                 glEnable(GL_BLEND);
952
953                 glColor4f(Dialog::currentScene().color[0], Dialog::currentScene().color[1], Dialog::currentScene().color[2], 0.7);
954                 glBegin(GL_QUADS);
955                 glVertex3f(0, 0, 0.0f);
956                 glVertex3f(1, 0, 0.0f);
957                 glVertex3f(1, 1, 0.0f);
958                 glVertex3f(0, 1, 0.0f);
959                 glEnd();
960                 glMatrixMode(GL_PROJECTION);
961                 glPopMatrix();
962                 glMatrixMode(GL_MODELVIEW);
963                 glPopMatrix();
964                 glEnable(GL_DEPTH_TEST);
965                 glEnable(GL_CULL_FACE);
966                 glDisable(GL_BLEND);
967                 glDepthMask(1);
968                 glEnable(GL_TEXTURE_2D);
969
970                 tutorialopac = 1;
971
972                 float startx;
973                 float starty;
974
975                 startx = screenwidth * 1 / 5;
976                 if (Dialog::currentScene().location == 1) {
977                     starty = screenheight / 16 + screenheight * 4 / 5;
978                 } else {
979                     starty = screenheight * 1 / 5 - screenheight / 16;
980                 }
981
982                 // FIXME - What is that char[] building for?
983                 char tempname[264];
984                 int tempnum = 0;
985                 for (int i = 0; i < 264; i++) {
986                     tempname[i] = '\0';
987                 }
988
989                 for (unsigned i = 0; i < Dialog::currentScene().name.size(); i++) {
990                     tempname[tempnum] = Dialog::currentScene().name[i];
991                     if (tempname[tempnum] == '#' || tempname[tempnum] == '\0')
992                         tempname[tempnum] = '\0';
993                     else
994                         tempnum++;
995                 }
996
997                 string = std::string(tempname) + ": ";
998
999                 if (Dialog::currentScene().color[0] + Dialog::currentScene().color[1] + Dialog::currentScene().color[2] < 1.5) {
1000                     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);
1001                 } else {
1002                     glColor4f(0, 0, 0, tutorialopac);
1003                     text->glPrintOutline(startx - 2 * 7.6 * string.size()*screenwidth / 1024 - 4, starty - 4, string, 1, 1.5 * 1.25 * screenwidth / 1024, screenwidth, screenheight);
1004                 }
1005
1006                 tempnum = 0;
1007                 for (unsigned i = 0; i < Dialog::currentScene().text.size() + 1; i++) {
1008                     tempname[tempnum] = Dialog::currentScene().text[i];
1009                     if (Dialog::currentScene().text[i] != '#')
1010                         tempnum++;
1011                 }
1012
1013                 string = tempname;
1014
1015                 int lastline = 0;
1016                 int line = 0;
1017                 bool done = false;
1018                 int i = 0;
1019                 while (!done) {
1020                     if (string[i] == '\n' || string[i] > 'z' || string[i] < ' ' || string[i] == '\0') {
1021                         if (Dialog::currentScene().color[0] + Dialog::currentScene().color[1] + Dialog::currentScene().color[2] < 1.5) {
1022                             text->glPrintOutlined(1, 1, 1, tutorialopac, startx, starty - 20 * screenwidth / 1024 * line, string, 1, 1.5 * screenwidth / 1024, screenwidth, screenheight, lastline, i);
1023                         } else {
1024                             glColor4f(0, 0, 0, tutorialopac);
1025                             text->glPrint(startx, starty - 20 * screenwidth / 1024 * line, string, 1, 1.5 * screenwidth / 1024, screenwidth, screenheight, lastline, i);
1026                         }
1027                         lastline = i + 1;
1028                         line++;
1029                         if (string[i] == '\0')
1030                             done = 1;
1031                     }
1032                     if (i >= 255)
1033                         done = 1;
1034                     i++;
1035                 }
1036             }
1037
1038             if (!tutoriallevel && !winfreeze && !Dialog::inDialog() && !mainmenu) {
1039                 if (campaign) {
1040                     if (scoreadded) {
1041                         string = "Score: " + to_string(int(Account::active().getCampaignScore()));
1042                     } else {
1043                         string = "Score: " + to_string(int(Account::active().getCampaignScore() + bonustotal));
1044                     }
1045                 } else {
1046                     string = "Score: " + to_string(int(bonustotal));
1047                 }
1048                 text->glPrintOutlined(1, 0, 0, 1, 1024 / 40, 768 / 16 + 768 * 14 / 16, string, 1, 1.5, 1024, 768);
1049                 if (showdamagebar) {
1050                     glDisable(GL_DEPTH_TEST);
1051                     glDisable(GL_CULL_FACE);
1052                     glDisable(GL_LIGHTING);
1053                     glDisable(GL_TEXTURE_2D);
1054                     glDepthMask(0);
1055                     glMatrixMode(GL_PROJECTION);
1056                     glPushMatrix();
1057                     glLoadIdentity();
1058                     glOrtho(0, screenwidth, 0, screenheight, -100, 100);
1059                     glMatrixMode(GL_MODELVIEW);
1060                     glPushMatrix();
1061                     glLoadIdentity();
1062                     glTranslatef(15, screenheight * 17.5 / 20, 0);
1063                     glScalef(screenwidth / 3 + 20, screenheight / 20, 1);
1064                     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1065                     glEnable(GL_BLEND);
1066                     glColor4f(0.0, 0.4, 0.0, 0.7);
1067                     float bar = ((float)Person::players[0]->damage) / Person::players[0]->damagetolerance;
1068                     glBegin(GL_QUADS);
1069                     glVertex3f((bar < 1 ? bar : 1), 0, 0.0f);
1070                     glVertex3f(1, 0, 0.0f);
1071                     glVertex3f(1, 1, 0.0f);
1072                     glVertex3f((bar < 1 ? bar : 1), 1, 0.0f);
1073                     glEnd();
1074                     glColor4f(0.1, 0.0, 0.0, 1);
1075                     bar = ((float)Person::players[0]->bloodloss) / Person::players[0]->damagetolerance;
1076                     glBegin(GL_QUADS);
1077                     glVertex3f(0, 0, 0.0f);
1078                     glVertex3f((bar < 1 ? bar : 1), 0, 0.0f);
1079                     glVertex3f((bar < 1 ? bar : 1), 1, 0.0f);
1080                     glVertex3f(0, 1, 0.0f);
1081                     glEnd();
1082                     glColor4f(0.4, 0.0, 0.0, 0.7);
1083                     bar = ((float)Person::players[0]->damage) / Person::players[0]->damagetolerance;
1084                     glBegin(GL_QUADS);
1085                     glVertex3f(0, 0, 0.0f);
1086                     glVertex3f((bar < 1 ? bar : 1), 0, 0.0f);
1087                     glVertex3f((bar < 1 ? bar : 1), 1, 0.0f);
1088                     glVertex3f(0, 1, 0.0f);
1089                     glEnd();
1090                     glColor4f(0.4, 0.0, 0.0, 0.7);
1091                     bar = ((float)Person::players[0]->permanentdamage) / Person::players[0]->damagetolerance;
1092                     glBegin(GL_QUADS);
1093                     glVertex3f(0, 0, 0.0f);
1094                     glVertex3f((bar < 1 ? bar : 1), 0, 0.0f);
1095                     glVertex3f((bar < 1 ? bar : 1), 1, 0.0f);
1096                     glVertex3f(0, 1, 0.0f);
1097                     glEnd();
1098                     glColor4f(0.4, 0.0, 0.0, 0.7);
1099                     bar = ((float)Person::players[0]->superpermanentdamage) / Person::players[0]->damagetolerance;
1100                     glBegin(GL_QUADS);
1101                     glVertex3f(0, 0, 0.0f);
1102                     glVertex3f((bar < 1 ? bar : 1), 0, 0.0f);
1103                     glVertex3f((bar < 1 ? bar : 1), 1, 0.0f);
1104                     glVertex3f(0, 1, 0.0f);
1105                     glEnd();
1106                     glColor4f(0.0, 0.0, 0.0, 0.7);
1107                     glLineWidth(2.0);
1108                     glBegin(GL_LINE_STRIP);
1109                     glVertex3f(0, 0, 0.0f);
1110                     glVertex3f(1, 0, 0.0f);
1111                     glVertex3f(1, 1, 0.0f);
1112                     glVertex3f(0, 1, 0.0f);
1113                     glVertex3f(0, 0, 0.0f);
1114                     glEnd();
1115
1116                     glMatrixMode(GL_PROJECTION);
1117                     glPopMatrix();
1118                     glMatrixMode(GL_MODELVIEW);
1119                     glPopMatrix();
1120                     glEnable(GL_DEPTH_TEST);
1121                     glEnable(GL_CULL_FACE);
1122                     glDisable(GL_BLEND);
1123                     glDepthMask(1);
1124                     glEnable(GL_TEXTURE_2D);
1125
1126                     // writing the numbers :
1127                     string = "Damages : " + to_string(int(Person::players[0]->damage)) + "/" + to_string(int(Person::players[0]->damagetolerance)) + " (" + to_string(int(Person::players[0]->bloodloss)) + ")";
1128                     text->glPrintOutlined(1, 0, 0, 1, 1024 / 40, 768 / 16 + 768 * 14 / 16 - 40, string, 1, 1.5, 1024, 768);
1129                 }
1130             }
1131
1132             glColor4f(.5, .5, .5, 1);
1133
1134
1135             if ((texttoggle || editorenabled) && devtools && !mainmenu) {
1136                 string = "The framespersecond is " + to_string(int(fps));
1137                 text->glPrint(10, 30, string, 0, .8, 1024, 768);
1138
1139                 if (editorenabled) {
1140                     string = "Map editor enabled.";
1141                 } else {
1142                     string = "Map editor disabled.";
1143                 }
1144                 text->glPrint(10, 60, string, 0, .8, 1024, 768);
1145                 if (editorenabled) {
1146                     string = "Object size: " + to_string(editorsize);
1147                     text->glPrint(10, 75, string, 0, .8, 1024, 768);
1148                     if (editoryaw >= 0) {
1149                         string = "Object yaw: " + to_string(editoryaw);
1150                     } else {
1151                         string = "Object yaw: Random";
1152                     }
1153                     text->glPrint(10, 90, string, 0, .8, 1024, 768);
1154                     if (editorpitch >= 0) {
1155                         string = "Object pitch: " + to_string(editorpitch);
1156                     } else {
1157                         string = "Object pitch: Random";
1158                     }
1159                     text->glPrint(10, 105, string, 0, .8, 1024, 768);
1160                     string = "Object type: " + to_string(editortype);
1161                     text->glPrint(10, 120, string, 0, .8, 1024, 768);
1162                     switch (editortype) {
1163                     case boxtype:
1164                         string = "(box)";
1165                         break;
1166                     case treetrunktype:
1167                         string = "(tree)";
1168                         break;
1169                     case walltype:
1170                         string = "(wall)";
1171                         break;
1172                     case weirdtype:
1173                         string = "(weird)";
1174                         break;
1175                     case spiketype:
1176                         string = "(spike)";
1177                         break;
1178                     case rocktype:
1179                         string = "(rock)";
1180                         break;
1181                     case bushtype:
1182                         string = "(bush)";
1183                         break;
1184                     case tunneltype:
1185                         string = "(tunnel)";
1186                         break;
1187                     case chimneytype:
1188                         string = "(chimney)";
1189                         break;
1190                     case platformtype:
1191                         string = "(platform)";
1192                         break;
1193                     case cooltype:
1194                         string = "(cool)";
1195                         break;
1196                     case firetype:
1197                         string = "(fire)";
1198                         break;
1199                     }
1200                     text->glPrint(130, 120, string, 0, .8, 1024, 768);
1201
1202                     string = "Numplayers: " + to_string(Person::players.size());
1203                     text->glPrint(10, 155, string, 0, .8, 1024, 768);
1204                     string = "Player " + to_string(int(Person::players.size()) - 1) + ": numwaypoints: " + to_string(Person::players.back()->numwaypoints);
1205                     text->glPrint(10, 140, string, 0, .8, 1024, 768);
1206                 }
1207                 string = "Difficulty: " + to_string(difficulty);
1208                 text->glPrint(10, 240, string, 0, .8, 1024, 768);
1209
1210             }
1211         }
1212
1213         if (drawmode == glowmode) {
1214             glDisable(GL_DEPTH_TEST);
1215             glDisable(GL_CULL_FACE);
1216             glDisable(GL_LIGHTING);
1217             glDisable(GL_TEXTURE_2D);
1218             glDepthMask(0);
1219             glMatrixMode(GL_PROJECTION);
1220             glPushMatrix();
1221             glLoadIdentity();
1222             glOrtho(0, screenwidth, 0, screenheight, -100, 100);
1223             glMatrixMode(GL_MODELVIEW);
1224             glPushMatrix();
1225             glLoadIdentity();
1226             glScalef(screenwidth, screenheight, 1);
1227             glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1228             glEnable(GL_BLEND);
1229             glColor4f(0, 0, 0, .5);
1230             glBegin(GL_QUADS);
1231             glVertex3f(0, 0,  0.0f);
1232             glVertex3f(256, 0, 0.0f);
1233             glVertex3f(256, 256, 0.0f);
1234             glVertex3f(0, 256, 0.0f);
1235             glEnd();
1236             glMatrixMode(GL_PROJECTION);
1237             glPopMatrix();
1238             glMatrixMode(GL_MODELVIEW);
1239             glPopMatrix();
1240             glEnable(GL_DEPTH_TEST);
1241             glEnable(GL_CULL_FACE);
1242             glDisable(GL_BLEND);
1243             glDepthMask(1);
1244         }
1245
1246         if ((((blackout && damageeffects) || (Person::players[0]->bloodloss > 0 && damageeffects && Person::players[0]->blooddimamount > 0) || Person::players[0]->dead) && !cameramode) || console) {
1247             glDisable(GL_DEPTH_TEST);
1248             glDisable(GL_CULL_FACE);
1249             glDisable(GL_LIGHTING);
1250             glDisable(GL_TEXTURE_2D);
1251             glDepthMask(0);
1252             glMatrixMode(GL_PROJECTION);
1253             glPushMatrix();
1254             glLoadIdentity();
1255             glOrtho(0, screenwidth, 0, screenheight, -100, 100);
1256             glMatrixMode(GL_MODELVIEW);
1257             glPushMatrix();
1258             glLoadIdentity();
1259             glScalef(screenwidth, screenheight, 1);
1260             glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1261             glEnable(GL_BLEND);
1262             if (Person::players[0]->dead)
1263                 blackout += multiplier * 3;
1264             if (Person::players[0]->dead == 1)
1265                 blackout = .4f;
1266             if (Person::players[0]->dead == 2 && blackout > .6)
1267                 blackout = .6;
1268             glColor4f(0, 0, 0, blackout);
1269             if (!Person::players[0]->dead) {
1270                 if ((Person::players[0]->bloodloss / Person::players[0]->damagetolerance * (sin(woozy) / 4 + .5))*.3 < .3) {
1271                     glColor4f(0, 0, 0, Person::players[0]->blooddimamount * Person::players[0]->bloodloss / Person::players[0]->damagetolerance * (sin(woozy) / 4 + .5)*.3);
1272                     blackout = Person::players[0]->blooddimamount * Person::players[0]->bloodloss / Person::players[0]->damagetolerance * (sin(woozy) / 4 + .5) * .3;
1273                 } else {
1274                     glColor4f(0, 0, 0, Person::players[0]->blooddimamount * .3);
1275                     blackout = Person::players[0]->blooddimamount * .3;
1276                 }
1277             }
1278             if (console)
1279                 glColor4f(.7, 0, 0, .2);
1280             glBegin(GL_QUADS);
1281             glVertex3f(0, 0,  0.0f);
1282             glVertex3f(256, 0,  0.0f);
1283             glVertex3f(256, 256, 0.0f);
1284             glVertex3f(0, 256, 0.0f);
1285             glEnd();
1286             glMatrixMode(GL_PROJECTION);
1287             glPopMatrix();
1288             glMatrixMode(GL_MODELVIEW);
1289             glPopMatrix();
1290             glEnable(GL_DEPTH_TEST);
1291             glEnable(GL_CULL_FACE);
1292             glDisable(GL_BLEND);
1293             glDepthMask(1);
1294         }
1295
1296         if (flashamount > 0 && damageeffects) {
1297             if (flashamount > 1)
1298                 flashamount = 1;
1299             if (flashdelay <= 0)
1300                 flashamount -= multiplier;
1301             flashdelay--;
1302             if (flashamount < 0)
1303                 flashamount = 0;
1304             glDisable(GL_DEPTH_TEST);
1305             glDisable(GL_CULL_FACE);
1306             glDisable(GL_LIGHTING);
1307             glDepthMask(0);
1308             glMatrixMode(GL_PROJECTION);
1309             glPushMatrix();
1310             glLoadIdentity();
1311             glOrtho(0, screenwidth, 0, screenheight, -100, 100);
1312             glMatrixMode(GL_MODELVIEW);
1313             glPushMatrix();
1314             glLoadIdentity();
1315             glScalef(screenwidth, screenheight, 1);
1316             glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1317             glEnable(GL_BLEND);
1318             glColor4f(flashr, flashg, flashb, flashamount);
1319             glBegin(GL_QUADS);
1320             glVertex3f(0, 0,  0.0f);
1321             glVertex3f(256, 0, 0.0f);
1322             glVertex3f(256, 256, 0.0f);
1323             glVertex3f(0, 256, 0.0f);
1324             glEnd();
1325             glMatrixMode(GL_PROJECTION);
1326             glPopMatrix();
1327             glMatrixMode(GL_MODELVIEW);
1328             glPopMatrix();
1329             glEnable(GL_DEPTH_TEST);
1330             glEnable(GL_CULL_FACE);
1331             glDisable(GL_BLEND);
1332             glDepthMask(1);
1333         }
1334
1335         if (difficulty < 2 && !Dialog::inDialog()) { // minimap
1336             float mapviewdist = 20000;
1337
1338             glDisable(GL_DEPTH_TEST);
1339             glColor3f (1.0, 1.0, 1.0); // no coloring
1340
1341             glEnable(GL_TEXTURE_2D);
1342             glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
1343             glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
1344             glDisable(GL_DEPTH_TEST);
1345             glDisable(GL_CULL_FACE);
1346             glDisable(GL_LIGHTING);
1347             glDepthMask(0);
1348             glMatrixMode(GL_PROJECTION);
1349             glPushMatrix();
1350             glLoadIdentity();
1351             glOrtho(0, screenwidth, 0, screenheight, -100, 100);
1352             glMatrixMode(GL_MODELVIEW);
1353             glPushMatrix();
1354             glLoadIdentity();
1355             glScalef((float)screenwidth / 2, (float)screenwidth / 2, 1);
1356             glTranslatef(1.75, .25, 0);
1357             glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1358             glEnable(GL_BLEND);
1359             glColor4f(1, 1, 1, 1);
1360             glPushMatrix();
1361             float opac = .7;
1362             XYZ center;
1363             float radius;
1364             float distcheck;
1365
1366             center = Person::players[0]->coords;
1367
1368             radius = 110;
1369
1370             glScalef(.25 / radius * 256 * terrain.scale * .4, .25 / radius * 256 * terrain.scale * .4, 1);
1371             glPushMatrix();
1372             glScalef(1 / (1 / radius * 256 * terrain.scale * .4), 1 / (1 / radius * 256 * terrain.scale * .4), 1);
1373             glPopMatrix();
1374             glRotatef(Person::players[0]->lookyaw * -1 + 180, 0, 0, 1);
1375             glTranslatef(-(center.x / terrain.scale / 256 * -2 + 1), (center.z / terrain.scale / 256 * -2 + 1), 0);
1376             for (int i = 0; i < Object::objects.size(); i++) {
1377                 if (Object::objects[i]->type == treetrunktype) {
1378                     distcheck = distsq(&Person::players[0]->coords, &Object::objects[i]->position);
1379                     if (distcheck < mapviewdist) {
1380                         Mapcircletexture.bind();
1381                         glColor4f(0, .3, 0, opac * (1 - distcheck / mapviewdist));
1382                         glPushMatrix();
1383                         glTranslatef(Object::objects[i]->position.x / terrain.scale / 256 * -2 + 1, Object::objects[i]->position.z / terrain.scale / 256 * 2 - 1, 0);
1384                         glRotatef(Object::objects[i]->yaw, 0, 0, 1);
1385                         glScalef(.003, .003, .003);
1386                         glBegin(GL_QUADS);
1387                         glTexCoord2f(0, 0);
1388                         glVertex3f(-1, -1, 0.0f);
1389                         glTexCoord2f(1, 0);
1390                         glVertex3f(1, -1, 0.0f);
1391                         glTexCoord2f(1, 1);
1392                         glVertex3f(1, 1, 0.0f);
1393                         glTexCoord2f(0, 1);
1394                         glVertex3f(-1, 1, 0.0f);
1395                         glEnd();
1396                         glPopMatrix();
1397                     }
1398                 }
1399                 if (Object::objects[i]->type == boxtype) {
1400                     distcheck = distsq(&Person::players[0]->coords, &Object::objects[i]->position);
1401                     if (distcheck < mapviewdist) {
1402                         Mapboxtexture.bind();
1403                         glColor4f(.4, .4, .4, opac * (1 - distcheck / mapviewdist));
1404                         glPushMatrix();
1405                         glTranslatef(Object::objects[i]->position.x / terrain.scale / 256 * -2 + 1, Object::objects[i]->position.z / terrain.scale / 256 * 2 - 1, 0);
1406                         glRotatef(Object::objects[i]->yaw, 0, 0, 1);
1407                         glScalef(.01 * Object::objects[i]->scale, .01 * Object::objects[i]->scale, .01 * Object::objects[i]->scale);
1408                         glBegin(GL_QUADS);
1409                         glTexCoord2f(0, 0);
1410                         glVertex3f(-1, -1, 0.0f);
1411                         glTexCoord2f(1, 0);
1412                         glVertex3f(1, -1, 0.0f);
1413                         glTexCoord2f(1, 1);
1414                         glVertex3f(1, 1, 0.0f);
1415                         glTexCoord2f(0, 1);
1416                         glVertex3f(-1, 1, 0.0f);
1417                         glEnd();
1418                         glPopMatrix();
1419                     }
1420                 }
1421             }
1422             if (editorenabled) {
1423                 Mapcircletexture.bind();
1424                 for (int i = 0; i < numboundaries; i++) {
1425                     glColor4f(0, 0, 0, opac / 3);
1426                     glPushMatrix();
1427                     glTranslatef(boundary[i].x / terrain.scale / 256 * -2 + 1, boundary[i].z / terrain.scale / 256 * 2 - 1, 0);
1428                     glScalef(.002, .002, .002);
1429                     glBegin(GL_QUADS);
1430                     glTexCoord2f(0, 0);
1431                     glVertex3f(-1, -1, 0.0f);
1432                     glTexCoord2f(1, 0);
1433                     glVertex3f(1, -1, 0.0f);
1434                     glTexCoord2f(1, 1);
1435                     glVertex3f(1, 1, 0.0f);
1436                     glTexCoord2f(0, 1);
1437                     glVertex3f(-1, 1, 0.0f);
1438                     glEnd();
1439                     glPopMatrix();
1440                 }
1441             }
1442             for (unsigned i = 0; i < Person::players.size(); i++) {
1443                 distcheck = distsq(&Person::players[0]->coords, &Person::players[i]->coords);
1444                 if (distcheck < mapviewdist) {
1445                     glPushMatrix();
1446                     Maparrowtexture.bind();
1447                     if (i == 0)
1448                         glColor4f(1, 1, 1, opac);
1449                     else if (Person::players[i]->dead == 2 || Person::players[i]->howactive > typesleeping)
1450                         glColor4f(0, 0, 0, opac * (1 - distcheck / mapviewdist));
1451                     else if (Person::players[i]->dead)
1452                         glColor4f(.3, .3, .3, opac * (1 - distcheck / mapviewdist));
1453                     else if (Person::players[i]->aitype == attacktypecutoff)
1454                         glColor4f(1, 0, 0, opac * (1 - distcheck / mapviewdist));
1455                     else if (Person::players[i]->aitype == passivetype)
1456                         glColor4f(0, 1, 0, opac * (1 - distcheck / mapviewdist));
1457                     else
1458                         glColor4f(1, 1, 0, 1);
1459                     glTranslatef(Person::players[i]->coords.x / terrain.scale / 256 * -2 + 1, Person::players[i]->coords.z / terrain.scale / 256 * 2 - 1, 0);
1460                     glRotatef(Person::players[i]->yaw + 180, 0, 0, 1);
1461                     glScalef(.005, .005, .005);
1462                     glBegin(GL_QUADS);
1463                     glTexCoord2f(0, 0);
1464                     glVertex3f(-1, -1, 0.0f);
1465                     glTexCoord2f(1, 0);
1466                     glVertex3f(1, -1, 0.0f);
1467                     glTexCoord2f(1, 1);
1468                     glVertex3f(1, 1, 0.0f);
1469                     glTexCoord2f(0, 1);
1470                     glVertex3f(-1, 1, 0.0f);
1471                     glEnd();
1472                     glPopMatrix();
1473                 }
1474             }
1475             glPopMatrix();
1476             glDisable(GL_TEXTURE_2D);
1477             glMatrixMode(GL_PROJECTION);
1478             glPopMatrix();
1479             glMatrixMode(GL_MODELVIEW);
1480             glPopMatrix();
1481             glEnable(GL_DEPTH_TEST);
1482             glEnable(GL_CULL_FACE);
1483             glDisable(GL_BLEND);
1484             glDepthMask(1);
1485         }
1486
1487         if (loading && !stealthloading && (!campaign || Person::players[0]->dead)) {
1488             glDisable(GL_DEPTH_TEST);
1489             glDisable(GL_CULL_FACE);
1490             glDisable(GL_LIGHTING);
1491             glDisable(GL_TEXTURE_2D);
1492             glDepthMask(0);
1493             glMatrixMode(GL_PROJECTION);
1494             glPushMatrix();
1495             glLoadIdentity();
1496             glOrtho(0, screenwidth, 0, screenheight, -100, 100);
1497             glMatrixMode(GL_MODELVIEW);
1498             glPushMatrix();
1499             glLoadIdentity();
1500             glScalef(screenwidth, screenheight, 1);
1501             glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1502             glEnable(GL_BLEND);
1503             glColor4f(0, 0, 0, .7);
1504             glBegin(GL_QUADS);
1505             glVertex3f(0, 0, 0.0f);
1506             glVertex3f(256, 0, 0.0f);
1507             glVertex3f(256, 256, 0.0f);
1508             glVertex3f(0, 256, 0.0f);
1509             glEnd();
1510             glMatrixMode(GL_PROJECTION);
1511             glPopMatrix();
1512             glMatrixMode(GL_MODELVIEW);
1513             glPopMatrix();
1514             glEnable(GL_DEPTH_TEST);
1515             glEnable(GL_CULL_FACE);
1516             glDisable(GL_BLEND);
1517             glDepthMask(1);
1518
1519             //logo
1520             glDisable(GL_DEPTH_TEST);
1521             glColor3f (1.0, 1.0, 1.0); // no coloring
1522
1523             glEnable(GL_TEXTURE_2D);
1524
1525             //Minimap
1526
1527             if (loading != 4) {
1528                 glEnable(GL_TEXTURE_2D);
1529                 glColor4f(1, 1, 1, 1);
1530                 string = "Loading...";
1531                 text->glPrint(1024 / 2 - 90, 768 / 2, string, 1, 2, 1024, 768);
1532             }
1533             loading = 2;
1534             drawmode = normalmode;
1535         }
1536
1537         if (winfreeze && !campaign) {
1538             glDisable(GL_DEPTH_TEST);
1539             glDisable(GL_CULL_FACE);
1540             glDisable(GL_LIGHTING);
1541             glDisable(GL_TEXTURE_2D);
1542             glDepthMask(0);
1543             glMatrixMode(GL_PROJECTION);
1544             glPushMatrix();
1545             glLoadIdentity();
1546             glOrtho(0, screenwidth, 0, screenheight, -100, 100);
1547             glMatrixMode(GL_MODELVIEW);
1548             glPushMatrix();
1549             glLoadIdentity();
1550             glScalef(screenwidth, screenheight, 1);
1551             glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1552             glEnable(GL_BLEND);
1553             glColor4f(0, 0, 0, .4);
1554             glBegin(GL_QUADS);
1555             glVertex3f(0, 0, 0.0f);
1556             glVertex3f(256, 0, 0.0f);
1557             glVertex3f(256, 256, 0.0f);
1558             glVertex3f(0, 256, 0.0f);
1559             glEnd();
1560             glMatrixMode(GL_PROJECTION);
1561             glPopMatrix();
1562             glMatrixMode(GL_MODELVIEW);
1563             glPopMatrix();
1564             glEnable(GL_DEPTH_TEST);
1565             glEnable(GL_CULL_FACE);
1566             glDisable(GL_BLEND);
1567             glDepthMask(1);
1568
1569             //logo
1570             glDisable(GL_DEPTH_TEST);
1571             glColor3f (1.0, 1.0, 1.0); // no coloring
1572
1573             glEnable(GL_TEXTURE_2D);
1574
1575             //Win Screen Won Victory
1576
1577             glEnable(GL_TEXTURE_2D);
1578             glColor4f(1, 1, 1, 1);
1579             string = "Level Cleared!";
1580             text->glPrintOutlined(1024 / 2 - string.size() * 10, 768 * 7 / 8, string, 1, 2, 1024, 768);
1581
1582             string = "Score:     " + to_string(int(bonustotal - startbonustotal));
1583             text->glPrintOutlined(1024 / 30, 768 * 6 / 8, string, 1, 2, 1024, 768);
1584
1585             string = "Press Escape to return to menu or Space to continue";
1586             text->glPrintOutlined(640 / 2 - string.size() * 5, 480 * 1 / 16, string, 1, 1, 640, 480);
1587
1588             int wontime = (int)round(wonleveltime);
1589             string = "Time:      " + to_string(int((wontime - wontime % 60) / 60));
1590             if (wontime % 60 < 10) {
1591                 string += "0";
1592             }
1593             string += to_string(int(wontime % 60));
1594             text->glPrintOutlined(1024 / 30, 768 * 6 / 8 - 40, string, 1, 2, 1024, 768);
1595
1596             //Awards
1597             int awards[award_count];
1598             int numawards = award_awards(awards);
1599
1600             for (int i = 0; i < numawards && i < 6; i++)
1601                 text->glPrintOutlined(1024 / 30, 768 * 6 / 8 - 90 - 40 * i, award_names[awards[i]], 1, 2, 1024, 768);
1602         }
1603
1604         if (drawmode != normalmode) {
1605             glEnable(GL_TEXTURE_2D);
1606             glFinish();
1607             if (!drawtoggle || drawmode != realmotionblurmode || (drawtoggle == 2 || change == 1)) {
1608                 if (screentexture) {
1609
1610                     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
1611                     GLfloat subtractColor[4] = { 0.5, 0.5, 0.5, 0.0 };
1612                     glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, subtractColor);
1613                     glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE);
1614                     glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_CONSTANT);
1615                     glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE, 2.0f);
1616
1617                     glBindTexture( GL_TEXTURE_2D, screentexture);
1618                     glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, texviewwidth, texviewheight);
1619                 }
1620             }
1621             if ((drawtoggle || change == 1) && drawmode == realmotionblurmode) {
1622                 if (screentexture2) {
1623                     glBindTexture( GL_TEXTURE_2D, screentexture2);
1624                     glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, texviewwidth, texviewheight);
1625                 }
1626                 if (!screentexture2) {
1627                     glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
1628
1629                     glGenTextures( 1, &screentexture2 );
1630                     glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
1631
1632                     glEnable(GL_TEXTURE_2D);
1633                     glBindTexture( GL_TEXTURE_2D, screentexture2);
1634                     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
1635                     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
1636
1637                     glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, kTextureSize, kTextureSize, 0);
1638                 }
1639             }
1640         }
1641
1642         glClear(GL_DEPTH_BUFFER_BIT);
1643         Game::ReSizeGLScene(90, .1f);
1644         glViewport(0, 0, screenwidth, screenheight);
1645
1646         if (drawmode != normalmode) {
1647             glDisable(GL_DEPTH_TEST);
1648             if (drawmode == motionblurmode) {
1649                 glDrawBuffer(GL_FRONT);
1650                 glReadBuffer(GL_BACK);
1651             }
1652             glColor3f (1.0, 1.0, 1.0); // no coloring
1653
1654             glEnable(GL_TEXTURE_2D);
1655             glBindTexture( GL_TEXTURE_2D, screentexture);
1656             glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
1657             glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
1658             glDisable(GL_DEPTH_TEST);
1659             glDisable(GL_CULL_FACE);
1660             glDisable(GL_LIGHTING);
1661             glDepthMask(0);
1662             glMatrixMode(GL_PROJECTION);
1663             glPushMatrix();
1664             glLoadIdentity();
1665             glOrtho(0, screenwidth, 0, screenheight, -100, 100);
1666             glMatrixMode(GL_MODELVIEW);
1667             glPushMatrix();
1668             glLoadIdentity();
1669             glScalef((float)screenwidth / 2, (float)screenheight / 2, 1);
1670             glTranslatef(1, 1, 0);
1671             glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1672             glEnable(GL_BLEND);
1673             if (drawmode == motionblurmode) {
1674                 if (motionbluramount < .2)
1675                     motionbluramount = .2;
1676                 glColor4f(1, 1, 1, motionbluramount);
1677                 glPushMatrix();
1678                 glBegin(GL_QUADS);
1679                 glTexCoord2f(0, 0);
1680                 glVertex3f(-1, -1, 0.0f);
1681                 glTexCoord2f(texcoordwidth, 0);
1682                 glVertex3f(1, -1, 0.0f);
1683                 glTexCoord2f(texcoordwidth, texcoordheight);
1684                 glVertex3f(1, 1, 0.0f);
1685                 glTexCoord2f(0, texcoordheight);
1686                 glVertex3f(-1, 1, 0.0f);
1687                 glEnd();
1688                 glPopMatrix();
1689             }
1690             if (drawmode == realmotionblurmode) {
1691                 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
1692                 glClear(GL_COLOR_BUFFER_BIT);
1693                 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
1694                 glBindTexture( GL_TEXTURE_2D, screentexture);
1695                 glColor4f(1, 1, 1, .5);
1696                 glPushMatrix();
1697                 glBegin(GL_QUADS);
1698                 glTexCoord2f(0, 0);
1699                 glVertex3f(-1, -1, 0.0f);
1700                 glTexCoord2f(texcoordwidth, 0);
1701                 glVertex3f(1, -1, 0.0f);
1702                 glTexCoord2f(texcoordwidth, texcoordheight);
1703                 glVertex3f(1, 1, 0.0f);
1704                 glTexCoord2f(0, texcoordheight);
1705                 glVertex3f(-1, 1, 0.0f);
1706                 glEnd();
1707                 glPopMatrix();
1708                 glBindTexture( GL_TEXTURE_2D, screentexture2);
1709                 glColor4f(1, 1, 1, .5);
1710                 glPushMatrix();
1711                 glBegin(GL_QUADS);
1712                 glTexCoord2f(0, 0);
1713                 glVertex3f(-1, -1, 0.0f);
1714                 glTexCoord2f(texcoordwidth, 0);
1715                 glVertex3f(1, -1, 0.0f);
1716                 glTexCoord2f(texcoordwidth, texcoordheight);
1717                 glVertex3f(1, 1, 0.0f);
1718                 glTexCoord2f(0, texcoordheight);
1719                 glVertex3f(-1, 1, 0.0f);
1720                 glEnd();
1721                 glPopMatrix();
1722                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1723             }
1724             if (drawmode == doublevisionmode) {
1725                 static float crosseyedness;
1726                 crosseyedness = abs(Person::players[0]->damage - Person::players[0]->superpermanentdamage - (Person::players[0]->damagetolerance - Person::players[0]->superpermanentdamage) * 1 / 2) / 30;
1727                 if (crosseyedness > 1)
1728                     crosseyedness = 1;
1729                 if (crosseyedness < 0)
1730                     crosseyedness = 0;
1731                 glColor4f(1, 1, 1, 1);
1732                 glDisable(GL_BLEND);
1733                 glPushMatrix();
1734                 glScalef(1, 1, 1);
1735                 glBegin(GL_QUADS);
1736                 glTexCoord2f(0, 0);
1737                 glVertex3f(-1, -1, 0.0f);
1738                 glTexCoord2f(texcoordwidth, 0);
1739                 glVertex3f(1, -1, 0.0f);
1740                 glTexCoord2f(texcoordwidth, texcoordheight);
1741                 glVertex3f(1, 1, 0.0f);
1742                 glTexCoord2f(0, texcoordheight);
1743                 glVertex3f(-1, 1, 0.0f);
1744                 glEnd();
1745                 glPopMatrix();
1746                 if (crosseyedness) {
1747                     glColor4f(1, 1, 1, .5);
1748                     glEnable(GL_BLEND);
1749                     glPushMatrix();
1750                     glTranslatef(.015 * crosseyedness, 0, 0);
1751                     glScalef(1, 1, 1);
1752                     glBegin(GL_QUADS);
1753                     glTexCoord2f(0, 0);
1754                     glVertex3f(-1, -1, 0.0f);
1755                     glTexCoord2f(texcoordwidth, 0);
1756                     glVertex3f(1, -1, 0.0f);
1757                     glTexCoord2f(texcoordwidth, texcoordheight);
1758                     glVertex3f(1, 1, 0.0f);
1759                     glTexCoord2f(0, texcoordheight);
1760                     glVertex3f(-1, 1, 0.0f);
1761                     glEnd();
1762                     glPopMatrix();
1763                 }
1764             }
1765             if (drawmode == glowmode) {
1766                 glColor4f(.5, .5, .5, .5);
1767                 glEnable(GL_BLEND);
1768                 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
1769                 glPushMatrix();
1770                 glTranslatef(.01, 0, 0);
1771                 glBegin(GL_QUADS);
1772                 glTexCoord2f(0, 0);
1773                 glVertex3f(-1, -1, 0.0f);
1774                 glTexCoord2f(texcoordwidth, 0);
1775                 glVertex3f(1, -1, 0.0f);
1776                 glTexCoord2f(texcoordwidth, texcoordheight);
1777                 glVertex3f(1, 1, 0.0f);
1778                 glTexCoord2f(0, texcoordheight);
1779                 glVertex3f(-1, 1, 0.0f);
1780                 glEnd();
1781                 glPopMatrix();
1782                 glPushMatrix();
1783                 glTranslatef(-.01, 0, 0);
1784                 glBegin(GL_QUADS);
1785                 glTexCoord2f(0, 0);
1786                 glVertex3f(-1, -1, 0.0f);
1787                 glTexCoord2f(texcoordwidth, 0);
1788                 glVertex3f(1, -1, 0.0f);
1789                 glTexCoord2f(texcoordwidth, texcoordheight);
1790                 glVertex3f(1, 1, 0.0f);
1791                 glTexCoord2f(0, texcoordheight);
1792                 glVertex3f(-1, 1, 0.0f);
1793                 glEnd();
1794                 glPopMatrix();
1795                 glPushMatrix();
1796                 glTranslatef(.0, .01, 0);
1797                 glBegin(GL_QUADS);
1798                 glTexCoord2f(0, 0);
1799                 glVertex3f(-1, -1, 0.0f);
1800                 glTexCoord2f(texcoordwidth, 0);
1801                 glVertex3f(1, -1, 0.0f);
1802                 glTexCoord2f(texcoordwidth, texcoordheight);
1803                 glVertex3f(1, 1, 0.0f);
1804                 glTexCoord2f(0, texcoordheight);
1805                 glVertex3f(-1, 1, 0.0f);
1806                 glEnd();
1807                 glPopMatrix();
1808                 glPushMatrix();
1809                 glTranslatef(0, -.01, 0);
1810                 glBegin(GL_QUADS);
1811                 glTexCoord2f(0, 0);
1812                 glVertex3f(-1, -1, 0.0f);
1813                 glTexCoord2f(texcoordwidth, 0);
1814                 glVertex3f(1, -1, 0.0f);
1815                 glTexCoord2f(texcoordwidth, texcoordheight);
1816                 glVertex3f(1, 1, 0.0f);
1817                 glTexCoord2f(0, texcoordheight);
1818                 glVertex3f(-1, 1, 0.0f);
1819                 glEnd();
1820                 glPopMatrix();
1821             }
1822             if (drawmode == radialzoommode) {
1823                 for (int i = 0; i < 3; i++) {
1824                     glColor4f(1, 1, 1, 1 / ((float)i + 1));
1825                     glPushMatrix();
1826                     glScalef(1 + (float)i * .01, 1 + (float)i * .01, 1);
1827                     glBegin(GL_QUADS);
1828                     glTexCoord2f(0, 0);
1829                     glVertex3f(-1, -1, 0.0f);
1830                     glTexCoord2f(texcoordwidth, 0);
1831                     glVertex3f(1, -1, 0.0f);
1832                     glTexCoord2f(texcoordwidth, texcoordheight);
1833                     glVertex3f(1, 1, 0.0f);
1834                     glTexCoord2f(0, texcoordheight);
1835                     glVertex3f(-1, 1, 0.0f);
1836                     glEnd();
1837                     glPopMatrix();
1838                 }
1839             }
1840             glDisable(GL_TEXTURE_2D);
1841             glMatrixMode(GL_PROJECTION);
1842             glPopMatrix();
1843             glMatrixMode(GL_MODELVIEW);
1844             glPopMatrix();
1845             glEnable(GL_DEPTH_TEST);
1846             glEnable(GL_CULL_FACE);
1847             glDisable(GL_BLEND);
1848             glDepthMask(1);
1849         }
1850
1851         if (console) {
1852             glEnable(GL_TEXTURE_2D);
1853             glColor4f(1, 1, 1, 1);
1854             int offset = 0;
1855             if (consoleselected >= 60)
1856                 offset = consoleselected - 60;
1857             text->glPrint(10, 30, " ]", 0, 1, 1024, 768);
1858             if (consoleblink) {
1859                 text->glPrint(30 + (float)(consoleselected) * 10 - offset * 10, 30, "_", 0, 1, 1024, 768);
1860             }
1861             for (unsigned i = 0; i < 15; i++) {
1862                 text->glPrint(30 - offset * 10, 30 + i * 20, consoletext[i], 0, 1, 1024, 768);
1863             }
1864         }
1865     }
1866
1867     if (freeze || winfreeze || (mainmenu && gameon) || (!gameon && gamestarted)) {
1868         multiplier = tempmult;
1869     }
1870
1871     if (mainmenu) {
1872         DrawMenu();
1873     }
1874
1875     if (freeze || winfreeze || (mainmenu && gameon) || (!gameon && gamestarted)) {
1876         tempmult = multiplier;
1877         multiplier = 0;
1878     }
1879
1880     if ( side == stereoRight || side == stereoCenter ) {
1881         if (drawmode != motionblurmode || mainmenu) {
1882             swap_gl_buffers();
1883         }
1884     }
1885
1886     glDrawBuffer(GL_BACK);
1887     glReadBuffer(GL_BACK);
1888
1889     weapons.DoStuff();
1890
1891     if (drawtoggle == 2)
1892         drawtoggle = 0;
1893
1894     if (freeze || winfreeze || (mainmenu && gameon) || (!gameon && gamestarted)) {
1895         multiplier = tempmult;
1896     }
1897     //Jordan fixed your warning!
1898     return 0;
1899 }
1900
1901 void DrawMenu()
1902 {
1903     // !!! FIXME: hack: clamp framerate in menu so text input works correctly on fast systems.
1904     SDL_Delay(15);
1905
1906     glDrawBuffer(GL_BACK);
1907     glReadBuffer(GL_BACK);
1908     glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
1909     Game::ReSizeGLScene(90, .1f);
1910
1911     //draw menu background
1912     glClear(GL_DEPTH_BUFFER_BIT);
1913     glEnable(GL_ALPHA_TEST);
1914     glAlphaFunc(GL_GREATER, 0.001f);
1915     glEnable(GL_TEXTURE_2D);
1916     glDisable(GL_DEPTH_TEST);
1917     glDisable(GL_CULL_FACE);
1918     glDisable(GL_LIGHTING);
1919     glDepthMask(0);
1920     glMatrixMode(GL_PROJECTION);
1921     glPushMatrix();
1922     glLoadIdentity();
1923     glOrtho(0, screenwidth, 0, screenheight, -100, 100);
1924     glMatrixMode(GL_MODELVIEW);
1925     glPushMatrix();
1926     glLoadIdentity();
1927     glTranslatef(screenwidth / 2, screenheight / 2, 0);
1928     glPushMatrix();
1929     glScalef((float)screenwidth / 2, (float)screenheight / 2, 1);
1930     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1931     glDisable(GL_BLEND);
1932     glColor4f(0, 0, 0, 1.0);
1933     glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
1934     glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
1935     glDisable(GL_TEXTURE_2D);
1936     glBegin(GL_QUADS);
1937     glVertex3f(-1, -1, 0);
1938     glVertex3f(+1, -1, 0);
1939     glVertex3f(+1, +1, 0);
1940     glVertex3f(-1, +1, 0);
1941     glEnd();
1942     glEnable(GL_BLEND);
1943     glColor4f(0.4, 0.4, 0.4, 1.0);
1944     glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
1945     glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
1946     glEnable(GL_TEXTURE_2D);
1947     Game::Mainmenuitems[4].bind();
1948     glBegin(GL_QUADS);
1949     glTexCoord2f(0, 0);
1950     glVertex3f(-1, -1, 0);
1951     glTexCoord2f(1, 0);
1952     glVertex3f(+1, -1, 0);
1953     glTexCoord2f(1, 1);
1954     glVertex3f(+1, +1, 0);
1955     glTexCoord2f(0, 1);
1956     glVertex3f(-1, +1, 0);
1957     glEnd();
1958     glPopMatrix();
1959     glPopMatrix();
1960     glMatrixMode(GL_PROJECTION);
1961     glPopMatrix();
1962     glMatrixMode(GL_MODELVIEW);
1963
1964
1965
1966     glMatrixMode(GL_PROJECTION);
1967     glPushMatrix();
1968     glLoadIdentity();
1969     glOrtho(0, 640, 0, 480, -100, 100);
1970     glMatrixMode(GL_MODELVIEW);
1971     glPushMatrix();
1972     glLoadIdentity();
1973     glEnable(GL_TEXTURE_2D);
1974
1975     Menu::drawItems();
1976
1977     //draw mouse cursor
1978     glMatrixMode(GL_PROJECTION);
1979     glPopMatrix();
1980     glMatrixMode(GL_MODELVIEW);
1981     glPopMatrix();
1982
1983     glMatrixMode(GL_PROJECTION);
1984     glPushMatrix();
1985     glLoadIdentity();
1986     glOrtho(0, screenwidth, 0, screenheight, -100, 100);
1987     glMatrixMode(GL_MODELVIEW);
1988     glPushMatrix();
1989     glLoadIdentity();
1990     glTranslatef(screenwidth / 2, screenheight / 2, 0);
1991     glPushMatrix();
1992     glScalef((float)screenwidth / 2, (float)screenheight / 2, 1);
1993     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1994     glEnable(GL_BLEND);
1995     glEnable(GL_TEXTURE_2D);
1996     glColor4f(1, 1, 1, 1);
1997     glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
1998     glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
1999     glPopMatrix();
2000     if (!Game::waiting) { // hide the cursor while waiting for a key
2001         glPushMatrix();
2002         glTranslatef(Game::mousecoordh - screenwidth / 2, Game::mousecoordv * -1 + screenheight / 2, 0);
2003         glScalef((float)screenwidth / 64, (float)screenwidth / 64, 1);
2004         glTranslatef(1, -1, 0);
2005         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2006         glColor4f(1, 1, 1, 1);
2007         Game::cursortexture.bind();
2008         glPushMatrix();
2009         glBegin(GL_QUADS);
2010         glTexCoord2f(0, 0);
2011         glVertex3f(-1, -1, 0.0f);
2012         glTexCoord2f(1, 0);
2013         glVertex3f(1, -1, 0.0f);
2014         glTexCoord2f(1, 1);
2015         glVertex3f(1, 1, 0.0f);
2016         glTexCoord2f(0, 1);
2017         glVertex3f(-1, 1, 0.0f);
2018         glEnd();
2019         glPopMatrix();
2020         glPopMatrix();
2021     }
2022     glPopMatrix();
2023     glMatrixMode(GL_PROJECTION);
2024     glPopMatrix();
2025
2026
2027     //draw screen flash
2028     if (flashamount > 0) {
2029         if (flashamount > 1)
2030             flashamount = 1;
2031         if (flashdelay <= 0)
2032             flashamount -= multiplier;
2033         flashdelay--;
2034         if (flashamount < 0)
2035             flashamount = 0;
2036         glDisable(GL_DEPTH_TEST);
2037         glDisable(GL_CULL_FACE);
2038         glDisable(GL_LIGHTING);
2039         glDisable(GL_TEXTURE_2D);
2040         glDepthMask(0);
2041         glMatrixMode(GL_PROJECTION);
2042         glPushMatrix();
2043         glLoadIdentity();
2044         glOrtho(0, screenwidth, 0, screenheight, -100, 100);
2045         glMatrixMode(GL_MODELVIEW);
2046         glPushMatrix();
2047         glLoadIdentity();
2048         glScalef(screenwidth, screenheight, 1);
2049         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2050         glEnable(GL_BLEND);
2051         glColor4f(flashr, flashg, flashb, flashamount);
2052         glBegin(GL_QUADS);
2053         glVertex3f(0, 0, 0.0f);
2054         glVertex3f(256, 0, 0.0f);
2055         glVertex3f(256, 256, 0.0f);
2056         glVertex3f(0, 256, 0.0f);
2057         glEnd();
2058         glMatrixMode(GL_PROJECTION);
2059         glPopMatrix();
2060         glMatrixMode(GL_MODELVIEW);
2061         glPopMatrix();
2062         glEnable(GL_DEPTH_TEST);
2063         glEnable(GL_CULL_FACE);
2064         glDisable(GL_BLEND);
2065         glDepthMask(1);
2066     }
2067 }