New option system

Fix per-game settings (Issue #115)
Automatic load/save state (Issue #173)
Reload Naomi/AW BIOS after per-game settings are loaded to allow
per-game BIOS region. (Issue #96)
Restrict Soul Reaver widescreen cheat to the EU version (Issue #188)
Disable UI elements for overridden settings
Clean up/simplify legacy Naomi ROM loading
This commit is contained in:
Flyinghead 2021-03-01 10:13:40 +01:00
parent 51b2e30af8
commit c3a95594f9
86 changed files with 1597 additions and 1756 deletions

View File

@ -450,7 +450,9 @@ target_sources(${PROJECT_NAME} PRIVATE
core/cfg/cfg.h
core/cfg/cl.cpp
core/cfg/ini.cpp
core/cfg/ini.h)
core/cfg/ini.h
core/cfg/option.cpp
core/cfg/option.h)
target_sources(${PROJECT_NAME} PRIVATE
core/hw/aica/aica.cpp

View File

@ -202,10 +202,6 @@
#define FEAT_DSPREC DYNAREC_NONE
#endif
#if defined(TARGET_NO_COREIO_HTTP)
#define FEAT_HAS_COREIO_HTTP 0
#endif
//defaults
#ifndef FEAT_SHREC
@ -232,24 +228,10 @@
#endif
#endif
#ifndef FEAT_HAS_COREIO_HTTP
#define FEAT_HAS_COREIO_HTTP 1
#endif
#if HOST_CPU == CPU_X64 || HOST_CPU == CPU_ARM64
#define HOST_64BIT_CPU
#endif
//Depricated build configs
#ifdef HOST_NO_REC
#error Dont use HOST_NO_REC
#endif
#ifdef HOST_NO_AREC
#error Dont use HOST_NO_AREC
#endif
// Compiler Related
#ifndef _MSC_VER
@ -278,7 +260,7 @@
#define GD_CLOCK 33868800 //GDROM XTAL -- 768fs
#define AICA_CORE_CLOCK (GD_CLOCK*4/3) //[45158400] GD->PLL 3:4 -> AICA CORE -- 1024fs
#define ADAC_CLOCK (AICA_CORE_CLOCK/2) //[11289600] 44100*256, AICA CORE -> PLL 4:1 -> ADAC -- 256fs
#define ADAC_CLOCK (AICA_CORE_CLOCK/4) //[11289600] 44100*256, AICA CORE -> PLL 4:1 -> ADAC -- 256fs
#define AICA_ARM_CLOCK (AICA_CORE_CLOCK/2) //[22579200] AICA CORE -> PLL 2:1 -> ARM
#define AICA_SDRAM_CLOCK (GD_CLOCK*2) //[67737600] GD-> PLL 2 -> SDRAM
#define SH4_MAIN_CLOCK (200*1000*1000) //[200000000] XTal(13.5) -> PLL (33.3) -> PLL 1:6 (200)

View File

@ -1,9 +1,3 @@
/*
Config file crap
Supports various things, as virtual config entries and such crap
Works surprisingly well considering how old it is ...
*/
#include "cfg.h"
#include "ini.h"
#include "stdclass.h"
@ -15,10 +9,8 @@ static bool save_config = true;
static bool autoSave = true;
static emucfg::ConfigFile cfgdb;
static std::string game_id;
static bool has_game_specific_config = false;
void savecfgf()
static void saveConfigFile()
{
FILE* cfgfile = nowide::fopen(cfgPath.c_str(), "wt");
if (!cfgfile)
@ -31,49 +23,13 @@ void savecfgf()
std::fclose(cfgfile);
}
}
void cfgSaveStr(const char * Section, const char * Key, const char * String)
void cfgSaveStr(const std::string& section, const std::string& key, const std::string& string)
{
const std::string section(Section);
const std::string key(Key);
const std::string value(String);
if (cfgHasGameSpecificConfig())
{
if (cfgdb.get(section, key, "") == value)
// Same value as main config: delete entry
cfgdb.delete_entry(game_id, key);
else
cfgdb.set(game_id, key, value);
}
else
cfgdb.set(section, key, value);
cfgdb.set(section, key, string);
if (save_config && autoSave)
savecfgf();
saveConfigFile();
}
//New config code
/*
I want config to be really flexible .. so , here is the new implementation :
Functions :
cfgLoadInt : Load an int , if it does not exist save the default value to it and return it
cfgSaveInt : Save an int
cfgLoadStr : Load a str , if it does not exist save the default value to it and return it
cfgSaveStr : Save a str
cfgExists : Returns true if the Section:Key exists. If Key is null , it retuns true if Section exists
Config parameters can be read from the config file , and can be given at the command line
-cfg section:key=value -> defines a value at command line
If a cfgSave* is made on a value defined by command line , then the command line value is replaced by it
cfg values set by command line are not written to the cfg file , unless a cfgSave* is used
*/
///////////////////////////////
/*
** This will verify there is a working file @ ./szIniFn
** - if not present, it will write defaults
*/
bool cfgOpen()
{
@ -99,7 +55,7 @@ bool cfgOpen()
{
// Config file didn't exist
INFO_LOG(COMMON, "Creating new empty config file at '%s'", cfgPath.c_str());
savecfgf();
saveConfigFile();
}
else
{
@ -111,105 +67,54 @@ bool cfgOpen()
return true;
}
//Implementations of the interface :)
//Section must be set
//If key is 0 , it looks for the section
//0 : not found
//1 : found section , key was 0
//2 : found section & key
s32 cfgExists(const char * Section, const char * Key)
std::string cfgLoadStr(const std::string& section, const std::string& key, const std::string& def)
{
if(cfgdb.has_entry(std::string(Section), std::string(Key)))
{
return 2;
}
else
{
return (cfgdb.has_section(std::string(Section)) ? 1 : 0);
}
return cfgdb.get(section, key, def);
}
void cfgLoadStr(const char * Section, const char * Key, char * Return,const char* Default)
void cfgSaveInt(const std::string& section, const std::string& key, s32 value)
{
std::string value = cfgdb.get(Section, Key, Default);
// FIXME: Buffer overflow possible
strcpy(Return, value.c_str());
cfgSaveStr(section, key, std::to_string(value));
}
std::string cfgLoadStr(const char * Section, const char * Key, const char* Default)
s32 cfgLoadInt(const std::string& section, const std::string& key, s32 def)
{
std::string v = cfgdb.get(std::string(Section), std::string(Key), std::string(Default));
if (cfgHasGameSpecificConfig())
v = cfgdb.get(game_id, std::string(Key), v);
return v;
return cfgdb.get_int(section, key, def);
}
//These are helpers , mainly :)
void cfgSaveInt(const char * Section, const char * Key, s32 Int)
void cfgSaveBool(const std::string& section, const std::string& key, bool value)
{
char str[32];
sprintf(str, "%d", Int);
cfgSaveStr(Section, Key, str);
cfgSaveStr(section, key, value ? "yes" : "no");
}
s32 cfgLoadInt(const char * Section, const char * Key,s32 Default)
bool cfgLoadBool(const std::string& section, const std::string& key, bool def)
{
s32 v = cfgdb.get_int(std::string(Section), std::string(Key), Default);
if (cfgHasGameSpecificConfig())
v = cfgdb.get_int(game_id, std::string(Key), v);
return v;
return cfgdb.get_bool(section, key, def);
}
void cfgSaveBool(const char * Section, const char * Key, bool BoolValue)
void cfgSetVirtual(const std::string& section, const std::string& key, const std::string& value)
{
cfgSaveStr(Section, Key, BoolValue ? "yes" : "no");
cfgdb.set(section, key, value, true);
}
bool cfgLoadBool(const char * Section, const char * Key,bool Default)
bool cfgIsVirtual(const std::string& section, const std::string& key)
{
bool v = cfgdb.get_bool(std::string(Section), std::string(Key), Default);
if (cfgHasGameSpecificConfig())
v = cfgdb.get_bool(game_id, std::string(Key), v);
return v;
return cfgdb.is_virtual(section, key);
}
void cfgSetVirtual(const char * Section, const char * Key, const char * String)
bool cfgHasSection(const std::string& section)
{
cfgdb.set(std::string(Section), std::string(Key), std::string(String), true);
return cfgdb.has_section(section);
}
void cfgSetGameId(const char *id)
void cfgDeleteSection(const std::string& section)
{
game_id = id;
}
const char *cfgGetGameId()
{
return game_id.c_str();
}
bool cfgHasGameSpecificConfig()
{
return has_game_specific_config || cfgdb.has_section(game_id);
}
void cfgMakeGameSpecificConfig()
{
has_game_specific_config = true;
}
void cfgDeleteGameSpecificConfig()
{
has_game_specific_config = false;
cfgdb.delete_section(game_id);
cfgdb.delete_section(section);
}
void cfgSetAutoSave(bool autoSave)
{
::autoSave = autoSave;
if (autoSave)
savecfgf();
saveConfigFile();
}

View File

@ -1,29 +1,19 @@
#pragma once
#include "types.h"
/*
** cfg* prototypes, if you pass NULL to a cfgSave* it will wipe out the section
** } if you pass it to lpKey it will wipe out that particular entry
** } if you add write to something it will create it if its not present
** } ** Strings passed to LoadStr should be MAX_PATH in size ! **
*/
bool cfgOpen();
s32 cfgLoadInt(const char * lpSection, const char * lpKey,s32 Default);
void cfgSaveInt(const char * lpSection, const char * lpKey, s32 Int);
void cfgLoadStr(const char * lpSection, const char * lpKey, char * lpReturn,const char* lpDefault);
std::string cfgLoadStr(const char * Section, const char * Key, const char* Default);
void cfgSaveStr(const char * lpSection, const char * lpKey, const char * lpString);
void cfgSaveBool(const char * Section, const char * Key, bool BoolValue);
bool cfgLoadBool(const char * Section, const char * Key,bool Default);
s32 cfgExists(const char * Section, const char * Key);
void cfgSetVirtual(const char * lpSection, const char * lpKey, const char * lpString);
s32 cfgLoadInt(const std::string& section, const std::string& key, s32 def);
void cfgSaveInt(const std::string& section, const std::string& key, s32 value);
std::string cfgLoadStr(const std::string& section, const std::string& key, const std::string& def);
void cfgSaveStr(const std::string& section, const std::string& key, const std::string& value);
void cfgSaveBool(const std::string& section, const std::string& key, bool value);
bool cfgLoadBool(const std::string& section, const std::string& key, bool def);
void cfgSetVirtual(const std::string& section, const std::string& key, const std::string& value);
bool cfgIsVirtual(const std::string& section, const std::string& key);
bool ParseCommandLine(int argc,char* argv[]);
bool ParseCommandLine(int argc, char *argv[]);
void cfgSetGameId(const char *id);
const char *cfgGetGameId();
bool cfgHasGameSpecificConfig();
void cfgMakeGameSpecificConfig();
void cfgDeleteGameSpecificConfig();
void cfgSetAutoSave(bool autoSave);
bool cfgHasSection(const std::string& section);
void cfgDeleteSection(const std::string& section);

View File

@ -299,5 +299,13 @@ void ConfigFile::delete_entry(const std::string& section_name, const std::string
section->delete_entry(entry_name);
}
bool ConfigFile::is_virtual(const std::string& section_name, const std::string& entry_name)
{
ConfigSection *section = get_section(section_name, true);
if (section == nullptr)
return false;
return section->has_entry(entry_name);
}
} // namespace emucfg

View File

@ -31,6 +31,7 @@ struct ConfigFile {
public:
bool has_section(const std::string& name);
bool has_entry(const std::string& section_name, const std::string& entry_name);
bool is_virtual(const std::string& section_name, const std::string& entry_name);
void parse(FILE* fd);
void save(FILE* fd);

141
core/cfg/option.cpp Normal file
View File

@ -0,0 +1,141 @@
/*
Copyright 2021 flyinghead
This file is part of Flycast.
Flycast is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Flycast is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Flycast. If not, see <https://www.gnu.org/licenses/>.
*/
#include "option.h"
namespace config {
// Dynarec
Option<bool> DynarecEnabled("Dynarec.Enabled", true);
Option<bool> DynarecIdleSkip("Dynarec.idleskip", true);
Option<bool> DynarecUnstableOpt("Dynarec.unstable-opt");
Option<bool> DynarecSafeMode("Dynarec.safe-mode");
Option<bool> DisableVmem32("Dynarec.DisableVmem32");
// General
Option<int> Cable("Dreamcast.Cable", 3); // TV Composite
Option<int> Region("Dreamcast.Region", 1); // USA
Option<int> Broadcast("Dreamcast.Broadcast", 0); // NTSC
Option<int> Language("Dreamcast.Language", 1); // English
Option<bool> FullMMU("Dreamcast.FullMMU");
Option<bool> ForceWindowsCE("Dreamcast.ForceWindowsCE");
Option<bool> AutoSavestate("Dreamcast.AutoSavestate");
// Sound
Option<bool> LimitFPS("aica.LimitFPS", true);
Option<bool> DSPEnabled("aica.DSPEnabled", false);
Option<bool> DisableSound("aica.NoSound");
#if HOST_CPU == CPU_ARM
Option<int> AudioBufferSize("aica.BufferSize", 5644); // 128 ms
#else
Option<int> AudioBufferSize("aica.BufferSize", 2822); // 64 ms
#endif
OptionString AudioBackend("backend", "auto", "audio");
// Rendering
RendererOption RendererType;
Option<bool> UseMipmaps("rend.UseMipmaps", true);
Option<bool> Widescreen("rend.WideScreen");
Option<bool> ShowFPS("rend.ShowFPS");
Option<bool> RenderToTextureBuffer("rend.RenderToTextureBuffer");
Option<int> RenderToTextureUpscale("rend.RenderToTextureUpscale", 1);
Option<bool> TranslucentPolygonDepthMask("rend.TranslucentPolygonDepthMask");
Option<bool> ModifierVolumes("rend.ModifierVolumes", true);
Option<bool> Clipping("rend.Clipping", true);
Option<int> TextureUpscale("rend.TextureUpscale", 1);
Option<int> MaxFilteredTextureSize("rend.MaxFilteredTextureSize", 256);
Option<float> ExtraDepthScale("rend.ExtraDepthScale", 1.f);
Option<bool> CustomTextures("rend.CustomTextures");
Option<bool> DumpTextures("rend.DumpTextures");
Option<int> ScreenScaling("rend.ScreenScaling", 100);
Option<int> ScreenStretching("rend.ScreenStretching", 100);
Option<bool> Fog("rend.Fog", true);
Option<bool> FloatVMUs("rend.FloatVMUs");
Option<bool> Rotate90("rend.Rotate90");
Option<bool> PerStripSorting("rend.PerStripSorting");
Option<bool> DelayFrameSwapping("rend.DelayFrameSwapping");
Option<bool> WidescreenGameHacks("rend.WidescreenGameHacks");
std::array<Option<int>, 4> CrosshairColor {
Option<int>("rend.CrossHairColor1"),
Option<int>("rend.CrossHairColor2"),
Option<int>("rend.CrossHairColor3"),
Option<int>("rend.CrossHairColor4"),
};
Option<int> SkipFrame("ta.skip");
Option<int> MaxThreads("pvr.MaxThreads", 3);
Option<int> AutoSkipFrame("pvr.AutoSkipFrame", 0);
// Misc
Option<bool> SerialConsole("Debug.SerialConsoleEnabled");
Option<bool> SerialPTY("Debug.SerialPTY");
Option<bool> UseReios("UseReios");
Option<bool> OpenGlChecks("OpenGlChecks", false, "validate");
Option<std::vector<std::string>, false> ContentPath("Dreamcast.ContentPath");
Option<bool, false> HideLegacyNaomiRoms("Dreamcast.HideLegacyNaomiRoms", true);
// Network
Option<bool> NetworkEnable("Enable", false, "network");
Option<bool> ActAsServer("ActAsServer", false, "network");
OptionString DNS("DNS", "46.101.91.123", "network");
OptionString NetworkServer("server", "", "network");
Option<bool> EmulateBBA("EmulateBBA", false, "network");
#ifdef SUPPORT_DISPMANX
Option<bool> DispmanxMaintainAspect("maintain_aspect", true, "dispmanx");
#endif
#ifdef USE_OMX
Option<int> OmxAudioLatency("audio_latency", 100, "omx");
Option<bool> OmxAudioHdmi("audio_hdmi", true, "omx");
#endif
// Maple
Option<int> MouseSensitivity("MouseSensitivity", 100, "input");
Option<int> VirtualGamepadVibration("VirtualGamepadVibration", 20, "input");
std::array<Option<MapleDeviceType>, 4> MapleMainDevices {
Option<MapleDeviceType>("device1", MDT_SegaController, "input"),
Option<MapleDeviceType>("device2", MDT_None, "input"),
Option<MapleDeviceType>("device3", MDT_None, "input"),
Option<MapleDeviceType>("device4", MDT_None, "input"),
};
std::array<std::array<Option<MapleDeviceType>, 2>, 4> MapleExpansionDevices {
Option<MapleDeviceType>("device1.1", MDT_SegaVMU, "input"),
Option<MapleDeviceType>("device1.2", MDT_SegaVMU, "input"),
Option<MapleDeviceType>("device2.1", MDT_None, "input"),
Option<MapleDeviceType>("device2.2", MDT_None, "input"),
Option<MapleDeviceType>("device3.1", MDT_None, "input"),
Option<MapleDeviceType>("device3.2", MDT_None, "input"),
Option<MapleDeviceType>("device4.1", MDT_None, "input"),
Option<MapleDeviceType>("device4.2", MDT_None, "input"),
};
} // namespace config

402
core/cfg/option.h Normal file
View File

@ -0,0 +1,402 @@
/*
Copyright 2021 flyinghead
This file is part of Flycast.
Flycast is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Flycast is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Flycast. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <string>
#include <vector>
#include <array>
#include "cfg.h"
#include "hw/maple/maple_cfg.h"
extern int renderer_changed;
namespace config {
class BaseOption {
public:
virtual ~BaseOption() {}
virtual void save() const = 0;
virtual void load() = 0;
virtual void reset() = 0;
};
class Settings {
public:
void reset() {
for (const auto& o : options)
o->reset();
gameId.clear();
perGameConfig = false;
}
void load(bool gameSpecific) {
if (gameSpecific)
{
if (gameId.empty())
return;
if (!cfgHasSection(gameId))
return;
perGameConfig = true;
}
for (const auto& o : options)
o->load();
}
void save() {
cfgSetAutoSave(false);
for (const auto& o : options)
o->save();
cfgSetAutoSave(true);
}
const std::string& getGameId() const {
return gameId;
}
void setGameId(const std::string& gameId) {
this->gameId = gameId;
}
bool hasPerGameConfig() const {
return perGameConfig;
}
void setPerGameConfig(bool perGameConfig) {
this->perGameConfig = perGameConfig;
if (!perGameConfig) {
if (!gameId.empty())
cfgDeleteSection(gameId);
reset();
}
}
static Settings& instance() {
static Settings *_instance = new Settings();
return *_instance;
}
private:
std::vector<BaseOption *> options;
std::string gameId;
bool perGameConfig = false;
template<typename T, bool PerGameOption>
friend class Option;
};
// Missing in C++11
template <bool B, typename T = void>
using enable_if_t = typename std::enable_if<B, T>::type;
template<typename T, bool PerGameOption = true>
class Option : public BaseOption {
public:
Option(const std::string& name, T defaultValue = T(), const std::string& section = "config")
: section(section), name(name), value(defaultValue), defaultValue(defaultValue),
settings(Settings::instance())
{
settings.options.push_back(this);
}
virtual void reset() override {
value = defaultValue;
overridden = false;
}
virtual void load() override {
if (PerGameOption && settings.hasPerGameConfig())
set(doLoad(settings.getGameId(), section + "." + name));
else
{
set(doLoad(section, name));
if (cfgIsVirtual(section, name))
override(value);
}
}
virtual void save() const override
{
if (overridden) {
if (value == overriddenDefault)
return;
if (!settings.hasPerGameConfig())
// overridden options can only be saved in per-game settings
return;
}
else if (PerGameOption && settings.hasPerGameConfig())
{
if (value == doLoad(section, name))
return;
}
if (PerGameOption && settings.hasPerGameConfig())
doSave(settings.getGameId(), section + "." + name);
else
doSave(section, name);
}
T& get() { return value; }
void set(T v) { value = v; }
void override(T v) {
verify(PerGameOption);
overriddenDefault = v;
overridden = true;
value = v;
}
bool isReadOnly() const {
return overridden && !settings.hasPerGameConfig();
}
explicit operator T() const { return value; }
operator T&() { return value; }
T& operator=(const T& v) { set(v); return value; }
protected:
template <typename U = T>
enable_if_t<std::is_same<U, bool>::value, T>
doLoad(const std::string& section, const std::string& name) const
{
return cfgLoadBool(section, name, value);
}
template <typename U = T>
enable_if_t<(std::is_integral<U>::value || std::is_enum<U>::value)
&& !std::is_same<U, bool>::value, T>
doLoad(const std::string& section, const std::string& name) const
{
return (T)cfgLoadInt(section, name, (int)value);
}
template <typename U = T>
enable_if_t<std::is_same<U, std::string>::value, T>
doLoad(const std::string& section, const std::string& name) const
{
return cfgLoadStr(section, name, value);
}
template <typename U = T>
enable_if_t<std::is_same<float, U>::value, T>
doLoad(const std::string& section, const std::string& name) const
{
std::string strValue = cfgLoadStr(section, name, "");
if (strValue.empty())
return value;
else
return atof(strValue.c_str());
}
template <typename U = T>
enable_if_t<std::is_same<std::vector<std::string>, U>::value, T>
doLoad(const std::string& section, const std::string& name) const
{
std::string paths = cfgLoadStr(section, name, "");
if (paths.empty())
return value;
std::string::size_type start = 0;
std::vector<std::string> newValue;
while (true)
{
std::string::size_type end = paths.find(';', start);
if (end == std::string::npos)
end = paths.size();
if (start != end)
newValue.push_back(paths.substr(start, end - start));
if (end == paths.size())
break;
start = end + 1;
}
return newValue;
}
template <typename U = T>
enable_if_t<std::is_same<U, bool>::value>
doSave(const std::string& section, const std::string& name) const
{
cfgSaveBool(section, name, value);
}
template <typename U = T>
enable_if_t<(std::is_integral<U>::value || std::is_enum<U>::value)
&& !std::is_same<U, bool>::value>
doSave(const std::string& section, const std::string& name) const
{
cfgSaveInt(section, name, (int)value);
}
template <typename U = T>
enable_if_t<std::is_same<U, std::string>::value>
doSave(const std::string& section, const std::string& name) const
{
cfgSaveStr(section, name, value);
}
template <typename U = T>
enable_if_t<std::is_same<float, U>::value>
doSave(const std::string& section, const std::string& name) const
{
char buf[64];
snprintf(buf, sizeof(buf), "%f", value);
cfgSaveStr(section, name, buf);
}
template <typename U = T>
enable_if_t<std::is_same<std::vector<std::string>, U>::value>
doSave(const std::string& section, const std::string& name) const
{
std::string s;
for (auto& v : value)
{
if (s.empty())
s = v;
else
s += ";" + v;
}
cfgSaveStr(section, name, s);
}
std::string section;
std::string name;
T value;
T defaultValue;
T overriddenDefault = T();
bool overridden = false;
Settings& settings;
};
using OptionString = Option<std::string>;
// Dynarec
extern Option<bool> DynarecEnabled;
extern Option<bool> DynarecIdleSkip;
extern Option<bool> DynarecUnstableOpt;
extern Option<bool> DynarecSafeMode;
extern Option<bool> DisableVmem32;
// General
extern Option<int> Cable; // 0 -> VGA, 1 -> VGA, 2 -> RGB, 3 -> TV Composite
extern Option<int> Region; // 0 -> JP, 1 -> USA, 2 -> EU, 3 -> default
extern Option<int> Broadcast; // 0 -> NTSC, 1 -> PAL, 2 -> PAL/M, 3 -> PAL/N, 4 -> default
extern Option<int> Language; // 0 -> JP, 1 -> EN, 2 -> DE, 3 -> FR, 4 -> SP, 5 -> IT, 6 -> default
extern Option<bool> FullMMU;
extern Option<bool> ForceWindowsCE;
extern Option<bool> AutoSavestate;
// Sound
extern Option<bool> LimitFPS;
extern Option<bool> DSPEnabled;
extern Option<bool> DisableSound;
extern Option<int> AudioBufferSize; //In samples ,*4 for bytes (1024)
extern OptionString AudioBackend;
// Rendering
class RendererOption : public Option<RenderType> {
public:
RendererOption()
: Option<RenderType>("pvr.rend", RenderType::OpenGL) {}
bool isOpenGL() const {
return value == RenderType::OpenGL || value == RenderType::OpenGL_OIT;
}
RenderType& operator=(const RenderType& v) { set(v); return value; }
virtual void load() override {
RenderType current = value;
Option<RenderType>::load();
if (current != value) {
::renderer_changed = (int)value;
value = current;
}
}
virtual void reset() override {
RenderType current = value;
Option<RenderType>::reset();
if (current != value) {
::renderer_changed = (int)value;
value = current;
}
}
};
extern RendererOption RendererType;
extern Option<bool> UseMipmaps;
extern Option<bool> Widescreen;
extern Option<bool> ShowFPS;
extern Option<bool> RenderToTextureBuffer;
extern Option<int> RenderToTextureUpscale;
extern Option<bool> TranslucentPolygonDepthMask;
extern Option<bool> ModifierVolumes;
extern Option<bool> Clipping;
extern Option<int> TextureUpscale;
extern Option<int> MaxFilteredTextureSize;
extern Option<float> ExtraDepthScale;
extern Option<bool> CustomTextures;
extern Option<bool> DumpTextures;
extern Option<int> ScreenScaling; // in percent. 50 means half the native resolution
extern Option<int> ScreenStretching; // in percent. 150 means stretch from 4/3 to 6/3
extern Option<bool> Fog;
extern Option<bool> FloatVMUs;
extern Option<bool> Rotate90;
extern Option<bool> PerStripSorting;
extern Option<bool> DelayFrameSwapping; // Delay swapping frame until FB_R_SOF matches FB_W_SOF
extern Option<bool> WidescreenGameHacks;
extern std::array<Option<int>, 4> CrosshairColor;
extern Option<int> SkipFrame;
extern Option<int> MaxThreads;
extern Option<int> AutoSkipFrame; // 0: none, 1: some, 2: more
// Misc
extern Option<bool> SerialConsole;
extern Option<bool> SerialPTY;
extern Option<bool> UseReios;
extern Option<bool> OpenGlChecks;
extern Option<std::vector<std::string>, false> ContentPath;
extern Option<bool, false> HideLegacyNaomiRoms;
// Network
extern Option<bool> NetworkEnable;
extern Option<bool> ActAsServer;
extern OptionString DNS;
extern OptionString NetworkServer;
extern Option<bool> EmulateBBA;
#ifdef SUPPORT_DISPMANX
extern Option<bool> DispmanxMaintainAspect;
#endif
#ifdef USE_OMX
extern Option<int> OmxAudioLatency;
extern Option<bool> OmxAudioHdmi;
#endif
// Maple
extern Option<int> MouseSensitivity;
extern Option<int> VirtualGamepadVibration;
extern std::array<Option<MapleDeviceType>, 4> MapleMainDevices;
extern std::array<std::array<Option<MapleDeviceType>, 2>, 4> MapleExpansionDevices;
} // namespace config

View File

@ -234,8 +234,8 @@ const Cheat CheatManager::_widescreen_cheats[] =
{ "T9103M ", nullptr, { 0x25C714, 0x25C744, 0 }, { 0x43F00000, 0x3F400000 } }, // Sorcerian - Shichisei Mahou no Shito
{ "T1401D 50", nullptr, { 0x2D6138, 0 }, { 0x3F400000 } }, // Soul Calibur (PAL)
{ "T1401N ", nullptr, { 0x266C28, 0 }, { 0x3F400000 } }, // Soul Calibur (USA)
{ "T36802N ", nullptr, { 0x129FA0, 0x12A9BC, 0x1C9FDC, 0 },
{ 0x3EF00000, 0x3EF00000, 0x000000F0 } }, // Soul Reaver (PAL) Code 2 is a Render Fix
{ "T36802N ", " E ", { 0x129FA0, 0x12A9BC, 0x1C9FDC, 0 },
{ 0x3EF55555, 0x3EF55555, 0x000000F0 } }, // Soul Reaver (PAL) Code 2 is a Render Fix
{ "HDR-0190 ", nullptr, { 0x14D3E0, 0 }, { 0x3F400000 } }, // Space Channel 5 Part 2 (JP)
{ "T1216M ", nullptr, { 0x017C38, 0x17F00, 0 }, { 0x3A99999A, 0x3A99999A } }, // Spawn - In the Demon's Hand v1.003 (JP)
{ "T1216N ", nullptr, { 0x017C58, 0x17F20, 0 }, { 0x3A99999A, 0x3A99999A } }, // Spawn - In the Demon's Hand v1.000 (US)
@ -305,7 +305,7 @@ CheatManager cheatManager;
bool CheatManager::Reset()
{
_widescreen_cheat = nullptr;
if (!settings.rend.WidescreenGameHacks)
if (!config::WidescreenGameHacks)
return false;
if (settings.platform.system == DC_PLATFORM_DREAMCAST)
{

View File

@ -24,7 +24,8 @@ void *dc_run(void*)
rend_set_fb_scale(1.0, 1.0);
char frame_path[512];
cfgLoadStr("config", "image", frame_path, "null");
std::string s = cfgLoadStr("config", "image", "null");
strcpy(frame_path, s.c_str());
printf("Loading %s\n", frame_path);

View File

@ -23,8 +23,7 @@
#include <map>
#include <vector>
void InitSettings();
void LoadSettings(bool game_specific);
void LoadGameSpecificSettings();
void SaveSettings();
extern std::atomic<bool> loading_canceled;
@ -35,6 +34,7 @@ void dc_init();
void* dc_run(void*);
void dc_term();
void dc_stop();
void dc_term_game();
void dc_request_reset();
void dc_exit();
void dc_resume();

View File

@ -89,7 +89,7 @@ const int AICA_TICK = 145125; // 44.1 KHz / 32
static int AicaUpdate(int tag, int c, int j)
{
arm_Run(32);
if (!settings.aica.NoBatch && !settings.aica.DSPEnabled)
if (!settings.aica.NoBatch)
AICA_Sample32();
return AICA_TICK;
@ -105,7 +105,7 @@ void libAICA_TimeStep()
SCIPD->SAMPLE_DONE = 1;
MCIPD->SAMPLE_DONE = 1;
if (settings.aica.NoBatch || settings.aica.DSPEnabled)
if (settings.aica.NoBatch)
AICA_Sample();
//Make sure sh4/arm interrupt system is up to date :)

View File

@ -25,6 +25,7 @@
#include "dsp.h"
#include "oslib/audiostream.h"
#include "hw/gdrom/gdrom_if.h"
#include "cfg/option.h"
#include <algorithm>
#include <cmath>
@ -532,7 +533,7 @@ struct ChannelEx
Step(oLeft, oRight, oDsp);
*VolMix.DSPOut += oDsp;
if (oLeft + oRight == 0 && !settings.aica.DSPEnabled)
if (oLeft + oRight == 0 && !config::DSPEnabled)
oLeft = oRight = oDsp >> 4;
mixl+=oLeft;
@ -1406,15 +1407,12 @@ void AICA_Sample32()
//Add CDDA / DSP effect(s)
//CDDA
if (settings.aica.CDDAMute==0)
{
VOLPAN(EXTS0L,dsp_out_vol[16].EFSDL,dsp_out_vol[16].EFPAN,mixl,mixr);
VOLPAN(EXTS0R,dsp_out_vol[17].EFSDL,dsp_out_vol[17].EFPAN,mixl,mixr);
}
VOLPAN(EXTS0L, dsp_out_vol[16].EFSDL, dsp_out_vol[16].EFPAN, mixl, mixr);
VOLPAN(EXTS0R, dsp_out_vol[17].EFSDL, dsp_out_vol[17].EFPAN, mixl, mixr);
/*
no dsp for now -- needs special handling of oDSP for ch paraller version ...
if (settings.aica.DSPEnabled)
if (config::DSPEnabled)
{
dsp_step();
@ -1460,7 +1458,7 @@ void AICA_Sample32()
clip16(mixl);
clip16(mixr);
if (!fast_forward_mode && !settings.aica.NoSound)
if (!fast_forward_mode && !config::DisableSound)
WriteSample(mixr,mixl);
}
}
@ -1490,20 +1488,13 @@ void AICA_Sample()
//Add CDDA / DSP effect(s)
//CDDA
if (settings.aica.CDDAMute==0)
{
VOLPAN(EXTS0L,dsp_out_vol[16].EFSDL,dsp_out_vol[16].EFPAN,mixl,mixr);
VOLPAN(EXTS0R,dsp_out_vol[17].EFSDL,dsp_out_vol[17].EFPAN,mixl,mixr);
VOLPAN(EXTS0L, dsp_out_vol[16].EFSDL, dsp_out_vol[16].EFPAN, mixl, mixr);
VOLPAN(EXTS0R, dsp_out_vol[17].EFSDL, dsp_out_vol[17].EFPAN, mixl, mixr);
DSPData->EXTS[0] = EXTS0L;
DSPData->EXTS[1] = EXTS0R;
}
else
{
DSPData->EXTS[0] = 0;
DSPData->EXTS[1] = 0;
}
if (settings.aica.DSPEnabled)
DSPData->EXTS[0] = EXTS0L;
DSPData->EXTS[1] = EXTS0R;
if (config::DSPEnabled)
{
dsp_step();
@ -1511,7 +1502,7 @@ void AICA_Sample()
VOLPAN(*(s16*)&DSPData->EFREG[i], dsp_out_vol[i].EFSDL, dsp_out_vol[i].EFPAN, mixl, mixr);
}
if (fast_forward_mode || settings.aica.NoSound)
if (fast_forward_mode || config::DisableSound)
return;
//Mono !

View File

@ -13,6 +13,7 @@
#include "hw/pvr/pvr_sb_regs.h"
#include "emulator.h"
#include "hw/bba/bba.h"
#include "cfg/option.h"
std::array<RegisterStruct, 0x540> sb_regs;
@ -581,7 +582,7 @@ void sb_Init()
maple_Init();
aica_sb_Init();
if (settings.network.EmulateBBA)
if (config::EmulateBBA)
bba_Init();
else
ModemInit();
@ -598,7 +599,7 @@ void sb_Reset(bool hard)
SB_FFST_rc = 0;
SB_FFST = 0;
if (settings.network.EmulateBBA)
if (config::EmulateBBA)
bba_Reset(hard);
else
ModemTerm();
@ -615,7 +616,7 @@ void sb_Reset(bool hard)
void sb_Term()
{
if (settings.network.EmulateBBA)
if (config::EmulateBBA)
bba_Term();
else
ModemTerm();

View File

@ -15,6 +15,7 @@
#include "hw/sh4/sh4_mem.h"
#include "reios/reios.h"
#include "hw/bba/bba.h"
#include "cfg/option.h"
MemChip *sys_rom;
MemChip *sys_nvmem;
@ -110,20 +111,20 @@ void FixUpFlash()
static_cast<DCFlashChip*>(sys_nvmem)->Validate();
// overwrite factory flash settings
if (settings.dreamcast.region <= 2)
if (config::Region <= 2)
{
sys_nvmem->data[0x1a002] = '0' + settings.dreamcast.region;
sys_nvmem->data[0x1a0a2] = '0' + settings.dreamcast.region;
sys_nvmem->data[0x1a002] = '0' + config::Region;
sys_nvmem->data[0x1a0a2] = '0' + config::Region;
}
if (settings.dreamcast.language <= 5)
if (config::Language <= 5)
{
sys_nvmem->data[0x1a003] = '0' + settings.dreamcast.language;
sys_nvmem->data[0x1a0a3] = '0' + settings.dreamcast.language;
sys_nvmem->data[0x1a003] = '0' + config::Language;
sys_nvmem->data[0x1a0a3] = '0' + config::Language;
}
if (settings.dreamcast.broadcast <= 3)
if (config::Broadcast <= 3)
{
sys_nvmem->data[0x1a004] = '0' + settings.dreamcast.broadcast;
sys_nvmem->data[0x1a0a4] = '0' + settings.dreamcast.broadcast;
sys_nvmem->data[0x1a004] = '0' + config::Broadcast;
sys_nvmem->data[0x1a0a4] = '0' + config::Broadcast;
}
// overwrite user settings
@ -143,8 +144,8 @@ void FixUpFlash()
u32 now = GetRTC_now();
syscfg.time_lo = now & 0xffff;
syscfg.time_hi = now >> 16;
if (settings.dreamcast.language <= 5)
syscfg.lang = settings.dreamcast.language;
if (config::Language <= 5)
syscfg.lang = config::Language;
if (static_cast<DCFlashChip*>(sys_nvmem)->WriteBlock(FLASH_PT_USER, FLASH_USER_SYSCFG, &syscfg) != 1)
WARN_LOG(FLASHROM, "Failed to save time and language to flash RAM");
@ -208,7 +209,7 @@ void SaveRomFiles()
bool LoadHle()
{
if (!nvmem_load())
WARN_LOG(FLASHROM, "No nvmem loaded\n");
WARN_LOG(FLASHROM, "No nvmem loaded");
reios_reset(sys_rom->data);
@ -313,7 +314,7 @@ T DYNACALL ReadMem_area0(u32 addr)
{
if (settings.platform.system != DC_PLATFORM_DREAMCAST)
return (T)libExtDevice_ReadMem_A0_006(addr, sz);
else if (!settings.network.EmulateBBA)
else if (!config::EmulateBBA)
return (T)ModemReadMem_A0_006(addr, sz);
else
return (T)0;
@ -344,7 +345,7 @@ T DYNACALL ReadMem_area0(u32 addr)
{
if (settings.platform.system == DC_PLATFORM_NAOMI)
return (T)libExtDevice_ReadMem_A0_010(addr, sz);
else if (settings.network.EmulateBBA)
else if (config::EmulateBBA)
return (T)bba_ReadMem(addr, sz);
else
return (T)0;
@ -404,7 +405,7 @@ void DYNACALL WriteMem_area0(u32 addr,T data)
{
if (settings.platform.system != DC_PLATFORM_DREAMCAST)
libExtDevice_WriteMem_A0_006(addr, data, sz);
else if (!settings.network.EmulateBBA)
else if (!config::EmulateBBA)
ModemWriteMem_A0_006(addr, data, sz);
}
//map 0x0060 to 0x006F
@ -432,7 +433,7 @@ void DYNACALL WriteMem_area0(u32 addr,T data)
{
if (settings.platform.system == DC_PLATFORM_NAOMI)
libExtDevice_WriteMem_A0_010(addr, data, sz);
else if (settings.network.EmulateBBA)
else if (config::EmulateBBA)
bba_WriteMem(addr, data, sz);
}
else

View File

@ -3,6 +3,7 @@
#include "maple_if.h"
#include "hw/naomi/naomi_cart.h"
#include "input/gamepad_device.h"
#include "cfg/option.h"
static u8 GetBtFromSgn(s8 val)
{
@ -242,14 +243,14 @@ void mcfg_CreateDevices()
{
for (int bus = 0; bus < MAPLE_PORTS; ++bus)
{
switch ((MapleDeviceType)settings.input.maple_devices[bus])
switch (config::MapleMainDevices[bus])
{
case MDT_SegaController:
mcfg_Create(MDT_SegaController, bus, 5);
if (settings.input.maple_expansion_devices[bus][0] != MDT_None)
mcfg_Create((MapleDeviceType)settings.input.maple_expansion_devices[bus][0], bus, 0);
if (settings.input.maple_expansion_devices[bus][1] != MDT_None)
mcfg_Create((MapleDeviceType)settings.input.maple_expansion_devices[bus][1], bus, 1);
if (config::MapleExpansionDevices[bus][0] != MDT_None)
mcfg_Create(config::MapleExpansionDevices[bus][0], bus, 0);
if (config::MapleExpansionDevices[bus][1] != MDT_None)
mcfg_Create(config::MapleExpansionDevices[bus][1], bus, 1);
break;
case MDT_Keyboard:
@ -262,27 +263,27 @@ void mcfg_CreateDevices()
case MDT_LightGun:
mcfg_Create(MDT_LightGun, bus, 5);
if (settings.input.maple_expansion_devices[bus][0] != MDT_None)
mcfg_Create((MapleDeviceType)settings.input.maple_expansion_devices[bus][0], bus, 0);
if (config::MapleExpansionDevices[bus][0] != MDT_None)
mcfg_Create(config::MapleExpansionDevices[bus][0], bus, 0);
break;
case MDT_TwinStick:
mcfg_Create(MDT_TwinStick, bus, 5);
if (settings.input.maple_expansion_devices[bus][0] != MDT_None)
mcfg_Create((MapleDeviceType)settings.input.maple_expansion_devices[bus][0], bus, 0);
if (config::MapleExpansionDevices[bus][0] != MDT_None)
mcfg_Create(config::MapleExpansionDevices[bus][0], bus, 0);
break;
case MDT_AsciiStick:
mcfg_Create(MDT_AsciiStick, bus, 5);
if (settings.input.maple_expansion_devices[bus][0] != MDT_None)
mcfg_Create((MapleDeviceType)settings.input.maple_expansion_devices[bus][0], bus, 0);
if (config::MapleExpansionDevices[bus][0] != MDT_None)
mcfg_Create(config::MapleExpansionDevices[bus][0], bus, 0);
break;
case MDT_None:
break;
default:
WARN_LOG(MAPLE, "Invalid device type %d for port %d", settings.input.maple_devices[bus], bus);
WARN_LOG(MAPLE, "Invalid device type %d for port %d", (MapleDeviceType)config::MapleMainDevices[bus], bus);
break;
}
}

View File

@ -1,6 +1,25 @@
#pragma once
#include "types.h"
enum MapleDeviceType
{
MDT_SegaController,
MDT_SegaVMU,
MDT_Microphone,
MDT_PurupuruPack,
MDT_AsciiStick,
MDT_Keyboard,
MDT_Mouse,
MDT_LightGun,
MDT_TwinStick,
MDT_NaomiJamma,
MDT_None,
MDT_Count
};
enum PlainJoystickAxisId
{
PJAI_X1 = 0,

View File

@ -4,6 +4,7 @@
#include "hw/pvr/spg.h"
#include "stdclass.h"
#include "oslib/audiostream.h"
#include "cfg/option.h"
#include <zlib.h>
@ -1362,3 +1363,60 @@ maple_device* maple_Create(MapleDeviceType type)
return rv;
}
void SetMousePosition(int x, int y, int width, int height, u32 mouseId)
{
if (mouseId == 0)
{
mo_x_phy = x;
mo_y_phy = y;
}
if (config::Rotate90)
{
int t = y;
y = x;
x = height - t;
std::swap(width, height);
}
float fx, fy;
if ((float)width / height >= 640.f / 480.f)
{
float scale = 480.f / height;
fy = y * scale;
scale /= config::ScreenStretching / 100.f;
fx = (x - (width - 640.f / scale) / 2.f) * scale;
}
else
{
float scale = 640.f / width;
fx = x * scale;
scale /= config::ScreenStretching / 100.f;
fy = (y - (height - 480.f / scale) / 2.f) * scale;
}
mo_x_abs[mouseId] = (int)std::round(fx);
mo_y_abs[mouseId] = (int)std::round(fy);
if (mo_x_prev[mouseId] != -1)
{
mo_x_delta[mouseId] += (f32)(x - mo_x_prev[mouseId]) * config::MouseSensitivity / 100.f;
mo_y_delta[mouseId] += (f32)(y - mo_y_prev[mouseId]) * config::MouseSensitivity / 100.f;
}
mo_x_prev[mouseId] = x;
mo_y_prev[mouseId] = y;
}
void SetRelativeMousePosition(int xrel, int yrel, u32 mouseId)
{
if (config::Rotate90)
{
std::swap(xrel, yrel);
xrel = -xrel;
}
float dx = (float)xrel * config::MouseSensitivity / 100.f;
float dy = (float)yrel * config::MouseSensitivity / 100.f;
mo_x_delta[mouseId] += dx;
mo_y_delta[mouseId] += dy;
mo_x_abs[mouseId] += (int)std::round(dx);
mo_y_abs[mouseId] += (int)std::round(dy);
}

View File

@ -6,25 +6,6 @@
#include <cmath>
#include "input/gamepad.h"
enum MapleDeviceType
{
MDT_SegaController,
MDT_SegaVMU,
MDT_Microphone,
MDT_PurupuruPack,
MDT_AsciiStick,
MDT_Keyboard,
MDT_Mouse,
MDT_LightGun,
MDT_TwinStick,
MDT_NaomiJamma,
MDT_None,
MDT_Count
};
enum MapleFunctionID
{
MFID_0_Input = 0x01000000, //DC Controller, Lightgun buttons, arcade stick .. stuff like that
@ -199,62 +180,8 @@ extern s32 mo_y_phy;
extern s32 mo_x_prev[4];
extern s32 mo_y_prev[4];
static inline void SetMousePosition(int x, int y, int width, int height, u32 mouseId = 0)
{
if (mouseId == 0)
{
mo_x_phy = x;
mo_y_phy = y;
}
if (settings.rend.Rotate90)
{
int t = y;
y = x;
x = height - t;
std::swap(width, height);
}
float fx, fy;
if ((float)width / height >= 640.f / 480.f)
{
float scale = 480.f / height;
fy = y * scale;
scale /= settings.rend.ScreenStretching / 100.f;
fx = (x - (width - 640.f / scale) / 2.f) * scale;
}
else
{
float scale = 640.f / width;
fx = x * scale;
scale /= settings.rend.ScreenStretching / 100.f;
fy = (y - (height - 480.f / scale) / 2.f) * scale;
}
mo_x_abs[mouseId] = (int)std::round(fx);
mo_y_abs[mouseId] = (int)std::round(fy);
if (mo_x_prev[mouseId] != -1)
{
mo_x_delta[mouseId] += (f32)(x - mo_x_prev[mouseId]) * settings.input.MouseSensitivity / 100.f;
mo_y_delta[mouseId] += (f32)(y - mo_y_prev[mouseId]) * settings.input.MouseSensitivity / 100.f;
}
mo_x_prev[mouseId] = x;
mo_y_prev[mouseId] = y;
}
static inline void SetRelativeMousePosition(int xrel, int yrel, u32 mouseId = 0)
{
if (settings.rend.Rotate90)
{
std::swap(xrel, yrel);
xrel = -xrel;
}
float dx = (float)xrel * settings.input.MouseSensitivity / 100.f;
float dy = (float)yrel * settings.input.MouseSensitivity / 100.f;
mo_x_delta[mouseId] += dx;
mo_y_delta[mouseId] += dy;
mo_x_abs[mouseId] += (int)std::round(dx);
mo_y_abs[mouseId] += (int)std::round(dy);
}
void SetMousePosition(int x, int y, int width, int height, u32 mouseId = 0);
void SetRelativeMousePosition(int xrel, int yrel, u32 mouseId = 0);
#define SWAP32(a) ((((a) & 0xff) << 24) | (((a) & 0xff00) << 8) | (((a) >> 8) & 0xff00) | (((a) >> 24) & 0xff))

View File

@ -372,7 +372,7 @@ bool vmem32_init()
#ifdef _WIN32
return false;
#else
if (settings.dynarec.disable_vmem32 || !_nvmem_4gb_space())
if (config::DisableVmem32 || !_nvmem_4gb_space())
return false;
vmem32_inited = true;
vmem32_flush_mmu();

View File

@ -35,34 +35,18 @@
#include "stdclass.h"
#include "emulator.h"
#include "rend/gui.h"
#include "cfg/option.h"
Cartridge *CurrentCartridge;
bool bios_loaded = false;
#ifdef _WIN32
#include <windows.h>
typedef HANDLE fd_t;
#define INVALID_FD INVALID_HANDLE_VALUE
#else
typedef int fd_t;
#define INVALID_FD -1
#include <unistd.h>
#include <fcntl.h>
#include <cerrno>
#endif
fd_t* RomCacheMap = NULL;
u32 RomCacheMapCount;
char naomi_game_id[33];
InputDescriptors *NaomiGameInputs;
u8 *naomi_default_eeprom;
bool naomi_rotate_screen;
extern MemChip *sys_rom;
static bool naomi_LoadBios(const char *filename, Archive *child_archive, Archive *parent_archive, int region)
static bool loadBios(const char *filename, Archive *child_archive, Archive *parent_archive, int region)
{
int biosid = 0;
for (; BIOS[biosid].name != NULL; biosid++)
@ -166,31 +150,50 @@ static bool naomi_LoadBios(const char *filename, Archive *child_archive, Archive
static Game *FindGame(const char *filename)
{
const char *p = strrchr(filename, '/');
#ifdef _WIN32
const char *p2 = strrchr(filename, '\\');
if (p2 > p)
p = p2;
#endif
if (p == NULL)
p = filename;
else
p++;
char game_name[128];
strncpy(game_name, p, sizeof(game_name) - 1);
game_name[sizeof(game_name) - 1] = 0;
char *dot = strrchr(game_name, '.');
if (dot != NULL)
*dot = 0;
std::string gameName = get_file_basename(filename);
size_t folder_pos = get_last_slash_pos(gameName);
if (folder_pos != std::string::npos)
gameName = gameName.substr(folder_pos + 1);
int gameid = 0;
for (; Games[gameid].name != NULL; gameid++)
if (!stricmp(Games[gameid].name, game_name))
break;
if (Games[gameid].name == NULL)
return NULL;
for (int i = 0; Games[i].name != nullptr; i++)
if (gameName == Games[i].name)
return &Games[i];
return &Games[gameid];
return nullptr;
}
void naomi_cart_LoadBios(const char *filename)
{
Game *game = FindGame(filename);
if (game == nullptr)
return;
// Open archive and parent archive if any
std::unique_ptr<Archive> archive(OpenArchive(filename));
std::unique_ptr<Archive> parent_archive;
if (game->parent_name != NULL)
parent_archive.reset(OpenArchive((get_game_dir() + game->parent_name).c_str()));
const char *bios = "naomi";
if (game->bios != nullptr)
bios = game->bios;
u32 region_flag = std::min((int)config::Region, (int)game->region_flag);
if (game->region_flag == REGION_EXPORT_ONLY)
region_flag = REGION_EXPORT;
if (!loadBios(bios, archive.get(), parent_archive.get(), region_flag))
{
WARN_LOG(NAOMI, "Warning: Region %d bios not found in %s", region_flag, bios);
if (!loadBios(bios, archive.get(), parent_archive.get(), -1))
{
// If a specific BIOS is needed for this game, fail.
if (game->bios != NULL || !bios_loaded)
throw NaomiCartException(std::string("Error: cannot load BIOS ") + (game->bios != NULL ? game->bios : "naomi.zip"));
// otherwise use the default BIOS
}
}
bios_loaded = true;
}
static void naomi_cart_LoadZip(const char *filename)
@ -221,27 +224,7 @@ static void naomi_cart_LoadZip(const char *filename)
}
// Load the BIOS
const char *bios = "naomi";
if (game->bios != NULL)
bios = game->bios;
u32 region_flag = settings.dreamcast.region;
if (region_flag > game->region_flag)
region_flag = game->region_flag;
if (game->region_flag == REGION_EXPORT_ONLY)
region_flag = REGION_EXPORT;
if (!naomi_LoadBios(bios, archive.get(), parent_archive.get(), region_flag))
{
WARN_LOG(NAOMI, "Warning: Region %d bios not found in %s", region_flag, bios);
if (!naomi_LoadBios(bios, archive.get(), parent_archive.get(), -1))
{
// If a specific BIOS is needed for this game, fail.
if (game->bios != NULL || !bios_loaded)
throw NaomiCartException(std::string("Error: cannot load BIOS ") + (game->bios != NULL ? game->bios : "naomi.zip"));
// otherwise use the default BIOS
}
}
bios_loaded = true;
naomi_cart_LoadBios(filename);
// Now load the cartridge data
try {
@ -370,7 +353,8 @@ static void naomi_cart_LoadZip(const char *filename)
return;
if (naomi_default_eeprom == NULL && game->eeprom_dump != NULL)
naomi_default_eeprom = game->eeprom_dump;
naomi_rotate_screen = game->rotation_flag == ROT270;
if (game->rotation_flag == ROT270)
config::Rotate90.override(true);
CurrentCartridge->Init();
if (loading_canceled)
@ -381,7 +365,7 @@ static void naomi_cart_LoadZip(const char *filename)
strcpy(naomi_game_id, game->name);
NOTICE_LOG(NAOMI, "NAOMI GAME ID [%s]", naomi_game_id);
} catch (ReicastException& ex) {
} catch (const ReicastException& ex) {
delete CurrentCartridge;
CurrentCartridge = NULL;
@ -389,68 +373,48 @@ static void naomi_cart_LoadZip(const char *filename)
}
}
#ifdef _WIN32
#define CloseFile(f) CloseHandle(f)
#else
#define CloseFile(f) close(f)
#endif
void naomi_cart_LoadRom(const char* file)
{
INFO_LOG(NAOMI, "nullDC-Naomi rom loader v1.2");
naomi_cart_Close();
size_t folder_pos = strlen(file) - 1;
while (folder_pos>1 && (file[folder_pos] != '\\' && file[folder_pos] != '/'))
folder_pos--;
std::string extension = get_file_extension(file);
folder_pos++;
// FIXME: Data loss if buffer is too small
char t[512];
strncpy(t, file, sizeof(t));
t[sizeof(t) - 1] = '\0';
std::vector<std::string> files;
std::vector<u32> fstart;
std::vector<u32> fsize;
u32 setsize = 0;
bool raw_bin_file = false;
const char *pdot = strrchr(file, '.');
if (pdot != NULL
&& (!strcmp(pdot, ".zip") || !strcmp(pdot, ".ZIP")
|| !strcmp(pdot, ".7z") || !strcmp(pdot, ".7Z")))
if (extension == "zip" || extension == "7z")
{
naomi_cart_LoadZip(file);
return;
}
// Try to load BIOS from naomi.zip
if (!naomi_LoadBios("naomi", NULL, NULL, settings.dreamcast.region))
if (!loadBios("naomi", NULL, NULL, config::Region))
{
WARN_LOG(NAOMI, "Warning: Region %d bios not found in naomi.zip", settings.dreamcast.region);
if (!naomi_LoadBios("naomi", NULL, NULL, -1))
WARN_LOG(NAOMI, "Warning: Region %d bios not found in naomi.zip", config::Region.get());
if (!loadBios("naomi", NULL, NULL, -1))
{
if (!bios_loaded)
throw new ReicastException("Error: cannot load BIOS from naomi.zip");
}
}
u8* RomPtr;
u32 RomSize;
std::string folder;
std::vector<std::string> files;
std::vector<u32> fstart;
std::vector<u32> fsize;
u32 romSize = 0;
if (pdot != NULL && (!strcmp(pdot, ".lst") || !strcmp(pdot, ".LST")))
if (extension == "lst")
{
// LST file
size_t folder_pos = get_last_slash_pos(file);
if (folder_pos != std::string::npos)
folder = std::string(file).substr(0, folder_pos + 1);
FILE* fl = nowide::fopen(t, "r");
FILE *fl = nowide::fopen(file, "r");
if (!fl)
throw new ReicastException("Error: can't open " + std::string(t));
throw new ReicastException("Error: can't open " + std::string(file));
char* line = std::fgets(t, 512, fl);
char t[512];
char* line = std::fgets(t, sizeof(t), fl);
if (!line)
{
std::fclose(fl);
@ -461,19 +425,18 @@ void naomi_cart_LoadRom(const char* file)
if (!eon)
DEBUG_LOG(NAOMI, "+Loading naomi rom that has no name");
else
{
*eon = 0;
DEBUG_LOG(NAOMI, "+Loading naomi rom : %s", line);
}
DEBUG_LOG(NAOMI, "+Loading naomi rom : %s", line);
line = std::fgets(t, 512, fl);
line = std::fgets(t, sizeof(t), fl);
if (!line)
{
std::fclose(fl);
throw new ReicastException("Error: Invalid LST file");
}
RomSize = 0;
while (line)
{
char filename[512];
@ -483,147 +446,86 @@ void naomi_cart_LoadRom(const char* file)
files.push_back(filename);
fstart.push_back(addr);
fsize.push_back(sz);
setsize += sz;
RomSize = std::max(RomSize, (addr + sz));
romSize = std::max(romSize, (addr + sz));
}
else if (line[0] != 0 && line[0] != '\n' && line[0] != '\r')
WARN_LOG(NAOMI, "Warning: invalid line in .lst file: %s", line);
line = std::fgets(t, 512, fl);
line = std::fgets(t, sizeof(t), fl);
}
std::fclose(fl);
}
else
{
// BIN loading
FILE* fp = nowide::fopen(t, "rb");
FILE* fp = nowide::fopen(file, "rb");
if (fp == NULL)
throw new ReicastException("Error: can't open " + std::string(t));
throw new ReicastException("Error: can't open " + std::string(file));
std::fseek(fp, 0, SEEK_END);
u32 file_size = std::ftell(fp);
u32 file_size = (u32)std::ftell(fp);
std::fclose(fp);
files.push_back(t);
files.push_back(file);
fstart.push_back(0);
fsize.push_back(file_size);
setsize = file_size;
RomSize = file_size;
raw_bin_file = true;
romSize = file_size;
}
INFO_LOG(NAOMI, "+%zd romfiles, %.2f MB set size, %.2f MB set address space", files.size(), setsize / 1024.f / 1024.f, RomSize / 1024.f / 1024.f);
INFO_LOG(NAOMI, "+%zd romfiles, %.2f MB set address space", files.size(), romSize / 1024.f / 1024.f);
if (RomCacheMap)
{
for (u32 i = 0; i < RomCacheMapCount; i++)
if (RomCacheMap[i] != INVALID_FD)
CloseFile(RomCacheMap[i]);
RomCacheMapCount = 0;
delete[] RomCacheMap;
}
RomCacheMapCount = (u32)files.size();
RomCacheMap = new fd_t[files.size()]();
//Allocate space for the ram, so we are sure we have a segment of continuous ram
RomPtr = (u8*)mem_region_reserve(NULL, RomSize);
verify(RomPtr != NULL);
// Allocate space for the rom
u8 *romBase = (u8 *)malloc(romSize);
verify(romBase != nullptr);
bool load_error = false;
//Create File Mapping Objects
for (size_t i = 0; i<files.size(); i++)
{
if (!raw_bin_file)
FILE *fp = nullptr;
if (files[i] != "null")
{
strncpy(t, file, sizeof(t));
t[sizeof(t) - 1] = '\0';
t[folder_pos] = 0;
strcat(t, files[i].c_str());
}
else
{
strncpy(t, files[i].c_str(), sizeof(t));
t[sizeof(t) - 1] = '\0';
std::string file(folder + files[i]);
fp = nowide::fopen(file.c_str(), "rb");
if (fp == nullptr)
{
ERROR_LOG(NAOMI, "Unable to open file %s: error %d", file.c_str(), errno);
load_error = true;
break;
}
}
u8* romDest = romBase + fstart[i];
fd_t RomCache;
if (strcmp(files[i].c_str(), "null") == 0)
{
RomCacheMap[i] = INVALID_FD;
continue;
}
// FIXME use nowide::fopen instead
#ifdef _WIN32
RomCache = CreateFile(t, FILE_READ_ACCESS, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
#else
RomCache = open(t, O_RDONLY);
#endif
if (RomCache == INVALID_FD)
{
ERROR_LOG(NAOMI, "-Unable to read file %s: error %d", t, errno);
RomCacheMap[i] = INVALID_FD;
load_error = true;
break;
}
#ifdef _WIN32
// Windows doesn't allow mapping a read-only file to a memory area larger than the file size
BY_HANDLE_FILE_INFORMATION file_info;
GetFileInformationByHandle(RomCache, &file_info);
fsize[i] = file_info.nFileSizeLow;
RomCacheMap[i] = CreateFileMapping(RomCache, 0, PAGE_READONLY, 0, fsize[i], 0);
verify(RomCacheMap[i] != NULL);
verify(CloseHandle(RomCache));
#else
RomCacheMap[i] = RomCache;
#endif
verify(RomCacheMap[i] != INVALID_FD);
//printf("-Preparing \"%s\" at 0x%08X, size 0x%08X\n", files[i].c_str(), fstart[i], fsize[i]);
}
//Release the segment we reserved so we can map the files there
mem_region_release(RomPtr, RomSize);
if (load_error)
{
for (size_t i = 0; i < files.size(); i++)
if (RomCacheMap[i] != INVALID_FD)
CloseFile(RomCacheMap[i]);
throw new ReicastException("Error: Failed to load BIN/DAT file");
}
//We have all file mapping objects, we start to map the ram
//Map the files into the segment of the ram that was reserved
for (size_t i = 0; i<RomCacheMapCount; i++)
{
u8* RomDest = RomPtr + fstart[i];
if (RomCacheMap[i] == INVALID_FD)
if (fp == nullptr)
{
//printf("-Reserving ram at 0x%08X, size 0x%08X\n", fstart[i], fsize[i]);
bool mapped = RomDest == (u8 *)mem_region_reserve(RomDest, fsize[i]);
verify(mapped);
memset(romDest, -1, fsize[i]);
}
else
{
//printf("-Mapping \"%s\" at 0x%08X, size 0x%08X\n", files[i].c_str(), fstart[i], fsize[i]);
bool mapped = RomDest == (u8 *)mem_region_map_file((void *)(uintptr_t)RomCacheMap[i], RomDest, fsize[i], 0, false);
bool mapped = fread(romDest, 1, fsize[i], fp) == fsize[i];
fclose(fp);
if (!mapped)
{
ERROR_LOG(NAOMI, "-Mapping ROM FAILED: %s @ %08x size %x", files[i].c_str(), fstart[i], fsize[i]);
throw new ReicastException("Memory mapping of ROM failed");
ERROR_LOG(NAOMI, "Unable to read file %s @ %08x size %x", files[i].c_str(),
fstart[i], fsize[i]);
load_error = true;
break;
}
}
}
//done :)
INFO_LOG(NAOMI, "Mapped ROM Successfully !");
if (load_error)
{
free(romBase);
throw new ReicastException("Error: Failed to load BIN/DAT file");
}
CurrentCartridge = new DecryptedCartridge(RomPtr, RomSize);
DEBUG_LOG(NAOMI, "Legacy ROM loaded successfully");
CurrentCartridge = new DecryptedCartridge(romBase, romSize);
strcpy(naomi_game_id, CurrentCartridge->GetGameId().c_str());
NOTICE_LOG(NAOMI, "NAOMI GAME ID [%s]", naomi_game_id);
}
@ -635,15 +537,6 @@ void naomi_cart_Close()
delete CurrentCartridge;
CurrentCartridge = NULL;
}
if (RomCacheMap != NULL)
{
for (u32 i = 0; i < RomCacheMapCount; i++)
if (RomCacheMap[i] != INVALID_FD)
CloseFile(RomCacheMap[i]);
RomCacheMapCount = 0;
delete[] RomCacheMap;
RomCacheMap = NULL;
}
bios_loaded = false;
}
@ -732,9 +625,6 @@ void* NaomiCartridge::GetDmaPtr(u32& size)
return GetPtr(DmaOffset, size);
}
void NaomiCartridge::AdvancePtr(u32 size) {
}
u32 NaomiCartridge::ReadMem(u32 address, u32 size)
{
verify(size!=1);
@ -805,36 +695,6 @@ u32 NaomiCartridge::ReadMem(u32 address, u32 size)
DEBUG_LOG(NAOMI, "naomi ReadBoardId: %X, %d", address, size);
return 1;
case NAOMI_COMM2_CTRL_addr & 255:
DEBUG_LOG(NAOMI, "NAOMI_COMM2_CTRL read");
return comm_ctrl;
case NAOMI_COMM2_OFFSET_addr & 255:
DEBUG_LOG(NAOMI, "NAOMI_COMM2_OFFSET read");
return comm_offset;
case NAOMI_COMM2_DATA_addr & 255:
{
DEBUG_LOG(NAOMI, "NAOMI_COMM2_DATA read @ %04x", comm_offset);
u16 value;
if (comm_ctrl & 1)
value = m68k_ram[comm_offset / 2];
else {
// TODO u16 *commram = (u16*)membank("comm_ram")->base();
value = comm_ram[comm_offset / 2];
}
comm_offset += 2;
return value;
}
case NAOMI_COMM2_STATUS0_addr & 255:
DEBUG_LOG(NAOMI, "NAOMI_COMM2_STATUS0 read");
return comm_status0;
case NAOMI_COMM2_STATUS1_addr & 255:
DEBUG_LOG(NAOMI, "NAOMI_COMM2_STATUS1 read");
return comm_status1;
default:
break;
}
@ -953,37 +813,6 @@ void NaomiCartridge::WriteMem(u32 address, u32 data, u32 size)
DEBUG_LOG(NAOMI, "naomi WriteMem: %X <= %X, %d", address, data, size);
return;
case NAOMI_COMM2_CTRL_addr & 255:
comm_ctrl = (u16)data;
DEBUG_LOG(NAOMI, "NAOMI_COMM2_CTRL set to %x", comm_ctrl);
return;
case NAOMI_COMM2_OFFSET_addr & 255:
comm_offset = (u16)data;
DEBUG_LOG(NAOMI, "NAOMI_COMM2_OFFSET set to %x", comm_offset);
return;
case NAOMI_COMM2_DATA_addr & 255:
DEBUG_LOG(NAOMI, "NAOMI_COMM2_DATA written @ %04x %04x", comm_offset, (u16)data);
if (comm_ctrl & 1)
m68k_ram[comm_offset / 2] = (u16)data;
else {
// TODO u16 *commram = (u16*)membank("comm_ram")->base();
comm_ram[comm_offset / 2] = (u16)data;
}
comm_offset += 2;
return;
case NAOMI_COMM2_STATUS0_addr & 255:
comm_status0 = (u16)data;
DEBUG_LOG(NAOMI, "NAOMI_COMM2_STATUS0 set to %x", comm_status0);
return;
case NAOMI_COMM2_STATUS1_addr & 255:
comm_status1 = (u16)data;
DEBUG_LOG(NAOMI, "NAOMI_COMM2_STATUS1 set to %x", comm_status1);
return;
default: break;
}
DEBUG_LOG(NAOMI, "naomi?WTF? WriteMem: %X <= %X, %d", address, data, size);
@ -1103,11 +932,3 @@ void M2Cartridge::Unserialize(void** data, unsigned int* total_size) {
REICAST_US(naomi_cart_ram);
NaomiCartridge::Unserialize(data, total_size);
}
DecryptedCartridge::~DecryptedCartridge()
{
// TODO this won't work on windows -> need to unmap each file first
mem_region_release(RomPtr, RomSize);
// Avoid crash when freeing vmem
RomPtr = NULL;
}

View File

@ -38,7 +38,7 @@ public:
virtual u32 ReadMem(u32 address, u32 size) override;
virtual void WriteMem(u32 address, u32 data, u32 size) override;
virtual void* GetDmaPtr(u32 &size) override;
virtual void AdvancePtr(u32 size) override;
virtual void AdvancePtr(u32 size) override {}
virtual void Serialize(void** data, unsigned int* total_size) override;
virtual void Unserialize(void** data, unsigned int* total_size) override;
@ -52,20 +52,12 @@ protected:
u32 DmaOffset;
u32 DmaCount;
u32 key = 0;
// Naomi 840-0001E communication board
u16 comm_ctrl = 0xC000;
u16 comm_offset = 0;
u16 comm_status0 = 0;
u16 comm_status1 = 0;
u16 m68k_ram[128 * 1024 / sizeof(u16)];
u16 comm_ram[64 * 1024 / sizeof(u16)];
};
class DecryptedCartridge : public NaomiCartridge
{
public:
DecryptedCartridge(u8 *rom_ptr, u32 size) : NaomiCartridge(size) { free(RomPtr); RomPtr = rom_ptr; }
virtual ~DecryptedCartridge() override;
};
class M2Cartridge : public NaomiCartridge
@ -94,10 +86,10 @@ public:
void naomi_cart_LoadRom(const char* file);
void naomi_cart_Close();
int naomi_cart_GetPlatform(const char *path);
void naomi_cart_LoadBios(const char *filename);
extern char naomi_game_id[];
extern u8 *naomi_default_eeprom;
extern bool naomi_rotate_screen;
extern Cartridge *CurrentCartridge;

View File

@ -5,6 +5,7 @@
#include "hw/pvr/pvr_mem.h"
#include "oslib/oslib.h"
#include "rend/TexCache.h"
#include "cfg/option.h"
#include <mutex>
#include <zlib.h>
@ -225,7 +226,7 @@ bool rend_single_frame(const bool& enabled)
{
{
std::lock_guard<std::mutex> lock(swap_mutex);
if (settings.rend.DelayFrameSwapping && !_pvrrc->rend.isRenderFramebuffer && fb_w_cur != FB_R_SOF1 && !do_swap)
if (config::DelayFrameSwapping && !_pvrrc->rend.isRenderFramebuffer && fb_w_cur != FB_R_SOF1 && !do_swap)
// Delay swap
frame_rendered = false;
else
@ -257,7 +258,7 @@ static void rend_create_renderer()
#ifdef NO_REND
renderer = rend_norend();
#else
switch (settings.pvr.rend)
switch (config::RendererType)
{
default:
case RenderType::OpenGL:

View File

@ -1,6 +1,7 @@
#include "ta_ctx.h"
#include "spg.h"
#include "oslib/oslib.h"
#include "cfg/option.h"
extern u32 fskip;
extern u32 FrameCount;
@ -77,10 +78,10 @@ bool QueueRender(TA_context* ctx)
bool skipFrame = false;
RenderCount++;
if (RenderCount % (settings.pvr.ta_skip + 1) != 0)
if (RenderCount % (config::SkipFrame + 1) != 0)
skipFrame = true;
else if (rqueue && (settings.pvr.AutoSkipFrame == 0
|| (settings.pvr.AutoSkipFrame == 1 && SH4FastEnough)))
else if (rqueue && (config::AutoSkipFrame == 0
|| (config::AutoSkipFrame == 1 && SH4FastEnough)))
// The previous render hasn't completed yet so we wait.
// If autoskipframe is enabled (normal level), we only do so if the CPU is running
// fast enough over the last frames

View File

@ -14,6 +14,7 @@
#include "hw/sh4/sh4_core.h"
#include "hw/sh4/sh4_mem.h"
#include "decoder_opcodes.h"
#include "cfg/option.h"
#define BLOCK_MAX_SH_OPS_SOFT 500
#define BLOCK_MAX_SH_OPS_HARD 511
@ -623,7 +624,7 @@ static u32 MatchDiv32(u32 pc , Sh4RegType &reg1,Sh4RegType &reg2 , Sh4RegType &r
static bool MatchDiv32u(u32 op,u32 pc)
{
if (settings.dynarec.safemode)
if (config::DynarecSafeMode)
return false;
div_som_reg1=NoReg;
@ -645,7 +646,7 @@ static bool MatchDiv32u(u32 op,u32 pc)
static bool MatchDiv32s(u32 op,u32 pc)
{
if (settings.dynarec.safemode)
if (config::DynarecSafeMode)
return false;
u32 n = GetN(op);
@ -1095,7 +1096,7 @@ _end:
#endif
//cycle tricks
if (settings.dynarec.idleskip)
if (config::DynarecIdleSkip)
{
//Experimental hash-id based idle skip
if (!mmu_enabled() && strstr(idle_hash, blk->hash()))

View File

@ -8,6 +8,7 @@
#include "hw/sh4/sh4_mem.h"
#include "hw/sh4/modules/mmu.h"
#include "cfg/option.h"
#include <ctime>
#include <cfloat>
@ -70,7 +71,7 @@ static void recSh4_Run()
sh4_dyna_rcb=(u8*)&Sh4cntx + sizeof(Sh4cntx);
INFO_LOG(DYNAREC, "cntx // fpcb offset: %td // pc offset: %td // pc %08X", (u8*)&sh4rcb.fpcb - sh4_dyna_rcb, (u8*)&sh4rcb.cntx.pc - sh4_dyna_rcb, sh4rcb.cntx.pc);
if (settings.dynarec.unstable_opt)
if (config::DynarecUnstableOpt)
NOTICE_LOG(DYNAREC, "Warning: Unstable optimizations is on");
verify(rcb_noffs(&next_pc)==-184);

View File

@ -4,6 +4,7 @@
#include "hw/sh4/sh4_mmr.h"
#include "hw/naomi/naomi.h"
#include "cfg/option.h"
BSC_PDTRA_type BSC_PDTRA;
@ -52,7 +53,7 @@ u32 read_BSC_PDTRA(u32 addr)
else if ((tpctra&0xf) == 0xC && (tpdtra&0xf) == 2)
tfinal = 3;
tfinal |= settings.dreamcast.cable <<8;
tfinal |= config::Cable << 8;
return tfinal;
}

View File

@ -84,13 +84,13 @@ void CCN_CCR_write(u32 addr, u32 value)
if (temp.ICI) {
DEBUG_LOG(SH4, "Sh4: i-cache invalidation %08X", curr_pc);
//Shikigami No Shiro II uses ICI frequently
if (!settings.dynarec.Enable)
if (!config::DynarecEnabled)
icache.Invalidate();
temp.ICI = 0;
}
if (temp.OCI) {
DEBUG_LOG(SH4, "Sh4: o-cache invalidation %08X", curr_pc);
if (!settings.dynarec.Enable)
if (!config::DynarecEnabled)
ocache.Invalidate();
temp.OCI = 0;
}

View File

@ -648,7 +648,7 @@ retry_ITLB_Match:
void mmu_set_state()
{
if (CCN_MMUCR.AT == 1 && settings.dreamcast.FullMMU)
if (CCN_MMUCR.AT == 1 && config::FullMMU)
{
NOTICE_LOG(SH4, "Enabling Full MMU support");
_vmem_enable_mmu(true);
@ -745,7 +745,7 @@ template void mmu_WriteMem(u32 adr, u64 data);
bool mmu_TranslateSQW(u32 adr, u32* out)
{
if (!settings.dreamcast.FullMMU)
if (!config::FullMMU)
{
//This will only work for 1 mb pages .. hopefully nothing else is used
//*FIXME* to work for all page sizes ?

View File

@ -2,6 +2,7 @@
#include "types.h"
#include "hw/sh4/sh4_mmr.h"
#include "hw/mem/_vmem.h"
#include "cfg/option.h"
//Translation Types
//Opcode read
@ -51,7 +52,7 @@ void mmu_raise_exception(u32 mmu_error, u32 address, u32 am);
static INLINE bool mmu_enabled()
{
#ifndef NO_MMU
return settings.dreamcast.FullMMU && CCN_MMUCR.AT == 1;
return config::FullMMU && CCN_MMUCR.AT == 1;
#else
return false;
#endif

View File

@ -14,6 +14,7 @@
#include "types.h"
#include "hw/sh4/sh4_mmr.h"
#include "hw/sh4/sh4_interrupts.h"
#include "cfg/option.h"
static int tty = 1; // stdout by default
@ -65,7 +66,7 @@ static void Serial_UpdateInterrupts()
static void SerialWrite(u32 addr, u32 data)
{
if (settings.debug.SerialConsole)
if (config::SerialConsole)
write(tty, &data, 1);
SCIF_SCFSR2.TDFE = 1;
@ -79,7 +80,7 @@ static u32 ReadSerialStatus(u32 addr)
{
#if HOST_OS == OS_LINUX || defined(__APPLE__)
int count = 0;
if (settings.debug.SerialConsole && tty != 1
if (config::SerialConsole && tty != 1
&& ioctl(tty, FIONREAD, &count) == 0 && count > 0)
{
return SCIF_SCFSR2.full | 2;
@ -169,7 +170,7 @@ void serial_init()
sh4_rio_reg(SCIF,SCIF_SCLSR2_addr,RIO_DATA,16);
#if HOST_OS == OS_LINUX || defined(__APPLE__)
if (settings.debug.SerialConsole && settings.debug.SerialPTY)
if (config::SerialConsole && config::SerialPTY)
{
tty = open("/dev/ptmx", O_RDWR | O_NDELAY | O_NOCTTY | O_NONBLOCK);
if (tty < 0)

View File

@ -1,7 +1,7 @@
#pragma once
#include "types.h"
#include "sh4_if.h"
#include "cfg/option.h"
#define r Sh4cntx.r
#define r_bank Sh4cntx.r_bank
@ -107,7 +107,7 @@ struct SH4ThrownException {
static INLINE void RaiseFPUDisableException()
{
#if !defined(NO_MMU)
if (settings.dreamcast.FullMMU)
if (config::FullMMU)
{
SH4ThrownException ex = { next_pc - 2, 0x800, 0x100 };
throw ex;
@ -126,7 +126,7 @@ static INLINE void AdjustDelaySlotException(SH4ThrownException& ex)
ex.expEvn = 0x1A0; // Slot illegal instruction exception
}
// The SH4 sets the signaling bit to 0 for qNaN (unlike all recent CPUs). Some games relies on this.
// The SH4 sets the signaling bit to 0 for qNaN (unlike all recent CPUs). Some games rely on this.
static INLINE f32 fixNaN(f32 f)
{
#ifdef STRICT_MODE

View File

@ -314,14 +314,14 @@ void SetMemoryHandlers()
{
#ifndef NO_MMU
#ifdef STRICT_MODE
if (settings.dynarec.Enable && interpreterRunning)
if (config::DynarecEnabled && interpreterRunning)
{
// Flush caches when interp -> dynarec
ocache.WriteBackAll();
icache.Invalidate();
}
if (!settings.dynarec.Enable)
if (!config::DynarecEnabled)
{
interpreterRunning = true;
IReadMem16 = &IReadCachedMem;
@ -339,7 +339,7 @@ void SetMemoryHandlers()
}
interpreterRunning = false;
#endif
if (CCN_MMUCR.AT == 1 && settings.dreamcast.FullMMU)
if (CCN_MMUCR.AT == 1 && config::FullMMU)
{
IReadMem16 = &mmu_IReadMem16;
ReadMem8 = &mmu_ReadMem<u8>;

View File

@ -409,7 +409,7 @@ static FILE *get_record_input(bool write)
void GamepadDevice::Register(std::shared_ptr<GamepadDevice> gamepad)
{
int maple_port = cfgLoadInt("input",
(MAPLE_PORT_CFG_PREFIX + gamepad->unique_id()).c_str(), 12345);
MAPLE_PORT_CFG_PREFIX + gamepad->unique_id(), 12345);
if (maple_port != 12345)
gamepad->set_maple_port(maple_port);
#ifdef TEST_AUTOMATION
@ -443,11 +443,12 @@ void GamepadDevice::SaveMaplePorts()
{
std::shared_ptr<GamepadDevice> gamepad = GamepadDevice::GetGamepad(i);
if (gamepad != NULL && !gamepad->unique_id().empty())
cfgSaveInt("input", (MAPLE_PORT_CFG_PREFIX + gamepad->unique_id()).c_str(), gamepad->maple_port());
cfgSaveInt("input", MAPLE_PORT_CFG_PREFIX + gamepad->unique_id(), gamepad->maple_port());
}
}
#ifdef TEST_AUTOMATION
#include "cfg/option.h"
static bool replay_inited;
FILE *replay_file;
u64 next_event;
@ -463,10 +464,10 @@ void replay_input()
replay_inited = true;
}
u64 now = sh4_sched_now64();
if (settings.bios.UseReios)
if (config::UseReios)
{
// Account for the swirl time
if (settings.dreamcast.broadcast == 0)
if (config::Broadcast == 0)
now = std::max((int64_t)now - 2152626532L, 0L);
else
now = std::max((int64_t)now - 2191059108L, 0L);

View File

@ -2,6 +2,7 @@
#include "dispmanx.h"
#include "types.h"
#include "wsi/context.h"
#include "cfg/option.h"
#include <bcm_host.h>
#include <EGL/egl.h>
@ -25,8 +26,8 @@ void dispmanx_window_create()
graphics_get_display_size(0 /* LCD */, &screen_width, &screen_height);
window_width = settings.dispmanx.Width;
window_height = settings.dispmanx.Height;
window_width = cfgLoadInt("window", "width", 0);
window_height = cfgLoadInt("window", "height", 0);
if(window_width < 1)
window_width = screen_width;
@ -38,7 +39,7 @@ void dispmanx_window_create()
src_rect.width = window_width << 16;
src_rect.height = window_height << 16;
if(settings.dispmanx.Keep_Aspect)
if (config::DispmanxMaintainAspect)
{
float screen_aspect = (float)screen_width / screen_height;
float window_aspect = (float)window_width / window_height;

View File

@ -365,8 +365,6 @@ int main(int argc, char* argv[])
common_linux_setup();
settings.profile.run_counts=0;
if (reicast_init(argc, argv))
die("Reicast initialization failed\n");

View File

@ -200,8 +200,6 @@ void common_linux_setup()
install_fault_handler();
signal(SIGINT, exit);
settings.profile.run_counts=0;
DEBUG_LOG(BOOT, "Linux paging: %ld %08X %08X", sysconf(_SC_PAGESIZE), PAGE_SIZE, PAGE_MASK);
verify(PAGE_MASK==(sysconf(_SC_PAGESIZE)-1));
}

View File

@ -27,6 +27,7 @@
#include "rend/gui.h"
#include "hw/naomi/naomi_cart.h"
#include "hw/naomi/naomi_flashrom.h"
#include "cfg/option.h"
#ifdef _MSC_VER
#if defined(_WIN64)
@ -67,7 +68,7 @@ sock_t NaomiNetwork::createAndBind(int protocol)
bool NaomiNetwork::init()
{
if (!settings.network.Enable)
if (!config::NetworkEnable)
return false;
#ifdef _WIN32
WSADATA wsaData;
@ -77,7 +78,7 @@ bool NaomiNetwork::init()
return false;
}
#endif
if (settings.network.ActAsServer)
if (config::ActAsServer)
{
miniupnp.Init();
miniupnp.AddPortMapping(SERVER_PORT, true);
@ -223,7 +224,7 @@ bool NaomiNetwork::startNetwork()
using namespace std::chrono;
const auto timeout = seconds(20);
if (settings.network.ActAsServer)
if (config::ActAsServer)
{
NOTICE_LOG(NETWORK, "Waiting for slave connections");
steady_clock::time_point start_time = steady_clock::now();
@ -338,11 +339,11 @@ bool NaomiNetwork::startNetwork()
}
else
{
if (!settings.network.server.empty())
if (!config::NetworkServer.get().empty())
{
struct addrinfo *resultAddr;
if (getaddrinfo(settings.network.server.c_str(), 0, nullptr, &resultAddr))
WARN_LOG(NETWORK, "Server %s is unknown", settings.network.server.c_str());
if (getaddrinfo(config::NetworkServer.get().c_str(), 0, nullptr, &resultAddr))
WARN_LOG(NETWORK, "Server %s is unknown", config::NetworkServer.get().c_str());
else
for (struct addrinfo *ptr = resultAddr; ptr != nullptr; ptr = ptr->ai_next)
if (ptr->ai_family == AF_INET)
@ -408,7 +409,7 @@ bool NaomiNetwork::syncNetwork()
using namespace std::chrono;
const auto timeout = seconds(10);
if (settings.network.ActAsServer)
if (config::ActAsServer)
{
steady_clock::time_point start_time = steady_clock::now();
@ -622,7 +623,7 @@ void NaomiNetwork::shutdown()
void NaomiNetwork::terminate()
{
shutdown();
if (settings.network.ActAsServer)
if (config::ActAsServer)
miniupnp.Term();
if (VALID(beacon_sock))
closeSocket(beacon_sock);
@ -713,7 +714,7 @@ bool NaomiNetworkSupported()
"HEAVY METAL JAPAN", "OUTTRIGGER JAPAN", "SLASHOUT JAPAN VERSION", "SPAWN JAPAN",
"SPIKERS BATTLE JAPAN VERSION", "VIRTUAL-ON ORATORIO TANGRAM", "WAVE RUNNER GP", "WORLD KICKS"
};
if (!settings.network.Enable)
if (!config::NetworkEnable)
return false;
for (auto game : games)
if (!strcmp(game, naomi_game_id))

View File

@ -46,6 +46,7 @@ extern "C" {
#include "miniupnp.h"
#include "reios/reios.h"
#include "hw/naomi/naomi_cart.h"
#include "cfg/option.h"
#include <map>
#include <mutex>
@ -892,11 +893,11 @@ static void *pico_thread_func(void *)
}
u32 addr;
pico_string_to_ipv4(settings.network.dns.c_str(), &addr);
pico_string_to_ipv4(config::DNS.get().c_str(), &addr);
memcpy(&dnsaddr.addr, &addr, sizeof(addr));
// Create ppp/eth device
if (!settings.network.EmulateBBA)
if (!config::EmulateBBA)
{
// PPP
pico_dev = pico_ppp_create();
@ -1041,7 +1042,7 @@ static void *pico_thread_func(void *)
if (pico_dev)
{
if (!settings.network.EmulateBBA)
if (!config::EmulateBBA)
{
pico_ppp_destroy(pico_dev);
}

View File

@ -4,7 +4,6 @@
#include <future>
#include <thread>
//initialse Emu
#include "types.h"
#include "emulator.h"
#include "oslib/oslib.h"
@ -12,6 +11,7 @@
#include "hw/mem/_vmem.h"
#include "stdclass.h"
#include "cfg/cfg.h"
#include "cfg/option.h"
#include "hw/maple/maple_cfg.h"
#include "hw/sh4/sh4_mem.h"
@ -38,25 +38,16 @@
#include "archive/rzip.h"
void FlushCache();
static void LoadCustom();
extern bool fast_forward_mode;
settings_t settings;
// Set if game has corresponding option by default, so that it's not saved in the config
static bool rtt_to_buffer_game;
static bool safemode_game;
static bool tr_poly_depth_mask_game;
static bool extra_depth_game;
static bool disable_vmem32_game;
static int forced_game_region = -1;
static int forced_game_cable = -1;
static int saved_screen_stretching = -1;
cThread emu_thread(&dc_run, NULL);
static std::future<void> loading_done;
std::atomic<bool> loading_canceled;
static bool init_done;
static s32 plugins_Init()
{
@ -104,22 +95,15 @@ static void LoadSpecialSettings()
prod_id = trim_trailing_ws(prod_id);
NOTICE_LOG(BOOT, "Game ID is [%s]", prod_id.c_str());
rtt_to_buffer_game = false;
safemode_game = false;
tr_poly_depth_mask_game = false;
extra_depth_game = false;
disable_vmem32_game = false;
forced_game_region = -1;
forced_game_cable = -1;
if (ip_meta.isWindowsCE() || settings.dreamcast.ForceWindowsCE
if (ip_meta.isWindowsCE() || config::ForceWindowsCE
|| prod_id == "T26702N") // PBA Tour Bowling 2001
{
INFO_LOG(BOOT, "Enabling Full MMU and Extra depth scaling for Windows CE game");
settings.rend.ExtraDepthScale = 0.1; // taxi 2 needs 0.01 for FMV (amd, per-tri)
extra_depth_game = true;
settings.dreamcast.FullMMU = true;
settings.aica.NoBatch = true;
config::ExtraDepthScale.override(0.1); // taxi 2 needs 0.01 for FMV (amd, per-tri)
config::FullMMU.override(true);
if (!config::ForceWindowsCE)
config::ForceWindowsCE.override(true);
}
// Tony Hawk's Pro Skater 2
@ -148,36 +132,31 @@ static void LoadSpecialSettings()
|| prod_id == "T-45001D05")
{
INFO_LOG(BOOT, "Enabling render to texture buffer for game %s", prod_id.c_str());
settings.rend.RenderToTextureBuffer = 1;
rtt_to_buffer_game = true;
config::RenderToTextureBuffer.override(true);
}
if (prod_id == "HDR-0176" || prod_id == "RDC-0057")
{
INFO_LOG(BOOT, "Enabling translucent depth multipass for game %s", prod_id.c_str());
// Cosmic Smash
settings.rend.TranslucentPolygonDepthMask = 1;
tr_poly_depth_mask_game = true;
config::TranslucentPolygonDepthMask.override(true);
}
// NHL 2K2
if (prod_id == "MK-51182")
{
INFO_LOG(BOOT, "Enabling Extra depth scaling for game %s", prod_id.c_str());
settings.rend.ExtraDepthScale = 1000000; // Mali needs 1M, 10K is enough for others
extra_depth_game = true;
config::ExtraDepthScale.override(1000000.f); // Mali needs 1M, 10K is enough for others
}
// Re-Volt (US, EU)
else if (prod_id == "T-8109N" || prod_id == "T8107D 50")
{
INFO_LOG(BOOT, "Enabling Extra depth scaling for game %s", prod_id.c_str());
settings.rend.ExtraDepthScale = 100;
extra_depth_game = true;
config::ExtraDepthScale.override(100.f);
}
// Samurai Shodown 6 dc port
else if (prod_id == "T0002M")
{
INFO_LOG(BOOT, "Enabling Extra depth scaling for game %s", prod_id.c_str());
settings.rend.ExtraDepthScale = 1e26;
extra_depth_game = true;
config::ExtraDepthScale.override(1e26f);
}
// Super Producers
if (prod_id == "T14303M"
@ -211,8 +190,7 @@ static void LoadSpecialSettings()
|| prod_id == "T26702N")
{
INFO_LOG(BOOT, "Disabling 32-bit virtual memory for game %s", prod_id.c_str());
settings.dynarec.disable_vmem32 = true;
disable_vmem32_game = true;
config::DisableVmem32.override(true);
}
std::string areas(ip_meta.area_symbols, sizeof(ip_meta.area_symbols));
bool region_usa = areas.find('U') != std::string::npos;
@ -220,52 +198,47 @@ static void LoadSpecialSettings()
bool region_japan = areas.find('J') != std::string::npos;
if (region_usa || region_eu || region_japan)
{
switch (settings.dreamcast.region)
switch (config::Region)
{
case 0: // Japan
if (!region_japan)
{
NOTICE_LOG(BOOT, "Japan region not supported. Using %s instead", region_usa ? "USA" : "Europe");
settings.dreamcast.region = region_usa ? 1 : 2;
forced_game_region = settings.dreamcast.region;
config::Region.override(region_usa ? 1 : 2);
}
break;
case 1: // USA
if (!region_usa)
{
NOTICE_LOG(BOOT, "USA region not supported. Using %s instead", region_eu ? "Europe" : "Japan");
settings.dreamcast.region = region_eu ? 2 : 0;
forced_game_region = settings.dreamcast.region;
config::Region.override(region_eu ? 2 : 0);
}
break;
case 2: // Europe
if (!region_eu)
{
NOTICE_LOG(BOOT, "Europe region not supported. Using %s instead", region_usa ? "USA" : "Japan");
settings.dreamcast.region = region_usa ? 1 : 0;
forced_game_region = settings.dreamcast.region;
config::Region.override(region_usa ? 1 : 0);
}
break;
case 3: // Default
if (region_usa)
settings.dreamcast.region = 1;
config::Region.override(1);
else if (region_eu)
settings.dreamcast.region = 2;
config::Region.override(2);
else
settings.dreamcast.region = 0;
forced_game_region = settings.dreamcast.region;
config::Region.override(0);
break;
}
}
else
WARN_LOG(BOOT, "No region specified in IP.BIN");
if (settings.dreamcast.cable <= 1 && !ip_meta.supportsVGA())
if (config::Cable <= 1 && !ip_meta.supportsVGA())
{
NOTICE_LOG(BOOT, "Game doesn't support VGA. Using TV Composite instead");
settings.dreamcast.cable = 3;
forced_game_cable = settings.dreamcast.cable;
config::Cable.override(3);
}
if (settings.dreamcast.cable == 2 &&
if (config::Cable == 2 &&
(prod_id == "T40602N" // Centipede
|| prod_id == "T9710N" // Gauntlet Legends (US)
|| prod_id == "MK-51152" // World Series Baseball 2K2
@ -279,8 +252,7 @@ static void LoadSpecialSettings()
|| prod_id == "T1235M")) // Vampire Chronicle for Matching Service
{
NOTICE_LOG(BOOT, "Game doesn't support RGB. Using TV Composite instead");
settings.dreamcast.cable = 3;
forced_game_cable = settings.dreamcast.cable;
config::Cable.override(3);
}
}
else if (settings.platform.system == DC_PLATFORM_NAOMI || settings.platform.system == DC_PLATFORM_ATOMISWAVE)
@ -289,16 +261,15 @@ static void LoadSpecialSettings()
if (!strcmp("SAMURAI SPIRITS 6", naomi_game_id))
{
INFO_LOG(BOOT, "Enabling Extra depth scaling for game %s", naomi_game_id);
settings.rend.ExtraDepthScale = 1e26;
extra_depth_game = true;
config::ExtraDepthScale.override(1e26f);
}
if (!strcmp("COSMIC SMASH IN JAPAN", naomi_game_id))
{
INFO_LOG(BOOT, "Enabling translucent depth multipass for game %s", naomi_game_id);
settings.rend.TranslucentPolygonDepthMask = true;
tr_poly_depth_mask_game = true;
config::TranslucentPolygonDepthMask.override(true);
}
// Input configuration
settings.input.JammaSetup = JVS::Default;
if (!strcmp("DYNAMIC GOLF", naomi_game_id)
|| !strcmp("SHOOTOUT POOL", naomi_game_id)
|| !strcmp("SHOOTOUT POOL MEDAL", naomi_game_id)
@ -393,7 +364,6 @@ static void LoadSpecialSettings()
INFO_LOG(BOOT, "Enabling specific JVS setup for game %s", naomi_game_id);
settings.input.JammaSetup = JVS::TouchDeUno;
}
settings.rend.Rotate90 = naomi_rotate_screen;
}
}
@ -403,8 +373,6 @@ void dc_reset(bool hard)
mem_Reset(hard);
sh4_cpu.Reset(hard);
if (hard)
EventManager::event(Event::Terminate);
}
static bool reset_requested;
@ -424,7 +392,7 @@ int reicast_init(int argc, char* argv[])
{
return 69;
}
InitSettings();
config::Settings::instance().reset();
LogManager::Shutdown();
if (!cfgOpen())
{
@ -435,9 +403,8 @@ int reicast_init(int argc, char* argv[])
else
{
LogManager::Init();
LoadSettings(false);
config::Settings::instance().load(false);
}
settings.pvr.rend = (RenderType)cfgLoadInt("config", "pvr.rend", (int)settings.pvr.rend);
os_CreateWindow();
os_SetupInput();
@ -492,8 +459,6 @@ static void set_platform(int platform)
void dc_init()
{
static bool init_done;
if (init_done)
return;
@ -508,7 +473,7 @@ void dc_init()
#if FEAT_SHREC != DYNAREC_NONE
Get_Sh4Recompiler(&sh4_cpu);
sh4_cpu.Init(); // Also initialize the interpreter
if(settings.dynarec.Enable)
if(config::DynarecEnabled)
{
INFO_LOG(DYNAREC, "Using Recompiler");
}
@ -543,52 +508,28 @@ static int get_game_platform(const char *path)
static void dc_start_game(const char *path)
{
DEBUG_LOG(BOOT, "Loading game %s", path == nullptr ? "(nil)" : path);
bool forced_bios_file = false;
if (path != NULL)
{
if (path != nullptr)
strcpy(settings.imgread.ImagePath, path);
}
else
{
// Booting the BIOS requires a BIOS file
forced_bios_file = true;
settings.imgread.ImagePath[0] = '\0';
}
dc_init();
set_platform(get_game_platform(path));
mem_map_default();
InitSettings();
config::Settings::instance().reset();
dc_reset(true);
LoadSettings(false);
config::Settings::instance().load(false);
if (settings.platform.system == DC_PLATFORM_DREAMCAST)
{
if ((settings.bios.UseReios && !forced_bios_file) || !LoadRomFiles())
{
if (forced_bios_file)
throw ReicastException("No BIOS file found");
if (!LoadHle())
throw ReicastException("Failed to initialize HLE BIOS");
NOTICE_LOG(BOOT, "Did not load BIOS, using reios");
}
}
else
{
LoadRomFiles();
}
if (settings.platform.system == DC_PLATFORM_DREAMCAST)
{
mcfg_CreateDevices();
if (path == NULL)
{
// Boot BIOS
if (!LoadRomFiles())
throw ReicastException("No BIOS file found");
TermDrive();
InitDrive();
}
@ -598,26 +539,41 @@ static void dc_start_game(const char *path)
if (extension != "elf")
{
if (InitDrive())
LoadCustom();
{
LoadGameSpecificSettings();
if (config::UseReios || !LoadRomFiles())
{
LoadHle();
NOTICE_LOG(BOOT, "Did not load BIOS, using reios");
}
}
else
{
// Content load failed. Boot the BIOS
settings.imgread.ImagePath[0] = '\0';
forced_bios_file = true;
if (!LoadRomFiles())
throw ReicastException("No BIOS file found");
InitDrive();
}
}
else
{
// Elf only supported with HLE BIOS
LoadHle();
}
}
mcfg_CreateDevices();
FixUpFlash();
}
else if (settings.platform.system == DC_PLATFORM_NAOMI || settings.platform.system == DC_PLATFORM_ATOMISWAVE)
{
LoadRomFiles();
naomi_cart_LoadRom(path);
if (loading_canceled)
return;
LoadCustom();
LoadGameSpecificSettings();
// Reload the BIOS in case a game-specific region is set
naomi_cart_LoadBios(path);
if (settings.platform.system == DC_PLATFORM_NAOMI)
{
mcfg_CreateNAOMIJamma();
@ -629,20 +585,11 @@ static void dc_start_game(const char *path)
if (cheatManager.Reset())
{
gui_display_notification("Widescreen cheat activated", 1000);
if (saved_screen_stretching == -1)
saved_screen_stretching = settings.rend.ScreenStretching;
settings.rend.ScreenStretching = 133; // 4:3 -> 16:9
}
else
{
if (saved_screen_stretching != -1)
{
settings.rend.ScreenStretching = saved_screen_stretching;
saved_screen_stretching = -1;
}
config::ScreenStretching.override(134); // 4:3 -> 16:9
}
fast_forward_mode = false;
EventManager::event(Event::Start);
settings.gameStarted = true;
}
bool dc_is_running()
@ -655,7 +602,7 @@ void* dc_run(void*)
{
InitAudio();
if (settings.dynarec.Enable)
if (config::DynarecEnabled)
{
Get_Sh4Recompiler(&sh4_cpu);
INFO_LOG(DYNAREC, "Using Recompiler");
@ -671,10 +618,9 @@ void* dc_run(void*)
sh4_cpu.Run();
SaveRomFiles();
if (reset_requested)
{
dc_reset(false);
}
} while (reset_requested);
TermAudio();
@ -683,8 +629,23 @@ void* dc_run(void*)
}
#endif
void dc_term_game()
{
if (settings.gameStarted)
{
settings.gameStarted = false;
EventManager::event(Event::Terminate);
}
if (init_done)
dc_reset(true);
config::Settings::instance().reset();
config::Settings::instance().load(false);
}
void dc_term()
{
dc_term_game();
dc_cancel_load();
sh4_cpu.Term();
if (settings.platform.system != DC_PLATFORM_DREAMCAST)
@ -700,10 +661,12 @@ void dc_term()
void dc_stop()
{
bool running = dc_is_running();
sh4_cpu.Stop();
rend_cancel_emu_wait();
emu_thread.WaitToEnd();
EventManager::event(Event::Pause);
if (running)
EventManager::event(Event::Pause);
}
// Called on the emulator thread for soft reset
@ -719,232 +682,7 @@ void dc_exit()
mainui_stop();
}
void InitSettings()
{
settings.dynarec.Enable = true;
settings.dynarec.idleskip = true;
settings.dynarec.unstable_opt = false;
settings.dynarec.safemode = false;
settings.dynarec.disable_vmem32 = false;
settings.dreamcast.cable = 3; // TV composite
settings.dreamcast.region = 3; // default
settings.dreamcast.broadcast = 4; // default
settings.dreamcast.language = 6; // default
settings.dreamcast.FullMMU = false;
settings.dreamcast.ForceWindowsCE = false;
settings.dreamcast.HideLegacyNaomiRoms = true;
settings.aica.DSPEnabled = false;
settings.aica.LimitFPS = true;
settings.aica.NoBatch = false;
settings.aica.NoSound = false;
settings.audio.backend = "auto";
settings.rend.UseMipmaps = true;
settings.rend.WideScreen = false;
settings.rend.ShowFPS = false;
settings.rend.RenderToTextureBuffer = false;
settings.rend.RenderToTextureUpscale = 1;
settings.rend.TranslucentPolygonDepthMask = false;
settings.rend.ModifierVolumes = true;
settings.rend.Clipping = true;
settings.rend.TextureUpscale = 1;
settings.rend.MaxFilteredTextureSize = 256;
settings.rend.ExtraDepthScale = 1.f;
settings.rend.CustomTextures = false;
settings.rend.DumpTextures = false;
settings.rend.ScreenScaling = 100;
settings.rend.ScreenStretching = 100;
settings.rend.Fog = true;
settings.rend.FloatVMUs = false;
settings.rend.Rotate90 = false;
settings.rend.PerStripSorting = false;
settings.rend.DelayFrameSwapping = false;
settings.rend.WidescreenGameHacks = false;
memset(settings.rend.CrosshairColor, 0, sizeof(settings.rend.CrosshairColor));
settings.pvr.ta_skip = 0;
settings.pvr.MaxThreads = 3;
settings.pvr.AutoSkipFrame = 0;
settings.debug.SerialConsole = false;
settings.debug.SerialPTY = false;
settings.bios.UseReios = false;
settings.validate.OpenGlChecks = false;
settings.input.MouseSensitivity = 100;
settings.input.JammaSetup = JVS::Default;
settings.input.VirtualGamepadVibration = 20;
for (int i = 0; i < MAPLE_PORTS; i++)
{
settings.input.maple_devices[i] = i == 0 ? MDT_SegaController : MDT_None;
settings.input.maple_expansion_devices[i][0] = i == 0 ? MDT_SegaVMU : MDT_None;
settings.input.maple_expansion_devices[i][1] = i == 0 ? MDT_SegaVMU : MDT_None;
}
settings.network.Enable = false;
settings.network.ActAsServer = false;
settings.network.dns = "46.101.91.123"; // Dreamcast Live DNS
settings.network.server = "";
settings.network.EmulateBBA = false;
#if SUPPORT_DISPMANX
settings.dispmanx.Width = 0;
settings.dispmanx.Height = 0;
settings.dispmanx.Keep_Aspect = true;
#endif
#if HOST_CPU == CPU_ARM
settings.aica.BufferSize = 5644; // 128 ms
#else
settings.aica.BufferSize = 2822; // 64 ms
#endif
#if USE_OMX
settings.omx.Audio_Latency = 100;
settings.omx.Audio_HDMI = true;
#endif
}
void LoadSettings(bool game_specific)
{
const char *config_section = game_specific ? cfgGetGameId() : "config";
const char *input_section = game_specific ? cfgGetGameId() : "input";
const char *audio_section = game_specific ? cfgGetGameId() : "audio";
settings.dynarec.Enable = cfgLoadBool(config_section, "Dynarec.Enabled", settings.dynarec.Enable);
settings.dynarec.idleskip = cfgLoadBool(config_section, "Dynarec.idleskip", settings.dynarec.idleskip);
settings.dynarec.unstable_opt = cfgLoadBool(config_section, "Dynarec.unstable-opt", settings.dynarec.unstable_opt);
settings.dynarec.safemode = cfgLoadBool(config_section, "Dynarec.safe-mode", settings.dynarec.safemode);
settings.dynarec.disable_vmem32 = cfgLoadBool(config_section, "Dynarec.DisableVmem32", settings.dynarec.disable_vmem32);
//disable_nvmem can't be loaded, because nvmem init is before cfg load
settings.dreamcast.cable = cfgLoadInt(config_section, "Dreamcast.Cable", settings.dreamcast.cable);
settings.dreamcast.region = cfgLoadInt(config_section, "Dreamcast.Region", settings.dreamcast.region);
settings.dreamcast.broadcast = cfgLoadInt(config_section, "Dreamcast.Broadcast", settings.dreamcast.broadcast);
settings.dreamcast.language = cfgLoadInt(config_section, "Dreamcast.Language", settings.dreamcast.language);
settings.dreamcast.FullMMU = cfgLoadBool(config_section, "Dreamcast.FullMMU", settings.dreamcast.FullMMU);
settings.dreamcast.ForceWindowsCE = cfgLoadBool(config_section, "Dreamcast.ForceWindowsCE", settings.dreamcast.ForceWindowsCE);
if (settings.dreamcast.ForceWindowsCE)
settings.aica.NoBatch = true;
settings.aica.LimitFPS = cfgLoadBool(config_section, "aica.LimitFPS", settings.aica.LimitFPS)
|| cfgLoadInt(config_section, "aica.LimitFPS", 0) == 2;
settings.aica.DSPEnabled = cfgLoadBool(config_section, "aica.DSPEnabled", settings.aica.DSPEnabled);
settings.aica.NoSound = cfgLoadBool(config_section, "aica.NoSound", settings.aica.NoSound);
settings.aica.BufferSize = cfgLoadInt(config_section, "aica.BufferSize", settings.aica.BufferSize);
settings.aica.BufferSize = std::max(512u, settings.aica.BufferSize);
settings.audio.backend = cfgLoadStr(audio_section, "backend", settings.audio.backend.c_str());
settings.rend.UseMipmaps = cfgLoadBool(config_section, "rend.UseMipmaps", settings.rend.UseMipmaps);
settings.rend.WideScreen = cfgLoadBool(config_section, "rend.WideScreen", settings.rend.WideScreen);
settings.rend.ShowFPS = cfgLoadBool(config_section, "rend.ShowFPS", settings.rend.ShowFPS);
settings.rend.RenderToTextureBuffer = cfgLoadBool(config_section, "rend.RenderToTextureBuffer", settings.rend.RenderToTextureBuffer);
settings.rend.RenderToTextureUpscale = cfgLoadInt(config_section, "rend.RenderToTextureUpscale", settings.rend.RenderToTextureUpscale);
settings.rend.TranslucentPolygonDepthMask = cfgLoadBool(config_section, "rend.TranslucentPolygonDepthMask", settings.rend.TranslucentPolygonDepthMask);
settings.rend.ModifierVolumes = cfgLoadBool(config_section, "rend.ModifierVolumes", settings.rend.ModifierVolumes);
settings.rend.Clipping = cfgLoadBool(config_section, "rend.Clipping", settings.rend.Clipping);
settings.rend.TextureUpscale = cfgLoadInt(config_section, "rend.TextureUpscale", settings.rend.TextureUpscale);
settings.rend.MaxFilteredTextureSize = cfgLoadInt(config_section,"rend.MaxFilteredTextureSize", settings.rend.MaxFilteredTextureSize);
std::string extra_depth_scale_str = cfgLoadStr(config_section,"rend.ExtraDepthScale", "");
if (!extra_depth_scale_str.empty())
{
settings.rend.ExtraDepthScale = atof(extra_depth_scale_str.c_str());
if (settings.rend.ExtraDepthScale == 0)
settings.rend.ExtraDepthScale = 1.f;
}
settings.rend.CustomTextures = cfgLoadBool(config_section, "rend.CustomTextures", settings.rend.CustomTextures);
settings.rend.DumpTextures = cfgLoadBool(config_section, "rend.DumpTextures", settings.rend.DumpTextures);
settings.rend.ScreenScaling = cfgLoadInt(config_section, "rend.ScreenScaling", settings.rend.ScreenScaling);
settings.rend.ScreenScaling = std::min(std::max(1, settings.rend.ScreenScaling), 800);
settings.rend.ScreenStretching = cfgLoadInt(config_section, "rend.ScreenStretching", settings.rend.ScreenStretching);
settings.rend.Fog = cfgLoadBool(config_section, "rend.Fog", settings.rend.Fog);
settings.rend.FloatVMUs = cfgLoadBool(config_section, "rend.FloatVMUs", settings.rend.FloatVMUs);
settings.rend.Rotate90 = cfgLoadBool(config_section, "rend.Rotate90", settings.rend.Rotate90);
settings.rend.PerStripSorting = cfgLoadBool(config_section, "rend.PerStripSorting", settings.rend.PerStripSorting);
settings.rend.DelayFrameSwapping = cfgLoadBool(config_section, "rend.DelayFrameSwapping", settings.rend.DelayFrameSwapping);
settings.rend.WidescreenGameHacks = cfgLoadBool(config_section, "rend.WidescreenGameHacks", settings.rend.WidescreenGameHacks);
for (u32 i = 0; i < ARRAY_SIZE(settings.rend.CrosshairColor); i++)
{
std::string name = "rend.CrossHairColor" + std::to_string(i + 1);
settings.rend.CrosshairColor[i] = cfgLoadInt(config_section, name.c_str(), settings.rend.CrosshairColor[i]);
}
settings.pvr.ta_skip = cfgLoadInt(config_section, "ta.skip", settings.pvr.ta_skip);
settings.pvr.MaxThreads = cfgLoadInt(config_section, "pvr.MaxThreads", settings.pvr.MaxThreads);
if (game_specific)
settings.pvr.AutoSkipFrame = cfgLoadInt(config_section, "pvr.AutoSkipFrame", settings.pvr.AutoSkipFrame);
else
{
// compatibility with previous SynchronousRendering option
int autoskip = cfgLoadInt(config_section, "pvr.AutoSkipFrame", 99);
if (autoskip == 99)
autoskip = cfgLoadBool(config_section, "pvr.SynchronousRendering", true) ? 1 : 2;
settings.pvr.AutoSkipFrame = autoskip;
}
settings.debug.SerialConsole = cfgLoadBool(config_section, "Debug.SerialConsoleEnabled", settings.debug.SerialConsole);
settings.debug.SerialPTY = cfgLoadBool(config_section, "Debug.SerialPTY", settings.debug.SerialPTY);
settings.bios.UseReios = cfgLoadBool(config_section, "bios.UseReios", settings.bios.UseReios);
settings.validate.OpenGlChecks = cfgLoadBool(game_specific ? cfgGetGameId() : "validate", "OpenGlChecks", settings.validate.OpenGlChecks);
settings.input.MouseSensitivity = cfgLoadInt(input_section, "MouseSensitivity", settings.input.MouseSensitivity);
settings.input.JammaSetup = (JVS)cfgLoadInt(input_section, "JammaSetup", (int)settings.input.JammaSetup);
settings.input.VirtualGamepadVibration = cfgLoadInt(input_section, "VirtualGamepadVibration", settings.input.VirtualGamepadVibration);
for (int i = 0; i < MAPLE_PORTS; i++)
{
char device_name[32];
sprintf(device_name, "device%d", i + 1);
settings.input.maple_devices[i] = (MapleDeviceType)cfgLoadInt(input_section, device_name, settings.input.maple_devices[i]);
sprintf(device_name, "device%d.1", i + 1);
settings.input.maple_expansion_devices[i][0] = (MapleDeviceType)cfgLoadInt(input_section, device_name, settings.input.maple_expansion_devices[i][0]);
sprintf(device_name, "device%d.2", i + 1);
settings.input.maple_expansion_devices[i][1] = (MapleDeviceType)cfgLoadInt(input_section, device_name, settings.input.maple_expansion_devices[i][1]);
}
settings.network.Enable = cfgLoadBool("network", "Enable", settings.network.Enable);
settings.network.ActAsServer = cfgLoadBool("network", "ActAsServer", settings.network.ActAsServer);
settings.network.dns = cfgLoadStr("network", "DNS", settings.network.dns.c_str());
settings.network.server = cfgLoadStr("network", "server", settings.network.server.c_str());
settings.network.EmulateBBA = cfgLoadBool("network", "EmulateBBA", settings.network.EmulateBBA);
#if SUPPORT_DISPMANX
settings.dispmanx.Width = cfgLoadInt(game_specific ? cfgGetGameId() : "dispmanx", "width", settings.dispmanx.Width);
settings.dispmanx.Height = cfgLoadInt(game_specific ? cfgGetGameId() : "dispmanx", "height", settings.dispmanx.Height);
settings.dispmanx.Keep_Aspect = cfgLoadBool(game_specific ? cfgGetGameId() : "dispmanx", "maintain_aspect", settings.dispmanx.Keep_Aspect);
#endif
#if USE_OMX
settings.omx.Audio_Latency = cfgLoadInt(game_specific ? cfgGetGameId() : "omx", "audio_latency", settings.omx.Audio_Latency);
settings.omx.Audio_HDMI = cfgLoadBool(game_specific ? cfgGetGameId() : "omx", "audio_hdmi", settings.omx.Audio_HDMI);
#endif
if (!game_specific)
{
settings.dreamcast.ContentPath.clear();
std::string paths = cfgLoadStr(config_section, "Dreamcast.ContentPath", "");
std::string::size_type start = 0;
while (true)
{
std::string::size_type end = paths.find(';', start);
if (end == std::string::npos)
end = paths.size();
if (start != end)
settings.dreamcast.ContentPath.push_back(paths.substr(start, end - start));
if (end == paths.size())
break;
start = end + 1;
}
settings.dreamcast.HideLegacyNaomiRoms = cfgLoadBool(config_section, "Dreamcast.HideLegacyNaomiRoms", settings.dreamcast.HideLegacyNaomiRoms);
}
/*
//make sure values are valid
settings.dreamcast.cable = std::min(std::max(settings.dreamcast.cable, 0),3);
settings.dreamcast.region = std::min(std::max(settings.dreamcast.region, 0),3);
settings.dreamcast.broadcast = std::min(std::max(settings.dreamcast.broadcast,0),4);
*/
}
static void LoadCustom()
void LoadGameSpecificSettings()
{
char *reios_id;
if (settings.platform.system == DC_PLATFORM_DREAMCAST)
@ -969,124 +707,27 @@ static void LoadCustom()
// Default per-game settings
LoadSpecialSettings();
cfgSetGameId(reios_id);
config::Settings::instance().setGameId(reios_id);
// Reload per-game settings
LoadSettings(true);
config::Settings::instance().load(true);
}
void SaveSettings()
{
cfgSetAutoSave(false);
cfgSaveBool("config", "Dynarec.Enabled", settings.dynarec.Enable);
if (forced_game_cable == -1 || forced_game_cable != (int)settings.dreamcast.cable)
cfgSaveInt("config", "Dreamcast.Cable", settings.dreamcast.cable);
if (forced_game_region == -1 || forced_game_region != (int)settings.dreamcast.region)
cfgSaveInt("config", "Dreamcast.Region", settings.dreamcast.region);
cfgSaveInt("config", "Dreamcast.Broadcast", settings.dreamcast.broadcast);
cfgSaveBool("config", "Dreamcast.ForceWindowsCE", settings.dreamcast.ForceWindowsCE);
cfgSaveBool("config", "Dynarec.idleskip", settings.dynarec.idleskip);
cfgSaveBool("config", "Dynarec.unstable-opt", settings.dynarec.unstable_opt);
if (!safemode_game || !settings.dynarec.safemode)
cfgSaveBool("config", "Dynarec.safe-mode", settings.dynarec.safemode);
cfgSaveBool("config", "bios.UseReios", settings.bios.UseReios);
// if (!disable_vmem32_game || !settings.dynarec.disable_vmem32)
// cfgSaveBool("config", "Dynarec.DisableVmem32", settings.dynarec.disable_vmem32);
cfgSaveInt("config", "Dreamcast.Language", settings.dreamcast.language);
cfgSaveBool("config", "aica.LimitFPS", settings.aica.LimitFPS);
cfgSaveBool("config", "aica.DSPEnabled", settings.aica.DSPEnabled);
cfgSaveBool("config", "aica.NoSound", settings.aica.NoSound);
cfgSaveInt("config", "aica.BufferSize", settings.aica.BufferSize);
cfgSaveStr("audio", "backend", settings.audio.backend.c_str());
// Write backend specific settings
// std::map<std::string, std::map<std::string, std::string>>
for (const auto& pair : settings.audio.options)
{
const std::string& section = pair.first;
const auto& options = pair.second;
for (const auto& option : options)
cfgSaveStr(section.c_str(), option.first.c_str(), option.second.c_str());
}
cfgSaveBool("config", "rend.WideScreen", settings.rend.WideScreen);
cfgSaveBool("config", "rend.ShowFPS", settings.rend.ShowFPS);
if (!rtt_to_buffer_game || !settings.rend.RenderToTextureBuffer)
cfgSaveBool("config", "rend.RenderToTextureBuffer", settings.rend.RenderToTextureBuffer);
cfgSaveInt("config", "rend.RenderToTextureUpscale", settings.rend.RenderToTextureUpscale);
cfgSaveBool("config", "rend.ModifierVolumes", settings.rend.ModifierVolumes);
cfgSaveBool("config", "rend.Clipping", settings.rend.Clipping);
cfgSaveInt("config", "rend.TextureUpscale", settings.rend.TextureUpscale);
cfgSaveInt("config", "rend.MaxFilteredTextureSize", settings.rend.MaxFilteredTextureSize);
cfgSaveBool("config", "rend.CustomTextures", settings.rend.CustomTextures);
cfgSaveBool("config", "rend.DumpTextures", settings.rend.DumpTextures);
cfgSaveInt("config", "rend.ScreenScaling", settings.rend.ScreenScaling);
if (saved_screen_stretching != -1)
cfgSaveInt("config", "rend.ScreenStretching", saved_screen_stretching);
else
cfgSaveInt("config", "rend.ScreenStretching", settings.rend.ScreenStretching);
cfgSaveBool("config", "rend.Fog", settings.rend.Fog);
cfgSaveBool("config", "rend.FloatVMUs", settings.rend.FloatVMUs);
if (!naomi_rotate_screen || !settings.rend.Rotate90)
cfgSaveBool("config", "rend.Rotate90", settings.rend.Rotate90);
cfgSaveInt("config", "ta.skip", settings.pvr.ta_skip);
cfgSaveInt("config", "pvr.rend", (int)settings.pvr.rend);
cfgSaveBool("config", "rend.PerStripSorting", settings.rend.PerStripSorting);
cfgSaveBool("config", "rend.DelayFrameSwapping", settings.rend.DelayFrameSwapping);
cfgSaveBool("config", "rend.WidescreenGameHacks", settings.rend.WidescreenGameHacks);
for (u32 i = 0; i < ARRAY_SIZE(settings.rend.CrosshairColor); i++)
{
std::string name = "rend.CrossHairColor" + std::to_string(i + 1);
cfgSaveInt("config", name.c_str(), settings.rend.CrosshairColor[i]);
}
cfgSaveInt("config", "pvr.MaxThreads", settings.pvr.MaxThreads);
cfgSaveInt("config", "pvr.AutoSkipFrame", settings.pvr.AutoSkipFrame);
cfgSaveBool("config", "Debug.SerialConsoleEnabled", settings.debug.SerialConsole);
cfgSaveBool("config", "Debug.SerialPTY", settings.debug.SerialPTY);
cfgSaveInt("input", "MouseSensitivity", settings.input.MouseSensitivity);
cfgSaveInt("input", "VirtualGamepadVibration", settings.input.VirtualGamepadVibration);
for (int i = 0; i < MAPLE_PORTS; i++)
{
char device_name[32];
sprintf(device_name, "device%d", i + 1);
cfgSaveInt("input", device_name, (s32)settings.input.maple_devices[i]);
sprintf(device_name, "device%d.1", i + 1);
cfgSaveInt("input", device_name, (s32)settings.input.maple_expansion_devices[i][0]);
sprintf(device_name, "device%d.2", i + 1);
cfgSaveInt("input", device_name, (s32)settings.input.maple_expansion_devices[i][1]);
}
// FIXME This should never be a game-specific setting
std::string paths;
for (auto& path : settings.dreamcast.ContentPath)
{
if (!paths.empty())
paths += ";";
paths += path;
}
cfgSaveStr("config", "Dreamcast.ContentPath", paths.c_str());
cfgSaveBool("config", "Dreamcast.HideLegacyNaomiRoms", settings.dreamcast.HideLegacyNaomiRoms);
cfgSaveBool("network", "Enable", settings.network.Enable);
cfgSaveBool("network", "ActAsServer", settings.network.ActAsServer);
cfgSaveStr("network", "DNS", settings.network.dns.c_str());
cfgSaveStr("network", "server", settings.network.server.c_str());
cfgSaveBool("network", "EmulateBBA", settings.network.EmulateBBA);
config::Settings::instance().save();
GamepadDevice::SaveMaplePorts();
#ifdef __ANDROID__
void SaveAndroidSettings();
SaveAndroidSettings();
#endif
cfgSetAutoSave(true);
}
void dc_resume()
{
SetMemoryHandlers();
settings.aica.NoBatch = config::ForceWindowsCE || config::DSPEnabled;
EventManager::event(Event::Resume);
if (!emu_thread.thread.joinable())
emu_thread.Start();
@ -1126,8 +767,6 @@ void dc_savestate()
unsigned int total_size = 0 ;
void *data = NULL ;
dc_stop();
if ( ! dc_serialize(&data, &total_size) )
{
WARN_LOG(SAVESTATE, "Failed to save state - could not initialize total size") ;

View File

@ -112,7 +112,7 @@ static void alsa_init()
}
// Sample buffer size
buffer_size = settings.aica.BufferSize;
buffer_size = config::AudioBufferSize;
rc = snd_pcm_hw_params_set_buffer_size_near(handle, params, &buffer_size);
if (rc < 0)
{

View File

@ -120,7 +120,7 @@ static void coreaudio_init()
err = AudioUnitInitialize(audioUnit);
verify(err == noErr);
BUFSIZE = settings.aica.BufferSize * 4;
BUFSIZE = config::AudioBufferSize * 4;
samples_temp = new u8[BUFSIZE]();
samples_rptr = 0;
samples_wptr = 0;

View File

@ -87,8 +87,8 @@ static void omx_init()
}
// Initialize settings
latency_max = settings.omx.Audio_Latency;
buffer_size = settings.aica.BufferSize * 4;
latency_max = config::OmxAudioLatency;
buffer_size = config::AudioBufferSize * 4;
buffer_count = 2 + OUTPUT_FREQ * latency_max / (buffer_size * 1000);
OMX_CALLBACKTYPE callbacks;
@ -224,7 +224,7 @@ static void omx_init()
}
const char* output_device = "local";
if(settings.omx.Audio_HDMI)
if (config::OmxAudioHdmi)
output_device = (const char*)"hdmi";
// Set audio destination

View File

@ -210,7 +210,7 @@ static void pulseaudio_init()
pa_buffer_attr buffer_attr;
buffer_attr.maxlength = -1;
buffer_attr.tlength = pa_usec_to_bytes(settings.aica.BufferSize * PA_USEC_PER_SEC / 44100, &spec);
buffer_attr.tlength = pa_usec_to_bytes(config::AudioBufferSize * PA_USEC_PER_SEC / 44100, &spec);
buffer_attr.prebuf = -1;
buffer_attr.minreq = -1;
buffer_attr.fragsize = -1;

View File

@ -1,5 +1,4 @@
#include "audiostream.h"
#include "cfg/cfg.h"
#include <algorithm>
#include <memory>
@ -19,7 +18,7 @@ static bool eight_khz;
u32 GetAudioBackendCount()
{
return audiobackends != nullptr ? audiobackends->size() : 0;
return audiobackends != nullptr ? (u32)audiobackends->size() : 0;
}
audiobackend_t* GetAudioBackend(int num)
@ -98,7 +97,7 @@ void WriteSample(s16 r, s16 l)
WritePtr=ptr;
if (WritePtr == SAMPLE_COUNT - 1)
PushAudio(RingBuffer,SAMPLE_COUNT, settings.aica.LimitFPS);
PushAudio(RingBuffer,SAMPLE_COUNT, config::LimitFPS);
}
void InitAudio()
@ -114,7 +113,7 @@ void InitAudio()
SortAudioBackends();
std::string audiobackend_slug = settings.audio.backend;
std::string audiobackend_slug = config::AudioBackend;
audiobackend_current = GetAudioBackend(audiobackend_slug);
if (audiobackend_current == nullptr) {
INFO_LOG(AUDIO, "WARNING: Running without audio!");

View File

@ -1,5 +1,6 @@
#pragma once
#include "types.h"
#include "cfg/option.h"
typedef std::vector<std::string> (*audio_option_callback_t)();
enum audio_option_type

View File

@ -10,6 +10,7 @@
#include "hw/sh4/sh4_core.h"
#include "hw/sh4/dyna/ngen.h"
#include "hw/sh4/sh4_mem.h"
#include "cfg/option.h"
#define _DEVEL 1
#include "arm_emitter/arm_emitter.h"
@ -949,7 +950,7 @@ u32* ngen_readm_fail_v2(u32* ptrv,u32* regs,u32 fault_addr)
//fault offset must always be the addr from ubfx (sanity check)
verify((fault_offs==0) || fault_offs==(0x1FFFFFFF&sh4_addr));
if (settings.dynarec.unstable_opt && is_sq) //THPS2 uses cross area SZ_32F so this is disabled for now
if (config::DynarecUnstableOpt && is_sq) //THPS2 uses cross area SZ_32F so this is disabled for now
{
//SQ !
s32 sq_offs=sq_both-sh4_ctr;
@ -2210,14 +2211,6 @@ void ngen_Compile(RuntimeBlockInfo* block, bool force_checks, bool reset, bool s
//StoreImms(r0,r1,(u32)&last_run_block,(u32)code); //useful when code jumps to random locations ...
++blockno;
if (settings.profile.run_counts)
{
MOV32(r1,(u32)&block->runs);
LDR(r0,r1);
ADD(r0,r0,1);
STR(r0,r1);
}
//reg alloc
reg.DoAlloc(block,alloc_regs,alloc_fpu);

View File

@ -19,6 +19,7 @@
#include "CustomTexture.h"
#include "cfg/cfg.h"
#include "oslib/directory.h"
#include "cfg/option.h"
#include <sstream>
#define STB_IMAGE_IMPLEMENTATION
@ -82,7 +83,7 @@ void CustomTexture::LoaderThread()
std::string CustomTexture::GetGameId()
{
std::string game_id(cfgGetGameId());
std::string game_id(config::Settings::instance().getGameId());
const size_t str_end = game_id.find_last_not_of(' ');
if (str_end == std::string::npos)
return "";

View File

@ -270,7 +270,7 @@ static inline int getThreadCount()
int tcount = omp_get_num_procs() - 1;
if (tcount < 1)
tcount = 1;
return std::min(tcount, (int)settings.pvr.MaxThreads);
return std::min(tcount, (int)config::MaxThreads);
}
template<typename Func>
@ -563,7 +563,7 @@ void BaseTextureCacheData::Update()
return;
}
}
if (settings.rend.CustomTextures)
if (config::CustomTextures)
custom_texture.LoadCustomTextureAsync(this);
void *temp_tex_buffer = NULL;
@ -575,9 +575,9 @@ void BaseTextureCacheData::Update()
PixelBuffer<u8> pb8;
// Figure out if we really need to use a 32-bit pixel buffer
bool textureUpscaling = settings.rend.TextureUpscale > 1
bool textureUpscaling = config::TextureUpscale > 1
// Don't process textures that are too big
&& (int)(w * h) <= settings.rend.MaxFilteredTextureSize * settings.rend.MaxFilteredTextureSize
&& (int)(w * h) <= config::MaxFilteredTextureSize * config::MaxFilteredTextureSize
// Don't process YUV textures
&& tcw.PixelFmt != PixelYUV;
bool need_32bit_buffer = true;
@ -588,7 +588,7 @@ void BaseTextureCacheData::Update()
need_32bit_buffer = false;
// TODO avoid upscaling/depost. textures that change too often
bool mipmapped = IsMipmapped() && !settings.rend.DumpTextures;
bool mipmapped = IsMipmapped() && !config::DumpTextures;
if (texconv32 != NULL && need_32bit_buffer)
{
@ -636,15 +636,15 @@ void BaseTextureCacheData::Update()
if (textureUpscaling)
{
PixelBuffer<u32> tmp_buf;
tmp_buf.init(w * settings.rend.TextureUpscale, h * settings.rend.TextureUpscale);
tmp_buf.init(w * config::TextureUpscale, h * config::TextureUpscale);
if (tcw.PixelFmt == Pixel1555 || tcw.PixelFmt == Pixel4444)
// Alpha channel formats. Palettes with alpha are already handled
has_alpha = true;
UpscalexBRZ(settings.rend.TextureUpscale, pb32.data(), tmp_buf.data(), w, h, has_alpha);
UpscalexBRZ(config::TextureUpscale, pb32.data(), tmp_buf.data(), w, h, has_alpha);
pb32.steal_data(tmp_buf);
upscaled_w *= settings.rend.TextureUpscale;
upscaled_h *= settings.rend.TextureUpscale;
upscaled_w *= config::TextureUpscale;
upscaled_h *= config::TextureUpscale;
}
}
temp_tex_buffer = pb32.data();
@ -720,7 +720,7 @@ void BaseTextureCacheData::Update()
lock_block = libCore_vramlock_Lock(sa_tex,sa+size-1,this);
UploadToGPU(upscaled_w, upscaled_h, (u8*)temp_tex_buffer, IsMipmapped(), mipmapped);
if (settings.rend.DumpTextures)
if (config::DumpTextures)
{
ComputeHash();
custom_texture.DumpTexture(texture_hash, upscaled_w, upscaled_h, tex_type, temp_tex_buffer);

View File

@ -1,6 +1,7 @@
#pragma once
#include "oslib/oslib.h"
#include "hw/pvr/Renderer_if.h"
#include "cfg/option.h"
#include <algorithm>
#include <array>
@ -700,7 +701,7 @@ public:
bool IsMipmapped()
{
return tcw.MipMapped != 0 && tcw.ScanOrder == 0 && settings.rend.UseMipmaps;
return tcw.MipMapped != 0 && tcw.ScanOrder == 0 && config::UseMipmaps;
}
const char* GetPixelFormatName()
@ -739,8 +740,8 @@ public:
// This is currently limited to textures using nearest filtering and not mipmapped.
// Enabling texture upscaling or dumping also disables this mode.
return (tcw.PixelFmt == PixelPal4 || tcw.PixelFmt == PixelPal8)
&& settings.rend.TextureUpscale == 1
&& !settings.rend.DumpTextures
&& config::TextureUpscale == 1
&& !config::DumpTextures
&& tsp.FilterMode == 0
&& !tcw.MipMapped
&& !tcw.VQ_Comp;

View File

@ -26,6 +26,7 @@
#include "stdclass.h"
#include "hw/naomi/naomi_roms.h"
#include "oslib/directory.h"
#include "cfg/option.h"
struct GameMedia {
std::string name;
@ -70,6 +71,9 @@ class GameScanner
DirectoryTree tree(path);
for (const DirectoryTree::item& item : tree)
{
if (item.name.substr(0, 2) == "._")
// Ignore Mac OS turds
continue;
std::string name(item.name);
std::string child_path = item.parentPath + "/" + name;
#ifdef __APPLE__
@ -95,7 +99,7 @@ class GameScanner
if (arcade_gdroms.count(basename) != 0)
continue;
}
else if ((settings.dreamcast.HideLegacyNaomiRoms
else if ((config::HideLegacyNaomiRoms
|| (extension != "bin" && extension != "lst" && extension != "dat"))
&& extension != "cdi" && extension != "cue")
continue;
@ -143,7 +147,7 @@ public:
std::lock_guard<std::mutex> guard(mutex);
game_list.clear();
}
for (const auto& path : settings.dreamcast.ContentPath)
for (const auto& path : config::ContentPath.get())
{
add_game_directory(path);
if (!running)

View File

@ -127,7 +127,7 @@ static void SetGPState(const PolyParam* gp)
bool two_volumes_mode = (gp->tsp1.full != (u32)-1) && Type != ListType_Translucent;
bool color_clamp = gp->tsp.ColorClamp && (pvrrc.fog_clamp_min != 0 || pvrrc.fog_clamp_max != 0xffffffff);
int fog_ctrl = settings.rend.Fog ? gp->tsp.FogCtrl : 2;
int fog_ctrl = config::Fog ? gp->tsp.FogCtrl : 2;
palette = BaseTextureCacheData::IsGpuHandledPaletted(gp->tsp, gp->tcw);
CurrentShader = gl4GetProgram(Type == ListType_Punch_Through ? 1 : 0,
@ -212,7 +212,7 @@ static void SetGPState(const PolyParam* gp)
{
//bilinear filtering
//PowerVR supports also trilinear via two passes, but we ignore that for now
bool mipmapped = gp->tcw.MipMapped != 0 && gp->tcw.ScanOrder == 0 && settings.rend.UseMipmaps;
bool mipmapped = gp->tcw.MipMapped != 0 && gp->tcw.ScanOrder == 0 && config::UseMipmaps;
glSamplerParameteri(texSamplers[i], GL_TEXTURE_MIN_FILTER, mipmapped ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
glSamplerParameteri(texSamplers[i], GL_TEXTURE_MAG_FILTER, GL_LINEAR);
if (mipmapped)
@ -528,7 +528,7 @@ void gl4DrawStrips(GLuint output_fbo, int width, int height)
DrawList<ListType_Punch_Through, false, Pass::Depth>(pvrrc.global_param_pt, previous_pass.pt_count, current_pass.pt_count - previous_pass.pt_count);
// Modifier volumes
if (settings.rend.ModifierVolumes)
if (config::ModifierVolumes)
DrawModVols(previous_pass.mvo_count, current_pass.mvo_count - previous_pass.mvo_count);
//
@ -591,7 +591,7 @@ void gl4DrawStrips(GLuint output_fbo, int width, int height)
DrawList<ListType_Translucent, true, Pass::OIT>(pvrrc.global_param_tr, previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count);
// Translucent modifier volumes
if (settings.rend.ModifierVolumes)
if (config::ModifierVolumes)
{
SetBaseClipping();
DrawTranslucentModVols(previous_pass.mvo_tr_count, current_pass.mvo_tr_count - previous_pass.mvo_tr_count);

View File

@ -563,7 +563,7 @@ static bool gl4_init()
initABuffer();
if (settings.rend.TextureUpscale > 1)
if (config::TextureUpscale > 1)
{
// Trick to preload the tables used by xBRZ
u32 src[] { 0x11111111, 0x22222222, 0x33333333, 0x44444444 };
@ -628,12 +628,12 @@ static bool RenderFrame()
/*
Handle Dc to screen scaling
*/
const float screen_scaling = settings.rend.ScreenScaling / 100.f;
const float screen_scaling = config::ScreenScaling / 100.f;
int rendering_width;
int rendering_height;
if (is_rtt)
{
int scaling = settings.rend.RenderToTextureBuffer ? 1 : settings.rend.RenderToTextureUpscale;
int scaling = config::RenderToTextureBuffer ? 1 : config::RenderToTextureUpscale;
rendering_width = matrices.GetDreamcastViewport().x * scaling;
rendering_height = matrices.GetDreamcastViewport().y * scaling;
}
@ -661,7 +661,7 @@ static bool RenderFrame()
u8* fog_density=(u8*)&FOG_DENSITY;
float fog_den_mant=fog_density[1]/128.0f; //bit 7 -> x. bit, so [6:0] -> fraction -> /128
s32 fog_den_exp=(s8)fog_density[0];
gl4ShaderUniforms.fog_den_float = fog_den_mant * powf(2.0f,fog_den_exp) * settings.rend.ExtraDepthScale;
gl4ShaderUniforms.fog_den_float = fog_den_mant * powf(2.0f,fog_den_exp) * config::ExtraDepthScale;
gl4ShaderUniforms.fog_clamp_min[0] = ((pvrrc.fog_clamp_min >> 16) & 0xFF) / 255.0f;
gl4ShaderUniforms.fog_clamp_min[1] = ((pvrrc.fog_clamp_min >> 8) & 0xFF) / 255.0f;
@ -673,7 +673,7 @@ static bool RenderFrame()
gl4ShaderUniforms.fog_clamp_max[2] = ((pvrrc.fog_clamp_max >> 0) & 0xFF) / 255.0f;
gl4ShaderUniforms.fog_clamp_max[3] = ((pvrrc.fog_clamp_max >> 24) & 0xFF) / 255.0f;
if (fog_needs_update && settings.rend.Fog)
if (fog_needs_update && config::Fog)
{
fog_needs_update = false;
UpdateFogTexture((u8 *)FOG_TABLE, GL_TEXTURE5, GL_RED);
@ -735,7 +735,7 @@ static bool RenderFrame()
}
else
{
if (settings.rend.ScreenScaling != 100 || !theGLContext.IsSwapBufferPreserved())
if (config::ScreenScaling != 100 || !theGLContext.IsSwapBufferPreserved())
{
output_fbo = init_output_framebuffer(rendering_width, rendering_height);
}
@ -772,7 +772,7 @@ static bool RenderFrame()
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(struct PolyParam) * pvrrc.global_param_tr.used(), pvrrc.global_param_tr.head(), GL_STATIC_DRAW);
glCheck();
if (is_rtt || !settings.rend.WideScreen || matrices.IsClipped() || settings.rend.Rotate90)
if (is_rtt || !config::Widescreen || matrices.IsClipped() || config::Rotate90)
{
float width;
float height;
@ -829,12 +829,12 @@ static bool RenderFrame()
height = pvrrc.fb_Y_CLIP.max - pvrrc.fb_Y_CLIP.min + 1;
min_x = pvrrc.fb_X_CLIP.min;
min_y = pvrrc.fb_Y_CLIP.min;
if (settings.rend.RenderToTextureUpscale > 1 && !settings.rend.RenderToTextureBuffer)
if (config::RenderToTextureUpscale > 1 && !config::RenderToTextureBuffer)
{
min_x *= settings.rend.RenderToTextureUpscale;
min_y *= settings.rend.RenderToTextureUpscale;
width *= settings.rend.RenderToTextureUpscale;
height *= settings.rend.RenderToTextureUpscale;
min_x *= config::RenderToTextureUpscale;
min_y *= config::RenderToTextureUpscale;
width *= config::RenderToTextureUpscale;
height *= config::RenderToTextureUpscale;
}
}
gl4ShaderUniforms.base_clipping.enabled = true;
@ -866,7 +866,7 @@ static bool RenderFrame()
if (is_rtt)
ReadRTTBuffer();
else if (settings.rend.ScreenScaling != 100 || !theGLContext.IsSwapBufferPreserved())
else if (config::ScreenScaling != 100 || !theGLContext.IsSwapBufferPreserved())
gl4_render_output_framebuffer();
return !is_rtt;
@ -885,7 +885,7 @@ struct OpenGL4Renderer : OpenGLRenderer
{
screen_width=w;
screen_height=h;
resize((int)lroundf(w * settings.rend.ScreenScaling / 100.f), (int)lroundf(h * settings.rend.ScreenScaling / 100.f));
resize((int)lroundf(w * config::ScreenScaling / 100.f), (int)lroundf(h * config::ScreenScaling / 100.f));
}
void Term() override

View File

@ -16,12 +16,12 @@ GLuint gl4BindRTT(u32 addy, u32 fbw, u32 fbh, u32 channels, u32 fmt)
while (fbw2 < fbw)
fbw2 *= 2;
if (settings.rend.RenderToTextureUpscale > 1 && !settings.rend.RenderToTextureBuffer)
if (config::RenderToTextureUpscale > 1 && !config::RenderToTextureBuffer)
{
fbw *= settings.rend.RenderToTextureUpscale;
fbh *= settings.rend.RenderToTextureUpscale;
fbw2 *= settings.rend.RenderToTextureUpscale;
fbh2 *= settings.rend.RenderToTextureUpscale;
fbw *= config::RenderToTextureUpscale;
fbh *= config::RenderToTextureUpscale;
fbw2 *= config::RenderToTextureUpscale;
fbh2 *= config::RenderToTextureUpscale;
}
// Create a texture for rendering to

View File

@ -116,7 +116,7 @@ __forceinline
ShaderUniforms.trilinear_alpha = 1.f;
bool color_clamp = gp->tsp.ColorClamp && (pvrrc.fog_clamp_min != 0 || pvrrc.fog_clamp_max != 0xffffffff);
int fog_ctrl = settings.rend.Fog ? gp->tsp.FogCtrl : 2;
int fog_ctrl = config::Fog ? gp->tsp.FogCtrl : 2;
int clip_rect[4] = {};
TileClipping clipmode = GetTileClip(gp->tileclip, ViewportMatrix, clip_rect);
@ -180,7 +180,7 @@ __forceinline
{
//bilinear filtering
//PowerVR supports also trilinear via two passes, but we ignore that for now
bool mipmapped = gp->tcw.MipMapped != 0 && gp->tcw.ScanOrder == 0 && settings.rend.UseMipmaps;
bool mipmapped = gp->tcw.MipMapped != 0 && gp->tcw.ScanOrder == 0 && config::UseMipmaps;
glcache.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mipmapped ? GL_LINEAR_MIPMAP_NEAREST : GL_LINEAR);
glcache.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
#ifdef GL_TEXTURE_LOD_BIAS
@ -213,7 +213,7 @@ __forceinline
glcache.DepthFunc(Zfunction[gp->isp.DepthMode]);
}
if (SortingEnabled && !settings.rend.PerStripSorting)
if (SortingEnabled && !config::PerStripSorting)
glcache.DepthMask(GL_FALSE);
else
{
@ -332,7 +332,7 @@ void DrawSorted(bool multipass)
params++;
}
if (multipass && settings.rend.TranslucentPolygonDepthMask)
if (multipass && config::TranslucentPolygonDepthMask)
{
// Write to the depth buffer now. The next render pass might need it. (Cosmic Smash)
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
@ -610,14 +610,14 @@ void DrawStrips()
DrawList<ListType_Punch_Through,false>(pvrrc.global_param_pt, previous_pass.pt_count, current_pass.pt_count - previous_pass.pt_count);
// Modifier volumes
if (settings.rend.ModifierVolumes)
if (config::ModifierVolumes)
DrawModVols(previous_pass.mvo_count, current_pass.mvo_count - previous_pass.mvo_count);
//Alpha blended
{
if (current_pass.autosort)
{
if (!settings.rend.PerStripSorting)
if (!config::PerStripSorting)
{
SortTriangles(previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count);
DrawSorted(render_pass < pvrrc.render_passes.used() - 1);

View File

@ -912,7 +912,7 @@ bool gles_init()
#endif
glCheck();
if (settings.rend.TextureUpscale > 1)
if (config::TextureUpscale > 1)
{
// Trick to preload the tables used by xBRZ
u32 src[] { 0x11111111, 0x22222222, 0x33333333, 0x44444444 };
@ -1121,7 +1121,7 @@ bool RenderFrame()
u8* fog_density = (u8*)&FOG_DENSITY;
float fog_den_mant = fog_density[1] / 128.0f; //bit 7 -> x. bit, so [6:0] -> fraction -> /128
s32 fog_den_exp = (s8)fog_density[0];
ShaderUniforms.fog_den_float = fog_den_mant * powf(2.0f, fog_den_exp) * settings.rend.ExtraDepthScale;
ShaderUniforms.fog_den_float = fog_den_mant * powf(2.0f, fog_den_exp) * config::ExtraDepthScale;
ShaderUniforms.fog_clamp_min[0] = ((pvrrc.fog_clamp_min >> 16) & 0xFF) / 255.0f;
ShaderUniforms.fog_clamp_min[1] = ((pvrrc.fog_clamp_min >> 8) & 0xFF) / 255.0f;
@ -1133,7 +1133,7 @@ bool RenderFrame()
ShaderUniforms.fog_clamp_max[2] = ((pvrrc.fog_clamp_max >> 0) & 0xFF) / 255.0f;
ShaderUniforms.fog_clamp_max[3] = ((pvrrc.fog_clamp_max >> 24) & 0xFF) / 255.0f;
if (fog_needs_update && settings.rend.Fog)
if (fog_needs_update && config::Fog)
{
fog_needs_update = false;
UpdateFogTexture((u8 *)FOG_TABLE, GL_TEXTURE1, gl.single_channel_format);
@ -1158,7 +1158,7 @@ bool RenderFrame()
ShaderUniforms.Set(&it.second);
}
const float screen_scaling = settings.rend.ScreenScaling / 100.f;
const float screen_scaling = config::ScreenScaling / 100.f;
//setup render target first
if (is_rtt)
@ -1202,7 +1202,7 @@ bool RenderFrame()
}
else
{
if (settings.rend.ScreenScaling != 100 || !theGLContext.IsSwapBufferPreserved())
if (config::ScreenScaling != 100 || !theGLContext.IsSwapBufferPreserved())
{
init_output_framebuffer((int)lroundf(screen_width * screen_scaling), (int)lroundf(screen_height * screen_scaling));
}
@ -1216,7 +1216,7 @@ bool RenderFrame()
}
}
bool wide_screen_on = !is_rtt && settings.rend.WideScreen && !matrices.IsClipped() && !settings.rend.Rotate90;
bool wide_screen_on = !is_rtt && config::Widescreen && !matrices.IsClipped() && !config::Rotate90;
//Color is cleared by the background plane
@ -1304,12 +1304,12 @@ bool RenderFrame()
height = pvrrc.fb_Y_CLIP.max - pvrrc.fb_Y_CLIP.min + 1;
min_x = pvrrc.fb_X_CLIP.min;
min_y = pvrrc.fb_Y_CLIP.min;
if (settings.rend.RenderToTextureUpscale > 1 && !settings.rend.RenderToTextureBuffer)
if (config::RenderToTextureUpscale > 1 && !config::RenderToTextureBuffer)
{
min_x *= settings.rend.RenderToTextureUpscale;
min_y *= settings.rend.RenderToTextureUpscale;
width *= settings.rend.RenderToTextureUpscale;
height *= settings.rend.RenderToTextureUpscale;
min_x *= config::RenderToTextureUpscale;
min_y *= config::RenderToTextureUpscale;
width *= config::RenderToTextureUpscale;
height *= config::RenderToTextureUpscale;
}
}
ShaderUniforms.base_clipping.enabled = true;
@ -1336,7 +1336,7 @@ bool RenderFrame()
if (is_rtt)
ReadRTTBuffer();
else if (settings.rend.ScreenScaling != 100 || !theGLContext.IsSwapBufferPreserved())
else if (config::ScreenScaling != 100 || !theGLContext.IsSwapBufferPreserved())
render_output_framebuffer();
return !is_rtt;

View File

@ -8,7 +8,7 @@
#include <unordered_map>
#include <glm/glm.hpp>
#define glCheck() do { if (unlikely(settings.validate.OpenGlChecks)) { verify(glGetError()==GL_NO_ERROR); } } while(0)
#define glCheck() do { if (unlikely(config::OpenGlChecks)) { verify(glGetError()==GL_NO_ERROR); } } while(0)
#define VERTEX_POS_ARRAY 0
#define VERTEX_COL_BASE_ARRAY 1

View File

@ -136,12 +136,12 @@ void BindRTT(u32 addy, u32 fbw, u32 fbh, u32 channels, u32 fmt)
while (fbw2 < fbw)
fbw2 *= 2;
if (settings.rend.RenderToTextureUpscale > 1 && !settings.rend.RenderToTextureBuffer)
if (config::RenderToTextureUpscale > 1 && !config::RenderToTextureBuffer)
{
fbw *= settings.rend.RenderToTextureUpscale;
fbh *= settings.rend.RenderToTextureUpscale;
fbw2 *= settings.rend.RenderToTextureUpscale;
fbh2 *= settings.rend.RenderToTextureUpscale;
fbw *= config::RenderToTextureUpscale;
fbh *= config::RenderToTextureUpscale;
fbw2 *= config::RenderToTextureUpscale;
fbh2 *= config::RenderToTextureUpscale;
}
// Get the currently bound frame buffer object. On most platforms this just gives 0.
//glGetIntegerv(GL_FRAMEBUFFER_BINDING, &m_i32OriginalFbo);
@ -215,7 +215,7 @@ void ReadRTTBuffer() {
const u8 fb_packmode = FB_W_CTRL.fb_packmode;
if (settings.rend.RenderToTextureBuffer)
if (config::RenderToTextureBuffer)
{
u32 tex_addr = gl.rtt.TexAddr << 3;
@ -257,7 +257,7 @@ void ReadRTTBuffer() {
//dumpRtTexture(fb_rtt.TexAddr, w, h);
if (w > 1024 || h > 1024 || settings.rend.RenderToTextureBuffer) {
if (w > 1024 || h > 1024 || config::RenderToTextureBuffer) {
glcache.DeleteTextures(1, &gl.rtt.tex);
}
else

File diff suppressed because it is too large Load Diff

View File

@ -18,6 +18,7 @@
*/
#pragma once
#include "types.h"
#include "cfg/option.h"
void gui_init();
void gui_open_settings();
@ -34,7 +35,7 @@ extern u32 vmu_lcd_data[8][48 * 32];
extern bool vmu_lcd_status[8];
extern bool vmu_lcd_changed[8];
typedef enum {
enum class GuiState {
Closed,
Commands,
Settings,
@ -45,17 +46,17 @@ typedef enum {
SelectDisk,
Loading,
NetworkStart
} GuiState;
};
extern GuiState gui_state;
void ImGui_Impl_NewFrame();
static inline bool gui_is_open()
{
return gui_state != Closed && gui_state != VJoyEdit;
return gui_state != GuiState::Closed && gui_state != GuiState::VJoyEdit;
}
static inline bool gui_is_content_browser()
{
return gui_state == Main;
return gui_state == GuiState::Main;
}
float gui_get_scaling();
@ -63,8 +64,8 @@ float gui_get_scaling();
#define XHAIR_HEIGHT (40 * scaling)
static inline bool crosshairsNeeded()
{
if (settings.rend.CrosshairColor[0] == 0 && settings.rend.CrosshairColor[1] == 0
&& settings.rend.CrosshairColor[3] == 0 && settings.rend.CrosshairColor[3] == 0)
if (config::CrosshairColor[0] == 0 && config::CrosshairColor[1] == 0
&& config::CrosshairColor[3] == 0 && config::CrosshairColor[3] == 0)
return false;
if (settings.platform.system != DC_PLATFORM_DREAMCAST
&& settings.input.JammaSetup != JVS::LightGun

View File

@ -42,20 +42,20 @@ void gui_display_vjoy_commands(int screen_width, int screen_height, float scalin
if (ImGui::Button("Save", ImVec2(150 * scaling, 50 * scaling)))
{
vjoy_stop_editing(false);
gui_state = Settings;
gui_state = GuiState::Settings;
}
ImGui::SameLine();
if (ImGui::Button("Reset", ImVec2(150 * scaling, 50 * scaling)))
{
vjoy_reset_editing();
gui_state = VJoyEdit;
gui_state = GuiState::VJoyEdit;
}
ImGui::SameLine();
if (ImGui::Button("Cancel", ImVec2(150 * scaling, 50 * scaling)))
{
vjoy_stop_editing(true);
gui_state = Settings;
gui_state = GuiState::Settings;
}
ImGui::End();

View File

@ -174,7 +174,7 @@ void select_directory_popup(const char *prompt, float scaling, StringCallback ca
else
{
std::string extension = get_file_extension(name);
if ( extension == "zip" || extension == "7z" || extension == "chd" || extension == "gdi" || ((settings.dreamcast.HideLegacyNaomiRoms
if (extension == "zip" || extension == "7z" || extension == "chd" || extension == "gdi" || ((config::HideLegacyNaomiRoms
|| (extension != "bin" && extension != "lst" && extension != "dat"))
&& extension != "cdi" && extension != "cue") == false )
display_files.push_back(name);
@ -545,3 +545,127 @@ const ImWchar* GetGlyphRangesChineseTraditionalOfficial()
}
return &full_ranges[0];
}
// Helper to display a little (?) mark which shows a tooltip when hovered.
void ShowHelpMarker(const char* desc)
{
ImGui::TextDisabled("(?)");
if (ImGui::IsItemHovered())
{
ImGui::BeginTooltip();
ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
ImGui::TextUnformatted(desc);
ImGui::PopTextWrapPos();
ImGui::EndTooltip();
}
}
template<bool PerGameOption>
bool OptionCheckbox(const char *name, config::Option<bool, PerGameOption>& option, const char *help)
{
bool b = option;
if (option.isReadOnly())
{
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f);
}
bool pressed = ImGui::Checkbox(name, &b);
if (option.isReadOnly())
{
ImGui::PopItemFlag();
ImGui::PopStyleVar();
}
if (pressed)
option.set(b);
if (help != nullptr)
{
ImGui::SameLine();
ShowHelpMarker(help);
}
return pressed;
}
template bool OptionCheckbox(const char *name, config::Option<bool, true>& option, const char *help);
template bool OptionCheckbox(const char *name, config::Option<bool, false>& option, const char *help);
bool OptionSlider(const char *name, config::Option<int>& option, int min, int max, const char *help)
{
int v = option;
if (option.isReadOnly())
{
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f);
}
bool valueChanged = ImGui::SliderInt(name, &v, min, max);
if (option.isReadOnly())
{
ImGui::PopItemFlag();
ImGui::PopStyleVar();
}
else if (valueChanged)
option.set(v);
if (help != nullptr)
{
ImGui::SameLine();
ShowHelpMarker(help);
}
return valueChanged;
}
template<typename T>
bool OptionRadioButton(const char *name, config::Option<T>& option, T value, const char *help)
{
int v = (int)option;
if (option.isReadOnly())
{
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f);
}
bool pressed = ImGui::RadioButton(name, &v, (int)value);
if (option.isReadOnly())
{
ImGui::PopItemFlag();
ImGui::PopStyleVar();
}
if (pressed)
option.set((T)v);
if (help != nullptr)
{
ImGui::SameLine();
ShowHelpMarker(help);
}
return pressed;
}
template bool OptionRadioButton<bool>(const char *name, config::Option<bool>& option, bool value, const char *help);
template bool OptionRadioButton<int>(const char *name, config::Option<int>& option, int value, const char *help);
void OptionComboBox(const char *name, config::Option<int>& option, const char *values[], int count,
const char *help)
{
if (option.isReadOnly())
{
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f);
}
if (ImGui::BeginCombo(name, values[option], ImGuiComboFlags_None))
{
for (int i = 0; i < count; i++)
{
bool is_selected = option == i;
if (ImGui::Selectable(values[i], &is_selected))
option = i;
if (is_selected)
ImGui::SetItemDefaultFocus();
}
ImGui::EndCombo();
}
if (option.isReadOnly())
{
ImGui::PopItemFlag();
ImGui::PopStyleVar();
}
if (help != nullptr)
{
ImGui::SameLine();
ShowHelpMarker(help);
}
}

View File

@ -22,6 +22,7 @@
#include "types.h"
#include "imgui/imgui.h"
#include "imgui/imgui_internal.h"
#include "vulkan/imgui_impl_vulkan.h"
#include "gles/imgui_impl_opengl3.h"
#include "vulkan/vulkan_context.h"
@ -34,7 +35,7 @@ void select_directory_popup(const char *prompt, float scaling, StringCallback ca
static inline void ImGui_impl_RenderDrawData(ImDrawData *draw_data, bool save_background = false)
{
#ifdef USE_VULKAN
if (!settings.pvr.IsOpenGL())
if (!config::RendererType.isOpenGL())
{
VulkanContext *context = VulkanContext::Instance();
if (!context->IsValid())
@ -68,3 +69,13 @@ void ScrollWhenDraggingOnVoid(const ImVec2& delta, ImGuiMouseButton mouse_button
IMGUI_API const ImWchar* GetGlyphRangesChineseSimplifiedOfficial();// Default + Half-Width + Japanese Hiragana/Katakana + set of 7800 CJK Unified Ideographs from General Standard Chinese Characters
IMGUI_API const ImWchar* GetGlyphRangesChineseTraditionalOfficial();// Default + Half-Width + Japanese Hiragana/Katakana + set of 4700 CJK Unified Ideographs from Hong Kong's List of Graphemes of Commonly-Used Chinese Characters
// Helper to display a little (?) mark which shows a tooltip when hovered.
void ShowHelpMarker(const char* desc);
template<bool PerGameOption>
bool OptionCheckbox(const char *name, config::Option<bool, PerGameOption>& option, const char *help = nullptr);
bool OptionSlider(const char *name, config::Option<int>& option, int min, int max, const char *help = nullptr);
template<typename T>
bool OptionRadioButton(const char *name, config::Option<T>& option, T value, const char *help = nullptr);
void OptionComboBox(const char *name, config::Option<int>& option, const char *values[], int count,
const char *help = nullptr);

View File

@ -23,6 +23,7 @@
#include "gui.h"
#include "oslib/oslib.h"
#include "wsi/context.h"
#include "cfg/option.h"
bool mainui_enabled;
int renderer_changed = -1; // Signals the renderer thread to switch renderer
@ -34,11 +35,11 @@ bool mainui_rend_frame()
{
os_DoEvents();
if (gui_is_open() || gui_state == VJoyEdit)
if (gui_is_open() || gui_state == GuiState::VJoyEdit)
{
gui_display_ui();
// TODO refactor android vjoy out of renderer
if (gui_state == VJoyEdit && renderer != NULL)
if (gui_state == GuiState::VJoyEdit && renderer != NULL)
renderer->DrawOSD(true);
std::this_thread::sleep_for(std::chrono::milliseconds(16));
}
@ -68,14 +69,14 @@ void mainui_term()
void mainui_loop()
{
mainui_enabled = true;
renderer_changed = (int)settings.pvr.rend;
renderer_changed = (int)(RenderType)config::RendererType;
mainui_init();
while (mainui_enabled)
{
if (mainui_rend_frame())
{
if (settings.pvr.IsOpenGL())
if (config::RendererType.isOpenGL())
theGLContext.Swap();
#ifdef USE_VULKAN
else
@ -83,20 +84,20 @@ void mainui_loop()
#endif
}
if (renderer_changed != (int)settings.pvr.rend)
if (renderer_changed != (int)(RenderType)config::RendererType)
{
mainui_term();
if (renderer_changed == -1
|| settings.pvr.IsOpenGL() != ((RenderType)renderer_changed == RenderType::OpenGL || (RenderType)renderer_changed == RenderType::OpenGL_OIT))
|| config::RendererType.isOpenGL() != ((RenderType)renderer_changed == RenderType::OpenGL || (RenderType)renderer_changed == RenderType::OpenGL_OIT))
{
// Switch between vulkan and opengl (or full reinit)
SwitchRenderApi(renderer_changed == -1 ? settings.pvr.rend : (RenderType)renderer_changed);
SwitchRenderApi(renderer_changed == -1 ? config::RendererType : (RenderType)renderer_changed);
}
else
{
settings.pvr.rend = (RenderType)renderer_changed;
config::RendererType = (RenderType)renderer_changed;
}
renderer_changed = (int)settings.pvr.rend;
renderer_changed = (int)(RenderType)config::RendererType;
mainui_init();
}
}

View File

@ -21,6 +21,7 @@
#include "types.h"
#include "hw/pvr/Renderer_if.h"
#include "cfg/option.h"
enum class TileClipping {
Inside, // Render stuff outside the region
@ -31,7 +32,7 @@ enum class TileClipping {
// clip_rect[] will contain x, y, width, height
static inline TileClipping GetTileClip(u32 val, const glm::mat4& viewport, int *clip_rect)
{
if (!settings.rend.Clipping)
if (!config::Clipping)
return TileClipping::Off;
u32 clipmode = val >> 28;
@ -68,12 +69,12 @@ static inline TileClipping GetTileClip(u32 val, const glm::mat4& viewport, int *
cey = clip_end[1];
cex = clip_end[0];
}
else if (!settings.rend.RenderToTextureBuffer)
else if (!config::RenderToTextureBuffer)
{
csx *= settings.rend.RenderToTextureUpscale;
csy *= settings.rend.RenderToTextureUpscale;
cex *= settings.rend.RenderToTextureUpscale;
cey *= settings.rend.RenderToTextureUpscale;
csx *= config::RenderToTextureUpscale;
csy *= config::RenderToTextureUpscale;
cex *= config::RenderToTextureUpscale;
cey *= config::RenderToTextureUpscale;
}
clip_rect[0] = std::max(0, (int)lroundf(csx));
clip_rect[1] = std::max(0, (int)lroundf(std::min(csy, cey)));

View File

@ -21,6 +21,7 @@
#pragma once
#include "TexCache.h"
#include "hw/pvr/ta_ctx.h"
#include "cfg/option.h"
#include <glm/glm.hpp>
#include <glm/gtx/transform.hpp>
@ -127,7 +128,7 @@ public:
normalMatrix = glm::translate(glm::vec3(startx, starty, 0));
scissorMatrix = normalMatrix;
const float screen_stretching = settings.rend.ScreenStretching / 100.f;
const float screen_stretching = config::ScreenStretching / 100.f;
float scissoring_scale_x, scissoring_scale_y;
GetFramebufferScaling(true, scissoring_scale_x, scissoring_scale_y);
@ -135,7 +136,7 @@ public:
float y_coef;
glm::mat4 trans_rot;
if (settings.rend.Rotate90)
if (config::Rotate90)
{
float dc2s_scale_h = screen_height / 640.0f;
if (screen_width / 480.f < dc2s_scale_h)
@ -184,7 +185,7 @@ public:
* glm::scale(glm::vec3(x_coef * scissoring_scale_x, y_coef * scissoring_scale_y, 1.f))
* scissorMatrix;
}
normalMatrix = glm::scale(glm::vec3(1, 1, 1 / settings.rend.ExtraDepthScale))
normalMatrix = glm::scale(glm::vec3(1, 1, 1 / config::ExtraDepthScale))
* normalMatrix;
glm::mat4 vp_trans = glm::translate(glm::vec3(1, 1, 0));
@ -195,7 +196,7 @@ public:
}
else
{
float screen_scaling = settings.rend.ScreenScaling / 100.f;
float screen_scaling = config::ScreenScaling / 100.f;
vp_trans = glm::scale(glm::vec3(screen_width * screen_scaling / 2, screen_height * screen_scaling / 2, 1.f))
* vp_trans;
}

View File

@ -62,8 +62,8 @@ TileClipping BaseDrawer::SetTileClip(u32 val, vk::Rect2D& clipRect)
void BaseDrawer::SetBaseScissor()
{
bool wide_screen_on = settings.rend.WideScreen && !pvrrc.isRenderFramebuffer
&& !matrices.IsClipped() && !settings.rend.Rotate90;
bool wide_screen_on = config::Widescreen && !pvrrc.isRenderFramebuffer
&& !matrices.IsClipped() && !config::Rotate90;
if (!wide_screen_on)
{
float width;
@ -99,8 +99,8 @@ void BaseDrawer::SetBaseScissor()
}
else
{
u32 w = lroundf(screen_width * settings.rend.ScreenScaling / 100.f);
u32 h = lroundf(screen_height * settings.rend.ScreenScaling / 100.f);
u32 w = lroundf(screen_width * config::ScreenScaling / 100.f);
u32 h = lroundf(screen_height * config::ScreenScaling / 100.f);
baseScissor = { 0, 0, w, h };
}
}
@ -201,7 +201,7 @@ void Drawer::DrawList(const vk::CommandBuffer& cmdBuffer, u32 listType, bool sor
void Drawer::DrawModVols(const vk::CommandBuffer& cmdBuffer, int first, int count)
{
if (count == 0 || pvrrc.modtrig.used() == 0 || !settings.rend.ModifierVolumes)
if (count == 0 || pvrrc.modtrig.used() == 0 || !config::ModifierVolumes)
return;
vk::Buffer buffer = GetMainBuffer(0)->buffer.get();
@ -355,7 +355,7 @@ bool Drawer::Draw(const Texture *fogTexture, const Texture *paletteTexture)
DrawModVols(cmdBuffer, previous_pass.mvo_count, current_pass.mvo_count - previous_pass.mvo_count);
if (current_pass.autosort)
{
if (!settings.rend.PerStripSorting)
if (!config::PerStripSorting)
{
DrawSorted(cmdBuffer, sortedPolys[render_pass]);
}
@ -401,12 +401,12 @@ vk::CommandBuffer TextureDrawer::BeginRenderPass()
while (widthPow2 < upscaledWidth)
widthPow2 *= 2;
if (settings.rend.RenderToTextureUpscale > 1 && !settings.rend.RenderToTextureBuffer)
if (config::RenderToTextureUpscale > 1 && !config::RenderToTextureBuffer)
{
upscaledWidth *= settings.rend.RenderToTextureUpscale;
upscaledHeight *= settings.rend.RenderToTextureUpscale;
widthPow2 *= settings.rend.RenderToTextureUpscale;
heightPow2 *= settings.rend.RenderToTextureUpscale;
upscaledWidth *= config::RenderToTextureUpscale;
upscaledHeight *= config::RenderToTextureUpscale;
widthPow2 *= config::RenderToTextureUpscale;
heightPow2 *= config::RenderToTextureUpscale;
}
rttPipelineManager->CheckSettingsChange();
@ -430,7 +430,7 @@ vk::CommandBuffer TextureDrawer::BeginRenderPass()
vk::ImageView colorImageView;
vk::ImageLayout colorImageCurrentLayout;
if (!settings.rend.RenderToTextureBuffer)
if (!config::RenderToTextureBuffer)
{
// TexAddr : fb_rtt.TexAddr, Reserved : 0, StrideSel : 0, ScanOrder : 1
TCW tcw = { { textureAddr >> 3, 0, 0, 1 } };
@ -534,7 +534,7 @@ void TextureDrawer::EndRenderPass()
// Happens for Virtua Tennis
clippedWidth = stride / 2;
if (settings.rend.RenderToTextureBuffer)
if (config::RenderToTextureBuffer)
{
vk::BufferImageCopy copyRegion(0, clippedWidth, clippedHeight, vk::ImageSubresourceLayers(vk::ImageAspectFlagBits::eColor, 0, 0, 1), vk::Offset3D(0, 0, 0),
vk::Extent3D(vk::Extent2D(clippedWidth, clippedHeight), 1));
@ -557,7 +557,7 @@ void TextureDrawer::EndRenderPass()
currentCommandBuffer = nullptr;
commandPool->EndFrame();
if (settings.rend.RenderToTextureBuffer)
if (config::RenderToTextureBuffer)
{
vk::Fence fence = commandPool->GetCurrentFence();
GetContext()->GetDevice().waitForFences(1, &fence, true, UINT64_MAX);
@ -583,7 +583,7 @@ void TextureDrawer::EndRenderPass()
void ScreenDrawer::Init(SamplerManager *samplerManager, ShaderManager *shaderManager)
{
this->shaderManager = shaderManager;
currentScreenScaling = settings.rend.ScreenScaling;
currentScreenScaling = config::ScreenScaling;
vk::Extent2D viewport = GetContext()->GetViewPort();
viewport.width = lroundf(viewport.width * currentScreenScaling / 100.f);
viewport.height = lroundf(viewport.height * currentScreenScaling / 100.f);
@ -682,7 +682,7 @@ void ScreenDrawer::Init(SamplerManager *samplerManager, ShaderManager *shaderMan
vk::CommandBuffer ScreenDrawer::BeginRenderPass()
{
if (currentScreenScaling != settings.rend.ScreenScaling)
if (currentScreenScaling != config::ScreenScaling)
Init(samplerManager, shaderManager);
vk::CommandBuffer commandBuffer = commandPool->Allocate();

View File

@ -77,7 +77,7 @@ protected:
u8* fog_density = (u8*)&FOG_DENSITY;
float fog_den_mant = fog_density[1] / 128.0f; //bit 7 -> x. bit, so [6:0] -> fraction -> /128
s32 fog_den_exp = (s8)fog_density[0];
fragUniforms.sp_FOG_DENSITY = fog_den_mant * powf(2.0f, fog_den_exp) * settings.rend.ExtraDepthScale;
fragUniforms.sp_FOG_DENSITY = fog_den_mant * powf(2.0f, fog_den_exp) * config::ExtraDepthScale;
fragUniforms.colorClampMin[0] = ((pvrrc.fog_clamp_min >> 16) & 0xFF) / 255.0f;
fragUniforms.colorClampMin[1] = ((pvrrc.fog_clamp_min >> 8) & 0xFF) / 255.0f;
@ -114,9 +114,9 @@ protected:
{
GetCurrentDescSet().Reset();
imageIndex = (imageIndex + 1) % GetSwapChainSize();
if (perStripSorting != settings.rend.PerStripSorting)
if (perStripSorting != config::PerStripSorting)
{
perStripSorting = settings.rend.PerStripSorting;
perStripSorting = config::PerStripSorting;
pipelineManager->Reset();
}
renderPass = 0;

View File

@ -104,7 +104,7 @@ void OITDrawer::DrawList(const vk::CommandBuffer& cmdBuffer, u32 listType, bool
template<bool Translucent>
void OITDrawer::DrawModifierVolumes(const vk::CommandBuffer& cmdBuffer, int first, int count)
{
if (count == 0 || pvrrc.modtrig.used() == 0 || !settings.rend.ModifierVolumes)
if (count == 0 || pvrrc.modtrig.used() == 0 || !config::ModifierVolumes)
return;
vk::Buffer buffer = GetMainBuffer(0)->buffer.get();
@ -456,9 +456,9 @@ void OITDrawer::MakeBuffers(int width, int height)
void OITScreenDrawer::MakeFramebuffers()
{
if (currentScreenScaling == settings.rend.ScreenScaling)
if (currentScreenScaling == config::ScreenScaling)
return;
currentScreenScaling = settings.rend.ScreenScaling;
currentScreenScaling = config::ScreenScaling;
viewport.offset.x = 0;
viewport.offset.y = 0;
viewport.extent = GetContext()->GetViewPort();
@ -509,12 +509,12 @@ vk::CommandBuffer OITTextureDrawer::NewFrame()
while (widthPow2 < upscaledWidth)
widthPow2 *= 2;
if (settings.rend.RenderToTextureUpscale > 1 && !settings.rend.RenderToTextureBuffer)
if (config::RenderToTextureUpscale > 1 && !config::RenderToTextureBuffer)
{
upscaledWidth *= settings.rend.RenderToTextureUpscale;
upscaledHeight *= settings.rend.RenderToTextureUpscale;
widthPow2 *= settings.rend.RenderToTextureUpscale;
heightPow2 *= settings.rend.RenderToTextureUpscale;
upscaledWidth *= config::RenderToTextureUpscale;
upscaledHeight *= config::RenderToTextureUpscale;
widthPow2 *= config::RenderToTextureUpscale;
heightPow2 *= config::RenderToTextureUpscale;
}
rttPipelineManager->CheckSettingsChange();
@ -529,7 +529,7 @@ vk::CommandBuffer OITTextureDrawer::NewFrame()
vk::ImageView colorImageView;
vk::ImageLayout colorImageCurrentLayout;
if (!settings.rend.RenderToTextureBuffer)
if (!config::RenderToTextureBuffer)
{
// TexAddr : fb_rtt.TexAddr, Reserved : 0, StrideSel : 0, ScanOrder : 1
TCW tcw = { { textureAddr >> 3, 0, 0, 1 } };
@ -633,7 +633,7 @@ void OITTextureDrawer::EndFrame()
// Happens for Virtua Tennis
clippedWidth = stride / 2;
if (settings.rend.RenderToTextureBuffer)
if (config::RenderToTextureBuffer)
{
vk::BufferImageCopy copyRegion(0, clippedWidth, clippedHeight,
vk::ImageSubresourceLayers(vk::ImageAspectFlagBits::eColor, 0, 0, 1), vk::Offset3D(0, 0, 0),
@ -658,7 +658,7 @@ void OITTextureDrawer::EndFrame()
currentCommandBuffer = nullptr;
commandPool->EndFrame();
if (settings.rend.RenderToTextureBuffer)
if (config::RenderToTextureBuffer)
{
vk::Fence fence = commandPool->GetCurrentFence();
GetContext()->GetDevice().waitForFences(1, &fence, true, UINT64_MAX);

View File

@ -147,7 +147,7 @@ void OITPipelineManager::CreatePipeline(u32 listType, bool autosort, const PolyP
params.bumpmap = pp.tcw.PixelFmt == PixelBumpMap;
params.clamping = pp.tsp.ColorClamp && (pvrrc.fog_clamp_min != 0 || pvrrc.fog_clamp_max != 0xffffffff);
params.insideClipTest = (pp.tileclip >> 28) == 3;
params.fog = settings.rend.Fog ? pp.tsp.FogCtrl : 2;
params.fog = config::Fog ? pp.tsp.FogCtrl : 2;
params.gouraud = pp.pcw.Gouraud;
params.ignoreTexAlpha = pp.tsp.IgnoreTexA || pp.tcw.PixelFmt == Pixel565;
params.offset = pp.pcw.Offset;

View File

@ -347,7 +347,7 @@ private:
{
bool ignoreTexAlpha = pp->tsp.IgnoreTexA || pp->tcw.PixelFmt == Pixel565;
hash |= (pp->tsp.ShadInstr << 7) | (ignoreTexAlpha << 9) | (pp->tsp.UseAlpha << 10)
| (pp->tsp.ColorClamp << 11) | ((settings.rend.Fog ? pp->tsp.FogCtrl : 2) << 12)
| (pp->tsp.ColorClamp << 11) | ((config::Fog ? pp->tsp.FogCtrl : 2) << 12)
| (pp->tsp.SrcInstr << 14) | (pp->tsp.DstInstr << 17);
}
hash |= (pp->isp.ZWriteDis << 20) | (pp->isp.CullMode << 21) | ((autosort ? 6 : pp->isp.DepthMode) << 23);
@ -421,12 +421,12 @@ public:
this->oitBuffers = oitBuffers;
OITPipelineManager::Init(shaderManager, oitBuffers);
renderToTextureBuffer = settings.rend.RenderToTextureBuffer;
renderToTextureBuffer = config::RenderToTextureBuffer;
rttRenderPasses.Reset();
}
void CheckSettingsChange()
{
if (renderToTextureBuffer != settings.rend.RenderToTextureBuffer)
if (renderToTextureBuffer != config::RenderToTextureBuffer)
{
Init(shaderManager, oitBuffers);
}

View File

@ -70,13 +70,13 @@ protected:
vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eStore,
vk::AttachmentLoadOp::eDontCare, vk::AttachmentStoreOp::eDontCare,
vk::ImageLayout::eUndefined,
settings.rend.RenderToTextureBuffer && last ? vk::ImageLayout::eTransferSrcOptimal : vk::ImageLayout::eShaderReadOnlyOptimal);
config::RenderToTextureBuffer && last ? vk::ImageLayout::eTransferSrcOptimal : vk::ImageLayout::eShaderReadOnlyOptimal);
}
virtual vk::Format GetColorFormat() const override { return vk::Format::eR8G8B8A8Unorm; }
virtual std::vector<vk::SubpassDependency> GetSubpassDependencies() const override
{
std::vector<vk::SubpassDependency> deps;
if (settings.rend.RenderToTextureBuffer)
if (config::RenderToTextureBuffer)
deps.emplace_back(2, VK_SUBPASS_EXTERNAL,
vk::PipelineStageFlagBits::eColorAttachmentOutput, vk::PipelineStageFlagBits::eTransfer | vk::PipelineStageFlagBits::eHost,
vk::AccessFlagBits::eColorAttachmentWrite, vk::AccessFlagBits::eTransferRead | vk::AccessFlagBits::eHostRead);

View File

@ -22,6 +22,7 @@
#include "rend/gui.h"
#include "hw/maple/maple_devs.h"
#include "overlay.h"
#include "cfg/option.h"
VulkanOverlay::~VulkanOverlay()
{
@ -129,11 +130,11 @@ void VulkanOverlay::Draw(vk::Extent2D viewport, float scaling, bool vmu, bool cr
if (crosshair && crosshairsNeeded())
{
alphaPipeline->BindPipeline(commandBuffer);
for (size_t i = 0; i < ARRAY_SIZE(settings.rend.CrosshairColor); i++)
for (size_t i = 0; i < config::CrosshairColor.size(); i++)
{
if (settings.rend.CrosshairColor[i] == 0)
if (config::CrosshairColor[i] == 0)
continue;
if (settings.platform.system == DC_PLATFORM_DREAMCAST && settings.input.maple_devices[i] != MDT_LightGun)
if (settings.platform.system == DC_PLATFORM_DREAMCAST && config::MapleMainDevices[i] != MDT_LightGun)
continue;
float x, y;
@ -143,7 +144,7 @@ void VulkanOverlay::Draw(vk::Extent2D viewport, float scaling, bool vmu, bool cr
vk::Viewport viewport(x, y, XHAIR_WIDTH, XHAIR_HEIGHT);
commandBuffer.setViewport(0, 1, &viewport);
commandBuffer.setScissor(0, vk::Rect2D(vk::Offset2D(x, y), vk::Extent2D(XHAIR_WIDTH, XHAIR_HEIGHT)));
u32 color = settings.rend.CrosshairColor[i];
u32 color = config::CrosshairColor[i];
float xhairColor[4] {
(color & 0xff) / 255.f,
((color >> 8) & 0xff) / 255.f,

View File

@ -174,7 +174,7 @@ void PipelineManager::CreatePipeline(u32 listType, bool sortTriangles, const Pol
// Input assembly state
vk::PipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateCreateInfo(vk::PipelineInputAssemblyStateCreateFlags(),
sortTriangles && !settings.rend.PerStripSorting ? vk::PrimitiveTopology::eTriangleList : vk::PrimitiveTopology::eTriangleStrip);
sortTriangles && !config::PerStripSorting ? vk::PrimitiveTopology::eTriangleList : vk::PrimitiveTopology::eTriangleStrip);
// Viewport and scissor states
vk::PipelineViewportStateCreateInfo pipelineViewportStateCreateInfo(vk::PipelineViewportStateCreateFlags(), 1, nullptr, 1, nullptr);
@ -205,7 +205,7 @@ void PipelineManager::CreatePipeline(u32 listType, bool sortTriangles, const Pol
else
depthOp = depthOps[pp.isp.DepthMode];
bool depthWriteEnable;
if (sortTriangles && !settings.rend.PerStripSorting)
if (sortTriangles && !config::PerStripSorting)
// FIXME temporary work-around for intel driver bug
depthWriteEnable = GetContext()->GetVendorID() == VENDOR_INTEL;
else
@ -295,7 +295,7 @@ void PipelineManager::CreatePipeline(u32 listType, bool sortTriangles, const Pol
params.bumpmap = pp.tcw.PixelFmt == PixelBumpMap;
params.clamping = pp.tsp.ColorClamp && (pvrrc.fog_clamp_min != 0 || pvrrc.fog_clamp_max != 0xffffffff);
params.insideClipTest = (pp.tileclip >> 28) == 3;
params.fog = settings.rend.Fog ? pp.tsp.FogCtrl : 2;
params.fog = config::Fog ? pp.tsp.FogCtrl : 2;
params.gouraud = pp.pcw.Gouraud;
params.ignoreTexAlpha = pp.tsp.IgnoreTexA || pp.tcw.PixelFmt == Pixel565;
params.offset = pp.pcw.Offset;

View File

@ -227,7 +227,7 @@ private:
hash |= ((listType >> 1) << 5);
bool ignoreTexAlpha = pp->tsp.IgnoreTexA || pp->tcw.PixelFmt == Pixel565;
hash |= (pp->tsp.ShadInstr << 7) | (ignoreTexAlpha << 9) | (pp->tsp.UseAlpha << 10)
| (pp->tsp.ColorClamp << 11) | ((settings.rend.Fog ? pp->tsp.FogCtrl : 2) << 12) | (pp->tsp.SrcInstr << 14)
| (pp->tsp.ColorClamp << 11) | ((config::Fog ? pp->tsp.FogCtrl : 2) << 12) | (pp->tsp.SrcInstr << 14)
| (pp->tsp.DstInstr << 17);
hash |= (pp->isp.ZWriteDis << 20) | (pp->isp.CullMode << 21) | (pp->isp.DepthMode << 23);
hash |= ((u32)sortTriangles << 26) | ((u32)BaseTextureCacheData::IsGpuHandledPaletted(pp->tsp, pp->tcw) << 27);
@ -287,7 +287,7 @@ public:
void Init(ShaderManager *shaderManager)
{
// RTT render pass
renderToTextureBuffer = settings.rend.RenderToTextureBuffer;
renderToTextureBuffer = config::RenderToTextureBuffer;
vk::AttachmentDescription attachmentDescriptions[] = {
vk::AttachmentDescription(vk::AttachmentDescriptionFlags(), vk::Format::eR8G8B8A8Unorm, vk::SampleCountFlagBits::e1,
vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eStore, vk::AttachmentLoadOp::eDontCare, vk::AttachmentStoreOp::eDontCare,
@ -320,7 +320,7 @@ public:
void CheckSettingsChange()
{
if (renderToTextureBuffer != settings.rend.RenderToTextureBuffer)
if (renderToTextureBuffer != config::RenderToTextureBuffer)
Init(shaderManager);
}

View File

@ -873,14 +873,14 @@ void VulkanContext::PresentFrame(vk::ImageView imageView, vk::Extent2D extent) n
{
try {
NewFrame();
auto overlayCmdBuffers = PrepareOverlay(settings.rend.FloatVMUs, true);
auto overlayCmdBuffers = PrepareOverlay(config::FloatVMUs, true);
BeginRenderPass();
if (lastFrameView) // Might have been nullified if swap chain recreated
DrawFrame(imageView, extent);
DrawOverlay(gui_get_scaling(), settings.rend.FloatVMUs, true);
DrawOverlay(gui_get_scaling(), config::FloatVMUs, true);
renderer->DrawOSD(false);
EndFrame(overlayCmdBuffers);
} catch (const InvalidVulkanContext& err) {

View File

@ -288,7 +288,7 @@ protected:
fogTexture->tex_type = TextureType::_8;
fog_needs_update = true;
}
if (!fog_needs_update || !settings.rend.Fog)
if (!fog_needs_update || !config::Fog)
return;
fog_needs_update = false;
u8 texData[256];

View File

@ -20,6 +20,7 @@
#include "hw/naomi/naomi_cart.h"
#include "hw/sh4/sh4_cache.h"
#include "hw/bba/bba.h"
#include "cfg/option.h"
extern "C" void DYNACALL TAWriteSQ(u32 address,u8* sqb);
@ -439,8 +440,8 @@ bool dc_serialize(void **data, unsigned int *total_size)
REICAST_S(sch_list[vblank_schid].start) ;
REICAST_S(sch_list[vblank_schid].end) ;
REICAST_S(settings.network.EmulateBBA);
if (settings.network.EmulateBBA)
REICAST_S(config::EmulateBBA.get());
if (config::EmulateBBA)
{
bba_Serialize(data, total_size);
}
@ -474,9 +475,9 @@ bool dc_serialize(void **data, unsigned int *total_size)
naomi_Serialize(data, total_size);
REICAST_S(settings.dreamcast.broadcast);
REICAST_S(settings.dreamcast.cable);
REICAST_S(settings.dreamcast.region);
REICAST_S(config::Broadcast.get());
REICAST_S(config::Cable.get());
REICAST_S(config::Region.get());
if (CurrentCartridge != NULL)
CurrentCartridge->Serialize(data, total_size);
@ -732,14 +733,14 @@ static bool dc_unserialize_libretro(void **data, unsigned int *total_size)
naomi_Unserialize(data, total_size, VCUR_LIBRETRO);
REICAST_US(settings.dreamcast.broadcast);
REICAST_US(settings.dreamcast.cable);
REICAST_US(settings.dreamcast.region);
REICAST_US(config::Broadcast.get());
REICAST_US(config::Cable.get());
REICAST_US(config::Region.get());
if (CurrentCartridge != NULL)
CurrentCartridge->Unserialize(data, total_size);
gd_hle_state.Unserialize(data, total_size);
settings.network.EmulateBBA = false;
config::EmulateBBA.override(false);
DEBUG_LOG(SAVESTATE, "Loaded %d bytes (libretro compat)", *total_size);
@ -1013,10 +1014,10 @@ bool dc_unserialize(void **data, unsigned int *total_size)
}
if (version >= V13)
REICAST_S(settings.network.EmulateBBA);
REICAST_US(config::EmulateBBA.get());
else
settings.network.EmulateBBA = false;
if (settings.network.EmulateBBA)
config::EmulateBBA.override(false);
if (config::EmulateBBA)
{
bba_Unserialize(data, total_size);
}
@ -1086,12 +1087,12 @@ bool dc_unserialize(void **data, unsigned int *total_size)
REICAST_SKIP(4);
REICAST_SKIP(4);
}
REICAST_US(settings.dreamcast.broadcast);
verify(settings.dreamcast.broadcast <= 4);
REICAST_US(settings.dreamcast.cable);
verify(settings.dreamcast.cable <= 3);
REICAST_US(settings.dreamcast.region);
verify(settings.dreamcast.region <= 3);
REICAST_US(config::Broadcast.get());
verify(config::Broadcast <= 4);
REICAST_US(config::Cable.get());
verify(config::Cable <= 3);
REICAST_US(config::Region.get());
verify(config::Region <= 3);
if (CurrentCartridge != NULL)
CurrentCartridge->Unserialize(data, total_size);

View File

@ -319,139 +319,27 @@ struct settings_t
u32 bbsram_size;
} platform;
struct {
bool UseReios;
} bios;
struct
{
bool UseMipmaps;
bool WideScreen;
bool ShowFPS;
bool RenderToTextureBuffer;
int RenderToTextureUpscale;
bool TranslucentPolygonDepthMask;
bool ModifierVolumes;
bool Clipping;
int TextureUpscale;
int MaxFilteredTextureSize;
f32 ExtraDepthScale;
bool CustomTextures;
bool DumpTextures;
int ScreenScaling; // in percent. 50 means half the native resolution
int ScreenStretching; // in percent. 150 means stretch from 4/3 to 6/3
bool Fog;
bool FloatVMUs;
bool Rotate90; // Rotate the screen 90 deg CC
bool PerStripSorting;
bool DelayFrameSwapping; // Delay swapping frame until FB_R_SOF matches FB_W_SOF
bool WidescreenGameHacks;
u32 CrosshairColor[4];
} rend;
struct
{
bool Enable;
bool idleskip;
bool unstable_opt;
bool safemode;
bool disable_nvmem;
bool disable_vmem32;
} dynarec;
struct
{
u32 run_counts;
} profile;
struct
{
u32 cable; // 0 -> VGA, 1 -> VGA, 2 -> RGB, 3 -> TV
u32 region; // 0 -> JP, 1 -> USA, 2 -> EU, 3 -> default
u32 broadcast; // 0 -> NTSC, 1 -> PAL, 2 -> PAL/M, 3 -> PAL/N, 4 -> default
u32 language; // 0 -> JP, 1 -> EN, 2 -> DE, 3 -> FR, 4 -> SP, 5 -> IT, 6 -> default
std::vector<std::string> ContentPath;
bool FullMMU;
bool ForceWindowsCE;
bool HideLegacyNaomiRoms;
} dreamcast;
struct
{
u32 BufferSize; //In samples ,*4 for bytes (1024)
bool LimitFPS;
u32 CDDAMute;
bool DSPEnabled;
bool NoBatch;
bool NoSound;
} aica;
struct{
std::string backend;
// slug<<key, value>>
std::map<std::string, std::map<std::string, std::string>> options;
} audio;
#if USE_OMX
struct
{
u32 Audio_Latency;
bool Audio_HDMI;
} omx;
#endif
#if SUPPORT_DISPMANX
struct
{
u32 Width;
u32 Height;
bool Keep_Aspect;
} dispmanx;
#endif
struct
{
bool PatchRegion;
char ImagePath[512];
} imgread;
struct
{
u32 ta_skip;
RenderType rend;
u32 MaxThreads;
int AutoSkipFrame; // 0: none, 1: some, 2: more
bool IsOpenGL() { return rend == RenderType::OpenGL || rend == RenderType::OpenGL_OIT; }
} pvr;
struct {
bool SerialConsole;
bool SerialPTY;
} debug;
struct {
bool OpenGlChecks;
} validate;
struct {
u32 MouseSensitivity;
JVS JammaSetup;
int maple_devices[4];
int maple_expansion_devices[4][2];
int VirtualGamepadVibration;
} input;
struct {
bool Enable;
bool ActAsServer;
std::string dns;
std::string server;
bool EmulateBBA;
} network;
bool gameStarted;
};
extern settings_t settings;

View File

@ -20,6 +20,7 @@
*/
#include "context.h"
#include "rend/gui.h"
#include "cfg/option.h"
#ifdef USE_VULKAN
VulkanContext theVulkanContext;
@ -28,13 +29,13 @@ VulkanContext theVulkanContext;
void InitRenderApi()
{
#ifdef USE_VULKAN
if (!settings.pvr.IsOpenGL())
if (!config::RendererType.isOpenGL())
{
if (theVulkanContext.Init())
return;
// Fall back to Open GL
WARN_LOG(RENDERER, "Vulkan init failed. Falling back to Open GL.");
settings.pvr.rend = RenderType::OpenGL;
config::RendererType = RenderType::OpenGL;
}
#endif
if (!theGLContext.Init())
@ -44,7 +45,7 @@ void InitRenderApi()
void SwitchRenderApi(RenderType newApi)
{
TermRenderApi();
settings.pvr.rend = newApi;
config::RendererType = newApi;
InitRenderApi();
}

View File

@ -74,11 +74,14 @@ bool XGLGraphicsContext::Init()
glXMakeCurrent(this->display, this->window, context);
screen_width = 640;
screen_height = 480;
if (gl3wInit() == -1 || !gl3wIsSupported(3, 1))
return false;
Window win;
int temp;
unsigned int tempu;
XGetGeometry(display, window, &win, &temp, &temp, (u32 *)&screen_width, (u32 *)&screen_height, &tempu, &tempu);
PostInit();
return true;

View File

@ -31,7 +31,7 @@ public final class JNIdc
public static native void setupMic(SipEmulator sip);
public static native int getVirtualGamepadVibration();
public static native int getAicaBufferSize();
public static native int getAudioBufferSize();
public static native void screenDpi(int screenDpi);
public static native void guiOpenSettings();

View File

@ -28,6 +28,7 @@
#include "wsi/context.h"
#include "emulator.h"
#include "rend/mainui.h"
#include "cfg/option.h"
JavaVM* g_jvm;
@ -75,11 +76,11 @@ static thread_local JVMAttacher jvm_attacher;
#include "android_gamepad.h"
#define SETTINGS_ACCESSORS(jsetting, csetting, type) \
JNIEXPORT type JNICALL Java_com_reicast_emulator_emu_JNIdc_get ## jsetting(JNIEnv *env, jobject obj) __attribute__((visibility("default"))); \
JNIEXPORT type JNICALL Java_com_reicast_emulator_emu_JNIdc_get ## jsetting(JNIEnv *env, jobject obj) \
#define SETTINGS_ACCESSORS(setting, type) \
JNIEXPORT type JNICALL Java_com_reicast_emulator_emu_JNIdc_get ## setting(JNIEnv *env, jobject obj) __attribute__((visibility("default"))); \
JNIEXPORT type JNICALL Java_com_reicast_emulator_emu_JNIdc_get ## setting(JNIEnv *env, jobject obj) \
{ \
return settings.csetting; \
return (type)config::setting; \
}
extern "C"
@ -107,8 +108,8 @@ JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_getControllers(JNIEnv
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_setupMic(JNIEnv *env,jobject obj,jobject sip) __attribute__((visibility("default")));
SETTINGS_ACCESSORS(VirtualGamepadVibration, input.VirtualGamepadVibration, jint);
SETTINGS_ACCESSORS(AicaBufferSize, aica.BufferSize, jint);
SETTINGS_ACCESSORS(VirtualGamepadVibration, jint);
SETTINGS_ACCESSORS(AudioBufferSize, jint);
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_screenDpi(JNIEnv *env,jobject obj, jint screenDpi) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_guiOpenSettings(JNIEnv *env,jobject obj) __attribute__((visibility("default")));
@ -277,7 +278,7 @@ JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_setGameUri(JNIEnv *en
// TODO game paused/settings/...
if (game_started) {
dc_stop();
gui_state = Main;
gui_state = GuiState::Main;
dc_reset(true);
}
}
@ -311,6 +312,8 @@ JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_pause(JNIEnv *env,job
{
dc_stop();
game_started = true; // restart when resumed
if (config::AutoSavestate)
dc_savestate();
}
}
@ -322,8 +325,14 @@ JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_resume(JNIEnv *env,jo
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_stop(JNIEnv *env,jobject obj)
{
if (dc_is_running())
if (dc_is_running()) {
dc_stop();
if (config::AutoSavestate)
dc_savestate();
}
dc_term_game();
gui_state = GuiState::Main;
settings.imgread.ImagePath[0] = '\0';
}
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_destroy(JNIEnv *env,jobject obj)
@ -340,19 +349,6 @@ JNIEXPORT jint JNICALL Java_com_reicast_emulator_emu_JNIdc_send(JNIEnv *env,jobj
KillTex=true;
INFO_LOG(RENDERER, "Killing texture cache");
}
if (param==1)
{
settings.pvr.ta_skip^=1;
INFO_LOG(RENDERER, "settings.pvr.ta_skip: %d", settings.pvr.ta_skip);
}
if (param==2)
{
#if FEAT_SHREC != DYNAREC_NONE
print_stats=true;
INFO_LOG(DYNAREC, "Storing blocks ...");
#endif
}
}
return 0;
}
@ -439,15 +435,16 @@ JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_hideOsd(JNIEnv * env,
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_getControllers(JNIEnv *env, jobject obj, jintArray controllers, jobjectArray peripherals)
{
jint *controllers_body = env->GetIntArrayElements(controllers, 0);
memcpy(controllers_body, settings.input.maple_devices, sizeof(settings.input.maple_devices));
for (u32 i = 0; i < config::MapleMainDevices.size(); i++)
controllers_body[i] = (MapleDeviceType)config::MapleMainDevices[i];
env->ReleaseIntArrayElements(controllers, controllers_body, 0);
int obj_len = env->GetArrayLength(peripherals);
for (int i = 0; i < obj_len; ++i) {
jintArray port = (jintArray) env->GetObjectArrayElement(peripherals, i);
jint *items = env->GetIntArrayElements(port, 0);
items[0] = settings.input.maple_expansion_devices[i][0];
items[1] = settings.input.maple_expansion_devices[i][1];
items[0] = (MapleDeviceType)config::MapleExpansionDevices[i][0];
items[1] = (MapleDeviceType)config::MapleExpansionDevices[i][1];
env->ReleaseIntArrayElements(port, items, 0);
env->DeleteLocalRef(port);
}

View File

@ -58,8 +58,6 @@ extern "C" int reicast_main(int argc, char* argv[])
common_linux_setup();
settings.profile.run_counts=0;
dc_init(argc,argv);
dc_run();

View File

@ -304,6 +304,7 @@
AE8C274321122E2500D4D8F4 /* xbrz.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AE8C273D21122E2500D4D8F4 /* xbrz.cpp */; };
AE90679B235B6F6400CE473C /* gl_context.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AE90679A235B6F6400CE473C /* gl_context.cpp */; };
AE90679D235DF80400CE473C /* osd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AE90679C235DF80400CE473C /* osd.cpp */; };
AE9125CC25E3BBDC00ED4594 /* option.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AE9125CB25E3BBDC00ED4594 /* option.cpp */; };
AEA93E51259BA2180076297F /* audiobackend_sdl2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AEA93E50259BA2170076297F /* audiobackend_sdl2.cpp */; };
AEA93E5C259BCD530076297F /* rtl8139c.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AEA93E56259BCD530076297F /* rtl8139c.cpp */; };
AEA93E60259BCD530076297F /* bba.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AEA93E5A259BCD530076297F /* bba.cpp */; };
@ -915,6 +916,8 @@
AE8C274021122E2500D4D8F4 /* xbrz_tools.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xbrz_tools.h; sourceTree = "<group>"; };
AE90679A235B6F6400CE473C /* gl_context.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gl_context.cpp; sourceTree = "<group>"; };
AE90679C235DF80400CE473C /* osd.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = osd.cpp; sourceTree = "<group>"; };
AE9125CA25E3BBDC00ED4594 /* option.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = option.h; sourceTree = "<group>"; };
AE9125CB25E3BBDC00ED4594 /* option.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = option.cpp; sourceTree = "<group>"; };
AEA93E50259BA2170076297F /* audiobackend_sdl2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = audiobackend_sdl2.cpp; sourceTree = "<group>"; };
AEA93E53259BCD530076297F /* rtl8139c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rtl8139c.h; sourceTree = "<group>"; };
AEA93E55259BCD530076297F /* bba.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bba.h; sourceTree = "<group>"; };
@ -1254,6 +1257,8 @@
84B7BD131B72720100F9733F /* cfg */ = {
isa = PBXGroup;
children = (
AE9125CB25E3BBDC00ED4594 /* option.cpp */,
AE9125CA25E3BBDC00ED4594 /* option.h */,
8491687D1B782B2D00F3F2B4 /* ini.cpp */,
8491687E1B782B2D00F3F2B4 /* ini.h */,
84B7BD141B72720100F9733F /* cfg.cpp */,
@ -2950,6 +2955,7 @@
AEFF7F56214D9D590068CE11 /* pico_ethernet.c in Sources */,
AEE6277E220D7B7E00EC7E89 /* imgui_widgets.cpp in Sources */,
84B7BF771B72720200F9733F /* reios_elf.cpp in Sources */,
AE9125CC25E3BBDC00ED4594 /* option.cpp in Sources */,
84B7BF5C1B72720200F9733F /* common.cpp in Sources */,
AE82C6BE25B64AE200C79BC2 /* zip_source_crc.c in Sources */,
84B7BF681B72720200F9733F /* audiobackend_directsound.cpp in Sources */,
@ -3056,7 +3062,6 @@
GCC_FAST_MATH = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
TARGET_NO_COREIO_HTTP,
TARGET_NO_OPENMP,
CHD5_LZMA,
_7ZIP_ST,
@ -3109,7 +3114,6 @@
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_FAST_MATH = YES;
GCC_PREPROCESSOR_DEFINITIONS = (
TARGET_NO_COREIO_HTTP,
TARGET_NO_OPENMP,
CHD5_LZMA,
_7ZIP_ST,

View File

@ -4,6 +4,7 @@
#include "hw/maple/maple_cfg.h"
#include "hw/maple/maple_devs.h"
#include "emulator.h"
#include "cfg/option.h"
class SerializeTest : public ::testing::Test {
protected:
@ -17,13 +18,14 @@ protected:
TEST_F(SerializeTest, SizeTest)
{
InitSettings();
settings.input.maple_devices[0] = MDT_SegaController;
settings.input.maple_expansion_devices[0][0] = MDT_SegaVMU;
settings.input.maple_expansion_devices[0][1] = MDT_SegaVMU;
settings.input.maple_devices[1] = MDT_SegaController;
settings.input.maple_expansion_devices[1][0] = MDT_SegaVMU;
settings.input.maple_expansion_devices[1][1] = MDT_SegaVMU;
using namespace config;
Settings::instance().reset();
MapleMainDevices[0] = MDT_SegaController;
MapleExpansionDevices[0][0] = MDT_SegaVMU;
MapleExpansionDevices[0][1] = MDT_SegaVMU;
MapleMainDevices[1] = MDT_SegaController;
MapleExpansionDevices[1][0] = MDT_SegaVMU;
MapleExpansionDevices[1][1] = MDT_SegaVMU;
mcfg_CreateDevices();
unsigned int total_size = 0;