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