[Menus] Properly load menus

Overridden menus are just loaded in iw4x_code_post_gfx_mp and new ones are added to ui_mp/iw4x.txt
This commit is contained in:
TheApadayo 2019-01-17 18:39:01 -05:00
parent 8080700432
commit ad5a58462f
3 changed files with 51 additions and 21 deletions

View File

@ -2,7 +2,7 @@
namespace Assets namespace Assets
{ {
void IMenuList::load(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder) void IMenuList::load(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* /*builder*/)
{ {
header->menuList = Components::Menus::LoadMenuList(name); header->menuList = Components::Menus::LoadMenuList(name);

View File

@ -5,7 +5,7 @@ namespace Assets
std::unordered_map<std::string, Game::menuDef_t*> ImenuDef_t::LoadedMenus; std::unordered_map<std::string, Game::menuDef_t*> ImenuDef_t::LoadedMenus;
void ImenuDef_t::load(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder) void ImenuDef_t::load(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* /*builder*/)
{ {
// search menus loaded by a menufile // search menus loaded by a menufile
for (auto i = ImenuDef_t::LoadedMenus.begin(); i != ImenuDef_t::LoadedMenus.end(); ++i) for (auto i = ImenuDef_t::LoadedMenus.begin(); i != ImenuDef_t::LoadedMenus.end(); ++i)
@ -15,6 +15,14 @@ namespace Assets
return; return;
} }
} }
// load from disk
auto menus = Components::Menus::LoadMenu(Utils::String::VA("ui_mp/%s.menu", name.data()));
if (menus.size() == 0) return;
if (menus.size() > 1) Components::Logger::Print("Menu '%s' on disk has more than one menudef in it. Only saving the first one\n", name.data());
header->menu = menus[0].second;
} }

View File

@ -345,7 +345,7 @@ namespace Components
return { Game::Menus_FindByName(Game::uiContext, filename.data()) }; return { Game::Menus_FindByName(Game::uiContext, filename.data()) };
} }
Game::XAssetHeader Menus::MenuListFindHook(Game::XAssetType type, const std::string& filename) Game::XAssetHeader Menus::MenuListFindHook(Game::XAssetType /*type*/, const std::string& filename)
{ {
Game::XAssetHeader header = { nullptr }; Game::XAssetHeader header = { nullptr };
@ -392,7 +392,7 @@ namespace Components
Menus::UiContextMenus[menu->window.name] = { priority, menu }; Menus::UiContextMenus[menu->window.name] = { priority, menu };
} }
std::pair<int, Game::menuDef_t*> Menus::FindMenuInContext(Game::UiContext* ctx, const std::string& name) std::pair<int, Game::menuDef_t*> Menus::FindMenuInContext(Game::UiContext* /*ctx*/, const std::string& name)
{ {
auto entry = Menus::UiContextMenus.find(name); auto entry = Menus::UiContextMenus.find(name);
if (entry == Menus::UiContextMenus.end()) return { 0, nullptr }; if (entry == Menus::UiContextMenus.end()) return { 0, nullptr };
@ -438,10 +438,9 @@ namespace Components
// check if menu already exists in context and replace if priority is higher // check if menu already exists in context and replace if priority is higher
std::pair<int, Game::menuDef_t*> ctxEntry = Menus::FindMenuInContext(ctx, cur->window.name); std::pair<int, Game::menuDef_t*> ctxEntry = Menus::FindMenuInContext(ctx, cur->window.name);
if (ctxEntry.second) // if menu ptr is null then it wasnt found if (ctxEntry.second) // if menu ptr is null then it wasnt found
{ {
if (insertPriority > ctxEntry.first) // compare priorities to see if we should replace if (insertPriority >= ctxEntry.first) // compare priorities to see if we should replace
{ {
Menus::ReplaceMenuInContext(ctx, insertPriority, cur); Menus::ReplaceMenuInContext(ctx, insertPriority, cur);
} }
@ -460,8 +459,17 @@ namespace Components
void Menus::RegisterMenuLists() void Menus::RegisterMenuLists()
{ {
Utils::Hook::Call<void()>(0x401700)(); // call original load functions Utils::Hook::Call<void()>(0x401700)(); // reset ui context
// we can't call DB_FindXAssetHeader here because it blocks the rest of loading waiting on those 2 menulsits
// TODO: Figure out a better way to trigger the custom menulist loading because if you skip the intro the
// custom menus won't have loaded until a few seconds later. All overridden menus are already
// loaded so it isn't a black screen but it wont show the first time intro, credits, etc.
// as soon as this loads those start to work again
// if we just trigger this here it blocks the intro from showing because of the FindXAssetHeader calls
// that are waiting for zones to finish loading
Scheduler::OnReady([]()
{
// attempt to load iw4x menus // attempt to load iw4x menus
Game::XAssetHeader header = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_MENULIST, "ui_mp/iw4x.txt"); Game::XAssetHeader header = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_MENULIST, "ui_mp/iw4x.txt");
if (header.data && !(header.menuList->menuCount == 1 && !_stricmp("default_menu", header.menuList->menus[0]->window.name))) if (header.data && !(header.menuList->menuCount == 1 && !_stricmp("default_menu", header.menuList->menus[0]->window.name)))
@ -475,6 +483,7 @@ namespace Components
{ {
Menus::AddMenuListToContext(Game::uiContext, header.menuList, 1); Menus::AddMenuListToContext(Game::uiContext, header.menuList, 1);
} }
}, true);
} }
void Menus::ResetContextHook(int a1) void Menus::ResetContextHook(int a1)
@ -509,6 +518,20 @@ namespace Components
// reset our list on UiContext reset // reset our list on UiContext reset
Utils::Hook(0x4B5422, Menus::ResetContextHook, HOOK_CALL).install()->quick(); Utils::Hook(0x4B5422, Menus::ResetContextHook, HOOK_CALL).install()->quick();
// grab custom lists as they are loaded otherwise DB takes up to 20 seconds to load intro
/*
AssetHandler::OnLoad([](Game::XAssetType type, Game::XAssetHeader asset, std::string name, bool*)
{
if (type != Game::XAssetType::ASSET_TYPE_MENULIST) return;
if (name == "ui_mp/iw4x.txt" || name == "ui_mp/mod.txt")
{
Menus::AddMenuListToContext(Game::uiContext, asset.menuList, 1);
}
});
*/
// Use the connect menu open call to update server motds // Use the connect menu open call to update server motds
Utils::Hook(0x428E48, []() Utils::Hook(0x428E48, []()
{ {
@ -562,8 +585,7 @@ namespace Components
} }
else else
{ {
// re-register all menus Menus::RegisterMenuLists(); // register custom menus
Menus::RegisterMenuLists();
// Reopen main menu // Reopen main menu
Game::Menus_OpenByName(Game::uiContext, "main_text"); Game::Menus_OpenByName(Game::uiContext, "main_text");