Development:Adding Config Options

From FEX-Emu Wiki
Revision as of 13:40, 22 June 2022 by Neobrain (talk | contribs) (Add development category)
Jump to navigation Jump to search


Configuration options are programatically generated from json.

This file lives in `FEXCore/Source/Interface/Config/Config.json`

Options section

To add a configuration option that can be set from JSON, FEXLoader arguments, or Environment variables you need to add the option to this file.

Currently FEX has six groups to group configs

  • CPU
  • Emulation
  • Debug
  • Logging
  • Hacks
  • Misc

Configuration option object

Each JSON object under a group becomes a configuration.

Object Layout

  • Key:
 * Becomes the C++ enum. eg. 'Multiblock' becomes `FEXCore::Config::ConfigOption::CONFIG_MULTIBLOCK`
 * Also used for the environment variable. Becomes `FEX_MULTIBLOCK`
 * Also becomes the FEXLoader argument. Becomes `--multiblock`
 * If the object type is boolean then a negated argument also is generated. `--no-multiblock`
  • ShortArg:
 * This is the string that is used for FEXLoader short arguments
 * eg. Multiblock uses m, which turns in to -m in FEXLoader
  • Type:
 * Can be `[bool, uint8, int32, uint32, uint64, str, strarray]`
 * This is what the argument type ends up being once loaded from a configuration backing
  • Default:
 * Default value that matches this object
 * Used to generate code so needs to handle being codified. Compilation will fail otherwise
 * If Type is str or strarray then this string will be automatically wrapped with double-quotes when generated
  • TextDefault:
 * Used by FEXLoader argument loading
 * If the `Default` option which is used in code can't be represented by text. Like an enum being used.
 * eg. `Core` has a `Default` which is an enum. `TextDefault` is set to `irjit` for the user to handle this case
  • Choices:
 * Used by FEXLoader argument loading
 * Allows us to represent the textual options that a argument can accept
 * FEXLoader validates that a choice is supported otherwise errors out
 * eg. `Core` supports `[ "irint", "irjit", "host" ]`
  • ArgumentHandler:
 * Used by FEXLoader argument loading
 * If an argument option needs some special handling to be parsed then this points to a C++ function in the argument loader
 * `Core` uses it to convert the textual representation in to an enum
 * Don't use this as a way to modify other configuration options from FEXLoader
   * Do fix-ups in the ReloadMetaLayer function in FEXCore/Config.cpp instead
  • Desc:
 * Short description of what this option does
 * This is used to generate the help text with `FEXLoader --help` and also the text in the man pages

UnnamedOptions section

These are configuration options that can NOT be set by user means. There won't be any FEXLoader, Environment variable, or json helpers generated to load these.

These need to exist as a way to have internal configuration options existing in the same global space as user options. Allows us to pull internal configuration options the same way as user configurations.

These can exist under any group config. Currently only `Misc` is used. Only three things need to be set for these

  • Key: This is only used to generate the enum in code
  • Type: Same supported types as the regular options
  • Default: The default value of this configuration

Getting configurations in FEX code

FEX provides a `FEX_CONFIG_OPT` define to help developers get configuration options.

  • FEX_CONFIG_OPT(name, enum)
 * eg: `FEX_CONFIG_OPT(Cores, THREADS);`
 * This will load the THREADS configuration option from the configuration directory and save the value in to local value called `Cores`
  • Gotchas:
 * Construction of the object queries the the global configuration layer. This can be slow so be careful with its use.
 * Upon construction of the `FEXCore::Config::Value<T>` object it will pull the string configuration
 * Then it will convert that value in to whatever type the value needs
 * In high performance code, keep constructor instantiation outside of the hot code path
 * Construct the configuration inside of a class definition so it only pulls the configuration once
  • Caveats:
 * If the configuration changes then this doesn't pick up the change
 * Configuration isn't meant to change live in FEX so this is typically a non-issue
 * Frontend object loader needs to be careful with its configuration loading to ensure the meta layer stays in sync
 * ELFLoader.cpp for examples here