From 7538c4268a2e05f12cc526b88a3cfa07b1f19939 Mon Sep 17 00:00:00 2001 From: Aaron Robinson Date: Tue, 14 Sep 2004 07:23:35 +0000 Subject: [PATCH] HLE caching --- Cxbe.dsp | 4 +- Cxbx.dsp | 4 +- Cxbx.opt | Bin 62976 -> 62976 bytes CxbxKrnl.dsp | 10 +- Doc/Changelog.txt | 2 + Include/Win32/CxbxKrnl/Emu.h | 4 +- Include/Win32/CxbxKrnl/HLEDataBase.h | 5 + Include/Win32/CxbxKrnl/HLEIntercept.h | 39 ++ Source/Win32/CxbxKrnl/Emu.cpp | 569 +++------------------ Source/Win32/CxbxKrnl/EmuKrnl.cpp | 33 +- Source/Win32/CxbxKrnl/HLEDataBase.cpp | 2 + Source/Win32/CxbxKrnl/HLEIntercept.cpp | 676 +++++++++++++++++++++++++ 12 files changed, 833 insertions(+), 515 deletions(-) create mode 100644 Include/Win32/CxbxKrnl/HLEIntercept.h create mode 100644 Source/Win32/CxbxKrnl/HLEIntercept.cpp diff --git a/Cxbe.dsp b/Cxbe.dsp index 59491cee7..5b126cb06 100644 --- a/Cxbe.dsp +++ b/Cxbe.dsp @@ -42,7 +42,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /W3 /O2 /I "Include" /I "Include/Core/" /I "Include/Standard" /I "Include/Standard/Cxbe" /I "Include/Win32/" /I "Include/Win32/CxbxKrnl/" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "Include" /I "Include/Core/" /I "Include/Standard" /I "Include/Standard/Cxbe" /I "Include/Win32/" /I "Include/Win32/CxbxKrnl/" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe @@ -67,7 +67,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /W3 /Gm /Zi /Od /I "Include" /I "Include/Core/" /I "Include/Standard" /I "Include/Standard/Cxbe" /I "Include/Win32/" /I "Include/Win32/CxbxKrnl/" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I "Include" /I "Include/Core/" /I "Include/Standard" /I "Include/Standard/Cxbe" /I "Include/Win32/" /I "Include/Win32/CxbxKrnl/" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c # SUBTRACT CPP /Fr # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" diff --git a/Cxbx.dsp b/Cxbx.dsp index e0151eb06..f96613652 100644 --- a/Cxbx.dsp +++ b/Cxbx.dsp @@ -43,7 +43,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /Zi /O2 /I "Include" /I "Include/Core/" /I "Include/Win32/" /I "Include/Win32/Cxbxkrnl" /I "Include/Win32/Cxbx" /I "Include/Win32/Cxbx/jpegdec" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Fr /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /Zi /O2 /I "Include" /I "Include/Core/" /I "Include/Win32/" /I "Include/Win32/Cxbxkrnl" /I "Include/Win32/Cxbx" /I "Include/Win32/Cxbx/jpegdec" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Fr /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" @@ -74,7 +74,7 @@ PostBuild_Cmds=cd PostBuild upxCxbx.bat # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /Zi /Od /I "Include" /I "Include/Core/" /I "Include/Win32/" /I "Include/Win32/Cxbxkrnl" /I "Include/Win32/Cxbx" /I "Include/Win32/Cxbx/jpegdec" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Fr /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "Include" /I "Include/Core/" /I "Include/Win32/" /I "Include/Win32/Cxbxkrnl" /I "Include/Win32/Cxbx" /I "Include/Win32/Cxbx/jpegdec" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Fr /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" diff --git a/Cxbx.opt b/Cxbx.opt index 8af6a7b675e8649e0fcb09cbb3509dcd07393ea4..54c5e8b8114351600abb8b7f6446a30ddc6c3ac4 100644 GIT binary patch literal 62976 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 Y;bnmJzeeA&{>S=XV>C3MZB+g5|Gz^%SpWb4 literal 62976 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.h +// * +// * This file is part of the Cxbx project. +// * +// * Cxbx and Cxbe are free software; you can redistribute them +// * and/or modify them under the terms of the GNU General Public +// * License as published by the Free Software Foundation; either +// * version 2 of the license, or (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have recieved a copy of the GNU General Public License +// * along with this program; see the file COPYING. +// * If not, write to the Free Software Foundation, Inc., +// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA. +// * +// * (c) 2002-2003 Aaron Robinson +// * +// * All rights reserved +// * +// ****************************************************************** +#ifndef HLEINTERCEPT_H +#define HLEINTERCEPT_H + +extern "C" void EmuHLEIntercept(Xbe::LibraryVersion *LibraryVersion, Xbe::Header *XbeHeader); + +#endif diff --git a/Source/Win32/CxbxKrnl/Emu.cpp b/Source/Win32/CxbxKrnl/Emu.cpp index 2b3e09f0f..377d65d1e 100644 --- a/Source/Win32/CxbxKrnl/Emu.cpp +++ b/Source/Win32/CxbxKrnl/Emu.cpp @@ -54,29 +54,28 @@ namespace NtDll #include "EmuXTL.h" #include "EmuShared.h" #include "HLEDataBase.h" +#include "HLEIntercept.h" +#include #include // Global Variable(s) Xbe::TLS *g_pTLS = NULL; void *g_pTLSData = NULL; Xbe::Header *g_pXbeHeader = NULL; -HANDLE g_hCurDir = NULL; +HANDLE g_hCurDir = NULL; HANDLE g_hTDrive = NULL; HANDLE g_hUDrive = NULL; HANDLE g_hZDrive = NULL; -volatile BOOL g_bEmuSuspended = FALSE; -volatile BOOL g_bEmuException = FALSE; +volatile bool g_bEmuException = false; +volatile bool g_bEmuSuspended = false; volatile bool g_bPrintfOn = true; // global exception patching address uint32 g_HaloHack[4] = {0}; // Static Function(s) -static void *EmuLocateFunction(OOVPA *Oovpa, uint32 lower, uint32 upper); -static void EmuInstallWrappers(OOVPATable *OovpaTable, uint32 OovpaTableSize, void (*Entry)(), Xbe::Header *pXbeHeader); -static void EmuXRefFailure(); -static int ExitException(LPEXCEPTION_POINTERS e); +static int ExitException(LPEXCEPTION_POINTERS e); // Static Variable(s) static HANDLE g_hThreads[MAXIMUM_XBOX_THREADS] = {0}; @@ -150,7 +149,7 @@ extern "C" CXBXKRNL_API void NTAPI EmuInit g_pXbeHeader = pXbeHeader; g_hEmuParent = IsWindow(hwndParent) ? hwndParent : NULL; - // For Unicode Conversions + // for unicode conversions setlocale(LC_ALL, "English"); // debug console allocation (if configured) @@ -188,7 +187,10 @@ extern "C" CXBXKRNL_API void NTAPI EmuInit freopen("nul", "w", stdout); } + // // debug trace + // + { #ifdef _DEBUG_TRACE printf("EmuMain (0x%X): Debug Trace Enabled.\n", GetCurrentThreadId()); @@ -212,7 +214,10 @@ extern "C" CXBXKRNL_API void NTAPI EmuInit #endif } + // // load the necessary pieces of XbeHeader + // + { Xbe::Header *MemXbeHeader = (Xbe::Header*)0x00010000; @@ -231,7 +236,10 @@ extern "C" CXBXKRNL_API void NTAPI EmuInit memcpy((void*)pXbeHeader->dwCertificateAddr, &((uint08*)pXbeHeader)[pXbeHeader->dwCertificateAddr - 0x00010000], sizeof(Xbe::Certificate)); } + // // initialize current directory + // + { char szBuffer[260]; @@ -250,37 +258,49 @@ extern "C" CXBXKRNL_API void NTAPI EmuInit DbgPrintf("EmuMain (0x%X): CurDir := %s\n", GetCurrentThreadId(), szBuffer); } - // initialize T:\ and U:\ directories + // + // initialize EmuDisk + // + { char szBuffer[260]; - #ifdef _DEBUG - GetModuleFileName(GetModuleHandle("CxbxKrnl.dll"), szBuffer, 260); - #else - GetModuleFileName(GetModuleHandle("Cxbx.dll"), szBuffer, 260); - #endif + SHGetSpecialFolderPath(NULL, szBuffer, CSIDL_APPDATA, TRUE); + + strcat(szBuffer, "\\Cxbx\\"); + + CreateDirectory(szBuffer, NULL); + + sint32 spot = -1; - sint32 spot=-1; for(int v=0;v<260;v++) { - if(szBuffer[v] == '\\') - spot = v; - else if(szBuffer[v] == '\0') - break; + if(szBuffer[v] == '\\') { spot = v; } + else if(szBuffer[v] == '\0') { break; } } - if(spot != -1) - szBuffer[spot] = '\0'; + if(spot != -1) { szBuffer[spot] = '\0'; } Xbe::Certificate *pCertificate = (Xbe::Certificate*)pXbeHeader->dwCertificateAddr; - // Create TData Directory + // + // create EmuDisk directory + // + + strcpy(&szBuffer[spot], "\\EmuDisk"); + + CreateDirectory(szBuffer, NULL); + + // + // create T:\ directory + // + { - strcpy(&szBuffer[spot], "\\TDATA"); + strcpy(&szBuffer[spot], "\\EmuDisk\\T"); CreateDirectory(szBuffer, NULL); - sprintf(&szBuffer[spot+6], "\\%08x", pCertificate->dwTitleId); + sprintf(&szBuffer[spot+10], "\\%08x", pCertificate->dwTitleId); CreateDirectory(szBuffer, NULL); @@ -292,13 +312,16 @@ extern "C" CXBXKRNL_API void NTAPI EmuInit DbgPrintf("EmuMain (0x%X): T Data := %s\n", GetCurrentThreadId(), szBuffer); } - // Create UData Directory + // + // create U:\ directory + // + { - strcpy(&szBuffer[spot], "\\UDATA"); + strcpy(&szBuffer[spot], "\\EmuDisk\\U"); CreateDirectory(szBuffer, NULL); - sprintf(&szBuffer[spot+6], "\\%08x", pCertificate->dwTitleId); + sprintf(&szBuffer[spot+10], "\\%08x", pCertificate->dwTitleId); CreateDirectory(szBuffer, NULL); @@ -310,9 +333,12 @@ extern "C" CXBXKRNL_API void NTAPI EmuInit DbgPrintf("EmuMain (0x%X): U Data := %s\n", GetCurrentThreadId(), szBuffer); } - // Create ZData Directory + // + // create Z:\ directory + // + { - strcpy(&szBuffer[spot], "\\CxbxCache"); + strcpy(&szBuffer[spot], "\\EmuDisk\\Z"); CreateDirectory(szBuffer, NULL); @@ -331,14 +357,20 @@ extern "C" CXBXKRNL_API void NTAPI EmuInit } } - // initialize FS segment selector emulation + // + // initialize FS segment selector + // + { EmuInitFS(); EmuGenerateFS(pTLS, pTLSData); } - // we must duplicate this handle in order to retain Suspend/Resume thread rights from a remote thread + // + // duplicate handle in order to retain Suspend/Resume thread rights from a remote thread + // + { HANDLE hDupHandle = NULL; @@ -351,274 +383,14 @@ extern "C" CXBXKRNL_API void NTAPI EmuInit XTL::EmuD3DInit(pXbeHeader, dwXbeHeaderSize); - // initialize OpenXDK emulation (non-existant for now at least) - if(pLibraryVersion == 0) - DbgPrintf("EmuMain (0x%X): Detected OpenXDK application...\n", GetCurrentThreadId()); - - // initialize Microsoft XDK emulation - if(pLibraryVersion != 0) - { - DbgPrintf("EmuMain (0x%X): Detected Microsoft XDK application...\n", GetCurrentThreadId()); - - uint32 dwLibraryVersions = pXbeHeader->dwLibraryVersions; - uint32 dwHLEEntries = HLEDataBaseSize/sizeof(HLEData); - - uint32 LastUnResolvedXRefs = UnResolvedXRefs+1; - uint32 OrigUnResolvedXRefs = UnResolvedXRefs; - - for(int p=0;UnResolvedXRefs < LastUnResolvedXRefs;p++) - { - DbgPrintf("EmuMain (0x%X): Beginning HLE Pass %d...\n", GetCurrentThreadId(), p); - - LastUnResolvedXRefs = UnResolvedXRefs; - - bool bFoundD3D = false; - for(uint32 v=0;vdwBaseAddr; - uint32 upper = pXbeHeader->dwBaseAddr + pXbeHeader->dwSizeofImage; - - // locate XapiProcessHeap - { - void *pFunc = 0; - uint ProcessHeapOffs; - uint RtlCreateHeapOffs; - - if(BuildVersion >= 5849) - { - pFunc = EmuLocateFunction((OOVPA*)&XapiInitProcess_1_0_5849, lower, upper); - ProcessHeapOffs = 0x51; - RtlCreateHeapOffs = 0x4A; - } - else if(BuildVersion >= 5558) - { - pFunc = EmuLocateFunction((OOVPA*)&XapiInitProcess_1_0_5558, lower, upper); - - // 5659 has an updated function - if(pFunc == 0) - { - pFunc = EmuLocateFunction((OOVPA*)&XapiInitProcess_1_0_5659, lower, upper); - } - - ProcessHeapOffs = 0x51; - RtlCreateHeapOffs = 0x4A; - } - else if(BuildVersion >= 4361) - { - if(OrigBuildVersion == 4928) - { - pFunc = EmuLocateFunction((OOVPA*)&XapiInitProcess_1_0_4928, lower, upper); - ProcessHeapOffs = 0x44; - RtlCreateHeapOffs = 0x3B; - } - else - { - pFunc = EmuLocateFunction((OOVPA*)&XapiInitProcess_1_0_4361, lower, upper); - ProcessHeapOffs = 0x3E; - RtlCreateHeapOffs = 0x37; - } - } - else // 3911, 4034, 4134 - { - pFunc = EmuLocateFunction((OOVPA*)&XapiInitProcess_1_0_3911, lower, upper); - ProcessHeapOffs = 0x3E; - RtlCreateHeapOffs = 0x37; - } - - if(pFunc != 0) - { - XTL::EmuXapiProcessHeap = *(PVOID**)((uint32)pFunc + ProcessHeapOffs); - - XTL::g_pRtlCreateHeap = *(XTL::pfRtlCreateHeap*)((uint32)pFunc + RtlCreateHeapOffs); - XTL::g_pRtlCreateHeap = (XTL::pfRtlCreateHeap)((uint32)pFunc + (uint32)XTL::g_pRtlCreateHeap + RtlCreateHeapOffs + 0x04); - - DbgPrintf("EmuMain (0x%X): 0x%.08X -> EmuXapiProcessHeap\n", GetCurrentThreadId(), XTL::EmuXapiProcessHeap); - DbgPrintf("EmuMain (0x%X): 0x%.08X -> g_pRtlCreateHeap\n", GetCurrentThreadId(), XTL::g_pRtlCreateHeap); - } - } - } - else if(strcmp("D3D8", szLibraryName) == 0 && MajorVersion == 1 && MinorVersion == 0 && - (BuildVersion == 3925 || BuildVersion == 4134 || BuildVersion == 4361 || BuildVersion == 4432 - || BuildVersion == 4627 || BuildVersion == 5558 || BuildVersion == 5849)) - { - uint32 lower = pXbeHeader->dwBaseAddr; - uint32 upper = pXbeHeader->dwBaseAddr + pXbeHeader->dwSizeofImage; - - void *pFunc = 0; - - if(BuildVersion == 3925) - pFunc = EmuLocateFunction((OOVPA*)&IDirect3DDevice8_SetRenderState_CullMode_1_0_3925, lower, upper); - else if(BuildVersion < 5558) - pFunc = EmuLocateFunction((OOVPA*)&IDirect3DDevice8_SetRenderState_CullMode_1_0_4134, lower, upper); - else - pFunc = EmuLocateFunction((OOVPA*)&IDirect3DDevice8_SetRenderState_CullMode_1_0_5558, lower, upper); - - // locate D3DDeferredRenderState - if(pFunc != 0) - { - // offset for stencil cull enable render state in the deferred render state buffer - int patchOffset = 0; - - if(BuildVersion == 3925) - { - XTL::EmuD3DDeferredRenderState = (DWORD*)(*(DWORD*)((uint32)pFunc + 0x25) - 0x19F + 72*4); // TODO: Clean up (?) - patchOffset = 142*4 - 72*4; // TODO: Verify - } - else if(BuildVersion == 4134) - { - XTL::EmuD3DDeferredRenderState = (DWORD*)(*(DWORD*)((uint32)pFunc + 0x2B) - 0x248 + 82*4); // TODO: Verify - patchOffset = 142*4 - 82*4; - } - else if(BuildVersion == 4361) - { - XTL::EmuD3DDeferredRenderState = (DWORD*)(*(DWORD*)((uint32)pFunc + 0x2B) - 0x200 + 82*4); - patchOffset = 142*4 - 82*4; - } - else if(BuildVersion == 4432) - { - XTL::EmuD3DDeferredRenderState = (DWORD*)(*(DWORD*)((uint32)pFunc + 0x2B) - 0x204 + 83*4); - patchOffset = 143*4 - 83*4; - } - else if(BuildVersion == 4627) - { - XTL::EmuD3DDeferredRenderState = (DWORD*)(*(DWORD*)((uint32)pFunc + 0x2B) - 0x24C + 92*4); - patchOffset = 162*4 - 92*4; - } - else if(BuildVersion == 5558 || BuildVersion == 5849) - { - // WARNING: Not thoroughly tested (just seemed very correct right away) - XTL::EmuD3DDeferredRenderState = (DWORD*)(*(DWORD*)((uint32)pFunc + 0x2B) - 0x24C + 92*4); - patchOffset = 162*4 - 92*4; - } - - XRefDataBase[XREF_D3DDEVICE] = *(DWORD*)((DWORD)pFunc + 0x03); - XRefDataBase[XREF_D3DRS_STENCILCULLENABLE] = (uint32)XTL::EmuD3DDeferredRenderState + patchOffset + 0*4; - XRefDataBase[XREF_D3DRS_ROPZCMPALWAYSREAD] = (uint32)XTL::EmuD3DDeferredRenderState + patchOffset + 1*4; - XRefDataBase[XREF_D3DRS_ROPZREAD] = (uint32)XTL::EmuD3DDeferredRenderState + patchOffset + 2*4; - XRefDataBase[XREF_D3DRS_DONOTCULLUNCOMPRESSED] = (uint32)XTL::EmuD3DDeferredRenderState + patchOffset + 3*4; - - for(int v=0;v<44;v++) - XTL::EmuD3DDeferredRenderState[v] = X_D3DRS_UNK; - - DbgPrintf("EmuMain (0x%X): 0x%.08X -> EmuD3DDeferredRenderState\n", GetCurrentThreadId(), XTL::EmuD3DDeferredRenderState); - } - else - { - XTL::EmuD3DDeferredRenderState = 0; - EmuWarning("EmuD3DDeferredRenderState was not found!"); - } - - // locate D3DDeferredTextureState - { - pFunc = 0; - - if(BuildVersion == 3925) - pFunc = EmuLocateFunction((OOVPA*)&IDirect3DDevice8_SetTextureState_TexCoordIndex_1_0_3925, lower, upper); - else if(BuildVersion == 4134) - pFunc = EmuLocateFunction((OOVPA*)&IDirect3DDevice8_SetTextureState_TexCoordIndex_1_0_4134, lower, upper); - else if(BuildVersion == 4361 || BuildVersion == 4432) - pFunc = EmuLocateFunction((OOVPA*)&IDirect3DDevice8_SetTextureState_TexCoordIndex_1_0_4361, lower, upper); - else if(BuildVersion == 4627 || BuildVersion == 5558 || BuildVersion == 5849) - pFunc = EmuLocateFunction((OOVPA*)&IDirect3DDevice8_SetTextureState_TexCoordIndex_1_0_4627, lower, upper); - - if(pFunc != 0) - { - if(BuildVersion == 3925) // 0x18F180 - XTL::EmuD3DDeferredTextureState = (DWORD*)(*(DWORD*)((uint32)pFunc + 0x11) - 0x70); // TODO: Verify - else if(BuildVersion == 4134) - XTL::EmuD3DDeferredTextureState = (DWORD*)(*(DWORD*)((uint32)pFunc + 0x18) - 0x70); // TODO: Verify - else - XTL::EmuD3DDeferredTextureState = (DWORD*)(*(DWORD*)((uint32)pFunc + 0x19) - 0x70); - - for(int s=0;s<4;s++) - { - for(int v=0;v<32;v++) - XTL::EmuD3DDeferredTextureState[v+s*32] = X_D3DTSS_UNK; - } - - DbgPrintf("EmuMain (0x%X): 0x%.08X -> EmuD3DDeferredTextureState\n", GetCurrentThreadId(), XTL::EmuD3DDeferredTextureState); - } - else - { - XTL::EmuD3DDeferredTextureState = 0; - EmuCleanup("EmuD3DDeferredTextureState was not found!"); - } - } - } - } - - DbgPrintf("EmuMain (0x%X): Locating HLE Information for %s %d.%d.%d...", GetCurrentThreadId(), pLibraryVersion[v].szName, MajorVersion, MinorVersion, BuildVersion); - - bool found=false; - - for(uint32 d=0;dCount; - - // Skip out if this is an unnecessary search - if(!bXRefFirstPass && Oovpa->XRefCount == 0 && Oovpa->XRefSaveIndex == (uint08)-1) - return 0; - - // large - if(Oovpa->Large == 1) - { - LOOVPA<1> *Loovpa = (LOOVPA<1>*)Oovpa; - - upper -= Loovpa->Lovp[count-1].Offset; - - // search all of the image memory - for(uint32 cur=lower;curXRefCount;v++) - { - uint32 Offset = Loovpa->Lovp[v].Offset; - uint32 Value = Loovpa->Lovp[v].Value; - - uint32 RealValue = *(uint32*)(cur + Offset); - - if(XRefDataBase[Value] == -1) - goto skipout_L; // unsatisfied Xref is not acceptable - - if((RealValue + cur + Offset+4 != XRefDataBase[Value]) && (RealValue != XRefDataBase[Value])) - break; - } - - // check all pairs, moving on if any do not match - for(v=0;vLovp[v].Offset; - uint32 Value = Loovpa->Lovp[v].Value; - - uint08 RealValue = *(uint08*)(cur + Offset); - - if(RealValue != Value) - break; - } - - // success if we found all pairs - if(v == count) - { - if(Loovpa->XRefSaveIndex != (uint08)-1) - { - if(XRefDataBase[Loovpa->XRefSaveIndex] == -1) - { - UnResolvedXRefs--; - XRefDataBase[Loovpa->XRefSaveIndex] = cur; - - return (void*)cur; - } - else - { - return (void*)XRefDataBase[Loovpa->XRefSaveIndex]; // already Found, no bother patching again - } - } - - return (void*)cur; - } - - skipout_L:; - } - } - // small - else - { - SOOVPA<1> *Soovpa = (SOOVPA<1>*)Oovpa; - - upper -= Soovpa->Sovp[count-1].Offset; - - // search all of the image memory - for(uint32 cur=lower;curXRefCount;v++) - { - uint32 Offset = Soovpa->Sovp[v].Offset; - uint32 Value = Soovpa->Sovp[v].Value; - - uint32 RealValue = *(uint32*)(cur + Offset); - - if(XRefDataBase[Value] == -1) - goto skipout_S; // Unsatisfied XRef is not acceptable - - if( (RealValue + cur + Offset + 4 != XRefDataBase[Value]) && (RealValue != XRefDataBase[Value])) - break; - } - - // check OV pairs if all xrefs matched - if(v == Soovpa->XRefCount) - { - // check all pairs, moving on if any do not match - for(;vSovp[v].Offset; - uint32 Value = Soovpa->Sovp[v].Value; - - uint08 RealValue = *(uint08*)(cur + Offset); - - if(RealValue != Value) - break; - } - } - - // success if we found all pairs - if(v == count) - { - if(Soovpa->XRefSaveIndex != (uint08)-1) - { - if(XRefDataBase[Soovpa->XRefSaveIndex] == -1) - { - UnResolvedXRefs--; - XRefDataBase[Soovpa->XRefSaveIndex] = cur; - - return (void*)cur; - } - else - { - return (void*)XRefDataBase[Soovpa->XRefSaveIndex]; // already Found, no bother patching again - } - } - - return (void*)cur; - } - - skipout_S:; - } - } - - return 0; -} - -// install function interception wrappers -static void EmuInstallWrappers(OOVPATable *OovpaTable, uint32 OovpaTableSize, void (*Entry)(), Xbe::Header *pXbeHeader) -{ - uint32 lower = pXbeHeader->dwBaseAddr; - uint32 upper = pXbeHeader->dwBaseAddr + pXbeHeader->dwSizeofImage; - - // traverse the full OOVPA table - for(uint32 a=0;a %s\n", GetCurrentThreadId(), pFunc, OovpaTable[a].szFuncName); - #endif - - if(OovpaTable[a].lpRedirect == 0) - { - EmuInstallWrapper(pFunc, EmuXRefFailure); - } - else - { - EmuInstallWrapper(pFunc, OovpaTable[a].lpRedirect); - } - } - } -} - -// alert for the situation where an Xref function body is hit -static void EmuXRefFailure() -{ - EmuSwapFS(); // Win2k/XP FS - - EmuCleanup("XRef-only function body reached. Fatal Error."); -} - // exception handle for that tough final exit :) int ExitException(LPEXCEPTION_POINTERS e) { diff --git a/Source/Win32/CxbxKrnl/EmuKrnl.cpp b/Source/Win32/CxbxKrnl/EmuKrnl.cpp index cae88c036..7e1d1662a 100644 --- a/Source/Win32/CxbxKrnl/EmuKrnl.cpp +++ b/Source/Win32/CxbxKrnl/EmuKrnl.cpp @@ -1156,6 +1156,8 @@ XBSYSAPI EXPORTNUM(190) NTSTATUS NTAPI xboxkrnl::NtCreateFile if(szBuffer != NULL) { + //printf("Orig : %s\n", szBuffer); + // trim this off if(szBuffer[0] == '\\' && szBuffer[1] == '?' && szBuffer[2] == '?' && szBuffer[3] == '\\') { @@ -1181,7 +1183,7 @@ XBSYSAPI EXPORTNUM(190) NTSTATUS NTAPI xboxkrnl::NtCreateFile DbgPrintf("EmuKrnl (0x%X): NtCreateFile Corrected path...\n", GetCurrentThreadId()); DbgPrintf(" Org:\"%s\"\n", ObjectAttributes->ObjectName->Buffer); - DbgPrintf(" New:\"$CxbxPath\\TDATA\\%s\"\n", szBuffer); + DbgPrintf(" New:\"$CxbxPath\\EmuDisk\\T\\%s\"\n", szBuffer); } else if( (szBuffer[0] == 'U' || szBuffer[0] == 'u') && szBuffer[1] == ':' && szBuffer[2] == '\\') { @@ -1191,7 +1193,7 @@ XBSYSAPI EXPORTNUM(190) NTSTATUS NTAPI xboxkrnl::NtCreateFile DbgPrintf("EmuKrnl (0x%X): NtCreateFile Corrected path...\n", GetCurrentThreadId()); DbgPrintf(" Org:\"%s\"\n", ObjectAttributes->ObjectName->Buffer); - DbgPrintf(" New:\"$CxbxPath\\UDATA\\%s\"\n", szBuffer); + DbgPrintf(" New:\"$CxbxPath\\EmuDisk\\U\\%s\"\n", szBuffer); } else if( (szBuffer[0] == 'Z' || szBuffer[0] == 'z') && szBuffer[1] == ':' && szBuffer[2] == '\\') { @@ -1201,29 +1203,32 @@ XBSYSAPI EXPORTNUM(190) NTSTATUS NTAPI xboxkrnl::NtCreateFile DbgPrintf("EmuKrnl (0x%X): NtCreateFile Corrected path...\n", GetCurrentThreadId()); DbgPrintf(" Org:\"%s\"\n", ObjectAttributes->ObjectName->Buffer); - DbgPrintf(" New:\"$CxbxPath\\CxbxCache\\%s\"\n", szBuffer); + DbgPrintf(" New:\"$CxbxPath\\EmuDisk\\Z\\%s\"\n", szBuffer); } + // // TODO: Wildcards are not allowed?? + // + { for(int v=0;szBuffer[v] != '\0';v++) { if(szBuffer[v] == '*') { - if(v > 0) - ReplaceIndex = v-1; - else - ReplaceIndex = v; + if(v > 0) { ReplaceIndex = v-1; } + else { ReplaceIndex = v; } } } - - // Note: Hack: Not thread safe (if problems occur, create a temp buffer) - if(ReplaceIndex != -1) - { - ReplaceChar = szBuffer[ReplaceIndex]; - szBuffer[ReplaceIndex] = '\0'; - } } + + // Note: Hack: Not thread safe (if problems occur, create a temp buffer) + if(ReplaceIndex != -1) + { + ReplaceChar = szBuffer[ReplaceIndex]; + szBuffer[ReplaceIndex] = '\0'; + } + + //printf("Aftr : %s\n", szBuffer); } wchar_t wszObjectName[160]; diff --git a/Source/Win32/CxbxKrnl/HLEDataBase.cpp b/Source/Win32/CxbxKrnl/HLEDataBase.cpp index e59f53495..049c92ec1 100644 --- a/Source/Win32/CxbxKrnl/HLEDataBase.cpp +++ b/Source/Win32/CxbxKrnl/HLEDataBase.cpp @@ -37,6 +37,8 @@ #undef FIELD_OFFSET // prevent macro redefinition warnings #include +extern "C" const char *szHLELastCompileTime = __TIMESTAMP__; + #include "Emu.h" #include "EmuXTL.h" #include "HLEDataBase.h" diff --git a/Source/Win32/CxbxKrnl/HLEIntercept.cpp b/Source/Win32/CxbxKrnl/HLEIntercept.cpp new file mode 100644 index 000000000..70ee9432d --- /dev/null +++ b/Source/Win32/CxbxKrnl/HLEIntercept.cpp @@ -0,0 +1,676 @@ +// ****************************************************************** +// * +// * .,-::::: .,:: .::::::::. .,:: .: +// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;; +// * [[[ '[[,,[[' [[[__[[\. '[[,,[[' +// * $$$ Y$$$P $$""""Y$$ Y$$$P +// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo, +// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm, +// * +// * Cxbx->Win32->CxbxKrnl->HLEIntercept.cpp +// * +// * This file is part of the Cxbx project. +// * +// * Cxbx and Cxbe are free software; you can redistribute them +// * and/or modify them under the terms of the GNU General Public +// * License as published by the Free Software Foundation; either +// * version 2 of the license, or (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have recieved a copy of the GNU General Public License +// * along with this program; see the file COPYING. +// * If not, write to the Free Software Foundation, Inc., +// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA. +// * +// * (c) 2002-2003 Aaron Robinson +// * +// * All rights reserved +// * +// ****************************************************************** +#define _CXBXKRNL_INTERNAL + +#include "Emu.h" +#include "EmuFS.h" +#include "EmuXTL.h" +#include "EmuShared.h" +#include "HLEDataBase.h" +#include "HLEIntercept.h" + +static void *EmuLocateFunction(OOVPA *Oovpa, uint32 lower, uint32 upper); +static void EmuInstallWrappers(OOVPATable *OovpaTable, uint32 OovpaTableSize, Xbe::Header *pXbeHeader); +static void EmuXRefFailure(); + +#include + +#include + +static std::vector vCacheOut; + +static bool bCacheInp = false; +static std::vector vCacheInp; +static std::vector::const_iterator vCacheInpIter; + +extern "C" void EmuHLEIntercept +( + Xbe::LibraryVersion *pLibraryVersion, + Xbe::Header *pXbeHeader +) +{ + Xbe::Certificate *pCertificate = (Xbe::Certificate*)pXbeHeader->dwCertificateAddr; + + char szCacheFileName[260]; + + DbgPrintf("\n"); + DbgPrintf("*******************************************************************************\n"); + DbgPrintf("* Cxbx High Level Emulation database last modified %s\n", szHLELastCompileTime); + DbgPrintf("*******************************************************************************\n"); + DbgPrintf("\n"); + + // + // initialize HLE cache file + // + + { + SHGetSpecialFolderPath(NULL, szCacheFileName, CSIDL_APPDATA, TRUE); + + strcat(szCacheFileName, "\\Cxbx\\"); + + CreateDirectory(szCacheFileName, NULL); + + sint32 spot = -1; + + for(int v=0;v<260;v++) + { + if(szCacheFileName[v] == '\\') { spot = v; } + else if(szCacheFileName[v] == '\0') { break; } + } + + if(spot != -1) { szCacheFileName[spot] = '\0'; } + + // + // create HLECache directory + // + + strcpy(&szCacheFileName[spot], "\\HLECache"); + + CreateDirectory(szCacheFileName, NULL); + + // + // open title's cache file + // + + sprintf(&szCacheFileName[spot+9], "\\%08x.dat", pCertificate->dwTitleId); + + FILE *pCacheFile = fopen(szCacheFileName, "rb"); + + if(pCacheFile != NULL) + { + bool bVerified = false; + + // + // verify last compiled timestamp + // + + char szCacheLastCompileTime[64]; + + memset(szCacheLastCompileTime, 0, 64); + + if(fread(szCacheLastCompileTime, 64, 1, pCacheFile) == 1) + { + if(strcmp(szCacheLastCompileTime, szHLELastCompileTime) == 0) + { + bVerified = true; + } + } + + // + // load function addresses + // + + if(bVerified) + { + while(true) + { + void *cur; + + if(fread(&cur, 4, 1, pCacheFile) != 1) + break; + + vCacheInp.push_back(cur); + } + + bCacheInp = true; + + vCacheInpIter = vCacheInp.begin(); + + DbgPrintf("HLE: Loaded HLE Cache for 0x%.08X\n", pCertificate->dwTitleId); + } + + fclose(pCacheFile); + } + } + + // + // initialize openxdk emulation (TODO) + // + + if(pLibraryVersion == 0) + { + DbgPrintf("HLE: Detected OpenXDK application...\n"); + } + + // + // initialize Microsoft XDK emulation + // + + if(pLibraryVersion != 0) + { + DbgPrintf("HLE: Detected Microsoft XDK application...\n"); + + uint32 dwLibraryVersions = pXbeHeader->dwLibraryVersions; + uint32 dwHLEEntries = HLEDataBaseSize / sizeof(HLEData); + + uint32 LastUnResolvedXRefs = UnResolvedXRefs+1; + uint32 OrigUnResolvedXRefs = UnResolvedXRefs; + + for(int p=0;UnResolvedXRefs < LastUnResolvedXRefs;p++) + { + DbgPrintf("HLE: Starting pass #%d...\n", p+1); + + LastUnResolvedXRefs = UnResolvedXRefs; + + bool bFoundD3D = false; + for(uint32 v=0;vdwBaseAddr; + uint32 upper = pXbeHeader->dwBaseAddr + pXbeHeader->dwSizeofImage; + + // locate XapiProcessHeap + { + void *pFunc = 0; + uint ProcessHeapOffs; + uint RtlCreateHeapOffs; + + if(BuildVersion >= 5849) + { + pFunc = EmuLocateFunction((OOVPA*)&XapiInitProcess_1_0_5849, lower, upper); + ProcessHeapOffs = 0x51; + RtlCreateHeapOffs = 0x4A; + } + else if(BuildVersion >= 5558) + { + pFunc = EmuLocateFunction((OOVPA*)&XapiInitProcess_1_0_5558, lower, upper); + + // 5659 has an updated function + if(pFunc == 0) + { + pFunc = EmuLocateFunction((OOVPA*)&XapiInitProcess_1_0_5659, lower, upper); + } + + ProcessHeapOffs = 0x51; + RtlCreateHeapOffs = 0x4A; + } + else if(BuildVersion >= 4361) + { + if(OrigBuildVersion == 4928) + { + pFunc = EmuLocateFunction((OOVPA*)&XapiInitProcess_1_0_4928, lower, upper); + ProcessHeapOffs = 0x44; + RtlCreateHeapOffs = 0x3B; + } + else + { + pFunc = EmuLocateFunction((OOVPA*)&XapiInitProcess_1_0_4361, lower, upper); + ProcessHeapOffs = 0x3E; + RtlCreateHeapOffs = 0x37; + } + } + else // 3911, 4034, 4134 + { + pFunc = EmuLocateFunction((OOVPA*)&XapiInitProcess_1_0_3911, lower, upper); + ProcessHeapOffs = 0x3E; + RtlCreateHeapOffs = 0x37; + } + + if(pFunc != 0) + { + XTL::EmuXapiProcessHeap = *(PVOID**)((uint32)pFunc + ProcessHeapOffs); + + XTL::g_pRtlCreateHeap = *(XTL::pfRtlCreateHeap*)((uint32)pFunc + RtlCreateHeapOffs); + XTL::g_pRtlCreateHeap = (XTL::pfRtlCreateHeap)((uint32)pFunc + (uint32)XTL::g_pRtlCreateHeap + RtlCreateHeapOffs + 0x04); + + DbgPrintf("HLE: 0x%.08X -> EmuXapiProcessHeap\n", XTL::EmuXapiProcessHeap); + DbgPrintf("HLE: 0x%.08X -> g_pRtlCreateHeap\n", XTL::g_pRtlCreateHeap); + } + } + } + else if(strcmp("D3D8", szLibraryName) == 0 && MajorVersion == 1 && MinorVersion == 0 && + (BuildVersion == 3925 || BuildVersion == 4134 || BuildVersion == 4361 || BuildVersion == 4432 + || BuildVersion == 4627 || BuildVersion == 5558 || BuildVersion == 5849)) + { + uint32 lower = pXbeHeader->dwBaseAddr; + uint32 upper = pXbeHeader->dwBaseAddr + pXbeHeader->dwSizeofImage; + + void *pFunc = 0; + + if(BuildVersion == 3925) + pFunc = EmuLocateFunction((OOVPA*)&IDirect3DDevice8_SetRenderState_CullMode_1_0_3925, lower, upper); + else if(BuildVersion < 5558) + pFunc = EmuLocateFunction((OOVPA*)&IDirect3DDevice8_SetRenderState_CullMode_1_0_4134, lower, upper); + else + pFunc = EmuLocateFunction((OOVPA*)&IDirect3DDevice8_SetRenderState_CullMode_1_0_5558, lower, upper); + + // locate D3DDeferredRenderState + if(pFunc != 0) + { + // offset for stencil cull enable render state in the deferred render state buffer + int patchOffset = 0; + + if(BuildVersion == 3925) + { + XTL::EmuD3DDeferredRenderState = (DWORD*)(*(DWORD*)((uint32)pFunc + 0x25) - 0x19F + 72*4); // TODO: Clean up (?) + patchOffset = 142*4 - 72*4; // TODO: Verify + } + else if(BuildVersion == 4134) + { + XTL::EmuD3DDeferredRenderState = (DWORD*)(*(DWORD*)((uint32)pFunc + 0x2B) - 0x248 + 82*4); // TODO: Verify + patchOffset = 142*4 - 82*4; + } + else if(BuildVersion == 4361) + { + XTL::EmuD3DDeferredRenderState = (DWORD*)(*(DWORD*)((uint32)pFunc + 0x2B) - 0x200 + 82*4); + patchOffset = 142*4 - 82*4; + } + else if(BuildVersion == 4432) + { + XTL::EmuD3DDeferredRenderState = (DWORD*)(*(DWORD*)((uint32)pFunc + 0x2B) - 0x204 + 83*4); + patchOffset = 143*4 - 83*4; + } + else if(BuildVersion == 4627) + { + XTL::EmuD3DDeferredRenderState = (DWORD*)(*(DWORD*)((uint32)pFunc + 0x2B) - 0x24C + 92*4); + patchOffset = 162*4 - 92*4; + } + else if(BuildVersion == 5558 || BuildVersion == 5849) + { + // WARNING: Not thoroughly tested (just seemed very correct right away) + XTL::EmuD3DDeferredRenderState = (DWORD*)(*(DWORD*)((uint32)pFunc + 0x2B) - 0x24C + 92*4); + patchOffset = 162*4 - 92*4; + } + + XRefDataBase[XREF_D3DDEVICE] = *(DWORD*)((DWORD)pFunc + 0x03); + XRefDataBase[XREF_D3DRS_STENCILCULLENABLE] = (uint32)XTL::EmuD3DDeferredRenderState + patchOffset + 0*4; + XRefDataBase[XREF_D3DRS_ROPZCMPALWAYSREAD] = (uint32)XTL::EmuD3DDeferredRenderState + patchOffset + 1*4; + XRefDataBase[XREF_D3DRS_ROPZREAD] = (uint32)XTL::EmuD3DDeferredRenderState + patchOffset + 2*4; + XRefDataBase[XREF_D3DRS_DONOTCULLUNCOMPRESSED] = (uint32)XTL::EmuD3DDeferredRenderState + patchOffset + 3*4; + + for(int v=0;v<44;v++) + { + XTL::EmuD3DDeferredRenderState[v] = X_D3DRS_UNK; + } + + DbgPrintf("HLE: 0x%.08X -> EmuD3DDeferredRenderState\n", XTL::EmuD3DDeferredRenderState); + } + else + { + XTL::EmuD3DDeferredRenderState = 0; + EmuWarning("EmuD3DDeferredRenderState was not found!"); + } + + // locate D3DDeferredTextureState + { + pFunc = 0; + + if(BuildVersion == 3925) + pFunc = EmuLocateFunction((OOVPA*)&IDirect3DDevice8_SetTextureState_TexCoordIndex_1_0_3925, lower, upper); + else if(BuildVersion == 4134) + pFunc = EmuLocateFunction((OOVPA*)&IDirect3DDevice8_SetTextureState_TexCoordIndex_1_0_4134, lower, upper); + else if(BuildVersion == 4361 || BuildVersion == 4432) + pFunc = EmuLocateFunction((OOVPA*)&IDirect3DDevice8_SetTextureState_TexCoordIndex_1_0_4361, lower, upper); + else if(BuildVersion == 4627 || BuildVersion == 5558 || BuildVersion == 5849) + pFunc = EmuLocateFunction((OOVPA*)&IDirect3DDevice8_SetTextureState_TexCoordIndex_1_0_4627, lower, upper); + + if(pFunc != 0) + { + if(BuildVersion == 3925) // 0x18F180 + XTL::EmuD3DDeferredTextureState = (DWORD*)(*(DWORD*)((uint32)pFunc + 0x11) - 0x70); // TODO: Verify + else if(BuildVersion == 4134) + XTL::EmuD3DDeferredTextureState = (DWORD*)(*(DWORD*)((uint32)pFunc + 0x18) - 0x70); // TODO: Verify + else + XTL::EmuD3DDeferredTextureState = (DWORD*)(*(DWORD*)((uint32)pFunc + 0x19) - 0x70); + + for(int s=0;s<4;s++) + { + for(int v=0;v<32;v++) + XTL::EmuD3DDeferredTextureState[v+s*32] = X_D3DTSS_UNK; + } + + DbgPrintf("HLE: 0x%.08X -> EmuD3DDeferredTextureState\n", XTL::EmuD3DDeferredTextureState); + } + else + { + XTL::EmuD3DDeferredTextureState = 0; + EmuCleanup("EmuD3DDeferredTextureState was not found!"); + } + } + } + } + + DbgPrintf("HLE: * Searching HLE database for %s %d.%d.%d...", pLibraryVersion[v].szName, MajorVersion, MinorVersion, BuildVersion); + + bool found=false; + + for(uint32 d=0;d 0) + { + FILE *pCacheFile = fopen(szCacheFileName, "wb"); + + if(pCacheFile != NULL) + { + DbgPrintf("HLE: Saving HLE Cache for 0x%.08X...\n", pCertificate->dwTitleId); + + // + // write last compiled timestamp + // + + char szCacheLastCompileTime[64]; + + memset(szCacheLastCompileTime, 0, 64); + + strcpy(szCacheLastCompileTime, szHLELastCompileTime); + + fwrite(szCacheLastCompileTime, 64, 1, pCacheFile); + + // + // write function addresses + // + + std::vector::const_iterator cur; + + for(cur = vCacheOut.begin();cur != vCacheOut.end(); ++cur) + { + fwrite(&(*cur), 4, 1, pCacheFile); + } + } + + fclose(pCacheFile); + } + + vCacheOut.empty(); + + DbgPrintf("\n"); + + return; +} + +// install function interception wrapper +static inline void EmuInstallWrapper(void *FunctionAddr, void *WrapperAddr) +{ + uint08 *FuncBytes = (uint08*)FunctionAddr; + + *(uint08*)&FuncBytes[0] = 0xE9; + *(uint32*)&FuncBytes[1] = (uint32)WrapperAddr - (uint32)FunctionAddr - 5; +} + +// locate the given function, searching within lower and upper bounds +static void *EmuLocateFunction(OOVPA *Oovpa, uint32 lower, uint32 upper) +{ + uint32 count = Oovpa->Count; + + // Skip out if this is an unnecessary search + if(!bXRefFirstPass && Oovpa->XRefCount == 0 && Oovpa->XRefSaveIndex == (uint08)-1) + return 0; + + // large + if(Oovpa->Large == 1) + { + LOOVPA<1> *Loovpa = (LOOVPA<1>*)Oovpa; + + upper -= Loovpa->Lovp[count-1].Offset; + + // search all of the image memory + for(uint32 cur=lower;curXRefCount;v++) + { + uint32 Offset = Loovpa->Lovp[v].Offset; + uint32 Value = Loovpa->Lovp[v].Value; + + uint32 RealValue = *(uint32*)(cur + Offset); + + if(XRefDataBase[Value] == -1) + goto skipout_L; // unsatisfied Xref is not acceptable + + if((RealValue + cur + Offset+4 != XRefDataBase[Value]) && (RealValue != XRefDataBase[Value])) + break; + } + + // check all pairs, moving on if any do not match + for(v=0;vLovp[v].Offset; + uint32 Value = Loovpa->Lovp[v].Value; + + uint08 RealValue = *(uint08*)(cur + Offset); + + if(RealValue != Value) + break; + } + + // success if we found all pairs + if(v == count) + { + if(Loovpa->XRefSaveIndex != (uint08)-1) + { + if(XRefDataBase[Loovpa->XRefSaveIndex] == -1) + { + UnResolvedXRefs--; + XRefDataBase[Loovpa->XRefSaveIndex] = cur; + + return (void*)cur; + } + else + { + return (void*)XRefDataBase[Loovpa->XRefSaveIndex]; // already Found, no bother patching again + } + } + + return (void*)cur; + } + + skipout_L:; + } + } + // small + else + { + SOOVPA<1> *Soovpa = (SOOVPA<1>*)Oovpa; + + upper -= Soovpa->Sovp[count-1].Offset; + + // search all of the image memory + for(uint32 cur=lower;curXRefCount;v++) + { + uint32 Offset = Soovpa->Sovp[v].Offset; + uint32 Value = Soovpa->Sovp[v].Value; + + uint32 RealValue = *(uint32*)(cur + Offset); + + if(XRefDataBase[Value] == -1) + goto skipout_S; // Unsatisfied XRef is not acceptable + + if( (RealValue + cur + Offset + 4 != XRefDataBase[Value]) && (RealValue != XRefDataBase[Value])) + break; + } + + // check OV pairs if all xrefs matched + if(v == Soovpa->XRefCount) + { + // check all pairs, moving on if any do not match + for(;vSovp[v].Offset; + uint32 Value = Soovpa->Sovp[v].Value; + + uint08 RealValue = *(uint08*)(cur + Offset); + + if(RealValue != Value) + break; + } + } + + // success if we found all pairs + if(v == count) + { + if(Soovpa->XRefSaveIndex != (uint08)-1) + { + if(XRefDataBase[Soovpa->XRefSaveIndex] == -1) + { + UnResolvedXRefs--; + XRefDataBase[Soovpa->XRefSaveIndex] = cur; + + return (void*)cur; + } + else + { + return (void*)XRefDataBase[Soovpa->XRefSaveIndex]; // already Found, no bother patching again + } + } + + return (void*)cur; + } + + skipout_S:; + } + } + + return 0; +} + +// install function interception wrappers +static void EmuInstallWrappers(OOVPATable *OovpaTable, uint32 OovpaTableSize, Xbe::Header *pXbeHeader) +{ + uint32 lower = pXbeHeader->dwBaseAddr; + uint32 upper = pXbeHeader->dwBaseAddr + pXbeHeader->dwSizeofImage; + + // traverse the full OOVPA table + for(uint32 a=0;a %s\n", pFunc, OovpaTable[a].szFuncName); + + if(OovpaTable[a].lpRedirect == 0) + { + EmuInstallWrapper(pFunc, EmuXRefFailure); + } + else + { + EmuInstallWrapper(pFunc, OovpaTable[a].lpRedirect); + } + } + } +} + +// alert for the situation where an Xref function body is hit +static void EmuXRefFailure() +{ + EmuSwapFS(); // Win2k/XP FS + + EmuCleanup("XRef-only function body reached. Fatal Error."); +} +