#pragma once class CPUThread; namespace vm { template class _ptr_base { AT m_addr; public: typedef typename std::remove_cv::type type; static const u32 address_size = sizeof(AT); _ptr_base operator++ (int) { AT result = m_addr; m_addr += address_size; return make(result); } _ptr_base& operator++ () { m_addr += address_size; return *this; } _ptr_base operator-- (int) { AT result = m_addr; m_addr -= address_size; return make(result); } _ptr_base& operator-- () { m_addr -= address_size; return *this; } _ptr_base& operator += (AT count) { m_addr += count * address_size; return *this; } _ptr_base& operator -= (AT count) { m_addr -= count * address_size; return *this; } _ptr_base operator + (typename remove_be_t::type count) const { return make(m_addr + count * address_size); } _ptr_base operator + (typename to_be_t::type count) const { return make(m_addr + count * address_size); } _ptr_base operator - (typename remove_be_t::type count) const { return make(m_addr - count * address_size); } _ptr_base operator - (typename to_be_t::type count) const { return make(m_addr - count * address_size); } __forceinline bool operator <(const _ptr_base& right) const { return m_addr < right.m_addr; } __forceinline bool operator <=(const _ptr_base& right) const { return m_addr <= right.m_addr; } __forceinline bool operator >(const _ptr_base& right) const { return m_addr > right.m_addr; } __forceinline bool operator >=(const _ptr_base& right) const { return m_addr >= right.m_addr; } __forceinline bool operator ==(const _ptr_base& right) const { return m_addr == right.m_addr; } __forceinline bool operator !=(const _ptr_base& right) const { return m_addr != right.m_addr; } __forceinline bool operator ==(const nullptr_t& right) const { return m_addr == 0; } __forceinline bool operator !=(const nullptr_t& right) const { return m_addr != 0; } explicit operator bool() const { return m_addr != 0; } __forceinline _ptr_base::value, typename to_be_t::type, AT>>& operator *() const { return vm::get_ref<_ptr_base::value, typename to_be_t::type, AT>>>(vm::cast(m_addr)); } __forceinline _ptr_base::value, typename to_be_t::type, AT>>& operator [](AT index) const { return vm::get_ref<_ptr_base::value, typename to_be_t::type, AT>>>(vm::cast(m_addr + sizeof(AT)* index)); } template operator const _ptr_base() const { const AT2 addr = convert_le_be(m_addr); return reinterpret_cast&>(addr); } AT addr() const { return m_addr; } void set(const AT value) { m_addr = value; } static const _ptr_base make(const AT& addr) { return reinterpret_cast(addr); } _ptr_base& operator = (const _ptr_base& right) = default; }; template class _ptr_base { AT m_addr; public: typedef typename std::remove_cv::type type; static const u32 data_size = sizeof(T); __forceinline T* const operator -> () const { return vm::get_ptr(vm::cast(m_addr)); } _ptr_base operator++ (int) { AT result = m_addr; m_addr += data_size; return make(result); } _ptr_base& operator++ () { m_addr += data_size; return *this; } _ptr_base operator-- (int) { AT result = m_addr; m_addr -= data_size; return make(result); } _ptr_base& operator-- () { m_addr -= data_size; return *this; } _ptr_base& operator += (AT count) { m_addr += count * data_size; return *this; } _ptr_base& operator -= (AT count) { m_addr -= count * data_size; return *this; } _ptr_base operator + (typename remove_be_t::type count) const { return make(m_addr + count * data_size); } _ptr_base operator + (typename to_be_t::type count) const { return make(m_addr + count * data_size); } _ptr_base operator - (typename remove_be_t::type count) const { return make(m_addr - count * data_size); } _ptr_base operator - (typename to_be_t::type count) const { return make(m_addr - count * data_size); } __forceinline T& operator *() const { return vm::get_ref(vm::cast(m_addr)); } __forceinline T& operator [](typename remove_be_t::type index) const { return vm::get_ref(vm::cast(m_addr + data_size * index)); } __forceinline T& operator [](typename to_be_t::forced_type index) const { return vm::get_ref(vm::cast(m_addr + data_size * index)); } __forceinline bool operator <(const _ptr_base& right) const { return m_addr < right.m_addr; } __forceinline bool operator <=(const _ptr_base& right) const { return m_addr <= right.m_addr; } __forceinline bool operator >(const _ptr_base& right) const { return m_addr > right.m_addr; } __forceinline bool operator >=(const _ptr_base& right) const { return m_addr >= right.m_addr; } __forceinline bool operator ==(const _ptr_base& right) const { return m_addr == right.m_addr; } __forceinline bool operator !=(const _ptr_base& right) const { return m_addr != right.m_addr; } __forceinline bool operator ==(const nullptr_t& right) const { return m_addr == 0; } __forceinline bool operator !=(const nullptr_t& right) const { return m_addr != 0; } explicit operator bool() const { return m_addr != 0; } explicit operator T*() const { return get_ptr(); } AT addr() const { return m_addr; } template void set(U&& value) { m_addr = convert_le_be(value); } template operator const _ptr_base() const { const AT2 addr = convert_le_be(m_addr); return reinterpret_cast&>(addr); } T* get_ptr() const { return vm::get_ptr(vm::cast(m_addr)); } static const _ptr_base make(const AT& addr) { return reinterpret_cast(addr); } _ptr_base& operator = (const _ptr_base& right) = default; }; template class _ptr_base { AT m_addr; public: AT addr() const { return m_addr; } void set(const AT value) { m_addr = value; } void* get_ptr() const { return vm::get_ptr(vm::cast(m_addr)); } explicit operator void*() const { return get_ptr(); } __forceinline bool operator <(const _ptr_base& right) const { return m_addr < right.m_addr; } __forceinline bool operator <=(const _ptr_base& right) const { return m_addr <= right.m_addr; } __forceinline bool operator >(const _ptr_base& right) const { return m_addr > right.m_addr; } __forceinline bool operator >=(const _ptr_base& right) const { return m_addr >= right.m_addr; } __forceinline bool operator ==(const _ptr_base& right) const { return m_addr == right.m_addr; } __forceinline bool operator !=(const _ptr_base& right) const { return m_addr != right.m_addr; } __forceinline bool operator ==(const nullptr_t& right) const { return m_addr == 0; } __forceinline bool operator !=(const nullptr_t& right) const { return m_addr != 0; } explicit operator bool() const { return m_addr != 0; } template operator const _ptr_base() const { const AT2 addr = convert_le_be(m_addr); return reinterpret_cast&>(addr); } template operator const _ptr_base() const { const AT2 addr = convert_le_be(m_addr); return reinterpret_cast&>(addr); } static const _ptr_base make(const AT& addr) { return reinterpret_cast(addr); } _ptr_base& operator = (const _ptr_base& right) = default; }; template class _ptr_base { AT m_addr; public: AT addr() const { return m_addr; } void set(const AT value) { m_addr = value; } const void* get_ptr() const { return vm::get_ptr(vm::cast(m_addr)); } explicit operator const void*() const { return get_ptr(); } __forceinline bool operator <(const _ptr_base& right) const { return m_addr < right.m_addr; } __forceinline bool operator <=(const _ptr_base& right) const { return m_addr <= right.m_addr; } __forceinline bool operator >(const _ptr_base& right) const { return m_addr > right.m_addr; } __forceinline bool operator >=(const _ptr_base& right) const { return m_addr >= right.m_addr; } __forceinline bool operator ==(const _ptr_base& right) const { return m_addr == right.m_addr; } __forceinline bool operator !=(const _ptr_base& right) const { return m_addr != right.m_addr; } __forceinline bool operator ==(const nullptr_t& right) const { return m_addr == 0; } __forceinline bool operator !=(const nullptr_t& right) const { return m_addr != 0; } explicit operator bool() const { return m_addr != 0; } template operator const _ptr_base() const { const AT2 addr = convert_le_be(m_addr); return reinterpret_cast&>(addr); } static const _ptr_base make(const AT& addr) { return reinterpret_cast(addr); } _ptr_base& operator = (const _ptr_base& right) = default; }; template class _ptr_base { AT m_addr; public: typedef RT(*type)(T...); RT operator()(CPUThread& CPU, T... args) const; // defined in CB_FUNC.h, call using specified CPU thread context RT operator()(T... args) const; // defined in CB_FUNC.h, call using current CPU thread context AT addr() const { return m_addr; } void set(const AT value) { m_addr = value; } __forceinline bool operator <(const _ptr_base& right) const { return m_addr < right.m_addr; } __forceinline bool operator <=(const _ptr_base& right) const { return m_addr <= right.m_addr; } __forceinline bool operator >(const _ptr_base& right) const { return m_addr > right.m_addr; } __forceinline bool operator >=(const _ptr_base& right) const { return m_addr >= right.m_addr; } __forceinline bool operator ==(const _ptr_base& right) const { return m_addr == right.m_addr; } __forceinline bool operator !=(const _ptr_base& right) const { return m_addr != right.m_addr; } __forceinline bool operator ==(const nullptr_t& right) const { return m_addr == 0; } __forceinline bool operator !=(const nullptr_t& right) const { return m_addr != 0; } explicit operator bool() const { return m_addr != 0; } template operator const _ptr_base() const { const AT2 addr = convert_le_be(m_addr); return reinterpret_cast&>(addr); } static const _ptr_base make(const AT& addr) { return reinterpret_cast(addr); } operator const std::function() const { const AT addr = convert_le_be(m_addr); return [addr](T... args) -> RT { return make(addr)(args...); }; } _ptr_base& operator = (const _ptr_base& right) = default; }; //BE pointer to LE data template struct bptrl : public _ptr_base::type> { static const bptrl make(AT addr) { auto res = _ptr_base::type>::make(convert_le_be::type>(addr)); return static_cast(res); } using _ptr_base::type>::operator=; }; //BE pointer to BE data template struct bptrb : public _ptr_base::type, lvl, typename to_be_t::type> { static const bptrb make(AT addr) { auto res = _ptr_base::type, lvl, typename to_be_t::type>::make(convert_le_be::type>(addr)); return static_cast(res); } using _ptr_base::type, lvl, typename to_be_t::type>::operator=; }; //LE pointer to BE data template struct lptrb : public _ptr_base::type, lvl, AT> { static const lptrb make(AT addr) { auto res = _ptr_base::type, lvl, AT>::make(addr); return static_cast(res); } using _ptr_base::type, lvl, AT>::operator=; }; //LE pointer to LE data template struct lptrl : public _ptr_base { static const lptrl make(AT addr) { auto res = _ptr_base::make(addr); return static_cast(res); } using _ptr_base::operator=; }; namespace ps3 { template struct ptr; template struct bptr; //default pointer for HLE functions (LE pointer to BE data) template struct ptr : public lptrb { static const ptr make(AT addr) { auto res = lptrb::make(addr); return static_cast(res); } vm::ps3::bptr to_be() const { return vm::ps3::bptr::make(this->addr()); } using lptrb::operator=; }; //default pointer for HLE structures (BE pointer to BE data) template struct bptr : public bptrb { static const bptr make(AT addr) { auto res = bptrb::make(addr); return static_cast(res); } vm::ps3::ptr to_le() const { return vm::ps3::ptr::make(this->addr()); } using bptrb::operator=; }; } namespace psv { //default pointer for HLE functions & structures (LE pointer to LE data) template struct ptr : public lptrl { static const ptr make(AT addr) { auto res = lptrl::make(addr); return static_cast(res); } using lptrl::operator=; }; } //PS3 emulation is main now, so lets it be as default using namespace ps3; } namespace fmt { // external specializations for fmt::format function template struct unveil, false> { typedef typename unveil::result_type result_type; __forceinline static result_type get_value(const vm::ps3::ptr& arg) { return unveil::get_value(arg.addr()); } }; template struct unveil, false> { typedef typename unveil::result_type result_type; __forceinline static result_type get_value(const vm::ps3::bptr& arg) { return unveil::get_value(arg.addr()); } }; template struct unveil, false> { typedef typename unveil::result_type result_type; __forceinline static result_type get_value(const vm::psv::ptr& arg) { return unveil::get_value(arg.addr()); } }; } // external specializations for PPU GPR (SC_FUNC.h, CB_FUNC.h) template struct cast_ppu_gpr; template struct cast_ppu_gpr, false> { __forceinline static u64 to_gpr(const vm::ps3::ptr& value) { return value.addr(); } __forceinline static vm::ps3::ptr from_gpr(const u64 reg) { return vm::ps3::ptr::make(cast_ppu_gpr::value>::from_gpr(reg)); } }; // external specializations for ARMv7 GPR template struct cast_armv7_gpr; template struct cast_armv7_gpr, false> { __forceinline static u32 to_gpr(const vm::psv::ptr& value) { return value.addr(); } __forceinline static vm::psv::ptr from_gpr(const u32 reg) { return vm::psv::ptr::make(cast_armv7_gpr::value>::from_gpr(reg)); } };