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