Formatting system improved

`unveil<>` renamed to `fmt_unveil<>`, now packs args to u64 imitating va_args
`bijective...` removed, `cfg::enum_entry` now uses formatting system
`fmt_class_string<>` added, providing type-specific "%s" handler function
Added `fmt::append`, removed `fmt::narrow` (too obscure)
Utilities/cfmt.h: C-style format template function (WIP)
Minor formatting fixes and cleanup
This commit is contained in:
Nekotekina 2016-08-03 23:51:05 +03:00
parent 662fce38bd
commit 5a36c57c57
63 changed files with 1305 additions and 469 deletions

View File

@ -298,10 +298,6 @@ union alignas(16) v128
_u64[0] = 0; _u64[0] = 0;
_u64[1] = 0; _u64[1] = 0;
} }
std::string to_hex() const;
std::string to_xyzw() const;
}; };
inline v128 operator |(const v128& left, const v128& right) inline v128 operator |(const v128& left, const v128& right)
@ -950,11 +946,13 @@ template<typename T> using atomic_le_t = atomic_t<le_t<T>>;
// Formatting for BE/LE data // Formatting for BE/LE data
template<typename T, bool Se, std::size_t Align> template<typename T, bool Se, std::size_t Align>
struct unveil<se_t<T, Se, Align>, void> struct fmt_unveil<se_t<T, Se, Align>, void>
{ {
static inline auto get(const se_t<T, Se, Align>& arg) using type = typename fmt_unveil<T>::type;
static inline u64 get(const se_t<T, Se, Align>& arg)
{ {
return unveil<T>::get(arg); return fmt_unveil<T>::get(arg);
} }
}; };

View File

@ -242,3 +242,36 @@ struct ff_t : bf_base<T, N>
return V; return V;
} }
}; };
template<typename T, uint I, uint N>
struct fmt_unveil<bf_t<T, I, N>, void>
{
using type = typename fmt_unveil<simple_t<T>>::type;
static inline u64 get(const bf_t<T, I, N>& bf)
{
return fmt_unveil<type>::get(bf);
}
};
template<typename F, typename... Fields>
struct fmt_unveil<cf_t<F, Fields...>, void>
{
using type = typename fmt_unveil<simple_t<typename F::type>>::type;
static inline u64 get(const cf_t<F, Fields...>& cf)
{
return fmt_unveil<type>::get(cf);
}
};
template<typename T, T V, uint N>
struct fmt_unveil<ff_t<T, V, N>, void>
{
using type = typename fmt_unveil<simple_t<T>>::type;
static inline u64 get(const ff_t<T, V, N>& ff)
{
return fmt_unveil<type>::get(ff);
}
};

View File

@ -256,3 +256,14 @@ struct atomic_test_and_complement<bitset_t<T>, T, std::enable_if_t<std::is_enum<
static constexpr auto atomic_op = &_op; static constexpr auto atomic_op = &_op;
}; };
template<typename T, std::size_t BitSize>
struct fmt_unveil<bitset_t<T, BitSize>, void>
{
using type = typename bitset_t<T, BitSize>::raw_type;
static inline u64 get(const bitset_t<T, BitSize>& value)
{
return fmt_unveil<type>::get(static_cast<type>(value._value()));
}
};

View File

@ -85,6 +85,62 @@ bool cfg::try_to_int64(s64* out, const std::string& value, s64 min, s64 max)
return true; return true;
} }
bool cfg::try_to_enum_value(u64* out, decltype(&fmt_class_string<int>::format) func, const std::string& value)
{
for (u64 i = 0;; i++)
{
std::string var;
func(var, i);
if (var == value)
{
if (out) *out = i;
return true;
}
std::string hex;
fmt_class_string<u64>::format(hex, i);
if (var == hex)
{
break;
}
}
try
{
const auto val = std::stoull(value, nullptr, 0);
if (out) *out = val;
return true;
}
catch (...)
{
return false;
}
}
std::vector<std::string> cfg::try_to_enum_list(decltype(&fmt_class_string<int>::format) func)
{
std::vector<std::string> result;
for (u64 i = 0;; i++)
{
std::string var;
func(var, i);
std::string hex;
fmt_class_string<u64>::format(hex, i);
if (var == hex)
{
break;
}
result.emplace_back(std::move(var));
}
return result;
}
void cfg::encode(YAML::Emitter& out, const cfg::entry_base& rhs) void cfg::encode(YAML::Emitter& out, const cfg::entry_base& rhs)
{ {
switch (rhs.get_type()) switch (rhs.get_type())

View File

@ -2,6 +2,7 @@
#include "Utilities/types.h" #include "Utilities/types.h"
#include "Utilities/Atomic.h" #include "Utilities/Atomic.h"
#include "Utilities/StrFmt.h"
#include <initializer_list> #include <initializer_list>
#include <exception> #include <exception>
@ -18,6 +19,12 @@ namespace cfg
// Convert string to signed integer // Convert string to signed integer
bool try_to_int64(s64* out, const std::string& value, s64 min, s64 max); bool try_to_int64(s64* out, const std::string& value, s64 min, s64 max);
// Internal hack
bool try_to_enum_value(u64* out, decltype(&fmt_class_string<int>::format) func, const std::string&);
// Internal hack
std::vector<std::string> try_to_enum_list(decltype(&fmt_class_string<int>::format) func);
// Config tree entry type. // Config tree entry type.
enum class type : uint enum class type : uint
{ {
@ -296,26 +303,26 @@ namespace cfg
std::string to_string() const override std::string to_string() const override
{ {
for (std::size_t i = 0; i < sizeof(bijective<T, const char*>::map) / sizeof(bijective_pair<T, const char*>); i++) std::string result;
{ fmt_class_string<T>::format(result, fmt_unveil<T>::get(m_value));
if (bijective<T, const char*>::map[i].v1 == m_value) return result; // TODO: ???
{
return bijective<T, const char*>::map[i].v2;
}
}
return{}; // TODO: ???
} }
bool from_string(const std::string& value) override bool from_string(const std::string& value) override
{ {
for (std::size_t i = 0; i < sizeof(bijective<T, const char*>::map) / sizeof(bijective_pair<T, const char*>); i++) u64 result;
if (try_to_enum_value(&result, &fmt_class_string<T>::format, value))
{ {
if (bijective<T, const char*>::map[i].v2 == value) const auto val = static_cast<std::underlying_type_t<T>>(result);
if (static_cast<u64>(val) != result)
{ {
m_value = bijective<T, const char*>::map[i].v1; return false;
return true;
} }
m_value = static_cast<T>(val);
return true;
} }
return false; return false;
@ -323,14 +330,7 @@ namespace cfg
std::vector<std::string> to_list() const override std::vector<std::string> to_list() const override
{ {
std::vector<std::string> result; return try_to_enum_list(&fmt_class_string<T>::format);
for (std::size_t i = 0; i < sizeof(bijective<T, const char*>::map) / sizeof(bijective_pair<T, const char*>); i++)
{
result.emplace_back(bijective<T, const char*>::map[i].v2);
}
return result;
} }
}; };

View File

@ -1333,3 +1333,37 @@ u64 fs::get_dir_size(const std::string& path)
return result; return result;
} }
template<>
void fmt_class_string<fs::seek_mode>::format(std::string& out, u64 arg)
{
format_enum(out, arg, [](auto arg)
{
switch (arg)
{
STR_CASE(fs::seek_mode::seek_set);
STR_CASE(fs::seek_mode::seek_cur);
STR_CASE(fs::seek_mode::seek_end);
}
return unknown;
});
}
template<>
void fmt_class_string<fs::error>::format(std::string& out, u64 arg)
{
format_enum(out, arg, [](auto arg)
{
switch (arg)
{
case fs::error::ok: return "OK";
case fs::error::inval: return "Invalid arguments";
case fs::error::noent: return "Not found";
case fs::error::exist: return "Already exists";
}
return unknown;
});
}

View File

@ -463,21 +463,3 @@ namespace fs
// Error code returned // Error code returned
extern thread_local error g_tls_error; extern thread_local error g_tls_error;
} }
template<>
struct unveil<fs::error>
{
static inline const char* get(fs::error error)
{
switch (error)
{
case fs::error::ok: return "OK";
case fs::error::inval: return "Invalid arguments";
case fs::error::noent: return "Not found";
case fs::error::exist: return "Already exists";
default: throw error;
}
}
};

View File

@ -3,15 +3,31 @@
#include "StrFmt.h" #include "StrFmt.h"
#include "rpcs3_version.h" #include "rpcs3_version.h"
#include <cstdarg>
#include <string> #include <string>
// Thread-specific log prefix provider // Thread-specific log prefix provider
thread_local std::string(*g_tls_log_prefix)() = nullptr; thread_local std::string(*g_tls_log_prefix)() = nullptr;
#ifndef _MSC_VER template<>
constexpr DECLARE(bijective<logs::level, const char*>::map); void fmt_class_string<logs::level>::format(std::string& out, u64 arg)
#endif {
format_enum(out, arg, [](auto lev)
{
switch (lev)
{
case logs::level::always: return "Nothing";
case logs::level::fatal: return "Fatal";
case logs::level::error: return "Error";
case logs::level::todo: return "TODO";
case logs::level::success: return "Success";
case logs::level::warning: return "Warning";
case logs::level::notice: return "Notice";
case logs::level::trace: return "Trace";
}
return unknown;
});
}
namespace logs namespace logs
{ {
@ -72,13 +88,10 @@ void logs::listener::add(logs::listener* _new)
} }
} }
void logs::channel::broadcast(const logs::channel& ch, logs::level sev, const char* fmt...) void logs::channel::broadcast(const logs::channel& ch, logs::level sev, const char* fmt, const fmt::supplementary_info* sup, const u64* args)
{ {
va_list args; std::string text; fmt::raw_append(text, fmt, sup, args);
va_start(args, fmt); std::string prefix(g_tls_log_prefix ? g_tls_log_prefix() : "");
std::string&& text = fmt::unsafe_vformat(fmt, args);
std::string&& prefix = g_tls_log_prefix ? g_tls_log_prefix() : "";
va_end(args);
// Prepare message information // Prepare message information
message msg; message msg;

View File

@ -1,7 +1,9 @@
#pragma once #pragma once
#include "types.h" #include "types.h"
#include "Platform.h"
#include "Atomic.h" #include "Atomic.h"
#include "StrFmt.h"
namespace logs namespace logs
{ {
@ -67,19 +69,17 @@ namespace logs
// Formatting function // Formatting function
template<typename... Args> template<typename... Args>
void format(level sev, const char* fmt, const Args&... args) const SAFE_BUFFERS void format(level sev, const char* fmt, const Args&... args) const
{ {
#ifdef _MSC_VER if (UNLIKELY(sev <= enabled))
if (sev <= enabled) {
#else broadcast(*this, sev, fmt, fmt::arg_type_info::get<typename fmt_unveil<Args>::type...>(), fmt::args_t<Args...>{::fmt_unveil<Args>::get(args)...});
if (__builtin_expect(sev <= enabled, 0)) }
#endif
broadcast(*this, sev, fmt, ::unveil<Args>::get(args)...);
} }
#define GEN_LOG_METHOD(_sev)\ #define GEN_LOG_METHOD(_sev)\
template<typename... Args>\ template<typename... Args>\
void _sev(const char* fmt, const Args&... args) const\ SAFE_BUFFERS void _sev(const char* fmt, const Args&... args) const\
{\ {\
return format<Args...>(level::_sev, fmt, args...);\ return format<Args...>(level::_sev, fmt, args...);\
} }
@ -95,7 +95,7 @@ namespace logs
#undef GEN_LOG_METHOD #undef GEN_LOG_METHOD
private: private:
// Send log message to global logger instance // Send log message to global logger instance
static void broadcast(const channel& ch, level sev, const char* fmt...); static void broadcast(const channel& ch, level sev, const char*, const fmt::supplementary_info*, const u64*);
}; };
/* Small set of predefined channels */ /* Small set of predefined channels */
@ -110,22 +110,6 @@ namespace logs
extern channel ARMv7; extern channel ARMv7;
} }
template<>
struct bijective<logs::level, const char*>
{
static constexpr bijective_pair<logs::level, const char*> map[]
{
{ logs::level::always, "Nothing" },
{ logs::level::fatal, "Fatal" },
{ logs::level::error, "Error" },
{ logs::level::todo, "TODO" },
{ logs::level::success, "Success" },
{ logs::level::warning, "Warning" },
{ logs::level::notice, "Notice" },
{ logs::level::trace, "Trace" },
};
};
// Legacy: // Legacy:
#define LOG_SUCCESS(ch, fmt, ...) logs::ch.success(fmt, ##__VA_ARGS__) #define LOG_SUCCESS(ch, fmt, ...) logs::ch.success(fmt, ##__VA_ARGS__)

View File

@ -61,7 +61,7 @@ public:
Show(); Show();
} }
force_inline void Update(const u8 thread_id, const u64 value, const wxString& msg) void Update(const u8 thread_id, const u64 value, const wxString& msg)
{ {
if(thread_id > m_cores) return; if(thread_id > m_cores) return;

View File

@ -29,15 +29,21 @@
#endif #endif
#ifdef _MSC_VER #ifdef _MSC_VER
#define never_inline __declspec(noinline) #define SAFE_BUFFERS __declspec(safebuffers)
#else #else
#define never_inline __attribute__((noinline)) #define SAFE_BUFFERS
#endif #endif
#ifdef _MSC_VER #ifdef _MSC_VER
#define force_inline __forceinline #define NEVER_INLINE __declspec(noinline)
#else #else
#define force_inline __attribute__((always_inline)) inline #define NEVER_INLINE __attribute__((noinline))
#endif
#ifdef _MSC_VER
#define FORCE_INLINE __forceinline
#else
#define FORCE_INLINE __attribute__((always_inline)) inline
#endif #endif
#if defined(__GNUG__) #if defined(__GNUG__)

View File

@ -1,73 +1,178 @@
#include "StrFmt.h" #include "StrFmt.h"
#include "BEType.h" #include "BEType.h"
#include "StrUtil.h" #include "StrUtil.h"
#include "cfmt.h"
#include <cassert>
#include <array>
#include <memory>
#include <algorithm> #include <algorithm>
std::string v128::to_hex() const void fmt_class_string<const void*>::format(std::string& out, u64 arg)
{ {
return fmt::format("%016llx%016llx", _u64[1], _u64[0]); fmt::append(out, "%p", reinterpret_cast<const void*>(static_cast<std::uintptr_t>(arg)));
} }
std::string v128::to_xyzw() const void fmt_class_string<const char*>::format(std::string& out, u64 arg)
{ {
return fmt::format("x: %g y: %g z: %g w: %g", _f[3], _f[2], _f[1], _f[0]); out += reinterpret_cast<const char*>(static_cast<std::uintptr_t>(arg));
} }
std::string fmt::unsafe_vformat(const char* fmt, va_list _args) noexcept template<>
void fmt_class_string<std::string>::format(std::string& out, u64 arg)
{ {
// Fixed stack buffer for the first attempt out += get_object(arg).c_str(); // TODO?
std::array<char, 4096> fixed_buf; }
// Possibly dynamically allocated buffer for the second attempt template<>
std::unique_ptr<char[]> buf; void fmt_class_string<std::vector<char>>::format(std::string& out, u64 arg)
{
const std::vector<char>& obj = get_object(arg);
out.append(obj.cbegin(), obj.cend());
}
// Pointer to the current buffer template<>
char* buf_addr = fixed_buf.data(); void fmt_class_string<char>::format(std::string& out, u64 arg)
{
fmt::append(out, "0x%hhx", static_cast<char>(arg));
}
for (std::size_t buf_size = fixed_buf.size();;) template<>
void fmt_class_string<uchar>::format(std::string& out, u64 arg)
{
fmt::append(out, "0x%hhx", static_cast<uchar>(arg));
}
template<>
void fmt_class_string<schar>::format(std::string& out, u64 arg)
{
fmt::append(out, "0x%hhx", static_cast<schar>(arg));
}
template<>
void fmt_class_string<short>::format(std::string& out, u64 arg)
{
fmt::append(out, "0x%hx", static_cast<short>(arg));
}
template<>
void fmt_class_string<ushort>::format(std::string& out, u64 arg)
{
fmt::append(out, "0x%hx", static_cast<ushort>(arg));
}
template<>
void fmt_class_string<int>::format(std::string& out, u64 arg)
{
fmt::append(out, "0x%x", static_cast<int>(arg));
}
template<>
void fmt_class_string<uint>::format(std::string& out, u64 arg)
{
fmt::append(out, "0x%x", static_cast<uint>(arg));
}
template<>
void fmt_class_string<long>::format(std::string& out, u64 arg)
{
fmt::append(out, "0x%lx", static_cast<long>(arg));
}
template<>
void fmt_class_string<ulong>::format(std::string& out, u64 arg)
{
fmt::append(out, "0x%lx", static_cast<ulong>(arg));
}
template<>
void fmt_class_string<llong>::format(std::string& out, u64 arg)
{
fmt::append(out, "0x%llx", static_cast<llong>(arg));
}
template<>
void fmt_class_string<ullong>::format(std::string& out, u64 arg)
{
fmt::append(out, "0x%llx", static_cast<ullong>(arg));
}
template<>
void fmt_class_string<float>::format(std::string& out, u64 arg)
{
fmt::append(out, "%f", static_cast<float>(reinterpret_cast<f64&>(arg)));
}
template<>
void fmt_class_string<double>::format(std::string& out, u64 arg)
{
fmt::append(out, "%f", reinterpret_cast<f64&>(arg));
}
template<>
void fmt_class_string<bool>::format(std::string& out, u64 arg)
{
out += arg ? "true" : "false"; // TODO?
}
template<>
void fmt_class_string<v128>::format(std::string& out, u64 arg)
{
const v128& vec = get_object(arg);
fmt::append(out, "0x%016llx%016llx", vec._u64[1], vec._u64[0]);
}
namespace fmt
{
struct cfmt_src;
}
// Temporary implementation
struct fmt::cfmt_src
{
const fmt::supplementary_info* sup;
const u64* args;
bool test(std::size_t index = 0)
{ {
va_list args; for (std::size_t i = 0; i <= index; i++)
va_copy(args, _args);
#ifndef _MSC_VER
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-security"
#endif
const std::size_t len = std::vsnprintf(buf_addr, buf_size, fmt, args);
#ifndef _MSC_VER
#pragma GCC diagnostic pop
#endif
va_end(args);
assert(len <= INT_MAX);
if (len < buf_size)
{ {
return{ buf_addr, len }; if (!sup[i].fmt_string)
{
return false;
}
} }
buf.reset(buf_addr = new char[buf_size = len + 1]); return true;
} }
template<typename T>
T get(std::size_t index = 0)
{
return reinterpret_cast<const T&>(args[index]);
}
void skip(std::size_t extra)
{
++sup += extra;
++args += extra;
}
std::size_t fmt_string(std::string& out)
{
const std::size_t start = out.size();
sup->fmt_string(out, args[0]);
return out.size() - start;
}
};
void fmt::raw_append(std::string& out, const char* fmt, const fmt::supplementary_info* sup, const u64* args) noexcept
{
cfmt_append(out, fmt, cfmt_src{sup, args});
} }
std::string fmt::unsafe_format(const char* fmt...) noexcept char* fmt::alloc_format(const char* fmt, const fmt::supplementary_info* sup, const u64* args) noexcept
{ {
va_list args; std::string str;
va_start(args, fmt); raw_append(str, fmt, sup, args);
auto result = unsafe_vformat(fmt, args); return static_cast<char*>(std::memcpy(std::malloc(str.size() + 1), str.data(), str.size() + 1));
va_end(args);
return result;
}
fmt::exception_base::exception_base(const char* fmt...)
: std::runtime_error((va_start(m_args, fmt), unsafe_vformat(fmt, m_args)))
{
va_end(m_args);
} }
std::string fmt::replace_first(const std::string& src, const std::string& from, const std::string& to) std::string fmt::replace_first(const std::string& src, const std::string& from, const std::string& to)

View File

@ -1,6 +1,5 @@
#pragma once #pragma once
#include <cstdarg>
#include <exception> #include <exception>
#include <string> #include <string>
@ -9,44 +8,224 @@
namespace fmt namespace fmt
{ {
std::string unsafe_format(const char* fmt...) noexcept;
std::string unsafe_vformat(const char*, va_list) noexcept;
// Formatting function
template<typename... Args> template<typename... Args>
inline std::string format(const char* fmt, const Args&... args) static std::string format(const char*, const Args&...);
}
template<typename T, typename>
struct fmt_unveil
{
static_assert(sizeof(T) > 0, "fmt_unveil<>: cannot pass forward-declared object");
using type = T;
static inline u64 get(const T& arg)
{ {
return unsafe_format(fmt, ::unveil<Args>::get(args)...); return reinterpret_cast<std::uintptr_t>(&arg);
}
};
template<typename T>
struct fmt_unveil<T, std::enable_if_t<std::is_integral<T>::value && sizeof(T) <= 8 && alignof(T) <= 8>>
{
using type = T;
static inline u64 get(T arg)
{
return static_cast<T>(arg);
}
};
template<typename T>
struct fmt_unveil<T, std::enable_if_t<std::is_floating_point<T>::value && sizeof(T) <= 8 && alignof(T) <= 8>>
{
using type = T;
// Convert FP to f64 and reinterpret (TODO?)
static inline u64 get(f64 arg)
{
return reinterpret_cast<u64&>(arg);
}
};
template<typename T>
struct fmt_unveil<T, std::enable_if_t<std::is_enum<T>::value>>
{
using type = T;
static inline u64 get(T arg)
{
return static_cast<std::underlying_type_t<T>>(arg);
}
};
template<typename T>
struct fmt_unveil<T*, void>
{
using type = const T*;
static inline u64 get(const T* arg)
{
return reinterpret_cast<std::uintptr_t>(arg);
}
};
template<typename T, std::size_t N>
struct fmt_unveil<T[N], void>
{
using type = const T*;
static inline u64 get(const T* arg)
{
return reinterpret_cast<std::uintptr_t>(arg);
}
};
template<>
struct fmt_unveil<b8, void>
{
using type = bool;
static inline u64 get(const b8& value)
{
return fmt_unveil<bool>::get(value);
}
};
// String type format provider, also type classifier (format() called if an argument is formatted as "%s")
template<typename T, typename = void>
struct fmt_class_string
{
// Formatting function (must be explicitly specialized)
static void format(std::string& out, u64 arg);
// Helper typedef (visible in format())
using type = T;
// Helper function (converts arg to object reference)
static SAFE_BUFFERS FORCE_INLINE const T& get_object(u64 arg)
{
return *reinterpret_cast<const T*>(static_cast<std::uintptr_t>(arg));
} }
// Helper class // Helper function (safely converts arg to enum value)
class exception_base : public std::runtime_error static SAFE_BUFFERS FORCE_INLINE void format_enum(std::string& out, u64 arg, const char*(*get)(T value))
{ {
// Helper (there is no other room) const auto value = static_cast<std::underlying_type_t<T>>(arg);
va_list m_args;
protected: // Check narrowing
// Internal formatting constructor if (static_cast<u64>(value) == arg)
exception_base(const char* fmt...);
};
// Exception type derived from std::runtime_error with formatting constructor
class exception : public exception_base
{
public:
template<typename... Args>
exception(const char* fmt, const Args&... args)
: exception_base(fmt, ::unveil<Args>::get(args)...)
{ {
if (const char* str = get(static_cast<T>(value)))
{
out += str;
return;
}
}
// Fallback to underlying type formatting
fmt_class_string<std::underlying_type_t<T>>::format(out, static_cast<u64>(value));
}
// Helper constant (may be used in format_enum as lambda return value)
static constexpr const char* unknown = nullptr;
};
template<>
struct fmt_class_string<const void*, void>
{
static void format(std::string& out, u64 arg);
};
template<typename T>
struct fmt_class_string<T*, void> : fmt_class_string<const void*, void>
{
// Classify all pointers as const void*
};
template<>
struct fmt_class_string<const char*, void>
{
static void format(std::string& out, u64 arg);
};
template<>
struct fmt_class_string<char*, void> : fmt_class_string<const char*>
{
// Classify char* as const char*
};
namespace fmt
{
// Argument array type (each element generated via fmt_unveil<>)
template<typename... Args>
using args_t = const u64(&&)[sizeof...(Args) + 1];
using supplementary_info = const struct arg_type_info;
struct arg_type_info
{
decltype(&fmt_class_string<int>::format) fmt_string;
template<typename T>
static constexpr arg_type_info make()
{
return arg_type_info
{
&fmt_class_string<T>::format,
};
}
template<typename... Args>
static inline const supplementary_info* get()
{
// Constantly initialized null-terminated list of type-specific information
static constexpr arg_type_info result[sizeof...(Args) + 1]
{
make<Args>()...
};
return result;
} }
}; };
// Narrow cast (similar to gsl::narrow) with exception message formatting // Internal formatting function
template<typename To, typename From, typename... Args> void raw_append(std::string& out, const char*, const supplementary_info*, const u64*) noexcept;
inline auto narrow(const char* format_str, const From& value, const Args&... args) -> decltype(static_cast<To>(static_cast<From>(std::declval<To>())))
// Formatting function
template<typename... Args>
static SAFE_BUFFERS void append(std::string& out, const char* fmt, const Args&... args)
{ {
const auto result = static_cast<To>(value); raw_append(out, fmt, arg_type_info::get<typename fmt_unveil<Args>::type...>(), args_t<Args...>{::fmt_unveil<Args>::get(args)...});
if (static_cast<From>(result) != value) throw fmt::exception(format_str, value, args...); }
// Formatting function
template<typename... Args>
static SAFE_BUFFERS std::string format(const char* fmt, const Args&... args)
{
std::string result;
append<Args...>(result, fmt, args...);
return result; return result;
} }
// Internal helper function
char* alloc_format(const char*, const supplementary_info*, const u64*) noexcept;
// Exception type with formatting constructor
template<typename Base>
class exception_t : public Base
{
using base = Base;
public:
template<typename... Args>
SAFE_BUFFERS exception_t(const char* fmt, const Args&... args)
: base((fmt = alloc_format(fmt, arg_type_info::get<typename fmt_unveil<Args>::type...>(), args_t<Args...>{::fmt_unveil<Args>::get(args)...})))
{
std::free(const_cast<char*>(fmt));
}
};
// Exception type derived from std::runtime_error with formatting constructor
using exception = exception_t<std::runtime_error>;
} }

View File

@ -863,7 +863,7 @@ bool get_x64_reg_value(x64_context* context, x64_reg_t reg, size_t d_size, size_
return true; return true;
} }
LOG_ERROR(MEMORY, "get_x64_reg_value(): invalid arguments (reg=%d, d_size=%lld, i_size=%lld)", reg, d_size, i_size); LOG_ERROR(MEMORY, "get_x64_reg_value(): invalid arguments (reg=%d, d_size=%lld, i_size=%lld)", (u32)reg, d_size, i_size);
return false; return false;
} }
@ -882,7 +882,7 @@ bool put_x64_reg_value(x64_context* context, x64_reg_t reg, size_t d_size, u64 v
} }
} }
LOG_ERROR(MEMORY, "put_x64_reg_value(): invalid destination (reg=%d, d_size=%lld, value=0x%llx)", reg, d_size, value); LOG_ERROR(MEMORY, "put_x64_reg_value(): invalid destination (reg=%d, d_size=%lld, value=0x%llx)", (u32)reg, d_size, value);
return false; return false;
} }
@ -1062,7 +1062,7 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
if (a_size != 4 || !d_size || !i_size) if (a_size != 4 || !d_size || !i_size)
{ {
LOG_ERROR(MEMORY, "Invalid or unsupported instruction (op=%d, reg=%d, d_size=%lld, a_size=0x%llx, i_size=%lld)", op, reg, d_size, a_size, i_size); LOG_ERROR(MEMORY, "Invalid or unsupported instruction (op=%d, reg=%d, d_size=%lld, a_size=0x%llx, i_size=%lld)", (u32)op, (u32)reg, d_size, a_size, i_size);
report_opcode(); report_opcode();
return false; return false;
} }
@ -1134,7 +1134,7 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
case X64OP_STOS: case X64OP_STOS:
default: default:
{ {
LOG_ERROR(MEMORY, "Invalid or unsupported operation (op=%d, reg=%d, d_size=%lld, i_size=%lld)", op, reg, d_size, i_size); LOG_ERROR(MEMORY, "Invalid or unsupported operation (op=%d, reg=%d, d_size=%lld, i_size=%lld)", (u32)op, (u32)reg, d_size, i_size);
report_opcode(); report_opcode();
return false; return false;
} }
@ -1151,7 +1151,7 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
// write memory using "privileged" access to avoid breaking reservation // write memory using "privileged" access to avoid breaking reservation
if (!d_size || !i_size) if (!d_size || !i_size)
{ {
LOG_ERROR(MEMORY, "Invalid or unsupported instruction (op=%d, reg=%d, d_size=%lld, a_size=0x%llx, i_size=%lld)", op, reg, d_size, a_size, i_size); LOG_ERROR(MEMORY, "Invalid or unsupported instruction (op=%d, reg=%d, d_size=%lld, a_size=0x%llx, i_size=%lld)", (u32)op, (u32)reg, d_size, a_size, i_size);
report_opcode(); report_opcode();
return false; return false;
} }
@ -1165,7 +1165,7 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
{ {
if (reg - X64R_XMM0 >= 16) if (reg - X64R_XMM0 >= 16)
{ {
LOG_ERROR(MEMORY, "X64OP_STORE: d_size=16, reg=%d", reg); LOG_ERROR(MEMORY, "X64OP_STORE: d_size=16, reg=%d", (u32)reg);
return false; return false;
} }
@ -1577,7 +1577,7 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
} }
default: default:
{ {
LOG_ERROR(MEMORY, "Invalid or unsupported operation (op=%d, reg=%d, d_size=%lld, a_size=0x%llx, i_size=%lld)", op, reg, d_size, a_size, i_size); LOG_ERROR(MEMORY, "Invalid or unsupported operation (op=%d, reg=%d, d_size=%lld, a_size=0x%llx, i_size=%lld)", (u32)op, (u32)reg, d_size, a_size, i_size);
report_opcode(); report_opcode();
return false; return false;
} }

431
Utilities/cfmt.h Normal file
View File

@ -0,0 +1,431 @@
#pragma once
#include "types.h"
#include <string>
#include <vector>
/*
C-style format parser. Appends formatted string to `out`, returns number of characters written.
Arguments are provided via `src`. TODO
*/
template<typename Src, typename Size = std::size_t>
Size cfmt_append(std::string& out, const char* fmt, Src&& src)
{
const std::size_t old_size = out.size();
out.reserve(old_size + 992);
struct cfmt_context
{
std::size_t size; // Size of current format sequence
u8 args; // Number of extra args used
u8 type; // Integral type bytesize
bool dot; // Precision enabled
bool left;
bool sign;
bool space;
bool alter;
bool zeros;
uint width;
uint prec;
};
cfmt_context ctx{0};
// Error handling: print untouched sequence, stop further formatting
const auto drop_sequence = [&]
{
out.append(fmt - ctx.size, ctx.size);
ctx.size = -1;
};
// TODO: check overflow
const auto read_decimal = [&](uint result) -> uint
{
while (fmt[0] >= '0' && fmt[0] <= '9')
{
result = result * 10 + (fmt[0] - '0');
fmt++, ctx.size++;
}
return result;
};
// TODO: remove this
const auto fallback = [&]()
{
const std::string _fmt(fmt - ctx.size, fmt);
const u64 arg0 = src.template get<u64>();
const int arg1 = ctx.args >= 1 ? src.template get<int>(1) : 0;
const int arg2 = ctx.args >= 2 ? src.template get<int>(2) : 0;
if (const std::size_t _size = std::snprintf(0, 0, _fmt.c_str(), arg0, arg1, arg2))
{
out.resize(out.size() + _size);
std::snprintf(&out.front() + out.size() - _size, _size + 1, _fmt.c_str(), arg0, arg1, arg2);
}
};
// Single pass over fmt string (null-terminated), TODO: check correct order
while (const char ch = *fmt++) if (ctx.size == 0)
{
if (ch == '%')
{
ctx.size = 1;
}
else
{
out += ch;
}
}
else if (ctx.size == 1 && ch == '%')
{
ctx = {0};
out += ch;
}
else if (ctx.size == -1)
{
out += ch;
}
else switch (ctx.size++, ch)
{
case '-': ctx.left = true; break;
case '+': ctx.sign = true; break;
case ' ': ctx.space = true; break;
case '#': ctx.alter = true; break;
case '0': ctx.zeros = true; break;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
{
ctx.width = read_decimal(ch - '0');
break;
}
case '*':
{
if (!src.test(++ctx.args))
{
drop_sequence();
break;
}
const int warg = src.template get<int>(ctx.args);
ctx.width = std::abs(warg);
ctx.left |= warg < 0;
break;
}
case '.':
{
if (*fmt >= '0' && *fmt <= '9') // TODO: does it allow '0'?
{
ctx.prec = read_decimal(0);
ctx.dot = true;
}
else if (*fmt == '*')
{
if (!src.test(++ctx.args))
{
drop_sequence();
break;
}
fmt++, ctx.size++;
const int parg = src.template get<int>(ctx.args);
ctx.prec = parg;
ctx.dot = parg >= 0;
}
else
{
ctx.prec = 0;
ctx.dot = true;
}
break;
}
case 'h':
{
if (ctx.type)
{
drop_sequence();
}
else if (fmt[0] == 'h')
{
fmt++, ctx.size++;
ctx.type = sizeof(char);
}
else
{
ctx.type = sizeof(short);
}
break;
}
case 'l':
{
if (ctx.type)
{
drop_sequence();
}
else if (fmt[0] == 'l')
{
fmt++, ctx.size++;
ctx.type = sizeof(llong);
}
else
{
ctx.type = sizeof(long);
}
break;
}
case 'z':
{
if (ctx.type)
{
drop_sequence();
}
else
{
ctx.type = sizeof(std::size_t);
}
break;
}
case 'j':
{
if (ctx.type)
{
drop_sequence();
}
else
{
ctx.type = sizeof(std::intmax_t);
}
break;
}
case 't':
{
if (ctx.type)
{
drop_sequence();
}
else
{
ctx.type = sizeof(std::ptrdiff_t);
}
break;
}
case 'c':
{
if (ctx.type || !src.test())
{
drop_sequence();
break;
}
const std::size_t start = out.size();
out += src.template get<char>(0);
if (1 < ctx.width)
{
// Add spaces if necessary
out.insert(start + ctx.left, ctx.width - 1, ' ');
}
src.skip(ctx.args);
ctx = {0};
break;
}
case 's':
{
if (ctx.type || !src.test())
{
drop_sequence();
break;
}
const std::size_t start = out.size();
const std::size_t size1 = src.fmt_string(out);
if (ctx.dot && size1 > ctx.prec)
{
// Shrink if necessary
out.resize(start + ctx.prec);
}
// TODO: how it works if precision and width specified simultaneously?
const std::size_t size2 = out.size() - start;
if (size2 < ctx.width)
{
// Add spaces if necessary
out.insert(ctx.left ? out.size() : start, ctx.width - size2, ' ');
}
src.skip(ctx.args);
ctx = {0};
break;
}
case 'd':
case 'i':
{
if (!src.test())
{
drop_sequence();
break;
}
if (!ctx.type)
{
ctx.type = sizeof(int);
}
fallback(); // TODO
src.skip(ctx.args);
ctx = {0};
break;
}
case 'o':
{
if (!src.test())
{
drop_sequence();
break;
}
if (!ctx.type)
{
ctx.type = sizeof(int);
}
fallback(); // TODO
src.skip(ctx.args);
ctx = {0};
break;
}
case 'x':
case 'X':
{
if (!src.test())
{
drop_sequence();
break;
}
if (!ctx.type)
{
ctx.type = sizeof(int);
}
fallback(); // TODO
src.skip(ctx.args);
ctx = {0};
break;
}
case 'u':
{
if (!src.test())
{
drop_sequence();
break;
}
if (!ctx.type)
{
ctx.type = sizeof(int);
}
fallback(); // TODO
src.skip(ctx.args);
ctx = {0};
break;
}
case 'p':
{
if (!src.test())
{
drop_sequence();
break;
}
if (ctx.type)
{
drop_sequence();
break;
}
fallback(); // TODO
src.skip(ctx.args);
ctx = {0};
break;
}
case 'f':
case 'F':
case 'e':
case 'E':
case 'a':
case 'A':
case 'g':
case 'G':
{
if (!src.test())
{
drop_sequence();
break;
}
if (ctx.type)
{
drop_sequence();
break;
}
fallback(); // TODO
src.skip(ctx.args);
ctx = {0};
break;
}
case 'L': // long double, not supported
case 'n': // writeback, not supported
default:
{
drop_sequence();
}
}
// Handle unfinished sequence
if (ctx.size && ctx.size != -1)
{
fmt--, drop_sequence();
}
return static_cast<Size>(out.size() - old_size);
}

View File

@ -27,12 +27,13 @@ namespace gsl
enum class byte : u8; enum class byte : u8;
} }
template<typename T1, typename T2> namespace fmt
struct bijective_pair
{ {
T1 v1; }
T2 v2;
}; // Formatting helper, type-specific preprocessing for improving safety and functionality
template<typename T, typename = void>
struct fmt_unveil;
template<typename T, std::size_t Align = alignof(T), std::size_t Size = sizeof(T)> template<typename T, std::size_t Align = alignof(T), std::size_t Size = sizeof(T)>
struct se_storage; struct se_storage;
@ -40,10 +41,6 @@ struct se_storage;
template<typename T, bool Se = true, std::size_t Align = alignof(T)> template<typename T, bool Se = true, std::size_t Align = alignof(T)>
class se_t; class se_t;
// Specialization with static constexpr bijective_pair<T1, T2> map[] member expected
template<typename T1, typename T2>
struct bijective;
template<typename T, std::size_t Size = sizeof(T)> template<typename T, std::size_t Size = sizeof(T)>
struct atomic_storage; struct atomic_storage;
@ -501,40 +498,6 @@ struct multicast<void>
} }
}; };
template<typename T1, typename T2 = const char*, typename T = T1, typename DT = T2>
T2 bijective_find(const T& left, const DT& def = {})
{
for (std::size_t i = 0; i < sizeof(bijective<T1, T2>::map) / sizeof(bijective_pair<T1, T2>); i++)
{
if (bijective<T1, T2>::map[i].v1 == left)
{
return bijective<T1, T2>::map[i].v2;
}
}
return def;
}
// Formatting helper, type-specific preprocessing for improving safety and functionality
template<typename T, typename = void>
struct unveil
{
// TODO
static inline const T& get(const T& arg)
{
return arg;
}
};
template<typename T>
struct unveil<T, void_t<decltype(std::declval<T>().c_str())>>
{
static inline const char* get(const T& arg)
{
return arg.c_str();
}
};
// Tagged ID type // Tagged ID type
template<typename T = void, typename ID = u32> template<typename T = void, typename ID = u32>
class id_value class id_value
@ -560,3 +523,14 @@ public:
return m_value; return m_value;
} }
}; };
template<typename T, typename ID>
struct fmt_unveil<id_value<T, ID>>
{
using type = typename fmt_unveil<ID>::type;
static inline u64 get(const id_value<T, ID>& value)
{
return fmt_unveil<ID>::get(value);
}
};

View File

@ -7,86 +7,86 @@
// TODO: Still reliant on wxWidgets for zlib functions. Alternative solutions? // TODO: Still reliant on wxWidgets for zlib functions. Alternative solutions?
#include <zlib.h> #include <zlib.h>
force_inline u8 Read8(const fs::file& f) inline u8 Read8(const fs::file& f)
{ {
u8 ret; u8 ret;
f.read(&ret, sizeof(ret)); f.read(&ret, sizeof(ret));
return ret; return ret;
} }
force_inline u16 Read16(const fs::file& f) inline u16 Read16(const fs::file& f)
{ {
be_t<u16> ret; be_t<u16> ret;
f.read(&ret, sizeof(ret)); f.read(&ret, sizeof(ret));
return ret; return ret;
} }
force_inline u32 Read32(const fs::file& f) inline u32 Read32(const fs::file& f)
{ {
be_t<u32> ret; be_t<u32> ret;
f.read(&ret, sizeof(ret)); f.read(&ret, sizeof(ret));
return ret; return ret;
} }
force_inline u64 Read64(const fs::file& f) inline u64 Read64(const fs::file& f)
{ {
be_t<u64> ret; be_t<u64> ret;
f.read(&ret, sizeof(ret)); f.read(&ret, sizeof(ret));
return ret; return ret;
} }
force_inline u16 Read16LE(const fs::file& f) inline u16 Read16LE(const fs::file& f)
{ {
u16 ret; u16 ret;
f.read(&ret, sizeof(ret)); f.read(&ret, sizeof(ret));
return ret; return ret;
} }
force_inline u32 Read32LE(const fs::file& f) inline u32 Read32LE(const fs::file& f)
{ {
u32 ret; u32 ret;
f.read(&ret, sizeof(ret)); f.read(&ret, sizeof(ret));
return ret; return ret;
} }
force_inline u64 Read64LE(const fs::file& f) inline u64 Read64LE(const fs::file& f)
{ {
u64 ret; u64 ret;
f.read(&ret, sizeof(ret)); f.read(&ret, sizeof(ret));
return ret; return ret;
} }
force_inline void Write8(const fs::file& f, const u8 data) inline void Write8(const fs::file& f, const u8 data)
{ {
f.write(&data, sizeof(data)); f.write(&data, sizeof(data));
} }
force_inline void Write16LE(const fs::file& f, const u16 data) inline void Write16LE(const fs::file& f, const u16 data)
{ {
f.write(&data, sizeof(data)); f.write(&data, sizeof(data));
} }
force_inline void Write32LE(const fs::file& f, const u32 data) inline void Write32LE(const fs::file& f, const u32 data)
{ {
f.write(&data, sizeof(data)); f.write(&data, sizeof(data));
} }
force_inline void Write64LE(const fs::file& f, const u64 data) inline void Write64LE(const fs::file& f, const u64 data)
{ {
f.write(&data, sizeof(data)); f.write(&data, sizeof(data));
} }
force_inline void Write16(const fs::file& f, const be_t<u16> data) inline void Write16(const fs::file& f, const be_t<u16> data)
{ {
f.write(&data, sizeof(data)); f.write(&data, sizeof(data));
} }
force_inline void Write32(const fs::file& f, const be_t<u32> data) inline void Write32(const fs::file& f, const be_t<u32> data)
{ {
f.write(&data, sizeof(data)); f.write(&data, sizeof(data));
} }
force_inline void Write64(const fs::file& f, const be_t<u64> data) inline void Write64(const fs::file& f, const be_t<u64> data)
{ {
f.write(&data, sizeof(data)); f.write(&data, sizeof(data));
} }

View File

@ -4,6 +4,28 @@
#include <mutex> #include <mutex>
template<>
void fmt_class_string<cpu_type>::format(std::string& out, u64 arg)
{
format_enum(out, arg, [](auto arg)
{
switch (arg)
{
STR_CASE(cpu_type::ppu);
STR_CASE(cpu_type::spu);
STR_CASE(cpu_type::arm);
}
return unknown;
});
}
template<>
void fmt_class_string<bitset_t<cpu_state>::raw_type>::format(std::string& out, u64 arg)
{
out += "[UNIMPLEMENTED]";
}
thread_local cpu_thread* g_tls_current_cpu_thread = nullptr; thread_local cpu_thread* g_tls_current_cpu_thread = nullptr;
void cpu_thread::on_task() void cpu_thread::on_task()

View File

@ -390,7 +390,7 @@ public:
default: default:
{ {
throw EXCEPTION("Unknown task(%d)", task.type); throw EXCEPTION("Unknown task(%d)", (u32)task.type);
} }
} }
} }
@ -476,7 +476,7 @@ next:
default: default:
{ {
cellAdec.error("adecRawRead(): unknown task (%d)", task.type); cellAdec.error("adecRawRead(): unknown task (%d)", (u32)task.type);
Emu.Pause(); Emu.Pause();
return -1; return -1;
} }

View File

@ -461,7 +461,7 @@ s32 cellAudioGetPortConfig(u32 portNum, vm::ptr<CellAudioPortConfig> portConfig)
case audio_port_state::closed: portConfig->status = CELL_AUDIO_STATUS_CLOSE; break; case audio_port_state::closed: portConfig->status = CELL_AUDIO_STATUS_CLOSE; break;
case audio_port_state::opened: portConfig->status = CELL_AUDIO_STATUS_READY; break; case audio_port_state::opened: portConfig->status = CELL_AUDIO_STATUS_READY; break;
case audio_port_state::started: portConfig->status = CELL_AUDIO_STATUS_RUN; break; case audio_port_state::started: portConfig->status = CELL_AUDIO_STATUS_RUN; break;
default: throw fmt::exception("Invalid port state (%d: %d)", portNum, state); default: throw fmt::exception("Invalid port state (%d: %d)", portNum, (u32)state);
} }
portConfig->nChannel = port.channel; portConfig->nChannel = port.channel;
@ -492,7 +492,7 @@ s32 cellAudioPortStart(u32 portNum)
case audio_port_state::closed: return CELL_AUDIO_ERROR_PORT_NOT_OPEN; case audio_port_state::closed: return CELL_AUDIO_ERROR_PORT_NOT_OPEN;
case audio_port_state::started: return CELL_AUDIO_ERROR_PORT_ALREADY_RUN; case audio_port_state::started: return CELL_AUDIO_ERROR_PORT_ALREADY_RUN;
case audio_port_state::opened: return CELL_OK; case audio_port_state::opened: return CELL_OK;
default: throw fmt::exception("Invalid port state (%d: %d)", portNum, state); default: throw fmt::exception("Invalid port state (%d: %d)", portNum, (u32)state);
} }
} }
@ -517,7 +517,7 @@ s32 cellAudioPortClose(u32 portNum)
case audio_port_state::closed: return CELL_AUDIO_ERROR_PORT_NOT_OPEN; case audio_port_state::closed: return CELL_AUDIO_ERROR_PORT_NOT_OPEN;
case audio_port_state::started: return CELL_OK; case audio_port_state::started: return CELL_OK;
case audio_port_state::opened: return CELL_OK; case audio_port_state::opened: return CELL_OK;
default: throw fmt::exception("Invalid port state (%d: %d)", portNum, state); default: throw fmt::exception("Invalid port state (%d: %d)", portNum, (u32)state);
} }
} }
@ -542,7 +542,7 @@ s32 cellAudioPortStop(u32 portNum)
case audio_port_state::closed: return CELL_AUDIO_ERROR_PORT_NOT_RUN; case audio_port_state::closed: return CELL_AUDIO_ERROR_PORT_NOT_RUN;
case audio_port_state::started: return CELL_OK; case audio_port_state::started: return CELL_OK;
case audio_port_state::opened: return CELL_AUDIO_ERROR_PORT_NOT_RUN; case audio_port_state::opened: return CELL_AUDIO_ERROR_PORT_NOT_RUN;
default: throw fmt::exception("Invalid port state (%d: %d)", portNum, state); default: throw fmt::exception("Invalid port state (%d: %d)", portNum, (u32)state);
} }
} }

View File

@ -648,7 +648,7 @@ public:
default: default:
{ {
throw EXCEPTION("Demuxer thread error: unknown task (0x%x)", task.type); throw EXCEPTION("Demuxer thread error: unknown task (0x%x)", (u32)task.type);
} }
} }
} }

View File

@ -509,12 +509,12 @@ public:
return push(data, [do_exit]() { return do_exit && *do_exit; }); return push(data, [do_exit]() { return do_exit && *do_exit; });
} }
force_inline bool push(const T& data) bool push(const T& data)
{ {
return push(data, SQUEUE_NEVER_EXIT); return push(data, SQUEUE_NEVER_EXIT);
} }
force_inline bool try_push(const T& data) bool try_push(const T& data)
{ {
return push(data, SQUEUE_ALWAYS_EXIT); return push(data, SQUEUE_ALWAYS_EXIT);
} }
@ -577,12 +577,12 @@ public:
return pop(data, [do_exit]() { return do_exit && *do_exit; }); return pop(data, [do_exit]() { return do_exit && *do_exit; });
} }
force_inline bool pop(T& data) bool pop(T& data)
{ {
return pop(data, SQUEUE_NEVER_EXIT); return pop(data, SQUEUE_NEVER_EXIT);
} }
force_inline bool try_pop(T& data) bool try_pop(T& data)
{ {
return pop(data, SQUEUE_ALWAYS_EXIT); return pop(data, SQUEUE_ALWAYS_EXIT);
} }
@ -639,12 +639,12 @@ public:
return peek(data, start_pos, [do_exit]() { return do_exit && *do_exit; }); return peek(data, start_pos, [do_exit]() { return do_exit && *do_exit; });
} }
force_inline bool peek(T& data, u32 start_pos = 0) bool peek(T& data, u32 start_pos = 0)
{ {
return peek(data, start_pos, SQUEUE_NEVER_EXIT); return peek(data, start_pos, SQUEUE_NEVER_EXIT);
} }
force_inline bool try_peek(T& data, u32 start_pos = 0) bool try_peek(T& data, u32 start_pos = 0)
{ {
return peek(data, start_pos, SQUEUE_ALWAYS_EXIT); return peek(data, start_pos, SQUEUE_ALWAYS_EXIT);
} }

View File

@ -147,7 +147,7 @@ void cellRescSetVBlankHandler(vm::ptr<void(u32)> handler)
s32 cellRescCreateInterlaceTable(u32 ea_addr, f32 srcH, CellRescTableElement depth, s32 length) s32 cellRescCreateInterlaceTable(u32 ea_addr, f32 srcH, CellRescTableElement depth, s32 length)
{ {
cellResc.todo("cellRescCreateInterlaceTable(ea_addr=0x%x, srcH=%f, depth=%d, length=%d)", ea_addr, srcH, depth, length); cellResc.todo("cellRescCreateInterlaceTable(ea_addr=0x%x, srcH=%f, depth=%d, length=%d)", ea_addr, srcH, (s32)depth, length);
return CELL_OK; return CELL_OK;
} }

View File

@ -37,7 +37,7 @@ enum : u32
std::mutex g_savedata_mutex; std::mutex g_savedata_mutex;
static never_inline s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version, vm::cptr<char> dirName, static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version, vm::cptr<char> dirName,
u32 errDialog, PSetList setList, PSetBuf setBuf, PFuncList funcList, PFuncFixed funcFixed, PFuncStat funcStat, u32 errDialog, PSetList setList, PSetBuf setBuf, PFuncList funcList, PFuncFixed funcFixed, PFuncStat funcStat,
PFuncFile funcFile, u32 container, u32 unknown, vm::ptr<void> userdata, u32 userId, PFuncDone funcDone) PFuncFile funcFile, u32 container, u32 unknown, vm::ptr<void> userdata, u32 userId, PFuncDone funcDone)
{ {

View File

@ -562,7 +562,7 @@ struct alignas(128) CellSpurs
_sub_str4 wklH2[0x10]; // 0x1A00 _sub_str4 wklH2[0x10]; // 0x1A00
u8 unknown_[0x2000 - 0x1B00]; u8 unknown_[0x2000 - 0x1B00];
force_inline atomic_t<u8>& wklState(const u32 wid) atomic_t<u8>& wklState(const u32 wid)
{ {
if (wid & 0x10) if (wid & 0x10)
{ {

View File

@ -74,25 +74,15 @@ cfg::map_entry<s32> g_cfg_sys_language(cfg::root.sys, "Language",
{ "English (UK)", CELL_SYSUTIL_LANG_ENGLISH_GB }, { "English (UK)", CELL_SYSUTIL_LANG_ENGLISH_GB },
}); });
enum class systemparam_id_name : s32 {}; // For test
enum systemparam_id_name : s32 {};
template<> template<>
struct unveil<systemparam_id_name, void> void fmt_class_string<systemparam_id_name>::format(std::string& out, u64 arg)
{ {
struct temp format_enum(out, arg, [](auto value)
{ {
s32 value; switch (value)
char buf[12];
temp(systemparam_id_name value)
: value(s32(value))
{
}
};
static inline const char* get(temp&& in)
{
switch (in.value)
{ {
case CELL_SYSUTIL_SYSTEMPARAM_ID_LANG: return "ID_LANG"; case CELL_SYSUTIL_SYSTEMPARAM_ID_LANG: return "ID_LANG";
case CELL_SYSUTIL_SYSTEMPARAM_ID_ENTER_BUTTON_ASSIGN: return "ID_ENTER_BUTTON_ASSIGN"; case CELL_SYSUTIL_SYSTEMPARAM_ID_ENTER_BUTTON_ASSIGN: return "ID_ENTER_BUTTON_ASSIGN";
@ -113,14 +103,13 @@ struct unveil<systemparam_id_name, void>
case CELL_SYSUTIL_SYSTEMPARAM_ID_CURRENT_USERNAME: return "ID_CURRENT_USERNAME"; case CELL_SYSUTIL_SYSTEMPARAM_ID_CURRENT_USERNAME: return "ID_CURRENT_USERNAME";
} }
std::snprintf(in.buf, sizeof(in.buf), "!0x%04X", in.value); return unknown;
return in.buf; });
} }
};
s32 cellSysutilGetSystemParamInt(s32 id, vm::ptr<s32> value) s32 cellSysutilGetSystemParamInt(systemparam_id_name id, vm::ptr<s32> value)
{ {
cellSysutil.warning("cellSysutilGetSystemParamInt(id=%s, value=*0x%x)", systemparam_id_name(id), value); cellSysutil.warning("cellSysutilGetSystemParamInt(id=0x%x(%s), value=*0x%x)", id, id, value);
// TODO: load this information from config (preferably "sys/" group) // TODO: load this information from config (preferably "sys/" group)
@ -193,9 +182,9 @@ s32 cellSysutilGetSystemParamInt(s32 id, vm::ptr<s32> value)
return CELL_OK; return CELL_OK;
} }
s32 cellSysutilGetSystemParamString(s32 id, vm::ptr<char> buf, u32 bufsize) s32 cellSysutilGetSystemParamString(systemparam_id_name id, vm::ptr<char> buf, u32 bufsize)
{ {
cellSysutil.trace("cellSysutilGetSystemParamString(id=0x%x(%s), buf=*0x%x, bufsize=%d)", id, systemparam_id_name(id), buf, bufsize); cellSysutil.trace("cellSysutilGetSystemParamString(id=0x%x(%s), buf=*0x%x, bufsize=%d)", id, id, buf, bufsize);
memset(buf.get_ptr(), 0, bufsize); memset(buf.get_ptr(), 0, bufsize);

View File

@ -223,7 +223,7 @@ struct vdec_thread : ppu_thread
if (decode < 0) if (decode < 0)
{ {
throw fmt::exception("vdecDecodeAu: AU decoding error(0x%x)" HERE, decode); throw fmt::exception("AU decoding error(0x%x)" HERE, decode);
} }
if (got_picture == 0) if (got_picture == 0)
@ -233,7 +233,7 @@ struct vdec_thread : ppu_thread
if (decode != packet.size) if (decode != packet.size)
{ {
cellVdec.error("vdecDecodeAu: incorrect AU size (0x%x, decoded 0x%x)", packet.size, decode); cellVdec.error("Incorrect AU size (0x%x, decoded 0x%x)", packet.size, decode);
} }
if (got_picture) if (got_picture)
@ -322,7 +322,7 @@ struct vdec_thread : ppu_thread
frame.dts = last_dts = frame->pkt_dts != AV_NOPTS_VALUE ? frame->pkt_dts : last_dts; frame.dts = last_dts = frame->pkt_dts != AV_NOPTS_VALUE ? frame->pkt_dts : last_dts;
frame.userdata = au_usrd; frame.userdata = au_usrd;
cellVdec.trace("got picture (pts=0x%llx, dts=0x%llx)", frame.pts, frame.dts); cellVdec.trace("Got picture (pts=0x%llx, dts=0x%llx)", frame.pts, frame.dts);
thread_lock{*this}, out.push(std::move(frame)); thread_lock{*this}, out.push(std::move(frame));
@ -355,7 +355,7 @@ struct vdec_thread : ppu_thread
default: default:
{ {
throw fmt::exception("Unknown command (0x%x)" HERE, vcmd); throw fmt::exception("Unknown command (0x%x)" HERE, (u32)vcmd);
} }
} }
} }
@ -476,7 +476,7 @@ s32 cellVdecEndSeq(u32 handle)
s32 cellVdecDecodeAu(u32 handle, CellVdecDecodeMode mode, vm::cptr<CellVdecAuInfo> auInfo) s32 cellVdecDecodeAu(u32 handle, CellVdecDecodeMode mode, vm::cptr<CellVdecAuInfo> auInfo)
{ {
cellVdec.trace("cellVdecDecodeAu(handle=0x%x, mode=%d, auInfo=*0x%x)", handle, mode, auInfo); cellVdec.trace("cellVdecDecodeAu(handle=0x%x, mode=%d, auInfo=*0x%x)", handle, (s32)mode, auInfo);
const auto vdec = idm::get<ppu_thread, vdec_thread>(handle); const auto vdec = idm::get<ppu_thread, vdec_thread>(handle);
@ -487,7 +487,7 @@ s32 cellVdecDecodeAu(u32 handle, CellVdecDecodeMode mode, vm::cptr<CellVdecAuInf
if (mode != CELL_VDEC_DEC_MODE_NORMAL) if (mode != CELL_VDEC_DEC_MODE_NORMAL)
{ {
throw EXCEPTION("Unsupported decoding mode (%d)", mode); throw EXCEPTION("Unsupported decoding mode (%d)", (s32)mode);
} }
// TODO: check info // TODO: check info
@ -689,12 +689,12 @@ s32 cellVdecGetPicItem(u32 handle, vm::pptr<CellVdecPicItem> picItem)
avc->horizontalSize = frame->width; avc->horizontalSize = frame->width;
avc->verticalSize = frame->height; avc->verticalSize = frame->height;
switch (frame->pict_type) switch (s32 pct = frame->pict_type)
{ {
case AV_PICTURE_TYPE_I: avc->pictureType[0] = CELL_VDEC_AVC_PCT_I; break; case AV_PICTURE_TYPE_I: avc->pictureType[0] = CELL_VDEC_AVC_PCT_I; break;
case AV_PICTURE_TYPE_P: avc->pictureType[0] = CELL_VDEC_AVC_PCT_P; break; case AV_PICTURE_TYPE_P: avc->pictureType[0] = CELL_VDEC_AVC_PCT_P; break;
case AV_PICTURE_TYPE_B: avc->pictureType[0] = CELL_VDEC_AVC_PCT_B; break; case AV_PICTURE_TYPE_B: avc->pictureType[0] = CELL_VDEC_AVC_PCT_B; break;
default: cellVdec.error("cellVdecGetPicItem(AVC): unknown pict_type value (0x%x)", frame->pict_type); default: cellVdec.error("cellVdecGetPicItem(AVC): unknown pict_type value (0x%x)", pct);
} }
avc->pictureType[1] = CELL_VDEC_AVC_PCT_UNKNOWN; // ??? avc->pictureType[1] = CELL_VDEC_AVC_PCT_UNKNOWN; // ???
@ -742,12 +742,12 @@ s32 cellVdecGetPicItem(u32 handle, vm::pptr<CellVdecPicItem> picItem)
{ {
const vm::ptr<CellVdecDivxInfo> dvx = vm::cast(info.addr() + SIZE_32(CellVdecPicItem)); const vm::ptr<CellVdecDivxInfo> dvx = vm::cast(info.addr() + SIZE_32(CellVdecPicItem));
switch (frame->pict_type) switch (s32 pct = frame->pict_type)
{ {
case AV_PICTURE_TYPE_I: dvx->pictureType = CELL_VDEC_DIVX_VCT_I; break; case AV_PICTURE_TYPE_I: dvx->pictureType = CELL_VDEC_DIVX_VCT_I; break;
case AV_PICTURE_TYPE_P: dvx->pictureType = CELL_VDEC_DIVX_VCT_P; break; case AV_PICTURE_TYPE_P: dvx->pictureType = CELL_VDEC_DIVX_VCT_P; break;
case AV_PICTURE_TYPE_B: dvx->pictureType = CELL_VDEC_DIVX_VCT_B; break; case AV_PICTURE_TYPE_B: dvx->pictureType = CELL_VDEC_DIVX_VCT_B; break;
default: cellVdec.error("cellVdecGetPicItem(DivX): unknown pict_type value (0x%x)", frame->pict_type); default: cellVdec.error("cellVdecGetPicItem(DivX): unknown pict_type value (0x%x)", pct);
} }
dvx->horizontalSize = frame->width; dvx->horizontalSize = frame->width;
@ -801,12 +801,12 @@ s32 cellVdecGetPicItem(u32 handle, vm::pptr<CellVdecPicItem> picItem)
mp2->video_format = CELL_VDEC_MPEG2_VF_UNSPECIFIED; // ??? mp2->video_format = CELL_VDEC_MPEG2_VF_UNSPECIFIED; // ???
mp2->colour_description = false; // ??? mp2->colour_description = false; // ???
switch (frame->pict_type) switch (s32 pct = frame->pict_type)
{ {
case AV_PICTURE_TYPE_I: mp2->picture_coding_type[0] = CELL_VDEC_MPEG2_PCT_I; break; case AV_PICTURE_TYPE_I: mp2->picture_coding_type[0] = CELL_VDEC_MPEG2_PCT_I; break;
case AV_PICTURE_TYPE_P: mp2->picture_coding_type[0] = CELL_VDEC_MPEG2_PCT_P; break; case AV_PICTURE_TYPE_P: mp2->picture_coding_type[0] = CELL_VDEC_MPEG2_PCT_P; break;
case AV_PICTURE_TYPE_B: mp2->picture_coding_type[0] = CELL_VDEC_MPEG2_PCT_B; break; case AV_PICTURE_TYPE_B: mp2->picture_coding_type[0] = CELL_VDEC_MPEG2_PCT_B; break;
default: cellVdec.error("cellVdecGetPicItem(MPEG2): unknown pict_type value (0x%x)", frame->pict_type); default: cellVdec.error("cellVdecGetPicItem(MPEG2): unknown pict_type value (0x%x)", pct);
} }
mp2->picture_coding_type[1] = CELL_VDEC_MPEG2_PCT_FORBIDDEN; // ??? mp2->picture_coding_type[1] = CELL_VDEC_MPEG2_PCT_FORBIDDEN; // ???
@ -822,7 +822,7 @@ s32 cellVdecGetPicItem(u32 handle, vm::pptr<CellVdecPicItem> picItem)
s32 cellVdecSetFrameRate(u32 handle, CellVdecFrameRate frc) s32 cellVdecSetFrameRate(u32 handle, CellVdecFrameRate frc)
{ {
cellVdec.trace("cellVdecSetFrameRate(handle=0x%x, frc=0x%x)", handle, frc); cellVdec.trace("cellVdecSetFrameRate(handle=0x%x, frc=0x%x)", handle, (s32)frc);
const auto vdec = idm::get<ppu_thread, vdec_thread>(handle); const auto vdec = idm::get<ppu_thread, vdec_thread>(handle);

View File

@ -147,7 +147,7 @@ namespace sys_net
// TODO // TODO
thread_local vm::ptr<_tls_data_t> g_tls_net_data{}; thread_local vm::ptr<_tls_data_t> g_tls_net_data{};
static never_inline void initialize_tls() static NEVER_INLINE void initialize_tls()
{ {
// allocate if not initialized // allocate if not initialized
if (!g_tls_net_data) if (!g_tls_net_data)

View File

@ -10,6 +10,12 @@
const ppu_decoder<ppu_itype> s_ppu_itype; const ppu_decoder<ppu_itype> s_ppu_itype;
const ppu_decoder<ppu_iname> s_ppu_iname; const ppu_decoder<ppu_iname> s_ppu_iname;
template<>
void fmt_class_string<bitset_t<ppu_attr>::raw_type>::format(std::string& out, u64 arg)
{
out += "[UNIMPLEMENTED]";
}
void ppu_validate(const std::string& fname, const std::vector<ppu_function>& funcs, u32 reloc) void ppu_validate(const std::string& fname, const std::vector<ppu_function>& funcs, u32 reloc)
{ {
// Load custom PRX configuration if available // Load custom PRX configuration if available

View File

@ -73,20 +73,20 @@ namespace ppu_cb_detail
{ {
static_assert(std::is_same<T, ppu_thread&>::value, "Invalid callback argument type for ARG_CONTEXT"); static_assert(std::is_same<T, ppu_thread&>::value, "Invalid callback argument type for ARG_CONTEXT");
force_inline static void set_value(ppu_thread& CPU, const T& arg) FORCE_INLINE static void set_value(ppu_thread& CPU, const T& arg)
{ {
} }
}; };
template<u32 g_count, u32 f_count, u32 v_count> template<u32 g_count, u32 f_count, u32 v_count>
force_inline static bool _bind_func_args(ppu_thread& CPU) FORCE_INLINE static bool _bind_func_args(ppu_thread& CPU)
{ {
// terminator // terminator
return false; return false;
} }
template<u32 g_count, u32 f_count, u32 v_count, typename T1, typename... T> template<u32 g_count, u32 f_count, u32 v_count, typename T1, typename... T>
force_inline static bool _bind_func_args(ppu_thread& CPU, T1 arg1, T... args) FORCE_INLINE static bool _bind_func_args(ppu_thread& CPU, T1 arg1, T... args)
{ {
const bool is_float = std::is_floating_point<T1>::value; const bool is_float = std::is_floating_point<T1>::value;
const bool is_vector = std::is_same<CV T1, CV v128>::value; const bool is_vector = std::is_same<CV T1, CV v128>::value;
@ -116,7 +116,7 @@ namespace ppu_cb_detail
static_assert(type == ARG_GENERAL, "Unknown callback result type"); static_assert(type == ARG_GENERAL, "Unknown callback result type");
static_assert(sizeof(T) <= 8, "Invalid callback result type for ARG_GENERAL"); static_assert(sizeof(T) <= 8, "Invalid callback result type for ARG_GENERAL");
force_inline static T get_value(const ppu_thread& CPU) FORCE_INLINE static T get_value(const ppu_thread& CPU)
{ {
return ppu_gpr_cast<T>(CPU.gpr[3]); return ppu_gpr_cast<T>(CPU.gpr[3]);
} }
@ -127,7 +127,7 @@ namespace ppu_cb_detail
{ {
static_assert(sizeof(T) <= 8, "Invalid callback result type for ARG_FLOAT"); static_assert(sizeof(T) <= 8, "Invalid callback result type for ARG_FLOAT");
force_inline static T get_value(const ppu_thread& CPU) FORCE_INLINE static T get_value(const ppu_thread& CPU)
{ {
return static_cast<T>(CPU.fpr[1]); return static_cast<T>(CPU.fpr[1]);
} }
@ -138,7 +138,7 @@ namespace ppu_cb_detail
{ {
static_assert(std::is_same<CV T, CV v128>::value, "Invalid callback result type for ARG_VECTOR"); static_assert(std::is_same<CV T, CV v128>::value, "Invalid callback result type for ARG_VECTOR");
force_inline static T get_value(const ppu_thread& CPU) FORCE_INLINE static T get_value(const ppu_thread& CPU)
{ {
return CPU.vr[2]; return CPU.vr[2];
} }
@ -147,7 +147,7 @@ namespace ppu_cb_detail
template<typename RT, typename... T> template<typename RT, typename... T>
struct _func_caller struct _func_caller
{ {
force_inline static RT call(ppu_thread& CPU, u32 pc, u32 rtoc, T... args) FORCE_INLINE static RT call(ppu_thread& CPU, u32 pc, u32 rtoc, T... args)
{ {
_func_caller<void, T...>::call(CPU, pc, rtoc, args...); _func_caller<void, T...>::call(CPU, pc, rtoc, args...);
@ -164,7 +164,7 @@ namespace ppu_cb_detail
template<typename... T> template<typename... T>
struct _func_caller<void, T...> struct _func_caller<void, T...>
{ {
force_inline static void call(ppu_thread& CPU, u32 pc, u32 rtoc, T... args) FORCE_INLINE static void call(ppu_thread& CPU, u32 pc, u32 rtoc, T... args)
{ {
const bool stack = _bind_func_args<0, 0, 0, T...>(CPU, args...); const bool stack = _bind_func_args<0, 0, 0, T...>(CPU, args...);
CPU.gpr[1] -= stack ? FIXED_STACK_FRAME_SIZE : 0x30; // create reserved area CPU.gpr[1] -= stack ? FIXED_STACK_FRAME_SIZE : 0x30; // create reserved area
@ -177,7 +177,7 @@ namespace ppu_cb_detail
namespace vm namespace vm
{ {
template<typename AT, typename RT, typename... T> template<typename AT, typename RT, typename... T>
force_inline RT _ptr_base<RT(T...), AT>::operator()(ppu_thread& CPU, T... args) const FORCE_INLINE RT _ptr_base<RT(T...), AT>::operator()(ppu_thread& CPU, T... args) const
{ {
const auto data = vm::ps3::_ptr<u32>(vm::cast(m_addr, HERE)); const auto data = vm::ps3::_ptr<u32>(vm::cast(m_addr, HERE));
const u32 pc = data[0]; const u32 pc = data[0];

View File

@ -66,7 +66,7 @@ namespace ppu_func_detail
{ {
static_assert(std::is_same<CV T, CV v128>::value, "Invalid function argument type for ARG_VECTOR"); static_assert(std::is_same<CV T, CV v128>::value, "Invalid function argument type for ARG_VECTOR");
static force_inline T get_arg(ppu_thread& ppu) static FORCE_INLINE T get_arg(ppu_thread& ppu)
{ {
return ppu.vr[v_count + 1]; return ppu.vr[v_count + 1];
} }
@ -77,7 +77,7 @@ namespace ppu_func_detail
{ {
static_assert(alignof(T) <= 16, "Unsupported type alignment for ARG_STACK"); static_assert(alignof(T) <= 16, "Unsupported type alignment for ARG_STACK");
static force_inline T get_arg(ppu_thread& ppu) static FORCE_INLINE T get_arg(ppu_thread& ppu)
{ {
return ppu_gpr_cast<T, u64>(*ppu.get_stack_arg(g_count, alignof(T))); // TODO return ppu_gpr_cast<T, u64>(*ppu.get_stack_arg(g_count, alignof(T))); // TODO
} }
@ -88,7 +88,7 @@ namespace ppu_func_detail
{ {
static_assert(std::is_same<T, ppu_thread&>::value, "Invalid function argument type for ARG_CONTEXT"); static_assert(std::is_same<T, ppu_thread&>::value, "Invalid function argument type for ARG_CONTEXT");
static force_inline ppu_thread& get_arg(ppu_thread& ppu) static FORCE_INLINE ppu_thread& get_arg(ppu_thread& ppu)
{ {
return ppu; return ppu;
} }
@ -99,7 +99,7 @@ namespace ppu_func_detail
{ {
static_assert(std::is_same<T, ppu_va_args_t>::value, "Invalid function argument type for ARG_VARIADIC"); static_assert(std::is_same<T, ppu_va_args_t>::value, "Invalid function argument type for ARG_VARIADIC");
static force_inline ppu_va_args_t get_arg(ppu_thread& ppu) static FORCE_INLINE ppu_va_args_t get_arg(ppu_thread& ppu)
{ {
return{ g_count }; return{ g_count };
} }
@ -111,7 +111,7 @@ namespace ppu_func_detail
static_assert(type == ARG_GENERAL, "Unknown function result type"); static_assert(type == ARG_GENERAL, "Unknown function result type");
static_assert(sizeof(T) <= 8, "Invalid function result type for ARG_GENERAL"); static_assert(sizeof(T) <= 8, "Invalid function result type for ARG_GENERAL");
static force_inline void put_result(ppu_thread& ppu, const T& result) static FORCE_INLINE void put_result(ppu_thread& ppu, const T& result)
{ {
ppu.gpr[3] = ppu_gpr_cast(result); ppu.gpr[3] = ppu_gpr_cast(result);
} }
@ -122,7 +122,7 @@ namespace ppu_func_detail
{ {
static_assert(sizeof(T) <= 8, "Invalid function result type for ARG_FLOAT"); static_assert(sizeof(T) <= 8, "Invalid function result type for ARG_FLOAT");
static force_inline void put_result(ppu_thread& ppu, const T& result) static FORCE_INLINE void put_result(ppu_thread& ppu, const T& result)
{ {
ppu.fpr[1] = static_cast<T>(result); ppu.fpr[1] = static_cast<T>(result);
} }
@ -133,7 +133,7 @@ namespace ppu_func_detail
{ {
static_assert(std::is_same<CV T, CV v128>::value, "Invalid function result type for ARG_VECTOR"); static_assert(std::is_same<CV T, CV v128>::value, "Invalid function result type for ARG_VECTOR");
static force_inline void put_result(ppu_thread& ppu, const T& result) static FORCE_INLINE void put_result(ppu_thread& ppu, const T& result)
{ {
ppu.vr[2] = result; ppu.vr[2] = result;
} }
@ -160,21 +160,21 @@ namespace ppu_func_detail
// argument type + g/f/v_count unpacker // argument type + g/f/v_count unpacker
template<typename T, u32 type_pack> struct bind_arg_packed template<typename T, u32 type_pack> struct bind_arg_packed
{ {
static force_inline T get_arg(ppu_thread& ppu) static FORCE_INLINE T get_arg(ppu_thread& ppu)
{ {
return bind_arg<T, static_cast<arg_class>(type_pack & 0xff), (type_pack >> 8) & 0xff, (type_pack >> 16) & 0xff, (type_pack >> 24)>::get_arg(ppu); return bind_arg<T, static_cast<arg_class>(type_pack & 0xff), (type_pack >> 8) & 0xff, (type_pack >> 16) & 0xff, (type_pack >> 24)>::get_arg(ppu);
} }
}; };
template<u32... Info, typename RT, typename... Args> template<u32... Info, typename RT, typename... Args>
force_inline RT call(ppu_thread& ppu, RT(*func)(Args...), arg_info_pack_t<Info...>) FORCE_INLINE RT call(ppu_thread& ppu, RT(*func)(Args...), arg_info_pack_t<Info...>)
{ {
// do the actual function call when all arguments are prepared (simultaneous unpacking of Args... and Info...) // do the actual function call when all arguments are prepared (simultaneous unpacking of Args... and Info...)
return func(bind_arg_packed<Args, Info>::get_arg(ppu)...); return func(bind_arg_packed<Args, Info>::get_arg(ppu)...);
} }
template<typename T, typename... Types, u32... Info, typename RT, typename... Args> template<typename T, typename... Types, u32... Info, typename RT, typename... Args>
force_inline RT call(ppu_thread& ppu, RT(*func)(Args...), arg_info_pack_t<Info...> info) FORCE_INLINE RT call(ppu_thread& ppu, RT(*func)(Args...), arg_info_pack_t<Info...> info)
{ {
// unpack previous type counts (0/0/0 for the first time) // unpack previous type counts (0/0/0 for the first time)
const u32 g_count = (info.last_value >> 8) & 0xff; const u32 g_count = (info.last_value >> 8) & 0xff;
@ -220,7 +220,7 @@ namespace ppu_func_detail
{ {
using func_t = void(*)(T...); using func_t = void(*)(T...);
static force_inline void do_call(ppu_thread& ppu, func_t func) static FORCE_INLINE void do_call(ppu_thread& ppu, func_t func)
{ {
call<T...>(ppu, func, arg_info_pack_t<>{}); call<T...>(ppu, func, arg_info_pack_t<>{});
} }
@ -231,14 +231,14 @@ namespace ppu_func_detail
{ {
using func_t = RT(*)(T...); using func_t = RT(*)(T...);
static force_inline void do_call(ppu_thread& ppu, func_t func) static FORCE_INLINE void do_call(ppu_thread& ppu, func_t func)
{ {
bind_result<RT, result_type<RT>::value>::put_result(ppu, call<T...>(ppu, func, arg_info_pack_t<>{})); bind_result<RT, result_type<RT>::value>::put_result(ppu, call<T...>(ppu, func, arg_info_pack_t<>{}));
} }
}; };
template<typename RT, typename... T> template<typename RT, typename... T>
force_inline void do_call(ppu_thread& ppu, RT(*func)(T...)) FORCE_INLINE void do_call(ppu_thread& ppu, RT(*func)(T...))
{ {
func_binder<RT, T...>::do_call(ppu, func); func_binder<RT, T...>::do_call(ppu, func);
} }

View File

@ -283,7 +283,7 @@ public:
} }
} }
force_inline __m128 operator [] (s32 scale) const FORCE_INLINE __m128 operator [] (s32 scale) const
{ {
return m_data[scale + 31]; return m_data[scale + 31];
} }

View File

@ -748,9 +748,9 @@ std::shared_ptr<lv2_prx_t> ppu_load_prx(const ppu_prx_object& elf)
{ {
if (prog.p_memsz) if (prog.p_memsz)
{ {
const u32 mem_size = fmt::narrow<u32>("Invalid p_memsz (0x%llx)" HERE, prog.p_memsz); const u32 mem_size = ::narrow<u32>(prog.p_memsz, "p_memsz" HERE);
const u32 file_size = fmt::narrow<u32>("Invalid p_filesz (0x%llx)" HERE, prog.p_filesz); const u32 file_size = ::narrow<u32>(prog.p_filesz, "p_filesz" HERE);
const u32 init_addr = fmt::narrow<u32>("Invalid p_vaddr (0x%llx)" HERE, prog.p_vaddr); const u32 init_addr = ::narrow<u32>(prog.p_vaddr, "p_vaddr" HERE);
// Alloc segment memory // Alloc segment memory
const u32 addr = vm::alloc(mem_size, vm::main); const u32 addr = vm::alloc(mem_size, vm::main);
@ -965,7 +965,7 @@ void ppu_load_exec(const ppu_exec_object& elf)
LOG_NOTICE(LOADER, "** Segment: p_type=0x%x, p_vaddr=0x%llx, p_filesz=0x%llx, p_memsz=0x%llx, flags=0x%x", prog.p_type, prog.p_vaddr, prog.p_filesz, prog.p_memsz, prog.p_flags); LOG_NOTICE(LOADER, "** Segment: p_type=0x%x, p_vaddr=0x%llx, p_filesz=0x%llx, p_memsz=0x%llx, flags=0x%x", prog.p_type, prog.p_vaddr, prog.p_filesz, prog.p_memsz, prog.p_flags);
const u32 addr = vm::cast(prog.p_vaddr, HERE); const u32 addr = vm::cast(prog.p_vaddr, HERE);
const u32 size = fmt::narrow<u32>("Invalid p_memsz: 0x%llx" HERE, prog.p_memsz); const u32 size = ::narrow<u32>(prog.p_memsz, "p_memsz" HERE);
if (prog.p_type == 0x1 /* LOAD */ && prog.p_memsz) if (prog.p_type == 0x1 /* LOAD */ && prog.p_memsz)
{ {
@ -1004,8 +1004,8 @@ void ppu_load_exec(const ppu_exec_object& elf)
case 0x00000007: // TLS case 0x00000007: // TLS
{ {
tls_vaddr = vm::cast(prog.p_vaddr, HERE); tls_vaddr = vm::cast(prog.p_vaddr, HERE);
tls_fsize = fmt::narrow<u32>("Invalid p_filesz (0x%llx)" HERE, prog.p_filesz); tls_fsize = ::narrow<u32>(prog.p_filesz, "p_filesz" HERE);
tls_vsize = fmt::narrow<u32>("Invalid p_memsz (0x%llx)" HERE, prog.p_memsz); tls_vsize = ::narrow<u32>(prog.p_memsz, "p_memsz" HERE);
break; break;
} }

View File

@ -87,7 +87,7 @@ std::string ppu_thread::dump() const
ret += "\nRegisters:\n=========\n"; ret += "\nRegisters:\n=========\n";
for (uint i = 0; i < 32; ++i) ret += fmt::format("GPR[%d] = 0x%llx\n", i, gpr[i]); for (uint i = 0; i < 32; ++i) ret += fmt::format("GPR[%d] = 0x%llx\n", i, gpr[i]);
for (uint i = 0; i < 32; ++i) ret += fmt::format("FPR[%d] = %.6G\n", i, fpr[i]); for (uint i = 0; i < 32; ++i) ret += fmt::format("FPR[%d] = %.6G\n", i, fpr[i]);
for (uint i = 0; i < 32; ++i) ret += fmt::format("VR[%d] = 0x%s [%s]\n", i, vr[i].to_hex().c_str(), vr[i].to_xyzw().c_str()); for (uint i = 0; i < 32; ++i) ret += fmt::format("VR[%d] = %s [x: %g y: %g z: %g w: %g]\n", i, vr[i], vr[i]._f[3], vr[i]._f[2], vr[i]._f[1], vr[i]._f[0]);
if (g_cfg_ppu_decoder.get() != ppu_decoder_type::llvm) if (g_cfg_ppu_decoder.get() != ppu_decoder_type::llvm)
{ {

View File

@ -130,7 +130,7 @@ std::string SPUThread::dump() const
{ {
std::string ret = "Registers:\n=========\n"; std::string ret = "Registers:\n=========\n";
for (uint i = 0; i<128; ++i) ret += fmt::format("GPR[%d] = 0x%s\n", i, gpr[i].to_hex().c_str()); for (uint i = 0; i<128; ++i) ret += fmt::format("GPR[%d] = %s\n", i, gpr[i]);
return ret; return ret;
} }
@ -1254,7 +1254,7 @@ bool SPUThread::stop_and_signal(u32 code)
} }
else else
{ {
throw EXCEPTION("Unexpected SPU Thread Group state (%d)", group->state); throw EXCEPTION("Unexpected SPU Thread Group state (%d)", (u32)group->state);
} }
if (queue->events()) if (queue->events())
@ -1294,7 +1294,7 @@ bool SPUThread::stop_and_signal(u32 code)
} }
else else
{ {
throw EXCEPTION("Unexpected SPU Thread Group state (%d)", group->state); throw EXCEPTION("Unexpected SPU Thread Group state (%d)", (u32)group->state);
} }
for (auto& thread : group->threads) for (auto& thread : group->threads)

View File

@ -377,7 +377,7 @@ struct spu_imm_table_t
public: public:
scale_table_t(); scale_table_t();
force_inline __m128 operator [] (s32 scale) const FORCE_INLINE __m128 operator [] (s32 scale) const
{ {
return m_data[scale + 155]; return m_data[scale + 155];
} }

View File

@ -80,7 +80,7 @@ void lv2_event_queue_t::push(lv2_lock_t, u64 source, u64 data1, u64 data2, u64 d
} }
else else
{ {
throw fmt::exception("Unexpected (queue.type=%d, thread.type=%d)" HERE, type, thread->type); throw fmt::exception("Unexpected (queue type=%d, thread type=%d)" HERE, type, (s32)thread->type);
} }
VERIFY(!thread->state.test_and_set(cpu_state::signal)); VERIFY(!thread->state.test_and_set(cpu_state::signal));

View File

@ -490,7 +490,7 @@ namespace vm
if (!block) if (!block)
{ {
throw EXCEPTION("Invalid memory location (%d)", location); throw fmt::exception("Invalid memory location (%u)" HERE, (uint)location);
} }
return block->alloc(size, align, sup); return block->alloc(size, align, sup);
@ -502,7 +502,7 @@ namespace vm
if (!block) if (!block)
{ {
throw EXCEPTION("Invalid memory location (%d, addr=0x%x)", location, addr); throw fmt::exception("Invalid memory location (%u, addr=0x%x)" HERE, (uint)location, addr);
} }
return block->falloc(addr, size, sup); return block->falloc(addr, size, sup);
@ -514,7 +514,7 @@ namespace vm
if (!block) if (!block)
{ {
throw EXCEPTION("Invalid memory location (%d, addr=0x%x)", location, addr); throw fmt::exception("Invalid memory location (%u, addr=0x%x)" HERE, (uint)location, addr);
} }
return block->dealloc(addr, sup_out); return block->dealloc(addr, sup_out);
@ -526,7 +526,7 @@ namespace vm
if (!block) if (!block)
{ {
LOG_ERROR(MEMORY, "vm::dealloc(): invalid memory location (%d, addr=0x%x)\n", location, addr); LOG_ERROR(MEMORY, "vm::dealloc(): invalid memory location (%u, addr=0x%x)\n", (uint)location, addr);
return; return;
} }

View File

@ -182,12 +182,12 @@ namespace vm
{ {
static vm::addr_t cast(u64 addr, const char* loc) static vm::addr_t cast(u64 addr, const char* loc)
{ {
return static_cast<vm::addr_t>(fmt::narrow<u32>("Memory address out of range: 0x%llx%s", addr, loc)); return static_cast<vm::addr_t>(static_cast<u32>(addr));
} }
static vm::addr_t cast(u64 addr) static vm::addr_t cast(u64 addr)
{ {
return static_cast<vm::addr_t>(fmt::narrow<u32>("Memory address out of range: 0x%llx", addr)); return static_cast<vm::addr_t>(static_cast<u32>(addr));
} }
}; };

View File

@ -492,10 +492,12 @@ struct to_se<vm::_ptr_base<T, AT>, Se>
// Format pointer // Format pointer
template<typename T, typename AT> template<typename T, typename AT>
struct unveil<vm::_ptr_base<T, AT>, void> struct fmt_unveil<vm::_ptr_base<T, AT>, void>
{ {
static inline auto get(const vm::_ptr_base<T, AT>& arg) using type = typename fmt_unveil<AT>::type;
static inline u64 get(const vm::_ptr_base<T, AT>& arg)
{ {
return unveil<AT>::get(arg.addr()); return fmt_unveil<AT>::get(arg.addr());
} }
}; };

View File

@ -191,7 +191,7 @@ struct to_se<vm::_ref_base<T, AT>, Se>
// Forbid formatting // Forbid formatting
template<typename T, typename AT> template<typename T, typename AT>
struct unveil<vm::_ref_base<T, AT>, void> struct fmt_unveil<vm::_ref_base<T, AT>, void>
{ {
static_assert(!sizeof(T), "vm::_ref_base<>: ambiguous format argument"); static_assert(!sizeof(T), "vm::_ref_base<>: ambiguous format argument");
}; };

View File

@ -5,7 +5,7 @@
namespace vm namespace vm
{ {
template<typename AT, typename RT, typename... T> template<typename AT, typename RT, typename... T>
force_inline RT _ptr_base<RT(T...), AT>::operator()(ARMv7Thread& cpu, T... args) const FORCE_INLINE RT _ptr_base<RT(T...), AT>::operator()(ARMv7Thread& cpu, T... args) const
{ {
return arm_func_detail::func_caller<RT, T...>::call(cpu, vm::cast(this->addr(), HERE), args...); return arm_func_detail::func_caller<RT, T...>::call(cpu, vm::cast(this->addr(), HERE), args...);
} }

View File

@ -39,12 +39,12 @@ namespace arm_func_detail
static_assert(!std::is_reference<T>::value, "Invalid function argument type (reference)"); static_assert(!std::is_reference<T>::value, "Invalid function argument type (reference)");
static_assert(sizeof(T) <= 4, "Invalid function argument type for ARG_GENERAL"); static_assert(sizeof(T) <= 4, "Invalid function argument type for ARG_GENERAL");
force_inline static T get_arg(ARMv7Thread& cpu) FORCE_INLINE static T get_arg(ARMv7Thread& cpu)
{ {
return arm_gpr_cast<T>(cpu.GPR[g_count - 1]); return arm_gpr_cast<T>(cpu.GPR[g_count - 1]);
} }
force_inline static void put_arg(ARMv7Thread& cpu, const T& arg) FORCE_INLINE static void put_arg(ARMv7Thread& cpu, const T& arg)
{ {
cpu.GPR[g_count - 1] = arm_gpr_cast(arg); cpu.GPR[g_count - 1] = arm_gpr_cast(arg);
} }
@ -56,12 +56,12 @@ namespace arm_func_detail
// first u64 argument is passed in r0-r1, second one is passed in r2-r3 (if g_count = 3) // first u64 argument is passed in r0-r1, second one is passed in r2-r3 (if g_count = 3)
static_assert(g_count == 2 || g_count == 4, "Wrong u64 argument position"); static_assert(g_count == 2 || g_count == 4, "Wrong u64 argument position");
force_inline static u64 get_arg(ARMv7Thread& cpu) FORCE_INLINE static u64 get_arg(ARMv7Thread& cpu)
{ {
return cpu.GPR_D[(g_count - 1) >> 1]; return cpu.GPR_D[(g_count - 1) >> 1];
} }
force_inline static void put_arg(ARMv7Thread& cpu, u64 arg) FORCE_INLINE static void put_arg(ARMv7Thread& cpu, u64 arg)
{ {
cpu.GPR_D[(g_count - 1) >> 1] = arg; cpu.GPR_D[(g_count - 1) >> 1] = arg;
} }
@ -72,12 +72,12 @@ namespace arm_func_detail
{ {
static_assert(g_count == 2 || g_count == 4, "Wrong s64 argument position"); static_assert(g_count == 2 || g_count == 4, "Wrong s64 argument position");
force_inline static s64 get_arg(ARMv7Thread& cpu) FORCE_INLINE static s64 get_arg(ARMv7Thread& cpu)
{ {
return cpu.GPR_D[(g_count - 1) >> 1]; return cpu.GPR_D[(g_count - 1) >> 1];
} }
force_inline static void put_arg(ARMv7Thread& cpu, s64 arg) FORCE_INLINE static void put_arg(ARMv7Thread& cpu, s64 arg)
{ {
cpu.GPR_D[(g_count - 1) >> 1] = arg; cpu.GPR_D[(g_count - 1) >> 1] = arg;
} }
@ -89,11 +89,11 @@ namespace arm_func_detail
static_assert(f_count <= 0, "TODO: Unsupported argument type (float)"); static_assert(f_count <= 0, "TODO: Unsupported argument type (float)");
static_assert(sizeof(T) <= 8, "Invalid function argument type for ARG_FLOAT"); static_assert(sizeof(T) <= 8, "Invalid function argument type for ARG_FLOAT");
force_inline static T get_arg(ARMv7Thread& cpu) FORCE_INLINE static T get_arg(ARMv7Thread& cpu)
{ {
} }
force_inline static void put_arg(ARMv7Thread& cpu, const T& arg) FORCE_INLINE static void put_arg(ARMv7Thread& cpu, const T& arg)
{ {
} }
}; };
@ -104,11 +104,11 @@ namespace arm_func_detail
static_assert(v_count <= 0, "TODO: Unsupported argument type (vector)"); static_assert(v_count <= 0, "TODO: Unsupported argument type (vector)");
static_assert(std::is_same<CV T, CV v128>::value, "Invalid function argument type for ARG_VECTOR"); static_assert(std::is_same<CV T, CV v128>::value, "Invalid function argument type for ARG_VECTOR");
force_inline static T get_arg(ARMv7Thread& cpu) FORCE_INLINE static T get_arg(ARMv7Thread& cpu)
{ {
} }
force_inline static void put_arg(ARMv7Thread& cpu, const T& arg) FORCE_INLINE static void put_arg(ARMv7Thread& cpu, const T& arg)
{ {
} }
}; };
@ -120,13 +120,13 @@ namespace arm_func_detail
static_assert(v_count <= 0, "TODO: Unsupported stack argument type (vector)"); static_assert(v_count <= 0, "TODO: Unsupported stack argument type (vector)");
static_assert(sizeof(T) <= 4, "Invalid function argument type for ARG_STACK"); static_assert(sizeof(T) <= 4, "Invalid function argument type for ARG_STACK");
force_inline static T get_arg(ARMv7Thread& cpu) FORCE_INLINE static T get_arg(ARMv7Thread& cpu)
{ {
// TODO: check // TODO: check
return arm_gpr_cast<T, u32>(vm::psv::read32(cpu.SP + sizeof(u32) * (g_count - 5))); return arm_gpr_cast<T, u32>(vm::psv::read32(cpu.SP + sizeof(u32) * (g_count - 5)));
} }
force_inline static void put_arg(ARMv7Thread& cpu, const T& arg) FORCE_INLINE static void put_arg(ARMv7Thread& cpu, const T& arg)
{ {
// TODO: check // TODO: check
const int stack_pos = (g_count - 5) * 4 - FIXED_STACK_FRAME_SIZE; const int stack_pos = (g_count - 5) * 4 - FIXED_STACK_FRAME_SIZE;
@ -139,13 +139,13 @@ namespace arm_func_detail
template<u32 g_count, u32 f_count, u32 v_count> template<u32 g_count, u32 f_count, u32 v_count>
struct bind_arg<u64, ARG_STACK, g_count, f_count, v_count> struct bind_arg<u64, ARG_STACK, g_count, f_count, v_count>
{ {
force_inline static u64 get_arg(ARMv7Thread& cpu) FORCE_INLINE static u64 get_arg(ARMv7Thread& cpu)
{ {
// TODO: check // TODO: check
return vm::psv::read64(cpu.SP + sizeof(u32) * (g_count - 6)); return vm::psv::read64(cpu.SP + sizeof(u32) * (g_count - 6));
} }
force_inline static void put_arg(ARMv7Thread& cpu, u64 arg) FORCE_INLINE static void put_arg(ARMv7Thread& cpu, u64 arg)
{ {
// TODO: check // TODO: check
const int stack_pos = (g_count - 6) * 4 - FIXED_STACK_FRAME_SIZE; const int stack_pos = (g_count - 6) * 4 - FIXED_STACK_FRAME_SIZE;
@ -158,13 +158,13 @@ namespace arm_func_detail
template<u32 g_count, u32 f_count, u32 v_count> template<u32 g_count, u32 f_count, u32 v_count>
struct bind_arg<s64, ARG_STACK, g_count, f_count, v_count> struct bind_arg<s64, ARG_STACK, g_count, f_count, v_count>
{ {
force_inline static s64 get_arg(ARMv7Thread& cpu) FORCE_INLINE static s64 get_arg(ARMv7Thread& cpu)
{ {
// TODO: check // TODO: check
return vm::psv::read64(cpu.SP + sizeof(u32) * (g_count - 6)); return vm::psv::read64(cpu.SP + sizeof(u32) * (g_count - 6));
} }
force_inline static void put_arg(ARMv7Thread& cpu, s64 arg) FORCE_INLINE static void put_arg(ARMv7Thread& cpu, s64 arg)
{ {
// TODO: check // TODO: check
const int stack_pos = (g_count - 6) * 4 - FIXED_STACK_FRAME_SIZE; const int stack_pos = (g_count - 6) * 4 - FIXED_STACK_FRAME_SIZE;
@ -179,12 +179,12 @@ namespace arm_func_detail
{ {
static_assert(std::is_same<T, ARMv7Thread&>::value, "Invalid function argument type for ARG_CONTEXT"); static_assert(std::is_same<T, ARMv7Thread&>::value, "Invalid function argument type for ARG_CONTEXT");
force_inline static ARMv7Thread& get_arg(ARMv7Thread& cpu) FORCE_INLINE static ARMv7Thread& get_arg(ARMv7Thread& cpu)
{ {
return cpu; return cpu;
} }
force_inline static void put_arg(ARMv7Thread& cpu, ARMv7Thread& arg) FORCE_INLINE static void put_arg(ARMv7Thread& cpu, ARMv7Thread& arg)
{ {
} }
}; };
@ -194,7 +194,7 @@ namespace arm_func_detail
{ {
static_assert(std::is_same<CV T, CV arm_va_args_t>::value, "Invalid function argument type for ARG_VARIADIC"); static_assert(std::is_same<CV T, CV arm_va_args_t>::value, "Invalid function argument type for ARG_VARIADIC");
force_inline static arm_va_args_t get_arg(ARMv7Thread& cpu) FORCE_INLINE static arm_va_args_t get_arg(ARMv7Thread& cpu)
{ {
return{ g_count }; return{ g_count };
} }
@ -208,12 +208,12 @@ namespace arm_func_detail
static_assert(type == ARG_GENERAL, "Wrong use of bind_result template"); static_assert(type == ARG_GENERAL, "Wrong use of bind_result template");
static_assert(sizeof(T) <= 4, "Invalid function result type for ARG_GENERAL"); static_assert(sizeof(T) <= 4, "Invalid function result type for ARG_GENERAL");
force_inline static T get_result(ARMv7Thread& cpu) FORCE_INLINE static T get_result(ARMv7Thread& cpu)
{ {
return arm_gpr_cast<T>(cpu.GPR[0]); return arm_gpr_cast<T>(cpu.GPR[0]);
} }
force_inline static void put_result(ARMv7Thread& cpu, const T& result) FORCE_INLINE static void put_result(ARMv7Thread& cpu, const T& result)
{ {
cpu.GPR[0] = arm_gpr_cast(result); cpu.GPR[0] = arm_gpr_cast(result);
} }
@ -222,12 +222,12 @@ namespace arm_func_detail
template<> template<>
struct bind_result<u64, ARG_GENERAL> struct bind_result<u64, ARG_GENERAL>
{ {
force_inline static u64 get_result(ARMv7Thread& cpu) FORCE_INLINE static u64 get_result(ARMv7Thread& cpu)
{ {
return cpu.GPR_D[0]; return cpu.GPR_D[0];
} }
force_inline static void put_result(ARMv7Thread& cpu, u64 result) FORCE_INLINE static void put_result(ARMv7Thread& cpu, u64 result)
{ {
cpu.GPR_D[0] = result; cpu.GPR_D[0] = result;
} }
@ -236,12 +236,12 @@ namespace arm_func_detail
template<> template<>
struct bind_result<s64, ARG_GENERAL> struct bind_result<s64, ARG_GENERAL>
{ {
force_inline static s64 get_result(ARMv7Thread& cpu) FORCE_INLINE static s64 get_result(ARMv7Thread& cpu)
{ {
return cpu.GPR_D[0]; return cpu.GPR_D[0];
} }
force_inline static void put_result(ARMv7Thread& cpu, s64 result) FORCE_INLINE static void put_result(ARMv7Thread& cpu, s64 result)
{ {
cpu.GPR_D[0] = result; cpu.GPR_D[0] = result;
} }
@ -252,7 +252,7 @@ namespace arm_func_detail
//{ //{
// static_assert(sizeof(T) <= 8, "Invalid function result type for ARG_FLOAT"); // static_assert(sizeof(T) <= 8, "Invalid function result type for ARG_FLOAT");
// static force_inline void put_result(ARMv7Thread& cpu, const T& result) // static FORCE_INLINE void put_result(ARMv7Thread& cpu, const T& result)
// { // {
// } // }
//}; //};
@ -262,7 +262,7 @@ namespace arm_func_detail
//{ //{
// static_assert(std::is_same<std::remove_cv_t<T>, v128>::value, "Invalid function result type for ARG_VECTOR"); // static_assert(std::is_same<std::remove_cv_t<T>, v128>::value, "Invalid function result type for ARG_VECTOR");
// static force_inline void put_result(ARMv7Thread& cpu, const T& result) // static FORCE_INLINE void put_result(ARMv7Thread& cpu, const T& result)
// { // {
// } // }
//}; //};
@ -322,21 +322,21 @@ namespace arm_func_detail
// argument type + g/f/v_count unpacker // argument type + g/f/v_count unpacker
template<typename T, u32 type_pack> struct bind_arg_packed template<typename T, u32 type_pack> struct bind_arg_packed
{ {
force_inline static T get_arg(ARMv7Thread& cpu) FORCE_INLINE static T get_arg(ARMv7Thread& cpu)
{ {
return bind_arg<T, static_cast<arg_class>(type_pack & 0xff), (type_pack >> 8) & 0xff, (type_pack >> 16) & 0xff, (type_pack >> 24)>::get_arg(cpu); return bind_arg<T, static_cast<arg_class>(type_pack & 0xff), (type_pack >> 8) & 0xff, (type_pack >> 16) & 0xff, (type_pack >> 24)>::get_arg(cpu);
} }
}; };
template<u32... Info, typename RT, typename... Args> template<u32... Info, typename RT, typename... Args>
force_inline RT call(ARMv7Thread& cpu, RT(*func)(Args...), arg_info_pack_t<Info...> info) FORCE_INLINE RT call(ARMv7Thread& cpu, RT(*func)(Args...), arg_info_pack_t<Info...> info)
{ {
// do the actual function call when all arguments are prepared (simultaneous unpacking of Args... and Info...) // do the actual function call when all arguments are prepared (simultaneous unpacking of Args... and Info...)
return func(bind_arg_packed<Args, Info>::get_arg(cpu)...); return func(bind_arg_packed<Args, Info>::get_arg(cpu)...);
} }
template<typename T, typename... Types, u32... Info, typename RT, typename... Args> template<typename T, typename... Types, u32... Info, typename RT, typename... Args>
force_inline RT call(ARMv7Thread& cpu, RT(*func)(Args...), arg_info_pack_t<Info...> info) FORCE_INLINE RT call(ARMv7Thread& cpu, RT(*func)(Args...), arg_info_pack_t<Info...> info)
{ {
// unpack previous type counts (0/0/0 for the first time) // unpack previous type counts (0/0/0 for the first time)
const u32 g_count = (info.last_value >> 8) & 0xff; const u32 g_count = (info.last_value >> 8) & 0xff;
@ -353,14 +353,14 @@ namespace arm_func_detail
} }
template<u32 g_count, u32 f_count, u32 v_count> template<u32 g_count, u32 f_count, u32 v_count>
force_inline static bool put_func_args(ARMv7Thread& cpu) FORCE_INLINE static bool put_func_args(ARMv7Thread& cpu)
{ {
// terminator // terminator
return false; return false;
} }
template<u32 g_count, u32 f_count, u32 v_count, typename T1, typename... T> template<u32 g_count, u32 f_count, u32 v_count, typename T1, typename... T>
force_inline static bool put_func_args(ARMv7Thread& cpu, T1 arg, T... args) FORCE_INLINE static bool put_func_args(ARMv7Thread& cpu, T1 arg, T... args)
{ {
using type = arg_type<T1, g_count, f_count, v_count>; using type = arg_type<T1, g_count, f_count, v_count>;
const arg_class t = type::value; const arg_class t = type::value;
@ -402,7 +402,7 @@ namespace arm_func_detail
template<typename RT, typename... T> template<typename RT, typename... T>
struct func_caller struct func_caller
{ {
force_inline static RT call(ARMv7Thread& cpu, u32 addr, T... args) FORCE_INLINE static RT call(ARMv7Thread& cpu, u32 addr, T... args)
{ {
func_caller<void, T...>::call(cpu, addr, args...); func_caller<void, T...>::call(cpu, addr, args...);
@ -413,7 +413,7 @@ namespace arm_func_detail
template<typename... T> template<typename... T>
struct func_caller<void, T...> struct func_caller<void, T...>
{ {
force_inline static void call(ARMv7Thread& cpu, u32 addr, T... args) FORCE_INLINE static void call(ARMv7Thread& cpu, u32 addr, T... args)
{ {
if (put_func_args<0, 0, 0, T...>(cpu, args...)) if (put_func_args<0, 0, 0, T...>(cpu, args...))
{ {
@ -428,7 +428,7 @@ namespace arm_func_detail
} }
}; };
template<typename RT, typename... T> force_inline void do_call(ARMv7Thread& cpu, RT(*func)(T...)) template<typename RT, typename... T> FORCE_INLINE void do_call(ARMv7Thread& cpu, RT(*func)(T...))
{ {
func_binder<RT, T...>::do_call(cpu, func); func_binder<RT, T...>::do_call(cpu, func);
} }

View File

@ -20,7 +20,7 @@ D3D12_BLEND_OP get_blend_op(rsx::blend_equation op)
case rsx::blend_equation::reverse_substract_signed: case rsx::blend_equation::reverse_substract_signed:
break; break;
} }
throw EXCEPTION("Invalid or unsupported blend op (0x%x)", op); throw EXCEPTION("Invalid or unsupported blend op (0x%x)", (u32)op);
} }
D3D12_BLEND get_blend_factor(rsx::blend_factor factor) D3D12_BLEND get_blend_factor(rsx::blend_factor factor)
@ -45,7 +45,7 @@ D3D12_BLEND get_blend_factor(rsx::blend_factor factor)
case rsx::blend_factor::one_minus_constant_alpha: case rsx::blend_factor::one_minus_constant_alpha:
return D3D12_BLEND_INV_BLEND_FACTOR; return D3D12_BLEND_INV_BLEND_FACTOR;
} }
throw EXCEPTION("Invalid blend factor (0x%x)", factor); throw EXCEPTION("Invalid blend factor (0x%x)", (u32)factor);
} }
D3D12_BLEND get_blend_factor_alpha(rsx::blend_factor factor) D3D12_BLEND get_blend_factor_alpha(rsx::blend_factor factor)
@ -70,7 +70,7 @@ D3D12_BLEND get_blend_factor_alpha(rsx::blend_factor factor)
case rsx::blend_factor::one_minus_constant_alpha: case rsx::blend_factor::one_minus_constant_alpha:
return D3D12_BLEND_INV_BLEND_FACTOR; return D3D12_BLEND_INV_BLEND_FACTOR;
} }
throw EXCEPTION("Invalid blend alpha factor (0x%x)", factor); throw EXCEPTION("Invalid blend alpha factor (0x%x)", (u32)factor);
} }
/** /**
@ -96,7 +96,7 @@ D3D12_LOGIC_OP get_logic_op(rsx::logic_op op)
case rsx::logic_op::logic_or_inverted: return D3D12_LOGIC_OP_OR_INVERTED; case rsx::logic_op::logic_or_inverted: return D3D12_LOGIC_OP_OR_INVERTED;
case rsx::logic_op::logic_nand: return D3D12_LOGIC_OP_NAND; case rsx::logic_op::logic_nand: return D3D12_LOGIC_OP_NAND;
} }
throw EXCEPTION("Invalid logic op (0x%x)", op); throw EXCEPTION("Invalid logic op (0x%x)", (u32)op);
} }
/** /**
@ -115,7 +115,7 @@ D3D12_STENCIL_OP get_stencil_op(rsx::stencil_op op)
case rsx::stencil_op::incr_wrap: return D3D12_STENCIL_OP_INCR; case rsx::stencil_op::incr_wrap: return D3D12_STENCIL_OP_INCR;
case rsx::stencil_op::decr_wrap: return D3D12_STENCIL_OP_DECR; case rsx::stencil_op::decr_wrap: return D3D12_STENCIL_OP_DECR;
} }
throw EXCEPTION("Invalid stencil op (0x%x)", op); throw EXCEPTION("Invalid stencil op (0x%x)", (u32)op);
} }
D3D12_COMPARISON_FUNC get_compare_func(rsx::comparison_function op) D3D12_COMPARISON_FUNC get_compare_func(rsx::comparison_function op)
@ -131,7 +131,7 @@ D3D12_COMPARISON_FUNC get_compare_func(rsx::comparison_function op)
case rsx::comparison_function::greater_or_equal: return D3D12_COMPARISON_FUNC_GREATER_EQUAL; case rsx::comparison_function::greater_or_equal: return D3D12_COMPARISON_FUNC_GREATER_EQUAL;
case rsx::comparison_function::always: return D3D12_COMPARISON_FUNC_ALWAYS; case rsx::comparison_function::always: return D3D12_COMPARISON_FUNC_ALWAYS;
} }
throw EXCEPTION("Invalid or unsupported compare func (0x%x)", op); throw EXCEPTION("Invalid or unsupported compare func (0x%x)", (u32)op);
} }
DXGI_FORMAT get_texture_format(u8 format) DXGI_FORMAT get_texture_format(u8 format)
@ -169,7 +169,7 @@ DXGI_FORMAT get_texture_format(u8 format)
case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: return DXGI_FORMAT_R8G8_B8G8_UNORM; case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: return DXGI_FORMAT_R8G8_B8G8_UNORM;
break; break;
} }
throw EXCEPTION("Invalid or unsupported texture format (0x%x)", format); throw EXCEPTION("Invalid or unsupported texture format (0x%x)", (u32)format);
} }
UINT get_texture_max_aniso(rsx::texture_max_anisotropy aniso) UINT get_texture_max_aniso(rsx::texture_max_anisotropy aniso)
@ -185,7 +185,7 @@ UINT get_texture_max_aniso(rsx::texture_max_anisotropy aniso)
case rsx::texture_max_anisotropy::x12: return 12; case rsx::texture_max_anisotropy::x12: return 12;
case rsx::texture_max_anisotropy::x16: return 16; case rsx::texture_max_anisotropy::x16: return 16;
} }
throw EXCEPTION("Invalid texture max aniso (0x%x)", aniso); throw EXCEPTION("Invalid texture max aniso (0x%x)", (u32)aniso);
} }
D3D12_TEXTURE_ADDRESS_MODE get_texture_wrap_mode(rsx::texture_wrap_mode wrap) D3D12_TEXTURE_ADDRESS_MODE get_texture_wrap_mode(rsx::texture_wrap_mode wrap)
@ -201,7 +201,7 @@ D3D12_TEXTURE_ADDRESS_MODE get_texture_wrap_mode(rsx::texture_wrap_mode wrap)
case rsx::texture_wrap_mode::mirror_once_border: return D3D12_TEXTURE_ADDRESS_MODE_MIRROR_ONCE; case rsx::texture_wrap_mode::mirror_once_border: return D3D12_TEXTURE_ADDRESS_MODE_MIRROR_ONCE;
case rsx::texture_wrap_mode::mirror_once_clamp: return D3D12_TEXTURE_ADDRESS_MODE_MIRROR_ONCE; case rsx::texture_wrap_mode::mirror_once_clamp: return D3D12_TEXTURE_ADDRESS_MODE_MIRROR_ONCE;
} }
throw EXCEPTION("Invalid texture wrap mode (0x%x)", wrap); throw EXCEPTION("Invalid texture wrap mode (0x%x)", (u32)wrap);
} }
namespace namespace
@ -277,7 +277,7 @@ D3D12_PRIMITIVE_TOPOLOGY get_primitive_topology(rsx::primitive_type draw_mode)
case rsx::primitive_type::quad_strip: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; case rsx::primitive_type::quad_strip: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
case rsx::primitive_type::polygon: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; case rsx::primitive_type::polygon: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
} }
throw EXCEPTION("Invalid draw mode (0x%x)", draw_mode); throw EXCEPTION("Invalid draw mode (0x%x)", (u32)draw_mode);
} }
D3D12_PRIMITIVE_TOPOLOGY_TYPE get_primitive_topology_type(rsx::primitive_type draw_mode) D3D12_PRIMITIVE_TOPOLOGY_TYPE get_primitive_topology_type(rsx::primitive_type draw_mode)
@ -295,7 +295,7 @@ D3D12_PRIMITIVE_TOPOLOGY_TYPE get_primitive_topology_type(rsx::primitive_type dr
case rsx::primitive_type::polygon: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; case rsx::primitive_type::polygon: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
case rsx::primitive_type::line_loop: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE; case rsx::primitive_type::line_loop: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE;
} }
throw EXCEPTION("Invalid or unsupported draw mode (0x%x)", draw_mode); throw EXCEPTION("Invalid or unsupported draw mode (0x%x)", (u32)draw_mode);
} }
DXGI_FORMAT get_color_surface_format(rsx::surface_color_format format) DXGI_FORMAT get_color_surface_format(rsx::surface_color_format format)
@ -316,7 +316,7 @@ DXGI_FORMAT get_color_surface_format(rsx::surface_color_format format)
case rsx::surface_color_format::w32z32y32x32: return DXGI_FORMAT_R32G32B32A32_FLOAT; case rsx::surface_color_format::w32z32y32x32: return DXGI_FORMAT_R32G32B32A32_FLOAT;
case rsx::surface_color_format::x32: return DXGI_FORMAT_R32_FLOAT; case rsx::surface_color_format::x32: return DXGI_FORMAT_R32_FLOAT;
} }
throw EXCEPTION("Invalid format (0x%x)", format); throw EXCEPTION("Invalid format (0x%x)", (u32)format);
} }
DXGI_FORMAT get_depth_stencil_surface_format(rsx::surface_depth_format format) DXGI_FORMAT get_depth_stencil_surface_format(rsx::surface_depth_format format)
@ -326,7 +326,7 @@ DXGI_FORMAT get_depth_stencil_surface_format(rsx::surface_depth_format format)
case rsx::surface_depth_format::z16: return DXGI_FORMAT_D16_UNORM; case rsx::surface_depth_format::z16: return DXGI_FORMAT_D16_UNORM;
case rsx::surface_depth_format::z24s8: return DXGI_FORMAT_D24_UNORM_S8_UINT; case rsx::surface_depth_format::z24s8: return DXGI_FORMAT_D24_UNORM_S8_UINT;
} }
throw EXCEPTION("Invalid format (0x%x)", format); throw EXCEPTION("Invalid format (0x%x)", (u32)format);
} }
DXGI_FORMAT get_depth_stencil_surface_clear_format(rsx::surface_depth_format format) DXGI_FORMAT get_depth_stencil_surface_clear_format(rsx::surface_depth_format format)
@ -336,7 +336,7 @@ DXGI_FORMAT get_depth_stencil_surface_clear_format(rsx::surface_depth_format for
case rsx::surface_depth_format::z16: return DXGI_FORMAT_D16_UNORM; case rsx::surface_depth_format::z16: return DXGI_FORMAT_D16_UNORM;
case rsx::surface_depth_format::z24s8: return DXGI_FORMAT_D24_UNORM_S8_UINT; case rsx::surface_depth_format::z24s8: return DXGI_FORMAT_D24_UNORM_S8_UINT;
} }
throw EXCEPTION("Invalid format (0x%x)", format); throw EXCEPTION("Invalid format (0x%x)", (u32)format);
} }
DXGI_FORMAT get_depth_stencil_typeless_surface_format(rsx::surface_depth_format format) DXGI_FORMAT get_depth_stencil_typeless_surface_format(rsx::surface_depth_format format)
@ -346,7 +346,7 @@ DXGI_FORMAT get_depth_stencil_typeless_surface_format(rsx::surface_depth_format
case rsx::surface_depth_format::z16: return DXGI_FORMAT_R16_TYPELESS; case rsx::surface_depth_format::z16: return DXGI_FORMAT_R16_TYPELESS;
case rsx::surface_depth_format::z24s8: return DXGI_FORMAT_R24G8_TYPELESS; case rsx::surface_depth_format::z24s8: return DXGI_FORMAT_R24G8_TYPELESS;
} }
throw EXCEPTION("Invalid format (0x%x)", format); throw EXCEPTION("Invalid format (0x%x)", (u32)format);
} }
DXGI_FORMAT get_depth_samplable_surface_format(rsx::surface_depth_format format) DXGI_FORMAT get_depth_samplable_surface_format(rsx::surface_depth_format format)
@ -356,7 +356,7 @@ DXGI_FORMAT get_depth_samplable_surface_format(rsx::surface_depth_format format)
case rsx::surface_depth_format::z16: return DXGI_FORMAT_R16_UNORM; case rsx::surface_depth_format::z16: return DXGI_FORMAT_R16_UNORM;
case rsx::surface_depth_format::z24s8: return DXGI_FORMAT_R24_UNORM_X8_TYPELESS; case rsx::surface_depth_format::z24s8: return DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
} }
throw EXCEPTION("Invalid format (0x%x)", format); throw EXCEPTION("Invalid format (0x%x)", (u32)format);
} }
BOOL get_front_face_ccw(rsx::front_face ffv) BOOL get_front_face_ccw(rsx::front_face ffv)
@ -366,7 +366,7 @@ BOOL get_front_face_ccw(rsx::front_face ffv)
case rsx::front_face::cw: return FALSE; case rsx::front_face::cw: return FALSE;
case rsx::front_face::ccw: return TRUE; case rsx::front_face::ccw: return TRUE;
} }
throw EXCEPTION("Invalid front face value (0x%x)", ffv); throw EXCEPTION("Invalid front face value (0x%x)", (u32)ffv);
} }
D3D12_CULL_MODE get_cull_face(rsx::cull_face cfv) D3D12_CULL_MODE get_cull_face(rsx::cull_face cfv)
@ -377,7 +377,7 @@ D3D12_CULL_MODE get_cull_face(rsx::cull_face cfv)
case rsx::cull_face::back: return D3D12_CULL_MODE_BACK; case rsx::cull_face::back: return D3D12_CULL_MODE_BACK;
case rsx::cull_face::front_and_back: return D3D12_CULL_MODE_NONE; case rsx::cull_face::front_and_back: return D3D12_CULL_MODE_NONE;
} }
throw EXCEPTION("Invalid cull face value (0x%x)", cfv); throw EXCEPTION("Invalid cull face value (0x%x)", (u32)cfv);
} }
DXGI_FORMAT get_index_type(rsx::index_array_type index_type) DXGI_FORMAT get_index_type(rsx::index_array_type index_type)
@ -387,7 +387,7 @@ DXGI_FORMAT get_index_type(rsx::index_array_type index_type)
case rsx::index_array_type::u16: return DXGI_FORMAT_R16_UINT; case rsx::index_array_type::u16: return DXGI_FORMAT_R16_UINT;
case rsx::index_array_type::u32: return DXGI_FORMAT_R32_UINT; case rsx::index_array_type::u32: return DXGI_FORMAT_R32_UINT;
} }
throw EXCEPTION("Invalid index_type (0x%x)", index_type); throw EXCEPTION("Invalid index_type (0x%x)", (u32)index_type);
} }
DXGI_FORMAT get_vertex_attribute_format(rsx::vertex_base_type type, u8 size) DXGI_FORMAT get_vertex_attribute_format(rsx::vertex_base_type type, u8 size)
@ -473,7 +473,7 @@ DXGI_FORMAT get_vertex_attribute_format(rsx::vertex_base_type type, u8 size)
} }
} }
throw EXCEPTION("Invalid or unsupported type or size (type=0x%x, size=0x%x)", type, size); throw EXCEPTION("Invalid or unsupported type or size (type=0x%x, size=0x%x)", (u32)type, size);
} }
D3D12_RECT get_scissor(u16 clip_origin_x, u16 clip_origin_y, u16 clip_w, u16 clip_h) D3D12_RECT get_scissor(u16 clip_origin_x, u16 clip_origin_y, u16 clip_w, u16 clip_h)

View File

@ -363,7 +363,7 @@ void GLGSRender::end()
switch (control) switch (control)
{ {
default: default:
LOG_ERROR(RSX, "bad clip plane control (0x%x)", control); LOG_ERROR(RSX, "bad clip plane control (0x%x)", (u32)control);
case rsx::user_clip_plane_op::disable: case rsx::user_clip_plane_op::disable:
value = 0; value = 0;
@ -1019,7 +1019,7 @@ void GLGSRender::flip(int buffer)
std::string message = std::string message =
"draw_calls: " + std::to_string(m_draw_calls) + ", " + "draw_call_setup: " + std::to_string(m_begin_time) + "us, " + "vertex_upload_time: " + std::to_string(m_vertex_upload_time) + "us, " + "draw_call_execution: " + std::to_string(m_draw_time) + "us"; "draw_calls: " + std::to_string(m_draw_calls) + ", " + "draw_call_setup: " + std::to_string(m_begin_time) + "us, " + "vertex_upload_time: " + std::to_string(m_vertex_upload_time) + "us, " + "draw_call_execution: " + std::to_string(m_draw_time) + "us";
LOG_ERROR(RSX, message.c_str()); LOG_ERROR(RSX, "%s", message);
} }
} }

View File

@ -46,7 +46,7 @@ color_format rsx::internals::surface_color_format_to_gl(rsx::surface_color_forma
case rsx::surface_color_format::a8b8g8r8: case rsx::surface_color_format::a8b8g8r8:
default: default:
LOG_ERROR(RSX, "Surface color buffer: Unsupported surface color format (0x%x)", color_format); LOG_ERROR(RSX, "Surface color buffer: Unsupported surface color format (0x%x)", (u32)color_format);
return{ ::gl::texture::type::uint_8_8_8_8, ::gl::texture::format::bgra, false, 4, 1 }; return{ ::gl::texture::type::uint_8_8_8_8, ::gl::texture::format::bgra, false, 4, 1 };
} }
} }
@ -59,7 +59,7 @@ depth_format rsx::internals::surface_depth_format_to_gl(rsx::surface_depth_forma
return{ ::gl::texture::type::ushort, ::gl::texture::format::depth, ::gl::texture::internal_format::depth16 }; return{ ::gl::texture::type::ushort, ::gl::texture::format::depth, ::gl::texture::internal_format::depth16 };
default: default:
LOG_ERROR(RSX, "Surface depth buffer: Unsupported surface depth format (0x%x)", depth_format); LOG_ERROR(RSX, "Surface depth buffer: Unsupported surface depth format (0x%x)", (u32)depth_format);
case rsx::surface_depth_format::z24s8: case rsx::surface_depth_format::z24s8:
return{ ::gl::texture::type::uint_24_8, ::gl::texture::format::depth_stencil, ::gl::texture::internal_format::depth24_stencil8 }; return{ ::gl::texture::type::uint_24_8, ::gl::texture::format::depth_stencil, ::gl::texture::internal_format::depth24_stencil8 };
} }

View File

@ -37,7 +37,7 @@ namespace
case CELL_GCM_TEXTURE_COMPRESSED_DXT23: return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; case CELL_GCM_TEXTURE_COMPRESSED_DXT23: return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
case CELL_GCM_TEXTURE_COMPRESSED_DXT45: return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; case CELL_GCM_TEXTURE_COMPRESSED_DXT45: return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
} }
throw EXCEPTION("Compressed or unknown texture format %x", texture_format); throw EXCEPTION("Compressed or unknown texture format 0x%x", texture_format);
} }
@ -66,7 +66,7 @@ namespace
case CELL_GCM_TEXTURE_D8R8G8B8: return std::make_tuple(GL_BGRA, GL_UNSIGNED_INT_8_8_8_8); case CELL_GCM_TEXTURE_D8R8G8B8: return std::make_tuple(GL_BGRA, GL_UNSIGNED_INT_8_8_8_8);
case CELL_GCM_TEXTURE_Y16_X16_FLOAT: return std::make_tuple(GL_RG, GL_HALF_FLOAT); case CELL_GCM_TEXTURE_Y16_X16_FLOAT: return std::make_tuple(GL_RG, GL_HALF_FLOAT);
} }
throw EXCEPTION("Compressed or unknown texture format %x", texture_format); throw EXCEPTION("Compressed or unknown texture format 0x%x", texture_format);
} }
bool is_compressed_format(u32 texture_format) bool is_compressed_format(u32 texture_format)
@ -99,7 +99,7 @@ namespace
case CELL_GCM_TEXTURE_COMPRESSED_DXT45: case CELL_GCM_TEXTURE_COMPRESSED_DXT45:
return true; return true;
} }
throw EXCEPTION("Unknown format %x", texture_format); throw EXCEPTION("Unknown format 0x%x", texture_format);
} }
bool requires_unpack_byte(u32 texture_format) bool requires_unpack_byte(u32 texture_format)
@ -178,7 +178,7 @@ namespace
return { GL_ZERO, GL_GREEN, GL_BLUE, GL_RED }; return { GL_ZERO, GL_GREEN, GL_BLUE, GL_RED };
} }
throw EXCEPTION("Unknown format %x", texture_format); throw EXCEPTION("Unknown format 0x%x", texture_format);
} }
} }
@ -248,7 +248,7 @@ namespace rsx
case rsx::texture_wrap_mode::mirror_once_clamp: return GL_MIRROR_CLAMP_EXT; case rsx::texture_wrap_mode::mirror_once_clamp: return GL_MIRROR_CLAMP_EXT;
} }
LOG_ERROR(RSX, "Texture wrap error: bad wrap (%d).", wrap); LOG_ERROR(RSX, "Texture wrap error: bad wrap (%d)", (u32)wrap);
return GL_REPEAT; return GL_REPEAT;
} }
@ -266,7 +266,7 @@ namespace rsx
case rsx::texture_max_anisotropy::x16: return 16.0f; case rsx::texture_max_anisotropy::x16: return 16.0f;
} }
LOG_ERROR(RSX, "Texture anisotropy error: bad max aniso (%d).", aniso); LOG_ERROR(RSX, "Texture anisotropy error: bad max aniso (%d)", (u32)aniso);
return 1.0f; return 1.0f;
} }
@ -526,7 +526,7 @@ namespace rsx
{ {
if (tex.get_exact_mipmap_count() <= 1 || m_target == GL_TEXTURE_RECTANGLE) if (tex.get_exact_mipmap_count() <= 1 || m_target == GL_TEXTURE_RECTANGLE)
{ {
LOG_WARNING(RSX, "Texture %d, target 0x%X, requesting mipmap filtering without any mipmaps set!", m_id, m_target); LOG_WARNING(RSX, "Texture %d, target 0x%x, requesting mipmap filtering without any mipmaps set!", m_id, m_target);
min_filter = GL_LINEAR; min_filter = GL_LINEAR;
} }
} }
@ -631,7 +631,7 @@ namespace rsx
{ {
if (tex.get_exact_mipmap_count() <= 1 || m_target == GL_TEXTURE_RECTANGLE) if (tex.get_exact_mipmap_count() <= 1 || m_target == GL_TEXTURE_RECTANGLE)
{ {
LOG_WARNING(RSX, "Texture %d, target 0x%X, requesting mipmap filtering without any mipmaps set!", m_id, m_target); LOG_WARNING(RSX, "Texture %d, target 0x%x, requesting mipmap filtering without any mipmaps set!", m_id, m_target);
min_filter = GL_LINEAR; min_filter = GL_LINEAR;
} }
} }

View File

@ -20,7 +20,7 @@ namespace
const u32* vec_selectors[] = { 0, vec1_types, vec2_types, vec3_types, vec4_types }; const u32* vec_selectors[] = { 0, vec1_types, vec2_types, vec3_types, vec4_types };
if (type > rsx::vertex_base_type::ub256) if (type > rsx::vertex_base_type::ub256)
throw EXCEPTION("OpenGL error: unknown vertex base type 0x%X.", (u32)type); throw EXCEPTION("OpenGL error: unknown vertex base type 0x%x", (u32)type);
return vec_selectors[size][(int)type]; return vec_selectors[size][(int)type];
} }
@ -131,7 +131,7 @@ namespace
std::tuple<u32, u32> get_index_array_for_emulated_non_indexed_draw(const std::vector<std::pair<u32, u32>> &first_count_commands, rsx::primitive_type primitive_mode, gl::ring_buffer &dst) std::tuple<u32, u32> get_index_array_for_emulated_non_indexed_draw(const std::vector<std::pair<u32, u32>> &first_count_commands, rsx::primitive_type primitive_mode, gl::ring_buffer &dst)
{ {
u32 vertex_draw_count = 0; u32 vertex_draw_count = 0;
assert(!gl::is_primitive_native(primitive_mode)); EXPECTS(gl::is_primitive_native(primitive_mode));
for (const auto &pair : first_count_commands) for (const auto &pair : first_count_commands)
{ {
@ -411,7 +411,7 @@ u32 GLGSRender::set_vertex_buffer()
break; break;
} }
default: default:
LOG_ERROR(RSX, "bad non array vertex data format (type = %d, size = %d)", vertex_info.type, vertex_info.size); LOG_ERROR(RSX, "bad non array vertex data format (type=%d, size=%d)", (u32)vertex_info.type, vertex_info.size);
break; break;
} }
} }

View File

@ -44,7 +44,7 @@ namespace rsx
void old_shaders_cache::shaders_cache::load(const std::string &path, shader_language lang) void old_shaders_cache::shaders_cache::load(const std::string &path, shader_language lang)
{ {
const std::string lang_name(::unveil<shader_language>::get(lang)); const std::string lang_name(lang == shader_language::glsl ? "glsl" : "hlsl");
auto extract_hash = [](const std::string &string) auto extract_hash = [](const std::string &string)
{ {
@ -180,7 +180,7 @@ namespace rsx
case vertex_base_type::cmp: return sizeof(u16) * 4; case vertex_base_type::cmp: return sizeof(u16) * 4;
case vertex_base_type::ub256: EXPECTS(size == 4); return sizeof(u8) * 4; case vertex_base_type::ub256: EXPECTS(size == 4); return sizeof(u8) * 4;
} }
throw EXCEPTION("RSXVertexData::GetTypeSize: Bad vertex data type (%d)!", type); throw EXCEPTION("RSXVertexData::GetTypeSize: Bad vertex data type (%d)!", (u8)type);
} }
void tiled_region::write(const void *src, u32 width, u32 height, u32 pitch) void tiled_region::write(const void *src, u32 width, u32 height, u32 pitch)

View File

@ -34,21 +34,6 @@ namespace rsx
} }
} }
template<>
struct unveil<rsx::old_shaders_cache::shader_language>
{
static inline const char* get(rsx::old_shaders_cache::shader_language in)
{
switch (in)
{
case rsx::old_shaders_cache::shader_language::glsl: return "glsl";
case rsx::old_shaders_cache::shader_language::hlsl: return "hlsl";
}
return "";
}
};
namespace rsx namespace rsx
{ {
namespace limits namespace limits

View File

@ -36,7 +36,7 @@ VkFormat get_compatible_depth_surface_format(const gpu_formats_support &support,
throw EXCEPTION("No hardware support for z24s8"); throw EXCEPTION("No hardware support for z24s8");
} }
} }
throw EXCEPTION("Invalid format (0x%x)", format); throw EXCEPTION("Invalid format (0x%x)", (u32)format);
} }
std::tuple<VkFilter, VkSamplerMipmapMode> get_min_filter_and_mip(rsx::texture_minify_filter min_filter) std::tuple<VkFilter, VkSamplerMipmapMode> get_min_filter_and_mip(rsx::texture_minify_filter min_filter)
@ -62,7 +62,7 @@ VkFilter get_mag_filter(rsx::texture_magnify_filter mag_filter)
case rsx::texture_magnify_filter::linear: return VK_FILTER_LINEAR; case rsx::texture_magnify_filter::linear: return VK_FILTER_LINEAR;
case rsx::texture_magnify_filter::convolution_mag: return VK_FILTER_LINEAR; case rsx::texture_magnify_filter::convolution_mag: return VK_FILTER_LINEAR;
} }
throw EXCEPTION("Invalid mag filter (0x%x)", mag_filter); throw EXCEPTION("Invalid mag filter (0x%x)", (u32)mag_filter);
} }
VkBorderColor get_border_color(u8 color) VkBorderColor get_border_color(u8 color)
@ -105,7 +105,7 @@ float max_aniso(rsx::texture_max_anisotropy gcm_aniso)
case rsx::texture_max_anisotropy::x16: return 16.0f; case rsx::texture_max_anisotropy::x16: return 16.0f;
} }
throw EXCEPTION("Texture anisotropy error: bad max aniso (%d).", gcm_aniso); throw EXCEPTION("Texture anisotropy error: bad max aniso (%d)", (u32)gcm_aniso);
} }

View File

@ -44,7 +44,7 @@ namespace vk
case rsx::comparison_function::not_equal: return VK_COMPARE_OP_NOT_EQUAL; case rsx::comparison_function::not_equal: return VK_COMPARE_OP_NOT_EQUAL;
case rsx::comparison_function::always: return VK_COMPARE_OP_ALWAYS; case rsx::comparison_function::always: return VK_COMPARE_OP_ALWAYS;
default: default:
throw EXCEPTION("Unknown compare op: 0x%X", op); throw EXCEPTION("Unknown compare op: 0x%x", (u32)op);
} }
} }
@ -91,7 +91,7 @@ namespace vk
return std::make_pair(VK_FORMAT_R32_SFLOAT, vk::default_component_map()); return std::make_pair(VK_FORMAT_R32_SFLOAT, vk::default_component_map());
default: default:
LOG_ERROR(RSX, "Surface color buffer: Unsupported surface color format (0x%x)", color_format); LOG_ERROR(RSX, "Surface color buffer: Unsupported surface color format (0x%x)", (u32)color_format);
return std::make_pair(VK_FORMAT_B8G8R8A8_UNORM, vk::default_component_map()); return std::make_pair(VK_FORMAT_B8G8R8A8_UNORM, vk::default_component_map());
} }
} }
@ -170,7 +170,7 @@ namespace vk
case rsx::surface_target::surfaces_a_b_c_d: case rsx::surface_target::surfaces_a_b_c_d:
return{ 0, 1, 2, 3 }; return{ 0, 1, 2, 3 };
default: default:
LOG_ERROR(RSX, "Bad surface color target: %d", fmt); LOG_ERROR(RSX, "Bad surface color target: %d", (u32)fmt);
return{}; return{};
} }
} }
@ -195,7 +195,7 @@ namespace vk
case rsx::logic_op::logic_or_inverted: return VK_LOGIC_OP_OR_INVERTED; case rsx::logic_op::logic_or_inverted: return VK_LOGIC_OP_OR_INVERTED;
case rsx::logic_op::logic_nand: return VK_LOGIC_OP_NAND; case rsx::logic_op::logic_nand: return VK_LOGIC_OP_NAND;
default: default:
throw EXCEPTION("Unknown logic op 0x%X", op); throw EXCEPTION("Unknown logic op 0x%x", (u32)op);
} }
} }
@ -218,7 +218,7 @@ namespace vk
case rsx::blend_factor::one_minus_constant_alpha: return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA; case rsx::blend_factor::one_minus_constant_alpha: return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA;
case rsx::blend_factor::one_minus_constant_color: return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR; case rsx::blend_factor::one_minus_constant_color: return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR;
default: default:
throw EXCEPTION("Unknown blend factor 0x%X", factor); throw EXCEPTION("Unknown blend factor 0x%x", (u32)factor);
} }
}; };
@ -232,7 +232,7 @@ namespace vk
case rsx::blend_equation::min: return VK_BLEND_OP_MIN; case rsx::blend_equation::min: return VK_BLEND_OP_MIN;
case rsx::blend_equation::max: return VK_BLEND_OP_MAX; case rsx::blend_equation::max: return VK_BLEND_OP_MAX;
default: default:
throw EXCEPTION("Unknown blend op: 0x%X", op); throw EXCEPTION("Unknown blend op: 0x%x", (u32)op);
} }
} }
@ -250,7 +250,7 @@ namespace vk
case rsx::stencil_op::incr_wrap: return VK_STENCIL_OP_INCREMENT_AND_WRAP; case rsx::stencil_op::incr_wrap: return VK_STENCIL_OP_INCREMENT_AND_WRAP;
case rsx::stencil_op::decr_wrap: return VK_STENCIL_OP_DECREMENT_AND_WRAP; case rsx::stencil_op::decr_wrap: return VK_STENCIL_OP_DECREMENT_AND_WRAP;
default: default:
throw EXCEPTION("Unknown stencil op: 0x%X", op); throw EXCEPTION("Unknown stencil op: 0x%x", (u32)op);
} }
} }
@ -261,7 +261,7 @@ namespace vk
case rsx::front_face::cw: return VK_FRONT_FACE_CLOCKWISE; case rsx::front_face::cw: return VK_FRONT_FACE_CLOCKWISE;
case rsx::front_face::ccw: return VK_FRONT_FACE_COUNTER_CLOCKWISE; case rsx::front_face::ccw: return VK_FRONT_FACE_COUNTER_CLOCKWISE;
default: default:
throw EXCEPTION("Unknown front face value: 0x%X", ffv); throw EXCEPTION("Unknown front face value: 0x%x", (u32)ffv);
} }
} }
@ -274,7 +274,7 @@ namespace vk
case CELL_GCM_FRONT_AND_BACK: return VK_CULL_MODE_FRONT_AND_BACK; case CELL_GCM_FRONT_AND_BACK: return VK_CULL_MODE_FRONT_AND_BACK;
default: return VK_CULL_MODE_NONE; default: return VK_CULL_MODE_NONE;
} }
throw EXCEPTION("Unknown cull face value: 0x%X", cfv); throw EXCEPTION("Unknown cull face value: 0x%x", (u32)cfv);
} }
} }
@ -861,7 +861,7 @@ bool VKGSRender::load_program()
if (rsx::method_registers.restart_index() != 0xFFFF && if (rsx::method_registers.restart_index() != 0xFFFF &&
rsx::method_registers.restart_index() != 0xFFFFFFFF) rsx::method_registers.restart_index() != 0xFFFFFFFF)
{ {
LOG_ERROR(RSX, "Custom primitive restart index 0x%X. Should rewrite index buffer with proper value!", rsx::method_registers.restart_index()); LOG_ERROR(RSX, "Custom primitive restart index 0x%x should rewrite index buffer with proper value!", rsx::method_registers.restart_index());
} }
properties.ia.primitiveRestartEnable = VK_TRUE; properties.ia.primitiveRestartEnable = VK_TRUE;
} }

View File

@ -24,7 +24,7 @@ namespace rsx
namespace vk namespace vk
{ {
#define CHECK_RESULT(expr) { VkResult __res = expr; if(__res != VK_SUCCESS) throw EXCEPTION("Assertion failed! Result is %Xh", __res); } #define CHECK_RESULT(expr) do { VkResult _res = (expr); if (_res != VK_SUCCESS) throw fmt::exception("Assertion failed! Result is %Xh", (s32)_res); } while (0)
VKAPI_ATTR void *VKAPI_CALL mem_realloc(void *pUserData, void *pOriginal, size_t size, size_t alignment, VkSystemAllocationScope allocationScope); VKAPI_ATTR void *VKAPI_CALL mem_realloc(void *pUserData, void *pOriginal, size_t size, size_t alignment, VkSystemAllocationScope allocationScope);
VKAPI_ATTR void *VKAPI_CALL mem_alloc(void *pUserData, size_t size, size_t alignment, VkSystemAllocationScope allocationScope); VKAPI_ATTR void *VKAPI_CALL mem_alloc(void *pUserData, size_t size, size_t alignment, VkSystemAllocationScope allocationScope);

View File

@ -49,7 +49,7 @@ namespace vk
const VkFormat* vec_selectors[] = { 0, vec1_types, vec2_types, vec3_types, vec4_types }; const VkFormat* vec_selectors[] = { 0, vec1_types, vec2_types, vec3_types, vec4_types };
if (type > rsx::vertex_base_type::ub256) if (type > rsx::vertex_base_type::ub256)
throw EXCEPTION("VKGS error: unknown vertex base type 0x%X.", (u32)type); throw EXCEPTION("VKGS error: unknown vertex base type 0x%x", (u32)type);
return vec_selectors[size][(int)type]; return vec_selectors[size][(int)type];
} }
@ -425,7 +425,7 @@ VKGSRender::upload_vertex_data()
vk::copy_inlined_data_to_buffer<u16, 1>(src, dst, vertex_draw_count, vertex_info.type, vertex_info.size, opt_size, element_size, stride); vk::copy_inlined_data_to_buffer<u16, 1>(src, dst, vertex_draw_count, vertex_info.type, vertex_info.size, opt_size, element_size, stride);
break; break;
default: default:
throw EXCEPTION("Unknown base type %d", vertex_info.type); throw EXCEPTION("Unknown base type %d", (u32)vertex_info.type);
} }
m_attrib_ring_info.unmap(); m_attrib_ring_info.unmap();
@ -545,7 +545,7 @@ VKGSRender::upload_vertex_data()
break; break;
} }
default: default:
LOG_ERROR(RSX, "bad non array vertex data format (type = %d, size = %d)", vertex_info.type, vertex_info.size); LOG_ERROR(RSX, "bad non array vertex data format (type=%d, size=%d)", (u32)vertex_info.type, vertex_info.size);
break; break;
} }
} }

View File

@ -298,7 +298,7 @@ namespace rsx
case blit_engine::context_dma::to_memory_get_report: location = CELL_GCM_LOCATION_LOCAL; break; case blit_engine::context_dma::to_memory_get_report: location = CELL_GCM_LOCATION_LOCAL; break;
case blit_engine::context_dma::report_location_main: location = CELL_GCM_LOCATION_MAIN; break; case blit_engine::context_dma::report_location_main: location = CELL_GCM_LOCATION_MAIN; break;
default: default:
LOG_WARNING(RSX, "nv4097::get_report: bad report dma: 0x%x", report_dma); LOG_WARNING(RSX, "nv4097::get_report: bad report dma: 0x%x", (u8)report_dma);
return; return;
} }
@ -406,12 +406,12 @@ namespace rsx
if (in_origin != blit_engine::transfer_origin::corner) if (in_origin != blit_engine::transfer_origin::corner)
{ {
LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown origin (%d)", in_origin); LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown origin (%d)", (u8)in_origin);
} }
if (operation != rsx::blit_engine::transfer_operation::srccopy) if (operation != rsx::blit_engine::transfer_operation::srccopy)
{ {
LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown operation (%d)", operation); LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown operation (%d)", (u8)operation);
} }
const u32 src_offset = method_registers.blit_engine_input_offset(); const u32 src_offset = method_registers.blit_engine_input_offset();
@ -440,7 +440,7 @@ namespace rsx
break; break;
default: default:
LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown m_context_surface (0x%x)", method_registers.blit_engine_context_surface()); LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown m_context_surface (0x%x)", (u8)method_registers.blit_engine_context_surface());
return; return;
} }
@ -512,13 +512,13 @@ namespace rsx
if (dst_color_format != rsx::blit_engine::transfer_destination_format::r5g6b5 && if (dst_color_format != rsx::blit_engine::transfer_destination_format::r5g6b5 &&
dst_color_format != rsx::blit_engine::transfer_destination_format::a8r8g8b8) dst_color_format != rsx::blit_engine::transfer_destination_format::a8r8g8b8)
{ {
LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown dst_color_format (%d)", dst_color_format); LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown dst_color_format (%d)", (u8)dst_color_format);
} }
if (src_color_format != rsx::blit_engine::transfer_source_format::r5g6b5 && if (src_color_format != rsx::blit_engine::transfer_source_format::r5g6b5 &&
src_color_format != rsx::blit_engine::transfer_source_format::a8r8g8b8) src_color_format != rsx::blit_engine::transfer_source_format::a8r8g8b8)
{ {
LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown src_color_format (%d)", src_color_format); LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown src_color_format (%d)", (u8)src_color_format);
} }
//LOG_WARNING(RSX, "NV3089_IMAGE_IN_SIZE: SIZE=0x%08x, pitch=0x%x, offset=0x%x, scaleX=%f, scaleY=%f, CLIP_SIZE=0x%08x, OUT_SIZE=0x%08x", //LOG_WARNING(RSX, "NV3089_IMAGE_IN_SIZE: SIZE=0x%08x, pitch=0x%x, offset=0x%x, scaleX=%f, scaleY=%f, CLIP_SIZE=0x%08x, OUT_SIZE=0x%08x",

View File

@ -121,10 +121,10 @@ public:
void Resume(); void Resume();
void Stop(); void Stop();
force_inline bool IsRunning() const { return m_status == Running; } bool IsRunning() const { return m_status == Running; }
force_inline bool IsPaused() const { return m_status == Paused; } bool IsPaused() const { return m_status == Paused; }
force_inline bool IsStopped() const { return m_status == Stopped; } bool IsStopped() const { return m_status == Stopped; }
force_inline bool IsReady() const { return m_status == Ready; } bool IsReady() const { return m_status == Ready; }
}; };
extern Emulator Emu; extern Emulator Emu;

View File

@ -27,14 +27,14 @@ static YAML::Node loaded;
static YAML::Node saved; static YAML::Node saved;
// Emit sorted YAML // Emit sorted YAML
static never_inline void emit(YAML::Emitter& out, const YAML::Node& node) static NEVER_INLINE void emit(YAML::Emitter& out, const YAML::Node& node)
{ {
// TODO // TODO
out << node; out << node;
} }
// Incrementally load YAML // Incrementally load YAML
static never_inline void operator +=(YAML::Node& left, const YAML::Node& node) static NEVER_INLINE void operator +=(YAML::Node& left, const YAML::Node& node)
{ {
if (node && !node.IsNull()) if (node && !node.IsNull())
{ {

31
rpcs3/Loader/ELF.cpp Normal file
View File

@ -0,0 +1,31 @@
#include "stdafx.h"
#include "ELF.h"
// ELF loading error information
template<>
void fmt_class_string<elf_error>::format(std::string& out, u64 arg)
{
format_enum(out, arg, [](elf_error error)
{
switch (error)
{
case elf_error::ok: return "OK";
case elf_error::stream: return "Invalid stream";
case elf_error::stream_header: return "Failed to read ELF header";
case elf_error::stream_phdrs: return "Failed to read ELF program headers";
case elf_error::stream_shdrs: return "Failed to read ELF section headers";
case elf_error::stream_data: return "Failed to read ELF program data";
case elf_error::header_magic: return "Not an ELF";
case elf_error::header_version: return "Invalid or unsupported ELF format";
case elf_error::header_class: return "Invalid ELF class";
case elf_error::header_machine: return "Invalid ELF machine";
case elf_error::header_endianness: return "Invalid ELF data (endianness)";
case elf_error::header_type: return "Invalid ELF type";
case elf_error::header_os: return "Invalid ELF OS ABI";
}
return unknown;
});
}

View File

@ -153,35 +153,6 @@ enum class elf_error
header_os, header_os,
}; };
// ELF loading error information
template<>
struct unveil<elf_error>
{
static inline const char* get(elf_error error)
{
switch (error)
{
case elf_error::ok: return "OK";
case elf_error::stream: return "Invalid stream";
case elf_error::stream_header: return "Failed to read ELF header";
case elf_error::stream_phdrs: return "Failed to read ELF program headers";
case elf_error::stream_shdrs: return "Failed to read ELF section headers";
case elf_error::stream_data: return "Failed to read ELF program data";
case elf_error::header_magic: return "Not an ELF";
case elf_error::header_version: return "Invalid or unsupported ELF format";
case elf_error::header_class: return "Invalid ELF class";
case elf_error::header_machine: return "Invalid ELF machine";
case elf_error::header_endianness: return "Invalid ELF data (endianness)";
case elf_error::header_type: return "Invalid ELF type";
case elf_error::header_os: return "Invalid ELF OS ABI";
default: throw error;
}
}
};
// ELF object with specified parameters. // ELF object with specified parameters.
// en_t: endianness (specify le_t or be_t) // en_t: endianness (specify le_t or be_t)
// sz_t: size (specify u32 for ELF32, u64 for ELF64) // sz_t: size (specify u32 for ELF32, u64 for ELF64)

View File

@ -1,6 +1,22 @@
#include "stdafx.h" #include "stdafx.h"
#include "PSF.h" #include "PSF.h"
template<>
void fmt_class_string<psf::format>::format(std::string& out, u64 arg)
{
format_enum(out, arg, [](auto fmt)
{
switch (fmt)
{
STR_CASE(psf::format::array);
STR_CASE(psf::format::string);
STR_CASE(psf::format::integer);
}
return unknown;
});
}
namespace psf namespace psf
{ {
logs::channel log("PSF", logs::level::notice); logs::channel log("PSF", logs::level::notice);

View File

@ -367,6 +367,7 @@
<ClCompile Include="Emu\RSX\RSXThread.cpp" /> <ClCompile Include="Emu\RSX\RSXThread.cpp" />
<ClCompile Include="Emu\Memory\vm.cpp" /> <ClCompile Include="Emu\Memory\vm.cpp" />
<ClCompile Include="Emu\System.cpp" /> <ClCompile Include="Emu\System.cpp" />
<ClCompile Include="Loader\ELF.cpp" />
<ClCompile Include="Loader\PSF.cpp" /> <ClCompile Include="Loader\PSF.cpp" />
<ClCompile Include="Loader\TROPUSR.cpp" /> <ClCompile Include="Loader\TROPUSR.cpp" />
<ClCompile Include="Loader\TRP.cpp" /> <ClCompile Include="Loader\TRP.cpp" />
@ -386,6 +387,7 @@
<ClInclude Include="..\Utilities\BEType.h" /> <ClInclude Include="..\Utilities\BEType.h" />
<ClInclude Include="..\Utilities\BitField.h" /> <ClInclude Include="..\Utilities\BitField.h" />
<ClInclude Include="..\Utilities\BitSet.h" /> <ClInclude Include="..\Utilities\BitSet.h" />
<ClInclude Include="..\Utilities\cfmt.h" />
<ClInclude Include="..\Utilities\dynamic_library.h" /> <ClInclude Include="..\Utilities\dynamic_library.h" />
<ClInclude Include="..\Utilities\event.h" /> <ClInclude Include="..\Utilities\event.h" />
<ClInclude Include="..\Utilities\geometry.h" /> <ClInclude Include="..\Utilities\geometry.h" />

View File

@ -884,6 +884,9 @@
<ClCompile Include="Emu\RSX\gcm_enums.cpp"> <ClCompile Include="Emu\RSX\gcm_enums.cpp">
<Filter>Emu\GPU\RSX</Filter> <Filter>Emu\GPU\RSX</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Loader\ELF.cpp">
<Filter>Loader</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="Crypto\aes.h"> <ClInclude Include="Crypto\aes.h">
@ -1702,5 +1705,8 @@
<ClInclude Include="Emu\RSX\gcm_enums.h"> <ClInclude Include="Emu\RSX\gcm_enums.h">
<Filter>Emu\GPU\RSX</Filter> <Filter>Emu\GPU\RSX</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\Utilities\cfmt.h">
<Filter>Utilities</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -175,7 +175,7 @@ bool Rpcs3App::OnInit()
case frame_type::Vulkan: return std::make_unique<GSFrame>("Vulkan", w, h); case frame_type::Vulkan: return std::make_unique<GSFrame>("Vulkan", w, h);
} }
throw EXCEPTION("Invalid Frame Type (0x%x)", type); throw fmt::exception("Invalid frame type (0x%x)" HERE, (int)type);
}; };
callbacks.get_gs_render = PURE_EXPR(g_cfg_gs_render.get()()); callbacks.get_gs_render = PURE_EXPR(g_cfg_gs_render.get()());