[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()
{
__asm
@ -311,13 +326,13 @@ namespace Components
}
});
Renderer::OnDeviceRecoveryEnd([]()
/*Renderer::OnDeviceRecoveryEnd([]()
{
for (auto& image : Materials::ImageTable)
{
Utils::Hook::Call<void(void*)>(0x51F7B0)(image);
}
});
});*/
}
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 void DeleteImage(Game::GfxImage* image);
static bool IsValid(Game::Material* material);
private:
static std::vector<Game::GfxImage*> ImageTable;
static std::vector<Game::Material*> MaterialTable;

View File

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

View File

@ -71,6 +71,29 @@ namespace Components
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()
{
if (Dedicated::IsEnabled()) return;
@ -108,17 +131,25 @@ namespace Components
Utils::Hook(0x536A80, Renderer::BackendFrameStub, HOOK_JUMP).install()->quick();
// Begin device recovery (not D3D9Ex)
Utils::Hook(0x508298, [] ()
{
Game::DB_BeginRecoverLostDevice();
Renderer::BeginRecoverDeviceSignal();
}, HOOK_CALL).install()->quick();
// End device recovery (not D3D9Ex)
Utils::Hook(0x508355, [] ()
{
Renderer::EndRecoverDeviceSignal();
Game::DB_EndRecoverLostDevice();
}, 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()

View File

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

View File

@ -59,9 +59,9 @@ namespace Components
float fontSize = 0.9f;
float descSize = 0.9f;
Game::Material* white = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_MATERIAL, "white").material;
Game::Font* font = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_FONT, "fonts/objectiveFont").font;
Game::Font* descfont = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_FONT, "fonts/normalFont").font;
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; if (!font) return;
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 bgColor = { 0.0f, 0.0f, 0.0f, 0.5f };
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
// Image
if (toast->image && toast->image->textureTable && toast->image->textureCount && toast->image->textureTable->info.image && toast->image->textureTable->info.image->map)
{
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::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, image);
// Text
float leftText = width / 2 - bWidth / 2 - cornerSize + iOffsetLeft * 2 + imgDim;