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 8af6a7b67..54c5e8b81 100644 Binary files a/Cxbx.opt and b/Cxbx.opt differ diff --git a/CxbxKrnl.dsp b/CxbxKrnl.dsp index fd4f72bac..c96554e55 100644 --- a/CxbxKrnl.dsp +++ b/CxbxKrnl.dsp @@ -43,7 +43,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CXBXKRNL_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /O2 /I "Include" /I "Include/Core/" /I "Include/Win32/" /I "Include/Win32/Cxbx" /I "Include/Win32/CxbxKrnl" /I "Include/Win32/CxbxKrnl/HLEDataBase" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CXBXKRNL_EXPORTS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "Include" /I "Include/Core/" /I "Include/Win32/" /I "Include/Win32/Cxbx" /I "Include/Win32/CxbxKrnl" /I "Include/Win32/CxbxKrnl/HLEDataBase" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CXBXKRNL_EXPORTS" /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" @@ -347,6 +347,10 @@ SOURCE=.\Include\Win32\CxbxKrnl\HLEDataBase.h # End Source File # Begin Source File +SOURCE=.\Include\Win32\CxbxKrnl\HLEIntercept.h +# End Source File +# Begin Source File + SOURCE=.\Include\Win32\Mutex.h # End Source File # Begin Source File @@ -622,6 +626,10 @@ SOURCE=.\Source\Win32\CxbxKrnl\HLEDataBase.cpp # End Source File # Begin Source File +SOURCE=.\Source\Win32\CxbxKrnl\HLEIntercept.cpp +# End Source File +# Begin Source File + SOURCE=.\Source\Win32\CxbxKrnl\KernelThunk.cpp # End Source File # Begin Source File diff --git a/Doc/Changelog.txt b/Doc/Changelog.txt index e3a5c296b..0bc4e08f5 100644 --- a/Doc/Changelog.txt +++ b/Doc/Changelog.txt @@ -19,6 +19,8 @@ version: 0.8.0 (??/??/??) - Toggle Wireframe/Dots/Normal with F11 +- HLE caching (so very very nice and speedy!) + - Tons of new debug support, including integrated debug console - DirectSound support! Turok and Stella (Atari 2600 emulator) diff --git a/Include/Win32/CxbxKrnl/Emu.h b/Include/Win32/CxbxKrnl/Emu.h index be2028039..879bd4eeb 100644 --- a/Include/Win32/CxbxKrnl/Emu.h +++ b/Include/Win32/CxbxKrnl/Emu.h @@ -81,8 +81,8 @@ extern int EmuException(LPEXCEPTION_POINTERS e); extern int EmuCheckAllocationSize(LPVOID pBase, bool largeBound); // global flags specifying current emulation state -extern volatile BOOL g_bEmuException; -extern volatile BOOL g_bEmuSuspended; +extern volatile bool g_bEmuException; +extern volatile bool g_bEmuSuspended; // global exception patching address extern uint32 g_HaloHack[4]; diff --git a/Include/Win32/CxbxKrnl/HLEDataBase.h b/Include/Win32/CxbxKrnl/HLEDataBase.h index c4ab934c9..7b71ee300 100644 --- a/Include/Win32/CxbxKrnl/HLEDataBase.h +++ b/Include/Win32/CxbxKrnl/HLEDataBase.h @@ -60,6 +60,11 @@ #include "XNet.1.0.3911.h" #include "XOnline.1.0.4361.h" +// ****************************************************************** +// * szHLELastCompileTime +// ****************************************************************** +extern "C" const char *szHLELastCompileTime; + // ****************************************************************** // * HLEDataBase // ****************************************************************** diff --git a/Include/Win32/CxbxKrnl/HLEIntercept.h b/Include/Win32/CxbxKrnl/HLEIntercept.h new file mode 100644 index 000000000..15ef63cdd --- /dev/null +++ b/Include/Win32/CxbxKrnl/HLEIntercept.h @@ -0,0 +1,39 @@ +// ****************************************************************** +// * +// * .,-::::: .,:: .::::::::. .,:: .: +// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;; +// * [[[ '[[,,[[' [[[__[[\. '[[,,[[' +// * $$$ Y$$$P $$""""Y$$ Y$$$P +// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo, +// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm, +// * +// * Cxbx->Win32->CxbxKrnl->HLEIntercept.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."); +} +