#include "STDInclude.hpp" namespace Components { Utils::Hook Renderer::DrawFrameHook; Utils::Signal Renderer::FrameSignal; Utils::Signal Renderer::FrameOnceSignal; Utils::Signal Renderer::BackendFrameSignal; Utils::Signal Renderer::EndRecoverDeviceSignal; Utils::Signal Renderer::BeginRecoverDeviceSignal; __declspec(naked) void Renderer::FrameStub() { __asm { pushad call Renderer::FrameHandler popad jmp Renderer::DrawFrameHook.original } } void Renderer::FrameHandler() { Renderer::FrameSignal(); auto copy = Renderer::FrameOnceSignal; Renderer::FrameOnceSignal.clear(); copy(); } __declspec(naked) void Renderer::BackendFrameStub() { __asm { pushad call Renderer::BackendFrameHandler popad mov eax, ds:66E1BF0h mov ecx, 536A85h jmp ecx } } void Renderer::BackendFrameHandler() { IDirect3DDevice9* device = *Game::dx_ptr; if (device) { device->AddRef(); Renderer::BackendFrameSignal(device); device->Release(); } } void Renderer::Once(Utils::Slot callback) { Renderer::FrameOnceSignal.connect(callback); } void Renderer::OnFrame(Utils::Slot callback) { Renderer::FrameSignal.connect(callback); } void Renderer::OnBackendFrame(Utils::Slot callback) { Renderer::BackendFrameSignal.connect(callback); } void Renderer::OnDeviceRecoveryEnd(Utils::Slot callback) { Renderer::EndRecoverDeviceSignal.connect(callback); } void Renderer::OnDeviceRecoveryBegin(Utils::Slot callback) { Renderer::BeginRecoverDeviceSignal.connect(callback); } int Renderer::Width() { return Utils::Hook::Get(0x66E1C68); } int Renderer::Height() { return Utils::Hook::Get(0x66E1C6C); } Renderer::Renderer() { // Renderer::OnBackendFrame([] (IDirect3DDevice9* device) // { // if (Game::Sys_Milliseconds() % 2) // { // device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL, 0, 0, 0); // } // // return; // // IDirect3DSurface9* buffer = nullptr; // // device->CreateOffscreenPlainSurface(Renderer::Width(), Renderer::Height(), D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &buffer, nullptr); // device->GetFrontBufferData(0, buffer); // // if (buffer) // { // D3DSURFACE_DESC desc; // D3DLOCKED_RECT lockedRect; // // buffer->GetDesc(&desc); // // HRESULT res = buffer->LockRect(&lockedRect, NULL, D3DLOCK_READONLY); // // // buffer->UnlockRect(); // } // }); // Frame hook Renderer::DrawFrameHook.initialize(0x5ACB99, Renderer::FrameStub, HOOK_CALL)->install(); Utils::Hook(0x536A80, Renderer::BackendFrameStub, HOOK_JUMP).install()->quick(); Utils::Hook(0x508298, [] () { Game::DB_BeginRecoverLostDevice(); Renderer::BeginRecoverDeviceSignal(); }, HOOK_CALL).install()->quick(); Utils::Hook(0x508355, [] () { Renderer::EndRecoverDeviceSignal(); Game::DB_EndRecoverLostDevice(); }, HOOK_CALL).install()->quick(); } Renderer::~Renderer() { Renderer::DrawFrameHook.uninstall(); Renderer::BackendFrameSignal.clear(); Renderer::FrameOnceSignal.clear(); Renderer::FrameSignal.clear(); Renderer::EndRecoverDeviceSignal.clear(); Renderer::BeginRecoverDeviceSignal.clear(); } }