Revolution WUD work (mostly matching) (#3080)

* WUD mostly matching for Wii

Mostly copied from Petari with small modifications, Shield match is
still pretty bad.

* Implement WUDHidHost

* Fix WUD regressions in Shield/ShieldD
This commit is contained in:
Max Roncace
2026-02-03 02:17:29 -05:00
committed by GitHub
parent 67f179161f
commit 3bc0670b91
24 changed files with 3644 additions and 469 deletions
+1
View File
@@ -105,6 +105,7 @@ u8 __gUnknown800030E3 AT_ADDRESS(OS_BASE_CACHED | 0x30E3);
#define OSMillisecondsToTicks(msec) ((msec) * (OS_TIMER_CLOCK / 1000))
#define OSNanosecondsToTicks(nsec) (((nsec) * (OS_TIMER_CLOCK / 125000)) / 8000)
#define OSMicrosecondsToTicks(usec) (((usec) * (OS_TIMER_CLOCK / 125000)) / 8)
#define OSTicksDelta(x, y) ((s32)x, (s32)y)
u32 OSGetConsoleType(void);
void OSInit(void);
+59
View File
@@ -11,6 +11,13 @@ extern "C" {
typedef u8 SCType;
typedef enum {
SC_STATUS_OK,
SC_STATUS_BUSY,
SC_STATUS_FATAL,
SC_STATUS_PARSE,
} SCStatus;
typedef struct {
u8 mode;
u8 led;
@@ -108,6 +115,57 @@ typedef struct {
u32 flushSize;
} SCControl;
#define SC_MAX_DEV_ENTRY_FOR_STD 10
#define SC_MAX_DEV_ENTRY_FOR_SMP 6
#define SC_MAX_DEV_ENTRY (SC_MAX_DEV_ENTRY_FOR_STD + SC_MAX_DEV_ENTRY_FOR_SMP)
typedef struct {
BD_ADDR bd_addr;
u8 bd_name[64];
u8 link_key[16];
} SCBtCmpDevInfoSingle;
typedef struct {
BD_ADDR bd_addr;
u8 bd_name[64];
} SCBtDeviceInfoSingle;
typedef struct {
u8 num;
SCBtCmpDevInfoSingle info[6];
} SCBtCmpDevInfoArray;
typedef struct SCDevInfo {
char devName[20]; // at 0x0
char at_0x14[1];
char UNK_0x15[0xB];
LINK_KEY linkKey; // at 0x20
char UNK_0x30[0x10];
} SCDevInfo;
typedef struct SCBtDeviceInfo {
BD_ADDR addr; // at 0x0
SCDevInfo info; // at 0x6
} SCBtDeviceInfo;
typedef struct SCBtDeviceInfoArray {
/* 0x000 */ u8 num;
union {
struct {
#if SDK_AUG2010
/* 0x001 */ SCBtDeviceInfo regist[SC_MAX_DEV_ENTRY_FOR_STD];
/* 0x2BD */ SCBtDeviceInfo active[SC_MAX_DEV_ENTRY_FOR_SMP];
#else
/* 0x001 */ SCBtDeviceInfo regist[SC_MAX_DEV_ENTRY];
#endif
};
};
#if SDK_AUG2010
SCBtDeviceInfoSingle info[16];
#endif
} SCBtDeviceInfoArray;
#define SC_LANG_JAPANESE 0u
#define SC_LANG_ENGLISH 1u
#define SC_LANG_GERMAN 2u
@@ -152,6 +210,7 @@ BOOL SCFindS8Item(s8* data, SCItemID id);
BOOL SCFindU32Item(u32* data, SCItemID id);
BOOL SCReplaceU8Item(u8 data, SCItemID id);
void SCFlushAsync(SCFlushCallback callback);
BOOL SCGetBtDeviceInfoArray(SCBtDeviceInfoArray*);
BOOL SCSetBtDeviceInfoArray(const SCBtDeviceInfoArray*);
u32 SCCheckStatus(void);
s32 SCReloadConfFileAsync(u8* bufp, u32 bufSize, SCReloadConfFileCallback callback);
+1 -1
View File
@@ -135,7 +135,7 @@ typedef void (*WPADInitFunc)(void);
typedef void (*WPADCallback)(s32 chan, s32 result);
typedef void (*WPADExtensionCallback)(s32 chan, s32 devType);
typedef void* (*WPADAlloc)(u32 size);
typedef u8 (*WPADFree)(void* ptr);
typedef BOOL (*WPADFree)(void* ptr);
typedef void (*WPADSyncDeviceCallback)(s32 result, s32 num);
typedef void (*WPADSamplingCallback)(s32 chan);
typedef void (*WPADConnectCallback)(s32 chan, s32 result);
+13 -42
View File
@@ -596,13 +596,19 @@ typedef union
typedef void (tBTA_DM_SEC_CBACK)(tBTA_DM_SEC_EVT event, tBTA_DM_SEC *p_data);
/* Search callback events */
#define BTA_DM_INQ_RES_EVT 0 /* Inquiry result for a peer device. */
#define BTA_DM_INQ_CMPL_EVT 1 /* Inquiry complete. */
#define BTA_DM_DISC_RES_EVT 2 /* Discovery result for a peer device. */
#define BTA_DM_DISC_BLE_RES_EVT 3 /* Discovery result for BLE GATT based service on a peer device. */
#define BTA_DM_DISC_CMPL_EVT 4 /* Discovery complete. */
#define BTA_DM_DI_DISC_CMPL_EVT 5 /* Discovery complete. */
#define BTA_DM_SEARCH_CANCEL_CMPL_EVT 6 /* Search cancelled */
enum BTA_DM_State_e {
BTA_DM_INQ_RES_EVT, /* Inquiry result for a peer device. */
BTA_DM_INQ_CMPL_EVT, /* Inquiry complete. */
BTA_DM_DISC_RES_EVT, /* Discovery result for a peer device. */
#if SDK_AUG2010
BTA_DM_DISC_BLE_RES_EVT, /* Discovery result for BLE GATT based service on a peer device. */
#endif
BTA_DM_DISC_CMPL_EVT, /* Discovery complete. */
#if SDK_AUG2010
BTA_DM_DI_DISC_CMPL_EVT, /* Discovery complete. */
#endif
BTA_DM_SEARCH_CANCEL_CMPL_EVT, /* Search cancelled */
};
typedef UINT8 tBTA_DM_SEARCH_EVT;
@@ -1028,39 +1034,4 @@ void BTA_HhGetAclQueueInfo(void);
void BTA_Init(void);
void BTA_CleanUp(void (*p_cb)(tBTA_STATUS status)); // probably
// ---
/* muff1n: I wrote this definition myself
* TODO: would this be part of BLE or WUD?
*/
struct small_dev_info
{
char devName[20]; // size 0x14? offset 0x00 // might be 0x13?
char at_0x14[1]; // size 0x??, offset 0x14?
char __pad0[0x20 - (0x14 + 0x01)];
LINK_KEY linkKey; // size 0x10, offset 0x20
char __pad1[0x10];
}; // size 0x40
typedef struct {
BD_ADDR bd_addr;
u8 bd_name[64];
u8 link_key[16];
} SCBtCmpDevInfoSingle;
typedef struct {
BD_ADDR bd_addr;
u8 bd_name[64];
} SCBtDeviceInfoSingle;
typedef struct {
u8 num;
SCBtCmpDevInfoSingle info[6];
} SCBtCmpDevInfoArray;
typedef struct {
u8 num;
SCBtDeviceInfoSingle info[16];
} SCBtDeviceInfoArray;
#endif // CONTEXT_BTE_H
+150
View File
@@ -0,0 +1,150 @@
#ifndef RVL_SDK_WUD_H
#define RVL_SDK_WUD_H
#include <revolution/sc.h>
#include <revolution/wpad/bte.h>
#include "types.h"
#ifdef __cplusplus
extern "C" {
#endif
#define WUD_MAX_DEV_ENTRY_FOR_STD SC_MAX_DEV_ENTRY_FOR_STD
#define WUD_MAX_DEV_ENTRY_FOR_SMP SC_MAX_DEV_ENTRY_FOR_SMP
#define WUD_MAX_DEV_ENTRY SC_MAX_DEV_ENTRY
#define WUD_DEV_HANDLE_INVALID (-1)
#define WUD_ADDR_LEN BD_ADDR_LEN
// Forward declarations
typedef struct WUDDevInfo WUDDevInfo;
typedef enum {
WUD_LIB_STATUS_0,
WUD_LIB_STATUS_1,
WUD_LIB_STATUS_2,
WUD_LIB_STATUS_3,
WUD_LIB_STATUS_4,
WUD_LIB_STATUS_5,
} WUDLibStatus;
typedef enum {
WUD_CHAN0,
WUD_CHAN1,
WUD_CHAN2,
WUD_CHAN3,
WUD_MAX_CHANNELS,
WUD_CHAN_INVALID = -1
} WUDChannel;
typedef enum {
WUD_SYNC_TYPE_STANDARD,
WUD_SYNC_TYPE_SIMPLE,
} WUDSyncType;
typedef enum {
WUD_RESULT_SYNC_BUSY = -1,
WUD_RESULT_SYNC_WAITING,
WUD_RESULT_SYNC_DONE,
} WUDSyncResult;
typedef void* (*WUDAllocFunc)(u32 size);
typedef BOOL (*WUDFreeFunc)(void* pBlock);
typedef void (*WUDSyncDeviceCallback)(s32 result, s32 num);
typedef void (*WUDClearDeviceCallback)(s32 result);
typedef void (*WUDHidConnCallback)(u8, u8);
typedef void (*WUDHidRecvCallback)(UINT8 devHandle, UINT8* pReport, UINT16 len);
typedef struct WUDDevInfo {
SCDevInfo conf; // at 0x0
BD_ADDR devAddr; // at 0x40
LINK_KEY linkKey; // at 0x46
UINT8 devHandle; // at 0x56
UINT8 subclass; // at 0x57
UINT8 appID; // at 0x58
u8 status; // at 0x59
s8 UNK_0x5A; // at 0x5A
u8 sync_type; // at 0x5B
u8 UNK_0x5C; // at 0x5C
u8 UNK_0x5D[1];
tBTA_HH_ATTR_MASK hhAttrMask; // at 0x5E
} WUDDevInfo;
BOOL WUDInit(void);
BOOL WUDIsBusy(void);
void WUDRegisterAllocator(WUDAllocFunc pAllocFunc, WUDFreeFunc pFreeFunc);
u32 WUDGetAllocatedMemSize(void);
void WUDShutdown(void);
WUDLibStatus WUDGetStatus(void);
u8 WUDGetBufferStatus(void);
void WUDSetSniffMode(BD_ADDR addr, s32 interval);
// clang-format off
WUDSyncDeviceCallback
WUDSetSyncSimpleCallback(WUDSyncDeviceCallback pCallback);
WUDClearDeviceCallback
WUDSetClearDeviceCallback(WUDClearDeviceCallback pCallback);
// clang-format on
BOOL WUDStartSyncDevice(void);
BOOL WUDStartFastSyncSimple(void);
BOOL WUDStartSyncSimple(void);
BOOL WUDStopSyncSimple(void);
BOOL WUDCancelSyncDevice(void);
BOOL WUDStartClearDevice(void);
BOOL WUDSetDisableChannel(s8 afhChannel);
WUDHidRecvCallback WUDSetHidRecvCallback(WUDHidRecvCallback pCallback);
WUDHidConnCallback WUDSetHidConnCallback(WUDHidConnCallback pCallback);
void WUDSetVisibility(u8 disc, u8 conn);
u8 WUDGetConnectable(void);
void WUDiGetFirmwareVersion(void);
void WUDiInitSub(void);
void WUDiEnableStack(void);
void WUDiAutoSync(void);
void WUDiDeleteAllLinkKeys(void);
void WUDiRegisterDevice(BD_ADDR addr);
void WUDiRemoveDevice(BD_ADDR addr);
WUDDevInfo* WUDiGetDevInfo(BD_ADDR addr);
WUDDevInfo* WUDiGetDevInfoIndex(int idx);
WUDDevInfo* WUDiGetNewDevInfo(void);
void WUDiRemoveDevInfo(BD_ADDR addr);
void WUDiClearDevice(void);
u8 WUDiGetDevNumber(void);
u8 WUDiGetDevSmpNumber(void);
u8 WUDiGetConnNumber(void);
u8 WUDiGetLinkNum(void);
void WUDiMoveTopSmpDevInfoPtr(WUDDevInfo* pInfo);
void WUDiMoveBottomSmpDevInfoPtr(WUDDevInfo* pInfo);
WUDDevInfo* WUDiGetRemoveSmpDevice(void);
void WUDiMoveTopOfDisconnectedSmpDevice(WUDDevInfo* pInfo);
void WUDiMoveTopStdDevInfoPtr(WUDDevInfo* pInfo);
void WUDiMoveBottomStdDevInfoPtr(WUDDevInfo* pInfo);
WUDDevInfo* WUDiGetRemoveStdDevice(void);
void WUDiMoveTopOfDisconnectedStdDevice(WUDDevInfo* pInfo);
BD_ADDR_PTR _WUDGetDevAddr(UINT8 handle);
u16 _WUDGetQueuedSize(s8 dev_handle);
u16 _WUDGetNotAckedSize(s8 dev_handle);
u8 _WUDGetLinkNumber(void);
#ifdef __cplusplus
}
#endif
#endif
-256
View File
@@ -1,256 +0,0 @@
#ifndef _REVOLUTION_WUD_WUD_H_
#define _REVOLUTION_WUD_WUD_H_
#include <revolution/wpad/bte.h>
#include <revolution.h>
#ifdef __cplusplus
extern "C" {
#endif
#define WUD_CHAN0 0
#define WUD_CHAN1 1
#define WUD_CHAN2 2
#define WUD_CHAN3 3
#define WUD_MAX_CHANNELS 4
#define WUD_CHAN_INVALID -1
typedef void* WUDAllocFunc(u32 size);
typedef int WUDFreeFunc(void* ptr); // signature from petari. not sure what the int is, though
typedef struct WUDDevInfo {
/* 0x00 */ struct small_dev_info small;
/* 0x40 */ BD_ADDR devAddr;
/* 0x46 */ LINK_KEY linkKey;
/* 0x56 */ u8 devHandle;
/* 0x57 */ u8 subclass;
/* 0x58 */ u8 appID;
/* 0x59 */ u8 at_0x59;
/* 0x5a */ u8 at_0x5a; /* unknown */
/* 0x5b */ u8 at_0x5b;
/* 0x5c */ u8 at_0x5c;
u8 at_0x5d[1]; // padding?
/* 0x5e */ tBTA_HH_ATTR_MASK hhAttrMask;
} WUDDevInfo; // size 0x60
typedef void WUDHidConnectCallback(WUDDevInfo* devInfo, u8 isOpenEvent);
typedef void WUDHidReceiveCallback(u8 dev_handle, u8* p_rpt, u16 len);
u8 WUDGetBufferStatus(void);
u8 _WUDGetLinkNumber(void);
u16 _WUDGetQueuedSize(s8 dev_handle);
u16 _WUDGetNotAckedSize(s8 dev_handle);
typedef u8 BTD_NAME[64];
typedef u8 BTD_ADDR[6];
typedef u8 LINKKEY[16];
typedef enum {
WUD_STATE_SYNC_START = 0,
WUD_STATE_SYNC_PREPARE_SEARCH = 1,
WUD_STATE_SYNC_START_SEARCH = 2,
WUD_STATE_SYNC_WAIT_FOR_SEARCH_RESULT = 3,
WUD_STATE_SYNC_CHECK_SEARCH_RESULT = 4,
WUD_STATE_SYNC_IS_EXISTED_DEVICE = 5,
WUD_STATE_SYNC_6 = 6,
WUD_STATE_SYNC_STORED_LINK_KEY_TO_EEPROM = 7,
WUD_STATE_SYNC_WAIT_FOR_STORING = 8,
WUD_STATE_SYNC_WAIT_FOR_READING = 10,
WUD_STATE_SYNC_11 = 11,
WUD_STATE_SYNC_12 = 12,
WUD_STATE_SYNC_13 = 13,
WUD_STATE_SYNC_DONE = 14,
WUD_STATE_SYNC_TRY_CONNECT = 15,
WUD_STATE_SYNC_PREPARE_FOR_EXISTED_DEVICE = 16,
WUD_STATE_SYNC_PREPARE_FOR_UNKNOWN_DEVICE = 17,
WUD_STATE_SYNC_REGISTER_DEVICE = 18,
WUD_STATE_SYNC_VIRGIN_SIMPLE = 19,
WUD_STATE_SYNC_VIRGIN_STANDARD = 20,
WUD_STATE_SYNC_CHANGE_SIMPLE_TO_STANDARD = 21,
WUD_STATE_SYNC_STORED_DEV_INFO_TO_NAND = 22,
WUD_STATE_SYNC_COMPLETE = 23,
WUD_STATE_SYNC_WAIT_FOR_INCOMING = 24,
WUD_STATE_SYNC_SC_FLUSH = 25,
WUD_STATE_SYNC_CANCEL_SEARCH = 26,
WUD_STATE_SYNC_WAIT_FOR_START_SEARCH = 29,
WUD_STATE_SYNC_ERROR = 255,
} WUDSyncState;
typedef enum {
WUD_STATE_DELETE_START = 0,
WUD_STATE_DELETE_DISALLOW_INCOMING = 1,
WUD_STATE_DELETE_DISCONNECT_ALL = 2,
WUD_STATE_DELETE_CLEANUP_DATABASE = 3,
WUD_STATE_DELETE_CLEANUP_SETTING = 5,
WUD_STATE_DELETE_6 = 6,
WUD_STATE_DELETE_7 = 7,
WUD_STATE_DELETE_DONE = 8
} WUDDeleteState;
typedef enum {
WUD_RESULT_DELETE_BUSY = -1,
WUD_RESULT_DELETE_WAITING,
WUD_RESULT_DELETE_COMPLETE,
} WUDDeleteResult;
typedef enum {
WUD_STATE_LINK_KEY_START = 0,
WUD_STATE_LINK_KEY_READING = 1,
WUD_STATE_LINK_KEY_WRITING = 2,
WUD_STATE_LINK_KEY_DELETING = 3,
WUD_STATE_LINK_KEY_ERROR = 255,
} WUDLinkKeyState;
typedef enum {
WUD_STATE_STACK_START = 0,
WUD_STATE_STACK_GET_STORED_LINK_KEY = 1,
WUD_STATE_STACK_CHECK_DEVICE_INFO = 2,
WUD_STATE_STACK_DONE = 3,
WUD_STATE_STACK_INITIALIZED = 4,
WUD_STATE_STACK_ERROR = 255,
} WUDStackState;
typedef enum {
WUD_STATE_INIT_START = 0,
WUD_STATE_INIT_WAIT_FOR_INITIALIZATION = 1,
WUD_STATE_INIT_GET_DEV_INFO = 2,
WUD_STATE_INIT_DONE = 3,
WUD_STATE_INIT_INITIALIZED = 4,
WUD_STATE_INIT_ERROR = 255,
} WUDInitState;
typedef enum {
WUD_STATE_SHUTDOWN_START = 0,
WUD_STATE_SHUTDOWN_STORE_SETTINGS = 1,
WUD_STATE_SHUTDOWN_FLUSH_SETTINGS = 2,
WUD_STATE_SHUTDOWN_DONE = 3,
WUD_STATE_SHUTDOWN_ERROR = 255,
} WUDShutdownState;
typedef enum {
WUD_VSE_INITIATE_PAIRING = 8,
WUD_VSE_DELETE_ALL_KEYS,
WUD_VSE_SI_PORT_STATUS,
WUD_VSE_WATCH_DOG_RESET_HW = 16,
} WUDVendorSpecificEvent;
typedef struct WUDDeviceInfo {
BTD_NAME bd_name;
BTD_ADDR bd_addr;
LINKKEY link_key;
u8 handle;
u8 sub_class;
u8 app_id;
u8 status;
u8 overwrite;
u8 sync_type;
u8 reg;
u16 attr_mask;
} WUDDeviceInfo;
typedef void* (*WUDAlloc)(u32);
typedef u8 (*WUDFree)(void*);
typedef void (*WUDSyncDeviceCallback)(s32 result, s32 num); // what is result?
typedef void (*WUDClearDeviceCallback)(s32);
typedef void (*WUDHidRecvCallback)(u8, u8*, u16);
typedef void (*WUDHidConnCallback)(u8, u8);
typedef void (*WUDStoredCallback)(void*);
typedef struct DeviceList {
WUDDeviceInfo* info;
void* prev;
void* next;
} DeviceList;
typedef struct WUDControlBlock {
WUDSyncDeviceCallback syncCallback;
WUDSyncDeviceCallback syncSmpCallback;
WUDClearDeviceCallback clearCallback;
u8 syncStatus;
u8 delStatus;
u8 keyStatus;
u8 profStatus;
u8 initStatus;
u8 shutStatus;
u8 devNums;
u8 devSmpNums;
DeviceList* smpListHead;
DeviceList* smpListTail;
DeviceList smpList[6];
DeviceList* stdListHead;
DeviceList* stdListTail;
DeviceList stdList[10];
WUDDeviceInfo devInfo[10];
WUDDeviceInfo devSmpInfo[6];
u8 connNums;
u8 linkNums;
u8 pairNums;
u8 syncFast;
s8 syncLoop;
u8 syncMode;
u8 connectable;
u8 discoverable;
WUDHidRecvCallback hidRecvCallback;
WUDHidConnCallback hidConnCallback;
WUDAlloc alloc;
WUDFree free;
BTD_ADDR lastAddr;
BTD_ADDR hostAddr;
s8 status;
u8 siStatus;
u8 pmId;
s8 rssi;
OSAlarm evtAlarm;
u32 profileMask;
u16 aclAvailBufSize;
u16 aclMaxBufSize;
s16 delayCnt;
s16 incomeCnt;
} WUDControlBlock;
BOOL WUDInit();
BOOL WUDStartSyncSimple(void);
BOOL WUDStartFastSyncSimple(void);
u32 WUDGetAllocatedMemSize(void);
WUDSyncDeviceCallback WUDSetSyncSimpleCallback(WUDSyncDeviceCallback);
void WUDiMoveTopSmpDevInfoPtr(WUDDeviceInfo*);
void WUDiMoveTopStdDevInfoPtr(WUDDeviceInfo*);
void WUDSetSniffMode(BTD_ADDR, s32);
void WUDiRemoveDevice(BTD_ADDR);
void WUDiMoveBottomSmpDevInfoPtr(WUDDeviceInfo*);
void WUDiMoveTopSmpDevInfoPtr(WUDDeviceInfo*);
void WUDiMoveBottomStdDevInfoPtr(WUDDeviceInfo*);
void WUDiMoveTopOfDisconnectedSmpDevice(WUDDeviceInfo*);
void WUDiMoveTopOfDisconnectedStdDevice(WUDDeviceInfo*);
WUDDeviceInfo* WUDiGetDevInfo(BTD_ADDR);
BOOL WUDCancelSyncDevice(void);
BOOL WUDStopSyncSimple(void);
s32 WUDGetStatus(void);
void WUDShutdown();
void WUDSetVisibility(u8, u8);
u8 WUDGetConnectable(void);
BOOL WUDIsBusy(void);
WUDHidRecvCallback WUDSetHidRecvCallback(WUDHidRecvCallback);
WUDHidConnCallback WUDSetHidConnCallback(WUDHidConnCallback);
void WUDRegisterAllocator(WUDAlloc, WUDFree);
u8* _WUDGetDevAddr(u8);
BOOL WUDSetDisableChannel(s8);
u8 WUDGetBufferStatus(void);
u8 _WUDGetLinkNumber(void);
u16 _WUDGetQueuedSize(s8);
u16 _WUDGetNotAckedSize(s8);
extern WUDControlBlock _wcb;
extern WUDDeviceInfo _work;
extern u8* _dev_handle_to_bda[16];
extern u16 _dev_handle_queue_size[16];
extern u16 _dev_handle_notack_num[16];
extern SCBtDeviceInfoArray _scArray;
#ifdef __cplusplus
}
#endif
#endif /* _REVOLUTION_WUD_WUD_H_ */
-14
View File
@@ -1,14 +0,0 @@
#ifndef _REVOLUTION_WUD_DEBUG_MSG_H_
#define _REVOLUTION_WUD_DEBUG_MSG_H_
#ifdef __cplusplus
extern "C" {
#endif
void WUD_DEBUGPrint(const char*, ...);
#ifdef __cplusplus
}
#endif
#endif /* _REVOLUTION_WUD_DEBUG_MSG_H_ */