be_t simplified, vm::ref improved

remove_be_t renamed to to_ne_t (to native endianness)
le_t and to_le_t draft, bugfixes
This commit is contained in:
Nekotekina 2015-06-13 04:31:45 +03:00
parent 5ae2349f36
commit 1256d648c1
22 changed files with 585 additions and 535 deletions

View file

@ -556,52 +556,49 @@ template<u64 _value> struct const_se_t<u64, _value, 8>
((_value << 56) & 0xff00000000000000); ((_value << 56) & 0xff00000000000000);
}; };
template<typename T, size_t size = sizeof(T)> template<typename T, size_t size = sizeof(T)> struct be_storage
struct be_storage_t
{ {
static_assert(!size, "Bad be_storage_t type"); static_assert(!size, "Bad be_storage_t<> type");
}; };
template<typename T> template<typename T> struct be_storage<T, 2>
struct be_storage_t<T, 1>
{
typedef u8 type;
};
template<typename T>
struct be_storage_t<T, 2>
{ {
typedef u16 type; typedef u16 type;
}; };
template<typename T> template<typename T> struct be_storage<T, 4>
struct be_storage_t<T, 4>
{ {
typedef u32 type; typedef u32 type;
}; };
template<typename T> template<typename T> struct be_storage<T, 8>
struct be_storage_t<T, 8>
{ {
typedef u64 type; typedef u64 type;
}; };
template<typename T> template<typename T> struct be_storage<T, 16>
struct be_storage_t<T, 16>
{ {
typedef u128 type; typedef u128 type;
}; };
template<typename T, typename T2 = T> template<typename T> using be_storage_t = typename be_storage<T>::type;
class be_t
{ template<typename T>
public: struct be_t
typedef typename std::remove_cv<T>::type type; {
typedef typename be_storage_t<T2>::type stype; using type = std::remove_cv_t<T>;
using stype = be_storage_t<type>;
private:
stype m_data; stype m_data;
static_assert(!std::is_class<type>::value, "be_t<> error: invalid type (class or structure)");
static_assert(!std::is_union<type>::value || std::is_same<type, u128>::value, "be_t<> error: invalid type (union)");
static_assert(!std::is_pointer<type>::value, "be_t<> error: invalid type (pointer)");
static_assert(!std::is_reference<type>::value, "be_t<> error: invalid type (reference)");
static_assert(!std::is_array<type>::value, "be_t<> error: invalid type (array)");
static_assert(__alignof(type) == __alignof(stype), "be_t<> error: unexpected alignment");
private:
template<typename Tto, typename Tfrom, int mode> template<typename Tto, typename Tfrom, int mode>
struct _convert struct _convert
{ {
@ -639,7 +636,7 @@ private:
type ToLE() const type ToLE() const
{ {
return se_t<type, sizeof(T2)>::from_be(m_data); return se_t<type, sizeof(stype)>::from_be(m_data);
} }
void FromBE(const stype& value) void FromBE(const stype& value)
@ -649,13 +646,12 @@ private:
void FromLE(const type& value) void FromLE(const type& value)
{ {
m_data = se_t<type, sizeof(T2)>::to_be(value); m_data = se_t<type, sizeof(stype)>::to_be(value);
} }
public:
static be_t MakeFromLE(const type& value) static be_t MakeFromLE(const type& value)
{ {
stype data = se_t<type, sizeof(T2)>::to_be(value); stype data = se_t<type, sizeof(stype)>::to_be(value);
return (be_t&)data; return (be_t&)data;
} }
@ -664,6 +660,7 @@ public:
return (be_t&)value; return (be_t&)value;
} }
public:
//make be_t from current machine byte ordering //make be_t from current machine byte ordering
static be_t make(const type& value) static be_t make(const type& value)
{ {
@ -691,35 +688,42 @@ public:
be_t& operator =(const be_t& value) = default; be_t& operator =(const be_t& value) = default;
be_t& operator = (const type& value) template<typename CT> std::enable_if_t<std::is_assignable<type&, CT>::value, be_t&> operator =(const CT& value)
{ {
m_data = se_t<type, sizeof(T2)>::to_be(value); m_data = se_t<type, sizeof(stype)>::to_be(value);
return *this; return *this;
} }
//template<typename CT> operator std::enable_if_t<std::is_convertible<type, CT>::value, CT>() const
//{
// return value();
//}
operator type() const operator type() const
{ {
return value(); return value();
} }
template<typename T1> // conversion to another be_t type
operator const be_t<T1>() const template<typename T1> operator be_t<T1>() const
{ {
return be_t<T1>::make(value()); return be_t<T1>::make(value());
// TODO (complicated cases like int-float conversions are not handled correctly)
//return _convert<T1, T, ((sizeof(T1) > sizeof(T)) ? 1 : (sizeof(T1) < sizeof(T) ? 2 : 0))>::func(m_data); //return _convert<T1, T, ((sizeof(T1) > sizeof(T)) ? 1 : (sizeof(T1) < sizeof(T) ? 2 : 0))>::func(m_data);
} }
template<typename T1> be_t& operator += (T1 right) { return *this = T(*this) + right; } template<typename T1> be_t& operator += (T1 right) { return *this = value() + right; }
template<typename T1> be_t& operator -= (T1 right) { return *this = T(*this) - right; } template<typename T1> be_t& operator -= (T1 right) { return *this = value() - right; }
template<typename T1> be_t& operator *= (T1 right) { return *this = T(*this) * right; } template<typename T1> be_t& operator *= (T1 right) { return *this = value() * right; }
template<typename T1> be_t& operator /= (T1 right) { return *this = T(*this) / right; } template<typename T1> be_t& operator /= (T1 right) { return *this = value() / right; }
template<typename T1> be_t& operator %= (T1 right) { return *this = T(*this) % right; } template<typename T1> be_t& operator %= (T1 right) { return *this = value() % right; }
template<typename T1> be_t& operator &= (T1 right) { return *this = T(*this) & right; } template<typename T1> be_t& operator &= (T1 right) { return *this = value() & right; }
template<typename T1> be_t& operator |= (T1 right) { return *this = T(*this) | right; } template<typename T1> be_t& operator |= (T1 right) { return *this = value() | right; }
template<typename T1> be_t& operator ^= (T1 right) { return *this = T(*this) ^ right; } template<typename T1> be_t& operator ^= (T1 right) { return *this = value() ^ right; }
template<typename T1> be_t& operator <<= (T1 right) { return *this = T(*this) << right; } template<typename T1> be_t& operator <<= (T1 right) { return *this = value() << right; }
template<typename T1> be_t& operator >>= (T1 right) { return *this = T(*this) >> right; } template<typename T1> be_t& operator >>= (T1 right) { return *this = value() >> right; }
template<typename T1> be_t& operator += (const be_t<T1>& right) { return *this = ToLE() + right.ToLE(); } template<typename T1> be_t& operator += (const be_t<T1>& right) { return *this = ToLE() + right.ToLE(); }
template<typename T1> be_t& operator -= (const be_t<T1>& right) { return *this = ToLE() - right.ToLE(); } template<typename T1> be_t& operator -= (const be_t<T1>& right) { return *this = ToLE() - right.ToLE(); }
@ -730,9 +734,9 @@ public:
template<typename T1> be_t& operator |= (const be_t<T1>& right) { return *this = ToBE() | right.ToBE(); } template<typename T1> be_t& operator |= (const be_t<T1>& right) { return *this = ToBE() | right.ToBE(); }
template<typename T1> be_t& operator ^= (const be_t<T1>& right) { return *this = ToBE() ^ right.ToBE(); } template<typename T1> be_t& operator ^= (const be_t<T1>& right) { return *this = ToBE() ^ right.ToBE(); }
template<typename T1> be_t operator & (const be_t<T1>& right) const { be_t<T> res; res.FromBE(ToBE() & right.ToBE()); return res; } template<typename T1> be_t operator & (const be_t<T1>& right) const { be_t res; res.FromBE(ToBE() & right.ToBE()); return res; }
template<typename T1> be_t operator | (const be_t<T1>& right) const { be_t<T> res; res.FromBE(ToBE() | right.ToBE()); return res; } template<typename T1> be_t operator | (const be_t<T1>& right) const { be_t res; res.FromBE(ToBE() | right.ToBE()); return res; }
template<typename T1> be_t operator ^ (const be_t<T1>& right) const { be_t<T> res; res.FromBE(ToBE() ^ right.ToBE()); return res; } template<typename T1> be_t operator ^ (const be_t<T1>& right) const { be_t res; res.FromBE(ToBE() ^ right.ToBE()); return res; }
template<typename T1> bool operator == (T1 right) const { return (T1)ToLE() == right; } template<typename T1> bool operator == (T1 right) const { return (T1)ToLE() == right; }
template<typename T1> bool operator != (T1 right) const { return !(*this == right); } template<typename T1> bool operator != (T1 right) const { return !(*this == right); }
@ -754,114 +758,40 @@ public:
be_t& operator-- () { *this -= 1; return *this; } be_t& operator-- () { *this -= 1; return *this; }
}; };
template<typename T, typename T2 = T> template<typename T> struct is_be_t : public std::integral_constant<bool, false>
struct is_be_t : public std::integral_constant<bool, false> {};
template<typename T, typename T2>
struct is_be_t<be_t<T, T2>, T2> : public std::integral_constant<bool, true> {};
template<typename T, typename T2 = T>
struct remove_be_t
{ {
typedef T type;
}; };
template<typename T, typename T2> template<typename T> struct is_be_t<be_t<T>> : public std::integral_constant<bool, true>
struct remove_be_t<be_t<T, T2>>
{ {
typedef T type;
}; };
template<typename T, typename T2 = T> // to_be_t helper struct
class to_be_t template<typename T> struct to_be
{ {
template<typename TT, typename TT2, bool is_need_swap> using type = std::conditional_t<std::is_arithmetic<T>::value || std::is_enum<T>::value, be_t<T>, T>;
struct _be_type_selector
{
typedef TT type;
}; };
template<typename TT, typename TT2> // be_t<T> if possible, T otherwise
struct _be_type_selector<TT, TT2, true> template<typename T> using to_be_t = typename to_be<T>::type;
template<typename T> struct to_be<const T>
{ {
typedef be_t<TT, TT2> type; // move const qualifier
using type = const to_be_t<std::remove_const_t<T>>;
}; };
public: template<typename T> struct to_be<volatile T>
//true if need swap endianes for be
static const bool value = std::is_arithmetic<T>::value || std::is_enum<T>::value;
//be_t<T, size> if need swap endianes, T otherwise
typedef typename _be_type_selector< T, T2, value >::type type;
typedef typename _be_type_selector< T, T2, !is_be_t<T, T2>::value >::type forced_type;
};
template<typename T, typename T2>
class to_be_t<T, const T2>
{ {
public: // move volatile qualifier
static const bool value = to_be_t<T, T2>::value; using type = volatile to_be_t<std::remove_volatile_t<T>>;
typedef const typename to_be_t<T, T2>::type type;
typedef const typename to_be_t<T, T2>::forced_type forced_type;
}; };
template<typename T> template<> struct to_be<void> { using type = void; };
class to_be_t<T, void> template<> struct to_be<bool> { using type = bool; };
{ template<> struct to_be<char> { using type = char; };
public: template<> struct to_be<u8> { using type = u8; };
static const bool value = false; template<> struct to_be<s8> { using type = s8; };
typedef void type;
typedef void forced_type;
};
template<typename T>
class to_be_t<T, u8>
{
public:
static const bool value = false;
typedef u8 type;
typedef u8 forced_type;
};
template<typename T>
class to_be_t<T, s8>
{
public:
static const bool value = false;
typedef s8 type;
typedef s8 forced_type;
};
template<typename T>
class to_be_t<T, char>
{
public:
static const bool value = false;
typedef char type;
typedef char forced_type;
};
template<typename T>
class to_be_t<T, bool>
{
public:
static const bool value = false;
typedef bool type;
typedef bool forced_type;
};
template<typename T, typename T2 = T>
struct invert_be_t
{
typedef typename to_be_t<T, T2>::type type;
};
template<typename T, typename T2>
struct invert_be_t<be_t<T, T2>>
{
typedef T type;
};
template<typename T, typename T1, T1 value> struct _se : public const_se_t<T, value> {}; template<typename T, typename T1, T1 value> struct _se : public const_se_t<T, value> {};
template<typename T, typename T1, T1 value> struct _se<be_t<T>, T1, value> : public const_se_t<T, value> {}; template<typename T, typename T1, T1 value> struct _se<be_t<T>, T1, value> : public const_se_t<T, value> {};
@ -880,28 +810,28 @@ struct convert_le_be_t
} }
}; };
template<typename Tt, typename Tt1, typename Tfrom> template<typename Tt, typename Tfrom>
struct convert_le_be_t<be_t<Tt, Tt1>, Tfrom> struct convert_le_be_t<be_t<Tt>, Tfrom>
{ {
static be_t<Tt, Tt1> func(Tfrom value) static be_t<Tt> func(Tfrom value)
{ {
return be_t<Tt, Tt1>::make(value); return be_t<Tt>::make(value);
} }
}; };
template<typename Tt, typename Tt1, typename Tf, typename Tf1> template<typename Tt, typename Tf>
struct convert_le_be_t<be_t<Tt, Tt1>, be_t<Tf, Tf1>> struct convert_le_be_t<be_t<Tt>, be_t<Tf>>
{ {
static be_t<Tt, Tt1> func(be_t<Tf, Tf1> value) static be_t<Tt> func(be_t<Tf> value)
{ {
return value; return value;
} }
}; };
template<typename Tto, typename Tf, typename Tf1> template<typename Tto, typename Tf>
struct convert_le_be_t<Tto, be_t<Tf, Tf1>> struct convert_le_be_t<Tto, be_t<Tf>>
{ {
static Tto func(be_t<Tf, Tf1> value) static Tto func(be_t<Tf> value)
{ {
return value.value(); return value.value();
} }
@ -919,6 +849,85 @@ force_inline void convert_le_be(Tto& dst, Tfrom src)
dst = convert_le_be_t<Tto, Tfrom>::func(src); dst = convert_le_be_t<Tto, Tfrom>::func(src);
} }
template<typename T> using le_t = T; template<typename T> struct le_t
{
using type = std::remove_cv_t<T>;
using stype = be_storage_t<type>;
template<typename T> struct to_le_t { using type = T; }; stype m_data;
type value() const
{
return reinterpret_cast<const type&>(m_data);
}
le_t& operator =(const le_t& value) = default;
template<typename CT> std::enable_if_t<std::is_assignable<type&, CT>::value, le_t&> operator =(const CT& value)
{
m_data = reinterpret_cast<const stype&>(value);
return *this;
}
//template<typename CT> operator std::enable_if_t<std::is_convertible<type, CT>::value, CT>() const
//{
// return value();
//}
operator type() const
{
return value();
}
// conversion to another le_t type
//template<typename T1> operator const le_t<T1>() const
//{
// return le_t<T1>::make(value());
//}
};
template<typename T> struct to_le
{
using type = std::conditional_t<std::is_arithmetic<T>::value || std::is_enum<T>::value, le_t<T>, T>;
};
// le_t<T> if possible, T otherwise
template<typename T> using to_le_t = typename to_le<T>::type;
template<typename T> struct to_le<const T>
{
// move const qualifier
using type = const to_le_t<std::remove_const_t<T>>;
};
template<typename T> struct to_le<volatile T>
{
// move volatile qualifier
using type = volatile to_le_t<std::remove_volatile_t<T>>;
};
template<> struct to_le<void> { using type = void; };
template<> struct to_le<bool> { using type = bool; };
template<> struct to_le<char> { using type = char; };
template<> struct to_le<u8> { using type = u8; };
template<> struct to_le<s8> { using type = s8; };
// to_ne_t helper struct
template<typename T> struct to_ne
{
using type = T;
};
// restore native endianness for T: returns T for be_t<T> or le_t<T>, T otherwise
template<typename T> using to_ne_t = typename to_ne<T>::type;
template<typename T> struct to_ne<be_t<T>>
{
using type = T;
};
template<typename T> struct to_ne<le_t<T>>
{
using type = T;
};

View file

@ -82,42 +82,42 @@ int clock_gettime(int foo, struct timespec *ts);
#endif /* __APPLE__ */ #endif /* __APPLE__ */
template<typename T, typename T2> static inline typename std::enable_if<std::is_arithmetic<T>::value, T>::type sync_val_compare_and_swap(volatile T* dest, T2 comp, T2 exch) template<typename T, typename T2> static inline std::enable_if_t<std::is_arithmetic<T>::value, T> sync_val_compare_and_swap(volatile T* dest, T2 comp, T2 exch)
{ {
return __sync_val_compare_and_swap(dest, comp, exch); return __sync_val_compare_and_swap(dest, comp, exch);
} }
template<typename T, typename T2> static inline typename std::enable_if<std::is_arithmetic<T>::value, bool>::type sync_bool_compare_and_swap(volatile T* dest, T2 comp, T2 exch) template<typename T, typename T2> static inline std::enable_if_t<std::is_arithmetic<T>::value, bool> sync_bool_compare_and_swap(volatile T* dest, T2 comp, T2 exch)
{ {
return __sync_bool_compare_and_swap(dest, comp, exch); return __sync_bool_compare_and_swap(dest, comp, exch);
} }
template<typename T, typename T2> static inline typename std::enable_if<std::is_arithmetic<T>::value, T>::type sync_lock_test_and_set(volatile T* dest, T2 value) template<typename T, typename T2> static inline std::enable_if_t<std::is_arithmetic<T>::value, T> sync_lock_test_and_set(volatile T* dest, T2 value)
{ {
return __sync_lock_test_and_set(dest, value); return __sync_lock_test_and_set(dest, value);
} }
template<typename T, typename T2> static inline typename std::enable_if<std::is_arithmetic<T>::value, T>::type sync_fetch_and_add(volatile T* dest, T2 value) template<typename T, typename T2> static inline std::enable_if_t<std::is_arithmetic<T>::value, T> sync_fetch_and_add(volatile T* dest, T2 value)
{ {
return __sync_fetch_and_add(dest, value); return __sync_fetch_and_add(dest, value);
} }
template<typename T, typename T2> static inline typename std::enable_if<std::is_arithmetic<T>::value, T>::type sync_fetch_and_sub(volatile T* dest, T2 value) template<typename T, typename T2> static inline std::enable_if_t<std::is_arithmetic<T>::value, T> sync_fetch_and_sub(volatile T* dest, T2 value)
{ {
return __sync_fetch_and_sub(dest, value); return __sync_fetch_and_sub(dest, value);
} }
template<typename T, typename T2> static inline typename std::enable_if<std::is_arithmetic<T>::value, T>::type sync_fetch_and_or(volatile T* dest, T2 value) template<typename T, typename T2> static inline std::enable_if_t<std::is_arithmetic<T>::value, T> sync_fetch_and_or(volatile T* dest, T2 value)
{ {
return __sync_fetch_and_or(dest, value); return __sync_fetch_and_or(dest, value);
} }
template<typename T, typename T2> static inline typename std::enable_if<std::is_arithmetic<T>::value, T>::type sync_fetch_and_and(volatile T* dest, T2 value) template<typename T, typename T2> static inline std::enable_if_t<std::is_arithmetic<T>::value, T> sync_fetch_and_and(volatile T* dest, T2 value)
{ {
return __sync_fetch_and_and(dest, value); return __sync_fetch_and_and(dest, value);
} }
template<typename T, typename T2> static inline typename std::enable_if<std::is_arithmetic<T>::value, T>::type sync_fetch_and_xor(volatile T* dest, T2 value) template<typename T, typename T2> static inline std::enable_if_t<std::is_arithmetic<T>::value, T> sync_fetch_and_xor(volatile T* dest, T2 value)
{ {
return __sync_fetch_and_xor(dest, value); return __sync_fetch_and_xor(dest, value);
} }

View file

@ -179,7 +179,7 @@ namespace fmt
template<typename T, bool is_enum = std::is_enum<T>::value> template<typename T, bool is_enum = std::is_enum<T>::value>
struct unveil struct unveil
{ {
typedef T result_type; using result_type = T;
force_inline static result_type get_value(const T& arg) force_inline static result_type get_value(const T& arg)
{ {
@ -190,7 +190,7 @@ namespace fmt
template<> template<>
struct unveil<char*, false> struct unveil<char*, false>
{ {
typedef const char* result_type; using result_type = const char*;
force_inline static result_type get_value(const char* arg) force_inline static result_type get_value(const char* arg)
{ {
@ -201,7 +201,7 @@ namespace fmt
template<size_t N> template<size_t N>
struct unveil<const char[N], false> struct unveil<const char[N], false>
{ {
typedef const char* result_type; using result_type = const char*;
force_inline static result_type get_value(const char(&arg)[N]) force_inline static result_type get_value(const char(&arg)[N])
{ {
@ -212,7 +212,7 @@ namespace fmt
template<> template<>
struct unveil<std::string, false> struct unveil<std::string, false>
{ {
typedef const char* result_type; using result_type = const char*;
force_inline static result_type get_value(const std::string& arg) force_inline static result_type get_value(const std::string& arg)
{ {
@ -223,7 +223,7 @@ namespace fmt
template<typename T> template<typename T>
struct unveil<T, true> struct unveil<T, true>
{ {
typedef typename std::underlying_type<T>::type result_type; using result_type = std::underlying_type_t<T>;
force_inline static result_type get_value(const T& arg) force_inline static result_type get_value(const T& arg)
{ {
@ -231,12 +231,12 @@ namespace fmt
} }
}; };
template<typename T, typename T2> template<typename T>
struct unveil<be_t<T, T2>, false> struct unveil<be_t<T>, false>
{ {
typedef typename unveil<T>::result_type result_type; using result_type = typename unveil<T>::result_type;
force_inline static result_type get_value(const be_t<T, T2>& arg) force_inline static result_type get_value(const be_t<T>& arg)
{ {
return unveil<T>::get_value(arg.value()); return unveil<T>::get_value(arg.value());
} }

View file

@ -187,16 +187,14 @@ struct cast_armv7_gpr
{ {
static_assert(is_enum, "Invalid type for cast_armv7_gpr"); static_assert(is_enum, "Invalid type for cast_armv7_gpr");
typedef typename std::underlying_type<T>::type underlying_type;
force_inline static u32 to_gpr(const T& value) force_inline static u32 to_gpr(const T& value)
{ {
return cast_armv7_gpr<underlying_type>::to_gpr(static_cast<underlying_type>(value)); return cast_armv7_gpr<std::underlying_type_t<T>>::to_gpr(static_cast<std::underlying_type_t<T>>(value));
} }
force_inline static T from_gpr(const u32 reg) force_inline static T from_gpr(const u32 reg)
{ {
return static_cast<T>(cast_armv7_gpr<underlying_type>::from_gpr(reg)); return static_cast<T>(cast_armv7_gpr<std::underlying_type_t<T>>::from_gpr(reg));
} }
}; };

View file

@ -307,7 +307,7 @@ namespace psv_func_detail
template <typename RT, typename F, typename Tuple> template <typename RT, typename F, typename Tuple>
force_inline RT call(F f, Tuple && t) force_inline RT call(F f, Tuple && t)
{ {
typedef typename std::decay<Tuple>::type ttype; using ttype = std::decay_t<Tuple>;
return psv_func_detail::call_impl<RT, F, Tuple, 0 == std::tuple_size<ttype>::value, std::tuple_size<ttype>::value>::call(f, std::forward<Tuple>(t)); return psv_func_detail::call_impl<RT, F, Tuple, 0 == std::tuple_size<ttype>::value, std::tuple_size<ttype>::value>::call(f, std::forward<Tuple>(t));
} }

View file

@ -845,16 +845,14 @@ struct cast_ppu_gpr
{ {
static_assert(is_enum, "Invalid type for cast_ppu_gpr"); static_assert(is_enum, "Invalid type for cast_ppu_gpr");
typedef typename std::underlying_type<T>::type underlying_type;
force_inline static u64 to_gpr(const T& value) force_inline static u64 to_gpr(const T& value)
{ {
return cast_ppu_gpr<underlying_type>::to_gpr(static_cast<underlying_type>(value)); return cast_ppu_gpr<std::underlying_type_t<T>>::to_gpr(static_cast<std::underlying_type_t<T>>(value));
} }
force_inline static T from_gpr(const u64 reg) force_inline static T from_gpr(const u64 reg)
{ {
return static_cast<T>(cast_ppu_gpr<underlying_type>::from_gpr(reg)); return static_cast<T>(cast_ppu_gpr<std::underlying_type_t<T>>::from_gpr(reg));
} }
}; };

View file

@ -1,46 +1,41 @@
#pragma once #pragma once
template<typename T, size_t size = sizeof(T)> template<typename T, size_t size = sizeof(T)> struct _to_atomic_subtype
struct _to_atomic_subtype
{ {
static_assert(size == 1 || size == 2 || size == 4 || size == 8 || size == 16, "Invalid atomic type"); static_assert(size == 1 || size == 2 || size == 4 || size == 8 || size == 16, "Invalid atomic type");
}; };
template<typename T> template<typename T> struct _to_atomic_subtype<T, 1>
struct _to_atomic_subtype<T, 1>
{ {
using type = uint8_t; using type = u8;
}; };
template<typename T> template<typename T> struct _to_atomic_subtype<T, 2>
struct _to_atomic_subtype<T, 2>
{ {
using type = uint16_t; using type = u16;
}; };
template<typename T> template<typename T> struct _to_atomic_subtype<T, 4>
struct _to_atomic_subtype<T, 4>
{ {
using type = uint32_t; using type = u32;
}; };
template<typename T> template<typename T> struct _to_atomic_subtype<T, 8>
struct _to_atomic_subtype<T, 8>
{ {
using type = uint64_t; using type = u64;
}; };
template<typename T> template<typename T> struct _to_atomic_subtype<T, 16>
struct _to_atomic_subtype<T, 16>
{ {
using type = u128; using type = u128;
}; };
template<typename T> template<typename T> using atomic_subtype_t = typename _to_atomic_subtype<T>::type;
union _atomic_base
template<typename T> union _atomic_base
{ {
using type = typename std::remove_cv<T>::type; using type = std::remove_cv_t<T>;
using subtype = typename _to_atomic_subtype<type, sizeof(type)>::type; using subtype = atomic_subtype_t<type>;
type data; // unsafe direct access type data; // unsafe direct access
subtype sub_data; // unsafe direct access to substitute type subtype sub_data; // unsafe direct access to substitute type
@ -197,8 +192,8 @@ public:
// Helper definitions // Helper definitions
template<typename T, typename T2 = T> using if_arithmetic_le_t = const typename std::enable_if<std::is_arithmetic<T>::value && std::is_arithmetic<T2>::value, le_t<T>>::type; template<typename T, typename T2 = T> using if_arithmetic_le_t = std::enable_if_t<std::is_arithmetic<T>::value && std::is_arithmetic<T2>::value, le_t<T>>;
template<typename T, typename T2 = T> using if_arithmetic_be_t = const typename std::enable_if<std::is_arithmetic<T>::value && std::is_arithmetic<T2>::value, be_t<T>>::type; template<typename T, typename T2 = T> using if_arithmetic_be_t = std::enable_if_t<std::is_arithmetic<T>::value && std::is_arithmetic<T2>::value, be_t<T>>;
template<typename T> inline static if_arithmetic_le_t<T> operator ++(_atomic_base<le_t<T>>& left) template<typename T> inline static if_arithmetic_le_t<T> operator ++(_atomic_base<le_t<T>>& left)
{ {
@ -304,6 +299,6 @@ template<typename T, typename T2> inline static if_arithmetic_be_t<T, T2> operat
template<typename T> using atomic = _atomic_base<T>; // Atomic Type with native endianness (for emulator memory) template<typename T> using atomic = _atomic_base<T>; // Atomic Type with native endianness (for emulator memory)
template<typename T> using atomic_be_t = _atomic_base<typename to_be_t<T>::type>; // Atomic BE Type (for PS3 virtual memory) template<typename T> using atomic_be_t = _atomic_base<to_be_t<T>>; // Atomic BE Type (for PS3 virtual memory)
template<typename T> using atomic_le_t = _atomic_base<typename to_le_t<T>::type>; // Atomic LE Type (for PSV virtual memory) template<typename T> using atomic_le_t = _atomic_base<to_le_t<T>>; // Atomic LE Type (for PSV virtual memory)

View file

@ -127,10 +127,10 @@ namespace vm
} }
}; };
template<typename T, typename T2> template<typename T>
struct cast_ptr<be_t<T, T2>> struct cast_ptr<be_t<T>>
{ {
force_inline static u32 cast(const be_t<T, T2>& addr, const char* func) force_inline static u32 cast(const be_t<T>& addr, const char* func)
{ {
return cast_ptr<T>::cast(addr.value(), func); return cast_ptr<T>::cast(addr.value(), func);
} }

View file

@ -10,7 +10,11 @@ namespace vm
{ {
AT m_addr; AT m_addr;
typedef typename std::remove_cv<T>::type type; using type = T;
static_assert(!std::is_pointer<T>::value, "vm::_ptr_base<> error: invalid type (pointer)");
static_assert(!std::is_reference<T>::value, "vm::_ptr_base<> error: invalid type (reference)");
static const u32 address_size = sizeof(AT); static const u32 address_size = sizeof(AT);
_ptr_base operator++ (int) _ptr_base operator++ (int)
@ -51,10 +55,8 @@ namespace vm
return *this; return *this;
} }
_ptr_base operator + (typename remove_be_t<AT>::type count) const { return make(m_addr + count * address_size); } _ptr_base operator + (to_ne_t<AT> count) const { return make(m_addr + count * address_size); }
_ptr_base operator + (typename to_be_t<AT>::type count) const { return make(m_addr + count * address_size); } _ptr_base operator - (to_ne_t<AT> count) const { return make(m_addr - count * address_size); }
_ptr_base operator - (typename remove_be_t<AT>::type count) const { return make(m_addr - count * address_size); }
_ptr_base operator - (typename to_be_t<AT>::type count) const { return make(m_addr - count * address_size); }
force_inline bool operator <(const _ptr_base& right) const { return m_addr < right.m_addr; } force_inline bool operator <(const _ptr_base& right) const { return m_addr < right.m_addr; }
force_inline bool operator <=(const _ptr_base& right) const { return m_addr <= right.m_addr; } force_inline bool operator <=(const _ptr_base& right) const { return m_addr <= right.m_addr; }
@ -66,23 +68,21 @@ namespace vm
force_inline bool operator !=(const nullptr_t& right) const { return m_addr != 0; } force_inline bool operator !=(const nullptr_t& right) const { return m_addr != 0; }
explicit operator bool() const { return m_addr != 0; } explicit operator bool() const { return m_addr != 0; }
force_inline _ptr_base<T, lvl - 1, typename std::conditional<is_be_t<T>::value, typename to_be_t<AT>::type, AT>::type> operator *() const force_inline _ptr_base<T, lvl - 1, std::conditional_t<is_be_t<T>::value, to_be_t<AT>, AT>> operator *() const
{ {
AT addr = convert_le_be<AT>(read64(convert_le_be<u32>(m_addr))); AT addr = convert_le_be<AT>(read64(convert_le_be<u32>(m_addr)));
return (_ptr_base<T, lvl - 1, typename std::conditional<is_be_t<T>::value, typename to_be_t<AT>::type, AT>::type>&)addr; return (_ptr_base<T, lvl - 1, std::conditional_t<is_be_t<T>::value, to_be_t<AT>, AT>>&)addr;
} }
force_inline _ptr_base<T, lvl - 1, typename std::conditional<is_be_t<T>::value, typename to_be_t<AT>::type, AT>::type> operator [](AT index) const force_inline _ptr_base<T, lvl - 1, std::conditional_t<is_be_t<T>::value, to_be_t<AT>, AT>> operator [](AT index) const
{ {
AT addr = convert_le_be<AT>(read64(convert_le_be<u32>(m_addr + 8 * index))); AT addr = convert_le_be<AT>(read64(convert_le_be<u32>(m_addr + 8 * index)));
return (_ptr_base<T, lvl - 1, typename std::conditional<is_be_t<T>::value, typename to_be_t<AT>::type, AT>::type>&)addr; return (_ptr_base<T, lvl - 1, std::conditional_t<is_be_t<T>::value, to_be_t<AT>, AT>>&)addr;
} }
template<typename AT2> template<typename AT2> operator _ptr_base<T, lvl, AT2>() const
operator _ptr_base<T, lvl, AT2>() const
{ {
AT2 addr = convert_le_be<AT2>(m_addr); return{ convert_le_be<AT2>(m_addr) };
return reinterpret_cast<_ptr_base<T, lvl, AT2>&>(addr);
} }
AT addr() const AT addr() const
@ -90,15 +90,14 @@ namespace vm
return m_addr; return m_addr;
} }
template<typename U> template<typename U> void set(U&& value)
void set(U&& value)
{ {
m_addr = convert_le_be<AT>(value); m_addr = convert_le_be<AT>(value);
} }
static _ptr_base make(const AT& addr) template<typename AT2 = AT> static _ptr_base make(const AT2& addr)
{ {
return reinterpret_cast<const _ptr_base&>(addr); return{ convert_le_be<AT>(addr) };
} }
_ptr_base& operator = (const _ptr_base& right) = default; _ptr_base& operator = (const _ptr_base& right) = default;
@ -109,9 +108,10 @@ namespace vm
{ {
AT m_addr; AT m_addr;
using type = T;
static_assert(!std::is_pointer<T>::value, "vm::_ptr_base<> error: invalid type (pointer)"); static_assert(!std::is_pointer<T>::value, "vm::_ptr_base<> error: invalid type (pointer)");
static_assert(!std::is_reference<T>::value, "vm::_ptr_base<> error: invalid type (reference)"); static_assert(!std::is_reference<T>::value, "vm::_ptr_base<> error: invalid type (reference)");
typedef typename std::remove_cv<T>::type type;
force_inline static const u32 data_size() force_inline static const u32 data_size()
{ {
@ -161,22 +161,15 @@ namespace vm
return *this; return *this;
} }
_ptr_base operator + (typename remove_be_t<AT>::type count) const { return make(convert_le_be<AT>(convert_le_be<decltype(count)>(m_addr) + count * convert_le_be<decltype(count)>(data_size()))); } _ptr_base operator + (to_ne_t<AT> count) const { return make(convert_le_be<AT>(convert_le_be<decltype(count)>(m_addr) +count * convert_le_be<decltype(count)>(data_size()))); }
_ptr_base operator + (typename to_be_t<AT>::type count) const { return make(convert_le_be<AT>(convert_le_be<decltype(count)>(m_addr) + count * convert_le_be<decltype(count)>(data_size()))); } _ptr_base operator - (to_ne_t<AT> count) const { return make(convert_le_be<AT>(convert_le_be<decltype(count)>(m_addr) -count * convert_le_be<decltype(count)>(data_size()))); }
_ptr_base operator - (typename remove_be_t<AT>::type count) const { return make(convert_le_be<AT>(convert_le_be<decltype(count)>(m_addr) - count * convert_le_be<decltype(count)>(data_size()))); }
_ptr_base operator - (typename to_be_t<AT>::type count) const { return make(convert_le_be<AT>(convert_le_be<decltype(count)>(m_addr) - count * convert_le_be<decltype(count)>(data_size()))); }
force_inline T& operator *() const force_inline T& operator *() const
{ {
return vm::get_ref<T>(vm::cast(m_addr)); return vm::get_ref<T>(vm::cast(m_addr));
} }
force_inline T& operator [](typename remove_be_t<AT>::type index) const force_inline T& operator [](to_ne_t<AT> index) const
{
return vm::get_ref<T>(vm::cast(m_addr + data_size() * index));
}
force_inline T& operator [](typename to_be_t<AT>::forced_type index) const
{ {
return vm::get_ref<T>(vm::cast(m_addr + data_size() * index)); return vm::get_ref<T>(vm::cast(m_addr + data_size() * index));
} }
@ -192,24 +185,21 @@ namespace vm
explicit operator bool() const { return m_addr != 0; } explicit operator bool() const { return m_addr != 0; }
explicit operator T*() const { return get_ptr(); } explicit operator T*() const { return get_ptr(); }
template<typename AT2> operator _ptr_base<T, 1, AT2>() const
{
return{ convert_le_be<AT2>(m_addr) };
}
AT addr() const AT addr() const
{ {
return m_addr; return m_addr;
} }
template<typename U> template<typename U> void set(U&& value)
void set(U&& value)
{ {
m_addr = convert_le_be<AT>(value); m_addr = convert_le_be<AT>(value);
} }
template<typename AT2>
operator _ptr_base<T, 1, AT2>() const
{
AT2 addr = convert_le_be<AT2>(m_addr);
return reinterpret_cast<_ptr_base<T, 1, AT2>&>(addr);
}
T* get_ptr() const T* get_ptr() const
{ {
return vm::get_ptr<T>(vm::cast(m_addr)); return vm::get_ptr<T>(vm::cast(m_addr));
@ -220,9 +210,9 @@ namespace vm
return vm::priv_ptr<T>(vm::cast(m_addr)); return vm::priv_ptr<T>(vm::cast(m_addr));
} }
static const _ptr_base make(const AT& addr) template<typename AT2 = AT> static _ptr_base make(const AT2& addr)
{ {
return reinterpret_cast<const _ptr_base&>(addr); return{ convert_le_be<AT>(addr) };
} }
_ptr_base& operator = (const _ptr_base& right) = default; _ptr_base& operator = (const _ptr_base& right) = default;
@ -269,23 +259,19 @@ namespace vm
force_inline bool operator !=(const nullptr_t& right) const { return m_addr != 0; } force_inline bool operator !=(const nullptr_t& right) const { return m_addr != 0; }
explicit operator bool() const { return m_addr != 0; } explicit operator bool() const { return m_addr != 0; }
template<typename AT2> template<typename AT2> operator _ptr_base<void, 1, AT2>() const
operator _ptr_base<void, 1, AT2>() const
{ {
AT2 addr = convert_le_be<AT2>(m_addr); return{ convert_le_be<AT2>(m_addr) };
return reinterpret_cast<_ptr_base<void, 1, AT2>&>(addr);
} }
template<typename AT2> template<typename AT2> operator _ptr_base<const void, 1, AT2>() const
operator _ptr_base<const void, 1, AT2>() const
{ {
AT2 addr = convert_le_be<AT2>(m_addr); return{ convert_le_be<AT2>(m_addr) };
return reinterpret_cast<_ptr_base<const void, 1, AT2>&>(addr);
} }
static const _ptr_base make(const AT& addr) template<typename AT2 = AT> static _ptr_base make(const AT2& addr)
{ {
return reinterpret_cast<const _ptr_base&>(addr); return{ convert_le_be<AT>(addr) };
} }
_ptr_base& operator = (const _ptr_base& right) = default; _ptr_base& operator = (const _ptr_base& right) = default;
@ -332,16 +318,14 @@ namespace vm
force_inline bool operator !=(const nullptr_t& right) const { return m_addr != 0; } force_inline bool operator !=(const nullptr_t& right) const { return m_addr != 0; }
explicit operator bool() const { return m_addr != 0; } explicit operator bool() const { return m_addr != 0; }
template<typename AT2> template<typename AT2> operator _ptr_base<const void, 1, AT2>() const
operator _ptr_base<const void, 1, AT2>() const
{ {
AT2 addr = convert_le_be<AT2>(m_addr); return{ convert_le_be<AT2>(m_addr) };
return reinterpret_cast<_ptr_base<const void, 1, AT2>&>(addr);
} }
static const _ptr_base make(const AT& addr) template<typename AT2 = AT> static _ptr_base make(const AT2& addr)
{ {
return reinterpret_cast<const _ptr_base&>(addr); return{ convert_le_be<AT>(addr) };
} }
_ptr_base& operator = (const _ptr_base& right) = default; _ptr_base& operator = (const _ptr_base& right) = default;
@ -384,16 +368,14 @@ namespace vm
force_inline bool operator !=(const nullptr_t& right) const { return m_addr != 0; } force_inline bool operator !=(const nullptr_t& right) const { return m_addr != 0; }
explicit operator bool() const { return m_addr != 0; } explicit operator bool() const { return m_addr != 0; }
template<typename AT2> template<typename AT2> operator _ptr_base<type, 1, AT2>() const
operator _ptr_base<type, 1, AT2>() const
{ {
AT2 addr = convert_le_be<AT2>(m_addr); return{ convert_le_be<AT2>(m_addr) };
return reinterpret_cast<_ptr_base<type, 1, AT2>&>(addr);
} }
static const _ptr_base make(const AT& addr) template<typename AT2 = AT> static _ptr_base make(const AT2& addr)
{ {
return reinterpret_cast<const _ptr_base&>(addr); return{ convert_le_be<AT>(addr) };
} }
operator const std::function<type>() const operator const std::function<type>() const
@ -414,22 +396,22 @@ namespace vm
}; };
// Native endianness pointer to LE data // Native endianness pointer to LE data
template<typename T, int lvl = 1, typename AT = u32> using ptrl = _ptr_base<typename to_le_t<T>::type, lvl, AT>; template<typename T, int lvl = 1, typename AT = u32> using ptrl = _ptr_base<to_le_t<T>, lvl, AT>;
// Native endianness pointer to BE data // Native endianness pointer to BE data
template<typename T, int lvl = 1, typename AT = u32> using ptrb = _ptr_base<typename to_be_t<T>::type, lvl, AT>; template<typename T, int lvl = 1, typename AT = u32> using ptrb = _ptr_base<to_be_t<T>, lvl, AT>;
// BE pointer to LE data // BE pointer to LE data
template<typename T, int lvl = 1, typename AT = u32> using bptrl = _ptr_base<typename to_le_t<T>::type, lvl, typename to_be_t<AT>::type>; template<typename T, int lvl = 1, typename AT = u32> using bptrl = _ptr_base<to_le_t<T>, lvl, to_be_t<AT>>;
// BE pointer to BE data // BE pointer to BE data
template<typename T, int lvl = 1, typename AT = u32> using bptrb = _ptr_base<typename to_be_t<T>::type, lvl, typename to_be_t<AT>::type>; template<typename T, int lvl = 1, typename AT = u32> using bptrb = _ptr_base<to_be_t<T>, lvl, to_be_t<AT>>;
// LE pointer to LE data // LE pointer to LE data
template<typename T, int lvl = 1, typename AT = u32> using lptrl = _ptr_base<typename to_le_t<T>::type, lvl, typename to_le_t<AT>::type>; template<typename T, int lvl = 1, typename AT = u32> using lptrl = _ptr_base<to_le_t<T>, lvl, to_le_t<AT>>;
// LE pointer to BE data // LE pointer to BE data
template<typename T, int lvl = 1, typename AT = u32> using lptrb = _ptr_base<typename to_be_t<T>::type, lvl, typename to_le_t<AT>::type>; template<typename T, int lvl = 1, typename AT = u32> using lptrb = _ptr_base<to_be_t<T>, lvl, to_le_t<AT>>;
namespace ps3 namespace ps3
{ {
@ -456,8 +438,7 @@ namespace vm
{ {
template<typename T, int lvl, typename AT> operator _ptr_base<T, lvl, AT>() const template<typename T, int lvl, typename AT> operator _ptr_base<T, lvl, AT>() const
{ {
const std::array<AT, 1> value = {}; return{};
return _ptr_base<T, lvl, AT>::make(value[0]);
} }
}; };
@ -465,6 +446,37 @@ namespace vm
static null_t null; static null_t null;
} }
// external specialization for is_be_t<>
template<typename T, int lvl, typename AT>
struct is_be_t<vm::_ptr_base<T, lvl, AT>> : public std::integral_constant<bool, is_be_t<AT>::value>
{
};
// external specialization for to_ne_t<>
template<typename T, int lvl, typename AT>
struct to_ne<vm::_ptr_base<T, lvl, AT>>
{
using type = vm::_ptr_base<T, lvl, to_ne_t<AT>>;
};
// external specialization for to_be_t<>
template<typename T, int lvl, typename AT>
struct to_be<vm::_ptr_base<T, lvl, AT>>
{
using type = vm::_ptr_base<T, lvl, to_be_t<AT>>;
};
// external specialization for to_le_t<> (not used)
template<typename T, int lvl, typename AT>
struct to_le<vm::_ptr_base<T, lvl, AT>>
{
using type = vm::_ptr_base<T, lvl, to_le_t<AT>>;
};
namespace fmt namespace fmt
{ {
// external specialization for fmt::format function // external specialization for fmt::format function
@ -472,7 +484,7 @@ namespace fmt
template<typename T, int lvl, typename AT> template<typename T, int lvl, typename AT>
struct unveil<vm::_ptr_base<T, lvl, AT>, false> struct unveil<vm::_ptr_base<T, lvl, AT>, false>
{ {
typedef typename unveil<AT>::result_type result_type; using result_type = typename unveil<AT>::result_type;
force_inline static result_type get_value(const vm::_ptr_base<T, lvl, AT>& arg) force_inline static result_type get_value(const vm::_ptr_base<T, lvl, AT>& arg)
{ {

View file

@ -3,26 +3,30 @@
namespace vm namespace vm
{ {
template<typename T, typename AT = u32> template<typename T, typename AT = u32>
class _ref_base struct _ref_base
{ {
protected: const AT m_addr;
AT m_addr;
using type = T;
public:
typedef T type;
static_assert(!std::is_pointer<T>::value, "vm::_ref_base<> error: invalid type (pointer)"); static_assert(!std::is_pointer<T>::value, "vm::_ref_base<> error: invalid type (pointer)");
static_assert(!std::is_reference<T>::value, "vm::_ref_base<> error: invalid type (reference)"); static_assert(!std::is_reference<T>::value, "vm::_ref_base<> error: invalid type (reference)");
typedef typename remove_be_t<T>::type le_type;
typedef typename to_be_t<T>::type be_type;
operator T&() //template<typename CT> operator std::enable_if_t<std::is_convertible<T, CT>::value, CT>()
//{
// return get_ref<T>(m_addr);
//}
// temporarily, because SFINAE doesn't work for some reason:
operator to_ne_t<T>() const
{ {
return get_ref<T>(m_addr); return get_ref<T>(m_addr);
} }
operator const T&() const operator T() const
{ {
return get_ref<const T>(m_addr); return get_ref<T>(m_addr);
} }
AT addr() const AT addr() const
@ -32,28 +36,16 @@ namespace vm
static _ref_base make(const AT& addr) static _ref_base make(const AT& addr)
{ {
return reinterpret_cast<_ref_base&>(addr); return{ addr };
} }
_ref_base& operator = (le_type right) template<typename CT> const _ref_base& operator =(const _ref_base<T, CT>& right) const
{ {
get_ref<T>(m_addr) = right; get_ref<T>(m_addr) = right;
return *this; return *this;
} }
const _ref_base& operator = (le_type right) const template<typename CT> std::enable_if_t<std::is_assignable<T&, CT>::value, const _ref_base&> operator =(const CT& right) const
{
get_ref<T>(m_addr) = right;
return *this;
}
_ref_base& operator = (be_type right)
{
get_ref<T>(m_addr) = right;
return *this;
}
const _ref_base& operator = (be_type right) const
{ {
get_ref<T>(m_addr) = right; get_ref<T>(m_addr) = right;
return *this; return *this;
@ -61,22 +53,22 @@ namespace vm
}; };
// Native endianness reference to LE data // Native endianness reference to LE data
template<typename T, typename AT = u32> using refl = _ref_base<typename to_le_t<T>::type, AT>; template<typename T, typename AT = u32> using refl = _ref_base<to_le_t<T>, AT>;
// Native endianness reference to BE data // Native endianness reference to BE data
template<typename T, typename AT = u32> using refb = _ref_base<typename to_be_t<T>::type, AT>; template<typename T, typename AT = u32> using refb = _ref_base<to_be_t<T>, AT>;
// BE reference to LE data // BE reference to LE data
template<typename T, typename AT = u32> using brefl = _ref_base<typename to_le_t<T>::type, typename to_be_t<AT>::type>; template<typename T, typename AT = u32> using brefl = _ref_base<to_le_t<T>, to_be_t<AT>>;
// BE reference to BE data // BE reference to BE data
template<typename T, typename AT = u32> using brefb = _ref_base<typename to_be_t<T>::type, typename to_be_t<AT>::type>; template<typename T, typename AT = u32> using brefb = _ref_base<to_be_t<T>, to_be_t<AT>>;
// LE reference to LE data // LE reference to LE data
template<typename T, typename AT = u32> using lrefl = _ref_base<typename to_le_t<T>::type, typename to_le_t<AT>::type>; template<typename T, typename AT = u32> using lrefl = _ref_base<to_le_t<T>, to_le_t<AT>>;
// LE reference to BE data // LE reference to BE data
template<typename T, typename AT = u32> using lrefb = _ref_base<typename to_be_t<T>::type, typename to_le_t<AT>::type>; template<typename T, typename AT = u32> using lrefb = _ref_base<to_be_t<T>, to_le_t<AT>>;
namespace ps3 namespace ps3
{ {
@ -98,7 +90,38 @@ namespace vm
//PS3 emulation is main now, so lets it be as default //PS3 emulation is main now, so lets it be as default
using namespace ps3; using namespace ps3;
} };
// external specialization for is_be_t<>
template<typename T, typename AT>
struct is_be_t<vm::_ref_base<T, AT>> : public std::integral_constant<bool, is_be_t<AT>::value>
{
};
// external specialization for to_ne_t<>
template<typename T, typename AT>
struct to_ne<vm::_ref_base<T, AT>>
{
using type = vm::_ref_base<T, to_ne_t<AT>>;
};
// external specialization for to_be_t<>
template<typename T, typename AT>
struct to_be<vm::_ref_base<T, AT>>
{
using type = vm::_ref_base<T, to_be_t<AT>>;
};
// external specialization for to_le_t<> (not used)
template<typename T, typename AT>
struct to_le<vm::_ref_base<T, AT>>
{
using type = vm::_ref_base<T, to_le_t<AT>>;
};
namespace fmt namespace fmt
{ {
@ -107,7 +130,7 @@ namespace fmt
template<typename T, typename AT> template<typename T, typename AT>
struct unveil<vm::_ref_base<T, AT>, false> struct unveil<vm::_ref_base<T, AT>, false>
{ {
typedef typename unveil<AT>::result_type result_type; using result_type = typename unveil<AT>::result_type;
force_inline static result_type get_value(const vm::_ref_base<T, AT>& arg) force_inline static result_type get_value(const vm::_ref_base<T, AT>& arg)
{ {

View file

@ -19,10 +19,10 @@ enum CellGifDecStreamSrcSel
CELL_GIFDEC_BUFFER = 1, // Input from a buffer CELL_GIFDEC_BUFFER = 1, // Input from a buffer
}; };
enum CellGifDecColorSpace enum CellGifDecSpuThreadEna
{ {
CELL_GIFDEC_RGBA = 10, CELL_GIFDEC_SPU_THREAD_DISABLE = 0, // Do not use SPU threads
CELL_GIFDEC_ARGB = 20, CELL_GIFDEC_SPU_THREAD_ENABLE = 1, // Use SPU threads
}; };
enum CellGifDecRecordType enum CellGifDecRecordType
@ -32,10 +32,22 @@ enum CellGifDecRecordType
CELL_GIFDEC_RECORD_TYPE_TERMINATE = 3, // Trailer block CELL_GIFDEC_RECORD_TYPE_TERMINATE = 3, // Trailer block
}; };
enum CellGifDecColorSpace
{
CELL_GIFDEC_RGBA = 10, // RGBA
CELL_GIFDEC_ARGB = 20, // ARGB
};
enum CellGifDecCommand
{
CELL_GIFDEC_CONTINUE = 0, // Continue decoding
CELL_GIFDEC_STOP = 1, // Force decoding to stop
};
enum CellGifDecDecodeStatus enum CellGifDecDecodeStatus
{ {
CELL_GIFDEC_DEC_STATUS_FINISH = 0, // Decoding finished CELL_GIFDEC_DEC_STATUS_FINISH = 0, // Decoding finished
CELL_GIFDEC_DEC_STATUS_STOP = 1, //Decoding halted CELL_GIFDEC_DEC_STATUS_STOP = 1, // Decoding was stopped
}; };
struct CellGifDecInfo struct CellGifDecInfo
@ -65,9 +77,9 @@ struct CellGifDecInParam
{ {
be_t<u32> commandPtr; be_t<u32> commandPtr;
be_t<u32> colorSpace; // CellGifDecColorSpace be_t<u32> colorSpace; // CellGifDecColorSpace
be_t<u8> outputColorAlpha1; u8 outputColorAlpha1;
be_t<u8> outputColorAlpha2; u8 outputColorAlpha2;
be_t<u8> reserved[2]; u8 reserved[2];
}; };
struct CellGifDecOutParam struct CellGifDecOutParam
@ -83,8 +95,8 @@ struct CellGifDecOutParam
struct CellGifDecExtension struct CellGifDecExtension
{ {
be_t<u8> label; u8 label;
be_t<u32> data; vm::ptr<u8> data;
}; };
struct CellGifDecDataOutInfo struct CellGifDecDataOutInfo

View file

@ -71,8 +71,8 @@ struct CellJpgDecInParam
be_t<u32> method; // CellJpgDecMethod be_t<u32> method; // CellJpgDecMethod
be_t<u32> outputMode; // CellJpgDecOutputMode be_t<u32> outputMode; // CellJpgDecOutputMode
be_t<u32> outputColorSpace; // CellJpgDecColorSpace be_t<u32> outputColorSpace; // CellJpgDecColorSpace
be_t<u8> outputColorAlpha; u8 outputColorAlpha;
be_t<u8> reserved[3]; u8 reserved[3];
}; };
struct CellJpgDecOutParam struct CellJpgDecOutParam

View file

@ -2,44 +2,47 @@
#include "Emu/Memory/Memory.h" #include "Emu/Memory/Memory.h"
#include "Emu/SysCalls/Modules.h" #include "Emu/SysCalls/Modules.h"
#include "cellL10n.h"
#include <stdio.h>
#include <stdlib.h>
#ifdef _MSC_VER #ifdef _MSC_VER
#include <windows.h> #include <windows.h>
#include <wchar.h>
#include <codecvt>
#else #else
#include <iconv.h> #include <iconv.h>
#endif #endif
#include "cellL10n.h"
#include <codecvt>
#include <stdio.h>
#include <stdlib.h>
extern Module cellL10n; extern Module cellL10n;
int UTF16stoUTF8s(vm::lptrl<const char16_t> utf16, vm::ptr<u32> utf16_len, vm::ptr<char> utf8, vm::ptr<u32> utf8_len) s32 UTF16stoUTF8s(vm::ptr<const char16_t> utf16, vm::ref<u32> utf16_len, vm::ptr<char> utf8, vm::ref<u32> utf8_len)
{ {
cellL10n.Warning("UTF16stoUTF8s(utf16_addr=0x%x, utf16_len_addr=0x%x, utf8_addr=0x%x, utf8_len_addr=0x%x)", cellL10n.Warning("UTF16stoUTF8s(utf16=*0x%x, utf16_len=*0x%x, utf8=*0x%x, utf8_len=*0x%x)", utf16, utf16_len, utf8, utf8_len);
utf16.addr(), utf16_len.addr(), utf8.addr(), utf8_len.addr());
std::u16string wstr;
wstr.resize(utf16_len);
for (auto& wc : wstr)
{
wc = *utf16++;
}
std::u16string wstr = utf16.get_ptr(); // ???
wstr.resize(*utf16_len); // TODO: Is this really the role of utf16_len in this function?
#ifdef _MSC_VER
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert; std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
std::string str = convert.to_bytes(wstr); std::string str = convert.to_bytes(wstr);
if (*utf8_len < str.size()) if (utf8_len < str.size())
{ {
*utf8_len = str.size(); utf8_len = str.size();
return DSTExhausted; return DSTExhausted;
} }
*utf8_len = str.size(); utf8_len = str.size();
memcpy(utf8.get_ptr(), str.c_str(), str.size()); memcpy(utf8.get_ptr(), str.c_str(), str.size());
#endif
return ConversionOK; return ConversionOK;
} }
int jstrchk(vm::ptr<const char> jstr) s32 jstrchk(vm::ptr<const char> jstr)
{ {
cellL10n.Warning("jstrchk(jstr_addr=0x%x) -> utf8", jstr.addr()); cellL10n.Warning("jstrchk(jstr_addr=0x%x) -> utf8", jstr.addr());
@ -48,7 +51,7 @@ int jstrchk(vm::ptr<const char> jstr)
//translate code id to code name. some codepage may has another name. //translate code id to code name. some codepage may has another name.
//If this makes your compilation fail, try replace the string code with one in "iconv -l" //If this makes your compilation fail, try replace the string code with one in "iconv -l"
bool _L10nCodeParse(int code, std::string& retCode) bool _L10nCodeParse(s32 code, std::string& retCode)
{ {
if ((code >= _L10N_CODE_) || (code < 0)) return false; if ((code >= _L10N_CODE_) || (code < 0)) return false;
switch (code) switch (code)
@ -113,7 +116,7 @@ bool _L10nCodeParse(int code, std::string& retCode)
//translate code id to code name. //translate code id to code name.
//If this makes your compilation fail, try replace the string code with one in "iconv -l" //If this makes your compilation fail, try replace the string code with one in "iconv -l"
bool _L10nCodeParse(int code, unsigned int & retCode) bool _L10nCodeParse(s32 code, u32& retCode)
{ {
retCode = 0; retCode = 0;
if ((code >= _L10N_CODE_) || (code < 0)) return false; if ((code >= _L10N_CODE_) || (code < 0)) return false;
@ -182,10 +185,10 @@ bool _L10nCodeParse(int code, unsigned int & retCode)
#ifdef _MSC_VER #ifdef _MSC_VER
//Use code page to transform std::string to std::wstring. //Use code page to transform std::string to std::wstring.
int _OEM2Wide(unsigned int oem_code, const std::string src, std::wstring& dst) s32 _OEM2Wide(u32 oem_code, const std::string src, std::wstring& dst)
{ {
//Such length returned should include the '\0' character. //Such length returned should include the '\0' character.
int length = MultiByteToWideChar(oem_code, 0, src.c_str(), -1, NULL, 0); s32 length = MultiByteToWideChar(oem_code, 0, src.c_str(), -1, NULL, 0);
wchar_t *store = new wchar_t[length](); wchar_t *store = new wchar_t[length]();
MultiByteToWideChar(oem_code, 0, src.c_str(), -1, (LPWSTR)store, length); MultiByteToWideChar(oem_code, 0, src.c_str(), -1, (LPWSTR)store, length);
@ -199,10 +202,10 @@ int _OEM2Wide(unsigned int oem_code, const std::string src, std::wstring& dst)
} }
//Use Code page to transform std::wstring to std::string. //Use Code page to transform std::wstring to std::string.
int _Wide2OEM(unsigned int oem_code, const std::wstring src, std::string& dst) s32 _Wide2OEM(u32 oem_code, const std::wstring src, std::string& dst)
{ {
//Such length returned should include the '\0' character. //Such length returned should include the '\0' character.
int length = WideCharToMultiByte(oem_code, 0, src.c_str(), -1, NULL, 0, NULL, NULL); s32 length = WideCharToMultiByte(oem_code, 0, src.c_str(), -1, NULL, 0, NULL, NULL);
char *store = new char[length](); char *store = new char[length]();
WideCharToMultiByte(oem_code, 0, src.c_str(), -1, store, length, NULL, NULL); WideCharToMultiByte(oem_code, 0, src.c_str(), -1, store, length, NULL, NULL);
@ -216,7 +219,7 @@ int _Wide2OEM(unsigned int oem_code, const std::wstring src, std::string& dst)
} }
//Convert Codepage to Codepage (all char*) //Convert Codepage to Codepage (all char*)
std::string _OemToOem(unsigned int src_code, unsigned int dst_code, const std::string str) std::string _OemToOem(u32 src_code, u32 dst_code, const std::string str)
{ {
std::wstring wide; std::string result; std::wstring wide; std::string result;
_OEM2Wide(src_code, str, wide); _OEM2Wide(src_code, str, wide);
@ -227,9 +230,9 @@ std::string _OemToOem(unsigned int src_code, unsigned int dst_code, const std::s
/* /*
//Original piece of code. and this is for windows using with _OEM2Wide,_Wide2OEM,_OemToOem. //Original piece of code. and this is for windows using with _OEM2Wide,_Wide2OEM,_OemToOem.
//The Char -> Char Execution of this function has already been tested using VS and CJK text with encoding. //The Char -> Char Execution of this function has already been tested using VS and CJK text with encoding.
int _L10nConvertStr(int src_code, const void *src, size_t * src_len, int dst_code, void *dst, size_t * dst_len) s32 _L10nConvertStr(s32 src_code, const void *src, size_t * src_len, s32 dst_code, void *dst, size_t * dst_len)
{ {
unsigned int srcCode = 0, dstCode = 0; //OEM code pages u32 srcCode = 0, dstCode = 0; //OEM code pages
bool src_page_converted = _L10nCodeParse(src_code, srcCode); //Check if code is in list. bool src_page_converted = _L10nCodeParse(src_code, srcCode); //Check if code is in list.
bool dst_page_converted = _L10nCodeParse(dst_code, dstCode); bool dst_page_converted = _L10nCodeParse(dst_code, dstCode);
@ -251,10 +254,10 @@ int _L10nConvertStr(int src_code, const void *src, size_t * src_len, int dst_cod
} }
//This is the one used with iconv library for linux/mac. Also char->char. //This is the one used with iconv library for linux/mac. Also char->char.
//I've tested the code with console apps using codeblocks. //I've tested the code with console apps using codeblocks.
int _L10nConvertStr(int src_code, const void* src, size_t * src_len, int dst_code, void * dst, size_t * dst_len) s32 _L10nConvertStr(s32 src_code, const void* src, size_t * src_len, s32 dst_code, void * dst, size_t * dst_len)
{ {
std::string srcCode, dstCode; std::string srcCode, dstCode;
int retValue = ConversionOK; s32 retValue = ConversionOK;
if ((_L10nCodeParse(src_code, srcCode)) && (_L10nCodeParse(dst_code, dstCode))) if ((_L10nCodeParse(src_code, srcCode)) && (_L10nCodeParse(dst_code, dstCode)))
{ {
iconv_t ict = iconv_open(srcCode.c_str(), dstCode.c_str()); iconv_t ict = iconv_open(srcCode.c_str(), dstCode.c_str());
@ -281,13 +284,13 @@ int _L10nConvertStr(int src_code, const void* src, size_t * src_len, int dst_cod
#endif #endif
//TODO: Check the code in emulation. If support for UTF8/UTF16/UTF32/UCS2/UCS4 should use wider chars.. awful. //TODO: Check the code in emulation. If support for UTF8/UTF16/UTF32/UCS2/UCS4 should use wider chars.. awful.
int L10nConvertStr(int src_code, vm::ptr<const void> src, vm::ptr<u32> src_len, int dst_code, vm::ptr<void> dst, vm::ptr<u32> dst_len) s32 L10nConvertStr(s32 src_code, vm::ptr<const void> src, vm::ptr<u32> src_len, s32 dst_code, vm::ptr<void> dst, vm::ptr<u32> dst_len)
{ {
cellL10n.Error("L10nConvertStr(src_code=%d, srca_addr=0x%x, src_len_addr=0x%x, dst_code=%d, dst_addr=0x%x, dst_len_addr=0x%x)", cellL10n.Error("L10nConvertStr(src_code=%d, srca_addr=0x%x, src_len_addr=0x%x, dst_code=%d, dst_addr=0x%x, dst_len_addr=0x%x)",
src_code, src.addr(), src_len.addr(), dst_code, dst.addr(), dst_len.addr()); src_code, src.addr(), src_len.addr(), dst_code, dst.addr(), dst_len.addr());
//cellL10n.Todo("L10nConvertStr: 1st char at dst: 0x%x", *((char*)src.get_ptr())); //cellL10n.Todo("L10nConvertStr: 1st char at dst: 0x%x", *((char*)src.get_ptr()));
#ifdef _MSC_VER #ifdef _MSC_VER
unsigned int srcCode = 0, dstCode = 0; //OEM code pages u32 srcCode = 0, dstCode = 0; //OEM code pages
bool src_page_converted = _L10nCodeParse(src_code, srcCode); //Check if code is in list. bool src_page_converted = _L10nCodeParse(src_code, srcCode); //Check if code is in list.
bool dst_page_converted = _L10nCodeParse(dst_code, dstCode); bool dst_page_converted = _L10nCodeParse(dst_code, dstCode);
@ -308,7 +311,7 @@ int L10nConvertStr(int src_code, vm::ptr<const void> src, vm::ptr<u32> src_len,
return ConversionOK; return ConversionOK;
#else #else
std::string srcCode, dstCode; std::string srcCode, dstCode;
int retValue = ConversionOK; s32 retValue = ConversionOK;
if ((_L10nCodeParse(src_code, srcCode)) && (_L10nCodeParse(dst_code, dstCode))) if ((_L10nCodeParse(src_code, srcCode)) && (_L10nCodeParse(dst_code, dstCode)))
{ {
iconv_t ict = iconv_open(srcCode.c_str(), dstCode.c_str()); iconv_t ict = iconv_open(srcCode.c_str(), dstCode.c_str());
@ -490,7 +493,7 @@ Module cellL10n("cellL10n", []()
// REG_FUNC(cellL10n, UTF8stoHZs); // REG_FUNC(cellL10n, UTF8stoHZs);
// REG_FUNC(cellL10n, eucjp2kuten); // REG_FUNC(cellL10n, eucjp2kuten);
// REG_FUNC(cellL10n, UTF8toBIG5); // REG_FUNC(cellL10n, UTF8toBIG5);
// REG_FUNC(cellL10n, UTF16stoUTF8s); REG_FUNC(cellL10n, UTF16stoUTF8s);
// REG_FUNC(cellL10n, JISstoUCS2s); // REG_FUNC(cellL10n, JISstoUCS2s);
// REG_FUNC(cellL10n, GB18030toUTF8); // REG_FUNC(cellL10n, GB18030toUTF8);
// REG_FUNC(cellL10n, UTF8toSJIS); // REG_FUNC(cellL10n, UTF8toSJIS);

View file

@ -1,9 +1,4 @@
#include "stdafx.h" #pragma once
// Requires GCC 4.10 apparently..
#ifdef _MSC_VER
#include <codecvt>
#endif
// L10nResult // L10nResult
enum enum

View file

@ -18,7 +18,7 @@ extern "C"
extern Module cellPngDec; extern Module cellPngDec;
s32 pngDecCreate( s32 pngDecCreate(
vm::ptr<u32> mainHandle, vm::ptr<CellPngDecMainHandle> mainHandle,
vm::ptr<const CellPngDecThreadInParam> param, vm::ptr<const CellPngDecThreadInParam> param,
vm::ptr<const CellPngDecExtThreadInParam> ext = vm::null) vm::ptr<const CellPngDecExtThreadInParam> ext = vm::null)
{ {
@ -41,7 +41,7 @@ s32 pngDecCreate(
} }
// use virtual memory address as a handle // use virtual memory address as a handle
*mainHandle = dec.addr(); *mainHandle = dec;
return CELL_OK; return CELL_OK;
} }
@ -58,7 +58,7 @@ s32 pngDecDestroy(CellPngDecMainHandle dec)
s32 pngDecOpen( s32 pngDecOpen(
CellPngDecMainHandle dec, CellPngDecMainHandle dec,
vm::ptr<u32> subHandle, vm::ptr<CellPngDecSubHandle> subHandle,
vm::ptr<const CellPngDecSrc> src, vm::ptr<const CellPngDecSrc> src,
vm::ptr<CellPngDecOpnInfo> openInfo, vm::ptr<CellPngDecOpnInfo> openInfo,
vm::ptr<const CellPngDecCbCtrlStrm> cb = vm::null, vm::ptr<const CellPngDecCbCtrlStrm> cb = vm::null,
@ -105,7 +105,7 @@ s32 pngDecOpen(
} }
// use virtual memory address as a handle // use virtual memory address as a handle
*subHandle = stream.addr(); *subHandle = stream;
// set memory info // set memory info
openInfo->initSpaceAllocated = 4096; openInfo->initSpaceAllocated = 4096;
@ -366,7 +366,10 @@ s32 pngDecodeData(
return CELL_OK; return CELL_OK;
} }
s32 cellPngDecCreate(vm::ptr<u32> mainHandle, vm::ptr<const CellPngDecThreadInParam> threadInParam, vm::ptr<CellPngDecThreadOutParam> threadOutParam) s32 cellPngDecCreate(
vm::ptr<CellPngDecMainHandle> mainHandle,
vm::ptr<const CellPngDecThreadInParam> threadInParam,
vm::ptr<CellPngDecThreadOutParam> threadOutParam)
{ {
cellPngDec.Warning("cellPngDecCreate(mainHandle=**0x%x, threadInParam=*0x%x, threadOutParam=*0x%x)", mainHandle, threadInParam, threadOutParam); cellPngDec.Warning("cellPngDecCreate(mainHandle=**0x%x, threadInParam=*0x%x, threadOutParam=*0x%x)", mainHandle, threadInParam, threadOutParam);
@ -380,7 +383,7 @@ s32 cellPngDecCreate(vm::ptr<u32> mainHandle, vm::ptr<const CellPngDecThreadInPa
} }
s32 cellPngDecExtCreate( s32 cellPngDecExtCreate(
vm::ptr<u32> mainHandle, vm::ptr<CellPngDecMainHandle> mainHandle,
vm::ptr<const CellPngDecThreadInParam> threadInParam, vm::ptr<const CellPngDecThreadInParam> threadInParam,
vm::ptr<CellPngDecThreadOutParam> threadOutParam, vm::ptr<CellPngDecThreadOutParam> threadOutParam,
vm::ptr<const CellPngDecExtThreadInParam> extThreadInParam, vm::ptr<const CellPngDecExtThreadInParam> extThreadInParam,
@ -410,7 +413,7 @@ s32 cellPngDecDestroy(CellPngDecMainHandle mainHandle)
s32 cellPngDecOpen( s32 cellPngDecOpen(
CellPngDecMainHandle mainHandle, CellPngDecMainHandle mainHandle,
vm::ptr<u32> subHandle, vm::ptr<CellPngDecSubHandle> subHandle,
vm::ptr<const CellPngDecSrc> src, vm::ptr<const CellPngDecSrc> src,
vm::ptr<CellPngDecOpnInfo> openInfo) vm::ptr<CellPngDecOpnInfo> openInfo)
{ {
@ -422,7 +425,7 @@ s32 cellPngDecOpen(
s32 cellPngDecExtOpen( s32 cellPngDecExtOpen(
CellPngDecMainHandle mainHandle, CellPngDecMainHandle mainHandle,
vm::ptr<u32> subHandle, vm::ptr<CellPngDecSubHandle> subHandle,
vm::ptr<const CellPngDecSrc> src, vm::ptr<const CellPngDecSrc> src,
vm::ptr<CellPngDecOpnInfo> openInfo, vm::ptr<CellPngDecOpnInfo> openInfo,
vm::ptr<const CellPngDecCbCtrlStrm> cbCtrlStrm, vm::ptr<const CellPngDecCbCtrlStrm> cbCtrlStrm,

View file

@ -6,11 +6,8 @@ enum : u32
PNGDEC_CODEC_VERSION = 0x00420000, PNGDEC_CODEC_VERSION = 0x00420000,
}; };
struct PngDecoder; using CellPngDecMainHandle = vm::ptr<struct PngDecoder>;
struct PngStream; using CellPngDecSubHandle = vm::ptr<struct PngStream>;
typedef vm::ptr<PngDecoder> CellPngDecMainHandle;
typedef vm::ptr<PngStream> CellPngDecSubHandle;
// Return Codes // Return Codes
enum enum
@ -28,7 +25,7 @@ enum
}; };
// Consts // Consts
enum CellPngDecColorSpace : u32 enum CellPngDecColorSpace : s32
{ {
CELL_PNGDEC_GRAYSCALE = 1, CELL_PNGDEC_GRAYSCALE = 1,
CELL_PNGDEC_RGB = 2, CELL_PNGDEC_RGB = 2,
@ -38,62 +35,62 @@ enum CellPngDecColorSpace : u32
CELL_PNGDEC_ARGB = 20, CELL_PNGDEC_ARGB = 20,
}; };
enum CellPngDecSpuThreadEna : u32 enum CellPngDecSpuThreadEna : s32
{ {
CELL_PNGDEC_SPU_THREAD_DISABLE = 0, CELL_PNGDEC_SPU_THREAD_DISABLE = 0,
CELL_PNGDEC_SPU_THREAD_ENABLE = 1, CELL_PNGDEC_SPU_THREAD_ENABLE = 1,
}; };
enum CellPngDecStreamSrcSel : u32 enum CellPngDecStreamSrcSel : s32
{ {
CELL_PNGDEC_FILE = 0, CELL_PNGDEC_FILE = 0,
CELL_PNGDEC_BUFFER = 1, CELL_PNGDEC_BUFFER = 1,
}; };
enum CellPngDecInterlaceMode : u32 enum CellPngDecInterlaceMode : s32
{ {
CELL_PNGDEC_NO_INTERLACE = 0, CELL_PNGDEC_NO_INTERLACE = 0,
CELL_PNGDEC_ADAM7_INTERLACE = 1, CELL_PNGDEC_ADAM7_INTERLACE = 1,
}; };
enum CellPngDecOutputMode : u32 enum CellPngDecOutputMode : s32
{ {
CELL_PNGDEC_TOP_TO_BOTTOM = 0, CELL_PNGDEC_TOP_TO_BOTTOM = 0,
CELL_PNGDEC_BOTTOM_TO_TOP = 1, CELL_PNGDEC_BOTTOM_TO_TOP = 1,
}; };
enum CellPngDecPackFlag : u32 enum CellPngDecPackFlag : s32
{ {
CELL_PNGDEC_1BYTE_PER_NPIXEL = 0, CELL_PNGDEC_1BYTE_PER_NPIXEL = 0,
CELL_PNGDEC_1BYTE_PER_1PIXEL = 1, CELL_PNGDEC_1BYTE_PER_1PIXEL = 1,
}; };
enum CellPngDecAlphaSelect : u32 enum CellPngDecAlphaSelect : s32
{ {
CELL_PNGDEC_STREAM_ALPHA = 0, CELL_PNGDEC_STREAM_ALPHA = 0,
CELL_PNGDEC_FIX_ALPHA = 1, CELL_PNGDEC_FIX_ALPHA = 1,
}; };
enum CellPngDecCommand : u32 enum CellPngDecCommand : s32
{ {
CELL_PNGDEC_CONTINUE = 0, CELL_PNGDEC_CONTINUE = 0,
CELL_PNGDEC_STOP = 1, CELL_PNGDEC_STOP = 1,
}; };
enum CellPngDecDecodeStatus : u32 enum CellPngDecDecodeStatus : s32
{ {
CELL_PNGDEC_DEC_STATUS_FINISH = 0, CELL_PNGDEC_DEC_STATUS_FINISH = 0,
CELL_PNGDEC_DEC_STATUS_STOP = 1, CELL_PNGDEC_DEC_STATUS_STOP = 1,
}; };
// Callbacks // Callbacks for memory management
typedef vm::ptr<void>(CellPngDecCbControlMalloc)(u32 size, vm::ptr<void> cbCtrlMallocArg); typedef vm::ptr<void>(CellPngDecCbControlMalloc)(u32 size, vm::ptr<void> cbCtrlMallocArg);
typedef s32(CellPngDecCbControlFree)(vm::ptr<void> ptr, vm::ptr<void> cbCtrlFreeArg); typedef s32(CellPngDecCbControlFree)(vm::ptr<void> ptr, vm::ptr<void> cbCtrlFreeArg);
// Structs // Structs
struct CellPngDecThreadInParam struct CellPngDecThreadInParam
{ {
be_t<CellPngDecSpuThreadEna> spuThreadEnable; be_t<s32> spuThreadEnable; // CellPngDecSpuThreadEna
be_t<u32> ppuThreadPriority; be_t<u32> ppuThreadPriority;
be_t<u32> spuThreadPriority; be_t<u32> spuThreadPriority;
vm::bptr<CellPngDecCbControlMalloc> cbCtrlMallocFunc; vm::bptr<CellPngDecCbControlMalloc> cbCtrlMallocFunc;
@ -104,7 +101,7 @@ struct CellPngDecThreadInParam
struct CellPngDecExtThreadInParam struct CellPngDecExtThreadInParam
{ {
be_t<u32> spurs_addr; // it could be vm::bptr<CellSpurs>, but nobody will use SPURS in HLE implementation vm::bptr<struct CellSpurs> spurs;
u8 priority[8]; u8 priority[8];
be_t<u32> maxContention; be_t<u32> maxContention;
}; };
@ -121,13 +118,13 @@ struct CellPngDecExtThreadOutParam
struct CellPngDecSrc struct CellPngDecSrc
{ {
be_t<CellPngDecStreamSrcSel> srcSelect; be_t<s32> srcSelect; // CellPngDecStreamSrcSel
vm::bptr<const char> fileName; vm::bptr<const char> fileName;
be_t<s64> fileOffset; be_t<s64> fileOffset;
be_t<u32> fileSize; be_t<u32> fileSize;
vm::bptr<void> streamPtr; vm::bptr<void> streamPtr;
be_t<u32> streamSize; be_t<u32> streamSize;
be_t<CellPngDecSpuThreadEna> spuThreadEnable; be_t<s32> spuThreadEnable; // CellGifDecSpuThreadEna
}; };
struct CellPngDecOpnInfo struct CellPngDecOpnInfo
@ -140,20 +137,20 @@ struct CellPngDecInfo
be_t<u32> imageWidth; be_t<u32> imageWidth;
be_t<u32> imageHeight; be_t<u32> imageHeight;
be_t<u32> numComponents; be_t<u32> numComponents;
be_t<CellPngDecColorSpace> colorSpace; be_t<s32> colorSpace; // CellPngDecColorSpace
be_t<u32> bitDepth; be_t<u32> bitDepth;
be_t<CellPngDecInterlaceMode> interlaceMethod; be_t<s32> interlaceMethod; // CellPngDecInterlaceMode
be_t<u32> chunkInformation; be_t<u32> chunkInformation;
}; };
struct CellPngDecInParam struct CellPngDecInParam
{ {
vm::bptr<volatile CellPngDecCommand> commandPtr; vm::bptr<volatile s32> commandPtr; // CellPngDecCommand
be_t<CellPngDecOutputMode> outputMode; be_t<s32> outputMode; // CellPngDecOutputMode
be_t<CellPngDecColorSpace> outputColorSpace; be_t<s32> outputColorSpace; // CellPngDecColorSpace
be_t<u32> outputBitDepth; be_t<u32> outputBitDepth;
be_t<CellPngDecPackFlag> outputPackFlag; be_t<s32> outputPackFlag; // CellPngDecPackFlag
be_t<CellPngDecAlphaSelect> outputAlphaSelect; be_t<s32> outputAlphaSelect; // CellPngDecAlphaSelect
be_t<u32> outputColorAlpha; be_t<u32> outputColorAlpha;
}; };
@ -164,8 +161,8 @@ struct CellPngDecOutParam
be_t<u32> outputHeight; be_t<u32> outputHeight;
be_t<u32> outputComponents; be_t<u32> outputComponents;
be_t<u32> outputBitDepth; be_t<u32> outputBitDepth;
be_t<CellPngDecOutputMode> outputMode; be_t<s32> outputMode; // CellPngDecOutputMode
be_t<CellPngDecColorSpace> outputColorSpace; be_t<s32> outputColorSpace; // CellPngDecOutputMode
be_t<u32> useMemorySpace; be_t<u32> useMemorySpace;
}; };
@ -179,14 +176,17 @@ struct CellPngDecDataOutInfo
be_t<u32> chunkInformation; be_t<u32> chunkInformation;
be_t<u32> numText; be_t<u32> numText;
be_t<u32> numUnknownChunk; be_t<u32> numUnknownChunk;
be_t<CellPngDecDecodeStatus> status; be_t<s32> status; // CellPngDecDecodeStatus
}; };
// Functions // Functions
s32 cellPngDecCreate(vm::ptr<u32> mainHandle, vm::ptr<const CellPngDecThreadInParam> threadInParam, vm::ptr<CellPngDecThreadOutParam> threadOutParam); s32 cellPngDecCreate(
vm::ptr<CellPngDecMainHandle> mainHandle,
vm::ptr<const CellPngDecThreadInParam> threadInParam,
vm::ptr<CellPngDecThreadOutParam> threadOutParam);
s32 cellPngDecExtCreate( s32 cellPngDecExtCreate(
vm::ptr<u32> mainHandle, vm::ptr<CellPngDecMainHandle> mainHandle,
vm::ptr<const CellPngDecThreadInParam> threadInParam, vm::ptr<const CellPngDecThreadInParam> threadInParam,
vm::ptr<CellPngDecThreadOutParam> threadOutParam, vm::ptr<CellPngDecThreadOutParam> threadOutParam,
vm::ptr<const CellPngDecExtThreadInParam> extThreadInParam, vm::ptr<const CellPngDecExtThreadInParam> extThreadInParam,
@ -194,11 +194,14 @@ s32 cellPngDecExtCreate(
s32 cellPngDecOpen( s32 cellPngDecOpen(
CellPngDecMainHandle mainHandle, CellPngDecMainHandle mainHandle,
vm::ptr<u32> subHandle, vm::ptr<CellPngDecSubHandle> subHandle,
vm::ptr<const CellPngDecSrc> src, vm::ptr<const CellPngDecSrc> src,
vm::ptr<CellPngDecOpnInfo> openInfo); vm::ptr<CellPngDecOpnInfo> openInfo);
s32 cellPngDecReadHeader(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr<CellPngDecInfo> info); s32 cellPngDecReadHeader(
CellPngDecMainHandle mainHandle,
CellPngDecSubHandle subHandle,
vm::ptr<CellPngDecInfo> info);
s32 cellPngDecSetParameter( s32 cellPngDecSetParameter(
CellPngDecMainHandle mainHandle, CellPngDecMainHandle mainHandle,
@ -217,11 +220,123 @@ s32 cellPngDecClose(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHand
s32 cellPngDecDestroy(CellPngDecMainHandle mainHandle); s32 cellPngDecDestroy(CellPngDecMainHandle mainHandle);
s32 cellPngDecGetTextChunk( // Defines for decoding partial streams
enum CellPngDecBufferMode : s32
{
CELL_PNGDEC_LINE_MODE = 1,
};
enum CellPngDecSpuMode : s32
{
CELL_PNGDEC_RECEIVE_EVENT = 0,
CELL_PNGDEC_TRYRECEIVE_EVENT = 1,
};
// Structs for decoding partial streams
struct CellPngDecStrmInfo
{
be_t<u32> decodedStrmSize;
};
struct CellPngDecStrmParam
{
vm::bptr<void> strmPtr;
be_t<u32> strmSize;
};
struct CellPngDecDispInfo
{
be_t<u64> outputFrameWidthByte;
be_t<u32> outputFrameHeight;
be_t<u64> outputStartXByte;
be_t<u32> outputStartY;
be_t<u64> outputWidthByte;
be_t<u32> outputHeight;
be_t<u32> outputBitDepth;
be_t<u32> outputComponents;
be_t<u32> nextOutputStartY;
be_t<u32> scanPassCount;
vm::bptr<void> outputImage;
};
struct CellPngDecDispParam
{
vm::bptr<void> nextOutputImage;
};
struct CellPngDecOpnParam
{
be_t<u32> selectChunk;
};
struct CellPngDecExtInfo
{
be_t<u64> reserved;
};
struct CellPngDecExtInParam
{
be_t<s32> bufferMode; // CellPngDecBufferMode
be_t<u32> outputCounts;
be_t<s32> spuMode; // CellPngDecSpuMode
};
struct CellPngDecExtOutParam
{
be_t<u64> outputWidthByte;
be_t<u32> outputHeight;
};
// Callbacks for decoding partial streams
typedef s32(CellPngDecCbControlStream)(vm::ptr<CellPngDecStrmInfo> strmInfo, vm::ptr<CellPngDecStrmParam> strmParam, vm::ptr<void> cbCtrlStrmArg);
typedef s32(CellPngDecCbControlDisp)(vm::ptr<CellPngDecDispInfo> dispInfo, vm::ptr<CellPngDecDispParam> dispParam, vm::ptr<void> cbCtrlDispArg);
struct CellPngDecCbCtrlStrm
{
vm::bptr<CellPngDecCbControlStream> cbCtrlStrmFunc;
vm::bptr<void> cbCtrlStrmArg;
};
struct CellPngDecCbCtrlDisp
{
vm::bptr<CellPngDecCbControlDisp> cbCtrlDispFunc;
vm::bptr<void> cbCtrlDispArg;
};
// Functions for decoding partial streams
s32 cellPngDecExtOpen(
CellPngDecMainHandle mainHandle,
vm::ptr<CellPngDecSubHandle> subHandle,
vm::ptr<const CellPngDecSrc> src,
vm::ptr<CellPngDecOpnInfo> openInfo,
vm::ptr<const CellPngDecCbCtrlStrm> cbCtrlStrm,
vm::ptr<const CellPngDecOpnParam> opnParam);
s32 cellPngDecExtReadHeader(
CellPngDecMainHandle mainHandle, CellPngDecMainHandle mainHandle,
CellPngDecSubHandle subHandle, CellPngDecSubHandle subHandle,
vm::ptr<u32> textInfoNum, vm::ptr<CellPngDecInfo> info,
vm::ptr<vm::bptr<CellPngTextInfo>> textInfo); vm::ptr<CellPngDecExtInfo> extInfo);
s32 cellPngDecExtSetParameter(
CellPngDecMainHandle mainHandle,
CellPngDecSubHandle subHandle,
vm::ptr<const CellPngDecInParam> inParam,
vm::ptr<CellPngDecOutParam> outParam,
vm::ptr<const CellPngDecExtInParam> extInParam,
vm::ptr<CellPngDecExtOutParam> extOutParam);
s32 cellPngDecExtDecodeData(
CellPngDecMainHandle mainHandle,
CellPngDecSubHandle subHandle,
vm::ptr<u8> data,
vm::ptr<const CellPngDecDataCtrlParam> dataCtrlParam,
vm::ptr<CellPngDecDataOutInfo> dataOutInfo,
vm::ptr<const CellPngDecCbCtrlDisp> cbCtrlDisp,
vm::ptr<CellPngDecDispParam> dispParam);
// Functions for accessing ancillary chunks
s32 cellPngDecGetTextChunk(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr<u32> textInfoNum, vm::ptr<vm::bptr<CellPngTextInfo>> textInfo);
s32 cellPngDecGetPLTE(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr<CellPngPLTE> plte); s32 cellPngDecGetPLTE(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr<CellPngPLTE> plte);
@ -253,128 +368,7 @@ s32 cellPngDecGetcHRM(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHa
s32 cellPngDecGetpCAL(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr<CellPngPCAL> pcal); s32 cellPngDecGetpCAL(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr<CellPngPCAL> pcal);
s32 cellPngDecGetUnknownChunks( s32 cellPngDecGetUnknownChunks(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr<vm::bptr<CellPngUnknownChunk>> unknownChunk, vm::ptr<u32> unknownChunkNumber);
CellPngDecMainHandle mainHandle,
CellPngDecSubHandle subHandle,
vm::ptr<vm::bptr<CellPngUnknownChunk>> unknownChunk,
vm::ptr<u32> unknownChunkNumber);
enum CellPngDecBufferMode
{
CELL_PNGDEC_LINE_MODE = 1,
};
enum CellPngDecSpuMode
{
CELL_PNGDEC_RECEIVE_EVENT = 0,
CELL_PNGDEC_TRYRECEIVE_EVENT = 1,
};
// Structs
struct CellPngDecStrmInfo
{
be_t<u32> decodedStrmSize;
};
struct CellPngDecStrmParam
{
vm::bptr<void> strmPtr;
be_t<u32> strmSize;
};
typedef s32(CellPngDecCbControlStream)(vm::ptr<CellPngDecStrmInfo> strmInfo, vm::ptr<CellPngDecStrmParam> strmParam, vm::ptr<void> cbCtrlStrmArg);
struct CellPngDecDispInfo
{
be_t<u64> outputFrameWidthByte;
be_t<u32> outputFrameHeight;
be_t<u64> outputStartXByte;
be_t<u32> outputStartY;
be_t<u64> outputWidthByte;
be_t<u32> outputHeight;
be_t<u32> outputBitDepth;
be_t<u32> outputComponents;
be_t<u32> nextOutputStartY;
be_t<u32> scanPassCount;
vm::bptr<void> outputImage;
};
struct CellPngDecDispParam
{
vm::bptr<void> nextOutputImage;
};
// Callback
typedef s32(CellPngDecCbControlDisp)(vm::ptr<CellPngDecDispInfo> dispInfo, vm::ptr<CellPngDecDispParam> dispParam, vm::ptr<void> cbCtrlDispArg);
// Structs
struct CellPngDecOpnParam
{
be_t<u32> selectChunk;
};
struct CellPngDecCbCtrlStrm
{
vm::bptr<CellPngDecCbControlStream> cbCtrlStrmFunc;
be_t<vm::ptr<void>> cbCtrlStrmArg;
};
struct CellPngDecExtInfo
{
be_t<u64> reserved;
};
struct CellPngDecExtInParam
{
be_t<CellPngDecBufferMode> bufferMode;
be_t<u32> outputCounts;
be_t<CellPngDecSpuMode> spuMode;
};
struct CellPngDecExtOutParam
{
be_t<u64> outputWidthByte;
be_t<u32> outputHeight;
};
struct CellPngDecCbCtrlDisp
{
vm::bptr<CellPngDecCbControlDisp> cbCtrlDispFunc;
be_t<vm::ptr<void>> cbCtrlDispArg;
};
// Functions
s32 cellPngDecExtOpen(
CellPngDecMainHandle mainHandle,
vm::ptr<u32> subHandle,
vm::ptr<const CellPngDecSrc> src,
vm::ptr<CellPngDecOpnInfo> openInfo,
vm::ptr<const CellPngDecCbCtrlStrm> cbCtrlStrm,
vm::ptr<const CellPngDecOpnParam> opnParam);
s32 cellPngDecExtReadHeader(
CellPngDecMainHandle mainHandle,
CellPngDecSubHandle subHandle,
vm::ptr<CellPngDecInfo> info,
vm::ptr<CellPngDecExtInfo> extInfo);
s32 cellPngDecExtSetParameter(
CellPngDecMainHandle mainHandle,
CellPngDecSubHandle subHandle,
vm::ptr<const CellPngDecInParam> inParam,
vm::ptr<CellPngDecOutParam> outParam,
vm::ptr<const CellPngDecExtInParam> extInParam,
vm::ptr<CellPngDecExtOutParam> extOutParam);
s32 cellPngDecExtDecodeData(
CellPngDecMainHandle mainHandle,
CellPngDecSubHandle subHandle,
vm::ptr<u8> data,
vm::ptr<const CellPngDecDataCtrlParam> dataCtrlParam,
vm::ptr<CellPngDecDataOutInfo> dataOutInfo,
vm::ptr<const CellPngDecCbCtrlDisp> cbCtrlDisp,
vm::ptr<CellPngDecDispParam> dispParam);
// Custom structs // Custom structs
struct PngDecoder struct PngDecoder

View file

@ -24,8 +24,6 @@ enum
CELL_SEARCH_ERROR_GENERIC = 0x8002C8FF, CELL_SEARCH_ERROR_GENERIC = 0x8002C8FF,
}; };
typedef be_t<s32> CellSearchId;
// Constants // Constants
enum enum
{ {
@ -173,7 +171,7 @@ struct CellSearchContentId
struct CellSearchResultParam struct CellSearchResultParam
{ {
be_t<CellSearchId> searchId; be_t<s32> searchId;
be_t<u32> resultNum; be_t<u32> resultNum;
}; };
@ -271,7 +269,7 @@ struct CellSearchVideoSceneInfo
be_t<CellSearchSceneType> sceneType; be_t<CellSearchSceneType> sceneType;
be_t<s64> startTime_ms; be_t<s64> startTime_ms;
be_t<s64> endTime_ms; be_t<s64> endTime_ms;
be_t<CellSearchContentId> videoId; CellSearchContentId videoId;
char title[CELL_SEARCH_TITLE_LEN_MAX + 1]; char title[CELL_SEARCH_TITLE_LEN_MAX + 1];
char reserved[3]; char reserved[3];
char tags[CELL_SEARCH_TAG_NUM_MAX][CELL_SEARCH_TAG_LEN_MAX]; char tags[CELL_SEARCH_TAG_NUM_MAX][CELL_SEARCH_TAG_LEN_MAX];

View file

@ -872,8 +872,8 @@ struct CellSpursTaskInfo
const be_t<u32> eaElf_addr; //void *eaElf const be_t<u32> eaElf_addr; //void *eaElf
const be_t<u32> eaContext_addr; //void *eaContext const be_t<u32> eaContext_addr; //void *eaContext
be_t<u32> sizeContext; be_t<u32> sizeContext;
be_t<u8> state; u8 state;
be_t<u8> hasSignal; u8 hasSignal;
const be_t<u32> CellSpursTaskExitCode_addr; const be_t<u32> CellSpursTaskExitCode_addr;
u8 guid[8]; u8 guid[8];
//be_t<u8> reserved[]; //be_t<u8> reserved[];

View file

@ -368,7 +368,7 @@ int cellSurMixerCreate(vm::ptr<const CellSurMixerConfig> config)
for (auto& p : ssp) if (p.m_active && p.m_created) for (auto& p : ssp) if (p.m_active && p.m_created)
{ {
auto v = vm::lptrl<s16>::make(p.m_addr); // 16-bit LE audio data auto v = vm::ptrl<s16>::make(p.m_addr); // 16-bit LE audio data
float left = 0.0f; float left = 0.0f;
float right = 0.0f; float right = 0.0f;
float speed = fabs(p.m_speed); float speed = fabs(p.m_speed);

View file

@ -108,8 +108,7 @@ enum
}; };
// Request handle for clan API // Request handle for clan API
struct SceNpClansRequest; using SceNpClansRequestHandle = vm::ptr<struct SceNpClansRequest>;
typedef vm::ptr<SceNpClansRequest> SceNpClansRequestHandle;
// Paging request structure // Paging request structure
struct SceNpClansPagingRequest struct SceNpClansPagingRequest

View file

@ -897,9 +897,20 @@ s32 sys_raw_spu_image_load(s32 id, vm::ptr<sys_spu_image> img)
sysPrxForUser.Warning("sys_raw_spu_image_load(id=%d, img=*0x%x)", id, img); sysPrxForUser.Warning("sys_raw_spu_image_load(id=%d, img=*0x%x)", id, img);
// TODO: use segment info // TODO: use segment info
const auto stamp0 = get_system_time();
memcpy(vm::get_ptr<void>(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * id), vm::get_ptr<void>(img->addr), 256 * 1024); memcpy(vm::get_ptr<void>(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * id), vm::get_ptr<void>(img->addr), 256 * 1024);
const auto stamp1 = get_system_time();
vm::write32(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * id + RAW_SPU_PROB_OFFSET + SPU_NPC_offs, img->entry_point | be_t<u32>::make(1)); vm::write32(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * id + RAW_SPU_PROB_OFFSET + SPU_NPC_offs, img->entry_point | be_t<u32>::make(1));
const auto stamp2 = get_system_time();
LOG_ERROR(GENERAL, "memcpy() latency: %lldus", (stamp1 - stamp0));
LOG_ERROR(GENERAL, "MMIO latency: %lldus", (stamp2 - stamp1));
return CELL_OK; return CELL_OK;
} }

View file

@ -136,7 +136,7 @@ namespace ppu_func_detail
template <typename RT, typename F, typename Tuple> template <typename RT, typename F, typename Tuple>
force_inline RT call(F f, Tuple && t) force_inline RT call(F f, Tuple && t)
{ {
typedef typename std::decay<Tuple>::type ttype; using ttype = std::decay_t<Tuple>;
return ppu_func_detail::call_impl<RT, F, Tuple, 0 == std::tuple_size<ttype>::value, std::tuple_size<ttype>::value>::call(f, std::forward<Tuple>(t)); return ppu_func_detail::call_impl<RT, F, Tuple, 0 == std::tuple_size<ttype>::value, std::tuple_size<ttype>::value>::call(f, std::forward<Tuple>(t));
} }