Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
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();
}