Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reverse parts of CustomBuildingDNPipeline #574

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 108 additions & 25 deletions source/game_sa/Pipelines/CustomBuilding/CustomBuildingDNPipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,20 @@
#include "CustomBuildingDNPipeline.h"
#include "CustomCarEnvMapPipeline.h"

uint32& s_Magic1 = StaticRef<uint32, 0xC02C14>();
uint32& s_Magic2 = StaticRef<uint32, 0xC02C18>();

void CCustomBuildingDNPipeline::InjectHooks() {
RH_ScopedClass(CCustomBuildingDNPipeline);
RH_ScopedCategory("Pipelines");

RH_ScopedInstall(ExtraVertColourPluginAttach, 0x5D72E0);
RH_ScopedInstall(pluginExtraVertColourConstructorCB, 0x5D6D10, { .reversed = false });
RH_ScopedInstall(pluginExtraVertColourDestructorCB, 0x5D6D30, { .reversed = false });
RH_ScopedInstall(pluginExtraVertColourStreamReadCB, 0x5D6DE0, { .reversed = false });
RH_ScopedInstall(pluginExtraVertColourStreamWriteCB, 0x5D6D80, { .reversed = false });
RH_ScopedInstall(pluginExtraVertColourStreamGetSizeCB, 0x5D6DC0, { .reversed = false });
RH_ScopedInstall(PreRenderUpdate, 0x5D7200, { .reversed = false });
RH_ScopedInstall(pluginExtraVertColourConstructorCB, 0x5D6D10);
RH_ScopedInstall(pluginExtraVertColourDestructorCB, 0x5D6D30);
RH_ScopedInstall(pluginExtraVertColourStreamReadCB, 0x5D6DE0);
RH_ScopedInstall(pluginExtraVertColourStreamWriteCB, 0x5D6D80);
RH_ScopedInstall(pluginExtraVertColourStreamGetSizeCB, 0x5D6DC0);
RH_ScopedInstall(PreRenderUpdate, 0x5D7200);
RH_ScopedInstall(PreRenderUpdateRpAtomicCB, 0x5D72A0);
RH_ScopedInstall(CreatePipe, 0x5D7100);
RH_ScopedInstall(DestroyPipe, 0x5D5FA0);
Expand All @@ -23,13 +26,22 @@ void CCustomBuildingDNPipeline::InjectHooks() {

// 0x5D72E0
bool CCustomBuildingDNPipeline::ExtraVertColourPluginAttach() {
ms_extraVertColourPluginOffset = -1;
ms_extraVertColourPluginOffset = RpGeometryRegisterPlugin(12, EXTRA_VERTCOLOUR_PLUGIN_ID, pluginExtraVertColourConstructorCB, pluginExtraVertColourDestructorCB, nullptr);
if (ms_extraVertColourPluginOffset == -1) {
if ((ms_extraVertColourPluginOffset = RpGeometryRegisterPlugin(
sizeof(ExtraVertColour),
EXTRA_VERTCOLOUR_PLUGIN_ID,
pluginExtraVertColourConstructorCB,
pluginExtraVertColourDestructorCB,
nullptr
)) == -1) {
return false;
}

if (RpGeometryRegisterPluginStream(EXTRA_VERTCOLOUR_PLUGIN_ID, pluginExtraVertColourStreamReadCB, pluginExtraVertColourStreamWriteCB, pluginExtraVertColourStreamGetSizeCB) < 0) {
if (RpGeometryRegisterPluginStream(
EXTRA_VERTCOLOUR_PLUGIN_ID,
pluginExtraVertColourStreamReadCB,
pluginExtraVertColourStreamWriteCB,
pluginExtraVertColourStreamGetSizeCB
) < 0) {
ms_extraVertColourPluginOffset = -1;
return false;
}
Expand All @@ -38,38 +50,109 @@ bool CCustomBuildingDNPipeline::ExtraVertColourPluginAttach() {
}

// 0x5D6D10
void* CCustomBuildingDNPipeline::pluginExtraVertColourConstructorCB(void* object, int32 offsetInObject, int32 sizeInObject) {
return plugin::CallAndReturn<void*, 0x5D6D10, void*, int32, int32>(object, offsetInObject, sizeInObject);
void* CCustomBuildingDNPipeline::pluginExtraVertColourConstructorCB(void* object, RwInt32 offsetInObject, RwInt32 sizeInObject) {
const auto self = GetExtraVertColourPtr(object);

self->NightColors = self->DayColors = nullptr;
self->Intensity = 0.f;

return object;
}

// 0x5D6D30
void* CCustomBuildingDNPipeline::pluginExtraVertColourDestructorCB(void* object, int32 offsetInObject, int32 sizeInObject) {
return plugin::CallAndReturn<void*, 0x5D6D30, void*, int32, int32>(object, offsetInObject, sizeInObject);
void* CCustomBuildingDNPipeline::pluginExtraVertColourDestructorCB(void* object, RwInt32 offsetInObject, RwInt32 sizeInObject) {
const auto self = GetExtraVertColourPtr(object);

for (const auto ptr : { &self->NightColors, &self->DayColors }) {
CMemoryMgr::Free(*ptr);
*ptr = nullptr;
}

return object;
}

// 0x5D6DE0
RwStream* CCustomBuildingDNPipeline::pluginExtraVertColourStreamReadCB(RwStream* stream, int32 binaryLength, void* object, int32 offsetInObject, int32 sizeInObject) {
return plugin::CallAndReturn<RwStream*, 0x5D6DE0, RwStream*, int32, void*, int32, int32>(stream, binaryLength, object, offsetInObject, sizeInObject);
RwStream* CCustomBuildingDNPipeline::pluginExtraVertColourStreamReadCB(
RwStream* stream,
RwInt32 binaryLength,
void* object,
RwInt32 offsetInObject,
RwInt32 sizeInObject
) {
const auto self = GetExtraVertColourPtr(object);
const auto geo = static_cast<RpGeometry*>(object);

uint32 magicNumber;
VERIFY(RwStreamRead(stream, &magicNumber, sizeof(magicNumber)) != 0);

if (magicNumber) {
const auto numVerts = (size_t)RpGeometryGetNumVertices(geo);

for (const auto ptr : { &self->NightColors, &self->DayColors }) {
*ptr = static_cast<RwRGBA*>(CMemoryMgr::Malloc(sizeof(RwRGBA) * numVerts));
}
self->Intensity = 1.f;

VERIFY(RwStreamRead(stream, self->NightColors, sizeof(RwRGBA) * numVerts) != 0);

if (const auto prelit = RpGeometryGetPreLightColors(geo)) {
rng::copy(std::span{prelit, numVerts}, self->DayColors);
}
}

return stream;
}

// 0x5D6D80
RwStream* CCustomBuildingDNPipeline::pluginExtraVertColourStreamWriteCB(RwStream* stream, int32 binaryLength, const void* object, int32 offsetInObject, int32 sizeInObject) {
return plugin::CallAndReturn<RwStream*, 0x5D6D80, RwStream *, int32, const void*, int32, int32>(stream, binaryLength, object, offsetInObject, sizeInObject);
RwStream* CCustomBuildingDNPipeline::pluginExtraVertColourStreamWriteCB(RwStream* stream, RwInt32 binaryLength, const void* object, RwInt32 offsetInObject, RwInt32 sizeInObject) {
const auto self = GetExtraVertColourPtr(object);
const auto geo = static_cast<const RpGeometry*>(object);

RwStreamWrite(stream, &self->NightColors, sizeof(self->NightColors));
if (self->NightColors) {
RwStreamWrite(stream, self->NightColors, sizeof(RwRGBA) * RpGeometryGetNumVertices(geo));
}
return stream;
}

// 0x5D6DC0
int32 CCustomBuildingDNPipeline::pluginExtraVertColourStreamGetSizeCB(const void* object, int32 offsetInObject, int32 sizeInObject) {
return plugin::CallAndReturn<int32, 0x5D6DC0, const void*, int32, int32>(object, offsetInObject, sizeInObject);
RwInt32 CCustomBuildingDNPipeline::pluginExtraVertColourStreamGetSizeCB(const void* object, RwInt32 offsetInObject, RwInt32 sizeInObject) {
const auto geo = static_cast<const RpGeometry*>(object);

return 2 * sizeof(RwRGBA) * RpGeometryGetNumVertices(geo) /*Day and Night colors*/ + sizeof(ExtraVertColour::Intensity);
}

// 0x5D5FC0
bool AtomicHasNVCPipeline(RpAtomic* atomic) {
return atomic->pipeline == CCustomBuildingDNPipeline::ObjPipeline;
}

// 0x5D6850 [AKA `NVC__Process`]
void NVCPipelineProcess(RpAtomic* a, float DNBalance) {
plugin::Call<0x5D6850>(a, DNBalance);
}

// 0x5D7200
void CCustomBuildingDNPipeline::PreRenderUpdate(RpAtomic* atomic, bool ignoreDNBalanceParam) {
plugin::Call<0x5D7200, RpAtomic*, bool>(atomic, ignoreDNBalanceParam);
void CCustomBuildingDNPipeline::PreRenderUpdate(RpAtomic* a, bool ignoreDNBalanceParam) {
if (!a) {
return;
}
if (!AtomicHasNVCPipeline(a)) {
return;
}
const auto intensity = std::abs(GetExtraVertColourPtr(RpAtomicGetGeometry(a))->Intensity - m_fDNBalanceParam);
if (intensity <= 0.01f && !ignoreDNBalanceParam) {
return;
}
if (((uint32)a / 0x70) % 16 != s_Magic1 && !s_Magic2 && !ignoreDNBalanceParam && intensity <= 0.3f) {
return;
}
NVCPipelineProcess(a, m_fDNBalanceParam);
}

// 0x5D72A0
RpAtomic* CCustomBuildingDNPipeline::PreRenderUpdateRpAtomicCB(RpAtomic* atomic, void* data) {
PreRenderUpdate(atomic, reinterpret_cast<bool*>(data));
PreRenderUpdate(atomic, *reinterpret_cast<bool*>(data));
return atomic;
}

Expand Down Expand Up @@ -152,8 +235,8 @@ void CCustomBuildingDNPipeline::CustomPipeRenderCB(RwResEntry* entry, void* obje
}

// 0x5D6E90
void* CCustomBuildingDNPipeline::GetExtraVertColourPtr(RpGeometry* geometry) {
return *RWPLUGINOFFSET(void*, geometry, ms_extraVertColourPluginOffset); // todo: return type
ExtraVertColour* CCustomBuildingDNPipeline::GetExtraVertColourPtr(const void* geometry) {
return RWPLUGINOFFSET(ExtraVertColour, geometry, ms_extraVertColourPluginOffset);
}

void CCustomBuildingDNPipeline::SetFxEnvTexture(RpMaterial* material, RwTexture* texture) {
Expand Down
21 changes: 14 additions & 7 deletions source/game_sa/Pipelines/CustomBuilding/CustomBuildingDNPipeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,16 @@

struct RxOpenGLMeshInstanceData;

constexpr auto EXTRA_VERTCOLOUR_PLUGIN_ID = 0x253F2F9;
constexpr auto EXTRA_VERTCOLOUR_PLUGIN_ID = MAKECHUNKID(rwVENDORID_DEVELOPER, 0xF9);
constexpr auto CUSTOM_BUILDING_DN_PIPELINE_ID = 0x0;

//! Extra Vertex Colour plugin data [Inside RpGeometry]
struct ExtraVertColour { // AKA `gtaVertexColorPlugin`
RwRGBA *NightColors, *DayColors; // heap allocated
float Intensity;
};
VALIDATE_SIZE(ExtraVertColour, 12); // 24 on Android

class CCustomBuildingDNPipeline {
public:
static inline float& m_fDNBalanceParam = *(float*)0x8D12C0; // 1.0f
Expand All @@ -30,16 +37,16 @@ class CCustomBuildingDNPipeline {
static void PreRenderUpdate(RpAtomic* atomic, bool ignoreDNBalanceParam);
static RpAtomic* PreRenderUpdateRpAtomicCB(RpAtomic* atomic, void* data);

static void* pluginExtraVertColourConstructorCB(void* object, int32 offsetInObject, int32 sizeInObject);
static void* pluginExtraVertColourDestructorCB(void* object, int32 offsetInObject, int32 sizeInObject);
static RwStream* pluginExtraVertColourStreamReadCB(RwStream* stream, int32 binaryLength, void* object, int32 offsetInObject, int32 sizeInObject);
static RwStream* pluginExtraVertColourStreamWriteCB(RwStream* stream, int32 binaryLength, const void* object, int32 offsetInObject, int32 sizeInObject);
static int32 pluginExtraVertColourStreamGetSizeCB(const void* object, int32 offsetInObject, int32 sizeInObject);
static void* pluginExtraVertColourConstructorCB(void* object, RwInt32 offsetInObject, RwInt32 sizeInObject);
static void* pluginExtraVertColourDestructorCB(void* object, RwInt32 offsetInObject, RwInt32 sizeInObject);
static RwStream* pluginExtraVertColourStreamReadCB(RwStream* stream, RwInt32 binaryLength, void* object, RwInt32 offsetInObject, RwInt32 sizeInObject);
static RwStream* pluginExtraVertColourStreamWriteCB(RwStream* stream, RwInt32 binaryLength, const void* object, RwInt32 offsetInObject, RwInt32 sizeInObject);
static RwInt32 pluginExtraVertColourStreamGetSizeCB(const void* object, RwInt32 offsetInObject, RwInt32 sizeInObject);

static RpMaterial* CustomPipeMaterialSetup(RpMaterial* material, void* a2);
static void CustomPipeRenderCB(RwResEntry* entry, void* object, uint8 type, uint32 flags);

static void* GetExtraVertColourPtr(RpGeometry* geometry);
static ExtraVertColour* GetExtraVertColourPtr(const void* geometry);

static RwTexture* GetFxEnvTexture(RpMaterial* material);
static void SetFxEnvTexture(RpMaterial* material, RwTexture* texture);
Expand Down
Loading