#include "Cafe/OS/common/OSCommon.h" #include "Cafe/IOSU/legacy/iosu_ioctl.h" #include "Cafe/IOSU/legacy/iosu_act.h" #include "Cafe/IOSU/legacy/iosu_fpd.h" #include "Cafe/OS/libs/coreinit/coreinit_IOS.h" #define fpdPrepareRequest() \ StackAllocator _buf_fpdRequest; \ StackAllocator _buf_bufferVector; \ iosu::fpd::iosuFpdCemuRequest_t* fpdRequest = _buf_fpdRequest.GetPointer(); \ ioBufferVector_t* fpdBufferVector = _buf_bufferVector.GetPointer(); \ memset(fpdRequest, 0, sizeof(iosu::fpd::iosuFpdCemuRequest_t)); \ memset(fpdBufferVector, 0, sizeof(ioBufferVector_t)); \ fpdBufferVector->buffer = (uint8*)fpdRequest; namespace nn { namespace fp { struct { bool isInitialized; bool isAdminMode; }g_fp = { }; void Initialize() { if (g_fp.isInitialized == false) { g_fp.isInitialized = true; fpdPrepareRequest(); fpdRequest->requestCode = iosu::fpd::IOSU_FPD_INITIALIZE; __depr__IOS_Ioctlv(IOS_DEVICE_FPD, IOSU_FPD_REQUEST_CEMU, 1, 1, fpdBufferVector); } } void export_IsInitialized(PPCInterpreter_t* hCPU) { forceLogDebug_printf("Called nn_fp.IsInitialized LR %08x", hCPU->spr.LR); osLib_returnFromFunction(hCPU, g_fp.isInitialized ? 1 : 0); } void export_Initialize(PPCInterpreter_t* hCPU) { forceLogDebug_printf("Called nn_fp.Initialize LR %08x", hCPU->spr.LR); Initialize(); osLib_returnFromFunction(hCPU, 0); } void export_InitializeAdmin(PPCInterpreter_t* hCPU) { forceLogDebug_printf("Called nn_fp.InitializeAdmin LR %08x", hCPU->spr.LR); Initialize(); g_fp.isAdminMode = true; osLib_returnFromFunction(hCPU, 0); } void export_IsInitializedAdmin(PPCInterpreter_t* hCPU) { forceLogDebug_printf("nn_fp.IsInitializedAdmin()"); osLib_returnFromFunction(hCPU, g_fp.isInitialized ? 1 : 0); } void export_SetNotificationHandler(PPCInterpreter_t* hCPU) { ppcDefineParamU32(notificationMask, 0); ppcDefineParamMPTR(funcMPTR, 1); ppcDefineParamMPTR(customParam, 2); forceLogDebug_printf("nn_fp.SetNotificationHandler(0x%08x,0x%08x,0x%08x)", hCPU->gpr[3], hCPU->gpr[4], hCPU->gpr[5]); fpdPrepareRequest(); fpdRequest->requestCode = iosu::fpd::IOSU_FPD_SET_NOTIFICATION_HANDLER; fpdRequest->setNotificationHandler.notificationMask = notificationMask; fpdRequest->setNotificationHandler.funcPtr = funcMPTR; fpdRequest->setNotificationHandler.custom = customParam; __depr__IOS_Ioctlv(IOS_DEVICE_FPD, IOSU_FPD_REQUEST_CEMU, 1, 1, fpdBufferVector); osLib_returnFromFunction(hCPU, 0); } void export_LoginAsync(PPCInterpreter_t* hCPU) { ppcDefineParamMPTR(funcPtr, 0); ppcDefineParamMPTR(custom, 1); forceLogDebug_printf("nn_fp.LoginAsync(0x%08x,0x%08x)", funcPtr, custom); if (g_fp.isInitialized == false) { osLib_returnFromFunction(hCPU, 0xC0C00580); return; } fpdPrepareRequest(); fpdRequest->requestCode = iosu::fpd::IOSU_FPD_LOGIN_ASYNC; fpdRequest->loginAsync.funcPtr = funcPtr; fpdRequest->loginAsync.custom = custom; __depr__IOS_Ioctlv(IOS_DEVICE_FPD, IOSU_FPD_REQUEST_CEMU, 1, 1, fpdBufferVector); osLib_returnFromFunction(hCPU, 0); } void export_HasLoggedIn(PPCInterpreter_t* hCPU) { // Sonic All Star Racing needs this forceLogDebug_printf("nn_fp.HasLoggedIn()"); osLib_returnFromFunction(hCPU, 1); } void export_IsOnline(PPCInterpreter_t* hCPU) { //forceLogDebug_printf("nn_fp.IsOnline();\n"); fpdPrepareRequest(); fpdRequest->requestCode = iosu::fpd::IOSU_FPD_IS_ONLINE; __depr__IOS_Ioctlv(IOS_DEVICE_FPD, IOSU_FPD_REQUEST_CEMU, 1, 1, fpdBufferVector); forceLogDebug_printf("nn_fp.IsOnline() -> %d", fpdRequest->resultU32.u32); osLib_returnFromFunction(hCPU, fpdRequest->resultU32.u32); } void export_GetFriendList(PPCInterpreter_t* hCPU) { ppcDefineParamMEMPTR(pidList, uint32be, 0); ppcDefineParamMEMPTR(returnedCount, uint32be, 1); ppcDefineParamU32(startIndex, 2); ppcDefineParamU32(maxCount, 3); forceLogDebug_printf("nn_fp.GetFriendList(...)"); //debug_printf("nn_fp.GetFriendList(0x%08x, 0x%08x, %d, %d)\n", hCPU->gpr[3], hCPU->gpr[4], hCPU->gpr[5], hCPU->gpr[6]); fpdPrepareRequest(); fpdRequest->requestCode = iosu::fpd::IOSU_FPD_GET_FRIEND_LIST; fpdRequest->getFriendList.pidList = pidList; fpdRequest->getFriendList.startIndex = startIndex; fpdRequest->getFriendList.maxCount = maxCount; __depr__IOS_Ioctlv(IOS_DEVICE_FPD, IOSU_FPD_REQUEST_CEMU, 1, 1, fpdBufferVector); *returnedCount = fpdRequest->resultU32.u32; osLib_returnFromFunction(hCPU, fpdRequest->returnCode); } void export_GetFriendRequestList(PPCInterpreter_t* hCPU) { // GetFriendRequestList__Q2_2nn2fpFPUiT1UiT3 ppcDefineParamMEMPTR(pidList, uint32be, 0); ppcDefineParamMEMPTR(returnedCount, uint32be, 1); ppcDefineParamU32(startIndex, 2); ppcDefineParamU32(maxCount, 3); forceLogDebug_printf("nn_fp.GetFriendRequestList(...)"); //debug_printf("nn_fp.GetFriendList(0x%08x, 0x%08x, %d, %d)\n", hCPU->gpr[3], hCPU->gpr[4], hCPU->gpr[5], hCPU->gpr[6]); fpdPrepareRequest(); fpdRequest->requestCode = iosu::fpd::IOSU_FPD_GET_FRIENDREQUEST_LIST; fpdRequest->getFriendList.pidList = pidList; fpdRequest->getFriendList.startIndex = startIndex; fpdRequest->getFriendList.maxCount = maxCount; __depr__IOS_Ioctlv(IOS_DEVICE_FPD, IOSU_FPD_REQUEST_CEMU, 1, 1, fpdBufferVector); *returnedCount = fpdRequest->resultU32.u32; osLib_returnFromFunction(hCPU, fpdRequest->returnCode); } void export_GetFriendListAll(PPCInterpreter_t* hCPU) { ppcDefineParamMEMPTR(pidList, uint32be, 0); ppcDefineParamMEMPTR(returnedCount, uint32be, 1); ppcDefineParamU32(startIndex, 2); ppcDefineParamU32(maxCount, 3); forceLogDebug_printf("nn_fp.GetFriendListAll(...)"); //debug_printf("nn_fp.GetFriendListAll(0x%08x, 0x%08x, %d, %d)\n", hCPU->gpr[3], hCPU->gpr[4], hCPU->gpr[5], hCPU->gpr[6]); fpdPrepareRequest(); fpdRequest->requestCode = iosu::fpd::IOSU_FPD_GET_FRIEND_LIST_ALL; fpdRequest->getFriendList.pidList = pidList; fpdRequest->getFriendList.startIndex = startIndex; fpdRequest->getFriendList.maxCount = maxCount; __depr__IOS_Ioctlv(IOS_DEVICE_FPD, IOSU_FPD_REQUEST_CEMU, 1, 1, fpdBufferVector); *returnedCount = fpdRequest->resultU32.u32; osLib_returnFromFunction(hCPU, fpdRequest->returnCode); } void export_GetFriendListEx(PPCInterpreter_t* hCPU) { ppcDefineParamMEMPTR(friendData, iosu::fpd::friendData_t, 0); ppcDefineParamMEMPTR(pidList, uint32be, 1); ppcDefineParamU32(count, 2); forceLogDebug_printf("nn_fp.GetFriendListEx(...)"); fpdPrepareRequest(); fpdRequest->requestCode = iosu::fpd::IOSU_FPD_GET_FRIEND_LIST_EX; fpdRequest->getFriendListEx.friendData = friendData; fpdRequest->getFriendListEx.pidList = pidList; fpdRequest->getFriendListEx.count = count; __depr__IOS_Ioctlv(IOS_DEVICE_FPD, IOSU_FPD_REQUEST_CEMU, 1, 1, fpdBufferVector); osLib_returnFromFunction(hCPU, fpdRequest->returnCode); } void export_GetFriendRequestListEx(PPCInterpreter_t* hCPU) { ppcDefineParamMEMPTR(friendRequest, iosu::fpd::friendRequest_t, 0); ppcDefineParamMEMPTR(pidList, uint32be, 1); ppcDefineParamU32(count, 2); forceLogDebug_printf("nn_fp.GetFriendRequestListEx(...)"); fpdPrepareRequest(); fpdRequest->requestCode = iosu::fpd::IOSU_FPD_GET_FRIENDREQUEST_LIST_EX; fpdRequest->getFriendRequestListEx.friendRequest = friendRequest; fpdRequest->getFriendRequestListEx.pidList = pidList; fpdRequest->getFriendRequestListEx.count = count; __depr__IOS_Ioctlv(IOS_DEVICE_FPD, IOSU_FPD_REQUEST_CEMU, 1, 1, fpdBufferVector); osLib_returnFromFunction(hCPU, fpdRequest->returnCode); } void export_GetBasicInfoAsync(PPCInterpreter_t* hCPU) { ppcDefineParamMEMPTR(basicInfo, iosu::fpd::friendBasicInfo_t, 0); ppcDefineParamTypePtr(pidList, uint32be, 1); ppcDefineParamU32(count, 2); ppcDefineParamMPTR(funcMPTR, 3); ppcDefineParamU32(customParam, 4); fpdPrepareRequest(); fpdRequest->requestCode = iosu::fpd::IOSU_FPD_GET_BASIC_INFO_ASYNC; fpdRequest->getBasicInfo.basicInfo = basicInfo; fpdRequest->getBasicInfo.pidList = pidList; fpdRequest->getBasicInfo.count = count; fpdRequest->getBasicInfo.funcPtr = funcMPTR; fpdRequest->getBasicInfo.custom = customParam; __depr__IOS_Ioctlv(IOS_DEVICE_FPD, IOSU_FPD_REQUEST_CEMU, 1, 1, fpdBufferVector);; osLib_returnFromFunction(hCPU, fpdRequest->returnCode); } void export_GetMyPrincipalId(PPCInterpreter_t* hCPU) { forceLogDebug_printf("nn_fp.GetMyPrincipalId()"); fpdPrepareRequest(); fpdRequest->requestCode = iosu::fpd::IOSU_FPD_GET_MY_PRINCIPAL_ID; __depr__IOS_Ioctlv(IOS_DEVICE_FPD, IOSU_FPD_REQUEST_CEMU, 1, 1, fpdBufferVector); uint32 principalId = fpdRequest->resultU32.u32; osLib_returnFromFunction(hCPU, principalId); } void export_GetMyAccountId(PPCInterpreter_t* hCPU) { forceLogDebug_printf("nn_fp.GetMyAccountId(0x%08x)", hCPU->gpr[3]); ppcDefineParamTypePtr(accountId, uint8, 0); fpdPrepareRequest(); fpdRequest->requestCode = iosu::fpd::IOSU_FPD_GET_MY_ACCOUNT_ID; fpdRequest->common.ptr = (void*)accountId; __depr__IOS_Ioctlv(IOS_DEVICE_FPD, IOSU_FPD_REQUEST_CEMU, 1, 1, fpdBufferVector); osLib_returnFromFunction(hCPU, fpdRequest->returnCode); } void export_GetMyScreenName(PPCInterpreter_t* hCPU) { forceLogDebug_printf("nn_fp.GetMyScreenName(0x%08x)", hCPU->gpr[3]); ppcDefineParamTypePtr(screenname, uint16be, 0); screenname[0] = '\0'; fpdPrepareRequest(); fpdRequest->requestCode = iosu::fpd::IOSU_FPD_GET_MY_SCREENNAME; fpdRequest->common.ptr = (void*)screenname; __depr__IOS_Ioctlv(IOS_DEVICE_FPD, IOSU_FPD_REQUEST_CEMU, 1, 1, fpdBufferVector); osLib_returnFromFunction(hCPU, 0); } typedef struct { uint8 showOnline; // show online status to others uint8 showGame; // show played game to others uint8 blockFriendRequests; // block friend requests }fpPerference_t; void export_GetMyPreference(PPCInterpreter_t* hCPU) { forceLogDebug_printf("nn_fp.GetMyPreference(0x%08x) - placeholder", hCPU->gpr[3]); ppcDefineParamTypePtr(pref, fpPerference_t, 0); pref->showOnline = 1; pref->showGame = 1; pref->blockFriendRequests = 0; osLib_returnFromFunction(hCPU, 0); } // GetMyPreference__Q2_2nn2fpFPQ3_2nn2fp10Preference void export_GetMyMii(PPCInterpreter_t* hCPU) { forceLogDebug_printf("nn_fp.GetMyMii(0x%08x)", hCPU->gpr[3]); ppcDefineParamTypePtr(fflData, FFLData_t, 0); fpdPrepareRequest(); fpdRequest->requestCode = iosu::fpd::IOSU_FPD_GET_MY_MII; fpdRequest->common.ptr = (void*)fflData; __depr__IOS_Ioctlv(IOS_DEVICE_FPD, IOSU_FPD_REQUEST_CEMU, 1, 1, fpdBufferVector); osLib_returnFromFunction(hCPU, fpdRequest->returnCode); } void export_GetFriendAccountId(PPCInterpreter_t* hCPU) { forceLogDebug_printf("nn_fp.GetFriendAccountId(0x%08x,0x%08x,0x%08x)", hCPU->gpr[3], hCPU->gpr[4], hCPU->gpr[5]); ppcDefineParamMEMPTR(accountIds, char, 0); ppcDefineParamMEMPTR(pidList, uint32be, 1); ppcDefineParamU32(count, 2); fpdPrepareRequest(); fpdRequest->requestCode = iosu::fpd::IOSU_FPD_GET_FRIEND_ACCOUNT_ID; fpdRequest->getFriendAccountId.accountIds = accountIds; fpdRequest->getFriendAccountId.pidList = pidList; fpdRequest->getFriendAccountId.count = count; __depr__IOS_Ioctlv(IOS_DEVICE_FPD, IOSU_FPD_REQUEST_CEMU, 1, 1, fpdBufferVector); osLib_returnFromFunction(hCPU, fpdRequest->returnCode); } void export_GetFriendScreenName(PPCInterpreter_t* hCPU) { // GetFriendScreenName__Q2_2nn2fpFPA11_wPCUiUibPUc forceLogDebug_printf("nn_fp.GetFriendScreenName(0x%08x,0x%08x,0x%08x,%d,0x%08x)", hCPU->gpr[3], hCPU->gpr[4], hCPU->gpr[5], hCPU->gpr[6], hCPU->gpr[7]); ppcDefineParamMEMPTR(nameList, uint16be, 0); ppcDefineParamMEMPTR(pidList, uint32be, 1); ppcDefineParamU32(count, 2); ppcDefineParamU32(replaceNonAscii, 3); ppcDefineParamMEMPTR(languageList, uint8, 4); fpdPrepareRequest(); fpdRequest->requestCode = iosu::fpd::IOSU_FPD_GET_FRIEND_SCREENNAME; fpdRequest->getFriendScreenname.nameList = nameList; fpdRequest->getFriendScreenname.pidList = pidList; fpdRequest->getFriendScreenname.count = count; fpdRequest->getFriendScreenname.replaceNonAscii = replaceNonAscii != 0; fpdRequest->getFriendScreenname.languageList = languageList; __depr__IOS_Ioctlv(IOS_DEVICE_FPD, IOSU_FPD_REQUEST_CEMU, 1, 1, fpdBufferVector); osLib_returnFromFunction(hCPU, fpdRequest->returnCode); } void export_GetFriendMii(PPCInterpreter_t* hCPU) { forceLogDebug_printf("nn_fp.GetFriendMii(0x%08x,0x%08x,0x%08x)", hCPU->gpr[3], hCPU->gpr[4], hCPU->gpr[5]); ppcDefineParamMEMPTR(miiList, FFLData_t, 0); ppcDefineParamMEMPTR(pidList, uint32be, 1); ppcDefineParamU32(count, 2); fpdPrepareRequest(); fpdRequest->requestCode = iosu::fpd::IOSU_FPD_GET_FRIEND_MII; fpdRequest->getFriendMii.miiList = (uint8*)miiList.GetPtr(); fpdRequest->getFriendMii.pidList = pidList; fpdRequest->getFriendMii.count = count; __depr__IOS_Ioctlv(IOS_DEVICE_FPD, IOSU_FPD_REQUEST_CEMU, 1, 1, fpdBufferVector); osLib_returnFromFunction(hCPU, fpdRequest->returnCode); } void export_GetFriendPresence(PPCInterpreter_t* hCPU) { forceLogDebug_printf("nn_fp.GetFriendPresence(0x%08x,0x%08x,0x%08x)", hCPU->gpr[3], hCPU->gpr[4], hCPU->gpr[5]); ppcDefineParamMEMPTR(presenceList, uint8, 0); ppcDefineParamMEMPTR(pidList, uint32be, 1); ppcDefineParamU32(count, 2); fpdPrepareRequest(); fpdRequest->requestCode = iosu::fpd::IOSU_FPD_GET_FRIEND_PRESENCE; fpdRequest->getFriendPresence.presenceList = (uint8*)presenceList.GetPtr(); fpdRequest->getFriendPresence.pidList = pidList; fpdRequest->getFriendPresence.count = count; __depr__IOS_Ioctlv(IOS_DEVICE_FPD, IOSU_FPD_REQUEST_CEMU, 1, 1, fpdBufferVector); osLib_returnFromFunction(hCPU, fpdRequest->returnCode); } void export_GetFriendRelationship(PPCInterpreter_t* hCPU) { forceLogDebug_printf("nn_fp.GetFriendRelationship(0x%08x,0x%08x,0x%08x)", hCPU->gpr[3], hCPU->gpr[4], hCPU->gpr[5]); ppcDefineParamMEMPTR(relationshipList, uint8, 0); ppcDefineParamMEMPTR(pidList, uint32be, 1); ppcDefineParamU32(count, 2); fpdPrepareRequest(); fpdRequest->requestCode = iosu::fpd::IOSU_FPD_GET_FRIEND_RELATIONSHIP; fpdRequest->getFriendRelationship.relationshipList = (uint8*)relationshipList.GetPtr(); fpdRequest->getFriendRelationship.pidList = pidList; fpdRequest->getFriendRelationship.count = count; __depr__IOS_Ioctlv(IOS_DEVICE_FPD, IOSU_FPD_REQUEST_CEMU, 1, 1, fpdBufferVector); osLib_returnFromFunction(hCPU, fpdRequest->returnCode); } void export_IsJoinable(PPCInterpreter_t* hCPU) { ppcDefineParamTypePtr(presence, iosu::fpd::friendPresence_t, 0); ppcDefineParamU64(joinMask, 2); if (presence->isValid == 0 || presence->isOnline == 0 || presence->gameMode.joinGameId == 0 || presence->gameMode.matchmakeType == 0 || presence->gameMode.groupId == 0 || presence->gameMode.joinGameMode >= 64 ) { osLib_returnFromFunction(hCPU, 0); return; } uint32 joinGameMode = presence->gameMode.joinGameMode; uint64 joinModeMask = (1ULL<gameMode.joinFlagMask; if (joinFlagMask == 0) { osLib_returnFromFunction(hCPU, 0); return; } if (joinFlagMask == 1) { osLib_returnFromFunction(hCPU, 1); return; } if (joinFlagMask == 2) { // check relationship uint8 relationship[1] = { 0 }; StackAllocator pidList; pidList[0] = presence->gameMode.hostPid; fpdPrepareRequest(); fpdRequest->requestCode = iosu::fpd::IOSU_FPD_GET_FRIEND_RELATIONSHIP; fpdRequest->getFriendRelationship.relationshipList = relationship; fpdRequest->getFriendRelationship.pidList = pidList.GetPointer(); fpdRequest->getFriendRelationship.count = 1; __depr__IOS_Ioctlv(IOS_DEVICE_FPD, IOSU_FPD_REQUEST_CEMU, 1, 1, fpdBufferVector); if(relationship[0] == iosu::fpd::RELATIONSHIP_FRIEND) osLib_returnFromFunction(hCPU, 1); else osLib_returnFromFunction(hCPU, 0); return; } if (joinFlagMask == 0x65 || joinFlagMask == 0x66) { cemuLog_log(LogType::Force, "Unsupported friend invite"); } osLib_returnFromFunction(hCPU, 0); } void export_CheckSettingStatusAsync(PPCInterpreter_t* hCPU) { forceLogDebug_printf("nn_fp.CheckSettingStatusAsync(0x%08x,0x%08x,0x%08x) - placeholder", hCPU->gpr[3], hCPU->gpr[4], hCPU->gpr[5]); ppcDefineParamTypePtr(uknR3, uint8, 0); ppcDefineParamMPTR(funcMPTR, 1); ppcDefineParamU32(customParam, 2); if (g_fp.isAdminMode == false) { osLib_returnFromFunction(hCPU, 0xC0C00800); return; } *uknR3 = 1; StackAllocator callbackResultCode; *callbackResultCode.GetPointer() = 0; hCPU->gpr[3] = callbackResultCode.GetMPTR(); hCPU->gpr[4] = customParam; PPCCore_executeCallbackInternal(funcMPTR); osLib_returnFromFunction(hCPU, 0); } void export_IsPreferenceValid(PPCInterpreter_t* hCPU) { forceLogDebug_printf("nn_fp.IsPreferenceValid()"); fpdPrepareRequest(); fpdRequest->requestCode = iosu::fpd::IOSU_FPD_IS_PREFERENCE_VALID; __depr__IOS_Ioctlv(IOS_DEVICE_FPD, IOSU_FPD_REQUEST_CEMU, 1, 1, fpdBufferVector); osLib_returnFromFunction(hCPU, fpdRequest->resultU32.u32); } void export_UpdatePreferenceAsync(PPCInterpreter_t* hCPU) { forceLogDebug_printf("nn_fp.UpdatePreferenceAsync(0x%08x,0x%08x,0x%08x) - placeholder", hCPU->gpr[3], hCPU->gpr[4], hCPU->gpr[5]); ppcDefineParamTypePtr(uknR3, uint8, 0); ppcDefineParamMPTR(funcMPTR, 1); ppcDefineParamU32(customParam, 2); if (g_fp.isAdminMode == false) { osLib_returnFromFunction(hCPU, 0xC0C00800); return; } //*uknR3 = 0; // seems to be 3 bytes (nn::fp::Preference const *) StackAllocator callbackResultCode; *callbackResultCode.GetPointer() = 0; hCPU->gpr[3] = callbackResultCode.GetMPTR(); hCPU->gpr[4] = customParam; PPCCore_executeCallbackInternal(funcMPTR); osLib_returnFromFunction(hCPU, 0); } void export_UpdateGameMode(PPCInterpreter_t* hCPU) { forceLogDebug_printf("nn_fp.UpdateGameMode(0x%08x,0x%08x,%d)", hCPU->gpr[3], hCPU->gpr[4], hCPU->gpr[5]); ppcDefineParamMEMPTR(gameMode, iosu::fpd::gameMode_t, 0); ppcDefineParamMEMPTR(gameModeMessage, uint16be, 1); ppcDefineParamU32(uknR5, 2); fpdPrepareRequest(); fpdRequest->requestCode = iosu::fpd::IOSU_FPD_UPDATE_GAMEMODE; fpdRequest->updateGameMode.gameMode = gameMode; fpdRequest->updateGameMode.gameModeMessage = gameModeMessage; __depr__IOS_Ioctlv(IOS_DEVICE_FPD, IOSU_FPD_REQUEST_CEMU, 1, 1, fpdBufferVector); osLib_returnFromFunction(hCPU, 0); } void export_GetRequestBlockSettingAsync(PPCInterpreter_t* hCPU) { ppcDefineParamTypePtr(settingList, uint8, 0); ppcDefineParamTypePtr(pidList, uint32be, 1); ppcDefineParamU32(pidCount, 2); ppcDefineParamMPTR(funcMPTR, 3); ppcDefineParamMPTR(customParam, 4); forceLogDebug_printf("GetRequestBlockSettingAsync(...) - todo"); for (uint32 i = 0; i < pidCount; i++) settingList[i] = 0; // 0 means not blocked. Friend app will continue with GetBasicInformation() // 1 means blocked. Friend app will continue with AddFriendAsync to add the user as a provisional friend StackAllocator callbackResultCode; *callbackResultCode.GetPointer() = 0; hCPU->gpr[3] = callbackResultCode.GetMPTR(); hCPU->gpr[4] = customParam; PPCCore_executeCallbackInternal(funcMPTR); osLib_returnFromFunction(hCPU, 0); } void export_AddFriendAsync(PPCInterpreter_t* hCPU) { // AddFriendAsync__Q2_2nn2fpFPCcPFQ2_2nn6ResultPv_vPv ppcDefineParamU32(principalId, 0); ppcDefineParamMPTR(funcMPTR, 1); ppcDefineParamMPTR(customParam, 2); #ifdef CEMU_DEBUG_ASSERT assert_dbg(); #endif fpdPrepareRequest(); fpdRequest->requestCode = iosu::fpd::IOSU_FPD_ADD_FRIEND; fpdRequest->addOrRemoveFriend.pid = principalId; fpdRequest->addOrRemoveFriend.funcPtr = funcMPTR; fpdRequest->addOrRemoveFriend.custom = customParam; __depr__IOS_Ioctlv(IOS_DEVICE_FPD, IOSU_FPD_REQUEST_CEMU, 1, 1, fpdBufferVector); osLib_returnFromFunction(hCPU, fpdRequest->returnCode); } void export_DeleteFriendFlagsAsync(PPCInterpreter_t* hCPU) { forceLogDebug_printf("nn_fp.DeleteFriendFlagsAsync(...) - todo"); ppcDefineParamU32(uknR3, 0); // example value: pointer ppcDefineParamU32(uknR4, 1); // example value: 1 ppcDefineParamU32(uknR5, 2); // example value: 1 ppcDefineParamMPTR(funcMPTR, 3); ppcDefineParamU32(customParam, 4); if (g_fp.isAdminMode == false) { osLib_returnFromFunction(hCPU, 0xC0C00800); return; } StackAllocator callbackResultCode; *callbackResultCode.GetPointer() = 0; hCPU->gpr[3] = callbackResultCode.GetMPTR(); hCPU->gpr[4] = customParam; PPCCore_executeCallbackInternal(funcMPTR); osLib_returnFromFunction(hCPU, 0); } typedef struct { /* +0x00 */ uint32be pid; /* +0x04 */ uint8 ukn04; /* +0x05 */ uint8 ukn05; /* +0x06 */ uint8 ukn06[0x22]; /* +0x28 */ uint8 ukn28[0x22]; /* +0x4A */ uint8 _uknOrPadding4A[6]; /* +0x50 */ uint32be ukn50; /* +0x54 */ uint32be ukn54; /* +0x58 */ uint16be ukn58; /* +0x5C */ uint8 _padding5C[4]; /* +0x60 */ iosu::fpd::fpdDate_t date; }RecentPlayRecordEx_t; static_assert(sizeof(RecentPlayRecordEx_t) == 0x68, ""); static_assert(offsetof(RecentPlayRecordEx_t, ukn06) == 0x06, ""); static_assert(offsetof(RecentPlayRecordEx_t, ukn50) == 0x50, ""); void export_AddFriendRequestAsync(PPCInterpreter_t* hCPU) { ppcDefineParamTypePtr(playRecord, RecentPlayRecordEx_t, 0); ppcDefineParamTypePtr(message, uint16be, 1); ppcDefineParamMPTR(funcMPTR, 2); ppcDefineParamMPTR(customParam, 3); fpdPrepareRequest(); uint8* uknData = (uint8*)playRecord; fpdRequest->requestCode = iosu::fpd::IOSU_FPD_ADD_FRIEND_REQUEST; fpdRequest->addFriendRequest.pid = playRecord->pid; fpdRequest->addFriendRequest.message = message; fpdRequest->addFriendRequest.funcPtr = funcMPTR; fpdRequest->addFriendRequest.custom = customParam; __depr__IOS_Ioctlv(IOS_DEVICE_FPD, IOSU_FPD_REQUEST_CEMU, 1, 1, fpdBufferVector); osLib_returnFromFunction(hCPU, fpdRequest->returnCode); } void export_RemoveFriendAsync(PPCInterpreter_t* hCPU) { ppcDefineParamU32(principalId, 0); ppcDefineParamMPTR(funcMPTR, 1); ppcDefineParamMPTR(customParam, 2); fpdPrepareRequest(); fpdRequest->requestCode = iosu::fpd::IOSU_FPD_REMOVE_FRIEND_ASYNC; fpdRequest->addOrRemoveFriend.pid = principalId; fpdRequest->addOrRemoveFriend.funcPtr = funcMPTR; fpdRequest->addOrRemoveFriend.custom = customParam; __depr__IOS_Ioctlv(IOS_DEVICE_FPD, IOSU_FPD_REQUEST_CEMU, 1, 1, fpdBufferVector); osLib_returnFromFunction(hCPU, fpdRequest->returnCode); } void export_MarkFriendRequestsAsReceivedAsync(PPCInterpreter_t* hCPU) { ppcDefineParamTypePtr(messageIdList, uint64, 0); ppcDefineParamU32(count, 1); ppcDefineParamMPTR(funcMPTR, 2); ppcDefineParamMPTR(customParam, 3); fpdPrepareRequest(); fpdRequest->requestCode = iosu::fpd::IOSU_FPD_MARK_FRIEND_REQUEST_AS_RECEIVED_ASYNC; fpdRequest->markFriendRequest.messageIdList = messageIdList; fpdRequest->markFriendRequest.count = count; fpdRequest->markFriendRequest.funcPtr = funcMPTR; fpdRequest->markFriendRequest.custom = customParam; __depr__IOS_Ioctlv(IOS_DEVICE_FPD, IOSU_FPD_REQUEST_CEMU, 1, 1, fpdBufferVector); osLib_returnFromFunction(hCPU, fpdRequest->returnCode); } void export_CancelFriendRequestAsync(PPCInterpreter_t* hCPU) { ppcDefineParamU64(frqMessageId, 0); ppcDefineParamMPTR(funcMPTR, 2); ppcDefineParamMPTR(customParam, 3); fpdPrepareRequest(); fpdRequest->requestCode = iosu::fpd::IOSU_FPD_CANCEL_FRIEND_REQUEST_ASYNC; fpdRequest->cancelOrAcceptFriendRequest.messageId = frqMessageId; fpdRequest->cancelOrAcceptFriendRequest.funcPtr = funcMPTR; fpdRequest->cancelOrAcceptFriendRequest.custom = customParam; __depr__IOS_Ioctlv(IOS_DEVICE_FPD, IOSU_FPD_REQUEST_CEMU, 1, 1, fpdBufferVector); osLib_returnFromFunction(hCPU, fpdRequest->returnCode); } void export_AcceptFriendRequestAsync(PPCInterpreter_t* hCPU) { ppcDefineParamU64(frqMessageId, 0); ppcDefineParamMPTR(funcMPTR, 2); ppcDefineParamMPTR(customParam, 3); fpdPrepareRequest(); fpdRequest->requestCode = iosu::fpd::IOSU_FPD_ACCEPT_FRIEND_REQUEST_ASYNC; fpdRequest->cancelOrAcceptFriendRequest.messageId = frqMessageId; fpdRequest->cancelOrAcceptFriendRequest.funcPtr = funcMPTR; fpdRequest->cancelOrAcceptFriendRequest.custom = customParam; __depr__IOS_Ioctlv(IOS_DEVICE_FPD, IOSU_FPD_REQUEST_CEMU, 1, 1, fpdBufferVector); osLib_returnFromFunction(hCPU, fpdRequest->returnCode); } void load() { osLib_addFunction("nn_fp", "Initialize__Q2_2nn2fpFv", export_Initialize); osLib_addFunction("nn_fp", "InitializeAdmin__Q2_2nn2fpFv", export_InitializeAdmin); osLib_addFunction("nn_fp", "IsInitialized__Q2_2nn2fpFv", export_IsInitialized); osLib_addFunction("nn_fp", "IsInitializedAdmin__Q2_2nn2fpFv", export_IsInitializedAdmin); osLib_addFunction("nn_fp", "SetNotificationHandler__Q2_2nn2fpFUiPFQ3_2nn2fp16NotificationTypeUiPv_vPv", export_SetNotificationHandler); osLib_addFunction("nn_fp", "LoginAsync__Q2_2nn2fpFPFQ2_2nn6ResultPv_vPv", export_LoginAsync); osLib_addFunction("nn_fp", "HasLoggedIn__Q2_2nn2fpFv", export_HasLoggedIn); osLib_addFunction("nn_fp", "IsOnline__Q2_2nn2fpFv", export_IsOnline); osLib_addFunction("nn_fp", "GetFriendList__Q2_2nn2fpFPUiT1UiT3", export_GetFriendList); osLib_addFunction("nn_fp", "GetFriendRequestList__Q2_2nn2fpFPUiT1UiT3", export_GetFriendRequestList); osLib_addFunction("nn_fp", "GetFriendListAll__Q2_2nn2fpFPUiT1UiT3", export_GetFriendListAll); osLib_addFunction("nn_fp", "GetFriendListEx__Q2_2nn2fpFPQ3_2nn2fp10FriendDataPCUiUi", export_GetFriendListEx); osLib_addFunction("nn_fp", "GetFriendRequestListEx__Q2_2nn2fpFPQ3_2nn2fp13FriendRequestPCUiUi", export_GetFriendRequestListEx); osLib_addFunction("nn_fp", "GetBasicInfoAsync__Q2_2nn2fpFPQ3_2nn2fp9BasicInfoPCUiUiPFQ2_2nn6ResultPv_vPv", export_GetBasicInfoAsync); osLib_addFunction("nn_fp", "GetMyPrincipalId__Q2_2nn2fpFv", export_GetMyPrincipalId); osLib_addFunction("nn_fp", "GetMyAccountId__Q2_2nn2fpFPc", export_GetMyAccountId); osLib_addFunction("nn_fp", "GetMyScreenName__Q2_2nn2fpFPw", export_GetMyScreenName); osLib_addFunction("nn_fp", "GetMyMii__Q2_2nn2fpFP12FFLStoreData", export_GetMyMii); osLib_addFunction("nn_fp", "GetMyPreference__Q2_2nn2fpFPQ3_2nn2fp10Preference", export_GetMyPreference); osLib_addFunction("nn_fp", "GetFriendAccountId__Q2_2nn2fpFPA17_cPCUiUi", export_GetFriendAccountId); osLib_addFunction("nn_fp", "GetFriendScreenName__Q2_2nn2fpFPA11_wPCUiUibPUc", export_GetFriendScreenName); osLib_addFunction("nn_fp", "GetFriendMii__Q2_2nn2fpFP12FFLStoreDataPCUiUi", export_GetFriendMii); osLib_addFunction("nn_fp", "GetFriendPresence__Q2_2nn2fpFPQ3_2nn2fp14FriendPresencePCUiUi", export_GetFriendPresence); osLib_addFunction("nn_fp", "GetFriendRelationship__Q2_2nn2fpFPUcPCUiUi", export_GetFriendRelationship); osLib_addFunction("nn_fp", "IsJoinable__Q2_2nn2fpFPCQ3_2nn2fp14FriendPresenceUL", export_IsJoinable); osLib_addFunction("nn_fp", "CheckSettingStatusAsync__Q2_2nn2fpFPUcPFQ2_2nn6ResultPv_vPv", export_CheckSettingStatusAsync); osLib_addFunction("nn_fp", "IsPreferenceValid__Q2_2nn2fpFv", export_IsPreferenceValid); osLib_addFunction("nn_fp", "UpdatePreferenceAsync__Q2_2nn2fpFPCQ3_2nn2fp10PreferencePFQ2_2nn6ResultPv_vPv", export_UpdatePreferenceAsync); osLib_addFunction("nn_fp", "UpdateGameMode__Q2_2nn2fpFPCQ3_2nn2fp8GameModePCwUi", export_UpdateGameMode); osLib_addFunction("nn_fp", "GetRequestBlockSettingAsync__Q2_2nn2fpFPUcPCUiUiPFQ2_2nn6ResultPv_vPv", export_GetRequestBlockSettingAsync); osLib_addFunction("nn_fp", "AddFriendAsync__Q2_2nn2fpFPCcPFQ2_2nn6ResultPv_vPv", export_AddFriendAsync); osLib_addFunction("nn_fp", "AddFriendRequestAsync__Q2_2nn2fpFPCQ3_2nn2fp18RecentPlayRecordExPCwPFQ2_2nn6ResultPv_vPv", export_AddFriendRequestAsync); osLib_addFunction("nn_fp", "DeleteFriendFlagsAsync__Q2_2nn2fpFPCUiUiT2PFQ2_2nn6ResultPv_vPv", export_DeleteFriendFlagsAsync); osLib_addFunction("nn_fp", "RemoveFriendAsync__Q2_2nn2fpFUiPFQ2_2nn6ResultPv_vPv", export_RemoveFriendAsync); osLib_addFunction("nn_fp", "MarkFriendRequestsAsReceivedAsync__Q2_2nn2fpFPCULUiPFQ2_2nn6ResultPv_vPv", export_MarkFriendRequestsAsReceivedAsync); osLib_addFunction("nn_fp", "CancelFriendRequestAsync__Q2_2nn2fpFULPFQ2_2nn6ResultPv_vPv", export_CancelFriendRequestAsync); osLib_addFunction("nn_fp", "AcceptFriendRequestAsync__Q2_2nn2fpFULPFQ2_2nn6ResultPv_vPv", export_AcceptFriendRequestAsync); } } }