Merge branch 'master' into mii_selector

This commit is contained in:
wheremyfoodat 2023-08-24 15:45:38 +03:00
commit 52304763bb
10 changed files with 141 additions and 26 deletions

View file

@ -8,11 +8,15 @@ namespace ACCommands {
CloseAsync = 0x00080004,
GetLastErrorCode = 0x000A0000,
RegisterDisconnectEvent = 0x00300004,
IsConnected = 0x003E0042,
SetClientVersion = 0x00400042,
};
}
void ACService::reset() {}
void ACService::reset() {
connected = false;
disconnectEvent = std::nullopt;
}
void ACService::handleSyncRequest(u32 messagePointer) {
const u32 command = mem.read32(messagePointer);
@ -21,6 +25,7 @@ void ACService::handleSyncRequest(u32 messagePointer) {
case ACCommands::CloseAsync: closeAsync(messagePointer); break;
case ACCommands::CreateDefaultConfig: createDefaultConfig(messagePointer); break;
case ACCommands::GetLastErrorCode: getLastErrorCode(messagePointer); break;
case ACCommands::IsConnected: isConnected(messagePointer); break;
case ACCommands::RegisterDisconnectEvent: registerDisconnectEvent(messagePointer); break;
case ACCommands::SetClientVersion: setClientVersion(messagePointer); break;
default: Helpers::panic("AC service requested. Command: %08X\n", command);
@ -37,6 +42,11 @@ void ACService::cancelConnectAsync(u32 messagePointer) {
void ACService::closeAsync(u32 messagePointer) {
log("AC::CloseAsync (stubbed)\n");
connected = false;
if (disconnectEvent.has_value()) {
Helpers::warn("AC::DisconnectEvent should be signalled but isn't implemented yet");
}
// TODO: Verify if this response header is correct on hardware
mem.write32(messagePointer, IPC::responseHeader(0x8, 1, 0));
@ -59,6 +69,15 @@ void ACService::getLastErrorCode(u32 messagePointer) {
mem.write32(messagePointer + 8, 0); // Hopefully this means no error?
}
void ACService::isConnected(u32 messagePointer) {
log("AC::IsConnected\n");
// This has parameters according to the command word but it's unknown what they are
mem.write32(messagePointer, IPC::responseHeader(0x3E, 2, 0));
mem.write32(messagePointer + 4, Result::Success);
mem.write8(messagePointer + 8, connected ? 1 : 0);
}
void ACService::setClientVersion(u32 messagePointer) {
u32 version = mem.read32(messagePointer + 4);
log("AC::SetClientVersion (version = %d)\n", version);
@ -71,9 +90,11 @@ void ACService::registerDisconnectEvent(u32 messagePointer) {
log("AC::RegisterDisconnectEvent (stubbed)\n");
const u32 pidHeader = mem.read32(messagePointer + 4);
const u32 copyHandleHeader = mem.read32(messagePointer + 12);
// Event signaled when disconnecting from AC
// Event signaled when disconnecting from AC. TODO: Properly implement it.
const Handle eventHandle = mem.read32(messagePointer + 16);
disconnectEvent = eventHandle;
mem.write32(messagePointer, IPC::responseHeader(0x30, 1, 0));
mem.write32(messagePointer + 4, Result::Success);
}

View file

@ -19,6 +19,7 @@ namespace FRDCommands {
GetMyMii = 0x000A0000,
GetFriendKeyList = 0x00110080,
GetFriendPresence = 0x00120042,
GetFriendProfile = 0x00150042,
GetFriendAttributeFlags = 0x00170042,
UpdateGameModeDescription = 0x001D0002,
};
@ -33,6 +34,7 @@ void FRDService::handleSyncRequest(u32 messagePointer) {
case FRDCommands::GetFriendAttributeFlags: getFriendAttributeFlags(messagePointer); break;
case FRDCommands::GetFriendKeyList: getFriendKeyList(messagePointer); break;
case FRDCommands::GetFriendPresence: getFriendPresence(messagePointer); break;
case FRDCommands::GetFriendProfile: getFriendProfile(messagePointer); break;
case FRDCommands::GetMyFriendKey: getMyFriendKey(messagePointer); break;
case FRDCommands::GetMyMii: getMyMii(messagePointer); break;
case FRDCommands::GetMyPresence: getMyPresence(messagePointer); break;
@ -87,6 +89,41 @@ void FRDService::getFriendKeyList(u32 messagePointer) {
}
}
void FRDService::getFriendProfile(u32 messagePointer) {
log("FRD::GetFriendProfile\n");
const u32 count = mem.read32(messagePointer + 4);
const u32 friendKeyList = mem.read32(messagePointer + 12); // Pointer to list of friend keys
const u32 profile = mem.read32(messagePointer + 0x104); // Pointer to friend profile where we'll write info to
mem.write32(messagePointer, IPC::responseHeader(0x15, 1, 2));
mem.write32(messagePointer + 4, Result::Success);
// Clear all profiles
for (u32 i = 0; i < count; i++) {
const u32 pointer = profile + (i * sizeof(Profile));
for (u32 j = 0; j < sizeof(Profile); j++) {
mem.write8(pointer + j, 0);
}
}
}
void FRDService::getFriendAttributeFlags(u32 messagePointer) {
log("FRD::GetFriendAttributeFlags\n");
const u32 count = mem.read32(messagePointer + 4);
const u32 friendKeyList = mem.read32(messagePointer + 12); // Pointer to list of friend keys
const u32 profile = mem.read32(messagePointer + 0x104); // Pointer to friend profile where we'll write info to
mem.write32(messagePointer, IPC::responseHeader(0x17, 1, 2));
mem.write32(messagePointer + 4, Result::Success);
// Clear flags
for (u32 i = 0; i < count; i++) {
mem.write8(profile + i, 0);
}
}
void FRDService::getMyPresence(u32 messagePointer) {
static constexpr u32 presenceSize = 0x12C; // A presence seems to be 12C bytes of data, not sure what it contains
log("FRD::GetMyPresence\n");
@ -100,21 +137,6 @@ void FRDService::getMyPresence(u32 messagePointer) {
mem.write32(messagePointer + 4, Result::Success);
}
void FRDService::getFriendAttributeFlags(u32 messagePointer) {
log("FRD::GetFriendAttributeFlags\n");
const u32 count = mem.read32(messagePointer + 4);
const u32 buffer = mem.read32(messagePointer + 0x104); // Buffer to write flag info to.
// Clear all flags. Assume one flag == 1 byte (u8) for now.
for (u32 i = 0; i < count; i++) {
const u32 pointer = buffer + (i * sizeof(u8));
for (u32 j = 0; j < sizeof(u8); j++) {
mem.write8(pointer + j, 0);
}
}
}
void FRDService::getFriendPresence(u32 messagePointer) {
Helpers::warn("FRD::GetFriendPresence (stubbed)");

View file

@ -1,11 +1,15 @@
#include "services/mic.hpp"
#include "ipc.hpp"
#include "kernel/kernel.hpp"
namespace MICCommands {
enum : u32 {
MapSharedMem = 0x00010042,
UnmapSharedMem = 0x00020000,
StartSampling = 0x00030140,
StopSampling = 0x00050000,
IsSampling = 0x00060000,
GetEventHandle = 0x00070000,
SetGain = 0x00080040,
GetGain = 0x00090000,
SetPower = 0x000A0040,
@ -18,14 +22,18 @@ namespace MICCommands {
void MICService::reset() {
micEnabled = false;
shouldClamp = false;
isSampling = false;
currentlySampling = false;
gain = 0;
eventHandle = std::nullopt;
}
void MICService::handleSyncRequest(u32 messagePointer) {
const u32 command = mem.read32(messagePointer);
switch (command) {
case MICCommands::GetEventHandle: getEventHandle(messagePointer); break;
case MICCommands::GetGain: getGain(messagePointer); break;
case MICCommands::IsSampling: isSampling(messagePointer); break;
case MICCommands::MapSharedMem: mapSharedMem(messagePointer); break;
case MICCommands::SetClamp: setClamp(messagePointer); break;
case MICCommands::SetGain: setGain(messagePointer); break;
@ -33,6 +41,7 @@ void MICService::handleSyncRequest(u32 messagePointer) {
case MICCommands::SetPower: setPower(messagePointer); break;
case MICCommands::StartSampling: startSampling(messagePointer); break;
case MICCommands::StopSampling: stopSampling(messagePointer); break;
case MICCommands::UnmapSharedMem: unmapSharedMem(messagePointer); break;
case MICCommands::CaptainToadFunction: theCaptainToadFunction(messagePointer); break;
default: Helpers::panic("MIC service requested. Command: %08X\n", command);
}
@ -47,6 +56,27 @@ void MICService::mapSharedMem(u32 messagePointer) {
mem.write32(messagePointer + 4, Result::Success);
}
void MICService::unmapSharedMem(u32 messagePointer) {
log("MIC::UnmapSharedMem (stubbed)\n");
mem.write32(messagePointer, IPC::responseHeader(0x2, 1, 0));
mem.write32(messagePointer + 4, Result::Success);
}
void MICService::getEventHandle(u32 messagePointer) {
log("MIC::GetEventHandle\n");
Helpers::warn("Acquire MIC event handle");
if (!eventHandle.has_value()) {
eventHandle = kernel.makeEvent(ResetType::OneShot);
}
mem.write32(messagePointer, IPC::responseHeader(0x7, 1, 2));
mem.write32(messagePointer + 4, Result::Success);
// TODO: Translation descriptor
mem.write32(messagePointer + 12, eventHandle.value());
}
void MICService::getGain(u32 messagePointer) {
log("MIC::GetGain\n");
mem.write32(messagePointer, IPC::responseHeader(0x9, 2, 0));
@ -91,19 +121,27 @@ void MICService::startSampling(u32 messagePointer) {
encoding, sampleRate, offset, dataSize, loop ? "yes" : "no"
);
isSampling = true;
currentlySampling = true;
mem.write32(messagePointer, IPC::responseHeader(0x3, 1, 0));
mem.write32(messagePointer + 4, Result::Success);
}
void MICService::stopSampling(u32 messagePointer) {
log("MIC::StopSampling\n");
isSampling = false;
currentlySampling = false;
mem.write32(messagePointer, IPC::responseHeader(0x5, 1, 0));
mem.write32(messagePointer + 4, Result::Success);
}
void MICService::isSampling(u32 messagePointer) {
log("MIC::IsSampling");
mem.write32(messagePointer, IPC::responseHeader(0x6, 2, 0));
mem.write32(messagePointer + 4, Result::Success);
mem.write8(messagePointer + 8, currentlySampling ? 1 : 0);
}
void MICService::setIirFilter(u32 messagePointer) {
const u32 size = mem.read32(messagePointer + 4);
const u32 pointer = mem.read32(messagePointer + 12);

View file

@ -8,7 +8,7 @@
ServiceManager::ServiceManager(std::span<u32, 16> regs, Memory& mem, GPU& gpu, u32& currentPID, Kernel& kernel, const EmulatorConfig& config)
: regs(regs), mem(mem), kernel(kernel), ac(mem), am(mem), boss(mem), act(mem), apt(mem, kernel), cam(mem, kernel), cecd(mem, kernel), cfg(mem),
dlp_srvr(mem), dsp(mem, kernel), hid(mem, kernel), http(mem), ir_user(mem, kernel), frd(mem), fs(mem, kernel),
gsp_gpu(mem, gpu, kernel, currentPID), gsp_lcd(mem), ldr(mem), mcu_hwc(mem, config), mic(mem), nfc(mem, kernel), nim(mem), ndm(mem),
gsp_gpu(mem, gpu, kernel, currentPID), gsp_lcd(mem), ldr(mem), mcu_hwc(mem, config), mic(mem, kernel), nfc(mem, kernel), nim(mem), ndm(mem),
news_u(mem), ptm(mem, config), soc(mem), ssl(mem), y2r(mem, kernel) {}
static constexpr int MAX_NOTIFICATION_COUNT = 16;