[Materials] Recover images to prevent vid_restart crashes

This commit is contained in:
momo5502 2017-06-06 14:02:56 +02:00
parent b7d1cb2e38
commit 5e3a8b313c
6 changed files with 60 additions and 10 deletions

View File

@ -120,6 +120,21 @@ namespace Components
} }
} }
bool Materials::IsValid(Game::Material* material)
{
if (!material || !material->textureCount || !material->textureTable) return false;
for(char i = 0; i < material->textureCount; ++i)
{
if (!material->textureTable[i].info.image || !material->textureTable[i].info.image->map)
{
return false;
}
}
return true;
}
__declspec(naked) void Materials::ImageVersionCheck() __declspec(naked) void Materials::ImageVersionCheck()
{ {
__asm __asm
@ -311,13 +326,13 @@ namespace Components
} }
}); });
Renderer::OnDeviceRecoveryEnd([]() /*Renderer::OnDeviceRecoveryEnd([]()
{ {
for (auto& image : Materials::ImageTable) for (auto& image : Materials::ImageTable)
{ {
Utils::Hook::Call<void(void*)>(0x51F7B0)(image); Utils::Hook::Call<void(void*)>(0x51F7B0)(image);
} }
}); });*/
} }
Materials::~Materials() Materials::~Materials()

View File

@ -16,6 +16,8 @@ namespace Components
static Game::GfxImage* CreateImage(std::string name, unsigned int width, unsigned int height, unsigned int depth, unsigned int flags, _D3DFORMAT format); static Game::GfxImage* CreateImage(std::string name, unsigned int width, unsigned int height, unsigned int depth, unsigned int flags, _D3DFORMAT format);
static void DeleteImage(Game::GfxImage* image); static void DeleteImage(Game::GfxImage* image);
static bool IsValid(Game::Material* material);
private: private:
static std::vector<Game::GfxImage*> ImageTable; static std::vector<Game::GfxImage*> ImageTable;
static std::vector<Game::Material*> MaterialTable; static std::vector<Game::Material*> MaterialTable;

View File

@ -17,7 +17,6 @@ namespace Components
static int FrameTime; static int FrameTime;
static int64_t* GetStatsID(); static int64_t* GetStatsID();
static void ShutdownStub(int num);
static void SelectStringTableEntryInDvarStub(); static void SelectStringTableEntryInDvarStub();

View File

@ -71,6 +71,29 @@ namespace Components
return Utils::Hook::Get<int>(0x66E1C6C); return Utils::Hook::Get<int>(0x66E1C6C);
} }
void Renderer::PreVidRestart()
{
Renderer::BeginRecoverDeviceSignal();
}
void Renderer::PostVidRestart()
{
Renderer::EndRecoverDeviceSignal();
}
__declspec(naked) void Renderer::PostVidRestartStub()
{
__asm
{
pushad
call Renderer::PostVidRestart
popad
push 4F84C0h
retn
}
}
Renderer::Renderer() Renderer::Renderer()
{ {
if (Dedicated::IsEnabled()) return; if (Dedicated::IsEnabled()) return;
@ -108,17 +131,25 @@ namespace Components
Utils::Hook(0x536A80, Renderer::BackendFrameStub, HOOK_JUMP).install()->quick(); Utils::Hook(0x536A80, Renderer::BackendFrameStub, HOOK_JUMP).install()->quick();
// Begin device recovery (not D3D9Ex)
Utils::Hook(0x508298, [] () Utils::Hook(0x508298, [] ()
{ {
Game::DB_BeginRecoverLostDevice(); Game::DB_BeginRecoverLostDevice();
Renderer::BeginRecoverDeviceSignal(); Renderer::BeginRecoverDeviceSignal();
}, HOOK_CALL).install()->quick(); }, HOOK_CALL).install()->quick();
// End device recovery (not D3D9Ex)
Utils::Hook(0x508355, [] () Utils::Hook(0x508355, [] ()
{ {
Renderer::EndRecoverDeviceSignal(); Renderer::EndRecoverDeviceSignal();
Game::DB_EndRecoverLostDevice(); Game::DB_EndRecoverLostDevice();
}, HOOK_CALL).install()->quick(); }, HOOK_CALL).install()->quick();
// Begin vid_restart
Utils::Hook(0x4CA2FD, Renderer::PreVidRestart, HOOK_CALL).install()->quick();
// End vid_restart
Utils::Hook(0x4CA3A7, Renderer::PostVidRestartStub, HOOK_CALL).install()->quick();
} }
Renderer::~Renderer() Renderer::~Renderer()

View File

@ -24,6 +24,10 @@ namespace Components
static void BackendFrameStub(); static void BackendFrameStub();
static void BackendFrameHandler(); static void BackendFrameHandler();
static void PreVidRestart();
static void PostVidRestart();
static void PostVidRestartStub();
static Utils::Signal<Scheduler::Callback> EndRecoverDeviceSignal; static Utils::Signal<Scheduler::Callback> EndRecoverDeviceSignal;
static Utils::Signal<Scheduler::Callback> BeginRecoverDeviceSignal; static Utils::Signal<Scheduler::Callback> BeginRecoverDeviceSignal;

View File

@ -59,9 +59,9 @@ namespace Components
float fontSize = 0.9f; float fontSize = 0.9f;
float descSize = 0.9f; float descSize = 0.9f;
Game::Material* white = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_MATERIAL, "white").material; Game::Material* white = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_MATERIAL, "white").material; if (!white) return;
Game::Font* font = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_FONT, "fonts/objectiveFont").font; Game::Font* font = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_FONT, "fonts/objectiveFont").font; if (!font) return;
Game::Font* descfont = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_FONT, "fonts/normalFont").font; Game::Font* descfont = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_FONT, "fonts/normalFont").font; if (!descfont) return;
Game::vec4_t wColor = { 1.0f, 1.0f, 1.0f, 1.0f }; Game::vec4_t wColor = { 1.0f, 1.0f, 1.0f, 1.0f };
Game::vec4_t bgColor = { 0.0f, 0.0f, 0.0f, 0.5f }; Game::vec4_t bgColor = { 0.0f, 0.0f, 0.0f, 0.5f };
Game::vec4_t borderColor = { 1.0f, 1.0f, 1.0f, 0.2f }; Game::vec4_t borderColor = { 1.0f, 1.0f, 1.0f, 0.2f };
@ -116,10 +116,9 @@ namespace Components
Game::CL_DrawStretchPicPhysical(static_cast<float>(width / 2 - bWidth / 2), static_cast<float>(height + bHeight / 2), bWidth * 1.0f, border * 1.0f, 0, 0, 1.0f, 1.0f, borderColor, white); // Bottom Game::CL_DrawStretchPicPhysical(static_cast<float>(width / 2 - bWidth / 2), static_cast<float>(height + bHeight / 2), bWidth * 1.0f, border * 1.0f, 0, 0, 1.0f, 1.0f, borderColor, white); // Bottom
// Image // Image
if (toast->image && toast->image->textureTable && toast->image->textureCount && toast->image->textureTable->info.image && toast->image->textureTable->info.image->map) Game::Material* image = toast->image;
{ if (!Materials::IsValid(image)) image = Game::DB_FindXAssetDefaultHeaderInternal(Game::XAssetType::ASSET_TYPE_MATERIAL).material;
Game::CL_DrawStretchPicPhysical(static_cast<float>(width / 2 - bWidth / 2 + iOffsetLeft), static_cast<float>(height - bHeight / 2 + iOffset), imgDim * 1.0f, imgDim * 1.0f, 0, 0, 1.0f, 1.0f, wColor, toast->image); Game::CL_DrawStretchPicPhysical(static_cast<float>(width / 2 - bWidth / 2 + iOffsetLeft), static_cast<float>(height - bHeight / 2 + iOffset), imgDim * 1.0f, imgDim * 1.0f, 0, 0, 1.0f, 1.0f, wColor, image);
}
// Text // Text
float leftText = width / 2 - bWidth / 2 - cornerSize + iOffsetLeft * 2 + imgDim; float leftText = width / 2 - bWidth / 2 - cornerSize + iOffsetLeft * 2 + imgDim;