2 Copyright (C) 2003, 2010 - Wolfire Games
3 Copyright (C) 2010-2017 - Lugaru contributors (see AUTHORS file)
5 This file is part of Lugaru.
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.
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.
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/>.
23 #include "Animation/Animation.hpp"
24 #include "Audio/openal_wrapper.hpp"
25 #include "Graphic/Texture.hpp"
26 #include "Menu/Menu.hpp"
27 #include "Utils/Folders.hpp"
29 extern float screenwidth, screenheight;
30 extern float viewdistance;
32 extern float fadestart;
33 extern float texscale;
36 extern Terrain terrain;
37 extern int kTextureSize;
38 extern float texdetail;
39 extern float realtexdetail;
42 extern bool cellophane;
43 extern bool ismotionblur;
44 extern bool trilinear;
45 extern bool musictoggle;
46 extern int environment;
47 extern bool ambientsound;
48 extern float multiplier;
49 extern int netdatanew;
51 extern bool stillloading;
53 extern bool visibleloading;
54 extern float flashamount, flashr, flashg, flashb;
55 extern int flashdelay;
56 extern int whichjointstartarray[26];
57 extern int whichjointendarray[26];
58 extern float slomospeed;
59 extern bool gamestarted;
61 extern float accountcampaignhighscore[10];
62 extern float accountcampaignfasttime[10];
63 extern float accountcampaignscore[10];
64 extern float accountcampaigntime[10];
66 extern int accountcampaignchoicesmade[10];
67 extern int accountcampaignchoices[10][5000];
69 void LOG(const std::string&, ...)
71 // !!! FIXME: write me.
78 if (Game::endgame == 2) {
79 Account::active().endGame();
83 Account::saveFile(Folders::getUserSavePath());
87 LOG("Shutting down sound system...");
89 OPENAL_StopSound(OPENAL_ALL);
91 for (int i = 0; i < sounds_count; ++i) {
92 OPENAL_Sample_Free(samp[i]);
101 textmono = new Text();
102 skybox = new SkyBox();
105 void Game::deleteGame()
111 glDeleteTextures(1, &screentexture);
112 glDeleteTextures(1, &screentexture2);
117 void LoadSave(const std::string& fileName, GLubyte* array)
121 LOG(std::string("Loading (S)...") + fileName);
124 float temptexdetail = texdetail;
129 if (!load_image(Folders::getResourcePath(fileName).c_str(), texture)) {
130 texdetail = temptexdetail;
133 texdetail = temptexdetail;
135 int bytesPerPixel = texture.bpp / 8;
138 for (int i = 0; i < (int)(texture.sizeY * texture.sizeX * bytesPerPixel); i++) {
139 if ((i + 1) % 4 || bytesPerPixel == 3) {
140 array[tempnum] = texture.data[i];
146 //***************> ResizeGLScene() <******/
147 GLvoid Game::ReSizeGLScene(float fov, float pnear)
149 if (screenheight == 0) {
153 glViewport(0, 0, screenwidth, screenheight);
155 glMatrixMode(GL_PROJECTION);
158 gluPerspective(fov, (GLfloat)screenwidth / (GLfloat)screenheight, pnear, viewdistance);
160 glMatrixMode(GL_MODELVIEW);
164 void Game::LoadingScreen()
166 if (!visibleloading) {
170 static float loadprogress;
171 static AbsoluteTime frametime = { 0, 0 };
172 AbsoluteTime currTime = UpTime();
173 double deltaTime = (float)AbsoluteDeltaToDuration(currTime, frametime);
175 if (0 > deltaTime) { // if negative microseconds
176 deltaTime /= -1000000.0;
177 } else { // else milliseconds
181 multiplier = deltaTime;
182 if (multiplier < .001) {
185 if (multiplier > 10) {
188 if (multiplier > .05) {
189 frametime = currTime; // reset for next time interval
193 glClearColor(0, 0, 0, 1);
194 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
196 loadtime += multiplier * 4;
198 loadprogress = loadtime;
199 if (loadprogress > 100) {
205 glEnable(GL_TEXTURE_2D);
206 loadscreentexture.bind();
207 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
208 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
209 glDisable(GL_DEPTH_TEST);
210 glDisable(GL_CULL_FACE);
211 glDisable(GL_LIGHTING);
213 glMatrixMode(GL_PROJECTION);
216 glOrtho(0, screenwidth, 0, screenheight, -100, 100);
217 glMatrixMode(GL_MODELVIEW);
220 glTranslatef(screenwidth / 2, screenheight / 2, 0);
221 glScalef((float)screenwidth / 2, (float)screenheight / 2, 1);
222 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
224 glColor4f(loadprogress / 100, loadprogress / 100, loadprogress / 100, 1);
227 glTexCoord2f(.1 - loadprogress / 100, 0 + loadprogress / 100 + .3);
228 glVertex3f(-1, -1, 0.0f);
229 glTexCoord2f(.1 - loadprogress / 100, 0 + loadprogress / 100 + .3);
230 glVertex3f(1, -1, 0.0f);
231 glTexCoord2f(.1 - loadprogress / 100, 1 + loadprogress / 100 + .3);
232 glVertex3f(1, 1, 0.0f);
233 glTexCoord2f(.1 - loadprogress / 100, 1 + loadprogress / 100 + .3);
234 glVertex3f(-1, 1, 0.0f);
240 glTexCoord2f(.4 + loadprogress / 100, 0 + loadprogress / 100);
241 glVertex3f(-1, -1, 0.0f);
242 glTexCoord2f(.4 + loadprogress / 100, 0 + loadprogress / 100);
243 glVertex3f(1, -1, 0.0f);
244 glTexCoord2f(.4 + loadprogress / 100, 1 + loadprogress / 100);
245 glVertex3f(1, 1, 0.0f);
246 glTexCoord2f(.4 + loadprogress / 100, 1 + loadprogress / 100);
247 glVertex3f(-1, 1, 0.0f);
250 glDisable(GL_TEXTURE_2D);
251 glMatrixMode(GL_PROJECTION);
253 glMatrixMode(GL_MODELVIEW);
258 glEnable(GL_TEXTURE_2D);
259 loadscreentexture.bind();
260 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
261 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
262 glDisable(GL_DEPTH_TEST);
263 glDisable(GL_CULL_FACE);
264 glDisable(GL_LIGHTING);
266 glMatrixMode(GL_PROJECTION);
269 glOrtho(0, screenwidth, 0, screenheight, -100, 100);
270 glMatrixMode(GL_MODELVIEW);
273 glTranslatef(screenwidth / 2, screenheight / 2, 0);
274 glScalef((float)screenwidth / 2 * (1.5 - (loadprogress) / 200), (float)screenheight / 2 * (1.5 - (loadprogress) / 200), 1);
275 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
277 glColor4f(loadprogress / 100, loadprogress / 100, loadprogress / 100, 1);
280 glTexCoord2f(0 + .5, 0 + .5);
281 glVertex3f(-1, -1, 0.0f);
282 glTexCoord2f(1 + .5, 0 + .5);
283 glVertex3f(1, -1, 0.0f);
284 glTexCoord2f(1 + .5, 1 + .5);
285 glVertex3f(1, 1, 0.0f);
286 glTexCoord2f(0 + .5, 1 + .5);
287 glVertex3f(-1, 1, 0.0f);
290 glDisable(GL_TEXTURE_2D);
291 glMatrixMode(GL_PROJECTION);
293 glMatrixMode(GL_MODELVIEW);
298 glEnable(GL_TEXTURE_2D);
299 loadscreentexture.bind();
300 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
301 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
302 glDisable(GL_DEPTH_TEST);
303 glDisable(GL_CULL_FACE);
304 glDisable(GL_LIGHTING);
306 glMatrixMode(GL_PROJECTION);
309 glOrtho(0, screenwidth, 0, screenheight, -100, 100);
310 glMatrixMode(GL_MODELVIEW);
313 glTranslatef(screenwidth / 2, screenheight / 2, 0);
314 glScalef((float)screenwidth / 2 * (100 + loadprogress) / 100, (float)screenheight / 2 * (100 + loadprogress) / 100, 1);
315 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
317 glColor4f(loadprogress / 100, loadprogress / 100, loadprogress / 100, .4);
320 glTexCoord2f(0 + .2, 0 + .8);
321 glVertex3f(-1, -1, 0.0f);
322 glTexCoord2f(1 + .2, 0 + .8);
323 glVertex3f(1, -1, 0.0f);
324 glTexCoord2f(1 + .2, 1 + .8);
325 glVertex3f(1, 1, 0.0f);
326 glTexCoord2f(0 + .2, 1 + .8);
327 glVertex3f(-1, 1, 0.0f);
330 glDisable(GL_TEXTURE_2D);
331 glMatrixMode(GL_PROJECTION);
333 glMatrixMode(GL_MODELVIEW);
340 if (flashamount > 0) {
341 if (flashamount > 1) {
344 if (flashdelay <= 0) {
345 flashamount -= multiplier;
348 if (flashamount < 0) {
351 glDisable(GL_DEPTH_TEST);
352 glDisable(GL_CULL_FACE);
353 glDisable(GL_LIGHTING);
354 glDisable(GL_TEXTURE_2D);
356 glMatrixMode(GL_PROJECTION);
359 glOrtho(0, screenwidth, 0, screenheight, -100, 100);
360 glMatrixMode(GL_MODELVIEW);
363 glScalef(screenwidth, screenheight, 1);
364 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
366 glColor4f(flashr, flashg, flashb, flashamount);
368 glVertex3f(0, 0, 0.0f);
369 glVertex3f(256, 0, 0.0f);
370 glVertex3f(256, 256, 0.0f);
371 glVertex3f(0, 256, 0.0f);
373 glMatrixMode(GL_PROJECTION);
375 glMatrixMode(GL_MODELVIEW);
377 glEnable(GL_DEPTH_TEST);
378 glEnable(GL_CULL_FACE);
387 void FadeLoadingScreen(float howmuch)
389 static float loadprogress;
393 glClearColor(0, 0, 0, 1);
394 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
396 loadprogress = howmuch;
400 glDisable(GL_TEXTURE_2D);
401 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
402 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
403 glDisable(GL_DEPTH_TEST);
404 glDisable(GL_CULL_FACE);
405 glDisable(GL_LIGHTING);
407 glMatrixMode(GL_PROJECTION);
410 glOrtho(0, screenwidth, 0, screenheight, -100, 100);
411 glMatrixMode(GL_MODELVIEW);
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);
418 glColor4f(loadprogress / 100, 0, 0, 1);
422 glVertex3f(-1, -1, 0.0f);
424 glVertex3f(1, -1, 0.0f);
426 glVertex3f(1, 1, 0.0f);
428 glVertex3f(-1, 1, 0.0f);
431 glDisable(GL_TEXTURE_2D);
432 glMatrixMode(GL_PROJECTION);
434 glMatrixMode(GL_MODELVIEW);
442 void Game::InitGame()
446 numchallengelevels = 14;
448 Account::loadFile(Folders::getUserSavePath());
450 whichjointstartarray[0] = righthip;
451 whichjointendarray[0] = rightfoot;
453 whichjointstartarray[1] = righthip;
454 whichjointendarray[1] = rightankle;
456 whichjointstartarray[2] = righthip;
457 whichjointendarray[2] = rightknee;
459 whichjointstartarray[3] = rightknee;
460 whichjointendarray[3] = rightankle;
462 whichjointstartarray[4] = rightankle;
463 whichjointendarray[4] = rightfoot;
465 whichjointstartarray[5] = lefthip;
466 whichjointendarray[5] = leftfoot;
468 whichjointstartarray[6] = lefthip;
469 whichjointendarray[6] = leftankle;
471 whichjointstartarray[7] = lefthip;
472 whichjointendarray[7] = leftknee;
474 whichjointstartarray[8] = leftknee;
475 whichjointendarray[8] = leftankle;
477 whichjointstartarray[9] = leftankle;
478 whichjointendarray[9] = leftfoot;
480 whichjointstartarray[10] = abdomen;
481 whichjointendarray[10] = rightshoulder;
483 whichjointstartarray[11] = abdomen;
484 whichjointendarray[11] = rightelbow;
486 whichjointstartarray[12] = abdomen;
487 whichjointendarray[12] = rightwrist;
489 whichjointstartarray[13] = abdomen;
490 whichjointendarray[13] = righthand;
492 whichjointstartarray[14] = rightshoulder;
493 whichjointendarray[14] = rightelbow;
495 whichjointstartarray[15] = rightelbow;
496 whichjointendarray[15] = rightwrist;
498 whichjointstartarray[16] = rightwrist;
499 whichjointendarray[16] = righthand;
501 whichjointstartarray[17] = abdomen;
502 whichjointendarray[17] = leftshoulder;
504 whichjointstartarray[18] = abdomen;
505 whichjointendarray[18] = leftelbow;
507 whichjointstartarray[19] = abdomen;
508 whichjointendarray[19] = leftwrist;
510 whichjointstartarray[20] = abdomen;
511 whichjointendarray[20] = lefthand;
513 whichjointstartarray[21] = leftshoulder;
514 whichjointendarray[21] = leftelbow;
516 whichjointstartarray[22] = leftelbow;
517 whichjointendarray[22] = leftwrist;
519 whichjointstartarray[23] = leftwrist;
520 whichjointendarray[23] = lefthand;
522 whichjointstartarray[24] = abdomen;
523 whichjointendarray[24] = neck;
525 whichjointstartarray[25] = neck;
526 whichjointendarray[25] = head;
528 FadeLoadingScreen(0);
532 int temptexdetail = texdetail;
534 text->LoadFontTexture("Textures/Font.png");
536 textmono->LoadFontTexture("Textures/FontMono.png");
537 textmono->BuildFont();
538 texdetail = temptexdetail;
540 FadeLoadingScreen(10);
552 LOG("Initializing sound system...");
554 OPENAL_Init(44100, 32, 0);
556 OPENAL_SetSFXMasterVolume((int)(volume * 255));
560 emit_stream_np(stream_menutheme);
563 cursortexture.load("Textures/Cursor.png", 0);
565 Mapcircletexture.load("Textures/MapCircle.png", 0);
566 Mapboxtexture.load("Textures/MapBox.png", 0);
567 Maparrowtexture.load("Textures/MapArrow.png", 0);
569 temptexdetail = texdetail;
573 Mainmenuitems[0].load("Textures/Lugaru.png", 0);
574 Mainmenuitems[1].load("Textures/NewGame.png", 0);
575 Mainmenuitems[2].load("Textures/Options.png", 0);
576 Mainmenuitems[3].load("Textures/Quit.png", 0);
577 Mainmenuitems[4].load("Textures/Eyelid.png", 0);
578 Mainmenuitems[5].load("Textures/Resume.png", 0);
579 Mainmenuitems[6].load("Textures/EndGame.png", 0);
581 texdetail = temptexdetail;
583 FadeLoadingScreen(95);
589 firstLoadDone = false;
592 newscreenwidth = screenwidth;
593 newscreenheight = screenheight;
597 Animation::loadAll();
601 Person::players.emplace_back(new Person());
604 void Game::LoadScreenTexture()
606 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
608 if (!Game::screentexture) {
609 glGenTextures(1, &Game::screentexture);
611 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
613 glEnable(GL_TEXTURE_2D);
614 glBindTexture(GL_TEXTURE_2D, Game::screentexture);
615 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
616 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
618 glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, kTextureSize, kTextureSize, 0);
621 //TODO: move LoadStuff() closer to GameTick.cpp to get rid of various vars shared in Game.hpp
622 /* Loads models and textures which only needs to be loaded once */
623 void Game::LoadStuff()
626 float viewdistdetail;
635 visibleloading = false; //don't use loadscreentexture yet
636 loadscreentexture.load("Textures/Fire.jpg", 1);
637 visibleloading = true;
639 temptexdetail = texdetail;
641 text->LoadFontTexture("Textures/Font.png");
643 textmono->LoadFontTexture("Textures/FontMono.png");
644 textmono->BuildFont();
645 texdetail = temptexdetail;
648 viewdistance = 50 * megascale * viewdistdetail;
653 } else if (detail == 1) {
661 realtexdetail = texdetail;
665 terrain.shadowtexture.load("Textures/Shadow.png", 0);
666 terrain.bloodtexture.load("Textures/Blood.png", 0);
667 terrain.breaktexture.load("Textures/Break.png", 0);
668 terrain.bloodtexture2.load("Textures/Blood.png", 0);
670 terrain.footprinttexture.load("Textures/Footprint.png", 0);
671 terrain.bodyprinttexture.load("Textures/Bodyprint.png", 0);
672 hawktexture.load("Textures/Hawk.png", 0);
674 Sprite::cloudtexture.load("Textures/Cloud.png", 1);
675 Sprite::cloudimpacttexture.load("Textures/CloudImpact.png", 1);
676 Sprite::bloodtexture.load("Textures/BloodParticle.png", 1);
677 Sprite::snowflaketexture.load("Textures/SnowFlake.png", 1);
678 Sprite::flametexture.load("Textures/Flame.png", 1);
679 Sprite::bloodflametexture.load("Textures/BloodFlame.png", 1);
680 Sprite::smoketexture.load("Textures/Smoke.png", 1);
681 Sprite::shinetexture.load("Textures/Shine.png", 1);
682 Sprite::splintertexture.load("Textures/Splinter.png", 1);
683 Sprite::leaftexture.load("Textures/Leaf.png", 1);
684 Sprite::toothtexture.load("Textures/Tooth.png", 1);
688 ReSizeGLScene(90, .01);
692 //Set up distant light
693 light.color[0] = .95;
694 light.color[1] = .95;
696 light.ambient[0] = .2;
697 light.ambient[1] = .2;
698 light.ambient[2] = .24;
699 light.location.x = 1;
700 light.location.y = 1;
701 light.location.z = -.2;
702 Normalise(&light.location);
711 texscale = .2 / megascale / viewdistdetail;
712 terrain.scale = 3 * megascale * viewdistdetail;
714 viewer.x = terrain.size / 2 * terrain.scale;
715 viewer.z = terrain.size / 2 * terrain.scale;
717 hawk.load("Models/Hawk.solid");
718 hawk.Scale(.03, .03, .03);
719 hawk.Rotate(90, 1, 1);
720 hawk.CalculateNormals(0);
721 hawk.ScaleNormals(-1, -1, -1);
722 hawkcoords.x = terrain.size / 2 * terrain.scale - 5 - 7;
723 hawkcoords.z = terrain.size / 2 * terrain.scale - 5 - 7;
724 hawkcoords.y = terrain.getHeight(hawkcoords.x, hawkcoords.z) + 25;
726 eye.load("Models/Eye.solid");
727 eye.Scale(.03, .03, .03);
728 eye.CalculateNormals(0);
730 cornea.load("Models/Cornea.solid");
731 cornea.Scale(.03, .03, .03);
732 cornea.CalculateNormals(0);
734 iris.load("Models/Iris.solid");
735 iris.Scale(.03, .03, .03);
736 iris.CalculateNormals(0);
738 LoadSave("Textures/WolfBloodFur.png", &PersonType::types[wolftype].bloodText[0]);
739 LoadSave("Textures/BloodFur.png", &PersonType::types[rabbittype].bloodText[0]);
746 //Fix knife stab, too lazy to do it manually
750 // FIXME - Why this uses skeleton.joints.size() and not Animation::numjoints? (are they equal?)
751 // It seems skeleton.joints.size() is 0 at this point, so this is useless.
752 for (unsigned i = 0; i < Person::players[0]->skeleton.joints.size(); i++) {
753 for (unsigned j = 0; j < Animation::animations[knifesneakattackanim].frames.size(); j++) {
754 Animation::animations[knifesneakattackanim].frames[j].joints[i].position += moveamount;
760 for (unsigned i = 0; i < Person::players[0]->skeleton.joints.size(); i++) {
761 for (unsigned j = 0; j < Animation::animations[knifesneakattackedanim].frames.size(); j++) {
762 Animation::animations[knifesneakattackedanim].frames[j].joints[i].position += moveamount;
768 for (unsigned i = 0; i < Person::players[0]->skeleton.joints.size(); i++) {
769 Animation::animations[dead1anim].frames[1].joints[i].position = Animation::animations[dead1anim].frames[0].joints[i].position;
770 Animation::animations[dead2anim].frames[1].joints[i].position = Animation::animations[dead2anim].frames[0].joints[i].position;
771 Animation::animations[dead3anim].frames[1].joints[i].position = Animation::animations[dead3anim].frames[0].joints[i].position;
772 Animation::animations[dead4anim].frames[1].joints[i].position = Animation::animations[dead4anim].frames[0].joints[i].position;
774 Animation::animations[dead1anim].frames[0].speed = 0.001;
775 Animation::animations[dead2anim].frames[0].speed = 0.001;
776 Animation::animations[dead3anim].frames[0].speed = 0.001;
777 Animation::animations[dead4anim].frames[0].speed = 0.001;
779 Animation::animations[dead1anim].frames[1].speed = 0.001;
780 Animation::animations[dead2anim].frames[1].speed = 0.001;
781 Animation::animations[dead3anim].frames[1].speed = 0.001;
782 Animation::animations[dead4anim].frames[1].speed = 0.001;
784 for (unsigned i = 0; i < Person::players[0]->skeleton.joints.size(); i++) {
785 for (unsigned j = 0; j < Animation::animations[swordsneakattackanim].frames.size(); j++) {
786 Animation::animations[swordsneakattackanim].frames[j].joints[i].position += moveamount;
790 for (unsigned j = 0; j < Animation::animations[swordsneakattackanim].frames.size(); j++) {
791 Animation::animations[swordsneakattackanim].frames[j].weapontarget += moveamount;
796 for (unsigned i = 0; i < Person::players[0]->skeleton.joints.size(); i++) {
797 for (unsigned j = 0; j < Animation::animations[swordsneakattackedanim].frames.size(); j++) {
798 Animation::animations[swordsneakattackedanim].frames[j].joints[i].position += moveamount;
804 if (!screentexture) {
808 if (targetlevel != 7) {
809 emit_sound_at(fireendsound);
816 visibleloading = false;
817 firstLoadDone = true;