Close imagefile handles

This commit is contained in:
fed 2023-03-10 09:58:53 +01:00
parent e6901318e8
commit 9ceda4f4fd
5 changed files with 81 additions and 6 deletions

View File

@ -7,6 +7,7 @@
#include "console.hpp"
#include "mods.hpp"
#include "fonts.hpp"
#include "imagefiles.hpp"
#include <utils/hook.hpp>
#include <utils/concurrency.hpp>
@ -31,6 +32,7 @@ namespace fastfiles
utils::hook::detour db_try_load_x_file_internal_hook;
utils::hook::detour db_find_xasset_header;
utils::hook::detour load_xasset_header_hook;
utils::hook::detour db_unload_x_zones_hook;
void db_try_load_x_file_internal(const char* zone_name, const int flags)
{
@ -158,10 +160,13 @@ namespace fastfiles
void load_pre_gfx_zones(game::XZoneInfo* zone_info,
unsigned int zone_count, game::DBSyncMode sync_mode)
{
imagefiles::close_custom_handles();
// code_pre_gfx
utils::memory::allocator allocator;
std::vector<game::XZoneInfo> zones;
try_add_zone(zones, allocator, "h2_mod_pre_gfx", true);
add_mod_zones(zones, allocator, mods::zone_priority::pre_gfx);
push_zones(zones, zone_info, zone_count);
@ -570,6 +575,22 @@ namespace fastfiles
load_xasset_header_hook.invoke<void>(a1);
}
void db_unload_x_zones_stub(const unsigned short* unload_zones,
const unsigned int unload_count, const bool create_default)
{
for (auto i = 0u; i < unload_count; i++)
{
const auto zone_name = game::g_zones[unload_zones[i]].name;
if (zone_name[0] != '\0')
{
printf("unload zone %s\n", zone_name);
imagefiles::close_handle(zone_name);
}
}
db_unload_x_zones_hook.invoke<void>(unload_zones, unload_count, create_default);
}
}
bool exists(const std::string& zone)
@ -585,7 +606,6 @@ namespace fastfiles
{
db_fs->vftbl->Close(db_fs, handle);
}
});
return handle != nullptr;
@ -644,6 +664,8 @@ namespace fastfiles
db_try_load_x_file_internal_hook.create(0x1404173B0, db_try_load_x_file_internal);
db_find_xasset_header.create(game::DB_FindXAssetHeader, db_find_xasset_header_stub);
db_unload_x_zones_hook.create(0x140417D80, db_unload_x_zones_stub);
// Allow loading of mixed compressor types
utils::hook::nop(0x1403E66A7, 2);

View File

@ -26,6 +26,7 @@ namespace imagefiles
char __pad0[88];
};
utils::memory::allocator image_file_allocator;
std::unordered_map<std::string, image_file_unk*> image_file_unk_map;
std::unordered_map<std::string, game::DB_IFileSysFile*> image_file_handles;
@ -44,7 +45,7 @@ namespace imagefiles
const auto name = get_image_file_name();
if (image_file_unk_map.find(name) == image_file_unk_map.end())
{
const auto unk = utils::memory::get_allocator()->allocate<image_file_unk>();
const auto unk = image_file_allocator.allocate<image_file_unk>();
image_file_unk_map[name] = unk;
return unk;
}
@ -129,6 +130,41 @@ namespace imagefiles
}
}
void close_custom_handles()
{
const auto db_fs = game::DB_FSInitialize();
for (const auto& handle : image_file_handles)
{
if (handle.second != nullptr)
{
db_fs->vftbl->Close(db_fs, handle.second);
}
}
image_file_handles.clear();
image_file_unk_map.clear();
image_file_allocator.clear();
}
void close_handle(const std::string& fastfile)
{
if (!image_file_handles.contains(fastfile))
{
return;
}
const auto db_fs = game::DB_FSInitialize();
const auto handle = image_file_handles[fastfile];
if (handle != nullptr)
{
db_fs->vftbl->Close(db_fs, handle);
}
image_file_handles.erase(fastfile);
image_file_allocator.free(image_file_unk_map[fastfile]);
image_file_unk_map.erase(fastfile);
}
class component final : public component_interface
{
public:

View File

@ -0,0 +1,7 @@
#pragma once
namespace imagefiles
{
void close_custom_handles();
void close_handle(const std::string& fastfile);
}

View File

@ -1156,6 +1156,15 @@ namespace game
DB_ZONE_CUSTOM = 0x1000 // added for custom zone loading
};
struct XZone
{
char __pad0[24];
char name[64];
char __pad1[128];
};
static_assert(sizeof(XZone) == 216);
struct XZoneInfo
{
const char* name;

View File

@ -223,12 +223,13 @@ namespace game
WEAK symbol<HWND> hWnd{0x14CCF81C0};
WEAK game::symbol<const char*> g_assetNames{0x140BEF280};
WEAK symbol<const char*> g_assetNames{0x140BEF280};
WEAK game::symbol<void*> g_assetPool{0x140BF3620};
WEAK symbol<void*> g_assetPool{0x140BF3620};
WEAK game::symbol<unsigned int> g_zoneCount{0x1422F45F4};
WEAK game::symbol<unsigned short> g_zoneIndex{0x1422F8DC8};
WEAK symbol<unsigned int> g_zoneCount{0x1422F45F4};
WEAK symbol<unsigned short> g_zoneIndex{0x1422F8DC8};
WEAK symbol<XZone> g_zones{0x144176040};
WEAK symbol<int> g_compressor{0x142065E80};
WEAK symbol<int> g_poolSize{0x140BF2E40};