UI and menus¶
This page groups UI element logic, menu loops, and transition helpers.
UI element timeline (ui_elements_update_and_render / FUN_0041a530)¶
Responsibilities:
-
Updates the global transition timeline
ui_elements_timeline(DAT_00487248) usingDAT_00480844. Direction is controlled byui_transition_direction(DAT_0048724c) (0 = countdown, nonzero = count up). -
When the timeline goes below zero, it calls
game_state_set(FUN_004461c0) withgame_state_pending(DAT_00487274) to switch state and then setsgame_state_pending(DAT_00487274) =0x19(idle). -
Clamps the timeline to the maximum active element value (
ui_elements_max_timeline). -
Iterates the UI element pointer table (
0x0048f168 .. 0x0048f20b, 41 pointers) in reverse order (fromui_element_table_startdown toui_element_table_end), callingui_element_update(FUN_00446900) andui_element_renderfor each entry.
Helpers:
-
ui_elements_reset_state(FUN_00446170) clears element active flags, hover timers, and per-element callbacks (on_activate/on_update). -
ui_elements_max_timeline(FUN_00446190) returns the max timeline value among active elements.
Recovered menu init bitfields¶
Recent data-map lifts for one-shot setup guards:
menu_item_palette_init_flags(0x004cc910):ui_menu_item_updatestatic color palette init (idle/hover RGBA blocks).statistics_menu_init_flags(0x004d0f20):statistics_menu_updatetab/button setup guards (High scores, Weapons, Perks, Credits, Typ-o, Mods, Check for updates, Back).profile_menu_init_flags(0x004cccd8):ui_profile_menu_updatesetup guards for profile text input, action buttons, and list widget wiring.- Profile name text-input state in
ui_profile_menu_update:profile_name_input_state(0x004d0f28),profile_name_input_state_cursor(0x004d0f2c),profile_name_input_state_max_chars(0x004d0f30),profile_name_input_state_width_px(0x004d0f34),profile_name_input_state_alpha(0x004d0f38). credits_screen_init_flags(0x00480978):credits_screen_updateone-shot setup guards for Back and Secret buttons.mods_menu_init_flags(0x00481bb8):mods_menu_updateone-shot setup guards for list widget and action buttons.unlocked_weapons_database_init_flags(0x004ccc51): one-shot setup guards for the unlocked-weapons database list and Back button.unlocked_perks_database_init_flags(0x004ccc50): one-shot setup guards for the unlocked-perks database list and Back button.quest_select_screen_flags(0x004d79d4):quest_select_menu_updateruntime setup guards for Hardcore checkbox and Back button.demo_trial_overlay_init_flags(0x0047f62c):demo_trial_overlay_renderone-shot setup guards for Maybe later / Purchase / Already paid.demo_trial_purchase_button(0x0047f5f8): persistentui_button_tstate used bydemo_trial_overlay_renderfor the Purchase action.tutorial_prompt_dialog_init_flags(0x00480148):tutorial_prompt_dialogone-shot setup guards for Repeat / Play buttons.tutorial_prompt_repeat_button(0x00480250) andtutorial_prompt_primary_button(0x004807d0): persistentui_button_tstates used bytutorial_prompt_dialog(primary label switches between "Play a game" and "Skip tutorial").demo_purchase_screen_init_flags(0x00480320):demo_purchase_screen_updateone-shot setup guards for Maybe later / Purchase.ui_aim_indicators_init_flags(0x00480340):ui_render_aim_indicatorsone-shot atexit registration guards.ui_hud_init_flags(0x0048f528):ui_render_hudone-shot setup guard for quest-progress bar tint defaults.
Additional shared UI strings/globals:
menu_label_back(0x00472e80): shared"Back"label used by multiple menu buttons.s_fmt_decimal_int/s_fmt_decimal_int_zero_prefixed(0x00471f40/0x00471f44):%dand0%dformat strings used in menu counters and demo-time formatting.screen_height_f(0x00471144): float mirror of_config_screen_heightused by centered splash/loading layout.stats_menu_easter_egg_roll(0x00471308): one-shot random roll (0..31) used bystatistics_menu_updatefor the March-3 "Orbes Volantes Exstare" Easter-egg text gate (roll == 3, then reset to-1).ui_button_tex_small/ui_button_tex_medium(0x00478670/0x00478674): lazy-loaded texture-handle caches used byui_button_updatefor small/medium button frames.ui_menu_item_color_idle_*(0x004ccd40..0x004ccd4c) andui_menu_item_color_hover_*(0x004d0e28..0x004d0e34): persistent RGBA palette vectors used byui_menu_item_updatefor idle/hover text tint.
Quest HUD helper globals¶
Recovered runtime globals used by the in-game quest panel in ui_render_hud:
quest_progress_bar_color_r/g/b/a(0x004871a0..0x004871ac): RGBA vector passed toui_draw_progress_barfor quest-kill progress fill. RGB is seeded to(0.2, 0.8, 0.3)and alpha is scaled from transition alpha.quest_stage_label_buffer(0x0048f788): scratch text buffer used for formatted stage labels (major-minor) near the quest title card.
Controls menu lists¶
Recovered controls-menu dropdown blocks (ui_list_widget_t, size 0x1c):
controls_move_method_list(0x004d7638)controls_aim_method_list(0x004d76a8)controls_player_profile_list(0x004d7660)
controls_menu_update recomputes .enabled each frame so only one dropdown
stays interactive while the others are open.
Options sliders¶
Recovered segmented-slider state blocks used by options_menu_update
(ui_segmented_slider_update):
- SFX volume:
options_sfx_volume_slider(0x004d77f8) - Music volume:
options_music_volume_slider(0x004d75e8) - Graphics detail preset:
options_graphics_detail_slider(0x004d7590) - Mouse sensitivity:
options_mouse_sensitivity_slider(0x004d7680) - Checkbox state blocks (
ui_checkbox_t):options_ui_info_checkbox(0x004d77e0),controls_direction_arrow_checkbox(0x004d77f0),quest_select_hardcore_checkbox(0x004d7700),highscore_hardcore_checkbox(0x004d0d98), andhighscore_online_scores_checkbox(0x004d0e20).
Additional controls-rebind runtime globals:
ui_menu_item_t(0x10bytes,ui_menu_item_updatepayload):label(+0x0),hovered(+0x4),activated(+0x5),enabled(+0x6),hover_phase(+0x8),alpha(+0xc).ui_list_widget_t(0x1cbytes,ui_list_widget_updatepayload):enabled(+0x0),open(+0x4),selected_index(+0x8),items(+0xc),item_count(+0x10),hovered(+0x14),active_index(+0x18).- Rebind action table passed to
ui_menu_item_update:controls_rebind_items(0x004d7898,controls_rebind_item_table_t) with slot aliases such ascontrols_rebind_move_secondary_item,controls_rebind_move_tertiary_item,controls_rebind_move_quaternary_item,controls_rebind_fire_item,controls_rebind_torso_left_item,controls_rebind_torso_right_item,controls_rebind_aim_up_down_axis_item,controls_rebind_aim_left_right_axis_item,controls_rebind_move_up_down_axis_item,controls_rebind_move_left_right_axis_item(0x004d78a8..0x004d7958). controls_key_pick_perk_item(0x004d7968):ui_menu_item_tslot for the Level Up action;.labelis updated from_config_key_pick_perk.controls_key_reload_item(0x004d7978):ui_menu_item_tslot for the Reload/Move-to-cursor action;.labelis updated from_config_key_reload.controls_rebind_axis_peak_abs_13f/140/141/153/154/155(0x004d79e4..0x004d79f8): per-axis absolute-value peaks accumulated during analog rebind capture and compared against the0.5assignment threshold.
Menu UI loop (perk_selection_screen_update)¶
A common menu loop that:
1) Calls the gameplay render pass (gameplay_render_world, FUN_00405960).
2) Runs ui_elements_update_and_render.
3) Draws menu content and buttons (ui_button_update).
TODO (runtime)¶
Perk selection does not fade the world; it keeps the gameplay render pass and overlays active.
perk_selection_screen_updatecallsgameplay_render_worldbut does not callhud_update_and_render, so the HUD disappears immediately when entering state6.gameplay_render_worldforcesui_transition_alpha = 1.0forgame_state_id == 6(perk selection) and== 9(gameplay), so the usualui_transition_alphagates inplayer_render_overlays/creature_render_all/projectile_render/bonus_renderdo not hide those layers during perk selection.- The perk menu panel slides using the UI element timeline (
ui_elements_timeline) andui_element_update'srender_modeoffset path (slide_x).
Pause/transition fades appear to be handled elsewhere (not perk selection). Capture HUD alpha when returning from perk selection to confirm the exact fade-in timing/curve.
Perk prompt origin/bounds can be captured with scripts/frida/perk_prompt_trace.js (see analysis/ghidra/maps/data_map.json
for the underlying globals).
Recovered action-button globals for this state:
perk_selection_cancel_button(0x00480090)perk_selection_select_button(0x00480820)- Choice-item state table base:
perk_selection_choice_items(0x004800a8,perk_selection_choice_item_table_t) with stride0x10across perk slots. - Perk-selection one-shot idle/hover color vectors:
perk_selection_choice_color_idle_*(0x00480298..0x004802a4) andperk_selection_choice_color_hover_*(0x00480310..0x0048031c).
Runtime capture request (next large run)¶
For deeper carving of ui_menu_item_element subtemplate blocks
(0x0048fd78..0x004902ff), capture:
- One memory snapshot immediately after
ui_menu_assets_init(0x00419dd0) returns. - One memory snapshot immediately after
ui_menu_layout_init(0x0044fcb0) returns. - Per-frame deltas for
0x0048fd78..0x004902ffwhile visiting these states: main menu (0), options, statistics, perk selection (6), and in-game HUD (9). - Write-trace events (address + value + EIP) for this range, especially writes to
offsets repeating with stride
0x1c(8-slot blocks). - A trace of
ui_element_renderinput pointers for frames where these blocks are visible, so we can map block/slot identity to rendered widget role.
Goal: promote block-local _pad* fields to named slot fields (position,
mode/timeline, UV/color tuples) with confidence across menu variants.
UI element render (ui_element_render / FUN_00446c40)¶
ui_element_render updates focus/click handling and draws a UI element's quads,
colors, and textures. See UI elements for struct details.
Keyboard focus updates are globally gated by ui_focus_input_locked; controls
rebind flows toggle this lock while waiting for key/axis capture.
Main menu (state 0)¶
The main menu is game_state_id == 0 and is built from the shared UI element
system (logo sign + ui_menuItem elements with overlay label atlas).
- Main menu (state 0)
main_menu_full_version_layout_latch(0x00486faa) is a one-shot guard used by main-menu layout update paths to avoid reapplying full-version slot shifts every frame.
Button helpers¶
High-confidence button helpers are tracked in Detangling notes under UI button helpers.