diff --git a/nier.cpp b/nier.cpp new file mode 100644 index 0000000..c02f28c --- /dev/null +++ b/nier.cpp @@ -0,0 +1,238 @@ +#define _CRT_SECURE_NO_WARNINGS + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include + + +sk::ParameterFactory far_factory; +iSK_INI* far_prefs = nullptr; +sk::ParameterInt* far_gi_workgroups = nullptr; + + +// (Presumable) Size of compute shader workgroup +int __FAR_GlobalIllumWorkGroupSize = 128; + +extern void +__stdcall +SK_SetPluginName (std::wstring name); + +#define FAR_VERSION_NUM L"0.1.0" +#define FAR_VERSION_STR L"FAR v " FAR_VERSION_NUM + + +typedef HRESULT (WINAPI *D3D11Dev_CreateBuffer_pfn)( + _In_ ID3D11Device *This, + _In_ const D3D11_BUFFER_DESC *pDesc, + _In_opt_ const D3D11_SUBRESOURCE_DATA *pInitialData, + _Out_opt_ ID3D11Buffer **ppBuffer +); +typedef HRESULT (WINAPI *D3D11Dev_CreateShaderResourceView_pfn)( + _In_ ID3D11Device *This, + _In_ ID3D11Resource *pResource, + _In_opt_ const D3D11_SHADER_RESOURCE_VIEW_DESC *pDesc, + _Out_opt_ ID3D11ShaderResourceView **ppSRView +); + +static D3D11Dev_CreateBuffer_pfn D3D11Dev_CreateBuffer_Original; +static D3D11Dev_CreateShaderResourceView_pfn D3D11Dev_CreateShaderResourceView_Original; + +extern +HRESULT +WINAPI +D3D11Dev_CreateBuffer_Override ( + _In_ ID3D11Device *This, + _In_ const D3D11_BUFFER_DESC *pDesc, + _In_opt_ const D3D11_SUBRESOURCE_DATA *pInitialData, + _Out_opt_ ID3D11Buffer **ppBuffer ); + +extern +HRESULT +WINAPI +D3D11Dev_CreateShaderResourceView_Override ( + _In_ ID3D11Device *This, + _In_ ID3D11Resource *pResource, + _In_opt_ const D3D11_SHADER_RESOURCE_VIEW_DESC *pDesc, + _Out_opt_ ID3D11ShaderResourceView **ppSRView ); + + +unsigned int +__stdcall +SK_FAR_CheckVersionThread (LPVOID user) +{ + UNREFERENCED_PARAMETER (user); + + extern bool + __stdcall + SK_FetchVersionInfo (const wchar_t* wszProduct); + + if (SK_FetchVersionInfo (L"FAR")) { + extern HRESULT + __stdcall + SK_UpdateSoftware (const wchar_t* wszProduct); + + SK_UpdateSoftware (L"FAR"); + } + + CloseHandle (GetCurrentThread ()); + + return 0; +} + +HRESULT +WINAPI +SK_FAR_CreateBuffer ( + _In_ ID3D11Device *This, + _In_ const D3D11_BUFFER_DESC *pDesc, + _In_opt_ const D3D11_SUBRESOURCE_DATA *pInitialData, + _Out_opt_ ID3D11Buffer **ppBuffer ) +{ + if ( pDesc != nullptr && pDesc->StructureByteStride == 96 && + pDesc->ByteWidth == 96 * 128 ) + { + D3D11_BUFFER_DESC new_desc = *pDesc; + + new_desc.ByteWidth = 96 * __FAR_GlobalIllumWorkGroupSize; + + return D3D11Dev_CreateBuffer_Original (This, &new_desc, pInitialData, ppBuffer); + } + + return D3D11Dev_CreateBuffer_Original (This, pDesc, pInitialData, ppBuffer); +} + +HRESULT +WINAPI +SK_FAR_CreateShaderResourceView ( + _In_ ID3D11Device *This, + _In_ ID3D11Resource *pResource, + _In_opt_ const D3D11_SHADER_RESOURCE_VIEW_DESC *pDesc, + _Out_opt_ ID3D11ShaderResourceView **ppSRView ) +{ + if ( pDesc != nullptr && pDesc->ViewDimension == D3D_SRV_DIMENSION_BUFFEREX && + pDesc->BufferEx.NumElements == 128 ) + { + CComPtr pBuf; + + if ( SUCCEEDED ( + pResource->QueryInterface (__uuidof (ID3D11Buffer), (void **)&pBuf) + ) + ) + { + D3D11_SHADER_RESOURCE_VIEW_DESC new_desc = *pDesc; + D3D11_BUFFER_DESC buf_desc; + + pBuf->GetDesc (&buf_desc); + + if (buf_desc.ByteWidth == 96 * __FAR_GlobalIllumWorkGroupSize) + new_desc.BufferEx.NumElements = __FAR_GlobalIllumWorkGroupSize; + + return D3D11Dev_CreateShaderResourceView_Original (This, pResource, &new_desc, ppSRView); + } + } + + return D3D11Dev_CreateShaderResourceView_Original (This, pResource, pDesc, ppSRView); +} + +void +SK_FAR_InitPlugin (void) +{ + if (! SK_IsInjected ()) + _beginthreadex ( nullptr, + 0, + SK_FAR_CheckVersionThread, + nullptr, + 0x00, + nullptr ); + + SK_SetPluginName (FAR_VERSION_STR); + + SK_CreateFuncHook ( L"ID3D11Device::CreateBuffer", + D3D11Dev_CreateBuffer_Override, + SK_FAR_CreateBuffer, + (LPVOID *)&D3D11Dev_CreateBuffer_Original ); + MH_QueueEnableHook (D3D11Dev_CreateBuffer_Override); + + SK_CreateFuncHook ( L"ID3D11Device::CreateShaderResourceView", + D3D11Dev_CreateShaderResourceView_Override, + SK_FAR_CreateShaderResourceView, + (LPVOID *)&D3D11Dev_CreateShaderResourceView_Original ); + MH_QueueEnableHook (D3D11Dev_CreateShaderResourceView_Override); + + MH_ApplyQueued (); + + + if (far_prefs == nullptr) + { + wchar_t far_prefs_file [MAX_PATH] = { L'\0' }; + + lstrcatW (far_prefs_file, SK_GetConfigPath ()); + lstrcatW (far_prefs_file, L"FAR.ini"); + + far_prefs = new iSK_INI (far_prefs_file); + far_prefs->parse (); + + far_gi_workgroups = + static_cast + (far_factory.create_parameter (L"Global Illumination Compute Shader Workgroups")); + + far_gi_workgroups->register_to_ini ( far_prefs, + L"FAR.Lighting", + L"GlobalIlluminationWorkgroups" ); + + if ( far_prefs->get_section (L"FAR.Lighting").contains_key (L"GlobalIlluminationWorkgroups") ) + __FAR_GlobalIllumWorkGroupSize = far_gi_workgroups->get_value (); + + far_gi_workgroups->set_value (__FAR_GlobalIllumWorkGroupSize); + far_gi_workgroups->store (); + + far_prefs->write (far_prefs_file); + + + SK_GetCommandProcessor ()->AddVariable ("FAR.GIWorkgroups", SK_CreateVar (SK_IVariable::Int, &__FAR_GlobalIllumWorkGroupSize)); + } +} + +// Not currently used +bool +WINAPI +SK_FAR_ShutdownPlugin (const wchar_t* backend) +{ + UNREFERENCED_PARAMETER (backend); + + return true; +} + + +void +__stdcall +SK_FAR_ControlPanel (void) +{ + if (ImGui::CollapsingHeader("NieR: Automata")) + { + if (ImGui::SliderInt ("Global Illumination Workgroup Size", &__FAR_GlobalIllumWorkGroupSize, 0, 128)) + { + if (__FAR_GlobalIllumWorkGroupSize % 16 > 0) + __FAR_GlobalIllumWorkGroupSize += 16 - (__FAR_GlobalIllumWorkGroupSize % 16); + } + } +} + +bool +__stdcall +SK_FAR_IsPlugIn (void) +{ + return far_prefs != nullptr; +} \ No newline at end of file