Overlay local gameinis over global gameinis instead of copying.

Huge megacommit because a lot of things needed to be modified to make this
possible.
This commit is contained in:
Pierre Bourdon
2013-09-07 23:02:49 +02:00
parent cf4c39d2be
commit 501eafb407
1549 changed files with 544 additions and 609 deletions

View File

@ -59,7 +59,7 @@
#define GC_USER_DIR "GC"
#define WII_USER_DIR "Wii"
#define CONFIG_DIR "Config"
#define GAMECONFIG_DIR "GameConfig"
#define GAMESETTINGS_DIR "GameSettings"
#define MAPS_DIR "Maps"
#define CACHE_DIR "Cache"
#define SHADERCACHE_DIR "ShaderCache"

View File

@ -740,7 +740,7 @@ const std::string& GetUserPath(const unsigned int DirIDX, const std::string &new
paths[D_WIIROOT_IDX] = paths[D_USER_IDX] + WII_USER_DIR;
paths[D_WIIUSER_IDX] = paths[D_WIIROOT_IDX] + DIR_SEP;
paths[D_CONFIG_IDX] = paths[D_USER_IDX] + CONFIG_DIR DIR_SEP;
paths[D_GAMECONFIG_IDX] = paths[D_USER_IDX] + GAMECONFIG_DIR DIR_SEP;
paths[D_GAMESETTINGS_IDX] = paths[D_USER_IDX] + GAMESETTINGS_DIR DIR_SEP;
paths[D_MAPS_IDX] = paths[D_USER_IDX] + MAPS_DIR DIR_SEP;
paths[D_CACHE_IDX] = paths[D_USER_IDX] + CACHE_DIR DIR_SEP;
paths[D_SHADERCACHE_IDX] = paths[D_USER_IDX] + SHADERCACHE_DIR DIR_SEP;
@ -791,37 +791,37 @@ const std::string& GetUserPath(const unsigned int DirIDX, const std::string &new
break;
case D_USER_IDX:
paths[D_GCUSER_IDX] = paths[D_USER_IDX] + GC_USER_DIR DIR_SEP;
paths[D_WIIROOT_IDX] = paths[D_USER_IDX] + WII_USER_DIR;
paths[D_WIIUSER_IDX] = paths[D_WIIROOT_IDX] + DIR_SEP;
paths[D_CONFIG_IDX] = paths[D_USER_IDX] + CONFIG_DIR DIR_SEP;
paths[D_GAMECONFIG_IDX] = paths[D_USER_IDX] + GAMECONFIG_DIR DIR_SEP;
paths[D_MAPS_IDX] = paths[D_USER_IDX] + MAPS_DIR DIR_SEP;
paths[D_CACHE_IDX] = paths[D_USER_IDX] + CACHE_DIR DIR_SEP;
paths[D_SHADERCACHE_IDX] = paths[D_USER_IDX] + SHADERCACHE_DIR DIR_SEP;
paths[D_SHADERS_IDX] = paths[D_USER_IDX] + SHADERS_DIR DIR_SEP;
paths[D_STATESAVES_IDX] = paths[D_USER_IDX] + STATESAVES_DIR DIR_SEP;
paths[D_SCREENSHOTS_IDX] = paths[D_USER_IDX] + SCREENSHOTS_DIR DIR_SEP;
paths[D_OPENCL_IDX] = paths[D_USER_IDX] + OPENCL_DIR DIR_SEP;
paths[D_HIRESTEXTURES_IDX] = paths[D_USER_IDX] + HIRES_TEXTURES_DIR DIR_SEP;
paths[D_DUMP_IDX] = paths[D_USER_IDX] + DUMP_DIR DIR_SEP;
paths[D_DUMPFRAMES_IDX] = paths[D_DUMP_IDX] + DUMP_FRAMES_DIR DIR_SEP;
paths[D_DUMPAUDIO_IDX] = paths[D_DUMP_IDX] + DUMP_AUDIO_DIR DIR_SEP;
paths[D_DUMPTEXTURES_IDX] = paths[D_DUMP_IDX] + DUMP_TEXTURES_DIR DIR_SEP;
paths[D_DUMPDSP_IDX] = paths[D_DUMP_IDX] + DUMP_DSP_DIR DIR_SEP;
paths[D_LOGS_IDX] = paths[D_USER_IDX] + LOGS_DIR DIR_SEP;
paths[D_MAILLOGS_IDX] = paths[D_LOGS_IDX] + MAIL_LOGS_DIR DIR_SEP;
paths[D_WIISYSCONF_IDX] = paths[D_WIIUSER_IDX] + WII_SYSCONF_DIR DIR_SEP;
paths[D_THEMES_IDX] = paths[D_USER_IDX] + THEMES_DIR DIR_SEP;
paths[F_DOLPHINCONFIG_IDX] = paths[D_CONFIG_IDX] + DOLPHIN_CONFIG;
paths[F_DEBUGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + DEBUGGER_CONFIG;
paths[F_LOGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + LOGGER_CONFIG;
paths[F_MAINLOG_IDX] = paths[D_LOGS_IDX] + MAIN_LOG;
paths[F_WIISYSCONF_IDX] = paths[D_WIISYSCONF_IDX] + WII_SYSCONF;
paths[F_RAMDUMP_IDX] = paths[D_DUMP_IDX] + RAM_DUMP;
paths[F_ARAMDUMP_IDX] = paths[D_DUMP_IDX] + ARAM_DUMP;
paths[F_FAKEVMEMDUMP_IDX] = paths[D_DUMP_IDX] + FAKEVMEM_DUMP;
paths[F_GCSRAM_IDX] = paths[D_GCUSER_IDX] + GC_SRAM;
paths[D_GCUSER_IDX] = paths[D_USER_IDX] + GC_USER_DIR DIR_SEP;
paths[D_WIIROOT_IDX] = paths[D_USER_IDX] + WII_USER_DIR;
paths[D_WIIUSER_IDX] = paths[D_WIIROOT_IDX] + DIR_SEP;
paths[D_CONFIG_IDX] = paths[D_USER_IDX] + CONFIG_DIR DIR_SEP;
paths[D_GAMESETTINGS_IDX] = paths[D_USER_IDX] + GAMESETTINGS_DIR DIR_SEP;
paths[D_MAPS_IDX] = paths[D_USER_IDX] + MAPS_DIR DIR_SEP;
paths[D_CACHE_IDX] = paths[D_USER_IDX] + CACHE_DIR DIR_SEP;
paths[D_SHADERCACHE_IDX] = paths[D_USER_IDX] + SHADERCACHE_DIR DIR_SEP;
paths[D_SHADERS_IDX] = paths[D_USER_IDX] + SHADERS_DIR DIR_SEP;
paths[D_STATESAVES_IDX] = paths[D_USER_IDX] + STATESAVES_DIR DIR_SEP;
paths[D_SCREENSHOTS_IDX] = paths[D_USER_IDX] + SCREENSHOTS_DIR DIR_SEP;
paths[D_OPENCL_IDX] = paths[D_USER_IDX] + OPENCL_DIR DIR_SEP;
paths[D_HIRESTEXTURES_IDX] = paths[D_USER_IDX] + HIRES_TEXTURES_DIR DIR_SEP;
paths[D_DUMP_IDX] = paths[D_USER_IDX] + DUMP_DIR DIR_SEP;
paths[D_DUMPFRAMES_IDX] = paths[D_DUMP_IDX] + DUMP_FRAMES_DIR DIR_SEP;
paths[D_DUMPAUDIO_IDX] = paths[D_DUMP_IDX] + DUMP_AUDIO_DIR DIR_SEP;
paths[D_DUMPTEXTURES_IDX] = paths[D_DUMP_IDX] + DUMP_TEXTURES_DIR DIR_SEP;
paths[D_DUMPDSP_IDX] = paths[D_DUMP_IDX] + DUMP_DSP_DIR DIR_SEP;
paths[D_LOGS_IDX] = paths[D_USER_IDX] + LOGS_DIR DIR_SEP;
paths[D_MAILLOGS_IDX] = paths[D_LOGS_IDX] + MAIL_LOGS_DIR DIR_SEP;
paths[D_WIISYSCONF_IDX] = paths[D_WIIUSER_IDX] + WII_SYSCONF_DIR DIR_SEP;
paths[D_THEMES_IDX] = paths[D_USER_IDX] + THEMES_DIR DIR_SEP;
paths[F_DOLPHINCONFIG_IDX] = paths[D_CONFIG_IDX] + DOLPHIN_CONFIG;
paths[F_DEBUGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + DEBUGGER_CONFIG;
paths[F_LOGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + LOGGER_CONFIG;
paths[F_MAINLOG_IDX] = paths[D_LOGS_IDX] + MAIN_LOG;
paths[F_WIISYSCONF_IDX] = paths[D_WIISYSCONF_IDX] + WII_SYSCONF;
paths[F_RAMDUMP_IDX] = paths[D_DUMP_IDX] + RAM_DUMP;
paths[F_ARAMDUMP_IDX] = paths[D_DUMP_IDX] + ARAM_DUMP;
paths[F_FAKEVMEMDUMP_IDX] = paths[D_DUMP_IDX] + FAKEVMEM_DUMP;
paths[F_GCSRAM_IDX] = paths[D_GCUSER_IDX] + GC_SRAM;
break;
case D_CONFIG_IDX:

View File

@ -21,8 +21,8 @@ enum {
D_GCUSER_IDX,
D_WIIROOT_IDX,
D_WIIUSER_IDX,
D_CONFIG_IDX,
D_GAMECONFIG_IDX,
D_CONFIG_IDX, // global settings
D_GAMESETTINGS_IDX, // user-specified settings which override both the global and the default settings (per game)
D_MAPS_IDX,
D_CACHE_IDX,
D_SHADERCACHE_IDX,

View File

@ -111,115 +111,121 @@ bool CompareValues(const u32 val1, const u32 val2, const int type);
// ----------------------
// AR Remote Functions
void LoadCodes(IniFile &ini, bool forceLoad)
void LoadCodes(IniFile &globalIni, IniFile &localIni, bool forceLoad)
{
// Parses the Action Replay section of a game ini file.
if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bEnableCheats
&& !forceLoad)
return;
std::vector<std::string> lines;
std::vector<std::string> encryptedLines;
ARCode currentCode;
arCodes.clear();
if (!ini.GetLines("ActionReplay", lines))
return; // no codes found.
std::vector<std::string>::const_iterator
it = lines.begin(),
lines_end = lines.end();
for (; it != lines_end; ++it)
std::vector<std::string> enabledLines;
std::set<std::string> enabledNames;
localIni.GetLines("ActionReplay_Enabled", enabledLines);
for (auto iter = enabledLines.begin(); iter != enabledLines.end(); ++iter)
{
const std::string line = *it;
if (line.empty())
continue;
std::vector<std::string> pieces;
// Check if the line is a name of the code
if (line[0] == '+' || line[0] == '$')
const std::string& line = *iter;
if (line.size() != 0 && line[0] == '$')
{
if (currentCode.ops.size())
{
arCodes.push_back(currentCode);
currentCode.ops.clear();
}
if (encryptedLines.size())
{
DecryptARCode(encryptedLines, currentCode.ops);
arCodes.push_back(currentCode);
currentCode.ops.clear();
encryptedLines.clear();
}
if (line.size() > 1)
{
if (line[0] == '+')
{
currentCode.active = true;
currentCode.name = line.substr(2, line.size() - 2);;
if (!forceLoad)
Core::DisplayMessage("AR code active: " + currentCode.name, 5000);
}
else
{
currentCode.active = false;
currentCode.name = line.substr(1, line.size() - 1);
}
}
continue;
std::string name = line.substr(1, line.size() - 1);
enabledNames.insert(name);
}
}
SplitString(line, ' ', pieces);
IniFile* inis[] = {&globalIni, &localIni};
for (size_t i = 0; i < ArraySize(inis); ++i)
{
std::vector<std::string> lines;
std::vector<std::string> encryptedLines;
ARCode currentCode;
inis[i]->GetLines("ActionReplay", lines);
// Check if the AR code is decrypted
if (pieces.size() == 2 && pieces[0].size() == 8 && pieces[1].size() == 8)
std::vector<std::string>::const_iterator
it = lines.begin(),
lines_end = lines.end();
for (; it != lines_end; ++it)
{
AREntry op;
bool success_addr = TryParse(std::string("0x") + pieces[0], &op.cmd_addr);
bool success_val = TryParse(std::string("0x") + pieces[1], &op.value);
if (!(success_addr | success_val)) {
PanicAlertT("Action Replay Error: invalid AR code line: %s", line.c_str());
if (!success_addr) PanicAlertT("The address is invalid");
if (!success_val) PanicAlertT("The value is invalid");
const std::string line = *it;
if (line.empty())
continue;
std::vector<std::string> pieces;
// Check if the line is a name of the code
if (line[0] == '$')
{
if (currentCode.ops.size())
{
arCodes.push_back(currentCode);
currentCode.ops.clear();
}
if (encryptedLines.size())
{
DecryptARCode(encryptedLines, currentCode.ops);
arCodes.push_back(currentCode);
currentCode.ops.clear();
encryptedLines.clear();
}
currentCode.name = line.substr(1, line.size() - 1);
currentCode.active = enabledNames.find(currentCode.name) != enabledNames.end();
currentCode.user_defined = (i == 1);
}
else
{
currentCode.ops.push_back(op);
}
}
else
{
SplitString(line, '-', pieces);
if (pieces.size() == 3 && pieces[0].size() == 4 && pieces[1].size() == 4 && pieces[2].size() == 5)
{
// Encrypted AR code
// Decryption is done in "blocks", so we must push blocks into a vector,
// then send to decrypt when a new block is encountered, or if it's the last block.
encryptedLines.push_back(pieces[0]+pieces[1]+pieces[2]);
}
}
}
SplitString(line, ' ', pieces);
// Handle the last code correctly.
if (currentCode.ops.size())
{
arCodes.push_back(currentCode);
}
if (encryptedLines.size())
{
DecryptARCode(encryptedLines, currentCode.ops);
arCodes.push_back(currentCode);
// Check if the AR code is decrypted
if (pieces.size() == 2 && pieces[0].size() == 8 && pieces[1].size() == 8)
{
AREntry op;
bool success_addr = TryParse(std::string("0x") + pieces[0], &op.cmd_addr);
bool success_val = TryParse(std::string("0x") + pieces[1], &op.value);
if (!(success_addr | success_val)) {
PanicAlertT("Action Replay Error: invalid AR code line: %s", line.c_str());
if (!success_addr) PanicAlertT("The address is invalid");
if (!success_val) PanicAlertT("The value is invalid");
}
else
{
currentCode.ops.push_back(op);
}
}
else
{
SplitString(line, '-', pieces);
if (pieces.size() == 3 && pieces[0].size() == 4 && pieces[1].size() == 4 && pieces[2].size() == 5)
{
// Encrypted AR code
// Decryption is done in "blocks", so we must push blocks into a vector,
// then send to decrypt when a new block is encountered, or if it's the last block.
encryptedLines.push_back(pieces[0]+pieces[1]+pieces[2]);
}
}
}
}
// Handle the last code correctly.
if (currentCode.ops.size())
{
arCodes.push_back(currentCode);
}
if (encryptedLines.size())
{
DecryptARCode(encryptedLines, currentCode.ops);
arCodes.push_back(currentCode);
}
}
UpdateActiveList();
}
void LoadCodes(std::vector<ARCode> &_arCodes, IniFile &ini)
void LoadCodes(std::vector<ARCode> &_arCodes, IniFile &globalIni, IniFile& localIni)
{
LoadCodes(ini, true);
LoadCodes(globalIni, localIni, true);
_arCodes = arCodes;
}

View File

@ -23,12 +23,13 @@ struct ARCode
std::string name;
std::vector<AREntry> ops;
bool active;
bool user_defined;
};
void RunAllActive();
bool RunCode(const ARCode &arcode);
void LoadCodes(IniFile &ini, bool forceLoad);
void LoadCodes(std::vector<ARCode> &_arCodes, IniFile &ini);
void LoadCodes(IniFile &globalIni, IniFile &localIni, bool forceLoad);
void LoadCodes(std::vector<ARCode> &_arCodes, IniFile &globalIni, IniFile &localIni);
size_t GetCodeListSize();
ARCode GetARCode(size_t index);
void SetARCode_IsActive(bool active, size_t index);

View File

@ -24,6 +24,7 @@
#include <vector>
#include "Common.h"
#include "CommonPaths.h"
#include "IniFile.h"
#include "BootManager.h"
#include "Volume.h"
@ -73,11 +74,16 @@ bool BootCore(const std::string& _rFilename)
return false;
// Load game specific settings
IniFile game_ini;
std::string unique_id = StartUp.GetUniqueID();
StartUp.m_strGameIni = File::GetUserPath(D_GAMECONFIG_IDX) + unique_id + ".ini";
if (unique_id.size() == 6 && game_ini.Load(StartUp.m_strGameIni.c_str()))
StartUp.m_strGameIniDefault = File::GetSysDirectory() + GAMESETTINGS_DIR DIR_SEP + unique_id + ".ini";
StartUp.m_strGameIniLocal = File::GetUserPath(D_GAMESETTINGS_IDX) + unique_id + ".ini";
if (unique_id.size() == 6)
{
IniFile game_ini;
game_ini.Load(StartUp.m_strGameIniDefault);
game_ini.Load(StartUp.m_strGameIniLocal, true);
config_cache.valid = true;
config_cache.bCPUThread = StartUp.bCPUThread;
config_cache.bSkipIdle = StartUp.bSkipIdle;

View File

@ -205,7 +205,8 @@ bool Init()
if (g_aspect_wide)
{
IniFile gameIni;
gameIni.Load(_CoreParameter.m_strGameIni.c_str());
gameIni.Load(_CoreParameter.m_strGameIniDefault.c_str());
gameIni.Load(_CoreParameter.m_strGameIniLocal.c_str(), true);
gameIni.Get("Wii", "Widescreen", &g_aspect_wide,
!!SConfig::GetInstance().m_SYSCONF->
GetData<u8>("IPL.AR"));

View File

@ -198,7 +198,8 @@ struct SCoreStartupParameter
std::string m_strApploader;
std::string m_strUniqueID;
std::string m_strName;
std::string m_strGameIni;
std::string m_strGameIniDefault;
std::string m_strGameIniLocal;
// Constructor just calls LoadDefaults
SCoreStartupParameter();

View File

@ -15,6 +15,7 @@
namespace Gecko
{
// TODO: Support loading codes from default game inis.
void LoadCodes(const IniFile& inifile, std::vector<GeckoCode>& gcodes)
{
std::vector<std::string> lines;
@ -96,7 +97,7 @@ void SaveGeckoCode(std::vector<std::string>& lines, const GeckoCode& gcode)
}
lines.push_back(name);
// save all the code lines
std::vector<GeckoCode::Code>::const_iterator
codes_iter = gcode.codes.begin(),

View File

@ -20,6 +20,7 @@
#include <map>
#include <algorithm>
#include "CommonPaths.h"
#include "StringUtil.h"
#include "PatchEngine.h"
#include "HW/Memmap.h"
@ -44,22 +45,40 @@ std::vector<Patch> onFrame;
std::map<u32, int> speedHacks;
std::vector<std::string> discList;
void LoadPatchSection(const char *section, std::vector<Patch> &patches, IniFile &ini)
void LoadPatchSection(const char *section, std::vector<Patch> &patches,
IniFile &globalIni, IniFile &localIni)
{
std::vector<std::string> lines;
if (!ini.GetLines(section, lines))
return;
Patch currentPatch;
for (std::vector<std::string>::const_iterator iter = lines.begin(); iter != lines.end(); ++iter)
// Load the name of all enabled patches
std::string enabledSectionName = std::string(section) + "_Enabled";
std::vector<std::string> enabledLines;
std::set<std::string> enabledNames;
localIni.GetLines(enabledSectionName.c_str(), enabledLines);
for (auto iter = enabledLines.begin(); iter != enabledLines.end(); ++iter)
{
std::string line = *iter;
if (line.size())
const std::string& line = *iter;
if (line.size() != 0 && line[0] == '$')
{
if (line[0] == '+' || line[0] == '$')
std::string name = line.substr(1, line.size() - 1);
enabledNames.insert(name);
}
}
IniFile* inis[] = {&globalIni, &localIni};
for (size_t i = 0; i < ArraySize(inis); ++i)
{
std::vector<std::string> lines;
Patch currentPatch;
inis[i]->GetLines(section, lines);
for (auto iter = lines.begin(); iter != lines.end(); ++iter)
{
std::string line = *iter;
if (line.size() == 0)
continue;
if (line[0] == '$')
{
// Take care of the previous code
if (currentPatch.name.size())
@ -67,39 +86,38 @@ void LoadPatchSection(const char *section, std::vector<Patch> &patches, IniFile
currentPatch.entries.clear();
// Set active and name
currentPatch.active = (line[0] == '+') ? true : false;
if (currentPatch.active)
currentPatch.name = line.substr(2, line.size() - 2);
else
currentPatch.name = line.substr(1, line.size() - 1);
continue;
currentPatch.name = line.substr(1, line.size() - 1);
currentPatch.active = enabledNames.find(currentPatch.name) != enabledNames.end();
currentPatch.user_defined = (i == 1);
}
std::string::size_type loc = line.find_first_of('=', 0);
if (loc != std::string::npos)
line[loc] = ':';
std::vector<std::string> items;
SplitString(line, ':', items);
if (items.size() >= 3)
else
{
PatchEntry pE;
bool success = true;
success &= TryParse(items[0], &pE.address);
success &= TryParse(items[2], &pE.value);
std::string::size_type loc = line.find_first_of('=', 0);
pE.type = PatchType(std::find(PatchTypeStrings, PatchTypeStrings + 3, items[1]) - PatchTypeStrings);
success &= (pE.type != (PatchType)3);
if (success)
currentPatch.entries.push_back(pE);
if (loc != std::string::npos)
line[loc] = ':';
std::vector<std::string> items;
SplitString(line, ':', items);
if (items.size() >= 3)
{
PatchEntry pE;
bool success = true;
success &= TryParse(items[0], &pE.address);
success &= TryParse(items[2], &pE.value);
pE.type = PatchType(std::find(PatchTypeStrings, PatchTypeStrings + 3, items[1]) - PatchTypeStrings);
success &= (pE.type != (PatchType)3);
if (success)
currentPatch.entries.push_back(pE);
}
}
}
}
if (currentPatch.name.size() && currentPatch.entries.size())
patches.push_back(currentPatch);
if (currentPatch.name.size() && currentPatch.entries.size())
patches.push_back(currentPatch);
}
}
static void LoadDiscList(const char *section, std::vector<std::string> &_discList, IniFile &ini)
@ -150,22 +168,24 @@ int GetSpeedhackCycles(const u32 addr)
void LoadPatches(const char *gameID)
{
IniFile ini;
std::string filename = File::GetUserPath(D_GAMECONFIG_IDX) + gameID + ".ini";
IniFile globalIni, localIni;
globalIni.Load(File::GetSysDirectory() + GAMESETTINGS_DIR DIR_SEP + gameID + ".ini");
localIni.Load(File::GetUserPath(D_GAMESETTINGS_IDX) + gameID + ".ini", true);
if (ini.Load(filename.c_str()))
{
LoadPatchSection("OnFrame", onFrame, ini);
ActionReplay::LoadCodes(ini, false);
// lil silly
std::vector<Gecko::GeckoCode> gcodes;
Gecko::LoadCodes(ini, gcodes);
Gecko::SetActiveCodes(gcodes);
IniFile merged;
merged.Load(File::GetSysDirectory() + GAMESETTINGS_DIR DIR_SEP + gameID + ".ini");
merged.Load(File::GetUserPath(D_GAMESETTINGS_IDX) + gameID + ".ini", true);
LoadSpeedhacks("Speedhacks", speedHacks, ini);
LoadDiscList("DiscList", discList, ini);
}
LoadPatchSection("OnFrame", onFrame, globalIni, localIni);
ActionReplay::LoadCodes(globalIni, localIni, false);
// lil silly
std::vector<Gecko::GeckoCode> gcodes;
Gecko::LoadCodes(localIni, gcodes);
Gecko::SetActiveCodes(gcodes);
LoadSpeedhacks("Speedhacks", speedHacks, merged);
LoadDiscList("DiscList", discList, merged);
}
void ApplyPatches(const std::vector<Patch> &patches)

View File

@ -33,10 +33,12 @@ struct Patch
std::string name;
std::vector<PatchEntry> entries;
bool active;
bool user_defined; // False if this code is shipped with Dolphin.
};
int GetSpeedhackCycles(const u32 addr);
void LoadPatchSection(const char *section, std::vector<Patch> &patches, IniFile &ini);
void LoadPatchSection(const char *section, std::vector<Patch> &patches,
IniFile &globalIni, IniFile &localIni);
void LoadPatches(const char *gameID);
void ApplyFramePatches();
void ApplyARPatches();

View File

@ -5,6 +5,7 @@
#include "Globals.h"
#include "CheatsWindow.h"
#include "ActionReplay.h"
#include "CommonPaths.h"
#include "Core.h"
#include "ConfigManager.h"
#include "VolumeHandler.h"
@ -243,8 +244,10 @@ void wxCheatsWindow::OnEvent_Close(wxCloseEvent& ev)
void wxCheatsWindow::UpdateGUI()
{
// load code
m_gameini_path = File::GetUserPath(D_GAMECONFIG_IDX) + Core::g_CoreStartupParameter.GetUniqueID() + ".ini";
m_gameini.Load(m_gameini_path);
m_gameini_default_path = File::GetSysDirectory() + GAMESETTINGS_DIR DIR_SEP + Core::g_CoreStartupParameter.GetUniqueID() + ".ini";
m_gameini_default.Load(m_gameini_default_path);
m_gameini_local_path = File::GetUserPath(D_GAMESETTINGS_IDX) + Core::g_CoreStartupParameter.GetUniqueID() + ".ini";
m_gameini_local.Load(m_gameini_local_path, true);
Load_ARCodes();
Load_GeckoCodes();
@ -283,7 +286,7 @@ void wxCheatsWindow::Load_ARCodes()
void wxCheatsWindow::Load_GeckoCodes()
{
m_geckocode_panel->LoadCodes(m_gameini, Core::g_CoreStartupParameter.GetUniqueID(), true);
m_geckocode_panel->LoadCodes(m_gameini_local, Core::g_CoreStartupParameter.GetUniqueID(), true);
}
void wxCheatsWindow::OnEvent_CheatsList_ItemSelected(wxCommandEvent& WXUNUSED (event))
@ -338,10 +341,10 @@ void wxCheatsWindow::OnEvent_ApplyChanges_Press(wxCommandEvent& ev)
Gecko::SetActiveCodes(m_geckocode_panel->GetCodes());
// Save gameini, with changed gecko codes
if (m_gameini_path.size())
if (m_gameini_local_path.size())
{
Gecko::SaveCodes(m_gameini, m_geckocode_panel->GetCodes());
m_gameini.Save(m_gameini_path);
Gecko::SaveCodes(m_gameini_local, m_geckocode_panel->GetCodes());
m_gameini_local.Save(m_gameini_local_path);
}
ev.Skip();

View File

@ -130,8 +130,10 @@ class wxCheatsWindow : public wxDialog
std::vector<ARCodeIndex> indexList;
Gecko::CodeConfigPanel *m_geckocode_panel;
IniFile m_gameini;
std::string m_gameini_path;
IniFile m_gameini_default;
IniFile m_gameini_local;
std::string m_gameini_default_path;
std::string m_gameini_local_path;
void Init_ChildControls();

View File

@ -115,7 +115,8 @@ GameListItem::GameListItem(const std::string& _rFileName)
if (IsValid())
{
IniFile ini;
ini.Load(File::GetUserPath(D_GAMECONFIG_IDX) + m_UniqueID + ".ini");
ini.Load(File::GetSysDirectory() + GAMESETTINGS_DIR DIR_SEP + m_UniqueID + ".ini");
ini.Load(File::GetUserPath(D_GAMESETTINGS_IDX) + m_UniqueID + ".ini", true);
ini.Get("EmuState", "EmulationStateId", &m_emu_state);
ini.Get("EmuState", "EmulationIssues", &m_issues);
}

View File

@ -6,6 +6,8 @@
#import <Cocoa/Cocoa.h>
#endif
#include <type_traits>
#include "Common.h"
#include "CommonPaths.h"
#include "Globals.h"
@ -45,6 +47,7 @@ BEGIN_EVENT_TABLE(CISOProperties, wxDialog)
EVT_CLOSE(CISOProperties::OnClose)
EVT_BUTTON(wxID_OK, CISOProperties::OnCloseClick)
EVT_BUTTON(ID_EDITCONFIG, CISOProperties::OnEditConfig)
EVT_BUTTON(ID_SHOWDEFAULTCONFIG, CISOProperties::OnShowDefaultConfig)
EVT_CHOICE(ID_EMUSTATE, CISOProperties::SetRefresh)
EVT_CHOICE(ID_EMU_ISSUES, CISOProperties::SetRefresh)
EVT_BUTTON(ID_PHSETTINGS, CISOProperties::PHackButtonClicked)
@ -70,6 +73,7 @@ END_EVENT_TABLE()
CISOProperties::CISOProperties(const std::string fileName, wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& position, const wxSize& size, long style)
: wxDialog(parent, id, title, position, size, style)
{
// Load ISO data
OpenISO = DiscIO::CreateVolumeFromFilename(fileName);
if (DiscIO::IsVolumeWiiDisc(OpenISO))
{
@ -102,12 +106,7 @@ CISOProperties::CISOProperties(const std::string fileName, wxWindow* parent, wxW
}
}
OpenGameListItem = new GameListItem(fileName);
bRefreshList = false;
CreateGUIControls(DiscIO::IsVolumeWadFile(OpenISO));
// Load game ini
std::string _iniFilename = OpenISO->GetUniqueID();
if (!_iniFilename.length())
@ -121,34 +120,21 @@ CISOProperties::CISOProperties(const std::string fileName, wxWindow* parent, wxW
}
}
GameIniFile = File::GetUserPath(D_GAMECONFIG_IDX) + _iniFilename + ".ini";
GameIniFileDefault = File::GetSysDirectory() + GAMESETTINGS_DIR DIR_SEP + _iniFilename + ".ini";
GameIniFileLocal = File::GetUserPath(D_GAMESETTINGS_IDX) + _iniFilename + ".ini";
if (GameIni.Load(GameIniFile.c_str()))
{
LoadGameConfig();
}
else
{
// Will fail out if GameConfig folder doesn't exist
std::ofstream f;
OpenFStream(f, GameIniFile, std::ios_base::out);
if (f)
{
f << "# " << OpenISO->GetUniqueID() << " - " << OpenISO->GetName() << '\n'
<< "[Core] Values set here will override the main dolphin settings.\n"
<< "[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.\n"
<< "[OnFrame] Add memory patches to be applied every frame here.\n"
<< "[ActionReplay] Add action replay cheats here.\n";
f.close();
}
printf("Loading\n");
GameIniDefault.Load(GameIniFileDefault);
GameIniLocal.Load(GameIniFileLocal);
if (GameIni.Load(GameIniFile.c_str()))
LoadGameConfig();
else
wxMessageBox(wxString::Format(_("Could not create %s"),
StrToWxStr(GameIniFile).c_str()),
_("Error"), wxOK|wxICON_ERROR, this);
}
// Setup GUI
OpenGameListItem = new GameListItem(fileName);
bRefreshList = false;
CreateGUIControls(DiscIO::IsVolumeWadFile(OpenISO));
LoadGameConfig();
// Disk header and apploader
@ -280,6 +266,15 @@ size_t CISOProperties::CreateDirectoryTree(wxTreeItemId& parent,
return CurrentIndex;
}
long CISOProperties::GetElementStyle(const char* section, const char* key)
{
// Disable 3rd state if default gameini overrides the setting
if (GameIniDefault.Exists(section, key))
return 0;
return wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER;
}
void CISOProperties::CreateGUIControls(bool IsWad)
{
wxButton * const EditConfig =
@ -287,13 +282,9 @@ void CISOProperties::CreateGUIControls(bool IsWad)
EditConfig->SetToolTip(_("This will let you Manually Edit the INI config file"));
wxButton * const EditConfigDefault =
new wxButton(this, ID_EDITCONFIG, _("Show Defaults"), wxDefaultPosition, wxDefaultSize);
new wxButton(this, ID_SHOWDEFAULTCONFIG, _("Show Defaults"), wxDefaultPosition, wxDefaultSize);
EditConfigDefault->SetToolTip(_("Opens the default (read-only) configuration for this game in an external text editor."));
wxButton * const EditConfigLocal =
new wxButton(this, ID_EDITCONFIG, _("Edit Local Overrides"), wxDefaultPosition, wxDefaultSize);
EditConfigLocal->SetToolTip(_("Opens the user specified overrides in an external text editor."));
// Notebook
wxNotebook * const m_Notebook =
new wxNotebook(this, ID_NOTEBOOK, wxDefaultPosition, wxDefaultSize);
@ -314,32 +305,33 @@ void CISOProperties::CreateGUIControls(bool IsWad)
// GameConfig editing - Overrides and emulation state
wxStaticText * const OverrideText = new wxStaticText(m_GameConfig, wxID_ANY, _("These settings override core Dolphin settings.\nUndetermined means the game uses Dolphin's setting."));
// Core
CPUThread = new wxCheckBox(m_GameConfig, ID_USEDUALCORE, _("Enable Dual Core"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
SkipIdle = new wxCheckBox(m_GameConfig, ID_IDLESKIP, _("Enable Idle Skipping"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
MMU = new wxCheckBox(m_GameConfig, ID_MMU, _("Enable MMU"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
CPUThread = new wxCheckBox(m_GameConfig, ID_USEDUALCORE, _("Enable Dual Core"), wxDefaultPosition, wxDefaultSize, GetElementStyle("Core", "CPUThread"), wxDefaultValidator);
SkipIdle = new wxCheckBox(m_GameConfig, ID_IDLESKIP, _("Enable Idle Skipping"), wxDefaultPosition, wxDefaultSize, GetElementStyle("Core", "SkipIdle"), wxDefaultValidator);
MMU = new wxCheckBox(m_GameConfig, ID_MMU, _("Enable MMU"), wxDefaultPosition, wxDefaultSize, GetElementStyle("Core", "MMU"), wxDefaultValidator);
MMU->SetToolTip(_("Enables the Memory Management Unit, needed for some games. (ON = Compatible, OFF = Fast)"));
TLBHack = new wxCheckBox(m_GameConfig, ID_TLBHACK, _("MMU Speed Hack"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
TLBHack = new wxCheckBox(m_GameConfig, ID_TLBHACK, _("MMU Speed Hack"), wxDefaultPosition, wxDefaultSize, GetElementStyle("Core", "TLBHack"), wxDefaultValidator);
TLBHack->SetToolTip(_("Fast version of the MMU. Does not work for every game."));
DCBZOFF = new wxCheckBox(m_GameConfig, ID_DCBZOFF, _("Skip DCBZ clearing"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
DCBZOFF = new wxCheckBox(m_GameConfig, ID_DCBZOFF, _("Skip DCBZ clearing"), wxDefaultPosition, wxDefaultSize, GetElementStyle("Core", "DCBZ"), wxDefaultValidator);
DCBZOFF->SetToolTip(_("Bypass the clearing of the data cache by the DCBZ instruction. Usually leave this option disabled."));
VBeam = new wxCheckBox(m_GameConfig, ID_VBEAM, _("VBeam Speed Hack"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
VBeam = new wxCheckBox(m_GameConfig, ID_VBEAM, _("VBeam Speed Hack"), wxDefaultPosition, wxDefaultSize, GetElementStyle("Core", "VBeam"), wxDefaultValidator);
VBeam->SetToolTip(_("Doubles the emulated GPU clock rate. May speed up some games (ON = Fast, OFF = Compatible)"));
SyncGPU = new wxCheckBox(m_GameConfig, ID_SYNCGPU, _("Synchronize GPU thread"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
SyncGPU = new wxCheckBox(m_GameConfig, ID_SYNCGPU, _("Synchronize GPU thread"), wxDefaultPosition, wxDefaultSize, GetElementStyle("Core", "SyncGPU"), wxDefaultValidator);
SyncGPU->SetToolTip(_("Synchronizes the GPU and CPU threads to help prevent random freezes in Dual Core mode. (ON = Compatible, OFF = Fast)"));
FastDiscSpeed = new wxCheckBox(m_GameConfig, ID_DISCSPEED, _("Speed up Disc Transfer Rate"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
FastDiscSpeed = new wxCheckBox(m_GameConfig, ID_DISCSPEED, _("Speed up Disc Transfer Rate"), wxDefaultPosition, wxDefaultSize, GetElementStyle("Core", "FastDiscSpeed"), wxDefaultValidator);
FastDiscSpeed->SetToolTip(_("Enable fast disc access. Needed for a few games. (ON = Fast, OFF = Compatible)"));
BlockMerging = new wxCheckBox(m_GameConfig, ID_MERGEBLOCKS, _("Enable Block Merging"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
DSPHLE = new wxCheckBox(m_GameConfig, ID_AUDIO_DSP_HLE, _("DSP HLE emulation (fast)"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
BlockMerging = new wxCheckBox(m_GameConfig, ID_MERGEBLOCKS, _("Enable Block Merging"), wxDefaultPosition, wxDefaultSize, GetElementStyle("Core", "BlockMerging"), wxDefaultValidator);
DSPHLE = new wxCheckBox(m_GameConfig, ID_AUDIO_DSP_HLE, _("DSP HLE emulation (fast)"), wxDefaultPosition, wxDefaultSize, GetElementStyle("Core", "DSPHLE"), wxDefaultValidator);
// Wii Console
EnableWideScreen = new wxCheckBox(m_GameConfig, ID_ENABLEWIDESCREEN, _("Enable WideScreen"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
EnableWideScreen = new wxCheckBox(m_GameConfig, ID_ENABLEWIDESCREEN, _("Enable WideScreen"), wxDefaultPosition, wxDefaultSize, GetElementStyle("Wii", "Widescreen"), wxDefaultValidator);
// Video
UseBBox = new wxCheckBox(m_GameConfig, ID_USE_BBOX, _("Enable Bounding Box Calculation"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER);
UseBBox = new wxCheckBox(m_GameConfig, ID_USE_BBOX, _("Enable Bounding Box Calculation"), wxDefaultPosition, wxDefaultSize, GetElementStyle("Video", "UseBBox"));
UseBBox->SetToolTip(_("If checked, the bounding box registers will be updated. Used by the Paper Mario games."));
UseZTPSpeedupHack = new wxCheckBox(m_GameConfig, ID_ZTP_SPEEDUP, _("ZTP hack"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER);
UseZTPSpeedupHack = new wxCheckBox(m_GameConfig, ID_ZTP_SPEEDUP, _("ZTP hack"), wxDefaultPosition, wxDefaultSize, GetElementStyle("Video", "ZTPSpeedupHack"));
UseZTPSpeedupHack->SetToolTip(_("Enable this to speed up The Legend of Zelda: Twilight Princess. Disable for ANY other game."));
// Hack
@ -567,10 +559,13 @@ void CISOProperties::CreateGUIControls(bool IsWad)
wxSizer* sButtons = CreateButtonSizer(wxNO_DEFAULT);
sButtons->Prepend(EditConfigDefault);
sButtons->Prepend(EditConfigLocal);
sButtons->Prepend(EditConfig);
sButtons->Add(new wxButton(this, wxID_OK, _("Close")));
// If there is no default gameini, disable the button.
if (!File::Exists(GameIniFileDefault))
EditConfigDefault->Disable();
// Add notebook and buttons to the dialog
wxBoxSizer* sMain;
sMain = new wxBoxSizer(wxVERTICAL);
@ -586,7 +581,7 @@ void CISOProperties::CreateGUIControls(bool IsWad)
void CISOProperties::OnClose(wxCloseEvent& WXUNUSED (event))
{
if (!SaveGameConfig())
PanicAlertT("Could not save %s", GameIniFile.c_str());
PanicAlertT("Could not save %s", GameIniFileLocal.c_str());
EndModal(bRefreshList ? wxID_OK : wxID_CANCEL);
}
@ -945,234 +940,193 @@ void CISOProperties::SetRefresh(wxCommandEvent& event)
EmuIssues->Enable(event.GetSelection() != 0);
}
void CISOProperties::SetCheckboxValueFromGameini(const char* section, const char* key, wxCheckBox* checkbox)
{
// Prefer local gameini value over default gameini value.
bool value;
if (GameIniLocal.Get(section, key, &value))
checkbox->Set3StateValue((wxCheckBoxState)value);
else if (GameIniDefault.Get(section, key, &value))
checkbox->Set3StateValue((wxCheckBoxState)value);
else
checkbox->Set3StateValue(wxCHK_UNDETERMINED);
}
void CISOProperties::LoadGameConfig()
{
SetCheckboxValueFromGameini("Core", "CPUThread", CPUThread);
SetCheckboxValueFromGameini("Core", "SkipIdle", SkipIdle);
SetCheckboxValueFromGameini("Core", "MMU", MMU);
SetCheckboxValueFromGameini("Core", "TLBHack", TLBHack);
SetCheckboxValueFromGameini("Core", "DCBZ", DCBZOFF);
SetCheckboxValueFromGameini("Core", "VBeam", VBeam);
SetCheckboxValueFromGameini("Core", "SyncGPU", SyncGPU);
SetCheckboxValueFromGameini("Core", "FastDiscSpeed", FastDiscSpeed);
SetCheckboxValueFromGameini("Core", "BlockMerging", BlockMerging);
SetCheckboxValueFromGameini("Core", "DSPHLE", DSPHLE);
SetCheckboxValueFromGameini("Wii", "Widescreen", EnableWideScreen);
SetCheckboxValueFromGameini("Video", "UseBBox", UseBBox);
SetCheckboxValueFromGameini("Video", "ZTPSpeedupHack", UseZTPSpeedupHack);
// First set values from default gameini, then apply values from local gameini
bool bTemp;
GameIniDefault.Get("Video", "ProjectionHack", &bTemp);
PHackEnable->SetValue(bTemp);
if (GameIniLocal.Get("Video", "ProjectionHack", &bTemp))
PHackEnable->SetValue(bTemp);
GameIniDefault.Get("Video", "PH_SZNear", &PHack_Data.PHackSZNear);
GameIniLocal.Get("Video", "PH_SZNear", &PHack_Data.PHackSZNear);
GameIniDefault.Get("Video", "PH_SZFar", &PHack_Data.PHackSZFar);
GameIniLocal.Get("Video", "PH_SZFar", &PHack_Data.PHackSZFar);
GameIniDefault.Get("Video", "PH_ExtraParam", &PHack_Data.PHackExP);
GameIniLocal.Get("Video", "PH_ExtraParam", &PHack_Data.PHackExP);
GameIniDefault.Get("Video", "PH_ZNear", &PHack_Data.PHZNear);
GameIniLocal.Get("Video", "PH_ZNear", &PHack_Data.PHZNear);
GameIniDefault.Get("Video", "PH_ZFar", &PHack_Data.PHZFar);
GameIniLocal.Get("Video", "PH_ZFar", &PHack_Data.PHZFar);
int iTemp;
std::string sTemp;
if (GameIni.Get("Core", "CPUThread", &bTemp))
CPUThread->Set3StateValue((wxCheckBoxState)bTemp);
else
CPUThread->Set3StateValue(wxCHK_UNDETERMINED);
if (GameIni.Get("Core", "SkipIdle", &bTemp))
SkipIdle->Set3StateValue((wxCheckBoxState)bTemp);
else
SkipIdle->Set3StateValue(wxCHK_UNDETERMINED);
if (GameIni.Get("Core", "MMU", &bTemp))
MMU->Set3StateValue((wxCheckBoxState)bTemp);
else
MMU->Set3StateValue(wxCHK_UNDETERMINED);
if (GameIni.Get("Core", "TLBHack", &bTemp))
TLBHack->Set3StateValue((wxCheckBoxState)bTemp);
else
TLBHack->Set3StateValue(wxCHK_UNDETERMINED);
if (GameIni.Get("Core", "DCBZ", &bTemp))
DCBZOFF->Set3StateValue((wxCheckBoxState)bTemp);
else
DCBZOFF->Set3StateValue(wxCHK_UNDETERMINED);
if (GameIni.Get("Core", "VBeam", &bTemp))
VBeam->Set3StateValue((wxCheckBoxState)bTemp);
else
VBeam->Set3StateValue(wxCHK_UNDETERMINED);
if (GameIni.Get("Core", "SyncGPU", &bTemp))
SyncGPU->Set3StateValue((wxCheckBoxState)bTemp);
else
SyncGPU->Set3StateValue(wxCHK_UNDETERMINED);
if (GameIni.Get("Core", "FastDiscSpeed", &bTemp))
FastDiscSpeed->Set3StateValue((wxCheckBoxState)bTemp);
else
FastDiscSpeed->Set3StateValue(wxCHK_UNDETERMINED);
if (GameIni.Get("Core", "BlockMerging", &bTemp))
BlockMerging->Set3StateValue((wxCheckBoxState)bTemp);
else
BlockMerging->Set3StateValue(wxCHK_UNDETERMINED);
if (GameIni.Get("Core", "DSPHLE", &bTemp))
DSPHLE->Set3StateValue((wxCheckBoxState)bTemp);
else
DSPHLE->Set3StateValue(wxCHK_UNDETERMINED);
// ??
if (GameIni.Get("Wii", "Widescreen", &bTemp))
EnableWideScreen->Set3StateValue((wxCheckBoxState)bTemp);
else
EnableWideScreen->Set3StateValue(wxCHK_UNDETERMINED);
if (GameIni.Get("Video", "UseBBox", &bTemp))
UseBBox->Set3StateValue((wxCheckBoxState)bTemp);
else
UseBBox->Set3StateValue(wxCHK_UNDETERMINED);
if (GameIni.Get("Video", "ZTPSpeedupHack", &bTemp))
UseZTPSpeedupHack->Set3StateValue((wxCheckBoxState)bTemp);
else
UseZTPSpeedupHack->Set3StateValue(wxCHK_UNDETERMINED);
GameIni.Get("Video", "ProjectionHack", &bTemp);
PHackEnable->Set3StateValue((wxCheckBoxState)bTemp);
GameIni.Get("Video", "PH_SZNear", &PHack_Data.PHackSZNear);
GameIni.Get("Video", "PH_SZFar", &PHack_Data.PHackSZFar);
GameIni.Get("Video", "PH_ExtraParam", &PHack_Data.PHackExP);
GameIni.Get("Video", "PH_ZNear", &PHack_Data.PHZNear);
GameIni.Get("Video", "PH_ZFar", &PHack_Data.PHZFar);
GameIni.Get("EmuState", "EmulationStateId", &iTemp, 0/*Not Set*/);
GameIniDefault.Get("EmuState", "EmulationStateId", &iTemp, 0/*Not Set*/);
EmuState->SetSelection(iTemp);
if (GameIniLocal.Get("EmuState", "EmulationStateId", &iTemp, 0/*Not Set*/))
EmuState->SetSelection(iTemp);
GameIni.Get("EmuState", "EmulationIssues", &sTemp);
std::string sTemp;
GameIniDefault.Get("EmuState", "EmulationIssues", &sTemp);
if (!sTemp.empty())
{
EmuIssues->SetValue(StrToWxStr(sTemp));
}
if (GameIniLocal.Get("EmuState", "EmulationIssues", &sTemp))
EmuIssues->SetValue(StrToWxStr(sTemp));
EmuIssues->Enable(EmuState->GetSelection() != 0);
PatchList_Load();
ActionReplayList_Load();
m_geckocode_panel->LoadCodes(GameIni, OpenISO->GetUniqueID());
m_geckocode_panel->LoadCodes(GameIniLocal, OpenISO->GetUniqueID());
}
void CISOProperties::SaveGameIniValueFrom3StateCheckbox(const char* section, const char* key, wxCheckBox* checkbox)
{
// Delete any existing entries from the local gameini if checkbox is undetermined.
// Otherwise, write the current value to the local gameini if the value differs from the default gameini values.
// Delete any existing entry from the local gameini if the value does not differ from the default gameini value.
bool checkbox_val = (checkbox->Get3StateValue() == wxCHK_CHECKED);
if (checkbox->Get3StateValue() == wxCHK_UNDETERMINED)
GameIniLocal.DeleteKey(section, key);
else if (!GameIniDefault.Exists(section, key))
GameIniLocal.Set(section, key, checkbox_val);
else
{
bool default_value;
GameIniDefault.Get(section, key, &default_value);
if (default_value != checkbox_val)
GameIniLocal.Set(section, key, checkbox_val);
else
GameIniLocal.DeleteKey(section, key);
}
}
bool CISOProperties::SaveGameConfig()
{
if (CPUThread->Get3StateValue() == wxCHK_UNDETERMINED)
GameIni.DeleteKey("Core", "CPUThread");
else
GameIni.Set("Core", "CPUThread", CPUThread->Get3StateValue());
SaveGameIniValueFrom3StateCheckbox("Core", "CPUThread", CPUThread);
SaveGameIniValueFrom3StateCheckbox("Core", "SkipIdle", SkipIdle);
SaveGameIniValueFrom3StateCheckbox("Core", "MMU", MMU);
SaveGameIniValueFrom3StateCheckbox("Core", "TLBHack", TLBHack);
SaveGameIniValueFrom3StateCheckbox("Core", "DCBZ", DCBZOFF);
SaveGameIniValueFrom3StateCheckbox("Core", "VBeam", VBeam);
SaveGameIniValueFrom3StateCheckbox("Core", "SyncGPU", SyncGPU);
SaveGameIniValueFrom3StateCheckbox("Core", "FastDiscSpeed", FastDiscSpeed);
SaveGameIniValueFrom3StateCheckbox("Core", "BlockMerging", BlockMerging);
SaveGameIniValueFrom3StateCheckbox("Core", "DSPHLE", DSPHLE);
SaveGameIniValueFrom3StateCheckbox("Wii", "Widescreen", EnableWideScreen);
SaveGameIniValueFrom3StateCheckbox("Video", "UseBBox", UseBBox);
SaveGameIniValueFrom3StateCheckbox("Video", "ZTPSpeedupHack", UseZTPSpeedupHack);
if (SkipIdle->Get3StateValue() == wxCHK_UNDETERMINED)
GameIni.DeleteKey("Core", "SkipIdle");
else
GameIni.Set("Core", "SkipIdle", SkipIdle->Get3StateValue());
#define SAVE_IF_NOT_DEFAULT(section, key, val, def) do { \
if (GameIniDefault.Exists((section), (key))) { \
std::remove_reference<decltype((val))>::type tmp__; \
GameIniDefault.Get((section), (key), &tmp__); \
if ((val) != tmp__) \
GameIniLocal.Set((section), (key), (val)); \
else \
GameIniLocal.DeleteKey((section), (key)); \
} else if ((val) != (def)) \
GameIniLocal.Set((section), (key), (val)); \
else \
GameIniLocal.DeleteKey((section), (key)); \
} while (0)
if (MMU->Get3StateValue() == wxCHK_UNDETERMINED)
GameIni.DeleteKey("Core", "MMU");
else
GameIni.Set("Core", "MMU", MMU->Get3StateValue());
SAVE_IF_NOT_DEFAULT("Video", "ProjectionHack", PHackEnable->GetValue(), false);
SAVE_IF_NOT_DEFAULT("Video", "PH_SZNear", (PHack_Data.PHackSZNear ? 1 : 0), 0);
SAVE_IF_NOT_DEFAULT("Video", "PH_SZFar", (PHack_Data.PHackSZFar ? 1 : 0), 0);
SAVE_IF_NOT_DEFAULT("Video", "PH_ExtraParam", (PHack_Data.PHackExP ? 1 : 0), 0);
SAVE_IF_NOT_DEFAULT("Video", "PH_ZNear", PHack_Data.PHZNear, "");
SAVE_IF_NOT_DEFAULT("Video", "PH_ZFar", PHack_Data.PHZFar, "");
SAVE_IF_NOT_DEFAULT("EmuState", "EmulationStateId", EmuState->GetSelection(), 0);
if (TLBHack->Get3StateValue() == wxCHK_UNDETERMINED)
GameIni.DeleteKey("Core", "TLBHack");
else
GameIni.Set("Core", "TLBHack", TLBHack->Get3StateValue());
if (DCBZOFF->Get3StateValue() == wxCHK_UNDETERMINED)
GameIni.DeleteKey("Core", "DCBZ");
else
GameIni.Set("Core", "DCBZ", DCBZOFF->Get3StateValue());
if (VBeam->Get3StateValue() == wxCHK_UNDETERMINED)
GameIni.DeleteKey("Core", "VBeam");
else
GameIni.Set("Core", "VBeam", VBeam->Get3StateValue());
if (SyncGPU->Get3StateValue() == wxCHK_UNDETERMINED)
GameIni.DeleteKey("Core", "SyncGPU");
else
GameIni.Set("Core", "SyncGPU", SyncGPU->Get3StateValue());
if (FastDiscSpeed->Get3StateValue() == wxCHK_UNDETERMINED)
GameIni.DeleteKey("Core", "FastDiscSpeed");
else
GameIni.Set("Core", "FastDiscSpeed", FastDiscSpeed->Get3StateValue());
if (BlockMerging->Get3StateValue() == wxCHK_UNDETERMINED)
GameIni.DeleteKey("Core", "BlockMerging");
else
GameIni.Set("Core", "BlockMerging", BlockMerging->Get3StateValue());
if (DSPHLE->Get3StateValue() == wxCHK_UNDETERMINED)
GameIni.DeleteKey("Core", "DSPHLE");
else
GameIni.Set("Core", "DSPHLE", DSPHLE->Get3StateValue());
if (EnableWideScreen->Get3StateValue() == wxCHK_UNDETERMINED)
GameIni.DeleteKey("Wii", "Widescreen");
else
GameIni.Set("Wii", "Widescreen", EnableWideScreen->Get3StateValue());
if (UseBBox->Get3StateValue() == wxCHK_UNDETERMINED)
GameIni.DeleteKey("Video", "UseBBox");
else
GameIni.Set("Video", "UseBBox", UseBBox->Get3StateValue());
if (UseZTPSpeedupHack->Get3StateValue() == wxCHK_UNDETERMINED)
GameIni.DeleteKey("Video", "ZTPSpeedupHack");
else
GameIni.Set("Video", "ZTPSpeedupHack", UseZTPSpeedupHack->Get3StateValue());
GameIni.Set("Video", "ProjectionHack", PHackEnable->Get3StateValue());
GameIni.Set("Video", "PH_SZNear", PHack_Data.PHackSZNear ? 1 : 0);
GameIni.Set("Video", "PH_SZFar", PHack_Data.PHackSZFar ? 1 : 0);
GameIni.Set("Video", "PH_ExtraParam", PHack_Data.PHackExP ? 1 : 0);
GameIni.Set("Video", "PH_ZNear", PHack_Data.PHZNear);
GameIni.Set("Video", "PH_ZFar", PHack_Data.PHZFar);
GameIni.Set("EmuState", "EmulationStateId", EmuState->GetSelection());
std::string sTemp;
GameIni.Get("EmuState","EmulationIssues", &sTemp);
if (EmuIssues->GetValue() != sTemp)
bRefreshList = true;
GameIni.Set("EmuState", "EmulationIssues", WxStrToStr(EmuIssues->GetValue()));
std::string emu_issues = EmuIssues->GetValue().ToStdString();
SAVE_IF_NOT_DEFAULT("EmuState", "EmulationIssues", emu_issues, "");
PatchList_Save();
ActionReplayList_Save();
Gecko::SaveCodes(GameIni, m_geckocode_panel->GetCodes());
Gecko::SaveCodes(GameIniLocal, m_geckocode_panel->GetCodes());
return GameIni.Save(GameIniFile.c_str());
bool success = GameIniLocal.Save(GameIniFileLocal.c_str());
// If the resulting file is empty, delete it. Kind of a hack, but meh.
if (success && File::GetSize(GameIniFileLocal) == 0)
File::Delete(GameIniFileLocal);
return success;
}
void CISOProperties::LaunchExternalEditor(const std::string& filename)
{
#ifdef __APPLE__
// wxTheMimeTypesManager is not yet implemented for wxCocoa
[[NSWorkspace sharedWorkspace] openFile:
[NSString stringWithUTF8String: filename.c_str()]
withApplication: @"TextEdit"];
#else
wxFileType* filetype = wxTheMimeTypesManager->GetFileTypeFromExtension(_T("ini"));
if(filetype == NULL) // From extension failed, trying with MIME type now
{
filetype = wxTheMimeTypesManager->GetFileTypeFromMimeType(_T("text/plain"));
if(filetype == NULL) // MIME type failed, aborting mission
{
PanicAlertT("Filetype 'ini' is unknown! Will not open!");
return;
}
}
wxString OpenCommand;
OpenCommand = filetype->GetOpenCommand(StrToWxStr(filename));
if(OpenCommand.IsEmpty())
PanicAlertT("Couldn't find open command for extension 'ini'!");
else
if(wxExecute(OpenCommand, wxEXEC_SYNC) == -1)
PanicAlertT("wxExecute returned -1 on application run!");
#endif
bRefreshList = true; // Just in case
// Once we're done with the ini edit, give the focus back to Dolphin
SetFocus();
}
void CISOProperties::OnEditConfig(wxCommandEvent& WXUNUSED (event))
{
if (File::Exists(GameIniFile))
{
SaveGameConfig();
SaveGameConfig();
LaunchExternalEditor(GameIniFileLocal);
GameIniLocal.Load(GameIniFileLocal);
LoadGameConfig();
}
#ifdef __APPLE__
// wxTheMimeTypesManager is not yet implemented for wxCocoa
[[NSWorkspace sharedWorkspace] openFile:
[NSString stringWithUTF8String: GameIniFile.c_str()]
withApplication: @"TextEdit"];
#else
wxFileType* filetype = wxTheMimeTypesManager->GetFileTypeFromExtension(_T("ini"));
if(filetype == NULL) // From extension failed, trying with MIME type now
{
filetype = wxTheMimeTypesManager->GetFileTypeFromMimeType(_T("text/plain"));
if(filetype == NULL) // MIME type failed, aborting mission
{
PanicAlertT("Filetype 'ini' is unknown! Will not open!");
return;
}
}
wxString OpenCommand;
OpenCommand = filetype->GetOpenCommand(StrToWxStr(GameIniFile));
if(OpenCommand.IsEmpty())
PanicAlertT("Couldn't find open command for extension 'ini'!");
else
if(wxExecute(OpenCommand, wxEXEC_SYNC) == -1)
PanicAlertT("wxExecute returned -1 on application run!");
#endif
GameIni.Load(GameIniFile.c_str());
LoadGameConfig();
bRefreshList = true; // Just in case
}
// Once we're done with the ini edit, give the focus back to Dolphin
SetFocus();
void CISOProperties::OnShowDefaultConfig(wxCommandEvent& WXUNUSED (event))
{
LaunchExternalEditor(GameIniFileDefault);
}
void CISOProperties::ListSelectionChanged(wxCommandEvent& event)
@ -1180,14 +1134,26 @@ void CISOProperties::ListSelectionChanged(wxCommandEvent& event)
switch (event.GetId())
{
case ID_PATCHES_LIST:
if (Patches->GetSelection() != wxNOT_FOUND)
if (Patches->GetSelection() == wxNOT_FOUND
|| DefaultPatches.find(Patches->GetString(Patches->GetSelection()).ToStdString()) != DefaultPatches.end())
{
EditPatch->Disable();
RemovePatch->Disable();
}
else
{
EditPatch->Enable();
RemovePatch->Enable();
}
break;
case ID_CHEATS_LIST:
if (Cheats->GetSelection() != wxNOT_FOUND)
if (Cheats->GetSelection() == wxNOT_FOUND
|| DefaultCheats.find(Cheats->GetString(Cheats->GetSelection()).ToStdString()) != DefaultCheats.end())
{
EditCheat->Disable();
RemoveCheat->Disable();
}
else
{
EditCheat->Enable();
RemoveCheat->Enable();
@ -1200,14 +1166,17 @@ void CISOProperties::PatchList_Load()
{
onFrame.clear();
Patches->Clear();
PatchEngine::LoadPatchSection("OnFrame", onFrame, GameIni);
PatchEngine::LoadPatchSection("OnFrame", onFrame, GameIniDefault, GameIniLocal);
u32 index = 0;
for (std::vector<PatchEngine::Patch>::const_iterator it = onFrame.begin(); it != onFrame.end(); ++it)
for (auto it = onFrame.begin(); it != onFrame.end(); ++it)
{
PatchEngine::Patch p = *it;
Patches->Append(StrToWxStr(p.name));
Patches->Check(index, p.active);
if (!p.user_defined)
DefaultPatches.insert(p.name);
++index;
}
}
@ -1215,20 +1184,27 @@ void CISOProperties::PatchList_Load()
void CISOProperties::PatchList_Save()
{
std::vector<std::string> lines;
std::vector<std::string> enabledLines;
u32 index = 0;
for (std::vector<PatchEngine::Patch>::const_iterator onFrame_it = onFrame.begin(); onFrame_it != onFrame.end(); ++onFrame_it)
for (auto onFrame_it = onFrame.begin(); onFrame_it != onFrame.end(); ++onFrame_it)
{
lines.push_back(Patches->IsChecked(index) ? "+$" + onFrame_it->name : "$" + onFrame_it->name);
if (Patches->IsChecked(index))
enabledLines.push_back("$" + onFrame_it->name);
for (std::vector<PatchEngine::PatchEntry>::const_iterator iter2 = onFrame_it->entries.begin(); iter2 != onFrame_it->entries.end(); ++iter2)
// Do not save default patches.
if (DefaultPatches.find(onFrame_it->name) == DefaultPatches.end())
{
std::string temp = StringFromFormat("0x%08X:%s:0x%08X", iter2->address, PatchEngine::PatchTypeStrings[iter2->type], iter2->value);
lines.push_back(temp);
lines.push_back("$" + onFrame_it->name);
for (auto iter2 = onFrame_it->entries.begin(); iter2 != onFrame_it->entries.end(); ++iter2)
{
std::string temp = StringFromFormat("0x%08X:%s:0x%08X", iter2->address, PatchEngine::PatchTypeStrings[iter2->type], iter2->value);
lines.push_back(temp);
}
}
++index;
}
GameIni.SetLines("OnFrame", lines);
lines.clear();
GameIniLocal.SetLines("OnFrame_Enabled", enabledLines);
GameIniLocal.SetLines("OnFrame", lines);
}
void CISOProperties::PHackButtonClicked(wxCommandEvent& event)
@ -1282,7 +1258,7 @@ void CISOProperties::ActionReplayList_Load()
{
arCodes.clear();
Cheats->Clear();
ActionReplay::LoadCodes(arCodes, GameIni);
ActionReplay::LoadCodes(arCodes, GameIniDefault, GameIniLocal);
u32 index = 0;
for (std::vector<ActionReplay::ARCode>::const_iterator it = arCodes.begin(); it != arCodes.end(); ++it)
@ -1290,6 +1266,8 @@ void CISOProperties::ActionReplayList_Load()
ActionReplay::ARCode arCode = *it;
Cheats->Append(StrToWxStr(arCode.name));
Cheats->Check(index, arCode.active);
if (!arCode.user_defined)
DefaultCheats.insert(arCode.name);
++index;
}
}
@ -1297,20 +1275,28 @@ void CISOProperties::ActionReplayList_Load()
void CISOProperties::ActionReplayList_Save()
{
std::vector<std::string> lines;
std::vector<std::string> enabledLines;
u32 index = 0;
for (std::vector<ActionReplay::ARCode>::const_iterator iter = arCodes.begin(); iter != arCodes.end(); ++iter)
for (auto iter = arCodes.begin(); iter != arCodes.end(); ++iter)
{
ActionReplay::ARCode code = *iter;
lines.push_back(Cheats->IsChecked(index) ? "+$" + code.name : "$" + code.name);
if (Cheats->IsChecked(index))
enabledLines.push_back("$" + code.name);
for (std::vector<ActionReplay::AREntry>::const_iterator iter2 = code.ops.begin(); iter2 != code.ops.end(); ++iter2)
// Do not save default cheats.
if (DefaultCheats.find(code.name) == DefaultCheats.end())
{
lines.push_back(WxStrToStr(wxString::Format(wxT("%08X %08X"), iter2->cmd_addr, iter2->value)));
lines.push_back("$" + code.name);
for (auto iter2 = code.ops.begin(); iter2 != code.ops.end(); ++iter2)
{
lines.push_back(WxStrToStr(wxString::Format(wxT("%08X %08X"), iter2->cmd_addr, iter2->value)));
}
}
++index;
}
GameIni.SetLines("ActionReplay", lines);
GameIniLocal.SetLines("ActionReplay_Enabled", enabledLines);
GameIniLocal.SetLines("ActionReplay", lines);
}
void CISOProperties::ActionReplayButtonClicked(wxCommandEvent& event)

View File

@ -129,6 +129,7 @@ private:
ID_ENABLEPROGRESSIVESCAN,
ID_ENABLEWIDESCREEN,
ID_EDITCONFIG,
ID_SHOWDEFAULTCONFIG,
ID_EMUSTATE,
ID_EMU_ISSUES,
ID_PATCHES_LIST,
@ -163,10 +164,13 @@ private:
IDM_BNRSAVEAS
};
void LaunchExternalEditor(const std::string& filename);
void CreateGUIControls(bool);
void OnClose(wxCloseEvent& event);
void OnCloseClick(wxCommandEvent& event);
void OnEditConfig(wxCommandEvent& event);
void OnShowDefaultConfig(wxCommandEvent& event);
void ListSelectionChanged(wxCommandEvent& event);
void PatchButtonClicked(wxCommandEvent& event);
void ActionReplayButtonClicked(wxCommandEvent& event);
@ -193,13 +197,22 @@ private:
void ExportDir(const char* _rFullPath, const char* _rExportFilename,
const int partitionNum = 0);
IniFile GameIni;
std::string GameIniFile;
IniFile GameIniDefault;
IniFile GameIniLocal;
std::string GameIniFileDefault;
std::string GameIniFileLocal;
std::set<std::string> DefaultPatches;
std::set<std::string> DefaultCheats;
void LoadGameConfig();
void PatchList_Load();
void PatchList_Save();
void ActionReplayList_Save();
void ChangeBannerDetails(int lang);
long GetElementStyle(const char* section, const char* key);
void SetCheckboxValueFromGameini(const char* section, const char* key, wxCheckBox* checkbox);
void SaveGameIniValueFrom3StateCheckbox(const char* section, const char* key, wxCheckBox* checkbox);
};
#endif

View File

@ -253,15 +253,12 @@ bool DolphinApp::OnInit()
File::CopyDir(File::GetSysDirectory() + WII_USER_DIR,
File::GetUserPath(D_WIIUSER_IDX));
// TODO: replace these with overlays
File::CopyDir(std::string(File::GetSysDirectory() + GAMECONFIG_DIR DIR_SEP),
File::GetUserPath(D_GAMECONFIG_IDX));
File::CreateFullPath(File::GetUserPath(D_USER_IDX));
File::CreateFullPath(File::GetUserPath(D_CACHE_IDX));
File::CreateFullPath(File::GetUserPath(D_CONFIG_IDX));
File::CreateFullPath(File::GetUserPath(D_DUMPDSP_IDX));
File::CreateFullPath(File::GetUserPath(D_DUMPTEXTURES_IDX));
File::CreateFullPath(File::GetUserPath(D_GAMESETTINGS_IDX));
File::CreateFullPath(File::GetUserPath(D_GCUSER_IDX));
File::CreateFullPath(File::GetUserPath(D_GCUSER_IDX) + USA_DIR DIR_SEP);
File::CreateFullPath(File::GetUserPath(D_GCUSER_IDX) + EUR_DIR DIR_SEP);

View File

@ -2,6 +2,7 @@
// Licensed under GPLv2
// Refer to the license.txt file included.
#include "CommonPaths.h"
#include "PHackSettings.h"
#include "ConfigManager.h"
#include "WxUtils.h"
@ -18,10 +19,9 @@ CPHackSettings::CPHackSettings(wxWindow* parent, wxWindowID id, const wxString&
{
CreateGUIControls();
std::string _iniFilename;
_iniFilename = File::GetUserPath(D_GAMECONFIG_IDX) + "PH_PRESETS.ini";
_iniFilename = File::GetSysDirectory() + GAMESETTINGS_DIR DIR_SEP "PH_PRESETS.ini";
PHPresetsIni.Load(_iniFilename.c_str());
//PHPresetsIni.SortSections();
//PHPresetsIni.Save(_iniFilename.c_str());
PHPresetsIni.SortSections();
LoadPHackData();
}

View File

@ -3,6 +3,7 @@
// Refer to the license.txt file included.
#include "InputConfig.h"
#include "CommonPaths.h"
#include "../../Core/Src/ConfigManager.h"
#include "../../Core/Src/HW/Wiimote.h"
@ -37,7 +38,8 @@ bool InputPlugin::LoadConfig(bool isGC)
type = "Wiimote";
path = "Profiles/Wiimote/";
}
game_ini.Load(File::GetUserPath(D_GAMECONFIG_IDX) + SConfig::GetInstance().m_LocalCoreStartupParameter.GetUniqueID() + ".ini");
game_ini.Load(File::GetSysDirectory() + GAMESETTINGS_DIR DIR_SEP + SConfig::GetInstance().m_LocalCoreStartupParameter.GetUniqueID() + ".ini");
game_ini.Load(File::GetUserPath(D_GAMESETTINGS_IDX) + SConfig::GetInstance().m_LocalCoreStartupParameter.GetUniqueID() + ".ini", true);
for (int i = 0; i < 4; i++)
{
if (game_ini.Exists("Controls", (type + "Profile" + num[i]).c_str()))
@ -46,7 +48,10 @@ bool InputPlugin::LoadConfig(bool isGC)
if (File::Exists(File::GetUserPath(D_CONFIG_IDX) + path + profile[i] + ".ini"))
useProfile[i] = true;
else
{
// TODO: Having a PanicAlert for this is dumb.
PanicAlertT("Selected controller profile does not exist");
}
}
}
}
@ -94,6 +99,6 @@ void InputPlugin::SaveConfig()
e = controllers.end();
for ( ; i!=e; ++i )
(*i)->SaveConfig(inifile.GetOrCreateSection((*i)->GetName().c_str()));
inifile.Save(ini_filename);
}

View File

@ -120,13 +120,13 @@ void VideoConfig::Load(const char *ini_file)
OSD::AddMessage("Warning: Shader Debugging is enabled, performance will suffer heavily", 15000);
}
void VideoConfig::GameIniLoad(const char *ini_file)
void VideoConfig::GameIniLoad(const char* default_ini_file, const char* local_ini_file)
{
bool gfx_override_exists = false;
// XXX: Again, bad place to put OSD messages at (see delroth's comment above)
// XXX: This will add an OSD message for each projection hack value... meh
#define CHECK_SETTING(section, key, var) { \
#define CHECK_SETTING(section, key, var) do { \
decltype(var) temp = var; \
if (iniFile.GetIfExists(section, key, &var) && var != temp) { \
char buf[256]; \
@ -134,10 +134,11 @@ void VideoConfig::GameIniLoad(const char *ini_file)
OSD::AddMessage(buf, 7500); \
gfx_override_exists = true; \
} \
}
} while (0)
IniFile iniFile;
iniFile.Load(ini_file);
iniFile.Load(default_ini_file);
iniFile.Load(local_ini_file, true);
CHECK_SETTING("Video_Hardware", "VSync", bVSync);
@ -279,7 +280,7 @@ void VideoConfig::Save(const char *ini_file)
iniFile.Set("Hacks", "EFBAccessEnable", bEFBAccessEnable);
iniFile.Set("Hacks", "DlistCachingEnable", bDlistCachingEnable);
iniFile.Set("Hacks", "EFBCopyEnable", bEFBCopyEnable);
iniFile.Set("Hacks", "EFBToTextureEnable", bCopyEFBToTexture);
iniFile.Set("Hacks", "EFBToTextureEnable", bCopyEFBToTexture);
iniFile.Set("Hacks", "EFBScaledCopy", bCopyEFBScaled);
iniFile.Set("Hacks", "EFBCopyCacheEnable", bEFBCopyCacheEnable);
iniFile.Set("Hacks", "EFBEmulateFormatChanges", bEFBEmulateFormatChanges);
@ -290,60 +291,6 @@ void VideoConfig::Save(const char *ini_file)
iniFile.Save(ini_file);
}
void VideoConfig::GameIniSave(const char* default_ini, const char* game_ini)
{
// wxWidgets doesn't provide us with a nice way to change 3-state checkboxes into 2-state ones
// This would allow us to make the "default config" dialog layout to be 2-state based, but the
// "game config" layout to be 3-state based (with the 3rd state being "use default")
// Since we can't do that, we instead just save anything which differs from the default config
// TODO: Make this less ugly
VideoConfig defCfg;
defCfg.Load(default_ini);
IniFile iniFile;
iniFile.Load(game_ini);
#define SET_IF_DIFFERS(section, key, member) { if ((member) != (defCfg.member)) iniFile.Set((section), (key), (member)); else iniFile.DeleteKey((section), (key)); }
SET_IF_DIFFERS("Video_Hardware", "VSync", bVSync);
SET_IF_DIFFERS("Video_Settings", "wideScreenHack", bWidescreenHack);
SET_IF_DIFFERS("Video_Settings", "AspectRatio", iAspectRatio);
SET_IF_DIFFERS("Video_Settings", "Crop", bCrop);
SET_IF_DIFFERS("Video_Settings", "UseXFB", bUseXFB);
SET_IF_DIFFERS("Video_Settings", "UseRealXFB", bUseRealXFB);
SET_IF_DIFFERS("Video_Settings", "SafeTextureCacheColorSamples", iSafeTextureCache_ColorSamples);
SET_IF_DIFFERS("Video_Settings", "DLOptimize", iCompileDLsLevel);
SET_IF_DIFFERS("Video_Settings", "HiresTextures", bHiresTextures);
SET_IF_DIFFERS("Video_Settings", "AnaglyphStereo", bAnaglyphStereo);
SET_IF_DIFFERS("Video_Settings", "AnaglyphStereoSeparation", iAnaglyphStereoSeparation);
SET_IF_DIFFERS("Video_Settings", "AnaglyphFocalAngle", iAnaglyphFocalAngle);
SET_IF_DIFFERS("Video_Settings", "EnablePixelLighting", bEnablePixelLighting);
SET_IF_DIFFERS("Video_Settings", "FastDepthCalc", bFastDepthCalc);
SET_IF_DIFFERS("Video_Settings", "MSAA", iMultisampleMode);
SET_IF_DIFFERS("Video_Settings", "EFBScale", iEFBScale); // integral
SET_IF_DIFFERS("Video_Settings", "DstAlphaPass", bDstAlphaPass);
SET_IF_DIFFERS("Video_Settings", "DisableFog", bDisableFog);
SET_IF_DIFFERS("Video_Settings", "EnableOpenCL", bEnableOpenCL);
SET_IF_DIFFERS("Video_Settings", "OMPDecoder", bOMPDecoder);
SET_IF_DIFFERS("Video_Enhancements", "ForceFiltering", bForceFiltering);
SET_IF_DIFFERS("Video_Enhancements", "MaxAnisotropy", iMaxAnisotropy); // NOTE - this is x in (1 << x)
SET_IF_DIFFERS("Video_Enhancements", "PostProcessingShader", sPostProcessingShader);
SET_IF_DIFFERS("Video_Enhancements", "Enable3dVision", b3DVision);
SET_IF_DIFFERS("Video_Hacks", "EFBAccessEnable", bEFBAccessEnable);
SET_IF_DIFFERS("Video_Hacks", "DlistCachingEnable", bDlistCachingEnable);
SET_IF_DIFFERS("Video_Hacks", "EFBCopyEnable", bEFBCopyEnable);
SET_IF_DIFFERS("Video_Hacks", "EFBToTextureEnable", bCopyEFBToTexture);
SET_IF_DIFFERS("Video_Hacks", "EFBScaledCopy", bCopyEFBScaled);
SET_IF_DIFFERS("Video_Hacks", "EFBCopyCacheEnable", bEFBCopyCacheEnable);
SET_IF_DIFFERS("Video_Hacks", "EFBEmulateFormatChanges", bEFBEmulateFormatChanges);
iniFile.Save(game_ini);
}
bool VideoConfig::IsVSync()
{
return Core::isTabPressed ? false : bVSync;

View File

@ -50,7 +50,7 @@ struct VideoConfig
{
VideoConfig();
void Load(const char *ini_file);
void GameIniLoad(const char *ini_file);
void GameIniLoad(const char* default_ini, const char* game_ini);
void VerifyValidity();
void Save(const char *ini_file);
void GameIniSave(const char* default_ini, const char* game_ini);

View File

@ -154,8 +154,10 @@ bool VideoBackend::Initialize(void *&window_handle)
frameCount = 0;
const SCoreStartupParameter& core_params = SConfig::GetInstance().m_LocalCoreStartupParameter;
g_Config.Load((File::GetUserPath(D_CONFIG_IDX) + "gfx_dx11.ini").c_str());
g_Config.GameIniLoad(SConfig::GetInstance().m_LocalCoreStartupParameter.m_strGameIni.c_str());
g_Config.GameIniLoad(core_params.m_strGameIniDefault.c_str(), core_params.m_strGameIniLocal.c_str());
g_Config.UpdateProjectionHack();
g_Config.VerifyValidity();
UpdateActiveConfig();

View File

@ -150,7 +150,8 @@ bool VideoBackend::Initialize(void *&window_handle)
frameCount = 0;
g_Config.Load((File::GetUserPath(D_CONFIG_IDX) + "gfx_dx9.ini").c_str());
g_Config.GameIniLoad(SConfig::GetInstance().m_LocalCoreStartupParameter.m_strGameIni.c_str());
g_Config.GameIniLoad(SConfig::GetInstance().m_LocalCoreStartupParameter.m_strGameIniDefault.c_str(),
SConfig::GetInstance().m_LocalCoreStartupParameter.m_strGameIniLocal.c_str());
g_Config.UpdateProjectionHack();
g_Config.VerifyValidity();
// as only some driver/hardware configurations support dual source blending only enable it if is

View File

@ -172,7 +172,8 @@ bool VideoBackend::Initialize(void *&window_handle)
frameCount = 0;
g_Config.Load((File::GetUserPath(D_CONFIG_IDX) + "gfx_opengl.ini").c_str());
g_Config.GameIniLoad(SConfig::GetInstance().m_LocalCoreStartupParameter.m_strGameIni.c_str());
g_Config.GameIniLoad(SConfig::GetInstance().m_LocalCoreStartupParameter.m_strGameIniDefault.c_str(),
SConfig::GetInstance().m_LocalCoreStartupParameter.m_strGameIniLocal.c_str());
g_Config.UpdateProjectionHack();
g_Config.VerifyValidity();
UpdateActiveConfig();