diff options
| -rw-r--r-- | engines/sword1/detection.cpp | 259 | ||||
| -rw-r--r-- | engines/sword1/module.mk | 1 | ||||
| -rw-r--r-- | engines/sword1/sword1.cpp | 240 | 
3 files changed, 262 insertions, 238 deletions
| diff --git a/engines/sword1/detection.cpp b/engines/sword1/detection.cpp new file mode 100644 index 0000000000..3d8f12db34 --- /dev/null +++ b/engines/sword1/detection.cpp @@ -0,0 +1,259 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "sword1/sword1.h" + +#include "base/plugins.h" +#include "common/config-manager.h" +#include "common/file.h" +#include "common/fs.h" +#include "common/savefile.h" + +#include "engines/metaengine.h" + +/* Broken Sword 1 */ +static const PlainGameDescriptor sword1FullSettings = +	{"sword1", "Broken Sword 1: The Shadow of the Templars"}; +static const PlainGameDescriptor sword1DemoSettings = +	{"sword1demo", "Broken Sword 1: The Shadow of the Templars (Demo)"}; +static const PlainGameDescriptor sword1MacFullSettings = +	{"sword1mac", "Broken Sword 1: The Shadow of the Templars (Mac)"}; +static const PlainGameDescriptor sword1MacDemoSettings = +	{"sword1macdemo", "Broken Sword 1: The Shadow of the Templars (Mac demo)"}; + +// check these subdirectories (if present) +static const char *g_dirNames[] = {	"clusters",	"speech" }; + +#define NUM_COMMON_FILES_TO_CHECK 1 +#define NUM_PC_FILES_TO_CHECK 3 +#define NUM_MAC_FILES_TO_CHECK 4 +#define NUM_DEMO_FILES_TO_CHECK 1 +#define NUM_MAC_DEMO_FILES_TO_CHECK 1 +#define NUM_FILES_TO_CHECK NUM_COMMON_FILES_TO_CHECK + NUM_PC_FILES_TO_CHECK + NUM_MAC_FILES_TO_CHECK + NUM_DEMO_FILES_TO_CHECK + NUM_MAC_DEMO_FILES_TO_CHECK +static const char *g_filesToCheck[NUM_FILES_TO_CHECK] = { // these files have to be found +	"swordres.rif", // Mac and PC version +	"general.clu", // PC version only +	"compacts.clu", // PC version only +	"scripts.clu", // PC version only +	"general.clm", // Mac version only +	"compacts.clm", // Mac version only +	"scripts.clm", // Mac version only +	"paris2.clm", // Mac version (full game only) +	"cows.mad",	// this one should only exist in the demo version +	"scripts.clm", // Mac version both demo and full game +	// the engine needs several more files to work, but checking these should be sufficient +}; + +class SwordMetaEngine : public MetaEngine { +public: +	virtual const char *getName() const { +		return "Broken Sword"; +	} +	virtual const char *getCopyright() const { +		return "Broken Sword Games (C) Revolution"; +	} + +	virtual bool hasFeature(MetaEngineFeature f) const; +	virtual GameList getSupportedGames() const; +	virtual GameDescriptor findGame(const char *gameid) const; +	virtual GameList detectGames(const Common::FSList &fslist) const; +	virtual SaveStateList listSaves(const char *target) const; +	virtual int getMaximumSaveSlot() const; + +	virtual Common::Error createInstance(OSystem *syst, Engine **engine) const; +}; + +bool SwordMetaEngine::hasFeature(MetaEngineFeature f) const { +	return +		(f == kSupportsListSaves) || +		(f == kSupportsLoadingDuringStartup); +} + +bool Sword1::SwordEngine::hasFeature(EngineFeature f) const { +	return +		(f == kSupportsRTL); +} + +GameList SwordMetaEngine::getSupportedGames() const { +	GameList games; +	games.push_back(sword1FullSettings); +	games.push_back(sword1DemoSettings); +	games.push_back(sword1MacFullSettings); +	games.push_back(sword1MacDemoSettings); +	return games; +} + +GameDescriptor SwordMetaEngine::findGame(const char *gameid) const { +	if (0 == scumm_stricmp(gameid, sword1FullSettings.gameid)) +		return sword1FullSettings; +	if (0 == scumm_stricmp(gameid, sword1DemoSettings.gameid)) +		return sword1DemoSettings; +	if (0 == scumm_stricmp(gameid, sword1MacFullSettings.gameid)) +		return sword1MacFullSettings; +	if (0 == scumm_stricmp(gameid, sword1MacDemoSettings.gameid)) +		return sword1MacDemoSettings; +	return GameDescriptor(); +} + +void Sword1CheckDirectory(const Common::FSList &fslist, bool *filesFound) { +	for (Common::FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) { +		if (!file->isDirectory()) { +			const char *fileName = file->getName().c_str(); +			for (int cnt = 0; cnt < NUM_FILES_TO_CHECK; cnt++) +				if (scumm_stricmp(fileName, g_filesToCheck[cnt]) == 0) +					filesFound[cnt] = true; +		} else { +			for (int cnt = 0; cnt < ARRAYSIZE(g_dirNames); cnt++) +				if (scumm_stricmp(file->getName().c_str(), g_dirNames[cnt]) == 0) { +					Common::FSList fslist2; +					if (file->getChildren(fslist2, Common::FSNode::kListFilesOnly)) +						Sword1CheckDirectory(fslist2, filesFound); +				} +		} +	} +} + +GameList SwordMetaEngine::detectGames(const Common::FSList &fslist) const { +	int i, j; +	GameList detectedGames; +	bool filesFound[NUM_FILES_TO_CHECK]; +	for (i = 0; i < NUM_FILES_TO_CHECK; i++) +		filesFound[i] = false; + +	Sword1CheckDirectory(fslist, filesFound); +	bool mainFilesFound = true; +	bool pcFilesFound = true; +	bool macFilesFound = true; +	bool demoFilesFound = true; +	bool macDemoFilesFound = true; +	for (i = 0; i < NUM_COMMON_FILES_TO_CHECK; i++) +		if (!filesFound[i]) +			mainFilesFound = false; +	for (j = 0; j < NUM_PC_FILES_TO_CHECK; i++, j++) +		if (!filesFound[i]) +			pcFilesFound = false; +	for (j = 0; j < NUM_MAC_FILES_TO_CHECK; i++, j++) +		if (!filesFound[i]) +			macFilesFound = false; +	for (j = 0; j < NUM_DEMO_FILES_TO_CHECK; i++, j++) +		if (!filesFound[i]) +			demoFilesFound = false; +	for (j = 0; j < NUM_DEMO_FILES_TO_CHECK; i++, j++) +		if (!filesFound[i]) +			macDemoFilesFound = false; + +	if (mainFilesFound && pcFilesFound && demoFilesFound) +		detectedGames.push_back(sword1DemoSettings); +	else if (mainFilesFound && pcFilesFound) +		detectedGames.push_back(sword1FullSettings); +	else if (mainFilesFound && macFilesFound) +		detectedGames.push_back(sword1MacFullSettings); +	else if (mainFilesFound && macDemoFilesFound) +		detectedGames.push_back(sword1MacDemoSettings); + +	return detectedGames; +} + +Common::Error SwordMetaEngine::createInstance(OSystem *syst, Engine **engine) const { +	assert(engine); +	*engine = new Sword1::SwordEngine(syst); +	return Common::kNoError; +} + +SaveStateList SwordMetaEngine::listSaves(const char *target) const { +	Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); +	SaveStateList saveList; + +	Common::String pattern = "SAVEGAME.???"; +	Common::StringList filenames = saveFileMan->listSavefiles(pattern.c_str()); +	sort(filenames.begin(), filenames.end()); +	Common::StringList::const_iterator file = filenames.begin(); + +	Common::InSaveFile *in = saveFileMan->openForLoading("SAVEGAME.INF"); + +	if (in) { +		Common::Array<uint32> offsets; +		uint8 stop = 0; +		int slotsInFile = 0; + +		// Find the offset for each savegame name in the file. +		while (stop != 255 && !in->eos()) { +			offsets.push_back(in->pos()); +			slotsInFile++; +			stop = 0; +			while (stop != 10 && stop != 255 && !in->eos()) +				stop = in->readByte(); +		} + +		// Match the savegames to the save slot names. +		while (file != filenames.end()) { +			char saveDesc[32]; + +			if (file->compareToIgnoreCase("SAVEGAME.INF") == 0) { +				file++; +				continue; +			} +			 +			// Obtain the last 3 digits of the filename, since they correspond to the save slot +			int slotNum = atoi(file->c_str() + file->size() - 3); + +			if (slotNum >= 0 && slotNum < slotsInFile) { +				in->seek(offsets[slotNum]); + +				uint pos = 0; +				do { +					stop = in->readByte(); +					if (pos < sizeof(saveDesc) - 1) { +						if (stop == 10 || stop == 255 || in->eos()) +							saveDesc[pos++] = '\0'; +						else if (stop >= 32) +							saveDesc[pos++] = stop; +					} +				} while (stop != 10 && stop != 255 && !in->eos()); +			} + +			if (saveDesc[0] == 0) +				strcpy(saveDesc, "Unnamed savegame"); + +			// FIXME: The in-game dialog shows the first save slot as 1, not 0, +			// but if we change the numbering here, the launcher won?t set +			// "save_slot" correctly. +			saveList.push_back(SaveStateDescriptor(slotNum, saveDesc)); +			file++; +		} +	} + +	delete in; + +	return saveList; +} + +int SwordMetaEngine::getMaximumSaveSlot() const { return 999; } + +#if PLUGIN_ENABLED_DYNAMIC(SWORD1) +	REGISTER_PLUGIN_DYNAMIC(SWORD1, PLUGIN_TYPE_ENGINE, SwordMetaEngine); +#else +	REGISTER_PLUGIN_STATIC(SWORD1, PLUGIN_TYPE_ENGINE, SwordMetaEngine); +#endif diff --git a/engines/sword1/module.mk b/engines/sword1/module.mk index 87c0061c3c..f101be6cef 100644 --- a/engines/sword1/module.mk +++ b/engines/sword1/module.mk @@ -5,6 +5,7 @@ MODULE_OBJS := \  	control.o \  	credits.o \  	debug.o \ +	detection.o \  	eventman.o \  	logic.o \  	memman.o \ diff --git a/engines/sword1/sword1.cpp b/engines/sword1/sword1.cpp index 2ba59c0f18..504b2ce92d 100644 --- a/engines/sword1/sword1.cpp +++ b/engines/sword1/sword1.cpp @@ -25,17 +25,6 @@  #include "sword1/sword1.h" -#include "base/plugins.h" -#include "common/config-manager.h" -#include "common/file.h" -#include "common/fs.h" -#include "common/timer.h" -#include "common/events.h" -#include "common/savefile.h" -#include "common/system.h" - -#include "engines/metaengine.h" -  #include "sword1/resman.h"  #include "sword1/objectman.h"  #include "sword1/mouse.h" @@ -47,236 +36,11 @@  #include "sword1/music.h"  #include "sword1/control.h" +#include "common/config-manager.h" +  #include "gui/message.h"  #include "gui/newgui.h" -using namespace Sword1; - -/* Broken Sword 1 */ -static const PlainGameDescriptor sword1FullSettings = -	{"sword1", "Broken Sword 1: The Shadow of the Templars"}; -static const PlainGameDescriptor sword1DemoSettings = -	{"sword1demo", "Broken Sword 1: The Shadow of the Templars (Demo)"}; -static const PlainGameDescriptor sword1MacFullSettings = -	{"sword1mac", "Broken Sword 1: The Shadow of the Templars (Mac)"}; -static const PlainGameDescriptor sword1MacDemoSettings = -	{"sword1macdemo", "Broken Sword 1: The Shadow of the Templars (Mac demo)"}; - -// check these subdirectories (if present) -static const char *g_dirNames[] = {	"clusters",	"speech" }; - -#define NUM_COMMON_FILES_TO_CHECK 1 -#define NUM_PC_FILES_TO_CHECK 3 -#define NUM_MAC_FILES_TO_CHECK 4 -#define NUM_DEMO_FILES_TO_CHECK 1 -#define NUM_MAC_DEMO_FILES_TO_CHECK 1 -#define NUM_FILES_TO_CHECK NUM_COMMON_FILES_TO_CHECK + NUM_PC_FILES_TO_CHECK + NUM_MAC_FILES_TO_CHECK + NUM_DEMO_FILES_TO_CHECK + NUM_MAC_DEMO_FILES_TO_CHECK -static const char *g_filesToCheck[NUM_FILES_TO_CHECK] = { // these files have to be found -	"swordres.rif", // Mac and PC version -	"general.clu", // PC version only -	"compacts.clu", // PC version only -	"scripts.clu", // PC version only -	"general.clm", // Mac version only -	"compacts.clm", // Mac version only -	"scripts.clm", // Mac version only -	"paris2.clm", // Mac version (full game only) -	"cows.mad",	// this one should only exist in the demo version -	"scripts.clm", // Mac version both demo and full game -	// the engine needs several more files to work, but checking these should be sufficient -}; - -class SwordMetaEngine : public MetaEngine { -public: -	virtual const char *getName() const { -		return "Broken Sword"; -	} -	virtual const char *getCopyright() const { -		return "Broken Sword Games (C) Revolution"; -	} - -	virtual bool hasFeature(MetaEngineFeature f) const; -	virtual GameList getSupportedGames() const; -	virtual GameDescriptor findGame(const char *gameid) const; -	virtual GameList detectGames(const Common::FSList &fslist) const; -	virtual SaveStateList listSaves(const char *target) const; -	virtual int getMaximumSaveSlot() const; - -	virtual Common::Error createInstance(OSystem *syst, Engine **engine) const; -}; - -bool SwordMetaEngine::hasFeature(MetaEngineFeature f) const { -	return -		(f == kSupportsListSaves) || -		(f == kSupportsLoadingDuringStartup); -} - -bool Sword1::SwordEngine::hasFeature(EngineFeature f) const { -	return -		(f == kSupportsRTL); -} - -GameList SwordMetaEngine::getSupportedGames() const { -	GameList games; -	games.push_back(sword1FullSettings); -	games.push_back(sword1DemoSettings); -	games.push_back(sword1MacFullSettings); -	games.push_back(sword1MacDemoSettings); -	return games; -} - -GameDescriptor SwordMetaEngine::findGame(const char *gameid) const { -	if (0 == scumm_stricmp(gameid, sword1FullSettings.gameid)) -		return sword1FullSettings; -	if (0 == scumm_stricmp(gameid, sword1DemoSettings.gameid)) -		return sword1DemoSettings; -	if (0 == scumm_stricmp(gameid, sword1MacFullSettings.gameid)) -		return sword1MacFullSettings; -	if (0 == scumm_stricmp(gameid, sword1MacDemoSettings.gameid)) -		return sword1MacDemoSettings; -	return GameDescriptor(); -} - -void Sword1CheckDirectory(const Common::FSList &fslist, bool *filesFound) { -	for (Common::FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) { -		if (!file->isDirectory()) { -			const char *fileName = file->getName().c_str(); -			for (int cnt = 0; cnt < NUM_FILES_TO_CHECK; cnt++) -				if (scumm_stricmp(fileName, g_filesToCheck[cnt]) == 0) -					filesFound[cnt] = true; -		} else { -			for (int cnt = 0; cnt < ARRAYSIZE(g_dirNames); cnt++) -				if (scumm_stricmp(file->getName().c_str(), g_dirNames[cnt]) == 0) { -					Common::FSList fslist2; -					if (file->getChildren(fslist2, Common::FSNode::kListFilesOnly)) -						Sword1CheckDirectory(fslist2, filesFound); -				} -		} -	} -} - -GameList SwordMetaEngine::detectGames(const Common::FSList &fslist) const { -	int i, j; -	GameList detectedGames; -	bool filesFound[NUM_FILES_TO_CHECK]; -	for (i = 0; i < NUM_FILES_TO_CHECK; i++) -		filesFound[i] = false; - -	Sword1CheckDirectory(fslist, filesFound); -	bool mainFilesFound = true; -	bool pcFilesFound = true; -	bool macFilesFound = true; -	bool demoFilesFound = true; -	bool macDemoFilesFound = true; -	for (i = 0; i < NUM_COMMON_FILES_TO_CHECK; i++) -		if (!filesFound[i]) -			mainFilesFound = false; -	for (j = 0; j < NUM_PC_FILES_TO_CHECK; i++, j++) -		if (!filesFound[i]) -			pcFilesFound = false; -	for (j = 0; j < NUM_MAC_FILES_TO_CHECK; i++, j++) -		if (!filesFound[i]) -			macFilesFound = false; -	for (j = 0; j < NUM_DEMO_FILES_TO_CHECK; i++, j++) -		if (!filesFound[i]) -			demoFilesFound = false; -	for (j = 0; j < NUM_DEMO_FILES_TO_CHECK; i++, j++) -		if (!filesFound[i]) -			macDemoFilesFound = false; - -	if (mainFilesFound && pcFilesFound && demoFilesFound) -		detectedGames.push_back(sword1DemoSettings); -	else if (mainFilesFound && pcFilesFound) -		detectedGames.push_back(sword1FullSettings); -	else if (mainFilesFound && macFilesFound) -		detectedGames.push_back(sword1MacFullSettings); -	else if (mainFilesFound && macDemoFilesFound) -		detectedGames.push_back(sword1MacDemoSettings); - -	return detectedGames; -} - -Common::Error SwordMetaEngine::createInstance(OSystem *syst, Engine **engine) const { -	assert(engine); -	*engine = new SwordEngine(syst); -	return Common::kNoError; -} - -SaveStateList SwordMetaEngine::listSaves(const char *target) const { -	Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); -	SaveStateList saveList; - -	Common::String pattern = "SAVEGAME.???"; -	Common::StringList filenames = saveFileMan->listSavefiles(pattern.c_str()); -	sort(filenames.begin(), filenames.end()); -	Common::StringList::const_iterator file = filenames.begin(); - -	Common::InSaveFile *in = saveFileMan->openForLoading("SAVEGAME.INF"); - -	if (in) { -		Common::Array<uint32> offsets; -		uint8 stop = 0; -		int slotsInFile = 0; - -		// Find the offset for each savegame name in the file. -		while (stop != 255 && !in->eos()) { -			offsets.push_back(in->pos()); -			slotsInFile++; -			stop = 0; -			while (stop != 10 && stop != 255 && !in->eos()) -				stop = in->readByte(); -		} - -		// Match the savegames to the save slot names. -		while (file != filenames.end()) { -			char saveDesc[32]; - -			if (file->compareToIgnoreCase("SAVEGAME.INF") == 0) { -				file++; -				continue; -			} -			 -			// Obtain the last 3 digits of the filename, since they correspond to the save slot -			int slotNum = atoi(file->c_str() + file->size() - 3); - -			if (slotNum >= 0 && slotNum < slotsInFile) { -				in->seek(offsets[slotNum]); - -				uint pos = 0; -				do { -					stop = in->readByte(); -					if (pos < sizeof(saveDesc) - 1) { -						if (stop == 10 || stop == 255 || in->eos()) -							saveDesc[pos++] = '\0'; -						else if (stop >= 32) -							saveDesc[pos++] = stop; -					} -				} while (stop != 10 && stop != 255 && !in->eos()); -			} - -			if (saveDesc[0] == 0) -				strcpy(saveDesc, "Unnamed savegame"); - -			// FIXME: The in-game dialog shows the first save slot as 1, not 0, -			// but if we change the numbering here, the launcher won̈́t set -			// "save_slot" correctly. -			saveList.push_back(SaveStateDescriptor(slotNum, saveDesc)); -			file++; -		} -	} - -	delete in; - -	return saveList; -} - -int SwordMetaEngine::getMaximumSaveSlot() const { return 999; } - -#if PLUGIN_ENABLED_DYNAMIC(SWORD1) -	REGISTER_PLUGIN_DYNAMIC(SWORD1, PLUGIN_TYPE_ENGINE, SwordMetaEngine); -#else -	REGISTER_PLUGIN_STATIC(SWORD1, PLUGIN_TYPE_ENGINE, SwordMetaEngine); -#endif -  namespace Sword1 {  SystemVars SwordEngine::_systemVars; | 
