2017-01-19 16:23:59 -05:00
|
|
|
#include "STDInclude.hpp"
|
|
|
|
|
|
|
|
namespace Components
|
|
|
|
{
|
|
|
|
Utils::Signal<Renderer::BackendCallback> Renderer::BackendFrameSignal;
|
2017-06-22 16:05:22 -04:00
|
|
|
Utils::Signal<Renderer::BackendCallback> Renderer::SingleBackendFrameSignal;
|
2017-01-19 16:23:59 -05:00
|
|
|
|
2017-05-31 09:45:12 -04:00
|
|
|
Utils::Signal<Scheduler::Callback> Renderer::EndRecoverDeviceSignal;
|
|
|
|
Utils::Signal<Scheduler::Callback> Renderer::BeginRecoverDeviceSignal;
|
2017-04-23 07:31:48 -04:00
|
|
|
|
2017-01-19 16:23:59 -05:00
|
|
|
__declspec(naked) void Renderer::FrameStub()
|
|
|
|
{
|
|
|
|
__asm
|
|
|
|
{
|
|
|
|
pushad
|
2017-05-31 09:45:12 -04:00
|
|
|
call Scheduler::FrameHandler
|
2017-01-19 16:23:59 -05:00
|
|
|
popad
|
2017-01-20 19:52:30 -05:00
|
|
|
|
2017-01-28 06:39:03 -05:00
|
|
|
push 5AC950h
|
|
|
|
retn
|
2017-01-19 16:23:59 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
__declspec(naked) void Renderer::BackendFrameStub()
|
|
|
|
{
|
|
|
|
__asm
|
|
|
|
{
|
|
|
|
pushad
|
|
|
|
call Renderer::BackendFrameHandler
|
|
|
|
popad
|
|
|
|
|
|
|
|
mov eax, ds:66E1BF0h
|
2017-01-28 06:39:03 -05:00
|
|
|
push 536A85h
|
|
|
|
retn
|
2017-01-19 16:23:59 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Renderer::BackendFrameHandler()
|
|
|
|
{
|
|
|
|
IDirect3DDevice9* device = *Game::dx_ptr;
|
|
|
|
|
|
|
|
if (device)
|
|
|
|
{
|
|
|
|
device->AddRef();
|
2017-06-22 16:05:22 -04:00
|
|
|
|
2017-01-19 16:23:59 -05:00
|
|
|
Renderer::BackendFrameSignal(device);
|
2017-06-22 16:05:22 -04:00
|
|
|
|
|
|
|
Utils::Signal<Renderer::BackendCallback> copy(Renderer::SingleBackendFrameSignal);
|
|
|
|
Renderer::SingleBackendFrameSignal.clear();
|
|
|
|
copy(device);
|
|
|
|
|
2017-01-19 16:23:59 -05:00
|
|
|
device->Release();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-22 16:05:22 -04:00
|
|
|
void Renderer::OnNextBackendFrame(Utils::Slot<Renderer::BackendCallback> callback)
|
|
|
|
{
|
|
|
|
Renderer::SingleBackendFrameSignal.connect(callback);
|
|
|
|
}
|
|
|
|
|
2017-01-19 16:23:59 -05:00
|
|
|
void Renderer::OnBackendFrame(Utils::Slot<Renderer::BackendCallback> callback)
|
|
|
|
{
|
|
|
|
Renderer::BackendFrameSignal.connect(callback);
|
|
|
|
}
|
|
|
|
|
2017-05-31 09:45:12 -04:00
|
|
|
void Renderer::OnDeviceRecoveryEnd(Utils::Slot<Scheduler::Callback> callback)
|
2017-01-19 16:23:59 -05:00
|
|
|
{
|
|
|
|
Renderer::EndRecoverDeviceSignal.connect(callback);
|
|
|
|
}
|
|
|
|
|
2017-05-31 09:45:12 -04:00
|
|
|
void Renderer::OnDeviceRecoveryBegin(Utils::Slot<Scheduler::Callback> callback)
|
2017-01-19 16:23:59 -05:00
|
|
|
{
|
|
|
|
Renderer::BeginRecoverDeviceSignal.connect(callback);
|
|
|
|
}
|
|
|
|
|
|
|
|
int Renderer::Width()
|
|
|
|
{
|
2017-06-22 16:05:22 -04:00
|
|
|
return reinterpret_cast<LPPOINT>(0x66E1C68)->x;
|
2017-01-19 16:23:59 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
int Renderer::Height()
|
|
|
|
{
|
2017-06-22 16:05:22 -04:00
|
|
|
return reinterpret_cast<LPPOINT>(0x66E1C68)->y;
|
2017-01-19 16:23:59 -05:00
|
|
|
}
|
|
|
|
|
2017-06-06 08:02:56 -04:00
|
|
|
void Renderer::PreVidRestart()
|
|
|
|
{
|
|
|
|
Renderer::BeginRecoverDeviceSignal();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Renderer::PostVidRestart()
|
|
|
|
{
|
|
|
|
Renderer::EndRecoverDeviceSignal();
|
|
|
|
}
|
|
|
|
|
|
|
|
__declspec(naked) void Renderer::PostVidRestartStub()
|
|
|
|
{
|
|
|
|
__asm
|
|
|
|
{
|
|
|
|
pushad
|
|
|
|
call Renderer::PostVidRestart
|
|
|
|
popad
|
|
|
|
|
|
|
|
push 4F84C0h
|
|
|
|
retn
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-24 15:42:39 -05:00
|
|
|
void Renderer::R_TextureFromCodeError(const char* sampler, Game::GfxCmdBufState* state)
|
|
|
|
{
|
|
|
|
Game::Com_Error(0, "Tried to use '%s' when it isn't valid for material '%s' and technique '%s'",
|
|
|
|
sampler, state->material->info.name, state->technique->name);
|
|
|
|
}
|
|
|
|
|
|
|
|
__declspec(naked) void Renderer::StoreGfxBufContextPtrStub1()
|
|
|
|
{
|
|
|
|
__asm
|
|
|
|
{
|
|
|
|
// original code
|
|
|
|
mov eax, DWORD PTR[eax * 4 + 0066E600Ch];
|
|
|
|
|
|
|
|
// store GfxCmdBufContext
|
|
|
|
/*push edx;
|
|
|
|
mov edx, [esp + 24h];
|
|
|
|
mov gfxState, edx;
|
|
|
|
pop edx;*/
|
|
|
|
|
|
|
|
// show error
|
|
|
|
pushad;
|
|
|
|
push[esp + 24h + 20h];
|
|
|
|
push eax;
|
|
|
|
call R_TextureFromCodeError;
|
|
|
|
add esp, 8;
|
|
|
|
popad;
|
|
|
|
|
|
|
|
// go back
|
|
|
|
push 0x0054CAC1;
|
|
|
|
retn;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
__declspec(naked) void Renderer::StoreGfxBufContextPtrStub2()
|
|
|
|
{
|
|
|
|
__asm
|
|
|
|
{
|
|
|
|
// original code
|
|
|
|
mov edx, DWORD PTR[eax * 4 + 0066E600Ch];
|
|
|
|
|
|
|
|
// show error
|
|
|
|
pushad;
|
|
|
|
push ebx;
|
|
|
|
push edx;
|
|
|
|
call R_TextureFromCodeError;
|
|
|
|
add esp, 8;
|
|
|
|
popad;
|
|
|
|
|
|
|
|
// go back
|
|
|
|
push 0x0054CFA4;
|
|
|
|
retn;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-25 16:47:10 -05:00
|
|
|
int Renderer::DrawTechsetForMaterial(int a1, float a2, float a3, const char* material, Game::vec4_t* color, int a6)
|
|
|
|
{
|
|
|
|
auto mat = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_MATERIAL, Utils::String::VA("wc/%s", material)).material;
|
|
|
|
return Utils::Hook::Call<int(int, float, float, const char*, Game::vec4_t*, int)>(0x005033E0)(a1, a2, a3, Utils::String::VA("%s (^3%s^7)", mat->info.name, mat->techniqueSet->name), color, a6);
|
|
|
|
}
|
|
|
|
|
2017-01-19 16:23:59 -05:00
|
|
|
Renderer::Renderer()
|
|
|
|
{
|
2017-02-25 06:54:26 -05:00
|
|
|
if (Dedicated::IsEnabled()) return;
|
|
|
|
|
2017-01-19 16:23:59 -05:00
|
|
|
// 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();
|
|
|
|
// }
|
|
|
|
// });
|
|
|
|
|
2018-12-24 15:42:39 -05:00
|
|
|
// Log broken materials
|
|
|
|
Utils::Hook(0x0054CAAA, Renderer::StoreGfxBufContextPtrStub1, HOOK_JUMP).install()->quick();
|
|
|
|
Utils::Hook(0x0054CF8D, Renderer::StoreGfxBufContextPtrStub2, HOOK_JUMP).install()->quick();
|
|
|
|
|
2018-12-25 16:47:10 -05:00
|
|
|
// Enhance cg_drawMaterial
|
|
|
|
Utils::Hook::Set(0x005086DA, "^3solid^7");
|
|
|
|
Utils::Hook(0x00580F53, Renderer::DrawTechsetForMaterial, HOOK_CALL).install()->quick();
|
|
|
|
|
2017-01-19 16:23:59 -05:00
|
|
|
// Frame hook
|
2017-01-28 06:39:03 -05:00
|
|
|
Utils::Hook(0x5ACB99, Renderer::FrameStub, HOOK_CALL).install()->quick();
|
2017-01-19 16:23:59 -05:00
|
|
|
|
|
|
|
Utils::Hook(0x536A80, Renderer::BackendFrameStub, HOOK_JUMP).install()->quick();
|
|
|
|
|
2017-06-06 08:02:56 -04:00
|
|
|
// Begin device recovery (not D3D9Ex)
|
2017-06-14 06:06:04 -04:00
|
|
|
Utils::Hook(0x508298, []()
|
2017-01-19 16:23:59 -05:00
|
|
|
{
|
|
|
|
Game::DB_BeginRecoverLostDevice();
|
|
|
|
Renderer::BeginRecoverDeviceSignal();
|
|
|
|
}, HOOK_CALL).install()->quick();
|
|
|
|
|
2017-06-06 08:02:56 -04:00
|
|
|
// End device recovery (not D3D9Ex)
|
2017-06-14 06:06:04 -04:00
|
|
|
Utils::Hook(0x508355, []()
|
2017-01-19 16:23:59 -05:00
|
|
|
{
|
|
|
|
Renderer::EndRecoverDeviceSignal();
|
|
|
|
Game::DB_EndRecoverLostDevice();
|
|
|
|
}, HOOK_CALL).install()->quick();
|
2017-06-06 08:02:56 -04:00
|
|
|
|
|
|
|
// Begin vid_restart
|
|
|
|
Utils::Hook(0x4CA2FD, Renderer::PreVidRestart, HOOK_CALL).install()->quick();
|
|
|
|
|
|
|
|
// End vid_restart
|
|
|
|
Utils::Hook(0x4CA3A7, Renderer::PostVidRestartStub, HOOK_CALL).install()->quick();
|
2017-01-19 16:23:59 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
Renderer::~Renderer()
|
|
|
|
{
|
|
|
|
Renderer::BackendFrameSignal.clear();
|
2017-06-22 16:05:22 -04:00
|
|
|
Renderer::SingleBackendFrameSignal.clear();
|
2017-01-19 16:23:59 -05:00
|
|
|
|
|
|
|
Renderer::EndRecoverDeviceSignal.clear();
|
|
|
|
Renderer::BeginRecoverDeviceSignal.clear();
|
|
|
|
}
|
|
|
|
}
|