Browse Source
modernize #1
modernize #1
5 changed files with 64 additions and 940 deletions
-
10src/ios/Eden/AppUI.swift
-
90src/ios/Eden/Wrapper/AppUIGameInformation/AppUIGameInformation.mm
-
573src/ios/Eden/Wrapper/Config/Config.h
-
330src/ios/Eden/Wrapper/Config/Config.mm
-
1src/ios/Eden/Wrapper/DirectoryManager/DirectoryManager.mm
@ -1,568 +1,19 @@ |
|||
// |
|||
// Config.h |
|||
// AppUI |
|||
// |
|||
// Created by Jarrod Norwell on 13/3/2024. |
|||
// |
|||
|
|||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-2.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
namespace DefaultINI { |
|||
|
|||
const char* android_config_file = R"( |
|||
|
|||
[ControlsP0] |
|||
# The input devices and parameters for each Switch native input |
|||
# The config section determines the player number where the config will be applied on. For example "ControlsP0", "ControlsP1", ... |
|||
# It should be in the format of "engine:[engine_name],[param1]:[value1],[param2]:[value2]..." |
|||
# Escape characters $0 (for ':'), $1 (for ',') and $2 (for '$') can be used in values |
|||
|
|||
# Indicates if this player should be connected at boot |
|||
connected= |
|||
|
|||
# for button input, the following devices are available: |
|||
# - "keyboard" (default) for keyboard input. Required parameters: |
|||
# - "code": the code of the key to bind |
|||
# - "sdl" for joystick input using SDL. Required parameters: |
|||
# - "guid": SDL identification GUID of the joystick |
|||
# - "port": the index of the joystick to bind |
|||
# - "button"(optional): the index of the button to bind |
|||
# - "hat"(optional): the index of the hat to bind as direction buttons |
|||
# - "axis"(optional): the index of the axis to bind |
|||
# - "direction"(only used for hat): the direction name of the hat to bind. Can be "up", "down", "left" or "right" |
|||
# - "threshold"(only used for axis): a float value in (-1.0, 1.0) which the button is |
|||
# triggered if the axis value crosses |
|||
# - "direction"(only used for axis): "+" means the button is triggered when the axis value |
|||
# is greater than the threshold; "-" means the button is triggered when the axis value |
|||
# is smaller than the threshold |
|||
button_a= |
|||
button_b= |
|||
button_x= |
|||
button_y= |
|||
button_lstick= |
|||
button_rstick= |
|||
button_l= |
|||
button_r= |
|||
button_zl= |
|||
button_zr= |
|||
button_plus= |
|||
button_minus= |
|||
button_dleft= |
|||
button_dup= |
|||
button_dright= |
|||
button_ddown= |
|||
button_lstick_left= |
|||
button_lstick_up= |
|||
button_lstick_right= |
|||
button_lstick_down= |
|||
button_sl= |
|||
button_sr= |
|||
button_home= |
|||
button_screenshot= |
|||
|
|||
# for analog input, the following devices are available: |
|||
# - "analog_from_button" (default) for emulating analog input from direction buttons. Required parameters: |
|||
# - "up", "down", "left", "right": sub-devices for each direction. |
|||
# Should be in the format as a button input devices using escape characters, for example, "engine$0keyboard$1code$00" |
|||
# - "modifier": sub-devices as a modifier. |
|||
# - "modifier_scale": a float number representing the applied modifier scale to the analog input. |
|||
# Must be in range of 0.0-1.0. Defaults to 0.5 |
|||
# - "sdl" for joystick input using SDL. Required parameters: |
|||
# - "guid": SDL identification GUID of the joystick |
|||
# - "port": the index of the joystick to bind |
|||
# - "axis_x": the index of the axis to bind as x-axis (default to 0) |
|||
# - "axis_y": the index of the axis to bind as y-axis (default to 1) |
|||
lstick= |
|||
rstick= |
|||
|
|||
# for motion input, the following devices are available: |
|||
# - "keyboard" (default) for emulating random motion input from buttons. Required parameters: |
|||
# - "code": the code of the key to bind |
|||
# - "sdl" for motion input using SDL. Required parameters: |
|||
# - "guid": SDL identification GUID of the joystick |
|||
# - "port": the index of the joystick to bind |
|||
# - "motion": the index of the motion sensor to bind |
|||
# - "cemuhookudp" for motion input using Cemu Hook protocol. Required parameters: |
|||
# - "guid": the IP address of the cemu hook server encoded to a hex string. for example 192.168.0.1 = "c0a80001" |
|||
# - "port": the port of the cemu hook server |
|||
# - "pad": the index of the joystick |
|||
# - "motion": the index of the motion sensor of the joystick to bind |
|||
motionleft= |
|||
motionright= |
|||
|
|||
[ControlsGeneral] |
|||
# To use the debug_pad, prepend debug_pad_ before each button setting above. |
|||
# i.e. debug_pad_button_a= |
|||
|
|||
# Enable debug pad inputs to the guest |
|||
# 0 (default): Disabled, 1: Enabled |
|||
debug_pad_enabled = |
|||
|
|||
# Whether to enable or disable vibration |
|||
# 0: Disabled, 1 (default): Enabled |
|||
vibration_enabled = |
|||
|
|||
# Whether to enable or disable accurate vibrations |
|||
# 0 (default): Disabled, 1: Enabled |
|||
enable_accurate_vibrations = |
|||
|
|||
# Enables controller motion inputs |
|||
# 0: Disabled, 1 (default): Enabled |
|||
motion_enabled = |
|||
|
|||
# Defines the udp device's touch screen coordinate system for cemuhookudp devices |
|||
# - "min_x", "min_y", "max_x", "max_y" |
|||
touch_device= |
|||
|
|||
# for mapping buttons to touch inputs. |
|||
#touch_from_button_map=1 |
|||
#touch_from_button_maps_0_name=default |
|||
#touch_from_button_maps_0_count=2 |
|||
#touch_from_button_maps_0_bind_0=foo |
|||
#touch_from_button_maps_0_bind_1=bar |
|||
# etc. |
|||
|
|||
# List of Cemuhook UDP servers, delimited by ','. |
|||
# Default: 127.0.0.1:26760 |
|||
# Example: 127.0.0.1:26760,123.4.5.67:26761 |
|||
udp_input_servers = |
|||
|
|||
# Enable controlling an axis via a mouse input. |
|||
# 0 (default): Off, 1: On |
|||
mouse_panning = |
|||
|
|||
# Set mouse sensitivity. |
|||
# Default: 1.0 |
|||
mouse_panning_sensitivity = |
|||
|
|||
# Emulate an analog control stick from keyboard inputs. |
|||
# 0 (default): Disabled, 1: Enabled |
|||
emulate_analog_keyboard = |
|||
|
|||
# Enable mouse inputs to the guest |
|||
# 0 (default): Disabled, 1: Enabled |
|||
mouse_enabled = |
|||
|
|||
# Enable keyboard inputs to the guest |
|||
# 0 (default): Disabled, 1: Enabled |
|||
keyboard_enabled = |
|||
|
|||
[Core] |
|||
# Whether to use multi-core for CPU emulation |
|||
# 0: Disabled, 1 (default): Enabled |
|||
use_multi_core = |
|||
|
|||
# Enable unsafe extended guest system memory layout (8GB DRAM) |
|||
# 0 (default): Disabled, 1: Enabled |
|||
use_unsafe_extended_memory_layout = |
|||
|
|||
[Cpu] |
|||
# Adjusts various optimizations. |
|||
# Auto-select mode enables choice unsafe optimizations. |
|||
# Accurate enables only safe optimizations. |
|||
# Unsafe allows any unsafe optimizations. |
|||
# 0 (default): Auto-select, 1: Accurate, 2: Enable unsafe optimizations |
|||
cpu_accuracy = |
|||
|
|||
# Allow disabling safe optimizations. |
|||
# 0 (default): Disabled, 1: Enabled |
|||
cpu_debug_mode = |
|||
|
|||
# Enable inline page tables optimization (faster guest memory access) |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_page_tables = |
|||
|
|||
# Enable block linking CPU optimization (reduce block dispatcher use during predictable jumps) |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_block_linking = |
|||
|
|||
# Enable return stack buffer CPU optimization (reduce block dispatcher use during predictable returns) |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_return_stack_buffer = |
|||
|
|||
# Enable fast dispatcher CPU optimization (use a two-tiered dispatcher architecture) |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_fast_dispatcher = |
|||
|
|||
# Enable context elimination CPU Optimization (reduce host memory use for guest context) |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_context_elimination = |
|||
|
|||
# Enable constant propagation CPU optimization (basic IR optimization) |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_const_prop = |
|||
|
|||
# Enable miscellaneous CPU optimizations (basic IR optimization) |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_misc_ir = |
|||
|
|||
# Enable reduction of memory misalignment checks (reduce memory fallbacks for misaligned access) |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_reduce_misalign_checks = |
|||
|
|||
# Enable Host MMU Emulation (faster guest memory access) |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_fastmem = |
|||
|
|||
# Enable Host MMU Emulation for exclusive memory instructions (faster guest memory access) |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_fastmem_exclusives = |
|||
|
|||
# Enable fallback on failure of fastmem of exclusive memory instructions (faster guest memory access) |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_recompile_exclusives = |
|||
|
|||
# Enable optimization to ignore invalid memory accesses (faster guest memory access) |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_ignore_memory_aborts = |
|||
|
|||
# Enable unfuse FMA (improve performance on CPUs without FMA) |
|||
# Only enabled if cpu_accuracy is set to Unsafe. Automatically chosen with cpu_accuracy = Auto-select. |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_unsafe_unfuse_fma = |
|||
|
|||
# Enable faster FRSQRTE and FRECPE |
|||
# Only enabled if cpu_accuracy is set to Unsafe. |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_unsafe_reduce_fp_error = |
|||
|
|||
# Enable faster ASIMD instructions (32 bits only) |
|||
# Only enabled if cpu_accuracy is set to Unsafe. Automatically chosen with cpu_accuracy = Auto-select. |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_unsafe_ignore_standard_fpcr = |
|||
|
|||
# Enable inaccurate NaN handling |
|||
# Only enabled if cpu_accuracy is set to Unsafe. Automatically chosen with cpu_accuracy = Auto-select. |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_unsafe_inaccurate_nan = |
|||
|
|||
# Disable address space checks (64 bits only) |
|||
# Only enabled if cpu_accuracy is set to Unsafe. Automatically chosen with cpu_accuracy = Auto-select. |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_unsafe_fastmem_check = |
|||
|
|||
# Enable faster exclusive instructions |
|||
# Only enabled if cpu_accuracy is set to Unsafe. Automatically chosen with cpu_accuracy = Auto-select. |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_unsafe_ignore_global_monitor = |
|||
|
|||
[Renderer] |
|||
# Which backend API to use. |
|||
# 0: OpenGL (unsupported), 1 (default): Vulkan, 2: Null |
|||
backend = |
|||
|
|||
# Whether to enable asynchronous presentation (Vulkan only) |
|||
# 0: Off, 1 (default): On |
|||
async_presentation = |
|||
|
|||
# Forces the GPU to run at the maximum possible clocks (thermal constraints will still be applied). |
|||
# 0 (default): Disabled, 1: Enabled |
|||
force_max_clock = |
|||
|
|||
# Enable graphics API debugging mode. |
|||
# 0 (default): Disabled, 1: Enabled |
|||
debug = |
|||
|
|||
# Enable shader feedback. |
|||
# 0 (default): Disabled, 1: Enabled |
|||
renderer_shader_feedback = |
|||
|
|||
# Enable Nsight Aftermath crash dumps |
|||
# 0 (default): Disabled, 1: Enabled |
|||
nsight_aftermath = |
|||
|
|||
# Disable shader loop safety checks, executing the shader without loop logic changes |
|||
# 0 (default): Disabled, 1: Enabled |
|||
disable_shader_loop_safety_checks = |
|||
|
|||
# Which Vulkan physical device to use (defaults to 0) |
|||
vulkan_device = |
|||
|
|||
# 0: 0.5x (360p/540p) [EXPERIMENTAL] |
|||
# 1: 0.75x (540p/810p) [EXPERIMENTAL] |
|||
# 2 (default): 1x (720p/1080p) |
|||
# 3: 2x (1440p/2160p) |
|||
# 4: 3x (2160p/3240p) |
|||
# 5: 4x (2880p/4320p) |
|||
# 6: 5x (3600p/5400p) |
|||
# 7: 6x (4320p/6480p) |
|||
resolution_setup = |
|||
|
|||
# Pixel filter to use when up- or down-sampling rendered frames. |
|||
# 0: Nearest Neighbor |
|||
# 1 (default): Bilinear |
|||
# 2: Bicubic |
|||
# 3: Gaussian |
|||
# 4: ScaleForce |
|||
# 5: AMD FidelityFX™️ Super Resolution [Vulkan Only] |
|||
scaling_filter = |
|||
|
|||
# Anti-Aliasing (AA) |
|||
# 0 (default): None, 1: FXAA |
|||
anti_aliasing = |
|||
|
|||
# Whether to use fullscreen or borderless window mode |
|||
# 0 (Windows default): Borderless window, 1 (All other default): Exclusive fullscreen |
|||
fullscreen_mode = |
|||
|
|||
# Aspect ratio |
|||
# 0: Default (16:9), 1: Force 4:3, 2: Force 21:9, 3: Force 16:10, 4: Stretch to Window |
|||
aspect_ratio = |
|||
|
|||
# Anisotropic filtering |
|||
# 0: Default, 1: 2x, 2: 4x, 3: 8x, 4: 16x |
|||
max_anisotropy = |
|||
|
|||
# Whether to enable VSync or not. |
|||
# OpenGL: Values other than 0 enable VSync |
|||
# Vulkan: FIFO is selected if the requested mode is not supported by the driver. |
|||
# FIFO (VSync) does not drop frames or exhibit tearing but is limited by the screen refresh rate. |
|||
# FIFO Relaxed is similar to FIFO but allows tearing as it recovers from a slow down. |
|||
# Mailbox can have lower latency than FIFO and does not tear but may drop frames. |
|||
# Immediate (no synchronization) just presents whatever is available and can exhibit tearing. |
|||
# 0: Immediate (Off), 1 (Default): Mailbox (On), 2: FIFO, 3: FIFO Relaxed |
|||
use_vsync = |
|||
|
|||
# Selects the OpenGL shader backend. NV_gpu_program5 is required for GLASM. If NV_gpu_program5 is |
|||
# not available and GLASM is selected, GLSL will be used. |
|||
# 0: GLSL, 1 (default): GLASM, 2: SPIR-V |
|||
shader_backend = |
|||
|
|||
# Whether to allow asynchronous shader building. |
|||
# 0 (default): Off, 1: On |
|||
use_asynchronous_shaders = |
|||
|
|||
# Uses reactive flushing instead of predictive flushing. Allowing a more accurate syncing of memory. |
|||
# 0 (default): Off, 1: On |
|||
use_reactive_flushing = |
|||
|
|||
# NVDEC emulation. |
|||
# 0: Disabled, 1: CPU Decoding, 2 (default): GPU Decoding |
|||
nvdec_emulation = |
|||
|
|||
# Accelerate ASTC texture decoding. |
|||
# 0 (default): Off, 1: On |
|||
accelerate_astc = |
|||
|
|||
# Turns on the speed limiter, which will limit the emulation speed to the desired speed limit value |
|||
# 0: Off, 1: On (default) |
|||
use_speed_limit = |
|||
|
|||
# Limits the speed of the game to run no faster than this value as a percentage of target speed |
|||
# 1 - 9999: Speed limit as a percentage of target game speed. 100 (default) |
|||
speed_limit = |
|||
|
|||
# Whether to use disk based shader cache |
|||
# 0: Off, 1 (default): On |
|||
use_disk_shader_cache = |
|||
|
|||
# Which gpu accuracy level to use |
|||
# 0 (default): Normal, 1: High, 2: Extreme (Very slow) |
|||
gpu_accuracy = |
|||
|
|||
# Whether to use asynchronous GPU emulation |
|||
# 0 : Off (slow), 1 (default): On (fast) |
|||
use_asynchronous_gpu_emulation = |
|||
|
|||
# Inform the guest that GPU operations completed more quickly than they did. |
|||
# 0: Off, 1 (default): On |
|||
use_fast_gpu_time = |
|||
|
|||
# Force unmodified buffers to be flushed, which can cost performance. |
|||
# 0: Off (default), 1: On |
|||
use_pessimistic_flushes = |
|||
|
|||
# Whether to use garbage collection or not for GPU caches. |
|||
# 0 (default): Off, 1: On |
|||
use_caches_gc = |
|||
|
|||
# The clear color for the renderer. What shows up on the sides of the bottom screen. |
|||
# Must be in range of 0-255. Defaults to 0 for all. |
|||
bg_red = |
|||
bg_blue = |
|||
bg_green = |
|||
|
|||
[Audio] |
|||
# Which audio output engine to use. |
|||
# auto (default): Auto-select |
|||
# cubeb: Cubeb audio engine (if available) |
|||
# sdl2: SDL2 audio engine (if available) |
|||
# null: No audio output |
|||
output_engine = |
|||
|
|||
# Which audio device to use. |
|||
# auto (default): Auto-select |
|||
output_device = |
|||
|
|||
# Output volume. |
|||
# 100 (default): 100%, 0; mute |
|||
volume = |
|||
|
|||
[Data Storage] |
|||
# Whether to create a virtual SD card. |
|||
# 1: Yes, 0 (default): No |
|||
use_virtual_sd = |
|||
|
|||
# Whether or not to enable gamecard emulation |
|||
# 1: Yes, 0 (default): No |
|||
gamecard_inserted = |
|||
|
|||
# Whether or not the gamecard should be emulated as the current game |
|||
# If 'gamecard_inserted' is 0 this setting is irrelevant |
|||
# 1: Yes, 0 (default): No |
|||
gamecard_current_game = |
|||
|
|||
# Path to an XCI file to use as the gamecard |
|||
# If 'gamecard_inserted' is 0 this setting is irrelevant |
|||
# If 'gamecard_current_game' is 1 this setting is irrelevant |
|||
gamecard_path = |
|||
|
|||
[System] |
|||
# Whether the system is docked |
|||
# 1: Yes, 0 (default): No |
|||
use_docked_mode = |
|||
|
|||
# Sets the seed for the RNG generator built into the switch |
|||
# rng_seed will be ignored and randomly generated if rng_seed_enabled is false |
|||
rng_seed_enabled = |
|||
rng_seed = |
|||
|
|||
# Sets the current time (in seconds since 12:00 AM Jan 1, 1970) that will be used by the time service |
|||
# This will auto-increment, with the time set being the time the game is started |
|||
# This override will only occur if custom_rtc_enabled is true, otherwise the current time is used |
|||
custom_rtc_enabled = |
|||
custom_rtc = |
|||
|
|||
# Sets the systems language index |
|||
# 0: Japanese, 1: English (default), 2: French, 3: German, 4: Italian, 5: Spanish, 6: Chinese, |
|||
# 7: Korean, 8: Dutch, 9: Portuguese, 10: Russian, 11: Taiwanese, 12: British English, 13: Canadian French, |
|||
# 14: Latin American Spanish, 15: Simplified Chinese, 16: Traditional Chinese, 17: Brazilian Portuguese |
|||
language_index = |
|||
|
|||
# The system region that yuzu will use during emulation |
|||
# -1: Auto-select (default), 0: Japan, 1: USA, 2: Europe, 3: Australia, 4: China, 5: Korea, 6: Taiwan |
|||
region_index = |
|||
|
|||
# The system time zone that yuzu will use during emulation |
|||
# 0: Auto-select (default), 1: Default (system archive value), Others: Index for specified time zone |
|||
time_zone_index = |
|||
|
|||
# Sets the sound output mode. |
|||
# 0: Mono, 1 (default): Stereo, 2: Surround |
|||
sound_index = |
|||
|
|||
[Miscellaneous] |
|||
# A filter which removes logs below a certain logging level. |
|||
# Examples: *:Debug Kernel.SVC:Trace Service.*:Critical |
|||
log_filter = *:Trace |
|||
|
|||
# Use developer keys |
|||
# 0 (default): Disabled, 1: Enabled |
|||
use_dev_keys = |
|||
|
|||
[Debugging] |
|||
# Record frame time data, can be found in the log directory. Boolean value |
|||
record_frame_times = |
|||
# Determines whether or not yuzu will dump the ExeFS of all games it attempts to load while loading them |
|||
dump_exefs=false |
|||
# Determines whether or not yuzu will dump all NSOs it attempts to load while loading them |
|||
dump_nso=false |
|||
# Determines whether or not yuzu will save the filesystem access log. |
|||
enable_fs_access_log=false |
|||
# Enables verbose reporting services |
|||
reporting_services = |
|||
# Determines whether or not yuzu will report to the game that the emulated console is in Kiosk Mode |
|||
# false: Retail/Normal Mode (default), true: Kiosk Mode |
|||
quest_flag = |
|||
# Determines whether debug asserts should be enabled, which will throw an exception on asserts. |
|||
# false: Disabled (default), true: Enabled |
|||
use_debug_asserts = |
|||
# Determines whether unimplemented HLE service calls should be automatically stubbed. |
|||
# false: Disabled (default), true: Enabled |
|||
use_auto_stub = |
|||
# Enables/Disables the macro JIT compiler |
|||
disable_macro_jit=false |
|||
# Determines whether to enable the GDB stub and wait for the debugger to attach before running. |
|||
# false: Disabled (default), true: Enabled |
|||
use_gdbstub=false |
|||
# The port to use for the GDB server, if it is enabled. |
|||
gdbstub_port=6543 |
|||
|
|||
[WebService] |
|||
# Whether or not to enable telemetry |
|||
# 0: No, 1 (default): Yes |
|||
enable_telemetry = |
|||
# URL for Web API |
|||
web_api_url = |
|||
# Username and token for yuzu Web Service |
|||
# See https://profile.yuzu-emu.org/ for more info |
|||
yuzu_username = |
|||
yuzu_token = |
|||
|
|||
[Network] |
|||
# Name of the network interface device to use with yuzu LAN play. |
|||
# e.g. On *nix: 'enp7s0', 'wlp6s0u1u3u3', 'lo' |
|||
# e.g. On Windows: 'Ethernet', 'Wi-Fi' |
|||
network_interface = |
|||
|
|||
[AddOns] |
|||
# Used to disable add-ons |
|||
# List of title IDs of games that will have add-ons disabled (separated by '|'): |
|||
title_ids = |
|||
# For each title ID, have a key/value pair called `disabled_<title_id>` equal to the names of the add-ons to disable (sep. by '|') |
|||
# e.x. disabled_0100000000010000 = Update|DLC <- disables Updates and |
|||
on Super Mario Odyssey |
|||
)"; |
|||
} // namespace DefaultINI |
|||
|
|||
|
|||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-2.0-or-later |
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project |
|||
// SPDX-License-Identifier: GPL-3.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include <filesystem> |
|||
#include <memory> |
|||
#include <optional> |
|||
#include <string> |
|||
#include <common/settings_common.h> |
|||
#include "common/common_types.h" |
|||
#include "common/settings_setting.h" |
|||
#include "common/settings_enums.h" |
|||
|
|||
#include "common/settings.h" |
|||
|
|||
class INIReader; |
|||
|
|||
class Config { |
|||
bool LoadINI(const std::string& default_contents = "", bool retry = true); |
|||
|
|||
public: |
|||
enum class ConfigType { |
|||
GlobalConfig, |
|||
PerGameConfig, |
|||
InputProfile, |
|||
namespace IOSSettings { |
|||
struct Values { |
|||
Settings::Linkage linkage; |
|||
Settings::Setting<bool> touchscreen{linkage, true, "touchscreen", Settings::Category::Overlay}; |
|||
}; |
|||
|
|||
explicit Config(const std::string& config_name = "config", |
|||
ConfigType config_type = ConfigType::GlobalConfig); |
|||
~Config(); |
|||
|
|||
void Initialize(const std::string& config_name); |
|||
|
|||
private: |
|||
/** |
|||
* Applies a value read from the config to a Setting. |
|||
* |
|||
* @param group The name of the INI group |
|||
* @param setting The yuzu setting to modify |
|||
*/ |
|||
template <typename Type, bool ranged> |
|||
void ReadSetting(const std::string& group, YuzuSettings::Setting<Type, ranged>& setting); |
|||
|
|||
void ReadValues(); |
|||
extern Values values; |
|||
|
|||
const ConfigType type; |
|||
std::unique_ptr<INIReader> config; |
|||
std::string config_loc; |
|||
const bool global; |
|||
}; |
|||
} // namespace IOSSettings |
|||
@ -1,330 +1,8 @@ |
|||
// |
|||
// Config.m - Sudachi |
|||
// Created by Jarrod Norwell on 13/3/2024. |
|||
// |
|||
|
|||
#import "Config.h" |
|||
#include "Config.h" |
|||
|
|||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-2.0-or-later |
|||
namespace IOSSettings { |
|||
|
|||
#include <memory> |
|||
#include <optional> |
|||
#include <sstream> |
|||
Values values; |
|||
|
|||
#include <INIReader.h> |
|||
#include "common/fs/file.h" |
|||
#include "common/fs/fs.h" |
|||
#include "common/fs/path_util.h" |
|||
#include "common/logging/log.h" |
|||
#include "common/settings.h" |
|||
#include "common/settings_enums.h" |
|||
#include "core/hle/service/acc/profile_manager.h" |
|||
#include "input_common/main.h" |
|||
|
|||
namespace FS = Common::FS; |
|||
|
|||
Config::Config(const std::string& config_name, ConfigType config_type) |
|||
: type(config_type), global{config_type == ConfigType::GlobalConfig} { |
|||
Initialize(config_name); |
|||
} |
|||
|
|||
Config::~Config() = default; |
|||
|
|||
bool Config::LoadINI(const std::string& default_contents, bool retry) { |
|||
void(FS::CreateParentDir(config_loc)); |
|||
config = std::make_unique<INIReader>(FS::PathToUTF8String(config_loc)); |
|||
const auto config_loc_str = FS::PathToUTF8String(config_loc); |
|||
if (config->ParseError() < 0) { |
|||
if (retry) { |
|||
LOG_WARNING(Config, "Failed to load {}. Creating file from defaults...", |
|||
config_loc_str); |
|||
|
|||
void(FS::CreateParentDir(config_loc)); |
|||
void(FS::WriteStringToFile(config_loc, FS::FileType::TextFile, default_contents)); |
|||
|
|||
config = std::make_unique<INIReader>(config_loc_str); |
|||
|
|||
return LoadINI(default_contents, false); |
|||
} |
|||
LOG_ERROR(Config, "Failed."); |
|||
return false; |
|||
} |
|||
LOG_INFO(Config, "Successfully loaded {}", config_loc_str); |
|||
return true; |
|||
} |
|||
|
|||
template <> |
|||
void Config::ReadSetting(const std::string& group, YuzuSettings::Setting<std::string>& setting) { |
|||
std::string setting_value = config->Get(group, setting.GetLabel(), setting.GetDefault()); |
|||
if (setting_value.empty()) { |
|||
setting_value = setting.GetDefault(); |
|||
} |
|||
setting = std::move(setting_value); |
|||
} |
|||
|
|||
template <> |
|||
void Config::ReadSetting(const std::string& group, YuzuSettings::Setting<bool>& setting) { |
|||
setting = config->GetBoolean(group, setting.GetLabel(), setting.GetDefault()); |
|||
} |
|||
|
|||
template <typename Type, bool ranged> |
|||
void Config::ReadSetting(const std::string& group, YuzuSettings::Setting<Type, ranged>& setting) { |
|||
setting = static_cast<Type>( |
|||
config->GetInteger(group, setting.GetLabel(), static_cast<long>(setting.GetDefault()))); |
|||
} |
|||
|
|||
void Config::ReadValues() { |
|||
ReadSetting("ControlsGeneral", YuzuSettings::values.mouse_enabled); |
|||
ReadSetting("ControlsGeneral", YuzuSettings::values.touch_device); |
|||
ReadSetting("ControlsGeneral", YuzuSettings::values.keyboard_enabled); |
|||
ReadSetting("ControlsGeneral", YuzuSettings::values.debug_pad_enabled); |
|||
ReadSetting("ControlsGeneral", YuzuSettings::values.vibration_enabled); |
|||
ReadSetting("ControlsGeneral", YuzuSettings::values.enable_accurate_vibrations); |
|||
ReadSetting("ControlsGeneral", YuzuSettings::values.motion_enabled); |
|||
YuzuSettings::values.touchscreen.enabled = |
|||
config->GetBoolean("ControlsGeneral", "touch_enabled", true); |
|||
YuzuSettings::values.touchscreen.rotation_angle = |
|||
config->GetInteger("ControlsGeneral", "touch_angle", 0); |
|||
YuzuSettings::values.touchscreen.diameter_x = |
|||
config->GetInteger("ControlsGeneral", "touch_diameter_x", 15); |
|||
YuzuSettings::values.touchscreen.diameter_y = |
|||
config->GetInteger("ControlsGeneral", "touch_diameter_y", 15); |
|||
|
|||
int num_touch_from_button_maps = |
|||
config->GetInteger("ControlsGeneral", "touch_from_button_map", 0); |
|||
if (num_touch_from_button_maps > 0) { |
|||
for (int i = 0; i < num_touch_from_button_maps; ++i) { |
|||
YuzuSettings::TouchFromButtonMap map; |
|||
map.name = config->Get("ControlsGeneral", |
|||
std::string("touch_from_button_maps_") + std::to_string(i) + |
|||
std::string("_name"), |
|||
"default"); |
|||
const int num_touch_maps = config->GetInteger( |
|||
"ControlsGeneral", |
|||
std::string("touch_from_button_maps_") + std::to_string(i) + std::string("_count"), |
|||
0); |
|||
map.buttons.reserve(num_touch_maps); |
|||
|
|||
for (int j = 0; j < num_touch_maps; ++j) { |
|||
std::string touch_mapping = |
|||
config->Get("ControlsGeneral", |
|||
std::string("touch_from_button_maps_") + std::to_string(i) + |
|||
std::string("_bind_") + std::to_string(j), |
|||
""); |
|||
map.buttons.emplace_back(std::move(touch_mapping)); |
|||
} |
|||
|
|||
YuzuSettings::values.touch_from_button_maps.emplace_back(std::move(map)); |
|||
} |
|||
} else { |
|||
YuzuSettings::values.touch_from_button_maps.emplace_back( |
|||
YuzuSettings::TouchFromButtonMap{"default", {}}); |
|||
num_touch_from_button_maps = 1; |
|||
} |
|||
YuzuSettings::values.touch_from_button_map_index = std::clamp( |
|||
YuzuSettings::values.touch_from_button_map_index.GetValue(), 0, num_touch_from_button_maps - 1); |
|||
|
|||
ReadSetting("ControlsGeneral", YuzuSettings::values.udp_input_servers); |
|||
|
|||
// Data Storage |
|||
ReadSetting("Data Storage", YuzuSettings::values.use_virtual_sd); |
|||
FS::SetYuzuPath(FS::YuzuPath::NANDDir, |
|||
config->Get("Data Storage", "nand_directory", |
|||
FS::GetYuzuPathString(FS::YuzuPath::NANDDir))); |
|||
FS::SetYuzuPath(FS::YuzuPath::SDMCDir, |
|||
config->Get("Data Storage", "sdmc_directory", |
|||
FS::GetYuzuPathString(FS::YuzuPath::SDMCDir))); |
|||
FS::SetYuzuPath(FS::YuzuPath::LoadDir, |
|||
config->Get("Data Storage", "load_directory", |
|||
FS::GetYuzuPathString(FS::YuzuPath::LoadDir))); |
|||
FS::SetYuzuPath(FS::YuzuPath::DumpDir, |
|||
config->Get("Data Storage", "dump_directory", |
|||
FS::GetYuzuPathString(FS::YuzuPath::DumpDir))); |
|||
ReadSetting("Data Storage", YuzuSettings::values.gamecard_inserted); |
|||
ReadSetting("Data Storage", YuzuSettings::values.gamecard_current_game); |
|||
ReadSetting("Data Storage", YuzuSettings::values.gamecard_path); |
|||
|
|||
// System |
|||
ReadSetting("System", YuzuSettings::values.current_user); |
|||
YuzuSettings::values.current_user = std::clamp<int>(YuzuSettings::values.current_user.GetValue(), 0, |
|||
Service::Account::MAX_USERS - 1); |
|||
|
|||
// Enable docked mode by default on iOS |
|||
YuzuSettings::values.use_docked_mode.SetValue(config->GetBoolean("System", "use_docked_mode", false) |
|||
? YuzuSettings::ConsoleMode::Docked |
|||
: YuzuSettings::ConsoleMode::Handheld); |
|||
|
|||
const auto rng_seed_enabled = config->GetBoolean("System", "rng_seed_enabled", false); |
|||
if (rng_seed_enabled) { |
|||
YuzuSettings::values.rng_seed.SetValue(config->GetInteger("System", "rng_seed", 0)); |
|||
} else { |
|||
YuzuSettings::values.rng_seed.SetValue(0); |
|||
} |
|||
YuzuSettings::values.rng_seed_enabled.SetValue(rng_seed_enabled); |
|||
|
|||
const auto custom_rtc_enabled = config->GetBoolean("System", "custom_rtc_enabled", false); |
|||
if (custom_rtc_enabled) { |
|||
YuzuSettings::values.custom_rtc = config->GetInteger("System", "custom_rtc", 0); |
|||
} else { |
|||
YuzuSettings::values.custom_rtc = 0; |
|||
} |
|||
YuzuSettings::values.custom_rtc_enabled = custom_rtc_enabled; |
|||
|
|||
ReadSetting("System", YuzuSettings::values.language_index); |
|||
ReadSetting("System", YuzuSettings::values.region_index); |
|||
ReadSetting("System", YuzuSettings::values.time_zone_index); |
|||
ReadSetting("System", YuzuSettings::values.sound_index); |
|||
|
|||
// Core |
|||
ReadSetting("Core", YuzuSettings::values.use_multi_core); |
|||
ReadSetting("Core", YuzuSettings::values.memory_layout_mode); |
|||
|
|||
// Cpu |
|||
ReadSetting("Cpu", YuzuSettings::values.cpu_accuracy); |
|||
ReadSetting("Cpu", YuzuSettings::values.cpu_debug_mode); |
|||
ReadSetting("Cpu", YuzuSettings::values.cpuopt_page_tables); |
|||
ReadSetting("Cpu", YuzuSettings::values.cpuopt_block_linking); |
|||
ReadSetting("Cpu", YuzuSettings::values.cpuopt_return_stack_buffer); |
|||
ReadSetting("Cpu", YuzuSettings::values.cpuopt_fast_dispatcher); |
|||
ReadSetting("Cpu", YuzuSettings::values.cpuopt_context_elimination); |
|||
ReadSetting("Cpu", YuzuSettings::values.cpuopt_const_prop); |
|||
ReadSetting("Cpu", YuzuSettings::values.cpuopt_misc_ir); |
|||
ReadSetting("Cpu", YuzuSettings::values.cpuopt_reduce_misalign_checks); |
|||
ReadSetting("Cpu", YuzuSettings::values.cpuopt_fastmem); |
|||
ReadSetting("Cpu", YuzuSettings::values.cpuopt_fastmem_exclusives); |
|||
ReadSetting("Cpu", YuzuSettings::values.cpuopt_recompile_exclusives); |
|||
ReadSetting("Cpu", YuzuSettings::values.cpuopt_ignore_memory_aborts); |
|||
ReadSetting("Cpu", YuzuSettings::values.cpuopt_unsafe_unfuse_fma); |
|||
ReadSetting("Cpu", YuzuSettings::values.cpuopt_unsafe_reduce_fp_error); |
|||
ReadSetting("Cpu", YuzuSettings::values.cpuopt_unsafe_ignore_standard_fpcr); |
|||
ReadSetting("Cpu", YuzuSettings::values.cpuopt_unsafe_inaccurate_nan); |
|||
ReadSetting("Cpu", YuzuSettings::values.cpuopt_unsafe_fastmem_check); |
|||
ReadSetting("Cpu", YuzuSettings::values.cpuopt_unsafe_ignore_global_monitor); |
|||
|
|||
// Renderer |
|||
ReadSetting("Renderer", YuzuSettings::values.renderer_backend); |
|||
ReadSetting("Renderer", YuzuSettings::values.renderer_debug); |
|||
ReadSetting("Renderer", YuzuSettings::values.renderer_shader_feedback); |
|||
ReadSetting("Renderer", YuzuSettings::values.enable_nsight_aftermath); |
|||
ReadSetting("Renderer", YuzuSettings::values.disable_shader_loop_safety_checks); |
|||
ReadSetting("Renderer", YuzuSettings::values.vulkan_device); |
|||
|
|||
ReadSetting("Renderer", YuzuSettings::values.resolution_setup); |
|||
ReadSetting("Renderer", YuzuSettings::values.scaling_filter); |
|||
ReadSetting("Renderer", YuzuSettings::values.fsr_sharpening_slider); |
|||
ReadSetting("Renderer", YuzuSettings::values.anti_aliasing); |
|||
ReadSetting("Renderer", YuzuSettings::values.fullscreen_mode); |
|||
ReadSetting("Renderer", YuzuSettings::values.aspect_ratio); |
|||
ReadSetting("Renderer", YuzuSettings::values.max_anisotropy); |
|||
ReadSetting("Renderer", YuzuSettings::values.use_speed_limit); |
|||
ReadSetting("Renderer", YuzuSettings::values.speed_limit); |
|||
ReadSetting("Renderer", YuzuSettings::values.use_disk_shader_cache); |
|||
ReadSetting("Renderer", YuzuSettings::values.use_asynchronous_gpu_emulation); |
|||
ReadSetting("Renderer", YuzuSettings::values.vsync_mode); |
|||
ReadSetting("Renderer", YuzuSettings::values.shader_backend); |
|||
ReadSetting("Renderer", YuzuSettings::values.use_asynchronous_shaders); |
|||
ReadSetting("Renderer", YuzuSettings::values.nvdec_emulation); |
|||
ReadSetting("Renderer", YuzuSettings::values.use_fast_gpu_time); |
|||
ReadSetting("Renderer", YuzuSettings::values.use_vulkan_driver_pipeline_cache); |
|||
|
|||
ReadSetting("Renderer", YuzuSettings::values.bg_red); |
|||
ReadSetting("Renderer", YuzuSettings::values.bg_green); |
|||
ReadSetting("Renderer", YuzuSettings::values.bg_blue); |
|||
|
|||
// Use GPU accuracy normal by default on Android |
|||
YuzuSettings::values.gpu_accuracy = static_cast<YuzuSettings::GpuAccuracy>(config->GetInteger( |
|||
"Renderer", "gpu_accuracy", static_cast<u32>(YuzuSettings::GpuAccuracy::Normal))); |
|||
|
|||
// Use GPU default anisotropic filtering on Android |
|||
YuzuSettings::values.max_anisotropy = |
|||
static_cast<YuzuSettings::AnisotropyMode>(config->GetInteger("Renderer", "max_anisotropy", 1)); |
|||
|
|||
// Disable ASTC compute by default on iOS |
|||
YuzuSettings::values.accelerate_astc.SetValue( |
|||
config->GetBoolean("Renderer", "accelerate_astc", false) ? YuzuSettings::AstcDecodeMode::Gpu |
|||
: YuzuSettings::AstcDecodeMode::Cpu); |
|||
|
|||
// Enable asynchronous presentation by default on Android |
|||
YuzuSettings::values.async_presentation = |
|||
config->GetBoolean("Renderer", "async_presentation", true); |
|||
|
|||
// Disable force_max_clock by default on Android |
|||
YuzuSettings::values.renderer_force_max_clock = |
|||
config->GetBoolean("Renderer", "force_max_clock", false); |
|||
|
|||
// Disable use_reactive_flushing by default on Android |
|||
YuzuSettings::values.use_reactive_flushing = |
|||
config->GetBoolean("Renderer", "use_reactive_flushing", false); |
|||
|
|||
// Audio |
|||
ReadSetting("Audio", YuzuSettings::values.sink_id); |
|||
ReadSetting("Audio", YuzuSettings::values.audio_output_device_id); |
|||
ReadSetting("Audio", YuzuSettings::values.volume); |
|||
|
|||
// Miscellaneous |
|||
// log_filter has a different default here than from common |
|||
YuzuSettings::values.log_filter = "*:Info"; |
|||
ReadSetting("Miscellaneous", YuzuSettings::values.use_dev_keys); |
|||
|
|||
// Debugging |
|||
YuzuSettings::values.record_frame_times = |
|||
config->GetBoolean("Debugging", "record_frame_times", false); |
|||
ReadSetting("Debugging", YuzuSettings::values.dump_exefs); |
|||
ReadSetting("Debugging", YuzuSettings::values.dump_nso); |
|||
ReadSetting("Debugging", YuzuSettings::values.enable_fs_access_log); |
|||
ReadSetting("Debugging", YuzuSettings::values.reporting_services); |
|||
ReadSetting("Debugging", YuzuSettings::values.quest_flag); |
|||
ReadSetting("Debugging", YuzuSettings::values.use_debug_asserts); |
|||
ReadSetting("Debugging", YuzuSettings::values.use_auto_stub); |
|||
ReadSetting("Debugging", YuzuSettings::values.disable_macro_jit); |
|||
ReadSetting("Debugging", YuzuSettings::values.disable_macro_hle); |
|||
ReadSetting("Debugging", YuzuSettings::values.use_gdbstub); |
|||
ReadSetting("Debugging", YuzuSettings::values.gdbstub_port); |
|||
|
|||
const auto title_list = config->Get("AddOns", "title_ids", ""); |
|||
std::stringstream ss(title_list); |
|||
std::string line; |
|||
while (std::getline(ss, line, '|')) { |
|||
const auto title_id = std::strtoul(line.c_str(), nullptr, 16); |
|||
const auto disabled_list = config->Get("AddOns", "disabled_" + line, ""); |
|||
|
|||
std::stringstream inner_ss(disabled_list); |
|||
std::string inner_line; |
|||
std::vector<std::string> out; |
|||
while (std::getline(inner_ss, inner_line, '|')) { |
|||
out.push_back(inner_line); |
|||
} |
|||
|
|||
YuzuSettings::values.disabled_addons.insert_or_assign(title_id, out); |
|||
} |
|||
|
|||
// Web Service |
|||
ReadSetting("WebService", YuzuSettings::values.enable_telemetry); |
|||
ReadSetting("WebService", YuzuSettings::values.web_api_url); |
|||
ReadSetting("WebService", YuzuSettings::values.yuzu_username); |
|||
ReadSetting("WebService", YuzuSettings::values.yuzu_token); |
|||
|
|||
// Network |
|||
ReadSetting("Network", YuzuSettings::values.network_interface); |
|||
} |
|||
|
|||
void Config::Initialize(const std::string& config_name) { |
|||
const auto fs_config_loc = FS::GetYuzuPath(FS::YuzuPath::ConfigDir); |
|||
const auto config_file = fmt::format("{}.ini", config_name); |
|||
|
|||
switch (type) { |
|||
case ConfigType::GlobalConfig: |
|||
config_loc = FS::PathToUTF8String(fs_config_loc / config_file); |
|||
break; |
|||
case ConfigType::PerGameConfig: |
|||
config_loc = FS::PathToUTF8String(fs_config_loc / "custom" / FS::ToU8String(config_file)); |
|||
break; |
|||
case ConfigType::InputProfile: |
|||
config_loc = FS::PathToUTF8String(fs_config_loc / "input" / config_file); |
|||
LoadINI(DefaultINI::android_config_file); |
|||
return; |
|||
} |
|||
LoadINI(DefaultINI::android_config_file); |
|||
ReadValues(); |
|||
} |
|||
} // namespace IOSSettings |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue