Skip to content

Commit

Permalink
DM: Add loading from game
Browse files Browse the repository at this point in the history
  • Loading branch information
Bendegúz Nagy committed Aug 26, 2016
1 parent 5cb1d02 commit efac7b5
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 24 deletions.
4 changes: 3 additions & 1 deletion engines/dm/TODOs/todo.txt
Expand Up @@ -18,4 +18,6 @@ Code stuff todo:
Save file f433_processCommand140_saveGame fails silently, add error checking

Add loading from dungeon
Fix incorrect thumbnail
Fix incorrect thumbnail
Add translations to f433_processCommand140_saveGame 'LOAD'

4 changes: 2 additions & 2 deletions engines/dm/dialog.cpp
Expand Up @@ -223,7 +223,7 @@ int16 DialogMan::f424_dialogGetChoice(uint16 choiceCount, uint16 dialogSetIndex,
L1303_s_BoxB = L1304_s_BoxA;
L1303_s_BoxB._x1 = L1303_s_BoxB._x2;
_vm->_displayMan->D24_fillScreenBox(L1303_s_BoxB, k0_ColorBlack);
_vm->f22_delay(5);
_vm->f22_delay(2);
L1303_s_BoxB = L1304_s_BoxA;
L1303_s_BoxB._y1++;
L1303_s_BoxB._y2 = L1303_s_BoxB._y1;
Expand Down Expand Up @@ -251,7 +251,7 @@ int16 DialogMan::f424_dialogGetChoice(uint16 choiceCount, uint16 dialogSetIndex,
L1303_s_BoxB._x1 = L1303_s_BoxB._x2 = L1303_s_BoxB._x2 + 3;
L1303_s_BoxB._y2 += 2;
_vm->_displayMan->D24_fillScreenBox(L1303_s_BoxB, k13_ColorLightestGray);
_vm->f22_delay(5);
_vm->f22_delay(2);
L1304_s_BoxA._x2 += 3;
L1304_s_BoxA._y2 += 3;
_vm->_displayMan->f132_blitToBitmap(_vm->_displayMan->_g296_bitmapViewport, _vm->_displayMan->_g348_bitmapScreen,
Expand Down
43 changes: 40 additions & 3 deletions engines/dm/dm.cpp
Expand Up @@ -207,6 +207,8 @@ DMEngine::DMEngine(OSystem *syst, const ADGameDescription *desc) : Engine(syst),
debug("DMEngine::DMEngine");

_saveThumbnail = nullptr;
_canLoadFromGMM = false;
_loadSaveSlotAtRuntime = -1;
}

DMEngine::~DMEngine() {
Expand Down Expand Up @@ -243,6 +245,26 @@ bool DMEngine::hasFeature(EngineFeature f) const {
(f == kSupportsLoadingDuringRuntime);
}

Common::Error DMEngine::loadGameState(int slot) {
if (f435_loadgame(slot) != kM1_LoadgameFailure) {
_displayMan->fillScreen(k0_ColorBlack);
_displayMan->f436_STARTEND_FadeToPalette(_displayMan->_palDungeonView[0]);
_g298_newGame = k0_modeLoadSavedGame;

f462_startGame();
_g523_restartGameRequest = false;
_eventMan->f77_hideMouse();
_eventMan->f357_discardAllInput();
return Common::kNoError;
}

return Common::kNoGameDataFoundError;
}

bool DMEngine::canLoadGameStateCurrently() {
return _canLoadFromGMM;
}

void DMEngine::f22_delay(uint16 verticalBlank) {
for (uint16 i = 0; i < verticalBlank * 2; ++i) {
_eventMan->processInput();
Expand Down Expand Up @@ -386,9 +408,18 @@ Common::Error DMEngine::run() {
f463_initializeGame();
while (true) {
f2_gameloop();

if (_engineShouldQuit)
return Common::kNoError;
f444_endGame(_championMan->_g303_partyDead);

if (_loadSaveSlotAtRuntime == -1)
f444_endGame(_championMan->_g303_partyDead);
else {
loadGameState(_loadSaveSlotAtRuntime);
_menuMan->f457_drawEnabledMenus();
_displayMan->updateScreen();
_loadSaveSlotAtRuntime = -1;
}
}

return Common::kNoError;
Expand All @@ -403,10 +434,13 @@ void DMEngine::f2_gameloop() {
_dungeonMan->_g308_partyDir = kDirWest;
}

_canLoadFromGMM = true;
_g318_waitForInputMaxVerticalBlankCount = 10;
while (true) {
if (_engineShouldQuit)
if (_engineShouldQuit) {
_canLoadFromGMM = false;
return;
}

// DEBUG CODE
for (int16 i = 0; i < _championMan->_g305_partyChampionCount; ++i) {
Expand Down Expand Up @@ -495,8 +529,10 @@ void DMEngine::f2_gameloop() {
}

_eventMan->f380_processCommandQueue();
if (_engineShouldQuit)
if (_engineShouldQuit || _loadSaveSlotAtRuntime != -1) {
_canLoadFromGMM = false;
return;
}
_displayMan->updateScreen();
if (!_g321_stopWaitingForPlayerInput) {
_eventMan->f363_highlightBoxDisable();
Expand All @@ -508,6 +544,7 @@ void DMEngine::f2_gameloop() {

} while (!_g321_stopWaitingForPlayerInput || !_g301_gameTimeTicking);
}
_canLoadFromGMM = false;
}

int16 DMEngine::M1_ordinalToIndex(int16 val) {
Expand Down
6 changes: 6 additions & 0 deletions engines/dm/dm.h
Expand Up @@ -219,6 +219,10 @@ class DMEngine : public Engine {
explicit DMEngine(OSystem *syst, const ADGameDescription *gameDesc);
~DMEngine();
virtual bool hasFeature(EngineFeature f) const;

virtual Common::Error loadGameState(int slot);
virtual bool canLoadGameStateCurrently();

GUI::Debugger *getDebugger() { return _console; }

void f22_delay(uint16 verticalBlank); // @ F0022_MAIN_Delay
Expand Down Expand Up @@ -250,6 +254,7 @@ class DMEngine : public Engine {

byte *_savedScreenForOpenEntranceDoors; // ad-hoc HACK
const ADGameDescription *_gameVersion;
bool _canLoadFromGMM;
public:
Console *_console;
DisplayMan *_displayMan;
Expand All @@ -270,6 +275,7 @@ class DMEngine : public Engine {
Common::MemoryWriteStreamDynamic *_saveThumbnail;

bool _engineShouldQuit;
int _loadSaveSlotAtRuntime;

int16 _g298_newGame; // @ G0298_B_NewGame
bool _g523_restartGameRequest; // @ G0523_B_RestartGameRequested
Expand Down
2 changes: 0 additions & 2 deletions engines/dm/dungeonman.cpp
Expand Up @@ -740,8 +740,6 @@ void DungeonMan::f173_setCurrentMap(uint16 mapIndex) {
DoorInfo(5, 255) /* Door type 3 Ra door */
};

if (_g272_currMapIndex == mapIndex)
return;

_g272_currMapIndex = mapIndex;
_g271_currMapData = _g279_dungeonMapData[mapIndex];
Expand Down
38 changes: 22 additions & 16 deletions engines/dm/loadsave.cpp
Expand Up @@ -56,19 +56,13 @@ LoadgameResponse DMEngine::f435_loadgame(int16 slot) {
Common::InSaveFile *file = nullptr;

struct {
int16 _saveFormat;
int16 _saveAndPlayChoice;
int32 _gameId;
int16 _platform;
uint16 _dungeonId;
int16 _saveFormat = 0;
int16 _saveAndPlayChoice = 0;
int32 _gameId = 0;
int16 _platform = 0;
uint16 _dungeonId = 0;
} dmSaveHeader;

dmSaveHeader._saveFormat = 0;
dmSaveHeader._saveAndPlayChoice = 0;
dmSaveHeader._gameId = 0;
dmSaveHeader._platform = 0;
dmSaveHeader._dungeonId = 0;

if (!_g298_newGame) {
fileName = getSavefileName(slot);
saveFileManager = _system->getSavefileManager();
Expand Down Expand Up @@ -188,23 +182,35 @@ void DMEngine::f433_processCommand140_saveGame() {
switch (getGameLanguage()) { // localized
default:
case Common::EN_ANY:
_dialog->f427_dialogDraw(nullptr, nullptr, "SAVE AND PLAY", "SAVE AND QUIT", "CANCEL", nullptr, false, false, false);
_dialog->f427_dialogDraw(nullptr, nullptr, "SAVE AND PLAY", "SAVE AND QUIT", "CANCEL", "LOAD", false, false, false);
break;
case Common::DE_DEU:
_dialog->f427_dialogDraw(nullptr, nullptr, "SICHERN/SPIEL", "SICHERN/ENDEN", "WIDERRUFEN", nullptr, false, false, false);
_dialog->f427_dialogDraw(nullptr, nullptr, "SICHERN/SPIEL", "SICHERN/ENDEN", "WIDERRUFEN", "LOAD", false, false, false);
break;
case Common::FR_FRA:
_dialog->f427_dialogDraw(nullptr, nullptr, "GARDER/JOUER", "GARDER/SORTIR", "ANNULLER", nullptr, false, false, false);
_dialog->f427_dialogDraw(nullptr, nullptr, "GARDER/JOUER", "GARDER/SORTIR", "ANNULLER", "LOAD", false, false, false);
break;
}

enum SaveAndPlayChoice {
kSaveAndPlay = 1,
kSaveAndQuit = 2,
kCancel = 3
kCancel = 3,
kLoad = 4
};

SaveAndPlayChoice saveAndPlayChoice = (SaveAndPlayChoice)_dialog->f424_dialogGetChoice(3, k0_DIALOG_SET_VIEWPORT, 0, k0_DIALOG_CHOICE_NONE);
SaveAndPlayChoice saveAndPlayChoice = (SaveAndPlayChoice)_dialog->f424_dialogGetChoice(4, k0_DIALOG_SET_VIEWPORT, 0, k0_DIALOG_CHOICE_NONE);

if (saveAndPlayChoice == kLoad) {
GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Restore game:"), _("Restore"), false);
int loadSlot = dialog->runModalWithCurrentTarget();
if (loadSlot >= 0) {
_loadSaveSlotAtRuntime = loadSlot;
return;
}

saveAndPlayChoice = kCancel;
}

if (saveAndPlayChoice == kSaveAndQuit || saveAndPlayChoice == kSaveAndPlay) {
GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), true);
Expand Down

0 comments on commit efac7b5

Please sign in to comment.