Skip to content

GUI API

DronCode edited this page May 3, 2020 · 11 revisions

Get ZWINDOWS instance

Little note about how to get access to ZWINDOWS global instance:

auto ccom = ioi::hm3::getCCOMObjectFromEngineDB(sys->m_engineDataBase);
ccom->getSTDOBJEntityIdByName("MenuZWindows", &menuZWindows);
ZWINDOWS* windows = reinterpret_cast<ZWINDOWS*>(ioi::hm3::getSTDOBJById(menuZWindows));

And easier way:

gameData->m_MenuElements->m_XMLGUISystem->getZWindowsSubsystem()

or through static method when ZXMLGUISystem not available:

typedef ioi::hm3::ZWINDOWS*(__thiscall* getZWindows_t)(ioi::hm3::ZHM3GameData*);
getZWindows_t getZWindows = (getZWindows_t)0x0069D8C0;
auto zWindows = getZWindows(gameData);

Show UI menu in game

How to show pause menu (works for any mission)

auto gameData = ioi::hm3::getGlacierInterface<ioi::hm3::ZHM3GameData>(ioi::hm3::GameData);

const int sub_568260 = 0x00568260;
const char* aIngamemenu = "IngameMenu";

__asm {
    mov     eax, gameData
    mov     ecx, [eax + 0x0A1C]
    mov     ecx, [ecx + 0x4]
    push    1
    push    aIngamemenu
    call    sub_568260
    xor	    eax, eax
}

or

typedef int(__thiscall* showUIMenu_t)(ioi::hm3::ZXMLGUISystem*, const char*, int);
showUIMenu_t showUIMenu = (showUIMenu_t)0x00568260;
showUIMenu(gameData->m_MenuElements->m_XMLGUISystem, "IngameMenu", 1);

or

typedef int(__thiscall* showUIMenuWithoutSounds_t)(ioi::hm3::ZXMLGUISystem*, const char*, int, int);
showUIMenuWithoutSounds_t showUIMenuWithoutSounds = (showUIMenuWithoutSounds_t)0x005678F0;
showUIMenuWithoutSounds(gameData->m_MenuElements->m_XMLGUISystem, "IngameMenu", 1, 0));

Available menus:

  • IngameMenu - pause menu in mission
  • MissionBriefing
  • TrainingBriefing
  • InventoryMenu
  • MissionFailedMenu
  • CreditsEndMenu (credits after M13 completed)
  • CreditsMenu (credits in M13)
  • ControllerLossMenu (empty menu, from PS/XBox port menu)

Get top window

typedef ioi::hm3::ZGUIBase* (__thiscall* GetTopUIWindow_t)(ioi::hm3::ZXMLGUISystem*);
GetTopUIWindow_t GetTopUIWindow = (GetTopUIWindow_t)0x005665E0;
auto window = GetTopUIWindow(gameData->m_MenuElements->m_XMLGUISystem);

Close top window

typedef bool(__thiscall* CloseTopWindow_t)(ioi::hm3::ZXMLGUISystem*, int);
CloseTopWindow_t CloseTopWindow = (CloseTopWindow_t)0x005685C0;
CloseTopWindow(gameData->m_MenuElements->m_XMLGUISystem, 0);

Disable/Enable UI and UI hotkeys

auto gui = gameData->m_Gui;
typedef int(__thiscall* setUIHotkeysState_t)(ioi::hm3::ZGUI*, bool);
setUIHotkeysState_t setUIHotkeysState = (setUIHotkeysState_t)0x00671560;
setUIHotkeysState(gui, false); //disable
setUIHotkeysState(gui, true); //enable

Jump to menu

Works only in main menu (scene HitmanBloodMoney/HitmanBloodMoney.GMS)

typedef void(__stdcall* UI__SwitchToMenu_t)(const char*, int, int);
UI__SwitchToMenu_t UI__SwitchToMenu = (UI__SwitchToMenu_t)0x0055E420;
UI__SwitchToMenu("MainMenu", 0, 1); /// Jump to the main menu. Can avoid profile selector.

Find UI element by name

typedef ioi::hm3::ZGUIBase* (__thiscall* sub_5645D0_t)(ioi::hm3::ZHM3MenuElements*, const char*, int);
sub_5645D0_t sub_5645D0 = (sub_5645D0_t)0x005645D0;
auto _tfWidget = sub_5645D0(gameData->m_MenuElements, "MissionFailedReason", 0); // Widget

Set text

typedef void(__thiscall* sub_67A6B0_t)(ioi::hm3::ZGUIBase*, const char*);
sub_67A6B0_t sub_67A6B0 = (sub_67A6B0_t)0x0067A6B0;
sub_67A6B0(_tfWidget, "TEST TEXT FROM RE-HITMAN"); // Set text

Sample usage

typedef ioi::hm3::ZGUIBase* (__thiscall* sub_5645D0_t)(ioi::hm3::ZHM3MenuElements*, const char*, int);
sub_5645D0_t sub_5645D0 = (sub_5645D0_t)0x005645D0;
auto _tfWidget = sub_5645D0(gameData->m_MenuElements, "MissionFailedReason", 0); // Widget

typedef void(__thiscall* sub_67A6B0_t)(ioi::hm3::ZGUIBase*, const char*);
sub_67A6B0_t sub_67A6B0 = (sub_67A6B0_t)0x0067A6B0;
sub_67A6B0(_tfWidget, "TEST TEXT FROM RE-HITMAN"); // Set text

typedef void(__thiscall* sub_568260_t)(ioi::hm3::ZXMLGUISystem*, const char*, int);
sub_568260_t sub_568260 = (sub_568260_t)0x00568260;
sub_568260(gameData->m_MenuElements->m_XMLGUISystem, "MissionFailedMenu", 1);    // Menu on top

result:

Example

Add window to stack notes

------------------------------------------------------------------------ TOP
	sub_56B4E0 
	ECX ZStandardWindow *
	#1  int*				((int*)(menuEls->m_XMLGUISystem) + 0x3C)
	#2  int					{ 1 }
	#3  ZWINDOW*			?
	#4	int					{ 1 }
------------------------------------------------------------------------ 
	sub_566E20
	ECX int*				((int*)(menuEls->m_XMLGUISystem) + 0x3C)
	#1	ZStandardWindow*	?
	#2  int					{ 1 }
	#3  ZWINDOW*			?
------------------------------------------------------------------------ BOTTOM
	sub_566E20
	ECX ZXMLGUISystem*		{ gameData->menuElements->XMLGUISystem }
	#1  ZGUIBase*			{ our element }
	#2  int					{ 1 }
	#3  ZWINDOW*			{ ? }

So ZWINDOW* is (ZWINDOW*)((0x4C * _ZXMLGUISystem->field_564) + _ZXMLGUISystem->field_480)
or (ZWINDOW*)(0x4C * GET_MEMBER_BY_OFFSET(_ZXMLGUISystem, 0x564) + GET_MEMBER_BY_OFFSET(_ZXMLGUISystem, 0x480))

Notes pack : https://gist.github.com/DronCode/1c4b8b420571fe928b3629f2e3e84517