mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu-mainline.git
				synced 2025-03-21 01:53:15 +00:00 
			
		
		
		
	Merge pull request #823 from Subv/applets_drawing
Library applet support (swkbd for now)
This commit is contained in:
		
						commit
						f4e1d8ea36
					
				@ -25,6 +25,8 @@ set(SRCS
 | 
			
		||||
            file_sys/ivfc_archive.cpp
 | 
			
		||||
            hle/config_mem.cpp
 | 
			
		||||
            hle/hle.cpp
 | 
			
		||||
            hle/applets/applet.cpp
 | 
			
		||||
            hle/applets/swkbd.cpp
 | 
			
		||||
            hle/kernel/address_arbiter.cpp
 | 
			
		||||
            hle/kernel/event.cpp
 | 
			
		||||
            hle/kernel/kernel.cpp
 | 
			
		||||
@ -150,6 +152,8 @@ set(HEADERS
 | 
			
		||||
            hle/config_mem.h
 | 
			
		||||
            hle/function_wrappers.h
 | 
			
		||||
            hle/hle.h
 | 
			
		||||
            hle/applets/applet.h
 | 
			
		||||
            hle/applets/swkbd.h
 | 
			
		||||
            hle/kernel/address_arbiter.h
 | 
			
		||||
            hle/kernel/event.h
 | 
			
		||||
            hle/kernel/kernel.h
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										94
									
								
								src/core/hle/applets/applet.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								src/core/hle/applets/applet.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,94 @@
 | 
			
		||||
// Copyright 2015 Citra Emulator Project
 | 
			
		||||
// Licensed under GPLv2 or any later version
 | 
			
		||||
// Refer to the license.txt file included.
 | 
			
		||||
 | 
			
		||||
#include "common/assert.h"
 | 
			
		||||
#include "common/logging/log.h"
 | 
			
		||||
 | 
			
		||||
#include "core/core_timing.h"
 | 
			
		||||
#include "core/hle/applets/applet.h"
 | 
			
		||||
#include "core/hle/applets/swkbd.h"
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
// Specializes std::hash for AppletId, so that we can use it in std::unordered_map.
 | 
			
		||||
// Workaround for libstdc++ bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60970
 | 
			
		||||
namespace std {
 | 
			
		||||
    template <>
 | 
			
		||||
    struct hash<Service::APT::AppletId> {
 | 
			
		||||
        typedef Service::APT::AppletId argument_type;
 | 
			
		||||
        typedef std::size_t result_type;
 | 
			
		||||
 | 
			
		||||
        result_type operator()(const argument_type& id_code) const {
 | 
			
		||||
            typedef std::underlying_type<argument_type>::type Type;
 | 
			
		||||
            return std::hash<Type>()(static_cast<Type>(id_code));
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace HLE {
 | 
			
		||||
namespace Applets {
 | 
			
		||||
 | 
			
		||||
static std::unordered_map<Service::APT::AppletId, std::shared_ptr<Applet>> applets;
 | 
			
		||||
static u32 applet_update_event = -1; ///< The CoreTiming event identifier for the Applet update callback.
 | 
			
		||||
/// The interval at which the Applet update callback will be called, 16.6ms
 | 
			
		||||
static const u64 applet_update_interval_us = 16666;
 | 
			
		||||
 | 
			
		||||
ResultCode Applet::Create(Service::APT::AppletId id) {
 | 
			
		||||
    switch (id) {
 | 
			
		||||
    case Service::APT::AppletId::SoftwareKeyboard1:
 | 
			
		||||
    case Service::APT::AppletId::SoftwareKeyboard2:
 | 
			
		||||
        applets[id] = std::make_shared<SoftwareKeyboard>(id);
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        // TODO(Subv): Find the right error code
 | 
			
		||||
        return ResultCode(ErrorDescription::NotFound, ErrorModule::Applet, ErrorSummary::NotSupported, ErrorLevel::Permanent);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return RESULT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::shared_ptr<Applet> Applet::Get(Service::APT::AppletId id) {
 | 
			
		||||
    auto itr = applets.find(id);
 | 
			
		||||
    if (itr != applets.end())
 | 
			
		||||
        return itr->second;
 | 
			
		||||
    return nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Handles updating the current Applet every time it's called.
 | 
			
		||||
static void AppletUpdateEvent(u64 applet_id, int cycles_late) {
 | 
			
		||||
    Service::APT::AppletId id = static_cast<Service::APT::AppletId>(applet_id);
 | 
			
		||||
    std::shared_ptr<Applet> applet = Applet::Get(id);
 | 
			
		||||
    ASSERT_MSG(applet != nullptr, "Applet doesn't exist! applet_id=%08X", id);
 | 
			
		||||
 | 
			
		||||
    applet->Update();
 | 
			
		||||
 | 
			
		||||
    // If the applet is still running after the last update, reschedule the event
 | 
			
		||||
    if (applet->IsRunning()) {
 | 
			
		||||
        CoreTiming::ScheduleEvent(usToCycles(applet_update_interval_us) - cycles_late,
 | 
			
		||||
            applet_update_event, applet_id);
 | 
			
		||||
    } else {
 | 
			
		||||
        // Otherwise the applet has terminated, in which case we should clean it up
 | 
			
		||||
        applets[id] = nullptr;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ResultCode Applet::Start(const Service::APT::AppletStartupParameter& parameter) {
 | 
			
		||||
    ResultCode result = StartImpl(parameter);
 | 
			
		||||
    if (result.IsError())
 | 
			
		||||
        return result;
 | 
			
		||||
    // Schedule the update event
 | 
			
		||||
    CoreTiming::ScheduleEvent(usToCycles(applet_update_interval_us), applet_update_event, static_cast<u64>(id));
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Init() {
 | 
			
		||||
    // Register the applet update callback
 | 
			
		||||
    applet_update_event = CoreTiming::RegisterEvent("HLE Applet Update Event", AppletUpdateEvent);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Shutdown() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
} // namespace
 | 
			
		||||
							
								
								
									
										77
									
								
								src/core/hle/applets/applet.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								src/core/hle/applets/applet.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,77 @@
 | 
			
		||||
// Copyright 2015 Citra Emulator Project
 | 
			
		||||
// Licensed under GPLv2 or any later version
 | 
			
		||||
// Refer to the license.txt file included.
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "common/common_types.h"
 | 
			
		||||
#include "core/hle/kernel/kernel.h"
 | 
			
		||||
#include "core/hle/kernel/shared_memory.h"
 | 
			
		||||
#include "core/hle/service/apt/apt.h"
 | 
			
		||||
 | 
			
		||||
namespace HLE {
 | 
			
		||||
namespace Applets {
 | 
			
		||||
 | 
			
		||||
class Applet {
 | 
			
		||||
public:
 | 
			
		||||
    virtual ~Applet() { }
 | 
			
		||||
    Applet(Service::APT::AppletId id) : id(id) { }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates an instance of the Applet subclass identified by the parameter.
 | 
			
		||||
     * and stores it in a global map.
 | 
			
		||||
     * @param id Id of the applet to create.
 | 
			
		||||
     * @returns ResultCode Whether the operation was successful or not.
 | 
			
		||||
     */
 | 
			
		||||
    static ResultCode Create(Service::APT::AppletId id);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Retrieves the Applet instance identified by the specified id.
 | 
			
		||||
     * @param id Id of the Applet to retrieve.
 | 
			
		||||
     * @returns Requested Applet or nullptr if not found.
 | 
			
		||||
     */
 | 
			
		||||
    static std::shared_ptr<Applet> Get(Service::APT::AppletId id);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Handles a parameter from the application.
 | 
			
		||||
     * @param parameter Parameter data to handle.
 | 
			
		||||
     * @returns ResultCode Whether the operation was successful or not.
 | 
			
		||||
     */
 | 
			
		||||
    virtual ResultCode ReceiveParameter(const Service::APT::MessageParameter& parameter) = 0;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Handles the Applet start event, triggered from the application.
 | 
			
		||||
     * @param parameter Parameter data to handle.
 | 
			
		||||
     * @returns ResultCode Whether the operation was successful or not.
 | 
			
		||||
     */
 | 
			
		||||
    ResultCode Start(const Service::APT::AppletStartupParameter& parameter);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Whether the applet is currently executing instead of the host application or not.
 | 
			
		||||
     */
 | 
			
		||||
    virtual bool IsRunning() const = 0;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Handles an update tick for the Applet, lets it update the screen, send commands, etc.
 | 
			
		||||
     */
 | 
			
		||||
    virtual void Update() = 0;
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    /**
 | 
			
		||||
     * Handles the Applet start event, triggered from the application.
 | 
			
		||||
     * @param parameter Parameter data to handle.
 | 
			
		||||
     * @returns ResultCode Whether the operation was successful or not.
 | 
			
		||||
     */
 | 
			
		||||
    virtual ResultCode StartImpl(const Service::APT::AppletStartupParameter& parameter) = 0;
 | 
			
		||||
 | 
			
		||||
    Service::APT::AppletId id; ///< Id of this Applet
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Initializes the HLE applets
 | 
			
		||||
void Init();
 | 
			
		||||
 | 
			
		||||
/// Shuts down the HLE applets
 | 
			
		||||
void Shutdown();
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
} // namespace
 | 
			
		||||
							
								
								
									
										105
									
								
								src/core/hle/applets/swkbd.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								src/core/hle/applets/swkbd.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,105 @@
 | 
			
		||||
// Copyright 2015 Citra Emulator Project
 | 
			
		||||
// Licensed under GPLv2 or any later version
 | 
			
		||||
// Refer to the license.txt file included.
 | 
			
		||||
 | 
			
		||||
#include "common/assert.h"
 | 
			
		||||
#include "common/logging/log.h"
 | 
			
		||||
#include "common/string_util.h"
 | 
			
		||||
 | 
			
		||||
#include "core/hle/applets/swkbd.h"
 | 
			
		||||
#include "core/hle/service/hid/hid.h"
 | 
			
		||||
#include "core/hle/service/gsp_gpu.h"
 | 
			
		||||
#include "video_core/video_core.h"
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
namespace HLE {
 | 
			
		||||
namespace Applets {
 | 
			
		||||
 | 
			
		||||
SoftwareKeyboard::SoftwareKeyboard(Service::APT::AppletId id) : Applet(id), started(false) {
 | 
			
		||||
    // Create the SharedMemory that will hold the framebuffer data
 | 
			
		||||
    // TODO(Subv): What size should we use here?
 | 
			
		||||
    using Kernel::MemoryPermission;
 | 
			
		||||
    framebuffer_memory = Kernel::SharedMemory::Create(0x1000, MemoryPermission::ReadWrite, MemoryPermission::ReadWrite, "SoftwareKeyboard Memory");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ResultCode SoftwareKeyboard::ReceiveParameter(Service::APT::MessageParameter const& parameter) {
 | 
			
		||||
    if (parameter.signal != static_cast<u32>(Service::APT::SignalType::LibAppJustStarted)) {
 | 
			
		||||
        LOG_ERROR(Service_APT, "unsupported signal %u", parameter.signal);
 | 
			
		||||
        UNIMPLEMENTED();
 | 
			
		||||
        // TODO(Subv): Find the right error code
 | 
			
		||||
        return ResultCode(-1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Service::APT::MessageParameter result;
 | 
			
		||||
    // The buffer passed in parameter contains the data returned by GSPGPU::ImportDisplayCaptureInfo
 | 
			
		||||
    result.signal = static_cast<u32>(Service::APT::SignalType::LibAppFinished);
 | 
			
		||||
    result.data = nullptr;
 | 
			
		||||
    result.buffer_size = 0;
 | 
			
		||||
    result.destination_id = static_cast<u32>(Service::APT::AppletId::Application);
 | 
			
		||||
    result.sender_id = static_cast<u32>(id);
 | 
			
		||||
    result.object = framebuffer_memory;
 | 
			
		||||
 | 
			
		||||
    Service::APT::SendParameter(result);
 | 
			
		||||
    return RESULT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ResultCode SoftwareKeyboard::StartImpl(Service::APT::AppletStartupParameter const& parameter) {
 | 
			
		||||
    ASSERT_MSG(parameter.buffer_size == sizeof(config), "The size of the parameter (SoftwareKeyboardConfig) is wrong");
 | 
			
		||||
 | 
			
		||||
    memcpy(&config, parameter.data, parameter.buffer_size);
 | 
			
		||||
    text_memory = boost::static_pointer_cast<Kernel::SharedMemory, Kernel::Object>(parameter.object);
 | 
			
		||||
 | 
			
		||||
    // TODO(Subv): Verify if this is the correct behavior
 | 
			
		||||
    memset(text_memory->GetPointer(), 0, text_memory->size);
 | 
			
		||||
 | 
			
		||||
    DrawScreenKeyboard();
 | 
			
		||||
 | 
			
		||||
    started = true;
 | 
			
		||||
    return RESULT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SoftwareKeyboard::Update() {
 | 
			
		||||
    // TODO(Subv): Handle input using the touch events from the HID module
 | 
			
		||||
 | 
			
		||||
    // TODO(Subv): Remove this hardcoded text
 | 
			
		||||
    std::u16string text = Common::UTF8ToUTF16("Citra");
 | 
			
		||||
    memcpy(text_memory->GetPointer(), text.c_str(), text.length() * sizeof(char16_t));
 | 
			
		||||
 | 
			
		||||
    // TODO(Subv): Ask for input and write it to the shared memory
 | 
			
		||||
    // TODO(Subv): Find out what are the possible values for the return code,
 | 
			
		||||
    // some games seem to check for a hardcoded 2
 | 
			
		||||
    config.return_code = 2;
 | 
			
		||||
    config.text_length = 6;
 | 
			
		||||
    config.text_offset = 0;
 | 
			
		||||
 | 
			
		||||
    // 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 SoftwareKeyboard::DrawScreenKeyboard() {
 | 
			
		||||
    auto bottom_screen = GSP_GPU::GetFrameBufferInfo(0, 1);
 | 
			
		||||
    auto info = bottom_screen->framebuffer_info[bottom_screen->index];
 | 
			
		||||
 | 
			
		||||
    // TODO(Subv): Draw the HLE keyboard, for now just zero-fill the framebuffer
 | 
			
		||||
    memset(Memory::GetPointer(info.address_left), 0, info.stride * 320);
 | 
			
		||||
 | 
			
		||||
    GSP_GPU::SetBufferSwap(1, info);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SoftwareKeyboard::Finalize() {
 | 
			
		||||
    // Let the application know that we're closing
 | 
			
		||||
    Service::APT::MessageParameter message;
 | 
			
		||||
    message.buffer_size = sizeof(SoftwareKeyboardConfig);
 | 
			
		||||
    message.data = reinterpret_cast<u8*>(&config);
 | 
			
		||||
    message.signal = static_cast<u32>(Service::APT::SignalType::LibAppClosed);
 | 
			
		||||
    message.destination_id = static_cast<u32>(Service::APT::AppletId::Application);
 | 
			
		||||
    message.sender_id = static_cast<u32>(id);
 | 
			
		||||
    Service::APT::SendParameter(message);
 | 
			
		||||
 | 
			
		||||
    started = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
} // namespace
 | 
			
		||||
							
								
								
									
										87
									
								
								src/core/hle/applets/swkbd.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								src/core/hle/applets/swkbd.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,87 @@
 | 
			
		||||
// Copyright 2015 Citra Emulator Project
 | 
			
		||||
// Licensed under GPLv2 or any later version
 | 
			
		||||
// Refer to the license.txt file included.
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "common/common_types.h"
 | 
			
		||||
#include "core/hle/applets/applet.h"
 | 
			
		||||
#include "core/hle/kernel/kernel.h"
 | 
			
		||||
#include "core/hle/kernel/shared_memory.h"
 | 
			
		||||
#include "core/hle/service/apt/apt.h"
 | 
			
		||||
 | 
			
		||||
namespace HLE {
 | 
			
		||||
namespace Applets {
 | 
			
		||||
 | 
			
		||||
struct SoftwareKeyboardConfig {
 | 
			
		||||
    INSERT_PADDING_WORDS(0x8);
 | 
			
		||||
 | 
			
		||||
    u16 max_text_length; ///< Maximum length of the input text
 | 
			
		||||
 | 
			
		||||
    INSERT_PADDING_BYTES(0x6E);
 | 
			
		||||
 | 
			
		||||
    char16_t display_text[65]; ///< Text to display when asking the user for input
 | 
			
		||||
 | 
			
		||||
    INSERT_PADDING_BYTES(0xE);
 | 
			
		||||
 | 
			
		||||
    u32 default_text_offset; ///< Offset of the default text in the output SharedMemory
 | 
			
		||||
 | 
			
		||||
    INSERT_PADDING_WORDS(0x3);
 | 
			
		||||
 | 
			
		||||
    u32 shared_memory_size; ///< Size of the SharedMemory
 | 
			
		||||
 | 
			
		||||
    INSERT_PADDING_WORDS(0x1);
 | 
			
		||||
 | 
			
		||||
    u32 return_code; ///< Return code of the SoftwareKeyboard, usually 2, other values are unknown
 | 
			
		||||
 | 
			
		||||
    INSERT_PADDING_WORDS(0x2);
 | 
			
		||||
 | 
			
		||||
    u32 text_offset; ///< Offset in the SharedMemory where the output text starts
 | 
			
		||||
    u16 text_length; ///< Length in characters of the output text
 | 
			
		||||
 | 
			
		||||
    INSERT_PADDING_BYTES(0x2B6);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The size of this structure (0x400) has been verified via reverse engineering of multiple games
 | 
			
		||||
 * that use the software keyboard.
 | 
			
		||||
 */
 | 
			
		||||
static_assert(sizeof(SoftwareKeyboardConfig) == 0x400, "Software Keyboard Config size is wrong");
 | 
			
		||||
 | 
			
		||||
class SoftwareKeyboard final : public Applet {
 | 
			
		||||
public:
 | 
			
		||||
    SoftwareKeyboard(Service::APT::AppletId id);
 | 
			
		||||
    ~SoftwareKeyboard() {}
 | 
			
		||||
 | 
			
		||||
    ResultCode ReceiveParameter(const Service::APT::MessageParameter& parameter) override;
 | 
			
		||||
    ResultCode StartImpl(const Service::APT::AppletStartupParameter& parameter) override;
 | 
			
		||||
    void Update() override;
 | 
			
		||||
    bool IsRunning() const override { return started; }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Draws a keyboard to the current bottom screen framebuffer.
 | 
			
		||||
     */
 | 
			
		||||
    void DrawScreenKeyboard();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sends the LibAppletClosing signal to the application,
 | 
			
		||||
     * along with the relevant data buffers.
 | 
			
		||||
     */
 | 
			
		||||
    void Finalize();
 | 
			
		||||
 | 
			
		||||
    /// TODO(Subv): Find out what this is actually used for.
 | 
			
		||||
    /// It is believed that the application stores the current screen image here.
 | 
			
		||||
    Kernel::SharedPtr<Kernel::SharedMemory> framebuffer_memory;
 | 
			
		||||
 | 
			
		||||
    /// SharedMemory where the output text will be stored
 | 
			
		||||
    Kernel::SharedPtr<Kernel::SharedMemory> text_memory;
 | 
			
		||||
 | 
			
		||||
    /// Configuration of this instance of the SoftwareKeyboard, as received from the application
 | 
			
		||||
    SoftwareKeyboardConfig config;
 | 
			
		||||
 | 
			
		||||
    /// Whether this applet is currently running instead of the host application or not.
 | 
			
		||||
    bool started;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
} // namespace
 | 
			
		||||
@ -6,6 +6,7 @@
 | 
			
		||||
#include "common/file_util.h"
 | 
			
		||||
#include "common/logging/log.h"
 | 
			
		||||
 | 
			
		||||
#include "core/hle/applets/applet.h"
 | 
			
		||||
#include "core/hle/service/service.h"
 | 
			
		||||
#include "core/hle/service/apt/apt.h"
 | 
			
		||||
#include "core/hle/service/apt/apt_a.h"
 | 
			
		||||
@ -34,12 +35,21 @@ static Kernel::SharedPtr<Kernel::SharedMemory> shared_font_mem;
 | 
			
		||||
 | 
			
		||||
static Kernel::SharedPtr<Kernel::Mutex> lock;
 | 
			
		||||
static Kernel::SharedPtr<Kernel::Event> notification_event; ///< APT notification event
 | 
			
		||||
static Kernel::SharedPtr<Kernel::Event> start_event; ///< APT start event
 | 
			
		||||
static Kernel::SharedPtr<Kernel::Event> parameter_event; ///< APT parameter event
 | 
			
		||||
 | 
			
		||||
static std::vector<u8> shared_font;
 | 
			
		||||
 | 
			
		||||
static u32 cpu_percent; ///< CPU time available to the running application
 | 
			
		||||
 | 
			
		||||
/// Parameter data to be returned in the next call to Glance/ReceiveParameter
 | 
			
		||||
static MessageParameter next_parameter;
 | 
			
		||||
 | 
			
		||||
void SendParameter(const MessageParameter& parameter) {
 | 
			
		||||
    next_parameter = parameter;
 | 
			
		||||
    // Signal the event to let the application know that a new parameter is ready to be read
 | 
			
		||||
    parameter_event->Signal();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Initialize(Service::Interface* self) {
 | 
			
		||||
    u32* cmd_buff = Kernel::GetCommandBuffer();
 | 
			
		||||
    u32 app_id = cmd_buff[1];
 | 
			
		||||
@ -47,18 +57,18 @@ void Initialize(Service::Interface* self) {
 | 
			
		||||
 | 
			
		||||
    cmd_buff[2] = IPC::MoveHandleDesc(2);
 | 
			
		||||
    cmd_buff[3] = Kernel::g_handle_table.Create(notification_event).MoveFrom();
 | 
			
		||||
    cmd_buff[4] = Kernel::g_handle_table.Create(start_event).MoveFrom();
 | 
			
		||||
    cmd_buff[4] = Kernel::g_handle_table.Create(parameter_event).MoveFrom();
 | 
			
		||||
 | 
			
		||||
    // TODO(bunnei): Check if these events are cleared every time Initialize is called.
 | 
			
		||||
    notification_event->Clear();
 | 
			
		||||
    start_event->Clear();
 | 
			
		||||
    parameter_event->Clear();
 | 
			
		||||
 | 
			
		||||
    ASSERT_MSG((nullptr != lock), "Cannot initialize without lock");
 | 
			
		||||
    lock->Release();
 | 
			
		||||
 | 
			
		||||
    cmd_buff[1] = RESULT_SUCCESS.raw; // No error
 | 
			
		||||
 | 
			
		||||
    LOG_TRACE(Service_APT, "called app_id=0x%08X, flags=0x%08X", app_id, flags);
 | 
			
		||||
    LOG_DEBUG(Service_APT, "called app_id=0x%08X, flags=0x%08X", app_id, flags);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GetSharedFont(Service::Interface* self) {
 | 
			
		||||
@ -85,9 +95,6 @@ void GetSharedFont(Service::Interface* self) {
 | 
			
		||||
void NotifyToWait(Service::Interface* self) {
 | 
			
		||||
    u32* cmd_buff = Kernel::GetCommandBuffer();
 | 
			
		||||
    u32 app_id = cmd_buff[1];
 | 
			
		||||
    // TODO(Subv): Verify this, it seems to get SWKBD and Home Menu further.
 | 
			
		||||
    start_event->Signal();
 | 
			
		||||
 | 
			
		||||
    cmd_buff[1] = RESULT_SUCCESS.raw; // No error
 | 
			
		||||
    LOG_WARNING(Service_APT, "(STUBBED) app_id=%u", app_id);
 | 
			
		||||
}
 | 
			
		||||
@ -100,7 +107,7 @@ void GetLockHandle(Service::Interface* self) {
 | 
			
		||||
 | 
			
		||||
    // Not sure what these parameters are used for, but retail apps check that they are 0 after
 | 
			
		||||
    // GetLockHandle has been called.
 | 
			
		||||
    cmd_buff[2] = 0;
 | 
			
		||||
    cmd_buff[2] = 0; // Applet Attributes, this value is passed to Enable.
 | 
			
		||||
    cmd_buff[3] = 0;
 | 
			
		||||
    cmd_buff[4] = 0;
 | 
			
		||||
 | 
			
		||||
@ -110,9 +117,10 @@ void GetLockHandle(Service::Interface* self) {
 | 
			
		||||
 | 
			
		||||
void Enable(Service::Interface* self) {
 | 
			
		||||
    u32* cmd_buff = Kernel::GetCommandBuffer();
 | 
			
		||||
    u32 unk = cmd_buff[1]; // TODO(bunnei): What is this field used for?
 | 
			
		||||
    u32 attributes = cmd_buff[1];
 | 
			
		||||
    cmd_buff[1] = RESULT_SUCCESS.raw; // No error
 | 
			
		||||
    LOG_WARNING(Service_APT, "(STUBBED) called unk=0x%08X", unk);
 | 
			
		||||
    parameter_event->Signal(); // Let the application know that it has been started
 | 
			
		||||
    LOG_WARNING(Service_APT, "(STUBBED) called attributes=0x%08X", attributes);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GetAppletManInfo(Service::Interface* self) {
 | 
			
		||||
@ -121,8 +129,8 @@ void GetAppletManInfo(Service::Interface* self) {
 | 
			
		||||
    cmd_buff[1] = RESULT_SUCCESS.raw; // No error
 | 
			
		||||
    cmd_buff[2] = 0;
 | 
			
		||||
    cmd_buff[3] = 0;
 | 
			
		||||
    cmd_buff[4] = static_cast<u32>(AppID::HomeMenu); // Home menu AppID
 | 
			
		||||
    cmd_buff[5] = static_cast<u32>(AppID::Application); // TODO(purpasmart96): Do this correctly
 | 
			
		||||
    cmd_buff[4] = static_cast<u32>(AppletId::HomeMenu); // Home menu AppID
 | 
			
		||||
    cmd_buff[5] = static_cast<u32>(AppletId::Application); // TODO(purpasmart96): Do this correctly
 | 
			
		||||
 | 
			
		||||
    LOG_WARNING(Service_APT, "(STUBBED) called unk=0x%08X", unk);
 | 
			
		||||
}
 | 
			
		||||
@ -131,7 +139,13 @@ void IsRegistered(Service::Interface* self) {
 | 
			
		||||
    u32* cmd_buff = Kernel::GetCommandBuffer();
 | 
			
		||||
    u32 app_id = cmd_buff[1];
 | 
			
		||||
    cmd_buff[1] = RESULT_SUCCESS.raw; // No error
 | 
			
		||||
    cmd_buff[2] = 1; // Set to registered
 | 
			
		||||
    /// TODO(Subv): It is currently unknown what this value (0x400) means,
 | 
			
		||||
    /// but i believe it is used as a global "LibraryApplet" id, to verify if there's
 | 
			
		||||
    /// any LibApplet currently running. This is not verified.
 | 
			
		||||
    if (app_id != 0x400)
 | 
			
		||||
        cmd_buff[2] = 1; // Set to registered
 | 
			
		||||
    else
 | 
			
		||||
        cmd_buff[2] = 0; // Set to not registered
 | 
			
		||||
    LOG_WARNING(Service_APT, "(STUBBED) called app_id=0x%08X", app_id);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -145,50 +159,82 @@ void InquireNotification(Service::Interface* self) {
 | 
			
		||||
 | 
			
		||||
void SendParameter(Service::Interface* self) {
 | 
			
		||||
    u32* cmd_buff = Kernel::GetCommandBuffer();
 | 
			
		||||
    u32 src_app_id          = cmd_buff[1];
 | 
			
		||||
    u32 dst_app_id          = cmd_buff[2];
 | 
			
		||||
    u32 signal_type         = cmd_buff[3];
 | 
			
		||||
    u32 buffer_size         = cmd_buff[4];
 | 
			
		||||
    u32 value               = cmd_buff[5];
 | 
			
		||||
    u32 handle              = cmd_buff[6];
 | 
			
		||||
    u32 size                = cmd_buff[7];
 | 
			
		||||
    u32 in_param_buffer_ptr = cmd_buff[8];
 | 
			
		||||
    u32 src_app_id     = cmd_buff[1];
 | 
			
		||||
    u32 dst_app_id     = cmd_buff[2];
 | 
			
		||||
    u32 signal_type    = cmd_buff[3];
 | 
			
		||||
    u32 buffer_size    = cmd_buff[4];
 | 
			
		||||
    u32 value          = cmd_buff[5];
 | 
			
		||||
    u32 handle         = cmd_buff[6];
 | 
			
		||||
    u32 size           = cmd_buff[7];
 | 
			
		||||
    u32 buffer         = cmd_buff[8];
 | 
			
		||||
 | 
			
		||||
    cmd_buff[1] = RESULT_SUCCESS.raw; // No error
 | 
			
		||||
    std::shared_ptr<HLE::Applets::Applet> dest_applet = HLE::Applets::Applet::Get(static_cast<AppletId>(dst_app_id));
 | 
			
		||||
 | 
			
		||||
    if (dest_applet == nullptr) {
 | 
			
		||||
        LOG_ERROR(Service_APT, "Unknown applet id=0x%08X", dst_app_id);
 | 
			
		||||
        cmd_buff[1] = -1; // TODO(Subv): Find the right error code
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    MessageParameter param;
 | 
			
		||||
    param.buffer_size = buffer_size;
 | 
			
		||||
    param.destination_id = dst_app_id;
 | 
			
		||||
    param.sender_id = src_app_id;
 | 
			
		||||
    param.object = Kernel::g_handle_table.GetGeneric(handle);
 | 
			
		||||
    param.signal = signal_type;
 | 
			
		||||
    param.data = Memory::GetPointer(buffer);
 | 
			
		||||
 | 
			
		||||
    cmd_buff[1] = dest_applet->ReceiveParameter(param).raw;
 | 
			
		||||
 | 
			
		||||
    LOG_WARNING(Service_APT, "(STUBBED) called src_app_id=0x%08X, dst_app_id=0x%08X, signal_type=0x%08X,"
 | 
			
		||||
               "buffer_size=0x%08X, value=0x%08X, handle=0x%08X, size=0x%08X, in_param_buffer_ptr=0x%08X",
 | 
			
		||||
               src_app_id, dst_app_id, signal_type, buffer_size, value, handle, size, in_param_buffer_ptr);
 | 
			
		||||
               src_app_id, dst_app_id, signal_type, buffer_size, value, handle, size, buffer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ReceiveParameter(Service::Interface* self) {
 | 
			
		||||
    u32* cmd_buff = Kernel::GetCommandBuffer();
 | 
			
		||||
    u32 app_id = cmd_buff[1];
 | 
			
		||||
    u32 buffer_size = cmd_buff[2];
 | 
			
		||||
    VAddr buffer = cmd_buff[0x104 >> 2];
 | 
			
		||||
 | 
			
		||||
    cmd_buff[1] = RESULT_SUCCESS.raw; // No error
 | 
			
		||||
    cmd_buff[2] = 0;
 | 
			
		||||
    cmd_buff[3] = static_cast<u32>(SignalType::AppJustStarted); // Signal type
 | 
			
		||||
    cmd_buff[4] = 0x10; // Parameter buffer size (16)
 | 
			
		||||
    cmd_buff[5] = 0;
 | 
			
		||||
    cmd_buff[2] = next_parameter.sender_id;
 | 
			
		||||
    cmd_buff[3] = next_parameter.signal; // Signal type
 | 
			
		||||
    cmd_buff[4] = next_parameter.buffer_size; // Parameter buffer size
 | 
			
		||||
    cmd_buff[5] = 0x10;
 | 
			
		||||
    cmd_buff[6] = 0;
 | 
			
		||||
    cmd_buff[7] = 0;
 | 
			
		||||
    LOG_WARNING(Service_APT, "(STUBBED) called app_id=0x%08X, buffer_size=0x%08X", app_id, buffer_size);
 | 
			
		||||
    if (next_parameter.object != nullptr)
 | 
			
		||||
        cmd_buff[6] = Kernel::g_handle_table.Create(next_parameter.object).MoveFrom();
 | 
			
		||||
    cmd_buff[7] = (next_parameter.buffer_size << 14) | 2;
 | 
			
		||||
    cmd_buff[8] = buffer;
 | 
			
		||||
 | 
			
		||||
    if (next_parameter.data)
 | 
			
		||||
        memcpy(Memory::GetPointer(buffer), next_parameter.data, std::min(buffer_size, next_parameter.buffer_size));
 | 
			
		||||
 | 
			
		||||
    LOG_WARNING(Service_APT, "called app_id=0x%08X, buffer_size=0x%08X", app_id, buffer_size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GlanceParameter(Service::Interface* self) {
 | 
			
		||||
    u32* cmd_buff = Kernel::GetCommandBuffer();
 | 
			
		||||
    u32 app_id = cmd_buff[1];
 | 
			
		||||
    u32 buffer_size = cmd_buff[2];
 | 
			
		||||
    VAddr buffer = cmd_buff[0x104 >> 2];
 | 
			
		||||
 | 
			
		||||
    cmd_buff[1] = RESULT_SUCCESS.raw; // No error
 | 
			
		||||
    cmd_buff[2] = 0;
 | 
			
		||||
    cmd_buff[3] = static_cast<u32>(SignalType::AppJustStarted); // Signal type
 | 
			
		||||
    cmd_buff[4] = 0x10; // Parameter buffer size (16)
 | 
			
		||||
    cmd_buff[5] = 0;
 | 
			
		||||
    cmd_buff[2] = next_parameter.sender_id;
 | 
			
		||||
    cmd_buff[3] = next_parameter.signal; // Signal type
 | 
			
		||||
    cmd_buff[4] = next_parameter.buffer_size; // Parameter buffer size
 | 
			
		||||
    cmd_buff[5] = 0x10;
 | 
			
		||||
    cmd_buff[6] = 0;
 | 
			
		||||
    cmd_buff[7] = 0;
 | 
			
		||||
    if (next_parameter.object != nullptr)
 | 
			
		||||
        cmd_buff[6] = Kernel::g_handle_table.Create(next_parameter.object).MoveFrom();
 | 
			
		||||
    cmd_buff[7] = (next_parameter.buffer_size << 14) | 2;
 | 
			
		||||
    cmd_buff[8] = buffer;
 | 
			
		||||
 | 
			
		||||
    LOG_WARNING(Service_APT, "(STUBBED) called app_id=0x%08X, buffer_size=0x%08X", app_id, buffer_size);
 | 
			
		||||
    if (next_parameter.data)
 | 
			
		||||
        memcpy(Memory::GetPointer(buffer), next_parameter.data, std::min(buffer_size, next_parameter.buffer_size));
 | 
			
		||||
 | 
			
		||||
    LOG_WARNING(Service_APT, "called app_id=0x%08X, buffer_size=0x%08X", app_id, buffer_size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CancelParameter(Service::Interface* self) {
 | 
			
		||||
@ -240,7 +286,7 @@ void AppletUtility(Service::Interface* self) {
 | 
			
		||||
    u32* cmd_buff = Kernel::GetCommandBuffer();
 | 
			
		||||
 | 
			
		||||
    // These are from 3dbrew - I'm not really sure what they're used for.
 | 
			
		||||
    u32 unk = cmd_buff[1];
 | 
			
		||||
    u32 command = cmd_buff[1];
 | 
			
		||||
    u32 buffer1_size = cmd_buff[2];
 | 
			
		||||
    u32 buffer2_size = cmd_buff[3];
 | 
			
		||||
    u32 buffer1_addr = cmd_buff[5];
 | 
			
		||||
@ -248,8 +294,8 @@ void AppletUtility(Service::Interface* self) {
 | 
			
		||||
 | 
			
		||||
    cmd_buff[1] = RESULT_SUCCESS.raw; // No error
 | 
			
		||||
 | 
			
		||||
    LOG_WARNING(Service_APT, "(STUBBED) called unk=0x%08X, buffer1_size=0x%08X, buffer2_size=0x%08X, "
 | 
			
		||||
             "buffer1_addr=0x%08X, buffer2_addr=0x%08X", unk, buffer1_size, buffer2_size,
 | 
			
		||||
    LOG_WARNING(Service_APT, "(STUBBED) called command=0x%08X, buffer1_size=0x%08X, buffer2_size=0x%08X, "
 | 
			
		||||
             "buffer1_addr=0x%08X, buffer2_addr=0x%08X", command, buffer1_size, buffer2_size,
 | 
			
		||||
             buffer1_addr, buffer2_addr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -281,11 +327,41 @@ void GetAppCpuTimeLimit(Service::Interface* self) {
 | 
			
		||||
    LOG_WARNING(Service_APT, "(STUBBED) called value=%u", value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PrepareToStartLibraryApplet(Service::Interface* self) {
 | 
			
		||||
    u32* cmd_buff = Kernel::GetCommandBuffer();
 | 
			
		||||
    AppletId applet_id = static_cast<AppletId>(cmd_buff[1]);
 | 
			
		||||
    cmd_buff[1] = HLE::Applets::Applet::Create(applet_id).raw;
 | 
			
		||||
    LOG_DEBUG(Service_APT, "called applet_id=%08X", applet_id);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void StartLibraryApplet(Service::Interface* self) {
 | 
			
		||||
    u32* cmd_buff = Kernel::GetCommandBuffer();
 | 
			
		||||
    AppletId applet_id = static_cast<AppletId>(cmd_buff[1]);
 | 
			
		||||
    std::shared_ptr<HLE::Applets::Applet> applet = HLE::Applets::Applet::Get(applet_id);
 | 
			
		||||
 | 
			
		||||
    LOG_DEBUG(Service_APT, "called applet_id=%08X", applet_id);
 | 
			
		||||
 | 
			
		||||
    if (applet == nullptr) {
 | 
			
		||||
        LOG_ERROR(Service_APT, "unknown applet id=%08X", applet_id);
 | 
			
		||||
        cmd_buff[1] = -1; // TODO(Subv): Find the right error code
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    AppletStartupParameter parameter;
 | 
			
		||||
    parameter.buffer_size = cmd_buff[2];
 | 
			
		||||
    parameter.object = Kernel::g_handle_table.GetGeneric(cmd_buff[4]);
 | 
			
		||||
    parameter.data = Memory::GetPointer(cmd_buff[6]);
 | 
			
		||||
 | 
			
		||||
    cmd_buff[1] = applet->Start(parameter).raw;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Init() {
 | 
			
		||||
    AddService(new APT_A_Interface);
 | 
			
		||||
    AddService(new APT_S_Interface);
 | 
			
		||||
    AddService(new APT_U_Interface);
 | 
			
		||||
 | 
			
		||||
    HLE::Applets::Init();
 | 
			
		||||
 | 
			
		||||
    // Load the shared system font (if available).
 | 
			
		||||
    // The expected format is a decrypted, uncompressed BCFNT file with the 0x80 byte header
 | 
			
		||||
    // generated by the APT:U service. The best way to get is by dumping it from RAM. We've provided
 | 
			
		||||
@ -318,7 +394,10 @@ void Init() {
 | 
			
		||||
 | 
			
		||||
    // TODO(bunnei): Check if these are created in Initialize or on APT process startup.
 | 
			
		||||
    notification_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "APT_U:Notification");
 | 
			
		||||
    start_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "APT_U:Start");
 | 
			
		||||
    parameter_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "APT_U:Start");
 | 
			
		||||
 | 
			
		||||
    next_parameter.signal = static_cast<u32>(SignalType::AppJustStarted);
 | 
			
		||||
    next_parameter.destination_id = 0x300;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Shutdown() {
 | 
			
		||||
@ -326,7 +405,8 @@ void Shutdown() {
 | 
			
		||||
    shared_font_mem = nullptr;
 | 
			
		||||
    lock = nullptr;
 | 
			
		||||
    notification_event = nullptr;
 | 
			
		||||
    start_event = nullptr;
 | 
			
		||||
    parameter_event = nullptr;
 | 
			
		||||
    HLE::Applets::Shutdown();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace APT
 | 
			
		||||
 | 
			
		||||
@ -11,6 +11,23 @@
 | 
			
		||||
namespace Service {
 | 
			
		||||
namespace APT {
 | 
			
		||||
 | 
			
		||||
/// Holds information about the parameters used in Send/Glance/ReceiveParameter
 | 
			
		||||
struct MessageParameter {
 | 
			
		||||
    u32 sender_id = 0;
 | 
			
		||||
    u32 destination_id = 0;
 | 
			
		||||
    u32 signal = 0;
 | 
			
		||||
    u32 buffer_size = 0;
 | 
			
		||||
    Kernel::SharedPtr<Kernel::Object> object = nullptr;
 | 
			
		||||
    u8* data = nullptr;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Holds information about the parameters used in StartLibraryApplet
 | 
			
		||||
struct AppletStartupParameter {
 | 
			
		||||
    u32 buffer_size = 0;
 | 
			
		||||
    Kernel::SharedPtr<Kernel::Object> object = nullptr;
 | 
			
		||||
    u8* data = nullptr;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Signals used by APT functions
 | 
			
		||||
enum class SignalType : u32 {
 | 
			
		||||
    None              = 0x0,
 | 
			
		||||
@ -23,7 +40,7 @@ enum class SignalType : u32 {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// App Id's used by APT functions
 | 
			
		||||
enum class AppID : u32 {
 | 
			
		||||
enum class AppletId : u32 {
 | 
			
		||||
    HomeMenu           = 0x101,
 | 
			
		||||
    AlternateMenu      = 0x103,
 | 
			
		||||
    Camera             = 0x110,
 | 
			
		||||
@ -45,6 +62,9 @@ enum class AppID : u32 {
 | 
			
		||||
    SoftwareKeyboard2  = 0x401,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Send a parameter to the currently-running application, which will read it via ReceiveParameter
 | 
			
		||||
void SendParameter(const MessageParameter& parameter);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * APT::Initialize service function
 | 
			
		||||
 * Service function that initializes the APT process for the running application
 | 
			
		||||
@ -249,6 +269,33 @@ void SetAppCpuTimeLimit(Service::Interface* self);
 | 
			
		||||
 */
 | 
			
		||||
void GetAppCpuTimeLimit(Service::Interface* self);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * APT::PrepareToStartLibraryApplet service function
 | 
			
		||||
 *  Inputs:
 | 
			
		||||
 *      0 : Command header [0x00180040]
 | 
			
		||||
 *      1 : Id of the applet to start
 | 
			
		||||
 *  Outputs:
 | 
			
		||||
 *      0 : Return header
 | 
			
		||||
 *      1 : Result of function, 0 on success, otherwise error code
 | 
			
		||||
 */
 | 
			
		||||
void PrepareToStartLibraryApplet(Service::Interface* self);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * APT::StartLibraryApplet service function
 | 
			
		||||
 *  Inputs:
 | 
			
		||||
 *      0 : Command header [0x001E0084]
 | 
			
		||||
 *      1 : Id of the applet to start
 | 
			
		||||
 *      2 : Buffer size
 | 
			
		||||
 *      3 : Always 0?
 | 
			
		||||
 *      4 : Handle passed to the applet
 | 
			
		||||
 *      5 : (Size << 14) | 2
 | 
			
		||||
 *      6 : Input buffer virtual address
 | 
			
		||||
 *  Outputs:
 | 
			
		||||
 *      0 : Return header
 | 
			
		||||
 *      1 : Result of function, 0 on success, otherwise error code
 | 
			
		||||
 */
 | 
			
		||||
void StartLibraryApplet(Service::Interface* self);
 | 
			
		||||
 | 
			
		||||
/// Initialize the APT service
 | 
			
		||||
void Init();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -10,19 +10,24 @@ namespace Service {
 | 
			
		||||
namespace APT {
 | 
			
		||||
 | 
			
		||||
const Interface::FunctionInfo FunctionTable[] = {
 | 
			
		||||
    {0x00010040, GetLockHandle,      "GetLockHandle?"},
 | 
			
		||||
    {0x00020080, Initialize,         "Initialize?"},
 | 
			
		||||
    {0x00030040, Enable,             "Enable?"},
 | 
			
		||||
    {0x00040040, nullptr,            "Finalize?"},
 | 
			
		||||
    {0x00050040, nullptr,            "GetAppletManInfo?"},
 | 
			
		||||
    {0x00060040, nullptr,            "GetAppletInfo?"},
 | 
			
		||||
    {0x000D0080, ReceiveParameter,   "ReceiveParameter?"},
 | 
			
		||||
    {0x000E0080, GlanceParameter,    "GlanceParameter?"},
 | 
			
		||||
    {0x003B0040, nullptr,            "CancelLibraryApplet?"},
 | 
			
		||||
    {0x00430040, NotifyToWait,       "NotifyToWait?"},
 | 
			
		||||
    {0x00440000, GetSharedFont,      "GetSharedFont?"},
 | 
			
		||||
    {0x004B00C2, AppletUtility,      "AppletUtility?"},
 | 
			
		||||
    {0x00550040, nullptr,            "WriteInputToNsState?"},
 | 
			
		||||
    {0x00010040, GetLockHandle,                "GetLockHandle?"},
 | 
			
		||||
    {0x00020080, Initialize,                   "Initialize?"},
 | 
			
		||||
    {0x00030040, Enable,                       "Enable?"},
 | 
			
		||||
    {0x00040040, nullptr,                      "Finalize?"},
 | 
			
		||||
    {0x00050040, nullptr,                      "GetAppletManInfo?"},
 | 
			
		||||
    {0x00060040, nullptr,                      "GetAppletInfo?"},
 | 
			
		||||
    {0x00090040, IsRegistered,                 "IsRegistered"},
 | 
			
		||||
    {0x000C0104, SendParameter,                "SendParameter"},
 | 
			
		||||
    {0x000D0080, ReceiveParameter,             "ReceiveParameter"},
 | 
			
		||||
    {0x000E0080, GlanceParameter,              "GlanceParameter"},
 | 
			
		||||
    {0x000F0100, CancelParameter,              "CancelParameter"},
 | 
			
		||||
    {0x00180040, PrepareToStartLibraryApplet,  "PrepareToStartLibraryApplet"},
 | 
			
		||||
    {0x001E0084, StartLibraryApplet,           "StartLibraryApplet"},
 | 
			
		||||
    {0x003B0040, nullptr,                      "CancelLibraryApplet?"},
 | 
			
		||||
    {0x00430040, NotifyToWait,                 "NotifyToWait?"},
 | 
			
		||||
    {0x00440000, GetSharedFont,                "GetSharedFont?"},
 | 
			
		||||
    {0x004B00C2, AppletUtility,                "AppletUtility?"},
 | 
			
		||||
    {0x00550040, nullptr,                      "WriteInputToNsState?"},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
APT_A_Interface::APT_A_Interface() {
 | 
			
		||||
 | 
			
		||||
@ -35,13 +35,13 @@ const Interface::FunctionInfo FunctionTable[] = {
 | 
			
		||||
    {0x00150140, nullptr,                         "PrepareToStartApplication"},
 | 
			
		||||
    {0x00160040, nullptr,                         "PreloadLibraryApplet"},
 | 
			
		||||
    {0x00170040, nullptr,                         "FinishPreloadingLibraryApplet"},
 | 
			
		||||
    {0x00180040, nullptr,                         "PrepareToStartLibraryApplet"},
 | 
			
		||||
    {0x00180040, PrepareToStartLibraryApplet,     "PrepareToStartLibraryApplet"},
 | 
			
		||||
    {0x00190040, nullptr,                         "PrepareToStartSystemApplet"},
 | 
			
		||||
    {0x001A0000, nullptr,                         "PrepareToStartNewestHomeMenu"},
 | 
			
		||||
    {0x001B00C4, nullptr,                         "StartApplication"},
 | 
			
		||||
    {0x001C0000, nullptr,                         "WakeupApplication"},
 | 
			
		||||
    {0x001D0000, nullptr,                         "CancelApplication"},
 | 
			
		||||
    {0x001E0084, nullptr,                         "StartLibraryApplet"},
 | 
			
		||||
    {0x001E0084, StartLibraryApplet,              "StartLibraryApplet"},
 | 
			
		||||
    {0x001F0084, nullptr,                         "StartSystemApplet"},
 | 
			
		||||
    {0x00200044, nullptr,                         "StartNewestHomeMenu"},
 | 
			
		||||
    {0x00210000, nullptr,                         "OrderToCloseApplication"},
 | 
			
		||||
 | 
			
		||||
@ -42,7 +42,7 @@ static inline u8* GetCommandBuffer(u32 thread_id) {
 | 
			
		||||
    return g_shared_memory->GetPointer(0x800 + (thread_id * sizeof(CommandBuffer)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline FrameBufferUpdate* GetFrameBufferInfo(u32 thread_id, u32 screen_index) {
 | 
			
		||||
FrameBufferUpdate* GetFrameBufferInfo(u32 thread_id, u32 screen_index) {
 | 
			
		||||
    DEBUG_ASSERT_MSG(screen_index < 2, "Invalid screen index");
 | 
			
		||||
 | 
			
		||||
    // For each thread there are two FrameBufferUpdate fields
 | 
			
		||||
@ -205,7 +205,7 @@ static void ReadHWRegs(Service::Interface* self) {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void SetBufferSwap(u32 screen_id, const FrameBufferInfo& info) {
 | 
			
		||||
void SetBufferSwap(u32 screen_id, const FrameBufferInfo& info) {
 | 
			
		||||
    u32 base_address = 0x400000;
 | 
			
		||||
    PAddr phys_address_left = Memory::VirtualToPhysicalAddress(info.address_left);
 | 
			
		||||
    PAddr phys_address_right = Memory::VirtualToPhysicalAddress(info.address_right);
 | 
			
		||||
 | 
			
		||||
@ -173,4 +173,14 @@ public:
 | 
			
		||||
 */
 | 
			
		||||
void SignalInterrupt(InterruptId interrupt_id);
 | 
			
		||||
 | 
			
		||||
void SetBufferSwap(u32 screen_id, const FrameBufferInfo& info);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Retrieves the framebuffer info stored in the GSP shared memory for the
 | 
			
		||||
 * specified screen index and thread id.
 | 
			
		||||
 * @param thread_id GSP thread id of the process that accesses the structure that we are requesting.
 | 
			
		||||
 * @param screen_index Index of the screen we are requesting (Top = 0, Bottom = 1).
 | 
			
		||||
 * @returns FramebufferUpdate Information about the specified framebuffer.
 | 
			
		||||
 */
 | 
			
		||||
FrameBufferUpdate* GetFrameBufferInfo(u32 thread_id, u32 screen_index);
 | 
			
		||||
} // namespace
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user