Commit 923dc70e authored by Gerstrong's avatar Gerstrong

split up the core game control core into proper classes

parent a6182490
......@@ -118,7 +118,9 @@ void CGame::run()
g_pVideoDriver->start();
}
// Process Game Control
m_Engine.process();
m_Engine.process();
}
// Render the Screen
......@@ -148,7 +150,7 @@ void CGame::run()
*/
void CGame::cleanup()
{
m_Engine.cleanupAll();
m_Engine.cleanup();
g_pInput->Del();
g_pSound->destroy();
......
......@@ -8,7 +8,7 @@
#ifndef CGAME_H_
#define CGAME_H_
#include "CGameControl.h"
#include "core/CGameControl.h"
#include "sdl/CSettings.h"
class CGame {
......
This diff is collapsed.
......@@ -17,8 +17,7 @@
CGameLauncher::CGameLauncher() {
m_mustquit = false;
m_hasbeenchosen = false;
m_chosenGame = 0;
m_chosenGame = -1;
mp_LaunchMenu = NULL;
m_ep1slot = -1;
}
......@@ -166,7 +165,6 @@ void CGameLauncher::process()
}
else
{
m_hasbeenchosen = true;
m_chosenGame = selection;
}
}
......
......@@ -47,10 +47,10 @@ public:
void process();
Uint8 retrievetEpisode(short chosengame);
unsigned char getChosengame(){ return m_chosenGame; }
bool setChosenGame(unsigned char chosengame) { m_chosenGame = chosengame; return (m_hasbeenchosen=true); }
bool waschosen(){ return m_hasbeenchosen; }
void letchooseagain() { m_hasbeenchosen=false; }
char getChosengame(){ return m_chosenGame; }
bool setChosenGame(unsigned char chosengame) { m_chosenGame = chosengame; return waschosen(); }
bool waschosen(){ return (m_chosenGame>=0); }
void letchooseagain() { m_chosenGame=-1; }
bool getQuit(){ return m_mustquit; }
std::string getDirectory(Uint8 slot) { return m_Entries.at(slot).path; }
......@@ -61,7 +61,6 @@ private:
bool m_mustquit;
short m_chosenGame;
bool m_hasbeenchosen;
Uint8 m_episode;
DirList m_DirList;
Sint8 m_ep1slot;
......
/*
* CGameControl.cpp
*
* Created on: 22.09.2009
* Author: gerstrong
*/
#include "CGameControl.h"
#include "CResourceLoader.h"
#include "fileio/CExeFile.h"
#include "fileio/CPatcher.h"
#include "fileio.h"
#include "CLogFile.h"
#include "sdl/sound/CSound.h"
#include "core/CGameLauncherMenu.h"
#include "core/CGamePassiveMode.h"
#include "core/CGamePlayMode.h"
#include "arguments.h"
#define SAFE_DELETE(x) if(x) { delete x; x = NULL; }
CGameControl::CGameControl(bool &firsttime) :
m_firsttime(firsttime),
m_show_finale(false),
m_episode(0)
{}
////
// Initialization Routine
////
bool CGameControl::init(int argc, char *argv[])
{
bool ok;
std::string argument;
argument = getArgument( argc, argv, "-game" );
mp_GameMode = new CGameLauncherMenu(m_firsttime, m_episode, m_Numplayers, m_Difficulty, m_DataDirectory);
ok = mp_GameMode->init();
// Check if some arguments were given.
/*if(argument != "")
{
// Get the game number according to the created menu list.
int chosengame = 0;
std::string buf = argument.substr(strlen("-game"));
chosengame = atoi(buf)-1;
if(chosengame >= 0)
{
// Tell the
mp_GameMode->mp_GameLauncher->setChosenGame(chosengame);
// Now check, if a level was also passed as parameter
argument = getArgument( argc, argv, "-level" );
buf = argument.substr(strlen("-level"));
//m_startLevel = atoi(buf);
//m_Numplayers = 1;
}
}*/
return ok;
}
////
// Process Routine
////
// This function is run every time, the Timer says so, through.
void CGameControl::process()
{
// process any triggered Game Control related event
CEventContainer& EventContainer = g_pBehaviorEngine->m_EventList;
if( ChangeMode* p_mode = EventContainer.occurredEvent<ChangeMode>() )
{
delete mp_GameMode;
if(p_mode->Mode == GM_GAMELAUNCHER)
{
mp_GameMode = new CGameLauncherMenu(m_firsttime, m_episode, m_Numplayers, m_Difficulty, m_DataDirectory);
}
else if(p_mode->Mode == GM_PASSIVE)
{
mp_GameMode = new CGamePassiveMode(m_episode, m_Numplayers, m_Difficulty, m_DataDirectory);
}
else if(p_mode->Mode == GM_PLAYGAME)
{
mp_GameMode = new CGamePlayMode(m_show_finale, m_episode, m_Numplayers, m_Difficulty, m_DataDirectory);
}
else if(p_mode->Mode == GM_QUIT)
{
mp_GameMode = NULL;
return;
}
mp_GameMode->init();
EventContainer.pop_Event();
}
// Process the game control object
mp_GameMode->process();
}
void CGameControl::cleanup()
{
delete mp_GameMode;
mp_GameMode = NULL;
}
CGameControl::~CGameControl() {
cleanup();
}
......@@ -17,63 +17,41 @@
#include "engine/CMessages.h"
#include "engine/CPassive.h"
#include "engine/playgame/CPlayGame.h"
#include "common/Menu/CProfilesMenu.h"
#include "core/CGameControl.h"
#include "core/CGameMode.h"
#include <string>
enum load_states{
LOADGFX=0x01,
LOADSTR=0x02,
LOADSND=0x04,
LOADALL=0xFF
};
#include <string>
class CGameControl {
public:
enum GameMode{
GAMELAUNCHER, PASSIVE, PLAYGAME, SHUTDOWN
};
CGameControl(bool &firsttime);
bool init(int argc, char *argv[]);
bool init(char mode=GAMELAUNCHER);
bool loadResources(Uint8 flags=LOADALL);
bool loadMenuResources();
//bool init();
void process();
void cleanup(char mode);
void cleanupAll();
void cleanup();
// getters and setters
bool mustShutdown(){ return (m_mode==SHUTDOWN); }
char m_mode;
bool mustShutdown(){ return (mp_GameMode==NULL); }
virtual ~CGameControl();
private:
CGameLauncher *mp_GameLauncher;
CPassive *mp_PassiveMode;
CPlayGame *mp_PlayGame;
CSavedGame m_SavedGame;
protected:
CGameMode *mp_GameMode;
bool &m_firsttime;
bool m_endgame;
bool m_show_finale;
Uint8 m_Episode;
Uint8 m_episode;
Uint8 m_Numplayers;
Uint8 m_ChosenGame;
Uint8 m_Difficulty;
std::string m_DataDirectory;
int current_demo;
Uint8 m_startLevel;
CEGAGraphics *m_EGAGraphics;
bool &m_firsttime;
CProfilesMenu *mp_FirstTimeMenu;
};
#endif /* CGAMECONTROL_H_ */
/*
* CGameLauncherMenu.cpp
*
* Created on: 26.03.2011
* Author: gerstrong
*/
#include "CGameLauncherMenu.h"
#include "CResourceLoader.h"
#include "fileio/CPatcher.h"
#include "engine/vorticon/CEGAGraphicsVort.h"
#include "engine/galaxy/CEGAGraphicsGalaxy.h"
#include "engine/CMessages.h"
#include "sdl/sound/CSound.h"
CGameLauncherMenu::CGameLauncherMenu(bool &firsttime, Uint8& Episode, Uint8& Numplayers,
Uint8& Difficulty, std::string& DataDirectory,
const int start_game_no, const int start_level) :
CGameMode(Episode, Numplayers, Difficulty, DataDirectory),
m_firsttime(firsttime),
mp_FirstTimeMenu(NULL),
m_start_game_no(start_game_no),
m_start_level(start_level)
{}
///
// Here the Resources for the menu are loaded. The file used here must exist in the directory
///
bool CGameLauncherMenu::loadMenuResources()
{
// Decode the entire graphics for the game (EGALATCH, EGASPRIT, etc.)
mp_EGAGraphics.tryDeleteData();
mp_EGAGraphics = new CEGAGraphics(0, "."); // It has to be the local data path where the interpreter is
if(!mp_EGAGraphics.get()) return false;
mp_EGAGraphics->loadData();
return true;
}
bool CGameLauncherMenu::init()
{
CEventContainer& EventContainer = g_pBehaviorEngine->m_EventList;
// If game was started for the first time, also open the firsttime dialog with configs.
if(m_firsttime)
{
m_firsttime = false;
mp_FirstTimeMenu = new CProfilesMenu(DLG_THEME_RED);
}
// Load the graphics for menu and background.
// Resources for the main menu
if(!loadMenuResources())
{
g_pLogFile->textOut(RED, "Sorry, but the basic for creating the menu is missing, please reinstall CG with all the data.<br>");
EventContainer.add( new ChangeMode(GM_QUIT) );
return false;
}
struct GamesScan: public Action
{
CGameLauncher*& mp_GameLauncher;
GamesScan(CGameLauncher*& p_GameLauncher) : mp_GameLauncher(p_GameLauncher) {};
int handle()
{
mp_GameLauncher = new CGameLauncher();
if(!mp_GameLauncher->init())
{
g_pLogFile->textOut(RED,"The game cannot start, because you are missing game data files.<br>");
return 0;
}
return 1;
}
};
const std::string threadname = "Scanning Game-Directory";
// He we start the thread for cycling the loading screen
g_pResourceLoader->setStyle(PROGRESS_STYLE_TEXT);
if(g_pResourceLoader->RunLoadAction(new GamesScan(mp_GameLauncher), threadname) == 0)
{
EventContainer.add( new ChangeMode(GM_QUIT) );
}
return true;
}
///
// This is used for loading all the resources of the game the use has chosen.
// It loads graphics, sound and text into the memory
///
bool CGameLauncherMenu::loadResources(const Uint8 flags)
{
int version;
unsigned char *p_exedata;
unsigned char *p_exeheader;
CExeFile &ExeFile = g_pBehaviorEngine->m_ExeFile;
m_SavedGame.setGameDirectory(m_DataDirectory);
m_SavedGame.setEpisode(m_Episode);
// TODO: not very readable. Check if there is a function for handling that.
if( m_DataDirectory.size() > 0 && m_DataDirectory[m_DataDirectory.size()-1] != '/' )
m_DataDirectory += "/";
version = ExeFile.getEXEVersion();
p_exedata = ExeFile.getRawData();
p_exeheader = ExeFile.getHeaderData();
g_pLogFile->ftextOut("Commander Keen Episode %d (Version %d.%d) was detected.<br>", m_Episode, version/100, version%100);
if( m_Episode == 1 && version == 134) g_pLogFile->ftextOut("This version of the game is not supported!<br>");
if(p_exeheader == NULL) {
g_pLogFile->textOut(RED, "CGameControl::loadResources: Could not load data from the EXE File<br>");
return false;
}
// Patch the EXE-File-Data directly in the memory.
CPatcher Patcher(ExeFile, g_pBehaviorEngine->m_is_a_mod);
Patcher.patchMemory();
g_pBehaviorEngine->setEpisode(m_Episode);
if( m_Episode == 1 || m_Episode == 2 || m_Episode == 3 ) // Vorticon resources
{
g_pBehaviorEngine->readTeleporterTable(p_exedata);
if( (flags & LOADGFX) == LOADGFX )
{
// Decode the entire graphics for the game (EGALATCH, EGASPRIT, etc.)
// This will also read the Tile-Properties
mp_EGAGraphics.tryDeleteData(); // except for the first start of a game this always happens
mp_EGAGraphics = new vorticon::CEGAGraphicsVort(m_Episode, m_DataDirectory);
if(!mp_EGAGraphics.get())
return false;
mp_EGAGraphics->loadData( version, p_exedata );
}
if( (flags & LOADSTR) == LOADSTR )
{
// load the strings.
CMessages Messages(p_exedata, m_Episode, version);
Messages.extractGlobalStrings();
}
if( (flags & LOADSND) == LOADSND )
{
// Load the sound data
g_pSound->loadSoundData(ExeFile);
}
g_pBehaviorEngine->getPhysicsSettings().loadGameConstants(m_Episode, p_exedata);
return true;
}
else if( m_Episode == 4 || m_Episode == 5 || m_Episode == 6 ) // Galaxy resources
{
// TODO: Lots of coding
if( (flags & LOADGFX) == LOADGFX )
{
// Decode the entire graphics for the game (Only EGAGRAPH.CK?)
mp_EGAGraphics.tryDeleteData();
mp_EGAGraphics = new galaxy::CEGAGraphicsGalaxy(ExeFile); // Path is relative to the data directory
if(!mp_EGAGraphics.get())
return false;
mp_EGAGraphics->loadData();
}
if( (flags & LOADSTR) == LOADSTR )
{
// load the strings.
// TODO:
}
if( (flags & LOADSND) == LOADSND )
{
// Load the sound data
g_pSound->loadSoundData(ExeFile);
}
}
return true;
}
void CGameLauncherMenu::process()
{
// If the firsttime menu is open, process it
if(mp_FirstTimeMenu)
{
mp_FirstTimeMenu->processCommon();
mp_FirstTimeMenu->processSpecific();
mp_FirstTimeMenu->postProcess();
if(mp_FirstTimeMenu->mustClose())
SAFE_DELETE(mp_FirstTimeMenu);
}
else
{
// Launch the code of the Startmenu here! The one for choosing the games
mp_GameLauncher->process();
m_start_game_no = mp_GameLauncher->getChosengame();
if( m_start_game_no >= 0 ) // Means a game has been selected
{
//// Game has been chosen. Launch it!
// Get the path were to Launch the game
m_DataDirectory = mp_GameLauncher->getDirectory( m_start_game_no );
// We have to check which Episode will be used
m_Episode = mp_GameLauncher->getEpisode( m_start_game_no );
if( m_Episode > 0 ) // The game has to have a valid episode!
{
// Get the EXE-Data of the game and load it into the memory.
if(!g_pBehaviorEngine->m_ExeFile.readData(m_Episode, m_DataDirectory))
{
mp_GameLauncher->letchooseagain();
delete mp_PassiveMode;
mp_PassiveMode = NULL;
}
else
{
// Load the Resources
if( loadResources() )
{
// Now look if there are any old savegames that need to be converted
CSavedGame savedgames;
savedgames.setGameDirectory(m_DataDirectory);
savedgames.setEpisode(m_Episode);
savedgames.convertAllOldFormats();
if(m_start_level == -1) // Starts normally
{
CEventContainer& EventContainer = g_pBehaviorEngine->m_EventList;
EventContainer.add( new ChangeMode(GM_PASSIVE) );
}
else // This happens, when a level was passed as argument when launching CG
{
CEventContainer& EventContainer = g_pBehaviorEngine->m_EventList;
EventContainer.add( new ChangeMode(GM_PLAYGAME) );
}
}
}
}
else
{
mp_GameLauncher->letchooseagain();
g_pLogFile->textOut(RED,"No Suitable game was detected in this path! Please check its contents!\n");
}
}
else if(mp_GameLauncher->getQuit())
{
// User chose "exit". So make CG quit...
CEventContainer& EventContainer = g_pBehaviorEngine->m_EventList;
EventContainer.add( new ChangeMode(GM_QUIT) );
}
}
}
/*
* CGameLauncherMenu.h
*
* Created on: 26.03.2011
* Author: gerstrong
*/
#ifndef CGAMELAUNCHERMENU_H_
#define CGAMELAUNCHERMENU_H_
#include "CGameMode.h"
#include "common/Menu/CProfilesMenu.h"
#include "SmartPointer.h"
enum load_states{
LOADGFX=0x01,
LOADSTR=0x02,
LOADSND=0x04,
LOADALL=0xFF
};
class CGameLauncherMenu : public CGameMode {
public:
CGameLauncherMenu(bool &firsttime, Uint8& Episode, Uint8& Numplayers,
Uint8& Difficulty, std::string& DataDirectory,
const int start_game_no = -1, const int start_level = -1);
bool loadMenuResources();
bool init();
bool loadResources(const Uint8 flags = LOADALL);
void process();
private:
bool &m_firsttime;
CProfilesMenu *mp_FirstTimeMenu;
int m_start_game_no;
int m_start_level;
SmartPointer<CEGAGraphics> mp_EGAGraphics;
};
#endif /* CGAMELAUNCHERMENU_H_ */
/*
* CGameMode.cpp
*
* Created on: 26.03.2011
* Author: gerstrong
*/
#include "CGameMode.h"
#include "engine/vorticon/CPassiveVort.h"
#include "engine/vorticon/CEGAGraphicsVort.h"
#include "engine/vorticon/CAudioVorticon.h"
#include "engine/vorticon/playgame/CPlayGameVorticon.h"
#include "engine/galaxy/CEGAGraphicsGalaxy.h"
#include "engine/galaxy/CPassive.h"
#include "engine/galaxy/CPlayGameGalaxy.h"
CGameMode::CGameMode(Uint8& Episode, Uint8& Numplayers,
Uint8& Difficulty, std::string& DataDirectory):
mp_GameLauncher(NULL),
mp_PassiveMode(NULL),
mp_PlayGame(NULL),
m_Episode(Episode),
m_Numplayers(Numplayers),
m_Difficulty(Difficulty),
m_DataDirectory(DataDirectory)
{
// TODO Auto-generated constructor stub
m_endgame = false;
}
CGameMode::~CGameMode() {
// TODO Auto-generated destructor stub
}
/*
* CGameMode.h
*
* Created on: 26.03.2011
* Author: gerstrong
*
* Base class responsible for controlling the CG Modes which are Launcher Menu, Passive and Play Mode
*/
#ifndef CGAMEMODE_H_
#define CGAMEMODE_H_
#include "engine/CEvent.h"
#include "common/CGameLauncher.h"
#include "engine/CPassive.h"
#include "engine/playgame/CPlayGame.h"
#include "engine/CEGAGraphics.h"
enum GameMode{
GM_GAMELAUNCHER, GM_PASSIVE, GM_PLAYGAME, GM_QUIT
};
struct ChangeMode : CEvent {
const GameMode Mode;
ChangeMode(const GameMode &l_Mode) : Mode(l_Mode){}
};
class CGameMode {
public:
CGameMode(Uint8& Episode, Uint8& Numplayers,
Uint8& Difficulty, std::string& DataDirectory);
virtual ~CGameMode();
virtual void process() = 0;
virtual bool init() = 0;
CGameLauncher *mp_GameLauncher;
CPassive *mp_PassiveMode;
CPlayGame *mp_PlayGame;
CSavedGame m_SavedGame;
bool m_endgame;
Uint8& m_Episode;
Uint8& m_Numplayers;
Uint8& m_Difficulty;
std::string& m_DataDirectory;
int current_demo;
};
#endif /* CGAMEMODE_H_ */
/*
* CGamePassiveMode.cpp
*
* Created on: 26.03.2011
* Author: gerstrong
*/
#include "CGamePassiveMode.h"
#include "sdl/sound/CSound.h"
#include "engine/vorticon/CPassiveVort.h"
#include "engine/galaxy/CPassive.h"
CGamePassiveMode::CGamePassiveMode(Uint8& episode, Uint8& Numplayers,
Uint8& Difficulty, std::string& DataDirectory) :
CGameMode(episode, Numplayers, Difficulty, DataDirectory)
{}
bool CGamePassiveMode::init()
{
CExeFile &ExeFile = g_pBehaviorEngine->m_ExeFile;
// Create mp_PassiveMode object used for the screens while Player is not playing
if(m_Episode >= 4)
mp_PassiveMode = new galaxy::CPassiveGalaxy( ExeFile, m_SavedGame, m_Difficulty );
else
mp_PassiveMode = new vorticon::CPassiveVort( ExeFile, m_SavedGame, m_Difficulty );
if( m_endgame == true )
{
m_endgame = false;
// TODO: Overload this function for galaxy
if( mp_PassiveMode->init(mp_PassiveMode->TITLE) ) return true;
}
else
{
if( mp_PassiveMode->init() ) return true;
}
CEventContainer& EventContainer = g_pBehaviorEngine->m_EventList;
EventContainer.add( new ChangeMode(GM_GAMELAUNCHER) );
return false;
}
void CGamePassiveMode::process()
{
CEventContainer& EventContainer = g_pBehaviorEngine->m_EventList;
if(mp_PlayGame != NULL)
{
if( mp_PlayGame->getEndGame() )
{
EventContainer.add( new ChangeMode(GM_PLAYGAME) );
}
}
mp_PassiveMode->process();
// check here what the player chose from the menu over the passive mode.
// NOTE: Demo is not part of playgame anymore!!
if(mp_PassiveMode->getchooseGame())
{
// TODO: Some of game resources are still not cleaned up here!
g_pSound->unloadSoundData();
EventContainer.add( new ChangeMode(GM_GAMELAUNCHER) );
return;
}
if(mp_PassiveMode->mustStartGame())
{
m_Episode = mp_PassiveMode->getEpisode();
m_Numplayers = mp_PassiveMode->getNumPlayers();
m_Difficulty = mp_PassiveMode->getDifficulty();