From 939eb09ab4e768dbaddfc7be038ddf05a7a04dba Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Sat, 9 Jun 2018 16:12:16 -0500 Subject: [PATCH 01/30] Fix define ordering number Since there are duplicate same values for different define. Doing this way will prevent future risk of overlapping each other. --- src/Cxbx/ResCxbx.h | 150 ++++++++++++++++++++++----------------------- 1 file changed, 74 insertions(+), 76 deletions(-) diff --git a/src/Cxbx/ResCxbx.h b/src/Cxbx/ResCxbx.h index d6ff58168..59989cb2c 100644 --- a/src/Cxbx/ResCxbx.h +++ b/src/Cxbx/ResCxbx.h @@ -39,84 +39,82 @@ #define IDC_SET_LEFT_NEGX 1017 #define IDC_SET_LEFT_NEGY 1018 #define IDC_SET_LEFT_POSX 1019 -#define IDC_INPUT_CONFIG_CANCEL 1022 -#define IDC_INPUT_CONFIG_ACCEPT 1023 -#define IDC_CONFIG_STATUS 1025 -#define IDC_SET_RIGHT_POSY 1026 -#define IDC_SET_RIGHT_NEGY 1027 -#define IDC_SET_RIGHT_NEGX 1028 -#define IDC_SET_RIGHT_POSX 1029 -#define IDC_BUTTON1 1030 -#define IDC_CONFIGURE_ALL 1030 -#define IDC_BTN_EJECT 1030 -#define IDC_BUTTON2 1031 -#define IDC_BTN_COCKPIT_HATCH 1031 -#define IDC_BTN_IGNITION 1032 -#define IDC_BTN_START 1033 -#define IDC_CV_FULLSCREEN 1034 -#define IDC_BTN_ZOOM_IN 1034 -#define IDC_BTN_ZOOM_OUT 1035 -#define IDC_BTN_MODE_SELECT 1036 -#define IDC_VC_DISPLAY_ADAPTER 1037 +#define IDC_INPUT_CONFIG_CANCEL 1020 +#define IDC_INPUT_CONFIG_ACCEPT 1021 +#define IDC_CONFIG_STATUS 1022 +#define IDC_SET_RIGHT_POSY 1023 +#define IDC_SET_RIGHT_NEGY 1024 +#define IDC_SET_RIGHT_NEGX 1025 +#define IDC_SET_RIGHT_POSX 1026 +#define IDC_CONFIGURE_ALL 1027 +#define IDC_BTN_EJECT 1028 +#define IDC_BTN_COCKPIT_HATCH 1029 +#define IDC_BTN_IGNITION 1030 +#define IDC_BTN_START 1031 +#define IDC_CV_FULLSCREEN 1032 +#define IDC_BTN_ZOOM_IN 1033 +#define IDC_BTN_ZOOM_OUT 1034 +#define IDC_BTN_MODE_SELECT 1035 +#define IDC_VC_DISPLAY_ADAPTER 1036 #define IDC_BTN_SUB_MONITOR_MODE_SELECT 1037 #define IDC_VC_D3D_DEVICE 1038 -#define IDC_BTN_OPEN_CLOSE 1038 -#define IDC_BTN_MAP_ZOON_IN_OUT 1039 -#define IDC_VC_ACCEPT 1040 -#define IDC_BTN_MAIN_WEAPON_CONTROL 1040 -#define IDC_VC_CANCEL 1041 -#define IDC_BTN_SUB_WEAPON_CONTROL 1041 -#define IDC_CV_VSYNC 1042 -#define IDC_BTN_EXTINGUISHER 1042 -#define IDC_BTN_MAGAZINE_CHANGE 1043 -#define IDC_BTN_CHAFF 1044 -#define IDC_BTN_WASHING 1045 -#define IDC_BTN_COM1 1046 -#define IDC_VC_VIDEO_RESOLUTION 1047 -#define IDC_BTN_COM2 1047 -#define IDC_BTN_COM3 1048 -#define IDC_BTN_COM4 1049 -#define IDC_CV_HARDWAREYUV 1050 -#define IDC_BTN_COM5 1050 -#define IDC_BTN_FUNC1 1051 -#define IDC_BTN_FUNC2 1052 -#define IDC_BTN_FUNC3 1053 -#define IDC_BTN_TANK_DETACH 1054 -#define IDC_LIST2 1055 -#define IDC_BTN_FSS 1055 -#define IDC_ABOUT 1056 -#define IDC_BTN_OVERRIDE 1056 -#define IDC_TAB1 1057 -#define IDC_BTN_NIGHT_SCOPE 1057 -#define IDC_AC_ACCEPT 1058 -#define IDC_BTN_MANIPULATOR 1058 -#define IDC_AC_CANCEL 1059 -#define IDC_BTN_LINE_COLOR_CHANGE 1059 -#define IDC_AC_AUDIO_ADAPTER 1060 -#define IDC_AC_PCM 1062 -#define IDC_AC_XADPCM 1063 -#define IDC_AC_UNKNOWN_CODEC 1064 -#define IDC_EE_CONFOUNDER 1065 -#define IDC_EE_HDDKEY 1066 -#define IDC_EE_XBOX_REGION 1067 -#define IDC_EE_SERIAL_NUMBER 1068 -#define IDC_EE_MAC_ADDRESS 1069 -#define IDC_EE_ONLINE_KEY 1070 -#define IDC_EE_AVREGION 1071 -#define IDC_EE_LANGUAGE 1072 -#define IDC_EE_AVSETTINGS 1073 -#define IDC_EE_AUDIOSETTINGS 1074 -#define IDC_EE_GAME_PRTL_CRTL 1075 -#define IDC_EE_PRTL_PASS 1076 -#define IDC_EE_MOVIE_PRTL_CRTL 1077 -#define IDC_EE_DVDREGION 1078 -#define IDC_EE_ACCEPT 1079 -#define IDC_EE_CANCEL 1080 -#define IDC_EE_RESET 1081 -#define IDC_EE_PAL60HZ 1082 -#define IDC_EE_480P 1083 -#define IDC_EE_720P 1084 -#define IDC_EE_1080I 1085 +#define IDC_BTN_OPEN_CLOSE 1039 +#define IDC_BTN_MAP_ZOON_IN_OUT 1040 +#define IDC_VC_ACCEPT 1041 +#define IDC_BTN_MAIN_WEAPON_CONTROL 1042 +#define IDC_VC_CANCEL 1043 +#define IDC_BTN_SUB_WEAPON_CONTROL 1044 +#define IDC_CV_VSYNC 1045 +#define IDC_BTN_EXTINGUISHER 1046 +#define IDC_BTN_MAGAZINE_CHANGE 1047 +#define IDC_BTN_CHAFF 1048 +#define IDC_BTN_WASHING 1049 +#define IDC_BTN_COM1 1050 +#define IDC_VC_VIDEO_RESOLUTION 1051 +#define IDC_BTN_COM2 1052 +#define IDC_BTN_COM3 1053 +#define IDC_BTN_COM4 1054 +#define IDC_CV_HARDWAREYUV 1055 +#define IDC_BTN_COM5 1056 +#define IDC_BTN_FUNC1 1057 +#define IDC_BTN_FUNC2 1058 +#define IDC_BTN_FUNC3 1059 +#define IDC_BTN_TANK_DETACH 1060 +#define IDC_LIST2 1061 +#define IDC_BTN_FSS 1062 +#define IDC_ABOUT 1063 +#define IDC_BTN_OVERRIDE 1064 +#define IDC_TAB1 1065 +#define IDC_BTN_NIGHT_SCOPE 1066 +#define IDC_AC_ACCEPT 1067 +#define IDC_BTN_MANIPULATOR 1068 +#define IDC_AC_CANCEL 1069 +#define IDC_BTN_LINE_COLOR_CHANGE 1070 +#define IDC_AC_AUDIO_ADAPTER 1071 +#define IDC_AC_PCM 1072 +#define IDC_AC_XADPCM 1073 +#define IDC_AC_UNKNOWN_CODEC 1074 +#define IDC_EE_CONFOUNDER 1075 +#define IDC_EE_HDDKEY 1076 +#define IDC_EE_XBOX_REGION 1077 +#define IDC_EE_SERIAL_NUMBER 1078 +#define IDC_EE_MAC_ADDRESS 1079 +#define IDC_EE_ONLINE_KEY 1080 +#define IDC_EE_AVREGION 1081 +#define IDC_EE_LANGUAGE 1082 +#define IDC_EE_AVSETTINGS 1083 +#define IDC_EE_AUDIOSETTINGS 1084 +#define IDC_EE_GAME_PRTL_CRTL 1085 +#define IDC_EE_PRTL_PASS 1086 +#define IDC_EE_MOVIE_PRTL_CRTL 1087 +#define IDC_EE_DVDREGION 1088 +#define IDC_EE_ACCEPT 1089 +#define IDC_EE_CANCEL 1090 +#define IDC_EE_RESET 1091 +#define IDC_EE_PAL60HZ 1092 +#define IDC_EE_480P 1093 +#define IDC_EE_720P 1094 +#define IDC_EE_1080I 1095 #define IDC_XBOX_PORT_0 1158 #define IDC_HOST_NOTCONNECT_0_0 1159 #define IDC_HOST_XINPUT_0_0 1160 From 98820626fab8e0191cd4098eaaddfd4a18ac9471 Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Sat, 9 Jun 2018 17:03:46 -0500 Subject: [PATCH 02/30] Fix GUI's LLE flags status --- src/Cxbx/WndMain.cpp | 10 ++++++---- src/CxbxKrnl/HLEIntercept.cpp | 26 ++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/Cxbx/WndMain.cpp b/src/Cxbx/WndMain.cpp index eac425f03..d2b76213d 100644 --- a/src/Cxbx/WndMain.cpp +++ b/src/Cxbx/WndMain.cpp @@ -2351,6 +2351,7 @@ void WndMain::DrawLedBitmap(HWND hwnd, bool bdefault) else { // draw colored bitmap int LedSequence[4] = { XBOX_LED_COLOUR_OFF, XBOX_LED_COLOUR_OFF, XBOX_LED_COLOUR_OFF, XBOX_LED_COLOUR_OFF }; static int LedSequenceOffset = 0; + int FlagsLLE = 0; g_EmuShared->GetLedSequence(LedSequence); @@ -2358,17 +2359,18 @@ void WndMain::DrawLedBitmap(HWND hwnd, bool bdefault) ActiveLEDColor = LedSequence[LedSequenceOffset & 3]; ++LedSequenceOffset; + g_EmuShared->GetFlagsLLE(&FlagsLLE); // Set LLE flags string based on selected LLE flags - if (m_FlagsLLE & LLE_APU) { + if (FlagsLLE & LLE_APU) { strcat(flagString, "A"); } - if (m_FlagsLLE & LLE_GPU) { + if (FlagsLLE & LLE_GPU) { strcat(flagString, "G"); } - if (m_FlagsLLE & LLE_JIT) { + if (FlagsLLE & LLE_JIT) { strcat(flagString, "J"); } - if (m_FlagsLLE == 0) { + if (FlagsLLE == 0) { sprintf(flagString, "HLE"); } } diff --git a/src/CxbxKrnl/HLEIntercept.cpp b/src/CxbxKrnl/HLEIntercept.cpp index 5ea271da5..7f10f1afa 100644 --- a/src/CxbxKrnl/HLEIntercept.cpp +++ b/src/CxbxKrnl/HLEIntercept.cpp @@ -324,6 +324,28 @@ void EmuD3D_Init_DeferredStates() } } +// Update shared structure with GUI process +void EmuUpdateLLEStatus() +{ + int FlagsLLE; + g_EmuShared->GetFlagsLLE(&FlagsLLE); + + if ((FlagsLLE & LLE_GPU) == false + && (g_SymbolAddresses.find("Direct3D_CreateDevice") == g_SymbolAddresses.end() + || g_SymbolAddresses["Direct3D_CreateDevice"] == 0)) { + bLLE_GPU = true; + FlagsLLE ^= LLE_GPU; + } + + if ((FlagsLLE & LLE_APU) == false + && (g_SymbolAddresses.find("DirectSoundCreate") == g_SymbolAddresses.end() + || g_SymbolAddresses["DirectSoundCreate"] == 0)) { + bLLE_APU = true; + FlagsLLE ^= LLE_APU; + } + g_EmuShared->SetFlagsLLE(&FlagsLLE); +} + // NOTE: EmuHLEIntercept do not get to be in XbSymbolDatabase, do the intecept in Cxbx project only. void EmuHLEIntercept(Xbe::Header *pXbeHeader) { @@ -444,6 +466,8 @@ void EmuHLEIntercept(Xbe::Header *pXbeHeader) EmuD3D_Init_DeferredStates(); + EmuUpdateLLEStatus(); + g_HLECacheUsed = true; } @@ -563,6 +587,8 @@ void EmuHLEIntercept(Xbe::Header *pXbeHeader) cacheAddress << std::hex << (*it).second; WritePrivateProfileString("Symbols", (*it).first.c_str(), cacheAddress.str().c_str(), filename.c_str()); } + + EmuUpdateLLEStatus(); } // NOTE: EmuInstallPatch do not get to be in XbSymbolDatabase, do the patches in Cxbx project only. From ae78a13a445a0429aa9d78c2d472e1f99056637e Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Sat, 9 Jun 2018 21:04:55 -0500 Subject: [PATCH 03/30] Prepare support for GetIsReady and SetIsReady in EmuShared class. --- src/Common/Win32/EmuShared.cpp | 2 +- src/CxbxKrnl/EmuShared.h | 31 +++++++++++++++++++------------ 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/Common/Win32/EmuShared.cpp b/src/Common/Win32/EmuShared.cpp index 5409f3746..d46e2693f 100644 --- a/src/Common/Win32/EmuShared.cpp +++ b/src/Common/Win32/EmuShared.cpp @@ -160,4 +160,4 @@ void EmuShared::Save() m_XBController.Save("Software\\Cxbx-Reloaded\\XBController"); m_XBVideo.Save("Software\\Cxbx-Reloaded\\XBVideo"); m_XBAudio.Save("Software\\Cxbx-Reloaded\\XBAudio"); -} \ No newline at end of file +} diff --git a/src/CxbxKrnl/EmuShared.h b/src/CxbxKrnl/EmuShared.h index 9846b5961..4a786667f 100644 --- a/src/CxbxKrnl/EmuShared.h +++ b/src/CxbxKrnl/EmuShared.h @@ -67,14 +67,20 @@ class EmuShared : public Mutex // ****************************************************************** static void Init(); - void EmuShared::Load(); - void EmuShared::Save(); + void Load(); + void Save(); // ****************************************************************** // * Each process needs to call this to cleanup shared memory // ****************************************************************** static void Cleanup(); + // ****************************************************************** + // * Each child process need to wait until parent process is ready + // ****************************************************************** + void GetIsReady(bool *isReady) { Lock(); *isReady = m_isReady; Unlock(); } + void SetIsReady(bool isReady) { Lock(); m_isReady = isReady; Unlock(); } + // ****************************************************************** // * Xbox Video Accessors // ****************************************************************** @@ -194,20 +200,21 @@ class EmuShared : public Mutex XBVideo m_XBVideo; XBAudio m_XBAudio; char m_XbePath[MAX_PATH]; - int m_BootFlags; + int m_BootFlags; int m_FlagsLLE; - int m_XInputEnabled; - int m_DisablePixelShaders; - int m_UncapFramerate; - int m_UseAllCores; - int m_SkipRdtscPatching; - float m_MSpF; + int m_XInputEnabled; + int m_DisablePixelShaders; + int m_UncapFramerate; + int m_UseAllCores; + int m_SkipRdtscPatching; + float m_MSpF; float m_FPS; - bool m_bMultiXbeFlag; - bool m_bDebugging; + bool m_bMultiXbeFlag; + bool m_bDebugging; int m_LedSequence[4]; int m_ScaleViewport; - int m_DirectHostBackBufferAccess; + int m_DirectHostBackBufferAccess; + bool m_isReady; }; // ****************************************************************** From 28a36b437fa6fa84721f3c1f6d96fbbba48528a3 Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Sat, 9 Jun 2018 21:08:16 -0500 Subject: [PATCH 04/30] Start using GetIsReady and SetIsReady to perform wait process. --- src/Cxbx/ResCxbx.h | 1 + src/Cxbx/WndMain.cpp | 33 +++++++++++++++++++++++---------- src/CxbxKrnl/CxbxKrnl.cpp | 23 +++++++++++++++++++++++ src/CxbxKrnl/EmuKrnlHal.cpp | 1 + 4 files changed, 48 insertions(+), 10 deletions(-) diff --git a/src/Cxbx/ResCxbx.h b/src/Cxbx/ResCxbx.h index 59989cb2c..793d18d32 100644 --- a/src/Cxbx/ResCxbx.h +++ b/src/Cxbx/ResCxbx.h @@ -115,6 +115,7 @@ #define IDC_EE_480P 1093 #define IDC_EE_720P 1094 #define IDC_EE_1080I 1095 +#define ID_KRNL_IS_READY 1096 #define IDC_XBOX_PORT_0 1158 #define IDC_HOST_NOTCONNECT_0_0 1159 #define IDC_HOST_XINPUT_0_0 1160 diff --git a/src/Cxbx/WndMain.cpp b/src/Cxbx/WndMain.cpp index d2b76213d..4f8facce7 100644 --- a/src/Cxbx/WndMain.cpp +++ b/src/Cxbx/WndMain.cpp @@ -507,21 +507,16 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP { CreateThread(NULL, NULL, CrashMonitorWrapper, (void*)this, NULL, NULL); // create the crash monitoring thread if (m_hwndChild == NULL) { - float fps = 0.0f; - float mspf = 0.0f; int LedSequence[4] = { XBOX_LED_COLOUR_GREEN, XBOX_LED_COLOUR_GREEN, XBOX_LED_COLOUR_GREEN, XBOX_LED_COLOUR_GREEN }; - g_EmuShared->SetCurrentMSpF(&mspf); - g_EmuShared->SetCurrentFPS(&fps); g_EmuShared->SetLedSequence(LedSequence); SetTimer(hwnd, TIMERID_FPS, 1000, (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 = (HWND)lParam; UpdateCaption(); RefreshMenus(); } - else - { - m_hwndChild = GetWindow(hwnd, GW_CHILD); + else { + m_hwndChild = (HWND)lParam; } } break; @@ -538,8 +533,23 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP } } break; - } - }; + + case WM_USER: { + switch(lParam) { + case ID_KRNL_IS_READY: { + float fps = 0.0f; + float mspf = 0.0f; + g_EmuShared->SetCurrentMSpF(&mspf); + g_EmuShared->SetCurrentFPS(&fps); + g_EmuShared->SetFlagsLLE(&m_FlagsLLE); + g_EmuShared->SetIsReady(true); + break; + } + } + break; + } + } + }; break; // added per PVS suggestion. case WM_TIMER: @@ -2240,6 +2250,7 @@ void WndMain::StartEmulation(HWND hwndParent, DebuggerState LocalDebuggerState / else { m_bIsStarted = true; + g_EmuShared->SetIsReady(true); printf("WndMain: %s emulation started with debugger.\n", m_Xbe->m_szAsciiTitle); } } @@ -2254,9 +2265,11 @@ void WndMain::StartEmulation(HWND hwndParent, DebuggerState LocalDebuggerState / else { m_bIsStarted = true; + g_EmuShared->SetIsReady(true); printf("WndMain: %s emulation started.\n", m_Xbe->m_szAsciiTitle); } } + } } diff --git a/src/CxbxKrnl/CxbxKrnl.cpp b/src/CxbxKrnl/CxbxKrnl.cpp index 5a2ba43a1..54345fccf 100644 --- a/src/CxbxKrnl/CxbxKrnl.cpp +++ b/src/CxbxKrnl/CxbxKrnl.cpp @@ -42,6 +42,7 @@ namespace xboxkrnl #include }; +#include "Cxbx\ResCxbx.h" #include "CxbxKrnl.h" #include "Cxbx\CxbxXbdm.h" // For Cxbx_LibXbdmThunkTable #include "CxbxVersion.h" @@ -905,6 +906,28 @@ void CxbxKrnlMain(int argc, char* argv[]) 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 + int waitCounter = 10; + bool isReady = false; + + while (waitCounter > 0) { + g_EmuShared->GetIsReady(&isReady); + if (isReady) { + break; + } + waitCounter--; + Sleep(100); + } + if (!isReady) { + CxbxKrnlCleanup("GUI process is not ready!"); + } + // Write a header to the log { printf("[0x%.4X] INIT: Cxbx-Reloaded Version %s\n", GetCurrentThreadId(), _CXBX_VERSION); diff --git a/src/CxbxKrnl/EmuKrnlHal.cpp b/src/CxbxKrnl/EmuKrnlHal.cpp index 5228ad041..bbd888636 100644 --- a/src/CxbxKrnl/EmuKrnlHal.cpp +++ b/src/CxbxKrnl/EmuKrnlHal.cpp @@ -575,6 +575,7 @@ XBSYSAPI EXPORTNUM(49) xboxkrnl::VOID DECLSPEC_NORETURN NTAPI xboxkrnl::HalRetur QuickReboot |= BOOT_QUICK_REBOOT; g_EmuShared->SetBootFlags(&QuickReboot); g_EmuShared->SetMultiXbeFlag(&bMultiXbe); + g_EmuShared->SetIsReady(false); char szArgsBuffer[4096]; From 96d390405a6e5328bd72726b45603faebe72911d Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Sat, 9 Jun 2018 21:14:46 -0500 Subject: [PATCH 05/30] Add note for WM_PARENTNOTIFY usage --- src/Cxbx/WndMain.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Cxbx/WndMain.cpp b/src/Cxbx/WndMain.cpp index 4f8facce7..1757c7ff0 100644 --- a/src/Cxbx/WndMain.cpp +++ b/src/Cxbx/WndMain.cpp @@ -499,6 +499,7 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP } break; + // NOTE: WM_PARENTNOTIFY was triggered by kernel process' graphic window creation. case WM_PARENTNOTIFY: { switch(LOWORD(wParam)) From 71cd6a1db4a39609079df2f83cc800d3d79f1873 Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Sun, 10 Jun 2018 10:07:28 -0500 Subject: [PATCH 06/30] Fix multi-xbe launch bug mutex from kernel process did not release even if perform hard crash. --- src/Cxbx/WndMain.cpp | 52 ++++++++++++++++++------------------- src/CxbxKrnl/CxbxKrnl.cpp | 9 +++++++ src/CxbxKrnl/EmuD3D8.cpp | 13 ---------- src/CxbxKrnl/EmuKrnlHal.cpp | 1 - 4 files changed, 35 insertions(+), 40 deletions(-) diff --git a/src/Cxbx/WndMain.cpp b/src/Cxbx/WndMain.cpp index 1757c7ff0..cba1ae1df 100644 --- a/src/Cxbx/WndMain.cpp +++ b/src/Cxbx/WndMain.cpp @@ -506,7 +506,6 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP { case WM_CREATE: { - CreateThread(NULL, NULL, CrashMonitorWrapper, (void*)this, NULL, NULL); // create the crash monitoring thread if (m_hwndChild == NULL) { int LedSequence[4] = { XBOX_LED_COLOUR_GREEN, XBOX_LED_COLOUR_GREEN, XBOX_LED_COLOUR_GREEN, XBOX_LED_COLOUR_GREEN }; g_EmuShared->SetLedSequence(LedSequence); @@ -519,6 +518,7 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP else { m_hwndChild = (HWND)lParam; } + CreateThread(NULL, NULL, CrashMonitorWrapper, (void*)this, NULL, NULL); // create the crash monitoring thread } break; @@ -2292,13 +2292,13 @@ void WndMain::StopEmulation() ResizeWindow(m_hwnd, /*bForGUI=*/true); } - // wrapper function to call CrashMonitor DWORD WINAPI WndMain::CrashMonitorWrapper(LPVOID lpVoid) { CxbxSetThreadName("Cxbx Crash Monitor"); static_cast(lpVoid)->CrashMonitor(); + return 0; } @@ -2306,41 +2306,41 @@ DWORD WINAPI WndMain::CrashMonitorWrapper(LPVOID lpVoid) void WndMain::CrashMonitor() { bool bQuickReboot; - HANDLE hCrashMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, "CrashMutex"); + DWORD dwProcessID_ExitCode = 0; + GetWindowThreadProcessId(m_hwndChild, &dwProcessID_ExitCode); - DWORD state = WaitForSingleObject(hCrashMutex, INFINITE); + HANDLE hProcess = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_INFORMATION, FALSE, dwProcessID_ExitCode); + + WaitForSingleObject(hProcess, INFINITE); + dwProcessID_ExitCode = 0; + GetExitCodeProcess(hProcess, &dwProcessID_ExitCode); g_EmuShared->GetMultiXbeFlag(&bQuickReboot); - if (state == WAIT_OBJECT_0) // StopEmulation - { - CloseHandle(hCrashMutex); - return; - } - - if (state == WAIT_ABANDONED && !bQuickReboot) // that's a crash - { - 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(); + if (!bQuickReboot) { + if (dwProcessID_ExitCode == EXIT_SUCCESS) {// StopEmulation + CloseHandle(hProcess); + return; + } else { // that's a crash + CloseHandle(hProcess); + 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; } - return; } // multi-xbe // destroy this thread and start a new one - CloseHandle(hCrashMutex); + CloseHandle(hProcess); bQuickReboot = false; g_EmuShared->SetMultiXbeFlag(&bQuickReboot); - - return; } // draw Xbox LED bitmap diff --git a/src/CxbxKrnl/CxbxKrnl.cpp b/src/CxbxKrnl/CxbxKrnl.cpp index 54345fccf..18de881ef 100644 --- a/src/CxbxKrnl/CxbxKrnl.cpp +++ b/src/CxbxKrnl/CxbxKrnl.cpp @@ -927,6 +927,15 @@ void CxbxKrnlMain(int argc, char* argv[]) if (!isReady) { CxbxKrnlCleanup("GUI process is not ready!"); } + 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 { diff --git a/src/CxbxKrnl/EmuD3D8.cpp b/src/CxbxKrnl/EmuD3D8.cpp index 6a4922d57..7dd0323d7 100644 --- a/src/CxbxKrnl/EmuD3D8.cpp +++ b/src/CxbxKrnl/EmuD3D8.cpp @@ -1420,17 +1420,6 @@ static DWORD WINAPI EmuRenderWindow(LPVOID lpVoid) 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 { HWND hwndParent = GetDesktopWindow(); @@ -1510,8 +1499,6 @@ static DWORD WINAPI EmuRenderWindow(LPVOID lpVoid) delete dbgConsole; - if (hCrashMutex != NULL) { ReleaseMutex(hCrashMutex); } - CxbxKrnlCleanup(NULL); } diff --git a/src/CxbxKrnl/EmuKrnlHal.cpp b/src/CxbxKrnl/EmuKrnlHal.cpp index bbd888636..5228ad041 100644 --- a/src/CxbxKrnl/EmuKrnlHal.cpp +++ b/src/CxbxKrnl/EmuKrnlHal.cpp @@ -575,7 +575,6 @@ XBSYSAPI EXPORTNUM(49) xboxkrnl::VOID DECLSPEC_NORETURN NTAPI xboxkrnl::HalRetur QuickReboot |= BOOT_QUICK_REBOOT; g_EmuShared->SetBootFlags(&QuickReboot); g_EmuShared->SetMultiXbeFlag(&bMultiXbe); - g_EmuShared->SetIsReady(false); char szArgsBuffer[4096]; From b9827337f6f511ce7adbaa8a597ec6baffde0025 Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Sun, 10 Jun 2018 10:20:37 -0500 Subject: [PATCH 07/30] Remove ready state from startup kernel proccess will send a message to gui process for sync purpose. --- src/Cxbx/WndMain.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Cxbx/WndMain.cpp b/src/Cxbx/WndMain.cpp index cba1ae1df..ec0c078cf 100644 --- a/src/Cxbx/WndMain.cpp +++ b/src/Cxbx/WndMain.cpp @@ -2251,7 +2251,6 @@ void WndMain::StartEmulation(HWND hwndParent, DebuggerState LocalDebuggerState / else { m_bIsStarted = true; - g_EmuShared->SetIsReady(true); printf("WndMain: %s emulation started with debugger.\n", m_Xbe->m_szAsciiTitle); } } @@ -2266,7 +2265,6 @@ void WndMain::StartEmulation(HWND hwndParent, DebuggerState LocalDebuggerState / else { m_bIsStarted = true; - g_EmuShared->SetIsReady(true); printf("WndMain: %s emulation started.\n", m_Xbe->m_szAsciiTitle); } } From 71a542d790d118cde1d82dcca8ad3bd27a112fec Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Sun, 10 Jun 2018 10:21:31 -0500 Subject: [PATCH 08/30] Prepare support shared emulating state --- src/CxbxKrnl/EmuShared.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/CxbxKrnl/EmuShared.h b/src/CxbxKrnl/EmuShared.h index 4a786667f..c3afb0bc3 100644 --- a/src/CxbxKrnl/EmuShared.h +++ b/src/CxbxKrnl/EmuShared.h @@ -75,6 +75,12 @@ class EmuShared : public Mutex // ****************************************************************** static void Cleanup(); + // ****************************************************************** + // * Check if parent process is emulating title + // ****************************************************************** + void GetIsEmulating(bool *isEmulating) { Lock(); *isEmulating = m_isEmulating; Unlock(); } + void SetIsEmulating(bool isEmulating) { Lock(); m_isEmulating = isEmulating; Unlock(); } + // ****************************************************************** // * Each child process need to wait until parent process is ready // ****************************************************************** @@ -214,7 +220,8 @@ class EmuShared : public Mutex int m_LedSequence[4]; int m_ScaleViewport; int m_DirectHostBackBufferAccess; - bool m_isReady; + bool m_isReady; + bool m_isEmulating; }; // ****************************************************************** From 7bd449c171b7b12554541069ca41af6d1a99c241 Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Sun, 10 Jun 2018 10:24:15 -0500 Subject: [PATCH 09/30] Prevent two titles emulating at same time. This will help producing false postive report and inform user to stop current title emulating before start new emulation. --- src/Cxbx/WndMain.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/Cxbx/WndMain.cpp b/src/Cxbx/WndMain.cpp index ec0c078cf..a0f5c6e3d 100644 --- a/src/Cxbx/WndMain.cpp +++ b/src/Cxbx/WndMain.cpp @@ -2188,6 +2188,17 @@ void WndMain::SaveXbeAs() void WndMain::StartEmulation(HWND hwndParent, DebuggerState LocalDebuggerState /*= debuggerOff*/) { 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 g_EmuShared->SetXbePath(m_Xbe->m_szPath); @@ -2288,6 +2299,7 @@ void WndMain::StopEmulation() RefreshMenus(); // Set the window size back to it's GUI dimensions ResizeWindow(m_hwnd, /*bForGUI=*/true); + g_EmuShared->SetIsEmulating(false); } // wrapper function to call CrashMonitor From bde83e72787019aa1cd75fbe82275e505288e4f2 Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Sun, 10 Jun 2018 10:30:09 -0500 Subject: [PATCH 10/30] Restore previous change May not require to wait for kernel process anyway. --- src/Cxbx/WndMain.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Cxbx/WndMain.cpp b/src/Cxbx/WndMain.cpp index a0f5c6e3d..98af20f36 100644 --- a/src/Cxbx/WndMain.cpp +++ b/src/Cxbx/WndMain.cpp @@ -507,7 +507,11 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP case WM_CREATE: { if (m_hwndChild == NULL) { + float fps = 0.0f; + float mspf = 0.0f; int LedSequence[4] = { XBOX_LED_COLOUR_GREEN, XBOX_LED_COLOUR_GREEN, XBOX_LED_COLOUR_GREEN, XBOX_LED_COLOUR_GREEN }; + g_EmuShared->SetCurrentMSpF(&mspf); + g_EmuShared->SetCurrentFPS(&fps); g_EmuShared->SetLedSequence(LedSequence); SetTimer(hwnd, TIMERID_FPS, 1000, (TIMERPROC)NULL); SetTimer(hwnd, TIMERID_LED, XBOX_LED_FLASH_PERIOD, (TIMERPROC)NULL); @@ -538,10 +542,6 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP case WM_USER: { switch(lParam) { case ID_KRNL_IS_READY: { - float fps = 0.0f; - float mspf = 0.0f; - g_EmuShared->SetCurrentMSpF(&mspf); - g_EmuShared->SetCurrentFPS(&fps); g_EmuShared->SetFlagsLLE(&m_FlagsLLE); g_EmuShared->SetIsReady(true); break; From 983432554a4463dd521b4836e2f64cde88f412ef Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Sun, 10 Jun 2018 10:31:00 -0500 Subject: [PATCH 11/30] Add note if gui process need to do something before kernel start do anything. --- src/Cxbx/WndMain.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Cxbx/WndMain.cpp b/src/Cxbx/WndMain.cpp index 98af20f36..b278c4dda 100644 --- a/src/Cxbx/WndMain.cpp +++ b/src/Cxbx/WndMain.cpp @@ -541,6 +541,7 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP 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); From 54ecfb0086b5360e289efade3c2fcb34933b8c30 Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Sun, 10 Jun 2018 10:41:29 -0500 Subject: [PATCH 12/30] Move m_isEmulating and m_isReady into proper aligned structure --- src/CxbxKrnl/EmuShared.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/CxbxKrnl/EmuShared.h b/src/CxbxKrnl/EmuShared.h index c3afb0bc3..726d5887a 100644 --- a/src/CxbxKrnl/EmuShared.h +++ b/src/CxbxKrnl/EmuShared.h @@ -78,14 +78,14 @@ class EmuShared : public Mutex // ****************************************************************** // * Check if parent process is emulating title // ****************************************************************** - void GetIsEmulating(bool *isEmulating) { Lock(); *isEmulating = m_isEmulating; Unlock(); } - void SetIsEmulating(bool isEmulating) { Lock(); m_isEmulating = isEmulating; Unlock(); } + 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_isReady; Unlock(); } - void SetIsReady(bool isReady) { Lock(); m_isReady = isReady; Unlock(); } + void GetIsReady(bool *isReady) { Lock(); *isReady = m_bReady; Unlock(); } + void SetIsReady(bool isReady) { Lock(); m_bReady = isReady; Unlock(); } // ****************************************************************** // * Xbox Video Accessors @@ -216,12 +216,12 @@ class EmuShared : public Mutex float m_MSpF; float m_FPS; bool m_bMultiXbeFlag; - bool m_bDebugging; + bool m_bDebugging; + bool m_bReady; + bool m_bEmulating; int m_LedSequence[4]; int m_ScaleViewport; - int m_DirectHostBackBufferAccess; - bool m_isReady; - bool m_isEmulating; + int m_DirectHostBackBufferAccess; }; // ****************************************************************** From b5b9e475e74e78c0e21c2c44a56cb6595f498eee Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Sun, 10 Jun 2018 11:00:45 -0500 Subject: [PATCH 13/30] Undo newline for no reason. :running: --- src/Cxbx/WndMain.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Cxbx/WndMain.cpp b/src/Cxbx/WndMain.cpp index b278c4dda..32341a200 100644 --- a/src/Cxbx/WndMain.cpp +++ b/src/Cxbx/WndMain.cpp @@ -2280,7 +2280,6 @@ void WndMain::StartEmulation(HWND hwndParent, DebuggerState LocalDebuggerState / printf("WndMain: %s emulation started.\n", m_Xbe->m_szAsciiTitle); } } - } } From c9e2406394317488c82cc1b485142ce688526bf4 Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Sun, 10 Jun 2018 17:14:41 -0500 Subject: [PATCH 14/30] Output log message of rollback to LLE flag. --- src/CxbxKrnl/HLEIntercept.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/CxbxKrnl/HLEIntercept.cpp b/src/CxbxKrnl/HLEIntercept.cpp index 7f10f1afa..95c676d47 100644 --- a/src/CxbxKrnl/HLEIntercept.cpp +++ b/src/CxbxKrnl/HLEIntercept.cpp @@ -335,6 +335,7 @@ void EmuUpdateLLEStatus() || g_SymbolAddresses["Direct3D_CreateDevice"] == 0)) { bLLE_GPU = true; FlagsLLE ^= LLE_GPU; + EmuOutputMessage(XB_OUTPUT_MESSAGE_INFO, "Rollback to LLE GPU."); } if ((FlagsLLE & LLE_APU) == false @@ -342,6 +343,7 @@ void EmuUpdateLLEStatus() || g_SymbolAddresses["DirectSoundCreate"] == 0)) { bLLE_APU = true; FlagsLLE ^= LLE_APU; + EmuOutputMessage(XB_OUTPUT_MESSAGE_INFO, "Rollback to LLE APU."); } g_EmuShared->SetFlagsLLE(&FlagsLLE); } From 63af4166e0e391bf7f939aeff5eae2bf75566a75 Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Sun, 10 Jun 2018 17:15:16 -0500 Subject: [PATCH 15/30] Fix newline, strange... --- src/CxbxKrnl/CxbxKrnl.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/CxbxKrnl/CxbxKrnl.cpp b/src/CxbxKrnl/CxbxKrnl.cpp index 18de881ef..38ce03fa1 100644 --- a/src/CxbxKrnl/CxbxKrnl.cpp +++ b/src/CxbxKrnl/CxbxKrnl.cpp @@ -928,13 +928,13 @@ void CxbxKrnlMain(int argc, char* argv[]) CxbxKrnlCleanup("GUI process is not ready!"); } 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); + + 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 From 90df98e5e686da5a8c9b1e5fdd0037259b67556f Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Sun, 10 Jun 2018 17:16:10 -0500 Subject: [PATCH 16/30] Request user interaction to either retry or cancel. --- src/CxbxKrnl/CxbxKrnl.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/CxbxKrnl/CxbxKrnl.cpp b/src/CxbxKrnl/CxbxKrnl.cpp index 38ce03fa1..deff0058a 100644 --- a/src/CxbxKrnl/CxbxKrnl.cpp +++ b/src/CxbxKrnl/CxbxKrnl.cpp @@ -911,7 +911,8 @@ void CxbxKrnlMain(int argc, char* argv[]) } else { SendMessage(CxbxKrnl_hEmuParent, WM_PARENTNOTIFY, WM_USER, ID_KRNL_IS_READY); } - + + retryWait: // Force wait until first allocated process is ready int waitCounter = 10; bool isReady = false; @@ -925,7 +926,12 @@ void CxbxKrnlMain(int argc, char* argv[]) Sleep(100); } if (!isReady) { - CxbxKrnlCleanup("GUI process is not ready!"); + 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) { + goto retryWait; + } } g_EmuShared->SetIsReady(false); From cdbd1aab50b813d2a46c89a337b50aec93307d42 Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Sun, 10 Jun 2018 17:37:28 -0500 Subject: [PATCH 17/30] Add verification before start monitoring kernel process --- src/Cxbx/WndMain.cpp | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/src/Cxbx/WndMain.cpp b/src/Cxbx/WndMain.cpp index 32341a200..0d8ad0615 100644 --- a/src/Cxbx/WndMain.cpp +++ b/src/Cxbx/WndMain.cpp @@ -2319,8 +2319,28 @@ void WndMain::CrashMonitor() DWORD dwProcessID_ExitCode = 0; GetWindowThreadProcessId(m_hwndChild, &dwProcessID_ExitCode); + // Did not received valid process ID, assume we do not have access or crashed in the process. + if (dwProcessID_ExitCode == 0) { + + crashCleanup: + + KillTimer(m_hwnd, TIMERID_FPS); + KillTimer(m_hwnd, TIMERID_LED); + DrawLedBitmap(m_hwnd, true); + m_hwndChild = NULL; + m_bIsStarted = false; + UpdateCaption(); + RefreshMenus(); + return; + } + HANDLE hProcess = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_INFORMATION, FALSE, dwProcessID_ExitCode); + // Did not received valid handle, assume we do not have access or crashed in the process. + if (hProcess == NULL) { + goto crashCleanup; + } + WaitForSingleObject(hProcess, INFINITE); dwProcessID_ExitCode = 0; GetExitCodeProcess(hProcess, &dwProcessID_ExitCode); @@ -2333,16 +2353,7 @@ void WndMain::CrashMonitor() return; } else { // that's a crash CloseHandle(hProcess); - 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; + goto crashCleanup; } } From 92788e9cd368c3b357a9c644208fa2f6610e99b3 Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Sun, 10 Jun 2018 17:56:53 -0500 Subject: [PATCH 18/30] Don't continue failed wait counter. --- src/CxbxKrnl/CxbxKrnl.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/CxbxKrnl/CxbxKrnl.cpp b/src/CxbxKrnl/CxbxKrnl.cpp index deff0058a..ec2b32c22 100644 --- a/src/CxbxKrnl/CxbxKrnl.cpp +++ b/src/CxbxKrnl/CxbxKrnl.cpp @@ -932,6 +932,7 @@ void CxbxKrnlMain(int argc, char* argv[]) if (mbRet == IDRETRY) { goto retryWait; } + CxbxKrnlShutDown(); } g_EmuShared->SetIsReady(false); From d3a131ea130b42e848a343f62e2fc2499cdd286c Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Mon, 11 Jun 2018 00:03:24 -0500 Subject: [PATCH 19/30] Use do while statement for user interaction. --- src/CxbxKrnl/CxbxKrnl.cpp | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/src/CxbxKrnl/CxbxKrnl.cpp b/src/CxbxKrnl/CxbxKrnl.cpp index ec2b32c22..0053cbc59 100644 --- a/src/CxbxKrnl/CxbxKrnl.cpp +++ b/src/CxbxKrnl/CxbxKrnl.cpp @@ -912,28 +912,31 @@ void CxbxKrnlMain(int argc, char* argv[]) SendMessage(CxbxKrnl_hEmuParent, WM_PARENTNOTIFY, WM_USER, ID_KRNL_IS_READY); } - retryWait: // Force wait until first allocated process is ready - int waitCounter = 10; - bool isReady = false; + do { + int waitCounter = 10; + bool isReady = false; - while (waitCounter > 0) { - g_EmuShared->GetIsReady(&isReady); - if (isReady) { - break; + while (waitCounter > 0) { + g_EmuShared->GetIsReady(&isReady); + if (isReady) { + break; + } + waitCounter--; + Sleep(100); } - 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) { - goto retryWait; + 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(); } - CxbxKrnlShutDown(); - } + break; + } while (true); + g_EmuShared->SetIsReady(false); bool bQuickReboot; From d0fd6d08d1969c7d986de20e004985980c4718e6 Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Mon, 11 Jun 2018 00:04:45 -0500 Subject: [PATCH 20/30] Identical method instead of using goto. --- src/Cxbx/WndMain.cpp | 75 +++++++++++++++++++++----------------------- 1 file changed, 36 insertions(+), 39 deletions(-) diff --git a/src/Cxbx/WndMain.cpp b/src/Cxbx/WndMain.cpp index 0d8ad0615..a2fb2e54d 100644 --- a/src/Cxbx/WndMain.cpp +++ b/src/Cxbx/WndMain.cpp @@ -2319,49 +2319,46 @@ void WndMain::CrashMonitor() DWORD dwProcessID_ExitCode = 0; GetWindowThreadProcessId(m_hwndChild, &dwProcessID_ExitCode); - // Did not received valid process ID, assume we do not have access or crashed in the process. - if (dwProcessID_ExitCode == 0) { - - crashCleanup: - - KillTimer(m_hwnd, TIMERID_FPS); - KillTimer(m_hwnd, TIMERID_LED); - DrawLedBitmap(m_hwnd, true); - m_hwndChild = NULL; - m_bIsStarted = false; - UpdateCaption(); - RefreshMenus(); - return; - } + // If we do receive valid process ID, let's do the next step. + if (dwProcessID_ExitCode != 0) { HANDLE hProcess = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_INFORMATION, FALSE, dwProcessID_ExitCode); - // Did not received valid handle, assume we do not have access or crashed in the process. - if (hProcess == NULL) { - goto crashCleanup; + // If we do receive valid handle, let's do the next step. + if (hProcess != NULL) { + + WaitForSingleObject(hProcess, INFINITE); + dwProcessID_ExitCode = 0; + GetExitCodeProcess(hProcess, &dwProcessID_ExitCode); + + g_EmuShared->GetMultiXbeFlag(&bQuickReboot); + + if (!bQuickReboot) { + if (dwProcessID_ExitCode == EXIT_SUCCESS) {// StopEmulation + CloseHandle(hProcess); + return; + } else { // that's a crash + CloseHandle(hProcess); + } + } + else { + + // multi-xbe + // destroy this thread and start a new one + CloseHandle(hProcess); + bQuickReboot = false; + g_EmuShared->SetMultiXbeFlag(&bQuickReboot); + return; + } + } } - - WaitForSingleObject(hProcess, INFINITE); - dwProcessID_ExitCode = 0; - GetExitCodeProcess(hProcess, &dwProcessID_ExitCode); - - g_EmuShared->GetMultiXbeFlag(&bQuickReboot); - - if (!bQuickReboot) { - if (dwProcessID_ExitCode == EXIT_SUCCESS) {// StopEmulation - CloseHandle(hProcess); - return; - } else { // that's a crash - CloseHandle(hProcess); - goto crashCleanup; - } - } - - // multi-xbe - // destroy this thread and start a new one - CloseHandle(hProcess); - bQuickReboot = false; - g_EmuShared->SetMultiXbeFlag(&bQuickReboot); + KillTimer(m_hwnd, TIMERID_FPS); + KillTimer(m_hwnd, TIMERID_LED); + DrawLedBitmap(m_hwnd, true); + m_hwndChild = NULL; + m_bIsStarted = false; + UpdateCaption(); + RefreshMenus(); } // draw Xbox LED bitmap From 8e2543af4f46a42330488620b0c27b9087d7daaf Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Mon, 11 Jun 2018 00:11:34 -0500 Subject: [PATCH 21/30] Little cleanup for CrashMonitor --- src/Cxbx/WndMain.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Cxbx/WndMain.cpp b/src/Cxbx/WndMain.cpp index a2fb2e54d..698c49a2f 100644 --- a/src/Cxbx/WndMain.cpp +++ b/src/Cxbx/WndMain.cpp @@ -2330,28 +2330,29 @@ void WndMain::CrashMonitor() WaitForSingleObject(hProcess, INFINITE); dwProcessID_ExitCode = 0; GetExitCodeProcess(hProcess, &dwProcessID_ExitCode); + CloseHandle(hProcess); g_EmuShared->GetMultiXbeFlag(&bQuickReboot); if (!bQuickReboot) { if (dwProcessID_ExitCode == EXIT_SUCCESS) {// StopEmulation - CloseHandle(hProcess); return; - } else { // that's a crash - CloseHandle(hProcess); } + // Or else, it's a crash } else { // multi-xbe // destroy this thread and start a new one - CloseHandle(hProcess); bQuickReboot = false; g_EmuShared->SetMultiXbeFlag(&bQuickReboot); return; } } } + + // Crash clean up. + KillTimer(m_hwnd, TIMERID_FPS); KillTimer(m_hwnd, TIMERID_LED); DrawLedBitmap(m_hwnd, true); From 2b8a7a82a88bc87cf6ebeebd981c0bfcca15bb7c Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Mon, 11 Jun 2018 01:54:38 -0500 Subject: [PATCH 22/30] Use Fallback wording instead of rollback. --- src/CxbxKrnl/HLEIntercept.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/CxbxKrnl/HLEIntercept.cpp b/src/CxbxKrnl/HLEIntercept.cpp index 95c676d47..91a9fa25a 100644 --- a/src/CxbxKrnl/HLEIntercept.cpp +++ b/src/CxbxKrnl/HLEIntercept.cpp @@ -335,7 +335,7 @@ void EmuUpdateLLEStatus() || g_SymbolAddresses["Direct3D_CreateDevice"] == 0)) { bLLE_GPU = true; FlagsLLE ^= LLE_GPU; - EmuOutputMessage(XB_OUTPUT_MESSAGE_INFO, "Rollback to LLE GPU."); + EmuOutputMessage(XB_OUTPUT_MESSAGE_INFO, "Fallback to LLE GPU."); } if ((FlagsLLE & LLE_APU) == false @@ -343,7 +343,7 @@ void EmuUpdateLLEStatus() || g_SymbolAddresses["DirectSoundCreate"] == 0)) { bLLE_APU = true; FlagsLLE ^= LLE_APU; - EmuOutputMessage(XB_OUTPUT_MESSAGE_INFO, "Rollback to LLE APU."); + EmuOutputMessage(XB_OUTPUT_MESSAGE_INFO, "Fallback to LLE APU."); } g_EmuShared->SetFlagsLLE(&FlagsLLE); } From 33b0df311234e1c11b67a302a14ae295cf3f1103 Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Mon, 11 Jun 2018 02:43:22 -0500 Subject: [PATCH 23/30] Cleaner and optimized check if title has containing library. It is a requirement to move library header before start scanning symbols. Plus only call status check once. --- src/CxbxKrnl/HLEIntercept.cpp | 54 +++++++++++++++++------------------ 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/src/CxbxKrnl/HLEIntercept.cpp b/src/CxbxKrnl/HLEIntercept.cpp index 91a9fa25a..bd713ecc3 100644 --- a/src/CxbxKrnl/HLEIntercept.cpp +++ b/src/CxbxKrnl/HLEIntercept.cpp @@ -325,22 +325,21 @@ void EmuD3D_Init_DeferredStates() } // Update shared structure with GUI process -void EmuUpdateLLEStatus() +void EmuUpdateLLEStatus(uint32_t XbLibScan) { int FlagsLLE; g_EmuShared->GetFlagsLLE(&FlagsLLE); if ((FlagsLLE & LLE_GPU) == false - && (g_SymbolAddresses.find("Direct3D_CreateDevice") == g_SymbolAddresses.end() - || g_SymbolAddresses["Direct3D_CreateDevice"] == 0)) { + && !((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 - && (g_SymbolAddresses.find("DirectSoundCreate") == g_SymbolAddresses.end() - || g_SymbolAddresses["DirectSoundCreate"] == 0)) { + && (XbLibScan & XbSymbolLib_DSOUND) == 0) { bLLE_APU = true; FlagsLLE ^= LLE_APU; EmuOutputMessage(XB_OUTPUT_MESSAGE_INFO, "Fallback to LLE APU."); @@ -353,6 +352,27 @@ void EmuHLEIntercept(Xbe::Header *pXbeHeader) { 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; + + // 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()); + } + } + + EmuUpdateLLEStatus(XbLibScan); + printf("\n"); printf("*******************************************************************************\n"); printf("* Cxbx-Reloaded High Level Emulation database\n"); @@ -468,8 +488,6 @@ void EmuHLEIntercept(Xbe::Header *pXbeHeader) EmuD3D_Init_DeferredStates(); - EmuUpdateLLEStatus(); - g_HLECacheUsed = true; } @@ -488,26 +506,10 @@ void EmuHLEIntercept(Xbe::Header *pXbeHeader) // // initialize Microsoft XDK emulation // - if(pLibraryVersion != 0) - { + if(pLibraryVersion != nullptr) { + 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. if ((XbLibScan & XbSymbolLib_D3D8) > 0 || (XbLibScan & XbSymbolLib_D3D8LTCG) > 0) { g_BuildVersion = xdkVersion; @@ -589,8 +591,6 @@ void EmuHLEIntercept(Xbe::Header *pXbeHeader) cacheAddress << std::hex << (*it).second; WritePrivateProfileString("Symbols", (*it).first.c_str(), cacheAddress.str().c_str(), filename.c_str()); } - - EmuUpdateLLEStatus(); } // NOTE: EmuInstallPatch do not get to be in XbSymbolDatabase, do the patches in Cxbx project only. From 7bb26a979092ef5f3a9e24082f6f71726b1851be Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Mon, 11 Jun 2018 03:13:58 -0500 Subject: [PATCH 24/30] Revert get child hwnd. --- src/Cxbx/WndMain.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Cxbx/WndMain.cpp b/src/Cxbx/WndMain.cpp index 698c49a2f..a927265b3 100644 --- a/src/Cxbx/WndMain.cpp +++ b/src/Cxbx/WndMain.cpp @@ -515,12 +515,12 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP g_EmuShared->SetLedSequence(LedSequence); SetTimer(hwnd, TIMERID_FPS, 1000, (TIMERPROC)NULL); SetTimer(hwnd, TIMERID_LED, XBOX_LED_FLASH_PERIOD, (TIMERPROC)NULL); - m_hwndChild = (HWND)lParam; + m_hwndChild = GetWindow(hwnd, GW_CHILD); UpdateCaption(); RefreshMenus(); } else { - m_hwndChild = (HWND)lParam; + m_hwndChild = GetWindow(hwnd, GW_CHILD); } CreateThread(NULL, NULL, CrashMonitorWrapper, (void*)this, NULL, NULL); // create the crash monitoring thread } From 1ed96cf553822c8a9f0637b2b66204e458156513 Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Mon, 11 Jun 2018 10:14:58 -0500 Subject: [PATCH 25/30] Fix 4039 titles with false positive not finding DSOUND library version. --- src/CxbxKrnl/HLEIntercept.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/CxbxKrnl/HLEIntercept.cpp b/src/CxbxKrnl/HLEIntercept.cpp index bd713ecc3..fc7517e3f 100644 --- a/src/CxbxKrnl/HLEIntercept.cpp +++ b/src/CxbxKrnl/HLEIntercept.cpp @@ -358,6 +358,8 @@ void EmuHLEIntercept(Xbe::Header *pXbeHeader) // 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++) { @@ -369,6 +371,15 @@ void EmuHLEIntercept(Xbe::Header *pXbeHeader) } 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, "DSOUND", 8) == 0) { + XbLibScan |= XbSymbolLib_DSOUND; + break; + } + } } EmuUpdateLLEStatus(XbLibScan); From df6c7cfc44aa637d9d0d89d15b9b97767a60bad6 Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Mon, 11 Jun 2018 22:22:27 -0500 Subject: [PATCH 26/30] Use existing define string for DSOUND. --- src/CxbxKrnl/HLEIntercept.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CxbxKrnl/HLEIntercept.cpp b/src/CxbxKrnl/HLEIntercept.cpp index fc7517e3f..314610bc6 100644 --- a/src/CxbxKrnl/HLEIntercept.cpp +++ b/src/CxbxKrnl/HLEIntercept.cpp @@ -375,7 +375,7 @@ void EmuHLEIntercept(Xbe::Header *pXbeHeader) // 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, "DSOUND", 8) == 0) { + if (strncmp(SectionName, Lib_DSOUND, 8) == 0) { XbLibScan |= XbSymbolLib_DSOUND; break; } From 6dacd65a4047c95acc265c03cc86121b6d9dc3a2 Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Tue, 12 Jun 2018 13:09:38 -0500 Subject: [PATCH 27/30] Temporary check HLE cache file for LLE flags used. --- src/Cxbx/WndMain.cpp | 3 - src/CxbxKrnl/HLEIntercept.cpp | 157 +++++++++++++++++----------------- 2 files changed, 80 insertions(+), 80 deletions(-) diff --git a/src/Cxbx/WndMain.cpp b/src/Cxbx/WndMain.cpp index a927265b3..d82010b49 100644 --- a/src/Cxbx/WndMain.cpp +++ b/src/Cxbx/WndMain.cpp @@ -1320,7 +1320,6 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP case ID_EMULATION_LLE_JIT: { m_FlagsLLE = m_FlagsLLE ^ LLE_JIT; - ClearHLECache(); RefreshMenus(); } break; @@ -1328,7 +1327,6 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP case ID_EMULATION_LLE_APU: { m_FlagsLLE = m_FlagsLLE ^ LLE_APU; - ClearHLECache(); RefreshMenus(); } break; @@ -1336,7 +1334,6 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP case ID_EMULATION_LLE_GPU: { m_FlagsLLE = m_FlagsLLE ^ LLE_GPU; - ClearHLECache(); RefreshMenus(); } break; diff --git a/src/CxbxKrnl/HLEIntercept.cpp b/src/CxbxKrnl/HLEIntercept.cpp index 314610bc6..a29dd8bfb 100644 --- a/src/CxbxKrnl/HLEIntercept.cpp +++ b/src/CxbxKrnl/HLEIntercept.cpp @@ -383,6 +383,8 @@ void EmuHLEIntercept(Xbe::Header *pXbeHeader) } EmuUpdateLLEStatus(XbLibScan); + int gFlagsLLE; + g_EmuShared->GetFlagsLLE(&gFlagsLLE); printf("\n"); printf("*******************************************************************************\n"); @@ -422,84 +424,81 @@ void EmuHLEIntercept(Xbe::Header *pXbeHeader) if (HLECacheHash == XbSymbolLibraryVersion()) { char buffer[SHRT_MAX] = { 0 }; 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; + const uint32 cacheFlagsLLE = GetPrivateProfileInt("Info", "FlagsLLE", 0, filename.c_str()); + + if (cacheFlagsLLE != gFlagsLLE) { + 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 @@ -572,6 +571,10 @@ void EmuHLEIntercept(Xbe::Header *pXbeHeader) WritePrivateProfileString("Info", "HLECacheHash", HLECacheHashString.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 WritePrivateProfileString("Certificate", "Name", tAsciiTitle, filename.c_str()); From e12c45716053f56f95d9c2118f3d2adff63fffbf Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Tue, 12 Jun 2018 13:32:06 -0500 Subject: [PATCH 28/30] Add revision number to cache file. Also, it will enforce recreate cache file to prevent older cache breaking emulation. --- src/CxbxKrnl/HLEIntercept.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/CxbxKrnl/HLEIntercept.cpp b/src/CxbxKrnl/HLEIntercept.cpp index a29dd8bfb..368b9c466 100644 --- a/src/CxbxKrnl/HLEIntercept.cpp +++ b/src/CxbxKrnl/HLEIntercept.cpp @@ -350,6 +350,9 @@ void EmuUpdateLLEStatus(uint32_t XbLibScan) // NOTE: EmuHLEIntercept do not get to be in XbSymbolDatabase, do the intecept in Cxbx project only. 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; uint16 xdkVersion = 0; @@ -425,11 +428,16 @@ void EmuHLEIntercept(Xbe::Header *pXbeHeader) char buffer[SHRT_MAX] = { 0 }; char* bufferPtr = buffer; 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"); @@ -571,6 +579,11 @@ void EmuHLEIntercept(Xbe::Header *pXbeHeader) 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()); From c06177ea977ad2c2f5a291fe37d9e4b840a2a3c6 Mon Sep 17 00:00:00 2001 From: Luke Usher Date: Tue, 12 Jun 2018 20:07:27 +0100 Subject: [PATCH 29/30] Enable Scale Viewport and Host Backbuffer by default --- src/Cxbx/WndMain.cpp | 4 ++-- src/CxbxKrnl/CxbxKrnl.cpp | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Cxbx/WndMain.cpp b/src/Cxbx/WndMain.cpp index a927265b3..d12550eb5 100644 --- a/src/Cxbx/WndMain.cpp +++ b/src/Cxbx/WndMain.cpp @@ -222,13 +222,13 @@ WndMain::WndMain(HINSTANCE x_hInstance) : dwType = REG_DWORD; dwSize = sizeof(DWORD); result = RegQueryValueEx(hKey, "HackScaleViewport", NULL, &dwType, (PBYTE)&m_ScaleViewport, &dwSize); if (result != ERROR_SUCCESS) { - m_ScaleViewport = 0; + m_ScaleViewport = 1; } dwType = REG_DWORD; dwSize = sizeof(DWORD); result = RegQueryValueEx(hKey, "HackDirectBackBufferAccess", NULL, &dwType, (PBYTE)&m_DirectHostBackBufferAccess, &dwSize); if (result != ERROR_SUCCESS) { - m_DirectHostBackBufferAccess = 0; + m_DirectHostBackBufferAccess = 1; } diff --git a/src/CxbxKrnl/CxbxKrnl.cpp b/src/CxbxKrnl/CxbxKrnl.cpp index 0053cbc59..9c71d4e5d 100644 --- a/src/CxbxKrnl/CxbxKrnl.cpp +++ b/src/CxbxKrnl/CxbxKrnl.cpp @@ -603,12 +603,12 @@ void PrintCurrentConfigurationLog() // Print Enabled Hacks { printf("--------------------------- HACKS CONFIG ---------------------------\n"); - printf("Disable Pixel Shaders: %s\n", g_DisablePixelShaders == 1 ? "On" : "Off"); - printf("Uncap Framerate: %s\n", g_UncapFramerate == 1 ? "On" : "Off"); - printf("Run Xbox threads on all cores: %s\n", g_UseAllCores == 1 ? "On" : "Off"); - printf("Skip RDTSC Patching: %s\n", g_SkipRdtscPatching == 1 ? "On" : "Off"); - printf("Scale Xbox to host viewport (and back): %s\n", g_ScaleViewport == 1 ? "On" : "Off"); - printf("Render directly to Host BackBuffer: %s\n", g_DirectHostBackBufferAccess == 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 (Default)"); + 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 (Default)"); + printf("Scale Xbox to host viewport (and back): %s\n", g_ScaleViewport == 1 ? "On (Default)" : "Off"); + printf("Render directly to Host BackBuffer: %s\n", g_DirectHostBackBufferAccess == 1 ? "On (Default)" : "Off"); } printf("------------------------- END OF CONFIG LOG ------------------------\n"); From 380f3829799f9bd0eeb96704641c52ea60157345 Mon Sep 17 00:00:00 2001 From: Luke Usher Date: Wed, 13 Jun 2018 08:10:59 +0100 Subject: [PATCH 30/30] ScaleViewport to unstable for default --- src/Cxbx/WndMain.cpp | 2 +- src/CxbxKrnl/CxbxKrnl.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Cxbx/WndMain.cpp b/src/Cxbx/WndMain.cpp index d12550eb5..dbbe40ecc 100644 --- a/src/Cxbx/WndMain.cpp +++ b/src/Cxbx/WndMain.cpp @@ -222,7 +222,7 @@ WndMain::WndMain(HINSTANCE x_hInstance) : dwType = REG_DWORD; dwSize = sizeof(DWORD); result = RegQueryValueEx(hKey, "HackScaleViewport", NULL, &dwType, (PBYTE)&m_ScaleViewport, &dwSize); if (result != ERROR_SUCCESS) { - m_ScaleViewport = 1; + m_ScaleViewport = 0; } dwType = REG_DWORD; dwSize = sizeof(DWORD); diff --git a/src/CxbxKrnl/CxbxKrnl.cpp b/src/CxbxKrnl/CxbxKrnl.cpp index 9c71d4e5d..aff3266b4 100644 --- a/src/CxbxKrnl/CxbxKrnl.cpp +++ b/src/CxbxKrnl/CxbxKrnl.cpp @@ -607,7 +607,7 @@ void PrintCurrentConfigurationLog() 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 (Default)"); 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 (Default)" : "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 (Default)" : "Off"); }