mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-11-03 23:28:48 +00:00 
			
		
		
		
	applets: implement HLE mii selector applet
This commit is contained in:
		
							parent
							
								
									f903d3161d
								
							
						
					
					
						commit
						041638ea4d
					
				
					 12 changed files with 350 additions and 18 deletions
				
			
		| 
						 | 
				
			
			@ -10,6 +10,8 @@ add_executable(citra-qt
 | 
			
		|||
    Info.plist
 | 
			
		||||
    aboutdialog.cpp
 | 
			
		||||
    aboutdialog.h
 | 
			
		||||
    applets/mii_selector.cpp
 | 
			
		||||
    applets/mii_selector.h
 | 
			
		||||
    applets/swkbd.cpp
 | 
			
		||||
    applets/swkbd.h
 | 
			
		||||
    bootmanager.cpp
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										125
									
								
								src/citra_qt/applets/mii_selector.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										125
									
								
								src/citra_qt/applets/mii_selector.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,125 @@
 | 
			
		|||
// Copyright 2018 Citra Emulator Project
 | 
			
		||||
// Licensed under GPLv2 or any later version
 | 
			
		||||
// Refer to the license.txt file included.
 | 
			
		||||
 | 
			
		||||
#include <QComboBox>
 | 
			
		||||
#include <QDialogButtonBox>
 | 
			
		||||
#include <QMessageBox>
 | 
			
		||||
#include <QString>
 | 
			
		||||
#include <QVBoxLayout>
 | 
			
		||||
#include "citra_qt/applets/mii_selector.h"
 | 
			
		||||
#include "common/file_util.h"
 | 
			
		||||
#include "core/file_sys/archive_extsavedata.h"
 | 
			
		||||
#include "core/file_sys/file_backend.h"
 | 
			
		||||
#include "core/hle/applets/buttons.h"
 | 
			
		||||
#include "core/hle/service/ptm/ptm.h"
 | 
			
		||||
 | 
			
		||||
QtMiiSelectorDialog::QtMiiSelectorDialog(QWidget* parent, QtMiiSelector* mii_selector_)
 | 
			
		||||
    : QDialog(parent), mii_selector(mii_selector_) {
 | 
			
		||||
    Frontend::MiiSelectorConfig config = mii_selector->config;
 | 
			
		||||
    layout = new QVBoxLayout;
 | 
			
		||||
    combobox = new QComboBox;
 | 
			
		||||
    buttons = new QDialogButtonBox;
 | 
			
		||||
    // Initialize buttons
 | 
			
		||||
    buttons->addButton(tr(AppletButton::Ok), QDialogButtonBox::ButtonRole::AcceptRole);
 | 
			
		||||
    if (config.enable_cancel_button) {
 | 
			
		||||
        buttons->addButton(tr(AppletButton::Cancel), QDialogButtonBox::ButtonRole::RejectRole);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    setWindowTitle(config.title.empty() ? tr("Mii Selector")
 | 
			
		||||
                                        : QString::fromStdU16String(config.title));
 | 
			
		||||
 | 
			
		||||
    std::string nand_directory{FileUtil::GetUserPath(FileUtil::UserPath::NANDDir)};
 | 
			
		||||
    FileSys::ArchiveFactory_ExtSaveData extdata_archive_factory(nand_directory, true);
 | 
			
		||||
 | 
			
		||||
    auto archive_result = extdata_archive_factory.Open(Service::PTM::ptm_shared_extdata_id);
 | 
			
		||||
    if (!archive_result.Succeeded()) {
 | 
			
		||||
        ShowNoMiis();
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    auto archive = std::move(archive_result).Unwrap();
 | 
			
		||||
 | 
			
		||||
    FileSys::Path file_path = "/CFL_DB.dat";
 | 
			
		||||
    FileSys::Mode mode{};
 | 
			
		||||
    mode.read_flag.Assign(1);
 | 
			
		||||
 | 
			
		||||
    auto file_result = archive->OpenFile(file_path, mode);
 | 
			
		||||
    if (!file_result.Succeeded()) {
 | 
			
		||||
        ShowNoMiis();
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    auto file = std::move(file_result).Unwrap();
 | 
			
		||||
 | 
			
		||||
    u32 saved_miis_offset = 0x8;
 | 
			
		||||
    // The Mii Maker has a 100 Mii limit on the 3ds
 | 
			
		||||
    for (int i = 0; i < 100; ++i) {
 | 
			
		||||
        HLE::Applets::MiiData mii;
 | 
			
		||||
        std::array<u8, sizeof(mii)> mii_raw;
 | 
			
		||||
        file->Read(saved_miis_offset, sizeof(mii), mii_raw.data());
 | 
			
		||||
        std::memcpy(&mii, mii_raw.data(), sizeof(mii));
 | 
			
		||||
        if (mii.mii_id != 0) {
 | 
			
		||||
            std::u16string name(sizeof(mii.mii_name), '\0');
 | 
			
		||||
            std::memcpy(&name[0], mii.mii_name.data(), sizeof(mii.mii_name));
 | 
			
		||||
            miis.emplace(combobox->count(), mii);
 | 
			
		||||
            combobox->addItem(QString::fromStdU16String(name));
 | 
			
		||||
        }
 | 
			
		||||
        saved_miis_offset += sizeof(mii);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (miis.empty()) {
 | 
			
		||||
        ShowNoMiis();
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (combobox->count() > static_cast<int>(config.initially_selected_mii_index)) {
 | 
			
		||||
        combobox->setCurrentIndex(static_cast<int>(config.initially_selected_mii_index));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    connect(buttons, &QDialogButtonBox::accepted, this, [this] { accept(); });
 | 
			
		||||
    connect(buttons, &QDialogButtonBox::rejected, this, [this] {
 | 
			
		||||
        return_code = 1;
 | 
			
		||||
        accept();
 | 
			
		||||
    });
 | 
			
		||||
    layout->addWidget(combobox);
 | 
			
		||||
    layout->addWidget(buttons);
 | 
			
		||||
    setLayout(layout);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QtMiiSelectorDialog::ShowNoMiis() {
 | 
			
		||||
    Frontend::MiiSelectorConfig config = mii_selector->config;
 | 
			
		||||
    QMessageBox::StandardButton answer = QMessageBox::question(
 | 
			
		||||
        nullptr,
 | 
			
		||||
        config.title.empty() ? tr("Mii Selector") : QString::fromStdU16String(config.title),
 | 
			
		||||
        tr("You don't have any Miis.\nUse standard Mii?"), QMessageBox::Yes | QMessageBox::No);
 | 
			
		||||
 | 
			
		||||
    if (answer == QMessageBox::No)
 | 
			
		||||
        return_code = 1;
 | 
			
		||||
 | 
			
		||||
    QMetaObject::invokeMethod(this, "close", Qt::QueuedConnection);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QtMiiSelector::QtMiiSelector(QWidget& parent_) : parent(parent_) {}
 | 
			
		||||
 | 
			
		||||
void QtMiiSelector::Setup(const Frontend::MiiSelectorConfig* config) {
 | 
			
		||||
    MiiSelector::Setup(config);
 | 
			
		||||
    QMetaObject::invokeMethod(this, "OpenDialog", Qt::BlockingQueuedConnection);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QtMiiSelector::OpenDialog() {
 | 
			
		||||
    QtMiiSelectorDialog dialog(&parent, this);
 | 
			
		||||
    dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint |
 | 
			
		||||
                          Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint);
 | 
			
		||||
    dialog.setWindowModality(Qt::WindowModal);
 | 
			
		||||
    dialog.exec();
 | 
			
		||||
 | 
			
		||||
    int index = dialog.combobox->currentIndex();
 | 
			
		||||
    LOG_INFO(Frontend, "Mii Selector dialog finished (return_code={}, index={})",
 | 
			
		||||
             dialog.return_code, index);
 | 
			
		||||
 | 
			
		||||
    HLE::Applets::MiiData mii_data =
 | 
			
		||||
        index == -1 ? HLE::Applets::MiiSelector::GetStandardMiiResult().selected_mii_data
 | 
			
		||||
                    : dialog.miis.at(dialog.combobox->currentIndex());
 | 
			
		||||
    Finalize(dialog.return_code, dialog.return_code == 0 ? mii_data : HLE::Applets::MiiData{});
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										48
									
								
								src/citra_qt/applets/mii_selector.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								src/citra_qt/applets/mii_selector.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,48 @@
 | 
			
		|||
// Copyright 2018 Citra Emulator Project
 | 
			
		||||
// Licensed under GPLv2 or any later version
 | 
			
		||||
// Refer to the license.txt file included.
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <unordered_map>
 | 
			
		||||
#include <QDialog>
 | 
			
		||||
#include "core/frontend/applets/mii_selector.h"
 | 
			
		||||
 | 
			
		||||
class QDialogButtonBox;
 | 
			
		||||
class QComboBox;
 | 
			
		||||
class QVBoxLayout;
 | 
			
		||||
class QtMiiSelector;
 | 
			
		||||
 | 
			
		||||
class QtMiiSelectorDialog final : public QDialog {
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    QtMiiSelectorDialog(QWidget* parent, QtMiiSelector* mii_selector_);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    void ShowNoMiis();
 | 
			
		||||
 | 
			
		||||
    QDialogButtonBox* buttons;
 | 
			
		||||
    QComboBox* combobox;
 | 
			
		||||
    QVBoxLayout* layout;
 | 
			
		||||
    QtMiiSelector* mii_selector;
 | 
			
		||||
    u32 return_code = 0;
 | 
			
		||||
    std::unordered_map<int, HLE::Applets::MiiData> miis;
 | 
			
		||||
 | 
			
		||||
    friend class QtMiiSelector;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class QtMiiSelector final : public QObject, public Frontend::MiiSelector {
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    explicit QtMiiSelector(QWidget& parent);
 | 
			
		||||
    void Setup(const Frontend::MiiSelectorConfig* config) override;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    Q_INVOKABLE void OpenDialog();
 | 
			
		||||
 | 
			
		||||
    QWidget& parent;
 | 
			
		||||
 | 
			
		||||
    friend class QtMiiSelectorDialog;
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -16,6 +16,7 @@
 | 
			
		|||
#include <QtWidgets>
 | 
			
		||||
#include <fmt/format.h>
 | 
			
		||||
#include "citra_qt/aboutdialog.h"
 | 
			
		||||
#include "citra_qt/applets/mii_selector.h"
 | 
			
		||||
#include "citra_qt/applets/swkbd.h"
 | 
			
		||||
#include "citra_qt/bootmanager.h"
 | 
			
		||||
#include "citra_qt/camera/qt_multimedia_camera.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -1896,6 +1897,7 @@ int main(int argc, char* argv[]) {
 | 
			
		|||
 | 
			
		||||
    // Register frontend applets
 | 
			
		||||
    Frontend::RegisterDefaultApplets();
 | 
			
		||||
    Frontend::RegisterMiiSelector(std::make_shared<QtMiiSelector>(main_window));
 | 
			
		||||
    Frontend::RegisterSoftwareKeyboard(std::make_shared<QtKeyboard>(main_window));
 | 
			
		||||
 | 
			
		||||
    main_window.show();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -84,6 +84,8 @@ add_library(core STATIC
 | 
			
		|||
    file_sys/title_metadata.h
 | 
			
		||||
    frontend/applets/default_applets.cpp
 | 
			
		||||
    frontend/applets/default_applets.h
 | 
			
		||||
    frontend/applets/mii_selector.cpp
 | 
			
		||||
    frontend/applets/mii_selector.h
 | 
			
		||||
    frontend/applets/swkbd.cpp
 | 
			
		||||
    frontend/applets/swkbd.h
 | 
			
		||||
    frontend/camera/blank_camera.cpp
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -276,6 +276,10 @@ const Cheats::CheatEngine& System::CheatEngine() const {
 | 
			
		|||
    return *cheat_engine;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void System::RegisterMiiSelector(std::shared_ptr<Frontend::MiiSelector> mii_selector) {
 | 
			
		||||
    registered_mii_selector = std::move(mii_selector);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void System::RegisterSoftwareKeyboard(std::shared_ptr<Frontend::SoftwareKeyboard> swkbd) {
 | 
			
		||||
    registered_swkbd = std::move(swkbd);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,6 +7,7 @@
 | 
			
		|||
#include <memory>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include "common/common_types.h"
 | 
			
		||||
#include "core/frontend/applets/mii_selector.h"
 | 
			
		||||
#include "core/frontend/applets/swkbd.h"
 | 
			
		||||
#include "core/loader/loader.h"
 | 
			
		||||
#include "core/memory.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -222,8 +223,14 @@ public:
 | 
			
		|||
 | 
			
		||||
    /// Frontend Applets
 | 
			
		||||
 | 
			
		||||
    void RegisterMiiSelector(std::shared_ptr<Frontend::MiiSelector> mii_selector);
 | 
			
		||||
 | 
			
		||||
    void RegisterSoftwareKeyboard(std::shared_ptr<Frontend::SoftwareKeyboard> swkbd);
 | 
			
		||||
 | 
			
		||||
    std::shared_ptr<Frontend::MiiSelector> GetMiiSelector() const {
 | 
			
		||||
        return registered_mii_selector;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::shared_ptr<Frontend::SoftwareKeyboard> GetSoftwareKeyboard() const {
 | 
			
		||||
        return registered_swkbd;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -260,6 +267,7 @@ private:
 | 
			
		|||
    std::shared_ptr<Service::SM::ServiceManager> service_manager;
 | 
			
		||||
 | 
			
		||||
    /// Frontend applets
 | 
			
		||||
    std::shared_ptr<Frontend::MiiSelector> registered_mii_selector;
 | 
			
		||||
    std::shared_ptr<Frontend::SoftwareKeyboard> registered_swkbd;
 | 
			
		||||
 | 
			
		||||
    /// Cheats manager
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,10 +3,12 @@
 | 
			
		|||
// Refer to the license.txt file included.
 | 
			
		||||
 | 
			
		||||
#include "core/frontend/applets/default_applets.h"
 | 
			
		||||
#include "core/frontend/applets/mii_selector.h"
 | 
			
		||||
#include "core/frontend/applets/swkbd.h"
 | 
			
		||||
 | 
			
		||||
namespace Frontend {
 | 
			
		||||
void RegisterDefaultApplets() {
 | 
			
		||||
    RegisterSoftwareKeyboard(std::make_shared<DefaultKeyboard>());
 | 
			
		||||
    RegisterMiiSelector(std::make_shared<DefaultMiiSelector>());
 | 
			
		||||
}
 | 
			
		||||
} // namespace Frontend
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										27
									
								
								src/core/frontend/applets/mii_selector.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/core/frontend/applets/mii_selector.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,27 @@
 | 
			
		|||
// Copyright 2018 Citra Emulator Project
 | 
			
		||||
// Licensed under GPLv2 or any later version
 | 
			
		||||
// Refer to the license.txt file included.
 | 
			
		||||
 | 
			
		||||
#include "core/core.h"
 | 
			
		||||
#include "core/frontend/applets/mii_selector.h"
 | 
			
		||||
 | 
			
		||||
namespace Frontend {
 | 
			
		||||
 | 
			
		||||
void MiiSelector::Finalize(u32 return_code, HLE::Applets::MiiData mii) {
 | 
			
		||||
    data = {return_code, mii};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DefaultMiiSelector::Setup(const Frontend::MiiSelectorConfig* config) {
 | 
			
		||||
    MiiSelector::Setup(config);
 | 
			
		||||
    Finalize(0, HLE::Applets::MiiSelector::GetStandardMiiResult().selected_mii_data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RegisterMiiSelector(std::shared_ptr<MiiSelector> applet) {
 | 
			
		||||
    Core::System::GetInstance().RegisterMiiSelector(applet);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::shared_ptr<MiiSelector> GetRegisteredMiiSelector() {
 | 
			
		||||
    return Core::System::GetInstance().GetMiiSelector();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace Frontend
 | 
			
		||||
							
								
								
									
										56
									
								
								src/core/frontend/applets/mii_selector.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								src/core/frontend/applets/mii_selector.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,56 @@
 | 
			
		|||
// Copyright 2018 Citra Emulator Project
 | 
			
		||||
// Licensed under GPLv2 or any later version
 | 
			
		||||
// Refer to the license.txt file included.
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <array>
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include "core/hle/applets/mii_selector.h"
 | 
			
		||||
 | 
			
		||||
namespace Frontend {
 | 
			
		||||
 | 
			
		||||
/// Configuration that's relevant to frontend implementation of applet. Anything missing that we
 | 
			
		||||
/// later learn is needed can be added here and filled in by the backend HLE applet
 | 
			
		||||
struct MiiSelectorConfig {
 | 
			
		||||
    bool enable_cancel_button;
 | 
			
		||||
    std::u16string title;
 | 
			
		||||
    u32 initially_selected_mii_index;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct MiiSelectorData {
 | 
			
		||||
    u32 return_code;
 | 
			
		||||
    HLE::Applets::MiiData mii;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class MiiSelector {
 | 
			
		||||
public:
 | 
			
		||||
    virtual void Setup(const MiiSelectorConfig* config) {
 | 
			
		||||
        this->config = MiiSelectorConfig(*config);
 | 
			
		||||
    }
 | 
			
		||||
    const MiiSelectorData* ReceiveData() {
 | 
			
		||||
        return &data;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Stores the data so that the HLE applet in core can
 | 
			
		||||
     * send this to the calling application
 | 
			
		||||
     */
 | 
			
		||||
    void Finalize(u32 return_code, HLE::Applets::MiiData mii);
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    MiiSelectorConfig config;
 | 
			
		||||
    MiiSelectorData data;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class DefaultMiiSelector final : public MiiSelector {
 | 
			
		||||
public:
 | 
			
		||||
    void Setup(const MiiSelectorConfig* config) override;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void RegisterMiiSelector(std::shared_ptr<MiiSelector> applet);
 | 
			
		||||
 | 
			
		||||
std::shared_ptr<MiiSelector> GetRegisteredMiiSelector();
 | 
			
		||||
 | 
			
		||||
} // namespace Frontend
 | 
			
		||||
| 
						 | 
				
			
			@ -4,10 +4,12 @@
 | 
			
		|||
 | 
			
		||||
#include <cstring>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <boost/crc.hpp>
 | 
			
		||||
#include "common/assert.h"
 | 
			
		||||
#include "common/logging/log.h"
 | 
			
		||||
#include "common/string_util.h"
 | 
			
		||||
#include "core/core.h"
 | 
			
		||||
#include "core/frontend/applets/mii_selector.h"
 | 
			
		||||
#include "core/hle/applets/mii_selector.h"
 | 
			
		||||
#include "core/hle/kernel/kernel.h"
 | 
			
		||||
#include "core/hle/kernel/shared_memory.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -52,12 +54,51 @@ ResultCode MiiSelector::ReceiveParameter(const Service::APT::MessageParameter& p
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
ResultCode MiiSelector::StartImpl(const Service::APT::AppletStartupParameter& parameter) {
 | 
			
		||||
    is_running = true;
 | 
			
		||||
 | 
			
		||||
    // TODO(Subv): Reverse the parameter format for the Mii Selector
 | 
			
		||||
    ASSERT_MSG(parameter.buffer.size() == sizeof(config),
 | 
			
		||||
               "The size of the parameter (MiiConfig) is wrong");
 | 
			
		||||
 | 
			
		||||
    memcpy(&config, parameter.buffer.data(), parameter.buffer.size());
 | 
			
		||||
 | 
			
		||||
    using namespace Frontend;
 | 
			
		||||
    frontend_applet = GetRegisteredMiiSelector();
 | 
			
		||||
    if (frontend_applet) {
 | 
			
		||||
        MiiSelectorConfig frontend_config = ToFrontendConfig(config);
 | 
			
		||||
        frontend_applet->Setup(&frontend_config);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    is_running = true;
 | 
			
		||||
    return RESULT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MiiSelector::Update() {
 | 
			
		||||
    using namespace Frontend;
 | 
			
		||||
    const MiiSelectorData* data = frontend_applet->ReceiveData();
 | 
			
		||||
    result.return_code = data->return_code;
 | 
			
		||||
    result.selected_mii_data = data->mii;
 | 
			
		||||
    // Calculate the checksum of the selected Mii, see https://www.3dbrew.org/wiki/Mii#Checksum
 | 
			
		||||
    result.mii_data_checksum = boost::crc<16, 0x1021, 0, 0, false, false>(
 | 
			
		||||
        &result.selected_mii_data, sizeof(HLE::Applets::MiiData) + sizeof(result.unknown1));
 | 
			
		||||
    result.selected_guest_mii_index = 0xFFFFFFFF;
 | 
			
		||||
 | 
			
		||||
    // TODO(Subv): We're finalizing the applet immediately after it's started,
 | 
			
		||||
    // but we should defer this call until after all the input has been collected.
 | 
			
		||||
    Finalize();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MiiSelector::Finalize() {
 | 
			
		||||
    // Let the application know that we're closing
 | 
			
		||||
    Service::APT::MessageParameter message;
 | 
			
		||||
    message.buffer.resize(sizeof(MiiResult));
 | 
			
		||||
    std::memcpy(message.buffer.data(), &result, message.buffer.size());
 | 
			
		||||
    message.signal = Service::APT::SignalType::WakeupByExit;
 | 
			
		||||
    message.destination_id = Service::APT::AppletId::Application;
 | 
			
		||||
    message.sender_id = id;
 | 
			
		||||
    SendParameter(message);
 | 
			
		||||
 | 
			
		||||
    is_running = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MiiResult MiiSelector::GetStandardMiiResult() {
 | 
			
		||||
    // This data was obtained by writing the returned buffer in AppletManager::GlanceParameter of
 | 
			
		||||
    // the LLEd Mii picker of version system version 11.8.0 to a file and then matching the values
 | 
			
		||||
    // to the members of the MiiResult struct
 | 
			
		||||
| 
						 | 
				
			
			@ -95,18 +136,14 @@ ResultCode MiiSelector::StartImpl(const Service::APT::AppletStartupParameter& pa
 | 
			
		|||
    result.mii_data_checksum = 0x056C;
 | 
			
		||||
    result.guest_mii_name.fill(0x0);
 | 
			
		||||
 | 
			
		||||
    // Let the application know that we're closing
 | 
			
		||||
    Service::APT::MessageParameter message;
 | 
			
		||||
    message.buffer.resize(sizeof(MiiResult));
 | 
			
		||||
    std::memcpy(message.buffer.data(), &result, message.buffer.size());
 | 
			
		||||
    message.signal = Service::APT::SignalType::WakeupByExit;
 | 
			
		||||
    message.destination_id = Service::APT::AppletId::Application;
 | 
			
		||||
    message.sender_id = id;
 | 
			
		||||
    SendParameter(message);
 | 
			
		||||
 | 
			
		||||
    is_running = false;
 | 
			
		||||
    return RESULT_SUCCESS;
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MiiSelector::Update() {}
 | 
			
		||||
Frontend::MiiSelectorConfig MiiSelector::ToFrontendConfig(const MiiConfig& config) const {
 | 
			
		||||
    Frontend::MiiSelectorConfig frontend_config;
 | 
			
		||||
    frontend_config.enable_cancel_button = config.enable_cancel_button == 1;
 | 
			
		||||
    frontend_config.title = reinterpret_cast<const char16_t*>(config.title.data());
 | 
			
		||||
    frontend_config.initially_selected_mii_index = config.initially_selected_mii_index;
 | 
			
		||||
    return frontend_config;
 | 
			
		||||
}
 | 
			
		||||
} // namespace HLE::Applets
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,6 +12,11 @@
 | 
			
		|||
#include "core/hle/result.h"
 | 
			
		||||
#include "core/hle/service/apt/apt.h"
 | 
			
		||||
 | 
			
		||||
namespace Frontend {
 | 
			
		||||
class MiiSelector;
 | 
			
		||||
struct MiiSelectorConfig;
 | 
			
		||||
} // namespace Frontend
 | 
			
		||||
 | 
			
		||||
namespace HLE::Applets {
 | 
			
		||||
 | 
			
		||||
struct MiiConfig {
 | 
			
		||||
| 
						 | 
				
			
			@ -19,13 +24,13 @@ struct MiiConfig {
 | 
			
		|||
    u8 enable_guest_mii;
 | 
			
		||||
    u8 show_on_top_screen;
 | 
			
		||||
    INSERT_PADDING_BYTES(5);
 | 
			
		||||
    u16 title[0x40];
 | 
			
		||||
    std::array<u16, 0x40> title;
 | 
			
		||||
    INSERT_PADDING_BYTES(4);
 | 
			
		||||
    u8 show_guest_miis;
 | 
			
		||||
    INSERT_PADDING_BYTES(3);
 | 
			
		||||
    u32 initially_selected_mii_index;
 | 
			
		||||
    u8 guest_mii_whitelist[6];
 | 
			
		||||
    u8 user_mii_whitelist[0x64];
 | 
			
		||||
    std::array<u8, 0x6> guest_mii_whitelist;
 | 
			
		||||
    std::array<u8, 0x64> user_mii_whitelist;
 | 
			
		||||
    INSERT_PADDING_BYTES(2);
 | 
			
		||||
    u32 magic_value;
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -117,12 +122,26 @@ public:
 | 
			
		|||
    ResultCode StartImpl(const Service::APT::AppletStartupParameter& parameter) override;
 | 
			
		||||
    void Update() override;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sends the LibAppletClosing signal to the application,
 | 
			
		||||
     * along with the relevant data buffers.
 | 
			
		||||
     */
 | 
			
		||||
    void Finalize();
 | 
			
		||||
 | 
			
		||||
    static MiiResult GetStandardMiiResult();
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    Frontend::MiiSelectorConfig ToFrontendConfig(const MiiConfig& config) const;
 | 
			
		||||
 | 
			
		||||
    /// This SharedMemory will be created when we receive the LibAppJustStarted message.
 | 
			
		||||
    /// It holds the framebuffer info retrieved by the application with
 | 
			
		||||
    /// GSPGPU::ImportDisplayCaptureInfo
 | 
			
		||||
    std::shared_ptr<Kernel::SharedMemory> framebuffer_memory;
 | 
			
		||||
 | 
			
		||||
    MiiConfig config;
 | 
			
		||||
 | 
			
		||||
    MiiResult result{};
 | 
			
		||||
 | 
			
		||||
    std::shared_ptr<Frontend::MiiSelector> frontend_applet;
 | 
			
		||||
};
 | 
			
		||||
} // namespace HLE::Applets
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue