Fixed a bug which made the main-menu crash sometimes git-svn-id: https://clonekeenplus.svn.sourceforge.net/svnroot/clonekeenplus/cgenius/trunk@205 4df4b0f3-56ce-47cb-b001-ed939b7d65a6
301 lines
8.0 KiB
C++
301 lines
8.0 KiB
C++
/*
|
|
* CGame.cpp
|
|
*
|
|
* Created on: 01.05.2009
|
|
* Author: gerstrong
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
|
|
#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...<br>");
|
|
|
|
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()<br>");
|
|
|
|
opt = mainmenu(pCKP, defaultopt); // Read option from the main menu
|
|
// of the game.
|
|
|
|
pCKP->Control.skipstarting=0;
|
|
|
|
g_pLogFile->ftextOut("gcl: opt = %d<br>", 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!!<br>");
|
|
}
|
|
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("********************<br>");
|
|
g_pLogFile->ftextOut(" Restarting game...<br>");
|
|
g_pLogFile->ftextOut("********************<br>\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<br>", 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.<br>", Episode, version/100,version%100);
|
|
if(version == 134) g_pLogFile->ftextOut("This version of the game is not supported!<br>");
|
|
|
|
// 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<br>");
|
|
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<br>");
|
|
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;
|
|
}
|