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_XBVideo.Save("Software\\Cxbx-Reloaded\\XBVideo");
m_XBAudio.Save("Software\\Cxbx-Reloaded\\XBAudio");
}
}

View File

@ -39,84 +39,83 @@
#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 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

View File

@ -231,7 +231,7 @@ WndMain::WndMain(HINSTANCE x_hInstance) :
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;
}
@ -523,13 +523,13 @@ 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))
{
case WM_CREATE:
{
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;
@ -539,14 +539,14 @@ 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 = GetWindow(hwnd, GW_CHILD); // (HWND)HIWORD(wParam) seems to be NULL
m_hwndChild = GetWindow(hwnd, GW_CHILD);
UpdateCaption();
RefreshMenus();
}
else
{
else {
m_hwndChild = GetWindow(hwnd, GW_CHILD);
}
CreateThread(NULL, NULL, CrashMonitorWrapper, (void*)this, NULL, NULL); // create the crash monitoring thread
}
break;
@ -562,8 +562,20 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
}
}
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.
case WM_TIMER:
@ -1393,7 +1405,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;
@ -1401,7 +1412,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;
@ -1409,7 +1419,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;
@ -2282,6 +2291,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);
@ -2384,15 +2404,16 @@ 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
DWORD WINAPI WndMain::CrashMonitorWrapper(LPVOID lpVoid)
{
CxbxSetThreadName("Cxbx Crash Monitor");
static_cast<WndMain*>(lpVoid)->CrashMonitor();
return 0;
}
@ -2400,41 +2421,50 @@ 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);
// 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
{
CloseHandle(hCrashMutex);
return;
// 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);
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
{
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;
}
// Crash clean up.
// multi-xbe
// destroy this thread and start a new one
CloseHandle(hCrashMutex);
bQuickReboot = false;
g_EmuShared->SetMultiXbeFlag(&bQuickReboot);
return;
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
@ -2459,6 +2489,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);
@ -2466,17 +2497,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");
}
}

View File

@ -42,6 +42,7 @@ namespace xboxkrnl
#include <xboxkrnl/xboxkrnl.h>
};
#include "Cxbx\ResCxbx.h"
#include "CxbxKrnl.h"
#include "Cxbx\CxbxXbdm.h" // For Cxbx_LibXbdmThunkTable
#include "CxbxVersion.h"
@ -602,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" : "Off (Default)");
printf("Render directly to Host BackBuffer: %s\n", g_DirectHostBackBufferAccess == 1 ? "On (Default)" : "Off");
}
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());
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
{
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);
}
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);
}

View File

@ -67,14 +67,26 @@ 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();
// ******************************************************************
// * 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
// ******************************************************************
@ -199,20 +211,22 @@ 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;
bool m_bReady;
bool m_bEmulating;
int m_LedSequence[4];
int m_ScaleViewport;
int m_DirectHostBackBufferAccess;
int m_DirectHostBackBufferAccess;
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.
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;
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("* Cxbx-Reloaded High Level Emulation database\n");
@ -367,84 +427,86 @@ 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 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
@ -462,26 +524,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;
@ -533,6 +579,15 @@ 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());
// Write the Certificate Details to the cache file
WritePrivateProfileString("Certificate", "Name", tAsciiTitle, filename.c_str());