mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 02:32:36 +01:00
Configuration simplified
This commit is contained in:
parent
d5107aab47
commit
f010b5b235
@ -7,7 +7,7 @@ namespace cfg
|
||||
{
|
||||
logs::channel cfg("CFG");
|
||||
|
||||
entry_base::entry_base(type _type)
|
||||
_base::_base(type _type)
|
||||
: m_type(_type)
|
||||
{
|
||||
if (_type != type::node)
|
||||
@ -16,51 +16,36 @@ namespace cfg
|
||||
}
|
||||
}
|
||||
|
||||
entry_base::entry_base(type _type, node& owner, const std::string& name)
|
||||
_base::_base(type _type, node* owner, const std::string& name)
|
||||
: m_type(_type)
|
||||
{
|
||||
if (!owner.m_nodes.emplace(name, this).second)
|
||||
for (const auto& pair : owner->m_nodes)
|
||||
{
|
||||
if (pair.first == name)
|
||||
{
|
||||
fmt::throw_exception<std::logic_error>("Node already exists: %s" HERE, name);
|
||||
}
|
||||
}
|
||||
|
||||
entry_base& entry_base::operator[](const std::string& name) const
|
||||
{
|
||||
if (m_type == type::node)
|
||||
{
|
||||
return *static_cast<const node&>(*this).m_nodes.at(name);
|
||||
owner->m_nodes.emplace_back(name, this);
|
||||
}
|
||||
|
||||
fmt::throw_exception<std::logic_error>("Invalid node type" HERE);
|
||||
}
|
||||
|
||||
entry_base& entry_base::operator[](const char* name) const
|
||||
{
|
||||
if (m_type == type::node)
|
||||
{
|
||||
return *static_cast<const node&>(*this).m_nodes.at(name);
|
||||
}
|
||||
|
||||
fmt::throw_exception<std::logic_error>("Invalid node type" HERE);
|
||||
}
|
||||
|
||||
bool entry_base::from_string(const std::string&)
|
||||
bool _base::from_string(const std::string&)
|
||||
{
|
||||
fmt::throw_exception<std::logic_error>("from_string() purecall" HERE);
|
||||
}
|
||||
|
||||
bool entry_base::from_list(std::vector<std::string>&&)
|
||||
bool _base::from_list(std::vector<std::string>&&)
|
||||
{
|
||||
fmt::throw_exception<std::logic_error>("from_list() purecall" HERE);
|
||||
}
|
||||
|
||||
// Emit YAML
|
||||
static void encode(YAML::Emitter& out, const class entry_base& rhs);
|
||||
static void encode(YAML::Emitter& out, const class _base& rhs);
|
||||
|
||||
// Incrementally load config entries from YAML::Node.
|
||||
// The config value is preserved if the corresponding YAML node doesn't exist.
|
||||
static void decode(const YAML::Node& data, class entry_base& rhs);
|
||||
static void decode(const YAML::Node& data, class _base& rhs);
|
||||
}
|
||||
|
||||
bool cfg::try_to_int64(s64* out, const std::string& value, s64 min, s64 max)
|
||||
@ -151,7 +136,7 @@ std::vector<std::string> cfg::try_to_enum_list(decltype(&fmt_class_string<int>::
|
||||
return result;
|
||||
}
|
||||
|
||||
void cfg::encode(YAML::Emitter& out, const cfg::entry_base& rhs)
|
||||
void cfg::encode(YAML::Emitter& out, const cfg::_base& rhs)
|
||||
{
|
||||
switch (rhs.get_type())
|
||||
{
|
||||
@ -197,7 +182,7 @@ void cfg::encode(YAML::Emitter& out, const cfg::entry_base& rhs)
|
||||
out << rhs.to_string();
|
||||
}
|
||||
|
||||
void cfg::decode(const YAML::Node& data, cfg::entry_base& rhs)
|
||||
void cfg::decode(const YAML::Node& data, cfg::_base& rhs)
|
||||
{
|
||||
switch (rhs.get_type())
|
||||
{
|
||||
@ -213,15 +198,12 @@ void cfg::decode(const YAML::Node& data, cfg::entry_base& rhs)
|
||||
if (!pair.first.IsScalar()) continue;
|
||||
|
||||
// Find the key among existing nodes
|
||||
const auto found = static_cast<node&>(rhs).get_nodes().find(pair.first.Scalar());
|
||||
|
||||
if (found != static_cast<node&>(rhs).get_nodes().cend())
|
||||
for (const auto& _pair : static_cast<node&>(rhs).get_nodes())
|
||||
{
|
||||
decode(pair.second, *found->second);
|
||||
if (_pair.first == pair.first.Scalar())
|
||||
{
|
||||
decode(pair.second, *_pair.second);
|
||||
}
|
||||
else
|
||||
{
|
||||
// ???
|
||||
}
|
||||
}
|
||||
|
||||
@ -297,19 +279,18 @@ void cfg::node::from_default()
|
||||
}
|
||||
}
|
||||
|
||||
void cfg::bool_entry::from_default()
|
||||
void cfg::_bool::from_default()
|
||||
{
|
||||
value = def;
|
||||
m_value = def;
|
||||
}
|
||||
|
||||
void cfg::string_entry::from_default()
|
||||
void cfg::string::from_default()
|
||||
{
|
||||
*this = def;
|
||||
m_value = def;
|
||||
}
|
||||
|
||||
void cfg::set_entry::from_default()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
m_set = {};
|
||||
}
|
||||
|
||||
@ -327,10 +308,3 @@ void cfg::log_entry::from_default()
|
||||
{
|
||||
set_map({});
|
||||
}
|
||||
|
||||
cfg::root_node& cfg::get_root()
|
||||
{
|
||||
// Magic static
|
||||
static root_node root;
|
||||
return root;
|
||||
}
|
||||
|
@ -1,19 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "Utilities/types.h"
|
||||
#include "Utilities/Atomic.h"
|
||||
#include "Utilities/StrFmt.h"
|
||||
#include "Utilities/Log.h"
|
||||
|
||||
#include <initializer_list>
|
||||
#include <exception>
|
||||
#include <utility>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
|
||||
namespace cfg
|
||||
{
|
||||
@ -30,37 +25,33 @@ namespace cfg
|
||||
enum class type : uint
|
||||
{
|
||||
node = 0, // cfg::node type
|
||||
boolean, // cfg::bool_entry type
|
||||
fixed_map, // cfg::map_entry type
|
||||
enumeration, // cfg::enum_entry type
|
||||
integer, // cfg::int_entry type
|
||||
string, // cfg::string_entry type
|
||||
_bool, // cfg::_bool type
|
||||
_enum, // cfg::_enum type
|
||||
_int, // cfg::_int type
|
||||
string, // cfg::string type
|
||||
set, // cfg::set_entry type
|
||||
log,
|
||||
};
|
||||
|
||||
// Config tree entry abstract base class
|
||||
class entry_base
|
||||
class _base
|
||||
{
|
||||
const type m_type;
|
||||
|
||||
protected:
|
||||
// Ownerless entry constructor
|
||||
entry_base(type _type);
|
||||
_base(type _type);
|
||||
|
||||
// Owned entry constructor
|
||||
entry_base(type _type, class node& owner, const std::string& name);
|
||||
_base(type _type, class node* owner, const std::string& name);
|
||||
|
||||
public:
|
||||
// Disallow copy/move constructors and assignments
|
||||
entry_base(const entry_base&) = delete;
|
||||
_base(const _base&) = delete;
|
||||
|
||||
// Get type
|
||||
type get_type() const { return m_type; }
|
||||
|
||||
// Access child node (must exist)
|
||||
entry_base& operator [](const std::string& name) const; entry_base& operator [](const char* name) const;
|
||||
|
||||
// Reset defaults
|
||||
virtual void from_default() = 0;
|
||||
|
||||
@ -84,27 +75,27 @@ namespace cfg
|
||||
};
|
||||
|
||||
// Config tree node which contains another nodes
|
||||
class node : public entry_base
|
||||
class node : public _base
|
||||
{
|
||||
std::map<std::string, entry_base*> m_nodes;
|
||||
std::vector<std::pair<std::string, _base*>> m_nodes;
|
||||
|
||||
friend class entry_base;
|
||||
friend class _base;
|
||||
|
||||
public:
|
||||
// Root node constructor
|
||||
node()
|
||||
: entry_base(type::node)
|
||||
: _base(type::node)
|
||||
{
|
||||
}
|
||||
|
||||
// Registered node constructor
|
||||
node(node& owner, const std::string& name)
|
||||
: entry_base(type::node, owner, name)
|
||||
node(node* owner, const std::string& name)
|
||||
: _base(type::node, owner, name)
|
||||
{
|
||||
}
|
||||
|
||||
// Get child nodes
|
||||
const std::map<std::string, entry_base*>& get_nodes() const
|
||||
const auto& get_nodes() const
|
||||
{
|
||||
return m_nodes;
|
||||
}
|
||||
@ -119,43 +110,38 @@ namespace cfg
|
||||
void from_default() override;
|
||||
};
|
||||
|
||||
struct bool_entry final : public entry_base
|
||||
class _bool final : public _base
|
||||
{
|
||||
atomic_t<bool> value;
|
||||
bool m_value;
|
||||
|
||||
public:
|
||||
const bool def;
|
||||
|
||||
bool_entry(node& owner, const std::string& name, bool def = false)
|
||||
: entry_base(type::boolean, owner, name)
|
||||
, value(def)
|
||||
_bool(node* owner, const std::string& name, bool def = false)
|
||||
: _base(type::_bool, owner, name)
|
||||
, m_value(def)
|
||||
, def(def)
|
||||
{
|
||||
}
|
||||
|
||||
explicit operator bool() const
|
||||
{
|
||||
return value.load();
|
||||
}
|
||||
|
||||
bool_entry& operator =(bool value)
|
||||
{
|
||||
value = value;
|
||||
return *this;
|
||||
return m_value;
|
||||
}
|
||||
|
||||
void from_default() override;
|
||||
|
||||
std::string to_string() const override
|
||||
{
|
||||
return value.load() ? "true" : "false";
|
||||
return m_value ? "true" : "false";
|
||||
}
|
||||
|
||||
bool from_string(const std::string& value) override
|
||||
{
|
||||
if (value == "false")
|
||||
this->value = false;
|
||||
m_value = false;
|
||||
else if (value == "true")
|
||||
this->value = true;
|
||||
m_value = true;
|
||||
else
|
||||
return false;
|
||||
|
||||
@ -163,116 +149,17 @@ namespace cfg
|
||||
}
|
||||
};
|
||||
|
||||
// Value node with fixed set of possible values, each maps to a value of type T.
|
||||
template<typename T>
|
||||
struct map_entry final : public entry_base
|
||||
{
|
||||
using init_type = std::initializer_list<std::pair<std::string, T>>;
|
||||
using map_type = std::unordered_map<std::string, T>;
|
||||
using list_type = std::vector<std::string>;
|
||||
using value_type = typename map_type::value_type;
|
||||
|
||||
static map_type make_map(init_type init)
|
||||
{
|
||||
map_type map(init.size());
|
||||
|
||||
for (const auto& v : init)
|
||||
{
|
||||
// Ensure elements are unique
|
||||
verify(HERE), map.emplace(v.first, v.second).second;
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
static list_type make_list(init_type init)
|
||||
{
|
||||
list_type list; list.reserve(init.size());
|
||||
|
||||
for (const auto& v : init)
|
||||
{
|
||||
list.emplace_back(v.first);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public:
|
||||
const map_type map;
|
||||
const list_type list; // Element list sorted in original order
|
||||
const value_type& def; // Pointer to the default value
|
||||
|
||||
private:
|
||||
atomic_t<const value_type*> m_value;
|
||||
|
||||
public:
|
||||
map_entry(node& owner, const std::string& name, const std::string& def, init_type init)
|
||||
: entry_base(type::fixed_map, owner, name)
|
||||
, map(make_map(init))
|
||||
, list(make_list(init))
|
||||
, def(*map.find(def))
|
||||
, m_value(&this->def)
|
||||
{
|
||||
}
|
||||
|
||||
map_entry(node& owner, const std::string& name, std::size_t def_index, init_type init)
|
||||
: map_entry(owner, name, (init.begin() + (def_index < init.size() ? def_index : 0))->first, init)
|
||||
{
|
||||
}
|
||||
|
||||
map_entry(node& owner, const std::string& name, init_type init)
|
||||
: map_entry(owner, name, 0, init)
|
||||
{
|
||||
}
|
||||
|
||||
const T& get() const
|
||||
{
|
||||
return m_value.load()->second;
|
||||
}
|
||||
|
||||
void from_default() override
|
||||
{
|
||||
m_value = &def;
|
||||
}
|
||||
|
||||
std::string to_string() const override
|
||||
{
|
||||
return m_value.load()->first;
|
||||
}
|
||||
|
||||
bool from_string(const std::string& value) override
|
||||
{
|
||||
const auto found = map.find(value);
|
||||
|
||||
if (found == map.end())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_value = &*found;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> to_list() const override
|
||||
{
|
||||
return list;
|
||||
}
|
||||
};
|
||||
|
||||
// Value node with fixed set of possible values, each maps to an enum value of type T.
|
||||
template<typename T, bool External = false>
|
||||
class enum_entry final : public entry_base
|
||||
template <typename T>
|
||||
class _enum final : public _base
|
||||
{
|
||||
// Value or reference
|
||||
std::conditional_t<External, atomic_t<T>&, atomic_t<T>> m_value;
|
||||
T m_value;
|
||||
|
||||
public:
|
||||
const T def;
|
||||
|
||||
enum_entry(node& owner, const std::string& name, std::conditional_t<External, atomic_t<T>&, T> value)
|
||||
: entry_base(type::enumeration, owner, name)
|
||||
_enum(node* owner, const std::string& name, T value = {})
|
||||
: _base(type::_enum, owner, name)
|
||||
, m_value(value)
|
||||
, def(value)
|
||||
{
|
||||
@ -280,13 +167,7 @@ namespace cfg
|
||||
|
||||
operator T() const
|
||||
{
|
||||
return m_value.load();
|
||||
}
|
||||
|
||||
enum_entry& operator =(T value)
|
||||
{
|
||||
m_value = value;
|
||||
return *this;
|
||||
return m_value;
|
||||
}
|
||||
|
||||
void from_default() override
|
||||
@ -322,21 +203,21 @@ namespace cfg
|
||||
};
|
||||
|
||||
// Signed 32/64-bit integer entry with custom Min/Max range.
|
||||
template<s64 Min, s64 Max>
|
||||
class int_entry final : public entry_base
|
||||
template <s64 Min, s64 Max>
|
||||
class _int final : public _base
|
||||
{
|
||||
static_assert(Min < Max, "Invalid cfg::int_entry range");
|
||||
static_assert(Min < Max, "Invalid cfg::_int range");
|
||||
|
||||
// Prefer 32 bit type if possible
|
||||
using int_type = std::conditional_t<Min >= INT32_MIN && Max <= INT32_MAX, s32, s64>;
|
||||
|
||||
atomic_t<int_type> m_value;
|
||||
int_type m_value;
|
||||
|
||||
public:
|
||||
const int_type def;
|
||||
|
||||
int_entry(node& owner, const std::string& name, int_type def = std::min<int_type>(Max, std::max<int_type>(Min, 0)))
|
||||
: entry_base(type::integer, owner, name)
|
||||
_int(node* owner, const std::string& name, int_type def = std::min<int_type>(Max, std::max<int_type>(Min, 0)))
|
||||
: _base(type::_int, owner, name)
|
||||
, m_value(def)
|
||||
, def(def)
|
||||
{
|
||||
@ -344,18 +225,7 @@ namespace cfg
|
||||
|
||||
operator int_type() const
|
||||
{
|
||||
return m_value.load();
|
||||
}
|
||||
|
||||
int_entry& operator =(int_type value)
|
||||
{
|
||||
if (value < Min || value > Max)
|
||||
{
|
||||
fmt::throw_exception("Value out of the valid range: %lld" HERE, s64{ value });
|
||||
}
|
||||
|
||||
m_value = value;
|
||||
return *this;
|
||||
return m_value;
|
||||
}
|
||||
|
||||
void from_default() override
|
||||
@ -365,7 +235,7 @@ namespace cfg
|
||||
|
||||
std::string to_string() const override
|
||||
{
|
||||
return std::to_string(m_value.load());
|
||||
return std::to_string(m_value);
|
||||
}
|
||||
|
||||
bool from_string(const std::string& value) override
|
||||
@ -382,22 +252,21 @@ namespace cfg
|
||||
};
|
||||
|
||||
// Alias for 32 bit int
|
||||
using int32_entry = int_entry<INT32_MIN, INT32_MAX>;
|
||||
using int32 = _int<INT32_MIN, INT32_MAX>;
|
||||
|
||||
// Alias for 64 bit int
|
||||
using int64_entry = int_entry<INT64_MIN, INT64_MAX>;
|
||||
using int64 = _int<INT64_MIN, INT64_MAX>;
|
||||
|
||||
// Simple string entry with mutex
|
||||
class string_entry final : public entry_base
|
||||
class string final : public _base
|
||||
{
|
||||
mutable std::mutex m_mutex;
|
||||
std::string m_value;
|
||||
|
||||
public:
|
||||
const std::string def;
|
||||
|
||||
string_entry(node& owner, const std::string& name, const std::string& def = {})
|
||||
: entry_base(type::string, owner, name)
|
||||
string(node* owner, const std::string& name, const std::string& def = {})
|
||||
: _base(type::string, owner, name)
|
||||
, m_value(def)
|
||||
, def(def)
|
||||
{
|
||||
@ -405,25 +274,16 @@ namespace cfg
|
||||
|
||||
operator std::string() const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
return m_value;
|
||||
}
|
||||
|
||||
std::string get() const
|
||||
const std::string& get() const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
string_entry& operator =(const std::string& value)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
m_value = value;
|
||||
return *this;
|
||||
return m_value;
|
||||
}
|
||||
|
||||
std::size_t size() const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
return m_value.size();
|
||||
}
|
||||
|
||||
@ -431,41 +291,35 @@ namespace cfg
|
||||
|
||||
std::string to_string() const override
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
return m_value;
|
||||
}
|
||||
|
||||
bool from_string(const std::string& value) override
|
||||
{
|
||||
*this = value;
|
||||
m_value = value;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
// Simple set entry with mutex (TODO: template for various types)
|
||||
class set_entry final : public entry_base
|
||||
class set_entry final : public _base
|
||||
{
|
||||
mutable std::mutex m_mutex;
|
||||
|
||||
std::set<std::string> m_set;
|
||||
|
||||
public:
|
||||
// Default value is empty list in current implementation
|
||||
set_entry(node& owner, const std::string& name)
|
||||
: entry_base(type::set, owner, name)
|
||||
set_entry(node* owner, const std::string& name)
|
||||
: _base(type::set, owner, name)
|
||||
{
|
||||
}
|
||||
|
||||
std::set<std::string> get_set() const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
|
||||
return m_set;
|
||||
}
|
||||
|
||||
void set_set(std::set<std::string>&& set)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
m_set = std::move(set);
|
||||
}
|
||||
|
||||
@ -473,27 +327,24 @@ namespace cfg
|
||||
|
||||
std::vector<std::string> to_list() const override
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
|
||||
return{ m_set.begin(), m_set.end() };
|
||||
}
|
||||
|
||||
bool from_list(std::vector<std::string>&& list) override
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
m_set = { std::make_move_iterator(list.begin()), std::make_move_iterator(list.end()) };
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class log_entry final : public entry_base
|
||||
class log_entry final : public _base
|
||||
{
|
||||
std::map<std::string, logs::level> m_map;
|
||||
|
||||
public:
|
||||
log_entry(node& owner, const std::string& name)
|
||||
: entry_base(type::log, owner, name)
|
||||
log_entry(node* owner, const std::string& name)
|
||||
: _base(type::log, owner, name)
|
||||
{
|
||||
}
|
||||
|
||||
@ -506,25 +357,4 @@ namespace cfg
|
||||
|
||||
void from_default() override;
|
||||
};
|
||||
|
||||
// Root type with some predefined nodes. Don't change it, this is not mandatory for adding nodes.
|
||||
struct root_node : node
|
||||
{
|
||||
node core {*this, "Core"};
|
||||
node vfs {*this, "VFS"};
|
||||
node video {*this, "Video"};
|
||||
node audio {*this, "Audio"};
|
||||
node io {*this, "Input/Output"};
|
||||
node sys {*this, "System"};
|
||||
node net {*this, "Net"};
|
||||
node misc {*this, "Miscellaneous"};
|
||||
|
||||
log_entry log{*this, "Log"};
|
||||
};
|
||||
|
||||
// Get global configuration root instance
|
||||
extern root_node& get_root();
|
||||
|
||||
// Global configuration root instance (cached reference)
|
||||
static root_node& root = get_root();
|
||||
}
|
||||
|
@ -3,7 +3,6 @@
|
||||
|
||||
#include "GDBDebugServer.h"
|
||||
#include "Log.h"
|
||||
#include "Config.h"
|
||||
#include <algorithm>
|
||||
#include "Emu/Memory/Memory.h"
|
||||
#include "Emu/System.h"
|
||||
@ -65,8 +64,6 @@ bool check_errno_again() {
|
||||
#endif
|
||||
}
|
||||
|
||||
cfg::int_entry<1, 65535> g_cfg_gdb_server_port(cfg::root.misc, "Port", 2345);
|
||||
|
||||
std::string u32_to_hex(u32 i) {
|
||||
return fmt::format("%" HEX_U32, i);
|
||||
}
|
||||
@ -119,7 +116,7 @@ void GDBDebugServer::start_server()
|
||||
|
||||
sockaddr_in server_saddr;
|
||||
server_saddr.sin_family = AF_INET;
|
||||
int port = g_cfg_gdb_server_port;
|
||||
int port = g_cfg.misc.gdb_server_port;
|
||||
server_saddr.sin_port = htons(port);
|
||||
server_saddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
|
||||
|
@ -1,12 +1,8 @@
|
||||
#include "stdafx.h"
|
||||
#include "Utilities/Config.h"
|
||||
#include "Emu/System.h"
|
||||
|
||||
#include "OpenALThread.h"
|
||||
|
||||
extern cfg::bool_entry g_cfg_audio_convert_to_u16;
|
||||
extern cfg::bool_entry g_cfg_audio_downmix_to_2ch;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma comment(lib, "OpenAL32.lib")
|
||||
#endif
|
||||
@ -46,13 +42,13 @@ OpenALThread::OpenALThread()
|
||||
alcMakeContextCurrent(m_context);
|
||||
checkForAlcError("alcMakeContextCurrent");
|
||||
|
||||
if (g_cfg_audio_downmix_to_2ch)
|
||||
if (g_cfg.audio.downmix_to_2ch)
|
||||
{
|
||||
m_format = g_cfg_audio_convert_to_u16 ? AL_FORMAT_STEREO16 : AL_FORMAT_STEREO_FLOAT32;
|
||||
m_format = g_cfg.audio.convert_to_u16 ? AL_FORMAT_STEREO16 : AL_FORMAT_STEREO_FLOAT32;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_format = g_cfg_audio_convert_to_u16 ? AL_FORMAT_71CHN16 : AL_FORMAT_71CHN32;
|
||||
m_format = g_cfg.audio.convert_to_u16 ? AL_FORMAT_71CHN16 : AL_FORMAT_71CHN32;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
#include "stdafx.h"
|
||||
#include "Utilities/Config.h"
|
||||
#include "Utilities/GSL.h"
|
||||
#include "Emu/System.h"
|
||||
|
||||
@ -9,10 +8,7 @@
|
||||
|
||||
#include <alsa/asoundlib.h>
|
||||
|
||||
extern cfg::bool_entry g_cfg_audio_convert_to_u16;
|
||||
extern cfg::bool_entry g_cfg_audio_downmix_to_2ch;
|
||||
|
||||
thread_local static snd_pcm_t* s_tls_handle{nullptr};
|
||||
static thread_local snd_pcm_t* s_tls_handle{nullptr};
|
||||
|
||||
static void error(int err, const char* reason)
|
||||
{
|
||||
@ -54,13 +50,13 @@ ALSAThread::ALSAThread()
|
||||
if (!check(snd_pcm_hw_params_set_access(s_tls_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED), "snd_pcm_hw_params_set_access"))
|
||||
return;
|
||||
|
||||
if (!check(snd_pcm_hw_params_set_format(s_tls_handle, hw_params, g_cfg_audio_convert_to_u16 ? SND_PCM_FORMAT_S16_LE : SND_PCM_FORMAT_FLOAT_LE), "snd_pcm_hw_params_set_format"))
|
||||
if (!check(snd_pcm_hw_params_set_format(s_tls_handle, hw_params, g_cfg.audio.convert_to_u16 ? SND_PCM_FORMAT_S16_LE : SND_PCM_FORMAT_FLOAT_LE), "snd_pcm_hw_params_set_format"))
|
||||
return;
|
||||
|
||||
if (!check(snd_pcm_hw_params_set_rate(s_tls_handle, hw_params, 48000, 0), "snd_pcm_hw_params_set_rate_near"))
|
||||
return;
|
||||
|
||||
if (!check(snd_pcm_hw_params_set_channels(s_tls_handle, hw_params, g_cfg_audio_downmix_to_2ch ? 2 : 8), "snd_pcm_hw_params_set_channels"))
|
||||
if (!check(snd_pcm_hw_params_set_channels(s_tls_handle, hw_params, g_cfg.audio.downmix_to_2ch ? 2 : 8), "snd_pcm_hw_params_set_channels"))
|
||||
return;
|
||||
|
||||
if (!check(snd_pcm_hw_params_set_buffer_size(s_tls_handle, hw_params, 8 * 256), "snd_pcm_hw_params_set_buffer_size"))
|
||||
@ -106,8 +102,8 @@ void ALSAThread::Open(const void* src, int size)
|
||||
|
||||
void ALSAThread::AddData(const void* src, int size)
|
||||
{
|
||||
size /= g_cfg_audio_convert_to_u16 ? 2 : 4;
|
||||
size /= g_cfg_audio_downmix_to_2ch ? 2 : 8;
|
||||
size /= g_cfg.audio.convert_to_u16 ? 2 : 4;
|
||||
size /= g_cfg.audio.downmix_to_2ch ? 2 : 8;
|
||||
|
||||
int res;
|
||||
|
||||
|
@ -2,15 +2,11 @@
|
||||
|
||||
#include "Utilities/Log.h"
|
||||
#include "Utilities/StrFmt.h"
|
||||
#include "Utilities/Config.h"
|
||||
#include "Emu/System.h"
|
||||
|
||||
#include "XAudio2Thread.h"
|
||||
#include "3rdparty/XAudio2_7/XAudio2.h"
|
||||
|
||||
extern cfg::bool_entry g_cfg_audio_convert_to_u16;
|
||||
extern cfg::bool_entry g_cfg_audio_downmix_to_2ch;
|
||||
|
||||
static thread_local HMODULE s_tls_xaudio2_lib{};
|
||||
static thread_local IXAudio2* s_tls_xaudio2_instance{};
|
||||
static thread_local IXAudio2MasteringVoice* s_tls_master_voice{};
|
||||
@ -38,7 +34,7 @@ void XAudio2Thread::xa27_init(void* lib2_7)
|
||||
return;
|
||||
}
|
||||
|
||||
hr = s_tls_xaudio2_instance->CreateMasteringVoice(&s_tls_master_voice, g_cfg_audio_downmix_to_2ch ? 2 : 8, 48000);
|
||||
hr = s_tls_xaudio2_instance->CreateMasteringVoice(&s_tls_master_voice, g_cfg.audio.downmix_to_2ch ? 2 : 8, 48000);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
LOG_ERROR(GENERAL, "XAudio2Thread : CreateMasteringVoice() failed(0x%08x)", (u32)hr);
|
||||
@ -105,11 +101,11 @@ void XAudio2Thread::xa27_open()
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
WORD sample_size = g_cfg_audio_convert_to_u16 ? sizeof(u16) : sizeof(float);
|
||||
WORD channels = g_cfg_audio_downmix_to_2ch ? 2 : 8;
|
||||
WORD sample_size = g_cfg.audio.convert_to_u16 ? sizeof(u16) : sizeof(float);
|
||||
WORD channels = g_cfg.audio.downmix_to_2ch ? 2 : 8;
|
||||
|
||||
WAVEFORMATEX waveformatex;
|
||||
waveformatex.wFormatTag = g_cfg_audio_convert_to_u16 ? WAVE_FORMAT_PCM : WAVE_FORMAT_IEEE_FLOAT;
|
||||
waveformatex.wFormatTag = g_cfg.audio.convert_to_u16 ? WAVE_FORMAT_PCM : WAVE_FORMAT_IEEE_FLOAT;
|
||||
waveformatex.nChannels = channels;
|
||||
waveformatex.nSamplesPerSec = 48000;
|
||||
waveformatex.nAvgBytesPerSec = 48000 * (DWORD)channels * (DWORD)sample_size;
|
||||
@ -125,7 +121,7 @@ void XAudio2Thread::xa27_open()
|
||||
return;
|
||||
}
|
||||
|
||||
s_tls_source_voice->SetVolume(g_cfg_audio_downmix_to_2ch ? 1.0 : 4.0);
|
||||
s_tls_source_voice->SetVolume(g_cfg.audio.downmix_to_2ch ? 1.0 : 4.0);
|
||||
}
|
||||
|
||||
void XAudio2Thread::xa27_add(const void* src, int size)
|
||||
|
@ -2,15 +2,11 @@
|
||||
|
||||
#include "Utilities/Log.h"
|
||||
#include "Utilities/StrFmt.h"
|
||||
#include "Utilities/Config.h"
|
||||
#include "Emu/System.h"
|
||||
|
||||
#include "XAudio2Thread.h"
|
||||
#include "3rdparty/minidx12/Include/xaudio2.h"
|
||||
|
||||
extern cfg::bool_entry g_cfg_audio_convert_to_u16;
|
||||
extern cfg::bool_entry g_cfg_audio_downmix_to_2ch;
|
||||
|
||||
static thread_local HMODULE s_tls_xaudio2_lib{};
|
||||
static thread_local IXAudio2* s_tls_xaudio2_instance{};
|
||||
static thread_local IXAudio2MasteringVoice* s_tls_master_voice{};
|
||||
@ -40,7 +36,7 @@ void XAudio2Thread::xa28_init(void* lib)
|
||||
return;
|
||||
}
|
||||
|
||||
hr = s_tls_xaudio2_instance->CreateMasteringVoice(&s_tls_master_voice, g_cfg_audio_downmix_to_2ch ? 2 : 8, 48000);
|
||||
hr = s_tls_xaudio2_instance->CreateMasteringVoice(&s_tls_master_voice, g_cfg.audio.downmix_to_2ch ? 2 : 8, 48000);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
LOG_ERROR(GENERAL, "XAudio2Thread : CreateMasteringVoice() failed(0x%08x)", (u32)hr);
|
||||
@ -107,11 +103,11 @@ void XAudio2Thread::xa28_open()
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
WORD sample_size = g_cfg_audio_convert_to_u16 ? sizeof(u16) : sizeof(float);
|
||||
WORD channels = g_cfg_audio_downmix_to_2ch ? 2 : 8;
|
||||
WORD sample_size = g_cfg.audio.convert_to_u16 ? sizeof(u16) : sizeof(float);
|
||||
WORD channels = g_cfg.audio.downmix_to_2ch ? 2 : 8;
|
||||
|
||||
WAVEFORMATEX waveformatex;
|
||||
waveformatex.wFormatTag = g_cfg_audio_convert_to_u16 ? WAVE_FORMAT_PCM : WAVE_FORMAT_IEEE_FLOAT;
|
||||
waveformatex.wFormatTag = g_cfg.audio.convert_to_u16 ? WAVE_FORMAT_PCM : WAVE_FORMAT_IEEE_FLOAT;
|
||||
waveformatex.nChannels = channels;
|
||||
waveformatex.nSamplesPerSec = 48000;
|
||||
waveformatex.nAvgBytesPerSec = 48000 * (DWORD)channels * (DWORD)sample_size;
|
||||
@ -127,7 +123,7 @@ void XAudio2Thread::xa28_open()
|
||||
return;
|
||||
}
|
||||
|
||||
s_tls_source_voice->SetVolume(g_cfg_audio_downmix_to_2ch ? 1.0 : 4.0);
|
||||
s_tls_source_voice->SetVolume(g_cfg.audio.downmix_to_2ch ? 1.0 : 4.0);
|
||||
}
|
||||
|
||||
void XAudio2Thread::xa28_add(const void* src, int size)
|
||||
|
@ -4,7 +4,6 @@
|
||||
#include "CPUThread.h"
|
||||
#include "Emu/IdManager.h"
|
||||
#include "Utilities/GDBDebugServer.h"
|
||||
#include "Utilities/Config.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
|
@ -1,5 +1,4 @@
|
||||
#include "stdafx.h"
|
||||
#include "Utilities/Config.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/IdManager.h"
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
@ -13,10 +12,6 @@
|
||||
|
||||
logs::channel cellAudio("cellAudio");
|
||||
|
||||
cfg::bool_entry g_cfg_audio_dump_to_file(cfg::root.audio, "Dump to file");
|
||||
cfg::bool_entry g_cfg_audio_convert_to_u16(cfg::root.audio, "Convert to 16 bit");
|
||||
cfg::bool_entry g_cfg_audio_downmix_to_2ch(cfg::root.audio, "Downmix to Stereo", true);
|
||||
|
||||
void audio_config::on_init(const std::shared_ptr<void>& _this)
|
||||
{
|
||||
m_buffer.set(vm::alloc(AUDIO_PORT_OFFSET * AUDIO_PORT_COUNT, vm::main));
|
||||
@ -34,12 +29,12 @@ void audio_config::on_init(const std::shared_ptr<void>& _this)
|
||||
|
||||
void audio_config::on_task()
|
||||
{
|
||||
AudioDumper m_dump(g_cfg_audio_dump_to_file ? 2 : 0); // Init AudioDumper for 2 channels if enabled
|
||||
AudioDumper m_dump(g_cfg.audio.dump_to_file ? 2 : 0); // Init AudioDumper for 2 channels if enabled
|
||||
|
||||
float buf2ch[2 * BUFFER_SIZE]{}; // intermediate buffer for 2 channels
|
||||
float buf8ch[8 * BUFFER_SIZE]{}; // intermediate buffer for 8 channels
|
||||
|
||||
const u32 buf_sz = BUFFER_SIZE * (g_cfg_audio_convert_to_u16 ? 2 : 4) * (g_cfg_audio_downmix_to_2ch ? 2 : 8);
|
||||
const u32 buf_sz = BUFFER_SIZE * (g_cfg.audio.convert_to_u16 ? 2 : 4) * (g_cfg.audio.downmix_to_2ch ? 2 : 8);
|
||||
|
||||
std::unique_ptr<float[]> out_buffer[BUFFER_NUM];
|
||||
|
||||
@ -227,7 +222,7 @@ void audio_config::on_task()
|
||||
if (!first_mix)
|
||||
{
|
||||
// Copy output data (2ch or 8ch)
|
||||
if (g_cfg_audio_downmix_to_2ch)
|
||||
if (g_cfg.audio.downmix_to_2ch)
|
||||
{
|
||||
for (u32 i = 0; i < (sizeof(buf2ch) / sizeof(float)); i++)
|
||||
{
|
||||
@ -250,7 +245,7 @@ void audio_config::on_task()
|
||||
std::memset(out_buffer[out_pos].get(), 0, 8 * BUFFER_SIZE * sizeof(float));
|
||||
}
|
||||
|
||||
if (g_cfg_audio_convert_to_u16)
|
||||
if (g_cfg.audio.convert_to_u16)
|
||||
{
|
||||
// convert the data from float to u16 with clipping:
|
||||
// 2x MULPS
|
||||
|
@ -1,5 +1,4 @@
|
||||
#include "stdafx.h"
|
||||
#include "Utilities/Config.h"
|
||||
#include "Emu/IdManager.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
@ -8,19 +7,37 @@
|
||||
|
||||
logs::channel cellCamera("cellCamera");
|
||||
|
||||
cfg::map_entry<bool> g_cfg_camera(cfg::root.io, "Camera",
|
||||
template <>
|
||||
void fmt_class_string<camera_handler>::format(std::string& out, u64 arg)
|
||||
{
|
||||
{ "Null", false },
|
||||
{ "Fake", true },
|
||||
});
|
||||
format_enum(out, arg, [](auto value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case camera_handler::null: return "Null";
|
||||
case camera_handler::fake: return "Fake";
|
||||
}
|
||||
|
||||
cfg::map_entry<CellCameraType> g_cfg_camera_type(cfg::root.io, "Camera type",
|
||||
return unknown;
|
||||
});
|
||||
}
|
||||
|
||||
template <>
|
||||
void fmt_class_string<fake_camera_type>::format(std::string& out, u64 arg)
|
||||
{
|
||||
{ "Unknown", CELL_CAMERA_TYPE_UNKNOWN },
|
||||
{ "EyeToy", CELL_CAMERA_EYETOY },
|
||||
{ "PS Eye", CELL_CAMERA_EYETOY2 },
|
||||
{ "UVC 1.1", CELL_CAMERA_USBVIDEOCLASS },
|
||||
});
|
||||
format_enum(out, arg, [](auto value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case fake_camera_type::unknown: return "Unknown";
|
||||
case fake_camera_type::eyetoy: return "EyeToy";
|
||||
case fake_camera_type::eyetoy2: return "PS Eye";
|
||||
case fake_camera_type::uvc1_1: return "UVC 1.1";
|
||||
}
|
||||
|
||||
return unknown;
|
||||
});
|
||||
}
|
||||
|
||||
static const char* get_camera_attr_name(s32 value)
|
||||
{
|
||||
@ -95,7 +112,7 @@ s32 cellCameraInit()
|
||||
{
|
||||
cellCamera.warning("cellCameraInit()");
|
||||
|
||||
if (!g_cfg_camera.get())
|
||||
if (g_cfg.io.camera == camera_handler::null)
|
||||
{
|
||||
return CELL_CAMERA_ERROR_DEVICE_NOT_FOUND;
|
||||
}
|
||||
@ -107,9 +124,9 @@ s32 cellCameraInit()
|
||||
return CELL_CAMERA_ERROR_ALREADY_INIT;
|
||||
}
|
||||
|
||||
switch (g_cfg_camera_type.get())
|
||||
switch (g_cfg.io.camera_type)
|
||||
{
|
||||
case CELL_CAMERA_EYETOY:
|
||||
case fake_camera_type::eyetoy:
|
||||
{
|
||||
camera->attr[CELL_CAMERA_SATURATION] = { 164 };
|
||||
camera->attr[CELL_CAMERA_BRIGHTNESS] = { 96 };
|
||||
@ -125,10 +142,10 @@ s32 cellCameraInit()
|
||||
camera->attr[CELL_CAMERA_MIRRORFLAG] = { 1 };
|
||||
camera->attr[CELL_CAMERA_422FLAG] = { 1 };
|
||||
camera->attr[CELL_CAMERA_USBLOAD] = { 4 };
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case CELL_CAMERA_EYETOY2:
|
||||
case fake_camera_type::eyetoy2:
|
||||
{
|
||||
camera->attr[CELL_CAMERA_SATURATION] = { 64 };
|
||||
camera->attr[CELL_CAMERA_BRIGHTNESS] = { 8 };
|
||||
@ -145,11 +162,8 @@ s32 cellCameraInit()
|
||||
camera->attr[CELL_CAMERA_PIXELOUTLIERFILTER] = { 1 };
|
||||
camera->attr[CELL_CAMERA_AGCLOW] = { 48 };
|
||||
camera->attr[CELL_CAMERA_AGCHIGH] = { 64 };
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Some other default attributes? Need to check the actual behaviour on a real PS3.
|
||||
@ -204,7 +218,14 @@ s32 cellCameraGetType(s32 dev_num, vm::ptr<s32> type)
|
||||
return CELL_CAMERA_ERROR_NOT_INIT;
|
||||
}
|
||||
|
||||
*type = g_cfg_camera_type.get();
|
||||
switch (g_cfg.io.camera_type)
|
||||
{
|
||||
case fake_camera_type::unknown: *type = CELL_CAMERA_TYPE_UNKNOWN; break;
|
||||
case fake_camera_type::eyetoy: *type = CELL_CAMERA_EYETOY; break;
|
||||
case fake_camera_type::eyetoy2: *type = CELL_CAMERA_EYETOY2; break;
|
||||
case fake_camera_type::uvc1_1: *type = CELL_CAMERA_USBVIDEOCLASS; break;
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@ -218,7 +239,7 @@ s32 cellCameraIsAttached(s32 dev_num)
|
||||
{
|
||||
cellCamera.warning("cellCameraIsAttached(dev_num=%d)", dev_num);
|
||||
|
||||
if (g_cfg_camera.get())
|
||||
if (g_cfg.io.camera == camera_handler::fake)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
#include "stdafx.h"
|
||||
#include "Utilities/Config.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
|
||||
@ -11,7 +10,7 @@
|
||||
|
||||
logs::channel cellNetCtl("cellNetCtl");
|
||||
|
||||
template<>
|
||||
template <>
|
||||
void fmt_class_string<CellNetCtlError>::format(std::string& out, u64 arg)
|
||||
{
|
||||
format_enum(out, arg, [](auto error)
|
||||
@ -69,15 +68,22 @@ void fmt_class_string<CellNetCtlError>::format(std::string& out, u64 arg)
|
||||
});
|
||||
}
|
||||
|
||||
cfg::map_entry<s32> g_cfg_net_status(cfg::root.net, "Connection status",
|
||||
template <>
|
||||
void fmt_class_string<CellNetCtlState>::format(std::string& out, u64 arg)
|
||||
{
|
||||
{ "Disconnected", CELL_NET_CTL_STATE_Disconnected },
|
||||
{ "Connecting", CELL_NET_CTL_STATE_Connecting },
|
||||
{ "Obtaining IP", CELL_NET_CTL_STATE_IPObtaining },
|
||||
{ "IP Obtained", CELL_NET_CTL_STATE_IPObtained },
|
||||
});
|
||||
format_enum(out, arg, [](CellNetCtlState value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case CELL_NET_CTL_STATE_Disconnected: return "Disconnected";
|
||||
case CELL_NET_CTL_STATE_Connecting: return "Connecting";
|
||||
case CELL_NET_CTL_STATE_IPObtaining: return "Obtaining IP";
|
||||
case CELL_NET_CTL_STATE_IPObtained: return "IP Obtained";
|
||||
}
|
||||
|
||||
cfg::string_entry g_cfg_net_ip_address(cfg::root.net, "IP address", "192.168.1.1");
|
||||
return unknown;
|
||||
});
|
||||
}
|
||||
|
||||
error_code cellNetCtlInit()
|
||||
{
|
||||
@ -97,7 +103,7 @@ error_code cellNetCtlGetState(vm::ptr<u32> state)
|
||||
{
|
||||
cellNetCtl.trace("cellNetCtlGetState(state=*0x%x)", state);
|
||||
|
||||
*state = g_cfg_net_status.get();
|
||||
*state = g_cfg.net.net_status;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@ -125,7 +131,7 @@ error_code cellNetCtlGetInfo(s32 code, vm::ptr<CellNetCtlInfo> info)
|
||||
}
|
||||
else if (code == CELL_NET_CTL_INFO_LINK)
|
||||
{
|
||||
if (g_cfg_net_status.get() != CELL_NET_CTL_STATE_Disconnected)
|
||||
if (g_cfg.net.net_status != CELL_NET_CTL_STATE_Disconnected)
|
||||
{
|
||||
info->link = CELL_NET_CTL_LINK_CONNECTED;
|
||||
}
|
||||
@ -136,14 +142,14 @@ error_code cellNetCtlGetInfo(s32 code, vm::ptr<CellNetCtlInfo> info)
|
||||
}
|
||||
else if (code == CELL_NET_CTL_INFO_IP_ADDRESS)
|
||||
{
|
||||
if (g_cfg_net_status.get() != CELL_NET_CTL_STATE_IPObtained)
|
||||
if (g_cfg.net.net_status != CELL_NET_CTL_STATE_IPObtained)
|
||||
{
|
||||
// 0.0.0.0 seems to be the default address when no ethernet cables are connected to the PS3
|
||||
strcpy_trunc(info->ip_address, "0.0.0.0");
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy_trunc(info->ip_address, g_cfg_net_ip_address);
|
||||
strcpy_trunc(info->ip_address, g_cfg.net.ip_address);
|
||||
}
|
||||
}
|
||||
else if (code == CELL_NET_CTL_INFO_NETMASK)
|
||||
|
@ -53,7 +53,7 @@ enum CellNetCtlError : u32
|
||||
};
|
||||
|
||||
// Network connection states
|
||||
enum
|
||||
enum CellNetCtlState : s32
|
||||
{
|
||||
CELL_NET_CTL_STATE_Disconnected = 0,
|
||||
CELL_NET_CTL_STATE_Connecting = 1,
|
||||
|
@ -1,5 +1,4 @@
|
||||
#include "stdafx.h"
|
||||
#include "Utilities/Config.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/IdManager.h"
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
@ -68,34 +67,43 @@ extern void sysutil_send_system_cmd(u64 status, u64 param)
|
||||
}
|
||||
}
|
||||
|
||||
cfg::map_entry<s32> g_cfg_sys_language(cfg::root.sys, "Language",
|
||||
template <>
|
||||
void fmt_class_string<CellSysutilLang>::format(std::string& out, u64 arg)
|
||||
{
|
||||
{ "Japanese", CELL_SYSUTIL_LANG_JAPANESE },
|
||||
{ "English (US)", CELL_SYSUTIL_LANG_ENGLISH_US },
|
||||
{ "French", CELL_SYSUTIL_LANG_FRENCH },
|
||||
{ "Spanish", CELL_SYSUTIL_LANG_SPANISH },
|
||||
{ "German", CELL_SYSUTIL_LANG_GERMAN },
|
||||
{ "Italian", CELL_SYSUTIL_LANG_ITALIAN },
|
||||
{ "Dutch", CELL_SYSUTIL_LANG_DUTCH },
|
||||
{ "Portuguese (PT)", CELL_SYSUTIL_LANG_PORTUGUESE_PT },
|
||||
{ "Russian", CELL_SYSUTIL_LANG_RUSSIAN },
|
||||
{ "Korean", CELL_SYSUTIL_LANG_KOREAN },
|
||||
{ "Chinese (Trad.)", CELL_SYSUTIL_LANG_CHINESE_T },
|
||||
{ "Chinese (Simp.)", CELL_SYSUTIL_LANG_CHINESE_S },
|
||||
{ "Finnish", CELL_SYSUTIL_LANG_FINNISH },
|
||||
{ "Swedish", CELL_SYSUTIL_LANG_SWEDISH },
|
||||
{ "Danish", CELL_SYSUTIL_LANG_DANISH },
|
||||
{ "Norwegian", CELL_SYSUTIL_LANG_NORWEGIAN },
|
||||
{ "Polish", CELL_SYSUTIL_LANG_POLISH },
|
||||
{ "English (UK)", CELL_SYSUTIL_LANG_ENGLISH_GB },
|
||||
{ "Portuguese (BR)", CELL_SYSUTIL_LANG_PORTUGUESE_BR },
|
||||
{ "Turkish", CELL_SYSUTIL_LANG_TURKISH },
|
||||
});
|
||||
format_enum(out, arg, [](CellSysutilLang value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case CELL_SYSUTIL_LANG_JAPANESE: return "Japanese";
|
||||
case CELL_SYSUTIL_LANG_ENGLISH_US: return "English (US)";
|
||||
case CELL_SYSUTIL_LANG_FRENCH: return "French";
|
||||
case CELL_SYSUTIL_LANG_SPANISH: return "Spanish";
|
||||
case CELL_SYSUTIL_LANG_GERMAN: return "German";
|
||||
case CELL_SYSUTIL_LANG_ITALIAN: return "Italian";
|
||||
case CELL_SYSUTIL_LANG_DUTCH: return "Dutch";
|
||||
case CELL_SYSUTIL_LANG_PORTUGUESE_PT: return "Portuguese (PT)";
|
||||
case CELL_SYSUTIL_LANG_RUSSIAN: return "Russian";
|
||||
case CELL_SYSUTIL_LANG_KOREAN: return "Korean";
|
||||
case CELL_SYSUTIL_LANG_CHINESE_T: return "Chinese (Trad.)";
|
||||
case CELL_SYSUTIL_LANG_CHINESE_S: return "Chinese (Simp.)";
|
||||
case CELL_SYSUTIL_LANG_FINNISH: return "Finnish";
|
||||
case CELL_SYSUTIL_LANG_SWEDISH: return "Swedish";
|
||||
case CELL_SYSUTIL_LANG_DANISH: return "Danish";
|
||||
case CELL_SYSUTIL_LANG_NORWEGIAN: return "Norwegian";
|
||||
case CELL_SYSUTIL_LANG_POLISH: return "Polish";
|
||||
case CELL_SYSUTIL_LANG_ENGLISH_GB: return "English (UK)";
|
||||
case CELL_SYSUTIL_LANG_PORTUGUESE_BR: return "Portuguese (BR)";
|
||||
case CELL_SYSUTIL_LANG_TURKISH: return "Turkish";
|
||||
}
|
||||
|
||||
return unknown;
|
||||
});
|
||||
}
|
||||
|
||||
// For test
|
||||
enum systemparam_id_name : s32 {};
|
||||
|
||||
template<>
|
||||
template <>
|
||||
void fmt_class_string<systemparam_id_name>::format(std::string& out, u64 arg)
|
||||
{
|
||||
format_enum(out, arg, [](auto value)
|
||||
@ -134,7 +142,7 @@ s32 cellSysutilGetSystemParamInt(systemparam_id_name id, vm::ptr<s32> value)
|
||||
switch(id)
|
||||
{
|
||||
case CELL_SYSUTIL_SYSTEMPARAM_ID_LANG:
|
||||
*value = g_cfg_sys_language.get();
|
||||
*value = g_cfg.sys.language;
|
||||
break;
|
||||
|
||||
case CELL_SYSUTIL_SYSTEMPARAM_ID_ENTER_BUTTON_ASSIGN:
|
||||
|
@ -38,7 +38,7 @@ enum
|
||||
CELL_SYSUTIL_SYSTEMPARAM_ID_CURRENT_USERNAME = 0x0131,
|
||||
};
|
||||
|
||||
enum
|
||||
enum CellSysutilLang : s32
|
||||
{
|
||||
CELL_SYSUTIL_LANG_JAPANESE = 0,
|
||||
CELL_SYSUTIL_LANG_ENGLISH_US = 1,
|
||||
|
@ -1,5 +1,4 @@
|
||||
#include "stdafx.h"
|
||||
#include "Utilities/Config.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
|
||||
@ -7,34 +6,35 @@
|
||||
|
||||
extern logs::channel cellSysutil;
|
||||
|
||||
cfg::map_entry<u8> g_cfg_video_out_resolution(cfg::root.video, "Resolution", "1280x720",
|
||||
const extern std::unordered_map<video_resolution, std::pair<int, int>, value_hash<video_resolution>> g_video_out_resolution_map
|
||||
{
|
||||
{ "1920x1080", CELL_VIDEO_OUT_RESOLUTION_1080 },
|
||||
{ "1280x720", CELL_VIDEO_OUT_RESOLUTION_720 },
|
||||
{ "720x480", CELL_VIDEO_OUT_RESOLUTION_480 },
|
||||
{ "720x576", CELL_VIDEO_OUT_RESOLUTION_576 },
|
||||
{ "1600x1080", CELL_VIDEO_OUT_RESOLUTION_1600x1080 },
|
||||
{ "1440x1080", CELL_VIDEO_OUT_RESOLUTION_1440x1080 },
|
||||
{ "1280x1080", CELL_VIDEO_OUT_RESOLUTION_1280x1080 },
|
||||
{ "960x1080", CELL_VIDEO_OUT_RESOLUTION_960x1080 },
|
||||
});
|
||||
{ video_resolution::_1080, { 1920, 1080 } },
|
||||
{ video_resolution::_720, { 1280, 720 } },
|
||||
{ video_resolution::_480, { 720, 480 } },
|
||||
{ video_resolution::_576, { 720, 576 } },
|
||||
{ video_resolution::_1600x1080, { 1600, 1080 } },
|
||||
{ video_resolution::_1440x1080, { 1440, 1080 } },
|
||||
{ video_resolution::_1280x1080, { 1280, 1080 } },
|
||||
{ video_resolution::_960x1080, { 960, 1080 } },
|
||||
};
|
||||
|
||||
cfg::map_entry<u8> g_cfg_video_out_aspect_ratio(cfg::root.video, "Aspect ratio", "16x9",
|
||||
const extern std::unordered_map<video_resolution, CellVideoOutResolutionId, value_hash<video_resolution>> g_video_out_resolution_id
|
||||
{
|
||||
{ "4x3", CELL_VIDEO_OUT_ASPECT_4_3 },
|
||||
{ "16x9", CELL_VIDEO_OUT_ASPECT_16_9 },
|
||||
});
|
||||
{ video_resolution::_1080, CELL_VIDEO_OUT_RESOLUTION_1080 },
|
||||
{ video_resolution::_720, CELL_VIDEO_OUT_RESOLUTION_720 },
|
||||
{ video_resolution::_480, CELL_VIDEO_OUT_RESOLUTION_480 },
|
||||
{ video_resolution::_576, CELL_VIDEO_OUT_RESOLUTION_576 },
|
||||
{ video_resolution::_1600x1080, CELL_VIDEO_OUT_RESOLUTION_1600x1080 },
|
||||
{ video_resolution::_1440x1080, CELL_VIDEO_OUT_RESOLUTION_1440x1080 },
|
||||
{ video_resolution::_1280x1080, CELL_VIDEO_OUT_RESOLUTION_1280x1080 },
|
||||
{ video_resolution::_960x1080, CELL_VIDEO_OUT_RESOLUTION_960x1080 },
|
||||
};
|
||||
|
||||
const extern std::unordered_map<u8, std::pair<int, int>> g_video_out_resolution_map
|
||||
const extern std::unordered_map<video_aspect, CellVideoOutDisplayAspect, value_hash<video_aspect>> g_video_out_aspect_id
|
||||
{
|
||||
{ CELL_VIDEO_OUT_RESOLUTION_1080, { 1920, 1080 } },
|
||||
{ CELL_VIDEO_OUT_RESOLUTION_720, { 1280, 720 } },
|
||||
{ CELL_VIDEO_OUT_RESOLUTION_480, { 720, 480 } },
|
||||
{ CELL_VIDEO_OUT_RESOLUTION_576, { 720, 576 } },
|
||||
{ CELL_VIDEO_OUT_RESOLUTION_1600x1080, { 1600, 1080 } },
|
||||
{ CELL_VIDEO_OUT_RESOLUTION_1440x1080, { 1440, 1080 } },
|
||||
{ CELL_VIDEO_OUT_RESOLUTION_1280x1080, { 1280, 1080 } },
|
||||
{ CELL_VIDEO_OUT_RESOLUTION_960x1080, { 960, 1080 } },
|
||||
{ video_aspect::_auto, CELL_VIDEO_OUT_ASPECT_AUTO },
|
||||
{ video_aspect::_16_9, CELL_VIDEO_OUT_ASPECT_16_9 },
|
||||
{ video_aspect::_4_3, CELL_VIDEO_OUT_ASPECT_4_3 },
|
||||
};
|
||||
|
||||
template<>
|
||||
@ -70,10 +70,10 @@ error_code cellVideoOutGetState(u32 videoOut, u32 deviceIndex, vm::ptr<CellVideo
|
||||
case CELL_VIDEO_OUT_PRIMARY:
|
||||
state->state = CELL_VIDEO_OUT_OUTPUT_STATE_ENABLED;
|
||||
state->colorSpace = CELL_VIDEO_OUT_COLOR_SPACE_RGB;
|
||||
state->displayMode.resolutionId = g_cfg_video_out_resolution.get(); // TODO
|
||||
state->displayMode.resolutionId = g_video_out_resolution_id.at(g_cfg.video.resolution); // TODO
|
||||
state->displayMode.scanMode = CELL_VIDEO_OUT_SCAN_MODE_PROGRESSIVE;
|
||||
state->displayMode.conversion = CELL_VIDEO_OUT_DISPLAY_CONVERSION_NONE;
|
||||
state->displayMode.aspect = g_cfg_video_out_aspect_ratio.get(); // TODO
|
||||
state->displayMode.aspect = g_video_out_aspect_id.at(g_cfg.video.aspect_ratio); // TODO
|
||||
state->displayMode.refreshRates = CELL_VIDEO_OUT_REFRESH_RATE_59_94HZ;
|
||||
return CELL_OK;
|
||||
|
||||
@ -133,11 +133,11 @@ error_code cellVideoOutConfigure(u32 videoOut, vm::ptr<CellVideoOutConfiguration
|
||||
switch (videoOut)
|
||||
{
|
||||
case CELL_VIDEO_OUT_PRIMARY:
|
||||
if (config->resolutionId != g_cfg_video_out_resolution.get()
|
||||
if (config->resolutionId != g_video_out_resolution_id.at(g_cfg.video.resolution)
|
||||
|| (config->format != CELL_VIDEO_OUT_BUFFER_COLOR_FORMAT_X8R8G8B8 &&
|
||||
config->format != CELL_VIDEO_OUT_BUFFER_COLOR_FORMAT_X8B8G8R8 &&
|
||||
config->format != CELL_VIDEO_OUT_BUFFER_COLOR_FORMAT_R16G16B16X16_FLOAT)
|
||||
|| (config->aspect != CELL_VIDEO_OUT_ASPECT_AUTO && config->aspect != g_cfg_video_out_aspect_ratio.get()))
|
||||
|| (config->aspect != CELL_VIDEO_OUT_ASPECT_AUTO && config->aspect != g_video_out_aspect_id.at(g_cfg.video.aspect_ratio)))
|
||||
{
|
||||
return CELL_VIDEO_OUT_ERROR_ILLEGAL_CONFIGURATION;
|
||||
}
|
||||
@ -160,10 +160,10 @@ error_code cellVideoOutGetConfiguration(u32 videoOut, vm::ptr<CellVideoOutConfig
|
||||
switch (videoOut)
|
||||
{
|
||||
case CELL_VIDEO_OUT_PRIMARY:
|
||||
config->resolutionId = g_cfg_video_out_resolution.get();
|
||||
config->resolutionId = g_video_out_resolution_id.at(g_cfg.video.resolution);
|
||||
config->format = CELL_VIDEO_OUT_BUFFER_COLOR_FORMAT_X8R8G8B8;
|
||||
config->aspect = g_cfg_video_out_aspect_ratio.get();
|
||||
config->pitch = 4 * g_video_out_resolution_map.at(g_cfg_video_out_resolution.get()).first;
|
||||
config->aspect = g_video_out_aspect_id.at(g_cfg.video.aspect_ratio);
|
||||
config->pitch = 4 * g_video_out_resolution_map.at(g_cfg.video.resolution).first;
|
||||
|
||||
return CELL_OK;
|
||||
|
||||
@ -197,10 +197,10 @@ error_code cellVideoOutGetDeviceInfo(u32 videoOut, u32 deviceIndex, vm::ptr<Cell
|
||||
info->colorInfo.whiteX = 0xFFFF;
|
||||
info->colorInfo.whiteY = 0xFFFF;
|
||||
info->colorInfo.gamma = 100;
|
||||
info->availableModes[0].aspect = g_cfg_video_out_aspect_ratio.get();
|
||||
info->availableModes[0].aspect = g_video_out_aspect_id.at(g_cfg.video.aspect_ratio);
|
||||
info->availableModes[0].conversion = CELL_VIDEO_OUT_DISPLAY_CONVERSION_NONE;
|
||||
info->availableModes[0].refreshRates = CELL_VIDEO_OUT_REFRESH_RATE_60HZ;
|
||||
info->availableModes[0].resolutionId = g_cfg_video_out_resolution.get();
|
||||
info->availableModes[0].resolutionId = g_video_out_resolution_id.at(g_cfg.video.resolution);
|
||||
info->availableModes[0].scanMode = CELL_VIDEO_OUT_SCAN_MODE_PROGRESSIVE;
|
||||
return CELL_OK;
|
||||
}
|
||||
@ -225,8 +225,8 @@ error_code cellVideoOutGetResolutionAvailability(u32 videoOut, u32 resolutionId,
|
||||
switch (videoOut)
|
||||
{
|
||||
case CELL_VIDEO_OUT_PRIMARY: return not_an_error(
|
||||
resolutionId == g_cfg_video_out_resolution.get()
|
||||
&& (aspect == CELL_VIDEO_OUT_ASPECT_AUTO || aspect == g_cfg_video_out_aspect_ratio.get())
|
||||
resolutionId == g_video_out_resolution_id.at(g_cfg.video.resolution)
|
||||
&& (aspect == CELL_VIDEO_OUT_ASPECT_AUTO || aspect == g_video_out_aspect_id.at(g_cfg.video.aspect_ratio))
|
||||
);
|
||||
case CELL_VIDEO_OUT_SECONDARY: return not_an_error(0);
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
#include "stdafx.h"
|
||||
#include "Utilities/Config.h"
|
||||
#include "Utilities/VirtualMemory.h"
|
||||
#include "Crypto/sha1.h"
|
||||
#include "Crypto/unself.h"
|
||||
@ -19,28 +18,6 @@
|
||||
|
||||
namespace vm { using namespace ps3; }
|
||||
|
||||
enum class lib_loader_mode
|
||||
{
|
||||
automatic,
|
||||
manual,
|
||||
both,
|
||||
liblv2only
|
||||
};
|
||||
|
||||
cfg::map_entry<lib_loader_mode> g_cfg_lib_loader(cfg::root.core, "Lib Loader", 3,
|
||||
{
|
||||
{ "Automatically load required libraries", lib_loader_mode::automatic },
|
||||
{ "Manually load selected libraries", lib_loader_mode::manual },
|
||||
{ "Load automatic and manual selection", lib_loader_mode::both },
|
||||
{ "Load liblv2.sprx only", lib_loader_mode::liblv2only },
|
||||
});
|
||||
|
||||
cfg::bool_entry g_cfg_hook_ppu_funcs(cfg::root.core, "Hook static functions");
|
||||
|
||||
cfg::set_entry g_cfg_load_libs(cfg::root.core, "Load libraries");
|
||||
|
||||
extern cfg::map_entry<ppu_decoder_type> g_cfg_ppu_decoder;
|
||||
|
||||
extern void ppu_initialize_syscalls();
|
||||
extern std::string ppu_get_function_name(const std::string& module, u32 fnid);
|
||||
extern std::string ppu_get_variable_name(const std::string& module, u32 vnid);
|
||||
@ -56,6 +33,23 @@ extern u32 g_ps3_sdk_version;
|
||||
// HLE function name cache
|
||||
std::vector<std::string> g_ppu_function_names;
|
||||
|
||||
template <>
|
||||
void fmt_class_string<lib_loading_type>::format(std::string& out, u64 arg)
|
||||
{
|
||||
format_enum(out, arg, [](lib_loading_type value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case lib_loading_type::automatic: return "Automatically load required libraries";
|
||||
case lib_loading_type::manual: return "Manually load selected libraries";
|
||||
case lib_loading_type::both: return "Load automatic and manual selection";
|
||||
case lib_loading_type::liblv2only: return "Load liblv2.sprx only";
|
||||
}
|
||||
|
||||
return unknown;
|
||||
});
|
||||
}
|
||||
|
||||
extern u32 ppu_generate_id(const char* name)
|
||||
{
|
||||
// Symbol name suffix
|
||||
@ -627,7 +621,7 @@ static void ppu_load_imports(const std::shared_ptr<ppu_linkage_info>& link, u32
|
||||
|
||||
std::shared_ptr<lv2_prx> ppu_load_prx(const ppu_prx_object& elf, const std::string& name)
|
||||
{
|
||||
if (g_cfg_ppu_decoder.get() == ppu_decoder_type::llvm && name == "libfiber.sprx")
|
||||
if (g_cfg.core.ppu_decoder == ppu_decoder_type::llvm && name == "libfiber.sprx")
|
||||
{
|
||||
LOG_FATAL(PPU, "libfiber.sprx is not compatible with PPU LLVM Recompiler. Use PPU Interpreter.");
|
||||
Emu.Pause();
|
||||
@ -833,7 +827,7 @@ std::shared_ptr<lv2_prx> ppu_load_prx(const ppu_prx_object& elf, const std::stri
|
||||
|
||||
void ppu_load_exec(const ppu_exec_object& elf)
|
||||
{
|
||||
if (g_cfg_hook_ppu_funcs)
|
||||
if (g_cfg.core.hook_functions)
|
||||
{
|
||||
LOG_TODO(LOADER, "'Hook static functions' option deactivated");
|
||||
}
|
||||
@ -1014,17 +1008,18 @@ void ppu_load_exec(const ppu_exec_object& elf)
|
||||
// Get LLE module list
|
||||
std::set<std::string> load_libs;
|
||||
|
||||
if (g_cfg_lib_loader.get() == lib_loader_mode::manual || g_cfg_lib_loader.get() == lib_loader_mode::both)
|
||||
if (g_cfg.core.lib_loading == lib_loading_type::manual || g_cfg.core.lib_loading == lib_loading_type::both)
|
||||
{
|
||||
// Load required set of modules
|
||||
load_libs = g_cfg_load_libs.get_set();
|
||||
load_libs = g_cfg.core.load_libraries.get_set();
|
||||
}
|
||||
else if (g_cfg_lib_loader.get() == lib_loader_mode::liblv2only)
|
||||
else if (g_cfg.core.lib_loading == lib_loading_type::liblv2only)
|
||||
{
|
||||
// Load only liblv2.sprx
|
||||
load_libs.emplace("liblv2.sprx");
|
||||
}
|
||||
if (g_cfg_lib_loader.get() == lib_loader_mode::automatic || g_cfg_lib_loader.get() == lib_loader_mode::both)
|
||||
|
||||
if (g_cfg.core.lib_loading == lib_loading_type::automatic || g_cfg.core.lib_loading == lib_loading_type::both)
|
||||
{
|
||||
// Load recommended set of modules: Module name -> SPRX
|
||||
std::unordered_multimap<std::string, std::string> sprx_map
|
||||
@ -1228,7 +1223,7 @@ void ppu_load_exec(const ppu_exec_object& elf)
|
||||
// TODO: adjust for liblv2 loading option
|
||||
u32 entry = static_cast<u32>(elf.header.e_entry);
|
||||
|
||||
if (g_cfg_lib_loader.get() != lib_loader_mode::liblv2only)
|
||||
if (g_cfg.core.lib_loading != lib_loading_type::liblv2only)
|
||||
{
|
||||
// Set TLS args, call sys_initialize_tls
|
||||
ppu->cmd_list
|
||||
|
@ -1,5 +1,4 @@
|
||||
#include "stdafx.h"
|
||||
#include "Utilities/Config.h"
|
||||
#include "Utilities/VirtualMemory.h"
|
||||
#include "Crypto/sha1.h"
|
||||
#include "Emu/Memory/Memory.h"
|
||||
@ -82,18 +81,21 @@ void fmt_class_string<join_status>::format(std::string& out, u64 arg)
|
||||
});
|
||||
}
|
||||
|
||||
cfg::map_entry<ppu_decoder_type> g_cfg_ppu_decoder(cfg::root.core, "PPU Decoder", 1,
|
||||
template <>
|
||||
void fmt_class_string<ppu_decoder_type>::format(std::string& out, u64 arg)
|
||||
{
|
||||
{ "Interpreter (precise)", ppu_decoder_type::precise },
|
||||
{ "Interpreter (fast)", ppu_decoder_type::fast },
|
||||
{ "Recompiler (LLVM)", ppu_decoder_type::llvm },
|
||||
});
|
||||
format_enum(out, arg, [](ppu_decoder_type type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case ppu_decoder_type::precise: return "Interpreter (precise)";
|
||||
case ppu_decoder_type::fast: return "Interpreter (fast)";
|
||||
case ppu_decoder_type::llvm: return "Recompiler (LLVM)";
|
||||
}
|
||||
|
||||
cfg::bool_entry g_cfg_ppu_debug(cfg::root.core, "PPU Debug");
|
||||
|
||||
cfg::bool_entry g_cfg_llvm_logs(cfg::root.core, "Save LLVM logs");
|
||||
|
||||
cfg::string_entry g_cfg_llvm_cpu(cfg::root.core, "Use LLVM CPU");
|
||||
return unknown;
|
||||
});
|
||||
}
|
||||
|
||||
const ppu_decoder<ppu_interpreter_precise> s_ppu_interpreter_precise;
|
||||
const ppu_decoder<ppu_interpreter_fast> s_ppu_interpreter_fast;
|
||||
@ -113,8 +115,8 @@ static u32 ppu_cache(u32 addr)
|
||||
{
|
||||
// Select opcode table
|
||||
const auto& table = *(
|
||||
g_cfg_ppu_decoder.get() == ppu_decoder_type::precise ? &s_ppu_interpreter_precise.get_table() :
|
||||
g_cfg_ppu_decoder.get() == ppu_decoder_type::fast ? &s_ppu_interpreter_fast.get_table() :
|
||||
g_cfg.core.ppu_decoder == ppu_decoder_type::precise ? &s_ppu_interpreter_precise.get_table() :
|
||||
g_cfg.core.ppu_decoder == ppu_decoder_type::fast ? &s_ppu_interpreter_fast.get_table() :
|
||||
(fmt::throw_exception<std::logic_error>("Invalid PPU decoder"), nullptr));
|
||||
|
||||
return ::narrow<u32>(reinterpret_cast<std::uintptr_t>(table[ppu_decode(vm::read32(addr))]));
|
||||
@ -122,14 +124,14 @@ static u32 ppu_cache(u32 addr)
|
||||
|
||||
static bool ppu_fallback(ppu_thread& ppu, ppu_opcode_t op)
|
||||
{
|
||||
if (g_cfg_ppu_decoder.get() == ppu_decoder_type::llvm)
|
||||
if (g_cfg.core.ppu_decoder == ppu_decoder_type::llvm)
|
||||
{
|
||||
fmt::throw_exception("Unregistered PPU function");
|
||||
}
|
||||
|
||||
ppu_ref(ppu.cia) = ppu_cache(ppu.cia);
|
||||
|
||||
if (g_cfg_ppu_debug)
|
||||
if (g_cfg.core.ppu_debug)
|
||||
{
|
||||
LOG_ERROR(PPU, "Unregistered instruction: 0x%08x", op.opcode);
|
||||
}
|
||||
@ -196,7 +198,7 @@ extern void ppu_register_function_at(u32 addr, u32 size, ppu_function_t ptr)
|
||||
|
||||
if (!size)
|
||||
{
|
||||
if (g_cfg_ppu_debug)
|
||||
if (g_cfg.core.ppu_debug)
|
||||
{
|
||||
LOG_ERROR(PPU, "ppu_register_function_at(0x%x): empty range", addr);
|
||||
}
|
||||
@ -204,7 +206,7 @@ extern void ppu_register_function_at(u32 addr, u32 size, ppu_function_t ptr)
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_cfg_ppu_decoder.get() == ppu_decoder_type::llvm)
|
||||
if (g_cfg.core.ppu_decoder == ppu_decoder_type::llvm)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -249,7 +251,7 @@ static bool ppu_break(ppu_thread& ppu, ppu_opcode_t op)
|
||||
// Set or remove breakpoint
|
||||
extern void ppu_breakpoint(u32 addr)
|
||||
{
|
||||
if (g_cfg_ppu_decoder.get() == ppu_decoder_type::llvm)
|
||||
if (g_cfg.core.ppu_decoder == ppu_decoder_type::llvm)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -292,7 +294,7 @@ void ppu_thread::on_init(const std::shared_ptr<void>& _this)
|
||||
//sets breakpoint, does nothing if there is a breakpoint there already
|
||||
extern void ppu_set_breakpoint(u32 addr)
|
||||
{
|
||||
if (g_cfg_ppu_decoder.get() == ppu_decoder_type::llvm)
|
||||
if (g_cfg.core.ppu_decoder == ppu_decoder_type::llvm)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -308,7 +310,7 @@ extern void ppu_set_breakpoint(u32 addr)
|
||||
//removes breakpoint, does nothing if there is no breakpoint at location
|
||||
extern void ppu_remove_breakpoint(u32 addr)
|
||||
{
|
||||
if (g_cfg_ppu_decoder.get() == ppu_decoder_type::llvm)
|
||||
if (g_cfg.core.ppu_decoder == ppu_decoder_type::llvm)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -369,7 +371,7 @@ std::string ppu_thread::dump() const
|
||||
fmt::append(ret, "XER = [CA=%u | OV=%u | SO=%u | CNT=%u]\n", xer.ca, xer.ov, xer.so, xer.cnt);
|
||||
fmt::append(ret, "VSCR = [SAT=%u | NJ=%u]\n", sat, nj);
|
||||
fmt::append(ret, "FPSCR = [FL=%u | FG=%u | FE=%u | FU=%u]\n", fpscr.fl, fpscr.fg, fpscr.fe, fpscr.fu);
|
||||
fmt::append(ret, "\nCall stack:\n=========\n0x%08x (0x0) called\n", g_cfg_ppu_decoder.get() == ppu_decoder_type::llvm ? 0 : cia);
|
||||
fmt::append(ret, "\nCall stack:\n=========\n0x%08x (0x0) called\n", g_cfg.core.ppu_decoder == ppu_decoder_type::llvm ? 0 : cia);
|
||||
|
||||
// Determine stack range
|
||||
u32 stack_ptr = static_cast<u32>(gpr[1]);
|
||||
@ -470,7 +472,7 @@ void ppu_thread::cpu_task()
|
||||
|
||||
void ppu_thread::exec_task()
|
||||
{
|
||||
if (g_cfg_ppu_decoder.get() == ppu_decoder_type::llvm)
|
||||
if (g_cfg.core.ppu_decoder == ppu_decoder_type::llvm)
|
||||
{
|
||||
reinterpret_cast<ppu_function_t>(static_cast<std::uintptr_t>(ppu_ref(cia)))(*this);
|
||||
return;
|
||||
@ -912,7 +914,7 @@ extern void ppu_initialize()
|
||||
|
||||
extern void ppu_initialize(const ppu_module& info)
|
||||
{
|
||||
if (g_cfg_ppu_decoder.get() != ppu_decoder_type::llvm)
|
||||
if (g_cfg.core.ppu_decoder != ppu_decoder_type::llvm)
|
||||
{
|
||||
// Temporarily
|
||||
s_ppu_toc = fxm::get_always<std::unordered_map<u32, u32>>().get();
|
||||
@ -924,7 +926,7 @@ extern void ppu_initialize(const ppu_module& info)
|
||||
ppu_register_function_at(block.first, block.second, nullptr);
|
||||
}
|
||||
|
||||
if (g_cfg_ppu_debug && func.size && func.toc != -1)
|
||||
if (g_cfg.core.ppu_debug && func.size && func.toc != -1)
|
||||
{
|
||||
s_ppu_toc->emplace(func.addr, func.toc);
|
||||
ppu_ref(func.addr) = ::narrow<u32>(reinterpret_cast<std::uintptr_t>(&ppu_check_toc));
|
||||
@ -1009,7 +1011,7 @@ extern void ppu_initialize(const ppu_module& info)
|
||||
}
|
||||
}
|
||||
|
||||
const auto jit = fxm::make<jit_compiler>(std::move(link_table), g_cfg_llvm_cpu.get());
|
||||
const auto jit = fxm::make<jit_compiler>(std::move(link_table), g_cfg.core.llvm_cpu);
|
||||
|
||||
LOG_SUCCESS(PPU, "LLVM: JIT initialized (%s)", jit->cpu());
|
||||
}
|
||||
@ -1210,7 +1212,7 @@ extern void ppu_initialize(const ppu_module& info)
|
||||
std::string result;
|
||||
raw_string_ostream out(result);
|
||||
|
||||
if (g_cfg_llvm_logs)
|
||||
if (g_cfg.core.llvm_logs)
|
||||
{
|
||||
out << *module; // print IR
|
||||
fs::file(Emu.GetCachePath() + obj_name + ".log", fs::rewrite).write(out.str());
|
||||
|
@ -18,13 +18,6 @@ enum class ppu_cmd : u32
|
||||
sleep,
|
||||
};
|
||||
|
||||
enum class ppu_decoder_type
|
||||
{
|
||||
precise,
|
||||
fast,
|
||||
llvm,
|
||||
};
|
||||
|
||||
class ppu_thread : public cpu_thread
|
||||
{
|
||||
public:
|
||||
|
@ -1,5 +1,4 @@
|
||||
#include "stdafx.h"
|
||||
#include "Utilities/Config.h"
|
||||
#include "Emu/Memory/Memory.h"
|
||||
#include "Emu/System.h"
|
||||
|
||||
@ -24,14 +23,12 @@
|
||||
const spu_decoder<spu_interpreter_fast> s_spu_interpreter; // TODO: remove
|
||||
const spu_decoder<spu_recompiler> s_spu_decoder;
|
||||
|
||||
extern cfg::bool_entry g_cfg_spu_debug;
|
||||
|
||||
spu_recompiler::spu_recompiler()
|
||||
: m_jit(std::make_shared<asmjit::JitRuntime>())
|
||||
{
|
||||
LOG_SUCCESS(SPU, "SPU Recompiler (ASMJIT) created...");
|
||||
|
||||
if (g_cfg_spu_debug)
|
||||
if (g_cfg.core.spu_debug)
|
||||
{
|
||||
fs::file log(Emu.GetCachePath() + "SPUJIT.log", fs::rewrite);
|
||||
log.write(fmt::format("SPU JIT initialization...\n\nTitle: %s\nTitle ID: %s\n\n", Emu.GetTitle().c_str(), Emu.GetTitleID().c_str()));
|
||||
@ -63,7 +60,7 @@ void spu_recompiler::compile(spu_function_t& f)
|
||||
|
||||
std::string log;
|
||||
|
||||
if (g_cfg_spu_debug)
|
||||
if (g_cfg.core.spu_debug)
|
||||
{
|
||||
fmt::append(log, "========== SPU FUNCTION 0x%05x - 0x%05x ==========\n\n", f.addr, f.addr + f.size);
|
||||
}
|
||||
@ -77,7 +74,7 @@ void spu_recompiler::compile(spu_function_t& f)
|
||||
X86Compiler compiler(&code);
|
||||
this->c = &compiler;
|
||||
|
||||
if (g_cfg_spu_debug)
|
||||
if (g_cfg.core.spu_debug)
|
||||
{
|
||||
// Set logger
|
||||
codeHolder->setLogger(&logger);
|
||||
@ -163,7 +160,7 @@ void spu_recompiler::compile(spu_function_t& f)
|
||||
}
|
||||
}
|
||||
|
||||
if (g_cfg_spu_debug)
|
||||
if (g_cfg.core.spu_debug)
|
||||
{
|
||||
// Disasm
|
||||
dis_asm.dump_pc = m_pos;
|
||||
@ -190,7 +187,7 @@ void spu_recompiler::compile(spu_function_t& f)
|
||||
m_pos += 4;
|
||||
}
|
||||
|
||||
if (g_cfg_spu_debug)
|
||||
if (g_cfg.core.spu_debug)
|
||||
{
|
||||
log += '\n';
|
||||
}
|
||||
@ -240,7 +237,7 @@ void spu_recompiler::compile(spu_function_t& f)
|
||||
|
||||
f.compiled = asmjit::Internal::ptr_cast<decltype(f.compiled)>(fn);
|
||||
|
||||
if (g_cfg_spu_debug)
|
||||
if (g_cfg.core.spu_debug)
|
||||
{
|
||||
// Add ASMJIT logs
|
||||
log += logger.getString();
|
||||
|
@ -1,5 +1,4 @@
|
||||
#include "stdafx.h"
|
||||
#include "Utilities/Config.h"
|
||||
#include "Utilities/lockless.h"
|
||||
#include "Emu/Memory/Memory.h"
|
||||
#include "Emu/System.h"
|
||||
@ -34,31 +33,28 @@ extern u64 get_timebased_time();
|
||||
|
||||
extern thread_local u64 g_tls_fault_spu;
|
||||
|
||||
enum class spu_decoder_type
|
||||
{
|
||||
precise,
|
||||
fast,
|
||||
asmjit,
|
||||
llvm,
|
||||
};
|
||||
|
||||
cfg::map_entry<spu_decoder_type> g_cfg_spu_decoder(cfg::root.core, "SPU Decoder", 2,
|
||||
{
|
||||
{ "Interpreter (precise)", spu_decoder_type::precise },
|
||||
{ "Interpreter (fast)", spu_decoder_type::fast },
|
||||
{ "Recompiler (ASMJIT)", spu_decoder_type::asmjit },
|
||||
{ "Recompiler (LLVM)", spu_decoder_type::llvm },
|
||||
});
|
||||
|
||||
cfg::bool_entry g_cfg_spu_debug(cfg::root.core, "SPU Debug");
|
||||
cfg::bool_entry g_cfg_core_bind_spu_cores(cfg::root.core, "Bind SPU threads to secondary cores");
|
||||
cfg::bool_entry g_cfg_core_lower_spu_priority(cfg::root.core, "Lower SPU thread priority");
|
||||
|
||||
const spu_decoder<spu_interpreter_precise> s_spu_interpreter_precise;
|
||||
const spu_decoder<spu_interpreter_fast> s_spu_interpreter_fast;
|
||||
|
||||
std::atomic<u64> g_num_spu_threads = { 0ull };
|
||||
|
||||
template <>
|
||||
void fmt_class_string<spu_decoder_type>::format(std::string& out, u64 arg)
|
||||
{
|
||||
format_enum(out, arg, [](spu_decoder_type type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case spu_decoder_type::precise: return "Interpreter (precise)";
|
||||
case spu_decoder_type::fast: return "Interpreter (fast)";
|
||||
case spu_decoder_type::asmjit: return "Recompiler (ASMJIT)";
|
||||
case spu_decoder_type::llvm: return "Recompiler (LLVM)";
|
||||
}
|
||||
|
||||
return unknown;
|
||||
});
|
||||
}
|
||||
|
||||
void spu_int_ctrl_t::set(u64 ints)
|
||||
{
|
||||
// leave only enabled interrupts
|
||||
@ -142,7 +138,7 @@ spu_imm_table_t::spu_imm_table_t()
|
||||
|
||||
void SPUThread::on_spawn()
|
||||
{
|
||||
if (g_cfg_core_bind_spu_cores)
|
||||
if (g_cfg.core.bind_spu_cores)
|
||||
{
|
||||
//Get next secondary core number
|
||||
auto core_count = std::thread::hardware_concurrency();
|
||||
@ -155,7 +151,7 @@ void SPUThread::on_spawn()
|
||||
}
|
||||
}
|
||||
|
||||
if (g_cfg_core_lower_spu_priority)
|
||||
if (g_cfg.core.lower_spu_priority)
|
||||
{
|
||||
set_native_priority(-1);
|
||||
}
|
||||
@ -238,7 +234,7 @@ void SPUThread::cpu_task()
|
||||
{
|
||||
std::fesetround(FE_TOWARDZERO);
|
||||
|
||||
if (g_cfg_spu_decoder.get() == spu_decoder_type::asmjit)
|
||||
if (g_cfg.core.spu_decoder == spu_decoder_type::asmjit)
|
||||
{
|
||||
if (!spu_db) spu_db = fxm::get_always<SPUDatabase>();
|
||||
return spu_recompiler_base::enter(*this);
|
||||
@ -253,8 +249,8 @@ void SPUThread::cpu_task()
|
||||
|
||||
// Select opcode table
|
||||
const auto& table = *(
|
||||
g_cfg_spu_decoder.get() == spu_decoder_type::precise ? &s_spu_interpreter_precise.get_table() :
|
||||
g_cfg_spu_decoder.get() == spu_decoder_type::fast ? &s_spu_interpreter_fast.get_table() :
|
||||
g_cfg.core.spu_decoder == spu_decoder_type::precise ? &s_spu_interpreter_precise.get_table() :
|
||||
g_cfg.core.spu_decoder == spu_decoder_type::fast ? &s_spu_interpreter_fast.get_table() :
|
||||
(fmt::throw_exception<std::logic_error>("Invalid SPU decoder"), nullptr));
|
||||
|
||||
// LS base address
|
||||
|
@ -1,5 +1,4 @@
|
||||
#include "stdafx.h"
|
||||
#include "Utilities/Config.h"
|
||||
#include "Emu/System.h"
|
||||
|
||||
#include "Emu/Cell/PPUFunction.h"
|
||||
@ -1005,9 +1004,6 @@ DECLARE(lv2_obj::g_ppu);
|
||||
DECLARE(lv2_obj::g_pending);
|
||||
DECLARE(lv2_obj::g_waiting);
|
||||
|
||||
// Amount of PPU threads running simultaneously (must be 2)
|
||||
cfg::int_entry<1, 16> g_cfg_ppu_threads(cfg::root.core, "PPU Threads", 2);
|
||||
|
||||
void lv2_obj::sleep_timeout(named_thread& thread, u64 timeout)
|
||||
{
|
||||
semaphore_lock lock(g_mutex);
|
||||
@ -1132,7 +1128,7 @@ void lv2_obj::awake(cpu_thread& cpu, u32 prio)
|
||||
}
|
||||
|
||||
// Suspend threads if necessary
|
||||
for (std::size_t i = g_cfg_ppu_threads; i < g_ppu.size(); i++)
|
||||
for (std::size_t i = g_cfg.core.ppu_threads; i < g_ppu.size(); i++)
|
||||
{
|
||||
const auto target = g_ppu[i];
|
||||
|
||||
@ -1158,7 +1154,7 @@ void lv2_obj::schedule_all()
|
||||
if (g_pending.empty())
|
||||
{
|
||||
// Wake up threads
|
||||
for (std::size_t i = 0, x = std::min<std::size_t>(g_cfg_ppu_threads, g_ppu.size()); i < x; i++)
|
||||
for (std::size_t i = 0, x = std::min<std::size_t>(g_cfg.core.ppu_threads, g_ppu.size()); i < x; i++)
|
||||
{
|
||||
const auto target = g_ppu[i];
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
#include "stdafx.h"
|
||||
#include "Utilities/Config.h"
|
||||
#include "Loader/ELF.h"
|
||||
#include "Emu/Memory/Memory.h"
|
||||
#include "Emu/System.h"
|
||||
|
@ -1,8 +1,8 @@
|
||||
#ifdef _MSC_VER
|
||||
#include "stdafx.h"
|
||||
#include "stdafx_d3d12.h"
|
||||
#include "Utilities/Config.h"
|
||||
#include "D3D12GSRender.h"
|
||||
#include "Emu/System.h"
|
||||
#include <wrl/client.h>
|
||||
#include <dxgi1_4.h>
|
||||
#include <thread>
|
||||
@ -15,14 +15,6 @@
|
||||
#include "D3D12Formats.h"
|
||||
#include "../rsx_methods.h"
|
||||
|
||||
extern cfg::bool_entry g_cfg_rsx_vsync;
|
||||
extern cfg::bool_entry g_cfg_rsx_debug_output;
|
||||
extern cfg::bool_entry g_cfg_rsx_overlay;
|
||||
|
||||
static cfg::node s_cfg_d3d12(cfg::root.video, "D3D12");
|
||||
|
||||
cfg::string_entry g_cfg_d3d12_adapter(s_cfg_d3d12, "Adapter");
|
||||
|
||||
PFN_D3D12_CREATE_DEVICE wrapD3D12CreateDevice;
|
||||
PFN_D3D12_GET_DEBUG_INTERFACE wrapD3D12GetDebugInterface;
|
||||
PFN_D3D12_SERIALIZE_ROOT_SIGNATURE wrapD3D12SerializeRootSignature;
|
||||
@ -141,11 +133,11 @@ namespace
|
||||
}
|
||||
|
||||
D3D12GSRender::D3D12GSRender()
|
||||
: GSRender(frame_type::DX12)
|
||||
: GSRender()
|
||||
, m_d3d12_lib()
|
||||
, m_current_pso({})
|
||||
{
|
||||
if (g_cfg_rsx_debug_output)
|
||||
if (g_cfg.video.debug_output)
|
||||
{
|
||||
Microsoft::WRL::ComPtr<ID3D12Debug> debugInterface;
|
||||
wrapD3D12GetDebugInterface(IID_PPV_ARGS(&debugInterface));
|
||||
@ -157,7 +149,7 @@ D3D12GSRender::D3D12GSRender()
|
||||
|
||||
// Create adapter
|
||||
ComPtr<IDXGIAdapter> adapter;
|
||||
const std::wstring& adapter_name = std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>>().from_bytes(g_cfg_d3d12_adapter);
|
||||
const std::wstring adapter_name = std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>>().from_bytes(g_cfg.video.d3d12.adapter);
|
||||
|
||||
for (UINT id = 0; dxgi_factory->EnumAdapters(id, adapter.ReleaseAndGetAddressOf()) != DXGI_ERROR_NOT_FOUND; id++)
|
||||
{
|
||||
@ -179,7 +171,7 @@ D3D12GSRender::D3D12GSRender()
|
||||
|
||||
if (FAILED(wrapD3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&m_device))))
|
||||
{
|
||||
LOG_ERROR(RSX, "Failed to initialize D3D device on adapter '%s', falling back to first available GPU", g_cfg_d3d12_adapter.to_string().c_str());
|
||||
LOG_ERROR(RSX, "Failed to initialize D3D device on adapter '%s', falling back to first available GPU", g_cfg.video.d3d12.adapter.get());
|
||||
|
||||
//Try to create a device on the first available device
|
||||
if (FAILED(wrapD3D12CreateDevice(NULL, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&m_device))))
|
||||
@ -267,7 +259,7 @@ D3D12GSRender::D3D12GSRender()
|
||||
)
|
||||
);
|
||||
|
||||
if (g_cfg_rsx_overlay)
|
||||
if (g_cfg.video.overlay)
|
||||
init_d2d_structures();
|
||||
}
|
||||
|
||||
@ -381,7 +373,7 @@ void D3D12GSRender::end()
|
||||
.Offset((INT)currentDescriptorIndex + vertex_buffer_count, m_descriptor_stride_srv_cbv_uav)
|
||||
);
|
||||
|
||||
if (m_transform_constants_dirty && !g_cfg_rsx_debug_output)
|
||||
if (m_transform_constants_dirty && !g_cfg.video.debug_output)
|
||||
{
|
||||
m_current_transform_constants_buffer_descriptor_id = (u32)currentDescriptorIndex + 1 + vertex_buffer_count;
|
||||
upload_and_bind_vertex_shader_constants(currentDescriptorIndex + 1 + vertex_buffer_count);
|
||||
@ -478,7 +470,7 @@ void D3D12GSRender::end()
|
||||
m_timers.draw_calls_duration += std::chrono::duration_cast<std::chrono::microseconds>(end_duration - start_duration).count();
|
||||
m_timers.draw_calls_count++;
|
||||
|
||||
if (g_cfg_rsx_debug_output)
|
||||
if (g_cfg.video.debug_output)
|
||||
{
|
||||
CHECK_HRESULT(get_current_resource_storage().command_list->Close());
|
||||
m_command_queue->ExecuteCommandLists(1, (ID3D12CommandList**)get_current_resource_storage().command_list.GetAddressOf());
|
||||
@ -646,21 +638,21 @@ void D3D12GSRender::flip(int buffer)
|
||||
if (resource_to_flip)
|
||||
get_current_resource_storage().command_list->DrawInstanced(4, 1, 0, 0);
|
||||
|
||||
if (!g_cfg_rsx_overlay)
|
||||
if (!g_cfg.video.overlay)
|
||||
get_current_resource_storage().command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_backbuffer[m_swap_chain->GetCurrentBackBufferIndex()].Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT));
|
||||
if (is_flip_surface_in_global_memory(rsx::method_registers.surface_color_target()) && resource_to_flip != nullptr)
|
||||
get_current_resource_storage().command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(resource_to_flip, D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_RENDER_TARGET));
|
||||
CHECK_HRESULT(get_current_resource_storage().command_list->Close());
|
||||
m_command_queue->ExecuteCommandLists(1, (ID3D12CommandList**)get_current_resource_storage().command_list.GetAddressOf());
|
||||
|
||||
if (g_cfg_rsx_overlay)
|
||||
if (g_cfg.video.overlay)
|
||||
render_overlay();
|
||||
|
||||
reset_timer();
|
||||
|
||||
std::chrono::time_point<steady_clock> flip_start = steady_clock::now();
|
||||
|
||||
CHECK_HRESULT(m_swap_chain->Present(g_cfg_rsx_vsync ? 1 : 0, 0));
|
||||
CHECK_HRESULT(m_swap_chain->Present(g_cfg.video.vsync ? 1 : 0, 0));
|
||||
// Add an event signaling queue completion
|
||||
|
||||
resource_storage &storage = get_non_current_resource_storage();
|
||||
|
@ -1,7 +1,6 @@
|
||||
#ifdef _MSC_VER
|
||||
#include "stdafx.h"
|
||||
#include "stdafx_d3d12.h"
|
||||
#include "Utilities/Config.h"
|
||||
#include "D3D12PipelineState.h"
|
||||
#include "D3D12GSRender.h"
|
||||
#include "D3D12Formats.h"
|
||||
@ -10,8 +9,6 @@
|
||||
|
||||
#define TO_STRING(x) #x
|
||||
|
||||
extern cfg::bool_entry g_cfg_rsx_debug_output;
|
||||
|
||||
extern pD3DCompile wrapD3DCompile;
|
||||
|
||||
void Shader::Compile(const std::string &code, SHADER_TYPE st)
|
||||
@ -20,7 +17,7 @@ void Shader::Compile(const std::string &code, SHADER_TYPE st)
|
||||
HRESULT hr;
|
||||
ComPtr<ID3DBlob> errorBlob;
|
||||
UINT compileFlags;
|
||||
if (g_cfg_rsx_debug_output)
|
||||
if (g_cfg.video.debug_output)
|
||||
compileFlags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION;
|
||||
else
|
||||
compileFlags = 0;
|
||||
|
@ -1,7 +1,6 @@
|
||||
#ifdef _MSC_VER
|
||||
#include "stdafx.h"
|
||||
#include "stdafx_d3d12.h"
|
||||
#include "Utilities/Config.h"
|
||||
#include "D3D12RenderTargetSets.h"
|
||||
#include "Emu/Memory/Memory.h"
|
||||
#include "Emu/System.h"
|
||||
@ -12,10 +11,6 @@
|
||||
#include "D3D12GSRender.h"
|
||||
#include "D3D12Formats.h"
|
||||
|
||||
extern cfg::bool_entry g_cfg_rsx_debug_output;
|
||||
extern cfg::bool_entry g_cfg_rsx_write_color_buffers;
|
||||
extern cfg::bool_entry g_cfg_rsx_write_depth_buffer;
|
||||
|
||||
namespace
|
||||
{
|
||||
u32 get_max_depth_value(rsx::surface_depth_format format)
|
||||
@ -158,7 +153,7 @@ void D3D12GSRender::clear_surface(u32 arg)
|
||||
m_timers.draw_calls_duration += std::chrono::duration_cast<std::chrono::microseconds>(end_duration - start_duration).count();
|
||||
m_timers.draw_calls_count++;
|
||||
|
||||
if (g_cfg_rsx_debug_output)
|
||||
if (g_cfg.video.debug_output)
|
||||
{
|
||||
CHECK_HRESULT(get_current_resource_storage().command_list->Close());
|
||||
m_command_queue->ExecuteCommandLists(1, (ID3D12CommandList**)get_current_resource_storage().command_list.GetAddressOf());
|
||||
@ -311,7 +306,7 @@ void D3D12GSRender::copy_render_target_to_dma_location()
|
||||
|
||||
bool need_transfer = false;
|
||||
|
||||
if (rsx::method_registers.surface_z_dma() && g_cfg_rsx_write_depth_buffer)
|
||||
if (rsx::method_registers.surface_z_dma() && g_cfg.video.write_depth_buffer)
|
||||
{
|
||||
get_current_resource_storage().command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(std::get<1>(m_rtts.m_bound_depth_stencil), D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_COPY_SOURCE));
|
||||
get_current_resource_storage().command_list->CopyTextureRegion(&CD3DX12_TEXTURE_COPY_LOCATION(m_readback_resources.get_heap(), { depth_buffer_offset_in_heap,{ DXGI_FORMAT_R32_TYPELESS, (UINT)clip_w, (UINT)clip_h, 1, (UINT)depth_row_pitch } }), 0, 0, 0,
|
||||
@ -323,7 +318,7 @@ void D3D12GSRender::copy_render_target_to_dma_location()
|
||||
}
|
||||
|
||||
size_t color_buffer_offset_in_heap[4];
|
||||
if (g_cfg_rsx_write_color_buffers)
|
||||
if (g_cfg.video.write_color_buffers)
|
||||
{
|
||||
for (u8 i : get_rtt_indexes(rsx::method_registers.surface_color_target()))
|
||||
{
|
||||
@ -344,7 +339,7 @@ void D3D12GSRender::copy_render_target_to_dma_location()
|
||||
//Wait for result
|
||||
wait_for_command_queue(m_device.Get(), m_command_queue.Get());
|
||||
|
||||
if (address_z && g_cfg_rsx_write_depth_buffer)
|
||||
if (address_z && g_cfg.video.write_depth_buffer)
|
||||
{
|
||||
auto ptr = vm::base(address_z);
|
||||
char *depth_buffer = (char*)ptr;
|
||||
@ -364,7 +359,7 @@ void D3D12GSRender::copy_render_target_to_dma_location()
|
||||
m_readback_resources.unmap();
|
||||
}
|
||||
|
||||
if (g_cfg_rsx_write_color_buffers)
|
||||
if (g_cfg.video.write_color_buffers)
|
||||
{
|
||||
size_t srcPitch = get_aligned_pitch(rsx::method_registers.surface_color(), clip_w);
|
||||
size_t dstPitch = get_packed_pitch(rsx::method_registers.surface_color(), clip_w);
|
||||
|
@ -1,16 +1,12 @@
|
||||
#include "stdafx.h"
|
||||
#include "Utilities/Config.h"
|
||||
#include "Emu/Memory/Memory.h"
|
||||
#include "Emu/System.h"
|
||||
#include "GLGSRender.h"
|
||||
#include "GLVertexProgram.h"
|
||||
#include "../rsx_methods.h"
|
||||
#include "../Common/BufferUtils.h"
|
||||
#include "../rsx_utils.h"
|
||||
|
||||
extern cfg::bool_entry g_cfg_rsx_debug_output;
|
||||
extern cfg::bool_entry g_cfg_rsx_overlay;
|
||||
extern cfg::bool_entry g_cfg_rsx_gl_legacy_buffers;
|
||||
|
||||
#define DUMP_VERTEX_DATA 0
|
||||
|
||||
namespace
|
||||
@ -26,7 +22,7 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
GLGSRender::GLGSRender() : GSRender(frame_type::OpenGL)
|
||||
GLGSRender::GLGSRender() : GSRender()
|
||||
{
|
||||
shaders_cache.load(rsx::old_shaders_cache::shader_language::glsl);
|
||||
}
|
||||
@ -413,7 +409,7 @@ void GLGSRender::end()
|
||||
|
||||
std::chrono::time_point<steady_clock> draw_start = steady_clock::now();
|
||||
|
||||
if (g_cfg_rsx_debug_output)
|
||||
if (g_cfg.video.debug_output)
|
||||
{
|
||||
m_program->validate();
|
||||
}
|
||||
@ -477,7 +473,7 @@ void GLGSRender::on_init_thread()
|
||||
|
||||
gl::init();
|
||||
|
||||
if (g_cfg_rsx_debug_output)
|
||||
if (g_cfg.video.debug_output)
|
||||
gl::enable_debugging();
|
||||
|
||||
LOG_NOTICE(RSX, "%s", (const char*)glGetString(GL_VERSION));
|
||||
@ -520,10 +516,11 @@ void GLGSRender::on_init_thread()
|
||||
if (!gl_caps.ARB_buffer_storage_supported)
|
||||
{
|
||||
LOG_WARNING(RSX, "Forcing use of legacy OpenGL buffers because ARB_buffer_storage is not supported");
|
||||
g_cfg_rsx_gl_legacy_buffers = true;
|
||||
// TODO: do not modify config options
|
||||
g_cfg.video.gl_legacy_buffers.from_string("true");
|
||||
}
|
||||
|
||||
if (g_cfg_rsx_gl_legacy_buffers)
|
||||
if (g_cfg.video.gl_legacy_buffers)
|
||||
{
|
||||
LOG_WARNING(RSX, "Using legacy openGL buffers.");
|
||||
manually_flush_ring_buffers = true;
|
||||
@ -551,7 +548,7 @@ void GLGSRender::on_init_thread()
|
||||
|
||||
m_vao.element_array_buffer = *m_index_ring_buffer;
|
||||
|
||||
if (g_cfg_rsx_overlay)
|
||||
if (g_cfg.video.overlay)
|
||||
{
|
||||
if (gl_caps.ARB_shader_draw_parameters_supported)
|
||||
{
|
||||
@ -908,7 +905,7 @@ void GLGSRender::flip(int buffer)
|
||||
|
||||
__glcheck flip_fbo->blit(gl::screen, screen_area, areai(aspect_ratio).flipped_vertical(), gl::buffers::color, gl::filter::linear);
|
||||
|
||||
if (g_cfg_rsx_overlay)
|
||||
if (g_cfg.video.overlay)
|
||||
{
|
||||
gl::screen.bind();
|
||||
glViewport(0, 0, m_frame->client_width(), m_frame->client_height());
|
||||
|
@ -1,12 +1,7 @@
|
||||
#include "stdafx.h"
|
||||
#include "Utilities/Config.h"
|
||||
#include "../rsx_methods.h"
|
||||
#include "GLGSRender.h"
|
||||
|
||||
extern cfg::bool_entry g_cfg_rsx_write_color_buffers;
|
||||
extern cfg::bool_entry g_cfg_rsx_write_depth_buffer;
|
||||
extern cfg::bool_entry g_cfg_rsx_read_color_buffers;
|
||||
extern cfg::bool_entry g_cfg_rsx_read_depth_buffer;
|
||||
#include "Emu/System.h"
|
||||
|
||||
color_format rsx::internals::surface_color_format_to_gl(rsx::surface_color_format color_format)
|
||||
{
|
||||
@ -274,7 +269,7 @@ void GLGSRender::init_buffers(bool skip_reading)
|
||||
}
|
||||
|
||||
//Mark buffer regions as NO_ACCESS on Cell visible side
|
||||
if (g_cfg_rsx_write_color_buffers)
|
||||
if (g_cfg.video.write_color_buffers)
|
||||
{
|
||||
auto color_format = rsx::internals::surface_color_format_to_gl(surface_format);
|
||||
|
||||
@ -288,7 +283,7 @@ void GLGSRender::init_buffers(bool skip_reading)
|
||||
}
|
||||
}
|
||||
|
||||
if (g_cfg_rsx_write_depth_buffer)
|
||||
if (g_cfg.video.write_depth_buffer)
|
||||
{
|
||||
if (depth_surface_info.address && depth_surface_info.pitch)
|
||||
{
|
||||
@ -330,7 +325,7 @@ void GLGSRender::read_buffers()
|
||||
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
|
||||
if (g_cfg_rsx_read_color_buffers)
|
||||
if (g_cfg.video.read_color_buffers)
|
||||
{
|
||||
auto color_format = rsx::internals::surface_color_format_to_gl(rsx::method_registers.surface_color());
|
||||
|
||||
@ -405,7 +400,7 @@ void GLGSRender::read_buffers()
|
||||
}
|
||||
}
|
||||
|
||||
if (g_cfg_rsx_read_depth_buffer)
|
||||
if (g_cfg.video.read_depth_buffer)
|
||||
{
|
||||
//TODO: use pitch
|
||||
u32 pitch = depth_surface_info.pitch;
|
||||
@ -459,7 +454,7 @@ void GLGSRender::write_buffers()
|
||||
if (!draw_fbo)
|
||||
return;
|
||||
|
||||
if (g_cfg_rsx_write_color_buffers)
|
||||
if (g_cfg.video.write_color_buffers)
|
||||
{
|
||||
auto write_color_buffers = [&](int index, int count)
|
||||
{
|
||||
@ -481,7 +476,7 @@ void GLGSRender::write_buffers()
|
||||
write_color_buffers(0, 4);
|
||||
}
|
||||
|
||||
if (g_cfg_rsx_write_depth_buffer)
|
||||
if (g_cfg.video.write_depth_buffer)
|
||||
{
|
||||
//TODO: use pitch
|
||||
if (depth_surface_info.pitch == 0) return;
|
||||
|
@ -14,15 +14,11 @@
|
||||
#include "GLRenderTargets.h"
|
||||
#include "../Common/TextureUtils.h"
|
||||
#include "../../Memory/vm.h"
|
||||
#include "Utilities/Config.h"
|
||||
|
||||
#include "../rsx_utils.h"
|
||||
|
||||
class GLGSRender;
|
||||
|
||||
extern cfg::bool_entry g_cfg_rsx_write_color_buffers;
|
||||
extern cfg::bool_entry g_cfg_rsx_write_depth_buffer;
|
||||
|
||||
namespace gl
|
||||
{
|
||||
class texture_cache
|
||||
|
@ -1,14 +1,9 @@
|
||||
#include "stdafx.h"
|
||||
#include "Utilities/Config.h"
|
||||
#include "Emu/Memory/Memory.h"
|
||||
#include "Emu/System.h"
|
||||
|
||||
#include "GSRender.h"
|
||||
|
||||
// temporarily (u8 value is really CellVideoOutResolutionId, but HLE declarations shouldn't be available for the rest of emu, even indirectly)
|
||||
extern cfg::map_entry<u8> g_cfg_video_out_resolution;
|
||||
extern const std::unordered_map<u8, std::pair<int, int>> g_video_out_resolution_map;
|
||||
|
||||
draw_context_t GSFrameBase::new_context()
|
||||
{
|
||||
if (void* context = make_context())
|
||||
@ -19,10 +14,9 @@ draw_context_t GSFrameBase::new_context()
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GSRender::GSRender(frame_type type)
|
||||
GSRender::GSRender()
|
||||
{
|
||||
const auto size = g_video_out_resolution_map.at(g_cfg_video_out_resolution.get());
|
||||
m_frame = Emu.GetCallbacks().get_gs_frame(type, size.first, size.second).release();
|
||||
m_frame = Emu.GetCallbacks().get_gs_frame().release();
|
||||
}
|
||||
|
||||
GSRender::~GSRender()
|
||||
|
@ -47,14 +47,6 @@ protected:
|
||||
virtual void* make_context() = 0;
|
||||
};
|
||||
|
||||
enum class frame_type
|
||||
{
|
||||
Null,
|
||||
OpenGL,
|
||||
DX12,
|
||||
Vulkan
|
||||
};
|
||||
|
||||
class GSRender : public rsx::thread
|
||||
{
|
||||
protected:
|
||||
@ -62,7 +54,7 @@ protected:
|
||||
draw_context_t m_context;
|
||||
|
||||
public:
|
||||
GSRender(frame_type type);
|
||||
GSRender();
|
||||
virtual ~GSRender();
|
||||
|
||||
void on_init_rsx() override;
|
||||
|
@ -2,7 +2,7 @@
|
||||
#include "NullGSRender.h"
|
||||
#include "Emu/System.h"
|
||||
|
||||
NullGSRender::NullGSRender() : GSRender(frame_type::Null)
|
||||
NullGSRender::NullGSRender() : GSRender()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
#include "stdafx.h"
|
||||
#include "Utilities/Config.h"
|
||||
#include "Emu/Memory/Memory.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/IdManager.h"
|
||||
@ -19,17 +18,6 @@ class GSRender;
|
||||
|
||||
#define CMD_DEBUG 0
|
||||
|
||||
cfg::bool_entry g_cfg_rsx_write_color_buffers(cfg::root.video, "Write Color Buffers");
|
||||
cfg::bool_entry g_cfg_rsx_write_depth_buffer(cfg::root.video, "Write Depth Buffer");
|
||||
cfg::bool_entry g_cfg_rsx_read_color_buffers(cfg::root.video, "Read Color Buffers");
|
||||
cfg::bool_entry g_cfg_rsx_read_depth_buffer(cfg::root.video, "Read Depth Buffer");
|
||||
cfg::bool_entry g_cfg_rsx_log_programs(cfg::root.video, "Log shader programs");
|
||||
cfg::bool_entry g_cfg_rsx_vsync(cfg::root.video, "VSync");
|
||||
cfg::bool_entry g_cfg_rsx_debug_output(cfg::root.video, "Debug output");
|
||||
cfg::bool_entry g_cfg_rsx_overlay(cfg::root.video, "Debug overlay");
|
||||
cfg::bool_entry g_cfg_rsx_gl_legacy_buffers(cfg::root.video, "Use Legacy OpenGL Buffers (Debug)");
|
||||
cfg::bool_entry g_cfg_rsx_use_gpu_texture_scaling(cfg::root.video, "Use GPU texture scaling", true);
|
||||
|
||||
bool user_asked_for_frame_capture = false;
|
||||
rsx::frame_capture_data frame_debug;
|
||||
|
||||
|
@ -7,10 +7,6 @@
|
||||
#include "../Common/BufferUtils.h"
|
||||
#include "VKFormats.h"
|
||||
|
||||
extern cfg::bool_entry g_cfg_rsx_overlay;
|
||||
extern cfg::bool_entry g_cfg_rsx_write_color_buffers;
|
||||
extern cfg::bool_entry g_cfg_rsx_write_depth_buffer;
|
||||
|
||||
namespace
|
||||
{
|
||||
u32 get_max_depth_value(rsx::surface_depth_format format)
|
||||
@ -451,7 +447,7 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
VKGSRender::VKGSRender() : GSRender(frame_type::Vulkan)
|
||||
VKGSRender::VKGSRender() : GSRender()
|
||||
{
|
||||
shaders_cache.load(rsx::old_shaders_cache::shader_language::glsl);
|
||||
|
||||
@ -556,7 +552,7 @@ VKGSRender::VKGSRender() : GSRender(frame_type::Vulkan)
|
||||
|
||||
vkCreateSemaphore((*m_device), &semaphore_info, nullptr, &m_present_semaphore);
|
||||
|
||||
if (g_cfg_rsx_overlay)
|
||||
if (g_cfg.video.overlay)
|
||||
{
|
||||
size_t idx = vk::get_render_pass_location( m_swap_chain->get_surface_format(), VK_FORMAT_UNDEFINED, 1);
|
||||
m_text_writer.reset(new vk::text_writer());
|
||||
@ -644,7 +640,7 @@ bool VKGSRender::on_access_violation(u32 address, bool is_writing)
|
||||
return m_texture_cache.invalidate_address(address);
|
||||
else
|
||||
{
|
||||
if (g_cfg_rsx_write_color_buffers || g_cfg_rsx_write_depth_buffer)
|
||||
if (g_cfg.video.write_color_buffers || g_cfg.video.write_depth_buffer)
|
||||
{
|
||||
bool flushable, synchronized;
|
||||
std::tie(flushable, synchronized) = m_texture_cache.address_is_flushable(address);
|
||||
@ -1066,7 +1062,7 @@ void VKGSRender::copy_render_targets_to_dma_location()
|
||||
if (!m_flush_draw_buffers)
|
||||
return;
|
||||
|
||||
if (!g_cfg_rsx_write_color_buffers && !g_cfg_rsx_write_depth_buffer)
|
||||
if (!g_cfg.video.write_color_buffers && !g_cfg.video.write_depth_buffer)
|
||||
return;
|
||||
|
||||
//TODO: Make this asynchronous. Should be similar to a glFlush() but in this case its similar to glFinish
|
||||
@ -1075,7 +1071,7 @@ void VKGSRender::copy_render_targets_to_dma_location()
|
||||
|
||||
vk::enter_uninterruptible();
|
||||
|
||||
if (g_cfg_rsx_write_color_buffers)
|
||||
if (g_cfg.video.write_color_buffers)
|
||||
{
|
||||
for (u8 index = 0; index < rsx::limits::color_buffers_count; index++)
|
||||
{
|
||||
@ -1087,7 +1083,7 @@ void VKGSRender::copy_render_targets_to_dma_location()
|
||||
}
|
||||
}
|
||||
|
||||
if (g_cfg_rsx_write_depth_buffer)
|
||||
if (g_cfg.video.write_depth_buffer)
|
||||
{
|
||||
if (m_depth_surface_info.pitch)
|
||||
{
|
||||
@ -1192,7 +1188,7 @@ void VKGSRender::process_swap_request()
|
||||
m_sampler_to_clean.clear();
|
||||
m_framebuffer_to_clean.clear();
|
||||
|
||||
if (g_cfg_rsx_overlay)
|
||||
if (g_cfg.video.overlay)
|
||||
{
|
||||
m_text_writer->reset_descriptors();
|
||||
}
|
||||
@ -1609,7 +1605,7 @@ void VKGSRender::prepare_rtts()
|
||||
m_depth_surface_info.pitch = 0;
|
||||
}
|
||||
|
||||
if (g_cfg_rsx_write_color_buffers)
|
||||
if (g_cfg.video.write_color_buffers)
|
||||
{
|
||||
for (u8 index : draw_buffers)
|
||||
{
|
||||
@ -1621,7 +1617,7 @@ void VKGSRender::prepare_rtts()
|
||||
}
|
||||
}
|
||||
|
||||
if (g_cfg_rsx_write_depth_buffer)
|
||||
if (g_cfg.video.write_depth_buffer)
|
||||
{
|
||||
if (m_depth_surface_info.address && m_depth_surface_info.pitch)
|
||||
{
|
||||
@ -1717,7 +1713,7 @@ void VKGSRender::flip(int buffer)
|
||||
|
||||
std::unique_ptr<vk::framebuffer> direct_fbo;
|
||||
std::vector<std::unique_ptr<vk::image_view>> swap_image_view;
|
||||
if (g_cfg_rsx_overlay)
|
||||
if (g_cfg.video.overlay)
|
||||
{
|
||||
//Change the image layout whilst setting up a dependency on waiting for the blit op to finish before we start writing
|
||||
auto subres = vk::get_image_subresource_range(0, 0, 1, 1, VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "Utilities/Config.h"
|
||||
#include "Emu/System.h"
|
||||
#include "VulkanAPI.h"
|
||||
#include "../GCM.h"
|
||||
#include "../Common/TextureUtils.h"
|
||||
@ -23,8 +23,6 @@
|
||||
#define TEXTURES_FIRST_BIND_SLOT 19
|
||||
#define VERTEX_TEXTURES_FIRST_BIND_SLOT 35 //19+16
|
||||
|
||||
extern cfg::bool_entry g_cfg_rsx_debug_output;
|
||||
|
||||
namespace rsx
|
||||
{
|
||||
class fragment_texture;
|
||||
@ -184,7 +182,7 @@ namespace vk
|
||||
|
||||
std::vector<const char *> layers;
|
||||
|
||||
if (g_cfg_rsx_debug_output)
|
||||
if (g_cfg.video.debug_output)
|
||||
layers.push_back("VK_LAYER_LUNARG_standard_validation");
|
||||
|
||||
VkDeviceCreateInfo device = {};
|
||||
@ -1090,7 +1088,7 @@ namespace vk
|
||||
|
||||
std::vector<const char *> layers;
|
||||
|
||||
if (g_cfg_rsx_debug_output)
|
||||
if (g_cfg.video.debug_output)
|
||||
layers.push_back("VK_LAYER_LUNARG_standard_validation");
|
||||
|
||||
VkInstanceCreateInfo instance_info = {};
|
||||
|
@ -1,5 +1,4 @@
|
||||
#include "stdafx.h"
|
||||
#include "Utilities/Config.h"
|
||||
#include "rsx_methods.h"
|
||||
#include "RSXThread.h"
|
||||
#include "Emu/Memory/Memory.h"
|
||||
@ -13,17 +12,24 @@
|
||||
|
||||
#include <thread>
|
||||
|
||||
cfg::map_entry<double> g_cfg_rsx_frame_limit(cfg::root.video, "Frame limit",
|
||||
template <>
|
||||
void fmt_class_string<frame_limit_type>::format(std::string& out, u64 arg)
|
||||
{
|
||||
{ "Off", 0. },
|
||||
{ "59.94", 59.94 },
|
||||
{ "50", 50. },
|
||||
{ "60", 60. },
|
||||
{ "30", 30. },
|
||||
{ "Auto", -1. },
|
||||
});
|
||||
format_enum(out, arg, [](frame_limit_type value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case frame_limit_type::none: return "Off";
|
||||
case frame_limit_type::_59_94: return "59.94";
|
||||
case frame_limit_type::_50: return "50";
|
||||
case frame_limit_type::_60: return "60";
|
||||
case frame_limit_type::_30: return "30";
|
||||
case frame_limit_type::_auto: return "Auto";
|
||||
}
|
||||
|
||||
extern cfg::bool_entry g_cfg_rsx_use_gpu_texture_scaling;
|
||||
return unknown;
|
||||
});
|
||||
}
|
||||
|
||||
namespace rsx
|
||||
{
|
||||
@ -575,7 +581,7 @@ namespace rsx
|
||||
}
|
||||
}
|
||||
|
||||
if (g_cfg_rsx_use_gpu_texture_scaling && dst_dma == CELL_GCM_CONTEXT_DMA_MEMORY_FRAME_BUFFER)
|
||||
if (g_cfg.video.use_gpu_texture_scaling && dst_dma == CELL_GCM_CONTEXT_DMA_MEMORY_FRAME_BUFFER)
|
||||
{
|
||||
//For now, only use this for actual scaled images, there are use cases that should not go through 3d engine, e.g program ucode transfer
|
||||
//TODO: Figure out more instances where we can use this without problems
|
||||
@ -811,10 +817,18 @@ namespace rsx
|
||||
Emu.Pause();
|
||||
}
|
||||
|
||||
if (double limit = g_cfg_rsx_frame_limit.get())
|
||||
double limit = 0.;
|
||||
switch (g_cfg.video.frame_limit)
|
||||
{
|
||||
case frame_limit_type::none: limit = 0.; break;
|
||||
case frame_limit_type::_59_94: limit = 59.94; break;
|
||||
case frame_limit_type::_50: limit = 50.; break;
|
||||
case frame_limit_type::_60: limit = 60.; break;
|
||||
case frame_limit_type::_30: limit = 30.; break;
|
||||
case frame_limit_type::_auto: limit = rsx->fps_limit; break; // TODO
|
||||
}
|
||||
if (limit)
|
||||
{
|
||||
if (limit < 0) limit = rsx->fps_limit; // TODO
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds((s64)(1000.0 / limit - rsx->timer_sync.GetElapsedTimeInMilliSec())));
|
||||
rsx->timer_sync.Start();
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
#include "stdafx.h"
|
||||
#include "Utilities/Config.h"
|
||||
#include "Utilities/event.h"
|
||||
#include "Utilities/bin_patch.h"
|
||||
#include "Emu/Memory/Memory.h"
|
||||
@ -27,21 +26,10 @@
|
||||
|
||||
#include "Utilities/GDBDebugServer.h"
|
||||
|
||||
cfg_root g_cfg;
|
||||
|
||||
system_type g_system;
|
||||
|
||||
cfg::bool_entry g_cfg_autostart(cfg::root.misc, "Always start after boot", true);
|
||||
cfg::bool_entry g_cfg_autoexit(cfg::root.misc, "Exit RPCS3 when process finishes");
|
||||
|
||||
cfg::string_entry g_cfg_vfs_emulator_dir(cfg::root.vfs, "$(EmulatorDir)"); // Default (empty): taken from fs::get_config_dir()
|
||||
cfg::string_entry g_cfg_vfs_dev_hdd0(cfg::root.vfs, "/dev_hdd0/", "$(EmulatorDir)dev_hdd0/");
|
||||
cfg::string_entry g_cfg_vfs_dev_hdd1(cfg::root.vfs, "/dev_hdd1/", "$(EmulatorDir)dev_hdd1/");
|
||||
cfg::string_entry g_cfg_vfs_dev_flash(cfg::root.vfs, "/dev_flash/", "$(EmulatorDir)dev_flash/");
|
||||
cfg::string_entry g_cfg_vfs_dev_usb000(cfg::root.vfs, "/dev_usb000/", "$(EmulatorDir)dev_usb000/");
|
||||
cfg::string_entry g_cfg_vfs_dev_bdvd(cfg::root.vfs, "/dev_bdvd/"); // Not mounted
|
||||
cfg::string_entry g_cfg_vfs_app_home(cfg::root.vfs, "/app_home/"); // Not mounted
|
||||
|
||||
cfg::bool_entry g_cfg_vfs_allow_host_root(cfg::root.vfs, "Enable /host_root/");
|
||||
|
||||
std::string g_cfg_defaults;
|
||||
|
||||
extern atomic_t<u32> g_thread_count;
|
||||
@ -55,6 +43,136 @@ extern std::shared_ptr<struct lv2_prx> ppu_load_prx(const ppu_prx_object&, const
|
||||
|
||||
fs::file g_tty;
|
||||
|
||||
template <>
|
||||
void fmt_class_string<keyboard_handler>::format(std::string& out, u64 arg)
|
||||
{
|
||||
format_enum(out, arg, [](keyboard_handler value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case keyboard_handler::null: return "Null";
|
||||
case keyboard_handler::basic: return "Basic";
|
||||
}
|
||||
|
||||
return unknown;
|
||||
});
|
||||
}
|
||||
|
||||
template <>
|
||||
void fmt_class_string<mouse_handler>::format(std::string& out, u64 arg)
|
||||
{
|
||||
format_enum(out, arg, [](mouse_handler value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case mouse_handler::null: return "Null";
|
||||
case mouse_handler::basic: return "Basic";
|
||||
}
|
||||
|
||||
return unknown;
|
||||
});
|
||||
}
|
||||
|
||||
template <>
|
||||
void fmt_class_string<pad_handler>::format(std::string& out, u64 arg)
|
||||
{
|
||||
format_enum(out, arg, [](pad_handler value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case pad_handler::null: return "Null";
|
||||
case pad_handler::keyboard: return "Keyboard";
|
||||
case pad_handler::ds4: return "DualShock 4";
|
||||
#ifdef _MSC_VER
|
||||
case pad_handler::xinput: return "XInput";
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
case pad_handler::mm: return "MMJoystick";
|
||||
#endif
|
||||
}
|
||||
|
||||
return unknown;
|
||||
});
|
||||
}
|
||||
|
||||
template <>
|
||||
void fmt_class_string<video_renderer>::format(std::string& out, u64 arg)
|
||||
{
|
||||
format_enum(out, arg, [](video_renderer value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case video_renderer::null: return "Null";
|
||||
case video_renderer::opengl: return "OpenGL";
|
||||
#ifdef _WIN32
|
||||
case video_renderer::vulkan: return "Vulkan";
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
case video_renderer::dx12: return "D3D12";
|
||||
#endif
|
||||
}
|
||||
|
||||
return unknown;
|
||||
});
|
||||
}
|
||||
|
||||
template <>
|
||||
void fmt_class_string<audio_renderer>::format(std::string& out, u64 arg)
|
||||
{
|
||||
format_enum(out, arg, [](audio_renderer value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case audio_renderer::null: return "Null";
|
||||
#ifdef _WIN32
|
||||
case audio_renderer::xaudio: return "XAudio2";
|
||||
#elif __linux__
|
||||
case audio_renderer::alsa: return "ALSA";
|
||||
#endif
|
||||
case audio_renderer::openal: return "OpenAL";
|
||||
}
|
||||
|
||||
return unknown;
|
||||
});
|
||||
}
|
||||
|
||||
template <>
|
||||
void fmt_class_string<video_resolution>::format(std::string& out, u64 arg)
|
||||
{
|
||||
format_enum(out, arg, [](video_resolution value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case video_resolution::_1080: return "1920x1080";
|
||||
case video_resolution::_720: return "1280x720";
|
||||
case video_resolution::_480: return "720x480";
|
||||
case video_resolution::_576: return "720x576";
|
||||
case video_resolution::_1600x1080: return "1600x1080";
|
||||
case video_resolution::_1440x1080: return "1440x1080";
|
||||
case video_resolution::_1280x1080: return "1280x1080";
|
||||
case video_resolution::_960x1080: return "960x1080";
|
||||
}
|
||||
|
||||
return unknown;
|
||||
});
|
||||
}
|
||||
|
||||
template <>
|
||||
void fmt_class_string<video_aspect>::format(std::string& out, u64 arg)
|
||||
{
|
||||
format_enum(out, arg, [](video_aspect value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case video_aspect::_auto: return "Auto";
|
||||
case video_aspect::_4_3: return "4:3";
|
||||
case video_aspect::_16_9: return "16:9";
|
||||
}
|
||||
|
||||
return unknown;
|
||||
});
|
||||
}
|
||||
|
||||
namespace rpcs3
|
||||
{
|
||||
event<void>& on_run() { static event<void> on_run; return on_run; }
|
||||
@ -74,18 +192,18 @@ void Emulator::Init()
|
||||
fxm::init();
|
||||
|
||||
// Reset defaults, cache them
|
||||
cfg::root.from_default();
|
||||
g_cfg_defaults = cfg::root.to_string();
|
||||
g_cfg.from_default();
|
||||
g_cfg_defaults = g_cfg.to_string();
|
||||
|
||||
// Reload global configuration
|
||||
cfg::root.from_string(fs::file(fs::get_config_dir() + "/config.yml", fs::read + fs::create).to_string());
|
||||
g_cfg.from_string(fs::file(fs::get_config_dir() + "/config.yml", fs::read + fs::create).to_string());
|
||||
|
||||
// Create directories
|
||||
const std::string emu_dir_ = g_cfg_vfs_emulator_dir;
|
||||
const std::string emu_dir_ = g_cfg.vfs.emulator_dir;
|
||||
const std::string emu_dir = emu_dir_.empty() ? fs::get_config_dir() : emu_dir_;
|
||||
const std::string dev_hdd0 = fmt::replace_all(g_cfg_vfs_dev_hdd0, "$(EmulatorDir)", emu_dir);
|
||||
const std::string dev_hdd1 = fmt::replace_all(g_cfg_vfs_dev_hdd1, "$(EmulatorDir)", emu_dir);
|
||||
const std::string dev_usb = fmt::replace_all(g_cfg_vfs_dev_usb000, "$(EmulatorDir)", emu_dir);
|
||||
const std::string dev_hdd0 = fmt::replace_all(g_cfg.vfs.dev_hdd0, "$(EmulatorDir)", emu_dir);
|
||||
const std::string dev_hdd1 = fmt::replace_all(g_cfg.vfs.dev_hdd1, "$(EmulatorDir)", emu_dir);
|
||||
const std::string dev_usb = fmt::replace_all(g_cfg.vfs.dev_usb000, "$(EmulatorDir)", emu_dir);
|
||||
|
||||
fs::create_path(dev_hdd0);
|
||||
fs::create_dir(dev_hdd0 + "game/");
|
||||
@ -151,18 +269,18 @@ bool Emulator::BootGame(const std::string& path, bool direct)
|
||||
|
||||
std::string Emulator::GetGameDir()
|
||||
{
|
||||
const std::string& emu_dir_ = g_cfg_vfs_emulator_dir;
|
||||
const std::string& emu_dir_ = g_cfg.vfs.emulator_dir;
|
||||
const std::string& emu_dir = emu_dir_.empty() ? fs::get_config_dir() : emu_dir_;
|
||||
|
||||
return fmt::replace_all(g_cfg_vfs_dev_hdd0, "$(EmulatorDir)", emu_dir) + "game/";
|
||||
return fmt::replace_all(g_cfg.vfs.dev_hdd0, "$(EmulatorDir)", emu_dir) + "game/";
|
||||
}
|
||||
|
||||
std::string Emulator::GetLibDir()
|
||||
{
|
||||
const std::string& emu_dir_ = g_cfg_vfs_emulator_dir;
|
||||
const std::string& emu_dir_ = g_cfg.vfs.emulator_dir;
|
||||
const std::string& emu_dir = emu_dir_.empty() ? fs::get_config_dir() : emu_dir_;
|
||||
|
||||
return fmt::replace_all(g_cfg_vfs_dev_flash, "$(EmulatorDir)", emu_dir) + "sys/external/";
|
||||
return fmt::replace_all(g_cfg.vfs.dev_flash, "$(EmulatorDir)", emu_dir) + "sys/external/";
|
||||
}
|
||||
|
||||
void Emulator::Load()
|
||||
@ -204,40 +322,40 @@ void Emulator::Load()
|
||||
if (fs::file cfg_file{m_cache_path + "/config.yml"})
|
||||
{
|
||||
LOG_NOTICE(LOADER, "Applying custom config: %s/config.yml", m_cache_path);
|
||||
cfg::root.from_string(cfg_file.to_string());
|
||||
g_cfg.from_string(cfg_file.to_string());
|
||||
}
|
||||
|
||||
// Load custom config-1
|
||||
if (fs::file cfg_file{fs::get_config_dir() + "data/" + m_title_id + "/config.yml"})
|
||||
{
|
||||
LOG_NOTICE(LOADER, "Applying custom config: data/%s/config.yml", m_title_id);
|
||||
cfg::root.from_string(cfg_file.to_string());
|
||||
g_cfg.from_string(cfg_file.to_string());
|
||||
}
|
||||
|
||||
// Load custom config-2
|
||||
if (fs::file cfg_file{m_path + ".yml"})
|
||||
{
|
||||
LOG_NOTICE(LOADER, "Applying custom config: %s.yml", m_path);
|
||||
cfg::root.from_string(cfg_file.to_string());
|
||||
g_cfg.from_string(cfg_file.to_string());
|
||||
}
|
||||
|
||||
LOG_NOTICE(LOADER, "Used configuration:\n%s\n", cfg::root.to_string());
|
||||
LOG_NOTICE(LOADER, "Used configuration:\n%s\n", g_cfg.to_string());
|
||||
|
||||
// Load patches from different locations
|
||||
fxm::check_unlocked<patch_engine>()->append(fs::get_config_dir() + "data/" + m_title_id + "/patch.yml");
|
||||
fxm::check_unlocked<patch_engine>()->append(m_cache_path + "/patch.yml");
|
||||
|
||||
// Mount all devices
|
||||
const std::string emu_dir_ = g_cfg_vfs_emulator_dir;
|
||||
const std::string emu_dir_ = g_cfg.vfs.emulator_dir;
|
||||
const std::string emu_dir = emu_dir_.empty() ? fs::get_config_dir() : emu_dir_;
|
||||
const std::string home_dir = g_cfg_vfs_app_home;
|
||||
std::string bdvd_dir = g_cfg_vfs_dev_bdvd;
|
||||
const std::string home_dir = g_cfg.vfs.app_home;
|
||||
std::string bdvd_dir = g_cfg.vfs.dev_bdvd;
|
||||
|
||||
vfs::mount("dev_hdd0", fmt::replace_all(g_cfg_vfs_dev_hdd0, "$(EmulatorDir)", emu_dir));
|
||||
vfs::mount("dev_hdd1", fmt::replace_all(g_cfg_vfs_dev_hdd1, "$(EmulatorDir)", emu_dir));
|
||||
vfs::mount("dev_flash", fmt::replace_all(g_cfg_vfs_dev_flash, "$(EmulatorDir)", emu_dir));
|
||||
vfs::mount("dev_usb", fmt::replace_all(g_cfg_vfs_dev_usb000, "$(EmulatorDir)", emu_dir));
|
||||
vfs::mount("dev_usb000", fmt::replace_all(g_cfg_vfs_dev_usb000, "$(EmulatorDir)", emu_dir));
|
||||
vfs::mount("dev_hdd0", fmt::replace_all(g_cfg.vfs.dev_hdd0, "$(EmulatorDir)", emu_dir));
|
||||
vfs::mount("dev_hdd1", fmt::replace_all(g_cfg.vfs.dev_hdd1, "$(EmulatorDir)", emu_dir));
|
||||
vfs::mount("dev_flash", fmt::replace_all(g_cfg.vfs.dev_flash, "$(EmulatorDir)", emu_dir));
|
||||
vfs::mount("dev_usb", fmt::replace_all(g_cfg.vfs.dev_usb000, "$(EmulatorDir)", emu_dir));
|
||||
vfs::mount("dev_usb000", fmt::replace_all(g_cfg.vfs.dev_usb000, "$(EmulatorDir)", emu_dir));
|
||||
vfs::mount("app_home", home_dir.empty() ? elf_dir + '/' : fmt::replace_all(home_dir, "$(EmulatorDir)", emu_dir));
|
||||
|
||||
// Mount /dev_bdvd/ if necessary
|
||||
@ -256,7 +374,7 @@ void Emulator::Load()
|
||||
}
|
||||
|
||||
// Mount /host_root/ if necessary
|
||||
if (g_cfg_vfs_allow_host_root)
|
||||
if (g_cfg.vfs.host_root)
|
||||
{
|
||||
vfs::mount("host_root", {});
|
||||
}
|
||||
@ -306,7 +424,7 @@ void Emulator::Load()
|
||||
{
|
||||
// PS3 executable
|
||||
g_system = system_type::ps3;
|
||||
m_status = Ready;
|
||||
m_state = system_state::ready;
|
||||
vm::ps3::init();
|
||||
|
||||
if (m_elf_path.empty())
|
||||
@ -323,7 +441,7 @@ void Emulator::Load()
|
||||
{
|
||||
// PPU PRX (experimental)
|
||||
g_system = system_type::ps3;
|
||||
m_status = Ready;
|
||||
m_state = system_state::ready;
|
||||
vm::ps3::init();
|
||||
ppu_load_prx(ppu_prx, "");
|
||||
}
|
||||
@ -331,7 +449,7 @@ void Emulator::Load()
|
||||
{
|
||||
// SPU executable (experimental)
|
||||
g_system = system_type::ps3;
|
||||
m_status = Ready;
|
||||
m_state = system_state::ready;
|
||||
vm::ps3::init();
|
||||
spu_load_exec(spu_exec);
|
||||
}
|
||||
@ -339,7 +457,7 @@ void Emulator::Load()
|
||||
{
|
||||
// ARMv7 executable
|
||||
g_system = system_type::psv;
|
||||
m_status = Ready;
|
||||
m_state = system_state::ready;
|
||||
vm::psv::init();
|
||||
|
||||
if (m_elf_path.empty())
|
||||
@ -361,13 +479,13 @@ void Emulator::Load()
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_cfg_autostart && IsReady())
|
||||
if (g_cfg.misc.autostart && IsReady())
|
||||
{
|
||||
Run();
|
||||
}
|
||||
else if (IsPaused())
|
||||
{
|
||||
m_status = Ready;
|
||||
m_state = system_state::ready;
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
@ -397,7 +515,7 @@ void Emulator::Run()
|
||||
|
||||
m_pause_start_time = 0;
|
||||
m_pause_amend_time = 0;
|
||||
m_status = Running;
|
||||
m_state = system_state::running;
|
||||
|
||||
auto on_select = [](u32, cpu_thread& cpu)
|
||||
{
|
||||
@ -415,9 +533,9 @@ bool Emulator::Pause()
|
||||
const u64 start = get_system_time();
|
||||
|
||||
// Try to pause
|
||||
if (!m_status.compare_and_swap_test(Running, Paused))
|
||||
if (!m_state.compare_and_swap_test(system_state::running, system_state::paused))
|
||||
{
|
||||
return m_status.compare_and_swap_test(Ready, Paused);
|
||||
return m_state.compare_and_swap_test(system_state::ready, system_state::paused);
|
||||
}
|
||||
|
||||
rpcs3::on_pause()();
|
||||
@ -458,7 +576,7 @@ void Emulator::Resume()
|
||||
}
|
||||
|
||||
// Try to resume
|
||||
if (!m_status.compare_and_swap_test(Paused, Running))
|
||||
if (!m_state.compare_and_swap_test(system_state::paused, system_state::running))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -489,7 +607,7 @@ void Emulator::Resume()
|
||||
|
||||
void Emulator::Stop()
|
||||
{
|
||||
if (m_status.exchange(Stopped) == Stopped)
|
||||
if (m_state.exchange(system_state::stopped) == system_state::stopped)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -542,7 +660,7 @@ void Emulator::Stop()
|
||||
RSXIOMem.Clear();
|
||||
vm::close();
|
||||
|
||||
if (g_cfg_autoexit)
|
||||
if (g_cfg.misc.autoexit)
|
||||
{
|
||||
GetCallbacks().exit();
|
||||
}
|
||||
|
@ -1,6 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "VFS.h"
|
||||
#include "Utilities/Atomic.h"
|
||||
#include "Utilities/Config.h"
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
enum class system_type
|
||||
{
|
||||
@ -9,11 +14,134 @@ enum class system_type
|
||||
//psp, // Hypothetical
|
||||
};
|
||||
|
||||
enum class system_state
|
||||
{
|
||||
running,
|
||||
paused,
|
||||
stopped,
|
||||
ready,
|
||||
};
|
||||
|
||||
enum class ppu_decoder_type
|
||||
{
|
||||
precise,
|
||||
fast,
|
||||
llvm,
|
||||
};
|
||||
|
||||
enum class spu_decoder_type
|
||||
{
|
||||
precise,
|
||||
fast,
|
||||
asmjit,
|
||||
llvm,
|
||||
};
|
||||
|
||||
enum class lib_loading_type
|
||||
{
|
||||
automatic,
|
||||
manual,
|
||||
both,
|
||||
liblv2only
|
||||
};
|
||||
|
||||
enum class keyboard_handler
|
||||
{
|
||||
null,
|
||||
basic,
|
||||
};
|
||||
|
||||
enum class mouse_handler
|
||||
{
|
||||
null,
|
||||
basic,
|
||||
};
|
||||
|
||||
enum class pad_handler
|
||||
{
|
||||
null,
|
||||
keyboard,
|
||||
ds4,
|
||||
#ifdef _MSC_VER
|
||||
xinput,
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
mm,
|
||||
#endif
|
||||
};
|
||||
|
||||
enum class video_renderer
|
||||
{
|
||||
null,
|
||||
opengl,
|
||||
#ifdef _WIN32
|
||||
vulkan,
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
dx12,
|
||||
#endif
|
||||
};
|
||||
|
||||
enum class audio_renderer
|
||||
{
|
||||
null,
|
||||
#ifdef _WIN32
|
||||
xaudio,
|
||||
#elif __linux__
|
||||
alsa,
|
||||
#endif
|
||||
openal,
|
||||
};
|
||||
|
||||
enum class camera_handler
|
||||
{
|
||||
null,
|
||||
fake,
|
||||
};
|
||||
|
||||
enum class fake_camera_type
|
||||
{
|
||||
unknown,
|
||||
eyetoy,
|
||||
eyetoy2,
|
||||
uvc1_1,
|
||||
};
|
||||
|
||||
enum class video_resolution
|
||||
{
|
||||
_1080,
|
||||
_720,
|
||||
_480,
|
||||
_576,
|
||||
_1600x1080,
|
||||
_1440x1080,
|
||||
_1280x1080,
|
||||
_960x1080,
|
||||
};
|
||||
|
||||
enum class video_aspect
|
||||
{
|
||||
_auto,
|
||||
_4_3,
|
||||
_16_9,
|
||||
};
|
||||
|
||||
enum class frame_limit_type
|
||||
{
|
||||
none,
|
||||
_59_94,
|
||||
_50,
|
||||
_60,
|
||||
_30,
|
||||
_auto,
|
||||
};
|
||||
|
||||
enum CellNetCtlState : s32;
|
||||
enum CellSysutilLang : s32;
|
||||
|
||||
// Current process type
|
||||
extern system_type g_system;
|
||||
|
||||
enum class frame_type;
|
||||
|
||||
struct EmuCallbacks
|
||||
{
|
||||
std::function<void(std::function<void()>)> call_after;
|
||||
@ -22,24 +150,16 @@ struct EmuCallbacks
|
||||
std::function<std::shared_ptr<class KeyboardHandlerBase>()> get_kb_handler;
|
||||
std::function<std::shared_ptr<class MouseHandlerBase>()> get_mouse_handler;
|
||||
std::function<std::shared_ptr<class PadHandlerBase>()> get_pad_handler;
|
||||
std::function<std::unique_ptr<class GSFrameBase>(frame_type, int, int)> get_gs_frame;
|
||||
std::function<std::unique_ptr<class GSFrameBase>()> get_gs_frame;
|
||||
std::function<std::shared_ptr<class GSRender>()> get_gs_render;
|
||||
std::function<std::shared_ptr<class AudioThread>()> get_audio;
|
||||
std::function<std::shared_ptr<class MsgDialogBase>()> get_msg_dialog;
|
||||
std::function<std::unique_ptr<class SaveDialogBase>()> get_save_dialog;
|
||||
};
|
||||
|
||||
enum Status : u32
|
||||
{
|
||||
Running,
|
||||
Paused,
|
||||
Stopped,
|
||||
Ready,
|
||||
};
|
||||
|
||||
class Emulator final
|
||||
{
|
||||
atomic_t<u32> m_status{Stopped};
|
||||
atomic_t<system_state> m_state{system_state::stopped};
|
||||
|
||||
EmuCallbacks m_cb;
|
||||
|
||||
@ -76,7 +196,7 @@ public:
|
||||
*/
|
||||
void SetTestMode()
|
||||
{
|
||||
m_status = Running;
|
||||
m_state = system_state::running;
|
||||
}
|
||||
|
||||
void Init();
|
||||
@ -118,11 +238,137 @@ public:
|
||||
void Resume();
|
||||
void Stop();
|
||||
|
||||
bool IsRunning() const { return m_status == Running; }
|
||||
bool IsPaused() const { return m_status == Paused; }
|
||||
bool IsStopped() const { return m_status == Stopped; }
|
||||
bool IsReady() const { return m_status == Ready; }
|
||||
auto GetStatus() const { return m_status.load(); }
|
||||
bool IsRunning() const { return m_state == system_state::running; }
|
||||
bool IsPaused() const { return m_state == system_state::paused; }
|
||||
bool IsStopped() const { return m_state == system_state::stopped; }
|
||||
bool IsReady() const { return m_state == system_state::ready; }
|
||||
auto GetStatus() const { return m_state.load(); }
|
||||
};
|
||||
|
||||
extern Emulator Emu;
|
||||
|
||||
struct cfg_root : cfg::node
|
||||
{
|
||||
struct node_core : cfg::node
|
||||
{
|
||||
node_core(cfg::node* _this) : cfg::node(_this, "Core") {}
|
||||
|
||||
cfg::_enum<ppu_decoder_type> ppu_decoder{this, "PPU Decoder", ppu_decoder_type::fast};
|
||||
cfg::_int<1, 16> ppu_threads{this, "PPU Threads", 2}; // Amount of PPU threads running simultaneously (must be 2)
|
||||
cfg::_bool ppu_debug{this, "PPU Debug"};
|
||||
cfg::_bool llvm_logs{this, "Save LLVM logs"};
|
||||
cfg::string llvm_cpu{this, "Use LLVM CPU"};
|
||||
|
||||
cfg::_enum<spu_decoder_type> spu_decoder{this, "SPU Decoder", spu_decoder_type::asmjit};
|
||||
cfg::_bool bind_spu_cores{this, "Bind SPU threads to secondary cores"};
|
||||
cfg::_bool lower_spu_priority{this, "Lower SPU thread priority"};
|
||||
cfg::_bool spu_debug{this, "SPU Debug"};
|
||||
|
||||
cfg::_enum<lib_loading_type> lib_loading{this, "Lib Loader", lib_loading_type::automatic};
|
||||
cfg::_bool hook_functions{this, "Hook static functions"};
|
||||
cfg::set_entry load_libraries{this, "Load libraries"};
|
||||
|
||||
} core{this};
|
||||
|
||||
struct node_vfs : cfg::node
|
||||
{
|
||||
node_vfs(cfg::node* _this) : cfg::node(_this, "VFS") {}
|
||||
|
||||
cfg::string emulator_dir{this, "$(EmulatorDir)"}; // Default (empty): taken from fs::get_config_dir()
|
||||
cfg::string dev_hdd0{this, "/dev_hdd0/", "$(EmulatorDir)dev_hdd0/"};
|
||||
cfg::string dev_hdd1{this, "/dev_hdd1/", "$(EmulatorDir)dev_hdd1/"};
|
||||
cfg::string dev_flash{this, "/dev_flash/", "$(EmulatorDir)dev_flash/"};
|
||||
cfg::string dev_usb000{this, "/dev_usb000/", "$(EmulatorDir)dev_usb000/"};
|
||||
cfg::string dev_bdvd{this, "/dev_bdvd/"}; // Not mounted
|
||||
cfg::string app_home{this, "/app_home/"}; // Not mounted
|
||||
|
||||
cfg::_bool host_root{this, "Enable /host_root/"};
|
||||
|
||||
} vfs{this};
|
||||
|
||||
struct node_video : cfg::node
|
||||
{
|
||||
node_video(cfg::node* _this) : cfg::node(_this, "Video") {}
|
||||
|
||||
cfg::_enum<video_renderer> renderer{this, "Renderer", video_renderer::opengl};
|
||||
|
||||
cfg::_enum<video_resolution> resolution{this, "Resolution", video_resolution::_720};
|
||||
cfg::_enum<video_aspect> aspect_ratio{this, "Aspect ratio", video_aspect::_16_9};
|
||||
cfg::_enum<frame_limit_type> frame_limit{this, "Frame limit", frame_limit_type::none};
|
||||
|
||||
cfg::_bool write_color_buffers{this, "Write Color Buffers"};
|
||||
cfg::_bool write_depth_buffer{this, "Write Depth Buffer"};
|
||||
cfg::_bool read_color_buffers{this, "Read Color Buffers"};
|
||||
cfg::_bool read_depth_buffer{this, "Read Depth Buffer"};
|
||||
cfg::_bool log_programs{this, "Log shader programs"};
|
||||
cfg::_bool vsync{this, "VSync"};
|
||||
cfg::_bool debug_output{this, "Debug output"};
|
||||
cfg::_bool overlay{this, "Debug overlay"};
|
||||
cfg::_bool gl_legacy_buffers{this, "Use Legacy OpenGL Buffers (Debug)"};
|
||||
cfg::_bool use_gpu_texture_scaling{this, "Use GPU texture scaling", true};
|
||||
|
||||
struct node_d3d12 : cfg::node
|
||||
{
|
||||
node_d3d12(cfg::node* _this) : cfg::node(_this, "D3D12") {}
|
||||
|
||||
cfg::string adapter{this, "Adapter"};
|
||||
|
||||
} d3d12{this};
|
||||
|
||||
} video{this};
|
||||
|
||||
struct node_audio : cfg::node
|
||||
{
|
||||
node_audio(cfg::node* _this) : cfg::node(_this, "Audio") {}
|
||||
|
||||
cfg::_enum<audio_renderer> renderer{this, "Renderer", static_cast<audio_renderer>(1)};
|
||||
|
||||
cfg::_bool dump_to_file{this, "Dump to file"};
|
||||
cfg::_bool convert_to_u16{this, "Convert to 16 bit"};
|
||||
cfg::_bool downmix_to_2ch{this, "Downmix to Stereo", true};
|
||||
|
||||
} audio{this};
|
||||
|
||||
struct node_io : cfg::node
|
||||
{
|
||||
node_io(cfg::node* _this) : cfg::node(_this, "Input/Output") {}
|
||||
|
||||
cfg::_enum<keyboard_handler> keyboard{this, "Keyboard", keyboard_handler::null};
|
||||
cfg::_enum<mouse_handler> mouse{this, "Mouse", mouse_handler::basic};
|
||||
cfg::_enum<pad_handler> pad{this, "Pad", pad_handler::keyboard};
|
||||
cfg::_enum<camera_handler> camera{this, "Camera", camera_handler::null};
|
||||
cfg::_enum<fake_camera_type> camera_type{this, "Camera type", fake_camera_type::unknown};
|
||||
|
||||
} io{this};
|
||||
|
||||
struct node_sys : cfg::node
|
||||
{
|
||||
node_sys(cfg::node* _this) : cfg::node(_this, "System") {}
|
||||
|
||||
cfg::_enum<CellSysutilLang> language{this, "Language"};
|
||||
|
||||
} sys{this};
|
||||
|
||||
struct node_net : cfg::node
|
||||
{
|
||||
node_net(cfg::node* _this) : cfg::node(_this, "Net") {}
|
||||
|
||||
cfg::_enum<CellNetCtlState> net_status{this, "Connection status"};
|
||||
cfg::string ip_address{this, "IP address", "192.168.1.1"};
|
||||
|
||||
} net{this};
|
||||
|
||||
struct node_misc : cfg::node
|
||||
{
|
||||
node_misc(cfg::node* _this) : cfg::node(_this, "Miscellaneous") {}
|
||||
|
||||
cfg::_bool autostart{this, "Always start after boot", true};
|
||||
cfg::_bool autoexit{this, "Exit RPCS3 when process finishes"};
|
||||
cfg::_int<1, 65535> gdb_server_port{this, "Port", 2345};
|
||||
|
||||
} misc{this};
|
||||
|
||||
cfg::log_entry log{this, "Log"};
|
||||
};
|
||||
|
||||
extern cfg_root g_cfg;
|
||||
|
@ -16,7 +16,7 @@ class DbgEmuPanel : public wxPanel
|
||||
wxButton* m_btn_stop;
|
||||
wxButton* m_btn_restart;
|
||||
wxButton* m_btn_capture_frame;
|
||||
u32 m_last_status = Ready;
|
||||
system_state m_last_status = system_state::ready;
|
||||
|
||||
public:
|
||||
DbgEmuPanel(wxWindow* parent) : wxPanel(parent)
|
||||
@ -54,10 +54,10 @@ public:
|
||||
{
|
||||
m_last_status = status;
|
||||
|
||||
m_btn_run->Enable(status != Stopped);
|
||||
m_btn_stop->Enable(status != Stopped);
|
||||
m_btn_run->Enable(status != system_state::stopped);
|
||||
m_btn_stop->Enable(status != system_state::stopped);
|
||||
m_btn_restart->Enable(!Emu.GetPath().empty());
|
||||
m_btn_run->SetLabel(status == Paused ? "Resume" : status == Running ? "Pause" : "Run");
|
||||
m_btn_run->SetLabel(status == system_state::paused ? "Resume" : status == system_state::running ? "Pause" : "Run");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,9 @@
|
||||
#include "stdafx.h"
|
||||
#include "stdafx_gui.h"
|
||||
#include "Utilities/Config.h"
|
||||
#include "Emu/System.h"
|
||||
#include "GLGSFrame.h"
|
||||
#include <wx/version.h>
|
||||
|
||||
extern cfg::bool_entry g_cfg_rsx_debug_output;
|
||||
|
||||
GLGSFrame::GLGSFrame(int w, int h)
|
||||
: GSFrame("OpenGL", w, h)
|
||||
{
|
||||
@ -19,7 +17,7 @@ GLGSFrame::GLGSFrame(int w, int h)
|
||||
WX_GL_MINOR_VERSION, 3,
|
||||
WX_GL_CORE_PROFILE,
|
||||
#if !defined(CMAKE_BUILD)
|
||||
g_cfg_rsx_debug_output ? WX_GL_DEBUG : 0,
|
||||
g_cfg.video.debug_output ? WX_GL_DEBUG : 0,
|
||||
#endif
|
||||
#endif
|
||||
0
|
||||
|
@ -252,43 +252,50 @@ void PADManager::OnKeyDown(wxKeyEvent &keyEvent)
|
||||
{
|
||||
m_key_pressed = true;
|
||||
|
||||
cfg::int32* entry = nullptr;
|
||||
switch (m_button_id)
|
||||
{
|
||||
case id_pad_lstick_left: g_kbpad_config.left_stick_left = keyEvent.GetKeyCode(); break;
|
||||
case id_pad_lstick_down: g_kbpad_config.left_stick_down = keyEvent.GetKeyCode(); break;
|
||||
case id_pad_lstick_right: g_kbpad_config.left_stick_right = keyEvent.GetKeyCode(); break;
|
||||
case id_pad_lstick_up: g_kbpad_config.left_stick_up = keyEvent.GetKeyCode(); break;
|
||||
case id_pad_lstick_left: entry = &g_kbpad_config.left_stick_left; break;
|
||||
case id_pad_lstick_down: entry = &g_kbpad_config.left_stick_down; break;
|
||||
case id_pad_lstick_right: entry = &g_kbpad_config.left_stick_right; break;
|
||||
case id_pad_lstick_up: entry = &g_kbpad_config.left_stick_up; break;
|
||||
|
||||
case id_pad_left: g_kbpad_config.left = keyEvent.GetKeyCode(); break;
|
||||
case id_pad_down: g_kbpad_config.down = keyEvent.GetKeyCode(); break;
|
||||
case id_pad_right: g_kbpad_config.right = keyEvent.GetKeyCode(); break;
|
||||
case id_pad_up: g_kbpad_config.up = keyEvent.GetKeyCode(); break;
|
||||
case id_pad_left: entry = &g_kbpad_config.left; break;
|
||||
case id_pad_down: entry = &g_kbpad_config.down; break;
|
||||
case id_pad_right: entry = &g_kbpad_config.right; break;
|
||||
case id_pad_up: entry = &g_kbpad_config.up; break;
|
||||
|
||||
case id_pad_l1: g_kbpad_config.l1 = keyEvent.GetKeyCode(); break;
|
||||
case id_pad_l2: g_kbpad_config.l2 = keyEvent.GetKeyCode(); break;
|
||||
case id_pad_l3: g_kbpad_config.l3 = keyEvent.GetKeyCode(); break;
|
||||
case id_pad_l1: entry = &g_kbpad_config.l1; break;
|
||||
case id_pad_l2: entry = &g_kbpad_config.l2; break;
|
||||
case id_pad_l3: entry = &g_kbpad_config.l3; break;
|
||||
|
||||
case id_pad_start: g_kbpad_config.start = keyEvent.GetKeyCode(); break;
|
||||
case id_pad_select: g_kbpad_config.select = keyEvent.GetKeyCode(); break;
|
||||
case id_pad_start: entry = &g_kbpad_config.start; break;
|
||||
case id_pad_select: entry = &g_kbpad_config.select; break;
|
||||
|
||||
case id_pad_r1: g_kbpad_config.r1 = keyEvent.GetKeyCode(); break;
|
||||
case id_pad_r2: g_kbpad_config.r2 = keyEvent.GetKeyCode(); break;
|
||||
case id_pad_r3: g_kbpad_config.r3 = keyEvent.GetKeyCode(); break;
|
||||
case id_pad_r1: entry = &g_kbpad_config.r1; break;
|
||||
case id_pad_r2: entry = &g_kbpad_config.r2; break;
|
||||
case id_pad_r3: entry = &g_kbpad_config.r3; break;
|
||||
|
||||
case id_pad_square: g_kbpad_config.square = keyEvent.GetKeyCode(); break;
|
||||
case id_pad_cross: g_kbpad_config.cross = keyEvent.GetKeyCode(); break;
|
||||
case id_pad_circle: g_kbpad_config.circle = keyEvent.GetKeyCode(); break;
|
||||
case id_pad_triangle: g_kbpad_config.triangle = keyEvent.GetKeyCode(); break;
|
||||
case id_pad_square: entry = &g_kbpad_config.square; break;
|
||||
case id_pad_cross: entry = &g_kbpad_config.cross; break;
|
||||
case id_pad_circle: entry = &g_kbpad_config.circle; break;
|
||||
case id_pad_triangle: entry = &g_kbpad_config.triangle; break;
|
||||
|
||||
case id_pad_rstick_left: g_kbpad_config.right_stick_left = keyEvent.GetKeyCode(); break;
|
||||
case id_pad_rstick_down: g_kbpad_config.right_stick_down = keyEvent.GetKeyCode(); break;
|
||||
case id_pad_rstick_right: g_kbpad_config.right_stick_right = keyEvent.GetKeyCode(); break;
|
||||
case id_pad_rstick_up: g_kbpad_config.right_stick_up = keyEvent.GetKeyCode(); break;
|
||||
case id_pad_rstick_left: entry = &g_kbpad_config.right_stick_left; break;
|
||||
case id_pad_rstick_down: entry = &g_kbpad_config.right_stick_down; break;
|
||||
case id_pad_rstick_right: entry = &g_kbpad_config.right_stick_right; break;
|
||||
case id_pad_rstick_up: entry = &g_kbpad_config.right_stick_up; break;
|
||||
|
||||
case 0: break;
|
||||
default: LOG_ERROR(HLE, "Unknown button ID: %d", m_button_id); break;
|
||||
}
|
||||
|
||||
if (entry)
|
||||
{
|
||||
// TODO: do not modify config
|
||||
entry->from_string(std::to_string(keyEvent.GetKeyCode()));
|
||||
}
|
||||
|
||||
UpdateLabel();
|
||||
keyEvent.Skip();
|
||||
}
|
||||
@ -316,7 +323,7 @@ void PADManager::OnButtonClicked(wxCommandEvent &event)
|
||||
{
|
||||
switch (event.GetId())
|
||||
{
|
||||
case id_reset_parameters: ResetParameters(); UpdateLabel(); break;
|
||||
case id_reset_parameters: g_kbpad_config.from_default(); UpdateLabel(); break;
|
||||
case wxID_OK: g_kbpad_config.save(); break;
|
||||
case wxID_CANCEL: break;
|
||||
|
||||
@ -437,40 +444,6 @@ void PADManager::UpdateLabel()
|
||||
b_right_rstick->SetLabel(GetKeyName(g_kbpad_config.right_stick_right));
|
||||
}
|
||||
|
||||
void PADManager::ResetParameters()
|
||||
{
|
||||
g_kbpad_config.left_stick_up = g_kbpad_config.left_stick_up.def;
|
||||
g_kbpad_config.left_stick_down = g_kbpad_config.left_stick_down.def;
|
||||
g_kbpad_config.left_stick_left = g_kbpad_config.left_stick_left.def;
|
||||
g_kbpad_config.left_stick_right = g_kbpad_config.left_stick_right.def;
|
||||
|
||||
g_kbpad_config.up = g_kbpad_config.up.def;
|
||||
g_kbpad_config.down = g_kbpad_config.down.def;
|
||||
g_kbpad_config.left = g_kbpad_config.left.def;
|
||||
g_kbpad_config.right = g_kbpad_config.right.def;
|
||||
|
||||
g_kbpad_config.l1 = g_kbpad_config.l1.def;
|
||||
g_kbpad_config.l2 = g_kbpad_config.l2.def;
|
||||
g_kbpad_config.l3 = g_kbpad_config.l3.def;
|
||||
|
||||
g_kbpad_config.start = g_kbpad_config.start.def;
|
||||
g_kbpad_config.select = g_kbpad_config.select.def;
|
||||
|
||||
g_kbpad_config.r1 = g_kbpad_config.r1.def;
|
||||
g_kbpad_config.r2 = g_kbpad_config.r2.def;
|
||||
g_kbpad_config.r3 = g_kbpad_config.r3.def;
|
||||
|
||||
g_kbpad_config.square = g_kbpad_config.square.def;
|
||||
g_kbpad_config.cross = g_kbpad_config.cross.def;
|
||||
g_kbpad_config.circle = g_kbpad_config.circle.def;
|
||||
g_kbpad_config.triangle = g_kbpad_config.triangle.def;
|
||||
|
||||
g_kbpad_config.right_stick_up = g_kbpad_config.right_stick_up.def;
|
||||
g_kbpad_config.right_stick_down = g_kbpad_config.right_stick_down.def;
|
||||
g_kbpad_config.right_stick_left = g_kbpad_config.right_stick_left.def;
|
||||
g_kbpad_config.right_stick_right = g_kbpad_config.right_stick_right.def;
|
||||
}
|
||||
|
||||
void PADManager::UpdateTimerLabel(const u32 id)
|
||||
{
|
||||
switch (id)
|
||||
|
@ -89,7 +89,6 @@ public:
|
||||
void OnKeyUp(wxKeyEvent &keyEvent);
|
||||
void OnButtonClicked(wxCommandEvent &event);
|
||||
void UpdateLabel();
|
||||
void ResetParameters();
|
||||
void UpdateTimerLabel(const u32 id);
|
||||
void SwitchButtons(const bool IsEnabled);
|
||||
const wxString GetKeyName(const u32 keyCode);
|
||||
|
@ -75,9 +75,25 @@ struct cfg_adapter
|
||||
{
|
||||
}
|
||||
|
||||
static cfg::entry_base& get_cfg(cfg::entry_base& root, cfg_location::const_iterator begin, cfg_location::const_iterator end)
|
||||
static cfg::_base& get_cfg(cfg::_base& root, const std::string& name)
|
||||
{
|
||||
return begin == end ? root : get_cfg(root[*begin], begin + 1, end);
|
||||
if (root.get_type() == cfg::type::node)
|
||||
{
|
||||
for (const auto& pair : static_cast<cfg::node&>(root).get_nodes())
|
||||
{
|
||||
if (pair.first == name)
|
||||
{
|
||||
return *pair.second;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fmt::throw_exception("Node not found: %s", name);
|
||||
}
|
||||
|
||||
static cfg::_base& get_cfg(cfg::_base& root, cfg_location::const_iterator begin, cfg_location::const_iterator end)
|
||||
{
|
||||
return begin == end ? root : get_cfg(get_cfg(root, *begin), begin + 1, end);
|
||||
}
|
||||
|
||||
static YAML::Node get_node(YAML::Node node, cfg_location::const_iterator begin, cfg_location::const_iterator end)
|
||||
@ -85,9 +101,9 @@ struct cfg_adapter
|
||||
return begin == end ? node : get_node(node[*begin], begin + 1, end); // TODO
|
||||
}
|
||||
|
||||
cfg::entry_base& get_cfg() const
|
||||
cfg::_base& get_cfg() const
|
||||
{
|
||||
return get_cfg(cfg::root, location.cbegin(), location.cend());
|
||||
return get_cfg(g_cfg, location.cbegin(), location.cend());
|
||||
}
|
||||
|
||||
YAML::Node get_node(YAML::Node root) const
|
||||
@ -106,7 +122,7 @@ struct radiobox_pad_helper
|
||||
radiobox_pad_helper(cfg_location&& _loc)
|
||||
: location(std::move(_loc))
|
||||
{
|
||||
for (const auto& v : cfg_adapter::get_cfg(cfg::root, location.cbegin(), location.cend()).to_list())
|
||||
for (const auto& v : cfg_adapter::get_cfg(g_cfg, location.cbegin(), location.cend()).to_list())
|
||||
{
|
||||
values.Add(fmt::FromUTF8(v));
|
||||
}
|
||||
|
@ -7,30 +7,30 @@ struct KeyboardPadConfig final : cfg::node
|
||||
{
|
||||
const std::string cfg_name = fs::get_config_dir() + "/config_kbpad.yml";
|
||||
|
||||
cfg::int32_entry left_stick_left{ *this, "Left Analog Stick Left", static_cast<int>('A') };
|
||||
cfg::int32_entry left_stick_down{ *this, "Left Analog Stick Down", static_cast<int>('S') };
|
||||
cfg::int32_entry left_stick_right{ *this, "Left Analog Stick Right", static_cast<int>('D') };
|
||||
cfg::int32_entry left_stick_up{ *this, "Left Analog Stick Up", static_cast<int>('W') };
|
||||
cfg::int32_entry right_stick_left{ *this, "Right Analog Stick Left", 313 };
|
||||
cfg::int32_entry right_stick_down{ *this, "Right Analog Stick Down", 367 };
|
||||
cfg::int32_entry right_stick_right{ *this, "Right Analog Stick Right", 312 };
|
||||
cfg::int32_entry right_stick_up{ *this, "Right Analog Stick Up", 366 };
|
||||
cfg::int32_entry start{ *this, "Start", 13 };
|
||||
cfg::int32_entry select{ *this, "Select", 32 };
|
||||
cfg::int32_entry square{ *this, "Square", static_cast<int>('Z') };
|
||||
cfg::int32_entry cross{ *this, "Cross", static_cast<int>('X') };
|
||||
cfg::int32_entry circle{ *this, "Circle", static_cast<int>('C') };
|
||||
cfg::int32_entry triangle{ *this, "Triangle", static_cast<int>('V') };
|
||||
cfg::int32_entry left{ *this, "Left", 314 };
|
||||
cfg::int32_entry down{ *this, "Down", 317 };
|
||||
cfg::int32_entry right{ *this, "Right", 316 };
|
||||
cfg::int32_entry up{ *this, "Up", 315 };
|
||||
cfg::int32_entry r1{ *this, "R1", static_cast<int>('E') };
|
||||
cfg::int32_entry r2{ *this, "R2", static_cast<int>('T') };
|
||||
cfg::int32_entry r3{ *this, "R3", static_cast<int>('G') };
|
||||
cfg::int32_entry l1{ *this, "L1", static_cast<int>('Q') };
|
||||
cfg::int32_entry l2{ *this, "L2", static_cast<int>('R') };
|
||||
cfg::int32_entry l3{ *this, "L3", static_cast<int>('F') };
|
||||
cfg::int32 left_stick_left{this, "Left Analog Stick Left", static_cast<int>('A')};
|
||||
cfg::int32 left_stick_down{this, "Left Analog Stick Down", static_cast<int>('S')};
|
||||
cfg::int32 left_stick_right{this, "Left Analog Stick Right", static_cast<int>('D')};
|
||||
cfg::int32 left_stick_up{this, "Left Analog Stick Up", static_cast<int>('W')};
|
||||
cfg::int32 right_stick_left{this, "Right Analog Stick Left", 313};
|
||||
cfg::int32 right_stick_down{this, "Right Analog Stick Down", 367};
|
||||
cfg::int32 right_stick_right{this, "Right Analog Stick Right", 312};
|
||||
cfg::int32 right_stick_up{this, "Right Analog Stick Up", 366};
|
||||
cfg::int32 start{this, "Start", 13};
|
||||
cfg::int32 select{this, "Select", 32};
|
||||
cfg::int32 square{this, "Square", static_cast<int>('Z')};
|
||||
cfg::int32 cross{this, "Cross", static_cast<int>('X')};
|
||||
cfg::int32 circle{this, "Circle", static_cast<int>('C')};
|
||||
cfg::int32 triangle{this, "Triangle", static_cast<int>('V')};
|
||||
cfg::int32 left{this, "Left", 314};
|
||||
cfg::int32 down{this, "Down", 317};
|
||||
cfg::int32 right{this, "Right", 316};
|
||||
cfg::int32 up{this, "Up", 315};
|
||||
cfg::int32 r1{this, "R1", static_cast<int>('E')};
|
||||
cfg::int32 r2{this, "R2", static_cast<int>('T')};
|
||||
cfg::int32 r3{this, "R3", static_cast<int>('G')};
|
||||
cfg::int32 l1{this, "L1", static_cast<int>('Q')};
|
||||
cfg::int32 l2{this, "L2", static_cast<int>('R')};
|
||||
cfg::int32 l3{this, "L3", static_cast<int>('F')};
|
||||
|
||||
bool load()
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "stdafx.h"
|
||||
#include "stdafx_gui.h"
|
||||
#ifdef _MSC_VER
|
||||
#ifdef _WIN32
|
||||
#include "MMJoystickHandler.h"
|
||||
|
||||
MMJoystickConfig g_mmjoystick_config;
|
||||
|
@ -8,30 +8,30 @@ struct MMJoystickConfig final : cfg::node
|
||||
{
|
||||
const std::string cfg_name = fs::get_config_dir() + "/config_mmjoystick.yml";
|
||||
|
||||
//cfg::int32_entry left_stick_left{ *this, "Left Analog Stick Left", static_cast<int>('A') };
|
||||
//cfg::int32_entry left_stick_down{ *this, "Left Analog Stick Down", static_cast<int>('S') };
|
||||
//cfg::int32_entry left_stick_right{ *this, "Left Analog Stick Right", static_cast<int>('D') };
|
||||
//cfg::int32_entry left_stick_up{ *this, "Left Analog Stick Up", static_cast<int>('W') };
|
||||
//cfg::int32_entry right_stick_left{ *this, "Right Analog Stick Left", 313 };
|
||||
//cfg::int32_entry right_stick_down{ *this, "Right Analog Stick Down", 367 };
|
||||
//cfg::int32_entry right_stick_right{ *this, "Right Analog Stick Right", 312 };
|
||||
//cfg::int32_entry right_stick_up{ *this, "Right Analog Stick Up", 366 };
|
||||
cfg::int32_entry start{ *this, "Start", JOY_BUTTON9 };
|
||||
cfg::int32_entry select{ *this, "Select", JOY_BUTTON10 };
|
||||
cfg::int32_entry square{ *this, "Square", JOY_BUTTON4 };
|
||||
cfg::int32_entry cross{ *this, "Cross", JOY_BUTTON3 };
|
||||
cfg::int32_entry circle{ *this, "Circle", JOY_BUTTON2 };
|
||||
cfg::int32_entry triangle{ *this, "Triangle", JOY_BUTTON1 };
|
||||
//cfg::int32_entry left{ *this, "Left", 314 };
|
||||
//cfg::int32_entry down{ *this, "Down", 317 };
|
||||
//cfg::int32_entry right{ *this, "Right", 316 };
|
||||
//cfg::int32_entry up{ *this, "Up", 315 };
|
||||
cfg::int32_entry r1{ *this, "R1", JOY_BUTTON8 };
|
||||
cfg::int32_entry r2{ *this, "R2", JOY_BUTTON6 };
|
||||
cfg::int32_entry r3{ *this, "R3", JOY_BUTTON12 };
|
||||
cfg::int32_entry l1{ *this, "L1", JOY_BUTTON7 };
|
||||
cfg::int32_entry l2{ *this, "L2", JOY_BUTTON5 };
|
||||
cfg::int32_entry l3{ *this, "L3", JOY_BUTTON11 };
|
||||
//cfg::int32 left_stick_left{this, "Left Analog Stick Left", static_cast<int>('A')};
|
||||
//cfg::int32 left_stick_down{this, "Left Analog Stick Down", static_cast<int>('S')};
|
||||
//cfg::int32 left_stick_right{this, "Left Analog Stick Right", static_cast<int>('D')};
|
||||
//cfg::int32 left_stick_up{this, "Left Analog Stick Up", static_cast<int>('W')};
|
||||
//cfg::int32 right_stick_left{this, "Right Analog Stick Left", 313};
|
||||
//cfg::int32 right_stick_down{this, "Right Analog Stick Down", 367};
|
||||
//cfg::int32 right_stick_right{this, "Right Analog Stick Right", 312};
|
||||
//cfg::int32 right_stick_up{this, "Right Analog Stick Up", 366};
|
||||
cfg::int32 start{this, "Start", JOY_BUTTON9};
|
||||
cfg::int32 select{this, "Select", JOY_BUTTON10};
|
||||
cfg::int32 square{this, "Square", JOY_BUTTON4};
|
||||
cfg::int32 cross{this, "Cross", JOY_BUTTON3};
|
||||
cfg::int32 circle{this, "Circle", JOY_BUTTON2};
|
||||
cfg::int32 triangle{this, "Triangle", JOY_BUTTON1};
|
||||
//cfg::int32 left{this, "Left", 314};
|
||||
//cfg::int32 down{this, "Down", 317};
|
||||
//cfg::int32 right{this, "Right", 316};
|
||||
//cfg::int32 up{this, "Up", 315};
|
||||
cfg::int32 r1{this, "R1", JOY_BUTTON8};
|
||||
cfg::int32 r2{this, "R2", JOY_BUTTON6};
|
||||
cfg::int32 r3{this, "R3", JOY_BUTTON12};
|
||||
cfg::int32 l1{this, "L1", JOY_BUTTON7};
|
||||
cfg::int32 l2{this, "L2", JOY_BUTTON5};
|
||||
cfg::int32 l3{this, "L3", JOY_BUTTON11};
|
||||
|
||||
bool load()
|
||||
{
|
||||
|
152
rpcs3/rpcs3.cpp
152
rpcs3/rpcs3.cpp
@ -20,6 +20,8 @@
|
||||
#include "DS4PadHandler.h"
|
||||
#ifdef _MSC_VER
|
||||
#include "XInputPadHandler.h"
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
#include "MMJoystickHandler.h"
|
||||
#endif
|
||||
|
||||
@ -72,55 +74,6 @@ void save_gui_cfg()
|
||||
IMPLEMENT_APP(Rpcs3App)
|
||||
Rpcs3App* TheApp;
|
||||
|
||||
cfg::map_entry<std::function<std::shared_ptr<KeyboardHandlerBase>()>> g_cfg_kb_handler(cfg::root.io, "Keyboard",
|
||||
{
|
||||
{ "Null", &std::make_shared<NullKeyboardHandler> },
|
||||
{ "Basic", &std::make_shared<BasicKeyboardHandler> },
|
||||
});
|
||||
|
||||
cfg::map_entry<std::function<std::shared_ptr<MouseHandlerBase>()>> g_cfg_mouse_handler(cfg::root.io, "Mouse",
|
||||
{
|
||||
{ "Null", &std::make_shared<NullMouseHandler> },
|
||||
{ "Basic", &std::make_shared<BasicMouseHandler> },
|
||||
});
|
||||
|
||||
cfg::map_entry<std::function<std::shared_ptr<PadHandlerBase>()>> g_cfg_pad_handler(cfg::root.io, "Pad", "Keyboard",
|
||||
{
|
||||
{ "Null", &std::make_shared<NullPadHandler> },
|
||||
{ "Keyboard", &std::make_shared<KeyboardPadHandler> },
|
||||
{ "DualShock 4", &std::make_shared<DS4PadHandler> },
|
||||
#ifdef _MSC_VER
|
||||
{ "XInput", &std::make_shared<XInputPadHandler> },
|
||||
{ "MMJoystick", &std::make_shared<MMJoystickHandler>},
|
||||
#endif
|
||||
});
|
||||
|
||||
cfg::map_entry<std::function<std::shared_ptr<GSRender>()>> g_cfg_gs_render(cfg::root.video, "Renderer", "OpenGL",
|
||||
{
|
||||
{ "Null", &std::make_shared<NullGSRender> },
|
||||
{ "OpenGL", &std::make_shared<GLGSRender> },
|
||||
#ifdef _MSC_VER
|
||||
{ "D3D12", &std::make_shared<D3D12GSRender> },
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
{ "Vulkan", &std::make_shared<VKGSRender> },
|
||||
#endif
|
||||
});
|
||||
|
||||
cfg::map_entry<std::function<std::shared_ptr<AudioThread>()>> g_cfg_audio_render(cfg::root.audio, "Renderer", 1,
|
||||
{
|
||||
{ "Null", &std::make_shared<NullAudioThread> },
|
||||
#ifdef _WIN32
|
||||
{ "XAudio2", &std::make_shared<XAudio2Thread> },
|
||||
#elif __linux__
|
||||
{ "ALSA", &std::make_shared<ALSAThread> },
|
||||
#endif
|
||||
{ "OpenAL", &std::make_shared<OpenALThread> },
|
||||
});
|
||||
|
||||
extern cfg::bool_entry g_cfg_autostart;
|
||||
extern cfg::bool_entry g_cfg_autoexit;
|
||||
|
||||
bool Rpcs3App::OnInit()
|
||||
{
|
||||
static const wxCmdLineEntryDesc desc[]
|
||||
@ -161,28 +114,93 @@ bool Rpcs3App::OnInit()
|
||||
wxGetApp().Exit();
|
||||
};
|
||||
|
||||
callbacks.get_kb_handler = []{ return g_cfg_kb_handler.get()(); };
|
||||
|
||||
callbacks.get_mouse_handler = []{ return g_cfg_mouse_handler.get()(); };
|
||||
|
||||
callbacks.get_pad_handler = []{ return g_cfg_pad_handler.get()(); };
|
||||
|
||||
callbacks.get_gs_frame = [](frame_type type, int w, int h) -> std::unique_ptr<GSFrameBase>
|
||||
callbacks.get_kb_handler = []() -> std::shared_ptr<KeyboardHandlerBase>
|
||||
{
|
||||
switch (type)
|
||||
switch (keyboard_handler type = g_cfg.io.keyboard)
|
||||
{
|
||||
case frame_type::OpenGL: return std::make_unique<GLGSFrame>(w, h);
|
||||
case frame_type::DX12: return std::make_unique<GSFrame>("DirectX 12", w, h);
|
||||
case frame_type::Null: return std::make_unique<GSFrame>("Null", w, h);
|
||||
case frame_type::Vulkan: return std::make_unique<GSFrame>("Vulkan", w, h);
|
||||
case keyboard_handler::null: return std::make_shared<NullKeyboardHandler>();
|
||||
case keyboard_handler::basic: return std::make_shared<BasicKeyboardHandler>();
|
||||
default: fmt::throw_exception("Invalid keyboard handler: %s", type);
|
||||
}
|
||||
|
||||
fmt::throw_exception("Invalid frame type (0x%x)" HERE, (int)type);
|
||||
};
|
||||
|
||||
callbacks.get_gs_render = []{ return g_cfg_gs_render.get()(); };
|
||||
callbacks.get_mouse_handler = []() -> std::shared_ptr<MouseHandlerBase>
|
||||
{
|
||||
switch (mouse_handler type = g_cfg.io.mouse)
|
||||
{
|
||||
case mouse_handler::null: return std::make_shared<NullMouseHandler>();
|
||||
case mouse_handler::basic: return std::make_shared<BasicMouseHandler>();
|
||||
default: fmt::throw_exception("Invalid mouse handler: %s", type);
|
||||
}
|
||||
};
|
||||
|
||||
callbacks.get_audio = []{ return g_cfg_audio_render.get()(); };
|
||||
callbacks.get_pad_handler = []() -> std::shared_ptr<PadHandlerBase>
|
||||
{
|
||||
switch (pad_handler type = g_cfg.io.pad)
|
||||
{
|
||||
case pad_handler::null: return std::make_shared<NullPadHandler>();
|
||||
case pad_handler::keyboard: return std::make_shared<KeyboardPadHandler>();
|
||||
case pad_handler::ds4: return std::make_shared<DS4PadHandler>();
|
||||
#ifdef _MSC_VER
|
||||
case pad_handler::xinput: return std::make_shared<XInputPadHandler>();
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
case pad_handler::mm: return std::make_shared<MMJoystickHandler>();
|
||||
#endif
|
||||
default: fmt::throw_exception("Invalid pad handler: %s", type);
|
||||
}
|
||||
};
|
||||
|
||||
callbacks.get_gs_frame = []() -> std::unique_ptr<GSFrameBase>
|
||||
{
|
||||
extern const std::unordered_map<video_resolution, std::pair<int, int>, value_hash<video_resolution>> g_video_out_resolution_map;
|
||||
|
||||
const auto size = g_video_out_resolution_map.at(g_cfg.video.resolution);
|
||||
|
||||
switch (video_renderer type = g_cfg.video.renderer)
|
||||
{
|
||||
case video_renderer::null: return std::make_unique<GSFrame>("Null", size.first, size.second);
|
||||
case video_renderer::opengl: return std::make_unique<GLGSFrame>(size.first, size.second);
|
||||
#ifdef _WIN32
|
||||
case video_renderer::vulkan: return std::make_unique<GSFrame>("Vulkan", size.first, size.second);
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
case video_renderer::dx12: return std::make_unique<GSFrame>("DirectX 12", size.first, size.second);
|
||||
#endif
|
||||
default: fmt::throw_exception("Invalid video renderer: %s" HERE, type);
|
||||
}
|
||||
};
|
||||
|
||||
callbacks.get_gs_render = []() -> std::shared_ptr<GSRender>
|
||||
{
|
||||
switch (video_renderer type = g_cfg.video.renderer)
|
||||
{
|
||||
case video_renderer::null: return std::make_shared<NullGSRender>();
|
||||
case video_renderer::opengl: return std::make_shared<GLGSRender>();
|
||||
#ifdef _WIN32
|
||||
case video_renderer::vulkan: return std::make_shared<VKGSRender>();
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
case video_renderer::dx12: return std::make_shared<D3D12GSRender>();
|
||||
#endif
|
||||
default: fmt::throw_exception("Invalid video renderer: %s" HERE, type);
|
||||
}
|
||||
};
|
||||
|
||||
callbacks.get_audio = []() -> std::shared_ptr<AudioThread>
|
||||
{
|
||||
switch (audio_renderer type = g_cfg.audio.renderer)
|
||||
{
|
||||
case audio_renderer::null: return std::make_shared<NullAudioThread>();
|
||||
#ifdef _WIN32
|
||||
case audio_renderer::xaudio: return std::make_shared<XAudio2Thread>();
|
||||
#elif __linux__
|
||||
case audio_renderer::alsa: return std::make_shared<ALSAThread>();
|
||||
#endif
|
||||
case audio_renderer::openal: return std::make_shared<OpenALThread>();
|
||||
default: fmt::throw_exception("Invalid audio renderer: %s" HERE, type);
|
||||
}
|
||||
};
|
||||
|
||||
callbacks.get_msg_dialog = []() -> std::shared_ptr<MsgDialogBase>
|
||||
{
|
||||
@ -227,8 +245,8 @@ void Rpcs3App::OnArguments(const wxCmdLineParser& parser)
|
||||
}
|
||||
|
||||
// TODO: clean implementation
|
||||
g_cfg_autostart = true;
|
||||
g_cfg_autoexit = true;
|
||||
g_cfg.misc.autostart.from_string("true");
|
||||
g_cfg.misc.autoexit.from_string("true");
|
||||
}
|
||||
|
||||
if (parser.GetParamCount() > 0)
|
||||
|
Loading…
Reference in New Issue
Block a user