LCOV - code coverage report
Current view: top level - src - Engine.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 17.0 % 377 64
Test Date: 2026-04-03 02:26:39 Functions: 48.3 % 29 14

            Line data    Source code
       1              : #include <cstdlib>
       2              : #include <string.h>
       3              : #include <dirent.h>
       4              : #include <png.h>
       5              : 
       6              : #include "Engine.h"
       7              : #include "api.h"
       8              : #include "buffer.h"
       9              : 
      10              : #define PNG_HEADER_SIZE 8
      11              : 
      12              : //------------------------------------------------------------------------------
      13           28 : Engine::Engine() {
      14              :   // initialize resources used by the engine //
      15           14 :   keyState_.initKeyState();
      16           14 :   specialKeyState_.initKeyState();
      17              : 
      18           14 :   currentLevel_ = NULL;
      19           14 :   storedLevel_  = NULL;
      20              : 
      21              :   // setup game timer /////////////////////////
      22           14 :   if(!timer_.init()) {
      23            0 :     PRINT_ERROR("Timer initialization failed.\n");
      24            0 :     exit (1);
      25              :   }
      26              :   ///////////////////////////////////////////////
      27              : 
      28           14 :   fps_ = 0.0f;
      29              : 
      30              : #if EDIT
      31              :   // terrain editing values //
      32              :   paint       = false;
      33              :   paintColor  = false;
      34              : 
      35              :   lastX       = 0.0f;
      36              :   lastY       = 0.0f;
      37              : 
      38              :   last_x      = 0;
      39              :   last_z      = 0;
      40              :   last_red    = 0.0f;
      41              :   last_green  = 0.0f;
      42              :   last_blue   = 0.0f;
      43              :   last_height = 0.0f;
      44              :   last_type   = 0;
      45              :   ////////////////////////////
      46              : #endif
      47              : 
      48           14 :   luaState_   = NULL;
      49           14 :   mainCamera_ = c1_ = c2_ = c3_ = c4_ = NULL;
      50              : 
      51           14 :   isPaused_ = false;
      52              : 
      53           14 :   mouseX_ = 0.0f;
      54           14 :   mouseY_ = 0.0f;
      55              : 
      56           14 :   isRunning_      = true;
      57           14 :   isIntroRunning_ = false;
      58              : 
      59           14 :   alcDevice_ = NULL;
      60           14 :   alcContext_ = NULL;
      61           28 : }
      62              : 
      63              : //------------------------------------------------------------------------------
      64            0 : bool Engine::loadGame(const std::string &file) {
      65              :   // If the lua state has not been initialized for this object, attempt to
      66              :   // initialize it.
      67            0 :   if (file == "" || luaState_ != NULL)
      68            0 :     return false;
      69              : 
      70            0 :   luaState_ = lua_open();
      71              : 
      72              :   // If the lua state still could not be initialized, then exit the game.
      73              :   // ... we can do something smarter with this in the finished product.
      74            0 :   if (!luaState_) {
      75            0 :     PRINT_ERROR("Could not create Lua state.\n");
      76            0 :     exit(-1);
      77              :   }
      78              : 
      79              :   // load Lua base libraries
      80            0 :   luaL_openlibs(luaState_);
      81              : 
      82              :   // Load our library
      83            0 :   luaopen_krigApi(luaState_);
      84              : 
      85              :   // load the script
      86              :   PRINT_DEBUG("Loading Lua game script '%s'...\n", file.c_str());
      87            0 :   luaL_dofile(luaState_, file.c_str());
      88              : 
      89              :   // Find the update function and call it
      90            0 :   lua_getglobal(luaState_, SCRIPT_CALLBACK_ON_LOAD);
      91              : 
      92            0 :   if (lua_isfunction(luaState_, -1)) {
      93            0 :     lua_call(luaState_, 0, 0);
      94            0 :   }
      95              :   else {
      96              :     PRINT_DEBUG_LVL(4, "'%s' function not defined.\n", SCRIPT_CALLBACK_ON_LOAD);
      97            0 :     lua_pop(luaState_, 1);
      98              :   }
      99              : 
     100            0 :   return (true);
     101            0 : }
     102              : 
     103              : //------------------------------------------------------------------------------
     104            0 : bool Engine::loadIntroCredits() {
     105              :   // load the intro script from the buffer
     106              :   PRINT_DEBUG("Loading Lua game script 'intro credits'...\n");
     107            0 :   loadLevelFromBuffer(intro_level_script_buffer);
     108              : 
     109            0 :   isIntroRunning_ = true;
     110              : 
     111            0 :   return (true);
     112              : }
     113              : 
     114              : //------------------------------------------------------------------------------
     115            0 : void Engine::updateGame(const float &elapsedTime) {
     116              :   // Attempt to execute the script only if the lua state has already been
     117              :   // initialized with a script
     118            0 :   if (!luaState_)
     119            0 :     return;
     120              : 
     121              :   // Find the update function and call it
     122            0 :   lua_getglobal(luaState_, SCRIPT_CALLBACK_ON_UPDATE);
     123              : 
     124            0 :   if (lua_isfunction(luaState_, -1)) {
     125            0 :     lua_pushnumber(luaState_, elapsedTime);
     126            0 :     lua_call(luaState_, 1, 0);
     127            0 :   }
     128              :   else {
     129              :     PRINT_DEBUG_LVL(4, "'%s' function not defined.\n", SCRIPT_CALLBACK_ON_UPDATE);
     130            0 :     lua_pop(luaState_, 1);
     131              :   }
     132            0 : }
     133              : 
     134              : //------------------------------------------------------------------------------
     135           13 : void Engine::unloadGame() {
     136              :   // Attempt to execute the on_unload function only if the lua state has
     137              :   // already been initialized with a script
     138           13 :   if (!luaState_)
     139           13 :     return;
     140              : 
     141              :   // Find the update function and call it
     142            0 :   lua_getglobal(luaState_, SCRIPT_CALLBACK_ON_UNLOAD);
     143              : 
     144            0 :   if (lua_isfunction(luaState_, -1)) {
     145            0 :     lua_call(luaState_, 0, 0);
     146            0 :   }
     147              :   else {
     148              :     PRINT_DEBUG_LVL(4, "'%s' function not defined.\n", SCRIPT_CALLBACK_ON_UNLOAD);
     149            0 :     lua_pop(luaState_, 1);
     150              :   }
     151              : 
     152            0 :   lua_close(luaState_);
     153            0 :   luaState_ = NULL;
     154           13 : }
     155              : 
     156              : //------------------------------------------------------------------------------
     157            0 : void Engine::gameCycle() {
     158            0 :   timeElapsed_ = timer_.getElapsedSeconds();
     159            0 :   updateGame(timeElapsed_);
     160            0 :   fps_ = timer_.getFPS();
     161              : 
     162            0 :   if (currentLevel_ != NULL && !isPaused_)
     163            0 :     currentLevel_->setElapsedTime(timeElapsed_);
     164              : 
     165            0 :   if (currentLevel_ != NULL) {
     166            0 :     if (currentLevel_->checkComplete()) {
     167            0 :       if (isIntroRunning_) {
     168            0 :         unloadGame();
     169            0 :         loadGame("./scripts/main.lua");
     170            0 :         isIntroRunning_ = false;
     171            0 :       }
     172            0 :     }
     173              :     else {
     174            0 :       if (!isPaused_) {
     175            0 :         mainCamera_->update(currentLevel_->getElapsedTime());
     176              : 
     177            0 :         currentLevel_->animateLevel();
     178              : 
     179              :         //processCommands();
     180              : 
     181            0 :         currentLevel_->updateLevel();
     182            0 :         currentLevel_->prepareLevel();   // collision detection
     183              : 
     184              :         //currentLevel_->updateLevel();
     185              : 
     186            0 :         prepare();
     187              : 
     188              :         //Matrix m;
     189              :         //mainCamera_->worldRotation.buildRotationMatrix(m);
     190              : 
     191              :         //glMultMatrixf(m.data);
     192            0 :         currentLevel_->drawLevel();
     193              : 
     194            0 :         currentLevel_->getMusic()->Update();
     195              : 
     196            0 :         glClear(GL_DEPTH_BUFFER_BIT);
     197            0 :         glLoadIdentity();
     198              : 
     199            0 :         glDepthFunc(GL_ALWAYS);
     200            0 :         currentLevel_->postDraw();
     201            0 :         glDepthFunc(GL_LESS);
     202              : 
     203            0 :         glutSwapBuffers();
     204            0 :       }
     205              :     }
     206            0 :   }
     207              : 
     208            0 :   processCommands();
     209            0 : }
     210              : 
     211              : //------------------------------------------------------------------------------
     212            0 : void Engine::prepare() {
     213            0 :   glClear(GL_DEPTH_BUFFER_BIT);
     214            0 :   glLoadIdentity();
     215              : 
     216            0 :   mainCamera_->prepareGLView();
     217              : 
     218            0 :   glDepthMask(GL_FALSE);
     219            0 :   currentLevel_->drawSky();
     220            0 :   glDepthMask(GL_TRUE);
     221              : 
     222              :   //glDepthFunc(GL_ALWAYS);
     223              :   //    currentLevel_->postDraw();
     224              :   // glDepthFunc(GL_LESS);
     225              : 
     226            0 :   Matrix translationMatrix;
     227              : 
     228            0 :   Vector position = mainCamera_->getPosition();
     229              : 
     230            0 :   translationMatrix.setTranslation(-position.x, -position.y, -position.z);
     231              : 
     232            0 :   glMultMatrixf(translationMatrix.data);
     233            0 : }
     234              : 
     235              : //------------------------------------------------------------------------------
     236            0 : void Engine::initGL() {
     237            0 :   loadModels();
     238              : 
     239            0 :   GLfloat shaderData[16] = {
     240              :     0.4f, 0.4f, 0.4f, 0.7f, 0.7f, 0.7f, 1.0f, 1.0f,
     241              :     1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f
     242              :   };
     243              : 
     244              :   //glClearColor(0.0f, 0.0f, 0.3f, 1.0f);
     245            0 :   glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
     246              : 
     247            0 :   glShadeModel(GL_SMOOTH); // use smooth shading
     248            0 :   glEnable(GL_DEPTH_TEST); // remove hidden surfaces
     249              : 
     250              :   // create 1D bitmap for lighting ////////////
     251            0 :   glGenTextures(1, &shaderTexture_[0]);
     252              : 
     253            0 :   glBindTexture(GL_TEXTURE_1D, shaderTexture_[0]);
     254            0 :   glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     255            0 :   glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     256              : 
     257            0 :   glTexImage1D(GL_TEXTURE_1D, 0, 1, 16, 0, GL_LUMINANCE, GL_FLOAT, shaderData);
     258              :   /////////////////////////////////////////////
     259              : 
     260            0 :   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     261            0 :   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     262            0 :   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
     263            0 :   glGenTextures(MAX_TEXTURES, Object::textureIds);
     264            0 :   loadTextures();
     265              : 
     266            0 :   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
     267            0 :   glFrontFace(GL_CCW);
     268            0 :   glEnable(GL_CULL_FACE);
     269            0 :   glPolygonMode(GL_FRONT, GL_FILL);
     270            0 :   glEnable(GL_BLEND);
     271              : 
     272              :   // setup projection matrix //////////////////
     273            0 :   glMatrixMode(GL_PROJECTION);
     274            0 :   glLoadIdentity();
     275            0 :   gluPerspective (45.0, (800.0f / 600.0f), 0.001f, 300.0f);
     276            0 :   glMatrixMode(GL_MODELVIEW);
     277              : 
     278            0 :   glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
     279            0 :   glDisable(GL_LIGHTING);
     280            0 :   glBindTexture(GL_TEXTURE_1D, shaderTexture_[0]);
     281            0 :   glLineWidth(1.0f);
     282              : 
     283            0 :   glDepthFunc(GL_LESS);
     284              : 
     285              :   // setup display lists //////////////////////
     286            0 :   lists_ = glGenLists(3);
     287              : 
     288              :   // list to setup cel shading ////////////////
     289            0 :   glNewList(lists_, GL_COMPILE);
     290            0 :   glDisable(GL_BLEND);
     291              :   //glEnable (GL_DEPTH_TEST);
     292            0 :   glDepthFunc(GL_LEQUAL);
     293            0 :   glEnable(GL_TEXTURE_1D);
     294              :   //glBindTexture(GL_TEXTURE_1D, shaderTexture[0]);
     295            0 :   glLineWidth(1.0f);
     296            0 :   glEndList();
     297              : 
     298              :   // list to setup to draw outline ////////////
     299            0 :   glNewList(lists_ + 1, GL_COMPILE);
     300            0 :   glDisable(GL_TEXTURE_1D);
     301            0 :   glEnable(GL_BLEND);
     302            0 :   glDepthFunc(GL_LESS);
     303            0 :   glLineWidth(3.0f);
     304            0 :   glCullFace(GL_FRONT);
     305            0 :   glPolygonMode(GL_BACK, GL_LINE);
     306            0 :   glEndList();
     307              : 
     308              :   // list to reset display settings
     309            0 :   glNewList(lists_ + 2, GL_COMPILE);
     310            0 :   glPolygonMode(GL_BACK, GL_FILL);
     311            0 :   glDepthFunc(GL_LESS);
     312            0 :   glCullFace(GL_BACK);
     313            0 :   glEndList();
     314              : 
     315            0 :   glHint(GL_POLYGON_SMOOTH, GL_NICEST);
     316            0 :   glEnable(GL_POLYGON_SMOOTH);
     317            0 :   glEnable(GL_BLEND);
     318            0 : }
     319              : 
     320              : //------------------------------------------------------------------------------
     321            0 : void Engine::initAL() {
     322              :   PRINT_DEBUG("Loading AL...\n");
     323            0 :   if (alcDevice_  || alcContext_) {
     324              :     PRINT_DEBUG("AL device or context already initialized; skipping init\n");
     325            0 :     return;
     326              :   }
     327              : 
     328            0 :   alcDevice_ = alcOpenDevice(NULL);
     329            0 :   if (!alcDevice_) {
     330              :     PRINT_DEBUG_LVL(1, "Could not initialize AL device; error code %d; skipping init\n", alGetError());
     331            0 :     return;
     332              :   }
     333              : 
     334            0 :   alcContext_ = alcCreateContext(alcDevice_, NULL);
     335            0 :   if (!alcContext_) {
     336              :     PRINT_DEBUG_LVL(1, "Could not create AL context; error code %d; skipping init\n", alGetError());
     337            0 :     alcCloseDevice(alcDevice_);
     338            0 :     return;
     339              :   }
     340              : 
     341            0 :   if (!alcMakeContextCurrent(alcContext_)) {
     342              :     PRINT_DEBUG_LVL(1, "Could not make AL context current; error code %d; skipping init\n", alGetError());
     343            0 :   }
     344            0 : }
     345              : 
     346              : //------------------------------------------------------------------------------
     347            0 : void Engine::loadSoundFx() {
     348              :   PRINT_DEBUG("Loading SoundFx...\n");
     349            0 :   soundFx_.load();
     350            0 : }
     351              : 
     352              : //------------------------------------------------------------------------------
     353           13 : void Engine::unloadSoundFx() {
     354              :   PRINT_DEBUG("Unloading SoundFx...\n");
     355           13 :   soundFx_.unload();
     356           13 : }
     357              : 
     358              : //------------------------------------------------------------------------------
     359            1 : void Engine::processKeyUp(const int &key) {
     360              :   PRINT_DEBUG_LVL(1, "special key up (%d)\n", key);
     361            1 :   specialKeyState_.keys[key] = KEY_STATE_RELEASED;
     362            1 : }
     363              : 
     364              : //------------------------------------------------------------------------------
     365            3 : void Engine::processKeyDown(const int &key) {
     366              :   PRINT_DEBUG_LVL(1, "special key down (%d)\n", key);
     367            3 :   specialKeyState_.keys[key] = KEY_STATE_PRESSED;
     368            3 : }
     369              : 
     370              : //------------------------------------------------------------------------------
     371            1 : void Engine::processCommands() {
     372            1 :   keyState_.initKeyState();
     373            1 :   specialKeyState_.initKeyState();
     374            1 : }
     375              : 
     376              : //------------------------------------------------------------------------------
     377            1 : void Engine::processNormalKeyUp(const unsigned char &key) {
     378              :   PRINT_DEBUG_LVL(1, "normal key up (%d)\n", key);
     379            1 :   keyState_.keys[key] = KEY_STATE_RELEASED;
     380            1 : }
     381              : 
     382              : //------------------------------------------------------------------------------
     383            3 : void Engine::processNormalKeyDown(const unsigned char &key) {
     384              :   PRINT_DEBUG_LVL(1, "normal key down (%d)\n", key);
     385            3 :   keyState_.keys[key] = KEY_STATE_PRESSED;
     386              : 
     387              : #if EDIT
     388              :   switch (key) {
     389              :     // Select current camera
     390              :     case '1':
     391              :       mainCamera_ = c1_;
     392              :       currentLevel_->setCamera(mainCamera_);
     393              :       break;
     394              :     case '2':
     395              :       mainCamera_ = c2_;
     396              :       currentLevel_->setCamera(mainCamera_);
     397              :       break;
     398              :     case '3':
     399              :       mainCamera_ = c3_;
     400              :       currentLevel_->setCamera(mainCamera_);
     401              :       break;
     402              :     case '4':
     403              :       mainCamera_ = c4_;
     404              :       currentLevel_->setCamera(mainCamera_);
     405              :       break;
     406              : 
     407              :       // Save terrain
     408              :     case 'O':
     409              :     case 'o':
     410              :       currentLevel_->saveTerrain("terrains/new_terrain.txt");
     411              :       break;
     412              : 
     413              :       // Toggle settings
     414              :     case 'G':
     415              :     case 'g':
     416              :       currentLevel_->toggleGrid();
     417              :       break;
     418              :     case 'B':
     419              :     case 'b':
     420              :       currentLevel_->toggleBoundingBoxes();
     421              :       break;
     422              :     case 'C':
     423              :     case 'c':
     424              :       currentLevel_->toggleControlTriangles();
     425              :       break;
     426              : 
     427              :     case '.':
     428              :       // used for profiling
     429              :       exit(0);
     430              :       break;
     431              :   }
     432              : #endif
     433            3 : }
     434              : 
     435              : //------------------------------------------------------------------------------
     436            0 : void Engine::prepLevelLoad() {
     437            0 :   if (currentLevel_)
     438            0 :     delete currentLevel_;
     439              : 
     440            0 :   if (!mainCamera_) {
     441              :     // setup camera(s) for the current level
     442            0 :     c1_ = new Camera(1); c1_->setProjectionMatrix();
     443            0 :     mainCamera_ = c1_;
     444              : 
     445            0 :     c2_ = new Camera(2); c2_->setProjectionMatrix();
     446            0 :     c3_ = new Camera(3); c3_->setProjectionMatrix();
     447            0 :     c4_ = new Camera(4); c4_->setProjectionMatrix();
     448              : 
     449            0 :     c2_->setPosition(0.0f, 100.0f, 0.0f);
     450            0 :     c2_->setRotationEuler(1.57, 0.0f, 0.0f);
     451            0 :     c3_->setPosition(0.0f, 0.0f, 0.0f);
     452            0 :     c4_->setPosition(0.0f, 0.0f, 0.0f);
     453            0 :   }
     454              : 
     455            0 :   mainCamera_->init();
     456            0 :   mainCamera_->unloadScript();
     457              : 
     458            0 :   currentLevel_ = new GameLevel(lists_);
     459            0 :   currentLevel_->setCamera(mainCamera_);
     460            0 : }
     461              : 
     462              : //------------------------------------------------------------------------------
     463            0 : void Engine::loadLevel(const char* levelFile) {
     464            0 :   prepLevelLoad();
     465            0 :   currentLevel_->loadLevel(levelFile);
     466            0 :   timeElapsed_ = timer_.getElapsedSeconds();
     467            0 : }
     468              : 
     469              : //------------------------------------------------------------------------------
     470            0 : void Engine::loadLevelFromBuffer(const char* buffer) {
     471            0 :   prepLevelLoad();
     472            0 :   currentLevel_->loadLevelFromBuffer(buffer);
     473            0 :   timeElapsed_ = timer_.getElapsedSeconds();
     474            0 : }
     475              : 
     476              : //------------------------------------------------------------------------------
     477            0 : void Engine::loadModels() {
     478            0 :   DIR *dir = opendir("./models/");
     479              : 
     480            0 :   if (dir == NULL) {
     481              :     PRINT_DEBUG_LVL(2, "'models' directory not present; no models will be loaded.\n");
     482            0 :     return;
     483              :   }
     484              : 
     485              :   dirent *de;
     486              :   ModelStorage *model;
     487              :   char filePath[MAX_PATH_LEN];
     488            0 :   std::string hashKey;
     489              : 
     490            0 :   while ((de = readdir(dir)) != NULL) {
     491              :     // only consider model files with the .mdl extension //
     492            0 :     if (strstr(de->d_name, ".mdl") != NULL) {
     493              :       // build full path to load //
     494            0 :       strcpy(filePath, "./models/");
     495            0 :       strcat(filePath, de->d_name);
     496              : 
     497              :       // load model file into model storage //
     498              :       PRINT_DEBUG("Loading model file '%s'...\n", filePath);
     499              : 
     500            0 :       model = new ModelStorage();
     501            0 :       model->load(filePath);
     502              : 
     503              :       // TODO: Investigate progress on "shadows" feature
     504              :       //model->buildEdges();
     505              : 
     506              :       // insert model file into model hash //
     507            0 :       hashKey = std::string(de->d_name);
     508            0 :       ModelGameObject::modelHash[hashKey] = model;
     509            0 :     }
     510              :   }
     511              : 
     512            0 :   closedir(dir);
     513            0 : }
     514              : 
     515              : //------------------------------------------------------------------------------
     516            0 : void Engine::loadTextures() {
     517            0 :   DIR *dir = opendir("./textures/");
     518              : 
     519            0 :   if (dir == NULL) {
     520              :     PRINT_DEBUG_LVL(2, "'textures' directory not present; no textures will be loaded.\n");
     521            0 :     return;
     522              :   }
     523              : 
     524              :   dirent *de;
     525              :   char filePath[MAX_PATH_LEN];
     526            0 :   std::string hashKey;
     527            0 :   int textureId = 0;
     528              : 
     529            0 :   while ((de = readdir(dir)) != NULL) {
     530            0 :     glBindTexture (GL_TEXTURE_2D, Object::textureIds[textureId]);
     531              :     // only load texture files with the .png extension //
     532            0 :     if (strstr(de->d_name, ".png") != NULL) {
     533              :       // build full path to load //
     534            0 :       strcpy(filePath, "./textures/");
     535            0 :       strcat(filePath, de->d_name);
     536              : 
     537              :       // load texture into storage
     538              :       PRINT_DEBUG("Loading texture file '%s'...\n", filePath);
     539              : 
     540            0 :       unsigned char* pixels = NULL;
     541            0 :       unsigned int format   = 0;
     542            0 :       unsigned int height   = 0;
     543            0 :       unsigned int width    = 0;
     544              : 
     545            0 :       if (!loadPng(filePath, &pixels, &format, &height, &width)) {
     546            0 :         PRINT_ERROR("Could not load texture file. Skipping...\n");
     547            0 :         if (pixels != NULL) {
     548            0 :           delete[] pixels;
     549            0 :         }
     550            0 :         continue;
     551              :       }
     552              : 
     553            0 :       if (pixels != NULL) {
     554            0 :         gluBuild2DMipmaps( GL_TEXTURE_2D, 4, width, height,
     555            0 :                      format, GL_UNSIGNED_BYTE, pixels );
     556              : 
     557            0 :         delete[] pixels;
     558            0 :       }
     559              : 
     560            0 :       hashKey = std::string(de->d_name);
     561            0 :       Object::textureHash[hashKey] = textureId++;
     562            0 :     }
     563              :   }
     564              : 
     565            0 :   closedir(dir);
     566            0 : }
     567              : 
     568              : //------------------------------------------------------------------------------
     569            1 : void Engine::processMouseMove(const int &x, const int &y) {
     570            1 :   mouseX_ = x;
     571            1 :   mouseY_ = y;
     572            1 : }
     573              : 
     574              : //------------------------------------------------------------------------------
     575            2 : void Engine::shutdown() {
     576            2 :   isRunning_ = false;
     577            2 : }
     578              : 
     579              : //------------------------------------------------------------------------------
     580           26 : Engine::~Engine() {
     581           13 :   unloadGame();
     582           13 :   unload();
     583           26 : }
     584              : 
     585              : //------------------------------------------------------------------------------
     586           13 : void Engine::unload() {
     587           13 :   if (currentLevel_)
     588            0 :     delete currentLevel_;
     589              : 
     590           13 :   if (storedLevel_)
     591            0 :     delete storedLevel_;
     592              : 
     593           13 :   if (mainCamera_) {
     594            0 :     delete c1_;
     595            0 :     delete c2_;
     596            0 :     delete c3_;
     597            0 :     delete c4_;
     598            0 :   }
     599              : 
     600           13 :   unloadSoundFx();
     601              : 
     602           13 :   currentLevel_ = storedLevel_ = NULL;
     603           13 :   c1_ = c2_ = c3_ = c4_ = mainCamera_ = NULL;
     604              : 
     605           13 :   alcMakeContextCurrent(NULL);
     606           13 :   alcDestroyContext(alcContext_);
     607           13 :   alcCloseDevice(alcDevice_);
     608           13 :   alcDevice_ = NULL;
     609           13 :   alcContext_ = NULL;
     610           13 : }
     611              : 
     612              : //------------------------------------------------------------------------------
     613            0 : void Engine::pause() {
     614            0 :   isPaused_ = !isPaused_;
     615            0 : }
     616              : 
     617              : //------------------------------------------------------------------------------
     618            0 : bool Engine::loadPng(const char* filePath, unsigned char** pixels, unsigned int* format, unsigned int* height, unsigned int* width) {
     619            0 :   FILE *fp = fopen(filePath, "rb");
     620            0 :   if (!fp) {
     621            0 :     return false;
     622              :   }
     623              : 
     624              :   unsigned char header[PNG_HEADER_SIZE];
     625              : 
     626            0 :   if (fread(header, 1, PNG_HEADER_SIZE, fp) != PNG_HEADER_SIZE) {
     627            0 :     fclose(fp);
     628            0 :     return false;
     629              :   }
     630              : 
     631            0 :   if (png_sig_cmp(header, 0, PNG_HEADER_SIZE)) {
     632            0 :     fclose(fp);
     633            0 :     return false;
     634              :   }
     635              : 
     636            0 :   png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
     637              : 
     638            0 :   if (!png_ptr) {
     639            0 :     fclose(fp);
     640            0 :     return false;
     641              :   }
     642              : 
     643            0 :   png_infop info_ptr = png_create_info_struct(png_ptr);
     644              : 
     645            0 :   if (!info_ptr) {
     646            0 :     png_destroy_read_struct(&png_ptr, NULL, NULL);
     647            0 :     fclose(fp);
     648            0 :     return false;
     649              :   }
     650              : 
     651            0 :   if (setjmp(png_jmpbuf(png_ptr))) {
     652            0 :     png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
     653            0 :     fclose(fp);
     654            0 :     return false;
     655              :   }
     656              : 
     657            0 :   png_init_io(png_ptr, fp);
     658            0 :   png_set_sig_bytes(png_ptr, PNG_HEADER_SIZE);
     659              : 
     660            0 :   png_read_info(png_ptr, info_ptr);
     661            0 :   *width  = png_get_image_width(png_ptr, info_ptr);
     662            0 :   *height = png_get_image_height(png_ptr, info_ptr);
     663              : 
     664            0 :   if (png_get_bit_depth(png_ptr, info_ptr) < 8) {
     665            0 :     png_set_packing(png_ptr);
     666            0 :   }
     667              : 
     668            0 :   if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
     669            0 :     png_set_tRNS_to_alpha(png_ptr);
     670            0 :   }
     671              : 
     672            0 :   *format = 0;
     673            0 :   switch(png_get_color_type(png_ptr, info_ptr)) {
     674              :     case PNG_COLOR_TYPE_GRAY:
     675            0 :       png_set_gray_to_rgb(png_ptr);
     676            0 :       *format = GL_RGB;
     677            0 :       break;
     678              :     case PNG_COLOR_TYPE_GRAY_ALPHA:
     679            0 :       png_set_gray_to_rgb(png_ptr);
     680            0 :       *format = GL_RGBA;
     681            0 :       break;
     682              :     case PNG_COLOR_TYPE_PALETTE:
     683            0 :       *format = GL_RGB;
     684            0 :       png_set_expand(png_ptr);
     685            0 :       break;
     686              :     case PNG_COLOR_TYPE_RGB:
     687            0 :       *format = GL_RGB;
     688            0 :       break;
     689              :     case PNG_COLOR_TYPE_RGB_ALPHA:
     690            0 :       *format = GL_RGBA;
     691            0 :       break;
     692              :     default:
     693            0 :       *format = -1;
     694            0 :   }
     695              : 
     696            0 :   if (*format == -1) {
     697            0 :     png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
     698            0 :     fclose(fp);
     699            0 :     return false;
     700              :   }
     701              : 
     702            0 :   unsigned int bpp = (unsigned int)png_get_rowbytes(png_ptr, info_ptr) / *width;
     703              : 
     704            0 :   png_set_interlace_handling(png_ptr);
     705              : 
     706            0 :   png_read_update_info(png_ptr, info_ptr);
     707              : 
     708            0 :   int totalPixels = *width * *height * bpp;
     709            0 :   *pixels = new unsigned char [totalPixels];
     710            0 :   memset(*pixels, 0, totalPixels);
     711              : 
     712            0 :   png_bytep rows[*height];
     713              : 
     714            0 :   unsigned char* p = *pixels;
     715            0 :   for (int i = 0; i < *height; ++i) {
     716            0 :     rows[i] = p;
     717            0 :     p += (*width * bpp);
     718            0 :   }
     719              : 
     720            0 :   png_read_image(png_ptr, rows);
     721            0 :   png_read_end(png_ptr, NULL);
     722            0 :   png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
     723            0 :   fclose(fp);
     724              : 
     725            0 :   return true;
     726            0 : }
     727              : 
     728              : #if EDIT
     729              : //------------------------------------------------------------------------------
     730              : void Engine::getTerrainInfo(int &x, int &z, float &height, int &type, float &red, float &green, float &blue) {
     731              :   if (mainCamera_ == NULL)
     732              :     return;
     733              : 
     734              :   Vector position = c2_->getPosition();
     735              : 
     736              :   x = (int)(position.x / 5.0f);
     737              :   z = -(int)(position.z / 5.0f);
     738              :   currentLevel_->getTerrainInfo(x, z, height, type, red, green, blue);
     739              : }
     740              : 
     741              : //------------------------------------------------------------------------------
     742              : void Engine::updateTerrain(int &x, int &z, float &height, int &type, float &red, float &green, float &blue) {
     743              :   if (!mainCamera_)
     744              :     return;
     745              : 
     746              :   if (mainCamera_->id_ == 2 || mainCamera_->id_ == 3) {
     747              :     Vector position = c2_->getPosition();
     748              :     x = (int)(position.x / 5.0f);
     749              :     z = -(int)(position.z / 5.0f);
     750              :     currentLevel_->updateTerrain(x,z,height,type,red,green,blue);
     751              : 
     752              :     last_x      = x;
     753              :     last_z      = z;
     754              :     last_type   = type;
     755              :     last_red    = red;
     756              :     last_green  = green;
     757              :     last_blue   = blue;
     758              :     last_height = height;
     759              :   }
     760              : }
     761              : 
     762              : //------------------------------------------------------------------------------
     763              : void Engine::updateColor(float &red, float &green, float &blue) {
     764              :   if (!mainCamera_)
     765              :     return;
     766              : 
     767              :   if (mainCamera_->id_ == 2 || mainCamera_->id_ == 3) {
     768              :     Vector position = c2_->getPosition();
     769              : 
     770              :     int x = (int)(position.x / 5.0f);
     771              :     int z = -(int)(position.z / 5.0f);
     772              :     currentLevel_->updateColor(x, z, red, green, blue);
     773              : 
     774              :     last_red   = red;
     775              :     last_green = green;
     776              :     last_blue  = blue;
     777              :   }
     778              : }
     779              : #endif
        

Generated by: LCOV version 2.4-0