Skip to content

Commit

Permalink
Merge pull request #116 from SaiyansKing/master
Browse files Browse the repository at this point in the history
Rewrite Animated_Inventory SystemPack option by SaiyansKing
  • Loading branch information
lucifer602288 authored Oct 24, 2022
2 parents fd24213 + 7d7116b commit d81dd50
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 24 deletions.
15 changes: 0 additions & 15 deletions D3D11Engine/D3D11GraphicsEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5196,21 +5196,6 @@ D3D11ENGINE_RENDER_STAGE D3D11GraphicsEngine::GetRenderingStage() {

/** Draws a VOB (used for inventory) */
void D3D11GraphicsEngine::DrawVobSingle( VobInfo* vob, zCCamera& camera ) {
#if defined(BUILD_GOTHIC_1_08k) && !defined(BUILD_1_12F)
// System Pack Animated_Inventory workaround
XMMATRIX worldMatrix = vob->Vob->GetWorldMatrixXM();
const uint32_t mask = _mm_movemask_epi8( _mm_packs_epi32(
_mm_castps_si128( _mm_cmpord_ps( worldMatrix.r[0], worldMatrix.r[1] ) ),
_mm_castps_si128( _mm_cmpord_ps( worldMatrix.r[2], worldMatrix.r[3] ) )
) );
if ( mask != 0xFFFF ) { // Check whether there are any NAN's in the mask
// Sometimes items position doesn't get initialized properly
// let's just call RotateForInventory to restart them
reinterpret_cast<void( __fastcall* )( zCVob*, int, int )>( 0x672560 )( vob->Vob, 0, 1 );
return;
}
#endif

Engine::GAPI->SetViewTransformXM( XMLoadFloat4x4( &camera.GetTransformDX( zCCamera::ETransformType::TT_VIEW ) ) );
GetContext()->OMSetRenderTargets( 1, HDRBackBuffer->GetRenderTargetView().GetAddressOf(),
DepthStencilBuffer->GetDepthStencilView().Get() );
Expand Down
3 changes: 3 additions & 0 deletions D3D11Engine/GothicAPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,9 @@ void GothicAPI::OnGameStart() {

UpdateMTResourceManager();

#if defined(BUILD_GOTHIC_1_08k) && !defined(BUILD_1_12F)
HookedFunctions::OriginalFunctions.InitAnimatedInventoryHooks();
#endif
void RegisterBinkPlayerHooks();
RegisterBinkPlayerHooks();
}
Expand Down
22 changes: 22 additions & 0 deletions D3D11Engine/GothicMemoryLocations.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,28 @@ static void PatchAddr( unsigned int adr, const T( &v )[n] ) {
}
}

static void PatchCall( unsigned int adr, unsigned int func ) {
DWORD dwOldProtect, dwNewProtect, dwNewCall;
dwNewCall = func - adr - 5;
if ( VirtualProtect( reinterpret_cast<void*>(adr), 5, PAGE_EXECUTE_READWRITE, &dwOldProtect ) ) {
*reinterpret_cast<BYTE*>(adr) = 0xE8;
*reinterpret_cast<DWORD*>(adr + 1) = dwNewCall;
VirtualProtect( reinterpret_cast<void*>(adr), 5, dwOldProtect, &dwNewProtect );
FlushInstructionCache( GetCurrentProcess(), reinterpret_cast<void*>(adr), 5 );
}
}

static void PatchJMP( unsigned int adr, unsigned int jmp ) {
DWORD dwOldProtect, dwNewProtect, dwNewCall;
dwNewCall = jmp - adr - 5;
if ( VirtualProtect( reinterpret_cast<void*>(adr), 5, PAGE_EXECUTE_READWRITE, &dwOldProtect ) ) {
*reinterpret_cast<BYTE*>(adr) = 0xE9;
*reinterpret_cast<DWORD*>(adr + 1) = dwNewCall;
VirtualProtect( reinterpret_cast<void*>(adr), 5, dwOldProtect, &dwNewProtect );
FlushInstructionCache( GetCurrentProcess(), reinterpret_cast<void*>(adr), 5 );
}
}

#define INST_NOP 0x90
#define REPLACE_OP(addr, op) {unsigned char* a = (unsigned char*)addr; *a = op;}
#define REPLACE_RANGE(start, end_incl, op) {for(int i=start; i<=end_incl;i++){REPLACE_OP(i, op);}}
Expand Down
42 changes: 42 additions & 0 deletions D3D11Engine/HookedFunctions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -417,3 +417,45 @@ FARPROC WINAPI HookedFunctionInfo::hooked_GetProcAddress( HMODULE mod, const cha
}
return GetProcAddress( mod, procName );
}

#if defined(BUILD_GOTHIC_1_08k) && !defined(BUILD_1_12F)
void HookedFunctionInfo::InitAnimatedInventoryHooks() {
if ( *reinterpret_cast<BYTE*>(0x67303D) != 0xD8 ) {
// Remove Animated_Inventory SystemPack memory jump and insert our function instead that doesn't fuckup items world matrix
PatchAddr( 0x67303D, "\xD8\x1D\xA4\x08\x7D\x00" );
DWORD FixAnimation = reinterpret_cast<DWORD>(VirtualAlloc( nullptr, 32, (MEM_RESERVE | MEM_COMMIT), PAGE_EXECUTE_READWRITE ));
if ( FixAnimation ) {
PatchAddr( FixAnimation, "\x8B\xCF\xE8\x00\x00\x00\x00\xE9\x00\x00\x00\x00\x6A\x01\x8B\xCF\xE8\x00\x00\x00\x00\xE9\x00\x00\x00\x00" );
PatchCall( FixAnimation + 2, reinterpret_cast<DWORD>(&HookedFunctionInfo::hooked_RotateInInventory) );
PatchCall( FixAnimation + 16, 0x672560 );
PatchJMP( FixAnimation + 7, 0x673053 );
PatchJMP( FixAnimation + 21, 0x673053 );
PatchJMP( 0x673049, FixAnimation );
PatchJMP( 0x67304E, FixAnimation + 12 );
PatchAddr( 0x673048, "\x0F\x8A" );
}
}
}

void __fastcall HookedFunctionInfo::hooked_RotateInInventory( DWORD oCItem ) {
// Call RotateForInventory to reset world matrix
reinterpret_cast<void( __thiscall* )( DWORD, int )>( 0x672560 )( oCItem, 1 );

float rotAxis[3] = { 0.f, 0.f, 0.f };
float* bbox3d = reinterpret_cast<float*>(oCItem + 0x7C);

float val = -1.f;
int index = 0;
for ( int i = 0; i < 3; ++i ) {
float v = (bbox3d[i + 3] - bbox3d[i]);
if ( v > val ) {
val = v;
index = i;
}
}
rotAxis[index] = 1.f;

// Call RotateLocal to rotate item world matrix
reinterpret_cast<void( __thiscall* )( DWORD, float*, float )>( 0x5EE100 )( oCItem, rotAxis, 20.f * (*reinterpret_cast<float*>(0x8CF1F0) / 1000.f) );
}
#endif
5 changes: 5 additions & 0 deletions D3D11Engine/HookedFunctions.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,11 @@ struct HookedFunctionInfo {
static void __fastcall hooked_SetLightmap( void* polygonPtr );

static FARPROC WINAPI hooked_GetProcAddress( HMODULE mod, const char* procName );

#if defined(BUILD_GOTHIC_1_08k) && !defined(BUILD_1_12F)
void InitAnimatedInventoryHooks();
static void __fastcall hooked_RotateInInventory( DWORD oCItem );
#endif
};

namespace HookedFunctions {
Expand Down
3 changes: 0 additions & 3 deletions D3D11Engine/Shaders/VS_Lines_XYZRHW.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,6 @@ float4 TransformXYZRHW(float4 xyzrhw)
ndc.y = 1 - ((2 * (xyzrhw.y - V_ViewportPos.y)) / V_ViewportSize.y);
ndc.z = xyzrhw.z;

// Remove the stupid half-pixel offset from pre D3D10
ndc.xy -= 0.5f / V_ViewportSize;

// Convert to clip-space. rhw is actually 1/w ("reciprocal"). So to undo the devide by w, devide by the given 1/w.
float actualW = 1.0f / xyzrhw.w;
float3 clipSpace = ndc.xyz * actualW;
Expand Down
3 changes: 0 additions & 3 deletions D3D11Engine/Shaders/VS_TransformedEx.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,6 @@ float4 TransformXYZRHW(float4 xyzrhw)
ndc.y = 1 - ((2 * (xyzrhw.y - V_ViewportPos.y)) / V_ViewportSize.y);
ndc.z = xyzrhw.z;

// Remove the stupid half-pixel offset from pre D3D10
ndc.xy -= 0.5f / V_ViewportSize;

// Convert to clip-space. rhw is actually 1/w ("reciprocal"). So to undo the devide by w, devide by the given 1/w.
float actualW = 1.0f / xyzrhw.w;
float3 clipSpace = ndc.xyz * actualW;
Expand Down
3 changes: 0 additions & 3 deletions D3D11Engine/Shaders/VS_XYZRHW_DIF_T1.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,6 @@ float4 TransformXYZRHW(float4 xyzrhw)
ndc.y = 1 - ((2 * (xyzrhw.y - V_ViewportPos.y)) / V_ViewportSize.y);
ndc.z = xyzrhw.z;

// Remove the stupid half-pixel offset from pre D3D10
ndc.xy -= 0.5f / V_ViewportSize;

// Convert to clip-space. rhw is actually 1/w ("reciprocal"). So to undo the devide by w, devide by the given 1/w.
float actualW = 1.0f / xyzrhw.w;
float3 clipSpace = ndc.xyz * actualW;
Expand Down

0 comments on commit d81dd50

Please # to comment.