LoadgameResult DMEngine::loadgame(int16 slot) { if (slot == -1 && _newGameFl == k0_modeLoadSavedGame) return kDMLoadgameFailure; bool fadePalette = true; Common::String fileName; Common::SaveFileManager *saveFileManager = nullptr; Common::InSaveFile *file = nullptr; struct { SaveTarget _saveTarget; int32 _saveVersion; OriginalSaveFormat _saveFormat; OriginalSavePlatform _savePlatform; uint16 _dungeonId; } dmSaveHeader; if (_newGameFl) { //L1366_B_FadePalette = !F0428_DIALOG_RequireGameDiskInDrive_NoDialogDrawn(C0_DO_NOT_FORCE_DIALOG_DM_CSB, true); _restartGameAllowed = false; _championMan->_partyChampionCount = 0; _championMan->_leaderHandObject = Thing::_none; } else { fileName = getSavefileName(slot); saveFileManager = _system->getSavefileManager(); file = saveFileManager->openForLoading(fileName); SaveGameHeader header; readSaveGameHeader(file, &header); warning("MISSING CODE: missing check for matching format and platform in save in f435_loadgame"); dmSaveHeader._saveTarget = (SaveTarget)file->readSint32BE(); dmSaveHeader._saveVersion = file->readSint32BE(); dmSaveHeader._saveFormat = (OriginalSaveFormat)file->readSint32BE(); dmSaveHeader._savePlatform = (OriginalSavePlatform)file->readSint32BE(); // Skip _gameId, which was useless file->readSint32BE(); dmSaveHeader._dungeonId = file->readUint16BE(); _gameTime = file->readSint32BE(); // G0349_ul_LastRandomNumber = L1371_s_GlobalData.LastRandomNumber; _championMan->_partyChampionCount = file->readUint16BE(); _dungeonMan->_partyMapX = file->readSint16BE(); _dungeonMan->_partyMapY = file->readSint16BE(); _dungeonMan->_partyDir = (Direction)file->readUint16BE(); _dungeonMan->_partyMapIndex = file->readByte(); _championMan->_leaderIndex = (ChampionIndex)file->readSint16BE(); _championMan->_magicCasterChampionIndex = (ChampionIndex)file->readSint16BE(); _timeline->_eventCount = file->readUint16BE(); _timeline->_firstUnusedEventIndex = file->readUint16BE(); _timeline->_eventMaxCount = file->readUint16BE(); _groupMan->_currActiveGroupCount = file->readUint16BE(); _projexpl->_lastCreatureAttackTime = file->readSint32BE(); _projexpl->_lastPartyMovementTime = file->readSint32BE(); _disabledMovementTicks = file->readSint16BE(); _projectileDisableMovementTicks = file->readSint16BE(); _lastProjectileDisabledMovementDirection = file->readSint16BE(); _championMan->_leaderHandObject = Thing(file->readUint16BE()); _groupMan->_maxActiveGroupCount = file->readUint16BE(); if (!_restartGameRequest) { _timeline->initTimeline(); _groupMan->initActiveGroups(); } _groupMan->loadActiveGroupPart(file); _championMan->loadPartyPart2(file); _timeline->loadEventsPart(file); _timeline->loadTimelinePart(file); // read sentinel uint32 sentinel = file->readUint32BE(); assert(sentinel == 0x6f85e3d3); _dungeonId = dmSaveHeader._dungeonId; } _dungeonMan->loadDungeonFile(file); delete file; if (_newGameFl) { _timeline->initTimeline(); _groupMan->initActiveGroups(); if (fadePalette) { _displayMan->startEndFadeToPalette(_displayMan->_blankBuffer); delay(1); _displayMan->fillScreen(kDMColorBlack); _displayMan->startEndFadeToPalette(_displayMan->_paletteTopAndBottomScreen); } } else { _restartGameAllowed = true; switch (getGameLanguage()) { // localized case Common::DE_DEU: _dialog->dialogDraw(nullptr, "SPIEL WIRD GELADEN . . .", nullptr, nullptr, nullptr, nullptr, true, true, true); break; case Common::FR_FRA: _dialog->dialogDraw(nullptr, "CHARGEMENT DU JEU . . .", nullptr, nullptr, nullptr, nullptr, true, true, true); break; default: _dialog->dialogDraw(nullptr, "LOADING GAME . . .", nullptr, nullptr, nullptr, nullptr, true, true, true); break; } } _championMan->_partyDead = false; return kDMLoadgameSuccess; }
void DMEngine::endGame(bool doNotDrawCreditsOnly) { static Box boxEndgameRestartOuterEN(103, 217, 145, 159); static Box boxEndgameRestartInnerEN(105, 215, 147, 157); static Box boxEndgameRestartOuterDE(82, 238, 145, 159); static Box boxEndgameRestartInnerDE(84, 236, 147, 157); static Box boxEndgameRestartOuterFR(100, 220, 145, 159); static Box boxEndgameRestartInnerFR(102, 218, 147, 157); Box restartOuterBox; Box restartInnerBox; switch (getGameLanguage()) { // localized default: case Common::EN_ANY: restartOuterBox = boxEndgameRestartOuterEN; restartInnerBox = boxEndgameRestartInnerEN; break; case Common::DE_DEU: restartOuterBox = boxEndgameRestartOuterDE; restartInnerBox = boxEndgameRestartInnerDE; break; case Common::FR_FRA: restartOuterBox = boxEndgameRestartOuterFR; restartInnerBox = boxEndgameRestartInnerFR; break; } static Box theEndBox(120, 199, 95, 108); static Box championMirrorBox(11, 74, 7, 49); static Box championPortraitBox(27, 58, 13, 41); bool waitBeforeDrawingRestart = true; _eventMan->setMousePointerToNormal(k0_pointerArrow); _eventMan->showMouse(); _eventMan->_primaryMouseInput = nullptr; _eventMan->_secondaryMouseInput = nullptr; _eventMan->_primaryKeyboardInput = nullptr; _eventMan->_secondaryKeyboardInput = nullptr; if (doNotDrawCreditsOnly && !_gameWon) { _sound->requestPlay(k06_soundSCREAM, _dungeonMan->_partyMapX, _dungeonMan->_partyMapY, k0_soundModePlayImmediately); delay(240); } if (_displayMan->_paletteSwitchingEnabled) { uint16 oldPalTopAndBottomScreen[16]; for (uint16 i = 0; i < 16; ++i) oldPalTopAndBottomScreen[i] = _displayMan->_paletteTopAndBottomScreen[i]; for (int i = 0; i <= 7; i++) { delay(1); for (int colIdx = 0; colIdx < 16; colIdx++) { _displayMan->_paletteMiddleScreen[colIdx] = _displayMan->getDarkenedColor(_displayMan->_paletteMiddleScreen[colIdx]); _displayMan->_paletteTopAndBottomScreen[colIdx] = _displayMan->getDarkenedColor(_displayMan->_paletteTopAndBottomScreen[colIdx]); } } _displayMan->_paletteSwitchingEnabled = false; delay(1); for (uint16 i = 0; i < 16; ++i) _displayMan->_paletteTopAndBottomScreen[i] = oldPalTopAndBottomScreen[i]; } else _displayMan->startEndFadeToPalette(_displayMan->_blankBuffer); uint16 darkBluePalette[16]; if (doNotDrawCreditsOnly) { if (_gameWon) { // Strangerke: Related to portraits. Game data could be missing for earlier versions of the game. _displayMan->fillScreen(k12_ColorDarkestGray); for (int16 championIndex = k0_ChampionFirst; championIndex < _championMan->_partyChampionCount; championIndex++) { int16 textPosY = championIndex * 48; Champion *curChampion = &_championMan->_champions[championIndex]; _displayMan->blitToScreen(_displayMan->getNativeBitmapOrGraphic(k208_wallOrn_43_champMirror), &championMirrorBox, k32_byteWidth, k10_ColorFlesh, 43); _displayMan->blitToScreen(curChampion->_portrait, &championPortraitBox, k16_byteWidth, k1_ColorDarkGary, 29); _textMan->printEndGameString(87, textPosY += 14, k9_ColorGold, curChampion->_name); int textPosX = (6 * strlen(curChampion->_name)) + 87; char championTitleFirstCharacter = curChampion->_title[0]; if ((championTitleFirstCharacter != ',') && (championTitleFirstCharacter != ';') && (championTitleFirstCharacter != '-')) textPosX += 6; _textMan->printEndGameString(textPosX, textPosY++, k9_ColorGold, curChampion->_title); for (int16 idx = k0_ChampionSkillFighter; idx <= k3_ChampionSkillWizard; idx++) { uint16 skillLevel = MIN<uint16>(16, _championMan->getSkillLevel(championIndex, idx | (k0x4000_IgnoreObjectModifiers | k0x8000_IgnoreTemporaryExperience))); if (skillLevel == 1) continue; char displStr[20]; strcpy(displStr, _inventoryMan->_skillLevelNames[skillLevel - 2]); strcat(displStr, " "); strcat(displStr, _championMan->_baseSkillName[idx]); _textMan->printEndGameString(105, textPosY = textPosY + 8, k13_ColorLightestGray, displStr); } championMirrorBox._y1 += 48; championMirrorBox._y2 += 48; championPortraitBox._y1 += 48; championPortraitBox._y1 += 48; } _displayMan->startEndFadeToPalette(_displayMan->_paletteTopAndBottomScreen); _engineShouldQuit = true; return; } T0444017: _displayMan->fillScreen(k0_ColorBlack); _displayMan->blitToScreen(_displayMan->getNativeBitmapOrGraphic(k6_theEndIndice), &theEndBox, k40_byteWidth, kM1_ColorNoTransparency, 14); for (uint16 i = 0; i < 16; ++i) darkBluePalette[i] = D01_RGB_DARK_BLUE; uint16 curPalette[16]; for (uint16 i = 0; i < 15; ++i) curPalette[i] = darkBluePalette[i]; curPalette[15] = D09_RGB_WHITE; _displayMan->startEndFadeToPalette(curPalette); _displayMan->updateScreen(); if (waitBeforeDrawingRestart) delay(300); if (_restartGameAllowed) { _displayMan->_useByteBoxCoordinates = false; _displayMan->fillScreenBox(restartOuterBox, k12_ColorDarkestGray); _displayMan->fillScreenBox(restartInnerBox, k0_ColorBlack); switch (getGameLanguage()) { // localized default: case Common::EN_ANY: _textMan->printToLogicalScreen(110, 154, k4_ColorCyan, k0_ColorBlack, "RESTART THIS GAME"); break; case Common::DE_DEU: _textMan->printToLogicalScreen(110, 154, k4_ColorCyan, k0_ColorBlack, "DIESES SPIEL NEU STARTEN"); break; case Common::FR_FRA: _textMan->printToLogicalScreen(110, 154, k4_ColorCyan, k0_ColorBlack, "RECOMMENCER CE JEU"); break; } curPalette[1] = D03_RGB_PINK; curPalette[4] = D09_RGB_WHITE; _eventMan->_primaryMouseInput = _eventMan->_primaryMouseInputRestartGame; _eventMan->discardAllInput(); _eventMan->hideMouse(); _displayMan->startEndFadeToPalette(curPalette); for (int16 verticalBlankCount = 900; --verticalBlankCount && !_restartGameRequest; delay(1)) _eventMan->processCommandQueue(); _eventMan->showMouse(); if (_restartGameRequest) { _displayMan->startEndFadeToPalette(darkBluePalette); _displayMan->fillScreen(k0_ColorBlack); _displayMan->startEndFadeToPalette(_displayMan->_palDungeonView[0]); _newGameFl = k0_modeLoadSavedGame; if (loadgame(1) != kM1_LoadgameFailure) { startGame(); _restartGameRequest = false; _eventMan->hideMouse(); _eventMan->discardAllInput(); return; } } } _displayMan->startEndFadeToPalette(darkBluePalette); } Box box(0, 319, 0, 199); _displayMan->blitToScreen(_displayMan->getNativeBitmapOrGraphic(k5_creditsGraphicIndice), &box, k160_byteWidthScreen, kM1_ColorNoTransparency, k200_heightScreen); _displayMan->startEndFadeToPalette(_displayMan->_palCredits); _eventMan->waitForMouseOrKeyActivity(); if (_engineShouldQuit) return; if (_restartGameAllowed && doNotDrawCreditsOnly) { waitBeforeDrawingRestart = false; _displayMan->startEndFadeToPalette(darkBluePalette); goto T0444017; } _engineShouldQuit = true; return; }
void DMEngine::saveGame() { _menuMan->drawDisabledMenu(); _eventMan->showMouse(); switch (getGameLanguage()) { // localized default: case Common::EN_ANY: _dialog->dialogDraw(nullptr, nullptr, "SAVE AND PLAY", "SAVE AND QUIT", "CANCEL", "LOAD", false, false, false); break; case Common::DE_DEU: _dialog->dialogDraw(nullptr, nullptr, "SICHERN/SPIEL", "SICHERN/ENDEN", "WIDERRUFEN", "LOAD", false, false, false); break; case Common::FR_FRA: _dialog->dialogDraw(nullptr, nullptr, "GARDER/JOUER", "GARDER/SORTIR", "ANNULLER", "LOAD", false, false, false); break; } enum SaveAndPlayChoice { kSaveAndPlay = 1, kSaveAndQuit = 2, kCancel = 3, kLoad = 4 }; SaveAndPlayChoice saveAndPlayChoice = (SaveAndPlayChoice)_dialog->getChoice(4, kDMDialogCommandSetViewport, 0, kDMDialogChoiceNone); 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); int16 saveSlot = dialog->runModalWithCurrentTarget(); Common::String saveDescription = dialog->getResultString(); if (saveDescription.empty()) saveDescription = "Nice save ^^"; delete dialog; if (saveSlot >= 0) { switch (getGameLanguage()) { // localized default: case Common::EN_ANY: _dialog->dialogDraw(nullptr, "SAVING GAME . . .", nullptr, nullptr, nullptr, nullptr, false, false, false); break; case Common::DE_DEU: _dialog->dialogDraw(nullptr, "SPIEL WIRD GESICHERT . . .", nullptr, nullptr, nullptr, nullptr, false, false, false); break; case Common::FR_FRA: _dialog->dialogDraw(nullptr, "UN MOMENT A SAUVEGARDER DU JEU...", nullptr, nullptr, nullptr, nullptr, false, false, false); break; } uint16 champHandObjWeight = 0; if (!_championMan->_leaderEmptyHanded) { champHandObjWeight = _dungeonMan->getObjectWeight(_championMan->_leaderHandObject); _championMan->_champions[_championMan->_leaderIndex]._load -= champHandObjWeight; } if (!writeCompleteSaveFile(saveSlot, saveDescription, saveAndPlayChoice)) { _dialog->dialogDraw(nullptr, "Unable to open file for saving", "OK", nullptr, nullptr, nullptr, false, false, false); _dialog->getChoice(1, kDMDialogCommandSetViewport, 0, kDMDialogChoiceNone); } if (!_championMan->_leaderEmptyHanded) { _championMan->_champions[_championMan->_leaderIndex]._load += champHandObjWeight; } } else saveAndPlayChoice = kCancel; } if (saveAndPlayChoice == kSaveAndQuit) { _eventMan->hideMouse(); endGame(false); } _restartGameAllowed = true; _menuMan->drawEnabledMenus(); _eventMan->hideMouse(); }