Esempio n. 1
0
static void __CheatStart() {
	__CheatStop();

	gameTitle = g_paramSFO.GetValueString("DISC_ID");

	activeCheatFile = GetSysDirectory(DIRECTORY_CHEATS) + gameTitle + ".ini";
	File::CreateFullPath(GetSysDirectory(DIRECTORY_CHEATS));

	if (!File::Exists(activeCheatFile)) {
		FILE *f = File::OpenCFile(activeCheatFile, "wb");
		if (f) {
			fwrite("\xEF\xBB\xBF", 1, 3, f);
			fclose(f);
		}
		if (!File::Exists(activeCheatFile)) {
			I18NCategory *err = GetI18NCategory("Error");
			osm.Show(err->T("Unable to create cheat file, disk may be full"));
		}

	}

	cheatEngine = new CWCheatEngine();
	cheatEngine->CreateCodeList();
	g_Config.bReloadCheats = false;
	cheatsEnabled = true;
}
Esempio n. 2
0
std::string GetThemeDir(const std::string& theme_name)
{
  std::string dir = File::GetUserPath(D_THEMES_IDX) + theme_name + "/";
  if (Exists(dir))
    return dir;

  // If the theme doesn't exist in the user dir, load from shared directory
  dir = GetSysDirectory() + THEMES_DIR "/" + theme_name + "/";
  if (Exists(dir))
    return dir;

  // If the theme doesn't exist at all, load the default theme
  return GetSysDirectory() + THEMES_DIR "/" DEFAULT_THEME_DIR "/";
}
Esempio n. 3
0
void CWCheatEngine::CreateCheatFile() {
	activeCheatFile = GetSysDirectory(DIRECTORY_CHEATS) + gameTitle + ".ini";
	File::CreateFullPath(GetSysDirectory(DIRECTORY_CHEATS));

	if (!File::Exists(activeCheatFile)) {
		FILE *f = File::OpenCFile(activeCheatFile, "wb");
		if (f) {
			fwrite("\xEF\xBB\xBF\n", 1, 4, f);
			fclose(f);
		}
		if (!File::Exists(activeCheatFile)) {
			I18NCategory *err = GetI18NCategory("Error");
			host->NotifyUserMessage(err->T("Unable to create cheat file, disk may be full"));
		}
	}
}
Esempio n. 4
0
static void __CheatStart() {
	__CheatStop();

	gameTitle = g_paramSFO.GetValueString("DISC_ID");

	activeCheatFile = GetSysDirectory(DIRECTORY_CHEATS) + gameTitle + ".ini";
	File::CreateFullPath(GetSysDirectory(DIRECTORY_CHEATS));

	if (!File::Exists(activeCheatFile)) {
		File::CreateEmptyFile(activeCheatFile);
	}

	cheatEngine = new CWCheatEngine();
	cheatEngine->CreateCodeList();
	g_Config.bReloadCheats = false;
	cheatsEnabled = true;
}
Esempio n. 5
0
u32 DiskCachingFileLoaderCache::CountCachedFiles() {
	std::string dir = cacheDir_;
	if (dir.empty()) {
		dir = GetSysDirectory(DIRECTORY_CACHE);
	}

	std::vector<FileInfo> files;
	return (u32)getFilesInDir(dir.c_str(), &files, "ppdc:");
}
Esempio n. 6
0
std::string GetThemeDir(const std::string& theme_name)
{
	std::string dir = File::GetUserPath(D_THEMES_IDX) + theme_name + "/";

	// If theme does not exist in user's dir load from shared directory
	if (!File::Exists(dir))
		dir = GetSysDirectory() + THEMES_DIR "/" + theme_name + "/";

	return dir;
}
Esempio n. 7
0
std::string DiskCachingFileLoaderCache::MakeCacheFilePath(const std::string &path) {
	std::string dir = cacheDir_;
	if (dir.empty()) {
		dir = GetSysDirectory(DIRECTORY_CACHE);
	}

	if (!File::Exists(dir)) {
		File::CreateFullPath(dir);
	}

	return dir + "/" + MakeCacheFilename(path);
}
Esempio n. 8
0
u64 DiskCachingFileLoaderCache::FreeDiskSpace() {
	std::string dir = cacheDir_;
	if (dir.empty()) {
		dir = GetSysDirectory(DIRECTORY_CACHE);
	}

	uint64_t result = 0;
	if (free_disk_space(dir, result)) {
		return result;
	}

	// We can't know for sure how much is free, so we have to assume none.
	return 0;
}
Esempio n. 9
0
std::vector<std::string> GameInfo::GetSaveDataDirectories() {
	std::string memc = GetSysDirectory(DIRECTORY_SAVEDATA);

	std::vector<FileInfo> dirs;
	getFilesInDir(memc.c_str(), &dirs);

	std::vector<std::string> directories;
	for (size_t i = 0; i < dirs.size(); i++) {
		if (startsWith(dirs[i].name, id)) {
			directories.push_back(dirs[i].fullName);
		}
	}

	return directories;
}
Esempio n. 10
0
void DiskCachingFileLoaderCache::GarbageCollectCacheFiles(u64 goalBytes) {
	// We attempt to free up at least enough files from the cache to get goalBytes more space.
	const std::vector<std::string> usedPaths = DiskCachingFileLoader::GetCachedPathsInUse();
	std::set<std::string> used;
	for (std::string path : usedPaths) {
		used.insert(MakeCacheFilename(path));
	}

	std::string dir = cacheDir_;
	if (dir.empty()) {
		dir = GetSysDirectory(DIRECTORY_CACHE);
	}

	std::vector<FileInfo> files;
	getFilesInDir(dir.c_str(), &files, "ppdc:");

	u64 remaining = goalBytes;
	// TODO: Could order by LRU or etc.
	for (FileInfo file : files) {
		if (file.isDirectory) {
			continue;
		}
		if (used.find(file.name) != used.end()) {
			// In use, must leave alone.
			continue;
		}

#ifdef _WIN32
		const std::wstring w32path = ConvertUTF8ToWString(file.fullName);
		bool success = DeleteFileW(w32path.c_str()) != 0;
#else
		bool success = unlink(file.fullName.c_str()) == 0;
#endif

		if (success) {
			if (file.size > remaining) {
				// We're done, huzzah.
				break;
			}

			// A little bit more.
			remaining -= file.size;
		}
	}

	// At this point, we've done all we can.
}
Esempio n. 11
0
void TextureReplacer::NotifyConfigChanged() {
	gameID_ = g_paramSFO.GetValueString("DISC_ID");

	enabled_ = !gameID_.empty() && (g_Config.bReplaceTextures || g_Config.bSaveNewTextures);
	if (enabled_) {
		basePath_ = GetSysDirectory(DIRECTORY_TEXTURES) + gameID_ + "/";

		// If we're saving, auto-create the directory.
		if (g_Config.bSaveNewTextures && !File::Exists(basePath_ + NEW_TEXTURE_DIR)) {
			File::CreateFullPath(basePath_ + NEW_TEXTURE_DIR);
		}

		enabled_ = File::Exists(basePath_) && File::IsDirectory(basePath_);
	}

	if (enabled_) {
		enabled_ = LoadIni();
	}
}
Esempio n. 12
0
void Compatibility::Load(const std::string &gameID) {
	Clear();

	{
		IniFile compat;
		// This loads from assets.
		if (compat.LoadFromVFS("compat.ini")) {
			CheckSettings(compat, gameID);
		}
	}

	{
		IniFile compat2;
		// This one is user-editable. Need to load it after the system one.
		std::string path = GetSysDirectory(DIRECTORY_SYSTEM) + "compat.ini";
		if (compat2.Load(path)) {
			CheckSettings(compat2, gameID);
		}
	}
}
Esempio n. 13
0
bool GameManager::Uninstall(std::string name) {
	if (name.empty()) {
		ERROR_LOG(HLE, "Cannot remove an empty-named game");
		return false;
	}
	std::string gameDir = GetSysDirectory(DIRECTORY_GAME) + name;
	INFO_LOG(HLE, "Deleting %s", gameDir.c_str());
	if (!File::Exists(gameDir)) {
		ERROR_LOG(HLE, "Game %s not installed, cannot uninstall", name.c_str());
		return false;
	}

	bool success = File::DeleteDirRecursively(gameDir);
	if (success) {
		INFO_LOG(HLE, "Successfully deleted game %s", name.c_str());
		g_Config.CleanRecent();
		return true;
	} else {
		ERROR_LOG(HLE, "Failed to delete game %s", name.c_str());
		return false;
	}
}
Esempio n. 14
0
// Run this at startup time. Please use GetSysDirectory if you need to query where folders are.
void InitSysDirectories() {
	if (!g_Config.memCardDirectory.empty() && !g_Config.flash0Directory.empty())
		return;

	const std::string path = ConvertWStringToUTF8(File::GetExeDirectory());

	// Mount a filesystem
	g_Config.flash0Directory = path + "/flash0/";

	// Detect the "My Documents"(XP) or "Documents"(on Vista/7/8) folder.
	wchar_t myDocumentsPath[MAX_PATH];
	const HRESULT result = SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, myDocumentsPath);
	const std::string myDocsPath = ConvertWStringToUTF8(myDocumentsPath) + "/PPSSPP/";

	const std::string installedFile = path + "/installed.txt";
	const bool installed = File::Exists(installedFile);

	// If installed.txt exists(and we can determine the Documents directory)
	if (installed && (result == S_OK))	{
		std::ifstream inputFile(ConvertUTF8ToWString(installedFile));

		if (!inputFile.fail() && inputFile.is_open()) {
			std::string tempString;

			std::getline(inputFile, tempString);

			// Skip UTF-8 encoding bytes if there are any. There are 3 of them.
			if (tempString.substr(0, 3) == "\xEF\xBB\xBF")
				tempString = tempString.substr(3);

			g_Config.memCardDirectory = tempString;
		}
		inputFile.close();

		// Check if the file is empty first, before appending the slash.
		if (g_Config.memCardDirectory.empty())
			g_Config.memCardDirectory = myDocsPath;

		size_t lastSlash = g_Config.memCardDirectory.find_last_of("/");
		if (lastSlash != (g_Config.memCardDirectory.length() - 1))
			g_Config.memCardDirectory.append("/");
	} else {
		g_Config.memCardDirectory = path + "/memstick/";
	}

	// Create the memstickpath before trying to write to it, and fall back on Documents yet again
	// if we can't make it.
	if (!File::Exists(g_Config.memCardDirectory)) {
		if (!File::CreateDir(g_Config.memCardDirectory))
			g_Config.memCardDirectory = myDocsPath;
	}

	const std::string testFile = "/_writable_test.$$$";

	// If any directory is read-only, fall back to the Documents directory.
	// We're screwed anyway if we can't write to Documents, or can't detect it.
	if (!File::CreateEmptyFile(g_Config.memCardDirectory + testFile))
		g_Config.memCardDirectory = myDocsPath;

	// Clean up our mess.
	if (File::Exists(g_Config.memCardDirectory + testFile))
		File::Delete(g_Config.memCardDirectory + testFile);

	if (g_Config.currentDirectory.empty()) {
		g_Config.currentDirectory = GetSysDirectory(DIRECTORY_GAME);
	}
}
Esempio n. 15
0
GPU_Vulkan::GPU_Vulkan(GraphicsContext *gfxCtx, Draw::DrawContext *draw)
	: GPUCommon(gfxCtx, draw),
		vulkan_((VulkanContext *)gfxCtx->GetAPIContext()),
		drawEngine_(vulkan_, draw),
		depalShaderCache_(draw, vulkan_),
		vulkan2D_(vulkan_) {
	UpdateVsyncInterval(true);
	CheckGPUFeatures();

	shaderManagerVulkan_ = new ShaderManagerVulkan(vulkan_);
	pipelineManager_ = new PipelineManagerVulkan(vulkan_);
	framebufferManagerVulkan_ = new FramebufferManagerVulkan(draw, vulkan_);
	framebufferManager_ = framebufferManagerVulkan_;
	textureCacheVulkan_ = new TextureCacheVulkan(draw, vulkan_);
	textureCache_ = textureCacheVulkan_;
	drawEngineCommon_ = &drawEngine_;
	shaderManager_ = shaderManagerVulkan_;

	drawEngine_.SetTextureCache(textureCacheVulkan_);
	drawEngine_.SetFramebufferManager(framebufferManagerVulkan_);
	drawEngine_.SetShaderManager(shaderManagerVulkan_);
	drawEngine_.SetPipelineManager(pipelineManager_);
	framebufferManagerVulkan_->SetVulkan2D(&vulkan2D_);
	framebufferManagerVulkan_->Init();
	framebufferManagerVulkan_->SetTextureCache(textureCacheVulkan_);
	framebufferManagerVulkan_->SetDrawEngine(&drawEngine_);
	framebufferManagerVulkan_->SetShaderManager(shaderManagerVulkan_);
	textureCacheVulkan_->SetDepalShaderCache(&depalShaderCache_);
	textureCacheVulkan_->SetFramebufferManager(framebufferManagerVulkan_);
	textureCacheVulkan_->SetShaderManager(shaderManagerVulkan_);
	textureCacheVulkan_->SetDrawEngine(&drawEngine_);
	textureCacheVulkan_->SetVulkan2D(&vulkan2D_);

	InitDeviceObjects();

	// Sanity check gstate
	if ((int *)&gstate.transferstart - (int *)&gstate != 0xEA) {
		ERROR_LOG(G3D, "gstate has drifted out of sync!");
	}

	BuildReportingInfo();
	// Update again after init to be sure of any silly driver problems.
	UpdateVsyncInterval(true);

	textureCacheVulkan_->NotifyConfigChanged();
	if (vulkan_->GetFeaturesEnabled().wideLines) {
		drawEngine_.SetLineWidth(PSP_CoreParameter().renderWidth / 480.0f);
	}

	// Load shader cache.
	std::string discID = g_paramSFO.GetDiscID();
	if (discID.size()) {
		File::CreateFullPath(GetSysDirectory(DIRECTORY_APP_CACHE));
		shaderCachePath_ = GetSysDirectory(DIRECTORY_APP_CACHE) + "/" + discID + ".vkshadercache";
		shaderCacheLoaded_ = false;

		std::thread th([&] {
			LoadCache(shaderCachePath_);
			shaderCacheLoaded_ = true;
		});
		th.detach();
	}
}
Esempio n. 16
0
int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow)
{
	setCurrentThreadName("Main");

	// Windows Vista and above: alert Windows that PPSSPP is DPI aware,
	// so that we don't flicker in fullscreen on some PCs.
	MakePPSSPPDPIAware();

	// FMA3 support in the 2013 CRT is broken on Vista and Windows 7 RTM (fixed in SP1). Just disable it.
#ifdef _M_X64
	_set_FMA3_enable(0);
#endif

	EnableCrashingOnCrashes();

	wchar_t modulePath[MAX_PATH];
	GetModuleFileName(NULL, modulePath, MAX_PATH);
	for (size_t i = wcslen(modulePath) - 1; i > 0; i--) {
		if (modulePath[i] == '\\') {
			modulePath[i] = 0;
			break;
		}
	}
	SetCurrentDirectory(modulePath);
	// GetCurrentDirectory(MAX_PATH, modulePath);  // for checking in the debugger

#ifndef _DEBUG
	bool showLog = false;
#else
	bool showLog = false;
#endif

	VFSRegister("", new DirectoryAssetReader("assets/"));
	VFSRegister("", new DirectoryAssetReader(""));

	wchar_t lcCountry[256];

	// LOCALE_SNAME is only available in WinVista+
	// Really should find a way to do this in XP too :/
	if (0 != GetLocaleInfo(LOCALE_NAME_USER_DEFAULT, LOCALE_SNAME, lcCountry, 256)) {
		langRegion = ConvertWStringToUTF8(lcCountry);
		for (size_t i = 0; i < langRegion.size(); i++) {
			if (langRegion[i] == '-')
				langRegion[i] = '_';
		}
	} else {
		langRegion = "en_US";
	}

	osName = GetWindowsVersion() + " " + GetWindowsSystemArchitecture();

	const char *configFilename = NULL;
	const char *configOption = "--config=";

	const char *controlsConfigFilename = NULL;
	const char *controlsOption = "--controlconfig=";

	for (int i = 1; i < __argc; ++i)
	{
		if (__argv[i][0] == '\0')
			continue;
		if (__argv[i][0] == '-')
		{
			if (!strncmp(__argv[i], configOption, strlen(configOption)) && strlen(__argv[i]) > strlen(configOption)) {
				configFilename = __argv[i] + strlen(configOption);
			}
			if (!strncmp(__argv[i], controlsOption, strlen(controlsOption)) && strlen(__argv[i]) > strlen(controlsOption)) {
				controlsConfigFilename = __argv[i] + strlen(controlsOption);
			}
		}
	}

	// On Win32 it makes more sense to initialize the system directories here 
	// because the next place it was called was in the EmuThread, and it's too late by then.
	InitSysDirectories();

	// Load config up here, because those changes below would be overwritten
	// if it's not loaded here first.
	g_Config.AddSearchPath("");
	g_Config.AddSearchPath(GetSysDirectory(DIRECTORY_SYSTEM));
	g_Config.SetDefaultPath(GetSysDirectory(DIRECTORY_SYSTEM));
	g_Config.Load(configFilename, controlsConfigFilename);

	bool debugLogLevel = false;

	// The rest is handled in NativeInit().
	for (int i = 1; i < __argc; ++i)
	{
		if (__argv[i][0] == '\0')
			continue;

		if (__argv[i][0] == '-')
		{
			switch (__argv[i][1])
			{
			case 'l':
				showLog = true;
				g_Config.bEnableLogging = true;
				break;
			case 's':
				g_Config.bAutoRun = false;
				g_Config.bSaveSettings = false;
				break;
			case 'd':
				debugLogLevel = true;
				break;
			}

			if (!strncmp(__argv[i], "--fullscreen", strlen("--fullscreen")))
				g_Config.bFullScreen = true;

			if (!strncmp(__argv[i], "--windowed", strlen("--windowed")))
				g_Config.bFullScreen = false;
		}
	}
#ifdef _DEBUG
	g_Config.bEnableLogging = true;
#endif

	LogManager::Init();
	// Consider at least the following cases before changing this code:
	//   - By default in Release, the console should be hidden by default even if logging is enabled.
	//   - By default in Debug, the console should be shown by default.
	//   - The -l switch is expected to show the log console, REGARDLESS of config settings.
	//   - It should be possible to log to a file without showing the console.
	LogManager::GetInstance()->GetConsoleListener()->Init(showLog, 150, 120, "PPSSPP Debug Console");
	
	if (debugLogLevel)
		LogManager::GetInstance()->SetAllLogLevels(LogTypes::LDEBUG);

	//Windows, API init stuff
	INITCOMMONCONTROLSEX comm;
	comm.dwSize = sizeof(comm);
	comm.dwICC = ICC_BAR_CLASSES | ICC_LISTVIEW_CLASSES | ICC_TAB_CLASSES;
	InitCommonControlsEx(&comm);
	timeBeginPeriod(1);
	MainWindow::Init(_hInstance);

	g_hPopupMenus = LoadMenu(_hInstance, (LPCWSTR)IDR_POPUPMENUS);

	MainWindow::Show(_hInstance, iCmdShow);

	HWND hwndMain = MainWindow::GetHWND();
	HWND hwndDisplay = MainWindow::GetDisplayHWND();
	
	//initialize custom controls
	CtrlDisAsmView::init();
	CtrlMemView::init();
	CtrlRegisterList::init();
	CGEDebugger::Init();

	DialogManager::AddDlg(vfpudlg = new CVFPUDlg(_hInstance, hwndMain, currentDebugMIPS));

	host = new WindowsHost(hwndMain, hwndDisplay);
	host->SetWindowTitle(0);

	MainWindow::CreateDebugWindows();

	// Emu thread is always running!
	EmuThread_Start();
	InputDevice::BeginPolling();

	HACCEL hAccelTable = LoadAccelerators(_hInstance, (LPCTSTR)IDR_ACCELS);
	HACCEL hDebugAccelTable = LoadAccelerators(_hInstance, (LPCTSTR)IDR_DEBUGACCELS);

	//so.. we're at the message pump of the GUI thread
	for (MSG msg; GetMessage(&msg, NULL, 0, 0); )	// for no quit
	{
		if (msg.message == WM_KEYDOWN)
		{
			//hack to enable/disable menu command accelerate keys
			MainWindow::UpdateCommands();

			//hack to make it possible to get to main window from floating windows with Esc
			if (msg.hwnd != hwndMain && msg.wParam == VK_ESCAPE)
				BringWindowToTop(hwndMain);
		}

		//Translate accelerators and dialog messages...
		HWND wnd;
		HACCEL accel;
		switch (g_activeWindow)
		{
		case WINDOW_MAINWINDOW:
			wnd = hwndMain;
			accel = hAccelTable;
			break;
		case WINDOW_CPUDEBUGGER:
			wnd = disasmWindow[0] ? disasmWindow[0]->GetDlgHandle() : 0;
			accel = hDebugAccelTable;
			break;
		case WINDOW_GEDEBUGGER:
		default:
			wnd = 0;
			accel = 0;
			break;
		}

		if (!TranslateAccelerator(wnd, accel, &msg))
		{
			if (!DialogManager::IsDialogMessage(&msg))
			{
				//and finally translate and dispatch
				TranslateMessage(&msg);
				DispatchMessage(&msg);
			}
		}
	}

	VFSShutdown();

	InputDevice::StopPolling();
	EmuThread_Stop();

	MainWindow::DestroyDebugWindows();
	DialogManager::DestroyAll();
	timeEndPeriod(1);
	delete host;
	g_Config.Save();
	LogManager::Shutdown();
	return 0;
}
Esempio n. 17
0
int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow)
{
	setCurrentThreadName("Main");

	CoInitializeEx(NULL, COINIT_MULTITHREADED);

#ifdef _DEBUG
	_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endif
	PROFILE_INIT();

#if defined(_M_X64) && defined(_MSC_VER) && _MSC_VER < 1900
	// FMA3 support in the 2013 CRT is broken on Vista and Windows 7 RTM (fixed in SP1). Just disable it.
	_set_FMA3_enable(0);
#endif

	EnableCrashingOnCrashes();

#ifndef _DEBUG
	bool showLog = false;
#else
	bool showLog = true;
#endif

	const std::string &exePath = File::GetExeDirectory();
	VFSRegister("", new DirectoryAssetReader((exePath + "/assets/").c_str()));
	VFSRegister("", new DirectoryAssetReader(exePath.c_str()));

	langRegion = GetDefaultLangRegion();
	osName = GetWindowsVersion() + " " + GetWindowsSystemArchitecture();

	char configFilename[MAX_PATH] = { 0 };
	const std::wstring configOption = L"--config=";

	char controlsConfigFilename[MAX_PATH] = { 0 };
	const std::wstring controlsOption = L"--controlconfig=";

	std::vector<std::wstring> wideArgs = GetWideCmdLine();

	for (size_t i = 1; i < wideArgs.size(); ++i) {
		if (wideArgs[i][0] == L'\0')
			continue;
		if (wideArgs[i][0] == L'-') {
			if (wideArgs[i].find(configOption) != std::wstring::npos && wideArgs[i].size() > configOption.size()) {
				const std::wstring tempWide = wideArgs[i].substr(configOption.size());
				const std::string tempStr = ConvertWStringToUTF8(tempWide);
				std::strncpy(configFilename, tempStr.c_str(), MAX_PATH);
			}

			if (wideArgs[i].find(controlsOption) != std::wstring::npos && wideArgs[i].size() > controlsOption.size()) {
				const std::wstring tempWide = wideArgs[i].substr(controlsOption.size());
				const std::string tempStr = ConvertWStringToUTF8(tempWide);
				std::strncpy(controlsConfigFilename, tempStr.c_str(), MAX_PATH);
			}
		}
	}

	// On Win32 it makes more sense to initialize the system directories here 
	// because the next place it was called was in the EmuThread, and it's too late by then.
	InitSysDirectories();

	// Load config up here, because those changes below would be overwritten
	// if it's not loaded here first.
	g_Config.AddSearchPath("");
	g_Config.AddSearchPath(GetSysDirectory(DIRECTORY_SYSTEM));
	g_Config.SetDefaultPath(GetSysDirectory(DIRECTORY_SYSTEM));
	g_Config.Load(configFilename, controlsConfigFilename);

	bool debugLogLevel = false;

	const std::wstring gpuBackend = L"--graphics=";

	// The rest is handled in NativeInit().
	for (size_t i = 1; i < wideArgs.size(); ++i) {
		if (wideArgs[i][0] == L'\0')
			continue;

		if (wideArgs[i][0] == L'-') {
			switch (wideArgs[i][1]) {
			case L'l':
				showLog = true;
				g_Config.bEnableLogging = true;
				break;
			case L's':
				g_Config.bAutoRun = false;
				g_Config.bSaveSettings = false;
				break;
			case L'd':
				debugLogLevel = true;
				break;
			}

			if (wideArgs[i] == L"--fullscreen")
				g_Config.bFullScreen = true;

			if (wideArgs[i] == L"--windowed")
				g_Config.bFullScreen = false;

			if (wideArgs[i].find(gpuBackend) != std::wstring::npos && wideArgs[i].size() > gpuBackend.size()) {
				const std::wstring restOfOption = wideArgs[i].substr(gpuBackend.size());

				// Force software rendering off, as picking directx9 or gles implies HW acceleration.
				// Once software rendering supports Direct3D9/11, we can add more options for software,
				// such as "software-gles", "software-d3d9", and "software-d3d11", or something similar.
				// For now, software rendering force-activates OpenGL.
				if (restOfOption == L"directx9") {
					g_Config.iGPUBackend = GPU_BACKEND_DIRECT3D9;
					g_Config.bSoftwareRendering = false;
				} else if (restOfOption == L"gles") {
					g_Config.iGPUBackend = GPU_BACKEND_OPENGL;
					g_Config.bSoftwareRendering = false;
				} else if (restOfOption == L"software") {
					g_Config.iGPUBackend = GPU_BACKEND_OPENGL;
					g_Config.bSoftwareRendering = true;
				}
			}
		}
	}
#ifdef _DEBUG
	g_Config.bEnableLogging = true;
#endif

	if (iCmdShow == SW_MAXIMIZE) {
		// Consider this to mean --fullscreen.
		g_Config.bFullScreen = true;
	}

	LogManager::Init();
	// Consider at least the following cases before changing this code:
	//   - By default in Release, the console should be hidden by default even if logging is enabled.
	//   - By default in Debug, the console should be shown by default.
	//   - The -l switch is expected to show the log console, REGARDLESS of config settings.
	//   - It should be possible to log to a file without showing the console.
	LogManager::GetInstance()->GetConsoleListener()->Init(showLog, 150, 120, "PPSSPP Debug Console");
	
	if (debugLogLevel)
		LogManager::GetInstance()->SetAllLogLevels(LogTypes::LDEBUG);

	//Windows, API init stuff
	INITCOMMONCONTROLSEX comm;
	comm.dwSize = sizeof(comm);
	comm.dwICC = ICC_BAR_CLASSES | ICC_LISTVIEW_CLASSES | ICC_TAB_CLASSES;
	InitCommonControlsEx(&comm);
	timeBeginPeriod(1);
	MainWindow::Init(_hInstance);

	g_hPopupMenus = LoadMenu(_hInstance, (LPCWSTR)IDR_POPUPMENUS);

	MainWindow::Show(_hInstance);

	HWND hwndMain = MainWindow::GetHWND();
	HWND hwndDisplay = MainWindow::GetDisplayHWND();
	
	//initialize custom controls
	CtrlDisAsmView::init();
	CtrlMemView::init();
	CtrlRegisterList::init();
	CGEDebugger::Init();

	DialogManager::AddDlg(vfpudlg = new CVFPUDlg(_hInstance, hwndMain, currentDebugMIPS));

	host = new WindowsHost(_hInstance, hwndMain, hwndDisplay);
	host->SetWindowTitle(0);

	MainWindow::CreateDebugWindows();

	const bool minimized = iCmdShow == SW_MINIMIZE || iCmdShow == SW_SHOWMINIMIZED || iCmdShow == SW_SHOWMINNOACTIVE;
	if (minimized) {
		MainWindow::Minimize();
	}

	// Emu thread is always running!
	EmuThread_Start();
	InputDevice::BeginPolling();

	HACCEL hAccelTable = LoadAccelerators(_hInstance, (LPCTSTR)IDR_ACCELS);
	HACCEL hDebugAccelTable = LoadAccelerators(_hInstance, (LPCTSTR)IDR_DEBUGACCELS);

	//so.. we're at the message pump of the GUI thread
	for (MSG msg; GetMessage(&msg, NULL, 0, 0); )	// for no quit
	{
		if (msg.message == WM_KEYDOWN)
		{
			//hack to enable/disable menu command accelerate keys
			MainWindow::UpdateCommands();
			 
			//hack to make it possible to get to main window from floating windows with Esc
			if (msg.hwnd != hwndMain && msg.wParam == VK_ESCAPE)
				BringWindowToTop(hwndMain);
		}

		//Translate accelerators and dialog messages...
		HWND wnd;
		HACCEL accel;
		switch (g_activeWindow)
		{
		case WINDOW_MAINWINDOW:
			wnd = hwndMain;
			accel = hAccelTable;
			break;
		case WINDOW_CPUDEBUGGER:
			wnd = disasmWindow[0] ? disasmWindow[0]->GetDlgHandle() : 0;
			accel = hDebugAccelTable;
			break;
		case WINDOW_GEDEBUGGER:
		default:
			wnd = 0;
			accel = 0;
			break;
		}

		if (!TranslateAccelerator(wnd, accel, &msg))
		{
			if (!DialogManager::IsDialogMessage(&msg))
			{
				//and finally translate and dispatch
				TranslateMessage(&msg);
				DispatchMessage(&msg);
			}
		}
	}

	VFSShutdown();

	InputDevice::StopPolling();
	EmuThread_Stop();

	MainWindow::DestroyDebugWindows();
	DialogManager::DestroyAll();
	timeEndPeriod(1);
	delete host;

	g_Config.Save();
	LogManager::Shutdown();

	if (g_Config.bRestartRequired) {
		W32Util::ExitAndRestart();
	}

	CoUninitialize();

	return 0;
}
Esempio n. 18
0
bool GameManager::IsGameInstalled(std::string name) {
	std::string pspGame = GetSysDirectory(DIRECTORY_GAME);
	return File::Exists(pspGame + name);
}
Esempio n. 19
0
bool GameManager::InstallGame(std::string zipfile, bool deleteAfter) {
	if (installInProgress_) {
		ERROR_LOG(HLE, "Cannot have two installs in progress at the same time");
		return false;
	}

	installInProgress_ = true;

	std::string pspGame = GetSysDirectory(DIRECTORY_GAME);
	INFO_LOG(HLE, "Installing %s into %s", zipfile.c_str(), pspGame.c_str());

	if (!File::Exists(zipfile)) {
		ERROR_LOG(HLE, "ZIP file %s doesn't exist", zipfile.c_str());
		return false;
	}

	int error;
#ifdef _WIN32
	struct zip *z = zip_open(ConvertUTF8ToWString(zipfile).c_str(), 0, &error);
#elif defined(__SYMBIAN32__)
	// If zipfile is non-ascii, this may not function correctly. Other options?
	struct zip *z = zip_open(std::wstring(zipfile.begin(), zipfile.end()).c_str(), 0, &error);
#else
	struct zip *z = zip_open(zipfile.c_str(), 0, &error);
#endif
	if (!z) {
		ERROR_LOG(HLE, "Failed to open ZIP file %s, error code=%i", zipfile.c_str(), error);
		return false;
	}

	int numFiles = zip_get_num_files(z);

	// First, find all the directories, and precreate them before we fill in with files.
	// Also, verify that this is a PSP zip file with the correct layout.
	bool isPSP = false;
	int stripChars = 0;

	for (int i = 0; i < numFiles; i++) {
		const char *fn = zip_get_name(z, i, 0);
		std::string zippedName = fn;
		if (zippedName.find("EBOOT.PBP") != std::string::npos) {
			int slashCount = 0;
			int lastSlashLocation = -1;
			int slashLocation = -1;
			for (size_t i = 0; i < zippedName.size(); i++) {
				if (zippedName[i] == '/') {
					slashCount++;
					slashLocation = lastSlashLocation;
					lastSlashLocation = i;
				}
			}
			if (slashCount >= 1 && (!isPSP || slashLocation < stripChars + 1)) {
				stripChars = slashLocation + 1;
				isPSP = true;
			} else {
				INFO_LOG(HLE, "Wrong number of slashes (%i) in %s", slashCount, zippedName.c_str());
			}
		}
	}

	if (!isPSP) {
		ERROR_LOG(HLE, "File not a PSP game, no EBOOT.PBP found.");
		return false;
	}

	size_t allBytes = 0, bytesCopied = 0;

	// Create all the directories in one pass
	std::set<std::string> createdDirs;
	for (int i = 0; i < numFiles; i++) {
		const char *fn = zip_get_name(z, i, 0);
		std::string zippedName = fn;
		std::string outFilename = pspGame + zippedName.substr(stripChars);
		bool isDir = *outFilename.rbegin() == '/';
		if (!isDir && outFilename.find("/") != std::string::npos) {
			outFilename = outFilename.substr(0, outFilename.rfind('/'));
		}
		if (createdDirs.find(outFilename) == createdDirs.end()) {
			File::CreateFullPath(outFilename.c_str());
			createdDirs.insert(outFilename);
		}
		if (!isDir) {
			struct zip_stat zstat;
			if (zip_stat_index(z, i, 0, &zstat) >= 0) {
				allBytes += zstat.size;
			}
		}
	}

	// Now, loop through again in a second pass, writing files.
	for (int i = 0; i < numFiles; i++) {
		const char *fn = zip_get_name(z, i, 0);
		// Note that we do NOT write files that are not in a directory, to avoid random
		// README files etc.
		if (strstr(fn, "/") != 0) {
			struct zip_stat zstat;
			zip_stat_index(z, i, 0, &zstat);
			size_t size = zstat.size;

			fn += stripChars;

			std::string outFilename = pspGame + fn;
			bool isDir = *outFilename.rbegin() == '/';
			if (isDir)
				continue;

			if (i < 10) {
				INFO_LOG(HLE, "Writing %i bytes to %s", (int)size, outFilename.c_str());
			}

			zip_file *zf = zip_fopen_index(z, i, 0);
			FILE *f = fopen(outFilename.c_str(), "wb");
			if (f) {
				size_t pos = 0;
				const size_t blockSize = 1024 * 128;
				u8 *buffer = new u8[blockSize];
				while (pos < size) {
					size_t bs = std::min(blockSize, pos - size);
					zip_fread(zf, buffer, bs);
					size_t written = fwrite(buffer, 1, bs, f);
					if (written != bs) {
						ERROR_LOG(HLE, "Wrote %i bytes out of %i - Disk full?", (int)written, (int)bs);
						// TODO: What do we do?
					}
					pos += bs;

					bytesCopied += bs;
					installProgress_ = (float)bytesCopied / (float)allBytes;
					// printf("Progress: %f\n", installProgress_);
				}
				zip_fclose(zf);
				fclose(f);
				delete [] buffer;
			} else {
				ERROR_LOG(HLE, "Failed to open file for writing");
			}
		}
	}
	INFO_LOG(HLE, "Extracted %i files (%i bytes).", numFiles, (int)bytesCopied);

	zip_close(z);
	installProgress_ = 1.0f;
	installInProgress_ = false;
	if (deleteAfter) {
		deleteFile(zipfile.c_str());
	}
	InstallDone();
	return true;
}
Esempio n. 20
0
// Run this at startup time. Please use GetSysDirectory if you need to query where folders are.
void InitSysDirectories() {
	if (!g_Config.memStickDirectory.empty() && !g_Config.flash0Directory.empty())
		return;

	const std::string path = File::GetExeDirectory();

	// Mount a filesystem
	g_Config.flash0Directory = path + "flash0/";

	// Detect the "My Documents"(XP) or "Documents"(on Vista/7/8) folder.
#if PPSSPP_PLATFORM(UWP)
	const std::string myDocsPath = "";  // TODO UWP
	const HRESULT result = E_FAIL;

#else
	wchar_t myDocumentsPath[MAX_PATH];
	const HRESULT result = SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, myDocumentsPath);
	const std::string myDocsPath = ConvertWStringToUTF8(myDocumentsPath) + "/PPSSPP/";
#endif
	const std::string installedFile = path + "installed.txt";
	const bool installed = File::Exists(installedFile);

	// If installed.txt exists(and we can determine the Documents directory)
	if (installed && (result == S_OK))	{
		std::ifstream inputFile(ConvertUTF8ToWString(installedFile));

		if (!inputFile.fail() && inputFile.is_open()) {
			std::string tempString;

			std::getline(inputFile, tempString);

			// Skip UTF-8 encoding bytes if there are any. There are 3 of them.
			if (tempString.substr(0, 3) == "\xEF\xBB\xBF")
				tempString = tempString.substr(3);

			g_Config.memStickDirectory = tempString;
		}
		inputFile.close();

		// Check if the file is empty first, before appending the slash.
		if (g_Config.memStickDirectory.empty())
			g_Config.memStickDirectory = myDocsPath;

		size_t lastSlash = g_Config.memStickDirectory.find_last_of("/");
		if (lastSlash != (g_Config.memStickDirectory.length() - 1))
			g_Config.memStickDirectory.append("/");
	} else {
		g_Config.memStickDirectory = path + "memstick/";
	}

	// Create the memstickpath before trying to write to it, and fall back on Documents yet again
	// if we can't make it.
	if (!File::Exists(g_Config.memStickDirectory)) {
		if (!File::CreateDir(g_Config.memStickDirectory))
			g_Config.memStickDirectory = myDocsPath;
		INFO_LOG(COMMON, "Memstick directory not present, creating at '%s'", g_Config.memStickDirectory.c_str());
	}

	const std::string testFile = g_Config.memStickDirectory + "/_writable_test.$$$";

	// If any directory is read-only, fall back to the Documents directory.
	// We're screwed anyway if we can't write to Documents, or can't detect it.
	if (!File::CreateEmptyFile(testFile))
		g_Config.memStickDirectory = myDocsPath;

	// Clean up our mess.
	if (File::Exists(testFile))
		File::Delete(testFile);

	// Create the default directories that a real PSP creates. Good for homebrew so they can
	// expect a standard environment. Skipping THEME though, that's pointless.
	File::CreateDir(g_Config.memStickDirectory + "PSP");
	File::CreateDir(g_Config.memStickDirectory + "PSP/COMMON");
	File::CreateDir(g_Config.memStickDirectory + "PSP/GAME");
	File::CreateDir(g_Config.memStickDirectory + "PSP/SAVEDATA");
	File::CreateDir(g_Config.memStickDirectory + "PSP/PPSSPP_STATE");
#ifdef ANDROID
	// Avoid media scanners in PPSSPP_STATE directory
	File::CreateEmptyFile(g_Config.memStickDirectory + "PSP/PPSSPP_STATE/.nomedia");
#endif

	if (g_Config.currentDirectory.empty()) {
		g_Config.currentDirectory = GetSysDirectory(DIRECTORY_GAME);
	}
}
Esempio n. 21
0
// Mix samples from the various audio channels into a single sample queue.
// This single sample queue is where __AudioMix should read from. If the sample queue is full, we should
// just sleep the main emulator thread a little.
void __AudioUpdate() {
	// Audio throttle doesn't really work on the PSP since the mixing intervals are so closely tied
	// to the CPU. Much better to throttle the frame rate on frame display and just throw away audio
	// if the buffer somehow gets full.
	bool firstChannel = true;

	for (u32 i = 0; i < PSP_AUDIO_CHANNEL_MAX + 1; i++)	{
		if (!chans[i].reserved)
			continue;

		__AudioWakeThreads(chans[i], 0, hwBlockSize);

		if (!chans[i].sampleQueue.size()) {
			continue;
		}

		if (hwBlockSize * 2 > (int)chans[i].sampleQueue.size()) {
			ERROR_LOG(SCEAUDIO, "Channel %i buffer underrun at %i of %i", i, (int)chans[i].sampleQueue.size() / 2, hwBlockSize);
		}

		const s16 *buf1 = 0, *buf2 = 0;
		size_t sz1, sz2;

		chans[i].sampleQueue.popPointers(hwBlockSize * 2, &buf1, &sz1, &buf2, &sz2);

		if (firstChannel) {
			for (size_t s = 0; s < sz1; s++)
				mixBuffer[s] = buf1[s];
			if (buf2) {
				for (size_t s = 0; s < sz2; s++)
					mixBuffer[s + sz1] = buf2[s];
			}
			firstChannel = false;
		} else {
			// Surprisingly hard to SIMD efficiently on SSE2 due to lack of 16-to-32-bit sign extension. NEON should be straight-forward though, and SSE4.1 can do it nicely.
			// Actually, the cmple/pack trick should work fine...
			for (size_t s = 0; s < sz1; s++)
				mixBuffer[s] += buf1[s];
			if (buf2) {
				for (size_t s = 0; s < sz2; s++)
					mixBuffer[s + sz1] += buf2[s];
			}
		}
	}

	if (firstChannel) {
		// Nothing was written above, let's memset.
		memset(mixBuffer, 0, hwBlockSize * 2 * sizeof(s32));
	}

	if (g_Config.bEnableSound) {
		resampler.PushSamples(mixBuffer, hwBlockSize);
#ifndef MOBILE_DEVICE
		if (!m_logAudio) {
			if (g_Config.bDumpAudio) {
				std::string audio_file_name = GetSysDirectory(DIRECTORY_AUDIO) + "audiodump.wav";
				// Create the path just in case it doesn't exist
				File::CreateDir(GetSysDirectory(DIRECTORY_AUDIO));
				File::CreateEmptyFile(audio_file_name);
				__StartLogAudio(audio_file_name);
			}
		} else {
			if (g_Config.bDumpAudio) {
				for (int i = 0; i < hwBlockSize * 2; i++) {
					clampedMixBuffer[i] = clamp_s16(mixBuffer[i]);
				}
				g_wave_writer.AddStereoSamples(clampedMixBuffer, hwBlockSize);
			} else {
				__StopLogAudio();
			}
		}
#endif
	}
}