#include "services/mic.hpp" #include "ipc.hpp" namespace MICCommands { enum : u32 { MapSharedMem = 0x00010042, StartSampling = 0x00030140, StopSampling = 0x00050000, SetGain = 0x00080040, GetGain = 0x00090000, SetPower = 0x000A0040, SetIirFilter = 0x000C0042, SetClamp = 0x000D0040, CaptainToadFunction = 0x00100040, }; } void MICService::reset() { micEnabled = false; shouldClamp = false; isSampling = false; gain = 0; } void MICService::handleSyncRequest(u32 messagePointer) { const u32 command = mem.read32(messagePointer); switch (command) { case MICCommands::GetGain: getGain(messagePointer); break; case MICCommands::MapSharedMem: mapSharedMem(messagePointer); break; case MICCommands::SetClamp: setClamp(messagePointer); break; case MICCommands::SetGain: setGain(messagePointer); break; case MICCommands::SetIirFilter: setIirFilter(messagePointer); break; case MICCommands::SetPower: setPower(messagePointer); break; case MICCommands::StartSampling: startSampling(messagePointer); break; case MICCommands::StopSampling: stopSampling(messagePointer); break; case MICCommands::CaptainToadFunction: theCaptainToadFunction(messagePointer); break; default: Helpers::panic("MIC service requested. Command: %08X\n", command); } } void MICService::mapSharedMem(u32 messagePointer) { u32 size = mem.read32(messagePointer + 4); u32 handle = mem.read32(messagePointer + 12); log("MIC::MapSharedMem (size = %08X, handle = %X) (stubbed)\n", size, handle); mem.write32(messagePointer, IPC::responseHeader(0x1, 1, 0)); mem.write32(messagePointer + 4, Result::Success); } void MICService::getGain(u32 messagePointer) { log("MIC::GetGain\n"); mem.write32(messagePointer, IPC::responseHeader(0x9, 2, 0)); mem.write32(messagePointer + 4, Result::Success); mem.write8(messagePointer + 8, gain); } void MICService::setGain(u32 messagePointer) { gain = mem.read8(messagePointer + 4); log("MIC::SetGain (value = %d)\n", gain); mem.write32(messagePointer, IPC::responseHeader(0x8, 1, 0)); mem.write32(messagePointer + 4, Result::Success); } void MICService::setPower(u32 messagePointer) { u8 val = mem.read8(messagePointer + 4); log("MIC::SetPower (value = %d)\n", val); micEnabled = val != 0; mem.write32(messagePointer, IPC::responseHeader(0xA, 1, 0)); mem.write32(messagePointer + 4, Result::Success); } void MICService::setClamp(u32 messagePointer) { u8 val = mem.read8(messagePointer + 4); log("MIC::SetClamp (value = %d)\n", val); shouldClamp = val != 0; mem.write32(messagePointer, IPC::responseHeader(0xD, 1, 0)); mem.write32(messagePointer + 4, Result::Success); } void MICService::startSampling(u32 messagePointer) { u8 encoding = mem.read8(messagePointer + 4); u8 sampleRate = mem.read8(messagePointer + 8); u32 offset = mem.read32(messagePointer + 12); u32 dataSize = mem.read32(messagePointer + 16); bool loop = mem.read8(messagePointer + 20); log("MIC::StartSampling (encoding = %d, sample rate = %d, offset = %08X, size = %08X, loop: %s) (stubbed)\n", encoding, sampleRate, offset, dataSize, loop ? "yes" : "no" ); isSampling = 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; mem.write32(messagePointer, IPC::responseHeader(0x5, 1, 0)); mem.write32(messagePointer + 4, Result::Success); } void MICService::setIirFilter(u32 messagePointer) { const u32 size = mem.read32(messagePointer + 4); const u32 pointer = mem.read32(messagePointer + 12); log("MIC::SetIirFilter (size = %X, pointer = %08X) (Stubbed)\n", size, pointer); mem.write32(messagePointer, IPC::responseHeader(0x0C, 1, 2)); mem.write32(messagePointer + 4, Result::Success); } // Found in Captain Toad: Treasure Tracker // This is what 3DBrew says: // When the input value is 0, value 1 is written to an u8 MIC module state field. // Otherwise, value 0 is written there.Normally the input value is non - zero. // Citra calls it setClientVersion but no idea how they got that void MICService::theCaptainToadFunction(u32 messagePointer) { log("MIC: Unknown function 0x00100040\n"); mem.write32(messagePointer, IPC::responseHeader(0x10, 1, 0)); mem.write32(messagePointer + 4, Result::Success); }