CGE: Added support for GMM save/load and launcher loading

This commit is contained in:
Paul Gilbert 2011-07-16 21:12:19 +10:00
parent ce070cdd3c
commit 00061bc5dd
4 changed files with 105 additions and 69 deletions

View File

@ -126,6 +126,7 @@ void CGEEngine::setup() {
for (int i = 0; i < 4; i++)
_flag[i] = false;
_startGameSlot = ConfMan.hasKey("save_slot") ? ConfMan.getInt("save_slot") : -1;
}
CGEEngine::~CGEEngine() {
@ -173,12 +174,25 @@ Common::Error CGEEngine::run() {
// Setup necessary game objects
setup();
// Additional setup.
debug("CGEEngine::init");
// Run the game
cge_main();
return Common::kNoError;
}
bool CGEEngine::hasFeature(EngineFeature f) const {
return
(f == kSupportsRTL) ||
(f == kSupportsLoadingDuringRuntime) ||
(f == kSupportsSavingDuringRuntime);
}
bool CGEEngine::canLoadGameStateCurrently() {
return (_startupMode == 0) && _mouse->_active;
}
bool CGEEngine::canSaveGameStateCurrently() {
return (_startupMode == 0) && _mouse->_active;
}
} // End of namespace CGE

View File

@ -69,19 +69,26 @@ struct SavegameHeader {
int totalFrames;
};
extern const char *SAVEGAME_STR;
#define SAVEGAME_STR_SIZE 11
class CGEEngine : public Engine {
private:
uint32 _lastFrame;
void tick();
void syncHeader(Common::Serializer &s);
bool readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header);
void writeSavegameHeader(Common::OutSaveFile *out, SavegameHeader &header);
static void writeSavegameHeader(Common::OutSaveFile *out, SavegameHeader &header);
void syncGame(Common::SeekableReadStream *readStream, Common::WriteStream *writeStream, bool tiny = false);
bool savegameExists(int slotNumber);
Common::String generateSaveName(int slot);
public:
CGEEngine(OSystem *syst, const ADGameDescription *gameDescription);
~CGEEngine();
virtual bool hasFeature(EngineFeature f) const;
virtual bool canLoadGameStateCurrently();
virtual bool canSaveGameStateCurrently();
virtual Common::Error loadGameState(int slot);
virtual Common::Error saveGameState(int slot, const Common::String &desc);
const ADGameDescription *_gameDescription;
bool _isDemo;
@ -107,6 +114,7 @@ public:
byte * _mini;
BMP_PTR * _miniShp;
BMP_PTR * _miniShpList;
int _startGameSlot;
virtual Common::Error run();
GUI::Debugger *getDebugger() {
@ -149,6 +157,7 @@ public:
void setDMA();
void mainLoop();
void saveGame(int slotNumber, const Common::String &desc);
static bool readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header);
void switchMusic();
void selectPocket(int n);
void expandSprite(Sprite *spr);

View File

@ -224,6 +224,24 @@ Common::String CGEEngine::generateSaveName(int slot) {
return Common::String::format("%s.%03d", _targetName.c_str(), slot);
}
Common::Error CGEEngine::loadGameState(int slot) {
// Clear current game activity
caveDown();
// Load the game
loadGame(slot, NULL, true);
caveUp();
loadGame(slot, NULL);
return Common::kNoError;
}
Common::Error CGEEngine::saveGameState(int slot, const Common::String &desc) {
saveGame(slot, desc);
return Common::kNoError;
}
void CGEEngine::saveSound() {
warning("STUB: CGEEngine::saveSound");
/* Convert to saving any such needed data in ScummVM configuration file
@ -268,7 +286,7 @@ void CGEEngine::writeSavegameHeader(Common::OutSaveFile *out, SavegameHeader &he
// Create a thumbnail and save it
Graphics::Surface *thumb = new Graphics::Surface();
Graphics::Surface *s = _vga->_page[1];
Graphics::Surface *s = _vga->_page[0];
::createThumbnail(thumb, (const byte *)s->pixels, SCR_WID, SCR_HIG, thumbPalette);
Graphics::saveThumbnail(*out, *thumb);
delete thumb;
@ -1451,8 +1469,8 @@ void CGEEngine::loadUser() {
loadGame(0, NULL);
} else {
if (Startup::_mode == 1) {
// Load initial game state savegame
loadGame(-1, NULL);
// Load either initial game state savegame or launcher specified savegame
loadGame(_startGameSlot, NULL);
} else {
error("Creating setup savegames not supported");
}
@ -1681,7 +1699,7 @@ bool CGEEngine::showTitle(const char *name) {
//Mouse.On();
// For ScummVM, skip prompting for name if a savegame in slot 0 already exists
if (savegameExists(0)) {
if ((_startGameSlot == -1) && savegameExists(0)) {
strcpy(_usrFnam, "User");
usr_ok = true;
} else {
@ -1755,18 +1773,29 @@ void CGEEngine::cge_main() {
if (_music && Startup::_soundOk)
loadMidi(0);
if (Startup::_mode < 2)
movie(LGO_EXT);
if (showTitle("WELCOME")) {
if ((!_isDemo) && (Startup::_mode == 1))
movie("X02"); // intro
if (_startGameSlot != -1) {
// Starting up a savegame from the launcher
Startup::_mode++;
runGame();
_startupMode = 2;
if (_flag[3]) // Flag FINIS
movie("X03");
} else
_vga->sunset();
} else {
if (Startup::_mode < 2)
movie(LGO_EXT);
if (showTitle("WELCOME")) {
if ((!_isDemo) && (Startup::_mode == 1))
movie("X02"); // intro
runGame();
_startupMode = 2;
if (_flag[3]) // Flag FINIS
movie("X03");
} else
_vga->sunset();
}
}
} // End of namespace CGE

View File

@ -103,6 +103,8 @@ public:
return "Soltys (c) 1994-1996 L.K. Avalon";
}
virtual bool hasFeature(MetaEngineFeature f) const;
virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
virtual int getMaximumSaveSlot() const;
@ -146,25 +148,26 @@ SaveStateList CGEMetaEngine::listSaves(const char *target) const {
slotNum = atoi(filename->c_str() + filename->size() - 3);
if (slotNum >= 0 && slotNum <= 99) {
Common::InSaveFile *file = saveFileMan->openForLoading(*filename);
if (file) {
int32 version = file->readSint32BE();
if (version != CGE_SAVEGAME_VERSION) {
delete file;
continue;
CGE::SavegameHeader header;
// Check to see if it's a ScummVM savegame or not
char buffer[SAVEGAME_STR_SIZE + 1];
file->read(buffer, SAVEGAME_STR_SIZE + 1);
if (!strncmp(buffer, CGE::SAVEGAME_STR, SAVEGAME_STR_SIZE + 1)) {
// Valid savegame
if (CGE::CGEEngine::readSavegameHeader(file, header)) {
saveList.push_back(SaveStateDescriptor(slotNum, header.saveName));
delete header.thumbnail;
}
} else {
// Must be an original format savegame
saveList.push_back(SaveStateDescriptor(slotNum, "Unknown"));
}
// read name
uint16 nameSize = file->readUint16BE();
if (nameSize >= 255) {
delete file;
continue;
}
char name[256];
file->read(name, nameSize);
name[nameSize] = 0;
saveList.push_back(SaveStateDescriptor(slotNum, name));
delete file;
}
}
@ -175,53 +178,34 @@ SaveStateList CGEMetaEngine::listSaves(const char *target) const {
SaveStateDescriptor CGEMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
Common::String fileName = Common::String::format("%s.%03d", target, slot);
Common::InSaveFile *file = g_system->getSavefileManager()->openForLoading(fileName);
Common::InSaveFile *f = g_system->getSavefileManager()->openForLoading(fileName);
assert(f);
if (file) {
CGE::SavegameHeader header;
int32 version = file->readSint32BE();
if (version != CGE_SAVEGAME_VERSION) {
delete file;
return SaveStateDescriptor();
}
// Check to see if it's a ScummVM savegame or not
char buffer[SAVEGAME_STR_SIZE + 1];
f->read(buffer, SAVEGAME_STR_SIZE + 1);
uint32 saveNameLength = file->readUint16BE();
char saveName[256];
file->read(saveName, saveNameLength);
saveName[saveNameLength] = 0;
SaveStateDescriptor desc(slot, saveName);
Graphics::Surface *thumbnail = new Graphics::Surface();
assert(thumbnail);
if (!Graphics::loadThumbnail(*file, *thumbnail)) {
delete thumbnail;
thumbnail = 0;
}
desc.setThumbnail(thumbnail);
bool hasHeader = !strncmp(buffer, CGE::SAVEGAME_STR, SAVEGAME_STR_SIZE + 1) &&
CGE::CGEEngine::readSavegameHeader(f, header);
delete f;
if (!hasHeader) {
// Original savegame perhaps?
SaveStateDescriptor desc(slot, "Unknown");
return desc;
} else {
// Create the return descriptor
SaveStateDescriptor desc(slot, header.saveName);
desc.setDeletableFlag(true);
desc.setWriteProtectedFlag(false);
desc.setThumbnail(header.thumbnail);
desc.setSaveDate(header.saveYear, header.saveMonth, header.saveDay);
desc.setSaveTime(header.saveHour, header.saveMinutes);
uint32 saveDate = file->readUint32BE();
uint16 saveTime = file->readUint16BE();
int day = (saveDate >> 24) & 0xFF;
int month = (saveDate >> 16) & 0xFF;
int year = saveDate & 0xFFFF;
desc.setSaveDate(year, month, day);
int hour = (saveTime >> 8) & 0xFF;
int minutes = saveTime & 0xFF;
desc.setSaveTime(hour, minutes);
delete file;
return desc;
}
return SaveStateDescriptor();
}
bool CGEMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {