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