Skip to content

Commit

Permalink
Merge branch 'master' of github.com:yamashi/CyberEngineTweaks
Browse files Browse the repository at this point in the history
  • Loading branch information
maximegmd committed Jan 3, 2021
2 parents 11928b4 + b6e5462 commit 322e0b6
Show file tree
Hide file tree
Showing 8 changed files with 391 additions and 60 deletions.
2 changes: 2 additions & 0 deletions src/overlay/Overlay_D3D12.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,8 @@ bool Overlay::InitializeD3D12Downlevel(ID3D12CommandQueue* pCommandQueue, ID3D12
}

m_pCommandQueue = pCommandQueue;
m_outWidth = static_cast<UINT>(pSourceTex2D->GetDesc().Width);
m_outHeight = pSourceTex2D->GetDesc().Height;

if (hWindow != m_hWnd)
spdlog::warn("Overlay::InitializeD3D12Downlevel() - current output window does not match hooked window! Currently hooked to {0} while current output window is {1}.", reinterpret_cast<void*>(m_hWnd), reinterpret_cast<void*>(hWindow));
Expand Down
26 changes: 7 additions & 19 deletions src/overlay/Overlay_Hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,27 +173,15 @@ HRESULT Overlay::PresentD3D12Downlevel(ID3D12CommandQueueDownlevel* pCommandQueu
{
auto& overlay = Get();

// On Windows 7 there is no swap chain to query the current backbuffer index. Instead do a reverse lookup in the known backbuffer list
const auto it = std::find(overlay.m_downlevelBackbuffers.cbegin(), overlay.m_downlevelBackbuffers.cend(), pSourceTex2D);
bool resizing = false;
if (it == overlay.m_downlevelBackbuffers.cend())
{
if (overlay.m_initialized)
{
spdlog::warn("Overlay::PresentD3D12Downlevel() - buffer at {0} not found in backbuffer list! Assuming window was resized - note that support for resizing is experimental.", (void*)pSourceTex2D);
overlay.ResetD3D12State();
}
// On Windows 7 there is no swap chain to query the current backbuffer index, so instead we simply count to 3 and wrap around.
// Increment the buffer index here even if the overlay is not enabled, so we stay in sync with the game's present calls.
// TODO: investigate if there isn't a better way of doing this (finding the current index in the game exe?)
overlay.m_downlevelBufferIndex = (!overlay.m_initialized || overlay.m_downlevelBufferIndex == 2) ? 0 : overlay.m_downlevelBufferIndex + 1;

overlay.m_downlevelBackbuffers.emplace_back(pSourceTex2D);

// If we don't have a full backbuffer list, do not attempt to reinitialize yet
resizing = overlay.m_downlevelBackbuffers.size() < 3;
}
else
overlay.m_downlevelBufferIndex = static_cast<uint32_t>(std::distance(overlay.m_downlevelBackbuffers.cbegin(), it));

if (!resizing && overlay.InitializeD3D12Downlevel(overlay.m_pCommandQueue, pSourceTex2D, hWindow))
if (overlay.InitializeD3D12Downlevel(overlay.m_pCommandQueue, pSourceTex2D, hWindow))
{
overlay.Render();
}

return overlay.m_realPresentD3D12Downlevel(pCommandQueueDownlevel, pOpenCommandList, pSourceTex2D, hWindow, Flags);
}
Expand Down
4 changes: 3 additions & 1 deletion src/reverse/Converter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "Converter.h"

#include "BasicTypes.h"
#include "Enum.h"
#include "LuaRED.h"

auto s_metaVisitor = [](auto... args) {
Expand All @@ -24,7 +25,8 @@ auto s_metaVisitor = [](auto... args) {
LuaRED<EulerAngles, "EulerAngles">(),
LuaRED<ItemID, "gameItemID">(),
LuaRED<TweakDBID, "TweakDBID">(),
LuaRED<CName, "CName">()
LuaRED<CName, "CName">(),
LuaRED<Enum, "Enum">()
);

size_t Converter::Size(RED4ext::IRTTIType* apRtti)
Expand Down
139 changes: 139 additions & 0 deletions src/reverse/Enum.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
#include <stdafx.h>

#include "Enum.h"

Enum::Enum(const RED4ext::CStackType& stackType)
{
Get(stackType);
}

Enum::Enum(const std::string& typeName, const std::string& value)
{
auto* pType = static_cast<RED4ext::CEnum*>(RED4ext::CRTTISystem::Get()->GetEnum(RED4ext::FNV1a(typeName.c_str())));
if (pType)
{
m_type = pType;
SetValueByName(value);
}
}

Enum::Enum(const std::string& typeName, uint32_t value)
{
auto* pType = static_cast<RED4ext::CEnum*>(RED4ext::CRTTISystem::Get()->GetEnum(RED4ext::FNV1a(typeName.c_str())));
if (pType)
{
m_type = pType;
SetValueSafe(static_cast<uint32_t>(value));
}
}


Enum::Enum(const RED4ext::CEnum* pType, const std::string& value)
: m_type(pType)
{
SetValueByName(value);
}


Enum::Enum(const RED4ext::CEnum* pType, uint32_t value)
: m_type(pType)
{
SetValueSafe(static_cast<uint32_t>(value));
}

void Enum::SetValueSafe(uint64_t value)
{
for (auto i = 0; i < m_type->valueList.size; ++i)
{
if (m_type->valueList[i] == value)
{
m_value = value;
break;
}
}
}

void Enum::Get(const RED4ext::CStackType& stackType)
{
m_type = static_cast<RED4ext::CEnum*>(stackType.type);
switch (stackType.type->GetSize())
{
case sizeof(uint8_t) :
m_value = *static_cast<uint8_t*>(stackType.value);
break;
case sizeof(uint16_t):
m_value = *static_cast<uint16_t*>(stackType.value);
break;
case sizeof(uint32_t):
m_value = *static_cast<uint32_t*>(stackType.value);
break;
case sizeof(uint64_t):
m_value = *static_cast<uint64_t*>(stackType.value);
break;
}
}

void Enum::Set(RED4ext::CStackType& stackType, TiltedPhoques::Allocator* apAllocator)
{
stackType.type = const_cast<RED4ext::CEnum*>(m_type); // Sad cast
switch (m_type->GetSize())
{
case sizeof(uint8_t):
stackType.value = apAllocator->New<uint8_t>(static_cast<uint8_t>(m_value));
break;
case sizeof(uint16_t):
stackType.value = apAllocator->New<uint16_t>(static_cast<uint16_t>(m_value));
break;
case sizeof(uint32_t):
stackType.value = apAllocator->New<uint32_t>(static_cast<uint32_t>(m_value));
break;
case sizeof(uint64_t):
stackType.value = apAllocator->New<uint64_t>(static_cast<uint64_t>(m_value));
break;
}
}


std::string Enum::GetValueName() const
{
for (auto i = 0; i < m_type->valueList.size; ++i)
{
if (m_type->valueList[i] == m_value)
{
return RED4ext::CName(m_type->hashList[i]).ToString();
}
}

return "";
}


void Enum::SetValueByName(const std::string& value)
{
for (auto i = 0; i < m_type->hashList.size; ++i)
{
if (m_type->hashList[i] == RED4ext::FNV1a(value.c_str()))
{
m_value = m_type->valueList[i];
break;
}
}
}

std::string Enum::ToString() const
{
if (m_type)
{
RED4ext::CName name;
m_type->GetName(name);
return name.ToString() + std::string(" : ") + GetValueName() + std::string(" (") + std::to_string(m_value) + std::string(")");
}

return "Invalid enum";
}

const RED4ext::CEnum* Enum::GetType() const
{
return m_type;
}

106 changes: 106 additions & 0 deletions src/reverse/Enum.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#pragma once

#include "LuaRED.h"

struct Enum
{
Enum(const RED4ext::CEnum*, const std::string& value);
Enum(const RED4ext::CEnum*, uint32_t value);
Enum(const RED4ext::CStackType& stackType);
Enum(const std::string& typeName, const std::string& value);
Enum(const std::string& typeName, uint32_t value);

void Get(const RED4ext::CStackType& stackType);
void Set(RED4ext::CStackType& stackType, TiltedPhoques::Allocator* apAllocator);

// Returns the enum value by name
std::string GetValueName() const;

// Sets value by name in the enum list
void SetValueByName(const std::string& value);

// Sets by value verified against enum list
void SetValueSafe(uint64_t value);

std::string ToString() const;

const RED4ext::CEnum* GetType() const;

protected:
const RED4ext::CEnum* m_type{ nullptr };
uint64_t m_value{ 0 };
};

template<>
struct LuaRED<Enum, "Enum">
{
sol::object ToLua(RED4ext::CStackType& aResult, sol::state_view aLua)
{
return make_object(aLua, Enum(aResult));
}

RED4ext::CStackType ToRED(sol::object aObject, RED4ext::IRTTIType* apRtti, TiltedPhoques::Allocator* apAllocator)
{
RED4ext::CStackType result;
if (aObject.is<Enum>())
{
auto* pEnum = aObject.as<Enum*>();
if (pEnum->GetType() == apRtti)
{
pEnum->Set(result, apAllocator);
}
else // The enum type we were passed isn't the same
{
result.type = apRtti;
result.value = nullptr;
}
}
else if (aObject.get_type() == sol::type::number) // Enum from number cast
{
auto* enumType = static_cast<RED4ext::CEnum*>(apRtti);
if (aObject != sol::nil)
{
Enum en(enumType, aObject.as<uint32_t>());
en.Set(result, apAllocator);
}
}
else if (aObject.get_type() == sol::type::string) // Enum from string cast
{
auto* enumType = static_cast<RED4ext::CEnum*>(apRtti);
if (aObject != sol::nil)
{
sol::state_view v(aObject.lua_state());
std::string str = v["tostring"](aObject);
Enum en(enumType, str);
en.Set(result, apAllocator);
}
}
else
{
// Probably not going to like this but ok
result.type = apRtti;
result.value = nullptr;
}

return result;
}

size_t Size() const noexcept
{
return m_pRtti ? m_pRtti->GetSize() : 0;
}

bool Is(RED4ext::IRTTIType* apRtti) const
{
if (apRtti->GetType() == RED4ext::ERTTIType::Enum)
{
m_pRtti = apRtti;
return true;
}

return false;
}

private:
mutable RED4ext::IRTTIType* m_pRtti{ nullptr };
};
63 changes: 48 additions & 15 deletions src/reverse/Type.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <stdafx.h>
#include <spdlog/fmt/fmt.h>

#include "Type.h"

Expand All @@ -14,6 +15,11 @@ std::string Type::Descriptor::ToString() const
{
result += "\t\t" + function + ",\n";
}
result += "},\n\tstaticFunctions: {\n";
for (auto& function : staticFunctions)
{
result += "\t\t" + function + ",\n";
}
result += "},\nproperties: {\n";
for (auto& property : properties)
{
Expand Down Expand Up @@ -57,8 +63,21 @@ sol::protected_function Type::InternalIndex(const std::string& acName)
auto* pFunc = m_pType->GetFunction(RED4ext::FNV1a(acName.c_str()));
if(!pFunc)
{
Overlay::Get().Log("Function '" + acName + "' not found in system '" + GetName() + "'.");
return sol::nil;
// Search the function table if it isn't found, the above function only searches by ShortName so overloads are not found
for (uint32_t i = 0; i < m_pType->funcs.size; ++i)
{
if (m_pType->funcs.entries[i]->name.hash == RED4ext::FNV1a(acName.c_str()))
{
pFunc = static_cast<RED4ext::CClassFunction*>(m_pType->funcs.entries[i]);
break;
}
}

if (!pFunc)
{
Overlay::Get().Log("Function '" + acName + "' not found in system '" + GetName() + "'.");
return sol::nil;
}
}

auto obj = make_object(m_lua, [pFunc, name = acName](Type* apType, sol::variadic_args args, sol::this_environment env, sol::this_state L)
Expand Down Expand Up @@ -98,21 +117,35 @@ Type::Descriptor Type::Dump() const
{
descriptor.name = m_pType->name.ToString();

for (auto i = 0u; i < m_pType->funcs.size; ++i)
RED4ext::CClass* type = m_pType;
while (type)
{
auto* pFunc = m_pType->funcs[i];
std::string funcName = pFunc->name.ToString();
descriptor.functions.push_back(funcName);
}
std::string name = type->name.ToString();
for (auto i = 0u; i < type->funcs.size; ++i)
{
auto* pFunc = type->funcs[i];
std::string funcName = "Owner:(" + name + ") Hash:" + pFunc->name.ToString() + " Hash:( " + fmt::format("{:016x}", pFunc->name.hash) + ") / ShortName:(" + pFunc->name2.ToString() + ") Hash:( " + fmt::format("{:016x}", pFunc->name2.hash) + ")";
descriptor.functions.push_back(funcName);
}

for (auto i = 0u; i < m_pType->props.size; ++i)
{
auto* pProperty = m_pType->props[i];
RED4ext::CName name;
pProperty->type->GetName(name);

std::string propName = std::string(pProperty->name.ToString()) + " : " + name.ToString();
descriptor.properties.push_back(propName);
for (auto i = 0u; i < type->staticFuncs.size; ++i)
{
auto* pFunc = type->staticFuncs[i];
std::string funcName = "Owner:(" + name + ") Hash:" + pFunc->name.ToString() + " Hash:( " + fmt::format("{:016x}", pFunc->name.hash) + ") / ShortName:(" + pFunc->name2.ToString() + ") Hash:( " + fmt::format("{:016x}", pFunc->name2.hash) + ")";
descriptor.staticFunctions.push_back(funcName);
}

for (auto i = 0u; i < type->props.size; ++i)
{
auto* pProperty = type->props[i];
RED4ext::CName name;
pProperty->type->GetName(name);

std::string propName = std::string(pProperty->name.ToString()) + " : " + name.ToString();
descriptor.properties.push_back(propName);
}

type = type->parent && type->parent->GetType() == RED4ext::ERTTIType::Class ? type->parent : nullptr;
}
}

Expand Down
Loading

0 comments on commit 322e0b6

Please sign in to comment.