#pragma once namespace vm { template class _ptr_base { AT m_addr; public: typedef T type; _ptr_base operator++ (int) { AT result = m_addr; m_addr += sizeof(AT); return make(result); } _ptr_base& operator++ () { m_addr += sizeof(AT); return *this; } _ptr_base operator-- (int) { AT result = m_addr; m_addr -= sizeof(AT); return make(result); } _ptr_base& operator-- () { m_addr -= sizeof(AT); return *this; } _ptr_base& operator += (int count) { m_addr += count * sizeof(AT); return *this; } _ptr_base& operator -= (int count) { m_addr -= count * sizeof(AT); return *this; } _ptr_base operator + (int count) const { return make(m_addr + count * sizeof(AT)); } _ptr_base operator - (int count) const { return make(m_addr - count * sizeof(AT)); } __forceinline _ptr_base& operator *() { return vm::get_ref<_ptr_base>(m_addr); } __forceinline const _ptr_base& operator *() const { return vm::get_ref>(m_addr); } __forceinline _ptr_base& operator [](int index) { return vm::get_ref<_ptr_base>(m_addr + sizeof(AT) * index); } __forceinline const _ptr_base& operator [](int index) const { return vm::get_ref>(m_addr + sizeof(AT) * index); } operator bool() const { return m_addr != 0; } AT addr() const { return m_addr; } static _ptr_base make(AT addr) { return (_ptr_base&)addr; } }; template class _ptr_base { AT m_addr; public: __forceinline T* const operator -> () { return vm::get_ptr(m_addr); } __forceinline const T* const operator -> () const { return vm::get_ptr(m_addr); } _ptr_base operator++ (int) { AT result = m_addr; m_addr += sizeof(T); return make(result); } _ptr_base& operator++ () { m_addr += sizeof(T); return *this; } _ptr_base operator-- (int) { AT result = m_addr; m_addr -= sizeof(T); return make(result); } _ptr_base& operator-- () { m_addr -= sizeof(T); return *this; } _ptr_base& operator += (int count) { m_addr += count * sizeof(T); return *this; } _ptr_base& operator -= (int count) { m_addr -= count * sizeof(T); return *this; } _ptr_base operator + (int count) const { return make(m_addr + count * sizeof(T)); } _ptr_base operator - (int count) const { return make(m_addr - count * sizeof(T)); } __forceinline T& operator *() { return get_ref(m_addr); } __forceinline const T& operator *() const { return get_ref(m_addr); } __forceinline T& operator [](int index) { return get_ref(m_addr + sizeof(T) * index); } __forceinline const T& operator [](int index) const { return get_ref(m_addr + sizeof(T) * index); } /* operator _ref_base() { return _ref_base::make(m_addr); } operator const _ref_base() const { return _ref_base::make(m_addr); } */ AT addr() const { return m_addr; } operator bool() const { return m_addr != 0; } T* const get_ptr() const { return vm::get_ptr(m_addr); } static _ptr_base make(AT addr) { return (_ptr_base&)addr; } }; template class _ptr_base { AT m_addr; public: AT addr() const { return m_addr; } void* const get_ptr() const { return vm::get_ptr(m_addr); } operator bool() const { return m_addr != 0; } static _ptr_base make(AT addr) { return (_ptr_base&)addr; } }; template class _ptr_base { AT m_addr; public: AT addr() const { return m_addr; } const void* const get_ptr() const { return vm::get_ptr(m_addr); } operator bool() const { return m_addr != 0; } static _ptr_base make(AT addr) { return (_ptr_base&)addr; } }; template class _ptr_base { AT m_addr; static_assert(!std::is_floating_point::value, "TODO: Unsupported callback result type (floating point)"); static_assert(!std::is_pointer::value, "Invalid callback result type (pointer)"); __forceinline RT call_func(bool is_async) const { Callback cb; cb.SetAddr(m_addr); return (RT)cb.Branch(!is_async); } public: typedef RT(*type)(); __forceinline RT operator()() const { return call_func(false); } __forceinline void async() const { call_func(true); } AT addr() const { return m_addr; } operator bool() const { return m_addr != 0; } static _ptr_base make(AT addr) { return (_ptr_base&)addr; } operator std::function() const { const AT addr = m_addr; return [addr]() -> RT { return make(addr)(); }; } }; template class _ptr_base { AT m_addr; static_assert(!std::is_floating_point::value, "TODO: Unsupported callback result type (floating point)"); static_assert(!std::is_pointer::value, "Invalid callback result type (pointer)"); template struct _func_arg { static_assert(!std::is_floating_point::value, "TODO: Unsupported callback argument type (floating point)"); static_assert(!std::is_pointer::value, "Invalid callback argument type (pointer)"); __forceinline static u64 get_value(const TT& arg) { u64 res = 0; (TT&)res = arg; return res; } }; __forceinline RT call_func(bool is_async, T... args) const { Callback cb; cb.SetAddr(m_addr); cb.Handle(_func_arg::get_value(args)...); return (RT)cb.Branch(!is_async); } public: typedef RT(*type)(T...); __forceinline RT operator()(T... args) const { return call_func(false, args...); } __forceinline void async(T... args) const { call_func(true, args...); } AT addr() const { return m_addr; } operator bool() const { return m_addr != 0; } static _ptr_base make(AT addr) { return (_ptr_base&)addr; } operator std::function() const { const AT addr = m_addr; return [addr](T... args) -> RT { return make(addr)(args...); }; } }; //BE pointer to LE data template struct bptrl : public _ptr_base::type> { static bptrl make(AT addr) { return (bptrl&)addr; } using _ptr_base::type>::operator=; }; //BE pointer to BE data template struct bptrb : public _ptr_base::type, lvl, typename to_be_t::type> { static bptrb make(AT addr) { return (bptrb&)addr; } 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 lptrb make(AT addr) { return (lptrb&)addr; } using _ptr_base::type, lvl, AT>::operator=; }; //LE pointer to LE data template struct lptrl : public _ptr_base { static lptrl make(AT addr) { return (lptrl&)addr; } using _ptr_base::operator=; }; namespace ps3 { //default pointer for HLE functions (LE ptrerence to BE data) template struct ptr : public lptrb { static ptr make(AT addr) { return (ptr&)addr; } using lptrb::operator=; }; //default pointer for HLE structures (BE ptrerence to BE data) template struct bptr : public bptrb { static bptr make(AT addr) { return (bptr&)addr; } using bptrb::operator=; }; } namespace psv { //default pointer for HLE functions & structures (LE ptrerence to LE data) template struct ptr : public lptrl { static ptr make(AT addr) { return (ptr&)addr; } using lptrl::operator=; }; } //PS3 emulation is main now, so lets it be as default using namespace ps3; }