Fix merge conflict from master

This commit is contained in:
RadWolfie 2018-06-13 18:03:00 -05:00
commit 2ad7cb8746
7 changed files with 376 additions and 247 deletions

View File

@ -160,4 +160,4 @@ void EmuShared::Save()
m_XBController.Save("Software\\Cxbx-Reloaded\\XBController"); m_XBController.Save("Software\\Cxbx-Reloaded\\XBController");
m_XBVideo.Save("Software\\Cxbx-Reloaded\\XBVideo"); m_XBVideo.Save("Software\\Cxbx-Reloaded\\XBVideo");
m_XBAudio.Save("Software\\Cxbx-Reloaded\\XBAudio"); m_XBAudio.Save("Software\\Cxbx-Reloaded\\XBAudio");
} }

View File

@ -39,84 +39,83 @@
#define IDC_SET_LEFT_NEGX 1017 #define IDC_SET_LEFT_NEGX 1017
#define IDC_SET_LEFT_NEGY 1018 #define IDC_SET_LEFT_NEGY 1018
#define IDC_SET_LEFT_POSX 1019 #define IDC_SET_LEFT_POSX 1019
#define IDC_INPUT_CONFIG_CANCEL 1022 #define IDC_INPUT_CONFIG_CANCEL 1020
#define IDC_INPUT_CONFIG_ACCEPT 1023 #define IDC_INPUT_CONFIG_ACCEPT 1021
#define IDC_CONFIG_STATUS 1025 #define IDC_CONFIG_STATUS 1022
#define IDC_SET_RIGHT_POSY 1026 #define IDC_SET_RIGHT_POSY 1023
#define IDC_SET_RIGHT_NEGY 1027 #define IDC_SET_RIGHT_NEGY 1024
#define IDC_SET_RIGHT_NEGX 1028 #define IDC_SET_RIGHT_NEGX 1025
#define IDC_SET_RIGHT_POSX 1029 #define IDC_SET_RIGHT_POSX 1026
#define IDC_BUTTON1 1030 #define IDC_CONFIGURE_ALL 1027
#define IDC_CONFIGURE_ALL 1030 #define IDC_BTN_EJECT 1028
#define IDC_BTN_EJECT 1030 #define IDC_BTN_COCKPIT_HATCH 1029
#define IDC_BUTTON2 1031 #define IDC_BTN_IGNITION 1030
#define IDC_BTN_COCKPIT_HATCH 1031 #define IDC_BTN_START 1031
#define IDC_BTN_IGNITION 1032 #define IDC_CV_FULLSCREEN 1032
#define IDC_BTN_START 1033 #define IDC_BTN_ZOOM_IN 1033
#define IDC_CV_FULLSCREEN 1034 #define IDC_BTN_ZOOM_OUT 1034
#define IDC_BTN_ZOOM_IN 1034 #define IDC_BTN_MODE_SELECT 1035
#define IDC_BTN_ZOOM_OUT 1035 #define IDC_VC_DISPLAY_ADAPTER 1036
#define IDC_BTN_MODE_SELECT 1036
#define IDC_VC_DISPLAY_ADAPTER 1037
#define IDC_BTN_SUB_MONITOR_MODE_SELECT 1037 #define IDC_BTN_SUB_MONITOR_MODE_SELECT 1037
#define IDC_VC_D3D_DEVICE 1038 #define IDC_VC_D3D_DEVICE 1038
#define IDC_BTN_OPEN_CLOSE 1038 #define IDC_BTN_OPEN_CLOSE 1039
#define IDC_BTN_MAP_ZOON_IN_OUT 1039 #define IDC_BTN_MAP_ZOON_IN_OUT 1040
#define IDC_VC_ACCEPT 1040 #define IDC_VC_ACCEPT 1041
#define IDC_BTN_MAIN_WEAPON_CONTROL 1040 #define IDC_BTN_MAIN_WEAPON_CONTROL 1042
#define IDC_VC_CANCEL 1041 #define IDC_VC_CANCEL 1043
#define IDC_BTN_SUB_WEAPON_CONTROL 1041 #define IDC_BTN_SUB_WEAPON_CONTROL 1044
#define IDC_CV_VSYNC 1042 #define IDC_CV_VSYNC 1045
#define IDC_BTN_EXTINGUISHER 1042 #define IDC_BTN_EXTINGUISHER 1046
#define IDC_BTN_MAGAZINE_CHANGE 1043 #define IDC_BTN_MAGAZINE_CHANGE 1047
#define IDC_BTN_CHAFF 1044 #define IDC_BTN_CHAFF 1048
#define IDC_BTN_WASHING 1045 #define IDC_BTN_WASHING 1049
#define IDC_BTN_COM1 1046 #define IDC_BTN_COM1 1050
#define IDC_VC_VIDEO_RESOLUTION 1047 #define IDC_VC_VIDEO_RESOLUTION 1051
#define IDC_BTN_COM2 1047 #define IDC_BTN_COM2 1052
#define IDC_BTN_COM3 1048 #define IDC_BTN_COM3 1053
#define IDC_BTN_COM4 1049 #define IDC_BTN_COM4 1054
#define IDC_CV_HARDWAREYUV 1050 #define IDC_CV_HARDWAREYUV 1055
#define IDC_BTN_COM5 1050 #define IDC_BTN_COM5 1056
#define IDC_BTN_FUNC1 1051 #define IDC_BTN_FUNC1 1057
#define IDC_BTN_FUNC2 1052 #define IDC_BTN_FUNC2 1058
#define IDC_BTN_FUNC3 1053 #define IDC_BTN_FUNC3 1059
#define IDC_BTN_TANK_DETACH 1054 #define IDC_BTN_TANK_DETACH 1060
#define IDC_LIST2 1055 #define IDC_LIST2 1061
#define IDC_BTN_FSS 1055 #define IDC_BTN_FSS 1062
#define IDC_ABOUT 1056 #define IDC_ABOUT 1063
#define IDC_BTN_OVERRIDE 1056 #define IDC_BTN_OVERRIDE 1064
#define IDC_TAB1 1057 #define IDC_TAB1 1065
#define IDC_BTN_NIGHT_SCOPE 1057 #define IDC_BTN_NIGHT_SCOPE 1066
#define IDC_AC_ACCEPT 1058 #define IDC_AC_ACCEPT 1067
#define IDC_BTN_MANIPULATOR 1058 #define IDC_BTN_MANIPULATOR 1068
#define IDC_AC_CANCEL 1059 #define IDC_AC_CANCEL 1069
#define IDC_BTN_LINE_COLOR_CHANGE 1059 #define IDC_BTN_LINE_COLOR_CHANGE 1070
#define IDC_AC_AUDIO_ADAPTER 1060 #define IDC_AC_AUDIO_ADAPTER 1071
#define IDC_AC_PCM 1062 #define IDC_AC_PCM 1072
#define IDC_AC_XADPCM 1063 #define IDC_AC_XADPCM 1073
#define IDC_AC_UNKNOWN_CODEC 1064 #define IDC_AC_UNKNOWN_CODEC 1074
#define IDC_EE_CONFOUNDER 1065 #define IDC_EE_CONFOUNDER 1075
#define IDC_EE_HDDKEY 1066 #define IDC_EE_HDDKEY 1076
#define IDC_EE_XBOX_REGION 1067 #define IDC_EE_XBOX_REGION 1077
#define IDC_EE_SERIAL_NUMBER 1068 #define IDC_EE_SERIAL_NUMBER 1078
#define IDC_EE_MAC_ADDRESS 1069 #define IDC_EE_MAC_ADDRESS 1079
#define IDC_EE_ONLINE_KEY 1070 #define IDC_EE_ONLINE_KEY 1080
#define IDC_EE_AVREGION 1071 #define IDC_EE_AVREGION 1081
#define IDC_EE_LANGUAGE 1072 #define IDC_EE_LANGUAGE 1082
#define IDC_EE_AVSETTINGS 1073 #define IDC_EE_AVSETTINGS 1083
#define IDC_EE_AUDIOSETTINGS 1074 #define IDC_EE_AUDIOSETTINGS 1084
#define IDC_EE_GAME_PRTL_CRTL 1075 #define IDC_EE_GAME_PRTL_CRTL 1085
#define IDC_EE_PRTL_PASS 1076 #define IDC_EE_PRTL_PASS 1086
#define IDC_EE_MOVIE_PRTL_CRTL 1077 #define IDC_EE_MOVIE_PRTL_CRTL 1087
#define IDC_EE_DVDREGION 1078 #define IDC_EE_DVDREGION 1088
#define IDC_EE_ACCEPT 1079 #define IDC_EE_ACCEPT 1089
#define IDC_EE_CANCEL 1080 #define IDC_EE_CANCEL 1090
#define IDC_EE_RESET 1081 #define IDC_EE_RESET 1091
#define IDC_EE_PAL60HZ 1082 #define IDC_EE_PAL60HZ 1092
#define IDC_EE_480P 1083 #define IDC_EE_480P 1093
#define IDC_EE_720P 1084 #define IDC_EE_720P 1094
#define IDC_EE_1080I 1085 #define IDC_EE_1080I 1095
#define ID_KRNL_IS_READY 1096
#define IDC_XBOX_PORT_0 1158 #define IDC_XBOX_PORT_0 1158
#define IDC_HOST_NOTCONNECT_0_0 1159 #define IDC_HOST_NOTCONNECT_0_0 1159
#define IDC_HOST_XINPUT_0_0 1160 #define IDC_HOST_XINPUT_0_0 1160

View File

@ -231,7 +231,7 @@ WndMain::WndMain(HINSTANCE x_hInstance) :
dwType = REG_DWORD; dwSize = sizeof(DWORD); dwType = REG_DWORD; dwSize = sizeof(DWORD);
result = RegQueryValueEx(hKey, "HackDirectBackBufferAccess", NULL, &dwType, (PBYTE)&m_DirectHostBackBufferAccess, &dwSize); result = RegQueryValueEx(hKey, "HackDirectBackBufferAccess", NULL, &dwType, (PBYTE)&m_DirectHostBackBufferAccess, &dwSize);
if (result != ERROR_SUCCESS) { if (result != ERROR_SUCCESS) {
m_DirectHostBackBufferAccess = 0; m_DirectHostBackBufferAccess = 1;
} }
@ -523,13 +523,13 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
} }
break; break;
// NOTE: WM_PARENTNOTIFY was triggered by kernel process' graphic window creation.
case WM_PARENTNOTIFY: case WM_PARENTNOTIFY:
{ {
switch(LOWORD(wParam)) switch(LOWORD(wParam))
{ {
case WM_CREATE: case WM_CREATE:
{ {
CreateThread(NULL, NULL, CrashMonitorWrapper, (void*)this, NULL, NULL); // create the crash monitoring thread
if (m_hwndChild == NULL) { if (m_hwndChild == NULL) {
float fps = 0.0f; float fps = 0.0f;
float mspf = 0.0f; float mspf = 0.0f;
@ -539,14 +539,14 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
g_EmuShared->SetLedSequence(LedSequence); g_EmuShared->SetLedSequence(LedSequence);
SetTimer(hwnd, TIMERID_FPS, 1000, (TIMERPROC)NULL); SetTimer(hwnd, TIMERID_FPS, 1000, (TIMERPROC)NULL);
SetTimer(hwnd, TIMERID_LED, XBOX_LED_FLASH_PERIOD, (TIMERPROC)NULL); SetTimer(hwnd, TIMERID_LED, XBOX_LED_FLASH_PERIOD, (TIMERPROC)NULL);
m_hwndChild = GetWindow(hwnd, GW_CHILD); // (HWND)HIWORD(wParam) seems to be NULL m_hwndChild = GetWindow(hwnd, GW_CHILD);
UpdateCaption(); UpdateCaption();
RefreshMenus(); RefreshMenus();
} }
else else {
{
m_hwndChild = GetWindow(hwnd, GW_CHILD); m_hwndChild = GetWindow(hwnd, GW_CHILD);
} }
CreateThread(NULL, NULL, CrashMonitorWrapper, (void*)this, NULL, NULL); // create the crash monitoring thread
} }
break; break;
@ -562,8 +562,20 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
} }
} }
break; break;
}
}; case WM_USER: {
switch(lParam) {
// NOTE: If anything need to set before kernel process start do anything, do it here.
case ID_KRNL_IS_READY: {
g_EmuShared->SetFlagsLLE(&m_FlagsLLE);
g_EmuShared->SetIsReady(true);
break;
}
}
break;
}
}
};
break; // added per PVS suggestion. break; // added per PVS suggestion.
case WM_TIMER: case WM_TIMER:
@ -1393,7 +1405,6 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
case ID_EMULATION_LLE_JIT: case ID_EMULATION_LLE_JIT:
{ {
m_FlagsLLE = m_FlagsLLE ^ LLE_JIT; m_FlagsLLE = m_FlagsLLE ^ LLE_JIT;
ClearHLECache();
RefreshMenus(); RefreshMenus();
} }
break; break;
@ -1401,7 +1412,6 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
case ID_EMULATION_LLE_APU: case ID_EMULATION_LLE_APU:
{ {
m_FlagsLLE = m_FlagsLLE ^ LLE_APU; m_FlagsLLE = m_FlagsLLE ^ LLE_APU;
ClearHLECache();
RefreshMenus(); RefreshMenus();
} }
break; break;
@ -1409,7 +1419,6 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
case ID_EMULATION_LLE_GPU: case ID_EMULATION_LLE_GPU:
{ {
m_FlagsLLE = m_FlagsLLE ^ LLE_GPU; m_FlagsLLE = m_FlagsLLE ^ LLE_GPU;
ClearHLECache();
RefreshMenus(); RefreshMenus();
} }
break; break;
@ -2282,6 +2291,17 @@ void WndMain::SaveXbeAs()
void WndMain::StartEmulation(HWND hwndParent, DebuggerState LocalDebuggerState /*= debuggerOff*/) void WndMain::StartEmulation(HWND hwndParent, DebuggerState LocalDebuggerState /*= debuggerOff*/)
{ {
char szBuffer[MAX_PATH]; char szBuffer[MAX_PATH];
bool isEmulating = false;
g_EmuShared->GetIsEmulating(&isEmulating);
if (isEmulating) {
MessageBox(m_hwnd, "A title is currently emulating, please stop emulation before attempt start again.",
"Cxbx-Reloaded", MB_ICONERROR | MB_OK);
return;
}
g_EmuShared->SetIsEmulating(true);
// register xbe path with emulator process // register xbe path with emulator process
g_EmuShared->SetXbePath(m_Xbe->m_szPath); g_EmuShared->SetXbePath(m_Xbe->m_szPath);
@ -2384,15 +2404,16 @@ void WndMain::StopEmulation()
RefreshMenus(); RefreshMenus();
// Set the window size back to it's GUI dimensions // Set the window size back to it's GUI dimensions
ResizeWindow(m_hwnd, /*bForGUI=*/true); ResizeWindow(m_hwnd, /*bForGUI=*/true);
g_EmuShared->SetIsEmulating(false);
} }
// wrapper function to call CrashMonitor // wrapper function to call CrashMonitor
DWORD WINAPI WndMain::CrashMonitorWrapper(LPVOID lpVoid) DWORD WINAPI WndMain::CrashMonitorWrapper(LPVOID lpVoid)
{ {
CxbxSetThreadName("Cxbx Crash Monitor"); CxbxSetThreadName("Cxbx Crash Monitor");
static_cast<WndMain*>(lpVoid)->CrashMonitor(); static_cast<WndMain*>(lpVoid)->CrashMonitor();
return 0; return 0;
} }
@ -2400,41 +2421,50 @@ DWORD WINAPI WndMain::CrashMonitorWrapper(LPVOID lpVoid)
void WndMain::CrashMonitor() void WndMain::CrashMonitor()
{ {
bool bQuickReboot; bool bQuickReboot;
HANDLE hCrashMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, "CrashMutex"); DWORD dwProcessID_ExitCode = 0;
GetWindowThreadProcessId(m_hwndChild, &dwProcessID_ExitCode);
DWORD state = WaitForSingleObject(hCrashMutex, INFINITE); // If we do receive valid process ID, let's do the next step.
if (dwProcessID_ExitCode != 0) {
g_EmuShared->GetMultiXbeFlag(&bQuickReboot); HANDLE hProcess = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_INFORMATION, FALSE, dwProcessID_ExitCode);
if (state == WAIT_OBJECT_0) // StopEmulation // If we do receive valid handle, let's do the next step.
{ if (hProcess != NULL) {
CloseHandle(hCrashMutex);
return; WaitForSingleObject(hProcess, INFINITE);
dwProcessID_ExitCode = 0;
GetExitCodeProcess(hProcess, &dwProcessID_ExitCode);
CloseHandle(hProcess);
g_EmuShared->GetMultiXbeFlag(&bQuickReboot);
if (!bQuickReboot) {
if (dwProcessID_ExitCode == EXIT_SUCCESS) {// StopEmulation
return;
}
// Or else, it's a crash
}
else {
// multi-xbe
// destroy this thread and start a new one
bQuickReboot = false;
g_EmuShared->SetMultiXbeFlag(&bQuickReboot);
return;
}
}
} }
if (state == WAIT_ABANDONED && !bQuickReboot) // that's a crash // Crash clean up.
{
CloseHandle(hCrashMutex);
if (m_bIsStarted) // that's a hard crash, Dr Watson is invoked
{
KillTimer(m_hwnd, TIMERID_FPS);
KillTimer(m_hwnd, TIMERID_LED);
DrawLedBitmap(m_hwnd, true);
m_hwndChild = NULL;
m_bIsStarted = false;
UpdateCaption();
RefreshMenus();
}
return;
}
// multi-xbe KillTimer(m_hwnd, TIMERID_FPS);
// destroy this thread and start a new one KillTimer(m_hwnd, TIMERID_LED);
CloseHandle(hCrashMutex); DrawLedBitmap(m_hwnd, true);
bQuickReboot = false; m_hwndChild = NULL;
g_EmuShared->SetMultiXbeFlag(&bQuickReboot); m_bIsStarted = false;
UpdateCaption();
return; RefreshMenus();
} }
// draw Xbox LED bitmap // draw Xbox LED bitmap
@ -2459,6 +2489,7 @@ void WndMain::DrawLedBitmap(HWND hwnd, bool bdefault)
else { // draw colored bitmap else { // draw colored bitmap
int LedSequence[4] = { XBOX_LED_COLOUR_OFF, XBOX_LED_COLOUR_OFF, XBOX_LED_COLOUR_OFF, XBOX_LED_COLOUR_OFF }; int LedSequence[4] = { XBOX_LED_COLOUR_OFF, XBOX_LED_COLOUR_OFF, XBOX_LED_COLOUR_OFF, XBOX_LED_COLOUR_OFF };
static int LedSequenceOffset = 0; static int LedSequenceOffset = 0;
int FlagsLLE = 0;
g_EmuShared->GetLedSequence(LedSequence); g_EmuShared->GetLedSequence(LedSequence);
@ -2466,17 +2497,18 @@ void WndMain::DrawLedBitmap(HWND hwnd, bool bdefault)
ActiveLEDColor = LedSequence[LedSequenceOffset & 3]; ActiveLEDColor = LedSequence[LedSequenceOffset & 3];
++LedSequenceOffset; ++LedSequenceOffset;
g_EmuShared->GetFlagsLLE(&FlagsLLE);
// Set LLE flags string based on selected LLE flags // Set LLE flags string based on selected LLE flags
if (m_FlagsLLE & LLE_APU) { if (FlagsLLE & LLE_APU) {
strcat(flagString, "A"); strcat(flagString, "A");
} }
if (m_FlagsLLE & LLE_GPU) { if (FlagsLLE & LLE_GPU) {
strcat(flagString, "G"); strcat(flagString, "G");
} }
if (m_FlagsLLE & LLE_JIT) { if (FlagsLLE & LLE_JIT) {
strcat(flagString, "J"); strcat(flagString, "J");
} }
if (m_FlagsLLE == 0) { if (FlagsLLE == 0) {
sprintf(flagString, "HLE"); sprintf(flagString, "HLE");
} }
} }

View File

@ -42,6 +42,7 @@ namespace xboxkrnl
#include <xboxkrnl/xboxkrnl.h> #include <xboxkrnl/xboxkrnl.h>
}; };
#include "Cxbx\ResCxbx.h"
#include "CxbxKrnl.h" #include "CxbxKrnl.h"
#include "Cxbx\CxbxXbdm.h" // For Cxbx_LibXbdmThunkTable #include "Cxbx\CxbxXbdm.h" // For Cxbx_LibXbdmThunkTable
#include "CxbxVersion.h" #include "CxbxVersion.h"
@ -602,12 +603,12 @@ void PrintCurrentConfigurationLog()
// Print Enabled Hacks // Print Enabled Hacks
{ {
printf("--------------------------- HACKS CONFIG ---------------------------\n"); printf("--------------------------- HACKS CONFIG ---------------------------\n");
printf("Disable Pixel Shaders: %s\n", g_DisablePixelShaders == 1 ? "On" : "Off"); printf("Disable Pixel Shaders: %s\n", g_DisablePixelShaders == 1 ? "On" : "Off (Default)");
printf("Uncap Framerate: %s\n", g_UncapFramerate == 1 ? "On" : "Off"); printf("Uncap Framerate: %s\n", g_UncapFramerate == 1 ? "On" : "Off (Default)");
printf("Run Xbox threads on all cores: %s\n", g_UseAllCores == 1 ? "On" : "Off"); printf("Run Xbox threads on all cores: %s\n", g_UseAllCores == 1 ? "On" : "Off (Default)");
printf("Skip RDTSC Patching: %s\n", g_SkipRdtscPatching == 1 ? "On" : "Off"); printf("Skip RDTSC Patching: %s\n", g_SkipRdtscPatching == 1 ? "On" : "Off (Default)");
printf("Scale Xbox to host viewport (and back): %s\n", g_ScaleViewport == 1 ? "On" : "Off"); printf("Scale Xbox to host viewport (and back): %s\n", g_ScaleViewport == 1 ? "On" : "Off (Default)");
printf("Render directly to Host BackBuffer: %s\n", g_DirectHostBackBufferAccess == 1 ? "On" : "Off"); printf("Render directly to Host BackBuffer: %s\n", g_DirectHostBackBufferAccess == 1 ? "On (Default)" : "Off");
} }
printf("------------------------- END OF CONFIG LOG ------------------------\n"); printf("------------------------- END OF CONFIG LOG ------------------------\n");
@ -905,6 +906,47 @@ void CxbxKrnlMain(int argc, char* argv[])
g_CurrentProcessHandle = GetCurrentProcess(); // OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId()); g_CurrentProcessHandle = GetCurrentProcess(); // OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());
if (CxbxKrnl_hEmuParent == NULL) {
CxbxKrnlCleanup("GUI process does not exist!");
} else {
SendMessage(CxbxKrnl_hEmuParent, WM_PARENTNOTIFY, WM_USER, ID_KRNL_IS_READY);
}
// Force wait until first allocated process is ready
do {
int waitCounter = 10;
bool isReady = false;
while (waitCounter > 0) {
g_EmuShared->GetIsReady(&isReady);
if (isReady) {
break;
}
waitCounter--;
Sleep(100);
}
if (!isReady) {
EmuWarning("GUI process is not ready!");
int mbRet = MessageBox(NULL, "GUI process is not ready, do you wish to retry?", TEXT("Cxbx-Reloaded"),
MB_ICONWARNING | MB_RETRYCANCEL | MB_TOPMOST | MB_SETFOREGROUND);
if (mbRet == IDRETRY) {
continue;
}
CxbxKrnlShutDown();
}
break;
} while (true);
g_EmuShared->SetIsReady(false);
bool bQuickReboot;
g_EmuShared->GetMultiXbeFlag(&bQuickReboot);
// precaution for multi-xbe titles in the case CrashMonitor has still not destoyed the previous mutex
while (bQuickReboot) {
g_EmuShared->GetMultiXbeFlag(&bQuickReboot);
}
// Write a header to the log // Write a header to the log
{ {
printf("[0x%.4X] INIT: Cxbx-Reloaded Version %s\n", GetCurrentThreadId(), _CXBX_VERSION); printf("[0x%.4X] INIT: Cxbx-Reloaded Version %s\n", GetCurrentThreadId(), _CXBX_VERSION);

View File

@ -1420,17 +1420,6 @@ static DWORD WINAPI EmuRenderWindow(LPVOID lpVoid)
RegisterClassEx(&wc); RegisterClassEx(&wc);
} }
bool bQuickReboot;
g_EmuShared->GetMultiXbeFlag(&bQuickReboot);
// precaution for multi-xbe titles in the case CrashMonitor has still not destoyed the previous mutex
while (bQuickReboot)
{
g_EmuShared->GetMultiXbeFlag(&bQuickReboot);
}
HANDLE hCrashMutex = CreateMutex(NULL, TRUE, "CrashMutex");
// create the window // create the window
{ {
HWND hwndParent = GetDesktopWindow(); HWND hwndParent = GetDesktopWindow();
@ -1510,8 +1499,6 @@ static DWORD WINAPI EmuRenderWindow(LPVOID lpVoid)
delete dbgConsole; delete dbgConsole;
if (hCrashMutex != NULL) { ReleaseMutex(hCrashMutex); }
CxbxKrnlCleanup(NULL); CxbxKrnlCleanup(NULL);
} }

View File

@ -67,14 +67,26 @@ class EmuShared : public Mutex
// ****************************************************************** // ******************************************************************
static void Init(); static void Init();
void EmuShared::Load(); void Load();
void EmuShared::Save(); void Save();
// ****************************************************************** // ******************************************************************
// * Each process needs to call this to cleanup shared memory // * Each process needs to call this to cleanup shared memory
// ****************************************************************** // ******************************************************************
static void Cleanup(); static void Cleanup();
// ******************************************************************
// * Check if parent process is emulating title
// ******************************************************************
void GetIsEmulating(bool *isEmulating) { Lock(); *isEmulating = m_bEmulating; Unlock(); }
void SetIsEmulating(bool isEmulating) { Lock(); m_bEmulating = isEmulating; Unlock(); }
// ******************************************************************
// * Each child process need to wait until parent process is ready
// ******************************************************************
void GetIsReady(bool *isReady) { Lock(); *isReady = m_bReady; Unlock(); }
void SetIsReady(bool isReady) { Lock(); m_bReady = isReady; Unlock(); }
// ****************************************************************** // ******************************************************************
// * Xbox Video Accessors // * Xbox Video Accessors
// ****************************************************************** // ******************************************************************
@ -199,20 +211,22 @@ class EmuShared : public Mutex
XBVideo m_XBVideo; XBVideo m_XBVideo;
XBAudio m_XBAudio; XBAudio m_XBAudio;
char m_XbePath[MAX_PATH]; char m_XbePath[MAX_PATH];
int m_BootFlags; int m_BootFlags;
int m_FlagsLLE; int m_FlagsLLE;
int m_XInputEnabled; int m_XInputEnabled;
int m_DisablePixelShaders; int m_DisablePixelShaders;
int m_UncapFramerate; int m_UncapFramerate;
int m_UseAllCores; int m_UseAllCores;
int m_SkipRdtscPatching; int m_SkipRdtscPatching;
float m_MSpF; float m_MSpF;
float m_FPS; float m_FPS;
bool m_bMultiXbeFlag; bool m_bMultiXbeFlag;
bool m_bDebugging; bool m_bDebugging;
bool m_bReady;
bool m_bEmulating;
int m_LedSequence[4]; int m_LedSequence[4];
int m_ScaleViewport; int m_ScaleViewport;
int m_DirectHostBackBufferAccess; int m_DirectHostBackBufferAccess;
char m_StorageLocation[MAX_PATH]; char m_StorageLocation[MAX_PATH];
}; };

View File

@ -324,11 +324,71 @@ void EmuD3D_Init_DeferredStates()
} }
} }
// Update shared structure with GUI process
void EmuUpdateLLEStatus(uint32_t XbLibScan)
{
int FlagsLLE;
g_EmuShared->GetFlagsLLE(&FlagsLLE);
if ((FlagsLLE & LLE_GPU) == false
&& !((XbLibScan & XbSymbolLib_D3D8) > 0
|| (XbLibScan & XbSymbolLib_D3D8LTCG) > 0)) {
bLLE_GPU = true;
FlagsLLE ^= LLE_GPU;
EmuOutputMessage(XB_OUTPUT_MESSAGE_INFO, "Fallback to LLE GPU.");
}
if ((FlagsLLE & LLE_APU) == false
&& (XbLibScan & XbSymbolLib_DSOUND) == 0) {
bLLE_APU = true;
FlagsLLE ^= LLE_APU;
EmuOutputMessage(XB_OUTPUT_MESSAGE_INFO, "Fallback to LLE APU.");
}
g_EmuShared->SetFlagsLLE(&FlagsLLE);
}
// NOTE: EmuHLEIntercept do not get to be in XbSymbolDatabase, do the intecept in Cxbx project only. // NOTE: EmuHLEIntercept do not get to be in XbSymbolDatabase, do the intecept in Cxbx project only.
void EmuHLEIntercept(Xbe::Header *pXbeHeader) void EmuHLEIntercept(Xbe::Header *pXbeHeader)
{ {
// NOTE: Increase this revision number any time we changed something inside Cxbx-Reloaded.
int revisionCache = 4;
Xbe::LibraryVersion *pLibraryVersion = (Xbe::LibraryVersion*)pXbeHeader->dwLibraryVersionsAddr; Xbe::LibraryVersion *pLibraryVersion = (Xbe::LibraryVersion*)pXbeHeader->dwLibraryVersionsAddr;
uint16 xdkVersion = 0;
uint32_t XbLibScan = 0;
// NOTE: We need to check if title has library header to optimize verification process.
if (pLibraryVersion != nullptr) {
uint32 dwLibraryVersions = pXbeHeader->dwLibraryVersions;
const char* SectionName = nullptr;
Xbe::SectionHeader* pSectionHeaders = (Xbe::SectionHeader*)pXbeHeader->dwSectionHeadersAddr;
// Get the highest revision build and prefix library to scan.
for (uint32 v = 0; v < dwLibraryVersions; v++) {
uint16 BuildVersion = pLibraryVersion[v].wBuildVersion;
uint16 QFEVersion = pLibraryVersion[v].wFlags.QFEVersion;
if (xdkVersion < BuildVersion) {
xdkVersion = BuildVersion;
}
XbLibScan |= XbSymbolLibrayToFlag(std::string(pLibraryVersion[v].szName, pLibraryVersion[v].szName + 8).c_str());
}
// Since XDK 4039 title does not have library version for DSOUND, let's check section header if it exists or not.
for (unsigned int v = 0; v < pXbeHeader->dwSections; v++) {
SectionName = (const char*)pSectionHeaders[v].dwSectionNameAddr;
if (strncmp(SectionName, Lib_DSOUND, 8) == 0) {
XbLibScan |= XbSymbolLib_DSOUND;
break;
}
}
}
EmuUpdateLLEStatus(XbLibScan);
int gFlagsLLE;
g_EmuShared->GetFlagsLLE(&gFlagsLLE);
printf("\n"); printf("\n");
printf("*******************************************************************************\n"); printf("*******************************************************************************\n");
printf("* Cxbx-Reloaded High Level Emulation database\n"); printf("* Cxbx-Reloaded High Level Emulation database\n");
@ -367,84 +427,86 @@ void EmuHLEIntercept(Xbe::Header *pXbeHeader)
if (HLECacheHash == XbSymbolLibraryVersion()) { if (HLECacheHash == XbSymbolLibraryVersion()) {
char buffer[SHRT_MAX] = { 0 }; char buffer[SHRT_MAX] = { 0 };
char* bufferPtr = buffer; char* bufferPtr = buffer;
printf("Using HLE Cache\n");
GetPrivateProfileSection("Symbols", buffer, sizeof(buffer), filename.c_str());
// Parse the .INI file into the map of symbol addresses
while (strlen(bufferPtr) > 0) {
std::string ini_entry(bufferPtr);
auto separator = ini_entry.find('=');
std::string key = ini_entry.substr(0, separator);
std::string value = ini_entry.substr(separator + 1, std::string::npos);
uint32_t addr = strtol(value.c_str(), 0, 16);
g_SymbolAddresses[key] = addr;
bufferPtr += strlen(bufferPtr) + 1;
}
// Iterate through the map of symbol addresses, calling GetEmuPatchAddr on all functions.
for (auto it = g_SymbolAddresses.begin(); it != g_SymbolAddresses.end(); ++it) {
std::string functionName = (*it).first;
xbaddr location = (*it).second;
std::stringstream output;
output << "HLECache: 0x" << std::setfill('0') << std::setw(8) << std::hex << location
<< " -> " << functionName;
void* pFunc = GetEmuPatchAddr(functionName);
if (pFunc != nullptr)
{
// skip entries that weren't located at all
if (location == NULL)
{
output << "\t(not patched)";
}
// Prevent patching illegal addresses
else if (location < XBE_IMAGE_BASE)
{
output << "\t*ADDRESS TOO LOW!*";
}
else if (location > g_SystemMaxMemory)
{
output << "\t*ADDRESS TOO HIGH!*";
}
else
{
EmuInstallPatch(functionName, location, pFunc);
output << "\t*PATCHED*";
}
}
else
{
if (location != NULL)
output << "\t(no patch)";
}
output << "\n";
printf(output.str().c_str());
}
// Fix up Render state and Texture States
if (g_SymbolAddresses.find("D3DDeferredRenderState") == g_SymbolAddresses.end()
|| g_SymbolAddresses["D3DDeferredRenderState"] == 0) {
EmuWarning("EmuD3DDeferredRenderState was not found!");
}
if (g_SymbolAddresses.find("D3DDeferredTextureState") == g_SymbolAddresses.end()
|| g_SymbolAddresses["D3DDeferredTextureState"] == 0) {
EmuWarning("EmuD3DDeferredTextureState was not found!");
}
if (g_SymbolAddresses.find("D3DDEVICE") == g_SymbolAddresses.end()
|| g_SymbolAddresses["D3DDEVICE"] == 0) {
EmuWarning("D3DDEVICE was not found!");
}
EmuD3D_Init_DeferredStates();
g_HLECacheUsed = true; g_HLECacheUsed = true;
const uint32 cacheRevision = GetPrivateProfileInt("Info", "revision", 0, filename.c_str());
const uint32 cacheFlagsLLE = GetPrivateProfileInt("Info", "FlagsLLE", 0, filename.c_str());
if (cacheFlagsLLE != gFlagsLLE) {
g_HLECacheUsed = false;
}
else if (cacheRevision != revisionCache) {
g_HLECacheUsed = false;
}
if (g_HLECacheUsed) {
printf("Using HLE Cache\n");
GetPrivateProfileSection("Symbols", buffer, sizeof(buffer), filename.c_str());
// Parse the .INI file into the map of symbol addresses
while (strlen(bufferPtr) > 0) {
std::string ini_entry(bufferPtr);
auto separator = ini_entry.find('=');
std::string key = ini_entry.substr(0, separator);
std::string value = ini_entry.substr(separator + 1, std::string::npos);
uint32_t addr = strtol(value.c_str(), 0, 16);
g_SymbolAddresses[key] = addr;
bufferPtr += strlen(bufferPtr) + 1;
}
// Iterate through the map of symbol addresses, calling GetEmuPatchAddr on all functions.
for (auto it = g_SymbolAddresses.begin(); it != g_SymbolAddresses.end(); ++it) {
std::string functionName = (*it).first;
xbaddr location = (*it).second;
std::stringstream output;
output << "HLECache: 0x" << std::setfill('0') << std::setw(8) << std::hex << location
<< " -> " << functionName;
void* pFunc = GetEmuPatchAddr(functionName);
if (pFunc != nullptr) {
// skip entries that weren't located at all
if (location == NULL) {
output << "\t(not patched)";
}
// Prevent patching illegal addresses
else if (location < XBE_IMAGE_BASE) {
output << "\t*ADDRESS TOO LOW!*";
} else if (location > g_SystemMaxMemory) {
output << "\t*ADDRESS TOO HIGH!*";
} else {
EmuInstallPatch(functionName, location, pFunc);
output << "\t*PATCHED*";
}
} else {
if (location != NULL)
output << "\t(no patch)";
}
output << "\n";
printf(output.str().c_str());
}
// Fix up Render state and Texture States
if (g_SymbolAddresses.find("D3DDeferredRenderState") == g_SymbolAddresses.end()
|| g_SymbolAddresses["D3DDeferredRenderState"] == 0) {
EmuWarning("EmuD3DDeferredRenderState was not found!");
}
if (g_SymbolAddresses.find("D3DDeferredTextureState") == g_SymbolAddresses.end()
|| g_SymbolAddresses["D3DDeferredTextureState"] == 0) {
EmuWarning("EmuD3DDeferredTextureState was not found!");
}
if (g_SymbolAddresses.find("D3DDEVICE") == g_SymbolAddresses.end()
|| g_SymbolAddresses["D3DDEVICE"] == 0) {
EmuWarning("D3DDEVICE was not found!");
}
EmuD3D_Init_DeferredStates();
}
} }
// If g_SymbolAddresses didn't get filled, the HLE cache is invalid // If g_SymbolAddresses didn't get filled, the HLE cache is invalid
@ -462,26 +524,10 @@ void EmuHLEIntercept(Xbe::Header *pXbeHeader)
// //
// initialize Microsoft XDK emulation // initialize Microsoft XDK emulation
// //
if(pLibraryVersion != 0) if(pLibraryVersion != nullptr) {
{
printf("HLE: Detected Microsoft XDK application...\n"); printf("HLE: Detected Microsoft XDK application...\n");
uint32 dwLibraryVersions = pXbeHeader->dwLibraryVersions;
uint16 xdkVersion = 0;
uint32_t XbLibScan = 0;
// Get the highest revision build and prefix library to scan.
for (uint32 v = 0; v < dwLibraryVersions; v++) {
uint16 BuildVersion = pLibraryVersion[v].wBuildVersion;
uint16 QFEVersion = pLibraryVersion[v].wFlags.QFEVersion;
if (xdkVersion < BuildVersion) {
xdkVersion = BuildVersion;
}
XbLibScan |= XbSymbolLibrayToFlag(std::string(pLibraryVersion[v].szName, pLibraryVersion[v].szName + 8).c_str());
}
// TODO: Is this enough for alias? We need to verify it. // TODO: Is this enough for alias? We need to verify it.
if ((XbLibScan & XbSymbolLib_D3D8) > 0 || (XbLibScan & XbSymbolLib_D3D8LTCG) > 0) { if ((XbLibScan & XbSymbolLib_D3D8) > 0 || (XbLibScan & XbSymbolLib_D3D8LTCG) > 0) {
g_BuildVersion = xdkVersion; g_BuildVersion = xdkVersion;
@ -533,6 +579,15 @@ void EmuHLEIntercept(Xbe::Header *pXbeHeader)
WritePrivateProfileString("Info", "HLECacheHash", HLECacheHashString.c_str(), filename.c_str()); WritePrivateProfileString("Info", "HLECacheHash", HLECacheHashString.c_str(), filename.c_str());
} }
std::stringstream revision;
revision << std::dec << revisionCache;
WritePrivateProfileString("Info", "revision", revision.str().c_str(), filename.c_str());
std::stringstream flagsLLE;
flagsLLE << std::dec << gFlagsLLE;
WritePrivateProfileString("Info", "FlagsLLE", flagsLLE.str().c_str(), filename.c_str());
// Write the Certificate Details to the cache file // Write the Certificate Details to the cache file
WritePrivateProfileString("Certificate", "Name", tAsciiTitle, filename.c_str()); WritePrivateProfileString("Certificate", "Name", tAsciiTitle, filename.c_str());