]> git.jsancho.org Git - lugaru.git/blob - Source/GameInitDispose.cpp
Some cleans, fullscreen is back if "--windowed" isn't passed as option.
[lugaru.git] / Source / GameInitDispose.cpp
1 /*
2 Copyright (C) 2003, 2010 - Wolfire Games
3
4 This file is part of Lugaru.
5
6 Lugaru is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
15 See the GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20 */
21
22 #include "Game.h"
23 #include "openal_wrapper.h"
24 #include "Animation.h"
25
26 extern float screenwidth,screenheight;
27 extern float viewdistance;
28 extern XYZ viewer;
29 extern XYZ lightlocation;
30 extern float lightambient[3],lightbrightness[3];
31 extern float fadestart;
32 extern float texscale;
33 extern float gravity;
34 extern Light light;
35 extern Skeleton testskeleton;
36 extern int numsounds;
37 extern Terrain terrain;
38 //extern Sprites sprites;
39 extern int kTextureSize;
40 extern float texdetail;
41 extern float realtexdetail;
42 extern float volume;
43 extern Objects objects;
44 extern int detail;
45 extern bool cellophane;
46 extern GLubyte bloodText[512*512*3];
47 extern GLubyte wolfbloodText[512*512*3];
48 extern bool ismotionblur;
49 extern bool trilinear;
50 extern bool osx;
51 extern bool musictoggle;
52 extern int environment;
53 extern bool ambientsound;
54 extern float multiplier;
55 extern int netdatanew;
56 extern float mapinfo;
57 extern bool stillloading;
58 extern TGAImageRec texture;
59 extern short vRefNum;
60 extern long dirID;
61 extern int mainmenu;
62 extern int oldmainmenu;
63 extern bool visibleloading;
64 extern float flashamount,flashr,flashg,flashb;
65 extern int flashdelay;
66 extern int whichjointstartarray[26];
67 extern int whichjointendarray[26];
68 extern int difficulty;
69 extern float tintr,tintg,tintb;
70 extern float slomospeed;
71 extern bool gamestarted;
72
73 extern int numdialogues;
74 extern int numdialogueboxes[20];
75 extern int dialoguetype[20];
76 extern int dialogueboxlocation[20][20];
77 extern float dialogueboxcolor[20][20][3];
78 extern int dialogueboxsound[20][20];
79 extern char dialoguetext[20][20][128];
80 extern char dialoguename[20][20][64];
81 extern XYZ dialoguecamera[20][20];
82 extern float dialoguecamerarotation[20][20];
83 extern float dialoguecamerarotation2[20][20];
84 extern int indialogue;
85 extern int whichdialogue;
86 extern float dialoguetime;
87
88 extern float accountcampaignhighscore[10];
89 extern float accountcampaignfasttime[10];
90 extern float accountcampaignscore[10];
91 extern float accountcampaigntime[10];
92
93 extern int accountcampaignchoicesmade[10];
94 extern int accountcampaignchoices[10][5000];
95
96 void LOG(const std::string &fmt, ...)
97 {
98     // !!! FIXME: write me.
99 }
100
101
102 void Game::Dispose()
103 {
104         LOGFUNC;
105
106         if(endgame==2){
107                 accountactive->endGame();
108                 endgame=0;
109         }
110
111         Account::saveFile(":Data:Users", accountactive);
112
113         //textures.clear();
114
115         LOG("Shutting down sound system...");
116
117         OPENAL_StopSound(OPENAL_ALL);
118
119 // this is causing problems on Linux, but we'll force an _exit() a little
120 //  later in the shutdown process.  --ryan.
121 #if !PLATFORM_LINUX
122
123         for (int i=0; i < sounds_count; ++i)
124         {
125                 OPENAL_Sample_Free(samp[i]);
126         }
127
128         OPENAL_Close();
129         if (texture.data)
130         {
131                 free(texture.data);
132         }
133         texture.data = 0;
134 #endif
135 }
136
137
138 void Game::LoadTexture(const char *fileName, GLuint *textureid,int mipmap, bool hasalpha){
139     textures.push_back(TextureInfo(fileName,textureid,mipmap,hasalpha));
140     textures.back().load();
141 }
142
143 void Game::LoadTextureSave(const char *fileName, GLuint *textureid,int mipmap,GLubyte *array, int *skinsize){
144     textures.push_back(TextureInfo(fileName,textureid,mipmap,array,skinsize));
145     textures.back().load();
146 }
147
148 void Game::LoadTextureData(const char *fileName, GLuint *textureid,int mipmap, bool hasalpha)
149 {
150         GLuint          type;
151
152         LOGFUNC;
153
154         LOG(std::string("Loading texture...") + fileName);
155
156         // Fix filename so that is os appropreate
157         char * fixedFN = ConvertFileName(fileName);
158
159         unsigned char fileNamep[256];
160         CopyCStringToPascal(fixedFN, fileNamep);
161         //Load Image
162         upload_image( fileNamep ,hasalpha);
163
164 //      std::string fname(fileName);
165 //      std::transform(fname.begin(), fname.end(), tolower);
166 //      TexIter it = textures.find(fname);
167
168         //Is it valid?
169         if(1==1)
170         //if(textures.end() == it)
171         {
172                 //Alpha channel?
173                 if ( texture.bpp == 24 )
174                         type = GL_RGB;
175                 else
176                         type = GL_RGBA;
177
178                 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
179
180                 if(!*textureid)
181                         glGenTextures( 1, textureid );
182                 glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
183
184                 glBindTexture( GL_TEXTURE_2D, *textureid);
185                 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
186                 if(trilinear)if(mipmap)glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
187                 if(!trilinear)if(mipmap)glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST );
188                 if(!mipmap)glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
189                 
190                 gluBuild2DMipmaps( GL_TEXTURE_2D, type, texture.sizeX, texture.sizeY, type, GL_UNSIGNED_BYTE, texture.data );
191         }
192 }
193
194 void Game::LoadTextureSaveData(const char *fileName, GLuint *textureid,int mipmap,GLubyte *array, int *skinsize, bool reload)
195 {
196         GLuint          type;
197         int i;
198         int bytesPerPixel;
199
200         LOGFUNC;
201
202         LOG(std::string("Loading texture (S)...") + fileName);
203
204         //Load Image
205         unsigned char fileNamep[256];
206         CopyCStringToPascal(ConvertFileName(fileName), fileNamep);
207         //Load Image
208         upload_image( fileNamep ,0);
209         //LoadTGA( fileName );
210
211 //      std::string fname(fileName);
212 //      std::transform(fname.begin(), fname.end(), tolower);
213 //      TexIter it = textures.find(fname);
214
215         //Is it valid?
216         if(1==1)
217         //if(textures.end() == it)
218         {
219                 bytesPerPixel=texture.bpp/8;
220
221                 //Alpha channel?
222                 if ( texture.bpp == 24 )
223                         type = GL_RGB;
224                 else
225                         type = GL_RGBA;
226
227                 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
228
229                 if(!*textureid)glGenTextures( 1, textureid );
230                 glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
231
232                 glBindTexture( GL_TEXTURE_2D, *textureid);
233                 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
234                 if(trilinear)if(mipmap)glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
235                 if(!trilinear)if(mipmap)glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST );
236                 if(!mipmap)glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
237
238                 int tempnum=0;
239         if(!reload)
240             for(i=0;i<(int)(texture.sizeY*texture.sizeX*bytesPerPixel);i++)
241                 if((i+1)%4||type==GL_RGB){
242                     array[tempnum]=texture.data[i];
243                     tempnum++;
244                 }
245
246                 *skinsize=texture.sizeX;
247
248                 gluBuild2DMipmaps( GL_TEXTURE_2D, type, texture.sizeX, texture.sizeY, GL_RGB, GL_UNSIGNED_BYTE, array );
249
250 //              textures.insert(std::make_pair(fname, *textureid));
251         }
252 //      else
253 //      {
254 //              *textureid = it->second;
255 //      }
256 }
257
258 void Game::LoadSave(const char *fileName, GLuint *textureid,bool mipmap,GLubyte *array, int *skinsize)
259 {
260         int i;
261         int bytesPerPixel;
262
263         LOGFUNC;
264
265         LOG(std::string("Loading (S)...") + fileName);
266
267         //Load Image
268         float temptexdetail=texdetail;
269         texdetail=1;
270         //upload_image( fileName );
271         //LoadTGA( fileName );
272
273         // Converting file to something os specific
274         char * fixedFN = ConvertFileName(fileName);
275
276         //Load Image
277         unsigned char fileNamep[256];
278         CopyCStringToPascal(fixedFN, fileNamep);
279         //Load Image
280         upload_image( fileNamep ,0);
281         texdetail=temptexdetail;
282
283         //Is it valid?
284         if(1==1){
285                 bytesPerPixel=texture.bpp/8;
286
287                 int tempnum=0;
288                 for(i=0;i<(int)(texture.sizeY*texture.sizeX*bytesPerPixel);i++){
289                         if((i+1)%4||bytesPerPixel==3){
290                                 array[tempnum]=texture.data[i];
291                                 tempnum++;
292                         }
293                 }
294         }
295 }
296
297 bool Game::AddClothes(const char *fileName, GLubyte *array)
298 {
299         int i;
300         int bytesPerPixel;
301
302         LOGFUNC;
303
304         //upload_image( fileName );
305         //LoadTGA( fileName );
306         //Load Image
307         unsigned char fileNamep[256];
308         CopyCStringToPascal(fileName,fileNamep);
309         //Load Image
310         bool opened;
311         opened=upload_image( fileNamep ,1);
312
313         float alphanum;
314         //Is it valid?
315         if(opened){
316                 if(tintr>1)tintr=1;
317                 if(tintg>1)tintg=1;
318                 if(tintb>1)tintb=1;
319
320                 if(tintr<0)tintr=0;
321                 if(tintg<0)tintg=0;
322                 if(tintb<0)tintb=0;
323
324                 bytesPerPixel=texture.bpp/8;
325
326                 int tempnum=0;
327                 alphanum=255;
328                 for(i=0;i<(int)(texture.sizeY*texture.sizeX*bytesPerPixel);i++){
329                         if(bytesPerPixel==3)alphanum=255;
330                         else if((i+1)%4==0)alphanum=texture.data[i];
331                         //alphanum/=2;
332                         if((i+1)%4||bytesPerPixel==3){
333                                 if((i%4)==0)texture.data[i]*=tintr;
334                                 if((i%4)==1)texture.data[i]*=tintg;
335                                 if((i%4)==2)texture.data[i]*=tintb;
336                                 array[tempnum]=(float)array[tempnum]*(1-alphanum/255)+(float)texture.data[i]*(alphanum/255);
337                                 tempnum++;
338                         }
339                 }
340         }
341         else return 0;
342         return 1;
343 }
344
345
346 //***************> ResizeGLScene() <******/
347 GLvoid Game::ReSizeGLScene(float fov, float pnear)
348 {
349         if (screenheight==0)
350         {
351                 screenheight=1;
352         }
353
354         glViewport(0,0,screenwidth,screenheight);
355
356         glMatrixMode(GL_PROJECTION);
357         glLoadIdentity();
358
359         gluPerspective(fov,(GLfloat)screenwidth/(GLfloat)screenheight,pnear,viewdistance);
360
361         glMatrixMode(GL_MODELVIEW);
362         glLoadIdentity();
363 }
364
365 void Game::LoadingScreen()
366 {
367         static float loadprogress;
368         static AbsoluteTime time = {0,0};
369         static AbsoluteTime frametime = {0,0};
370         AbsoluteTime currTime = UpTime ();
371         double deltaTime = (float) AbsoluteDeltaToDuration (currTime, frametime);
372
373         if (0 > deltaTime)      // if negative microseconds
374                 deltaTime /= -1000000.0;
375         else                            // else milliseconds
376                 deltaTime /= 1000.0;
377
378         multiplier=deltaTime;
379         if(multiplier<.001)multiplier=.001;
380         if(multiplier>10)multiplier=10;
381         if(multiplier>.05){
382                 frametime = currTime;   // reset for next time interval
383
384                 glLoadIdentity();
385                 //Clear to black
386                 glClearColor(0,0,0,1);
387                 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
388
389
390                 loadtime+=multiplier*4;
391
392                 loadprogress=loadtime;
393                 if(loadprogress>100)loadprogress=100;
394
395                 //loadprogress=abs(Random()%100);
396
397                 //Background
398
399                 glEnable(GL_TEXTURE_2D);
400                 glBindTexture( GL_TEXTURE_2D, loadscreentexture);
401                 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
402                 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
403                 glDisable(GL_DEPTH_TEST);                                                       // Disables Depth Testing
404                 glDisable(GL_CULL_FACE);
405                 glDisable(GL_LIGHTING);
406                 glDepthMask(0);
407                 glMatrixMode(GL_PROJECTION);                                            // Select The Projection Matrix
408                 glPushMatrix();                                                                         // Store The Projection Matrix
409                 glLoadIdentity();                                                                       // Reset The Projection Matrix
410                 glOrtho(0,screenwidth,0,screenheight,-100,100);                                         // Set Up An Ortho Screen
411                 glMatrixMode(GL_MODELVIEW);                                                     // Select The Modelview Matrix
412                 glPushMatrix();                                                                         // Store The Modelview Matrix
413                 glLoadIdentity();                                                               // Reset The Modelview Matrix
414                 glTranslatef(screenwidth/2,screenheight/2,0);
415                 glScalef((float)screenwidth/2,(float)screenheight/2,1);
416                 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
417                 glDisable(GL_BLEND);
418                 glColor4f(loadprogress/100,loadprogress/100,loadprogress/100,1);
419                 glPushMatrix();
420                 //glScalef(.25,.25,.25);
421                 glBegin(GL_QUADS);
422                 glTexCoord2f(.1-loadprogress/100,0+loadprogress/100+.3);
423                 glVertex3f(-1,          -1,      0.0f);
424                 glTexCoord2f(.1-loadprogress/100,0+loadprogress/100+.3);
425                 glVertex3f(1,   -1,      0.0f);
426                 glTexCoord2f(.1-loadprogress/100,1+loadprogress/100+.3);
427                 glVertex3f(1,   1, 0.0f);
428                 glTexCoord2f(.1-loadprogress/100,1+loadprogress/100+.3);
429                 glVertex3f(-1,  1, 0.0f);
430                 glEnd();
431                 glPopMatrix();
432                 glEnable(GL_BLEND);
433                 glPushMatrix();
434                 //glScalef(.25,.25,.25);
435                 glBegin(GL_QUADS);
436                 glTexCoord2f(.4+loadprogress/100,0+loadprogress/100);
437                 glVertex3f(-1,          -1,      0.0f);
438                 glTexCoord2f(.4+loadprogress/100,0+loadprogress/100);
439                 glVertex3f(1,   -1,      0.0f);
440                 glTexCoord2f(.4+loadprogress/100,1+loadprogress/100);
441                 glVertex3f(1,   1, 0.0f);
442                 glTexCoord2f(.4+loadprogress/100,1+loadprogress/100);
443                 glVertex3f(-1,  1, 0.0f);
444                 glEnd();
445                 glPopMatrix();
446                 glDisable(GL_TEXTURE_2D);
447                 glMatrixMode(GL_PROJECTION);                                            // Select The Projection Matrix
448                 glPopMatrix();                                                                          // Restore The Old Projection Matrix
449                 glMatrixMode(GL_MODELVIEW);                                                     // Select The Modelview Matrix
450                 glPopMatrix();                                                                          // Restore The Old Projection Matrix
451                 glDisable(GL_BLEND);
452                 glDepthMask(1);
453
454                 glEnable(GL_TEXTURE_2D);
455                 glBindTexture( GL_TEXTURE_2D, loadscreentexture);
456                 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
457                 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
458                 glDisable(GL_DEPTH_TEST);                                                       // Disables Depth Testing
459                 glDisable(GL_CULL_FACE);
460                 glDisable(GL_LIGHTING);
461                 glDepthMask(0);
462                 glMatrixMode(GL_PROJECTION);                                            // Select The Projection Matrix
463                 glPushMatrix();                                                                         // Store The Projection Matrix
464                 glLoadIdentity();                                                                       // Reset The Projection Matrix
465                 glOrtho(0,screenwidth,0,screenheight,-100,100);                                         // Set Up An Ortho Screen
466                 glMatrixMode(GL_MODELVIEW);                                                     // Select The Modelview Matrix
467                 glPushMatrix();                                                                         // Store The Modelview Matrix
468                 glLoadIdentity();                                                               // Reset The Modelview Matrix
469                 glTranslatef(screenwidth/2,screenheight/2,0);
470                 glScalef((float)screenwidth/2*(1.5-(loadprogress)/200),(float)screenheight/2*(1.5-(loadprogress)/200),1);
471                 glBlendFunc(GL_SRC_ALPHA,GL_ONE);
472                 glEnable(GL_BLEND);
473                 //glColor4f(loadprogress/100,loadprogress/100,loadprogress/100,1);
474                 glColor4f(loadprogress/100,loadprogress/100,loadprogress/100,1);
475                 glPushMatrix();
476                 //glScalef(.25,.25,.25);
477                 glBegin(GL_QUADS);
478                 glTexCoord2f(0+.5,0+.5);
479                 glVertex3f(-1,          -1,      0.0f);
480                 glTexCoord2f(1+.5,0+.5);
481                 glVertex3f(1,   -1,      0.0f);
482                 glTexCoord2f(1+.5,1+.5);
483                 glVertex3f(1,   1, 0.0f);
484                 glTexCoord2f(0+.5,1+.5);
485                 glVertex3f(-1,  1, 0.0f);
486                 glEnd();
487                 glPopMatrix();
488                 glDisable(GL_TEXTURE_2D);
489                 glMatrixMode(GL_PROJECTION);                                            // Select The Projection Matrix
490                 glPopMatrix();                                                                          // Restore The Old Projection Matrix
491                 glMatrixMode(GL_MODELVIEW);                                                     // Select The Modelview Matrix
492                 glPopMatrix();                                                                          // Restore The Old Projection Matrix
493                 glDisable(GL_BLEND);
494                 glDepthMask(1);
495
496                 glEnable(GL_TEXTURE_2D);
497                 glBindTexture( GL_TEXTURE_2D, loadscreentexture);
498                 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
499                 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
500                 glDisable(GL_DEPTH_TEST);                                                       // Disables Depth Testing
501                 glDisable(GL_CULL_FACE);
502                 glDisable(GL_LIGHTING);
503                 glDepthMask(0);
504                 glMatrixMode(GL_PROJECTION);                                            // Select The Projection Matrix
505                 glPushMatrix();                                                                         // Store The Projection Matrix
506                 glLoadIdentity();                                                                       // Reset The Projection Matrix
507                 glOrtho(0,screenwidth,0,screenheight,-100,100);                                         // Set Up An Ortho Screen
508                 glMatrixMode(GL_MODELVIEW);                                                     // Select The Modelview Matrix
509                 glPushMatrix();                                                                         // Store The Modelview Matrix
510                 glLoadIdentity();                                                               // Reset The Modelview Matrix
511                 glTranslatef(screenwidth/2,screenheight/2,0);
512                 glScalef((float)screenwidth/2*(100+loadprogress)/100,(float)screenheight/2*(100+loadprogress)/100,1);
513                 glBlendFunc(GL_SRC_ALPHA,GL_ONE);
514                 glEnable(GL_BLEND);
515                 glColor4f(loadprogress/100,loadprogress/100,loadprogress/100,.4);
516                 glPushMatrix();
517                 //glScalef(.25,.25,.25);
518                 glBegin(GL_QUADS);
519                 glTexCoord2f(0+.2,0+.8);
520                 glVertex3f(-1,          -1,      0.0f);
521                 glTexCoord2f(1+.2,0+.8);
522                 glVertex3f(1,   -1,      0.0f);
523                 glTexCoord2f(1+.2,1+.8);
524                 glVertex3f(1,   1, 0.0f);
525                 glTexCoord2f(0+.2,1+.8);
526                 glVertex3f(-1,  1, 0.0f);
527                 glEnd();
528                 glPopMatrix();
529                 glDisable(GL_TEXTURE_2D);
530                 glMatrixMode(GL_PROJECTION);                                            // Select The Projection Matrix
531                 glPopMatrix();                                                                          // Restore The Old Projection Matrix
532                 glMatrixMode(GL_MODELVIEW);                                                     // Select The Modelview Matrix
533                 glPopMatrix();                                                                          // Restore The Old Projection Matrix
534                 glDisable(GL_BLEND);
535                 glDepthMask(1);
536
537                 //Text
538
539                 if(flashamount>0){
540                         if(flashamount>1)flashamount=1;
541                         if(flashdelay<=0)flashamount-=multiplier;
542                         flashdelay--;
543                         if(flashamount<0)flashamount=0;
544                         glDisable(GL_DEPTH_TEST);                                                       // Disables Depth Testing
545                         glDisable(GL_CULL_FACE);
546                         glDisable(GL_LIGHTING);
547                         glDisable(GL_TEXTURE_2D);
548                         glDepthMask(0);
549                         glMatrixMode(GL_PROJECTION);                                            // Select The Projection Matrix
550                         glPushMatrix();                                                                         // Store The Projection Matrix
551                         glLoadIdentity();                                                                       // Reset The Projection Matrix
552                         glOrtho(0,screenwidth,0,screenheight,-100,100);                                         // Set Up An Ortho Screen
553                         glMatrixMode(GL_MODELVIEW);                                                     // Select The Modelview Matrix
554                         glPushMatrix();                                                                         // Store The Modelview Matrix
555                         glLoadIdentity();                                                               // Reset The Modelview Matrix
556                         glScalef(screenwidth,screenheight,1);
557                         glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
558                         glEnable(GL_BLEND);
559                         glColor4f(flashr,flashg,flashb,flashamount);
560                         glBegin(GL_QUADS);
561                         glVertex3f(0,           0,       0.0f);
562                         glVertex3f(256, 0,       0.0f);
563                         glVertex3f(256, 256, 0.0f);
564                         glVertex3f(0,   256, 0.0f);
565                         glEnd();
566                         glMatrixMode(GL_PROJECTION);                                            // Select The Projection Matrix
567                         glPopMatrix();                                                                          // Restore The Old Projection Matrix
568                         glMatrixMode(GL_MODELVIEW);                                                     // Select The Modelview Matrix
569                         glPopMatrix();                                                                          // Restore The Old Projection Matrix
570                         glEnable(GL_DEPTH_TEST);                                                        // Enables Depth Testing
571                         glEnable(GL_CULL_FACE);
572                         glDisable(GL_BLEND);
573                         glDepthMask(1);
574                 }
575
576                 swap_gl_buffers();
577         }
578 }
579
580 void Game::FadeLoadingScreen(float howmuch)
581 {
582         static float loadprogress;
583
584         glLoadIdentity();
585         //Clear to black
586         glClearColor(0,0,0,1);
587         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
588
589         loadprogress=howmuch;
590
591         //loadprogress=abs(Random()%100);
592
593         //Background
594
595         //glEnable(GL_TEXTURE_2D);
596         glDisable(GL_TEXTURE_2D);
597         //glBindTexture( GL_TEXTURE_2D, loadscreentexture);
598         glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
599         glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
600         glDisable(GL_DEPTH_TEST);                                                       // Disables Depth Testing
601         glDisable(GL_CULL_FACE);
602         glDisable(GL_LIGHTING);
603         glDepthMask(0);
604         glMatrixMode(GL_PROJECTION);                                            // Select The Projection Matrix
605         glPushMatrix();                                                                         // Store The Projection Matrix
606         glLoadIdentity();                                                                       // Reset The Projection Matrix
607         glOrtho(0,screenwidth,0,screenheight,-100,100);                                         // Set Up An Ortho Screen
608         glMatrixMode(GL_MODELVIEW);                                                     // Select The Modelview Matrix
609         glPushMatrix();                                                                         // Store The Modelview Matrix
610         glLoadIdentity();                                                               // Reset The Modelview Matrix
611         glTranslatef(screenwidth/2,screenheight/2,0);
612         glScalef((float)screenwidth/2,(float)screenheight/2,1);
613         glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
614         glDisable(GL_BLEND);
615         glColor4f(loadprogress/100,0,0,1);
616         glPushMatrix();
617         //glScalef(.25,.25,.25);
618         glBegin(GL_QUADS);
619         glTexCoord2f(0,0);
620         glVertex3f(-1,          -1,      0.0f);
621         glTexCoord2f(1,0);
622         glVertex3f(1,   -1,      0.0f);
623         glTexCoord2f(1,1);
624         glVertex3f(1,   1, 0.0f);
625         glTexCoord2f(0,1);
626         glVertex3f(-1,  1, 0.0f);
627         glEnd();
628         glPopMatrix();
629         glDisable(GL_TEXTURE_2D);
630         glMatrixMode(GL_PROJECTION);                                            // Select The Projection Matrix
631         glPopMatrix();                                                                          // Restore The Old Projection Matrix
632         glMatrixMode(GL_MODELVIEW);                                                     // Select The Modelview Matrix
633         glPopMatrix();                                                                          // Restore The Old Projection Matrix
634         glDisable(GL_BLEND);
635         glDepthMask(1);
636         //Text
637         swap_gl_buffers();
638 }
639
640
641 void Game::InitGame()
642 {
643 #if PLATFORM_MACOSX
644         ProcessSerialNumber PSN;
645         ProcessInfoRec pinfo;
646         FSSpec pspec;
647         OSStatus err;
648         /* set up process serial number */
649         PSN.highLongOfPSN = 0;
650         PSN.lowLongOfPSN = kCurrentProcess;
651         /* set up info block */
652         pinfo.processInfoLength = sizeof(pinfo);
653         pinfo.processName = NULL;
654         pinfo.processAppSpec = &pspec;
655         /* grab the vrefnum and directory */
656         err = GetProcessInformation(&PSN, &pinfo);
657         if (err == noErr) {
658                 vRefNum = pspec.vRefNum;
659                 dirID = pspec.parID;
660         }
661 #endif
662
663         LOGFUNC;
664
665         autocam=0;
666
667         numchallengelevels=14;
668
669         accountactive=Account::loadFile(":Data:Users");
670
671         tintr=1;
672         tintg=1;
673         tintb=1;
674
675         whichjointstartarray[0]=righthip;
676         whichjointendarray[0]=rightfoot;
677
678         whichjointstartarray[1]=righthip;
679         whichjointendarray[1]=rightankle;
680
681         whichjointstartarray[2]=righthip;
682         whichjointendarray[2]=rightknee;
683
684         whichjointstartarray[3]=rightknee;
685         whichjointendarray[3]=rightankle;
686
687         whichjointstartarray[4]=rightankle;
688         whichjointendarray[4]=rightfoot;
689
690         whichjointstartarray[5]=lefthip;
691         whichjointendarray[5]=leftfoot;
692
693         whichjointstartarray[6]=lefthip;
694         whichjointendarray[6]=leftankle;
695
696         whichjointstartarray[7]=lefthip;
697         whichjointendarray[7]=leftknee;
698
699         whichjointstartarray[8]=leftknee;
700         whichjointendarray[8]=leftankle;
701
702         whichjointstartarray[9]=leftankle;
703         whichjointendarray[9]=leftfoot;
704
705         whichjointstartarray[10]=abdomen;
706         whichjointendarray[10]=rightshoulder;
707
708         whichjointstartarray[11]=abdomen;
709         whichjointendarray[11]=rightelbow;
710
711         whichjointstartarray[12]=abdomen;
712         whichjointendarray[12]=rightwrist;
713
714         whichjointstartarray[13]=abdomen;
715         whichjointendarray[13]=righthand;
716
717         whichjointstartarray[14]=rightshoulder;
718         whichjointendarray[14]=rightelbow;
719
720         whichjointstartarray[15]=rightelbow;
721         whichjointendarray[15]=rightwrist;
722
723         whichjointstartarray[16]=rightwrist;
724         whichjointendarray[16]=righthand;
725
726         whichjointstartarray[17]=abdomen;
727         whichjointendarray[17]=leftshoulder;
728
729         whichjointstartarray[18]=abdomen;
730         whichjointendarray[18]=leftelbow;
731
732         whichjointstartarray[19]=abdomen;
733         whichjointendarray[19]=leftwrist;
734
735         whichjointstartarray[20]=abdomen;
736         whichjointendarray[20]=lefthand;
737
738         whichjointstartarray[21]=leftshoulder;
739         whichjointendarray[21]=leftelbow;
740
741         whichjointstartarray[22]=leftelbow;
742         whichjointendarray[22]=leftwrist;
743
744         whichjointstartarray[23]=leftwrist;
745         whichjointendarray[23]=lefthand;
746
747         whichjointstartarray[24]=abdomen;
748         whichjointendarray[24]=neck;
749
750         whichjointstartarray[25]=neck;
751         whichjointendarray[25]=head;
752
753         FadeLoadingScreen(0);
754
755         stillloading=1;
756
757         texture.data = ( GLubyte* )malloc( 1024*1024*4 );
758
759         int temptexdetail=texdetail;
760         texdetail=1;
761         text.LoadFontTexture(":Data:Textures:Font.png");
762         text.BuildFont();
763         texdetail=temptexdetail;
764
765         FadeLoadingScreen(10);
766
767         if(detail==2){
768                 texdetail=1;
769         }
770         if(detail==1){
771                 texdetail=2;
772         }
773         if(detail==0){
774                 texdetail=4;
775         }
776
777         LOG("Initializing sound system...");
778
779     int output = -1;
780
781     #if PLATFORM_LINUX
782     extern bool cmdline(const char *cmd);
783     unsigned char rc = 0;
784     output = OPENAL_OUTPUT_ALSA;  // Try alsa first...
785     if (cmdline("forceoss"))      //  ...but let user override that.
786         output = OPENAL_OUTPUT_OSS;
787     else if (cmdline("nosound"))
788         output = OPENAL_OUTPUT_NOSOUND;
789
790     OPENAL_SetOutput(output);
791         if ((rc = OPENAL_Init(44100, 32, 0)) == false)
792     {
793         // if we tried ALSA and failed, fall back to OSS.
794         if ( (output == OPENAL_OUTPUT_ALSA) && (!cmdline("forcealsa")) )
795         {
796             OPENAL_Close();
797             output = OPENAL_OUTPUT_OSS;
798             OPENAL_SetOutput(output);
799                 rc = OPENAL_Init(44100, 32, 0);
800         }
801     }
802
803     if (rc == false)
804     {
805         OPENAL_Close();
806         output = OPENAL_OUTPUT_NOSOUND;  // we tried! just do silence.
807         OPENAL_SetOutput(output);
808             rc = OPENAL_Init(44100, 32, 0);
809     }
810     #else
811         OPENAL_Init(44100, 32, 0);
812     #endif
813
814         OPENAL_SetSFXMasterVolume((int)(volume*255));
815         loadAllSounds();
816
817         if(musictoggle)
818           emit_stream_np(stream_menutheme);
819
820         LoadTexture(":Data:Textures:Cursor.png",&cursortexture,0,1);
821
822         LoadTexture(":Data:Textures:MapCircle.png",&Mapcircletexture,0,1);
823         LoadTexture(":Data:Textures:MapBox.png",&Mapboxtexture,0,1);
824         LoadTexture(":Data:Textures:MapArrow.png",&Maparrowtexture,0,1);
825
826         temptexdetail=texdetail;
827         if(texdetail>2)texdetail=2;
828         LoadTexture(":Data:Textures:Lugaru.png",&Mainmenuitems[0],0,0);
829         LoadTexture(":Data:Textures:Newgame.png",&Mainmenuitems[1],0,0);
830         LoadTexture(":Data:Textures:Options.png",&Mainmenuitems[2],0,0);
831         LoadTexture(":Data:Textures:Quit.png",&Mainmenuitems[3],0,0);
832         LoadTexture(":Data:Textures:Eyelid.png",&Mainmenuitems[4],0,1);
833         //LoadTexture(":Data:Textures:Eye.jpg",&Mainmenuitems[5],0,1);
834         //~ LoadTexture(":Data:Textures:World.png",&Mainmenuitems[7],0,0); // LoadCampaign will take care of that
835         texdetail=temptexdetail;
836
837         FadeLoadingScreen(95);
838
839
840         gameon=0;
841         mainmenu=1;
842
843         stillloading=0;
844         firstload=0;
845         oldmainmenu=0;
846
847         newdetail=detail;
848         newscreenwidth=screenwidth;
849         newscreenheight=screenheight;
850 }
851
852
853 void Game::LoadScreenTexture() {
854     glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
855
856     if(!screentexture)
857         glGenTextures( 1, &screentexture );
858     glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
859
860
861     glEnable(GL_TEXTURE_2D);
862     glBindTexture( GL_TEXTURE_2D, screentexture);
863     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
864     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
865
866     glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, kTextureSize, kTextureSize, 0);
867 }
868
869 void Game::LoadStuff()
870 {
871         static float temptexdetail;
872         static float viewdistdetail;
873         static int i,j;
874         float megascale =1;
875
876         LOGFUNC;
877
878         visibleloading=1;
879
880         loadtime=0;
881
882         stillloading=1;
883
884         //texture.data = ( GLubyte* )malloc( 1024*1024*4 );
885
886         for(i=0;i<maxplayers;i++)
887         {
888                 if (glIsTexture(player[i].skeleton.drawmodel.textureptr))
889                 {
890                         glDeleteTextures(1, &player[i].skeleton.drawmodel.textureptr);
891                 }
892                 player[i].skeleton.drawmodel.textureptr=0;;
893         }
894
895         //temptexdetail=texdetail;
896         //texdetail=1;
897         i=abs(Random()%4);
898         LoadTexture(":Data:Textures:fire.jpg",&loadscreentexture,1,0);
899         //texdetail=temptexdetail;
900
901         temptexdetail=texdetail;
902         texdetail=1;
903         text.LoadFontTexture(":Data:Textures:Font.png");
904         text.BuildFont();
905         texdetail=temptexdetail;
906
907         numsounds=71;
908
909         viewdistdetail=2;
910         viewdistance=50*megascale*viewdistdetail;
911
912         brightness=100;
913
914
915
916         if(detail==2){
917                 texdetail=1;
918         }
919         if(detail==1){
920                 texdetail=2;
921         }
922         if(detail==0){
923                 texdetail=4;
924         }
925
926         realtexdetail=texdetail;
927
928         /*texdetail/=4;
929         if(texdetail<1)texdetail=1;
930         realtexdetail=texdetail*4;
931         */
932         numplayers=1;
933
934
935
936         /*LoadTexture(":Data:Textures:snow.png",&terraintexture,1);
937
938         LoadTexture(":Data:Textures:rock.png",&terraintexture2,1);
939
940         LoadTexture(":Data:Textures:detail.png",&terraintexture3,1);
941         */
942
943
944         LOG("Loading weapon data...");
945
946         LoadTexture(":Data:Textures:knife.png",&Weapon::knifetextureptr,0,1);
947         LoadTexture(":Data:Textures:bloodknife.png",&Weapon::bloodknifetextureptr,0,1);
948         LoadTexture(":Data:Textures:lightbloodknife.png",&Weapon::lightbloodknifetextureptr,0,1);
949         LoadTexture(":Data:Textures:sword.jpg",&Weapon::swordtextureptr,1,0);
950         LoadTexture(":Data:Textures:Swordblood.jpg",&Weapon::bloodswordtextureptr,1,0);
951         LoadTexture(":Data:Textures:Swordbloodlight.jpg",&Weapon::lightbloodswordtextureptr,1,0);
952         LoadTexture(":Data:Textures:Staff.jpg",&Weapon::stafftextureptr,1,0);
953
954         Weapon::throwingknifemodel.load((char *)":Data:Models:throwingknife.solid",1);
955         Weapon::throwingknifemodel.Scale(.001,.001,.001);
956         //Weapon::throwingknifemodel.Rotate(0,0,-90);
957         Weapon::throwingknifemodel.Rotate(90,0,0);
958         Weapon::throwingknifemodel.Rotate(0,90,0);
959         Weapon::throwingknifemodel.flat=0;
960         Weapon::throwingknifemodel.CalculateNormals(1);
961         //Weapon::throwingknifemodel.ScaleNormals(-1,-1,-1);
962
963         Weapon::swordmodel.load((char *)":Data:Models:sword.solid",1);
964         Weapon::swordmodel.Scale(.001,.001,.001);
965         //Weapon::swordmodel.Rotate(0,0,-90);
966         Weapon::swordmodel.Rotate(90,0,0);
967         Weapon::swordmodel.Rotate(0,90,0);
968         Weapon::swordmodel.Rotate(0,0,90);
969         Weapon::swordmodel.flat=1;
970         Weapon::swordmodel.CalculateNormals(1);
971         //Weapon::swordmodel.ScaleNormals(-1,-1,-1);
972
973         Weapon::staffmodel.load((char *)":Data:Models:staff.solid",1);
974         Weapon::staffmodel.Scale(.005,.005,.005);
975         //Weapon::staffmodel.Rotate(0,0,-90);
976         Weapon::staffmodel.Rotate(90,0,0);
977         Weapon::staffmodel.Rotate(0,90,0);
978         Weapon::staffmodel.Rotate(0,0,90);
979         Weapon::staffmodel.flat=1;
980         Weapon::staffmodel.CalculateNormals(1);
981         //Weapon::staffmodel.ScaleNormals(-1,-1,-1);
982
983         //temptexdetail=texdetail;
984         //if(texdetail>4)texdetail=4;
985         LoadTexture(":Data:Textures:shadow.png",&terrain.shadowtexture,0,1);
986
987         LoadTexture(":Data:Textures:blood.png",&terrain.bloodtexture,0,1);
988
989         LoadTexture(":Data:Textures:break.png",&terrain.breaktexture,0,1);
990
991         LoadTexture(":Data:Textures:blood.png",&terrain.bloodtexture2,0,1);
992
993
994         LoadTexture(":Data:Textures:footprint.png",&terrain.footprinttexture,0,1);
995
996         LoadTexture(":Data:Textures:bodyprint.png",&terrain.bodyprinttexture,0,1);
997
998         /*LoadTexture(":Data:Textures:cloud.png",&Sprite::cloudtexture,1);
999
1000         LoadTexture(":Data:Textures:cloudimpact.png",&Sprite::cloudimpacttexture,1);
1001
1002         LoadTexture(":Data:Textures:bloodparticle.png",&Sprite::bloodtexture,1);
1003
1004         LoadTexture(":Data:Textures:snowflake.png",&Sprite::snowflaketexture,1);
1005
1006         LoadTexture(":Data:Textures:flame.png",&Sprite::flametexture,1);
1007
1008         LoadTexture(":Data:Textures:smoke.png",&Sprite::smoketexture,1);
1009         //texdetail=temptexdetail;
1010         LoadTexture(":Data:Textures:shine.png",&Sprite::shinetexture,1);*/
1011
1012
1013
1014         LoadTexture(":Data:Textures:hawk.png",&hawktexture,0,1);
1015
1016         LoadTexture(":Data:Textures:logo.png",&logotexture,0,1);
1017
1018
1019         //LoadTexture(":Data:Textures:box.jpg",&objects.boxtextureptr,1,0);
1020
1021
1022         LoadTexture(":Data:Textures:cloud.png",&Sprite::cloudtexture,1,1);
1023         LoadTexture(":Data:Textures:cloudimpact.png",&Sprite::cloudimpacttexture,1,1);
1024         LoadTexture(":Data:Textures:bloodparticle.png",&Sprite::bloodtexture,1,1);
1025         LoadTexture(":Data:Textures:snowflake.png",&Sprite::snowflaketexture,1,1);
1026         LoadTexture(":Data:Textures:flame.png",&Sprite::flametexture,1,1);
1027         LoadTexture(":Data:Textures:bloodflame.png",&Sprite::bloodflametexture,1,1);
1028         LoadTexture(":Data:Textures:smoke.png",&Sprite::smoketexture,1,1);
1029         LoadTexture(":Data:Textures:shine.png",&Sprite::shinetexture,1,0);
1030         LoadTexture(":Data:Textures:splinter.png",&Sprite::splintertexture,1,1);
1031         LoadTexture(":Data:Textures:leaf.png",&Sprite::leaftexture,1,1);
1032         LoadTexture(":Data:Textures:tooth.png",&Sprite::toothtexture,1,1);
1033
1034         rotation=0;
1035         rotation2=0;
1036         ReSizeGLScene(90,.01);
1037
1038         viewer=0;
1039
1040
1041
1042
1043         if(detail)kTextureSize=1024;
1044         if(detail==1)kTextureSize=512;
1045         if(detail==0)kTextureSize=256;
1046
1047
1048         //drawmode=motionblurmode;
1049
1050         //Set up distant light
1051         light.color[0]=.95;
1052         light.color[1]=.95;
1053         light.color[2]=1;
1054         light.ambient[0]=.2;
1055         light.ambient[1]=.2;
1056         light.ambient[2]=.24;
1057         light.location.x=1;
1058         light.location.y=1;
1059         light.location.z=-.2;
1060         Normalise(&light.location);
1061
1062         LoadingScreen();
1063
1064         SetUpLighting();
1065
1066
1067         fadestart=.6;
1068         gravity=-10;
1069
1070         texscale=.2/megascale/viewdistdetail;
1071         terrain.scale=3*megascale*viewdistdetail;
1072
1073         viewer.x=terrain.size/2*terrain.scale;
1074         viewer.z=terrain.size/2*terrain.scale;
1075
1076         hawk.load((char *)":Data:Models:hawk.solid",1);
1077         hawk.Scale(.03,.03,.03);
1078         hawk.Rotate(90,1,1);
1079         hawk.CalculateNormals(0);
1080         hawk.ScaleNormals(-1,-1,-1);
1081         hawkcoords.x=terrain.size/2*terrain.scale-5-7;
1082         hawkcoords.z=terrain.size/2*terrain.scale-5-7;
1083         hawkcoords.y=terrain.getHeight(hawkcoords.x,hawkcoords.z)+25;
1084
1085
1086         eye.load((char *)":Data:Models:eye.solid",1);
1087         eye.Scale(.03,.03,.03);
1088         eye.CalculateNormals(0);
1089
1090         cornea.load((char *)":Data:Models:cornea.solid",1);
1091         cornea.Scale(.03,.03,.03);
1092         cornea.CalculateNormals(0);
1093
1094         iris.load((char *)":Data:Models:iris.solid",1);
1095         iris.Scale(.03,.03,.03);
1096         iris.CalculateNormals(0);
1097
1098         LoadSave(":Data:Textures:Bloodfur.png",0,1,&bloodText[0],0);
1099         LoadSave(":Data:Textures:Wolfbloodfur.png",0,1,&wolfbloodText[0],0);
1100
1101         oldenvironment=-4;
1102
1103         gameon=1;
1104         mainmenu=0;
1105
1106         firstload=0;
1107         //if(targetlevel!=7)
1108                 Loadlevel(targetlevel);
1109
1110
1111         rabbitcoords=player[0].coords;
1112         rabbitcoords.y=terrain.getHeight(rabbitcoords.x,rabbitcoords.z);
1113
1114         loadAllAnimations();
1115         //Fix knife stab, too lazy to do it manually
1116         XYZ moveamount;
1117         moveamount=0;
1118         moveamount.z=2;
1119         for(i=0;i<player[0].skeleton.num_joints;i++){
1120                 for(j=0;j<animation[knifesneakattackanim].numframes;j++){
1121                         animation[knifesneakattackanim].position[i][j]+=moveamount;
1122                 }
1123         }
1124
1125         LoadingScreen();
1126
1127         for(i=0;i<player[0].skeleton.num_joints;i++){
1128                 for(j=0;j<animation[knifesneakattackedanim].numframes;j++){
1129                         animation[knifesneakattackedanim].position[i][j]+=moveamount;
1130                 }
1131         }
1132
1133         LoadingScreen();
1134
1135         for(i=0;i<player[0].skeleton.num_joints;i++){
1136                 animation[dead1anim].position[i][1]=animation[dead1anim].position[i][0];
1137                 animation[dead2anim].position[i][1]=animation[dead2anim].position[i][0];
1138                 animation[dead3anim].position[i][1]=animation[dead3anim].position[i][0];
1139                 animation[dead4anim].position[i][1]=animation[dead4anim].position[i][0];
1140         }
1141         animation[dead1anim].speed[0]=0.001;
1142         animation[dead2anim].speed[0]=0.001;
1143         animation[dead3anim].speed[0]=0.001;
1144         animation[dead4anim].speed[0]=0.001;
1145
1146         animation[dead1anim].speed[1]=0.001;
1147         animation[dead2anim].speed[1]=0.001;
1148         animation[dead3anim].speed[1]=0.001;
1149         animation[dead4anim].speed[1]=0.001;
1150
1151         for(i=0;i<player[0].skeleton.num_joints;i++){
1152                 for(j=0;j<animation[swordsneakattackanim].numframes;j++){
1153                         animation[swordsneakattackanim].position[i][j]+=moveamount;
1154                 }
1155         }
1156         LoadingScreen();
1157         for(j=0;j<animation[swordsneakattackanim].numframes;j++){
1158                 animation[swordsneakattackanim].weapontarget[j]+=moveamount;
1159         }
1160
1161         LoadingScreen();
1162
1163         for(i=0;i<player[0].skeleton.num_joints;i++){
1164                 for(j=0;j<animation[swordsneakattackedanim].numframes;j++){
1165                         animation[swordsneakattackedanim].position[i][j]+=moveamount;
1166                 }
1167         }
1168         
1169         LoadingScreen();
1170         temptexdetail=texdetail;
1171         texdetail=1;
1172         texdetail=temptexdetail;
1173
1174         LoadingScreen();
1175
1176         //if(ismotionblur){
1177         if(!screentexture){
1178         LoadScreenTexture();
1179         }
1180
1181         if(targetlevel!=7){
1182                 emit_sound_at(fireendsound);
1183         }
1184
1185         stillloading=0;
1186         loading=0;
1187         changedelay=1;
1188
1189         visibleloading=0;
1190 }
1191