/* * CGame.cpp * * Created on: 01.05.2009 * Author: gerstrong */ #include #include "keen.h" #include "CGame.h" #include "include/game.h" #include "include/misc.h" #include "include/main.h" #include "include/menu.h" #include "include/fileio/story.h" #include "vorticon/CHighScores.h" #include "vorticon/CIntro.h" #include "vorticon/CCredits.h" #include "CLogFile.h" #include "fileio.h" #include "fileio/CExeFile.h" #include "fileio/CTileLoader.h" #include "fileio/CPatcher.h" #include "sdl/sound/CSound.h" #include "sdl/CVideoDriver.h" CGame::CGame() { m_Episode = 0; TileLoader = NULL; EGAGraphics = NULL; m_Messages = NULL; } CGame::~CGame() { if(EGAGraphics) delete EGAGraphics; if(TileLoader) delete TileLoader; if(m_Messages) delete m_Messages; } short CGame::runCycle(stCloneKeenPlus *pCKP) { int opt = MAINMNU_1PLAYER; int retval; int eseq = 0; int defaultopt = 0; initgamefirsttime(pCKP, EGAGraphics->getNumSprites()); initgame(pCKP); g_pLogFile->ftextOut("Game starting...
"); if (eseq) { endsequence(pCKP); closeCKP(pCKP); } if(!pCKP->Control.skipstarting) { CIntro Intro; Intro.Render(pCKP); pCKP->Control.skipstarting=0; } do { if (QuitState==QUIT_TO_TITLE) QuitState = NO_QUIT; if(pCKP->Control.storyboard == 1) // Show the story of the game { char *text; int textsize; textsize = readStoryText(&text, pCKP->GameData[pCKP->Resources.GameSelected-1].Episode, pCKP->GameData[pCKP->Resources.GameSelected-1].DataDirectory); // Read text from // and store it at the text pointer if(textsize > 0) { showPage(text,pCKP,textsize); free(text); } else if(textsize == 0) { g_pLogFile->ftextOut("readStoryText(): Error reading story text. Are you sure that there is any story text?"); } else if(textsize == 0) { g_pLogFile->ftextOut("readStoryText(): Error reading story text. The version appears to be incompatible"); } pCKP->Control.storyboard = 0; } if(pCKP->Control.levelcontrol.command != LVLC_START_LEVEL) { g_pLogFile->ftextOut("calling mainmenu()
"); opt = mainmenu(pCKP, defaultopt); // Read option from the main menu // of the game. pCKP->Control.skipstarting=0; g_pLogFile->ftextOut("gcl: opt = %d
", opt); } defaultopt = 0; IntroCanceled = 0; switch(opt) { case MAINMNU_1PLAYER: numplayers = 1; defaultopt = 0; current_demo = 1; initgamefirsttime(pCKP, EGAGraphics->getNumSprites()); loadinggame = 0; playgame_levelmanager(pCKP); break; case MAINMNU_2PLAYER: defaultopt = 0; current_demo = 1; numplayers = 2; initgamefirsttime(pCKP, EGAGraphics->getNumSprites()); loadinggame = 0; playgame_levelmanager(pCKP); break; case MAINMNU_LOADGAME: if (loadslot) { loadinggame = 1; defaultopt = 0; current_demo = 1; numplayers = 1; // here was 2. Why was that? I don't understand initgamefirsttime(pCKP, EGAGraphics->getNumSprites()); playgame_levelmanager(pCKP); } break; case MAINMNU_STORY: pCKP->Control.storyboard=1; break; case MAINMNU_HIGHSCORES: CHighScores *pHighscores; pHighscores = new CHighScores(pCKP); if(pHighscores->showHighScore()) { g_pLogFile->ftextOut("Error processing Highscore!!
"); } delete pHighscores; break; case MAINMNU_NEW_GAME: pCKP->shutdown = SHUTDOWN_NEW_GAME; break; case MAINMNU_ABOUT: CCredits *pCredit; pCredit = new CCredits; pCredit->Render(pCKP); delete pCredit; pCredit = NULL; break; case MAINMNU_TIMEOUT: case MAINMNU_DEMO: retval = play_demo(current_demo, pCKP, EGAGraphics->getNumSprites()); if (retval==DEMO_RESULT_FILE_BAD) { // we tried to play a demo that did not exist--assume we // reached the last demo and go back to the intro //intro(pCKP); CIntro *pIntro; pIntro = new CIntro(); delete pIntro; pIntro = NULL; current_demo = 0; } else if (retval==DEMO_RESULT_CANCELED) { // user hit a key to cancel demo IntroCanceled = 1; // pop up menu } if (IntroCanceled) { // user canceled out of demo (or intro if at end of demos) // if user selected "demo" have it selected when he comes back if (opt==MAINMNU_DEMO) { defaultopt = MAINMNU_DEMO; } } current_demo++; break; case RESTART_GAME: g_pLogFile->ftextOut("********************
"); g_pLogFile->ftextOut(" Restarting game...
"); g_pLogFile->ftextOut("********************
\n"); cleanup(pCKP); pCKP->shutdown = SHUTDOWN_RESTART; return 0; break; case BACK2MAINMENU: default: break; } if(pCKP->shutdown == SHUTDOWN_NEW_GAME) return 0; g_pLogFile->ftextOut("bottom of game control loop opt=%d crashflag=%d
", opt, crashflag); if(pCKP->shutdown == SHUTDOWN_EXIT) break; } while(opt != MAINMNU_QUIT && opt != MAINMNU_NEW_GAME && !crashflag); return 0; } bool CGame::loadResources(unsigned short Episode, const std::string& DataDirectory) { m_Episode = Episode; m_DataDirectory = DataDirectory; if( m_DataDirectory.size() > 0 && m_DataDirectory[m_DataDirectory.size()-1] != '/' ) m_DataDirectory += "/"; // Decode the entire graphics for the game (EGALATCH, EGASPRIT) EGAGraphics = new CEGAGraphics(Episode, DataDirectory); // Path is relative to the data dir if(!EGAGraphics) return 1; EGAGraphics->loadData(); // Get the EXE of the game and decompress it if needed. CExeFile *ExeFile = new CExeFile(Episode, DataDirectory); ExeFile->readData(); int version = ExeFile->getEXEVersion(); g_pLogFile->ftextOut("Commander Keen Episode %d (Version %d.%d) was detected.
", Episode, version/100,version%100); if(version == 134) g_pLogFile->ftextOut("This version of the game is not supported!
"); // Patch the EXE-File-Data directly in the memory. CPatcher *Patcher = new CPatcher(Episode, ExeFile->getEXEVersion(), ExeFile->getData(), DataDirectory); Patcher->patchMemory(); delete Patcher; // Load tile attributes. if(TileLoader) delete TileLoader; if(ExeFile->getData() == NULL) { g_pLogFile->textOut(RED, "CGame::loadResources: Could not load data out of EXE
"); delete ExeFile; return false; } TileLoader = new CTileLoader(Episode, ExeFile->getEXEVersion(), ExeFile->getData()); if(!TileLoader->load()) { g_pLogFile->textOut(RED, "CGame::loadResources: Could not load data with TileLoader
"); delete ExeFile; return false; } // load the strings. TODO: After that this one will replace loadstrings //m_Messages = new CMessages(); delete ExeFile; //m_Messages->readData(char *buf, int episode, int version); loadstrings("strings.dat"); delete ExeFile; // Load the sound data bool ok = g_pSound->loadSoundData(m_Episode, DataDirectory); if( !ok ) return false; return true; } void CGame::freeResources(void) { if(EGAGraphics) { delete EGAGraphics; EGAGraphics = NULL; } } void CGame::preallocateCKP(stCloneKeenPlus *pCKP) { // This function prepares the CKP Structure so that the it is allocated in the memory. pCKP->numGames = 0; pCKP->Resources.GameSelected = 0; pCKP->GameData = NULL; pCKP->GameData = new stGameData[1]; framebyframe = 0; pCKP->Control.levelcontrol.demomode = DEMO_NODEMO; current_demo = 1; pCKP->Joystick = NULL; acceleratemode = 0; g_pVideoDriver->showFPS(false); player[0].x = player[0].y = 0; }