Open main menu

Difference between revisions of "HOWTO-Engines"

127 bytes added ,  00:41, 25 November 2009
Update quux example to work again in latest SVN
(Added link to truecolor API reference.)
(Update quux example to work again in latest SVN)
Line 108: Line 108:
#ifndef QUUX_H
#ifndef QUUX_H
#define QUUX_H
#define QUUX_H
 
#include "engines/engine.h"
#include "engines/engine.h"
#include "gui/debugger.h"
#include "gui/debugger.h"
 
namespace Quux {
namespace Quux {
 
class Console;
class Console;
 
// our engine debug levels
// our engine debug levels
enum {
enum {
Line 123: Line 123:
// the current limitation is 32 debug levels (1 << 31 is the last one)
// the current limitation is 32 debug levels (1 << 31 is the last one)
};
};
 
class QuuxEngine : public Engine {
class QuuxEngine : public Engine {
public:
public:
QuuxEngine(OSystem *syst);
QuuxEngine(OSystem *syst);
~QuuxEngine();
~QuuxEngine();
 
virtual int init();
virtual Common::Error run();
virtual int go();
 
private:
private:
Console *_console;
Console *_console;
 
// We need random numbers
// We need random numbers
Common::RandomSource _rnd;
Common::RandomSource _rnd;
};
};
 
// Example console class
// Example console class
class Console : public GUI::Debugger {
class Console : public GUI::Debugger {
public:
public:
Console(QuuxEngine *vm);
Console(QuuxEngine *vm) {}
virtual ~Console(void);
virtual ~Console(void) {}
};
};
 
} // End of namespace Quux
} // End of namespace Quux
 
#endif
#endif
</syntax>
</syntax>
Line 154: Line 153:
<syntax type="C++">
<syntax type="C++">
#include "common/scummsys.h"
#include "common/scummsys.h"
 
#include "common/events.h" // for getEventManager()
#include "common/config-manager.h"
#include "common/config-manager.h"
#include "common/debug.h"
#include "common/EventRecorder.h"
#include "common/file.h"
#include "common/file.h"
#include "common/fs.h"
#include "common/fs.h"
 
#include "quux/quux.h"
#include "quux/quux.h"
 
namespace Quux {
namespace Quux {
 
QuuxEngine::QuuxEngine(OSystem *syst)  
QuuxEngine::QuuxEngine(OSystem *syst)  
  : Engine(syst) {
  : Engine(syst) {
Line 169: Line 169:
// in particular, do not load data from files; rather, if you
// in particular, do not load data from files; rather, if you
// need to do such things, do them from init().
// need to do such things, do them from init().
 
// Do not initialize graphics here
// Do not initialize graphics here
 
// However this is the place to specify all default directories
// However this is the place to specify all default directories
Common::File::addDefaultDirectory(_gameDataPath + "sound/");
SearchMan.addSubDirectoryMatching(_gameDataDir, "sound");
 
// Here is the right place to set up the engine specific debug levels
// Here is the right place to set up the engine specific debug levels
Common::addSpecialDebugLevel(kQuuxDebugExample, "example", "this is just an example for a engine specific debug level");
Common::addDebugChannel(kQuuxDebugExample, "example", "this is just an example for a engine specific debug level");
Common::addSpecialDebugLevel(kQuuxDebugExample2, "example2", "also an example");
Common::addDebugChannel(kQuuxDebugExample2, "example2", "also an example");
 
// Don't forget to register your random source
// Don't forget to register your random source
_eventMan->registerRandomSource(_rnd, "quux");
g_eventRec.registerRandomSource(_rnd, "quux");
 
printf("QuuxEngine::QuuxEngine\n");
printf("QuuxEngine::QuuxEngine\n");
}
}
 
QuuxEngine::~QuuxEngine() {
QuuxEngine::~QuuxEngine() {
// Dispose your resources here
// Dispose your resources here
printf("QuuxEngine::~QuuxEngine\n");
printf("QuuxEngine::~QuuxEngine\n");
 
// Remove all of our debug levels here
// Remove all of our debug levels here
Common::clearAllSpecialDebugLevels();
Common::clearAllDebugChannels();
}
}
 
int QuuxEngine::init() {
Common::Error QuuxEngine::run() {
// Initialize graphics using following:
// Initialize graphics using following:
initGraphics(320, 200, false);
initGraphics(320, 200, false);
 
// You could use backend transactions directly as an alternative,
// You could use backend transactions directly as an alternative,
// but it isn't recommended, until you want to handle the error values
// but it isn't recommended, until you want to handle the error values
Line 211: Line 211:
//OSystem::kTransactionSizeChangeFailed here
//OSystem::kTransactionSizeChangeFailed here
//_system->endGFXTransaction();
//_system->endGFXTransaction();
// Create debugger console. It requires GFX to be initialized
// Create debugger console. It requires GFX to be initialized
_console = new Console(this);
_console = new Console(this);
 
// Additional setup.
// Additional setup.
printf("QuuxEngine::init\n");
printf("QuuxEngine::init\n");
return 0;
}


int QuuxEngine::go() {
// Your main even loop should be (invoked from) here.
// Your main even loop should be (invoked from) here.
printf("QuuxEngine::go: Hello, World!\n");
printf("QuuxEngine::go: Hello, World!\n");
 
// This test will show up if -d1 and --debugflags=example are specified on the commandline
// This test will show up if -d1 and --debugflags=example are specified on the commandline
debugC(1, kQuuxDebugExample, "Example debug call");
debugC(1, kQuuxDebugExample, "Example debug call");
 
// This test will show up if --debugflags=example or --debugflags=example2 or both of them and -d3 are specified on the commandline
// This test will show up if --debugflags=example or --debugflags=example2 or both of them and -d3 are specified on the commandline
debugC(3, kQuuxDebugExample | kQuuxDebugExample2, "Example debug call two");
debugC(3, kQuuxDebugExample | kQuuxDebugExample2, "Example debug call two");
 
return 0;
return Common::kNoError;
}
}
 
} // End of namespace Quux
} // End of namespace Quux
</syntax>
</syntax>
Line 240: Line 237:
<syntax type="C++">
<syntax type="C++">
#include "quux/quux.h"
#include "quux/quux.h"
#include "common/config-manager.h"
#include "common/error.h"
#include "common/fs.h"


#include "base/game.h"
#include "base/plugins.h"
#include "engines/metaengine.h"
#include "engines/metaengine.h"
 
static const PlainGameDescriptor quux_setting[] = {
static const PlainGameDescriptor quux_setting[] = {
{ "quux", "Quux the Example Module" },
{ "quux", "Quux the Example Module" },
Line 250: Line 249:
{ 0, 0 }
{ 0, 0 }
};
};
 
class QuuxMetaEngine : public MetaEngine {
class QuuxMetaEngine : public MetaEngine {
public:
public:
Line 256: Line 255:
return "Quux the Example Module";
return "Quux the Example Module";
}
}
 
virtual const char *getCopyright() const {
virtual const char *getOriginalCopyright() const {
return "Copyright (C) Quux Entertainment Ltd.";
return "Copyright (C) Quux Entertainment Ltd.";
}
}
 
virtual GameList getSupportedGames() const {
virtual GameList getSupportedGames() const {
GameList games;
GameList games;
Line 268: Line 267:
g++;
g++;
}
}
return games;
return games;
}
}
 
virtual GameDescriptor findGame(const char *gameid) const {
virtual GameDescriptor findGame(const char *gameid) const {
const PlainGameDescriptor *g = quux_setting;
const PlainGameDescriptor *g = quux_setting;
Line 281: Line 280:
return GameDescriptor(g->gameid, g->description);
return GameDescriptor(g->gameid, g->description);
}
}
 
virtual GameList detectGames(const FSList &fslist) const {
virtual GameList detectGames(const Common::FSList &fslist) const {
GameList detectedGames;
GameList detectedGames;
// Iterate over all files in the given directory
// Iterate over all files in the given directory
for (FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
for (Common::FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
if (!file->isDirectory()) {
if (!file->isDirectory()) {
const char *gameName = file->getName().c_str();
const char *gameName = file->getName().c_str();
if (0 == scumm_stricmp("README", gameName)) {
if (0 == scumm_stricmp("README", gameName)) {
// You could check the contents of the file now if you need to.
// You could check the contents of the file now if you need to.
Line 299: Line 298:
return detectedGames;
return detectedGames;
}
}
 
virtual PluginError createInstance(OSystem *syst, Engine **engine) const {
virtual Common::Error createInstance(OSystem *syst, Engine **engine) const {
assert(syst);
assert(syst);
assert(engine);
assert(engine);
 
// Scan the target directory for files (error out if it does not exist)
// Scan the target directory for files (error out if it does not exist)
FSList fslist;
Common::FSList fslist;
FilesystemNode dir(ConfMan.get("path"));
Common::FSNode dir(ConfMan.get("path"));
if (!dir.getChildren(fslist, FilesystemNode::kListAll)) {
if (!dir.getChildren(fslist, Common::FSNode::kListAll)) {
return kInvalidPathError;
return Common::kInvalidPathError;
}
}
 
// Invoke the detector
// Invoke the detector
Common::String gameid = ConfMan.get("gameid");
Common::String gameid = ConfMan.get("gameid");
GameList detectedGames = detectGames(fslist);
GameList detectedGames = detectGames(fslist);
 
for (uint i = 0; i < detectedGames.size(); i++) {
for (uint i = 0; i < detectedGames.size(); i++) {
if (detectedGames[i].gameid() == gameid) {
if (detectedGames[i].gameid() == gameid) {
// At this point you may want to perform additional sanity checks.
// At this point you may want to perform additional sanity checks.
*engine = new Quux::QuuxEngine(syst);
*engine = new Quux::QuuxEngine(syst);
return kNoError;
return Common::kNoError;
}
}
}
}
 
// Failed to find any game data
// Failed to find any game data
return kNoGameDataFoundError;
return Common::kNoGameDataFoundError;
}
}
};
};
 
#if PLUGIN_ENABLED_DYNAMIC(QUUX)
#if PLUGIN_ENABLED_DYNAMIC(QUUX)
REGISTER_PLUGIN_DYNAMIC(QUUX, PLUGIN_TYPE_ENGINE, QuuxMetaEngine);
REGISTER_PLUGIN_DYNAMIC(QUUX, PLUGIN_TYPE_ENGINE, QuuxMetaEngine);
Line 338: Line 337:
<syntax type="C++">
<syntax type="C++">
MODULE := engines/quux
MODULE := engines/quux
 
MODULE_OBJS := \
MODULE_OBJS := \
detection.o \
quux.o
quux.o
 
MODULE_DIRS += \
MODULE_DIRS += \
engines/quux
engines/quux
 
# This module can be built as a plugin
# This module can be built as a plugin
ifeq ($(ENABLE_QUUX), DYNAMIC_PLUGIN)
ifeq ($(ENABLE_QUUX), DYNAMIC_PLUGIN)
PLUGIN := 1
PLUGIN := 1
endif
endif
 
# Include common rules  
# Include common rules  
include $(srcdir)/rules.mk
include $(srcdir)/rules.mk
</syntax>
</syntax>
1,079

edits