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