Example #1
0
bool __KernelLoadExec(const char *filename, SceKernelLoadExecParam *param, std::string *error_string)
{
	// Wipe kernel here, loadexec should reset the entire system
	if (__KernelIsRunning())
		__KernelShutdown();

	__KernelModuleInit();
	__KernelInit();
	
	PSPFileInfo info = pspFileSystem.GetFileInfo(filename);

	u32 handle = pspFileSystem.OpenFile(filename, FILEACCESS_READ);

	u8 *temp = new u8[(int)info.size + 0x1000000];

	pspFileSystem.ReadFile(handle, temp, (size_t)info.size);

	Module *module = __KernelLoadModule(temp, 0, error_string);

	if (!module) {
		ERROR_LOG(LOADER, "Failed to load module %s", filename);
		return false;
	}

	mipsr4k.pc = module->nm.entry_addr;

	INFO_LOG(LOADER, "Module entry: %08x", mipsr4k.pc);

	delete [] temp;

	pspFileSystem.CloseFile(handle);

	SceKernelSMOption option;
	option.size = sizeof(SceKernelSMOption);
	option.attribute = PSP_THREAD_ATTR_USER;
	option.mpidstack = 2;
	option.priority = 0x20;
	option.stacksize = 0x40000;	// crazy? but seems to be the truth

	// Replace start options with module-specified values if they exist.
	if (module->nm.module_start_thread_attr != 0)
		option.attribute = module->nm.module_start_thread_attr;
	if (module->nm.module_start_thread_priority != 0)
		option.priority = module->nm.module_start_thread_priority;
	if (module->nm.module_start_thread_stacksize != 0)
		option.stacksize = module->nm.module_start_thread_stacksize;

	__KernelStartModule(module, (u32)strlen(filename) + 1, filename, &option);

	__KernelStartIdleThreads();
	return true;
}
Example #2
0
	void Enqueue(SaveState::Operation op)
	{
		std::lock_guard<std::recursive_mutex> guard(mutex);
		pending.push_back(op);

		// Don't actually run it until next CoreTiming::Advance().
		// It's possible there might be a duplicate but it won't hurt us.
		if (Core_IsInactive() && __KernelIsRunning()) {
			// Warning: this may run on a different thread.
			needsProcess = true;
			Process();
		} else {
			needsProcess = true;
		}
	}
Example #3
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);
		}
	}
Example #4
0
	void Process()
	{
		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];
			bool result;
			std::string reason;

			I18NCategory *s = GetI18NCategory("Screen"); 

			switch (op.type)
			{
			case SAVESTATE_LOAD:
				if (MIPSComp::jit)
					MIPSComp::jit->ClearCache();
				INFO_LOG(COMMON, "Loading state from %s", op.filename.c_str());
				result = CChunkFileReader::Load(op.filename, REVISION, state, &reason);
				if(result)
					osm.Show(s->T("Loaded State"), 2.0);
				else {
					osm.Show(s->T(reason.c_str(), "Load savestate failed"), 2.0);
				}
				break;

			case SAVESTATE_SAVE:
				if (MIPSComp::jit)
					MIPSComp::jit->ClearCache();
				INFO_LOG(COMMON, "Saving state to %s", op.filename.c_str());
				result = CChunkFileReader::Save(op.filename, REVISION, state);
				if(result)
					osm.Show(s->T("Saved State"), 2.0);
				else
					osm.Show(s->T("Save State Failed"), 2.0);
				break;

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

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

			if (op.callback != NULL)
				op.callback(result, op.cbUserData);
		}
	}
Example #5
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();
		}
	}