HLE caching
This commit is contained in:
parent
a91947eb52
commit
7538c4268a
4
Cxbe.dsp
4
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"
|
||||
|
|
4
Cxbx.dsp
4
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"
|
||||
|
|
10
CxbxKrnl.dsp
10
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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -60,6 +60,11 @@
|
|||
#include "XNet.1.0.3911.h"
|
||||
#include "XOnline.1.0.4361.h"
|
||||
|
||||
// ******************************************************************
|
||||
// * szHLELastCompileTime
|
||||
// ******************************************************************
|
||||
extern "C" const char *szHLELastCompileTime;
|
||||
|
||||
// ******************************************************************
|
||||
// * HLEDataBase
|
||||
// ******************************************************************
|
||||
|
|
|
@ -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 <caustik@caustik.com>
|
||||
// *
|
||||
// * All rights reserved
|
||||
// *
|
||||
// ******************************************************************
|
||||
#ifndef HLEINTERCEPT_H
|
||||
#define HLEINTERCEPT_H
|
||||
|
||||
extern "C" void EmuHLEIntercept(Xbe::LibraryVersion *LibraryVersion, Xbe::Header *XbeHeader);
|
||||
|
||||
#endif
|
|
@ -54,29 +54,28 @@ namespace NtDll
|
|||
#include "EmuXTL.h"
|
||||
#include "EmuShared.h"
|
||||
#include "HLEDataBase.h"
|
||||
#include "HLEIntercept.h"
|
||||
|
||||
#include <shlobj.h>
|
||||
#include <locale.h>
|
||||
|
||||
// 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;v<dwLibraryVersions;v++)
|
||||
{
|
||||
uint16 MajorVersion = pLibraryVersion[v].wMajorVersion;
|
||||
uint16 MinorVersion = pLibraryVersion[v].wMinorVersion;
|
||||
uint16 BuildVersion = pLibraryVersion[v].wBuildVersion;
|
||||
uint16 OrigBuildVersion = BuildVersion;
|
||||
|
||||
//
|
||||
// Aliases
|
||||
//
|
||||
{
|
||||
if(BuildVersion == 4928)
|
||||
BuildVersion = 4627;
|
||||
|
||||
if(BuildVersion == 5659)
|
||||
BuildVersion = 5558;
|
||||
}
|
||||
|
||||
char szLibraryName[9] = {0};
|
||||
|
||||
for(uint32 c=0;c<8;c++)
|
||||
szLibraryName[c] = pLibraryVersion[v].szName[c];
|
||||
|
||||
// TODO: HACK: These libraries are packed into one database
|
||||
if(strcmp(szLibraryName, "D3DX8") == 0)
|
||||
strcpy(szLibraryName, "D3D8");
|
||||
|
||||
if(strcmp(szLibraryName, "D3D8") == 0)
|
||||
{
|
||||
if(bFoundD3D)
|
||||
{
|
||||
DbgPrintf("Redundant\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
bFoundD3D = true;
|
||||
}
|
||||
|
||||
if(bXRefFirstPass)
|
||||
{
|
||||
if(strcmp("XAPILIB", szLibraryName) == 0 && MajorVersion == 1 && MinorVersion == 0 &&
|
||||
(BuildVersion == 3911 || BuildVersion == 4034 || BuildVersion == 4134 || BuildVersion == 4361
|
||||
|| BuildVersion == 4432 || BuildVersion == 4627 || BuildVersion == 5558 || BuildVersion == 5849))
|
||||
{
|
||||
uint32 lower = pXbeHeader->dwBaseAddr;
|
||||
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;d<dwHLEEntries;d++)
|
||||
{
|
||||
if(BuildVersion != HLEDataBase[d].BuildVersion || MinorVersion != HLEDataBase[d].MinorVersion || MajorVersion != HLEDataBase[d].MajorVersion || strcmp(szLibraryName, HLEDataBase[d].Library) != 0)
|
||||
continue;
|
||||
|
||||
found = true;
|
||||
|
||||
DbgPrintf("Found\n");
|
||||
|
||||
EmuInstallWrappers(HLEDataBase[d].OovpaTable, HLEDataBase[d].OovpaTableSize, Entry, pXbeHeader);
|
||||
}
|
||||
|
||||
if(!found)
|
||||
DbgPrintf("Skipped\n");
|
||||
}
|
||||
|
||||
bXRefFirstPass = false;
|
||||
}
|
||||
|
||||
// display Xref summary
|
||||
DbgPrintf("EmuMain (0x%X): Resolved %d cross reference(s)\n", GetCurrentThreadId(), OrigUnResolvedXRefs - UnResolvedXRefs);
|
||||
}
|
||||
EmuHLEIntercept(pLibraryVersion, pXbeHeader);
|
||||
|
||||
DbgPrintf("EmuMain (0x%X): Initial thread starting.\n", GetCurrentThreadId());
|
||||
|
||||
//
|
||||
// Xbe entry point
|
||||
//
|
||||
|
||||
__try
|
||||
{
|
||||
EmuSwapFS(); // XBox FS
|
||||
|
@ -702,7 +474,7 @@ extern "C" CXBXKRNL_API void NTAPI EmuWarning(const char *szWarningMessage, ...)
|
|||
// cleanup emulation
|
||||
extern "C" CXBXKRNL_API void NTAPI EmuCleanup(const char *szErrorMessage, ...)
|
||||
{
|
||||
g_bEmuException = TRUE;
|
||||
g_bEmuException = true;
|
||||
|
||||
EmuResume();
|
||||
|
||||
|
@ -818,7 +590,7 @@ extern "C" CXBXKRNL_API void NTAPI EmuSuspend()
|
|||
SetWindowText(hWnd, szBuffer);
|
||||
}
|
||||
|
||||
g_bEmuSuspended = TRUE;
|
||||
g_bEmuSuspended = true;
|
||||
}
|
||||
|
||||
// resume all threads that have been created with PsCreateSystemThreadEx
|
||||
|
@ -859,7 +631,7 @@ extern "C" CXBXKRNL_API void NTAPI EmuResume()
|
|||
}
|
||||
}
|
||||
|
||||
g_bEmuSuspended = FALSE;
|
||||
g_bEmuSuspended = false;
|
||||
}
|
||||
|
||||
// exception handler
|
||||
|
@ -868,7 +640,7 @@ extern int EmuException(LPEXCEPTION_POINTERS e)
|
|||
if(EmuIsXboxFS())
|
||||
EmuSwapFS();
|
||||
|
||||
g_bEmuException = TRUE;
|
||||
g_bEmuException = true;
|
||||
|
||||
// check for Halo hack
|
||||
{
|
||||
|
@ -923,7 +695,7 @@ extern int EmuException(LPEXCEPTION_POINTERS e)
|
|||
|
||||
DbgPrintf("EmuMain (0x%X): Halo Access Adjust 1 was applied!\n", GetCurrentThreadId());
|
||||
|
||||
g_bEmuException = FALSE;
|
||||
g_bEmuException = false;
|
||||
|
||||
return EXCEPTION_CONTINUE_EXECUTION;
|
||||
}
|
||||
|
@ -956,7 +728,7 @@ extern int EmuException(LPEXCEPTION_POINTERS e)
|
|||
|
||||
DbgPrintf("EmuMain (0x%X): Halo Access Adjust 2 was applied!\n", GetCurrentThreadId());
|
||||
|
||||
g_bEmuException = FALSE;
|
||||
g_bEmuException = false;
|
||||
|
||||
return EXCEPTION_CONTINUE_EXECUTION;
|
||||
}
|
||||
|
@ -1015,7 +787,7 @@ extern int EmuException(LPEXCEPTION_POINTERS e)
|
|||
{
|
||||
printf("EmuMain (0x%X): Ignored Breakpoint Exception\n", GetCurrentThreadId());
|
||||
|
||||
g_bEmuException = FALSE;
|
||||
g_bEmuException = false;
|
||||
|
||||
return EXCEPTION_CONTINUE_EXECUTION;
|
||||
}
|
||||
|
@ -1042,7 +814,7 @@ extern int EmuException(LPEXCEPTION_POINTERS e)
|
|||
}
|
||||
}
|
||||
|
||||
g_bEmuException = FALSE;
|
||||
g_bEmuException = false;
|
||||
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
@ -1072,197 +844,6 @@ extern int EmuCheckAllocationSize(LPVOID pBase, bool largeBound)
|
|||
return MemoryBasicInfo.RegionSize - ((DWORD)pBase - (DWORD)MemoryBasicInfo.BaseAddress);
|
||||
}
|
||||
|
||||
// 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;cur<upper;cur++)
|
||||
{
|
||||
uint32 v;
|
||||
|
||||
// check all cross references
|
||||
for(v=0;v<Loovpa->XRefCount;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;v<count;v++)
|
||||
{
|
||||
uint32 Offset = Loovpa->Lovp[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;cur<upper;cur++)
|
||||
{
|
||||
uint32 v;
|
||||
|
||||
// check all cross references
|
||||
for(v=0;v<Soovpa->XRefCount;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(;v<count;v++)
|
||||
{
|
||||
uint32 Offset = Soovpa->Sovp[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<OovpaTableSize/sizeof(OOVPATable);a++)
|
||||
{
|
||||
OOVPA *Oovpa = OovpaTable[a].Oovpa;
|
||||
|
||||
void *pFunc = EmuLocateFunction(Oovpa, lower, upper);
|
||||
|
||||
if(pFunc != 0)
|
||||
{
|
||||
#ifdef _DEBUG_TRACE
|
||||
DbgPrintf("EmuMain (0x%X): 0x%.08X -> %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)
|
||||
{
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -37,6 +37,8 @@
|
|||
#undef FIELD_OFFSET // prevent macro redefinition warnings
|
||||
#include <windows.h>
|
||||
|
||||
extern "C" const char *szHLELastCompileTime = __TIMESTAMP__;
|
||||
|
||||
#include "Emu.h"
|
||||
#include "EmuXTL.h"
|
||||
#include "HLEDataBase.h"
|
||||
|
|
|
@ -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 <caustik@caustik.com>
|
||||
// *
|
||||
// * 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 <shlobj.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
static std::vector<void *> vCacheOut;
|
||||
|
||||
static bool bCacheInp = false;
|
||||
static std::vector<void *> vCacheInp;
|
||||
static std::vector<void*>::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;v<dwLibraryVersions;v++)
|
||||
{
|
||||
uint16 MajorVersion = pLibraryVersion[v].wMajorVersion;
|
||||
uint16 MinorVersion = pLibraryVersion[v].wMinorVersion;
|
||||
uint16 BuildVersion = pLibraryVersion[v].wBuildVersion;
|
||||
uint16 OrigBuildVersion = BuildVersion;
|
||||
|
||||
// aliases
|
||||
if(BuildVersion == 4928) { BuildVersion = 4627; }
|
||||
if(BuildVersion == 5659) { BuildVersion = 5558; }
|
||||
|
||||
char szLibraryName[9] = {0};
|
||||
|
||||
for(uint32 c=0;c<8;c++)
|
||||
{
|
||||
szLibraryName[c] = pLibraryVersion[v].szName[c];
|
||||
}
|
||||
|
||||
// TODO: HACK: These libraries are packed into one database
|
||||
if(strcmp(szLibraryName, "D3DX8") == 0)
|
||||
{
|
||||
strcpy(szLibraryName, "D3D8");
|
||||
}
|
||||
|
||||
if(strcmp(szLibraryName, "D3D8") == 0)
|
||||
{
|
||||
if(bFoundD3D)
|
||||
{
|
||||
//DbgPrintf("Redundant\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
bFoundD3D = true;
|
||||
}
|
||||
|
||||
if(bXRefFirstPass)
|
||||
{
|
||||
if(strcmp("XAPILIB", szLibraryName) == 0 && MajorVersion == 1 && MinorVersion == 0 &&
|
||||
(BuildVersion == 3911 || BuildVersion == 4034 || BuildVersion == 4134 || BuildVersion == 4361
|
||||
|| BuildVersion == 4432 || BuildVersion == 4627 || BuildVersion == 5558 || BuildVersion == 5849))
|
||||
{
|
||||
uint32 lower = pXbeHeader->dwBaseAddr;
|
||||
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<dwHLEEntries;d++)
|
||||
{
|
||||
if(BuildVersion != HLEDataBase[d].BuildVersion || MinorVersion != HLEDataBase[d].MinorVersion || MajorVersion != HLEDataBase[d].MajorVersion || strcmp(szLibraryName, HLEDataBase[d].Library) != 0)
|
||||
continue;
|
||||
|
||||
found = true;
|
||||
|
||||
DbgPrintf("Found\n");
|
||||
|
||||
EmuInstallWrappers(HLEDataBase[d].OovpaTable, HLEDataBase[d].OovpaTableSize, pXbeHeader);
|
||||
}
|
||||
|
||||
if(!found) { DbgPrintf("Skipped\n"); }
|
||||
}
|
||||
|
||||
bXRefFirstPass = false;
|
||||
}
|
||||
|
||||
// display Xref summary
|
||||
DbgPrintf("HLE: Resolved %d cross reference(s)\n", OrigUnResolvedXRefs - UnResolvedXRefs);
|
||||
}
|
||||
|
||||
vCacheInp.empty();
|
||||
|
||||
//
|
||||
// update cache file
|
||||
//
|
||||
|
||||
if(vCacheOut.size() > 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<void*>::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;cur<upper;cur++)
|
||||
{
|
||||
uint32 v;
|
||||
|
||||
// check all cross references
|
||||
for(v=0;v<Loovpa->XRefCount;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;v<count;v++)
|
||||
{
|
||||
uint32 Offset = Loovpa->Lovp[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;cur<upper;cur++)
|
||||
{
|
||||
uint32 v;
|
||||
|
||||
// check all cross references
|
||||
for(v=0;v<Soovpa->XRefCount;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(;v<count;v++)
|
||||
{
|
||||
uint32 Offset = Soovpa->Sovp[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<OovpaTableSize/sizeof(OOVPATable);a++)
|
||||
{
|
||||
OOVPA *Oovpa = OovpaTable[a].Oovpa;
|
||||
|
||||
void *pFunc = NULL;
|
||||
|
||||
if(bCacheInp && (vCacheInpIter != vCacheInp.end()))
|
||||
{
|
||||
pFunc = (*vCacheInpIter);
|
||||
|
||||
++vCacheInpIter;
|
||||
}
|
||||
else
|
||||
{
|
||||
pFunc = EmuLocateFunction(Oovpa, lower, upper);
|
||||
vCacheOut.push_back(pFunc);
|
||||
}
|
||||
|
||||
if(pFunc != 0)
|
||||
{
|
||||
DbgPrintf("HLE: 0x%.08X -> %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.");
|
||||
}
|
||||
|
Loading…
Reference in New Issue