~ppsspp/ppsspp/ppsspp_1.3.0

« back to all changes in this revision

Viewing changes to Windows/main.cpp

  • Committer: Sérgio Benjamim
  • Date: 2017-01-02 00:12:05 UTC
  • Revision ID: sergio_br2@yahoo.com.br-20170102001205-cxbta9za203nmjwm
1.3.0 source (from ppsspp_1.3.0-r160.p5.l1762.a165.t83~56~ubuntu16.04.1.tar.xz).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright (c) 2012- PPSSPP Project.
 
2
 
 
3
// This program is free software: you can redistribute it and/or modify
 
4
// it under the terms of the GNU General Public License as published by
 
5
// the Free Software Foundation, version 2.0 or later versions.
 
6
 
 
7
// This program is distributed in the hope that it will be useful,
 
8
// but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
// GNU General Public License 2.0 for more details.
 
11
 
 
12
// A copy of the GPL 2.0 should have been included with the program.
 
13
// If not, see http://www.gnu.org/licenses/
 
14
 
 
15
// Official git repository and contact information can be found at
 
16
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
 
17
 
 
18
#include <algorithm>
 
19
#include <WinNls.h>
 
20
#include <math.h>
 
21
#include <Wbemidl.h>
 
22
 
 
23
#include "Common/CommonWindows.h"
 
24
 
 
25
#include "file/vfs.h"
 
26
#include "file/zip_read.h"
 
27
#include "base/NativeApp.h"
 
28
#include "profiler/profiler.h"
 
29
#include "thread/threadutil.h"
 
30
#include "util/text/utf8.h"
 
31
 
 
32
#include "Core/Config.h"
 
33
#include "Core/SaveState.h"
 
34
#include "Windows/EmuThread.h"
 
35
#include "Windows/DSoundStream.h"
 
36
#include "ext/disarm.h"
 
37
 
 
38
#include "Common/LogManager.h"
 
39
#include "Common/ConsoleListener.h"
 
40
 
 
41
#include "Commctrl.h"
 
42
 
 
43
#include "UI/GameInfoCache.h"
 
44
#include "Windows/resource.h"
 
45
 
 
46
#include "Windows/MainWindow.h"
 
47
#include "Windows/Debugger/Debugger_Disasm.h"
 
48
#include "Windows/Debugger/Debugger_MemoryDlg.h"
 
49
#include "Windows/Debugger/Debugger_VFPUDlg.h"
 
50
#include "Windows/GEDebugger/GEDebugger.h"
 
51
 
 
52
#include "Windows/W32Util/DialogManager.h"
 
53
 
 
54
#include "Windows/Debugger/CtrlDisAsmView.h"
 
55
#include "Windows/Debugger/CtrlMemView.h"
 
56
#include "Windows/Debugger/CtrlRegisterList.h"
 
57
#include "Windows/InputBox.h"
 
58
 
 
59
#include "Windows/WindowsHost.h"
 
60
#include "Windows/main.h"
 
61
 
 
62
 
 
63
// Nvidia drivers >= v302 will check if the application exports a global
 
64
// variable named NvOptimusEnablement to know if it should run the app in high
 
65
// performance graphics mode or using the IGP.
 
66
extern "C" {
 
67
        __declspec(dllexport) DWORD NvOptimusEnablement = 1;
 
68
}
 
69
 
 
70
CDisasm *disasmWindow[MAX_CPUCOUNT] = {0};
 
71
CGEDebugger *geDebuggerWindow = 0;
 
72
CMemoryDlg *memoryWindow[MAX_CPUCOUNT] = {0};
 
73
 
 
74
static std::string langRegion;
 
75
static std::string osName;
 
76
static std::string gpuDriverVersion;
 
77
 
 
78
void LaunchBrowser(const char *url) {
 
79
        ShellExecute(NULL, L"open", ConvertUTF8ToWString(url).c_str(), NULL, NULL, SW_SHOWNORMAL);
 
80
}
 
81
 
 
82
void Vibrate(int length_ms) {
 
83
        // Ignore on PC
 
84
}
 
85
 
 
86
bool DoesVersionMatchWindows(const u32 major, const u32 minor, const u32 spMajor = 0, const u32 spMinor = 0) {
 
87
        u64 conditionMask = 0;
 
88
        OSVERSIONINFOEX osvi;
 
89
        ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
 
90
 
 
91
        osvi.dwOSVersionInfoSize = sizeof(osvi);
 
92
        osvi.dwMajorVersion = major;
 
93
        osvi.dwMinorVersion = minor;
 
94
        osvi.wServicePackMajor = spMajor;
 
95
        osvi.wServicePackMinor = spMinor;
 
96
        u32 op = VER_EQUAL;
 
97
 
 
98
        VER_SET_CONDITION(conditionMask, VER_MAJORVERSION, op);
 
99
        VER_SET_CONDITION(conditionMask, VER_MINORVERSION, op);
 
100
        VER_SET_CONDITION(conditionMask, VER_SERVICEPACKMAJOR, op);
 
101
        VER_SET_CONDITION(conditionMask, VER_SERVICEPACKMINOR, op);
 
102
 
 
103
        const u32 typeMask = VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR;
 
104
 
 
105
        return VerifyVersionInfo(&osvi, typeMask, conditionMask) != FALSE;
 
106
}
 
107
 
 
108
std::string GetWindowsVersion() {
 
109
        const bool IsWindowsXPSP2 = DoesVersionMatchWindows(5, 1, 2, 0);
 
110
        const bool IsWindowsXPSP3 = DoesVersionMatchWindows(5, 1, 3, 0);
 
111
        const bool IsWindowsVista = DoesVersionMatchWindows(6, 0);
 
112
        const bool IsWindowsVistaSP1 = DoesVersionMatchWindows(6, 0, 1, 0);
 
113
        const bool IsWindowsVistaSP2 = DoesVersionMatchWindows(6, 0, 2, 0);
 
114
        const bool IsWindows7 = DoesVersionMatchWindows(6, 1);
 
115
        const bool IsWindows7SP1 = DoesVersionMatchWindows(6, 1, 1, 0);
 
116
        const bool IsWindows8 = DoesVersionMatchWindows(6, 2);
 
117
        const bool IsWindows8_1 = DoesVersionMatchWindows(6, 3);
 
118
 
 
119
 
 
120
        if (IsWindowsXPSP2)
 
121
                return "Microsoft Windows XP, Service Pack 2";
 
122
 
 
123
        if (IsWindowsXPSP3)
 
124
                return "Microsoft Windows XP, Service Pack 3";
 
125
 
 
126
        if (IsWindowsVista)
 
127
                return "Microsoft Windows Vista";
 
128
 
 
129
        if (IsWindowsVistaSP1)
 
130
                return "Microsoft Windows Vista, Service Pack 1";
 
131
 
 
132
        if (IsWindowsVistaSP2)
 
133
                return "Microsoft Windows Vista, Service Pack 2";
 
134
 
 
135
        if (IsWindows7)
 
136
                return "Microsoft Windows 7";
 
137
 
 
138
        if (IsWindows7SP1)
 
139
                return "Microsoft Windows 7, Service Pack 1";
 
140
 
 
141
        if (IsWindows8)
 
142
                return "Microsoft Windows 8 or greater"; // "Applications not manifested for Windows 10 will return the Windows 8 OS version value (6.2)."
 
143
                                                                                                
 
144
        if (IsWindows8_1)
 
145
                return "Microsoft Windows 8.1";
 
146
 
 
147
        return "Unsupported version of Microsoft Windows.";
 
148
}
 
149
 
 
150
std::string GetWindowsSystemArchitecture() {
 
151
        SYSTEM_INFO sysinfo;
 
152
        ZeroMemory(&sysinfo, sizeof(SYSTEM_INFO));
 
153
        GetNativeSystemInfo(&sysinfo);
 
154
 
 
155
        if (sysinfo.wProcessorArchitecture & PROCESSOR_ARCHITECTURE_AMD64)
 
156
                return "(x64)";
 
157
        // Need to check for equality here, since ANDing with 0 is always 0.
 
158
        else if (sysinfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
 
159
                return "(x86)";
 
160
        else if (sysinfo.wProcessorArchitecture & PROCESSOR_ARCHITECTURE_ARM)
 
161
                return "(ARM)";
 
162
        else
 
163
                return "(Unknown)";
 
164
}
 
165
 
 
166
// Adapted mostly as-is from http://www.gamedev.net/topic/495075-how-to-retrieve-info-about-videocard/?view=findpost&p=4229170
 
167
// so credit goes to that post's author, and in turn, the author of the site mentioned in that post (which seems to be down?).
 
168
std::string GetVideoCardDriverVersion() {
 
169
        std::string retvalue = "";
 
170
 
 
171
        HRESULT hr;
 
172
        hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
 
173
        if (FAILED(hr)) {
 
174
                return retvalue;
 
175
        }
 
176
 
 
177
        IWbemLocator *pIWbemLocator = NULL;
 
178
        hr = CoCreateInstance(__uuidof(WbemLocator), NULL, CLSCTX_INPROC_SERVER, 
 
179
                __uuidof(IWbemLocator), (LPVOID *)&pIWbemLocator);
 
180
        if (FAILED(hr)) {
 
181
                CoUninitialize();
 
182
                return retvalue;
 
183
        }
 
184
 
 
185
        BSTR bstrServer = SysAllocString(L"\\\\.\\root\\cimv2");
 
186
        IWbemServices *pIWbemServices;
 
187
        hr = pIWbemLocator->ConnectServer(bstrServer, NULL, NULL, 0L, 0L, NULL, NULL, &pIWbemServices);
 
188
        if (FAILED(hr)) {
 
189
                pIWbemLocator->Release();
 
190
                SysFreeString(bstrServer);
 
191
                CoUninitialize();
 
192
                return retvalue;
 
193
        }
 
194
 
 
195
        hr = CoSetProxyBlanket(pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, 
 
196
                NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL,EOAC_DEFAULT);
 
197
        
 
198
        BSTR bstrWQL = SysAllocString(L"WQL");
 
199
        BSTR bstrPath = SysAllocString(L"select * from Win32_VideoController");
 
200
        IEnumWbemClassObject* pEnum;
 
201
        hr = pIWbemServices->ExecQuery(bstrWQL, bstrPath, WBEM_FLAG_FORWARD_ONLY, NULL, &pEnum);
 
202
 
 
203
        ULONG uReturned;
 
204
        VARIANT var;
 
205
        IWbemClassObject* pObj = NULL;
 
206
        if (!FAILED(hr)) {
 
207
                hr = pEnum->Next(WBEM_INFINITE, 1, &pObj, &uReturned);
 
208
        }
 
209
 
 
210
        if (!FAILED(hr) && uReturned) {
 
211
                hr = pObj->Get(L"DriverVersion", 0, &var, NULL, NULL);
 
212
                if (SUCCEEDED(hr)) {
 
213
                        char str[MAX_PATH];
 
214
                        WideCharToMultiByte(CP_ACP, 0, var.bstrVal, -1, str, sizeof(str), NULL, NULL);
 
215
                        retvalue = str;
 
216
                }
 
217
        }
 
218
 
 
219
        pEnum->Release();
 
220
        SysFreeString(bstrPath);
 
221
        SysFreeString(bstrWQL);
 
222
        pIWbemServices->Release();
 
223
        pIWbemLocator->Release();
 
224
        SysFreeString(bstrServer);
 
225
        CoUninitialize();
 
226
        return retvalue;
 
227
}
 
228
 
 
229
std::string System_GetProperty(SystemProperty prop) {
 
230
        static bool hasCheckedGPUDriverVersion = false;
 
231
        switch (prop) {
 
232
        case SYSPROP_NAME:
 
233
                return osName;
 
234
        case SYSPROP_LANGREGION:
 
235
                return langRegion;
 
236
        case SYSPROP_CLIPBOARD_TEXT:
 
237
                {
 
238
                        std::string retval;
 
239
                        if (OpenClipboard(MainWindow::GetDisplayHWND())) {
 
240
                                HANDLE handle = GetClipboardData(CF_UNICODETEXT);
 
241
                                const wchar_t *wstr = (const wchar_t*)GlobalLock(handle);
 
242
                                if (wstr)
 
243
                                        retval = ConvertWStringToUTF8(wstr);
 
244
                                else
 
245
                                        retval = "";
 
246
                                GlobalUnlock(handle);
 
247
                                CloseClipboard();
 
248
                        }
 
249
                        return retval;
 
250
                }
 
251
        case SYSPROP_GPUDRIVER_VERSION:
 
252
                if (!hasCheckedGPUDriverVersion) {
 
253
                        hasCheckedGPUDriverVersion = true;
 
254
                        gpuDriverVersion = GetVideoCardDriverVersion();
 
255
                }
 
256
                return gpuDriverVersion;
 
257
        default:
 
258
                return "";
 
259
        }
 
260
}
 
261
 
 
262
// Ugly!
 
263
extern WindowsAudioBackend *winAudioBackend;
 
264
 
 
265
int System_GetPropertyInt(SystemProperty prop) {
 
266
        switch (prop) {
 
267
        case SYSPROP_AUDIO_SAMPLE_RATE:
 
268
                return winAudioBackend ? winAudioBackend->GetSampleRate() : -1;
 
269
        case SYSPROP_DISPLAY_REFRESH_RATE:
 
270
                return 60000;
 
271
        case SYSPROP_DEVICE_TYPE:
 
272
                return DEVICE_TYPE_DESKTOP;
 
273
        default:
 
274
                return -1;
 
275
        }
 
276
}
 
277
 
 
278
void System_SendMessage(const char *command, const char *parameter) {
 
279
        if (!strcmp(command, "finish")) {
 
280
                PostMessage(MainWindow::GetHWND(), WM_CLOSE, 0, 0);
 
281
        } else if (!strcmp(command, "setclipboardtext")) {
 
282
                if (OpenClipboard(MainWindow::GetDisplayHWND())) {
 
283
                        std::wstring data = ConvertUTF8ToWString(parameter);
 
284
                        HANDLE handle = GlobalAlloc(GMEM_MOVEABLE, (data.size() + 1) * sizeof(wchar_t));
 
285
                        wchar_t *wstr = (wchar_t *)GlobalLock(handle);
 
286
                        memcpy(wstr, data.c_str(), (data.size() + 1) * sizeof(wchar_t));
 
287
                        GlobalUnlock(wstr);
 
288
                        SetClipboardData(CF_UNICODETEXT, handle);
 
289
                        GlobalFree(handle);
 
290
                        CloseClipboard();
 
291
                }
 
292
        }
 
293
}
 
294
 
 
295
void System_AskForPermission(SystemPermission permission) {}
 
296
PermissionStatus System_GetPermissionStatus(SystemPermission permission) { return PERMISSION_STATUS_GRANTED; }
 
297
 
 
298
void EnableCrashingOnCrashes() {
 
299
        typedef BOOL (WINAPI *tGetPolicy)(LPDWORD lpFlags);
 
300
        typedef BOOL (WINAPI *tSetPolicy)(DWORD dwFlags);
 
301
        const DWORD EXCEPTION_SWALLOWING = 0x1;
 
302
 
 
303
        HMODULE kernel32 = LoadLibrary(L"kernel32.dll");
 
304
        tGetPolicy pGetPolicy = (tGetPolicy)GetProcAddress(kernel32,
 
305
                "GetProcessUserModeExceptionPolicy");
 
306
        tSetPolicy pSetPolicy = (tSetPolicy)GetProcAddress(kernel32,
 
307
                "SetProcessUserModeExceptionPolicy");
 
308
        if (pGetPolicy && pSetPolicy) {
 
309
                DWORD dwFlags;
 
310
                if (pGetPolicy(&dwFlags)) {
 
311
                        // Turn off the filter.
 
312
                        pSetPolicy(dwFlags & ~EXCEPTION_SWALLOWING);
 
313
                }
 
314
        }
 
315
        FreeLibrary(kernel32);
 
316
}
 
317
 
 
318
bool System_InputBoxGetString(const char *title, const char *defaultValue, char *outValue, size_t outLength)
 
319
{
 
320
        std::string out;
 
321
        if (InputBox_GetString(MainWindow::GetHInstance(), MainWindow::GetHWND(), ConvertUTF8ToWString(title).c_str(), defaultValue, out)) {
 
322
                strcpy(outValue, out.c_str());
 
323
                return true;
 
324
        } else {
 
325
                return false;
 
326
        }
 
327
}
 
328
 
 
329
bool System_InputBoxGetWString(const wchar_t *title, const std::wstring &defaultvalue, std::wstring &outvalue)
 
330
{
 
331
        if (InputBox_GetWString(MainWindow::GetHInstance(), MainWindow::GetHWND(), title, defaultvalue, outvalue)) {
 
332
                return true;
 
333
        } else {
 
334
                return false;
 
335
        }
 
336
}
 
337
 
 
338
static std::string GetDefaultLangRegion() {
 
339
        wchar_t lcLangName[256] = {};
 
340
 
 
341
        // LOCALE_SNAME is only available in WinVista+
 
342
        if (0 != GetLocaleInfo(LOCALE_NAME_USER_DEFAULT, LOCALE_SNAME, lcLangName, ARRAY_SIZE(lcLangName))) {
 
343
                std::string result = ConvertWStringToUTF8(lcLangName);
 
344
                std::replace(result.begin(), result.end(), '-', '_');
 
345
                return result;
 
346
        } else {
 
347
                // This should work on XP, but we may get numbers for some countries.
 
348
                if (0 != GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME, lcLangName, ARRAY_SIZE(lcLangName))) {
 
349
                        wchar_t lcRegion[256] = {};
 
350
                        if (0 != GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SISO3166CTRYNAME, lcRegion, ARRAY_SIZE(lcRegion))) {
 
351
                                return ConvertWStringToUTF8(lcLangName) + "_" + ConvertWStringToUTF8(lcRegion);
 
352
                        }
 
353
                }
 
354
                // Unfortunate default.  We tried.
 
355
                return "en_US";
 
356
        }
 
357
}
 
358
 
 
359
std::vector<std::wstring> GetWideCmdLine() {
 
360
        wchar_t **wargv;
 
361
        int wargc = -1;
 
362
        wargv = CommandLineToArgvW(GetCommandLineW(), &wargc);
 
363
 
 
364
        std::vector<std::wstring> wideArgs(wargv, wargv + wargc);
 
365
 
 
366
        return wideArgs;
 
367
}
 
368
 
 
369
int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow)
 
370
{
 
371
        setCurrentThreadName("Main");
 
372
 
 
373
        CoInitializeEx(NULL, COINIT_MULTITHREADED);
 
374
 
 
375
#ifdef _DEBUG
 
376
        _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
 
377
#endif
 
378
        PROFILE_INIT();
 
379
 
 
380
#if defined(_M_X64) && defined(_MSC_VER) && _MSC_VER < 1900
 
381
        // FMA3 support in the 2013 CRT is broken on Vista and Windows 7 RTM (fixed in SP1). Just disable it.
 
382
        _set_FMA3_enable(0);
 
383
#endif
 
384
 
 
385
        EnableCrashingOnCrashes();
 
386
 
 
387
#ifndef _DEBUG
 
388
        bool showLog = false;
 
389
#else
 
390
        bool showLog = true;
 
391
#endif
 
392
 
 
393
        const std::string &exePath = File::GetExeDirectory();
 
394
        VFSRegister("", new DirectoryAssetReader((exePath + "/assets/").c_str()));
 
395
        VFSRegister("", new DirectoryAssetReader(exePath.c_str()));
 
396
 
 
397
        langRegion = GetDefaultLangRegion();
 
398
        osName = GetWindowsVersion() + " " + GetWindowsSystemArchitecture();
 
399
 
 
400
        char configFilename[MAX_PATH] = { 0 };
 
401
        const std::wstring configOption = L"--config=";
 
402
 
 
403
        char controlsConfigFilename[MAX_PATH] = { 0 };
 
404
        const std::wstring controlsOption = L"--controlconfig=";
 
405
 
 
406
        std::vector<std::wstring> wideArgs = GetWideCmdLine();
 
407
 
 
408
        for (size_t i = 1; i < wideArgs.size(); ++i) {
 
409
                if (wideArgs[i][0] == L'\0')
 
410
                        continue;
 
411
                if (wideArgs[i][0] == L'-') {
 
412
                        if (wideArgs[i].find(configOption) != std::wstring::npos && wideArgs[i].size() > configOption.size()) {
 
413
                                const std::wstring tempWide = wideArgs[i].substr(configOption.size());
 
414
                                const std::string tempStr = ConvertWStringToUTF8(tempWide);
 
415
                                std::strncpy(configFilename, tempStr.c_str(), MAX_PATH);
 
416
                        }
 
417
 
 
418
                        if (wideArgs[i].find(controlsOption) != std::wstring::npos && wideArgs[i].size() > controlsOption.size()) {
 
419
                                const std::wstring tempWide = wideArgs[i].substr(controlsOption.size());
 
420
                                const std::string tempStr = ConvertWStringToUTF8(tempWide);
 
421
                                std::strncpy(controlsConfigFilename, tempStr.c_str(), MAX_PATH);
 
422
                        }
 
423
                }
 
424
        }
 
425
 
 
426
        // On Win32 it makes more sense to initialize the system directories here 
 
427
        // because the next place it was called was in the EmuThread, and it's too late by then.
 
428
        InitSysDirectories();
 
429
 
 
430
        // Load config up here, because those changes below would be overwritten
 
431
        // if it's not loaded here first.
 
432
        g_Config.AddSearchPath("");
 
433
        g_Config.AddSearchPath(GetSysDirectory(DIRECTORY_SYSTEM));
 
434
        g_Config.SetDefaultPath(GetSysDirectory(DIRECTORY_SYSTEM));
 
435
        g_Config.Load(configFilename, controlsConfigFilename);
 
436
 
 
437
        bool debugLogLevel = false;
 
438
 
 
439
        const std::wstring gpuBackend = L"--graphics=";
 
440
 
 
441
        // The rest is handled in NativeInit().
 
442
        for (size_t i = 1; i < wideArgs.size(); ++i) {
 
443
                if (wideArgs[i][0] == L'\0')
 
444
                        continue;
 
445
 
 
446
                if (wideArgs[i][0] == L'-') {
 
447
                        switch (wideArgs[i][1]) {
 
448
                        case L'l':
 
449
                                showLog = true;
 
450
                                g_Config.bEnableLogging = true;
 
451
                                break;
 
452
                        case L's':
 
453
                                g_Config.bAutoRun = false;
 
454
                                g_Config.bSaveSettings = false;
 
455
                                break;
 
456
                        case L'd':
 
457
                                debugLogLevel = true;
 
458
                                break;
 
459
                        }
 
460
 
 
461
                        if (wideArgs[i] == L"--fullscreen")
 
462
                                g_Config.bFullScreen = true;
 
463
 
 
464
                        if (wideArgs[i] == L"--windowed")
 
465
                                g_Config.bFullScreen = false;
 
466
 
 
467
                        if (wideArgs[i].find(gpuBackend) != std::wstring::npos && wideArgs[i].size() > gpuBackend.size()) {
 
468
                                const std::wstring restOfOption = wideArgs[i].substr(gpuBackend.size());
 
469
 
 
470
                                // Force software rendering off, as picking directx9 or gles implies HW acceleration.
 
471
                                // Once software rendering supports Direct3D9/11, we can add more options for software,
 
472
                                // such as "software-gles", "software-d3d9", and "software-d3d11", or something similar.
 
473
                                // For now, software rendering force-activates OpenGL.
 
474
                                if (restOfOption == L"directx9") {
 
475
                                        g_Config.iGPUBackend = GPU_BACKEND_DIRECT3D9;
 
476
                                        g_Config.bSoftwareRendering = false;
 
477
                                } else if (restOfOption == L"gles") {
 
478
                                        g_Config.iGPUBackend = GPU_BACKEND_OPENGL;
 
479
                                        g_Config.bSoftwareRendering = false;
 
480
                                } else if (restOfOption == L"software") {
 
481
                                        g_Config.iGPUBackend = GPU_BACKEND_OPENGL;
 
482
                                        g_Config.bSoftwareRendering = true;
 
483
                                }
 
484
                        }
 
485
                }
 
486
        }
 
487
#ifdef _DEBUG
 
488
        g_Config.bEnableLogging = true;
 
489
#endif
 
490
 
 
491
        if (iCmdShow == SW_MAXIMIZE) {
 
492
                // Consider this to mean --fullscreen.
 
493
                g_Config.bFullScreen = true;
 
494
        }
 
495
 
 
496
        LogManager::Init();
 
497
        // Consider at least the following cases before changing this code:
 
498
        //   - By default in Release, the console should be hidden by default even if logging is enabled.
 
499
        //   - By default in Debug, the console should be shown by default.
 
500
        //   - The -l switch is expected to show the log console, REGARDLESS of config settings.
 
501
        //   - It should be possible to log to a file without showing the console.
 
502
        LogManager::GetInstance()->GetConsoleListener()->Init(showLog, 150, 120, "PPSSPP Debug Console");
 
503
        
 
504
        if (debugLogLevel)
 
505
                LogManager::GetInstance()->SetAllLogLevels(LogTypes::LDEBUG);
 
506
 
 
507
        //Windows, API init stuff
 
508
        INITCOMMONCONTROLSEX comm;
 
509
        comm.dwSize = sizeof(comm);
 
510
        comm.dwICC = ICC_BAR_CLASSES | ICC_LISTVIEW_CLASSES | ICC_TAB_CLASSES;
 
511
        InitCommonControlsEx(&comm);
 
512
        timeBeginPeriod(1);
 
513
        MainWindow::Init(_hInstance);
 
514
 
 
515
        g_hPopupMenus = LoadMenu(_hInstance, (LPCWSTR)IDR_POPUPMENUS);
 
516
 
 
517
        MainWindow::Show(_hInstance);
 
518
 
 
519
        HWND hwndMain = MainWindow::GetHWND();
 
520
        HWND hwndDisplay = MainWindow::GetDisplayHWND();
 
521
        
 
522
        //initialize custom controls
 
523
        CtrlDisAsmView::init();
 
524
        CtrlMemView::init();
 
525
        CtrlRegisterList::init();
 
526
        CGEDebugger::Init();
 
527
 
 
528
        DialogManager::AddDlg(vfpudlg = new CVFPUDlg(_hInstance, hwndMain, currentDebugMIPS));
 
529
 
 
530
        host = new WindowsHost(_hInstance, hwndMain, hwndDisplay);
 
531
        host->SetWindowTitle(0);
 
532
 
 
533
        MainWindow::CreateDebugWindows();
 
534
 
 
535
        const bool minimized = iCmdShow == SW_MINIMIZE || iCmdShow == SW_SHOWMINIMIZED || iCmdShow == SW_SHOWMINNOACTIVE;
 
536
        if (minimized) {
 
537
                MainWindow::Minimize();
 
538
        }
 
539
 
 
540
        // Emu thread is always running!
 
541
        EmuThread_Start();
 
542
        InputDevice::BeginPolling();
 
543
 
 
544
        HACCEL hAccelTable = LoadAccelerators(_hInstance, (LPCTSTR)IDR_ACCELS);
 
545
        HACCEL hDebugAccelTable = LoadAccelerators(_hInstance, (LPCTSTR)IDR_DEBUGACCELS);
 
546
 
 
547
        //so.. we're at the message pump of the GUI thread
 
548
        for (MSG msg; GetMessage(&msg, NULL, 0, 0); )   // for no quit
 
549
        {
 
550
                if (msg.message == WM_KEYDOWN)
 
551
                {
 
552
                        //hack to enable/disable menu command accelerate keys
 
553
                        MainWindow::UpdateCommands();
 
554
                         
 
555
                        //hack to make it possible to get to main window from floating windows with Esc
 
556
                        if (msg.hwnd != hwndMain && msg.wParam == VK_ESCAPE)
 
557
                                BringWindowToTop(hwndMain);
 
558
                }
 
559
 
 
560
                //Translate accelerators and dialog messages...
 
561
                HWND wnd;
 
562
                HACCEL accel;
 
563
                switch (g_activeWindow)
 
564
                {
 
565
                case WINDOW_MAINWINDOW:
 
566
                        wnd = hwndMain;
 
567
                        accel = hAccelTable;
 
568
                        break;
 
569
                case WINDOW_CPUDEBUGGER:
 
570
                        wnd = disasmWindow[0] ? disasmWindow[0]->GetDlgHandle() : 0;
 
571
                        accel = hDebugAccelTable;
 
572
                        break;
 
573
                case WINDOW_GEDEBUGGER:
 
574
                default:
 
575
                        wnd = 0;
 
576
                        accel = 0;
 
577
                        break;
 
578
                }
 
579
 
 
580
                if (!TranslateAccelerator(wnd, accel, &msg))
 
581
                {
 
582
                        if (!DialogManager::IsDialogMessage(&msg))
 
583
                        {
 
584
                                //and finally translate and dispatch
 
585
                                TranslateMessage(&msg);
 
586
                                DispatchMessage(&msg);
 
587
                        }
 
588
                }
 
589
        }
 
590
 
 
591
        VFSShutdown();
 
592
 
 
593
        InputDevice::StopPolling();
 
594
        EmuThread_Stop();
 
595
 
 
596
        MainWindow::DestroyDebugWindows();
 
597
        DialogManager::DestroyAll();
 
598
        timeEndPeriod(1);
 
599
        delete host;
 
600
 
 
601
        g_Config.Save();
 
602
        LogManager::Shutdown();
 
603
 
 
604
        if (g_Config.bRestartRequired) {
 
605
                W32Util::ExitAndRestart();
 
606
        }
 
607
 
 
608
        CoUninitialize();
 
609
 
 
610
        return 0;
 
611
}