mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-08 07:05:40 +12:00
Merge branch 'master' into mii_selector
This commit is contained in:
commit
52304763bb
10 changed files with 141 additions and 26 deletions
9
.github/mac-bundle.sh
vendored
9
.github/mac-bundle.sh
vendored
|
@ -36,6 +36,15 @@ PlistBuddy Alber.app/Contents/Info.plist -c "add CFBundleIconFile string AppIcon
|
||||||
PlistBuddy Alber.app/Contents/Info.plist -c "add NSHighResolutionCapable bool true"
|
PlistBuddy Alber.app/Contents/Info.plist -c "add NSHighResolutionCapable bool true"
|
||||||
PlistBuddy Alber.app/Contents/version.plist -c "add ProjectName string Alber"
|
PlistBuddy Alber.app/Contents/version.plist -c "add ProjectName string Alber"
|
||||||
|
|
||||||
|
PlistBuddy Alber.app/Contents/Info.plist -c "add CFBundleExecutable string Alber"
|
||||||
|
PlistBuddy Alber.app/Contents/Info.plist -c "add CFBundleDevelopmentRegion string en"
|
||||||
|
PlistBuddy Alber.app/Contents/Info.plist -c "add CFBundleInfoDictionaryVersion string 6.0"
|
||||||
|
PlistBuddy Alber.app/Contents/Info.plist -c "add CFBundleName string Panda3DS"
|
||||||
|
PlistBuddy Alber.app/Contents/Info.plist -c "add CFBundlePackageType string APPL"
|
||||||
|
PlistBuddy Alber.app/Contents/Info.plist -c "add NSHumanReadableCopyright string Copyright 2023 Panda3DS Team"
|
||||||
|
|
||||||
|
PlistBuddy Alber.app/Contents/Info.plist -c "add LSMinimumSystemVersion string 10.15"
|
||||||
|
|
||||||
# Bundle dylibs
|
# Bundle dylibs
|
||||||
dylibbundler -od -b -x Alber.app/Contents/MacOS/Alber -d Alber.app/Contents/Frameworks/ -p @rpath -s /Users/runner/work/Panda3DS/Panda3DS/VULKAN_SDK/lib
|
dylibbundler -od -b -x Alber.app/Contents/MacOS/Alber -d Alber.app/Contents/Frameworks/ -p @rpath -s /Users/runner/work/Panda3DS/Panda3DS/VULKAN_SDK/lib
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# We need to be able to use enable_language(OBJC) on Mac, so we need CMake 3.16 vs the 3.10 we use otherwise. Blame Apple.
|
# We need to be able to use enable_language(OBJC) on Mac, so we need CMake 3.16 vs the 3.10 we use otherwise. Blame Apple.
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "11.0" CACHE STRING "Minimum OS X deployment version")
|
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "Minimum OS X deployment version")
|
||||||
cmake_minimum_required(VERSION 3.16)
|
cmake_minimum_required(VERSION 3.16)
|
||||||
else()
|
else()
|
||||||
cmake_minimum_required(VERSION 3.10)
|
cmake_minimum_required(VERSION 3.10)
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "helpers.hpp"
|
#include "helpers.hpp"
|
||||||
#include "kernel_types.hpp"
|
#include "kernel_types.hpp"
|
||||||
#include "logger.hpp"
|
#include "logger.hpp"
|
||||||
|
@ -15,10 +17,14 @@ class ACService {
|
||||||
void closeAsync(u32 messagePointer);
|
void closeAsync(u32 messagePointer);
|
||||||
void createDefaultConfig(u32 messagePointer);
|
void createDefaultConfig(u32 messagePointer);
|
||||||
void getLastErrorCode(u32 messagePointer);
|
void getLastErrorCode(u32 messagePointer);
|
||||||
|
void isConnected(u32 messagePointer);
|
||||||
void registerDisconnectEvent(u32 messagePointer);
|
void registerDisconnectEvent(u32 messagePointer);
|
||||||
void setClientVersion(u32 messagePointer);
|
void setClientVersion(u32 messagePointer);
|
||||||
|
|
||||||
public:
|
bool connected = false;
|
||||||
|
std::optional<Handle> disconnectEvent = std::nullopt;
|
||||||
|
|
||||||
|
public:
|
||||||
ACService(Memory& mem) : mem(mem) {}
|
ACService(Memory& mem) : mem(mem) {}
|
||||||
void reset();
|
void reset();
|
||||||
void handleSyncRequest(u32 messagePointer);
|
void handleSyncRequest(u32 messagePointer);
|
||||||
|
|
|
@ -26,6 +26,7 @@ class FRDService {
|
||||||
void getFriendAttributeFlags(u32 messagePointer);
|
void getFriendAttributeFlags(u32 messagePointer);
|
||||||
void getFriendKeyList(u32 messagePointer);
|
void getFriendKeyList(u32 messagePointer);
|
||||||
void getFriendPresence(u32 messagePointer);
|
void getFriendPresence(u32 messagePointer);
|
||||||
|
void getFriendProfile(u32 messagePointer);
|
||||||
void getMyFriendKey(u32 messagePointer);
|
void getMyFriendKey(u32 messagePointer);
|
||||||
void getMyMii(u32 messagePointer);
|
void getMyMii(u32 messagePointer);
|
||||||
void getMyPresence(u32 messagePointer);
|
void getMyPresence(u32 messagePointer);
|
||||||
|
@ -37,6 +38,15 @@ class FRDService {
|
||||||
void setNotificationMask(u32 messagePointer);
|
void setNotificationMask(u32 messagePointer);
|
||||||
void updateGameModeDescription(u32 messagePointer);
|
void updateGameModeDescription(u32 messagePointer);
|
||||||
|
|
||||||
|
struct Profile {
|
||||||
|
u8 region;
|
||||||
|
u8 country;
|
||||||
|
u8 area;
|
||||||
|
u8 language;
|
||||||
|
u32 unknown;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(Profile) == 8);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FRDService(Memory& mem) : mem(mem) {}
|
FRDService(Memory& mem) : mem(mem) {}
|
||||||
void reset();
|
void reset();
|
||||||
|
|
|
@ -5,13 +5,19 @@
|
||||||
#include "memory.hpp"
|
#include "memory.hpp"
|
||||||
#include "result/result.hpp"
|
#include "result/result.hpp"
|
||||||
|
|
||||||
|
// Circular dependencies, yay
|
||||||
|
class Kernel;
|
||||||
|
|
||||||
class MICService {
|
class MICService {
|
||||||
Handle handle = KernelHandles::MIC;
|
Handle handle = KernelHandles::MIC;
|
||||||
Memory& mem;
|
Memory& mem;
|
||||||
|
Kernel& kernel;
|
||||||
MAKE_LOG_FUNCTION(log, micLogger)
|
MAKE_LOG_FUNCTION(log, micLogger)
|
||||||
|
|
||||||
// Service commands
|
// Service commands
|
||||||
|
void getEventHandle(u32 messagePointer);
|
||||||
void getGain(u32 messagePointer);
|
void getGain(u32 messagePointer);
|
||||||
|
void isSampling(u32 messagePointer);
|
||||||
void mapSharedMem(u32 messagePointer);
|
void mapSharedMem(u32 messagePointer);
|
||||||
void setClamp(u32 messagePointer);
|
void setClamp(u32 messagePointer);
|
||||||
void setGain(u32 messagePointer);
|
void setGain(u32 messagePointer);
|
||||||
|
@ -19,15 +25,18 @@ class MICService {
|
||||||
void setPower(u32 messagePointer);
|
void setPower(u32 messagePointer);
|
||||||
void startSampling(u32 messagePointer);
|
void startSampling(u32 messagePointer);
|
||||||
void stopSampling(u32 messagePointer);
|
void stopSampling(u32 messagePointer);
|
||||||
|
void unmapSharedMem(u32 messagePointer);
|
||||||
void theCaptainToadFunction(u32 messagePointer);
|
void theCaptainToadFunction(u32 messagePointer);
|
||||||
|
|
||||||
u8 gain = 0; // How loud our microphone input signal is
|
u8 gain = 0; // How loud our microphone input signal is
|
||||||
bool micEnabled = false;
|
bool micEnabled = false;
|
||||||
bool shouldClamp = false;
|
bool shouldClamp = false;
|
||||||
bool isSampling = false;
|
bool currentlySampling = false;
|
||||||
|
|
||||||
|
std::optional<Handle> eventHandle;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MICService(Memory& mem) : mem(mem) {}
|
MICService(Memory& mem, Kernel& kernel) : mem(mem), kernel(kernel) {}
|
||||||
void reset();
|
void reset();
|
||||||
void handleSyncRequest(u32 messagePointer);
|
void handleSyncRequest(u32 messagePointer);
|
||||||
};
|
};
|
|
@ -1,5 +1,5 @@
|
||||||
# Panda3DS
|
# Panda3DS
|
||||||
[](https://github.com/wheremyfoodat/Panda3DS/actions/workflows/Windows_Build.yml) [](https://github.com/wheremyfoodat/Panda3DS/actions/workflows/MacOS_Build.yml) [](https://github.com/wheremyfoodat/Panda3DS/actions/workflows/Linux_Build.yml)
|
[](https://github.com/wheremyfoodat/Panda3DS/actions/workflows/Windows_Build.yml) [](https://github.com/wheremyfoodat/Panda3DS/actions/workflows/MacOS_Build.yml) [](https://github.com/wheremyfoodat/Panda3DS/actions/workflows/Linux_Build.yml) [](https://aur.archlinux.org/packages/panda3ds-git)
|
||||||
|
|
||||||
Panda3DS is an HLE, red-panda-themed Nintendo 3DS emulator written in C++ which started out as a fun project out of curiosity, but evolved into something that can sort of play games!
|
Panda3DS is an HLE, red-panda-themed Nintendo 3DS emulator written in C++ which started out as a fun project out of curiosity, but evolved into something that can sort of play games!
|
||||||
|
|
||||||
|
|
|
@ -8,11 +8,15 @@ namespace ACCommands {
|
||||||
CloseAsync = 0x00080004,
|
CloseAsync = 0x00080004,
|
||||||
GetLastErrorCode = 0x000A0000,
|
GetLastErrorCode = 0x000A0000,
|
||||||
RegisterDisconnectEvent = 0x00300004,
|
RegisterDisconnectEvent = 0x00300004,
|
||||||
|
IsConnected = 0x003E0042,
|
||||||
SetClientVersion = 0x00400042,
|
SetClientVersion = 0x00400042,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void ACService::reset() {}
|
void ACService::reset() {
|
||||||
|
connected = false;
|
||||||
|
disconnectEvent = std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
void ACService::handleSyncRequest(u32 messagePointer) {
|
void ACService::handleSyncRequest(u32 messagePointer) {
|
||||||
const u32 command = mem.read32(messagePointer);
|
const u32 command = mem.read32(messagePointer);
|
||||||
|
@ -21,6 +25,7 @@ void ACService::handleSyncRequest(u32 messagePointer) {
|
||||||
case ACCommands::CloseAsync: closeAsync(messagePointer); break;
|
case ACCommands::CloseAsync: closeAsync(messagePointer); break;
|
||||||
case ACCommands::CreateDefaultConfig: createDefaultConfig(messagePointer); break;
|
case ACCommands::CreateDefaultConfig: createDefaultConfig(messagePointer); break;
|
||||||
case ACCommands::GetLastErrorCode: getLastErrorCode(messagePointer); break;
|
case ACCommands::GetLastErrorCode: getLastErrorCode(messagePointer); break;
|
||||||
|
case ACCommands::IsConnected: isConnected(messagePointer); break;
|
||||||
case ACCommands::RegisterDisconnectEvent: registerDisconnectEvent(messagePointer); break;
|
case ACCommands::RegisterDisconnectEvent: registerDisconnectEvent(messagePointer); break;
|
||||||
case ACCommands::SetClientVersion: setClientVersion(messagePointer); break;
|
case ACCommands::SetClientVersion: setClientVersion(messagePointer); break;
|
||||||
default: Helpers::panic("AC service requested. Command: %08X\n", command);
|
default: Helpers::panic("AC service requested. Command: %08X\n", command);
|
||||||
|
@ -37,6 +42,11 @@ void ACService::cancelConnectAsync(u32 messagePointer) {
|
||||||
|
|
||||||
void ACService::closeAsync(u32 messagePointer) {
|
void ACService::closeAsync(u32 messagePointer) {
|
||||||
log("AC::CloseAsync (stubbed)\n");
|
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
|
// TODO: Verify if this response header is correct on hardware
|
||||||
mem.write32(messagePointer, IPC::responseHeader(0x8, 1, 0));
|
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?
|
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) {
|
void ACService::setClientVersion(u32 messagePointer) {
|
||||||
u32 version = mem.read32(messagePointer + 4);
|
u32 version = mem.read32(messagePointer + 4);
|
||||||
log("AC::SetClientVersion (version = %d)\n", version);
|
log("AC::SetClientVersion (version = %d)\n", version);
|
||||||
|
@ -71,9 +90,11 @@ void ACService::registerDisconnectEvent(u32 messagePointer) {
|
||||||
log("AC::RegisterDisconnectEvent (stubbed)\n");
|
log("AC::RegisterDisconnectEvent (stubbed)\n");
|
||||||
const u32 pidHeader = mem.read32(messagePointer + 4);
|
const u32 pidHeader = mem.read32(messagePointer + 4);
|
||||||
const u32 copyHandleHeader = mem.read32(messagePointer + 12);
|
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);
|
const Handle eventHandle = mem.read32(messagePointer + 16);
|
||||||
|
|
||||||
|
disconnectEvent = eventHandle;
|
||||||
|
|
||||||
mem.write32(messagePointer, IPC::responseHeader(0x30, 1, 0));
|
mem.write32(messagePointer, IPC::responseHeader(0x30, 1, 0));
|
||||||
mem.write32(messagePointer + 4, Result::Success);
|
mem.write32(messagePointer + 4, Result::Success);
|
||||||
}
|
}
|
|
@ -19,6 +19,7 @@ namespace FRDCommands {
|
||||||
GetMyMii = 0x000A0000,
|
GetMyMii = 0x000A0000,
|
||||||
GetFriendKeyList = 0x00110080,
|
GetFriendKeyList = 0x00110080,
|
||||||
GetFriendPresence = 0x00120042,
|
GetFriendPresence = 0x00120042,
|
||||||
|
GetFriendProfile = 0x00150042,
|
||||||
GetFriendAttributeFlags = 0x00170042,
|
GetFriendAttributeFlags = 0x00170042,
|
||||||
UpdateGameModeDescription = 0x001D0002,
|
UpdateGameModeDescription = 0x001D0002,
|
||||||
};
|
};
|
||||||
|
@ -33,6 +34,7 @@ void FRDService::handleSyncRequest(u32 messagePointer) {
|
||||||
case FRDCommands::GetFriendAttributeFlags: getFriendAttributeFlags(messagePointer); break;
|
case FRDCommands::GetFriendAttributeFlags: getFriendAttributeFlags(messagePointer); break;
|
||||||
case FRDCommands::GetFriendKeyList: getFriendKeyList(messagePointer); break;
|
case FRDCommands::GetFriendKeyList: getFriendKeyList(messagePointer); break;
|
||||||
case FRDCommands::GetFriendPresence: getFriendPresence(messagePointer); break;
|
case FRDCommands::GetFriendPresence: getFriendPresence(messagePointer); break;
|
||||||
|
case FRDCommands::GetFriendProfile: getFriendProfile(messagePointer); break;
|
||||||
case FRDCommands::GetMyFriendKey: getMyFriendKey(messagePointer); break;
|
case FRDCommands::GetMyFriendKey: getMyFriendKey(messagePointer); break;
|
||||||
case FRDCommands::GetMyMii: getMyMii(messagePointer); break;
|
case FRDCommands::GetMyMii: getMyMii(messagePointer); break;
|
||||||
case FRDCommands::GetMyPresence: getMyPresence(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) {
|
void FRDService::getMyPresence(u32 messagePointer) {
|
||||||
static constexpr u32 presenceSize = 0x12C; // A presence seems to be 12C bytes of data, not sure what it contains
|
static constexpr u32 presenceSize = 0x12C; // A presence seems to be 12C bytes of data, not sure what it contains
|
||||||
log("FRD::GetMyPresence\n");
|
log("FRD::GetMyPresence\n");
|
||||||
|
@ -100,21 +137,6 @@ void FRDService::getMyPresence(u32 messagePointer) {
|
||||||
mem.write32(messagePointer + 4, Result::Success);
|
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) {
|
void FRDService::getFriendPresence(u32 messagePointer) {
|
||||||
Helpers::warn("FRD::GetFriendPresence (stubbed)");
|
Helpers::warn("FRD::GetFriendPresence (stubbed)");
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
#include "services/mic.hpp"
|
#include "services/mic.hpp"
|
||||||
#include "ipc.hpp"
|
#include "ipc.hpp"
|
||||||
|
#include "kernel/kernel.hpp"
|
||||||
|
|
||||||
namespace MICCommands {
|
namespace MICCommands {
|
||||||
enum : u32 {
|
enum : u32 {
|
||||||
MapSharedMem = 0x00010042,
|
MapSharedMem = 0x00010042,
|
||||||
|
UnmapSharedMem = 0x00020000,
|
||||||
StartSampling = 0x00030140,
|
StartSampling = 0x00030140,
|
||||||
StopSampling = 0x00050000,
|
StopSampling = 0x00050000,
|
||||||
|
IsSampling = 0x00060000,
|
||||||
|
GetEventHandle = 0x00070000,
|
||||||
SetGain = 0x00080040,
|
SetGain = 0x00080040,
|
||||||
GetGain = 0x00090000,
|
GetGain = 0x00090000,
|
||||||
SetPower = 0x000A0040,
|
SetPower = 0x000A0040,
|
||||||
|
@ -18,14 +22,18 @@ namespace MICCommands {
|
||||||
void MICService::reset() {
|
void MICService::reset() {
|
||||||
micEnabled = false;
|
micEnabled = false;
|
||||||
shouldClamp = false;
|
shouldClamp = false;
|
||||||
isSampling = false;
|
currentlySampling = false;
|
||||||
gain = 0;
|
gain = 0;
|
||||||
|
|
||||||
|
eventHandle = std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MICService::handleSyncRequest(u32 messagePointer) {
|
void MICService::handleSyncRequest(u32 messagePointer) {
|
||||||
const u32 command = mem.read32(messagePointer);
|
const u32 command = mem.read32(messagePointer);
|
||||||
switch (command) {
|
switch (command) {
|
||||||
|
case MICCommands::GetEventHandle: getEventHandle(messagePointer); break;
|
||||||
case MICCommands::GetGain: getGain(messagePointer); break;
|
case MICCommands::GetGain: getGain(messagePointer); break;
|
||||||
|
case MICCommands::IsSampling: isSampling(messagePointer); break;
|
||||||
case MICCommands::MapSharedMem: mapSharedMem(messagePointer); break;
|
case MICCommands::MapSharedMem: mapSharedMem(messagePointer); break;
|
||||||
case MICCommands::SetClamp: setClamp(messagePointer); break;
|
case MICCommands::SetClamp: setClamp(messagePointer); break;
|
||||||
case MICCommands::SetGain: setGain(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::SetPower: setPower(messagePointer); break;
|
||||||
case MICCommands::StartSampling: startSampling(messagePointer); break;
|
case MICCommands::StartSampling: startSampling(messagePointer); break;
|
||||||
case MICCommands::StopSampling: stopSampling(messagePointer); break;
|
case MICCommands::StopSampling: stopSampling(messagePointer); break;
|
||||||
|
case MICCommands::UnmapSharedMem: unmapSharedMem(messagePointer); break;
|
||||||
case MICCommands::CaptainToadFunction: theCaptainToadFunction(messagePointer); break;
|
case MICCommands::CaptainToadFunction: theCaptainToadFunction(messagePointer); break;
|
||||||
default: Helpers::panic("MIC service requested. Command: %08X\n", command);
|
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);
|
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) {
|
void MICService::getGain(u32 messagePointer) {
|
||||||
log("MIC::GetGain\n");
|
log("MIC::GetGain\n");
|
||||||
mem.write32(messagePointer, IPC::responseHeader(0x9, 2, 0));
|
mem.write32(messagePointer, IPC::responseHeader(0x9, 2, 0));
|
||||||
|
@ -91,19 +121,27 @@ void MICService::startSampling(u32 messagePointer) {
|
||||||
encoding, sampleRate, offset, dataSize, loop ? "yes" : "no"
|
encoding, sampleRate, offset, dataSize, loop ? "yes" : "no"
|
||||||
);
|
);
|
||||||
|
|
||||||
isSampling = true;
|
currentlySampling = true;
|
||||||
mem.write32(messagePointer, IPC::responseHeader(0x3, 1, 0));
|
mem.write32(messagePointer, IPC::responseHeader(0x3, 1, 0));
|
||||||
mem.write32(messagePointer + 4, Result::Success);
|
mem.write32(messagePointer + 4, Result::Success);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MICService::stopSampling(u32 messagePointer) {
|
void MICService::stopSampling(u32 messagePointer) {
|
||||||
log("MIC::StopSampling\n");
|
log("MIC::StopSampling\n");
|
||||||
isSampling = false;
|
currentlySampling = false;
|
||||||
|
|
||||||
mem.write32(messagePointer, IPC::responseHeader(0x5, 1, 0));
|
mem.write32(messagePointer, IPC::responseHeader(0x5, 1, 0));
|
||||||
mem.write32(messagePointer + 4, Result::Success);
|
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) {
|
void MICService::setIirFilter(u32 messagePointer) {
|
||||||
const u32 size = mem.read32(messagePointer + 4);
|
const u32 size = mem.read32(messagePointer + 4);
|
||||||
const u32 pointer = mem.read32(messagePointer + 12);
|
const u32 pointer = mem.read32(messagePointer + 12);
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
ServiceManager::ServiceManager(std::span<u32, 16> regs, Memory& mem, GPU& gpu, u32& currentPID, Kernel& kernel, const EmulatorConfig& config)
|
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),
|
: 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),
|
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) {}
|
news_u(mem), ptm(mem, config), soc(mem), ssl(mem), y2r(mem, kernel) {}
|
||||||
|
|
||||||
static constexpr int MAX_NOTIFICATION_COUNT = 16;
|
static constexpr int MAX_NOTIFICATION_COUNT = 16;
|
||||||
|
|
Loading…
Add table
Reference in a new issue