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 }
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 ""; } }
//--------------------------------------------------------------------------------------------------- // 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; }
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 }
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; }
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; }
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"; } }
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 }
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 }
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; }
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; }
// 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; }
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 ""; }
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; }
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; }
// 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 }
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 }
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; }
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; }
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; }
// 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); } }
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; }
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; }
// 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); } }
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; }
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; }
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; }
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; }