2012-11-01 15:19:01 +00:00
|
|
|
// Copyright (c) 2012- PPSSPP Project.
|
|
|
|
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU General Public License as published by
|
2012-11-04 22:01:49 +00:00
|
|
|
// the Free Software Foundation, version 2.0 or later versions.
|
2012-11-01 15:19:01 +00:00
|
|
|
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU General Public License 2.0 for more details.
|
|
|
|
|
|
|
|
// A copy of the GPL 2.0 should have been included with the program.
|
|
|
|
// If not, see http://www.gnu.org/licenses/
|
|
|
|
|
|
|
|
// Official git repository and contact information can be found at
|
|
|
|
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
|
|
|
|
2013-09-04 10:07:42 +00:00
|
|
|
#include <WinNls.h>
|
2014-02-13 14:57:36 +00:00
|
|
|
#include <math.h>
|
|
|
|
|
2013-07-29 04:01:49 +00:00
|
|
|
#include "Common/CommonWindows.h"
|
2012-11-01 15:19:01 +00:00
|
|
|
|
|
|
|
#include "file/vfs.h"
|
|
|
|
#include "file/zip_read.h"
|
2013-09-04 09:29:38 +00:00
|
|
|
#include "base/NativeApp.h"
|
2014-06-29 10:53:03 +00:00
|
|
|
#include "thread/threadutil.h"
|
2013-08-26 17:00:16 +00:00
|
|
|
#include "util/text/utf8.h"
|
2012-11-01 15:19:01 +00:00
|
|
|
|
2013-07-29 04:01:49 +00:00
|
|
|
#include "Core/Config.h"
|
|
|
|
#include "Core/SaveState.h"
|
|
|
|
#include "Windows/EmuThread.h"
|
2013-01-08 16:03:17 +00:00
|
|
|
#include "ext/disarm.h"
|
2012-11-01 15:19:01 +00:00
|
|
|
|
2013-07-29 04:01:49 +00:00
|
|
|
#include "Common/LogManager.h"
|
|
|
|
#include "Common/ConsoleListener.h"
|
2012-11-01 15:19:01 +00:00
|
|
|
|
|
|
|
#include "Commctrl.h"
|
|
|
|
|
|
|
|
#include "Windows/resource.h"
|
|
|
|
|
|
|
|
#include "Windows/WndMainWindow.h"
|
2013-09-22 17:27:09 +00:00
|
|
|
#include "Windows/Debugger/Debugger_Disasm.h"
|
2012-11-01 15:19:01 +00:00
|
|
|
#include "Windows/Debugger/Debugger_MemoryDlg.h"
|
|
|
|
#include "Windows/Debugger/Debugger_VFPUDlg.h"
|
2013-09-22 18:03:29 +00:00
|
|
|
#include "Windows/GEDebugger/GEDebugger.h"
|
2012-11-01 15:19:01 +00:00
|
|
|
|
|
|
|
#include "Windows/W32Util/DialogManager.h"
|
|
|
|
|
|
|
|
#include "Windows/Debugger/CtrlDisAsmView.h"
|
|
|
|
#include "Windows/Debugger/CtrlMemView.h"
|
|
|
|
#include "Windows/Debugger/CtrlRegisterList.h"
|
2013-12-08 10:16:18 +00:00
|
|
|
#include "Windows/InputBox.h"
|
2012-11-01 15:19:01 +00:00
|
|
|
|
|
|
|
#include "Windows/WindowsHost.h"
|
|
|
|
#include "Windows/main.h"
|
|
|
|
|
2014-03-03 16:26:27 +00:00
|
|
|
// Nvidia drivers >= v302 will check if the application exports a global
|
|
|
|
// variable named NvOptimusEnablement to know if it should run the app in high
|
|
|
|
// performance graphics mode or using the IGP.
|
|
|
|
extern "C" {
|
|
|
|
__declspec(dllexport) DWORD NvOptimusEnablement = 1;
|
|
|
|
}
|
|
|
|
|
2013-04-01 01:35:29 +00:00
|
|
|
CDisasm *disasmWindow[MAX_CPUCOUNT] = {0};
|
2013-09-22 17:27:09 +00:00
|
|
|
CGEDebugger *geDebuggerWindow = 0;
|
2013-04-01 01:35:29 +00:00
|
|
|
CMemoryDlg *memoryWindow[MAX_CPUCOUNT] = {0};
|
2012-11-01 15:19:01 +00:00
|
|
|
|
2013-09-04 10:07:42 +00:00
|
|
|
static std::string langRegion;
|
2013-10-09 21:17:28 +00:00
|
|
|
static std::string osName;
|
2013-09-04 10:07:42 +00:00
|
|
|
|
2014-02-17 09:02:56 +00:00
|
|
|
typedef BOOL(WINAPI *isProcessDPIAwareProc)();
|
|
|
|
typedef BOOL(WINAPI *setProcessDPIAwareProc)();
|
|
|
|
|
2013-08-26 17:00:16 +00:00
|
|
|
void LaunchBrowser(const char *url) {
|
|
|
|
ShellExecute(NULL, L"open", ConvertUTF8ToWString(url).c_str(), NULL, NULL, SW_SHOWNORMAL);
|
2013-08-17 22:41:19 +00:00
|
|
|
}
|
|
|
|
|
2013-10-10 15:00:15 +00:00
|
|
|
void Vibrate(int length_ms) {
|
|
|
|
// Ignore on PC
|
|
|
|
}
|
|
|
|
|
2013-10-09 17:08:28 +00:00
|
|
|
bool DoesVersionMatchWindows(const u32 major, const u32 minor, const u32 spMajor = 0, const u32 spMinor = 0) {
|
2013-10-09 17:01:59 +00:00
|
|
|
u64 conditionMask = 0;
|
|
|
|
OSVERSIONINFOEX osvi;
|
2013-10-09 17:14:48 +00:00
|
|
|
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
|
2013-10-09 17:01:59 +00:00
|
|
|
|
|
|
|
osvi.dwOSVersionInfoSize = sizeof(osvi);
|
|
|
|
osvi.dwMajorVersion = major;
|
|
|
|
osvi.dwMinorVersion = minor;
|
|
|
|
osvi.wServicePackMajor = spMajor;
|
|
|
|
osvi.wServicePackMinor = spMinor;
|
|
|
|
u32 op = VER_EQUAL;
|
|
|
|
|
|
|
|
VER_SET_CONDITION(conditionMask, VER_MAJORVERSION, op);
|
|
|
|
VER_SET_CONDITION(conditionMask, VER_MINORVERSION, op);
|
|
|
|
VER_SET_CONDITION(conditionMask, VER_SERVICEPACKMAJOR, op);
|
|
|
|
VER_SET_CONDITION(conditionMask, VER_SERVICEPACKMINOR, op);
|
|
|
|
|
|
|
|
const u32 typeMask = VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR;
|
|
|
|
|
2013-10-10 15:00:15 +00:00
|
|
|
return VerifyVersionInfo(&osvi, typeMask, conditionMask) != FALSE;
|
2013-10-09 17:01:59 +00:00
|
|
|
}
|
|
|
|
|
2013-10-09 17:08:28 +00:00
|
|
|
std::string GetWindowsVersion() {
|
2013-10-09 17:01:59 +00:00
|
|
|
const bool IsWindowsXPSP2 = DoesVersionMatchWindows(5, 1, 2, 0);
|
|
|
|
const bool IsWindowsXPSP3 = DoesVersionMatchWindows(5, 1, 3, 0);
|
|
|
|
const bool IsWindowsVista = DoesVersionMatchWindows(6, 0);
|
|
|
|
const bool IsWindowsVistaSP1 = DoesVersionMatchWindows(6, 0, 1, 0);
|
|
|
|
const bool IsWindowsVistaSP2 = DoesVersionMatchWindows(6, 0, 2, 0);
|
|
|
|
const bool IsWindows7 = DoesVersionMatchWindows(6, 1);
|
|
|
|
const bool IsWindows7SP1 = DoesVersionMatchWindows(6, 1, 1, 0);
|
|
|
|
const bool IsWindows8 = DoesVersionMatchWindows(6, 2);
|
|
|
|
const bool IsWindows8_1 = DoesVersionMatchWindows(6, 3);
|
|
|
|
|
|
|
|
if (IsWindowsXPSP2)
|
|
|
|
return "Microsoft Windows XP, Service Pack 2";
|
|
|
|
|
|
|
|
if (IsWindowsXPSP3)
|
|
|
|
return "Microsoft Windows XP, Service Pack 3";
|
|
|
|
|
|
|
|
if (IsWindowsVista)
|
|
|
|
return "Microsoft Windows Vista";
|
|
|
|
|
|
|
|
if (IsWindowsVistaSP1)
|
|
|
|
return "Microsoft Windows Vista, Service Pack 1";
|
|
|
|
|
|
|
|
if (IsWindowsVistaSP2)
|
|
|
|
return "Microsoft Windows Vista, Service Pack 2";
|
|
|
|
|
|
|
|
if (IsWindows7)
|
|
|
|
return "Microsoft Windows 7";
|
|
|
|
|
|
|
|
if (IsWindows7SP1)
|
|
|
|
return "Microsoft Windows 7, Service Pack 1";
|
|
|
|
|
|
|
|
if (IsWindows8)
|
|
|
|
return "Microsoft Windows 8";
|
|
|
|
|
|
|
|
if (IsWindows8_1)
|
|
|
|
return "Microsoft Windows 8.1";
|
|
|
|
|
|
|
|
return "Unsupported version of Microsoft Windows.";
|
|
|
|
}
|
|
|
|
|
2013-10-09 21:17:28 +00:00
|
|
|
std::string GetWindowsSystemArchitecture() {
|
|
|
|
SYSTEM_INFO sysinfo;
|
|
|
|
ZeroMemory(&sysinfo, sizeof(SYSTEM_INFO));
|
|
|
|
GetNativeSystemInfo(&sysinfo);
|
|
|
|
|
2013-10-09 21:40:13 +00:00
|
|
|
if (sysinfo.wProcessorArchitecture & PROCESSOR_ARCHITECTURE_AMD64)
|
2013-10-09 21:17:28 +00:00
|
|
|
return "(x64)";
|
2013-10-09 21:40:13 +00:00
|
|
|
// Need to check for equality here, since ANDing with 0 is always 0.
|
|
|
|
else if (sysinfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
|
2013-10-09 21:17:28 +00:00
|
|
|
return "(x86)";
|
2013-10-09 21:40:13 +00:00
|
|
|
else if (sysinfo.wProcessorArchitecture & PROCESSOR_ARCHITECTURE_ARM)
|
2013-10-09 21:17:28 +00:00
|
|
|
return "(ARM)";
|
|
|
|
else
|
|
|
|
return "(Unknown)";
|
|
|
|
}
|
|
|
|
|
2013-09-04 09:29:38 +00:00
|
|
|
std::string System_GetProperty(SystemProperty prop) {
|
|
|
|
switch (prop) {
|
|
|
|
case SYSPROP_NAME:
|
2013-10-09 21:17:28 +00:00
|
|
|
return osName;
|
2013-09-04 09:29:38 +00:00
|
|
|
case SYSPROP_LANGREGION:
|
2013-09-04 10:07:42 +00:00
|
|
|
return langRegion;
|
2014-07-21 09:59:47 +00:00
|
|
|
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);
|
2014-07-21 12:54:17 +00:00
|
|
|
if (wstr)
|
|
|
|
retval = ConvertWStringToUTF8(wstr);
|
|
|
|
else
|
|
|
|
retval = "";
|
2014-07-21 09:59:47 +00:00
|
|
|
GlobalUnlock(handle);
|
|
|
|
CloseClipboard();
|
|
|
|
}
|
|
|
|
return retval;
|
|
|
|
}
|
2013-09-04 09:29:38 +00:00
|
|
|
default:
|
|
|
|
return "";
|
|
|
|
}
|
2013-08-17 22:41:19 +00:00
|
|
|
}
|
|
|
|
|
2014-07-20 10:11:50 +00:00
|
|
|
int System_GetPropertyInt(SystemProperty prop) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2014-04-26 05:00:45 +00:00
|
|
|
void System_SendMessage(const char *command, const char *parameter) {
|
|
|
|
if (!strcmp(command, "finish")) {
|
|
|
|
PostMessage(MainWindow::GetHWND(), WM_CLOSE, 0, 0);
|
|
|
|
}
|
|
|
|
}
|
2013-12-04 16:41:59 +00:00
|
|
|
|
2014-07-21 09:59:47 +00:00
|
|
|
void EnableCrashingOnCrashes() {
|
2013-11-12 16:50:35 +00:00
|
|
|
typedef BOOL (WINAPI *tGetPolicy)(LPDWORD lpFlags);
|
|
|
|
typedef BOOL (WINAPI *tSetPolicy)(DWORD dwFlags);
|
|
|
|
const DWORD EXCEPTION_SWALLOWING = 0x1;
|
|
|
|
|
2014-06-29 21:29:49 +00:00
|
|
|
HMODULE kernel32 = LoadLibrary(L"kernel32.dll");
|
2013-11-12 16:50:35 +00:00
|
|
|
tGetPolicy pGetPolicy = (tGetPolicy)GetProcAddress(kernel32,
|
|
|
|
"GetProcessUserModeExceptionPolicy");
|
|
|
|
tSetPolicy pSetPolicy = (tSetPolicy)GetProcAddress(kernel32,
|
|
|
|
"SetProcessUserModeExceptionPolicy");
|
|
|
|
if (pGetPolicy && pSetPolicy)
|
|
|
|
{
|
|
|
|
DWORD dwFlags;
|
|
|
|
if (pGetPolicy(&dwFlags))
|
|
|
|
{
|
|
|
|
// Turn off the filter
|
|
|
|
pSetPolicy(dwFlags & ~EXCEPTION_SWALLOWING);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-15 09:47:14 +00:00
|
|
|
bool System_InputBoxGetString(const char *title, const char *defaultValue, char *outValue, size_t outLength)
|
2013-12-08 10:16:18 +00:00
|
|
|
{
|
|
|
|
std::string out;
|
|
|
|
if (InputBox_GetString(MainWindow::GetHInstance(), MainWindow::GetHWND(), ConvertUTF8ToWString(title).c_str(), defaultValue, out)) {
|
|
|
|
strcpy(outValue, out.c_str());
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool System_InputBoxGetWString(const wchar_t *title, const std::wstring &defaultvalue, std::wstring &outvalue)
|
|
|
|
{
|
|
|
|
if (InputBox_GetWString(MainWindow::GetHInstance(), MainWindow::GetHWND(), title, defaultvalue, outvalue)) {
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-17 09:02:56 +00:00
|
|
|
void MakePPSSPPDPIAware()
|
2014-02-17 08:30:38 +00:00
|
|
|
{
|
2014-02-17 09:02:56 +00:00
|
|
|
isProcessDPIAwareProc isDPIAwareProc = (isProcessDPIAwareProc)
|
|
|
|
GetProcAddress(GetModuleHandle(TEXT("User32.dll")), "IsProcessDPIAware");
|
2014-02-17 08:30:38 +00:00
|
|
|
|
2014-02-17 09:02:56 +00:00
|
|
|
setProcessDPIAwareProc setDPIAwareProc = (setProcessDPIAwareProc)
|
|
|
|
GetProcAddress(GetModuleHandle(TEXT("User32.dll")), "SetProcessDPIAware");
|
2014-02-17 08:30:38 +00:00
|
|
|
|
2014-02-17 09:02:56 +00:00
|
|
|
// If we're not DPI aware, make it so, but do it safely.
|
|
|
|
if (isDPIAwareProc != nullptr) {
|
|
|
|
if (!isDPIAwareProc()) {
|
|
|
|
if (setDPIAwareProc != nullptr)
|
|
|
|
setDPIAwareProc();
|
|
|
|
}
|
|
|
|
}
|
2014-02-17 08:30:38 +00:00
|
|
|
}
|
|
|
|
|
2012-11-01 15:19:01 +00:00
|
|
|
int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow)
|
|
|
|
{
|
2014-06-29 10:53:03 +00:00
|
|
|
setCurrentThreadName("Main");
|
|
|
|
|
2014-02-17 08:30:38 +00:00
|
|
|
// Windows Vista and above: alert Windows that PPSSPP is DPI aware,
|
|
|
|
// so that we don't flicker in fullscreen on some PCs.
|
2014-02-17 09:02:56 +00:00
|
|
|
MakePPSSPPDPIAware();
|
2014-02-17 08:30:38 +00:00
|
|
|
|
2014-02-13 14:57:36 +00:00
|
|
|
// FMA3 support in the 2013 CRT is broken on Vista and Windows 7 RTM (fixed in SP1). Just disable it.
|
2014-02-13 15:02:10 +00:00
|
|
|
#ifdef _M_X64
|
2014-02-13 14:57:36 +00:00
|
|
|
_set_FMA3_enable(0);
|
2014-02-13 15:02:10 +00:00
|
|
|
#endif
|
2014-02-13 14:57:36 +00:00
|
|
|
|
2013-11-12 16:50:35 +00:00
|
|
|
EnableCrashingOnCrashes();
|
2012-11-01 15:19:01 +00:00
|
|
|
|
2013-08-26 18:48:34 +00:00
|
|
|
wchar_t modulePath[MAX_PATH];
|
|
|
|
GetModuleFileName(NULL, modulePath, MAX_PATH);
|
2013-08-31 05:12:04 +00:00
|
|
|
for (size_t i = wcslen(modulePath) - 1; i > 0; i--) {
|
2013-08-26 18:48:34 +00:00
|
|
|
if (modulePath[i] == '\\') {
|
|
|
|
modulePath[i] = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
SetCurrentDirectory(modulePath);
|
|
|
|
// GetCurrentDirectory(MAX_PATH, modulePath); // for checking in the debugger
|
2012-12-22 17:54:07 +00:00
|
|
|
|
2013-10-13 19:27:05 +00:00
|
|
|
#ifndef _DEBUG
|
2013-10-16 05:27:03 +00:00
|
|
|
bool showLog = false;
|
2013-10-13 19:27:05 +00:00
|
|
|
#else
|
2013-10-16 05:27:03 +00:00
|
|
|
bool showLog = false;
|
2013-10-13 19:27:05 +00:00
|
|
|
#endif
|
|
|
|
|
2013-09-15 09:02:13 +00:00
|
|
|
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);
|
2013-09-24 06:44:58 +00:00
|
|
|
for (size_t i = 0; i < langRegion.size(); i++) {
|
2013-09-15 09:02:13 +00:00
|
|
|
if (langRegion[i] == '-')
|
|
|
|
langRegion[i] = '_';
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
langRegion = "en_US";
|
|
|
|
}
|
|
|
|
|
2013-10-09 21:17:28 +00:00
|
|
|
osName = GetWindowsVersion() + " " + GetWindowsSystemArchitecture();
|
|
|
|
|
2013-10-12 23:02:03 +00:00
|
|
|
const char *configFilename = NULL;
|
2013-09-15 16:50:42 +00:00
|
|
|
const char *configOption = "--config=";
|
|
|
|
|
2013-10-12 23:02:03 +00:00
|
|
|
const char *controlsConfigFilename = NULL;
|
2013-09-15 16:50:42 +00:00
|
|
|
const char *controlsOption = "--controlconfig=";
|
|
|
|
|
|
|
|
for (int i = 1; i < __argc; ++i)
|
|
|
|
{
|
|
|
|
if (__argv[i][0] == '\0')
|
|
|
|
continue;
|
|
|
|
if (__argv[i][0] == '-')
|
|
|
|
{
|
2013-09-15 16:55:49 +00:00
|
|
|
if (!strncmp(__argv[i], configOption, strlen(configOption)) && strlen(__argv[i]) > strlen(configOption)) {
|
|
|
|
configFilename = __argv[i] + strlen(configOption);
|
2013-09-15 16:50:42 +00:00
|
|
|
}
|
|
|
|
if (!strncmp(__argv[i], controlsOption, strlen(controlsOption)) && strlen(__argv[i]) > strlen(controlsOption)) {
|
|
|
|
controlsConfigFilename = __argv[i] + strlen(controlsOption);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-10-15 06:03:39 +00:00
|
|
|
// On Win32 it makes more sense to initialize the system directories here
|
2013-10-15 06:28:14 +00:00
|
|
|
// because the next place it was called was in the EmuThread, and it's too late by then.
|
2013-10-15 06:03:39 +00:00
|
|
|
InitSysDirectories();
|
2013-09-15 16:50:42 +00:00
|
|
|
|
2013-09-12 20:56:18 +00:00
|
|
|
// Load config up here, because those changes below would be overwritten
|
|
|
|
// if it's not loaded here first.
|
2013-10-12 23:02:03 +00:00
|
|
|
g_Config.AddSearchPath("");
|
2013-10-15 06:03:39 +00:00
|
|
|
g_Config.AddSearchPath(GetSysDirectory(DIRECTORY_SYSTEM));
|
|
|
|
g_Config.SetDefaultPath(GetSysDirectory(DIRECTORY_SYSTEM));
|
2013-10-12 23:02:03 +00:00
|
|
|
g_Config.Load(configFilename, controlsConfigFilename);
|
2013-09-12 20:56:18 +00:00
|
|
|
|
2014-04-01 02:44:05 +00:00
|
|
|
bool debugLogLevel = false;
|
|
|
|
|
2013-04-01 01:22:27 +00:00
|
|
|
// The rest is handled in NativeInit().
|
2012-12-22 17:49:29 +00:00
|
|
|
for (int i = 1; i < __argc; ++i)
|
2012-11-01 15:19:01 +00:00
|
|
|
{
|
2012-12-22 17:49:29 +00:00
|
|
|
if (__argv[i][0] == '\0')
|
2012-12-22 17:21:23 +00:00
|
|
|
continue;
|
|
|
|
|
2012-12-22 17:49:29 +00:00
|
|
|
if (__argv[i][0] == '-')
|
2012-11-01 15:19:01 +00:00
|
|
|
{
|
2012-12-22 17:49:29 +00:00
|
|
|
switch (__argv[i][1])
|
2012-12-22 17:21:23 +00:00
|
|
|
{
|
|
|
|
case 'l':
|
2013-10-16 05:27:03 +00:00
|
|
|
showLog = true;
|
2013-10-13 18:25:59 +00:00
|
|
|
g_Config.bEnableLogging = true;
|
2012-12-22 17:21:23 +00:00
|
|
|
break;
|
|
|
|
case 's':
|
2013-01-04 09:26:14 +00:00
|
|
|
g_Config.bAutoRun = false;
|
|
|
|
g_Config.bSaveSettings = false;
|
2012-12-22 17:21:23 +00:00
|
|
|
break;
|
2014-04-01 02:44:05 +00:00
|
|
|
case 'd':
|
|
|
|
debugLogLevel = true;
|
|
|
|
break;
|
2012-12-22 17:21:23 +00:00
|
|
|
}
|
2013-09-12 20:56:18 +00:00
|
|
|
|
|
|
|
if (!strncmp(__argv[i], "--fullscreen", strlen("--fullscreen")))
|
|
|
|
g_Config.bFullScreen = true;
|
|
|
|
|
|
|
|
if (!strncmp(__argv[i], "--windowed", strlen("--windowed")))
|
|
|
|
g_Config.bFullScreen = false;
|
2012-12-22 17:21:23 +00:00
|
|
|
}
|
2012-11-01 15:19:01 +00:00
|
|
|
}
|
2013-10-13 18:25:59 +00:00
|
|
|
#ifdef _DEBUG
|
|
|
|
g_Config.bEnableLogging = true;
|
|
|
|
#endif
|
2012-11-01 15:19:01 +00:00
|
|
|
|
2013-06-15 08:55:18 +00:00
|
|
|
LogManager::Init();
|
2013-10-13 19:27:05 +00:00
|
|
|
// 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.
|
2013-10-16 05:27:03 +00:00
|
|
|
LogManager::GetInstance()->GetConsoleListener()->Init(showLog, 150, 120, "PPSSPP Debug Console");
|
2014-04-01 02:44:05 +00:00
|
|
|
|
|
|
|
if (debugLogLevel)
|
|
|
|
LogManager::GetInstance()->SetAllLogLevels(LogTypes::LDEBUG);
|
2013-06-08 00:32:07 +00:00
|
|
|
|
2012-11-01 15:19:01 +00:00
|
|
|
//Windows, API init stuff
|
|
|
|
INITCOMMONCONTROLSEX comm;
|
|
|
|
comm.dwSize = sizeof(comm);
|
|
|
|
comm.dwICC = ICC_BAR_CLASSES | ICC_LISTVIEW_CLASSES | ICC_TAB_CLASSES;
|
|
|
|
InitCommonControlsEx(&comm);
|
2012-12-03 08:44:37 +00:00
|
|
|
timeBeginPeriod(1);
|
2012-11-01 15:19:01 +00:00
|
|
|
MainWindow::Init(_hInstance);
|
|
|
|
|
2013-08-26 17:00:16 +00:00
|
|
|
g_hPopupMenus = LoadMenu(_hInstance, (LPCWSTR)IDR_POPUPMENUS);
|
2012-11-01 15:19:01 +00:00
|
|
|
|
2014-07-17 04:06:52 +00:00
|
|
|
MainWindow::Show(_hInstance);
|
2012-11-01 15:19:01 +00:00
|
|
|
|
|
|
|
HWND hwndMain = MainWindow::GetHWND();
|
2014-06-29 20:13:53 +00:00
|
|
|
HWND hwndDisplay = MainWindow::GetDisplayHWND();
|
2013-06-08 00:32:07 +00:00
|
|
|
|
2012-11-01 15:19:01 +00:00
|
|
|
//initialize custom controls
|
|
|
|
CtrlDisAsmView::init();
|
|
|
|
CtrlMemView::init();
|
|
|
|
CtrlRegisterList::init();
|
2013-09-28 05:41:44 +00:00
|
|
|
CGEDebugger::Init();
|
2012-11-01 15:19:01 +00:00
|
|
|
|
|
|
|
DialogManager::AddDlg(vfpudlg = new CVFPUDlg(_hInstance, hwndMain, currentDebugMIPS));
|
|
|
|
|
2014-06-29 20:13:53 +00:00
|
|
|
host = new WindowsHost(hwndMain, hwndDisplay);
|
2013-08-20 15:21:25 +00:00
|
|
|
host->SetWindowTitle(0);
|
2013-03-29 17:50:08 +00:00
|
|
|
|
2013-08-26 12:19:46 +00:00
|
|
|
MainWindow::CreateDebugWindows();
|
|
|
|
|
2013-03-29 17:50:08 +00:00
|
|
|
// Emu thread is always running!
|
|
|
|
EmuThread_Start();
|
2014-03-24 05:18:54 +00:00
|
|
|
InputDevice::BeginPolling();
|
2013-03-29 17:50:08 +00:00
|
|
|
|
2013-06-08 00:32:07 +00:00
|
|
|
HACCEL hAccelTable = LoadAccelerators(_hInstance, (LPCTSTR)IDR_ACCELS);
|
2013-08-14 21:30:50 +00:00
|
|
|
HACCEL hDebugAccelTable = LoadAccelerators(_hInstance, (LPCTSTR)IDR_DEBUGACCELS);
|
2012-12-22 17:21:23 +00:00
|
|
|
|
2012-11-01 15:19:01 +00:00
|
|
|
//so.. we're at the message pump of the GUI thread
|
2013-06-08 00:32:07 +00:00
|
|
|
for (MSG msg; GetMessage(&msg, NULL, 0, 0); ) // for no quit
|
2012-11-01 15:19:01 +00:00
|
|
|
{
|
2013-05-13 08:08:10 +00:00
|
|
|
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);
|
|
|
|
}
|
2012-11-01 15:19:01 +00:00
|
|
|
|
|
|
|
//Translate accelerators and dialog messages...
|
2013-08-14 21:46:59 +00:00
|
|
|
HWND wnd;
|
|
|
|
HACCEL accel;
|
2013-09-28 12:34:08 +00:00
|
|
|
switch (g_activeWindow)
|
|
|
|
{
|
|
|
|
case WINDOW_MAINWINDOW:
|
2013-08-14 21:46:59 +00:00
|
|
|
wnd = hwndMain;
|
|
|
|
accel = hAccelTable;
|
2013-09-28 12:34:08 +00:00
|
|
|
break;
|
|
|
|
case WINDOW_CPUDEBUGGER:
|
2014-02-15 05:17:36 +00:00
|
|
|
wnd = disasmWindow[0] ? disasmWindow[0]->GetDlgHandle() : 0;
|
2013-09-28 12:34:08 +00:00
|
|
|
accel = hDebugAccelTable;
|
|
|
|
break;
|
|
|
|
case WINDOW_GEDEBUGGER:
|
|
|
|
default:
|
|
|
|
wnd = 0;
|
|
|
|
accel = 0;
|
|
|
|
break;
|
2013-08-14 21:46:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!TranslateAccelerator(wnd, accel, &msg))
|
2012-11-01 15:19:01 +00:00
|
|
|
{
|
|
|
|
if (!DialogManager::IsDialogMessage(&msg))
|
|
|
|
{
|
|
|
|
//and finally translate and dispatch
|
|
|
|
TranslateMessage(&msg);
|
|
|
|
DispatchMessage(&msg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-08 18:35:05 +00:00
|
|
|
VFSShutdown();
|
|
|
|
|
2014-03-24 05:18:54 +00:00
|
|
|
InputDevice::StopPolling();
|
2013-06-30 00:47:09 +00:00
|
|
|
EmuThread_Stop();
|
|
|
|
|
2014-02-15 05:17:36 +00:00
|
|
|
MainWindow::DestroyDebugWindows();
|
2012-11-01 15:19:01 +00:00
|
|
|
DialogManager::DestroyAll();
|
2012-12-03 08:44:37 +00:00
|
|
|
timeEndPeriod(1);
|
2012-11-01 15:19:01 +00:00
|
|
|
delete host;
|
2013-06-26 07:31:52 +00:00
|
|
|
g_Config.Save();
|
|
|
|
LogManager::Shutdown();
|
2012-11-01 15:19:01 +00:00
|
|
|
return 0;
|
|
|
|
}
|