1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-25 12:12:50 +01:00

Added new config system

Added emulator state class
Added emulator events
Minor improvements
This commit is contained in:
DH 2015-10-13 20:32:08 +03:00
parent bbfca3fc0d
commit e4f6eb04e8
20 changed files with 1435 additions and 112 deletions

View File

@ -208,6 +208,16 @@ std::vector<std::string> fmt::split(const std::string& source, std::initializer_
return std::move(result);
}
std::string fmt::trim(const std::string& source, const std::string& values)
{
std::size_t begin = source.find_first_not_of(values);
if (begin == source.npos)
return{};
return source.substr(begin, source.find_last_not_of(values) + 1);
}
std::string fmt::tolower(std::string source)
{
std::transform(source.begin(), source.end(), source.begin(), ::tolower);

View File

@ -300,6 +300,7 @@ namespace fmt
std::vector<std::string> rSplit(const std::string& source, const std::string& delim);
std::vector<std::string> split(const std::string& source, std::initializer_list<std::string> separators, bool is_skip_empty = true);
std::string trim(const std::string& source, const std::string& values = " \t");
template<typename T>
std::string merge(const T& source, const std::string& separator)

View File

@ -0,0 +1,146 @@
#include "stdafx.h"
#include "config_context.h"
#include "convert.h"
#include "StrFmt.h"
#include <iostream>
#include <sstream>
void config_context_t::group::init()
{
m_cfg->m_groups[full_name()] = this;
}
config_context_t::group::group(config_context_t* cfg, const std::string& name)
: m_cfg(cfg)
, m_name(name)
, m_parent(nullptr)
{
init();
}
config_context_t::group::group(group* parent, const std::string& name)
: m_cfg(parent->m_cfg)
, m_name(name)
, m_parent(parent)
{
init();
}
void config_context_t::group::set_parent(config_context_t* cfg)
{
m_cfg = cfg;
init();
}
std::string config_context_t::group::name() const
{
return m_name;
}
std::string config_context_t::group::full_name() const
{
if (m_parent)
return m_parent->full_name() + "/" + m_name;
return m_name;
}
void config_context_t::assign(const config_context_t& rhs)
{
for (auto &rhs_g : rhs.m_groups)
{
auto g = m_groups.at(rhs_g.first);
for (auto rhs_e : rhs_g.second->entries)
{
g->entries[rhs_e.first]->value_from(rhs_e.second);
}
}
}
void config_context_t::deserialize(std::istream& stream)
{
set_defaults();
uint line_index = 0;
std::string line;
group *current_group = nullptr;
while (std::getline(stream, line))
{
++line_index;
line = fmt::trim(line);
if (line.empty())
continue;
if (line.front() == '[' && line.back() == ']')
{
std::string group_name = line.substr(1, line.length() - 2);
auto found = m_groups.find(group_name);
if (found == m_groups.end())
{
std::cerr << line_index << ": group '" << group_name << "' not exists. ignored" << std::endl;
current_group = nullptr;
continue;
}
current_group = found->second;
continue;
}
if (current_group == nullptr)
{
std::cerr << line_index << ": line '" << line << "' ignored, no group." << std::endl;
continue;
}
auto name_value = fmt::split(line, { "=" });
switch (name_value.size())
{
case 1: current_group->entries[fmt::trim(name_value[0])]->string_value({}); break;
default:
std::cerr << line_index << ": line '" << line << "' has more than one symbol '='. used only first" << std::endl;
case 2: current_group->entries[fmt::trim(name_value[0])]->string_value(fmt::trim(name_value[1])); break;
}
}
}
void config_context_t::serialize(std::ostream& stream) const
{
for (auto &g : m_groups)
{
stream << "[" + g.first + "]" << std::endl;
for (auto &e : g.second->entries)
{
stream << e.first << "=" << e.second->string_value() << std::endl;
}
stream << std::endl;
}
}
void config_context_t::set_defaults()
{
for (auto &g : m_groups)
{
for (auto &e : g.second->entries)
{
e.second->to_default();
}
}
}
std::string config_context_t::to_string() const
{
std::ostringstream result;
serialize(result);
return result.str();
}

127
Utilities/config_context.h Normal file
View File

@ -0,0 +1,127 @@
#pragma once
#include <unordered_map>
#include <string>
class config_context_t
{
public:
class entry_base;
protected:
class group
{
group* m_parent;
config_context_t* m_cfg;
std::string m_name;
void init();
public:
std::unordered_map<std::string, entry_base *> entries;
group(config_context_t* cfg, const std::string& name);
group(group* parent, const std::string& name);
void set_parent(config_context_t* cfg);
std::string name() const;
std::string full_name() const;
friend config_context_t;
};
public:
class entry_base
{
public:
virtual std::string name() = 0;
virtual void to_default() = 0;
virtual std::string string_value() = 0;
virtual void string_value(const std::string& value) = 0;
virtual void value_from(const entry_base* rhs) = 0;
};
template<typename T>
class entry : public entry_base
{
T m_default_value;
T m_value;
group* m_parent;
std::string m_name;
public:
entry(group* parent, const std::string& name, const T& default_value)
: m_parent(parent)
, m_name(name)
, m_default_value(default_value)
, m_value(default_value)
{
parent->entries[name] = this;
}
T default_value() const
{
return m_default_value;
}
T value() const
{
return m_value;
}
void value(const T& new_value)
{
m_value = new_value;
}
std::string name() override
{
return m_name;
}
void to_default() override
{
value(default_value());
}
std::string string_value() override
{
return convert::to<std::string>(value());
}
void string_value(const std::string &new_value) override
{
value(convert::to<T>(new_value));
}
void value_from(const entry_base* rhs)
{
value(static_cast<const entry*>(rhs)->value());
}
entry& operator = (const T& new_value)
{
value(new_value);
return *this;
}
explicit operator const T&() const
{
return m_value;
}
};
private:
std::unordered_map<std::string, group*> m_groups;
public:
config_context_t() = default;
void assign(const config_context_t& rhs);
void serialize(std::ostream& stream) const;
void deserialize(std::istream& stream);
void set_defaults();
std::string to_string() const;
};

240
Utilities/convert.h Normal file
View File

@ -0,0 +1,240 @@
#pragma once
#include <string>
namespace convert
{
template<typename ReturnType, typename FromType>
struct to_impl_t;
template<typename Type>
struct to_impl_t<Type, Type>
{
static Type func(const Type& value)
{
return value;
}
};
template<>
struct to_impl_t<std::string, bool>
{
static std::string func(bool value)
{
return value ? "true" : "false";
}
};
template<>
struct to_impl_t<bool, std::string>
{
static bool func(const std::string& value)
{
return value == "true" ? true : false;
}
};
template<>
struct to_impl_t<std::string, char>
{
static std::string func(char value)
{
return std::to_string(value);
}
};
template<>
struct to_impl_t<std::string, unsigned char>
{
static std::string func(unsigned char value)
{
return std::to_string(value);
}
};
template<>
struct to_impl_t<std::string, short>
{
static std::string func(short value)
{
return std::to_string(value);
}
};
template<>
struct to_impl_t<std::string, unsigned short>
{
static std::string func(unsigned short value)
{
return std::to_string(value);
}
};
template<>
struct to_impl_t<std::string, int>
{
static std::string func(int value)
{
return std::to_string(value);
}
};
template<>
struct to_impl_t<std::string, unsigned int>
{
static std::string func(unsigned int value)
{
return std::to_string(value);
}
};
template<>
struct to_impl_t<std::string, long>
{
static std::string func(long value)
{
return std::to_string(value);
}
};
template<>
struct to_impl_t<std::string, unsigned long>
{
static std::string func(unsigned long value)
{
return std::to_string(value);
}
};
template<>
struct to_impl_t<std::string, long long>
{
static std::string func(long long value)
{
return std::to_string(value);
}
};
template<>
struct to_impl_t<std::string, unsigned long long>
{
static std::string func(unsigned long long value)
{
return std::to_string(value);
}
};
template<>
struct to_impl_t<std::string, float>
{
static std::string func(float value)
{
return std::to_string(value);
}
};
template<>
struct to_impl_t<std::string, double>
{
static std::string func(double value)
{
return std::to_string(value);
}
};
template<>
struct to_impl_t<std::string, long double>
{
static std::string func(long double value)
{
return std::to_string(value);
}
};
template<>
struct to_impl_t<int, std::string>
{
static int func(const std::string& value)
{
return std::stoi(value);
}
};
template<>
struct to_impl_t<unsigned int, std::string>
{
static unsigned int func(const std::string& value)
{
return (unsigned long)std::stoul(value);
}
};
template<>
struct to_impl_t<long, std::string>
{
static long func(const std::string& value)
{
return std::stol(value);
}
};
template<>
struct to_impl_t<unsigned long, std::string>
{
static unsigned long func(const std::string& value)
{
return std::stoul(value);
}
};
template<>
struct to_impl_t<long long, std::string>
{
static long long func(const std::string& value)
{
return std::stoll(value);
}
};
template<>
struct to_impl_t<unsigned long long, std::string>
{
static unsigned long long func(const std::string& value)
{
return std::stoull(value);
}
};
template<>
struct to_impl_t<float, std::string>
{
static float func(const std::string& value)
{
return std::stof(value);
}
};
template<>
struct to_impl_t<double, std::string>
{
static double func(const std::string& value)
{
return std::stod(value);
}
};
template<>
struct to_impl_t<long double, std::string>
{
static long double func(const std::string& value)
{
return std::stold(value);
}
};
template<typename ReturnType, typename FromType>
ReturnType to(FromType value)
{
return to_impl_t<std::remove_all_extents_t<ReturnType>, std::remove_all_extents_t<FromType>>::func(value);
}
}

420
Utilities/event.h Normal file
View File

@ -0,0 +1,420 @@
#pragma once
#include <functional>
#include <deque>
#include <list>
enum class event_result
{
skip,
handled
};
class events_queue
{
std::deque<std::function<void()>> m_queue;
public:
/*template<typename Type>
events_queue& operator += (event<Type> &evt)
{
evt.set_queue(this);
return *this;
}
*/
void invoke(std::function<void()> function)
{
m_queue.push_back(function);
}
void flush()
{
while (!m_queue.empty())
{
std::function<void()> function = m_queue.front();
function();
m_queue.pop_front();
}
}
};
template<typename ...AT>
class event
{
using func_t = std::function<event_result(AT...)>;
using entry_t = typename std::list<func_t>::iterator;
std::list<func_t> handlers;
events_queue& m_queue;
public:
event(events_queue* queue = nullptr) : m_queue(*queue)
{
}
void invoke(AT... args)
{
m_queue.invoke(std::bind([&](AT... eargs)
{
for (auto &&handler : handlers)
{
if (handler(eargs...) == event_result::handled)
break;
}
}, args...));
}
void operator()(AT... args)
{
invoke(args...);
}
entry_t bind(func_t func)
{
handlers.push_front(func);
return handlers.begin();
}
template<typename T>
entry_t bind(T *caller, event_result(T::*callback)(AT...))
{
return bind([=](AT... args) { return (caller->*callback)(args...); });
}
template<typename T>
entry_t bind(T *caller, void(T::*callback)(AT...))
{
return bind([=](AT... args) { (caller->*callback)(args...); return event_result::skip; });
}
void unbind(entry_t entry)
{
handlers.erase(entry);
}
entry_t operator +=(func_t func)
{
return bind(func);
}
void operator -=(entry_t what)
{
return unbind(what);
}
};
template<>
class event<void>
{
using func_t = std::function<event_result()>;
using entry_t = std::list<func_t>::iterator;
std::list<func_t> m_listeners;
events_queue* m_queue;
void invoke_listeners()
{
for (auto &&listener : m_listeners)
{
if (listener() == event_result::handled)
break;
}
}
public:
event(events_queue* queue = nullptr) : m_queue(queue)
{
}
void invoke()
{
if (m_queue)
m_queue->invoke([=]() { invoke_listeners(); });
else
invoke_listeners();
}
void operator()()
{
invoke();
}
entry_t bind(func_t func)
{
m_listeners.push_front(func);
return m_listeners.begin();
}
template<typename T>
entry_t bind(T *caller, event_result(T::*callback)())
{
return bind([=]() { return (caller->*callback)(); });
}
template<typename T>
entry_t bind(T *caller, void(T::*callback)())
{
return bind([=]() { (caller->*callback)(); return event_result::skip; });
}
void unbind(entry_t what)
{
m_listeners.erase(what);
}
entry_t operator +=(func_t func)
{
return bind(func);
}
void operator -=(entry_t what)
{
return unbind(what);
}
};
class event_binder_t
{
template<typename Type>
class binder_impl_t
{
event_binder_t *m_binder;
event<Type> *m_event;
public:
binder_impl_t(event_binder_t *binder, event<Type> *evt)
: m_binder(binder)
, m_event(evt)
{
}
};
public:
template<typename Type>
binder_impl_t<Type> operator()(event<Type>& evt) const
{
return{ this, &evt };
}
};
template<typename T>
class combined_data;
template<typename T>
class local_data
{
public:
using type = T;
protected:
type m_data;
void set(type value)
{
m_data = value;
}
type get() const
{
return m_data;
}
bool equals(T value) const
{
return get() == value;
}
bool invoke_event(type value)
{
return false;
}
friend combined_data<T>;
};
template<typename T>
class combined_data
{
public:
using type = T;
protected:
local_data<type> m_local_data;
std::function<void(type)> m_invoke_event_function;
std::function<type()> m_get_function;
bool invoke_event(type value)
{
if (m_invoke_event_function)
{
m_invoke_event_function(value);
return true;
}
return false;
}
void set(type value)
{
m_local_data.set(value);
}
type get() const
{
if (m_get_function)
{
return m_get_function();
}
return m_local_data.get();
}
type get_local() const
{
return m_local_data.get();
}
bool equals(T value) const
{
return get_local() == value;
}
public:
void invoke_event_function(std::function<void(type)> function)
{
m_invoke_event_function = function;
}
void get_function(std::function<type()> function)
{
m_get_function = function;
}
};
template<typename T, typename base_type_ = local_data<T>>
class data_event : public base_type_
{
public:
using type = T;
using base_type = base_type_;
protected:
event_result dochange(type new_value)
{
auto old_value = get();
base_type::set(new_value);
onchanged(old_value);
return event_result::handled;
}
public:
event<type> onchange;
event<type> onchanged;
data_event(events_queue *queue = nullptr)
: onchange(queue)
, onchanged(queue)
{
onchange.bind(this, &data_event::dochange);
base_type::set({});
}
type get() const
{
return base_type::get();
}
type operator()() const
{
return get();
}
void change(type value, bool use_custom_invoke_event = true)
{
if (!base_type::equals(value))
{
if (!use_custom_invoke_event || !base_type::invoke_event(value))
{
onchange(value);
}
}
}
operator const type() const
{
return get();
}
operator type()
{
return get();
}
data_event& operator = (type value)
{
change(value);
return *this;
}
template<typename aType> auto operator + (aType value) const { return get() + value; }
template<typename aType> auto operator - (aType value) const { return get() - value; }
template<typename aType> auto operator * (aType value) const { return get() * value; }
template<typename aType> auto operator / (aType value) const { return get() / value; }
template<typename aType> auto operator % (aType value) const { return get() % value; }
template<typename aType> auto operator & (aType value) const { return get() & value; }
template<typename aType> auto operator | (aType value) const { return get() | value; }
template<typename aType> auto operator ^ (aType value) const { return get() ^ value; }
template<typename aType> data_event& operator += (aType value) { return *this = get() + value; }
template<typename aType> data_event& operator -= (aType value) { return *this = get() - value; }
template<typename aType> data_event& operator *= (aType value) { return *this = get() * value; }
template<typename aType> data_event& operator /= (aType value) { return *this = get() / value; }
template<typename aType> data_event& operator %= (aType value) { return *this = get() % value; }
template<typename aType> data_event& operator &= (aType value) { return *this = get() & value; }
template<typename aType> data_event& operator |= (aType value) { return *this = get() | value; }
template<typename aType> data_event& operator ^= (aType value) { return *this = get() ^ value; }
data_event& operator ++()
{
type value = get();
return *this = ++value;
}
type operator ++(int)
{
type value = get();
type result = value;
*this = value++;
return result;
}
data_event& operator --()
{
type value = get();
return *this = --value;
}
type operator --(int)
{
type value = get();
type result = value;
*this = value--;
return result;
}
};
struct with_event_binder
{
event_binder_t event_binder;
};
struct test_obj
{
void test(int)
{
event<int> i;
auto it = i.bind(this, &test_obj::test);
i(5);
i.unbind(it);
i(6);
}
};

View File

@ -8,6 +8,7 @@
#include <chrono>
#include "d3dx12.h"
#include <d3d11on12.h>
#include "Emu/state.h"
PFN_D3D12_CREATE_DEVICE wrapD3D12CreateDevice;
PFN_D3D12_GET_DEBUG_INTERFACE wrapD3D12GetDebugInterface;
@ -928,10 +929,10 @@ void D3D12GSRender::semaphore_PGRAPH_backend_release(u32 offset, u32 value)
u32 m_context_dma_color_d = rsx::method_registers[NV4097_SET_CONTEXT_DMA_COLOR_D];
u32 m_context_dma_z = rsx::method_registers[NV4097_SET_CONTEXT_DMA_ZETA];
bool needTransfer = (m_context_dma_z && Ini.GSDumpDepthBuffer.GetValue()) ||
((m_context_dma_color_a || m_context_dma_color_b || m_context_dma_color_c || m_context_dma_color_d) && Ini.GSDumpColorBuffers.GetValue());
bool needTransfer = (m_context_dma_z && rpcs3::state.config.rsx.opengl.write_depth_buffer) ||
((m_context_dma_color_a || m_context_dma_color_b || m_context_dma_color_c || m_context_dma_color_d) && rpcs3::state.config.rsx.opengl.write_color_buffers);
if (m_context_dma_z && Ini.GSDumpDepthBuffer.GetValue())
if (m_context_dma_z && rpcs3::state.config.rsx.opengl.write_depth_buffer)
{
size_t sizeInByte = clip_w * clip_h * 2;
assert(m_UAVHeap.canAlloc(sizeInByte));
@ -1016,7 +1017,7 @@ void D3D12GSRender::semaphore_PGRAPH_backend_release(u32 offset, u32 value)
}
ID3D12Resource *rtt0, *rtt1, *rtt2, *rtt3;
if (Ini.GSDumpColorBuffers.GetValue())
if (rpcs3::state.config.rsx.opengl.write_color_buffers)
{
switch (rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])
{
@ -1067,7 +1068,7 @@ void D3D12GSRender::semaphore_PGRAPH_backend_release(u32 offset, u32 value)
WaitForSingleObject(handle, INFINITE);
CloseHandle(handle);
if (m_context_dma_z && Ini.GSDumpDepthBuffer.GetValue())
if (m_context_dma_z && rpcs3::state.config.rsx.opengl.write_depth_buffer)
{
u32 address = rsx::get_address(rsx::method_registers[NV4097_SET_SURFACE_ZETA_OFFSET], m_context_dma_z - 0xfeed0000);
auto ptr = vm::get_ptr<void>(address);
@ -1101,7 +1102,7 @@ void D3D12GSRender::semaphore_PGRAPH_backend_release(u32 offset, u32 value)
break;
}
if (Ini.GSDumpColorBuffers.GetValue())
if (rpcs3::state.config.rsx.opengl.write_color_buffers)
{
switch (rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])
{

View File

@ -6,6 +6,7 @@
#include "Emu/Memory/Memory.h"
#include "Emu/System.h"
#include "GLGSRender.h"
#include "Emu/state.h"
#define DUMP_VERTEX_DATA 0
@ -1536,7 +1537,7 @@ void GLGSRender::read_buffers()
glDisable(GL_STENCIL_TEST);
if (Ini.GSReadColorBuffers.GetValue())
if (rpcs3::state.config.rsx.opengl.read_color_buffers)
{
auto color_format = surface_color_format_to_gl(m_surface.color_format);
@ -1576,7 +1577,7 @@ void GLGSRender::read_buffers()
}
}
if (Ini.GSReadDepthBuffer.GetValue())
if (rpcs3::state.config.rsx.opengl.read_depth_buffer)
{
auto depth_format = surface_depth_format_to_gl(m_surface.depth_format);
@ -1618,7 +1619,7 @@ void GLGSRender::write_buffers()
if (!draw_fbo)
return;
if (Ini.GSDumpColorBuffers.GetValue())
if (rpcs3::state.config.rsx.opengl.write_color_buffers)
{
//gl::buffer pbo_color;
//__glcheck pbo_color.create(m_draw_tex_color[0].width() * m_draw_tex_color[0].height() * 4);
@ -1678,7 +1679,7 @@ void GLGSRender::write_buffers()
}
}
if (Ini.GSDumpDepthBuffer.GetValue())
if (rpcs3::state.config.rsx.opengl.write_depth_buffer)
{
auto depth_format = surface_depth_format_to_gl(m_surface.depth_format);
@ -1725,7 +1726,7 @@ void GLGSRender::flip(int buffer)
u32 buffer_address = rsx::get_address(gcm_buffers[buffer].offset, CELL_GCM_LOCATION_LOCAL);
bool skip_read = false;
if (draw_fbo && !Ini.GSDumpColorBuffers.GetValue())
if (draw_fbo && !rpcs3::state.config.rsx.opengl.write_color_buffers)
{
skip_read = true;
/*

View File

@ -1,4 +1,9 @@
#include "stdafx.h"
#include "config.h"
#include "events.h"
#include "state.h"
#include "Utilities/Log.h"
#include "Utilities/File.h"
#include "rpcs3/Ini.h"
@ -61,6 +66,8 @@ Emulator::Emulator()
void Emulator::Init()
{
rpcs3::config.load();
rpcs3::oninit();
}
void Emulator::SetPath(const std::string& path, const std::string& elf_path)
@ -166,6 +173,9 @@ void Emulator::Load()
}
}
//TODO: load custom config if exists
rpcs3::state.config = rpcs3::config;
LOG_NOTICE(LOADER, "Loading '%s'...", m_path.c_str());
ResetInfo();
GetVFS().Init(elf_dir);
@ -213,14 +223,18 @@ void Emulator::Load()
}
LOG_NOTICE(LOADER, "Resolution: %s", Ini.ResolutionIdToString(Ini.GSResolution.GetValue()));
LOG_NOTICE(LOADER, "Write Depth Buffer: %s", Ini.GSDumpDepthBuffer.GetValue() ? "Yes" : "No");
/*LOG_NOTICE(LOADER, "Write Depth Buffer: %s", Ini.GSDumpDepthBuffer.GetValue() ? "Yes" : "No");
LOG_NOTICE(LOADER, "Write Color Buffers: %s", Ini.GSDumpColorBuffers.GetValue() ? "Yes" : "No");
LOG_NOTICE(LOADER, "Read Color Buffers: %s", Ini.GSReadColorBuffers.GetValue() ? "Yes" : "No");
LOG_NOTICE(LOADER, "Read Depth Buffer: %s", Ini.GSReadDepthBuffer.GetValue() ? "Yes" : "No");
LOG_NOTICE(LOADER, "Read Depth Buffer: %s", Ini.GSReadDepthBuffer.GetValue() ? "Yes" : "No");*/
LOG_NOTICE(LOADER, "Audio Out: %s", Ini.AudioOutIdToString(Ini.AudioOutMode.GetValue()));
LOG_NOTICE(LOADER, "Log Everything: %s", Ini.HLELogging.GetValue() ? "Yes" : "No");
LOG_NOTICE(LOADER, "RSX Logging: %s", Ini.RSXLogging.GetValue() ? "Yes" : "No");
LOG_NOTICE(LOADER, "");
LOG_NOTICE(LOADER, rpcs3::config.to_string().c_str());
LOG_NOTICE(LOADER, "");
f.Open("/app_home/../PARAM.SFO");
const PSFLoader psf(f);
@ -284,6 +298,8 @@ void Emulator::Run()
return;
}
rpcs3::onstart();
SendDbgCommand(DID_START_EMU);
m_pause_start_time = 0;
@ -304,6 +320,8 @@ bool Emulator::Pause()
return false;
}
rpcs3::onpause();
// update pause start time
if (m_pause_start_time.exchange(start))
{
@ -351,6 +369,8 @@ void Emulator::Resume()
t->awake(); // untrigger status check and signal
}
rpcs3::onstart();
SendDbgCommand(DID_RESUMED_EMU);
}
@ -365,6 +385,7 @@ void Emulator::Stop()
return;
}
rpcs3::onstop();
SendDbgCommand(DID_STOP_EMU);
{

10
rpcs3/Emu/events.cpp Normal file
View File

@ -0,0 +1,10 @@
#include "stdafx.h"
#include "events.h"
namespace rpcs3
{
event<void> oninit;
event<void> onstart;
event<void> onstop;
event<void> onpause;
}

10
rpcs3/Emu/events.h Normal file
View File

@ -0,0 +1,10 @@
#pragma once
#include "Utilities/event.h"
namespace rpcs3
{
extern event<void> oninit;
extern event<void> onstart;
extern event<void> onstop;
extern event<void> onpause;
}

9
rpcs3/Emu/state.cpp Normal file
View File

@ -0,0 +1,9 @@
#include "stdafx.h"
#include "state.h"
#include <sstream>
#include <type_traits>
namespace rpcs3
{
state_t state;
}

15
rpcs3/Emu/state.h Normal file
View File

@ -0,0 +1,15 @@
#pragma once
#include "config.h"
namespace rpcs3
{
struct state_t
{
config_t config;
std::string path_to_elf;
std::string virtual_path_to_elf;
};
extern state_t state;
}

View File

@ -7,6 +7,22 @@
#include "Utilities/Log.h"
#include <wx/radiobox.h>
#ifdef _WIN32
#include <windows.h>
#include <iphlpapi.h>
#pragma comment(lib, "iphlpapi.lib")
#else
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netdb.h>
#include <ifaddrs.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#endif
#if defined(DX12_SUPPORT)
#undef GetHwnd
#include <d3d12.h>
@ -14,7 +30,66 @@
#include <dxgi1_4.h>
#endif
SettingsDialog::SettingsDialog(wxWindow *parent)
std::vector<std::string> GetAdapters()
{
std::vector<std::string> adapters;
#ifdef _WIN32
PIP_ADAPTER_INFO pAdapterInfo;
pAdapterInfo = (IP_ADAPTER_INFO*)malloc(sizeof(IP_ADAPTER_INFO));
ULONG buflen = sizeof(IP_ADAPTER_INFO);
if (GetAdaptersInfo(pAdapterInfo, &buflen) == ERROR_BUFFER_OVERFLOW)
{
free(pAdapterInfo);
pAdapterInfo = (IP_ADAPTER_INFO*)malloc(buflen);
}
if (GetAdaptersInfo(pAdapterInfo, &buflen) == NO_ERROR)
{
PIP_ADAPTER_INFO pAdapter = pAdapterInfo;
while (pAdapter)
{
adapters.emplace_back(pAdapter->Description);
pAdapter = pAdapter->Next;
}
}
else
{
LOG_ERROR(HLE, "Call to GetAdaptersInfo failed.");
}
#else
struct ifaddrs *ifaddr, *ifa;
int family, s, n;
char host[NI_MAXHOST];
if (getifaddrs(&ifaddr) == -1)
{
LOG_ERROR(HLE, "Call to getifaddrs returned negative.");
}
for (ifa = ifaddr, n = 0; ifa != NULL; ifa = ifa->ifa_next, n++)
{
if (ifa->ifa_addr == NULL)
{
continue;
}
family = ifa->ifa_addr->sa_family;
if (family == AF_INET || family == AF_INET6)
{
adapters.emplace_back(ifa->ifa_name);
}
}
freeifaddrs(ifaddr);
#endif
return adapters;
}
SettingsDialog::SettingsDialog(wxWindow *parent, rpcs3::config_t* cfg)
: wxDialog(parent, wxID_ANY, "Settings", wxDefaultPosition)
{
bool paused = false;
@ -203,6 +278,7 @@ SettingsDialog::SettingsDialog(wxWindow *parent)
#if defined (_WIN32)
cbox_pad_handler->Append("XInput");
#endif
//cbox_pad_handler->Append("DirectInput");
cbox_keyboard_handler->Append("Null");
@ -255,10 +331,10 @@ SettingsDialog::SettingsDialog(wxWindow *parent)
// Get values from .ini
chbox_core_llvm_exclud->SetValue(Ini.LLVMExclusionRange.GetValue());
chbox_gs_log_prog->SetValue(Ini.GSLogPrograms.GetValue());
chbox_gs_dump_depth->SetValue(Ini.GSDumpDepthBuffer.GetValue());
chbox_gs_dump_color->SetValue(Ini.GSDumpColorBuffers.GetValue());
chbox_gs_read_color->SetValue(Ini.GSReadColorBuffers.GetValue());
chbox_gs_read_depth->SetValue(Ini.GSReadDepthBuffer.GetValue());
chbox_gs_dump_depth->SetValue((bool)cfg->rsx.opengl.write_depth_buffer);
chbox_gs_dump_color->SetValue((bool)cfg->rsx.opengl.write_color_buffers);
chbox_gs_read_color->SetValue((bool)cfg->rsx.opengl.read_color_buffers);
chbox_gs_read_depth->SetValue((bool)cfg->rsx.opengl.read_depth_buffer);
chbox_gs_vsync->SetValue(Ini.GSVSyncEnable.GetValue());
chbox_gs_debug_output->SetValue(Ini.GSDebugOutputEnable.GetValue());
chbox_gs_3dmonitor->SetValue(Ini.GS3DTV.GetValue());
@ -438,10 +514,10 @@ SettingsDialog::SettingsDialog(wxWindow *parent)
Ini.GSAspectRatio.SetValue(cbox_gs_aspect->GetSelection() + 1);
Ini.GSFrameLimit.SetValue(cbox_gs_frame_limit->GetSelection());
Ini.GSLogPrograms.SetValue(chbox_gs_log_prog->GetValue());
Ini.GSDumpDepthBuffer.SetValue(chbox_gs_dump_depth->GetValue());
Ini.GSDumpColorBuffers.SetValue(chbox_gs_dump_color->GetValue());
Ini.GSReadColorBuffers.SetValue(chbox_gs_read_color->GetValue());
Ini.GSReadDepthBuffer.SetValue(chbox_gs_read_depth->GetValue());
cfg->rsx.opengl.write_depth_buffer = chbox_gs_dump_depth->GetValue();
cfg->rsx.opengl.write_color_buffers = chbox_gs_dump_color->GetValue();
cfg->rsx.opengl.read_color_buffers = chbox_gs_read_color->GetValue();
cfg->rsx.opengl.read_depth_buffer = chbox_gs_read_depth->GetValue();
Ini.GSVSyncEnable.SetValue(chbox_gs_vsync->GetValue());
Ini.GSDebugOutputEnable.SetValue(chbox_gs_debug_output->GetValue());
Ini.GS3DTV.SetValue(chbox_gs_3dmonitor->GetValue());
@ -472,6 +548,7 @@ SettingsDialog::SettingsDialog(wxWindow *parent)
Ini.SysEmulationDirPathEnable.SetValue(chbox_emulationdir_enable->GetValue());
Ini.SysEmulationDirPath.SetValue(txt_emulationdir_path->GetValue().ToStdString());
cfg->save();
Ini.Save();
}

View File

@ -1,82 +1,11 @@
#pragma once
#include "Utilities/Log.h"
#include "config.h"
#ifdef _WIN32
#include <windows.h>
#include <iphlpapi.h>
#pragma comment(lib, "iphlpapi.lib")
#else
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netdb.h>
#include <ifaddrs.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#endif
std::vector<std::string> GetAdapters();
class SettingsDialog : public wxDialog
{
public:
SettingsDialog(wxWindow *parent);
SettingsDialog(wxWindow *parent, rpcs3::config_t* cfg = &rpcs3::config);
};
static std::vector<std::string> GetAdapters()
{
std::vector<std::string> adapters;
#ifdef _WIN32
PIP_ADAPTER_INFO pAdapterInfo;
pAdapterInfo = (IP_ADAPTER_INFO*)malloc(sizeof(IP_ADAPTER_INFO));
ULONG buflen = sizeof(IP_ADAPTER_INFO);
if (GetAdaptersInfo(pAdapterInfo, &buflen) == ERROR_BUFFER_OVERFLOW)
{
free(pAdapterInfo);
pAdapterInfo = (IP_ADAPTER_INFO*)malloc(buflen);
}
if (GetAdaptersInfo(pAdapterInfo, &buflen) == NO_ERROR)
{
PIP_ADAPTER_INFO pAdapter = pAdapterInfo;
while (pAdapter)
{
adapters.emplace_back(pAdapter->Description);
pAdapter = pAdapter->Next;
}
}
else
{
LOG_ERROR(HLE, "Call to GetAdaptersInfo failed.");
}
#else
struct ifaddrs *ifaddr, *ifa;
int family, s, n;
char host[NI_MAXHOST];
if (getifaddrs(&ifaddr) == -1)
{
LOG_ERROR(HLE, "Call to getifaddrs returned negative.");
}
for (ifa = ifaddr, n = 0; ifa != NULL; ifa = ifa->ifa_next, n++)
{
if (ifa->ifa_addr == NULL)
{
continue;
}
family = ifa->ifa_addr->sa_family;
if (family == AF_INET || family == AF_INET6)
{
adapters.emplace_back(ifa->ifa_name);
}
}
freeifaddrs(ifaddr);
#endif
return adapters;
}

View File

@ -109,10 +109,6 @@ public:
IniEntry<u8> GSAspectRatio;
IniEntry<u8> GSFrameLimit;
IniEntry<bool> GSLogPrograms;
IniEntry<bool> GSDumpColorBuffers;
IniEntry<bool> GSDumpDepthBuffer;
IniEntry<bool> GSReadColorBuffers;
IniEntry<bool> GSReadDepthBuffer;
IniEntry<bool> GSVSyncEnable;
IniEntry<bool> GS3DTV;
IniEntry<bool> GSDebugOutputEnable;
@ -201,10 +197,6 @@ public:
GSAspectRatio.Init("GS_AspectRatio", path);
GSFrameLimit.Init("GS_FrameLimit", path);
GSLogPrograms.Init("GS_LogPrograms", path);
GSDumpColorBuffers.Init("GS_DumpColorBuffers", path);
GSDumpDepthBuffer.Init("GS_DumpDepthBuffer", path);
GSReadColorBuffers.Init("GS_ReadColorBuffer", path);
GSReadDepthBuffer.Init("GS_ReadDepthBuffer", path);
GSVSyncEnable.Init("GS_VSyncEnable", path);
GSDebugOutputEnable.Init("GS_DebugOutputEnable", path);
GS3DTV.Init("GS_3DTV", path);
@ -289,10 +281,6 @@ public:
GSAspectRatio.Load(2);
GSFrameLimit.Load(0);
GSLogPrograms.Load(false);
GSDumpColorBuffers.Load(false);
GSDumpDepthBuffer.Load(false);
GSReadColorBuffers.Load(false);
GSReadDepthBuffer.Load(false);
GSVSyncEnable.Load(false);
GSDebugOutputEnable.Load(false);
GS3DTV.Load(false);
@ -377,10 +365,6 @@ public:
GSAspectRatio.Save();
GSFrameLimit.Save();
GSLogPrograms.Save();
GSDumpColorBuffers.Save();
GSDumpDepthBuffer.Save();
GSReadColorBuffers.Save();
GSReadDepthBuffer.Save();
GSVSyncEnable.Save();
GSDebugOutputEnable.Save();
GS3DTV.Save();

45
rpcs3/config.cpp Normal file
View File

@ -0,0 +1,45 @@
#include "stdafx.h"
#include "config.h"
#include <fstream>
namespace rpcs3
{
config_t::config_t(const std::string &path_)
{
path(path_);
}
config_t::config_t(const config_t& rhs)
{
assign(rhs);
}
config_t& config_t::operator =(const config_t& rhs)
{
assign(rhs);
return *this;
}
void config_t::path(const std::string &new_path)
{
m_path = new_path;
}
std::string config_t::path() const
{
return m_path;
}
void config_t::load()
{
if (!m_path.empty())
deserialize(std::ifstream{ m_path });
}
void config_t::save() const
{
if (!m_path.empty())
serialize(std::ofstream{ m_path });
}
config_t config{ "rpcs3.new.ini" };
}

241
rpcs3/config.h Normal file
View File

@ -0,0 +1,241 @@
#pragma once
#include "Utilities/convert.h"
#include "Utilities/config_context.h"
enum class audio_output_type
{
Null,
OpenAL,
XAudio2
};
template<>
struct convert::to_impl_t<std::string, audio_output_type>
{
static std::string func(audio_output_type value)
{
switch (value)
{
case audio_output_type::Null: return "Null";
case audio_output_type::OpenAL: return "OpenAL";
case audio_output_type::XAudio2: return "XAudio2";
}
return "Unknown";
}
};
template<>
struct convert::to_impl_t<audio_output_type, std::string>
{
static audio_output_type func(const std::string &value)
{
if (value == "Null")
return audio_output_type::Null;
if (value == "OpenAL")
return audio_output_type::OpenAL;
if (value == "XAudio2")
return audio_output_type::XAudio2;
return audio_output_type::Null;
}
};
enum class rsx_renderer_type
{
Null,
OpenGL,
DX12
};
template<>
struct convert::to_impl_t<std::string, rsx_renderer_type>
{
static std::string func(rsx_renderer_type value)
{
switch (value)
{
case rsx_renderer_type::Null: return "Null";
case rsx_renderer_type::OpenGL: return "OpenGL";
case rsx_renderer_type::DX12: return "DX12";
}
return "Unknown";
}
};
template<>
struct convert::to_impl_t<rsx_renderer_type, std::string>
{
static rsx_renderer_type func(const std::string &value)
{
if (value == "Null")
return rsx_renderer_type::Null;
if (value == "OpenGL")
return rsx_renderer_type::OpenGL;
if (value == "DX12")
return rsx_renderer_type::DX12;
return rsx_renderer_type::Null;
}
};
enum class ppu_decoder_type
{
interpreter,
interpreter2,
recompiler_llvm
};
template<>
struct convert::to_impl_t<std::string, ppu_decoder_type>
{
static std::string func(ppu_decoder_type value)
{
switch (value)
{
case ppu_decoder_type::interpreter: return "interpreter";
case ppu_decoder_type::interpreter2: return "interpreter2";
case ppu_decoder_type::recompiler_llvm: return "recompiler_llvm";
}
return "Unknown";
}
};
template<>
struct convert::to_impl_t<ppu_decoder_type, std::string>
{
static ppu_decoder_type func(const std::string &value)
{
if (value == "interpreter")
return ppu_decoder_type::interpreter;
if (value == "interpreter2")
return ppu_decoder_type::interpreter2;
if (value == "DX12")
return ppu_decoder_type::recompiler_llvm;
return ppu_decoder_type::interpreter;
}
};
enum class spu_decoder_type
{
interpreter_precise,
interpreter_fast,
recompiler_asmjit
};
template<>
struct convert::to_impl_t<std::string, spu_decoder_type>
{
static std::string func(spu_decoder_type value)
{
switch (value)
{
case spu_decoder_type::interpreter_precise: return "interpreter_precise";
case spu_decoder_type::interpreter_fast: return "interpreter_fast";
case spu_decoder_type::recompiler_asmjit: return "recompiler_asmjit";
}
return "Unknown";
}
};
template<>
struct convert::to_impl_t<spu_decoder_type, std::string>
{
static spu_decoder_type func(const std::string &value)
{
if (value == "interpreter_precise")
return spu_decoder_type::interpreter_precise;
if (value == "interpreter_fast")
return spu_decoder_type::interpreter_fast;
if (value == "recompiler_asmjit")
return spu_decoder_type::recompiler_asmjit;
return spu_decoder_type::interpreter_precise;
}
};
namespace rpcs3
{
class config_t : public config_context_t
{
std::string m_path;
public:
struct core_group : protected group
{
core_group(config_context_t *cfg) : group{ cfg, "core" } {}
entry<ppu_decoder_type> ppu_decoder{ this, "PPU Decoder", ppu_decoder_type::interpreter };
entry<spu_decoder_type> spu_decoder{ this, "SPU Decoder", spu_decoder_type::interpreter_precise };
entry<bool> load_liblv2{ this, "Load liblv2.sprx", false };
} core{ this };
struct rsx_group : protected group
{
struct opengl_group : protected group
{
opengl_group(group *grp) : group{ grp, "opengl" } {}
entry<bool> write_color_buffers{ this, "Write Color Buffers", true };
entry<bool> write_depth_buffer{ this, "Write Depth Buffer", true };
entry<bool> read_color_buffers{ this, "Read Color Buffers", true };
entry<bool> read_depth_buffer{ this, "Read Depth Buffer", true };
} opengl{ this };
rsx_group(config_context_t *cfg) : group{ cfg, "rsx" } {}
entry<rsx_renderer_type> renderer{ this, "Renderer", rsx_renderer_type::OpenGL };
} rsx{ this };
struct audio_group : protected group
{
audio_group(config_context_t *cfg) : group{ cfg, "audio" } {}
entry<audio_output_type> test{ this, "Audio Out", audio_output_type::OpenAL };
} audio{ this };
struct io_group : protected group
{
io_group(config_context_t *cfg) : group{ cfg, "io" } {}
} io{ this };
struct misc_group : protected group
{
misc_group(config_context_t *cfg) : group{ cfg, "misc" } {}
} misc{ this };
struct system_group : protected group
{
system_group(config_context_t *cfg) : group{ cfg, "system" } {}
} system{ this };
config_t() = default;
config_t(const std::string &path);
config_t(const config_t& rhs);
config_t(config_t&& rhs) = delete;
config_t& operator =(const config_t& rhs);
config_t& operator =(config_t&& rhs) = delete;
void path(const std::string &new_path);
std::string path() const;
void load();
void save() const;
};
extern config_t config;
}

View File

@ -40,6 +40,7 @@
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\Utilities\AutoPause.cpp" />
<ClCompile Include="..\Utilities\config_context.cpp" />
<ClCompile Include="..\Utilities\Log.cpp" />
<ClCompile Include="..\Utilities\File.cpp" />
<ClCompile Include="..\Utilities\rMsgBox.cpp" />
@ -52,11 +53,13 @@
<ClCompile Include="..\Utilities\StrFmt.cpp" />
<ClCompile Include="..\Utilities\Thread.cpp" />
<ClCompile Include="..\Utilities\VirtualMemory.cpp" />
<ClCompile Include="config.cpp" />
<ClCompile Include="Emu\Cell\PPUInterpreter.cpp" />
<ClCompile Include="Emu\Cell\PPULLVMRecompilerCore.cpp" />
<ClCompile Include="Emu\Cell\SPUAnalyser.cpp" />
<ClCompile Include="Emu\Cell\SPUASMJITRecompiler.cpp" />
<ClCompile Include="Emu\Cell\SPUInterpreter.cpp" />
<ClCompile Include="Emu\events.cpp" />
<ClCompile Include="Emu\IdManager.cpp" />
<ClCompile Include="Emu\RSX\CgBinaryFragmentProgram.cpp" />
<ClCompile Include="Emu\RSX\CgBinaryVertexProgram.cpp" />
@ -78,6 +81,7 @@
<ClCompile Include="Emu\RSX\GL\GLCommonDecompiler.cpp" />
<ClCompile Include="Emu\RSX\GL\gl_helpers.cpp" />
<ClCompile Include="Emu\RSX\Null\NullGSRender.cpp" />
<ClCompile Include="Emu\state.cpp" />
<ClCompile Include="Emu\SysCalls\lv2\sys_dbg.cpp" />
<ClCompile Include="Emu\SysCalls\lv2\sys_fs.cpp" />
<ClCompile Include="Emu\SysCalls\Modules\cellAtracMulti.cpp" />
@ -379,6 +383,9 @@
<ClInclude Include="..\Utilities\Atomic.h" />
<ClInclude Include="..\Utilities\AutoPause.h" />
<ClInclude Include="..\Utilities\BEType.h" />
<ClInclude Include="..\Utilities\config_context.h" />
<ClInclude Include="..\Utilities\convert.h" />
<ClInclude Include="..\Utilities\event.h" />
<ClInclude Include="..\Utilities\GNU.h" />
<ClInclude Include="..\Utilities\MTRingbuffer.h" />
<ClInclude Include="..\Utilities\Log.h" />
@ -397,6 +404,7 @@
<ClInclude Include="..\Utilities\Timer.h" />
<ClInclude Include="..\Utilities\types.h" />
<ClInclude Include="..\Utilities\VirtualMemory.h" />
<ClInclude Include="config.h" />
<ClInclude Include="Crypto\aes.h" />
<ClInclude Include="Crypto\ec.h" />
<ClInclude Include="Crypto\key_vault.h" />
@ -508,6 +516,7 @@
<ClInclude Include="Emu\CPU\CPUThreadManager.h" />
<ClInclude Include="Emu\DbgCommand.h" />
<ClInclude Include="Emu\Event.h" />
<ClInclude Include="Emu\events.h" />
<ClInclude Include="Emu\FS\VFS.h" />
<ClInclude Include="Emu\FS\vfsDevice.h" />
<ClInclude Include="Emu\FS\vfsDeviceLocalFile.h" />
@ -572,6 +581,7 @@
<ClInclude Include="Emu\Memory\vm_ptr.h" />
<ClInclude Include="Emu\Memory\vm_ref.h" />
<ClInclude Include="Emu\Memory\vm_var.h" />
<ClInclude Include="Emu\state.h" />
<ClInclude Include="Emu\SysCalls\Callback.h" />
<ClInclude Include="Emu\SysCalls\CB_FUNC.h" />
<ClInclude Include="Emu\SysCalls\ErrorCodes.h" />

View File

@ -1001,6 +1001,16 @@
<ClCompile Include="Emu\RSX\GL\gl_helpers.cpp">
<Filter>Emu\GPU\RSX\GL</Filter>
</ClCompile>
<ClCompile Include="..\Utilities\config_context.cpp">
<Filter>Utilities</Filter>
</ClCompile>
<ClCompile Include="config.cpp" />
<ClCompile Include="Emu\events.cpp">
<Filter>Emu</Filter>
</ClCompile>
<ClCompile Include="Emu\state.cpp">
<Filter>Emu</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Crypto\aes.h">
@ -1906,5 +1916,21 @@
<ClInclude Include="Emu\RSX\GL\gl_helpers.h">
<Filter>Emu\GPU\RSX\GL</Filter>
</ClInclude>
<ClInclude Include="..\Utilities\config_context.h">
<Filter>Utilities</Filter>
</ClInclude>
<ClInclude Include="..\Utilities\convert.h">
<Filter>Utilities</Filter>
</ClInclude>
<ClInclude Include="..\Utilities\event.h">
<Filter>Utilities</Filter>
</ClInclude>
<ClInclude Include="config.h" />
<ClInclude Include="Emu\events.h">
<Filter>Emu</Filter>
</ClInclude>
<ClInclude Include="Emu\state.h">
<Filter>Emu</Filter>
</ClInclude>
</ItemGroup>
</Project>