mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-06 06:05:40 +12:00
Add Mii Selector
This commit is contained in:
parent
8fc61769ab
commit
6e6c84eebb
7 changed files with 150 additions and 13 deletions
|
@ -84,7 +84,7 @@ namespace Applets {
|
|||
virtual const char* name() = 0;
|
||||
|
||||
// Called by APT::StartLibraryApplet and similar
|
||||
virtual Result::HorizonResult start(const MemoryBlock& sharedMem, const std::vector<u8>& parameters, u32 appID) = 0;
|
||||
virtual Result::HorizonResult start(const MemoryBlock* sharedMem, const std::vector<u8>& parameters, u32 appID) = 0;
|
||||
// Transfer parameters from application -> applet
|
||||
virtual Result::HorizonResult receiveParameter(const Parameter& parameter) = 0;
|
||||
virtual void reset() = 0;
|
||||
|
|
|
@ -1,13 +1,83 @@
|
|||
#include <string>
|
||||
|
||||
#include "applets/applet.hpp"
|
||||
#include "swap.hpp"
|
||||
|
||||
namespace Applets {
|
||||
struct MiiConfig {
|
||||
u8 enableCancelButton;
|
||||
u8 enableGuestMii;
|
||||
u8 showOnTopScreen;
|
||||
std::array<u8, 0x5> pad1;
|
||||
std::array<u16_le, 0x40> title;
|
||||
std::array<u8, 0x4> pad2;
|
||||
u8 showGuestMiis;
|
||||
std::array<u8, 0x3> pad3;
|
||||
u32 initiallySelectedIndex;
|
||||
std::array<u8, 0x6> guestMiiWhitelist;
|
||||
std::array<u8, 0x64> userMiiWhitelist;
|
||||
std::array<u8, 0x2> pad4;
|
||||
u32 magicValue;
|
||||
};
|
||||
static_assert(sizeof(MiiConfig) == 0x104, "Mii config size is wrong");
|
||||
|
||||
// Some members of this struct are not properly aligned so we need pragma pack
|
||||
#pragma pack(push, 1)
|
||||
struct MiiData {
|
||||
u8 version;
|
||||
u8 miiOptions;
|
||||
u8 miiPos;
|
||||
u8 consoleID;
|
||||
|
||||
u64_be systemID;
|
||||
u32_be miiID;
|
||||
std::array<u8, 0x6> creatorMAC;
|
||||
u16 padding;
|
||||
|
||||
u16_be miiDetails;
|
||||
std::array<char16_t, 0xA> miiName;
|
||||
u8 height;
|
||||
u8 width;
|
||||
|
||||
u8 faceStyle;
|
||||
u8 faceDetails;
|
||||
u8 hairStyle;
|
||||
u8 hairDetails;
|
||||
u32_be eyeDetails;
|
||||
u32_be eyebrowDetails;
|
||||
u16_be noseDetails;
|
||||
u16_be mouthDetails;
|
||||
u16_be moustacheDetails;
|
||||
u16_be beardDetails;
|
||||
u16_be glassesDetails;
|
||||
u16_be moleDetails;
|
||||
|
||||
std::array<char16_t, 0xA> authorName;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
static_assert(sizeof(MiiData) == 0x5C, "MiiData structure has incorrect size");
|
||||
|
||||
struct MiiResult {
|
||||
u32_be returnCode;
|
||||
u32_be isGuestMiiSelected;
|
||||
u32_be selectedGuestMiiIndex;
|
||||
MiiData selectedMiiData;
|
||||
u16_be unknown1;
|
||||
u16_be miiChecksum;
|
||||
std::array<u16_le, 0xC> guestMiiName;
|
||||
};
|
||||
static_assert(sizeof(MiiResult) == 0x84, "MiiResult structure has incorrect size");
|
||||
|
||||
class MiiSelectorApplet final : public AppletBase {
|
||||
public:
|
||||
virtual const char* name() override { return "Mii Selector"; }
|
||||
virtual Result::HorizonResult start(const MemoryBlock& sharedMem, const std::vector<u8>& parameters, u32 appID) override;
|
||||
virtual Result::HorizonResult start(const MemoryBlock* sharedMem, const std::vector<u8>& parameters, u32 appID) override;
|
||||
virtual Result::HorizonResult receiveParameter(const Applets::Parameter& parameter) override;
|
||||
virtual void reset() override;
|
||||
|
||||
MiiResult output;
|
||||
MiiConfig config;
|
||||
MiiResult getDefaultMii();
|
||||
MiiSelectorApplet(Memory& memory, std::optional<Parameter>& nextParam) : AppletBase(memory, nextParam) {}
|
||||
};
|
||||
} // namespace Applets
|
|
@ -150,7 +150,7 @@ namespace Applets {
|
|||
static_assert(sizeof(SoftwareKeyboardConfig) == 0x400, "Software keyboard config size is wrong");
|
||||
|
||||
virtual const char* name() override { return "Software Keyboard"; }
|
||||
virtual Result::HorizonResult start(const MemoryBlock& sharedMem, const std::vector<u8>& parameters, u32 appID) override;
|
||||
virtual Result::HorizonResult start(const MemoryBlock* sharedMem, const std::vector<u8>& parameters, u32 appID) override;
|
||||
virtual Result::HorizonResult receiveParameter(const Applets::Parameter& parameter) override;
|
||||
virtual void reset() override;
|
||||
|
||||
|
|
|
@ -1,11 +1,38 @@
|
|||
#include "applets/mii_selector.hpp"
|
||||
|
||||
#include <boost/crc.hpp>
|
||||
#include <limits>
|
||||
|
||||
#include "kernel/handles.hpp"
|
||||
|
||||
using namespace Applets;
|
||||
|
||||
void MiiSelectorApplet::reset() {}
|
||||
Result::HorizonResult MiiSelectorApplet::start(const MemoryBlock& sharedMem, const std::vector<u8>& parameters, u32 appID) { return Result::Success; }
|
||||
Result::HorizonResult MiiSelectorApplet::start(const MemoryBlock* sharedMem, const std::vector<u8>& parameters, u32 appID) {
|
||||
// Get mii configuration from the application
|
||||
std::memcpy(&config, ¶meters[0], sizeof(config));
|
||||
|
||||
Applets::Parameter param = Applets::Parameter{
|
||||
.senderID = appID,
|
||||
.destID = AppletIDs::Application,
|
||||
.signal = static_cast<u32>(APTSignal::WakeupByExit),
|
||||
.object = 0,
|
||||
};
|
||||
|
||||
// Thanks to Citra devs as always for the default mii data and other applet help
|
||||
output = getDefaultMii();
|
||||
output.returnCode = 0; // Success
|
||||
// output.selectedMiiData = miiData;
|
||||
output.selectedGuestMiiIndex = std::numeric_limits<u32>::max();
|
||||
output.miiChecksum = boost::crc<16, 0x1021, 0, 0, false, false>(&output.selectedMiiData, sizeof(MiiData) + sizeof(output.unknown1));
|
||||
|
||||
// Copy output into the response parameter
|
||||
param.data.resize(sizeof(output));
|
||||
std::memcpy(¶m.data[0], &output, sizeof(output));
|
||||
|
||||
nextParameter = param;
|
||||
return Result::Success;
|
||||
}
|
||||
|
||||
Result::HorizonResult MiiSelectorApplet::receiveParameter(const Applets::Parameter& parameter) {
|
||||
Helpers::warn("Mii Selector: Unimplemented ReceiveParameter");
|
||||
|
@ -20,4 +47,43 @@ Result::HorizonResult MiiSelectorApplet::receiveParameter(const Applets::Paramet
|
|||
|
||||
nextParameter = param;
|
||||
return Result::Success;
|
||||
}
|
||||
|
||||
MiiResult MiiSelectorApplet::getDefaultMii() {
|
||||
// This data was obtained from Citra
|
||||
MiiData miiData;
|
||||
miiData.version = 0x03;
|
||||
miiData.miiOptions = 0x00;
|
||||
miiData.miiPos = 0x10;
|
||||
miiData.consoleID = 0x30;
|
||||
miiData.systemID = 0xD285B6B300C8850A;
|
||||
miiData.miiID = 0x98391EE4;
|
||||
miiData.creatorMAC = {0x40, 0xF4, 0x07, 0xB7, 0x37, 0x10};
|
||||
miiData.padding = 0x0000;
|
||||
miiData.miiDetails = 0xA600;
|
||||
miiData.miiName = {'P', 'a', 'n', 'd', 'a', '3', 'D', 'S', 0x0, 0x0};
|
||||
miiData.height = 0x40;
|
||||
miiData.width = 0x40;
|
||||
miiData.faceStyle = 0x00;
|
||||
miiData.faceDetails = 0x00;
|
||||
miiData.hairStyle = 0x21;
|
||||
miiData.hairDetails = 0x01;
|
||||
miiData.eyeDetails = 0x02684418;
|
||||
miiData.eyebrowDetails = 0x26344614;
|
||||
miiData.noseDetails = 0x8112;
|
||||
miiData.mouthDetails = 0x1768;
|
||||
miiData.moustacheDetails = 0x0D00;
|
||||
miiData.beardDetails = 0x0029;
|
||||
miiData.glassesDetails = 0x0052;
|
||||
miiData.moleDetails = 0x4850;
|
||||
miiData.authorName = {u'B', u'O', u'N', u'K', u'E', u'R'};
|
||||
|
||||
MiiResult result;
|
||||
result.returnCode = 0x0;
|
||||
result.isGuestMiiSelected = 0x0;
|
||||
result.selectedGuestMiiIndex = std::numeric_limits<u32>::max();
|
||||
result.selectedMiiData = miiData;
|
||||
result.guestMiiName.fill(0x0);
|
||||
|
||||
return result;
|
||||
}
|
|
@ -33,17 +33,22 @@ Result::HorizonResult SoftwareKeyboardApplet::receiveParameter(const Applets::Pa
|
|||
return Result::Success;
|
||||
}
|
||||
|
||||
Result::HorizonResult SoftwareKeyboardApplet::start(const MemoryBlock& sharedMem, const std::vector<u8>& parameters, u32 appID) {
|
||||
Result::HorizonResult SoftwareKeyboardApplet::start(const MemoryBlock* sharedMem, const std::vector<u8>& parameters, u32 appID) {
|
||||
if (parameters.size() < sizeof(SoftwareKeyboardConfig)) {
|
||||
Helpers::warn("SoftwareKeyboard::Start: Invalid size for keyboard configuration");
|
||||
return Result::Success;
|
||||
}
|
||||
|
||||
if (sharedMem == nullptr) {
|
||||
Helpers::warn("SoftwareKeyboard: Missing shared memory");
|
||||
return Result::Success;
|
||||
}
|
||||
|
||||
// Get keyboard configuration from the application
|
||||
std::memcpy(&config, ¶meters[0], sizeof(config));
|
||||
|
||||
const std::u16string text = u"Pand";
|
||||
u32 textAddress = sharedMem.addr;
|
||||
u32 textAddress = sharedMem->addr;
|
||||
|
||||
// Copy text to shared memory the app gave us
|
||||
for (u32 i = 0; i < text.size(); i++) {
|
||||
|
|
|
@ -155,12 +155,8 @@ void APTService::startLibraryApplet(u32 messagePointer) {
|
|||
mem.write32(messagePointer + 4, Result::Success);
|
||||
} else {
|
||||
KernelObject* sharedMemObject = kernel.getObject(parameters);
|
||||
if (sharedMemObject == nullptr) {
|
||||
Helpers::warn("Couldn't find shared memory block\n");
|
||||
return;
|
||||
}
|
||||
|
||||
const MemoryBlock* sharedMem = sharedMemObject->getData<MemoryBlock>();
|
||||
const MemoryBlock* sharedMem = sharedMemObject ? sharedMemObject->getData<MemoryBlock>() : nullptr;
|
||||
std::vector<u8> data;
|
||||
data.reserve(bufferSize);
|
||||
|
||||
|
@ -168,7 +164,7 @@ void APTService::startLibraryApplet(u32 messagePointer) {
|
|||
data.push_back(mem.read8(buffer + i));
|
||||
}
|
||||
|
||||
Result::HorizonResult result = destApplet->start(*sharedMem, data, appID);
|
||||
Result::HorizonResult result = destApplet->start(sharedMem, data, appID);
|
||||
if (resumeEvent.has_value()) {
|
||||
kernel.signalEvent(resumeEvent.value());
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ void PTMService::getBatteryChargeState(u32 messagePointer) {
|
|||
|
||||
void PTMService::getPedometerState(u32 messagePointer) {
|
||||
log("PTM::GetPedometerState");
|
||||
const bool countingSteps = true;
|
||||
constexpr bool countingSteps = true;
|
||||
|
||||
mem.write32(messagePointer, IPC::responseHeader(0x9, 2, 0));
|
||||
mem.write32(messagePointer + 4, Result::Success);
|
||||
|
|
Loading…
Add table
Reference in a new issue