From f9c87723e11ae16fa1363776f1da5b58bc39a3dd Mon Sep 17 00:00:00 2001 From: Jan Petykiewicz Date: Thu, 2 Apr 2026 23:51:20 -0700 Subject: [PATCH] Map world entry simulation and shell input flow --- artifacts/exports/rt3-1.06/function-map.csv | 22 ++++++++-- docs/control-loop-atlas.md | 48 ++++++++++----------- 2 files changed, 42 insertions(+), 28 deletions(-) diff --git a/artifacts/exports/rt3-1.06/function-map.csv b/artifacts/exports/rt3-1.06/function-map.csv index 2c27dd5..c34b27c 100644 --- a/artifacts/exports/rt3-1.06/function-map.csv +++ b/artifacts/exports/rt3-1.06/function-map.csv @@ -1,5 +1,12 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,confidence,notes,verified_against +0x0040a590,892,simulation_service_periodic_boundary_work,simulation,cdecl,inferred,objdump + analysis-context,3,Periodic simulation-maintenance dispatcher inside the world-step family. It switches on the local calendar or phase byte at [this+0x0f] routes one heavy mode through the larger recurring service branch at 0x0040a160 falls back to the simpler one-step advance at 0x00409e80 for other modes and runs several global manager sweeps across 0x0062be10 0x006ceb9c 0x006cfcbc 0x006cec20 and 0x0062bae0 before handing control back to the enclosing stepper. One conditional branch also re-enters shell_map_file_world_bundle_coordinator at 0x00445de0 which keeps the save-or-package family connected to the live simulation cadence.,objdump + analysis-context + caller xrefs +0x0040ab50,339,simulation_advance_to_target_calendar_point,simulation,cdecl,inferred,objdump + analysis-context,3,Advances the active world state toward one caller-selected packed calendar target while guarded by the recursion counter at 0x0062b240. The helper compares the current local tuple fields [this+0x0d] [this+0x0f] [this+0x11] and [this+0x14] against a target resolved through 0x0051d550 and 0x0051d5f0 then either recurses in larger 0x168-sized chunks or advances through the smaller periodic step family rooted at 0x00409e80 and 0x0040a9c0. Each successful step notifies the live world root at 0x0062c120 through 0x00450030. Grounded callers include the frame-time accumulator at 0x00439140 the larger fast-forward helper at 0x00437b20 and one shell UI command path.,objdump + analysis-context + caller xrefs +0x00434300,881,world_runtime_release_global_services,map,cdecl,inferred,objdump + analysis-context,3,Releases or clears a broad set of world-runtime global services owned by the current map object before a new world entry or sibling save branch continues. The helper walks the owner collection at [this+0x66b2] and then touches many global manager slots including 0x0062b244 0x0062cfcbc 0x0062be10 0x0062c120 0x0062ba8c 0x0062ba88 0x0062b2fc 0x0062b268 0x006cea4c and 0x006acd34 through repeated release-style calls and nulling writes. Current grounded callers are the heavier world-entry branch at 0x00443a50 the sibling .smp world-state branch at 0x00446d40 and shell_transition_mode at 0x00482ec0.,objdump + analysis-context + caller xrefs +0x00439140,1086,simulation_frame_accumulate_and_step_world,simulation,cdecl,inferred,objdump + analysis-context,4,Frame-owned simulation cadence after world bring-up. The routine samples elapsed time through 0x0051d890 mixes shell and mode scalars into a simulation quantum keeps leftover fractional time in [this+0x4c80] and when enough time has accumulated repeatedly calls simulation_advance_to_target_calendar_point at 0x0040ab50 using the current step quantum from 0x005f2b38. Around those simulation steps it also refreshes shell-facing presentation helpers under 0x006d4024 and 0x006d0818 updates multiple world collections and transport or scenario side structures and then continues into later follow-up work. This is the strongest grounded owner so far for the recurring gameplay simulation cadence that follows world_entry_transition_and_runtime_bringup.,objdump + analysis-context + caller xrefs +0x00443a50,1073,world_entry_transition_and_runtime_bringup,map,cdecl,inferred,objdump + analysis-context,4,First grounded gameplay-world entry coordinator reached from shell_map_file_entry_coordinator. It stages the selected file path into 0x0062bee0 dismisses the shell detail-panel controller at 0x006d0818 drives shell_transition_mode through 0x00482ec0 and shell_state_service_active_mode_frame then marks shell state for the transition and resets the previous world bundle through world_runtime_release_global_services and the neighboring allocator branch at 0x00438890. After the transition wait it builds temporary bundle payloads from %1\\%2 and %1.tmp allocates or serializes several world-entry records through 0x00530c80 0x00531150 and 0x00531360 allocates the new world root at 0x0062c120 from the staged filename through 0x0044e910 notifies the shell owner at 0x0062be68 and then initializes multiple world-facing global managers including 0x0062ba8c 0x0062b2fc 0x0062b26c and 0x006ada90. This now looks like the first real shell-to-gameplay world-entry bring-up path rather than shell-only staging.,objdump + analysis-context + caller xrefs + strings 0x00444dd0,3301,map_bundle_open_reference_databases,map,cdecl,inferred,ghidra-headless,3,Opens and registers a broad reference-database bundle for the active map path. The routine formats %1\\%2 paths allocates bundle state through 0x00530c80 and wires many global datasets including gpdLabelDB gpdCityDB and related city geographic and map reference tables before later shell and map loaders continue.,ghidra + rizin + llvm-objdump + strings +0x00445ac0,790,shell_map_file_entry_coordinator,map,cdecl,inferred,objdump + analysis-context,3,Broad shell-side map or scenario file entry coordinator reached from tutorial launch shell UI editor-panel flows and scenario batch processing. It accepts either an incoming base filename or a generated Quicksave-style name chooses one extension family among .gmp .gmx .gmc .gms and .smp based on current shell state and then routes into either the heavier shell transition branch at 0x00443a50 or the sibling .smp world-state branch at 0x00446d40 while toggling shell event state and controller cleanup fields. This is currently the broadest grounded map-scenario coordinator above the narrower bundle loaders even though the exact user-facing verbs of every branch still need tightening.,objdump + analysis-context + caller xrefs + strings +0x00445de0,1115,shell_map_file_world_bundle_coordinator,map,cdecl,inferred,objdump + analysis-context,3,Lower-level world-bundle coordinator used by scenario batch processing and neighboring shell-editor callers. It derives a target filename or quicksave name chooses the same extension family and then either invokes 0x00446240 for the live-world serialization branch when the current runtime state takes the .smp path or falls back to map_bundle_open_reference_databases at 0x00444dd0 after shell-state gating status work and controller notifications. The function therefore sits directly above both the reference-database load path and one sibling live-world packaging path even though the exact user-facing verb of each branch remains partly unresolved.,objdump + analysis-context + caller xrefs + strings 0x00456920,3247,unit_visual_init_weapon_airframe_and_exhaust_effects,bootstrap,thiscall,inferred,ghidra-headless,4,Initializes one armed-unit visual bundle spanning turret and cannon hardware exhaust emitters and aircraft airframe attachments. The routine creates static Turret Mantlet Cannon and MuzzleFlash assets at [this+0x31a] through [this+0x326] direct JetExhaust and PropExhaust sprite emitters at [this+0x2f6] and [this+0x2fa] a cannon-audio attachment at [this+0x32a] indexed WingL and WingR assets plus plane-audio state at [this+0x32e] through [this+0x346] and cached Aileron Elevator Rudder and Thrust vectors at [this+0x2d1] [this+0x2c5] [this+0x2b9] and [this+0x2dd].,ghidra + rizin + llvm-objdump + strings 0x00461650,120,map_load_geographic_label_database,map,cdecl,inferred,ghidra-headless,3,Loads the geographic-label database branch inside the broader reference-bundle setup. It stages resource ids 0x5209 through 0x520b binds the selected bundle through 0x517d90 iterates the loaded collection with 0x517cf0 0x518380 and 0x518140 and dispatches each record through vtable slot +0x44 using the current map path context.,ghidra + rizin + llvm-objdump + strings 0x00464410,12679,shell_dispatch_ui_command,shell,cdecl,inferred,ghidra-headless,4,Large shell UI command dispatcher reached from shell-side event callbacks and direct command pushes. It switches over many command ids including 0x7530 through 0x7532 graphics-preset commands that route into 0x0051ebc0 0x00484590 and 0x004853c0; 0x7533 through 0x7534 TigerTank viewer actions; and 0x7540 through 0x7543 scenario-text report build and batch-processing commands that route into 0x00489830 0x004886e0 and 0x00489a20.,ghidra + rizin + llvm-objdump + strings @@ -8,10 +15,10 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x00474f70,97,effect_slot_update_attached_sprite_emitters,bootstrap,thiscall,inferred,ghidra-headless,3,Advances every sprite emitter stored in one effect-slot container by iterating its pointer list and calling 0x00555e50 with update mode zero. When the caller passes null it instead walks the global linked slot list rooted at 0x006cea74.,ghidra + rizin + llvm-objdump 0x00478200,291,shell_queue_single_world_anchor_overlay,shell,cdecl,inferred,ghidra-headless,3,Builds one world-anchor overlay packet for the current owner object. It samples the owner transform through 0x00455800 and 0x00455810 derives projected half-height and half-width through 0x00477a10 world_anchor_measure_projected_half_height and world_anchor_measure_projected_half_width and then enqueues the finished marker through shell_queue_world_anchor_marker.,ghidra + rizin + llvm-objdump 0x00478330,2432,shell_queue_world_anchor_overlay_list,shell,cdecl,inferred,ghidra-headless,3,Builds and queues a repeated world-anchor overlay list for one owner-managed collection. The routine iterates several owner sublists and state branches repeatedly derives projected extents through 0x00477a10 0x004779c0 world_anchor_measure_projected_half_height and world_anchor_measure_projected_half_width and emits one shell_queue_world_anchor_marker packet per accepted overlay entry.,ghidra + rizin + llvm-objdump -0x00483f70,352,shell_service_pump_iteration,shell,thiscall,inferred,objdump + analysis-context,4,Executes one outer shell-service iteration on the shell state rooted at 0x006cec74. The helper can queue service event 0xcc through the shell bundle at 0x006d4018 polls that bundle through 0x00483ea0 refreshes active-mode or shell-state flags ensures the controller work pointer [0x006d4024+0x28] defaults to 0x0062be68 runs several global maintenance helpers and auxiliary cleanup then dispatches shell_state_service_active_mode_frame; when shell-state flag [this+0x501] is set it also marks the controller layout dirty through 0x0051f070 before returning the loop-continue result. bootstrap_init_shell_window_services calls it in the repeating shell loop before mode transitions continue.,objdump + analysis-context + caller xrefs +0x00483f70,352,shell_service_pump_iteration,shell,thiscall,inferred,objdump + analysis-context,4,Executes one outer shell-service iteration on the shell state rooted at 0x006cec74. The helper can queue service event 0xcc through the shell bundle at 0x006d4018 polls that bundle through 0x00483ea0 refreshes active-mode or shell-state flags ensures the controller work pointer [0x006d4024+0x28] defaults to 0x0062be68 runs several global maintenance helpers and auxiliary cleanup then dispatches shell_state_service_active_mode_frame; when shell-state flag [this+0x501] is set it also marks the controller layout dirty through 0x0051f070 before returning the loop-continue result. bootstrap_init_shell_window_services calls it in the repeating shell loop that appears to own the observed shell lifetime before teardown.,objdump + analysis-context + caller xrefs 0x00485750,14,shell_has_tiger_tank_viewer,shell,cdecl,inferred,ghidra-headless,4,Returns whether the dedicated TigerTank shell viewer object at 0x006cfc8c is currently active. The 0x7533 open and 0x7534 close commands both gate on this global before showing status text or mutating viewer state.,ghidra + rizin + llvm-objdump + strings -0x004840e0,863,bootstrap_init_shell_window_services,bootstrap,cdecl,inferred,ghidra-headless,4,Consumes the early bootstrap object then allocates and installs the shell service bundle rooted at 0x006d4024 seeds a 640x480 fallback and enters the bootstrap-owned shell loop around shell_service_pump_iteration at 0x00483f70 until shell state [this+0x10] changes; after that it drives the next shell mode transition through 0x00482ec0 before later startup continues.,ghidra + rizin + llvm-objdump -0x00484440,323,app_bootstrap_main,bootstrap,cdecl,inferred,ghidra-headless,4,Primary post-CRT bootstrap coordinator; initializes COM and branding strings then probes host state and hands off into the main application bootstrap chain.,ghidra + rizin +0x004840e0,863,bootstrap_init_shell_window_services,bootstrap,cdecl,inferred,ghidra-headless,4,Consumes the early bootstrap object then allocates and installs the shell service bundle rooted at 0x006d4024 seeds a 640x480 fallback and enters the bootstrap-owned shell loop around shell_service_pump_iteration at 0x00483f70 until shell state [this+0x10] changes; after each break it drives the next shell mode transition through 0x00482ec0 and when the shell lifetime finally ends it tears the shell bundle back down through 0x00521390 before returning to app_bootstrap_main.,ghidra + rizin + llvm-objdump +0x00484440,323,app_bootstrap_main,bootstrap,cdecl,inferred,ghidra-headless,4,Primary post-CRT bootstrap coordinator; initializes COM and branding strings probes host state allocates the shell state at 0x006cec74 and then hands shell execution into bootstrap_init_shell_window_services. After that helper returns it releases the shell globals and finishes the remaining process-tail cleanup before exiting back through the CRT.,ghidra + rizin + llvm-objdump 0x00484590,887,shell_init_graphics_preset_state,shell,cdecl,inferred,ghidra-headless,3,Initializes the shell graphics-preset state block rooted at [this+0x70]. It clears a large option buffer seeds many default fields and applies one of three coarse mode layouts from its integer argument before later preset application or config-save helpers continue.,ghidra + rizin + llvm-objdump 0x00484910,105,shell_save_graphics_config,shell,cdecl,inferred,ghidra-headless,4,Persistently writes the current shell graphics configuration to data\\configuration\\game.cfg. It optionally syncs the global display runtime through 0x0051eea0 then writes config keys 0x429 and 0x48d from the shell state block before closing the file.,ghidra + rizin + llvm-objdump + strings 0x00484980,212,shell_load_graphics_config_or_init_defaults,shell,cdecl,inferred,ghidra-headless,4,Loads the shell graphics configuration from data\\configuration\\game.cfg during early shell setup. It optionally pulls the larger display-runtime blob through 0x0051ef20 validates key 0x429 reads key 0x48d into the shell state block at [this+0x70] and falls back to 0x00484590 plus 0x00484910 when the file is missing or invalid.,ghidra + rizin + llvm-objdump + strings @@ -27,6 +34,8 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x004874f0,70,shell_close_tiger_tank_viewer,shell,cdecl,inferred,ghidra-headless,4,Closes and frees the dedicated TigerTank shell viewer rooted at 0x006cfc8c. It detaches the viewer if currently selected in the shell owner at 0x0062be68 destroys its internal resources through 0x00530680 frees the object and clears the global viewer slot.,ghidra + rizin + llvm-objdump + strings 0x00489830,496,scenario_text_export_report_language_file,scenario,cdecl,inferred,ghidra-headless,3,Opens one existing MAPS\\%s.lng file for the selected map and reports on its parsed contents without rebuilding it. The routine loads the file into memory iterates numbered entries through 0x00488540 formats summary strings through 0x004895c0 and presents success or failure dialogs when interactive mode is enabled.,ghidra + rizin + llvm-objdump + strings 0x00489a20,1085,scenario_text_export_batch_process_maps,scenario,cdecl,inferred,ghidra-headless,4,Enumerates maps\\*.gmp and batch-processes every scenario through the scenario-text export branch. Command 0x7542 runs the build path through 0x004886e0 while command 0x7543 runs the report path through 0x00489830; the wrapper tracks progress formats per-map status strings and emits a final summary dialog.,ghidra + rizin + llvm-objdump + strings +0x004d4500,88,shell_ensure_editor_panel_window,shell,cdecl,inferred,objdump + analysis-context,4,Ensures the shell-side EditorPanel.win helper window rooted at 0x006d07b4 exists. When the panel is absent it allocates a 0x7c-byte window object seeds the vtable at 0x005d0cb8 binds the EditorPanel.win resource through 0x0053fa50 publishes the object to the shell runtime through 0x00538e50 event 0x1e and then runs the shared panel-open helper at 0x004d4160.,objdump + analysis-context + strings +0x004ddbd0,1096,shell_detail_panel_transition_manager,shell,thiscall,inferred,objdump + analysis-context,3,Transitions the shell detail-panel controller rooted at 0x006d0818 between many window or panel states tracked in [this+0x8c] with optional selection ids cached at [this+0x78] through [this+0x90]. The manager tears down the prior child panel at [this+0x88] through 0x004dd950 updates selector or status UI through 0x004dd410 conditionally opens helper windows such as EditorPanel.win through 0x004d4500 and then allocates one of many shell-facing detail windows including TrainDetail.win TrainList.win and neighboring panel objects before publishing the new child through the shell runtime at 0x006d401c. shell_transition_mode reaches this manager on one branch but the current evidence keeps it on the shell-detail path rather than the first gameplay-world-entry coordinator.,objdump + analysis-context + strings 0x00468d00,222,multiplayer_update_semicolon_name_list,shell,cdecl,inferred,ghidra-headless,4,Adds or removes one player-name token in the semicolon-delimited moderation list rooted at `[ecx+0x905c]`. With mode `1` it appends the supplied token only when not already present writing `;` as the delimiter; with mode `0` it removes the matched token collapses the remainder left and skips an adjacent delimiter when present.,ghidra + rizin + llvm-objdump + strings 0x00468de0,14,multiplayer_session_event_forward_action1_request,shell,unknown,inferred,ghidra-headless,2,Session-event callback wrapper that always forwards request id `1` through multiplayer_set_pending_session_substate with a zero auxiliary payload. The callback clears EDX before the shared setter call and currently lands on a request id that does not yet map to a visible pending substate so this row remains structural.,ghidra + rizin + llvm-objdump 0x00468e00,188,multiplayer_session_event_publish_pair_chat_template,shell,unknown,inferred,ghidra-headless,3,Session-event callback that formats one two-string chat/status line through multiplayer_route_chat_line when the callback status in EDX is zero and the current live session count is not positive. A selector near `[esp+0x214]` chooses the template `%s* %s` `%s %s` or `%s > %s`; the helper length-checks both inputs against the local 0x1f4-byte buffer before formatting and returns without publishing when either string is null or too long.,ghidra + rizin + llvm-objdump + strings @@ -129,7 +138,7 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x0051fa60,63,shell_get_nonnegative_memory_budget_floor_bytes,shell,thiscall,inferred,ghidra-headless,3,Returns a nonnegative lower memory-budget value for float consumers in the shell and presentation paths. It prefers explicit tier field [this+0x1146ce] then the active floor bucket behind [this+0x1146c6] and finally baseline field [this+0x1136a9] using the shared 0 1MB 2MB 4MB table at 0x00624c34 and clamping negative results to zero.,ghidra + rizin + llvm-objdump 0x005204b0,128,shell_flush_deferred_work_queues,shell,thiscall,inferred,ghidra-headless,4,Flushes the shell controller's three deferred-work queue roots at [this+0x1136a1] [this+0x11369d] and [this+0x1136a5]. The helper clears the first two containers through intrusive_queue_clear_and_release then rewinds the deferred-item queue through intrusive_queue_rewind_iterator repeatedly pops each queued payload through intrusive_queue_next_iterator_node clears its outer queued-handle slot at [item+0xe8] and finally releases the remaining queue storage before returning. It is used at the end of shell_service_frame_cycle and from the broader shell-mode helper at 0x00443a50.,ghidra + rizin + llvm-objdump 0x00520620,141,shell_service_frame_cycle,shell,thiscall,inferred,ghidra-headless,4,Acts as the outer owner for one pending shell frame cycle on the active controller. When pending-frame state is armed through [this+0x56] and controller pointers [this+0x18] [this+0x1c] and [this+0x28] are live it runs shell_refresh_presentation_frame through 0x0052b990; otherwise it still updates frame timing through 0x0051fd70 runs the mouse-cursor frame updater 0x0053f4e0 requests the deeper layout-state rebuild path through 0x00565110 performs a one-time ShowWindow on the controller window handle at [this] drains deferred work through 0x005204b0 and clears the pending flags at [this+0x56] and [this+0x58].,ghidra + rizin + llvm-objdump -0x00521060,805,bootstrap_init_shell_service_bundle,bootstrap,cdecl,inferred,ghidra-headless,4,Builds the shell-facing singleton bundle stored through globals like 0x006d4024 0x006d402c and 0x006d4030 wiring startup width and height state and an rt3_ prefixed service path.,ghidra + rizin +0x00521060,805,bootstrap_init_shell_service_bundle,bootstrap,cdecl,inferred,ghidra-headless,4,Builds the shell-facing singleton bundle stored through globals like 0x006d4024 0x006d402c and 0x006d4030 wiring startup width and height state an rt3_ prefixed service path and the separate shell input-state object rooted at 0x006d4018.,ghidra + rizin + objdump 0x00521390,486,bootstrap_destroy_shell_service_bundle,bootstrap,cdecl,inferred,ghidra-headless,4,Destroys the shell service bundle created by 0x00521060 releasing each global singleton and clearing 0x006d4024 0x006d402c 0x006d4030 0x006d4020 and 0x006d4018.,ghidra + rizin 0x00523d90,65,shell_commit_layout_updates,bootstrap,thiscall,inferred,ghidra-headless,3,Applies pending layout-slot changes from the shell controller into its subordinate layout-state object at [this+0x2d] by walking embedded service pointers and issuing the follow-on rebuild or refresh calls that make the updated slot table live.,ghidra + rizin 0x00523e40,51,shell_invalidate_layout_state,bootstrap,thiscall,inferred,ghidra-headless,4,Marks the shell controller's layout-state path dirty by setting flags [this+0x3747] [this+0x3748] and [this+0x3749] then forwarding two state parameters into the subordinate object at [this+0x2d].,ghidra + rizin @@ -179,6 +188,11 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x0054bb70,90,layout_state_bind_vertex24_table,bootstrap,thiscall,inferred,ghidra-headless,4,Binds the current 24-byte vertex24 table at [this+0x2647] onto the presentation node if it changed since the last bind. The helper drives node property 0x142 through vtable slots +0x130 and +0x14c with record size 0x18 and clears the local dirty byte at [this+0x263b].,ghidra + rizin + llvm-objdump 0x0054bc10,592,shell_init_layout_state_defaults,bootstrap,thiscall,inferred,ghidra-headless,4,Initializes the large subordinate layout-state object allocated by 0x0055e2b0; seeds default float and flag fields points [this+0x83c] at a shell-bundle template block near 0x006d4024+0x11468a optionally copies a 0x72c-byte preset table and notifies the shell bundle service at [0x006d4024+0x28].,ghidra + rizin 0x0054bea0,1399,layout_state_apply_interpolated_pose,bootstrap,thiscall,inferred,ghidra-headless,4,Applies an interpolated pose and palette sample on the subordinate layout-state object using the controller counters passed by callers; clamps the time window blends preset tables at offsets 0x840 through 0x86f updates color bytes at 0x2510 through 0x2512 invokes the bound presentation node at [this+0x25df] and finishes through 0x0054a280.,ghidra + rizin +0x0054e3a0,528,shell_controller_window_message_dispatch,shell,stdcall,inferred,objdump,4,Primary window-message ingress for the active shell controller window. The dispatcher branches over low window lifecycle messages handles `WM_KEYDOWN` and `WM_KEYUP` by first updating the shell controller through 0x0051f0c0 or 0x0051f0d0 and then forwarding the transition into shell_input_apply_window_key_transition at 0x0054f290 on the shell input object rooted at 0x006d4018 routes `WM_COMMAND` through 0x0054eb10 routes mouse messages in the `0x0200..0x0208` family through 0x0054ee50 and falls back to `DefWindowProcA` for unhandled cases. This is the first grounded shell-side input ingest path rather than only a generic message drain.,objdump + import table + callsite inspection +0x0054e5d0,88,shell_drain_pending_window_messages,shell,cdecl,inferred,objdump + analysis-context,4,Shared pending-message drain that loops on `PeekMessageA` with remove mode 1 and feeds each dequeued record through `TranslateMessage` and `DispatchMessageA` until the queue is empty. Shell modal waits layout rebuild paths mouse-cursor frame work and the keyboard-toggle helpers all reuse this routine so it sits below the real input handlers rather than serving as the input dispatcher itself.,objdump + analysis-context + import table +0x0054e710,110,shell_input_state_init,shell,thiscall,inferred,objdump + analysis-context,3,Initializes the standalone shell input-state object later stored at 0x006d4018. It zeroes the 0xaa8-byte state block resets counters and flags under +0xa88 through +0xa9c caches host metrics through `GetSystemMetrics` and `GetDoubleClickTime` and clears the per-key state storage that later window-message handlers update.,objdump + analysis-context + import table +0x0054f290,480,shell_input_apply_window_key_transition,shell,thiscall,inferred,objdump + analysis-context,4,Normalizes one `WM_KEYDOWN` or `WM_KEYUP` transition for the shell input object at 0x006d4018. The helper samples `GetKeyboardState` optionally derives an ASCII byte through `ToAscii` updates the 256-byte per-key table starting at [this+0x100] maps selected virtual-key ranges into packed shell input flags at [this+0xa8c] and then forwards the synthesized event record through 0x0054e9c0 for later shell consumers. The shell controller window dispatcher at 0x0054e3a0 is the grounded caller.,objdump + analysis-context + import table + callsite inspection +0x0054f4d0,109,shell_input_snapshot_dispatch_state,shell,thiscall,inferred,objdump + analysis-context,3,Captures one filtered snapshot of the current shell input object state into a 0x30-byte caller buffer while temporarily zeroing the nested-dispatch counter at [this+0xa90]. Several shell and cursor consumers use this as the read-side companion to shell_input_apply_window_key_transition optionally passing the snapshot through the callback hook stored at 0x006d4008 before consuming it.,objdump + analysis-context + caller xrefs 0x0054f640,83,shell_step_global_presentation_phase_scalar,shell,cdecl,inferred,ghidra-headless,2,Steps the shared presentation-phase scalar stored at 0x00d93850 downward by a small constant then clamps the returned value against fixed lower-bound constants. Callout-marker world-anchor and other presentation helpers use this as a common time-varying scalar after one of the nearby setters has seeded the global phase.,ghidra + rizin + llvm-objdump 0x0054f700,12,shell_set_global_presentation_phase_scalar,shell,cdecl,inferred,ghidra-headless,3,Stores one caller-supplied float into the shared presentation-phase scalar at 0x00d93850. Mouse-cursor geographic-label and other presentation helpers seed this global before later batch or marker helpers consume it through 0x0054f640.,ghidra + rizin + llvm-objdump 0x0054f710,729,shell_queue_callout_segment_marker,shell,cdecl,inferred,ghidra-headless,2,Queues one short world-space callout segment or marker packet using the shell zoom table rooted at [0x006d4024+0x11421e] and [0x006d4024+0x34]. The helper derives scaled endpoint deltas from the caller inputs applies flag-controlled clamps from arg_14h and emits three type-0x01 deferred messages through shell_enqueue_deferred_message_type1.,ghidra + rizin + llvm-objdump diff --git a/docs/control-loop-atlas.md b/docs/control-loop-atlas.md index a0df2b9..f6a1a70 100644 --- a/docs/control-loop-atlas.md +++ b/docs/control-loop-atlas.md @@ -20,19 +20,19 @@ anchor it, and where control is handed to neighboring subsystems. - Trigger/Cadence: one-time bootstrap handoff immediately after CRT completion. - Key Dispatchers: `app_bootstrap_main`, `bootstrap_init_shell_window_services`, `shell_install_global_controller`, `shell_service_pump_iteration`, graphics config load or default-init helpers, runtime capability probes, and early shell service initializers under the `0x004610..0x0053f0..` branch. - State Anchors: global shell controller pointer `0x006d4024`, sibling display/runtime globals under `0x006d402c` and `0x006d4030`, and host capability flags gathered by `bootstrap_probe_system_profile`. -- Subsystem Handoffs: after the global shell controller has been installed the bootstrap path enters the repeating `shell_service_pump_iteration` loop, which services shell-state work and hands each iteration down into the controller frame path. +- Subsystem Handoffs: after the global shell controller has been installed the bootstrap path enters the repeating `shell_service_pump_iteration` loop, which services shell-state work and hands each iteration down into the controller frame path; when the shell lifetime ends this same bootstrap path tears the shell bundle down and returns to `app_bootstrap_main`. - Evidence: `startup-call-chain.md`, function-map rows for `app_bootstrap_main`, `bootstrap_init_shell_window_services`, `shell_install_global_controller`, `shell_service_pump_iteration`, `shell_load_graphics_config_or_init_defaults`, `shell_reset_display_runtime_defaults`, and related graphics setup helpers. -- Open Questions: whether `bootstrap_init_shell_window_services` remains the long-lived shell main loop for all shell modes or later hands control to another outer coordinator after certain transitions. +- Open Questions: whether gameplay or in-engine world stepping later escapes this bootstrap-owned shell loop entirely, or whether gameplay entry still rendezvous with the same outer coordinator before the shell bundle is destroyed. ## Shell UI Command and Deferred Work Flow - Roots: shell callback paths that converge on `shell_dispatch_ui_command` at `0x00464410`. - Trigger/Cadence: event-driven UI command dispatch plus deferred-message queue flushing during shell activity. - Key Dispatchers: `shell_dispatch_ui_command`, `shell_enqueue_deferred_work_message`, `shell_post_deferred_message_type5`, `shell_post_deferred_message_type6`, `shell_enqueue_deferred_message_type4`, `shell_enqueue_deferred_message_type1`. -- State Anchors: shell object at `0x0062be68`, queue roots around `[this+0x11369d]`, `[this+0x1136a1]`, and `[this+0x1136a5]`, plus global routing gates at `0x006d4034`. -- Subsystem Handoffs: routes into graphics config, scenario-text export, overlay generation, multiplayer UI, and presentation-facing deferred work later drained by `shell_service_frame_cycle`. -- Evidence: function-map shell rows around `0x00464410` and `0x0051f1d0..0x0051f460`. -- Open Questions: whether the shell command dispatcher is also used by hotkeys or only by UI callback tables. +- State Anchors: shell object at `0x0062be68`, queue roots around `[this+0x11369d]`, `[this+0x1136a1]`, and `[this+0x1136a5]`, global routing gates at `0x006d4034`, and the separate detail-panel controller rooted at `0x006d0818`. +- Subsystem Handoffs: routes into graphics config, scenario-text export, overlay generation, multiplayer UI, shell detail windows such as `EditorPanel.win` and `TrainDetail.win`, and presentation-facing deferred work later drained by `shell_service_frame_cycle`. +- Evidence: function-map shell rows around `0x00464410`, `0x004d4500`, `0x004ddbd0`, and `0x0051f1d0..0x0051f460`. +- Open Questions: whether the shell command dispatcher is also used by hotkeys or only by UI callback tables; the current `0x006d0818` detail-panel path looks shell-only and does not yet explain gameplay world entry. ## Presentation, Overlay, and Frame Timing @@ -42,17 +42,17 @@ anchor it, and where control is handed to neighboring subsystems. - State Anchors: shell state at `0x006cec74`, active mode pointer `0x006cec78`, shell frame history ring at `0x006d403c`, display/runtime state inside the controller block near `[this+0x114282]` and `[this+0x11428a]`, presentation service pointer at `[this+0x0c]`, and the native controller window handle at `[this+0x00]`. - Subsystem Handoffs: the bootstrap-owned pump runs shell-bundle polling and shell-state maintenance before the shell-state pass synchronizes active-mode helpers and modal-status work and dispatches the controller frame cycle, which then consumes world/object state for overlays and presentation refresh, uses the controller window handle for one-time `ShowWindow` and related UI interaction, and drains the deferred work queues at the end of the cycle. - Evidence: function-map rows for `shell_service_pump_iteration`, `shell_state_service_active_mode_frame`, `shell_service_frame_cycle`, `shell_flush_deferred_work_queues`, frame history, gamma ramp, world-anchor overlay builders, and graphics runtime helpers. -- Open Questions: whether this bootstrap-owned shell pump also remains the steady-state owner for later shell modes and how simulation cadence rendezvous with the shell presentation cadence once gameplay takes over. +- Open Questions: how simulation cadence rendezvous with the shell presentation cadence once gameplay takes over and whether gameplay stepping exits this shell-owned controller path entirely. ## Map and Scenario Content Load -- Roots: reference-database setup via `map_bundle_open_reference_databases` at `0x00444dd0`, followed by narrower loaders such as `map_load_geographic_label_database` and `map_load_city_database`. -- Trigger/Cadence: map or scenario open paths and scenario-text export commands. -- Key Dispatchers: `map_bundle_open_reference_databases`, `map_load_geographic_label_database`, `map_load_city_database`, `scenario_text_export_build_language_file`, `scenario_text_export_report_language_file`, `scenario_text_export_batch_process_maps`. -- State Anchors: map bundle state allocated through `0x00530c80`, geography tables rooted at `0x0062b2fc` and `0x0062b268`, shell-side map-selection context. -- Subsystem Handoffs: feeds shell preview panels, scenario export tooling, and later gameplay map state. -- Evidence: function-map map/scenario rows, analysis-context exports for geographic-label and city database strings. -- Open Questions: the main gameplay map-load entrypoint is still broader than the currently grounded reference-database loaders; scenario load versus scenario-text export remain only partially overlapped. +- Roots: `shell_map_file_entry_coordinator` at `0x00445ac0`, the first grounded world-entry branch `world_entry_transition_and_runtime_bringup` at `0x00443a50`, `shell_map_file_world_bundle_coordinator` at `0x00445de0`, reference-database setup via `map_bundle_open_reference_databases` at `0x00444dd0`, and narrower loaders such as `map_load_geographic_label_database` and `map_load_city_database`. +- Trigger/Cadence: shell tutorial launch, editor or detail-panel file actions, map-scenario open paths, and scenario-text export batch commands. +- Key Dispatchers: `shell_map_file_entry_coordinator`, `world_entry_transition_and_runtime_bringup`, `world_runtime_release_global_services`, `shell_map_file_world_bundle_coordinator`, `map_bundle_open_reference_databases`, `map_load_geographic_label_database`, `map_load_city_database`, `scenario_text_export_build_language_file`, `scenario_text_export_report_language_file`, `scenario_text_export_batch_process_maps`. +- State Anchors: shell-side file staging buffers at `0x0062bee0` and `0x0062bec4`, shell and mode globals at `0x006cec74` and `0x006cec78`, world object root `0x0062c120`, map bundle state allocated through `0x00530c80`, and geography tables rooted at `0x0062b2fc` and `0x0062b268`. +- Subsystem Handoffs: the broad shell entry coordinator chooses between a full shell mode-transition and world bring-up path versus a sibling `.smp` world-state path. The heavier branch now appears to be the first true shell-to-gameplay handoff: it resets the prior world bundle, allocates the new `0x0062c120` world root from the staged filename, initializes multiple world-facing managers, and only then leaves later map content and runtime stepping to narrower helpers. The lower coordinator still fans into the live-world packaging branch at `0x00446240` or the reference-database bundle load at `map_bundle_open_reference_databases`, which in turn feeds shell preview panels scenario export tooling and later gameplay map state. +- Evidence: function-map map/scenario rows, analysis-context exports for `0x00445ac0`, `0x00445de0`, `0x00443a50`, `0x00434300`, and `0x00444dd0`, plus objdump string evidence for `.gmp`, `.gmx`, `.gmc`, `.gms`, `.smp`, and `Quicksave`. +- Open Questions: the exact user-facing verb split between the `.smp` branch and the `.gmp/.gmx/.gmc/.gms` branch still needs tightening, but the remaining high-value question is no longer whether `0x00443a50` is world entry. It is where the long-lived simulation cadence takes over after this bring-up and whether that cadence still rendezvous with the shell-owned frame path or escapes into a separate gameplay loop. ## Multiplayer Session and Transport Flow @@ -66,18 +66,18 @@ anchor it, and where control is handed to neighboring subsystems. ## Input, Save/Load, and Simulation -- Roots: not yet cleanly named in the current ledger. -- Trigger/Cadence: expected recurring gameplay or shell-driven loops, but the current evidence is still indirect. -- Key Dispatchers: currently unresolved; nearest grounded hints are `bootstrap_capture_keyboard_state`, filesystem-related strings, and shell pathways that save graphics config rather than gameplay state. -- State Anchors: input DLL import `DINPUT8.dll`, save/load path strings under `.\Saved Games\`, and map/scenario globals already observed elsewhere. -- Subsystem Handoffs: likely connect shell/UI into gameplay state, but not yet strongly evidenced in committed exports. -- Evidence: `binary-summary.json`, `imported-dlls.txt`, `subsystem-inventory.md`, and broad strings in `interesting-strings.txt`. -- Open Questions: first real input pump, first gameplay save/load dispatcher, first simulation tick owner, and the exact boundary between shell frame work and gameplay world stepping. +- Roots: the shell controller window-message ingress `shell_controller_window_message_dispatch` at `0x0054e3a0`, the shell input-state object initialized at `0x006d4018` through `shell_input_state_init` `0x0054e710`, `world_entry_transition_and_runtime_bringup` at `0x00443a50`, the frame-owned cadence `simulation_frame_accumulate_and_step_world` at `0x00439140`, and the lower step family rooted at `simulation_advance_to_target_calendar_point` `0x0040ab50` with periodic branches through `simulation_service_periodic_boundary_work` `0x0040a590`. +- Trigger/Cadence: shell-side input is event-driven by controller-window `WM_*` traffic while post-bring-up gameplay service becomes recurring once a world root exists at `0x0062c120`; elapsed wall-clock time is then accumulated and converted into one or more simulation-step quanta. +- Key Dispatchers: `shell_controller_window_message_dispatch`, `shell_input_apply_window_key_transition`, `shell_input_snapshot_dispatch_state`, `simulation_frame_accumulate_and_step_world`, `simulation_advance_to_target_calendar_point`, the smaller single-step helper at `0x00409e80`, `0x0040a9c0`, `0x0040a910`, and `simulation_service_periodic_boundary_work`. +- State Anchors: shell input object `0x006d4018`, per-key state table starting at `[input+0x100]`, packed shell input flags at `[input+0xa8c]`, nested dispatch counter `[input+0xa90]`, global shell controller `0x006d4024`, active world root `0x0062c120`, accumulated leftover simulation time at `[this+0x4c80]`, shell and mode globals at `0x006cec74`, `0x006cec78`, and `0x006cec7c`, world manager collections at `0x0062be10`, `0x006ceb9c`, `0x006cfcbc`, `0x006cec20`, and `0x0062bae0`, plus the packed calendar-like tuple fields around `[this+0x0d]`, `[this+0x0f]`, `[this+0x11]`, and `[this+0x14]`. +- Subsystem Handoffs: the controller window dispatcher now looks like the first grounded input ingress. It translates keyboard and mouse `WM_*` traffic into shell controller state and the separate input object at `0x006d4018`; read-side cursor and shell consumers later snapshot that object through `shell_input_snapshot_dispatch_state`. After world entry the frame-owned cadence computes how much simulation time should elapse and repeatedly hands that budget into `simulation_advance_to_target_calendar_point`; the step helper then advances the world in coarse or fine increments, enters the periodic maintenance family when boundary conditions hit, notifies the live world root through `0x00450030`, and returns to the frame owner for later shell-facing and world-facing follow-up work. +- Evidence: function-map rows for `shell_controller_window_message_dispatch`, `shell_drain_pending_window_messages`, `shell_input_state_init`, `shell_input_apply_window_key_transition`, `shell_input_snapshot_dispatch_state`, `world_entry_transition_and_runtime_bringup`, `simulation_frame_accumulate_and_step_world`, `simulation_advance_to_target_calendar_point`, and `simulation_service_periodic_boundary_work`, plus analysis-context exports for the shell input cluster and the simulation cluster around `0x00439140`, `0x0040ab50`, and `0x0040a590`. +- Open Questions: whether gameplay continues to reuse this shell controller and input object path or hands off to a deeper world-mode input branch; the exact public semantics of the packed simulation tuple fields need tightening; and the save/load family still needs a cleaner user-facing split between autosave or package work and regular simulation stepping. ## Next Mapping Passes -- Determine whether `bootstrap_init_shell_window_services` and `shell_service_pump_iteration` remain the long-lived shell main loop after early shell transitions or later hand off to another outer coordinator. -- Connect the map bundle open path to the broader map/scenario load coordinator instead of only the database leaves. +- Clarify the user-facing split between the `.smp` branch and the `.gmp/.gmx/.gmc/.gms` branch under `shell_map_file_entry_coordinator`. - Identify the owner loop that repeatedly services multiplayer transport I/O and dispatch-store work. -- Ground the first real input ingest path and the first gameplay save/load dispatcher. +- Determine whether gameplay keeps using `shell_controller_window_message_dispatch` and the `0x006d4018` input object or hands off to a deeper world-mode input branch after world entry. +- Ground the first gameplay save/load dispatcher and tie it back to the already-mapped `.smp` and live-world packaging branch. - Keep detailed pending-template or transport work scoped to the specific atlas edges that remain unresolved.