feat(system): Add startup working directory options - #3149
feat(system): Add startup working directory options#3149CryoTheRenegade wants to merge 11 commits into
Conversation
… directory Co-authored-by: Cursor <cursoragent@cursor.com>
PR Summary by QodoAdd -cwd flag to control startup working directory across game and tools
AI Description
Diagram
High-Level Assessment
Files changed (9)
|
Code Review by Qodo
1.
|
Co-authored-by: Cursor <cursoragent@cursor.com>
…Line Co-authored-by: Cursor <cursoragent@cursor.com>
Have the game and tools share parseCommandLineForStartup so the working directory is applied in one place, without a GlobalData flag or a second tokenizer. Co-authored-by: Cursor <cursoragent@cursor.com>
|
| Filename | Overview |
|---|---|
| Core/GameEngine/Source/Common/CommandLine.cpp | Centralizes CRT-based startup and engine argument parsing, records consumed argument positions, and applies the selected working-directory policy. |
| Core/GameEngine/Source/Common/WorkingDirectory.cpp | Implements executable-relative, inherited, and explicit Win32 working-directory selection. |
| Core/Tools/MapCacheBuilder/Source/WinMain.cpp | Reuses shared startup parsing and excludes consumed startup arguments from map inputs. |
| Generals/Code/Tools/WorldBuilder/src/WorldBuilder.cpp | Integrates shared startup parsing and filters consumed arguments before MFC-specific parsing. |
| GeneralsMD/Code/Tools/WorldBuilder/src/WorldBuilder.cpp | Mirrors the WorldBuilder startup and argument-filtering integration for Zero Hour. |
| Generals/Code/Main/WinMain.cpp | Moves shared startup parsing and working-directory selection ahead of relative startup resource loading. |
| GeneralsMD/Code/Main/WinMain.cpp | Applies the same startup ordering and working-directory behavior to Zero Hour. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
Start[Process startup] --> Parse[Parse startup arguments once]
Parse --> Choice{Working-directory option}
Choice -->|setCwd path| Explicit[Use explicit directory]
Choice -->|useCwd| Inherited[Keep inherited directory]
Choice -->|Neither| Executable[Use executable directory]
Explicit --> Record[Record consumed argument positions]
Inherited --> Record
Executable --> Record
Record --> App{Application}
App --> Game[Generals or Zero Hour]
App --> GUI[GUIEdit]
App --> WB[WorldBuilder]
App --> Cache[MapCacheBuilder]
WB --> Filter[Skip consumed startup arguments]
Cache --> Filter
Reviews (8): Last reviewed commit: "refactor(system): Clean up command-line ..." | Re-trigger Greptile
VC6 does not support in-class member initializers, which broke the WorldBuilder command-line parser on CI. Co-authored-by: Cursor <cursoragent@cursor.com>
xezon
left a comment
There was a problem hiding this comment.
Becomes better, but it is still sloppy.
| { | ||
| if (CommandLine::isCommandLineArgumentParsedForStartup(m_argIndex++)) | ||
| { | ||
| ParseLast(bLast); |
There was a problem hiding this comment.
ParseLast(bLast) tells MFC when command-line parsing is finished. Normally, CCommandLineInfo::ParseParam() calls it, but this branch returns early. Without this call, WorldBuilder.exe some.map -useCwd sees the map name but does not open it.
| // TheSuperHackers @feature 14/08/2026 | ||
| // -useCwd keeps the OS working directory. | ||
| s_cwdOptionSpecified = TRUE; | ||
| rts::keepCurrentDirectory(); |
There was a problem hiding this comment.
I don't think this is correct.
Picture setting command line -setCwd Path -useCwd, this then uses Path instead of Current Directory.
We would expect the last command line argument to win the race.
Summary
-useCwdto keep the inherited working directory and-setCwd <path>to select an explicit startup directoryCommandLine::parseCommandLineForStartup()for the games, GUIEdit, WorldBuilder, and MapCacheBuilderFor Visual Studio, add
-useCwdto Command Arguments and set Working Directory to the game install path.To select an explicit directory, pass its path after
-setCwd. Quote paths that contain spaces:This recreates the abandoned #1445 feature and applies the review feedback from that PR:
GlobalDatamiddleman flagWorkingDirectoryConsiderations from #1445:
mss32.dllandBINKW32.DLLare not system DLLs. See Win32 DLL search order.LoadImageAandLoadCursorFromFilesearch the executable path, then the current working directory, then%PATH%. See OpenFile remarks.fopenuse the current working directory.This change was drafted with LLM assistance.