dolphin/Source/Core/Core/ConfigManager.h

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

375 lines
9.6 KiB
C
Raw Normal View History

// Copyright 2008 Dolphin Emulator Project
2015-05-18 01:08:10 +02:00
// Licensed under GPLv2+
// Refer to the license.txt file included.
#pragma once
2016-08-14 19:54:01 +00:00
#include <limits>
#include <optional>
#include <set>
#include <string>
#include <utility>
#include <vector>
#include "Common/Common.h"
#include "Common/CommonTypes.h"
class IniFile;
namespace DiscIO
{
enum class Language;
enum class Platform;
enum class Region;
struct Partition;
class Volume;
2018-02-10 21:03:27 +01:00
} // namespace DiscIO
namespace ExpansionInterface
{
enum TEXIDevices : int;
} // namespace ExpansionInterface
namespace IOS::ES
{
class TMDReader;
} // namespace IOS::ES
namespace PowerPC
{
enum class CPUCore;
} // namespace PowerPC
namespace SerialInterface
{
enum SIDevices : int;
} // namespace SerialInterface
struct BootParameters;
2013-01-16 20:16:56 -05:00
// DSP Backend Types
2017-05-11 15:59:31 -07:00
#define BACKEND_NULLSOUND _trans("No Audio Output")
#define BACKEND_ALSA "ALSA"
2017-03-22 16:09:59 -07:00
#define BACKEND_CUBEB "Cubeb"
#define BACKEND_OPENAL "OpenAL"
#define BACKEND_PULSEAUDIO "Pulse"
#define BACKEND_OPENSLES "OpenSLES"
#define BACKEND_WASAPI _trans("WASAPI (Exclusive Mode)")
enum class GPUDeterminismMode
{
Auto,
Disabled,
// This is currently the only mode. There will probably be at least
// one more at some point.
FakeCompletion,
};
Remove NonCopyable The class NonCopyable is, like the name says, supposed to disallow copying. But should it allow moving? For a long time, NonCopyable used to not allow moving. (It declared a deleted copy constructor and assigment operator without declaring a move constructor and assignment operator, making the compiler implicitly delete the move constructor and assignment operator.) That's fine if the classes that inherit from NonCopyable don't need to be movable or if writing the move constructor and assignment operator by hand is fine, but that's not the case for all classes, as I discovered when I was working on the DirectoryBlob PR. Because of that, I decided to make NonCopyable movable in c7602cc, allowing me to use NonCopyable in DirectoryBlob.h. That was however an unfortunate decision, because some of the classes that inherit from NonCopyable have incorrect behavior when moved by default- generated move constructors and assignment operators, and do not explicitly delete the move constructors and assignment operators, relying on NonCopyable being non-movable. So what can we do about this? There are four solutions that I can think of: 1. Make NonCopyable non-movable and tell DirectoryBlob to suck it. 2. Keep allowing moving NonCopyable, and expect that classes that don't support moving will delete the move constructor and assignment operator manually. Not only is this inconsistent (having classes disallow copying one way and disallow moving another way), but deleting the move constructor and assignment operator manually is too easy to forget compared to how tricky the resulting problems are. 3. Have one "MovableNonCopyable" and one "NonMovableNonCopyable". It works, but it feels rather silly... 4. Don't have a NonCopyable class at all. Considering that deleting the copy constructor and assignment operator only takes two lines of code, I don't see much of a reason to keep NonCopyable. I suppose that there was more of a point in having NonCopyable back in the pre-C++11 days, when it wasn't possible to use "= delete". I decided to go with the fourth one (like the commit title says). The implementation of the commit is fairly straight-forward, though I would like to point out that I skipped adding "= delete" lines for classes whose only reason for being uncopyable is that they contain uncopyable classes like File::IOFile and std::unique_ptr, because the compiler makes such classes uncopyable automatically.
2017-08-04 23:57:12 +02:00
struct SConfig
{
// Wii Devices
bool m_WiiSDCard;
bool m_WiiKeyboard;
2013-02-11 17:58:56 -06:00
bool m_WiimoteContinuousScanning;
bool m_WiimoteEnableSpeaker;
2014-10-20 17:49:33 -04:00
// ISO folder
std::vector<std::string> m_ISOFolder;
bool m_RecursiveISOFolder;
// Settings
bool bEnableDebugging = false;
#ifdef USE_GDBSTUB
int iGDBPort;
#ifndef _WIN32
std::string gdb_socket;
#endif
#endif
bool bAutomaticStart = false;
bool bBootToPause = false;
PowerPC::CPUCore cpu_core;
bool bJITFollowBranch;
bool bJITNoBlockCache = false;
bool bJITNoBlockLinking = false;
bool bJITOff = false;
bool bJITLoadStoreOff = false;
bool bJITLoadStorelXzOff = false;
bool bJITLoadStorelwzOff = false;
bool bJITLoadStorelbzxOff = false;
bool bJITLoadStoreFloatingOff = false;
bool bJITLoadStorePairedOff = false;
bool bJITFloatingPointOff = false;
bool bJITIntegerOff = false;
bool bJITPairedOff = false;
bool bJITSystemRegistersOff = false;
bool bJITBranchOff = false;
bool bFastmem;
bool bFPRF = false;
bool bAccurateNaNs = false;
int iTimingVariance = 40; // in milli secounds
bool bCPUThread = true;
bool bDSPThread = false;
bool bDSPHLE = true;
bool bSyncGPUOnSkipIdleHack = true;
bool bHLE_BS2 = true;
bool bEnableCheats = false;
bool bEnableMemcardSdWriting = true;
bool bCopyWiiSaveNetplay = true;
bool bDPL2Decoder = false;
int iLatency = 20;
bool m_audio_stretch = false;
int m_audio_stretch_max_latency = 80;
bool bRunCompareServer = false;
bool bRunCompareClient = false;
bool bMMU = false;
bool bLowDCBZHack = false;
int iBBDumpPort = 0;
bool bFastDiscSpeed = false;
bool bSyncGPU = false;
int iSyncGpuMaxDistance;
int iSyncGpuMinDistance;
float fSyncGpuOverclock;
int SelectedLanguage = 0;
bool bOverrideRegionSettings = false;
bool bWii = false;
bool m_is_mios = false;
// Interface settings
bool bConfirmStop = false;
bool bHideCursor = false;
bool bUsePanicHandlers = true;
bool bOnScreenDisplayMessages = true;
std::string theme_name;
// Analytics settings.
std::string m_analytics_id;
bool m_analytics_enabled = false;
bool m_analytics_permission_asked = false;
// Bluetooth passthrough mode settings
bool m_bt_passthrough_enabled = false;
int m_bt_passthrough_pid = -1;
int m_bt_passthrough_vid = -1;
std::string m_bt_passthrough_link_keys;
// USB passthrough settings
std::set<std::pair<u16, u16>> m_usb_passthrough_devices;
bool IsUSBDeviceWhitelisted(std::pair<u16, u16> vid_pid) const;
// Fifo Player related settings
bool bLoopFifoReplay = true;
2016-07-13 16:46:14 -04:00
// Custom RTC
bool bEnableCustomRTC;
u32 m_customRTCValue;
DiscIO::Region m_region;
std::string m_strVideoBackend;
std::string m_strGPUDeterminismMode;
// set based on the string version
GPUDeterminismMode m_GPUDeterminismMode;
// files
std::string m_strBootROM;
std::string m_strSRAM;
std::string m_perfDir;
2017-06-05 13:55:54 +02:00
std::string m_debugger_game_id;
Boot: Clean up the boot code * Move out boot parameters to a separate struct, which is not part of SConfig/ConfigManager because there is no reason for it to be there. * Move out file name parsing and constructing the appropriate params from paths to a separate function that does that, and only that. * For every different boot type we support, add a proper struct with only the required parameters, with descriptive names and use std::variant to only store what we need. * Clean up the bHLE_BS2 stuff which made no sense sometimes. Now instead of using bHLE_BS2 for two different things, both for storing the user config setting and as a runtime boot parameter, we simply replace the Disc boot params with BootParameters::IPL. * Const correctness so it's clear what can or cannot update the config. * Drop unused parameters and unneeded checks. * Make a few checks a lot more concise. (Looking at you, extension checks for disc images.) * Remove a mildly terrible workaround where we needed to pass an empty string in order to boot the GC IPL without any game inserted. (Not required anymore thanks to std::variant and std::optional.) The motivation for this are multiple: cleaning up and being able to add support for booting an installed NAND title. Without this change, it'd be pretty much impossible to implement that. Also, using std::visit with std::variant makes the compiler do additional type checks: now we're guaranteed that the boot code will handle all boot types and no invalid boot type will be possible.
2017-05-27 15:43:40 +02:00
// TODO: remove this as soon as the ticket view hack in IOS/ES/Views is dropped.
bool m_disc_booted_from_game_list = false;
const std::string& GetGameID() const { return m_game_id; }
const std::string& GetTitleDescription() const { return m_title_description; }
u64 GetTitleID() const { return m_title_id; }
u16 GetRevision() const { return m_revision; }
void ResetRunningGameMetadata();
void SetRunningGameMetadata(const DiscIO::Volume& volume, const DiscIO::Partition& partition);
void SetRunningGameMetadata(const IOS::ES::TMDReader& tmd, DiscIO::Platform platform);
void LoadDefaults();
// Replaces NTSC-K with some other region, and doesn't replace non-NTSC-K regions
static DiscIO::Region ToGameCubeRegion(DiscIO::Region region);
// The region argument must be valid for GameCube (i.e. must not be NTSC-K)
static const char* GetDirectoryForRegion(DiscIO::Region region);
2017-05-21 22:21:34 +01:00
std::string GetBootROMPath(const std::string& region_directory) const;
Boot: Clean up the boot code * Move out boot parameters to a separate struct, which is not part of SConfig/ConfigManager because there is no reason for it to be there. * Move out file name parsing and constructing the appropriate params from paths to a separate function that does that, and only that. * For every different boot type we support, add a proper struct with only the required parameters, with descriptive names and use std::variant to only store what we need. * Clean up the bHLE_BS2 stuff which made no sense sometimes. Now instead of using bHLE_BS2 for two different things, both for storing the user config setting and as a runtime boot parameter, we simply replace the Disc boot params with BootParameters::IPL. * Const correctness so it's clear what can or cannot update the config. * Drop unused parameters and unneeded checks. * Make a few checks a lot more concise. (Looking at you, extension checks for disc images.) * Remove a mildly terrible workaround where we needed to pass an empty string in order to boot the GC IPL without any game inserted. (Not required anymore thanks to std::variant and std::optional.) The motivation for this are multiple: cleaning up and being able to add support for booting an installed NAND title. Without this change, it'd be pretty much impossible to implement that. Also, using std::visit with std::variant makes the compiler do additional type checks: now we're guaranteed that the boot code will handle all boot types and no invalid boot type will be possible.
2017-05-27 15:43:40 +02:00
bool SetPathsAndGameMetadata(const BootParameters& boot);
static DiscIO::Region GetFallbackRegion();
DiscIO::Language GetCurrentLanguage(bool wii) const;
DiscIO::Language GetLanguageAdjustedForRegion(bool wii, DiscIO::Region region) const;
IniFile LoadDefaultGameIni() const;
IniFile LoadLocalGameIni() const;
IniFile LoadGameIni() const;
static IniFile LoadDefaultGameIni(const std::string& id, std::optional<u16> revision);
static IniFile LoadLocalGameIni(const std::string& id, std::optional<u16> revision);
static IniFile LoadGameIni(const std::string& id, std::optional<u16> revision);
std::string m_strGbaCartA;
std::string m_strGbaCartB;
2017-03-18 17:46:05 -04:00
ExpansionInterface::TEXIDevices m_EXIDevice[3];
SerialInterface::SIDevices m_SIDevice[4];
std::string m_bba_mac;
// interface language
std::string m_InterfaceLanguage;
float m_EmulationSpeed;
bool m_OCEnable;
float m_OCFactor;
// other interface settings
bool m_InterfaceExtendedFPSInfo;
bool m_show_active_title = false;
bool m_use_builtin_title_database = true;
bool m_ListDrives;
bool m_ListWad;
bool m_ListElfDol;
bool m_ListWii;
bool m_ListGC;
bool m_ListPal;
bool m_ListUsa;
bool m_ListJap;
bool m_ListAustralia;
bool m_ListFrance;
bool m_ListGermany;
bool m_ListItaly;
bool m_ListKorea;
bool m_ListNetherlands;
bool m_ListRussia;
bool m_ListSpain;
bool m_ListTaiwan;
bool m_ListWorld;
bool m_ListUnknown;
int m_ListSort;
int m_ListSort2;
// Game list column toggles
bool m_showSystemColumn;
bool m_showBannerColumn;
2017-05-08 19:03:59 +02:00
bool m_showDescriptionColumn;
bool m_showTitleColumn;
bool m_showMakerColumn;
2015-10-11 04:44:53 +02:00
bool m_showFileNameColumn;
bool m_showIDColumn;
bool m_showRegionColumn;
bool m_showSizeColumn;
2018-10-01 09:10:40 +02:00
bool m_showTagsColumn;
std::string m_WirelessMac;
bool m_PauseMovie;
bool m_ShowLag;
2014-09-30 18:49:44 -04:00
bool m_ShowFrameCount;
2016-07-19 20:23:25 -04:00
bool m_ShowRTC;
std::string m_strMovieAuthor;
bool m_DumpFrames;
bool m_DumpFramesSilent;
2014-10-17 21:08:34 -04:00
bool m_ShowInputDisplay;
bool m_PauseOnFocusLost;
2013-01-16 20:16:56 -05:00
// DSP settings
bool m_DSPEnableJIT;
bool m_DSPCaptureLog;
2013-01-16 20:16:56 -05:00
bool m_DumpAudio;
2017-01-08 13:51:00 -05:00
bool m_DumpAudioSilent;
bool m_IsMuted;
bool m_DumpUCode;
2013-01-16 20:16:56 -05:00
int m_Volume;
std::string sBackend;
2018-02-10 21:03:27 +01:00
#ifdef _WIN32
// WSAPI settings
std::string sWASAPIDevice;
#endif
// Input settings
bool m_BackgroundInput;
Make the Wii U Gamecube adapter work with less magic. The Wii U Gamecube controller adapter setup has always been a bit weird. It tries to be as automatic as possible to make the user experience as easy as possible. The problem with this approach is that it brings a large disconnect in the user experience because you have the Gamecube controller setup with regular gamepads and then for some reason below that you have a "direct connect" option which will cause the Gamecube Adapter to overwrite the regular inputs if something was connected. While this works and allows the user to only click one checkbox to get the device working, it breaks the user's experience because they don't really know what "direct connect" means and won't look it up to figure out what it is. Just expecting the device to work (At least one occurence of this in the IRC channel in the last week). This way around also had the terrible nature of making the code more filthy than it needed to be. The GCAdapter namespace was parasitic and hooked in to the regular GC Controller SI class to overwrite the data that it was getting from the default configuration. Now instead we have a specific SIDevice class for the Wii U Gamecube adapter. This class is fairly simple and is a child of the regular SI Gamecube Pad device and only reimplements what it needs to. This also gives the ability to configure controllers individually, which allows the user to configure rumble individually per pad input. Overall the code is cleaner, and it fits more in line with how the rest of Dolphin works.
2015-12-31 11:09:47 -06:00
bool m_AdapterRumble[4];
Fix GCPad recalibration shortcut. Dolphin has supported the recalibration shortcut (X+Y+Start) for quite a long while. So if someont's axises are terrible, you could easily recalibrate. Games even get the initial calibration upon boot(Most of the time). While changing over the GCAdapter code, I was testing to make sure the reset and calibration shortcuts still worked, turns out they didn't work at all. Looking in to the problem, we capture the combination properly, and we wait three seconds until we actually fire that off recalibration. The problem is for Nintendo's SDK to properly handle recalibrating, we need to send back data saying that it needs to recalibrate. On hardware this is done as part of the 64bits of data the controller sends back to us. On holding of the controller, bit 61 of the return value is set, which the Nintendo SDK catches, and then signals immediately afterwards a CMD_ORIGIN command in order to recalibrate the controller. We were outright ignoring this bit, so the library wasn't ever recalibrating. I suspect in the past the class itself used to use the calibration data to to offset the data, but somewhere along the lines it got munged out of existence. The Gamecube adapter does this shortcut in a bit of a unique way, instead of sending the command and having the library support it and what have you. Once holding the shortcut for the amount of time, the adapter reports back that the controller has actually been disconnected. Then when you let go of the combination, the adapter states that a new device has been connected to that port, and the recalibration happens because a new device is "connected." This fixes controller calibration for both emulated GC controllers and also the Wii Gamecube Adapter.
2015-12-31 11:23:04 -06:00
bool m_AdapterKonga[4];
2015-06-16 21:48:09 +02:00
// Network settings
bool m_SSLDumpRead;
bool m_SSLDumpWrite;
2015-06-09 20:23:56 +02:00
bool m_SSLVerifyCert;
bool m_SSLDumpRootCA;
bool m_SSLDumpPeerCert;
2015-06-16 21:48:09 +02:00
// Auto-update settings
std::string m_auto_update_track;
std::string m_auto_update_hash_override;
Remove NonCopyable The class NonCopyable is, like the name says, supposed to disallow copying. But should it allow moving? For a long time, NonCopyable used to not allow moving. (It declared a deleted copy constructor and assigment operator without declaring a move constructor and assignment operator, making the compiler implicitly delete the move constructor and assignment operator.) That's fine if the classes that inherit from NonCopyable don't need to be movable or if writing the move constructor and assignment operator by hand is fine, but that's not the case for all classes, as I discovered when I was working on the DirectoryBlob PR. Because of that, I decided to make NonCopyable movable in c7602cc, allowing me to use NonCopyable in DirectoryBlob.h. That was however an unfortunate decision, because some of the classes that inherit from NonCopyable have incorrect behavior when moved by default- generated move constructors and assignment operators, and do not explicitly delete the move constructors and assignment operators, relying on NonCopyable being non-movable. So what can we do about this? There are four solutions that I can think of: 1. Make NonCopyable non-movable and tell DirectoryBlob to suck it. 2. Keep allowing moving NonCopyable, and expect that classes that don't support moving will delete the move constructor and assignment operator manually. Not only is this inconsistent (having classes disallow copying one way and disallow moving another way), but deleting the move constructor and assignment operator manually is too easy to forget compared to how tricky the resulting problems are. 3. Have one "MovableNonCopyable" and one "NonMovableNonCopyable". It works, but it feels rather silly... 4. Don't have a NonCopyable class at all. Considering that deleting the copy constructor and assignment operator only takes two lines of code, I don't see much of a reason to keep NonCopyable. I suppose that there was more of a point in having NonCopyable back in the pre-C++11 days, when it wasn't possible to use "= delete". I decided to go with the fourth one (like the commit title says). The implementation of the commit is fairly straight-forward, though I would like to point out that I skipped adding "= delete" lines for classes whose only reason for being uncopyable is that they contain uncopyable classes like File::IOFile and std::unique_ptr, because the compiler makes such classes uncopyable automatically.
2017-08-04 23:57:12 +02:00
SConfig(const SConfig&) = delete;
SConfig& operator=(const SConfig&) = delete;
SConfig(SConfig&&) = delete;
SConfig& operator=(SConfig&&) = delete;
// Save settings
void SaveSettings();
// Load settings
void LoadSettings();
// Return the permanent and somewhat globally used instance of this struct
static SConfig& GetInstance() { return (*m_Instance); }
static void Init();
static void Shutdown();
private:
SConfig();
~SConfig();
2014-06-16 01:12:43 -04:00
void SaveGeneralSettings(IniFile& ini);
void SaveInterfaceSettings(IniFile& ini);
void SaveGameListSettings(IniFile& ini);
void SaveCoreSettings(IniFile& ini);
void SaveDSPSettings(IniFile& ini);
void SaveInputSettings(IniFile& ini);
2014-06-16 01:12:43 -04:00
void SaveMovieSettings(IniFile& ini);
void SaveFifoPlayerSettings(IniFile& ini);
2015-06-16 21:48:09 +02:00
void SaveNetworkSettings(IniFile& ini);
void SaveAnalyticsSettings(IniFile& ini);
void SaveBluetoothPassthroughSettings(IniFile& ini);
void SaveUSBPassthroughSettings(IniFile& ini);
void SaveAutoUpdateSettings(IniFile& ini);
void SaveJitDebugSettings(IniFile& ini);
2014-06-16 01:12:43 -04:00
void LoadGeneralSettings(IniFile& ini);
void LoadInterfaceSettings(IniFile& ini);
void LoadGameListSettings(IniFile& ini);
void LoadCoreSettings(IniFile& ini);
void LoadDSPSettings(IniFile& ini);
void LoadInputSettings(IniFile& ini);
2014-06-16 01:12:43 -04:00
void LoadMovieSettings(IniFile& ini);
void LoadFifoPlayerSettings(IniFile& ini);
2015-06-16 21:48:09 +02:00
void LoadNetworkSettings(IniFile& ini);
void LoadAnalyticsSettings(IniFile& ini);
void LoadBluetoothPassthroughSettings(IniFile& ini);
void LoadUSBPassthroughSettings(IniFile& ini);
void LoadAutoUpdateSettings(IniFile& ini);
void LoadJitDebugSettings(IniFile& ini);
void SetRunningGameMetadata(const std::string& game_id, const std::string& gametdb_id,
u64 title_id, u16 revision, DiscIO::Region region);
static SConfig* m_Instance;
std::string m_game_id;
std::string m_gametdb_id;
std::string m_title_description;
u64 m_title_id;
u16 m_revision;
};