Пример #1
0
	void Process()
	{
#ifndef USING_GLES2
		if (g_Config.iRewindFlipFrequency != 0 && gpuStats.numFlips != 0)
			CheckRewindState();
#endif

		if (!needsProcess)
			return;
		needsProcess = false;

		if (!__KernelIsRunning())
		{
			ERROR_LOG(COMMON, "Savestate failure: Unable to load without kernel, this should never happen.");
			return;
		}

		std::vector<Operation> operations = Flush();
		SaveStart state;

		for (size_t i = 0, n = operations.size(); i < n; ++i)
		{
			Operation &op = operations[i];
			CChunkFileReader::Error result;
			bool callbackResult;
			std::string reason;

			I18NCategory *s = GetI18NCategory("Screen");
			// I couldn't stand the inconsistency.  But trying not to break old lang files.
			const char *i18nLoadFailure = s->T("Load savestate failed", "");
			const char *i18nSaveFailure = s->T("Save State Failed", "");
			if (strlen(i18nLoadFailure) == 0)
				i18nLoadFailure = s->T("Failed to load state");
			if (strlen(i18nSaveFailure) == 0)
				i18nSaveFailure = s->T("Failed to save state");

			switch (op.type)
			{
			case SAVESTATE_LOAD:
				INFO_LOG(COMMON, "Loading state from %s", op.filename.c_str());
				result = CChunkFileReader::Load(op.filename, REVISION, PPSSPP_GIT_VERSION, state, &reason);
				if (result == CChunkFileReader::ERROR_NONE) {
					osm.Show(s->T("Loaded State"), 2.0);
					callbackResult = true;
				} else if (result == CChunkFileReader::ERROR_BROKEN_STATE) {
					HandleFailure();
					osm.Show(i18nLoadFailure, 2.0);
					ERROR_LOG(COMMON, "Load state failure: %s", reason.c_str());
					callbackResult = false;
				} else {
					osm.Show(s->T(reason.c_str(), i18nLoadFailure), 2.0);
					callbackResult = false;
				}
				break;

			case SAVESTATE_SAVE:
				INFO_LOG(COMMON, "Saving state to %s", op.filename.c_str());
				result = CChunkFileReader::Save(op.filename, REVISION, PPSSPP_GIT_VERSION, state);
				if (result == CChunkFileReader::ERROR_NONE) {
					osm.Show(s->T("Saved State"), 2.0);
					callbackResult = true;
				} else if (result == CChunkFileReader::ERROR_BROKEN_STATE) {
					HandleFailure();
					osm.Show(i18nSaveFailure, 2.0);
					ERROR_LOG(COMMON, "Save state failure: %s", reason.c_str());
					callbackResult = false;
				} else {
					osm.Show(i18nSaveFailure, 2.0);
					callbackResult = false;
				}
				break;

			case SAVESTATE_VERIFY:
				INFO_LOG(COMMON, "Verifying save state system");
				callbackResult = CChunkFileReader::Verify(state) == CChunkFileReader::ERROR_NONE;
				break;

			case SAVESTATE_REWIND:
				INFO_LOG(COMMON, "Rewinding to recent savestate snapshot");
				result = rewindStates.Restore();
				if (result == CChunkFileReader::ERROR_NONE) {
					osm.Show(s->T("Loaded State"), 2.0);
					callbackResult = true;
				} else if (result == CChunkFileReader::ERROR_BROKEN_STATE) {
					// Cripes.  Good news is, we might have more.  Let's try those too, better than a reset.
					if (HandleFailure()) {
						// Well, we did rewind, even if too much...
						osm.Show(s->T("Loaded State"), 2.0);
						callbackResult = true;
					} else {
						osm.Show(i18nLoadFailure, 2.0);
						callbackResult = false;
					}
				} else {
					osm.Show(i18nLoadFailure, 2.0);
					callbackResult = false;
				}
				break;

			default:
				ERROR_LOG(COMMON, "Savestate failure: unknown operation type %d", op.type);
				callbackResult = false;
				break;
			}

			if (op.callback)
				op.callback(callbackResult, op.cbUserData);
		}
	}
Пример #2
0
	void Process()
	{
#ifndef MOBILE_DEVICE
		if (g_Config.iRewindFlipFrequency != 0 && gpuStats.numFlips != 0)
			CheckRewindState();
#endif

		if (!needsProcess)
			return;
		needsProcess = false;

		if (!__KernelIsRunning())
		{
			ERROR_LOG(COMMON, "Savestate failure: Unable to load without kernel, this should never happen.");
			return;
		}

		std::vector<Operation> operations = Flush();
		SaveStart state;

		for (size_t i = 0, n = operations.size(); i < n; ++i)
		{
			Operation &op = operations[i];
			CChunkFileReader::Error result;
			bool callbackResult;
			std::string callbackMessage;
			std::string reason;

			I18NCategory *sc = GetI18NCategory("Screen");
			const char *i18nLoadFailure = sc->T("Load savestate failed", "");
			const char *i18nSaveFailure = sc->T("Save State Failed", "");
			if (strlen(i18nLoadFailure) == 0)
				i18nLoadFailure = sc->T("Failed to load state");
			if (strlen(i18nSaveFailure) == 0)
				i18nSaveFailure = sc->T("Failed to save state");

			switch (op.type)
			{
			case SAVESTATE_LOAD:
				INFO_LOG(COMMON, "Loading state from %s", op.filename.c_str());
				result = CChunkFileReader::Load(op.filename, PPSSPP_GIT_VERSION, state, &reason);
				if (result == CChunkFileReader::ERROR_NONE) {
					callbackMessage = sc->T("Loaded State");
					callbackResult = true;
					hasLoadedState = true;
				} else if (result == CChunkFileReader::ERROR_BROKEN_STATE) {
					HandleFailure();
					callbackMessage = i18nLoadFailure;
					ERROR_LOG(COMMON, "Load state failure: %s", reason.c_str());
					callbackResult = false;
				} else {
					callbackMessage = sc->T(reason.c_str(), i18nLoadFailure);
					callbackResult = false;
				}
				break;

			case SAVESTATE_SAVE:
				INFO_LOG(COMMON, "Saving state to %s", op.filename.c_str());
				result = CChunkFileReader::Save(op.filename, g_paramSFO.GetValueString("TITLE"), PPSSPP_GIT_VERSION, state);
				if (result == CChunkFileReader::ERROR_NONE) {
					callbackMessage = sc->T("Saved State");
					callbackResult = true;
				} else if (result == CChunkFileReader::ERROR_BROKEN_STATE) {
					HandleFailure();
					callbackMessage = i18nSaveFailure;
					ERROR_LOG(COMMON, "Save state failure: %s", reason.c_str());
					callbackResult = false;
				} else {
					callbackMessage = i18nSaveFailure;
					callbackResult = false;
				}
				break;

			case SAVESTATE_VERIFY:
				callbackResult = CChunkFileReader::Verify(state) == CChunkFileReader::ERROR_NONE;
				if (callbackResult) {
					INFO_LOG(COMMON, "Verified save state system");
				} else {
					ERROR_LOG(COMMON, "Save state system verification failed");
				}
				break;

			case SAVESTATE_REWIND:
				INFO_LOG(COMMON, "Rewinding to recent savestate snapshot");
				result = rewindStates.Restore();
				if (result == CChunkFileReader::ERROR_NONE) {
					callbackMessage = sc->T("Loaded State");
					callbackResult = true;
					hasLoadedState = true;
				} else if (result == CChunkFileReader::ERROR_BROKEN_STATE) {
					// Cripes.  Good news is, we might have more.  Let's try those too, better than a reset.
					if (HandleFailure()) {
						// Well, we did rewind, even if too much...
						callbackMessage = sc->T("Loaded State");
						callbackResult = true;
						hasLoadedState = true;
					} else {
						callbackMessage = i18nLoadFailure;
						callbackResult = false;
					}
				} else {
					callbackMessage = i18nLoadFailure;
					callbackResult = false;
				}
				break;

			case SAVESTATE_SAVE_SCREENSHOT:
				callbackResult = TakeGameScreenshot(op.filename.c_str(), SCREENSHOT_JPG, SCREENSHOT_RENDER);
				if (!callbackResult) {
					ERROR_LOG(COMMON, "Failed to take a screenshot for the savestate! %s", op.filename.c_str());
				}
				break;

			default:
				ERROR_LOG(COMMON, "Savestate failure: unknown operation type %d", op.type);
				callbackResult = false;
				break;
			}

			if (op.callback)
				op.callback(callbackResult, callbackMessage, op.cbUserData);
		}
		if (operations.size()) {
			// Avoid triggering frame skipping due to slowdown
			__DisplaySetWasPaused();
		}
	}