mirror of
				https://github.com/hedge-dev/XenonRecomp.git
				synced 2025-10-30 07:11:38 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			409 lines
		
	
	
	
		
			9.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			409 lines
		
	
	
	
		
			9.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #pragma once
 | |
| #include <cstdint>
 | |
| #include <type_traits>
 | |
| #include <bit>
 | |
| #include <string>
 | |
| #include "byteswap.h"
 | |
| 
 | |
| #ifdef _WIN32
 | |
|     #include <windows.h>
 | |
| #endif
 | |
| 
 | |
| // real win32 handles will never use the upper bits unless something goes really wrong
 | |
| #define CHECK_GUEST_HANDLE(HANDLE) (((HANDLE) & 0x80000000) == 0x80000000)
 | |
| #define GUEST_HANDLE(HANDLE) ((HANDLE) | 0x80000000)
 | |
| #define HOST_HANDLE(HANDLE) ((HANDLE) & ~0x80000000)
 | |
| 
 | |
| // Return true to free the associated memory
 | |
| typedef bool(*TypeDestructor_t)(void*);
 | |
| 
 | |
| template<typename T>
 | |
| bool DestroyObject(void* obj)
 | |
| {
 | |
|     static_cast<T*>(obj)->~T();
 | |
|     return true;
 | |
| }
 | |
| 
 | |
| template<typename T>
 | |
| struct be
 | |
| {
 | |
|     T value;
 | |
| 
 | |
|     be() : value(0)
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     be(const T v)
 | |
|     {
 | |
|         set(v);
 | |
|     }
 | |
| 
 | |
|     static T byteswap(T value)
 | |
|     {
 | |
|         if constexpr (std::is_same_v<T, double>)
 | |
|         {
 | |
|             const uint64_t swapped = ByteSwap(*reinterpret_cast<uint64_t*>(&value));
 | |
|             return *reinterpret_cast<const T*>(&swapped);
 | |
|         }
 | |
|         else if constexpr (std::is_same_v<T, float>)
 | |
|         {
 | |
|             const uint32_t swapped = ByteSwap(*reinterpret_cast<uint32_t*>(&value));
 | |
|             return *reinterpret_cast<const T*>(&swapped);
 | |
|         }
 | |
|         else if constexpr (std::is_enum_v<T>)
 | |
|         {
 | |
|             const std::underlying_type_t<T> swapped = ByteSwap(*reinterpret_cast<std::underlying_type_t<T>*>(&value));
 | |
|             return *reinterpret_cast<const T*>(&swapped);
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             return ByteSwap(value);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     void set(const T v)
 | |
|     {
 | |
|         value = byteswap(v);
 | |
|     }
 | |
| 
 | |
|     T get() const
 | |
|     {
 | |
|         return byteswap(value);
 | |
|     }
 | |
| 
 | |
|     be& operator| (T value)
 | |
|     {
 | |
|         set(get() | value);
 | |
|         return *this;
 | |
|     }
 | |
| 
 | |
|     be& operator& (T value)
 | |
|     {
 | |
|         set(get() & value);
 | |
|         return *this;
 | |
|     }
 | |
| 
 | |
|     operator T() const
 | |
|     {
 | |
|         return get();
 | |
|     }
 | |
| 
 | |
|     be& operator=(T v)
 | |
|     {
 | |
|         set(v);
 | |
|         return *this;
 | |
|     }
 | |
| };
 | |
| 
 | |
| extern "C" void* MmGetHostAddress(uint32_t ptr);
 | |
| template<typename T>
 | |
| struct xpointer
 | |
| {
 | |
|     be<uint32_t> ptr;
 | |
| 
 | |
|     xpointer() : ptr(0)
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     xpointer(T* ptr) : ptr(reinterpret_cast<size_t>(ptr) - reinterpret_cast<size_t>(MmGetHostAddress(0)))
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     T* get() const
 | |
|     {
 | |
|         if (!ptr.value)
 | |
|         {
 | |
|             return nullptr;
 | |
|         }
 | |
| 
 | |
|         return reinterpret_cast<T*>(MmGetHostAddress(ptr));
 | |
|     }
 | |
| 
 | |
|     operator T* () const
 | |
|     {
 | |
|         return get();
 | |
|     }
 | |
| 
 | |
|     T* operator->() const
 | |
|     {
 | |
|         return get();
 | |
|     }
 | |
| };
 | |
| 
 | |
| template<typename TGuest>
 | |
| struct HostObject
 | |
| {
 | |
|     typedef TGuest guest_type;
 | |
| };
 | |
| 
 | |
| struct _XLIST_ENTRY;
 | |
| typedef _XLIST_ENTRY XLIST_ENTRY;
 | |
| typedef xpointer<XLIST_ENTRY> PXLIST_ENTRY;
 | |
| 
 | |
| typedef struct _IMAGE_CE_RUNTIME_FUNCTION
 | |
| {
 | |
|     uint32_t BeginAddress;
 | |
| 
 | |
|     union 
 | |
|     {
 | |
|         uint32_t Data;
 | |
|         struct
 | |
|         {
 | |
|             uint32_t PrologLength : 8;
 | |
|             uint32_t FunctionLength : 22;
 | |
|             uint32_t ThirtyTwoBit : 1;
 | |
|             uint32_t ExceptionFlag : 1;
 | |
|         };
 | |
|     };
 | |
| } IMAGE_CE_RUNTIME_FUNCTION;
 | |
| 
 | |
| static_assert(sizeof(IMAGE_CE_RUNTIME_FUNCTION) == 8);
 | |
| 
 | |
| typedef struct _XLIST_ENTRY
 | |
| {
 | |
|     be<uint32_t> Flink;
 | |
|     be<uint32_t> Blink;
 | |
| } XLIST_ENTRY;
 | |
| 
 | |
| typedef struct _XDISPATCHER_HEADER
 | |
| {
 | |
|     union
 | |
|     {
 | |
|         struct
 | |
|         {
 | |
|             uint8_t Type;
 | |
|             union
 | |
|             {
 | |
|                 uint8_t Abandoned;
 | |
|                 uint8_t Absolute;
 | |
|                 uint8_t NpxIrql;
 | |
|                 uint8_t Signalling;
 | |
|             };
 | |
|             union
 | |
|             {
 | |
|                 uint8_t Size;
 | |
|                 uint8_t Hand;
 | |
|             };
 | |
|             union
 | |
|             {
 | |
|                 uint8_t Inserted;
 | |
|                 uint8_t DebugActive;
 | |
|                 uint8_t DpcActive;
 | |
|             };
 | |
|         };
 | |
|         be<uint32_t> Lock;
 | |
|     };
 | |
| 
 | |
|     be<uint32_t> SignalState;
 | |
|     XLIST_ENTRY WaitListHead;
 | |
| } XDISPATCHER_HEADER, * XPDISPATCHER_HEADER;
 | |
| 
 | |
| // These variables are never accessed in guest code, we can safely use them in little endian
 | |
| typedef struct _XRTL_CRITICAL_SECTION
 | |
| {
 | |
|     XDISPATCHER_HEADER Header;
 | |
|     int32_t LockCount;
 | |
|     int32_t RecursionCount;
 | |
|     uint32_t OwningThread;
 | |
| } XRTL_CRITICAL_SECTION;
 | |
| 
 | |
| typedef struct _XANSI_STRING {
 | |
|     be<uint16_t> Length;
 | |
|     be<uint16_t> MaximumLength;
 | |
|     xpointer<char> Buffer;
 | |
| } XANSI_STRING;
 | |
| 
 | |
| typedef struct _XOBJECT_ATTRIBUTES
 | |
| {
 | |
|     be<uint32_t> RootDirectory;
 | |
|     xpointer<XANSI_STRING> Name;
 | |
|     xpointer<void> Attributes;
 | |
| } XOBJECT_ATTRIBUTES;
 | |
| 
 | |
| typedef XDISPATCHER_HEADER XKEVENT;
 | |
| 
 | |
| typedef struct _XIO_STATUS_BLOCK
 | |
| {
 | |
|     union {
 | |
|         be<uint32_t> Status;
 | |
|         be<uint32_t> Pointer;
 | |
|     };
 | |
|     be<uint32_t> Information;
 | |
| } XIO_STATUS_BLOCK;
 | |
| 
 | |
| typedef struct _XOVERLAPPED {
 | |
|     be<uint32_t> Internal;
 | |
|     be<uint32_t> InternalHigh;
 | |
|     be<uint32_t> Offset;
 | |
|     be<uint32_t> OffsetHigh;
 | |
|     be<uint32_t> hEvent;
 | |
| } XOVERLAPPED;
 | |
| 
 | |
| // this name is so dumb
 | |
| typedef struct _XXOVERLAPPED {
 | |
|     union
 | |
|     {
 | |
|         struct
 | |
|         {
 | |
|             be<uint32_t> Error;
 | |
|             be<uint32_t> Length;
 | |
|         };
 | |
| 
 | |
|         struct
 | |
|         {
 | |
|             uint32_t InternalLow;
 | |
|             uint32_t InternalHigh;
 | |
|         };
 | |
|     };
 | |
|     uint32_t InternalContext;
 | |
|     be<uint32_t> hEvent;
 | |
|     be<uint32_t> pCompletionRoutine;
 | |
|     be<uint32_t> dwCompletionContext;
 | |
|     be<uint32_t> dwExtendedError;
 | |
| } XXOVERLAPPED, *PXXOVERLAPPED;
 | |
| 
 | |
| static_assert(sizeof(_XXOVERLAPPED) == 0x1C);
 | |
| 
 | |
| // https://learn.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-memorystatus
 | |
| typedef struct _XMEMORYSTATUS {
 | |
|     be<uint32_t> dwLength;
 | |
|     be<uint32_t> dwMemoryLoad;
 | |
|     be<uint32_t> dwTotalPhys;
 | |
|     be<uint32_t> dwAvailPhys;
 | |
|     be<uint32_t> dwTotalPageFile;
 | |
|     be<uint32_t> dwAvailPageFile;
 | |
|     be<uint32_t> dwTotalVirtual;
 | |
|     be<uint32_t> dwAvailVirtual;
 | |
| } XMEMORYSTATUS, * XLPMEMORYSTATUS;
 | |
| 
 | |
| typedef struct _XVIDEO_MODE
 | |
| {
 | |
|     be<uint32_t> DisplayWidth;
 | |
|     be<uint32_t> DisplayHeight;
 | |
|     be<uint32_t> IsInterlaced;
 | |
|     be<uint32_t> IsWidescreen;
 | |
|     be<uint32_t> IsHighDefinition;
 | |
|     be<uint32_t> RefreshRate;
 | |
|     be<uint32_t> VideoStandard;
 | |
|     be<uint32_t> Unknown4A;
 | |
|     be<uint32_t> Unknown01;
 | |
|     be<uint32_t> reserved[3];
 | |
| } XVIDEO_MODE;
 | |
| 
 | |
| typedef struct _XKSEMAPHORE
 | |
| {
 | |
|     XDISPATCHER_HEADER Header;
 | |
|     be<uint32_t> Limit;
 | |
| } XKSEMAPHORE;
 | |
| 
 | |
| typedef struct _XUSER_SIGNIN_INFO {
 | |
|     be<uint64_t> xuid;
 | |
|     be<uint32_t> dwField08;
 | |
|     be<uint32_t> SigninState;
 | |
|     be<uint32_t> dwField10;
 | |
|     be<uint32_t> dwField14;
 | |
|     char Name[16];
 | |
| } XUSER_SIGNIN_INFO;
 | |
| 
 | |
| typedef struct _XTIME_FIELDS
 | |
| {
 | |
|     be<uint16_t> Year;
 | |
|     be<uint16_t> Month;
 | |
|     be<uint16_t> Day;
 | |
|     be<uint16_t> Hour;
 | |
|     be<uint16_t> Minute;
 | |
|     be<uint16_t> Second;
 | |
|     be<uint16_t> Milliseconds;
 | |
|     be<uint16_t> Weekday;
 | |
| } XTIME_FIELDS, * PXTIME_FIELDS;
 | |
| 
 | |
| // Content types
 | |
| #define XCONTENTTYPE_SAVEDATA 1
 | |
| #define XCONTENTTYPE_DLC      2
 | |
| #define XCONTENTTYPE_RESERVED 3
 | |
| 
 | |
| #define XCONTENT_NEW      1
 | |
| #define XCONTENT_EXISTING 2
 | |
| 
 | |
| #define XCONTENT_MAX_DISPLAYNAME 128
 | |
| #define XCONTENT_MAX_FILENAME    42
 | |
| #define XCONTENTDEVICE_MAX_NAME  27
 | |
| 
 | |
| typedef struct _XCONTENT_DATA
 | |
| {
 | |
|     be<uint32_t> DeviceID;
 | |
|     be<uint32_t> dwContentType;
 | |
|     be<uint16_t> szDisplayName[XCONTENT_MAX_DISPLAYNAME];
 | |
|     char szFileName[XCONTENT_MAX_FILENAME];
 | |
| } XCONTENT_DATA, * PXCONTENT_DATA;
 | |
| 
 | |
| typedef struct _XHOSTCONTENT_DATA : _XCONTENT_DATA
 | |
| {
 | |
|     // This is a host exclusive type so we don't care what goes on
 | |
|     std::string szRoot{};
 | |
| } XHOSTCONTENT_DATA, *PXHOSTCONTENT_DATA;
 | |
| 
 | |
| 
 | |
| #define XCONTENTDEVICETYPE_HDD 1
 | |
| #define XCONTENTDEVICETYPE_MU 2
 | |
| 
 | |
| typedef struct _XDEVICE_DATA
 | |
| {
 | |
|     be<uint32_t> DeviceID;
 | |
|     be<uint32_t> DeviceType;
 | |
|     be<uint64_t> ulDeviceBytes;
 | |
|     be<uint64_t> ulDeviceFreeBytes;
 | |
|     be<uint16_t> wszName[XCONTENTDEVICE_MAX_NAME];
 | |
| } XDEVICE_DATA, *PXDEVICE_DATA;
 | |
| 
 | |
| // Direct reflection of XInput structures
 | |
| 
 | |
| #define XAMINPUT_DEVTYPE_GAMEPAD          0x01
 | |
| #define XAMINPUT_DEVSUBTYPE_GAMEPAD       0x01
 | |
| 
 | |
| #define XAMINPUT_GAMEPAD_DPAD_UP          0x0001
 | |
| #define XAMINPUT_GAMEPAD_DPAD_DOWN        0x0002
 | |
| #define XAMINPUT_GAMEPAD_DPAD_LEFT        0x0004
 | |
| #define XAMINPUT_GAMEPAD_DPAD_RIGHT       0x0008
 | |
| #define XAMINPUT_GAMEPAD_START            0x0010
 | |
| #define XAMINPUT_GAMEPAD_BACK             0x0020
 | |
| #define XAMINPUT_GAMEPAD_LEFT_THUMB       0x0040
 | |
| #define XAMINPUT_GAMEPAD_RIGHT_THUMB      0x0080
 | |
| #define XAMINPUT_GAMEPAD_LEFT_SHOULDER    0x0100
 | |
| #define XAMINPUT_GAMEPAD_RIGHT_SHOULDER   0x0200
 | |
| #define XAMINPUT_GAMEPAD_A                0x1000
 | |
| #define XAMINPUT_GAMEPAD_B                0x2000
 | |
| #define XAMINPUT_GAMEPAD_X                0x4000
 | |
| #define XAMINPUT_GAMEPAD_Y                0x8000
 | |
| 
 | |
| typedef struct _XAMINPUT_GAMEPAD
 | |
| {
 | |
|     uint16_t                            wButtons;
 | |
|     uint8_t                             bLeftTrigger;
 | |
|     uint8_t                             bRightTrigger;
 | |
|     int16_t                             sThumbLX;
 | |
|     int16_t                             sThumbLY;
 | |
|     int16_t                             sThumbRX;
 | |
|     int16_t                             sThumbRY;
 | |
| } XAMINPUT_GAMEPAD, *PXAMINPUT_GAMEPAD;
 | |
| 
 | |
| typedef struct _XAMINPUT_VIBRATION
 | |
| {
 | |
|     uint16_t                            wLeftMotorSpeed;
 | |
|     uint16_t                            wRightMotorSpeed;
 | |
| } XAMINPUT_VIBRATION, * PXAMINPUT_VIBRATION;
 | |
| 
 | |
| typedef struct _XAMINPUT_CAPABILITIES
 | |
| {
 | |
|     uint8_t                             Type;
 | |
|     uint8_t                             SubType;
 | |
|     uint16_t                            Flags;
 | |
|     XAMINPUT_GAMEPAD                    Gamepad;
 | |
|     XAMINPUT_VIBRATION                  Vibration;
 | |
| } XAMINPUT_CAPABILITIES, * PXAMINPUT_CAPABILITIES;
 | |
| 
 | |
| typedef struct _XAMINPUT_STATE
 | |
| {
 | |
|     uint32_t                            dwPacketNumber;
 | |
|     XAMINPUT_GAMEPAD                    Gamepad;
 | |
| } XAMINPUT_STATE, * PXAMINPUT_STATE;
 | 
