mirror of
				https://git.tardis.systems/mirrors/yuzu
				synced 2025-11-04 04:34:07 +01:00 
			
		
		
		
	Merge pull request #12156 from german77/firmwarevs
yuzu: Display firmware version
This commit is contained in:
		
						commit
						257a1c884d
					
				@ -19,19 +19,8 @@
 | 
			
		||||
 | 
			
		||||
namespace Service::Set {
 | 
			
		||||
 | 
			
		||||
namespace {
 | 
			
		||||
constexpr u64 SYSTEM_VERSION_FILE_MINOR_REVISION_OFFSET = 0x05;
 | 
			
		||||
 | 
			
		||||
enum class GetFirmwareVersionType {
 | 
			
		||||
    Version1,
 | 
			
		||||
    Version2,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void GetFirmwareVersionImpl(Core::System& system, HLERequestContext& ctx,
 | 
			
		||||
                            GetFirmwareVersionType type) {
 | 
			
		||||
    ASSERT_MSG(ctx.GetWriteBufferSize() == 0x100,
 | 
			
		||||
               "FirmwareVersion output buffer must be 0x100 bytes in size!");
 | 
			
		||||
 | 
			
		||||
Result GetFirmwareVersionImpl(FirmwareVersionFormat& out_firmware, Core::System& system,
 | 
			
		||||
                              GetFirmwareVersionType type) {
 | 
			
		||||
    constexpr u64 FirmwareVersionSystemDataId = 0x0100000000000809;
 | 
			
		||||
    auto& fsc = system.GetFileSystemController();
 | 
			
		||||
 | 
			
		||||
@ -52,39 +41,34 @@ void GetFirmwareVersionImpl(Core::System& system, HLERequestContext& ctx,
 | 
			
		||||
            FileSys::SystemArchive::SynthesizeSystemArchive(FirmwareVersionSystemDataId));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const auto early_exit_failure = [&ctx](std::string_view desc, Result code) {
 | 
			
		||||
    const auto early_exit_failure = [](std::string_view desc, Result code) {
 | 
			
		||||
        LOG_ERROR(Service_SET, "General failure while attempting to resolve firmware version ({}).",
 | 
			
		||||
                  desc);
 | 
			
		||||
        IPC::ResponseBuilder rb{ctx, 2};
 | 
			
		||||
        rb.Push(code);
 | 
			
		||||
        return code;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    const auto ver_file = romfs->GetFile("file");
 | 
			
		||||
    if (ver_file == nullptr) {
 | 
			
		||||
        early_exit_failure("The system version archive didn't contain the file 'file'.",
 | 
			
		||||
                           FileSys::ERROR_INVALID_ARGUMENT);
 | 
			
		||||
        return;
 | 
			
		||||
        return early_exit_failure("The system version archive didn't contain the file 'file'.",
 | 
			
		||||
                                  FileSys::ERROR_INVALID_ARGUMENT);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    auto data = ver_file->ReadAllBytes();
 | 
			
		||||
    if (data.size() != 0x100) {
 | 
			
		||||
        early_exit_failure("The system version file 'file' was not the correct size.",
 | 
			
		||||
                           FileSys::ERROR_OUT_OF_BOUNDS);
 | 
			
		||||
        return;
 | 
			
		||||
    if (data.size() != sizeof(FirmwareVersionFormat)) {
 | 
			
		||||
        return early_exit_failure("The system version file 'file' was not the correct size.",
 | 
			
		||||
                                  FileSys::ERROR_OUT_OF_BOUNDS);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::memcpy(&out_firmware, data.data(), sizeof(FirmwareVersionFormat));
 | 
			
		||||
 | 
			
		||||
    // If the command is GetFirmwareVersion (as opposed to GetFirmwareVersion2), hardware will
 | 
			
		||||
    // zero out the REVISION_MINOR field.
 | 
			
		||||
    if (type == GetFirmwareVersionType::Version1) {
 | 
			
		||||
        data[SYSTEM_VERSION_FILE_MINOR_REVISION_OFFSET] = 0;
 | 
			
		||||
        out_firmware.revision_minor = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ctx.WriteBuffer(data);
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 2};
 | 
			
		||||
    rb.Push(ResultSuccess);
 | 
			
		||||
    return ResultSuccess;
 | 
			
		||||
}
 | 
			
		||||
} // Anonymous namespace
 | 
			
		||||
 | 
			
		||||
void SET_SYS::SetLanguageCode(HLERequestContext& ctx) {
 | 
			
		||||
    IPC::RequestParser rp{ctx};
 | 
			
		||||
@ -98,12 +82,32 @@ void SET_SYS::SetLanguageCode(HLERequestContext& ctx) {
 | 
			
		||||
 | 
			
		||||
void SET_SYS::GetFirmwareVersion(HLERequestContext& ctx) {
 | 
			
		||||
    LOG_DEBUG(Service_SET, "called");
 | 
			
		||||
    GetFirmwareVersionImpl(system, ctx, GetFirmwareVersionType::Version1);
 | 
			
		||||
 | 
			
		||||
    FirmwareVersionFormat firmware_data{};
 | 
			
		||||
    const auto result =
 | 
			
		||||
        GetFirmwareVersionImpl(firmware_data, system, GetFirmwareVersionType::Version1);
 | 
			
		||||
 | 
			
		||||
    if (result.IsSuccess()) {
 | 
			
		||||
        ctx.WriteBuffer(firmware_data);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 2};
 | 
			
		||||
    rb.Push(result);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SET_SYS::GetFirmwareVersion2(HLERequestContext& ctx) {
 | 
			
		||||
    LOG_DEBUG(Service_SET, "called");
 | 
			
		||||
    GetFirmwareVersionImpl(system, ctx, GetFirmwareVersionType::Version2);
 | 
			
		||||
 | 
			
		||||
    FirmwareVersionFormat firmware_data{};
 | 
			
		||||
    const auto result =
 | 
			
		||||
        GetFirmwareVersionImpl(firmware_data, system, GetFirmwareVersionType::Version2);
 | 
			
		||||
 | 
			
		||||
    if (result.IsSuccess()) {
 | 
			
		||||
        ctx.WriteBuffer(firmware_data);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 2};
 | 
			
		||||
    rb.Push(result);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SET_SYS::GetAccountSettings(HLERequestContext& ctx) {
 | 
			
		||||
 | 
			
		||||
@ -4,6 +4,7 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "common/uuid.h"
 | 
			
		||||
#include "core/hle/result.h"
 | 
			
		||||
#include "core/hle/service/service.h"
 | 
			
		||||
#include "core/hle/service/time/clock_types.h"
 | 
			
		||||
 | 
			
		||||
@ -12,6 +13,29 @@ class System;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace Service::Set {
 | 
			
		||||
enum class LanguageCode : u64;
 | 
			
		||||
enum class GetFirmwareVersionType {
 | 
			
		||||
    Version1,
 | 
			
		||||
    Version2,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct FirmwareVersionFormat {
 | 
			
		||||
    u8 major;
 | 
			
		||||
    u8 minor;
 | 
			
		||||
    u8 micro;
 | 
			
		||||
    INSERT_PADDING_BYTES(1);
 | 
			
		||||
    u8 revision_major;
 | 
			
		||||
    u8 revision_minor;
 | 
			
		||||
    INSERT_PADDING_BYTES(2);
 | 
			
		||||
    std::array<char, 0x20> platform;
 | 
			
		||||
    std::array<u8, 0x40> version_hash;
 | 
			
		||||
    std::array<char, 0x18> display_version;
 | 
			
		||||
    std::array<char, 0x80> display_title;
 | 
			
		||||
};
 | 
			
		||||
static_assert(sizeof(FirmwareVersionFormat) == 0x100, "FirmwareVersionFormat is an invalid size");
 | 
			
		||||
 | 
			
		||||
Result GetFirmwareVersionImpl(FirmwareVersionFormat& out_firmware, Core::System& system,
 | 
			
		||||
                              GetFirmwareVersionType type);
 | 
			
		||||
 | 
			
		||||
class SET_SYS final : public ServiceFramework<SET_SYS> {
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
@ -47,6 +47,7 @@
 | 
			
		||||
#include "core/hle/service/am/applet_ae.h"
 | 
			
		||||
#include "core/hle/service/am/applet_oe.h"
 | 
			
		||||
#include "core/hle/service/am/applets/applets.h"
 | 
			
		||||
#include "core/hle/service/set/set_sys.h"
 | 
			
		||||
#include "yuzu/multiplayer/state.h"
 | 
			
		||||
#include "yuzu/util/controller_navigation.h"
 | 
			
		||||
 | 
			
		||||
@ -1048,7 +1049,12 @@ void GMainWindow::InitializeWidgets() {
 | 
			
		||||
        statusBar()->addPermanentWidget(label);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // TODO (flTobi): Add the widget when multiplayer is fully implemented
 | 
			
		||||
    firmware_label = new QLabel();
 | 
			
		||||
    firmware_label->setObjectName(QStringLiteral("FirmwareLabel"));
 | 
			
		||||
    firmware_label->setVisible(false);
 | 
			
		||||
    firmware_label->setFocusPolicy(Qt::NoFocus);
 | 
			
		||||
    statusBar()->addPermanentWidget(firmware_label);
 | 
			
		||||
 | 
			
		||||
    statusBar()->addPermanentWidget(multiplayer_state->GetStatusText(), 0);
 | 
			
		||||
    statusBar()->addPermanentWidget(multiplayer_state->GetStatusIcon(), 0);
 | 
			
		||||
 | 
			
		||||
@ -2165,6 +2171,10 @@ void GMainWindow::OnEmulationStopped() {
 | 
			
		||||
    emu_frametime_label->setVisible(false);
 | 
			
		||||
    renderer_status_button->setEnabled(!UISettings::values.has_broken_vulkan);
 | 
			
		||||
 | 
			
		||||
    if (!firmware_label->text().isEmpty()) {
 | 
			
		||||
        firmware_label->setVisible(true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    current_game_path.clear();
 | 
			
		||||
 | 
			
		||||
    // When closing the game, destroy the GLWindow to clear the context after the game is closed
 | 
			
		||||
@ -4591,6 +4601,7 @@ void GMainWindow::UpdateStatusBar() {
 | 
			
		||||
    emu_speed_label->setVisible(!Settings::values.use_multi_core.GetValue());
 | 
			
		||||
    game_fps_label->setVisible(true);
 | 
			
		||||
    emu_frametime_label->setVisible(true);
 | 
			
		||||
    firmware_label->setVisible(false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GMainWindow::UpdateGPUAccuracyButton() {
 | 
			
		||||
@ -4810,6 +4821,8 @@ void GMainWindow::OnReinitializeKeys(ReinitializeKeyBehavior behavior) {
 | 
			
		||||
               "games."));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    SetFirmwareVersion();
 | 
			
		||||
 | 
			
		||||
    if (behavior == ReinitializeKeyBehavior::Warning) {
 | 
			
		||||
        game_list->PopulateAsync(UISettings::values.game_dirs);
 | 
			
		||||
    }
 | 
			
		||||
@ -4837,7 +4850,7 @@ bool GMainWindow::CheckSystemArchiveDecryption() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool GMainWindow::CheckFirmwarePresence() {
 | 
			
		||||
    constexpr u64 MiiEditId = 0x0100000000001009ull;
 | 
			
		||||
    constexpr u64 MiiEditId = static_cast<u64>(Service::AM::Applets::AppletProgramId::MiiEdit);
 | 
			
		||||
 | 
			
		||||
    auto bis_system = system->GetFileSystemController().GetSystemNANDContents();
 | 
			
		||||
    if (!bis_system) {
 | 
			
		||||
@ -4852,6 +4865,28 @@ bool GMainWindow::CheckFirmwarePresence() {
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GMainWindow::SetFirmwareVersion() {
 | 
			
		||||
    Service::Set::FirmwareVersionFormat firmware_data{};
 | 
			
		||||
    const auto result = Service::Set::GetFirmwareVersionImpl(
 | 
			
		||||
        firmware_data, *system, Service::Set::GetFirmwareVersionType::Version2);
 | 
			
		||||
 | 
			
		||||
    if (result.IsError() || !CheckFirmwarePresence()) {
 | 
			
		||||
        LOG_INFO(Frontend, "Installed firmware: No firmware available");
 | 
			
		||||
        firmware_label->setVisible(false);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    firmware_label->setVisible(true);
 | 
			
		||||
 | 
			
		||||
    const std::string display_version(firmware_data.display_version.data());
 | 
			
		||||
    const std::string display_title(firmware_data.display_title.data());
 | 
			
		||||
 | 
			
		||||
    LOG_INFO(Frontend, "Installed firmware: {}", display_title);
 | 
			
		||||
 | 
			
		||||
    firmware_label->setText(QString::fromStdString(display_version));
 | 
			
		||||
    firmware_label->setToolTip(QString::fromStdString(display_title));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool GMainWindow::SelectRomFSDumpTarget(const FileSys::ContentProvider& installed, u64 program_id,
 | 
			
		||||
                                        u64* selected_title_id, u8* selected_content_record_type) {
 | 
			
		||||
    using ContentInfo = std::tuple<u64, FileSys::TitleType, FileSys::ContentRecordType>;
 | 
			
		||||
 | 
			
		||||
@ -458,6 +458,7 @@ private:
 | 
			
		||||
    bool CheckDarkMode();
 | 
			
		||||
    bool CheckSystemArchiveDecryption();
 | 
			
		||||
    bool CheckFirmwarePresence();
 | 
			
		||||
    void SetFirmwareVersion();
 | 
			
		||||
    void ConfigureFilesystemProvider(const std::string& filepath);
 | 
			
		||||
    /**
 | 
			
		||||
     * Open (or not) the right confirm dialog based on current setting and game exit lock
 | 
			
		||||
@ -512,6 +513,7 @@ private:
 | 
			
		||||
    QLabel* game_fps_label = nullptr;
 | 
			
		||||
    QLabel* emu_frametime_label = nullptr;
 | 
			
		||||
    QLabel* tas_label = nullptr;
 | 
			
		||||
    QLabel* firmware_label = nullptr;
 | 
			
		||||
    QPushButton* gpu_accuracy_button = nullptr;
 | 
			
		||||
    QPushButton* renderer_status_button = nullptr;
 | 
			
		||||
    QPushButton* dock_status_button = nullptr;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user