mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-09-12 04:22:05 +00:00
docs: initial re-write of all documentation
This commit is contained in:
parent
71d266f867
commit
57ac153671
42 changed files with 711 additions and 626 deletions
438
docs/features/cheats.md
Normal file
438
docs/features/cheats.md
Normal file
|
@ -0,0 +1,438 @@
|
|||
# Cheats
|
||||
Atmosphère supports Action-Replay style cheat codes, with cheats loaded off of the SD card.
|
||||
|
||||
## Cheat Loading Process
|
||||
By default, Atmosphère will do the following when deciding whether to attach to a new application process:
|
||||
|
||||
+ Retrieve information about the new application process from `pm` and `loader`.
|
||||
+ Check whether a user-defined key combination is held, and stop if not.
|
||||
+ This defaults to "L is not held", but can be configured with override keys.
|
||||
+ The ini key to configure this is `cheat_enable_key`.
|
||||
+ Check whether the process is a real application, and stop if not.
|
||||
+ This guards against applying cheat codes to the Homebrew Loader.
|
||||
+ Attempt to load cheats from `/atmosphere/contents/<program_id>/cheats/<build_id>.txt`, where `build_id` is the hexadecimal representation of the first 8 bytes of the application's main executable's build id.
|
||||
+ If no cheats are found, then the cheat manager will stop.
|
||||
+ Open a kernel debug session for the new application process.
|
||||
+ Signal to a system event that a new cheat process has been attached to.
|
||||
|
||||
This behavior ensures that cheat codes are only loaded when the user would want them to.
|
||||
|
||||
In cases where `dmnt` has not activated the cheat manager, but the user wants to make it do so anyway, the cheat manager's service API provides a `ForceOpenCheatProcess` command that homebrew can use. This command will cause the cheat manager to try to force itself to attach to the process.
|
||||
|
||||
By default, all cheat codes listed in the loaded .txt file will be toggled on. This is configurable by the user, and the default can be set to toggled off by editing the `atmosphere!dmnt_cheats_enabled_by_default` entry to 0 instead of 1.
|
||||
|
||||
Users may use homebrew programs to toggle cheats on and off at runtime via the cheat manager's service API.
|
||||
|
||||
## Cheat Code Compatibility
|
||||
Atmosphère manages cheat code through the execution of a small, custom virtual machine. Care has been taken to ensure that Atmosphère's cheat code format is fully backwards compatible with the pre-existing cheat code format, though new features have been added and bugs in the pre-existing cheat code applier have been fixed. Here is a short summary of the changes from the pre-existing format:
|
||||
|
||||
+ A number of bugs were fixed in the processing of conditional instructions.
|
||||
+ The pre-existing implementation was fundamentally broken, and checked for the wrong value when detecting the end of a conditional block.
|
||||
+ The pre-existing implementation also did not properly decode instructions, and instead linearly scanned for the terminator value. This caused problems if an instruction happened to encode a terminator inside its immediate values.
|
||||
+ The pre-existing implementation did not bounds check, and thus certain conditional cheat codes could cause it to read out-of-bounds memory, and potentially crash due to a data abort.
|
||||
+ Support was added for nesting conditional blocks.
|
||||
+ An instruction was added to perform much more complex arbitrary arithmetic on two registers.
|
||||
+ An instruction was added to allow writing the contents of register to a memory address specified by another register.
|
||||
+ The pre-existing implementation did not correctly synchronize with the application process, and thus would cause heavy lag under certain circumstances (especially around loading screens). This has been fixed in Atmosphère's implementation.
|
||||
|
||||
## Cheat Code Format
|
||||
The following provides documentation of the instruction format for the virtual machine used to manage cheat codes.
|
||||
|
||||
Typically, instruction type is encoded in the upper nybble of the first instruction u32.
|
||||
|
||||
### Code Type 0: Store Static Value to Memory
|
||||
Code type 0 allows writing a static value to a memory address.
|
||||
|
||||
#### Encoding
|
||||
`0TMR00AA AAAAAAAA VVVVVVVV (VVVVVVVV)`
|
||||
|
||||
+ T: Width of memory write (1, 2, 4, or 8 bytes).
|
||||
+ M: Memory region to write to (0 = Main NSO, 1 = Heap).
|
||||
+ R: Register to use as an offset from memory region base.
|
||||
+ A: Immediate offset to use from memory region base.
|
||||
+ V: Value to write.
|
||||
|
||||
---
|
||||
|
||||
### Code Type 1: Begin Conditional Block
|
||||
Code type 1 performs a comparison of the contents of memory to a static value.
|
||||
|
||||
If the condition is not met, all instructions until the appropriate conditional block terminator are skipped.
|
||||
|
||||
#### Encoding
|
||||
`1TMC00AA AAAAAAAA VVVVVVVV (VVVVVVVV)`
|
||||
|
||||
+ T: Width of memory write (1, 2, 4, or 8 bytes).
|
||||
+ M: Memory region to write to (0 = Main NSO, 1 = Heap).
|
||||
+ C: Condition to use, see below.
|
||||
+ A: Immediate offset to use from memory region base.
|
||||
+ V: Value to compare to.
|
||||
|
||||
#### Conditions
|
||||
+ 1: >
|
||||
+ 2: >=
|
||||
+ 3: <
|
||||
+ 4: <=
|
||||
+ 5: ==
|
||||
+ 6: !=
|
||||
|
||||
---
|
||||
|
||||
### Code Type 2: End Conditional Block
|
||||
Code type 2 marks the end of a conditional block (started by Code Type 1 or Code Type 8).
|
||||
|
||||
#### Encoding
|
||||
`20000000`
|
||||
|
||||
---
|
||||
|
||||
### Code Type 3: Start/End Loop
|
||||
Code type 3 allows for iterating in a loop a fixed number of times.
|
||||
|
||||
#### Start Loop Encoding
|
||||
`300R0000 VVVVVVVV`
|
||||
|
||||
+ R: Register to use as loop counter.
|
||||
+ V: Number of iterations to loop.
|
||||
|
||||
#### End Loop Encoding
|
||||
`310R0000`
|
||||
|
||||
+ R: Register to use as loop counter.
|
||||
|
||||
---
|
||||
|
||||
### Code Type 4: Load Register with Static Value
|
||||
Code type 4 allows setting a register to a constant value.
|
||||
|
||||
#### Encoding
|
||||
`400R0000 VVVVVVVV VVVVVVVV`
|
||||
|
||||
+ R: Register to use.
|
||||
+ V: Value to load.
|
||||
|
||||
---
|
||||
|
||||
### Code Type 5: Load Register with Memory Value
|
||||
Code type 5 allows loading a value from memory into a register, either using a fixed address or by dereferencing the destination register.
|
||||
|
||||
#### Load From Fixed Address Encoding
|
||||
`5TMR00AA AAAAAAAA`
|
||||
|
||||
+ T: Width of memory read (1, 2, 4, or 8 bytes).
|
||||
+ M: Memory region to write to (0 = Main NSO, 1 = Heap).
|
||||
+ R: Register to load value into.
|
||||
+ A: Immediate offset to use from memory region base.
|
||||
|
||||
#### Load from Register Address Encoding
|
||||
`5TMR10AA AAAAAAAA`
|
||||
|
||||
+ T: Width of memory read (1, 2, 4, or 8 bytes).
|
||||
+ M: Memory region to write to (0 = Main NSO, 1 = Heap).
|
||||
+ R: Register to load value into.
|
||||
+ A: Immediate offset to use from register R.
|
||||
|
||||
---
|
||||
|
||||
### Code Type 6: Store Static Value to Register Memory Address
|
||||
Code type 6 allows writing a fixed value to a memory address specified by a register.
|
||||
|
||||
#### Encoding
|
||||
`6T0RIor0 VVVVVVVV VVVVVVVV`
|
||||
|
||||
+ T: Width of memory write (1, 2, 4, or 8 bytes).
|
||||
+ R: Register used as base memory address.
|
||||
+ I: Increment register flag (0 = do not increment R, 1 = increment R by T).
|
||||
+ o: Offset register enable flag (0 = do not add r to address, 1 = add r to address).
|
||||
+ r: Register used as offset when o is 1.
|
||||
+ V: Value to write to memory.
|
||||
|
||||
---
|
||||
|
||||
### Code Type 7: Legacy Arithmetic
|
||||
Code type 7 allows performing arithmetic on registers.
|
||||
|
||||
However, it has been deprecated by Code type 9, and is only kept for backwards compatibility.
|
||||
|
||||
#### Encoding
|
||||
`7T0RC000 VVVVVVVV`
|
||||
|
||||
+ T: Width of arithmetic operation (1, 2, 4, or 8 bytes).
|
||||
+ R: Register to apply arithmetic to.
|
||||
+ C: Arithmetic operation to apply, see below.
|
||||
+ V: Value to use for arithmetic operation.
|
||||
|
||||
#### Arithmetic Types
|
||||
+ 0: Addition
|
||||
+ 1: Subtraction
|
||||
+ 2: Multiplication
|
||||
+ 3: Left Shift
|
||||
+ 4: Right Shift
|
||||
|
||||
---
|
||||
|
||||
### Code Type 8: Begin Keypress Conditional Block
|
||||
Code type 8 enters or skips a conditional block based on whether a key combination is pressed.
|
||||
|
||||
#### Encoding
|
||||
`8kkkkkkk`
|
||||
|
||||
+ k: Keypad mask to check against, see below.
|
||||
|
||||
Note that for multiple button combinations, the bitmasks should be ORd together.
|
||||
|
||||
#### Keypad Values
|
||||
Note: This is the direct output of `hidKeysDown()`.
|
||||
|
||||
+ 0000001: A
|
||||
+ 0000002: B
|
||||
+ 0000004: X
|
||||
+ 0000008: Y
|
||||
+ 0000010: Left Stick Pressed
|
||||
+ 0000020: Right Stick Pressed
|
||||
+ 0000040: L
|
||||
+ 0000080: R
|
||||
+ 0000100: ZL
|
||||
+ 0000200: ZR
|
||||
+ 0000400: Plus
|
||||
+ 0000800: Minus
|
||||
+ 0001000: Left
|
||||
+ 0002000: Up
|
||||
+ 0004000: Right
|
||||
+ 0008000: Down
|
||||
+ 0010000: Left Stick Left
|
||||
+ 0020000: Left Stick Up
|
||||
+ 0040000: Left Stick Right
|
||||
+ 0080000: Left Stick Down
|
||||
+ 0100000: Right Stick Left
|
||||
+ 0200000: Right Stick Up
|
||||
+ 0400000: Right Stick Right
|
||||
+ 0800000: Right Stick Down
|
||||
+ 1000000: SL
|
||||
+ 2000000: SR
|
||||
|
||||
---
|
||||
|
||||
### Code Type 9: Perform Arithmetic
|
||||
Code type 9 allows performing arithmetic on registers.
|
||||
|
||||
#### Register Arithmetic Encoding
|
||||
`9TCRS0s0`
|
||||
|
||||
+ T: Width of arithmetic operation (1, 2, 4, or 8 bytes).
|
||||
+ C: Arithmetic operation to apply, see below.
|
||||
+ R: Register to store result in.
|
||||
+ S: Register to use as left-hand operand.
|
||||
+ s: Register to use as right-hand operand.
|
||||
|
||||
#### Immediate Value Arithmetic Encoding
|
||||
`9TCRS100 VVVVVVVV (VVVVVVVV)`
|
||||
|
||||
+ T: Width of arithmetic operation (1, 2, 4, or 8 bytes).
|
||||
+ C: Arithmetic operation to apply, see below.
|
||||
+ R: Register to store result in.
|
||||
+ S: Register to use as left-hand operand.
|
||||
+ V: Value to use as right-hand operand.
|
||||
|
||||
#### Arithmetic Types
|
||||
+ 0: Addition
|
||||
+ 1: Subtraction
|
||||
+ 2: Multiplication
|
||||
+ 3: Left Shift
|
||||
+ 4: Right Shift
|
||||
+ 5: Logical And
|
||||
+ 6: Logical Or
|
||||
+ 7: Logical Not (discards right-hand operand)
|
||||
+ 8: Logical Xor
|
||||
+ 9: None/Move (discards right-hand operand)
|
||||
|
||||
---
|
||||
|
||||
### Code Type 10: Store Register to Memory Address
|
||||
Code type 10 allows writing a register to memory.
|
||||
|
||||
#### Encoding
|
||||
`ATSRIOxa (aaaaaaaa)`
|
||||
|
||||
+ T: Width of memory write (1, 2, 4, or 8 bytes).
|
||||
+ S: Register to write to memory.
|
||||
+ R: Register to use as base address.
|
||||
+ I: Increment register flag (0 = do not increment R, 1 = increment R by T).
|
||||
+ O: Offset type, see below.
|
||||
+ x: Register used as offset when O is 1, Memory type when O is 3, 4 or 5.
|
||||
+ a: Value used as offset when O is 2, 4 or 5.
|
||||
|
||||
#### Offset Types
|
||||
+ 0: No Offset
|
||||
+ 1: Use Offset Register
|
||||
+ 2: Use Fixed Offset
|
||||
+ 3: Memory Region + Base Register
|
||||
+ 4: Memory Region + Relative Address (ignore address register)
|
||||
+ 5: Memory Region + Relative Address + Offset Register
|
||||
|
||||
---
|
||||
|
||||
### Code Type 11: Reserved
|
||||
Code Type 11 is currently reserved for future use.
|
||||
|
||||
---
|
||||
|
||||
### Code Type 12-15: Extended-Width Instruction
|
||||
Code Types 12-15 signal to the VM to treat the upper two nybbles of the first dword as instruction type, instead of just the upper nybble.
|
||||
|
||||
This reserves an additional 64 opcodes for future use.
|
||||
|
||||
---
|
||||
|
||||
### Code Type 0xC0: Begin Register Conditional Block
|
||||
Code type 0xC0 performs a comparison of the contents of a register and another value. This code support multiple operand types, see below.
|
||||
|
||||
If the condition is not met, all instructions until the appropriate conditional block terminator are skipped.
|
||||
|
||||
#### Encoding
|
||||
```
|
||||
C0TcSX##
|
||||
C0TcS0Ma aaaaaaaa
|
||||
C0TcS1Mr
|
||||
C0TcS2Ra aaaaaaaa
|
||||
C0TcS3Rr
|
||||
C0TcS400 VVVVVVVV (VVVVVVVV)
|
||||
C0TcS5X0
|
||||
```
|
||||
|
||||
+ T: Width of memory write (1, 2, 4, or 8 bytes).
|
||||
+ c: Condition to use, see below.
|
||||
+ S: Source Register.
|
||||
+ X: Operand Type, see below.
|
||||
+ M: Memory Type (operand types 0 and 1).
|
||||
+ R: Address Register (operand types 2 and 3).
|
||||
+ a: Relative Address (operand types 0 and 2).
|
||||
+ r: Offset Register (operand types 1 and 3).
|
||||
+ X: Other Register (operand type 5).
|
||||
+ V: Value to compare to (operand type 4).
|
||||
|
||||
#### Operand Type
|
||||
+ 0: Memory Base + Relative Offset
|
||||
+ 1: Memory Base + Offset Register
|
||||
+ 2: Register + Relative Offset
|
||||
+ 3: Register + Offset Register
|
||||
+ 4: Static Value
|
||||
+ 5: Other Register
|
||||
|
||||
#### Conditions
|
||||
+ 1: >
|
||||
+ 2: >=
|
||||
+ 3: <
|
||||
+ 4: <=
|
||||
+ 5: ==
|
||||
+ 6: !=
|
||||
|
||||
---
|
||||
|
||||
### Code Type 0xC1: Save or Restore Register
|
||||
Code type 0xC1 performs saving or restoring of registers.
|
||||
|
||||
#### Encoding
|
||||
```
|
||||
C10D0Sx0
|
||||
```
|
||||
|
||||
+ D: Destination index.
|
||||
+ S: Source index.
|
||||
+ x: Operand Type, see below.
|
||||
|
||||
#### Operand Type
|
||||
+ 0: Restore register
|
||||
+ 1: Save register
|
||||
+ 2: Clear saved value
|
||||
+ 3: Clear register
|
||||
|
||||
---
|
||||
|
||||
### Code Type 0xC2: Save or Restore Register with Mask
|
||||
Code type 0xC2 performs saving or restoring of multiple registers using a bitmask.
|
||||
|
||||
#### Encoding
|
||||
```
|
||||
C2x0XXXX
|
||||
```
|
||||
|
||||
+ x: Operand Type, see below.
|
||||
+ X: 16-bit bitmask, bit i == save or restore register i.
|
||||
|
||||
#### Operand Type
|
||||
+ 0: Restore register
|
||||
+ 1: Save register
|
||||
+ 2: Clear saved value
|
||||
+ 3: Clear register
|
||||
|
||||
---
|
||||
|
||||
### Code Type 0xC3: Read or Write Static Register
|
||||
Code type 0xC3 reads or writes a static register with a given register.
|
||||
|
||||
#### Encoding
|
||||
```
|
||||
C3000XXx
|
||||
```
|
||||
|
||||
+ XX: Static register index, 0x00 to 0x7F for reading or 0x80 to 0xFF for writing.
|
||||
+ x: Register index.
|
||||
|
||||
---
|
||||
|
||||
### Code Type 0xF0: Double Extended-Width Instruction
|
||||
Code Type 0xF0 signals to the VM to treat the upper three nybbles of the first dword as instruction type, instead of just the upper nybble.
|
||||
|
||||
This reserves an additional 16 opcodes for future use.
|
||||
|
||||
---
|
||||
|
||||
### Code Type 0xFF0: Pause Process
|
||||
Code type 0xFF0 pauses the current process.
|
||||
|
||||
#### Encoding
|
||||
```
|
||||
FF0?????
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Code Type 0xFF1: Resume Process
|
||||
Code type 0xFF1 resumes the current process.
|
||||
|
||||
#### Encoding
|
||||
```
|
||||
FF1?????
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Code Type 0xFFF: Debug Log
|
||||
Code type 0xFFF writes a debug log to the SD card under the folder `/atmosphere/cheat_vm_logs/`.
|
||||
|
||||
#### Encoding
|
||||
```
|
||||
FFFTIX##
|
||||
FFFTI0Ma aaaaaaaa
|
||||
FFFTI1Mr
|
||||
FFFTI2Ra aaaaaaaa
|
||||
FFFTI3Rr
|
||||
FFFTI4X0
|
||||
```
|
||||
|
||||
+ T: Width of memory write (1, 2, 4, or 8 bytes).
|
||||
+ I: Log id.
|
||||
+ X: Operand Type, see below.
|
||||
+ M: Memory Type (operand types 0 and 1).
|
||||
+ R: Address Register (operand types 2 and 3).
|
||||
+ a: Relative Address (operand types 0 and 2).
|
||||
+ r: Offset Register (operand types 1 and 3).
|
||||
+ X: Value Register (operand type 4).
|
||||
|
||||
#### Operand Type
|
||||
+ 0: Memory Base + Relative Offset
|
||||
+ 1: Memory Base + Offset Register
|
||||
+ 2: Register + Relative Offset
|
||||
+ 3: Register + Offset Register
|
||||
+ 4: Register Value
|
141
docs/features/configurations.md
Normal file
141
docs/features/configurations.md
Normal file
|
@ -0,0 +1,141 @@
|
|||
# Configurations
|
||||
Atmosphère provides a variety of customizable configurations to better adjust to users' needs.
|
||||
|
||||
## BCT.ini
|
||||
This is the configuration file used by Fusée.
|
||||
This file is located under the `/atmosphere/config/` folder on your SD card and a default template can be found inside the `/atmosphere/config_templates/` folder.
|
||||
|
||||
### Adding a Custom Boot Splashscreen
|
||||
Add the following lines to BCT.ini and change the value of `custom_splash` to the actual path and filename of your boot splashscreen:
|
||||
```
|
||||
[stage2]
|
||||
custom_splash = /path/to/your/bootlogo.bmp
|
||||
```
|
||||
|
||||
The boot splashscreen must be a BMP file, it must be 720x1280 (1280x720 rotated 90 degrees left/counterclockwise/anti-clockwise) resolution, and be in 32-bit ARGB format. You can use image editing software such as GIMP or Photoshop to export the image in this format.
|
||||
|
||||
### Configuring "nogc" Protection
|
||||
"nogc" is a feature provided by Fusée-secondary which disables the Nintendo Switch's Game Card reader. Its purpose is to prevent the reader from being updated when the console has been updated without burning fuses from a firmware lower than 4.0.0, to a newer firmware that is at least 4.0.0 or higher. By default, Atmosphère will protect the Game Card reader automatically, but you are free to change it.
|
||||
|
||||
To change its functionality, add the following line to the `stratosphere` section and change the value of `X` according to the following list:
|
||||
```
|
||||
nogc = X
|
||||
```
|
||||
```
|
||||
1 = force-enable nogc, so Atmosphère will always disable the Game Card reader.
|
||||
0 = force-disable nogc, so Atmosphère will always enable the Game Card reader.
|
||||
```
|
||||
|
||||
### NCM opt-in
|
||||
Atmosphère provides a reimplementation of the [ncm](../components/modules/ncm.md) system module, but currently this is not enabled by default. If you wish to enable this reimplementation add the following line to the `stratosphere` section:
|
||||
```
|
||||
enable_ncm = 1
|
||||
```
|
||||
|
||||
### Logging
|
||||
Add the following lines to BCT.ini and change the value of `X` according to the following list:
|
||||
```
|
||||
[config]
|
||||
log_level = X
|
||||
```
|
||||
```
|
||||
0 = NONE
|
||||
1 = ERROR
|
||||
2 = WARNING
|
||||
3 = MANDATORY
|
||||
4 = INFO
|
||||
5 = DEBUG
|
||||
```
|
||||
|
||||
## emummc.ini
|
||||
This is the configuration file used for the [emummc](../components/emummc.md) component.
|
||||
This file is located under the `/emummc/` folder on your SD card.
|
||||
|
||||
## exosphere.ini
|
||||
This is the configuration file used by Exosphère.
|
||||
This file is located in the root of your SD card and a default template can be found inside the `/atmosphere/config_templates/` folder.
|
||||
|
||||
### Configuring Debugging Modes
|
||||
By default, Atmosphère signals to the Horizon kernel that debugging is enabled while leaving usermode debugging disabled, but this can cause undesirable side-effects. If you wish to change this behavior, go to the `exosphere` section and change the value of `X` according to the following list.
|
||||
```
|
||||
debugmode = X
|
||||
debugmode_user = X
|
||||
```
|
||||
```
|
||||
1 = enable
|
||||
0 = disable
|
||||
```
|
||||
|
||||
### Blanking PRODINFO
|
||||
Atmosphère provides a way for users to blank their factory installed calibration data (known as PRODINFO) in either emulated or system eMMC environments. You can find more detailed information on this inside the respective template file. Usage of this configuration is not encouraged.
|
||||
|
||||
## override_config.ini
|
||||
This file is located under the `/atmosphere/config/` folder on your SD card and a default template can be found inside the `/atmosphere/config_templates/` folder.
|
||||
|
||||
### Overrides Format
|
||||
Overrides are parsed from the `/atmosphere/config/override_config.ini` file during the boot process.
|
||||
|
||||
By default `override_config.ini` is not configured. It can be used to select the behavior of certain buttons and bind them to functionalities such as launching the Homebrew Menu or enabling the cheat code manager.
|
||||
|
||||
You can modify the override_key entries in `override_config.ini` with this list of valid buttons:
|
||||
| Formal Name | .ini Name |
|
||||
| ----------- | --------- |
|
||||
| A Button | A |
|
||||
| B Button | B |
|
||||
| X Button | X |
|
||||
| Y Button | Y |
|
||||
| Left Stick | LS |
|
||||
| Right Stick | RS |
|
||||
| L Button | L |
|
||||
| R Button | R |
|
||||
| ZL Button | ZL |
|
||||
| ZR Button | ZR |
|
||||
| + Button | PLUS |
|
||||
| - Button | MINUS |
|
||||
| Left Dpad | DLEFT |
|
||||
| Up Dpad | DUP |
|
||||
| Right Dpad | DRIGHT |
|
||||
| Down Dpad | DDOWN |
|
||||
| SL Button | SL |
|
||||
| SR Button | SR |
|
||||
|
||||
To invert the behavior of the override key, place an exclamation point in front of whatever button you wish to use. It will launch the actual game while holding down that button, instead of going into the Homebrew Menu. For example, `override_key=!R` will run the game only while holding down R when launching it, otherwise it will boot into the Homebrew Menu. Afterwards you may reinsert your SD card into your Switch and boot into Atmosphère as you normally would. You should now be able to boot into the Homebrew Menu by launching your designated program of choice.
|
||||
|
||||
## system_settings.ini
|
||||
This file is located under the `/atmosphere/config/` folder on your SD card and a default template can be found inside the `/atmosphere/config_templates/` folder.
|
||||
|
||||
### Settings Format
|
||||
Settings are parsed from the `/atmosphere/config/system_settings.ini` file during the boot process. This file is a normal ini file, with some specific interpretations.
|
||||
|
||||
The standard representation of a system setting's identifier takes the form `name!key`. This is represented within `system_settings.ini` as a section `name`, with an entry `key`. For example:
|
||||
```
|
||||
[name]
|
||||
key = ...
|
||||
```
|
||||
|
||||
System settings can have variable types (strings, integral values, byte arrays, etc). To accommodate this, `system_settings.ini` must store values as a `type_identifier!value_store` pair. A number of different types are supported, with identifiers detailed below.
|
||||
Please note that a malformed value string will cause a fatal error to occur on boot. A full example of a custom setting is given below (setting `eupld!upload_enabled = 0`), for posterity:
|
||||
```
|
||||
[eupld]
|
||||
upload_enabled = u8!0x0
|
||||
```
|
||||
|
||||
#### Supported Types
|
||||
* Strings
|
||||
* Type identifiers: `str`, `string`
|
||||
* The value string is used directly as the setting, with null terminator appended.
|
||||
* Integral types
|
||||
* Type identifiers: `u8`, `u16`, `u32`, `u64`
|
||||
* The value string is parsed via a call to `strtoul(value, NULL, 0)`.
|
||||
* Setting bitwidth is determined by the identifier (8 for 1 byte, 16 for 2 bytes, and so on).
|
||||
* Raw bytes
|
||||
* Type identifiers: `hex`, `bytes`
|
||||
* The value string is parsed as a hexadecimal string.
|
||||
* The value string must be of even length, or a fatal error will be thrown on parse.
|
||||
|
||||
## Content Specific Flags
|
||||
Atmosphère supports customizing CFW behavior based on the presence of `flags` on the SD card.
|
||||
|
||||
The following flags are supported on a per-program basis, by placing `<flag_name>.flag` inside `/atmosphere/contents/<program_id>/flags/`:
|
||||
+ `boot2`, which indicates that the program should be launched during the `boot2` process.
|
||||
+ `redirect_save`, which indicates that the program wants its savedata to be redirected to the SD card.
|
Loading…
Add table
Add a link
Reference in a new issue