void Module::Interface::UnscrambleLocalFriendCode(Kernel::HLERequestContext& ctx) { const std::size_t scrambled_friend_code_size = 12; const std::size_t friend_code_size = 8; IPC::RequestParser rp(ctx, 0x1C, 1, 2); const u32 friend_code_count = rp.Pop<u32>(); std::vector<u8> scrambled_friend_codes = rp.PopStaticBuffer(); ASSERT_MSG(scrambled_friend_codes.size() == (friend_code_count * scrambled_friend_code_size), "Wrong input buffer size"); std::vector<u8> unscrambled_friend_codes(friend_code_count * friend_code_size, 0); // TODO(B3N30): Unscramble the codes and compare them against the friend list // Only write 0 if the code isn't in friend list, otherwise write the // unscrambled one // // Code for unscrambling (should be compared to HW): // std::array<u16, 6> scambled_friend_code; // Memory::ReadBlock(scrambled_friend_codes+(current*scrambled_friend_code_size), // scambled_friend_code.data(), scrambled_friend_code_size); std::array<u16, 4> // unscrambled_friend_code; unscrambled_friend_code[0] = scambled_friend_code[0] ^ // scambled_friend_code[5]; unscrambled_friend_code[1] = scambled_friend_code[1] ^ // scambled_friend_code[5]; unscrambled_friend_code[2] = scambled_friend_code[2] ^ // scambled_friend_code[5]; unscrambled_friend_code[3] = scambled_friend_code[3] ^ // scambled_friend_code[5]; LOG_WARNING(Service_FRD, "(STUBBED) called"); IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); rb.Push(RESULT_SUCCESS); rb.PushStaticBuffer(unscrambled_friend_codes, 0); }
void GSP_GPU::ReadHWRegs(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp(ctx, 0x4, 2, 0); u32 reg_addr = rp.Pop<u32>(); u32 input_size = rp.Pop<u32>(); static constexpr u32 MaxReadSize = 0x80; u32 size = std::min(input_size, MaxReadSize); if ((reg_addr % 4) != 0 || reg_addr >= 0x420000) { IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); rb.Push(ERR_REGS_OUTOFRANGE_OR_MISALIGNED); LOG_ERROR(Service_GSP, "Invalid address 0x{:08x}", reg_addr); return; } // size should be word-aligned if ((size % 4) != 0) { IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); rb.Push(ERR_REGS_MISALIGNED); LOG_ERROR(Service_GSP, "Invalid size 0x{:08x}", size); return; } std::vector<u8> buffer(size); for (u32 offset = 0; offset < size; ++offset) { HW::Read<u8>(buffer[offset], REGS_BEGIN + reg_addr + offset); } IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); rb.Push(RESULT_SUCCESS); rb.PushStaticBuffer(std::move(buffer), 0); }
void Module::Interface::GetFriendAttributeFlags(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp(ctx, 0x17, 1, 2); u32 count = rp.Pop<u32>(); std::vector<u8> frd_keys = rp.PopStaticBuffer(); ASSERT(frd_keys.size() == count * sizeof(FriendKey)); // TODO:(mailwl) figure out AttributeFlag size and zero all buffer. Assume 1 byte std::vector<u8> buffer(1 * count, 0); IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); rb.Push(RESULT_SUCCESS); rb.PushStaticBuffer(buffer, 0); LOG_WARNING(Service_FRD, "(STUBBED) called, count={}", count); }
void Module::Interface::GetFriendProfile(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp(ctx, 0x15, 1, 2); u32 count = rp.Pop<u32>(); std::vector<u8> frd_keys = rp.PopStaticBuffer(); ASSERT(frd_keys.size() == count * sizeof(FriendKey)); std::vector<u8> buffer(sizeof(Profile) * count, 0); IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); rb.Push(RESULT_SUCCESS); rb.PushStaticBuffer(buffer, 0); LOG_WARNING(Service_FRD, "(STUBBED) called, count={}", count); }
void Module::Interface::GetFriendKeyList(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp(ctx, 0x11, 2, 0); u32 unknown = rp.Pop<u32>(); u32 frd_count = rp.Pop<u32>(); std::vector<u8> buffer(sizeof(FriendKey) * frd_count, 0); IPC::RequestBuilder rb = rp.MakeBuilder(2, 2); rb.Push(RESULT_SUCCESS); rb.Push<u32>(0); // 0 friends rb.PushStaticBuffer(buffer, 0); LOG_WARNING(Service_FRD, "(STUBBED) called, unknown={}, frd_count={}", unknown, frd_count); }