~ppsspp/ppsspp/ppsspp-1.2.2

« back to all changes in this revision

Viewing changes to Windows/EmuThread.cpp

  • Committer: Sérgio Benjamim
  • Date: 2016-04-25 02:30:18 UTC
  • Revision ID: sergio_br2@yahoo.com.br-20160425023018-wk3rd7nu30fejjzz
1.2.2 source.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// NOTE: Apologies for the quality of this code, this is really from pre-opensource Dolphin - that is, 2003.
 
2
 
 
3
#include "base/timeutil.h"
 
4
#include "base/NativeApp.h"
 
5
#include "base/mutex.h"
 
6
#include "i18n/i18n.h"
 
7
#include "input/input_state.h"
 
8
#include "util/text/utf8.h"
 
9
 
 
10
#include "Common/Log.h"
 
11
#include "Common/StringUtils.h"
 
12
#include "../Globals.h"
 
13
#include "Windows/EmuThread.h"
 
14
#include "Windows/W32Util/Misc.h"
 
15
#include "Windows/MainWindow.h"
 
16
#include "Windows/resource.h"
 
17
#include "Core/Reporting.h"
 
18
#include "Core/MemMap.h"
 
19
#include "Core/Core.h"
 
20
#include "Core/Host.h"
 
21
#include "Core/System.h"
 
22
#include "Core/Config.h"
 
23
#include "thread/threadutil.h"
 
24
 
 
25
#include <tchar.h>
 
26
#include <process.h>
 
27
#include <intrin.h>
 
28
#pragma intrinsic(_InterlockedExchange)
 
29
 
 
30
static recursive_mutex emuThreadLock;
 
31
static HANDLE emuThread;
 
32
static volatile long emuThreadReady;
 
33
 
 
34
InputState input_state;
 
35
 
 
36
extern std::vector<std::wstring> GetWideCmdLine();
 
37
 
 
38
enum EmuThreadStatus : long
 
39
{
 
40
        THREAD_NONE = 0,
 
41
        THREAD_INIT,
 
42
        THREAD_CORE_LOOP,
 
43
        THREAD_SHUTDOWN,
 
44
        THREAD_END,
 
45
};
 
46
 
 
47
HANDLE EmuThread_GetThreadHandle()
 
48
{
 
49
        lock_guard guard(emuThreadLock);
 
50
        return emuThread;
 
51
}
 
52
 
 
53
unsigned int WINAPI TheThread(void *);
 
54
 
 
55
void EmuThread_Start()
 
56
{
 
57
        lock_guard guard(emuThreadLock);
 
58
        emuThread = (HANDLE)_beginthreadex(0, 0, &TheThread, 0, 0, 0);
 
59
}
 
60
 
 
61
void EmuThread_Stop()
 
62
{
 
63
        // Already stopped?
 
64
        {
 
65
                lock_guard guard(emuThreadLock);
 
66
                if (emuThread == NULL || emuThreadReady == THREAD_END)
 
67
                        return;
 
68
        }
 
69
 
 
70
        UpdateUIState(UISTATE_EXIT);
 
71
        Core_Stop();
 
72
        Core_WaitInactive(800);
 
73
        if (WAIT_TIMEOUT == WaitForSingleObject(emuThread, 800))
 
74
        {
 
75
                _dbg_assert_msg_(COMMON, false, "Wait for EmuThread timed out.");
 
76
        }
 
77
        {
 
78
                lock_guard guard(emuThreadLock);
 
79
                CloseHandle(emuThread);
 
80
                emuThread = 0;
 
81
        }
 
82
        host->UpdateUI();
 
83
}
 
84
 
 
85
bool EmuThread_Ready()
 
86
{
 
87
        return emuThreadReady == THREAD_CORE_LOOP;
 
88
}
 
89
 
 
90
unsigned int WINAPI TheThread(void *)
 
91
{
 
92
        _InterlockedExchange(&emuThreadReady, THREAD_INIT);
 
93
 
 
94
        setCurrentThreadName("Emu");  // And graphics...
 
95
 
 
96
        // Native overwrites host. Can't allow that.
 
97
 
 
98
        Host *oldHost = host;
 
99
 
 
100
        // Convert the command-line arguments to Unicode, then to proper UTF-8 
 
101
        // (the benefit being that we don't have to pollute the UI project with win32 ifdefs and lots of Convert<whatever>To<whatever>).
 
102
        // This avoids issues with PPSSPP inadvertently destroying paths with Unicode glyphs 
 
103
        // (using the ANSI args resulted in Japanese/Chinese glyphs being turned into question marks, at least for me..).
 
104
        // -TheDax
 
105
        std::vector<std::wstring> wideArgs = GetWideCmdLine();
 
106
        std::vector<std::string> argsUTF8;
 
107
        for (auto& string : wideArgs) {
 
108
                argsUTF8.push_back(ConvertWStringToUTF8(string));
 
109
        }
 
110
 
 
111
        std::vector<const char *> args;
 
112
 
 
113
        for (auto& string : argsUTF8) {
 
114
                args.push_back(string.c_str());
 
115
        }
 
116
 
 
117
        NativeInit(static_cast<int>(args.size()), &args[0], "1234", "1234", nullptr);
 
118
 
 
119
        Host *nativeHost = host;
 
120
        host = oldHost;
 
121
 
 
122
        host->UpdateUI();
 
123
 
 
124
        GraphicsContext *graphicsContext;
 
125
 
 
126
        std::string error_string;
 
127
        if (!host->InitGraphics(&error_string, &graphicsContext)) {
 
128
                I18NCategory *err = GetI18NCategory("Error");
 
129
                Reporting::ReportMessage("Graphics init error: %s", error_string.c_str());
 
130
 
 
131
                const char *defaultErrorOpenGL = "Failed initializing graphics. Try upgrading your graphics drivers.\n\nWould you like to try switching to DirectX 9?\n\nError message:";
 
132
                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:";
 
133
                const char *genericError;
 
134
                int nextBackend = GPU_BACKEND_DIRECT3D9;
 
135
                switch (g_Config.iGPUBackend) {
 
136
                case GPU_BACKEND_DIRECT3D9:
 
137
                        nextBackend = GPU_BACKEND_OPENGL;
 
138
                        genericError = err->T("GenericDirect3D9Error", defaultErrorDirect3D9);
 
139
                        break;
 
140
                case GPU_BACKEND_OPENGL:
 
141
                default:
 
142
                        nextBackend = GPU_BACKEND_DIRECT3D9;
 
143
                        genericError = err->T("GenericOpenGLError", defaultErrorOpenGL);
 
144
                        break;
 
145
                }
 
146
                std::string full_error = StringFromFormat("%s\n\n%s", genericError, error_string.c_str());
 
147
                std::wstring title = ConvertUTF8ToWString(err->T("GenericGraphicsError", "Graphics Error"));
 
148
                bool yes = IDYES == MessageBox(0, ConvertUTF8ToWString(full_error).c_str(), title.c_str(), MB_ICONERROR | MB_YESNO);
 
149
                ERROR_LOG(BOOT, full_error.c_str());
 
150
 
 
151
                if (yes) {
 
152
                        // Change the config to the alternative and restart.
 
153
                        g_Config.iGPUBackend = nextBackend;
 
154
                        g_Config.Save();
 
155
 
 
156
                        W32Util::ExitAndRestart();
 
157
                }
 
158
 
 
159
                // No safe way out without graphics.
 
160
                ExitProcess(1);
 
161
        }
 
162
 
 
163
        PSP_CoreParameter().graphicsContext = graphicsContext;
 
164
 
 
165
        NativeInitGraphics(graphicsContext);
 
166
        NativeResized();
 
167
 
 
168
        INFO_LOG(BOOT, "Done.");
 
169
        _dbg_update_();
 
170
 
 
171
        if (coreState == CORE_POWERDOWN) {
 
172
                INFO_LOG(BOOT, "Exit before core loop.");
 
173
                goto shutdown;
 
174
        }
 
175
 
 
176
        _InterlockedExchange(&emuThreadReady, THREAD_CORE_LOOP);
 
177
 
 
178
        if (g_Config.bBrowse)
 
179
                PostMessage(MainWindow::GetHWND(), WM_COMMAND, ID_FILE_LOAD, 0);
 
180
 
 
181
        Core_EnableStepping(FALSE);
 
182
 
 
183
        while (GetUIState() != UISTATE_EXIT)
 
184
        {
 
185
                // We're here again, so the game quit.  Restart Core_Run() which controls the UI.
 
186
                // This way they can load a new game.
 
187
                if (!Core_IsActive())
 
188
                        UpdateUIState(UISTATE_MENU);
 
189
 
 
190
                Core_Run(graphicsContext);
 
191
        }
 
192
 
 
193
shutdown:
 
194
        _InterlockedExchange(&emuThreadReady, THREAD_SHUTDOWN);
 
195
 
 
196
        NativeShutdownGraphics();
 
197
 
 
198
        host->ShutdownSound();
 
199
        host = nativeHost;
 
200
        NativeShutdown();
 
201
        host = oldHost;
 
202
        host->ShutdownGraphics();
 
203
        
 
204
        _InterlockedExchange(&emuThreadReady, THREAD_END);
 
205
 
 
206
        return 0;
 
207
}
 
208
 
 
209