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