* Add command-line option overrides to options system
- Extend `OptionsManager` to support storing and displaying reasons for overrides.
- Update related code paths to prioritize command-line overrides, ensure correct option resolution, and display override details in the UI.
- Add unit tests for override behavior and round-trip validation.
- Remove unused legacy functions (`removeVSyncOption`, `removeWindowModeOption`) in favor of the new system.
* Add unit tests for `Graphics.Anisotropy` option validation with and without OpenGL
* Add support for associating command-line option names to `OptionsManager` overrides
- Update HDR, shadow rendering, and graphics API option overrides to include their respective command-line flag names.
- Refactor `Graphics.RenderAPI` to use the `GraphicsAPI` enum instead of raw integers for better type safety and clarity.
- Ensure Vulkan support logic and fallback behavior function correctly with the updated options system.
- Update unit tests to validate override functionality and enum-based API configuration.
* Remove unused `removeVSyncOption` function
* Apply the PR review feedback for the command-line option overrides
Delete the unit-test run artifacts that this branch committed by mistake, and
add .gitignore rules for the files that the unittests binary writes.
Give an override priority over an in-session edit again. The options UI now
shows a disabled control for an overridden option, and setConfigValue()
refuses an edit for an overridden key. Before this change, a save wrote the
edit to the config file and applied it to the bound global, but getValue()
kept returning the override. The game and the options menu then showed
different values for the rest of the session.
Add a setOverride() overload that takes a JSON value. Every command-line flag
now builds its override with json_integer, json_real, json_true, json_false
or json_pack, in place of a hand-formatted string.
Make Graphics.CockpitFOV and Graphics.CockpitFOVToggle independent of the
order in which the options manager loads them, and remove the forced override
on the player's toggle preference. The toggle listener also replaces an
identical bind_to() call that made the listener dead code.
Add 16 to the values of Graphics.MSAASamples. The -msaa flag accepts 16, so an
override with that value made printValues() report an invalid value.
Keep the render API that the caller gives to gr_init(). Only a Default value
now comes from the Graphics.RenderAPI option, so FRED and the unit tests keep
the backend that they ask for.
Make the default_func of Graphics.Shadows and Graphics.ShadowRenderMethod
return their global. A constant discarded the value that -enable_shadows and
the mod table set. Set Max_rt_shadow_local_lights to 4, because 3 is not one
of the values that the option offers.
Also: resolve -lang one time, share the render API name with version.cpp,
correct the stale comments, and add unit tests with a fixture that clears the
overrides after each test.
Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UGh4ZM2u4oUGSbrP122Uyr
* Fix the order-dependent crash in the MSAA option test
The test `MsaaOverrideAcceptsEverySampleCountTheFlagAllows` calls
`getValidValues()`. `Option<T>` makes a display string for each value, and the
display function of `Graphics.MSAASamples` calls `XSTR()`. `XSTR()` runs
`Int3()` if `lcl_xstr_init()` did not run before. Only `FSTestFixture` runs it,
and `Xstr_inited` stays set for the remainder of the process. Thus the shuffled
test order decided if the test passed or if it stopped the test binary with
SIGILL.
Move that one test to a new fixture that derives from `FSTestFixture`. The
fixture initializes localization, and it also clears the overrides after each
test. Refresh the comment that told that the test binary never runs
`lcl_init()`.
Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UGh4ZM2u4oUGSbrP122Uyr
---------
Co-authored-by: Claude Opus 5 <[email protected]>
Add coverity[GLOBAL_INIT_ORDER] annotations to ~50 global variables
across 27 files. These were all analyzed and confirmed safe:
- ~48 OptionBuilder::finish() globals use a Meyers singleton
(OptionsManager::instance()), which guarantees safe init order.
Destruction is also safe due to shared_ptr ref-counting.
- 6 default-constructed container globals (vectors, maps) have no
cross-TU dependencies at construction or destruction time.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Just as special tokens are replaced in debriefings, replace them in command briefings and briefings as well.
Change `string_replace_tokens_with_keys` to `message_translate_tokens` (since it's the same thing) and add a `replaceContainers` script API function to complement `replaceVariables` and `replaceTokens`.
Also replace every category of token in `sexp_modify_variable` and add comments to places where token replacement might be expected but happens elsewhere.
Although normalized vectors in FSO are supposed to stay normalized, occasionally small floating point errors can pop up. In most cases these do not cause a problem, but in certain cases these errors can rapidly accumulate and corrupt an otherwise well-behaved matrix. This can most easily be seen with daisy-chained dock sequences or docked ships with angled dockpoints.
This PR audits the usage of `vm_vector_2_matrix_norm` to re-normalize vectors in cases where floating point errors could accumulate. There are also a few new Assertions for extra vigilance.
Follow-up to #6596. Fixes#6634.
Most places in the code that use `vm_vector_2_matrix` do so on already-normalized vectors. Changing these to `vm_vector_2_matrix_norm` avoids redundant normalization.
Original issue post #6509. This flag controls if set-camera-host sexp uses the model's eyepoint for the camera position and orientation when no submodel is specified.
Without the flag, the camera will use the model's origin position and orientation.
Make these convenient functions even more convenient:
1. Change `object_get_model()` to `object_get_model_num()` and `object_get_model_instance()` to `object_get_model_instance_num()` to more accurately reflect what they do
2. Add new `object_get_model()` and `object_get_model_instance()` functions to return `polymodel*` and `polymodel_instance*` values.
This refactors the object_h struct to store objects as indexes rather than pointers. This is a prerequisite for making the collection of objects dynamic in the future. See also #6100.
Follow-up to #5800 and #5829.
* add cockpit fov to in-game options and use a define for the default fov value for both fov options
* Add a controlling toggle option
* constexpr
* localization
* Create the ingame options game state
* Base working version of in-game options
* Cleanup + Optimization
* Localization pass
* more cleanup + documentation
* tooltips on option hover
* documentation and better inbounds check
* match case
* format strings instead of direct strings
* unused parameter
* address feedback
* localization id conflict with master
* Add this line back in
* pass the new option flags as well
* resolve xstr id conflict
Use a simpler, more robust, and more correct method of sharing the fire direction among beams: replicate the actual beam vector for all firing points. This further cleans up and simplifies the beam firing code and also clarifies some vector math.
For subtitles drawn using the `$Show-subtitle base resolution:` feature, text near the side of the screen would get clipped off mysteriously. The clipping corresponded precisely to the edge of a 4:3 boundary, which led me to discover that the clip boundary was still at the side of a 4:3 box, rather than a 16:10 box as was expected. Explicitly setting the clip boundary when setting the screen scale fixed the issue.
For any graphics coders in the know, is this actually the proper fix?
When the `$Use host orientation for set-camera-facing` flag in game_settings.tbl is active, the camera will use the host's orientation as a basis for rotation. However if there is no host, the camera unintentionally inherited its old stale orientation. Instead the camera should base its new orientation on the identity matrix which is the expected behavior.
By specifying a base resolution in game_settings.tbl, subtitles can be scaled to the screen in the same way as HUD gauges. This can be used to prevent subtitles from appearing smaller at larger resolutions.
Depends on and is a follow-up to #4157.
What it says on the tin. This allows more precise positioning of subtitles, and a future PR will add the ability to scale them according to screen resolution.
Consolidated these functions and replaced the `find_submodel_point_*` functions with their closest `world_find_` counterparts. (One of those functions may not have actually worked correctly.) Also use the correct coordinate logic when returning normals from collision info in scripting.
Related to #3985 although not yet a fix for it.
As @Baezon figured out, when a host exists, `get_info` will return the orientation relative to the host. When there is no host, `get_info` returns the absolute orientation. In the latter case, `set_rotation_facing` does not need to do extra calculations to find the delta orientation.
Follow-up to #3989.
This is a system for storing arbitrary data in the config file and then
easily retrieving it later on. This has full Lua support for exposing
the available options in a custom UI and changing the values of the
options. This ported some of the existing command line options over to
the new system which is opt-in for the moment by using a mod_table flag.
This maintains the type information which can be used for enforce
const-correctness and also for implementing more advanced ways of
handling the type information.
All transformations are now handled by shaders so there is nothing
special going on in the graphics API specific code anymore. Since model
uniform buffers require access to these matrices I moved the matrix
handling out of the graphics API code.