Remove HLE v1 Method From Cxbx
- Removed v1 database method - Migrate v2 into v1 functions - Format some coding standard - Fix compile issue - Say goodbye to HLE v1 method.
This commit is contained in:
parent
71aabebe27
commit
d33ffe0c15
|
@ -231,6 +231,7 @@ $(SOLUTIONDIR)Export.bat</Command>
|
||||||
<ClInclude Include="..\..\src\CxbxKrnl\EmuXOnline.h" />
|
<ClInclude Include="..\..\src\CxbxKrnl\EmuXOnline.h" />
|
||||||
<ClInclude Include="..\..\src\CxbxKrnl\EmuXTL.h" />
|
<ClInclude Include="..\..\src\CxbxKrnl\EmuXTL.h" />
|
||||||
<ClInclude Include="..\..\src\CxbxKrnl\HLEDataBase.h" />
|
<ClInclude Include="..\..\src\CxbxKrnl\HLEDataBase.h" />
|
||||||
|
<ClInclude Include="..\..\src\CxbxKrnl\HLEDataBase\D3D8.OOVPA.h" />
|
||||||
<ClInclude Include="..\..\src\CxbxKrnl\HLEIntercept.h" />
|
<ClInclude Include="..\..\src\CxbxKrnl\HLEIntercept.h" />
|
||||||
<ClInclude Include="..\..\src\CxbxKrnl\LibRc4.h" />
|
<ClInclude Include="..\..\src\CxbxKrnl\LibRc4.h" />
|
||||||
<ClInclude Include="..\..\src\CxbxKrnl\MemoryManager.h" />
|
<ClInclude Include="..\..\src\CxbxKrnl\MemoryManager.h" />
|
||||||
|
|
|
@ -399,6 +399,9 @@
|
||||||
<ClInclude Include="..\..\src\Common\Win32\XBAudio.h">
|
<ClInclude Include="..\..\src\Common\Win32\XBAudio.h">
|
||||||
<Filter>Shared</Filter>
|
<Filter>Shared</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\src\CxbxKrnl\HLEDataBase\D3D8.OOVPA.h">
|
||||||
|
<Filter>HLEDatabase\D3D8</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="..\..\resource\Splash.jpg">
|
<None Include="..\..\resource\Splash.jpg">
|
||||||
|
|
|
@ -81,18 +81,8 @@ const char *Sec_XNET = "XNET";
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
// * HLEDataBase
|
// * HLEDataBase
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
#define HLE_ENTRY(Lib, DB, Version) \
|
|
||||||
{Lib, Version, DB##_##Version, DB##_##Version##_SIZE }
|
|
||||||
// For example, HLE_ENTRY(Lib_XAPILIB, XAPI, 3911) results in:
|
|
||||||
// {Lib_XAPILIB, 3911, XAPI_3911, XAPI_3911_SIZE }
|
|
||||||
|
|
||||||
const HLEData HLEDataBase[] =
|
const HLEData HLEDataBase[] = {
|
||||||
{
|
|
||||||
|
|
||||||
HLE_ENTRY(Lib_XONLINE, XOnline, 4361), // TODO : Typo for XONLINES?
|
|
||||||
};
|
|
||||||
|
|
||||||
const HLEDataV2 HLEDataBaseV2[] = {
|
|
||||||
// Support inline functions in .text section
|
// Support inline functions in .text section
|
||||||
{ Lib_D3D8,{ Sec_text, Sec_D3D }, D3D8_OOVPAV2, D3D8_OOVPA_SIZEV2 },
|
{ Lib_D3D8,{ Sec_text, Sec_D3D }, D3D8_OOVPAV2, D3D8_OOVPA_SIZEV2 },
|
||||||
|
|
||||||
|
@ -146,8 +136,6 @@ const HLEDataV2 HLEDataBaseV2[] = {
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
const uint32 HLEDataBaseCount = sizeof(HLEDataBase) / sizeof(HLEData);
|
const uint32 HLEDataBaseCount = sizeof(HLEDataBase) / sizeof(HLEData);
|
||||||
|
|
||||||
const uint32 HLEDataBaseCountV2 = sizeof(HLEDataBaseV2) / sizeof(HLEDataV2);
|
|
||||||
|
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
// * XRefDataBase
|
// * XRefDataBase
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
|
|
|
@ -34,6 +34,8 @@
|
||||||
#ifndef HLEDATABASE_H
|
#ifndef HLEDATABASE_H
|
||||||
#define HLEDATABASE_H
|
#define HLEDATABASE_H
|
||||||
|
|
||||||
|
#include "HLEDataBase\D3D8.OOVPA.h"
|
||||||
|
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
// * szHLELastCompileTime
|
// * szHLELastCompileTime
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
|
@ -54,15 +56,6 @@ extern const char *Lib_XONLINES;
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
// * HLEDataBase
|
// * HLEDataBase
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
extern const struct HLEData
|
|
||||||
{
|
|
||||||
const char *Library;
|
|
||||||
|
|
||||||
uint16 BuildVersion;
|
|
||||||
OOVPATable *OovpaTable;
|
|
||||||
uint32 OovpaTableSize;
|
|
||||||
}
|
|
||||||
HLEDataBase[];
|
|
||||||
|
|
||||||
#define PAIRSCANSEC_MAX 3
|
#define PAIRSCANSEC_MAX 3
|
||||||
|
|
||||||
|
@ -71,22 +64,20 @@ const struct PairScanLibSec {
|
||||||
const char *section[PAIRSCANSEC_MAX];
|
const char *section[PAIRSCANSEC_MAX];
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const struct HLEDataV2
|
extern const struct HLEData
|
||||||
{
|
{
|
||||||
const PairScanLibSec LibSec;
|
const PairScanLibSec LibSec;
|
||||||
|
|
||||||
OOVPATable *OovpaTable;
|
OOVPATable *OovpaTable;
|
||||||
uint32 OovpaTableSize;
|
uint32 OovpaTableSize;
|
||||||
}
|
}
|
||||||
HLEDataBaseV2[];
|
HLEDataBase[];
|
||||||
|
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
// * HLEDataBaseCount
|
// * HLEDataBaseCount
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
extern const uint32 HLEDataBaseCount;
|
extern const uint32 HLEDataBaseCount;
|
||||||
|
|
||||||
extern const uint32 HLEDataBaseCountV2;
|
|
||||||
|
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
// * XRefDataBaseOffset
|
// * XRefDataBaseOffset
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
// ******************************************************************
|
||||||
|
// *
|
||||||
|
// * .,-::::: .,:: .::::::::. .,:: .:
|
||||||
|
// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;;
|
||||||
|
// * [[[ '[[,,[[' [[[__[[\. '[[,,[['
|
||||||
|
// * $$$ Y$$$P $$""""Y$$ Y$$$P
|
||||||
|
// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo,
|
||||||
|
// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm,
|
||||||
|
// *
|
||||||
|
// * Cxbx->Win32->CxbxKrnl->HLEDataBase->D3D8.OOVPA.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>
|
||||||
|
// * (c) 2017 jarupxx
|
||||||
|
// * (c) 2017 RadWolfie
|
||||||
|
// *
|
||||||
|
// * All rights reserved
|
||||||
|
// *
|
||||||
|
// ******************************************************************
|
||||||
|
#ifndef D3D8_OOVPA_H
|
||||||
|
#define D3D8_OOVPA_H
|
||||||
|
|
||||||
|
#include "../OOVPA.h"
|
||||||
|
|
||||||
|
extern LOOVPA<1 + 11> D3DDevice_SetTextureState_TexCoordIndex_3911;
|
||||||
|
extern LOOVPA<2 + 15> D3DDevice_SetRenderState_CullMode_3911;
|
||||||
|
|
||||||
|
extern LOOVPA<1 + 10> D3DDevice_SetTextureState_TexCoordIndex_4034;
|
||||||
|
extern LOOVPA<2 + 14> D3DDevice_SetRenderState_CullMode_4034;
|
||||||
|
|
||||||
|
extern LOOVPA<1 + 10> D3DDevice_SetTextureState_TexCoordIndex_4242;
|
||||||
|
|
||||||
|
extern LOOVPA<1 + 10> D3DDevice_SetTextureState_TexCoordIndex_4627;
|
||||||
|
|
||||||
|
#endif
|
|
@ -48,10 +48,9 @@
|
||||||
#include <Shlwapi.h>
|
#include <Shlwapi.h>
|
||||||
#include <subhook.h>
|
#include <subhook.h>
|
||||||
|
|
||||||
static xbaddr EmuLocateFunction(OOVPA *Oovpa, xbaddr lower, xbaddr upper);
|
xbaddr EmuLocateFunction(OOVPA *Oovpa, xbaddr lower, xbaddr upper);
|
||||||
static void EmuInstallPatches(OOVPATable *OovpaTable, uint32 OovpaTableSize, Xbe::Header *pXbeHeader);
|
void EmuInstallPatches(OOVPATable *OovpaTable, uint32 OovpaTableSize, Xbe::SectionHeader *pSectionHeader, uint16_t buildVersion);
|
||||||
static inline void EmuInstallPatch(std::string FunctionName, xbaddr FunctionAddr, void *Patch);
|
inline void EmuInstallPatch(std::string FunctionName, xbaddr FunctionAddr, void *Patch);
|
||||||
void EmuInstallPatchesV2(OOVPATable *OovpaTable, uint32 OovpaTableSize, Xbe::SectionHeader *pSectionHeader, uint16_t buildVersion);
|
|
||||||
|
|
||||||
#include <shlobj.h>
|
#include <shlobj.h>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
@ -294,7 +293,6 @@ void EmuHLEIntercept(Xbe::Header *pXbeHeader)
|
||||||
for(uint32 v=0;v<dwLibraryVersions;v++)
|
for(uint32 v=0;v<dwLibraryVersions;v++)
|
||||||
{
|
{
|
||||||
uint16 BuildVersion = pLibraryVersion[v].wBuildVersion;
|
uint16 BuildVersion = pLibraryVersion[v].wBuildVersion;
|
||||||
uint16 OrigBuildVersion = BuildVersion;
|
|
||||||
|
|
||||||
if (preserveVersion < BuildVersion) {
|
if (preserveVersion < BuildVersion) {
|
||||||
preserveVersion = BuildVersion;
|
preserveVersion = BuildVersion;
|
||||||
|
@ -304,21 +302,6 @@ void EmuHLEIntercept(Xbe::Header *pXbeHeader)
|
||||||
|
|
||||||
reProcessScan:
|
reProcessScan:
|
||||||
|
|
||||||
// Aliases - for testing purposes only
|
|
||||||
// TODO: Remove these and come up with a better way to handle XDKs we don't hve databases for
|
|
||||||
if(BuildVersion == 4039) { BuildVersion = 4034; }
|
|
||||||
if(BuildVersion == 4238) { BuildVersion = 4361; } // I don't think this XDK was released.
|
|
||||||
if(BuildVersion == 4242) { BuildVersion = 4361; }
|
|
||||||
if(BuildVersion == 4400) { BuildVersion = 4361; }
|
|
||||||
if(BuildVersion == 4531) { BuildVersion = 4432; }
|
|
||||||
if(BuildVersion == 4721) { BuildVersion = 4627; }
|
|
||||||
if(BuildVersion == 4831) { BuildVersion = 4627; }
|
|
||||||
if(BuildVersion == 4928) { BuildVersion = 4627; }
|
|
||||||
if(BuildVersion == 5455) { BuildVersion = 5558; }
|
|
||||||
if(BuildVersion == 5659) { BuildVersion = 5558; }
|
|
||||||
if(BuildVersion == 5120) { BuildVersion = 5233; }
|
|
||||||
if(BuildVersion == 5933) { BuildVersion = 5849; } // These XDK versions are pretty much the same
|
|
||||||
|
|
||||||
Xbe::SectionHeader* pSectionHeaders = reinterpret_cast<Xbe::SectionHeader*>(pXbeHeader->dwSectionHeadersAddr);
|
Xbe::SectionHeader* pSectionHeaders = reinterpret_cast<Xbe::SectionHeader*>(pXbeHeader->dwSectionHeadersAddr);
|
||||||
Xbe::SectionHeader* pSectionScan = nullptr;
|
Xbe::SectionHeader* pSectionScan = nullptr;
|
||||||
std::string SectionName;
|
std::string SectionName;
|
||||||
|
@ -362,23 +345,15 @@ void EmuHLEIntercept(Xbe::Header *pXbeHeader)
|
||||||
|
|
||||||
if(bXRefFirstPass)
|
if(bXRefFirstPass)
|
||||||
{
|
{
|
||||||
if (strcmp(LibraryName.c_str(), Lib_XAPILIB) == 0 &&
|
if (strcmp(LibraryName.c_str(), Lib_D3D8) == 0) {
|
||||||
(BuildVersion == 3911 || BuildVersion == 4034 || BuildVersion == 4134 || BuildVersion == 4361
|
|
||||||
|| BuildVersion == 4432 || BuildVersion == 4627 || BuildVersion == 5028 || BuildVersion == 5233
|
|
||||||
|| BuildVersion == 5344 || BuildVersion == 5558 || BuildVersion == 5788 || BuildVersion == 5849))
|
|
||||||
{
|
|
||||||
xbaddr lower = pXbeHeader->dwBaseAddr;
|
|
||||||
xbaddr upper = pXbeHeader->dwBaseAddr + pXbeHeader->dwSizeofImage;
|
|
||||||
}
|
|
||||||
else if (strcmp(LibraryName.c_str(), Lib_D3D8) == 0) {
|
|
||||||
// Save D3D8 build version
|
// Save D3D8 build version
|
||||||
g_BuildVersion = OrigBuildVersion;
|
g_BuildVersion = BuildVersion;
|
||||||
|
|
||||||
xbaddr lower = pXbeHeader->dwBaseAddr;
|
xbaddr lower = pXbeHeader->dwBaseAddr;
|
||||||
xbaddr upper = pXbeHeader->dwBaseAddr + pXbeHeader->dwSizeofImage;
|
xbaddr upper = pXbeHeader->dwBaseAddr + pXbeHeader->dwSizeofImage;
|
||||||
xbaddr pFunc = (xbaddr)nullptr;
|
xbaddr pFunc = (xbaddr)nullptr;
|
||||||
|
|
||||||
if (OrigBuildVersion >= 3911 && OrigBuildVersion < 4034) {
|
if (BuildVersion >= 3911 && BuildVersion < 4034) {
|
||||||
pFunc = EmuLocateFunction((OOVPA*)&D3DDevice_SetRenderState_CullMode_3911, lower, upper);
|
pFunc = EmuLocateFunction((OOVPA*)&D3DDevice_SetRenderState_CullMode_3911, lower, upper);
|
||||||
} else {
|
} else {
|
||||||
pFunc = EmuLocateFunction((OOVPA*)&D3DDevice_SetRenderState_CullMode_4034, lower, upper);
|
pFunc = EmuLocateFunction((OOVPA*)&D3DDevice_SetRenderState_CullMode_4034, lower, upper);
|
||||||
|
@ -395,7 +370,7 @@ void EmuHLEIntercept(Xbe::Header *pXbeHeader)
|
||||||
// Read address of D3DRS_CULLMODE from D3DDevice_SetRenderState_CullMode
|
// Read address of D3DRS_CULLMODE from D3DDevice_SetRenderState_CullMode
|
||||||
// TODO : Simplify this when XREF_D3DRS_CULLMODE derivation is deemed stable
|
// TODO : Simplify this when XREF_D3DRS_CULLMODE derivation is deemed stable
|
||||||
{
|
{
|
||||||
if (OrigBuildVersion >= 3911 && OrigBuildVersion < 4034) {
|
if (BuildVersion >= 3911 && BuildVersion < 4034) {
|
||||||
DerivedAddr_D3DRS_CULLMODE = *(xbaddr*)(pFunc + 0x25);
|
DerivedAddr_D3DRS_CULLMODE = *(xbaddr*)(pFunc + 0x25);
|
||||||
Decrement = 0x1FC; // TODO: Clean up (?)
|
Decrement = 0x1FC; // TODO: Clean up (?)
|
||||||
Increment = 82 * 4;
|
Increment = 82 * 4;
|
||||||
|
@ -404,17 +379,17 @@ void EmuHLEIntercept(Xbe::Header *pXbeHeader)
|
||||||
//Decrement = 0x19F; // TODO: Clean up (?)
|
//Decrement = 0x19F; // TODO: Clean up (?)
|
||||||
//Increment = 72 * 4;
|
//Increment = 72 * 4;
|
||||||
//patchOffset = 142*4; // TODO: Verify
|
//patchOffset = 142*4; // TODO: Verify
|
||||||
} else if (OrigBuildVersion >= 4034 && OrigBuildVersion <= 4361) {
|
} else if (BuildVersion >= 4034 && BuildVersion <= 4361) {
|
||||||
DerivedAddr_D3DRS_CULLMODE = *(xbaddr*)(pFunc + 0x2B);
|
DerivedAddr_D3DRS_CULLMODE = *(xbaddr*)(pFunc + 0x2B);
|
||||||
Decrement = 0x200;
|
Decrement = 0x200;
|
||||||
Increment = 82 * 4;
|
Increment = 82 * 4;
|
||||||
patchOffset = 142 * 4;
|
patchOffset = 142 * 4;
|
||||||
} else if (OrigBuildVersion >= 4432 && OrigBuildVersion < 4627) {
|
} else if (BuildVersion >= 4432 && BuildVersion < 4627) {
|
||||||
DerivedAddr_D3DRS_CULLMODE = *(xbaddr*)(pFunc + 0x2B);
|
DerivedAddr_D3DRS_CULLMODE = *(xbaddr*)(pFunc + 0x2B);
|
||||||
Decrement = 0x204;
|
Decrement = 0x204;
|
||||||
Increment = 83 * 4;
|
Increment = 83 * 4;
|
||||||
patchOffset = 143 * 4;
|
patchOffset = 143 * 4;
|
||||||
} else if (OrigBuildVersion >= 4627 && OrigBuildVersion <= 5933) {
|
} else if (BuildVersion >= 4627 && BuildVersion <= 5933) {
|
||||||
DerivedAddr_D3DRS_CULLMODE = *(xbaddr*)(pFunc + 0x2B);
|
DerivedAddr_D3DRS_CULLMODE = *(xbaddr*)(pFunc + 0x2B);
|
||||||
Decrement = 0x24C;
|
Decrement = 0x24C;
|
||||||
Increment = 92 * 4;
|
Increment = 92 * 4;
|
||||||
|
@ -469,13 +444,13 @@ void EmuHLEIntercept(Xbe::Header *pXbeHeader)
|
||||||
{
|
{
|
||||||
pFunc = (xbaddr)nullptr;
|
pFunc = (xbaddr)nullptr;
|
||||||
|
|
||||||
if(OrigBuildVersion >= 3911 && OrigBuildVersion < 4034)
|
if(BuildVersion >= 3911 && BuildVersion < 4034)
|
||||||
pFunc = EmuLocateFunction((OOVPA*)&D3DDevice_SetTextureState_TexCoordIndex_3911, lower, upper);
|
pFunc = EmuLocateFunction((OOVPA*)&D3DDevice_SetTextureState_TexCoordIndex_3911, lower, upper);
|
||||||
else if(OrigBuildVersion >= 4034 && OrigBuildVersion < 4242)
|
else if(BuildVersion >= 4034 && BuildVersion < 4242)
|
||||||
pFunc = EmuLocateFunction((OOVPA*)&D3DDevice_SetTextureState_TexCoordIndex_4034, lower, upper);
|
pFunc = EmuLocateFunction((OOVPA*)&D3DDevice_SetTextureState_TexCoordIndex_4034, lower, upper);
|
||||||
else if(OrigBuildVersion >= 4242 && OrigBuildVersion < 4627)
|
else if(BuildVersion >= 4242 && BuildVersion < 4627)
|
||||||
pFunc = EmuLocateFunction((OOVPA*)&D3DDevice_SetTextureState_TexCoordIndex_4242, lower, upper);
|
pFunc = EmuLocateFunction((OOVPA*)&D3DDevice_SetTextureState_TexCoordIndex_4242, lower, upper);
|
||||||
else if(OrigBuildVersion >= 4627)
|
else if(BuildVersion >= 4627)
|
||||||
pFunc = EmuLocateFunction((OOVPA*)&D3DDevice_SetTextureState_TexCoordIndex_4627, lower, upper);
|
pFunc = EmuLocateFunction((OOVPA*)&D3DDevice_SetTextureState_TexCoordIndex_4627, lower, upper);
|
||||||
|
|
||||||
if (pFunc != (xbaddr)nullptr) {
|
if (pFunc != (xbaddr)nullptr) {
|
||||||
|
@ -484,9 +459,9 @@ void EmuHLEIntercept(Xbe::Header *pXbeHeader)
|
||||||
|
|
||||||
// TODO : Remove this when XREF_D3DTSS_TEXCOORDINDEX derivation is deemed stable
|
// TODO : Remove this when XREF_D3DTSS_TEXCOORDINDEX derivation is deemed stable
|
||||||
{
|
{
|
||||||
if (OrigBuildVersion >= 3911 && OrigBuildVersion < 4034) // 0x18F180
|
if (BuildVersion >= 3911 && BuildVersion < 4034) // 0x18F180
|
||||||
DerivedAddr_D3DTSS_TEXCOORDINDEX = *(xbaddr*)(pFunc + 0x11);
|
DerivedAddr_D3DTSS_TEXCOORDINDEX = *(xbaddr*)(pFunc + 0x11);
|
||||||
else if (OrigBuildVersion >= 4034 && OrigBuildVersion < 4242)
|
else if (BuildVersion >= 4034 && BuildVersion < 4242)
|
||||||
DerivedAddr_D3DTSS_TEXCOORDINDEX = *(xbaddr*)(pFunc + 0x18);
|
DerivedAddr_D3DTSS_TEXCOORDINDEX = *(xbaddr*)(pFunc + 0x18);
|
||||||
else
|
else
|
||||||
DerivedAddr_D3DTSS_TEXCOORDINDEX = *(xbaddr*)(pFunc + 0x19);
|
DerivedAddr_D3DTSS_TEXCOORDINDEX = *(xbaddr*)(pFunc + 0x19);
|
||||||
|
@ -521,22 +496,9 @@ void EmuHLEIntercept(Xbe::Header *pXbeHeader)
|
||||||
|
|
||||||
printf("HLE: * Searching HLE database for %s version 1.0.%d... ", LibraryName.c_str(), BuildVersion);
|
printf("HLE: * Searching HLE database for %s version 1.0.%d... ", LibraryName.c_str(), BuildVersion);
|
||||||
|
|
||||||
bool notFoundHLEDB = true;
|
|
||||||
//HLE Database v1
|
|
||||||
for(uint32 d = 0; d < HLEDataBaseCount; d++) {
|
|
||||||
if (BuildVersion == HLEDataBase[d].BuildVersion && strcmp(LibraryName.c_str(), HLEDataBase[d].Library) == 0) {
|
|
||||||
if (g_bPrintfOn) printf("Found\n");
|
|
||||||
EmuInstallPatches(HLEDataBase[d].OovpaTable, HLEDataBase[d].OovpaTableSize, pXbeHeader);
|
|
||||||
notFoundHLEDB = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//HLE Database v2
|
|
||||||
if (notFoundHLEDB) {
|
|
||||||
//Initialize library scan against HLE database we want to search for address of patches and xreferences.
|
//Initialize library scan against HLE database we want to search for address of patches and xreferences.
|
||||||
for (uint32 d2 = 0; d2 < HLEDataBaseCountV2; d2++) {
|
for (uint32 d2 = 0; d2 < HLEDataBaseCount; d2++) {
|
||||||
if (strcmp(LibraryName.c_str(), HLEDataBaseV2[d2].LibSec.library) == 0) {
|
if (strcmp(LibraryName.c_str(), HLEDataBase[d2].LibSec.library) == 0) {
|
||||||
bool bPrintOn = g_bPrintfOn;
|
bool bPrintOn = g_bPrintfOn;
|
||||||
for (uint32 v = 0; v < pXbeHeader->dwSections; v++) {
|
for (uint32 v = 0; v < pXbeHeader->dwSections; v++) {
|
||||||
SectionName.assign((char*)pSectionHeaders[v].dwSectionNameAddr, (char*)pSectionHeaders[v].dwSectionNameAddr + 8);
|
SectionName.assign((char*)pSectionHeaders[v].dwSectionNameAddr, (char*)pSectionHeaders[v].dwSectionNameAddr + 8);
|
||||||
|
@ -544,14 +506,13 @@ void EmuHLEIntercept(Xbe::Header *pXbeHeader)
|
||||||
//Initialize a matching specific section is currently pair with library in order to scan specific section only.
|
//Initialize a matching specific section is currently pair with library in order to scan specific section only.
|
||||||
//By doing this method will reduce false detection dramatically. If it had happened before.
|
//By doing this method will reduce false detection dramatically. If it had happened before.
|
||||||
for (uint32 d3 = 0; d3 < PAIRSCANSEC_MAX; d3++) {
|
for (uint32 d3 = 0; d3 < PAIRSCANSEC_MAX; d3++) {
|
||||||
if (HLEDataBaseV2[d2].LibSec.section[d3] != NULL && strcmp(SectionName.c_str(), HLEDataBaseV2[d2].LibSec.section[d3]) == 0) {
|
if (HLEDataBase[d2].LibSec.section[d3] != NULL && strcmp(SectionName.c_str(), HLEDataBase[d2].LibSec.section[d3]) == 0) {
|
||||||
pSectionScan = pSectionHeaders + v;
|
pSectionScan = pSectionHeaders + v;
|
||||||
|
|
||||||
if (g_bPrintfOn) printf("Found\n");
|
if (g_bPrintfOn) printf("Found\n");
|
||||||
g_bPrintfOn = false;
|
g_bPrintfOn = false;
|
||||||
|
|
||||||
EmuInstallPatchesV2(HLEDataBaseV2[d2].OovpaTable, HLEDataBaseV2[d2].OovpaTableSize, pSectionScan, OrigBuildVersion);
|
EmuInstallPatches(HLEDataBase[d2].OovpaTable, HLEDataBase[d2].OovpaTableSize, pSectionScan, BuildVersion);
|
||||||
notFoundHLEDB = false;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -560,13 +521,11 @@ void EmuHLEIntercept(Xbe::Header *pXbeHeader)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (g_bPrintfOn) printf("Skipped\n");
|
||||||
}
|
|
||||||
if (g_bPrintfOn && notFoundHLEDB) printf("Skipped\n");
|
|
||||||
|
|
||||||
if (v == dwLibraryVersions - 1 && bDSoundLibSection == false) {
|
if (v == dwLibraryVersions - 1 && bDSoundLibSection == false) {
|
||||||
LibraryName = Lib_DSOUND;
|
LibraryName = Lib_DSOUND;
|
||||||
OrigBuildVersion = BuildVersion = preserveVersion;
|
BuildVersion = preserveVersion;
|
||||||
goto reProcessScan;
|
goto reProcessScan;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -617,25 +576,25 @@ void EmuHLEIntercept(Xbe::Header *pXbeHeader)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void EmuInstallPatch(std::string FunctionName, xbaddr FunctionAddr, void *Patch)
|
inline void EmuInstallPatch(std::string FunctionName, xbaddr FunctionAddr, void *Patch)
|
||||||
{
|
{
|
||||||
g_FunctionHooks[FunctionName].Install((void*)(FunctionAddr), Patch);
|
g_FunctionHooks[FunctionName].Install((void*)(FunctionAddr), Patch);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void GetXRefEntry(OOVPA *oovpa, int index, OUT uint32 &xref, OUT uint08 &offset)
|
inline void GetXRefEntry(OOVPA *oovpa, int index, OUT uint32 &xref, OUT uint08 &offset)
|
||||||
{
|
{
|
||||||
// Note : These are stored swapped by the XREF_ENTRY macro, hence this difference from GetOovpaEntry :
|
// Note : These are stored swapped by the XREF_ENTRY macro, hence this difference from GetOovpaEntry :
|
||||||
xref = (uint32)((LOOVPA<1>*)oovpa)->Lovp[index].Offset;
|
xref = (uint32)((LOOVPA<1>*)oovpa)->Lovp[index].Offset;
|
||||||
offset = ((LOOVPA<1>*)oovpa)->Lovp[index].Value;
|
offset = ((LOOVPA<1>*)oovpa)->Lovp[index].Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void GetOovpaEntry(OOVPA *oovpa, int index, OUT uint32 &offset, OUT uint08 &value)
|
inline void GetOovpaEntry(OOVPA *oovpa, int index, OUT uint32 &offset, OUT uint08 &value)
|
||||||
{
|
{
|
||||||
offset = (uint32)((LOOVPA<1>*)oovpa)->Lovp[index].Offset;
|
offset = (uint32)((LOOVPA<1>*)oovpa)->Lovp[index].Offset;
|
||||||
value = ((LOOVPA<1>*)oovpa)->Lovp[index].Value;
|
value = ((LOOVPA<1>*)oovpa)->Lovp[index].Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean CompareOOVPAToAddress(OOVPA *Oovpa, xbaddr cur)
|
boolean CompareOOVPAToAddress(OOVPA *Oovpa, xbaddr cur)
|
||||||
{
|
{
|
||||||
uint32 v = 0; // verification counter
|
uint32 v = 0; // verification counter
|
||||||
|
|
||||||
|
@ -681,202 +640,6 @@ static boolean CompareOOVPAToAddress(OOVPA *Oovpa, xbaddr cur)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// locate the given function, searching within lower and upper bounds
|
|
||||||
static xbaddr EmuLocateFunction(OOVPA *Oovpa, xbaddr lower, xbaddr upper)
|
|
||||||
{
|
|
||||||
// skip out if this is an unnecessary search
|
|
||||||
if (!bXRefFirstPass && Oovpa->XRefCount == XRefZero && Oovpa->XRefSaveIndex == XRefNoSaveIndex)
|
|
||||||
return (xbaddr)nullptr;
|
|
||||||
|
|
||||||
uint32_t derive_indices = 0;
|
|
||||||
// Check all XRefs are known (if not, don't do a useless scan) :
|
|
||||||
for (uint32 v = 0; v < Oovpa->XRefCount; v++)
|
|
||||||
{
|
|
||||||
uint32 XRef;
|
|
||||||
uint08 Offset;
|
|
||||||
|
|
||||||
// get currently registered (un)known address
|
|
||||||
GetXRefEntry(Oovpa, v, XRef, Offset);
|
|
||||||
xbaddr XRefAddr = XRefDataBase[XRef];
|
|
||||||
// Undetermined XRef cannot be checked yet
|
|
||||||
if (XRefAddr == XREF_ADDR_UNDETERMINED)
|
|
||||||
// Skip this scan over the address range
|
|
||||||
return (xbaddr)nullptr;
|
|
||||||
|
|
||||||
// Don't verify an xref that has to be (but isn't yet) derived
|
|
||||||
if (XRefAddr == XREF_ADDR_DERIVE)
|
|
||||||
{
|
|
||||||
// Mark (up to index 32) which xref needs to be derived
|
|
||||||
derive_indices |= (1 << v);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// correct upper bound with highest Oovpa offset
|
|
||||||
uint32 count = Oovpa->Count;
|
|
||||||
{
|
|
||||||
uint32 Offset;
|
|
||||||
uint08 Value; // ignored
|
|
||||||
|
|
||||||
GetOovpaEntry(Oovpa, count - 1, Offset, Value);
|
|
||||||
upper -= Offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
// search all of the image memory
|
|
||||||
for (xbaddr cur = lower; cur < upper; cur++)
|
|
||||||
if (CompareOOVPAToAddress(Oovpa, cur))
|
|
||||||
{
|
|
||||||
// do we need to save the found address?
|
|
||||||
if (Oovpa->XRefSaveIndex != XRefNoSaveIndex)
|
|
||||||
{
|
|
||||||
// is the XRef not saved yet?
|
|
||||||
switch (XRefDataBase[Oovpa->XRefSaveIndex]) {
|
|
||||||
case XREF_ADDR_NOT_FOUND:
|
|
||||||
{
|
|
||||||
EmuWarning("Found OOVPA after first finding nothing?");
|
|
||||||
// fallthrough to XREF_ADDR_UNDETERMINED
|
|
||||||
}
|
|
||||||
case XREF_ADDR_UNDETERMINED:
|
|
||||||
{
|
|
||||||
// save and count the found address
|
|
||||||
UnResolvedXRefs--;
|
|
||||||
XRefDataBase[Oovpa->XRefSaveIndex] = cur;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case XREF_ADDR_DERIVE:
|
|
||||||
{
|
|
||||||
EmuWarning("Cannot derive a save index!");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
if (XRefDataBase[Oovpa->XRefSaveIndex] != cur) {
|
|
||||||
EmuWarning("Found OOVPA on other address than in XRefDataBase!");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while (derive_indices > 0)
|
|
||||||
{
|
|
||||||
uint32 XRef;
|
|
||||||
uint08 Offset;
|
|
||||||
DWORD derive_index;
|
|
||||||
|
|
||||||
// Extract an index from the indices mask :
|
|
||||||
_BitScanReverse(&derive_index, derive_indices); // MSVC intrinsic; GCC has __builtin_clz
|
|
||||||
derive_indices ^= (1 << derive_index);
|
|
||||||
|
|
||||||
// get currently registered (un)known address
|
|
||||||
GetXRefEntry(Oovpa, derive_index, XRef, Offset);
|
|
||||||
|
|
||||||
// Calculate the address where the XRef resides
|
|
||||||
xbaddr XRefAddr = cur + Offset;
|
|
||||||
// Read the address it points to
|
|
||||||
XRefAddr = *((xbaddr*)XRefAddr);
|
|
||||||
|
|
||||||
/* For now assume it's a direct reference;
|
|
||||||
// TODO : Check if it's PC-relative reference?
|
|
||||||
if (XRefAddr + cur + Offset + 4 < XBE_MAX_VA)
|
|
||||||
XRefAddr = XRefAddr + cur + Offset + 4;
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Does the address seem valid?
|
|
||||||
if (XRefAddr < XBE_MAX_VA)
|
|
||||||
{
|
|
||||||
// save and count the derived address
|
|
||||||
UnResolvedXRefs--;
|
|
||||||
XRefDataBase[XRef] = XRefAddr;
|
|
||||||
printf("Derived OOVPA!\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return cur;
|
|
||||||
}
|
|
||||||
|
|
||||||
// found nothing
|
|
||||||
return (xbaddr)nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// install function interception wrappers
|
|
||||||
static void EmuInstallPatches(OOVPATable *OovpaTable, uint32 OovpaTableSize, Xbe::Header *pXbeHeader)
|
|
||||||
{
|
|
||||||
xbaddr lower = pXbeHeader->dwBaseAddr;
|
|
||||||
|
|
||||||
// Find the highest address contained within an executable segment
|
|
||||||
xbaddr upper = pXbeHeader->dwBaseAddr;
|
|
||||||
Xbe::SectionHeader* headers = reinterpret_cast<Xbe::SectionHeader*>(pXbeHeader->dwSectionHeadersAddr);
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < pXbeHeader->dwSections; i++) {
|
|
||||||
xbaddr end_addr = headers[i].dwVirtualAddr + headers[i].dwVirtualSize;
|
|
||||||
if (headers[i].dwFlags.bExecutable && end_addr > upper) {
|
|
||||||
upper = end_addr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// traverse the full OOVPA table
|
|
||||||
for(size_t a=0;a<OovpaTableSize/sizeof(OOVPATable);a++)
|
|
||||||
{
|
|
||||||
// Never used : skip scans when so configured
|
|
||||||
bool DontScan = (OovpaTable[a].Flags & Flag_DontScan) > 0;
|
|
||||||
if (DontScan)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Skip already found & handled symbols
|
|
||||||
xbaddr pFunc = g_SymbolAddresses[OovpaTable[a].szFuncName];
|
|
||||||
if (pFunc != (xbaddr)nullptr)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Search for each function's location using the OOVPA
|
|
||||||
OOVPA *Oovpa = OovpaTable[a].Oovpa;
|
|
||||||
pFunc = (xbaddr)EmuLocateFunction(Oovpa, lower, upper);
|
|
||||||
if (pFunc == (xbaddr)nullptr)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Now that we found the address, store it (regardless if we patch it or not)
|
|
||||||
g_SymbolAddresses[OovpaTable[a].szFuncName] = (uint32_t)pFunc;
|
|
||||||
|
|
||||||
// Output some details
|
|
||||||
std::stringstream output;
|
|
||||||
output << "HLE: 0x" << std::setfill('0') << std::setw(8) << std::hex << pFunc
|
|
||||||
<< " -> " << OovpaTable[a].szFuncName << " " << std::dec << OovpaTable[a].Version;
|
|
||||||
|
|
||||||
bool IsXRef = (OovpaTable[a].Flags & Flag_XRef) > 0;
|
|
||||||
if (IsXRef)
|
|
||||||
output << "\t(XREF)";
|
|
||||||
|
|
||||||
// Retrieve the associated patch, if any is available
|
|
||||||
void* addr = GetEmuPatchAddr(std::string(OovpaTable[a].szFuncName));
|
|
||||||
bool DontPatch = (OovpaTable[a].Flags & Flag_DontPatch) > 0;
|
|
||||||
if (DontPatch)
|
|
||||||
{
|
|
||||||
// Mention if there's an unused patch
|
|
||||||
if (addr != nullptr)
|
|
||||||
output << "\t*PATCH UNUSED!*";
|
|
||||||
else
|
|
||||||
output << "\t*DISABLED*";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (addr != nullptr)
|
|
||||||
{
|
|
||||||
EmuInstallPatch(OovpaTable[a].szFuncName, pFunc, addr);
|
|
||||||
output << "\t*PATCHED*";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Mention there's no patch available, if it was to be applied
|
|
||||||
if (!IsXRef) // TODO : Remove this restriction once we patch xrefs regularly
|
|
||||||
output << "\t*NO PATCH AVAILABLE!*";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
output << "\n";
|
|
||||||
printf(output.str().c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmuRegisterSymbol(OOVPATable *OovpaTable, xbaddr pFunc)
|
void EmuRegisterSymbol(OOVPATable *OovpaTable, xbaddr pFunc)
|
||||||
{
|
{
|
||||||
// Ignore registered symbol in current database.
|
// Ignore registered symbol in current database.
|
||||||
|
@ -957,9 +720,8 @@ void EmuRegisterSymbol(OOVPATable *OovpaTable, xbaddr pFunc)
|
||||||
printf(output.str().c_str());
|
printf(output.str().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// locate the given function, searching within lower and upper bounds
|
// locate the given function, searching within lower and upper bounds
|
||||||
xbaddr EmuLocateFunctionV2(OOVPA *Oovpa, xbaddr lower, xbaddr upper)
|
xbaddr EmuLocateFunction(OOVPA *Oovpa, xbaddr lower, xbaddr upper)
|
||||||
{
|
{
|
||||||
// skip out if this is an unnecessary search
|
// skip out if this is an unnecessary search
|
||||||
if (!bXRefFirstPass && Oovpa->XRefCount == XRefZero && Oovpa->XRefSaveIndex == XRefNoSaveIndex)
|
if (!bXRefFirstPass && Oovpa->XRefCount == XRefZero && Oovpa->XRefSaveIndex == XRefNoSaveIndex)
|
||||||
|
@ -1041,7 +803,7 @@ xbaddr EmuLocateFunctionV2(OOVPA *Oovpa, xbaddr lower, xbaddr upper)
|
||||||
}
|
}
|
||||||
|
|
||||||
// install function interception wrappers
|
// install function interception wrappers
|
||||||
static void EmuInstallPatchesV2(OOVPATable *OovpaTable, uint32 OovpaTableSize, Xbe::SectionHeader *pSectionHeader, uint16_t buildVersion)
|
void EmuInstallPatches(OOVPATable *OovpaTable, uint32 OovpaTableSize, Xbe::SectionHeader *pSectionHeader, uint16_t buildVersion)
|
||||||
{
|
{
|
||||||
xbaddr lower = pSectionHeader->dwVirtualAddr;
|
xbaddr lower = pSectionHeader->dwVirtualAddr;
|
||||||
|
|
||||||
|
@ -1073,7 +835,7 @@ static void EmuInstallPatchesV2(OOVPATable *OovpaTable, uint32 OovpaTableSize, X
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Search for each function's location using the OOVPA
|
// Search for each function's location using the OOVPA
|
||||||
xbaddr pFunc = (xbaddr)EmuLocateFunctionV2(pLoop->Oovpa, lower, upper);
|
xbaddr pFunc = (xbaddr)EmuLocateFunction(pLoop->Oovpa, lower, upper);
|
||||||
if (pFunc == (xbaddr)nullptr)
|
if (pFunc == (xbaddr)nullptr)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue