예제 #1
0
void GetSysDirectories(std::string &memstickpath, std::string &flash0path) {
#ifdef _WIN32
	wchar_t path_buffer[_MAX_PATH];
	char drive[_MAX_DRIVE] ,dir[_MAX_DIR], file[_MAX_FNAME], ext[_MAX_EXT];
	char memstickpath_buf[_MAX_PATH];
	char flash0path_buf[_MAX_PATH];

	GetModuleFileName(NULL, path_buffer, sizeof(path_buffer));

	std::string path = ConvertWStringToUTF8(path_buffer);

	_splitpath_s(path.c_str(), drive, dir, file, ext );

	// Mount a couple of filesystems
	sprintf(memstickpath_buf, "%s%smemstick\\", drive, dir);
	sprintf(flash0path_buf, "%s%sflash0\\", drive, dir);

	memstickpath = memstickpath_buf;
	flash0path = flash0path_buf;
#else
	// TODO
	memstickpath = g_Config.memCardDirectory;
	flash0path = g_Config.flashDirectory;
#endif
}
예제 #2
0
파일: main.cpp 프로젝트: Alceris/ppsspp
std::string System_GetProperty(SystemProperty prop) {
	static bool hasCheckedGPUDriverVersion = false;
	switch (prop) {
	case SYSPROP_NAME:
		return osName;
	case SYSPROP_LANGREGION:
		return langRegion;
	case SYSPROP_CLIPBOARD_TEXT:
		{
			std::string retval;
			if (OpenClipboard(MainWindow::GetDisplayHWND())) {
				HANDLE handle = GetClipboardData(CF_UNICODETEXT);
				const wchar_t *wstr = (const wchar_t*)GlobalLock(handle);
				if (wstr)
					retval = ConvertWStringToUTF8(wstr);
				else
					retval = "";
				GlobalUnlock(handle);
				CloseClipboard();
			}
			return retval;
		}
	case SYSPROP_GPUDRIVER_VERSION:
		if (!hasCheckedGPUDriverVersion) {
			hasCheckedGPUDriverVersion = true;
			gpuDriverVersion = GetVideoCardDriverVersion();
		}
		return gpuDriverVersion;
	default:
		return "";
	}
}
예제 #3
0
	//---------------------------------------------------------------------------------------------------
	// function WinBrowseForFileName
	//---------------------------------------------------------------------------------------------------
	bool BrowseForFileName (bool _bLoad, HWND _hParent, const wchar_t *_pTitle,
		const wchar_t *_pInitialFolder,const wchar_t *_pFilter,const wchar_t *_pExtension, 
		std::string& _strFileName)
	{
		wchar_t szFile [MAX_PATH+1] = {0};
		wchar_t szFileTitle [MAX_PATH+1] = {0};

		OPENFILENAME ofn;

		ZeroMemory (&ofn,sizeof (ofn));

		ofn.lStructSize		= sizeof (OPENFILENAME);
		ofn.lpstrInitialDir = _pInitialFolder;
		ofn.lpstrFilter		= _pFilter;
		ofn.nMaxFile		= sizeof (szFile);
		ofn.lpstrFile		= szFile;
		ofn.lpstrFileTitle	= szFileTitle;
		ofn.nMaxFileTitle	= sizeof (szFileTitle);
		ofn.lpstrDefExt     = _pExtension;
		ofn.hwndOwner		= _hParent;
		ofn.Flags			= OFN_NOCHANGEDIR | OFN_EXPLORER | OFN_HIDEREADONLY;

		if (_strFileName.size () != 0)
			wcscpy(ofn.lpstrFile, ConvertUTF8ToWString(_strFileName).c_str());

		if (((_bLoad) ? GetOpenFileName(&ofn) : GetSaveFileName (&ofn)))
		{
			_strFileName = ConvertWStringToUTF8(ofn.lpstrFile);
			return true;
		}
		else
			return false;
	}
예제 #4
0
파일: Misc.cpp 프로젝트: kg/ppsspp
const char *GetStringErrorMsg(int errCode) {
	static const size_t buff_size = 1023;
#ifndef _XBOX
#ifdef _WIN32
	static __declspec(thread) wchar_t err_strw[buff_size] = {};

	FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errCode,
		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
		err_strw, buff_size, NULL);

	static __declspec(thread) char err_str[buff_size] = {};
	snprintf(err_str, buff_size, ConvertWStringToUTF8(err_strw).c_str());
#else
	static __thread char err_str[buff_size] = {};

	// Thread safe (XSI-compliant)
	if (strerror_r(errCode, err_str, buff_size) == 0) {
		return "Unknown error";
	}
#endif

	return err_str;
#else
	return "GetStringErrorMsg";
#endif
}
예제 #5
0
	std::vector<std::string> BrowseForFileNameMultiSelect(bool _bLoad, HWND _hParent, const wchar_t *_pTitle,
		const wchar_t *_pInitialFolder,const wchar_t *_pFilter,const wchar_t *_pExtension)
	{
		wchar_t szFile [MAX_PATH+1+2048*2] = {0};
		wchar_t szFileTitle [MAX_PATH+1] = {0};

		OPENFILENAME ofn;

		ZeroMemory (&ofn,sizeof (ofn));

		ofn.lStructSize		= sizeof (OPENFILENAME);
		ofn.lpstrInitialDir = _pInitialFolder;
		ofn.lpstrFilter		= _pFilter;
		ofn.nMaxFile		= sizeof (szFile);
		ofn.lpstrFile		= szFile;
		ofn.lpstrFileTitle	= szFileTitle;
		ofn.nMaxFileTitle	= sizeof (szFileTitle);
		ofn.lpstrDefExt     = _pExtension;
		ofn.hwndOwner		= _hParent;
		ofn.Flags			= OFN_NOCHANGEDIR | OFN_EXPLORER | OFN_HIDEREADONLY | OFN_ALLOWMULTISELECT ;

		std::vector<std::string> files;

		if (((_bLoad) ? GetOpenFileName(&ofn) : GetSaveFileName(&ofn)))
		{
			std::string directory = ConvertWStringToUTF8(ofn.lpstrFile);
			wchar_t *temp = ofn.lpstrFile;
			wchar_t *oldtemp = temp;
			temp += wcslen(temp)+1;
			if (*temp==0)
			{
				//we only got one file
				files.push_back(ConvertWStringToUTF8(oldtemp));
			}
			else
			{
				while (*temp)
				{
					files.push_back(directory+"\\"+ConvertWStringToUTF8(temp));
					temp += wcslen(temp)+1;
				}
			}
			return files;
		}
		else
			return std::vector<std::string>(); // empty vector;
	}
예제 #6
0
파일: FileUtil.cpp 프로젝트: mailwl/ppsspp
const std::string &GetExeDirectory()
{
	static std::string ExePath;

	if (ExePath.empty()) {
#ifdef _WIN32
		TCHAR program_path[4096] = {0};
		GetModuleFileName(NULL, program_path, ARRAY_SIZE(program_path) - 1);
		program_path[ARRAY_SIZE(program_path) - 1] = '\0';
		TCHAR *last_slash = _tcsrchr(program_path, '\\');
		if (last_slash != NULL)
			*(last_slash + 1) = '\0';
#ifdef UNICODE
		ExePath = ConvertWStringToUTF8(program_path);
#else
		ExePath = program_path;
#endif

#elif (defined(__APPLE__) && !defined(IOS)) || defined(__linux__) || defined(KERN_PROC_PATHNAME)
		char program_path[4096];
		uint32_t program_path_size = sizeof(program_path) - 1;

#if defined(__linux__)
		if (readlink("/proc/self/exe", program_path, 4095) > 0)
#elif defined(__APPLE__) && !defined(IOS)
		if (_NSGetExecutablePath(program_path, &program_path_size) == 0)
#elif defined(KERN_PROC_PATHNAME)
		int mib[4] = {
			CTL_KERN,
#if defined(__NetBSD__)
			KERN_PROC_ARGS,
			-1,
			KERN_PROC_PATHNAME,
#else
			KERN_PROC,
			KERN_PROC_PATHNAME,
			-1,
#endif
		};
		size_t sz = program_path_size;

		if (sysctl(mib, 4, program_path, &sz, NULL, 0) == 0)
#else
#error Unmatched ifdef.
#endif
		{
			program_path[sizeof(program_path) - 1] = '\0';
			char *last_slash = strrchr(program_path, '/');
			if (last_slash != NULL)
				*(last_slash + 1) = '\0';
			ExePath = program_path;
		}
#endif
	}

	return ExePath;
}
예제 #7
0
파일: main.cpp 프로젝트: Alceris/ppsspp
static std::string GetDefaultLangRegion() {
	wchar_t lcLangName[256] = {};

	// LOCALE_SNAME is only available in WinVista+
	if (0 != GetLocaleInfo(LOCALE_NAME_USER_DEFAULT, LOCALE_SNAME, lcLangName, ARRAY_SIZE(lcLangName))) {
		std::string result = ConvertWStringToUTF8(lcLangName);
		std::replace(result.begin(), result.end(), '-', '_');
		return result;
	} else {
		// This should work on XP, but we may get numbers for some countries.
		if (0 != GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME, lcLangName, ARRAY_SIZE(lcLangName))) {
			wchar_t lcRegion[256] = {};
			if (0 != GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SISO3166CTRYNAME, lcRegion, ARRAY_SIZE(lcRegion))) {
				return ConvertWStringToUTF8(lcLangName) + "_" + ConvertWStringToUTF8(lcRegion);
			}
		}
		// Unfortunate default.  We tried.
		return "en_US";
	}
}
예제 #8
0
std::string GameManager::GetTempFilename() const {
#ifdef _WIN32
	wchar_t tempPath[MAX_PATH];
	GetTempPath(MAX_PATH, tempPath);
	wchar_t buffer[MAX_PATH];
	GetTempFileName(tempPath, L"PSP", 1, buffer);
	return ConvertWStringToUTF8(buffer);
#else
	return g_Config.externalDirectory + "/ppsspp.dl";
#endif
}
예제 #9
0
const std::string &GetExeDirectory()
{
	static std::string ExePath;

	if (ExePath.empty())
#ifndef _XBOX
	{
#if defined(_WIN32) && !defined(__MINGW32__)
		TCHAR program_path[4096] = {0};
		GetModuleFileName(NULL, program_path, ARRAY_SIZE(program_path) - 1);
		program_path[ARRAY_SIZE(program_path) - 1] = '\0';
		TCHAR *last_slash = _tcsrchr(program_path, '\\');
		if (last_slash != NULL)
			*(last_slash + 1) = '\0';
#ifdef UNICODE
		ExePath = ConvertWStringToUTF8(program_path);
#else
		ExePath = program_path;
#endif

#elif (defined(__APPLE__) && !defined(IOS)) || defined(__linux__)
		char program_path[4096];
		uint32_t program_path_size = sizeof(program_path) - 1;

#if defined(__linux__)
		if (readlink("/proc/self/exe", program_path, 4095) > 0)
#elif defined(__APPLE__) && !defined(IOS)
		if (_NSGetExecutablePath(program_path, &program_path_size) == 0)
#else
#error Unmatched ifdef.
#endif
		{
			program_path[sizeof(program_path) - 1] = '\0';
			char *last_slash = strrchr(program_path, '/');
			if (last_slash != NULL)
				*(last_slash + 1) = '\0';
			ExePath = program_path;
		}
#endif
	}

	return ExePath;
#else
	static std::wstring ExePath = L"game:\\";
	return ExePath;
#endif
}
예제 #10
0
bool InputBox_GetString(HINSTANCE hInst, HWND hParent, const wchar_t *title, const std::string &defaultValue, std::string &outvalue, bool selected)
{
	defaultSelected = selected;
	if (defaultValue.size() < 255)
		textBoxContents = ConvertUTF8ToWString(defaultValue);
	else
		textBoxContents = L"";

	if (title != NULL)
		windowTitle = title;
	else
		windowTitle = L"";

	if (IDOK == DialogBox(hInst, (LPCWSTR)IDD_INPUTBOX, hParent, InputBoxFunc)) {
		outvalue = ConvertWStringToUTF8(out);
		return true;
	}
	else 
		return false;
}
예제 #11
0
bool InputBox_GetString(HINSTANCE hInst, HWND hParent, const wchar_t *title, const std::string &defaultValue, std::string &outvalue)
{
	const wchar_t *defaultTitle = L"Input value";
	defaultSelected = true;

	textBoxContents = ConvertUTF8ToWString(defaultValue);

	if (title && wcslen(title) <= 0)
		windowTitle = defaultTitle;
	else if (title && wcslen(title) < 255)
		windowTitle = title;
	else
		windowTitle = defaultTitle;

	if (IDOK == DialogBox(hInst, (LPCWSTR)IDD_INPUTBOX, hParent, InputBoxFunc)) {
		outvalue = ConvertWStringToUTF8(out);
		return true;
	}
	else 
		return false;
}
예제 #12
0
// Returns a vector with the device names
std::vector<std::string> getWindowsDrives()
{
    std::vector<std::string> drives;

    const DWORD buffsize = GetLogicalDriveStrings(0, NULL);
    std::vector<TCHAR> buff(buffsize);
    if (GetLogicalDriveStrings(buffsize, buff.data()) == buffsize - 1)
    {
        auto drive = buff.data();
        while (*drive)
        {
            std::string str(ConvertWStringToUTF8(drive));
            str.pop_back();	// we don't want the final backslash
            str += "/";
            drives.push_back(str);

            // advance to next drive
            while (*drive++) {}
        }
    }
    return drives;
}
예제 #13
0
	std::string BrowseForFolder(HWND parent, char *title)
	{
		std::wstring titleString = ConvertUTF8ToWString(title);

		BROWSEINFO info;
		memset(&info,0,sizeof(info));
		info.hwndOwner = parent;
		info.lpszTitle = titleString.c_str();
		info.ulFlags = BIF_EDITBOX | BIF_RETURNONLYFSDIRS | BIF_USENEWUI;

		//info.pszDisplayName
		LPCITEMIDLIST idList = SHBrowseForFolder(&info);

		wchar_t temp[MAX_PATH];
		SHGetPathFromIDList(idList, temp);
		if (wcslen(temp))
		{
			return ConvertWStringToUTF8(temp);
		}
		else
			return "";
	}
예제 #14
0
unsigned int WINAPI TheThread(void *)
{
	_InterlockedExchange(&emuThreadReady, THREAD_INIT);

	setCurrentThreadName("Emu");  // And graphics...

	host = new WindowsHost(MainWindow::GetHInstance(), MainWindow::GetHWND(), MainWindow::GetDisplayHWND());
	host->SetWindowTitle(nullptr);

	// Convert the command-line arguments to Unicode, then to proper UTF-8 
	// (the benefit being that we don't have to pollute the UI project with win32 ifdefs and lots of Convert<whatever>To<whatever>).
	// This avoids issues with PPSSPP inadvertently destroying paths with Unicode glyphs 
	// (using the ANSI args resulted in Japanese/Chinese glyphs being turned into question marks, at least for me..).
	// -TheDax
	std::vector<std::wstring> wideArgs = GetWideCmdLine();
	std::vector<std::string> argsUTF8;
	for (auto& string : wideArgs) {
		argsUTF8.push_back(ConvertWStringToUTF8(string));
	}

	std::vector<const char *> args;

	for (auto& string : argsUTF8) {
		args.push_back(string.c_str());
	}

	bool performingRestart = NativeIsRestarting();
	NativeInit(static_cast<int>(args.size()), &args[0], "1234", "1234", nullptr);

	host->UpdateUI();

	GraphicsContext *graphicsContext = nullptr;

	std::string error_string;
	if (!host->InitGraphics(&error_string, &graphicsContext)) {
		// Before anything: are we restarting right now?
		if (performingRestart) {
			// Okay, switching graphics didn't work out.  Probably a driver bug - fallback to restart.
			// This happens on NVIDIA when switching OpenGL -> Vulkan.
			g_Config.Save();
			W32Util::ExitAndRestart();
		}

		I18NCategory *err = GetI18NCategory("Error");
		Reporting::ReportMessage("Graphics init error: %s", error_string.c_str());

		const char *defaultErrorVulkan = "Failed initializing graphics. Try upgrading your graphics drivers.\n\nWould you like to try switching to OpenGL?\n\nError message:";
		const char *defaultErrorOpenGL = "Failed initializing graphics. Try upgrading your graphics drivers.\n\nWould you like to try switching to DirectX 9?\n\nError message:";
		const char *defaultErrorDirect3D9 = "Failed initializing graphics. Try upgrading your graphics drivers and directx 9 runtime.\n\nWould you like to try switching to OpenGL?\n\nError message:";
		const char *genericError;
		int nextBackend = GPU_BACKEND_DIRECT3D9;
		switch (g_Config.iGPUBackend) {
		case GPU_BACKEND_DIRECT3D9:
			nextBackend = GPU_BACKEND_OPENGL;
			genericError = err->T("GenericDirect3D9Error", defaultErrorDirect3D9);
			break;
		case GPU_BACKEND_VULKAN:
			nextBackend = GPU_BACKEND_OPENGL;
			genericError = err->T("GenericVulkanError", defaultErrorVulkan);
			break;
		case GPU_BACKEND_OPENGL:
		default:
			nextBackend = GPU_BACKEND_DIRECT3D9;
			genericError = err->T("GenericOpenGLError", defaultErrorOpenGL);
			break;
		}
		std::string full_error = StringFromFormat("%s\n\n%s", genericError, error_string.c_str());
		std::wstring title = ConvertUTF8ToWString(err->T("GenericGraphicsError", "Graphics Error"));
		bool yes = IDYES == MessageBox(0, ConvertUTF8ToWString(full_error).c_str(), title.c_str(), MB_ICONERROR | MB_YESNO);
		ERROR_LOG(BOOT, full_error.c_str());

		if (yes) {
			// Change the config to the alternative and restart.
			g_Config.iGPUBackend = nextBackend;
			g_Config.Save();

			W32Util::ExitAndRestart();
		}

		// No safe way out without graphics.
		ExitProcess(1);
	}

	NativeInitGraphics(graphicsContext);
	NativeResized();

	INFO_LOG(BOOT, "Done.");
	_dbg_update_();

	if (coreState == CORE_POWERDOWN) {
		INFO_LOG(BOOT, "Exit before core loop.");
		goto shutdown;
	}

	_InterlockedExchange(&emuThreadReady, THREAD_CORE_LOOP);

	if (g_Config.bBrowse)
		PostMessage(MainWindow::GetHWND(), WM_COMMAND, ID_FILE_LOAD, 0);

	Core_EnableStepping(FALSE);

	while (GetUIState() != UISTATE_EXIT)
	{
		// We're here again, so the game quit.  Restart Core_Run() which controls the UI.
		// This way they can load a new game.
		if (!Core_IsActive())
			UpdateUIState(UISTATE_MENU);

		Core_Run(graphicsContext);
	}

shutdown:
	_InterlockedExchange(&emuThreadReady, THREAD_SHUTDOWN);

	NativeShutdownGraphics();

	// NativeShutdown deletes the graphics context through host->ShutdownGraphics().
	NativeShutdown();
	
	_InterlockedExchange(&emuThreadReady, THREAD_END);

	return 0;
}
예제 #15
0
unsigned int WINAPI TheThread(void *)
{
	_InterlockedExchange(&emuThreadReady, THREAD_INIT);

	setCurrentThreadName("Emu");  // And graphics...

	// Native overwrites host. Can't allow that.

	Host *oldHost = host;

	// Convert the command-line arguments to Unicode, then to proper UTF-8 
	// (the benefit being that we don't have to pollute the UI project with win32 ifdefs and lots of Convert<whatever>To<whatever>).
	// This avoids issues with PPSSPP inadvertently destroying paths with Unicode glyphs 
	// (using the ANSI args resulted in Japanese/Chinese glyphs being turned into question marks, at least for me..).
	// -TheDax
	std::vector<std::wstring> wideArgs = GetWideCmdLine();
	std::vector<std::string> argsUTF8;
	for (auto& string : wideArgs) {
		argsUTF8.push_back(ConvertWStringToUTF8(string));
	}

	std::vector<const char *> args;

	for (auto& string : argsUTF8) {
		args.push_back(string.c_str());
	}

	NativeInit(static_cast<int>(args.size()), &args[0], "1234", "1234", "1234");

	Host *nativeHost = host;
	host = oldHost;

	host->UpdateUI();
	
	//Check Colour depth
	HDC dc = GetDC(NULL);
	u32 colour_depth = GetDeviceCaps(dc, BITSPIXEL);
	ReleaseDC(NULL, dc);
	if (colour_depth != 32){
		MessageBox(0, L"Please switch your display to 32-bit colour mode", L"OpenGL Error", MB_OK);
		ExitProcess(1);
	}

	std::string error_string;
	if (!host->InitGraphics(&error_string)) {
		Reporting::ReportMessage("Graphics init error: %s", error_string.c_str());
		std::string full_error = StringFromFormat( "Failed initializing OpenGL. Try upgrading your graphics drivers.\n\nError message:\n\n%s", error_string.c_str());
		MessageBox(0, ConvertUTF8ToWString(full_error).c_str(), L"OpenGL Error", MB_OK | MB_ICONERROR);
		ERROR_LOG(BOOT, full_error.c_str());

		// No safe way out without OpenGL.
		ExitProcess(1);
	}

	NativeInitGraphics();
	NativeResized();

	INFO_LOG(BOOT, "Done.");
	_dbg_update_();

	if (coreState == CORE_POWERDOWN) {
		INFO_LOG(BOOT, "Exit before core loop.");
		goto shutdown;
	}

	_InterlockedExchange(&emuThreadReady, THREAD_CORE_LOOP);

	if (g_Config.bBrowse)
		PostMessage(MainWindow::GetHWND(), WM_COMMAND, ID_FILE_LOAD, 0);

	Core_EnableStepping(FALSE);

	while (GetUIState() != UISTATE_EXIT)
	{
		// We're here again, so the game quit.  Restart Core_Run() which controls the UI.
		// This way they can load a new game.
		if (!Core_IsActive())
			UpdateUIState(UISTATE_MENU);

		Core_Run();
	}

shutdown:
	_InterlockedExchange(&emuThreadReady, THREAD_SHUTDOWN);

	NativeShutdownGraphics();

	host->ShutdownSound();
	host = nativeHost;
	NativeShutdown();
	host = oldHost;
	host->ShutdownGraphics();
	
	_InterlockedExchange(&emuThreadReady, THREAD_END);

	return 0;
}
예제 #16
0
파일: FileUtil.cpp 프로젝트: mailwl/ppsspp
// Deletes the given directory and anything under it. Returns true on success.
bool DeleteDirRecursively(const std::string &directory)
{
#if PPSSPP_PLATFORM(UWP)
	return false;
#else
	INFO_LOG(COMMON, "DeleteDirRecursively: %s", directory.c_str());

#ifdef _WIN32

	// Find the first file in the directory.
	WIN32_FIND_DATA ffd;
	HANDLE hFind = FindFirstFile(ConvertUTF8ToWString(directory + "\\*").c_str(), &ffd);

	if (hFind == INVALID_HANDLE_VALUE)
	{
		return false;
	}
		
	// windows loop
	do
	{
		const std::string virtualName = ConvertWStringToUTF8(ffd.cFileName);
#else
	struct dirent *result = NULL;
	DIR *dirp = opendir(directory.c_str());
	if (!dirp)
		return false;

	// non windows loop
	while ((result = readdir(dirp)))
	{
		const std::string virtualName = result->d_name;
#endif
		// check for "." and ".."
		if (((virtualName[0] == '.') && (virtualName[1] == '\0')) ||
			((virtualName[0] == '.') && (virtualName[1] == '.') && 
			 (virtualName[2] == '\0')))
			continue;

		std::string newPath = directory + DIR_SEP + virtualName;
		if (IsDirectory(newPath))
		{
			if (!DeleteDirRecursively(newPath))
			{
#ifndef _WIN32
				closedir(dirp);
#else
				FindClose(hFind);
#endif
				return false;
			}
		}
		else
		{
			if (!File::Delete(newPath))
			{
#ifndef _WIN32
				closedir(dirp);
#else
				FindClose(hFind);
#endif
				return false;
			}
		}

#ifdef _WIN32
	} while (FindNextFile(hFind, &ffd) != 0);
	FindClose(hFind);
#else
	}
	closedir(dirp);
#endif
	return File::DeleteDir(directory);
#endif
}
예제 #17
0
파일: FileUtil.cpp 프로젝트: mailwl/ppsspp
std::string ResolvePath(const std::string &path) {
#ifdef _WIN32
	typedef DWORD (WINAPI *getFinalPathNameByHandleW_f)(HANDLE hFile, LPWSTR lpszFilePath, DWORD cchFilePath, DWORD dwFlags);
	static getFinalPathNameByHandleW_f getFinalPathNameByHandleW = nullptr;

#if PPSSPP_PLATFORM(UWP)
	getFinalPathNameByHandleW = &GetFinalPathNameByHandleW;
#else
	if (!getFinalPathNameByHandleW) {
		HMODULE kernel32 = GetModuleHandle(L"kernel32.dll");
		getFinalPathNameByHandleW = (getFinalPathNameByHandleW_f)GetProcAddress(kernel32, "GetFinalPathNameByHandleW");
	}
#endif

	static const int BUF_SIZE = 32768;
	wchar_t *buf = new wchar_t[BUF_SIZE];
	memset(buf, 0, BUF_SIZE);

	std::wstring input = ConvertUTF8ToWString(path);
	if (getFinalPathNameByHandleW) {
#if PPSSPP_PLATFORM(UWP)
		HANDLE hFile = CreateFile2(input.c_str(), GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr);
#else
		HANDLE hFile = CreateFile(input.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr);
#endif
		if (hFile == INVALID_HANDLE_VALUE) {
			wcscpy_s(buf, BUF_SIZE - 1, input.c_str());
		} else {
			int result = getFinalPathNameByHandleW(hFile, buf, BUF_SIZE - 1, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
			if (result >= BUF_SIZE || result == 0)
				wcscpy_s(buf, BUF_SIZE - 1, input.c_str());
			CloseHandle(hFile);
		}
	} else {
		wchar_t *longBuf = new wchar_t[BUF_SIZE];
		memset(buf, 0, BUF_SIZE);

		int result = GetLongPathNameW(input.c_str(), longBuf, BUF_SIZE - 1);
		if (result >= BUF_SIZE || result == 0)
			wcscpy_s(longBuf, BUF_SIZE - 1, input.c_str());

		result = GetFullPathNameW(longBuf, BUF_SIZE - 1, buf, nullptr);
		if (result >= BUF_SIZE || result == 0)
			wcscpy_s(buf, BUF_SIZE - 1, input.c_str());

		delete [] longBuf;

		// Normalize slashes just in case.
		for (int i = 0; i < BUF_SIZE; ++i) {
			if (buf[i] == '\\')
				buf[i] = '/';
		}
	}

	// Undo the \\?\C:\ syntax that's normally returned.
	std::string output = ConvertWStringToUTF8(buf);
	if (buf[0] == '\\' && buf[1] == '\\' && buf[2] == '?' && buf[3] == '\\' && isalpha(buf[4]) && buf[5] == ':')
		output = output.substr(4);
	delete [] buf;
	return output;

#else
	std::unique_ptr<char[]> buf(new char[PATH_MAX + 32768]);
	if (realpath(path.c_str(), buf.get()) == nullptr)
		return path;
	return buf.get();
#endif
}
예제 #18
0
	LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)	{
		switch (message) {
		case WM_CREATE:
			if (!DoesVersionMatchWindows(6, 0, 0, 0, true)) {
				// Remove the D3D11 choice on versions below XP
				RemoveMenu(GetMenu(hWnd), ID_OPTIONS_DIRECT3D11, MF_BYCOMMAND);
			}
			break;
			
		case WM_GETMINMAXINFO:
			{
				MINMAXINFO *minmax = reinterpret_cast<MINMAXINFO *>(lParam);
				RECT rc = { 0 };
				bool portrait = g_Config.IsPortrait();
				rc.right = portrait ? 272 : 480;
				rc.bottom = portrait ? 480 : 272;
				AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, TRUE);
				minmax->ptMinTrackSize.x = rc.right - rc.left;
				minmax->ptMinTrackSize.y = rc.bottom - rc.top;
			}
			return 0;

		case WM_ACTIVATE:
			{
				bool pause = true;
				if (wParam == WA_ACTIVE || wParam == WA_CLICKACTIVE) {
					WindowsRawInput::GainFocus();
					if (!IsIconic(GetHWND())) {
						InputDevice::GainFocus();
					}
					g_activeWindow = WINDOW_MAINWINDOW;
					pause = false;
				}
				if (!noFocusPause && g_Config.bPauseOnLostFocus && GetUIState() == UISTATE_INGAME) {
					if (pause != Core_IsStepping()) {	// != is xor for bools
						if (disasmWindow[0])
							SendMessage(disasmWindow[0]->GetDlgHandle(), WM_COMMAND, IDC_STOPGO, 0);
						else
							Core_EnableStepping(pause);
					}
				}

				if (wParam == WA_ACTIVE || wParam == WA_CLICKACTIVE) {
					NativeMessageReceived("got_focus", "");
					hasFocus = true;
					trapMouse = true;
				}
				if (wParam == WA_INACTIVE) {
					NativeMessageReceived("lost_focus", "");
					WindowsRawInput::LoseFocus();
					InputDevice::LoseFocus();
					hasFocus = false;
					trapMouse = false;
				}
			}
			break;

		case WM_ERASEBKGND:
			// This window is always covered by DisplayWindow. No reason to erase.
			return 1;

		case WM_MOVE:
			SavePosition();
			break;

		case WM_ENTERSIZEMOVE:
			inResizeMove = true;
			break;

		case WM_EXITSIZEMOVE:
			inResizeMove = false;
			HandleSizeChange(SIZE_RESTORED);
			break;

		case WM_SIZE:
			switch (wParam) {
			case SIZE_RESTORED:
			case SIZE_MAXIMIZED:
				if (g_IgnoreWM_SIZE) {
					return DefWindowProc(hWnd, message, wParam, lParam);
				} else if (!inResizeMove) {
					HandleSizeChange(wParam);
				}
				if (hasFocus) {
					InputDevice::GainFocus();
				}
				break;

			case SIZE_MINIMIZED:
				Core_NotifyWindowHidden(true);
				if (!g_Config.bPauseWhenMinimized) {
					NativeMessageReceived("window minimized", "true");
				}
				InputDevice::LoseFocus();
				break;
			default:
				break;
			}
			break;

    case WM_TIMER:
			// Hack: Take the opportunity to also show/hide the mouse cursor in fullscreen mode.
			switch (wParam) {
			case TIMER_CURSORUPDATE:
				CorrectCursor();
				return 0;

			case TIMER_CURSORMOVEUPDATE:
				hideCursor = true;
				KillTimer(hWnd, TIMER_CURSORMOVEUPDATE);
				return 0;
			}
			break;

		// For some reason, need to catch this here rather than in DisplayProc.
		case WM_MOUSEWHEEL:
			{
				int wheelDelta = (short)(wParam >> 16);
				KeyInput key;
				key.deviceId = DEVICE_ID_MOUSE;

				if (wheelDelta < 0) {
					key.keyCode = NKCODE_EXT_MOUSEWHEEL_DOWN;
					wheelDelta = -wheelDelta;
				} else {
					key.keyCode = NKCODE_EXT_MOUSEWHEEL_UP;
				}
				// There's no separate keyup event for mousewheel events, let's pass them both together.
				// This also means it really won't work great for key mapping :( Need to build a 1 frame delay or something.
				key.flags = KEY_DOWN | KEY_UP | KEY_HASWHEELDELTA | (wheelDelta << 16);
				NativeKey(key);
			}
			break;

		case WM_COMMAND:
			{
				if (!MainThread_Ready())
					return DefWindowProc(hWnd, message, wParam, lParam);

				MainWindowMenu_Process(hWnd, wParam);
			}
			break;

		case WM_USER_TOGGLE_FULLSCREEN:
			ToggleFullscreen(hwndMain, wParam ? true : false);
			break;

		case WM_INPUT:
			return WindowsRawInput::Process(hWnd, wParam, lParam);

		// TODO: Could do something useful with WM_INPUT_DEVICE_CHANGE?

		// Not sure why we are actually getting WM_CHAR even though we use RawInput, but alright..
		case WM_CHAR:
			return WindowsRawInput::ProcessChar(hWnd, wParam, lParam);

		case WM_DEVICECHANGE:
#ifndef _M_ARM
			DinputDevice::CheckDevices();
#endif
			return DefWindowProc(hWnd, message, wParam, lParam);

		case WM_VERYSLEEPY_MSG:
			switch (wParam) {
			case VERYSLEEPY_WPARAM_SUPPORTED:
				return TRUE;

			case VERYSLEEPY_WPARAM_GETADDRINFO:
				{
					VerySleepy_AddrInfo *info = (VerySleepy_AddrInfo *)lParam;
					const u8 *ptr = (const u8 *)info->addr;
					std::string name;

					if (MIPSComp::jit && MIPSComp::jit->DescribeCodePtr(ptr, name)) {
						swprintf_s(info->name, L"Jit::%S", name.c_str());
						return TRUE;
					}
					if (gpu && gpu->DescribeCodePtr(ptr, name)) {
						swprintf_s(info->name, L"GPU::%S", name.c_str());
						return TRUE;
					}
				}
				return FALSE;

			default:
				return FALSE;
			}
			break;

		case WM_DROPFILES:
			{
				if (!MainThread_Ready())
					return DefWindowProc(hWnd, message, wParam, lParam);

				HDROP hdrop = (HDROP)wParam;
				int count = DragQueryFile(hdrop,0xFFFFFFFF,0,0);
				if (count != 1) {
					MessageBox(hwndMain,L"You can only load one file at a time",L"Error",MB_ICONINFORMATION);
				}
				else
				{
					TCHAR filename[512];
					if (DragQueryFile(hdrop, 0, filename, 512) != 0) {
						const std::string utf8_filename = ReplaceAll(ConvertWStringToUTF8(filename), "\\", "/");
						NativeMessageReceived("boot", utf8_filename.c_str());
						Core_EnableStepping(false);
					}
				}
			}
			break;

		case WM_CLOSE:
			InputDevice::StopPolling();
			WindowsRawInput::Shutdown();
			return DefWindowProc(hWnd,message,wParam,lParam);

		case WM_DESTROY:
			KillTimer(hWnd, TIMER_CURSORUPDATE);
			KillTimer(hWnd, TIMER_CURSORMOVEUPDATE);
			PostQuitMessage(0);
			break;

		case WM_USER + 1:
			if (disasmWindow[0])
				disasmWindow[0]->NotifyMapLoaded();
			if (memoryWindow[0])
				memoryWindow[0]->NotifyMapLoaded();

			if (disasmWindow[0])
				disasmWindow[0]->UpdateDialog();

			SetForegroundWindow(hwndMain);
			break;

		case WM_USER_SAVESTATE_FINISH:
			SetCursor(LoadCursor(0, IDC_ARROW));
			break;

		case WM_USER_UPDATE_UI:
			TranslateMenus(hwndMain, menu);
			// Update checked status immediately for accelerators.
			UpdateMenus();
			break;

		case WM_USER_WINDOW_TITLE_CHANGED:
			UpdateWindowTitle();
			break;

		case WM_USER_BROWSE_BOOT_DONE:
			BrowseAndBootDone();
			break;

		case WM_USER_BROWSE_BG_DONE:
			BrowseBackgroundDone();
			break;

		case WM_USER_RESTART_EMUTHREAD:
			NativeSetRestarting();
			InputDevice::StopPolling();
			MainThread_Stop();
			coreState = CORE_POWERUP;
			UpdateUIState(UISTATE_MENU);
			MainThread_Start(g_Config.iGPUBackend == (int)GPUBackend::OPENGL);
			InputDevice::BeginPolling();
			break;

		case WM_MENUSELECT:
			// Called when a menu is opened. Also when an item is selected, but meh.
			UpdateMenus(true);
			WindowsRawInput::NotifyMenu();
			trapMouse = false;
			break;

		case WM_EXITMENULOOP:
			// Called when menu is closed.
			trapMouse = true;
			break;

		// Turn off the screensaver.
		// Note that if there's a screensaver password, this simple method
		// doesn't work on Vista or higher.
		case WM_SYSCOMMAND:
			{
				switch (wParam) {
				case SC_SCREENSAVE:  
					return 0;
				case SC_MONITORPOWER:
					return 0;      
				}
				return DefWindowProc(hWnd, message, wParam, lParam);
			}

		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
		}
		return 0;
	}
예제 #19
0
파일: main.cpp 프로젝트: Alceris/ppsspp
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;
}
std::vector<PSPFileInfo> VirtualDiscFileSystem::GetDirListing(std::string path)
{
	std::vector<PSPFileInfo> myVector;
#ifdef _WIN32
	WIN32_FIND_DATA findData;
	HANDLE hFind;

	// TODO: Handler files that are virtual might not be listed.

	std::string w32path = GetLocalPath(path) + "\\*.*";

	hFind = FindFirstFile(ConvertUTF8ToWString(w32path).c_str(), &findData);

	if (hFind == INVALID_HANDLE_VALUE) {
		return myVector; //the empty list
	}

	for (BOOL retval = 1; retval; retval = FindNextFile(hFind, &findData)) {
		if (!wcscmp(findData.cFileName, L"..") || !wcscmp(findData.cFileName, L".")) {
			continue;
		}

		PSPFileInfo entry;
		if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
			entry.type = FILETYPE_DIRECTORY;
		} else {
			entry.type = FILETYPE_NORMAL;
		}

		entry.access = FILEACCESS_READ;
		entry.size = findData.nFileSizeLow | ((u64)findData.nFileSizeHigh<<32);
		entry.name = ConvertWStringToUTF8(findData.cFileName);
		tmFromFiletime(entry.atime, findData.ftLastAccessTime);
		tmFromFiletime(entry.ctime, findData.ftCreationTime);
		tmFromFiletime(entry.mtime, findData.ftLastWriteTime);
		entry.isOnSectorSystem = true;

		std::string fullRelativePath = path + "/" + entry.name;
		int fileIndex = getFileListIndex(fullRelativePath);
		if (fileIndex != -1)
			entry.startSector = fileList[fileIndex].firstBlock;
		myVector.push_back(entry);
	}
	FindClose(hFind);
#else
	dirent *dirp;
	std::string localPath = GetLocalPath(path);
	DIR *dp = opendir(localPath.c_str());

#if HOST_IS_CASE_SENSITIVE
	if(dp == NULL && FixPathCase(basePath,path, FPC_FILE_MUST_EXIST)) {
		// May have failed due to case sensitivity, try again
		localPath = GetLocalPath(path);
		dp = opendir(localPath.c_str());
	}
#endif

	if (dp == NULL) {
		ERROR_LOG(FILESYS,"Error opening directory %s\n", path.c_str());
		return myVector;
	}

	while ((dirp = readdir(dp)) != NULL) {
		if (!strcmp(dirp->d_name, "..") || !strcmp(dirp->d_name, ".")) {
			continue;
		}

		PSPFileInfo entry;
		struct stat s;
		std::string fullName = GetLocalPath(path) + "/"+dirp->d_name;
		stat(fullName.c_str(), &s);
		if (S_ISDIR(s.st_mode))
			entry.type = FILETYPE_DIRECTORY;
		else
			entry.type = FILETYPE_NORMAL;
		entry.access = s.st_mode & 0x1FF;
		entry.name = dirp->d_name;
		entry.size = s.st_size;
		localtime_r((time_t*)&s.st_atime,&entry.atime);
		localtime_r((time_t*)&s.st_ctime,&entry.ctime);
		localtime_r((time_t*)&s.st_mtime,&entry.mtime);
		entry.isOnSectorSystem = true;

		std::string fullRelativePath = path + "/" + entry.name;
		int fileIndex = getFileListIndex(fullRelativePath);
		if (fileIndex != -1)
			entry.startSector = fileList[fileIndex].firstBlock;
		myVector.push_back(entry);
	}
	closedir(dp);
#endif
	return myVector;
}
예제 #21
0
BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam)
{
	//if (!m_hDlg) return FALSE;
	switch(message)
	{
	case WM_INITDIALOG:
		{
			return TRUE;
		}
		break;

	case WM_TIMER:
		{
			int iPage = TabCtrl_GetCurSel (GetDlgItem(m_hDlg, IDC_LEFTTABS));
			ShowWindow(GetDlgItem(m_hDlg, IDC_FUNCTIONLIST), iPage?SW_NORMAL:SW_HIDE);
			ShowWindow(GetDlgItem(m_hDlg, IDC_REGLIST),      iPage?SW_HIDE:SW_NORMAL);
		}
		break;

	case WM_NOTIFY:
		switch (wParam)
		{
		case IDC_LEFTTABS:
			{
				HWND tabs = GetDlgItem(m_hDlg, IDC_LEFTTABS);
				NMHDR* pNotifyMessage = NULL;
				pNotifyMessage = (LPNMHDR)lParam; 		
				if (pNotifyMessage->hwndFrom == tabs)
				{
					int iPage = TabCtrl_GetCurSel (tabs);
					ShowWindow(GetDlgItem(m_hDlg, IDC_FUNCTIONLIST), iPage?SW_NORMAL:SW_HIDE);
					ShowWindow(GetDlgItem(m_hDlg, IDC_REGLIST),      iPage?SW_HIDE:SW_NORMAL);
				}
			}
			break;
		case IDC_BREAKPOINTLIST:
			breakpointList->handleNotify(lParam);
			break;
		case IDC_THREADLIST:
			threadList->handleNotify(lParam);
			break;
		case IDC_STACKFRAMES:
			stackTraceView->handleNotify(lParam);
			break;
		}
		break;
	case WM_COMMAND:
		{
			CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW));
			CtrlRegisterList *reglist = CtrlRegisterList::getFrom(GetDlgItem(m_hDlg,IDC_REGLIST));
			switch(LOWORD(wParam))
			{
			case ID_TOGGLE_PAUSE:
				SendMessage(MainWindow::GetHWND(),WM_COMMAND,ID_TOGGLE_PAUSE,0);
				break;
				
			case ID_DEBUG_DISPLAYMEMVIEW:
				changeSubWindow(SUBWIN_MEM);
				break;

			case ID_DEBUG_DISPLAYBREAKPOINTLIST:
				changeSubWindow(SUBWIN_BREAKPOINT);
				break;

			case ID_DEBUG_DISPLAYTHREADLIST:
				changeSubWindow(SUBWIN_THREADS);
				break;

			case ID_DEBUG_DISPLAYSTACKFRAMELIST:
				changeSubWindow(SUBWIN_STACKFRAMES);
				break;

			case ID_DEBUG_DSIPLAYREGISTERLIST:
				TabCtrl_SetCurSel(GetDlgItem(m_hDlg, IDC_LEFTTABS),0);
				ShowWindow(GetDlgItem(m_hDlg, IDC_REGLIST), SW_NORMAL);
				ShowWindow(GetDlgItem(m_hDlg, IDC_FUNCTIONLIST), SW_HIDE);
				break;
				
			case ID_DEBUG_DSIPLAYFUNCTIONLIST:
				TabCtrl_SetCurSel(GetDlgItem(m_hDlg, IDC_LEFTTABS),1);
				ShowWindow(GetDlgItem(m_hDlg, IDC_REGLIST), SW_HIDE);
				ShowWindow(GetDlgItem(m_hDlg, IDC_FUNCTIONLIST), SW_NORMAL);
				break;

			case ID_DEBUG_ADDBREAKPOINT:
				{
					keepStatusBarText = true;
					bool isRunning = Core_IsActive();
					if (isRunning)
					{
						SetDebugMode(true);
						Core_EnableStepping(true);
						Core_WaitInactive(200);
					}

					BreakpointWindow bpw(m_hDlg,cpu);
					if (bpw.exec()) bpw.addBreakpoint();

					if (isRunning)
					{
						SetDebugMode(false);
						Core_EnableStepping(false);
					}
					keepStatusBarText = false;
				}
				break;

			case ID_DEBUG_STEPOVER:
				if (GetFocus() == GetDlgItem(m_hDlg,IDC_DISASMVIEW)) stepOver();
				break;

			case ID_DEBUG_STEPINTO:
				if (GetFocus() == GetDlgItem(m_hDlg,IDC_DISASMVIEW)) stepInto();
				break;

			case ID_DEBUG_RUNTOLINE:
				if (GetFocus() == GetDlgItem(m_hDlg,IDC_DISASMVIEW)) runToLine();
				break;

			case ID_DEBUG_STEPOUT:
				if (GetFocus() == GetDlgItem(m_hDlg,IDC_DISASMVIEW)) stepOut();
				break;

			case IDC_SHOWVFPU:
				vfpudlg->Show(true);
				break;

			case IDC_FUNCTIONLIST: 
				switch (HIWORD(wParam))
				{
				case CBN_DBLCLK:
					{
						HWND lb = GetDlgItem(m_hDlg,LOWORD(wParam));
						int n = ListBox_GetCurSel(lb);
						if (n!=-1)
						{
							unsigned int addr = (unsigned int)ListBox_GetItemData(lb,n);
							ptr->gotoAddr(addr);
							SetFocus(GetDlgItem(m_hDlg, IDC_DISASMVIEW));
						}
					}
					break;
				};
				break;

			case IDC_GOTOINT:
				switch (HIWORD(wParam))
				{
				case LBN_SELCHANGE:
					{
						HWND lb =GetDlgItem(m_hDlg,LOWORD(wParam));
						int n = ComboBox_GetCurSel(lb);
						unsigned int addr = (unsigned int)ComboBox_GetItemData(lb,n);
						if (addr != 0xFFFFFFFF)
						{
							ptr->gotoAddr(addr);
							SetFocus(GetDlgItem(m_hDlg, IDC_DISASMVIEW));
						}
					}
					break;
				};
				break;

			case IDC_STOPGO:
				{
					if (!Core_IsStepping())		// stop
					{
						ptr->setDontRedraw(false);
						SetDebugMode(true);
						Core_EnableStepping(true);
						_dbg_update_();
						Sleep(1); //let cpu catch up
						ptr->gotoPC();
						UpdateDialog();
						vfpudlg->Update();
					} else {					// go
						lastTicks = CoreTiming::GetTicks();

						// If the current PC is on a breakpoint, the user doesn't want to do nothing.
						CBreakPoints::SetSkipFirst(currentMIPS->pc);

						SetDebugMode(false);
						Core_EnableStepping(false);
					}
				}
				break;

			case IDC_STEP:
				stepInto();
				break;

			case IDC_STEPOVER:
				stepOver();
				break;

			case IDC_STEPOUT:
				stepOut();
				break;
				
			case IDC_STEPHLE:
				{
					if (Core_IsActive())
						break;
					lastTicks = CoreTiming::GetTicks();

					// If the current PC is on a breakpoint, the user doesn't want to do nothing.
					CBreakPoints::SetSkipFirst(currentMIPS->pc);

					hleDebugBreak();
					SetDebugMode(false);
					_dbg_update_();
					Core_EnableStepping(false);
				}
				break;

			case IDC_MEMCHECK:
				SendMessage(m_hDlg,WM_COMMAND,ID_DEBUG_ADDBREAKPOINT,0);
				break;
			case IDC_UPDATECALLSTACK:
				{
					HWND hDlg = m_hDlg;
					HWND list = GetDlgItem(hDlg,IDC_CALLSTACK);
					ComboBox_ResetContent(list);
					
					u32 pc = currentMIPS->pc;
					u32 ra = currentMIPS->r[MIPS_REG_RA];
					DWORD addr = Memory::ReadUnchecked_U32(pc);
					int count=1;
					ComboBox_SetItemData(list, ComboBox_AddString(list, ConvertUTF8ToWString(symbolMap.GetDescription(pc)).c_str()), pc);
					if (symbolMap.GetDescription(pc) != symbolMap.GetDescription(ra))
					{
						ComboBox_SetItemData(list, ComboBox_AddString(list, ConvertUTF8ToWString(symbolMap.GetDescription(ra)).c_str()), ra);
						count++;
					}
					//walk the stack chain
					while (addr != 0xFFFFFFFF && addr!=0 && count++<20)
					{
						DWORD fun = Memory::ReadUnchecked_U32(addr+4);
						const wchar_t *str = ConvertUTF8ToWString(symbolMap.GetDescription(fun)).c_str();
						if (wcslen(str) == 0)
							str = L"(unknown)";
						ComboBox_SetItemData(list, ComboBox_AddString(list,str), fun);
						addr = Memory::ReadUnchecked_U32(addr);
					}
					ComboBox_SetCurSel(list,0);
				}
				break;

			case IDC_GOTOPC:
				{
					ptr->gotoPC();	
					SetFocus(GetDlgItem(m_hDlg, IDC_DISASMVIEW));
					UpdateDialog();
				}
				break;
			case IDC_GOTOLR:
				{
					ptr->gotoAddr(cpu->GetLR());
					SetFocus(GetDlgItem(m_hDlg, IDC_DISASMVIEW));
				}
				break;

			case IDC_BACKWARDLINKS:
				{
					HWND box = GetDlgItem(m_hDlg, IDC_FUNCTIONLIST); 
					int funcnum = symbolMap.GetSymbolNum(ListBox_GetItemData(box,ListBox_GetCurSel(box)));
					if (funcnum!=-1)
						symbolMap.FillListBoxBLinks(box,funcnum);
					break;
				}

			case IDC_ALLFUNCTIONS:
				{
					symbolMap.FillSymbolListBox(GetDlgItem(m_hDlg, IDC_FUNCTIONLIST),ST_FUNCTION);
					break;
				}
			default:
				return FALSE;
			}
			return TRUE;
		}

	case WM_DEB_MAPLOADED:
		NotifyMapLoaded();
		break;

	case WM_DEB_GOTOWPARAM:
	{
		CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW));
		ptr->gotoAddr(wParam);
		SetFocus(GetDlgItem(m_hDlg,IDC_DISASMVIEW));
		break;
	}
	case WM_DEB_GOTOADDRESSEDIT:
		{
			wchar_t szBuffer[256];
			CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW));
			GetWindowText(GetDlgItem(m_hDlg,IDC_ADDRESS),szBuffer,256);

			u32 addr;
			if (parseExpression(ConvertWStringToUTF8(szBuffer).c_str(),cpu,addr) == false)
			{
				displayExpressionError(GetDlgItem(m_hDlg,IDC_ADDRESS));
			} else {
				ptr->gotoAddr(addr);
				SetFocus(GetDlgItem(m_hDlg, IDC_DISASMVIEW));
			}
			UpdateDialog();
		}
		break;

	case WM_DEB_SETDEBUGLPARAM:
		SetDebugMode(lParam != 0);
		return TRUE;

	case WM_DEB_UPDATE:
		Update();
		return TRUE;

	case WM_DEB_TABPRESSED:
		changeSubWindow(SUBWIN_NEXT);
		break;
	case WM_DEB_SETSTATUSBARTEXT:
		if (!keepStatusBarText)
			SendMessage(statusBarWnd,WM_SETTEXT,0,(LPARAM)ConvertUTF8ToWString((const char *)lParam).c_str());
		break;
	case WM_DEB_GOTOHEXEDIT:
		{
			CtrlMemView *memory = CtrlMemView::getFrom(GetDlgItem(m_hDlg,IDC_DEBUGMEMVIEW));
			memory->gotoAddr(wParam);
			
			// display the memory viewer too
			HWND bp = GetDlgItem(m_hDlg, IDC_BREAKPOINTLIST);
			HWND mem = GetDlgItem(m_hDlg, IDC_DEBUGMEMVIEW);
			HWND threads = GetDlgItem(m_hDlg, IDC_THREADLIST);
			ShowWindow(bp,SW_HIDE);
			ShowWindow(mem,SW_NORMAL);
			ShowWindow(threads,SW_HIDE);
		}
		break;
	case WM_SIZE:
		{
			UpdateSize(LOWORD(lParam), HIWORD(lParam));
			SendMessage(statusBarWnd,WM_SIZE,0,10);
			SavePosition();
			return TRUE;
		}

	case WM_MOVE:
		SavePosition();
		break;
	case WM_GETMINMAXINFO:
		{
			MINMAXINFO *m = (MINMAXINFO *)lParam;
			// Reduce the minimum size slightly, so they can size it however they like.
			m->ptMinTrackSize.x = defaultRect.right - defaultRect.left - 100;
			//m->ptMaxTrackSize.x = m->ptMinTrackSize.x;
			m->ptMinTrackSize.y = defaultRect.bottom - defaultRect.top - 200;
		}
		return TRUE;
	case WM_CLOSE:
		Show(false);
		return TRUE;
	case WM_ACTIVATE:
		if (wParam == WA_ACTIVE || wParam == WA_CLICKACTIVE)
		{
			g_debuggerActive = true;
		} else {
			g_debuggerActive = false;
		}
		break;
	}
	return FALSE;
}
예제 #22
0
파일: System.cpp 프로젝트: Carter07/ppsspp
// 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);
	}
}
예제 #23
0
파일: main.cpp 프로젝트: sigh0829/ppsspp
int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow)
{
    Common::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 hideLog = true;
#else
    bool hideLog = 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();

    std::string configFilename;
    const char *configOption = "--config=";

    std::string controlsConfigFilename;
    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);
            }
        }
    }

    if(configFilename.empty())
        configFilename = "ppsspp.ini";

    if(controlsConfigFilename.empty())
        controlsConfigFilename = "controls.ini";

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

    // 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':
                hideLog = false;
                break;
            case 's':
                g_Config.bAutoRun = false;
                g_Config.bSaveSettings = false;
                break;
            }

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

            if (!strncmp(__argv[i], "--windowed", strlen("--windowed")))
                g_Config.bFullScreen = false;
        }
    }

    LogManager::Init();
    LogManager::GetInstance()->GetConsoleListener()->Open(hideLog, 150, 120, "PPSSPP Debug Console");


    //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(memoryWindow[0] = new CMemoryDlg(_hInstance, hwndMain, currentDebugMIPS));
    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();

    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
    {
        //DSound_UpdateSound();

        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]->GetDlgHandle();
            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();

    EmuThread_Stop();

    DialogManager::DestroyAll();
    timeEndPeriod(1);
    delete host;
    g_Config.Save();
    LogManager::Shutdown();
    return 0;
}
예제 #24
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;
}
std::vector<PSPFileInfo> DirectoryFileSystem::GetDirListing(std::string path) {
	std::vector<PSPFileInfo> myVector;
#ifdef _WIN32_NO_MINGW
	WIN32_FIND_DATA findData;
	HANDLE hFind;

	std::string w32path = GetLocalPath(path) + "\\*.*";

	hFind = FindFirstFile(ConvertUTF8ToWString(w32path).c_str(), &findData);

	if (hFind == INVALID_HANDLE_VALUE) {
		return myVector; //the empty list
	}

	while (true) {
		PSPFileInfo entry;
		if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
			entry.type = FILETYPE_DIRECTORY;
		else
			entry.type = FILETYPE_NORMAL;

		// TODO: Make this more correct?
		entry.access = entry.type == FILETYPE_NORMAL ? 0666 : 0777;
		// TODO: is this just for .. or all subdirectories? Need to add a directory to the test
		// to find out. Also why so different than the old test results?
		if (!wcscmp(findData.cFileName, L"..") )
			entry.size = 4096;
		else
			entry.size = findData.nFileSizeLow | ((u64)findData.nFileSizeHigh<<32);
		entry.name = ConvertWStringToUTF8(findData.cFileName);
		tmFromFiletime(entry.atime, findData.ftLastAccessTime);
		tmFromFiletime(entry.ctime, findData.ftCreationTime);
		tmFromFiletime(entry.mtime, findData.ftLastWriteTime);
		myVector.push_back(entry);

		int retval = FindNextFile(hFind, &findData);
		if (!retval)
			break;
	}
	FindClose(hFind);
#else
	dirent *dirp;
	std::string localPath = GetLocalPath(path);
	DIR *dp = opendir(localPath.c_str());

#if HOST_IS_CASE_SENSITIVE
	if(dp == NULL && FixPathCase(basePath,path, FPC_FILE_MUST_EXIST)) {
		// May have failed due to case sensitivity, try again
		localPath = GetLocalPath(path);
		dp = opendir(localPath.c_str());
	}
#endif

	if (dp == NULL) {
		ERROR_LOG(FILESYS,"Error opening directory %s\n",path.c_str());
		return myVector;
	}

	while ((dirp = readdir(dp)) != NULL) {
		PSPFileInfo entry;
		struct stat s;
		std::string fullName = GetLocalPath(path) + "/"+dirp->d_name;
		stat(fullName.c_str(), &s);
		if (S_ISDIR(s.st_mode))
			entry.type = FILETYPE_DIRECTORY;
		else
			entry.type = FILETYPE_NORMAL;
		entry.access = s.st_mode & 0x1FF;
		entry.name = dirp->d_name;
		entry.size = s.st_size;
		localtime_r((time_t*)&s.st_atime,&entry.atime);
		localtime_r((time_t*)&s.st_ctime,&entry.ctime);
		localtime_r((time_t*)&s.st_mtime,&entry.mtime);
		myVector.push_back(entry);
	}
	closedir(dp);
#endif
	return myVector;
}
예제 #26
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);
	}
}
예제 #27
0
size_t getFilesInDir(const char *directory, std::vector<FileInfo> *files, const char *filter) {
    size_t foundEntries = 0;
    std::set<std::string> filters;
    std::string tmp;
    if (filter) {
        while (*filter) {
            if (*filter == ':') {
                filters.insert(tmp);
                tmp = "";
            } else {
                tmp.push_back(*filter);
            }
            filter++;
        }
    }
    if (tmp.size())
        filters.insert(tmp);
#ifdef _WIN32
    // Find the first file in the directory.
    WIN32_FIND_DATA ffd;
#ifdef UNICODE

    HANDLE hFind = FindFirstFile((ConvertUTF8ToWString(directory) + L"\\*").c_str(), &ffd);
#else
    HANDLE hFind = FindFirstFile((std::string(directory) + "\\*").c_str(), &ffd);
#endif
    if (hFind == INVALID_HANDLE_VALUE) {
        FindClose(hFind);
        return 0;
    }
    // windows loop
    do
    {
        const std::string virtualName = ConvertWStringToUTF8(ffd.cFileName);
#else
    struct dirent_large {
        struct dirent entry;
        char padding[FILENAME_MAX+1];
    };
    struct dirent_large diren;
    struct dirent *result = NULL;

    //std::string directoryWithSlash = directory;
    //if (directoryWithSlash.back() != '/')
    //	directoryWithSlash += "/";

    DIR *dirp = opendir(directory);
    if (!dirp)
        return 0;
    // non windows loop
    while (!readdir_r(dirp, (dirent*) &diren, &result) && result)
    {
        const std::string virtualName(result->d_name);
#endif
        // check for "." and ".."
        if (((virtualName[0] == '.') && (virtualName[1] == '\0')) ||
                ((virtualName[0] == '.') && (virtualName[1] == '.') &&
                 (virtualName[2] == '\0')))
            continue;

        // Remove dotfiles (should be made optional?)
        if (virtualName[0] == '.')
            continue;

        FileInfo info;
        info.name = virtualName;
        std::string dir = directory;

        // Only append a slash if there isn't one on the end.
        size_t lastSlash = dir.find_last_of("/");
        if (lastSlash != (dir.length() - 1))
            dir.append("/");

        info.fullName = dir + virtualName;
        info.isDirectory = isDirectory(info.fullName);
        info.exists = true;
        info.size = 0;
        if (!info.isDirectory) {
            std::string ext = getFileExtension(info.fullName);
            if (filter) {
                if (filters.find(ext) == filters.end())
                    continue;
            }
        }

        if (files)
            files->push_back(info);
        foundEntries++;
#ifdef _WIN32
    }
    while (FindNextFile(hFind, &ffd) != 0);
    FindClose(hFind);
#else
    }
    closedir(dirp);
#endif
    if (files)
        std::sort(files->begin(), files->end());
    return foundEntries;
}
예제 #28
0
bool D3D11Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) {
	hWnd_ = wnd;
	LoadD3D11Error result = LoadD3D11();

	HRESULT hr = E_FAIL;
	std::vector<std::string> adapterNames;
	std::string chosenAdapterName;
	if (result == LoadD3D11Error::SUCCESS) {
		std::vector<IDXGIAdapter *> adapters;
		int chosenAdapter = 0;

		IDXGIFactory * pFactory = nullptr;
		ptr_CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&pFactory);

		IDXGIAdapter *pAdapter;
		for (UINT i = 0; pFactory->EnumAdapters(i, &pAdapter) != DXGI_ERROR_NOT_FOUND; i++) {
			adapters.push_back(pAdapter);
			DXGI_ADAPTER_DESC desc;
			pAdapter->GetDesc(&desc);
			std::string str = ConvertWStringToUTF8(desc.Description);
			adapterNames.push_back(str);
			if (str == g_Config.sD3D11Device) {
				chosenAdapter = i;
			}
		}

		chosenAdapterName = adapterNames[chosenAdapter];
		hr = CreateTheDevice(adapters[chosenAdapter]);
		for (int i = 0; i < (int)adapters.size(); i++) {
			adapters[i]->Release();
		}
	}

	if (FAILED(hr)) {
		const char *defaultError = "Your GPU does not appear to support Direct3D 11.\n\nWould you like to try again using Direct3D 9 instead?";
		I18NCategory *err = GetI18NCategory("Error");

		std::wstring error;

		if (result == LoadD3D11Error::FAIL_NO_COMPILER) {
			error = ConvertUTF8ToWString(err->T("D3D11CompilerMissing", "D3DCompiler_47.dll not found. Please install. Or press Yes to try again using Direct3D9 instead."));
		} else if (result == LoadD3D11Error::FAIL_NO_D3D11) {
			error = ConvertUTF8ToWString(err->T("D3D11Missing", "Your operating system version does not include D3D11. Please run Windows Update.\n\nPress Yes to try again using Direct3D9 instead."));
		}

		error = ConvertUTF8ToWString(err->T("D3D11NotSupported", defaultError));
		std::wstring title = ConvertUTF8ToWString(err->T("D3D11InitializationError", "Direct3D 11 initialization error"));
		bool yes = IDYES == MessageBox(hWnd_, error.c_str(), title.c_str(), MB_ICONERROR | MB_YESNO);
		if (yes) {
			// Change the config to D3D9 and restart.
			g_Config.iGPUBackend = (int)GPUBackend::DIRECT3D9;
			g_Config.sFailedGPUBackends.clear();
			g_Config.Save("save_d3d9_fallback");

			W32Util::ExitAndRestart();
		}
		return false;
	}

	if (FAILED(device_->QueryInterface(__uuidof (ID3D11Device1), (void **)&device1_))) {
		device1_ = nullptr;
	}

	if (FAILED(context_->QueryInterface(__uuidof (ID3D11DeviceContext1), (void **)&context1_))) {
		context1_ = nullptr;
	}

#ifdef _DEBUG
	if (SUCCEEDED(device_->QueryInterface(__uuidof(ID3D11Debug), (void**)&d3dDebug_))) {
		if (SUCCEEDED(d3dDebug_->QueryInterface(__uuidof(ID3D11InfoQueue), (void**)&d3dInfoQueue_))) {
			d3dInfoQueue_->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_CORRUPTION, true);
			d3dInfoQueue_->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR, true);
			d3dInfoQueue_->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_WARNING, true);
		}
	}
#endif

	draw_ = Draw::T3DCreateD3D11Context(device_, context_, device1_, context1_, featureLevel_, hWnd_, adapterNames);
	SetGPUBackend(GPUBackend::DIRECT3D11, chosenAdapterName);
	bool success = draw_->CreatePresets();  // If we can run D3D11, there's a compiler installed. I think.
	_assert_msg_(G3D, success, "Failed to compile preset shaders");

	int width;
	int height;
	GetRes(hWnd_, width, height);

	// Obtain DXGI factory from device (since we used nullptr for pAdapter above)
	IDXGIFactory1* dxgiFactory = nullptr;
	IDXGIDevice* dxgiDevice = nullptr;
	IDXGIAdapter* adapter = nullptr;
	hr = device_->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&dxgiDevice));
	if (SUCCEEDED(hr)) {
		hr = dxgiDevice->GetAdapter(&adapter);
		if (SUCCEEDED(hr)) {
			hr = adapter->GetParent(__uuidof(IDXGIFactory1), reinterpret_cast<void**>(&dxgiFactory));
			DXGI_ADAPTER_DESC desc;
			adapter->GetDesc(&desc);
			adapter->Release();
		}
		dxgiDevice->Release();
	}

	// DirectX 11.0 systems
	DXGI_SWAP_CHAIN_DESC sd;
	ZeroMemory(&sd, sizeof(sd));
	sd.BufferCount = 1;
	sd.BufferDesc.Width = width;
	sd.BufferDesc.Height = height;
	sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	sd.BufferDesc.RefreshRate.Numerator = 60;
	sd.BufferDesc.RefreshRate.Denominator = 1;
	sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	sd.OutputWindow = hWnd_;
	sd.SampleDesc.Count = 1;
	sd.SampleDesc.Quality = 0;
	sd.Windowed = TRUE;

	hr = dxgiFactory->CreateSwapChain(device_, &sd, &swapChain_);
	dxgiFactory->MakeWindowAssociation(hWnd_, DXGI_MWA_NO_ALT_ENTER);
	dxgiFactory->Release();

	GotBackbuffer();
	return true;
}
예제 #29
0
BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam)
{
	//if (!m_hDlg) return FALSE;
	switch(message)
	{
	case WM_INITDIALOG:
		{
			return TRUE;
		}
		break;

	case WM_NOTIFY:
		switch (wParam)
		{
		case IDC_LEFTTABS:
			leftTabs->HandleNotify(lParam);
			break;
		case IDC_BREAKPOINTLIST:
			breakpointList->HandleNotify(lParam);
			break;
		case IDC_THREADLIST:
			threadList->HandleNotify(lParam);
			break;
		case IDC_STACKFRAMES:
			stackTraceView->HandleNotify(lParam);
			break;
		case IDC_MODULELIST:
			moduleList->HandleNotify(lParam);
			break;
		case IDC_DEBUG_BOTTOMTABS:
			bottomTabs->HandleNotify(lParam);
			break;
		}
		break;
	case WM_COMMAND:
		{
			CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW));
			CtrlRegisterList *reglist = CtrlRegisterList::getFrom(GetDlgItem(m_hDlg,IDC_REGLIST));
			switch(LOWORD(wParam))
			{
			case ID_TOGGLE_PAUSE:
				SendMessage(MainWindow::GetHWND(),WM_COMMAND,ID_TOGGLE_PAUSE,0);
				break;
				
			case ID_DEBUG_DISPLAYMEMVIEW:
				bottomTabs->ShowTab(GetDlgItem(m_hDlg,IDC_DEBUGMEMVIEW));
				break;

			case ID_DEBUG_DISPLAYBREAKPOINTLIST:
				bottomTabs->ShowTab(breakpointList->GetHandle());
				break;

			case ID_DEBUG_DISPLAYTHREADLIST:
				bottomTabs->ShowTab(threadList->GetHandle());
				break;

			case ID_DEBUG_DISPLAYSTACKFRAMELIST:
				bottomTabs->ShowTab(stackTraceView->GetHandle());
				break;

			case ID_DEBUG_DSIPLAYREGISTERLIST:
				leftTabs->ShowTab(0);
				break;
				
			case ID_DEBUG_DSIPLAYFUNCTIONLIST:
				leftTabs->ShowTab(1);
				break;

			case ID_DEBUG_ADDBREAKPOINT:
				{
					keepStatusBarText = true;
					bool isRunning = Core_IsActive();
					if (isRunning)
					{
						SetDebugMode(true, false);
						Core_EnableStepping(true);
						Core_WaitInactive(200);
					}

					BreakpointWindow bpw(m_hDlg,cpu);
					if (bpw.exec()) bpw.addBreakpoint();

					if (isRunning)
					{
						SetDebugMode(false, false);
						Core_EnableStepping(false);
					}
					keepStatusBarText = false;
				}
				break;

			case ID_DEBUG_STEPOVER:
				if (GetFocus() == GetDlgItem(m_hDlg,IDC_DISASMVIEW)) stepOver();
				break;

			case ID_DEBUG_STEPINTO:
				if (GetFocus() == GetDlgItem(m_hDlg,IDC_DISASMVIEW)) stepInto();
				break;

			case ID_DEBUG_RUNTOLINE:
				if (GetFocus() == GetDlgItem(m_hDlg,IDC_DISASMVIEW)) runToLine();
				break;

			case ID_DEBUG_STEPOUT:
				if (GetFocus() == GetDlgItem(m_hDlg,IDC_DISASMVIEW)) stepOut();
				break;

			case ID_DEBUG_HIDEBOTTOMTABS:
				{
					RECT rect;
					hideBottomTabs = !hideBottomTabs;
					GetClientRect(m_hDlg,&rect);
					UpdateSize(rect.right-rect.left,rect.bottom-rect.top);
				}
				break;

			case ID_DEBUG_TOGGLEBOTTOMTABTITLES:
				bottomTabs->SetShowTabTitles(!bottomTabs->GetShowTabTitles());
				break;

			case IDC_SHOWVFPU:
				vfpudlg->Show(true);
				break;

			case IDC_FUNCTIONLIST: 
				switch (HIWORD(wParam))
				{
				case CBN_DBLCLK:
					{
						HWND lb = GetDlgItem(m_hDlg,LOWORD(wParam));
						int n = ListBox_GetCurSel(lb);
						if (n!=-1)
						{
							unsigned int addr = (unsigned int)ListBox_GetItemData(lb,n);
							ptr->gotoAddr(addr);
							SetFocus(GetDlgItem(m_hDlg, IDC_DISASMVIEW));
						}
					}
					break;
				};
				break;

			case IDC_GOTOINT:
				switch (HIWORD(wParam))
				{
				case LBN_SELCHANGE:
					{
						HWND lb =GetDlgItem(m_hDlg,LOWORD(wParam));
						int n = ComboBox_GetCurSel(lb);
						unsigned int addr = (unsigned int)ComboBox_GetItemData(lb,n);
						if (addr != 0xFFFFFFFF)
						{
							ptr->gotoAddr(addr);
							SetFocus(GetDlgItem(m_hDlg, IDC_DISASMVIEW));
						}
					}
					break;
				};
				break;

			case IDC_STOPGO:
				{
					if (!PSP_IsInited()) {
						break;
					}
					if (!Core_IsStepping())		// stop
					{
						ptr->setDontRedraw(false);
						SetDebugMode(true, true);
						Core_EnableStepping(true);
						_dbg_update_();
						Sleep(1); //let cpu catch up
						ptr->gotoPC();
						UpdateDialog();
						vfpudlg->Update();
					} else {					// go
						lastTicks = CoreTiming::GetTicks();

						// If the current PC is on a breakpoint, the user doesn't want to do nothing.
						CBreakPoints::SetSkipFirst(currentMIPS->pc);

						SetDebugMode(false, true);
						Core_EnableStepping(false);
					}
				}
				break;

			case IDC_STEP:
				stepInto();
				break;

			case IDC_STEPOVER:
				stepOver();
				break;

			case IDC_STEPOUT:
				stepOut();
				break;
				
			case IDC_STEPHLE:
				{
					if (Core_IsActive())
						break;
					lastTicks = CoreTiming::GetTicks();

					// If the current PC is on a breakpoint, the user doesn't want to do nothing.
					CBreakPoints::SetSkipFirst(currentMIPS->pc);

					hleDebugBreak();
					SetDebugMode(false, true);
					_dbg_update_();
					Core_EnableStepping(false);
				}
				break;

			case IDC_MEMCHECK:
				SendMessage(m_hDlg,WM_COMMAND,ID_DEBUG_ADDBREAKPOINT,0);
				break;

			case IDC_GOTOPC:
				{
					ptr->gotoPC();	
					SetFocus(GetDlgItem(m_hDlg, IDC_DISASMVIEW));
					UpdateDialog();
				}
				break;
			case IDC_GOTOLR:
				{
					ptr->gotoAddr(cpu->GetLR());
					SetFocus(GetDlgItem(m_hDlg, IDC_DISASMVIEW));
				}
				break;

			case IDC_ALLFUNCTIONS:
				{
					symbolMap.FillSymbolListBox(GetDlgItem(m_hDlg, IDC_FUNCTIONLIST),ST_FUNCTION);
					break;
				}
			default:
				return FALSE;
			}
			return TRUE;
		}

	case WM_DEB_MAPLOADED:
		NotifyMapLoaded();
		break;

	case WM_DEB_GOTOWPARAM:
	{
		CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW));
		ptr->gotoAddr(wParam);
		SetFocus(GetDlgItem(m_hDlg,IDC_DISASMVIEW));
		break;
	}
	case WM_DEB_GOTOADDRESSEDIT:
		{
			if (!PSP_IsInited()) {
				break;
			}
			wchar_t szBuffer[256];
			CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW));
			GetWindowText(GetDlgItem(m_hDlg,IDC_ADDRESS),szBuffer,256);

			u32 addr;
			if (parseExpression(ConvertWStringToUTF8(szBuffer).c_str(),cpu,addr) == false)
			{
				displayExpressionError(GetDlgItem(m_hDlg,IDC_ADDRESS));
			} else {
				ptr->gotoAddr(addr);
				SetFocus(GetDlgItem(m_hDlg, IDC_DISASMVIEW));
			}
			UpdateDialog();
		}
		break;

	case WM_DEB_SETDEBUGLPARAM:
		SetDebugMode(lParam != 0, true);
		return TRUE;

	case WM_DEB_UPDATE:
		Update();
		return TRUE;

	case WM_DEB_TABPRESSED:
		bottomTabs->NextTab(true);
		SetFocus(bottomTabs->CurrentTabHandle());
		break;

	case WM_DEB_SETSTATUSBARTEXT:
		if (!keepStatusBarText)
			SetWindowText(statusBarWnd, ConvertUTF8ToWString((const char *)lParam).c_str());
		break;
	case WM_DEB_GOTOHEXEDIT:
		{
			CtrlMemView *memory = CtrlMemView::getFrom(GetDlgItem(m_hDlg,IDC_DEBUGMEMVIEW));
			memory->gotoAddr(wParam);
			
			// display the memory viewer too
			bottomTabs->ShowTab(GetDlgItem(m_hDlg,IDC_DEBUGMEMVIEW));
		}
		break;
	case WM_SIZE:
		{
			UpdateSize(LOWORD(lParam), HIWORD(lParam));
			SendMessage(statusBarWnd,WM_SIZE,0,10);
			SavePosition();
			return TRUE;
		}

	case WM_MOVE:
		SavePosition();
		break;
	case WM_GETMINMAXINFO:
		{
			MINMAXINFO *m = (MINMAXINFO *)lParam;
			// Reduce the minimum size slightly, so they can size it however they like.
			m->ptMinTrackSize.x = minWidth;
			//m->ptMaxTrackSize.x = m->ptMinTrackSize.x;
			m->ptMinTrackSize.y = minHeight;
		}
		return TRUE;
	case WM_CLOSE:
		Show(false);
		return TRUE;
	case WM_ACTIVATE:
		if (wParam == WA_ACTIVE || wParam == WA_CLICKACTIVE)
		{
			g_activeWindow = WINDOW_CPUDEBUGGER;
		}
		break;
	}
	return FALSE;
}
예제 #30
0
	LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)	{
		switch (message) {
		case WM_CREATE:
			break;
			
		case WM_GETMINMAXINFO:
			{
				MINMAXINFO *minmax = reinterpret_cast<MINMAXINFO *>(lParam);
				RECT rc = { 0 };
				bool portrait = g_Config.IsPortrait();
				rc.right = portrait ? 272 : 480;
				rc.bottom = portrait ? 480 : 272;
				AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, TRUE);
				minmax->ptMinTrackSize.x = rc.right - rc.left;
				minmax->ptMinTrackSize.y = rc.bottom - rc.top;
			}
			return 0;

		case WM_ACTIVATE:
			{
				bool pause = true;
				if (wParam == WA_ACTIVE || wParam == WA_CLICKACTIVE) {
					WindowsRawInput::GainFocus();
					InputDevice::GainFocus();
					g_activeWindow = WINDOW_MAINWINDOW;
					pause = false;
				}
				if (!noFocusPause && g_Config.bPauseOnLostFocus && GetUIState() == UISTATE_INGAME) {
					if (pause != Core_IsStepping()) {	// != is xor for bools
						if (disasmWindow[0])
							SendMessage(disasmWindow[0]->GetDlgHandle(), WM_COMMAND, IDC_STOPGO, 0);
						else
							Core_EnableStepping(pause);
					}
				}

				if (wParam == WA_ACTIVE) {
					NativeMessageReceived("got_focus", "");
				}
				if (wParam == WA_INACTIVE) {
					NativeMessageReceived("lost_focus", "");
					WindowsRawInput::LoseFocus();
					InputDevice::LoseFocus();
				}
			}
			break;

    case WM_ERASEBKGND:
      // This window is always covered by DisplayWindow. No reason to erase.
			return 1;

		case WM_MOVE:
			SavePosition();
			break;

		case WM_SIZE:
			switch (wParam) {
			case SIZE_RESTORED:
			case SIZE_MAXIMIZED:
				if (g_IgnoreWM_SIZE) {
					return DefWindowProc(hWnd, message, wParam, lParam);
				} else {
					SavePosition();
					Core_NotifyWindowHidden(false);
					if (!g_Config.bPauseWhenMinimized) {
						NativeMessageReceived("window minimized", "false");
					}

					int width = 0, height = 0;
					RECT rc;
					GetClientRect(hwndMain, &rc);
					width = rc.right - rc.left;
					height = rc.bottom - rc.top;

					// Moves the internal display window to match the inner size of the main window.
					MoveWindow(hwndDisplay, 0, 0, width, height, TRUE);

					// Setting pixelWidth to be too small could have odd consequences.
					if (width >= 4 && height >= 4) {
						// The framebuffer manager reads these once per frame, hopefully safe enough.. should really use a mutex or some
						// much better mechanism.
						PSP_CoreParameter().pixelWidth = width;
						PSP_CoreParameter().pixelHeight = height;
					}

					UpdateRenderResolution();

					if (UpdateScreenScale(width, height, IsWindowSmall())) {
						NativeMessageReceived("gpu resized", "");
					}

					// Don't save the window state if fullscreen.
					if (!g_Config.bFullScreen) {
						g_WindowState = wParam;
					}
				}
				break;

			case SIZE_MINIMIZED:
				Core_NotifyWindowHidden(true);
				if (!g_Config.bPauseWhenMinimized) {
					NativeMessageReceived("window minimized", "true");
				}
				break;
			default:
				break;
			}
			break;

    case WM_TIMER:
			// Hack: Take the opportunity to also show/hide the mouse cursor in fullscreen mode.
			switch (wParam) {
			case TIMER_CURSORUPDATE:
				CorrectCursor();
				return 0;

			case TIMER_CURSORMOVEUPDATE:
				hideCursor = true;
				KillTimer(hWnd, TIMER_CURSORMOVEUPDATE);
				return 0;
			}
			break;

		// For some reason, need to catch this here rather than in DisplayProc.
		case WM_MOUSEWHEEL:
			{
				int wheelDelta = (short)(wParam >> 16);
				KeyInput key;
				key.deviceId = DEVICE_ID_MOUSE;

				if (wheelDelta < 0) {
					key.keyCode = NKCODE_EXT_MOUSEWHEEL_DOWN;
					wheelDelta = -wheelDelta;
				} else {
					key.keyCode = NKCODE_EXT_MOUSEWHEEL_UP;
				}
				// There's no separate keyup event for mousewheel events, let's pass them both together.
				// This also means it really won't work great for key mapping :( Need to build a 1 frame delay or something.
				key.flags = KEY_DOWN | KEY_UP | KEY_HASWHEELDELTA | (wheelDelta << 16);
				NativeKey(key);
			}
			break;

		case WM_COMMAND:
			{
				if (!EmuThread_Ready())
					return DefWindowProc(hWnd, message, wParam, lParam);

				MainWindowMenu_Process(hWnd, wParam);
			}
			break;

		case WM_USER_TOGGLE_FULLSCREEN:
			ToggleFullscreen(hwndMain, !g_Config.bFullScreen);
			break;

		case WM_INPUT:
			return WindowsRawInput::Process(hWnd, wParam, lParam);

		// TODO: Could do something useful with WM_INPUT_DEVICE_CHANGE?

		// Not sure why we are actually getting WM_CHAR even though we use RawInput, but alright..
		case WM_CHAR:
			return WindowsRawInput::ProcessChar(hWnd, wParam, lParam);

		case WM_VERYSLEEPY_MSG:
			switch (wParam) {
			case VERYSLEEPY_WPARAM_SUPPORTED:
				return TRUE;

			case VERYSLEEPY_WPARAM_GETADDRINFO:
				{
					VerySleepy_AddrInfo *info = (VerySleepy_AddrInfo *)lParam;
					const u8 *ptr = (const u8 *)info->addr;
					std::string name;

					if (MIPSComp::jit && MIPSComp::jit->DescribeCodePtr(ptr, name)) {
						swprintf_s(info->name, L"Jit::%S", name.c_str());
						return TRUE;
					}
					if (gpu && gpu->DescribeCodePtr(ptr, name)) {
						swprintf_s(info->name, L"GPU::%S", name.c_str());
						return TRUE;
					}
				}
				return FALSE;

			default:
				return FALSE;
			}
			break;

		case WM_DROPFILES:
			{
				if (!EmuThread_Ready())
					return DefWindowProc(hWnd, message, wParam, lParam);

				HDROP hdrop = (HDROP)wParam;
				int count = DragQueryFile(hdrop,0xFFFFFFFF,0,0);
				if (count != 1) {
					MessageBox(hwndMain,L"You can only load one file at a time",L"Error",MB_ICONINFORMATION);
				}
				else
				{
					TCHAR filename[512];
					DragQueryFile(hdrop,0,filename,512);
					TCHAR *type = filename+_tcslen(filename)-3;
					
					NativeMessageReceived("boot", ConvertWStringToUTF8(filename).c_str());
					Core_EnableStepping(false);
				}
			}
			break;

		case WM_CLOSE:
			EmuThread_Stop();
			InputDevice::StopPolling();
			WindowsRawInput::Shutdown();

			return DefWindowProc(hWnd,message,wParam,lParam);

		case WM_DESTROY:
			KillTimer(hWnd, TIMER_CURSORUPDATE);
			KillTimer(hWnd, TIMER_CURSORMOVEUPDATE);
			PostQuitMessage(0);
			break;

		case WM_USER + 1:
			if (disasmWindow[0])
				disasmWindow[0]->NotifyMapLoaded();
			if (memoryWindow[0])
				memoryWindow[0]->NotifyMapLoaded();

			if (disasmWindow[0])
				disasmWindow[0]->UpdateDialog();

			SetForegroundWindow(hwndMain);
			break;

		case WM_USER_SAVESTATE_FINISH:
			SetCursor(LoadCursor(0, IDC_ARROW));
			break;

		case WM_USER_UPDATE_UI:
			TranslateMenus(hwndMain, menu);
			break;

		case WM_USER_UPDATE_SCREEN:
			ShowScreenResolution();
			break;

		case WM_USER_WINDOW_TITLE_CHANGED:
			UpdateWindowTitle();
			break;

		case WM_USER_BROWSE_BOOT_DONE:
			BrowseAndBootDone();
			break;

		case WM_MENUSELECT:
			// Unfortunately, accelerate keys (hotkeys) shares the same enabled/disabled states
			// with corresponding menu items.
			UpdateMenus();
			WindowsRawInput::NotifyMenu();
			break;

		// Turn off the screensaver.
		// Note that if there's a screensaver password, this simple method
		// doesn't work on Vista or higher.
		case WM_SYSCOMMAND:
			{
				switch (wParam) {
				case SC_SCREENSAVE:  
					return 0;
				case SC_MONITORPOWER:
					return 0;      
				}
				return DefWindowProc(hWnd, message, wParam, lParam);
			}

		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
		}
		return 0;
	}