2012-11-01 15:19:01 +00:00
|
|
|
// NOTE: Apologies for the quality of this code, this is really from pre-opensource Dolphin - that is, 2003.
|
|
|
|
|
2013-03-29 17:50:08 +00:00
|
|
|
#include "base/display.h"
|
|
|
|
#include "base/timeutil.h"
|
|
|
|
#include "base/NativeApp.h"
|
2013-08-13 15:09:36 +00:00
|
|
|
#include "base/mutex.h"
|
|
|
|
#include "Common/Log.h"
|
|
|
|
#include "Common/StringUtils.h"
|
2012-11-01 15:19:01 +00:00
|
|
|
#include "../Globals.h"
|
2013-08-13 15:09:36 +00:00
|
|
|
#include "Windows/EmuThread.h"
|
|
|
|
#include "Windows/WndMainWindow.h"
|
|
|
|
#include "Windows/resource.h"
|
|
|
|
#include "Core/Reporting.h"
|
|
|
|
#include "Core/MemMap.h"
|
|
|
|
#include "Core/Core.h"
|
|
|
|
#include "Core/Host.h"
|
|
|
|
#include "Core/System.h"
|
|
|
|
#include "Core/Config.h"
|
2013-04-13 19:24:07 +00:00
|
|
|
#include "thread/threadutil.h"
|
2012-11-01 15:19:01 +00:00
|
|
|
|
2012-11-17 22:44:29 +00:00
|
|
|
#include <tchar.h>
|
|
|
|
#include <process.h>
|
2013-06-08 00:32:07 +00:00
|
|
|
#include <intrin.h>
|
|
|
|
#pragma intrinsic(_InterlockedExchange)
|
2012-11-17 22:44:29 +00:00
|
|
|
|
2013-08-13 15:09:36 +00:00
|
|
|
static recursive_mutex emuThreadLock;
|
2012-11-01 15:19:01 +00:00
|
|
|
static HANDLE emuThread;
|
2013-08-13 15:09:36 +00:00
|
|
|
static volatile long emuThreadReady;
|
2013-06-08 00:32:07 +00:00
|
|
|
|
2013-08-13 15:09:36 +00:00
|
|
|
enum EmuThreadStatus : long
|
2013-06-08 00:32:07 +00:00
|
|
|
{
|
|
|
|
THREAD_NONE = 0,
|
|
|
|
THREAD_INIT,
|
|
|
|
THREAD_CORE_LOOP,
|
|
|
|
THREAD_SHUTDOWN,
|
|
|
|
THREAD_END,
|
|
|
|
};
|
2012-11-01 15:19:01 +00:00
|
|
|
|
|
|
|
HANDLE EmuThread_GetThreadHandle()
|
|
|
|
{
|
2013-08-13 15:09:36 +00:00
|
|
|
lock_guard guard(emuThreadLock);
|
2012-11-01 15:19:01 +00:00
|
|
|
return emuThread;
|
|
|
|
}
|
|
|
|
|
2013-06-08 00:32:07 +00:00
|
|
|
unsigned int WINAPI TheThread(void *);
|
2012-11-01 15:19:01 +00:00
|
|
|
|
2013-03-29 17:50:08 +00:00
|
|
|
void EmuThread_Start()
|
2012-11-01 15:19:01 +00:00
|
|
|
{
|
2013-08-13 15:09:36 +00:00
|
|
|
lock_guard guard(emuThreadLock);
|
2013-06-08 00:32:07 +00:00
|
|
|
emuThread = (HANDLE)_beginthreadex(0, 0, &TheThread, 0, 0, 0);
|
2012-11-01 15:19:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void EmuThread_Stop()
|
|
|
|
{
|
2013-08-13 15:03:13 +00:00
|
|
|
// Already stopped?
|
2013-08-13 15:09:36 +00:00
|
|
|
{
|
|
|
|
lock_guard guard(emuThreadLock);
|
|
|
|
if (emuThread == NULL)
|
|
|
|
return;
|
|
|
|
}
|
2013-08-13 15:03:13 +00:00
|
|
|
|
2013-06-18 07:31:15 +00:00
|
|
|
globalUIState = UISTATE_EXIT;
|
2012-11-01 15:19:01 +00:00
|
|
|
// DSound_UpdateSound();
|
|
|
|
Core_Stop();
|
2013-06-08 00:32:07 +00:00
|
|
|
Core_WaitInactive(800);
|
|
|
|
if (WAIT_TIMEOUT == WaitForSingleObject(emuThread, 800))
|
|
|
|
{
|
2013-07-01 05:50:58 +00:00
|
|
|
_dbg_assert_msg_(COMMON, false, "Wait for EmuThread timed out.");
|
2013-06-08 00:32:07 +00:00
|
|
|
}
|
2012-11-01 15:19:01 +00:00
|
|
|
{
|
2013-08-13 15:09:36 +00:00
|
|
|
lock_guard guard(emuThreadLock);
|
2013-06-08 00:32:07 +00:00
|
|
|
CloseHandle(emuThread);
|
|
|
|
emuThread = 0;
|
2012-11-01 15:19:01 +00:00
|
|
|
}
|
|
|
|
host->UpdateUI();
|
|
|
|
}
|
|
|
|
|
2013-06-08 00:32:07 +00:00
|
|
|
bool EmuThread_Ready()
|
|
|
|
{
|
|
|
|
return emuThreadReady == THREAD_CORE_LOOP;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int WINAPI TheThread(void *)
|
|
|
|
{
|
|
|
|
_InterlockedExchange(&emuThreadReady, THREAD_INIT);
|
|
|
|
|
2012-11-01 15:19:01 +00:00
|
|
|
setCurrentThreadName("EmuThread");
|
|
|
|
|
2013-03-29 17:50:08 +00:00
|
|
|
std::string memstick, flash0;
|
|
|
|
GetSysDirectories(memstick, flash0);
|
|
|
|
|
|
|
|
// Native overwrites host. Can't allow that.
|
|
|
|
|
|
|
|
Host *oldHost = host;
|
|
|
|
UpdateScreenScale();
|
|
|
|
|
2013-04-01 01:22:27 +00:00
|
|
|
NativeInit(__argc, (const char **)__argv, memstick.c_str(), memstick.c_str(), "1234");
|
2013-03-29 17:50:08 +00:00
|
|
|
Host *nativeHost = host;
|
|
|
|
host = oldHost;
|
2012-11-01 15:19:01 +00:00
|
|
|
|
|
|
|
host->UpdateUI();
|
2013-03-10 22:08:57 +00:00
|
|
|
|
|
|
|
std::string error_string;
|
|
|
|
if (!host->InitGL(&error_string)) {
|
2013-03-24 16:42:49 +00:00
|
|
|
Reporting::ReportMessage("OpenGL init error: %s", error_string.c_str());
|
2013-03-10 22:08:57 +00:00
|
|
|
std::string full_error = StringFromFormat( "Failed initializing OpenGL. Try upgrading your graphics drivers.\n\nError message:\n\n%s", error_string.c_str());
|
|
|
|
MessageBoxA(0, full_error.c_str(), "OpenGL Error", MB_OK | MB_ICONERROR);
|
|
|
|
ERROR_LOG(BOOT, full_error.c_str());
|
2013-09-11 19:35:04 +00:00
|
|
|
|
|
|
|
// No safe way out without OpenGL.
|
|
|
|
ExitProcess(1);
|
2013-03-10 22:08:57 +00:00
|
|
|
}
|
2012-11-01 15:19:01 +00:00
|
|
|
|
2013-03-29 17:50:08 +00:00
|
|
|
NativeInitGraphics();
|
2012-11-01 15:19:01 +00:00
|
|
|
|
|
|
|
INFO_LOG(BOOT, "Done.");
|
|
|
|
_dbg_update_();
|
|
|
|
|
2013-06-08 00:32:07 +00:00
|
|
|
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);
|
|
|
|
|
2013-03-29 17:50:08 +00:00
|
|
|
Core_EnableStepping(FALSE);
|
2013-06-08 00:32:07 +00:00
|
|
|
|
2013-06-18 07:31:15 +00:00
|
|
|
while (globalUIState != UISTATE_EXIT)
|
|
|
|
{
|
|
|
|
Core_Run();
|
|
|
|
|
|
|
|
// We're here again, so the game quit. Restart Core_Run() which controls the UI.
|
|
|
|
// This way they can load a new game.
|
|
|
|
Core_UpdateState(CORE_RUNNING);
|
|
|
|
}
|
2012-11-01 15:19:01 +00:00
|
|
|
|
2012-11-05 12:42:33 +00:00
|
|
|
shutdown:
|
2013-06-08 00:32:07 +00:00
|
|
|
_InterlockedExchange(&emuThreadReady, THREAD_SHUTDOWN);
|
2013-08-15 22:57:04 +00:00
|
|
|
|
2013-03-29 17:50:08 +00:00
|
|
|
NativeShutdownGraphics();
|
2013-09-11 19:35:04 +00:00
|
|
|
|
2013-08-19 06:25:14 +00:00
|
|
|
host->ShutdownSound();
|
2013-06-21 06:13:00 +00:00
|
|
|
host = nativeHost;
|
2013-03-29 17:50:08 +00:00
|
|
|
NativeShutdown();
|
|
|
|
host = oldHost;
|
2012-11-01 15:19:01 +00:00
|
|
|
host->ShutdownGL();
|
|
|
|
|
2013-06-08 00:32:07 +00:00
|
|
|
_InterlockedExchange(&emuThreadReady, THREAD_END);
|
|
|
|
|
2012-11-01 15:19:01 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|