diff options
Diffstat (limited to 'engines/drascula/detection.cpp')
| -rw-r--r-- | engines/drascula/detection.cpp | 305 | 
1 files changed, 192 insertions, 113 deletions
| diff --git a/engines/drascula/detection.cpp b/engines/drascula/detection.cpp index 760d8b7d98..1917bc879d 100644 --- a/engines/drascula/detection.cpp +++ b/engines/drascula/detection.cpp @@ -21,10 +21,13 @@   */  #include "base/plugins.h" +#include "common/file.h" +#include "common/translation.h"  #include "engines/advancedDetector.h"  #include "engines/savestate.h" -#include "common/file.h" + +#include "graphics/thumbnail.h"  #include "drascula/drascula.h" @@ -65,34 +68,58 @@ static const PlainGameDescriptor drasculaGames[] = {  namespace Drascula {  static const DrasculaGameDescription gameDescriptions[] = { + +	//// Packed versions ////////////////////////////////////////////////////// +  	{ -		// Drascula English version +		// Drascula English version (original packed files)  		{  			"drascula",  			0, -			AD_ENTRY1s("14.ald", "09b2735953edcd43af115c65ae00b10e", 1595), +			{ +				{"packet.001", 0, "c6a8697396e213a18472542d5f547cb4", 32847563}, +				// HACK: List packet.001 twice to ensure this detector entry +				// is ranked just as high as the others (which each have two +				// detection files). +				{"packet.001", 0, "c6a8697396e213a18472542d5f547cb4", 32847563}, +				{NULL, 0, NULL, 0} +			},  			Common::EN_ANY, -			Common::kPlatformPC, -			ADGF_NO_FLAGS, +			Common::kPlatformDOS, +			GF_PACKED,  			GUIO0()  		},  	},  	{ -		// Drascula English version (original packed files) +		// Drascula French version (original packed files)  		{  			"drascula",  			0,  			{  				{"packet.001", 0, "c6a8697396e213a18472542d5f547cb4", 32847563}, -				// HACK: List packet.001 twice to ensure this detector entry -				// is ranked just as high as the others (which each have two -				// detection files). +				{"packet.002", 1, "4401123400f22f212b89f15fb4b43013", 721122}, +				{NULL, 0, NULL, 0} +			}, +			Common::FR_FRA, +			Common::kPlatformDOS, +			GF_PACKED, +			GUIO0() +		}, +	}, + +	{ +		// Drascula French version (ScummVM repacked files) +		{ +			"drascula", +			0, +			{  				{"packet.001", 0, "c6a8697396e213a18472542d5f547cb4", 32847563}, +				{"packet.002", 1, "7b83cedb9bb326ed5143e5c459508d43", 722383},  				{NULL, 0, NULL, 0}  			}, -			Common::EN_ANY, -			Common::kPlatformPC, +			Common::FR_FRA, +			Common::kPlatformDOS,  			GF_PACKED,  			GUIO0()  		}, @@ -109,24 +136,37 @@ static const DrasculaGameDescription gameDescriptions[] = {  				{NULL, 0, NULL, 0}  			},  			Common::DE_DEU, -			Common::kPlatformPC, +			Common::kPlatformDOS,  			GF_PACKED,  			GUIO0()  		},  	},  	{ -		// Drascula French version (original packed files) +		// Drascula Italian version (original packed version) +		{ +			"drascula", +			0, +			AD_ENTRY1s("packet.001", "0253e924af223f5fe52537023385159b", 32564209), +			Common::IT_ITA, +			Common::kPlatformDOS, +			GF_PACKED, +			GUIO0() +		}, +	}, + +	{ +		// Drascula Italian version (ScummVM repacked files)  		{  			"drascula",  			0,  			{  				{"packet.001", 0, "c6a8697396e213a18472542d5f547cb4", 32847563}, -				{"packet.002", 1, "4401123400f22f212b89f15fb4b43013", 721122}, +				{"packet.005", 1, "58caac54b891f5d7f335e710e45e5d29", 16209623},  				{NULL, 0, NULL, 0}  			}, -			Common::FR_FRA, -			Common::kPlatformPC, +			Common::IT_ITA, +			Common::kPlatformDOS,  			GF_PACKED,  			GUIO0()  		}, @@ -139,33 +179,39 @@ static const DrasculaGameDescription gameDescriptions[] = {  			0,  			AD_ENTRY1s("packet.001", "3c971aba65a037d29d0b479cad6f5943", 31702652),  			Common::ES_ESP, -			Common::kPlatformPC, +			Common::kPlatformDOS,  			GF_PACKED,  			GUIO0()  		},  	},  	{ -		// Drascula Spanish version +		// Drascula Spanish version (ScummVM repacked files)  		{  			"drascula",  			0, -			AD_ENTRY1s("14.ald", "0746ed1a5cc8d9728f790c29813f4b43", 23059), +			{ +				{"packet.001", 0, "c6a8697396e213a18472542d5f547cb4", 32847563}, +				{"packet.004", 1, "a289d3cf80d50f25ec569b653248437e", 17205838}, +				{NULL, 0, NULL, 0} +			},  			Common::ES_ESP, -			Common::kPlatformPC, -			ADGF_NO_FLAGS, +			Common::kPlatformDOS, +			GF_PACKED,  			GUIO0()  		},  	}, +	//// Unpacked versions //////////////////////////////////////////////////// +  	{ -		// Drascula German version +		// Drascula English version  		{  			"drascula",  			0, -			AD_ENTRY1s("14.ald", "72e46089033d56bad1c179ac36e2a9d2", 610), -			Common::DE_DEU, -			Common::kPlatformPC, +			AD_ENTRY1s("14.ald", "09b2735953edcd43af115c65ae00b10e", 1595), +			Common::EN_ANY, +			Common::kPlatformDOS,  			ADGF_NO_FLAGS,  			GUIO0()  		}, @@ -178,84 +224,73 @@ static const DrasculaGameDescription gameDescriptions[] = {  			0,  			AD_ENTRY1s("14.ald", "eeeee96b82169003630e08992248296c", 608),  			Common::FR_FRA, -			Common::kPlatformPC, +			Common::kPlatformDOS,  			ADGF_NO_FLAGS,  			GUIO0()  		},  	},  	{ -		// Drascula Italian version (original packed version) +		// Drascula French version (updated - bug #3612236)  		{  			"drascula",  			0, -			AD_ENTRY1s("packet.001", "0253e924af223f5fe52537023385159b", 32564209), -			Common::IT_ITA, -			Common::kPlatformPC, -			GF_PACKED, +			AD_ENTRY1s("14.ald", "1f9fbded768bee061cc22bc5bdeab540", 611), +			Common::FR_FRA, +			Common::kPlatformDOS, +			ADGF_NO_FLAGS,  			GUIO0()  		},  	}, +  	{ -		// Drascula Italian version +		// Drascula German version  		{  			"drascula",  			0, -			AD_ENTRY1s("14.ald", "02b49a18328d0bf2efe6ba658c9c7a1d", 2098), -			Common::IT_ITA, -			Common::kPlatformPC, +			AD_ENTRY1s("14.ald", "72e46089033d56bad1c179ac36e2a9d2", 610), +			Common::DE_DEU, +			Common::kPlatformDOS,  			ADGF_NO_FLAGS,  			GUIO0()  		},  	},  	{ -		// Drascula Spanish version (ScummVM repacked files) +		// Drascula Italian version  		{  			"drascula",  			0, -			{ -				{"packet.001", 0, "c6a8697396e213a18472542d5f547cb4", 32847563}, -				{"packet.004", 1, "a289d3cf80d50f25ec569b653248437e", 17205838}, -				{NULL, 0, NULL, 0} -			}, -			Common::ES_ESP, -			Common::kPlatformPC, -			GF_PACKED, +			AD_ENTRY1s("14.ald", "02b49a18328d0bf2efe6ba658c9c7a1d", 2098), +			Common::IT_ITA, +			Common::kPlatformDOS, +			ADGF_NO_FLAGS,  			GUIO0()  		},  	},  	{ -		// Drascula Italian version (ScummVM repacked files) +		// Drascula Italian version (updated - bug #3612236)  		{  			"drascula",  			0, -			{ -				{"packet.001", 0, "c6a8697396e213a18472542d5f547cb4", 32847563}, -				{"packet.005", 1, "58caac54b891f5d7f335e710e45e5d29", 16209623}, -				{NULL, 0, NULL, 0} -			}, +			AD_ENTRY1s("14.ald", "ccaee939bb3b344c048f28f9205710d1", 2925),  			Common::IT_ITA, -			Common::kPlatformPC, -			GF_PACKED, +			Common::kPlatformDOS, +			ADGF_NO_FLAGS,  			GUIO0()  		},  	},  	{ -		// Drascula French version (ScummVM repacked files) +		// Drascula Spanish version  		{  			"drascula",  			0, -			{ -				{"packet.001", 0, "c6a8697396e213a18472542d5f547cb4", 32847563}, -				{"packet.002", 1, "7b83cedb9bb326ed5143e5c459508d43", 722383}, -				{NULL, 0, NULL, 0} -			}, -			Common::FR_FRA, -			Common::kPlatformPC, -			GF_PACKED, +			AD_ENTRY1s("14.ald", "0746ed1a5cc8d9728f790c29813f4b43", 23059), +			Common::ES_ESP, +			Common::kPlatformDOS, +			ADGF_NO_FLAGS,  			GUIO0()  		},  	}, @@ -263,81 +298,123 @@ static const DrasculaGameDescription gameDescriptions[] = {  	{ AD_TABLE_END_MARKER }  }; -} // End of namespace Drascula +static const ExtraGuiOption drasculaExtraGuiOption = { +	_s("Use original save/load screens"), +	_s("Use the original save/load screens, instead of the ScummVM ones"), +	"originalsaveload", +	false +}; + +SaveStateDescriptor loadMetaData(Common::ReadStream *s, int slot, bool setPlayTime);  class DrasculaMetaEngine : public AdvancedMetaEngine {  public:  	DrasculaMetaEngine() : AdvancedMetaEngine(Drascula::gameDescriptions, sizeof(Drascula::DrasculaGameDescription), drasculaGames) {  		_singleid = "drascula"; -		_guioptions = GUIO2(GUIO_NOMIDI, GUIO_NOLAUNCHLOAD); +		_guioptions = GUIO1(GUIO_NOMIDI);  	} -	virtual bool hasFeature(MetaEngineFeature f) const { -		return (f == kSupportsListSaves); +	virtual const char *getName() const { +		return "Drascula";  	} -	virtual SaveStateList listSaves(const char *target) const { -		Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); -		Common::String pattern = Common::String::format("%s??", target); +	virtual const char *getOriginalCopyright() const { +		return "Drascula Engine (C) 2000 Alcachofa Soft, (C) 1996 Digital Dreams Multimedia, (C) 1994 Emilio de Paz"; +	} -		// Get list of savefiles for target game -		Common::StringArray filenames = saveFileMan->listSavefiles(pattern); -		Common::Array<int> slots; -		for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file) { +	virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *gd) const; +	virtual bool hasFeature(MetaEngineFeature f) const; +	virtual const ExtraGuiOptions getExtraGuiOptions(const Common::String &target) const; +	virtual SaveStateList listSaves(const char *target) const; +	virtual int getMaximumSaveSlot() const; +	virtual void removeSaveState(const char *target, int slot) const; +	SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const; +}; -			// Obtain the last 2 digits of the filename, since they correspond to the save slot -			int slotNum = atoi(file->c_str() + file->size() - 2); +bool DrasculaMetaEngine::hasFeature(MetaEngineFeature f) const { +	return +		(f == kSupportsListSaves) || +		(f == kSupportsLoadingDuringStartup) || +		(f == kSupportsDeleteSave) || +		(f == kSavesSupportMetaInfo) || +		(f == kSavesSupportThumbnail) || +		(f == kSavesSupportCreationDate) || +		(f == kSavesSupportPlayTime); +} -			// Ensure save slot is within valid range -			if (slotNum >= 1 && slotNum <= 10) { -				slots.push_back(slotNum); +const ExtraGuiOptions DrasculaMetaEngine::getExtraGuiOptions(const Common::String &target) const { +	ExtraGuiOptions options; +	options.push_back(drasculaExtraGuiOption); +	return options; +} + +SaveStateList DrasculaMetaEngine::listSaves(const char *target) const { +	Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); +	Common::StringArray filenames; +	Common::String pattern = target; +	pattern += ".???"; + +	filenames = saveFileMan->listSavefiles(pattern); +	sort(filenames.begin(), filenames.end());	// Sort (hopefully ensuring we are sorted numerically..) + +	SaveStateList saveList; +	int slotNum = 0; +	for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file) { +		// Obtain the last 3 digits of the filename, since they correspond to the save slot +		slotNum = atoi(file->c_str() + file->size() - 3); + +		if (slotNum >= 0 && slotNum <= getMaximumSaveSlot()) { +			Common::InSaveFile *in = saveFileMan->openForLoading(*file); +			if (in) { +				SaveStateDescriptor desc = loadMetaData(in, slotNum, false); +				if (desc.getSaveSlot() != slotNum) { +					// invalid +					delete in; +					continue; +				} +				saveList.push_back(desc); +				delete in;  			}  		} +	} -		// Sort save slot ids -		Common::sort<int>(slots.begin(), slots.end()); - -		// Load save index -		Common::String fileEpa = Common::String::format("%s.epa", target); -		Common::InSaveFile *epa = saveFileMan->openForLoading(fileEpa); - -		// Get savegame names from index -		Common::String saveDesc; -		SaveStateList saveList; -		int line = 1; -		for (size_t i = 0; i < slots.size(); i++) { -			// ignore lines corresponding to unused saveslots -			for (; line < slots[i]; line++) -				epa->readLine(); +	return saveList; +} -			// copy the name in the line corresponding to the save slot and truncate to 22 characters -			saveDesc = Common::String(epa->readLine().c_str(), 22); +SaveStateDescriptor DrasculaMetaEngine::querySaveMetaInfos(const char *target, int slot) const { +	char fileName[MAXPATHLEN]; +	sprintf(fileName, "%s.%03d", target, slot); -			// handle cases where the save directory and save index are detectably out of sync -			if (saveDesc == "*") -				saveDesc = "No name specified."; +	Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(fileName); -			// increment line number to keep it in sync with slot number -			line++; +	SaveStateDescriptor desc; +	// Do not allow save slot 0 (used for auto-saving) to be deleted or +	// overwritten. +	desc.setDeletableFlag(slot != 0); +	desc.setWriteProtectedFlag(slot == 0); -			// Insert savegame name into list -			saveList.push_back(SaveStateDescriptor(slots[i], saveDesc)); +	if (in) { +		desc = Drascula::loadMetaData(in, slot, false); +		if (desc.getSaveSlot() != slot) { +			delete in; +			return SaveStateDescriptor();  		} -		delete epa; -		return saveList; -	} +		Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*in); +		desc.setThumbnail(thumbnail); -	virtual const char *getName() const { -		return "Drascula"; +		delete in;  	} -	virtual const char *getOriginalCopyright() const { -		return "Drascula Engine (C) 2000 Alcachofa Soft, (C) 1996 Digital Dreams Multimedia, (C) 1994 Emilio de Paz"; -	} +	return desc; +} -	virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const; -}; +int DrasculaMetaEngine::getMaximumSaveSlot() const { return 999; } + +void DrasculaMetaEngine::removeSaveState(const char *target, int slot) const { +	Common::String fileName = Common::String::format("%s.%03d", target, slot); +	g_system->getSavefileManager()->removeSavefile(fileName); +}  bool DrasculaMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {  	const Drascula::DrasculaGameDescription *gd = (const Drascula::DrasculaGameDescription *)desc; @@ -347,8 +424,10 @@ bool DrasculaMetaEngine::createInstance(OSystem *syst, Engine **engine, const AD  	return gd != 0;  } +} // End of namespace Drascula +  #if PLUGIN_ENABLED_DYNAMIC(DRASCULA) -	REGISTER_PLUGIN_DYNAMIC(DRASCULA, PLUGIN_TYPE_ENGINE, DrasculaMetaEngine); +	REGISTER_PLUGIN_DYNAMIC(DRASCULA, PLUGIN_TYPE_ENGINE, Drascula::DrasculaMetaEngine);  #else -	REGISTER_PLUGIN_STATIC(DRASCULA, PLUGIN_TYPE_ENGINE, DrasculaMetaEngine); +	REGISTER_PLUGIN_STATIC(DRASCULA, PLUGIN_TYPE_ENGINE, Drascula::DrasculaMetaEngine);  #endif | 
