early-access version 3992
This commit is contained in:
parent
3b750a7b7f
commit
365c4439d4
15 changed files with 280 additions and 102 deletions
|
@ -1,7 +1,7 @@
|
||||||
yuzu emulator early access
|
yuzu emulator early access
|
||||||
=============
|
=============
|
||||||
|
|
||||||
This is the source code for early-access 3990.
|
This is the source code for early-access 3992.
|
||||||
|
|
||||||
## Legal Notice
|
## Legal Notice
|
||||||
|
|
||||||
|
|
|
@ -167,6 +167,11 @@ protected:
|
||||||
*/
|
*/
|
||||||
std::pair<f32, f32> MapToTouchScreen(u32 framebuffer_x, u32 framebuffer_y) const;
|
std::pair<f32, f32> MapToTouchScreen(u32 framebuffer_x, u32 framebuffer_y) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clip the provided coordinates to be inside the touchscreen area.
|
||||||
|
*/
|
||||||
|
std::pair<u32, u32> ClipToTouchScreen(u32 new_x, u32 new_y) const;
|
||||||
|
|
||||||
WindowSystemInfo window_info;
|
WindowSystemInfo window_info;
|
||||||
|
|
||||||
bool strict_context_required = false;
|
bool strict_context_required = false;
|
||||||
|
@ -181,11 +186,6 @@ private:
|
||||||
// By default, ignore this request and do nothing.
|
// By default, ignore this request and do nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Clip the provided coordinates to be inside the touchscreen area.
|
|
||||||
*/
|
|
||||||
std::pair<u32, u32> ClipToTouchScreen(u32 new_x, u32 new_y) const;
|
|
||||||
|
|
||||||
Layout::FramebufferLayout framebuffer_layout; ///< Current framebuffer layout
|
Layout::FramebufferLayout framebuffer_layout; ///< Current framebuffer layout
|
||||||
|
|
||||||
u32 client_area_width; ///< Current client width, should be set by window impl.
|
u32 client_area_width; ///< Current client width, should be set by window impl.
|
||||||
|
|
|
@ -509,9 +509,11 @@ void EmulatedController::ReloadInput() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
turbo_button_state = 0;
|
turbo_button_state = 0;
|
||||||
|
is_initalized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmulatedController::UnloadInput() {
|
void EmulatedController::UnloadInput() {
|
||||||
|
is_initalized = false;
|
||||||
for (auto& button : button_devices) {
|
for (auto& button : button_devices) {
|
||||||
button.reset();
|
button.reset();
|
||||||
}
|
}
|
||||||
|
@ -1207,6 +1209,9 @@ void EmulatedController::SetNfc(const Common::Input::CallbackStatus& callback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EmulatedController::SetVibration(std::size_t device_index, VibrationValue vibration) {
|
bool EmulatedController::SetVibration(std::size_t device_index, VibrationValue vibration) {
|
||||||
|
if (!is_initalized) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (device_index >= output_devices.size()) {
|
if (device_index >= output_devices.size()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1242,6 +1247,10 @@ bool EmulatedController::IsVibrationEnabled(std::size_t device_index) {
|
||||||
const auto player_index = Service::HID::NpadIdTypeToIndex(npad_id_type);
|
const auto player_index = Service::HID::NpadIdTypeToIndex(npad_id_type);
|
||||||
const auto& player = Settings::values.players.GetValue()[player_index];
|
const auto& player = Settings::values.players.GetValue()[player_index];
|
||||||
|
|
||||||
|
if (!is_initalized) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!player.vibration_enabled) {
|
if (!player.vibration_enabled) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1261,6 +1270,10 @@ Common::Input::DriverResult EmulatedController::SetPollingMode(
|
||||||
EmulatedDeviceIndex device_index, Common::Input::PollingMode polling_mode) {
|
EmulatedDeviceIndex device_index, Common::Input::PollingMode polling_mode) {
|
||||||
LOG_INFO(Service_HID, "Set polling mode {}, device_index={}", polling_mode, device_index);
|
LOG_INFO(Service_HID, "Set polling mode {}, device_index={}", polling_mode, device_index);
|
||||||
|
|
||||||
|
if (!is_initalized) {
|
||||||
|
return Common::Input::DriverResult::InvalidHandle;
|
||||||
|
}
|
||||||
|
|
||||||
auto& left_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Left)];
|
auto& left_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Left)];
|
||||||
auto& right_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)];
|
auto& right_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)];
|
||||||
auto& nfc_output_device = output_devices[3];
|
auto& nfc_output_device = output_devices[3];
|
||||||
|
@ -1306,6 +1319,10 @@ bool EmulatedController::SetCameraFormat(
|
||||||
Core::IrSensor::ImageTransferProcessorFormat camera_format) {
|
Core::IrSensor::ImageTransferProcessorFormat camera_format) {
|
||||||
LOG_INFO(Service_HID, "Set camera format {}", camera_format);
|
LOG_INFO(Service_HID, "Set camera format {}", camera_format);
|
||||||
|
|
||||||
|
if (!is_initalized) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
auto& right_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)];
|
auto& right_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)];
|
||||||
auto& camera_output_device = output_devices[2];
|
auto& camera_output_device = output_devices[2];
|
||||||
|
|
||||||
|
@ -1329,6 +1346,11 @@ void EmulatedController::SetRingParam(Common::ParamPackage param) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EmulatedController::HasNfc() const {
|
bool EmulatedController::HasNfc() const {
|
||||||
|
|
||||||
|
if (!is_initalized) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
const auto& nfc_output_device = output_devices[3];
|
const auto& nfc_output_device = output_devices[3];
|
||||||
|
|
||||||
switch (npad_type) {
|
switch (npad_type) {
|
||||||
|
@ -1366,6 +1388,10 @@ bool EmulatedController::RemoveNfcHandle() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EmulatedController::StartNfcPolling() {
|
bool EmulatedController::StartNfcPolling() {
|
||||||
|
if (!is_initalized) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
auto& nfc_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)];
|
auto& nfc_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)];
|
||||||
auto& nfc_virtual_output_device = output_devices[3];
|
auto& nfc_virtual_output_device = output_devices[3];
|
||||||
|
|
||||||
|
@ -1377,6 +1403,10 @@ bool EmulatedController::StartNfcPolling() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EmulatedController::StopNfcPolling() {
|
bool EmulatedController::StopNfcPolling() {
|
||||||
|
if (!is_initalized) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
auto& nfc_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)];
|
auto& nfc_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)];
|
||||||
auto& nfc_virtual_output_device = output_devices[3];
|
auto& nfc_virtual_output_device = output_devices[3];
|
||||||
|
|
||||||
|
@ -1388,6 +1418,10 @@ bool EmulatedController::StopNfcPolling() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EmulatedController::ReadAmiiboData(std::vector<u8>& data) {
|
bool EmulatedController::ReadAmiiboData(std::vector<u8>& data) {
|
||||||
|
if (!is_initalized) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
auto& nfc_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)];
|
auto& nfc_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)];
|
||||||
auto& nfc_virtual_output_device = output_devices[3];
|
auto& nfc_virtual_output_device = output_devices[3];
|
||||||
|
|
||||||
|
@ -1400,6 +1434,10 @@ bool EmulatedController::ReadAmiiboData(std::vector<u8>& data) {
|
||||||
|
|
||||||
bool EmulatedController::ReadMifareData(const Common::Input::MifareRequest& request,
|
bool EmulatedController::ReadMifareData(const Common::Input::MifareRequest& request,
|
||||||
Common::Input::MifareRequest& out_data) {
|
Common::Input::MifareRequest& out_data) {
|
||||||
|
if (!is_initalized) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
auto& nfc_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)];
|
auto& nfc_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)];
|
||||||
auto& nfc_virtual_output_device = output_devices[3];
|
auto& nfc_virtual_output_device = output_devices[3];
|
||||||
|
|
||||||
|
@ -1412,6 +1450,10 @@ bool EmulatedController::ReadMifareData(const Common::Input::MifareRequest& requ
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EmulatedController::WriteMifareData(const Common::Input::MifareRequest& request) {
|
bool EmulatedController::WriteMifareData(const Common::Input::MifareRequest& request) {
|
||||||
|
if (!is_initalized) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
auto& nfc_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)];
|
auto& nfc_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)];
|
||||||
auto& nfc_virtual_output_device = output_devices[3];
|
auto& nfc_virtual_output_device = output_devices[3];
|
||||||
|
|
||||||
|
@ -1423,6 +1465,10 @@ bool EmulatedController::WriteMifareData(const Common::Input::MifareRequest& req
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EmulatedController::WriteNfc(const std::vector<u8>& data) {
|
bool EmulatedController::WriteNfc(const std::vector<u8>& data) {
|
||||||
|
if (!is_initalized) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
auto& nfc_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)];
|
auto& nfc_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)];
|
||||||
auto& nfc_virtual_output_device = output_devices[3];
|
auto& nfc_virtual_output_device = output_devices[3];
|
||||||
|
|
||||||
|
@ -1434,6 +1480,10 @@ bool EmulatedController::WriteNfc(const std::vector<u8>& data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmulatedController::SetLedPattern() {
|
void EmulatedController::SetLedPattern() {
|
||||||
|
if (!is_initalized) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (auto& device : output_devices) {
|
for (auto& device : output_devices) {
|
||||||
if (!device) {
|
if (!device) {
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -559,6 +559,7 @@ private:
|
||||||
NpadStyleTag supported_style_tag{NpadStyleSet::All};
|
NpadStyleTag supported_style_tag{NpadStyleSet::All};
|
||||||
bool is_connected{false};
|
bool is_connected{false};
|
||||||
bool is_configuring{false};
|
bool is_configuring{false};
|
||||||
|
bool is_initalized{false};
|
||||||
bool system_buttons_enabled{true};
|
bool system_buttons_enabled{true};
|
||||||
f32 motion_sensitivity{Core::HID::MotionInput::IsAtRestStandard};
|
f32 motion_sensitivity{Core::HID::MotionInput::IsAtRestStandard};
|
||||||
u32 turbo_button_state{0};
|
u32 turbo_button_state{0};
|
||||||
|
|
|
@ -19,19 +19,8 @@
|
||||||
|
|
||||||
namespace Service::Set {
|
namespace Service::Set {
|
||||||
|
|
||||||
namespace {
|
Result GetFirmwareVersionImpl(FirmwareVersionFormat& out_firmware, Core::System& system,
|
||||||
constexpr u64 SYSTEM_VERSION_FILE_MINOR_REVISION_OFFSET = 0x05;
|
GetFirmwareVersionType type) {
|
||||||
|
|
||||||
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!");
|
|
||||||
|
|
||||||
constexpr u64 FirmwareVersionSystemDataId = 0x0100000000000809;
|
constexpr u64 FirmwareVersionSystemDataId = 0x0100000000000809;
|
||||||
auto& fsc = system.GetFileSystemController();
|
auto& fsc = system.GetFileSystemController();
|
||||||
|
|
||||||
|
@ -52,39 +41,34 @@ void GetFirmwareVersionImpl(Core::System& system, HLERequestContext& ctx,
|
||||||
FileSys::SystemArchive::SynthesizeSystemArchive(FirmwareVersionSystemDataId));
|
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 ({}).",
|
LOG_ERROR(Service_SET, "General failure while attempting to resolve firmware version ({}).",
|
||||||
desc);
|
desc);
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
return code;
|
||||||
rb.Push(code);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto ver_file = romfs->GetFile("file");
|
const auto ver_file = romfs->GetFile("file");
|
||||||
if (ver_file == nullptr) {
|
if (ver_file == nullptr) {
|
||||||
early_exit_failure("The system version archive didn't contain the file 'file'.",
|
return early_exit_failure("The system version archive didn't contain the file 'file'.",
|
||||||
FileSys::ERROR_INVALID_ARGUMENT);
|
FileSys::ERROR_INVALID_ARGUMENT);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto data = ver_file->ReadAllBytes();
|
auto data = ver_file->ReadAllBytes();
|
||||||
if (data.size() != 0x100) {
|
if (data.size() != sizeof(FirmwareVersionFormat)) {
|
||||||
early_exit_failure("The system version file 'file' was not the correct size.",
|
return early_exit_failure("The system version file 'file' was not the correct size.",
|
||||||
FileSys::ERROR_OUT_OF_BOUNDS);
|
FileSys::ERROR_OUT_OF_BOUNDS);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::memcpy(&out_firmware, data.data(), sizeof(FirmwareVersionFormat));
|
||||||
|
|
||||||
// If the command is GetFirmwareVersion (as opposed to GetFirmwareVersion2), hardware will
|
// If the command is GetFirmwareVersion (as opposed to GetFirmwareVersion2), hardware will
|
||||||
// zero out the REVISION_MINOR field.
|
// zero out the REVISION_MINOR field.
|
||||||
if (type == GetFirmwareVersionType::Version1) {
|
if (type == GetFirmwareVersionType::Version1) {
|
||||||
data[SYSTEM_VERSION_FILE_MINOR_REVISION_OFFSET] = 0;
|
out_firmware.revision_minor = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.WriteBuffer(data);
|
return ResultSuccess;
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
|
||||||
rb.Push(ResultSuccess);
|
|
||||||
}
|
}
|
||||||
} // Anonymous namespace
|
|
||||||
|
|
||||||
void SET_SYS::SetLanguageCode(HLERequestContext& ctx) {
|
void SET_SYS::SetLanguageCode(HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp{ctx};
|
IPC::RequestParser rp{ctx};
|
||||||
|
@ -98,12 +82,32 @@ void SET_SYS::SetLanguageCode(HLERequestContext& ctx) {
|
||||||
|
|
||||||
void SET_SYS::GetFirmwareVersion(HLERequestContext& ctx) {
|
void SET_SYS::GetFirmwareVersion(HLERequestContext& ctx) {
|
||||||
LOG_DEBUG(Service_SET, "called");
|
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) {
|
void SET_SYS::GetFirmwareVersion2(HLERequestContext& ctx) {
|
||||||
LOG_DEBUG(Service_SET, "called");
|
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) {
|
void SET_SYS::GetAccountSettings(HLERequestContext& ctx) {
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "common/uuid.h"
|
#include "common/uuid.h"
|
||||||
|
#include "core/hle/result.h"
|
||||||
#include "core/hle/service/service.h"
|
#include "core/hle/service/service.h"
|
||||||
#include "core/hle/service/time/clock_types.h"
|
#include "core/hle/service/time/clock_types.h"
|
||||||
|
|
||||||
|
@ -12,6 +13,29 @@ class System;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Service::Set {
|
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> {
|
class SET_SYS final : public ServiceFramework<SET_SYS> {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -11,6 +11,11 @@
|
||||||
#include "core/hle/service/time/errors.h"
|
#include "core/hle/service/time/errors.h"
|
||||||
#include "core/hle/service/time/time_zone_types.h"
|
#include "core/hle/service/time/time_zone_types.h"
|
||||||
|
|
||||||
|
// Defined by WinBase.h on Windows
|
||||||
|
#ifdef GetCurrentTime
|
||||||
|
#undef GetCurrentTime
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Service::Time::Clock {
|
namespace Service::Time::Clock {
|
||||||
|
|
||||||
enum class TimeType : u8 {
|
enum class TimeType : u8 {
|
||||||
|
|
|
@ -265,33 +265,33 @@ std::string Device::GetVendorName() const {
|
||||||
if (vendor_name == "Intel") {
|
if (vendor_name == "Intel") {
|
||||||
// For Mesa, `Intel` is an overloaded vendor string that could mean crocus or iris.
|
// For Mesa, `Intel` is an overloaded vendor string that could mean crocus or iris.
|
||||||
// Simply return `INTEL` for those as well as the Windows driver.
|
// Simply return `INTEL` for those as well as the Windows driver.
|
||||||
return "INTEL";
|
return "Intel";
|
||||||
}
|
}
|
||||||
if (vendor_name == "Intel Open Source Technology Center") {
|
if (vendor_name == "Intel Open Source Technology Center") {
|
||||||
return "I965";
|
return "i965";
|
||||||
}
|
}
|
||||||
if (vendor_name == "Mesa Project") {
|
if (vendor_name == "Mesa Project") {
|
||||||
return "I915";
|
return "i915";
|
||||||
}
|
}
|
||||||
if (vendor_name == "Mesa/X.org") {
|
if (vendor_name == "Mesa/X.org") {
|
||||||
// This vendor string is overloaded between llvmpipe, softpipe, and virgl, so just return
|
// This vendor string is overloaded between llvmpipe, softpipe, and virgl, so just return
|
||||||
// MESA instead of one of those driver names.
|
// MESA instead of one of those driver names.
|
||||||
return "MESA";
|
return "Mesa";
|
||||||
}
|
}
|
||||||
if (vendor_name == "AMD") {
|
if (vendor_name == "AMD") {
|
||||||
return "RADEONSI";
|
return "RadeonSI";
|
||||||
}
|
}
|
||||||
if (vendor_name == "nouveau") {
|
if (vendor_name == "nouveau") {
|
||||||
return "NOUVEAU";
|
return "Nouveau";
|
||||||
}
|
}
|
||||||
if (vendor_name == "X.Org") {
|
if (vendor_name == "X.Org") {
|
||||||
return "R600";
|
return "R600";
|
||||||
}
|
}
|
||||||
if (vendor_name == "Collabora Ltd") {
|
if (vendor_name == "Collabora Ltd") {
|
||||||
return "ZINK";
|
return "Zink";
|
||||||
}
|
}
|
||||||
if (vendor_name == "Intel Corporation") {
|
if (vendor_name == "Intel Corporation") {
|
||||||
return "OPENSWR";
|
return "OpenSWR";
|
||||||
}
|
}
|
||||||
if (vendor_name == "Microsoft Corporation") {
|
if (vendor_name == "Microsoft Corporation") {
|
||||||
return "D3D12";
|
return "D3D12";
|
||||||
|
@ -300,7 +300,7 @@ std::string Device::GetVendorName() const {
|
||||||
// Mesa's tegra driver reports `NVIDIA`. Only present in this list because the default
|
// Mesa's tegra driver reports `NVIDIA`. Only present in this list because the default
|
||||||
// strategy would have returned `NVIDIA` here for this driver, the same result as the
|
// strategy would have returned `NVIDIA` here for this driver, the same result as the
|
||||||
// proprietary driver.
|
// proprietary driver.
|
||||||
return "TEGRA";
|
return "Tegra";
|
||||||
}
|
}
|
||||||
return vendor_name;
|
return vendor_name;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1785,8 +1785,22 @@ ImageView::ImageView(TextureCacheRuntime&, const VideoCommon::ImageInfo& info,
|
||||||
: VideoCommon::ImageViewBase{info, view_info, gpu_addr_},
|
: VideoCommon::ImageViewBase{info, view_info, gpu_addr_},
|
||||||
buffer_size{VideoCommon::CalculateGuestSizeInBytes(info)} {}
|
buffer_size{VideoCommon::CalculateGuestSizeInBytes(info)} {}
|
||||||
|
|
||||||
ImageView::ImageView(TextureCacheRuntime&, const VideoCommon::NullImageViewParams& params)
|
ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::NullImageViewParams& params)
|
||||||
: VideoCommon::ImageViewBase{params} {}
|
: VideoCommon::ImageViewBase{params}, device{&runtime.device} {
|
||||||
|
if (device->HasNullDescriptor()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle fallback for devices without nullDescriptor
|
||||||
|
ImageInfo info{};
|
||||||
|
info.format = PixelFormat::A8B8G8R8_UNORM;
|
||||||
|
|
||||||
|
null_image = MakeImage(*device, runtime.memory_allocator, info, {});
|
||||||
|
image_handle = *null_image;
|
||||||
|
for (u32 i = 0; i < Shader::NUM_TEXTURE_TYPES; i++) {
|
||||||
|
image_views[i] = MakeView(VK_FORMAT_A8B8G8R8_UNORM_PACK32, VK_IMAGE_ASPECT_COLOR_BIT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ImageView::~ImageView() = default;
|
ImageView::~ImageView() = default;
|
||||||
|
|
||||||
|
|
|
@ -267,6 +267,7 @@ private:
|
||||||
vk::ImageView depth_view;
|
vk::ImageView depth_view;
|
||||||
vk::ImageView stencil_view;
|
vk::ImageView stencil_view;
|
||||||
vk::ImageView color_view;
|
vk::ImageView color_view;
|
||||||
|
vk::Image null_image;
|
||||||
VkImage image_handle = VK_NULL_HANDLE;
|
VkImage image_handle = VK_NULL_HANDLE;
|
||||||
VkImageView render_target = VK_NULL_HANDLE;
|
VkImageView render_target = VK_NULL_HANDLE;
|
||||||
VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_1_BIT;
|
VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
|
|
@ -847,11 +847,41 @@ std::string Device::GetDriverName() const {
|
||||||
case VK_DRIVER_ID_NVIDIA_PROPRIETARY:
|
case VK_DRIVER_ID_NVIDIA_PROPRIETARY:
|
||||||
return "NVIDIA";
|
return "NVIDIA";
|
||||||
case VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS:
|
case VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS:
|
||||||
return "INTEL";
|
return "Intel";
|
||||||
case VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA:
|
case VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA:
|
||||||
return "ANV";
|
return "ANV";
|
||||||
|
case VK_DRIVER_ID_IMAGINATION_PROPRIETARY:
|
||||||
|
return "PowerVR";
|
||||||
|
case VK_DRIVER_ID_QUALCOMM_PROPRIETARY:
|
||||||
|
return "Qualcomm";
|
||||||
|
case VK_DRIVER_ID_ARM_PROPRIETARY:
|
||||||
|
return "Mali";
|
||||||
|
case VK_DRIVER_ID_GOOGLE_SWIFTSHADER:
|
||||||
|
return "SwiftShader";
|
||||||
|
case VK_DRIVER_ID_BROADCOM_PROPRIETARY:
|
||||||
|
return "Broadcom";
|
||||||
case VK_DRIVER_ID_MESA_LLVMPIPE:
|
case VK_DRIVER_ID_MESA_LLVMPIPE:
|
||||||
return "LAVAPIPE";
|
return "Lavapipe";
|
||||||
|
case VK_DRIVER_ID_MOLTENVK:
|
||||||
|
return "MoltenVK";
|
||||||
|
case VK_DRIVER_ID_VERISILICON_PROPRIETARY:
|
||||||
|
return "Vivante";
|
||||||
|
case VK_DRIVER_ID_MESA_TURNIP:
|
||||||
|
return "Turnip";
|
||||||
|
case VK_DRIVER_ID_MESA_V3DV:
|
||||||
|
return "V3DV";
|
||||||
|
case VK_DRIVER_ID_MESA_PANVK:
|
||||||
|
return "PanVK";
|
||||||
|
case VK_DRIVER_ID_MESA_VENUS:
|
||||||
|
return "Venus";
|
||||||
|
case VK_DRIVER_ID_MESA_DOZEN:
|
||||||
|
return "Dozen";
|
||||||
|
case VK_DRIVER_ID_MESA_NVK:
|
||||||
|
return "NVK";
|
||||||
|
case VK_DRIVER_ID_IMAGINATION_OPEN_SOURCE_MESA:
|
||||||
|
return "PVR";
|
||||||
|
// case VK_DRIVER_ID_MESA_AGXV:
|
||||||
|
// return "Asahi";
|
||||||
default:
|
default:
|
||||||
return properties.driver.driverName;
|
return properties.driver.driverName;
|
||||||
}
|
}
|
||||||
|
@ -869,7 +899,8 @@ bool Device::ShouldBoostClocks() const {
|
||||||
driver_id == VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA ||
|
driver_id == VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA ||
|
||||||
driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY || driver_id == VK_DRIVER_ID_MESA_TURNIP;
|
driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY || driver_id == VK_DRIVER_ID_MESA_TURNIP;
|
||||||
|
|
||||||
const bool is_steam_deck = vendor_id == 0x1002 && device_id == 0x163F;
|
const bool is_steam_deck = (vendor_id == 0x1002 && device_id == 0x163F) ||
|
||||||
|
(vendor_id == 0x1002 && device_id == 0x1435);
|
||||||
|
|
||||||
const bool is_debugging = this->HasDebuggingToolAttached();
|
const bool is_debugging = this->HasDebuggingToolAttached();
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
#include <QSize>
|
#include <QSize>
|
||||||
#include <QStringLiteral>
|
#include <QStringLiteral>
|
||||||
#include <QSurfaceFormat>
|
#include <QSurfaceFormat>
|
||||||
#include <QTimer>
|
|
||||||
#include <QWindow>
|
#include <QWindow>
|
||||||
#include <QtCore/qobjectdefs.h>
|
#include <QtCore/qobjectdefs.h>
|
||||||
|
|
||||||
|
@ -66,6 +65,8 @@ class QObject;
|
||||||
class QPaintEngine;
|
class QPaintEngine;
|
||||||
class QSurface;
|
class QSurface;
|
||||||
|
|
||||||
|
constexpr int default_mouse_constrain_timeout = 10;
|
||||||
|
|
||||||
EmuThread::EmuThread(Core::System& system) : m_system{system} {}
|
EmuThread::EmuThread(Core::System& system) : m_system{system} {}
|
||||||
|
|
||||||
EmuThread::~EmuThread() = default;
|
EmuThread::~EmuThread() = default;
|
||||||
|
@ -304,6 +305,9 @@ GRenderWindow::GRenderWindow(GMainWindow* parent, EmuThread* emu_thread_,
|
||||||
Qt::QueuedConnection);
|
Qt::QueuedConnection);
|
||||||
connect(this, &GRenderWindow::ExitSignal, parent, &GMainWindow::OnExit, Qt::QueuedConnection);
|
connect(this, &GRenderWindow::ExitSignal, parent, &GMainWindow::OnExit, Qt::QueuedConnection);
|
||||||
connect(this, &GRenderWindow::TasPlaybackStateChanged, parent, &GMainWindow::OnTasStateChanged);
|
connect(this, &GRenderWindow::TasPlaybackStateChanged, parent, &GMainWindow::OnTasStateChanged);
|
||||||
|
|
||||||
|
mouse_constrain_timer.setInterval(default_mouse_constrain_timeout);
|
||||||
|
connect(&mouse_constrain_timer, &QTimer::timeout, this, &GRenderWindow::ConstrainMouse);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GRenderWindow::ExecuteProgram(std::size_t program_index) {
|
void GRenderWindow::ExecuteProgram(std::size_t program_index) {
|
||||||
|
@ -393,6 +397,22 @@ void GRenderWindow::closeEvent(QCloseEvent* event) {
|
||||||
QWidget::closeEvent(event);
|
QWidget::closeEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GRenderWindow::leaveEvent(QEvent* event) {
|
||||||
|
if (Settings::values.mouse_panning) {
|
||||||
|
const QRect& rect = QWidget::geometry();
|
||||||
|
QPoint position = QCursor::pos();
|
||||||
|
|
||||||
|
qint32 x = qBound(rect.left(), position.x(), rect.right());
|
||||||
|
qint32 y = qBound(rect.top(), position.y(), rect.bottom());
|
||||||
|
// Only start the timer if the mouse has left the window bound.
|
||||||
|
// The leave event is also triggered when the window looses focus.
|
||||||
|
if (x != position.x() || y != position.y()) {
|
||||||
|
mouse_constrain_timer.start();
|
||||||
|
}
|
||||||
|
event->accept();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int GRenderWindow::QtKeyToSwitchKey(Qt::Key qt_key) {
|
int GRenderWindow::QtKeyToSwitchKey(Qt::Key qt_key) {
|
||||||
static constexpr std::array<std::pair<Qt::Key, Settings::NativeKeyboard::Keys>, 106> key_map = {
|
static constexpr std::array<std::pair<Qt::Key, Settings::NativeKeyboard::Keys>, 106> key_map = {
|
||||||
std::pair<Qt::Key, Settings::NativeKeyboard::Keys>{Qt::Key_A, Settings::NativeKeyboard::A},
|
std::pair<Qt::Key, Settings::NativeKeyboard::Keys>{Qt::Key_A, Settings::NativeKeyboard::A},
|
||||||
|
@ -658,10 +678,19 @@ void GRenderWindow::mouseMoveEvent(QMouseEvent* event) {
|
||||||
input_subsystem->GetMouse()->TouchMove(touch_x, touch_y);
|
input_subsystem->GetMouse()->TouchMove(touch_x, touch_y);
|
||||||
input_subsystem->GetMouse()->Move(pos.x(), pos.y(), center_x, center_y);
|
input_subsystem->GetMouse()->Move(pos.x(), pos.y(), center_x, center_y);
|
||||||
|
|
||||||
|
// Center mouse for mouse panning
|
||||||
if (Settings::values.mouse_panning && !Settings::values.mouse_enabled) {
|
if (Settings::values.mouse_panning && !Settings::values.mouse_enabled) {
|
||||||
QCursor::setPos(mapToGlobal(QPoint{center_x, center_y}));
|
QCursor::setPos(mapToGlobal(QPoint{center_x, center_y}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Constrain mouse for mouse emulation with mouse panning
|
||||||
|
if (Settings::values.mouse_panning && Settings::values.mouse_enabled) {
|
||||||
|
const auto [clamped_mouse_x, clamped_mouse_y] = ClipToTouchScreen(x, y);
|
||||||
|
QCursor::setPos(mapToGlobal(
|
||||||
|
QPoint{static_cast<int>(clamped_mouse_x), static_cast<int>(clamped_mouse_y)}));
|
||||||
|
}
|
||||||
|
|
||||||
|
mouse_constrain_timer.stop();
|
||||||
emit MouseActivity();
|
emit MouseActivity();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -675,6 +704,31 @@ void GRenderWindow::mouseReleaseEvent(QMouseEvent* event) {
|
||||||
input_subsystem->GetMouse()->ReleaseButton(button);
|
input_subsystem->GetMouse()->ReleaseButton(button);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GRenderWindow::ConstrainMouse() {
|
||||||
|
if (emu_thread == nullptr || !Settings::values.mouse_panning) {
|
||||||
|
mouse_constrain_timer.stop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!this->isActiveWindow()) {
|
||||||
|
mouse_constrain_timer.stop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Settings::values.mouse_enabled) {
|
||||||
|
const auto pos = mapFromGlobal(QCursor::pos());
|
||||||
|
const int new_pos_x = std::clamp(pos.x(), 0, width());
|
||||||
|
const int new_pos_y = std::clamp(pos.y(), 0, height());
|
||||||
|
|
||||||
|
QCursor::setPos(mapToGlobal(QPoint{new_pos_x, new_pos_y}));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int center_x = width() / 2;
|
||||||
|
const int center_y = height() / 2;
|
||||||
|
|
||||||
|
QCursor::setPos(mapToGlobal(QPoint{center_x, center_y}));
|
||||||
|
}
|
||||||
|
|
||||||
void GRenderWindow::wheelEvent(QWheelEvent* event) {
|
void GRenderWindow::wheelEvent(QWheelEvent* event) {
|
||||||
const int x = event->angleDelta().x();
|
const int x = event->angleDelta().x();
|
||||||
const int y = event->angleDelta().y();
|
const int y = event->angleDelta().y();
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
|
#include <QTimer>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <qglobal.h>
|
#include <qglobal.h>
|
||||||
#include <qnamespace.h>
|
#include <qnamespace.h>
|
||||||
|
@ -38,7 +39,6 @@ class QMouseEvent;
|
||||||
class QObject;
|
class QObject;
|
||||||
class QResizeEvent;
|
class QResizeEvent;
|
||||||
class QShowEvent;
|
class QShowEvent;
|
||||||
class QTimer;
|
|
||||||
class QTouchEvent;
|
class QTouchEvent;
|
||||||
class QWheelEvent;
|
class QWheelEvent;
|
||||||
|
|
||||||
|
@ -166,6 +166,7 @@ public:
|
||||||
std::pair<u32, u32> ScaleTouch(const QPointF& pos) const;
|
std::pair<u32, u32> ScaleTouch(const QPointF& pos) const;
|
||||||
|
|
||||||
void closeEvent(QCloseEvent* event) override;
|
void closeEvent(QCloseEvent* event) override;
|
||||||
|
void leaveEvent(QEvent* event) override;
|
||||||
|
|
||||||
void resizeEvent(QResizeEvent* event) override;
|
void resizeEvent(QResizeEvent* event) override;
|
||||||
|
|
||||||
|
@ -229,6 +230,7 @@ private:
|
||||||
void TouchBeginEvent(const QTouchEvent* event);
|
void TouchBeginEvent(const QTouchEvent* event);
|
||||||
void TouchUpdateEvent(const QTouchEvent* event);
|
void TouchUpdateEvent(const QTouchEvent* event);
|
||||||
void TouchEndEvent();
|
void TouchEndEvent();
|
||||||
|
void ConstrainMouse();
|
||||||
|
|
||||||
void RequestCameraCapture();
|
void RequestCameraCapture();
|
||||||
void OnCameraCapture(int requestId, const QImage& img);
|
void OnCameraCapture(int requestId, const QImage& img);
|
||||||
|
@ -268,6 +270,8 @@ private:
|
||||||
std::unique_ptr<QTimer> camera_timer;
|
std::unique_ptr<QTimer> camera_timer;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
QTimer mouse_constrain_timer;
|
||||||
|
|
||||||
Core::System& system;
|
Core::System& system;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -47,6 +47,7 @@
|
||||||
#include "core/hle/service/am/applet_ae.h"
|
#include "core/hle/service/am/applet_ae.h"
|
||||||
#include "core/hle/service/am/applet_oe.h"
|
#include "core/hle/service/am/applet_oe.h"
|
||||||
#include "core/hle/service/am/applets/applets.h"
|
#include "core/hle/service/am/applets/applets.h"
|
||||||
|
#include "core/hle/service/set/set_sys.h"
|
||||||
#include "yuzu/multiplayer/state.h"
|
#include "yuzu/multiplayer/state.h"
|
||||||
#include "yuzu/util/controller_navigation.h"
|
#include "yuzu/util/controller_navigation.h"
|
||||||
|
|
||||||
|
@ -186,7 +187,6 @@ __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
constexpr int default_mouse_hide_timeout = 2500;
|
constexpr int default_mouse_hide_timeout = 2500;
|
||||||
constexpr int default_mouse_center_timeout = 10;
|
|
||||||
constexpr int default_input_update_timeout = 1;
|
constexpr int default_input_update_timeout = 1;
|
||||||
|
|
||||||
constexpr size_t CopyBufferSize = 1_MiB;
|
constexpr size_t CopyBufferSize = 1_MiB;
|
||||||
|
@ -436,9 +436,6 @@ GMainWindow::GMainWindow(std::unique_ptr<QtConfig> config_, bool has_broken_vulk
|
||||||
connect(&mouse_hide_timer, &QTimer::timeout, this, &GMainWindow::HideMouseCursor);
|
connect(&mouse_hide_timer, &QTimer::timeout, this, &GMainWindow::HideMouseCursor);
|
||||||
connect(ui->menubar, &QMenuBar::hovered, this, &GMainWindow::ShowMouseCursor);
|
connect(ui->menubar, &QMenuBar::hovered, this, &GMainWindow::ShowMouseCursor);
|
||||||
|
|
||||||
mouse_center_timer.setInterval(default_mouse_center_timeout);
|
|
||||||
connect(&mouse_center_timer, &QTimer::timeout, this, &GMainWindow::CenterMouseCursor);
|
|
||||||
|
|
||||||
update_input_timer.setInterval(default_input_update_timeout);
|
update_input_timer.setInterval(default_input_update_timeout);
|
||||||
connect(&update_input_timer, &QTimer::timeout, this, &GMainWindow::UpdateInputDrivers);
|
connect(&update_input_timer, &QTimer::timeout, this, &GMainWindow::UpdateInputDrivers);
|
||||||
update_input_timer.start();
|
update_input_timer.start();
|
||||||
|
@ -1048,7 +1045,12 @@ void GMainWindow::InitializeWidgets() {
|
||||||
statusBar()->addPermanentWidget(label);
|
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->GetStatusText(), 0);
|
||||||
statusBar()->addPermanentWidget(multiplayer_state->GetStatusIcon(), 0);
|
statusBar()->addPermanentWidget(multiplayer_state->GetStatusIcon(), 0);
|
||||||
|
|
||||||
|
@ -1370,14 +1372,6 @@ void GMainWindow::InitializeHotkeys() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
connect_shortcut(QStringLiteral("Toggle Mouse Panning"), [&] {
|
connect_shortcut(QStringLiteral("Toggle Mouse Panning"), [&] {
|
||||||
if (Settings::values.mouse_enabled) {
|
|
||||||
Settings::values.mouse_panning = false;
|
|
||||||
QMessageBox::warning(
|
|
||||||
this, tr("Emulated mouse is enabled"),
|
|
||||||
tr("Real mouse input and mouse panning are incompatible. Please disable the "
|
|
||||||
"emulated mouse in input advanced settings to allow mouse panning."));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Settings::values.mouse_panning = !Settings::values.mouse_panning;
|
Settings::values.mouse_panning = !Settings::values.mouse_panning;
|
||||||
if (Settings::values.mouse_panning) {
|
if (Settings::values.mouse_panning) {
|
||||||
render_window->installEventFilter(render_window);
|
render_window->installEventFilter(render_window);
|
||||||
|
@ -2165,6 +2159,10 @@ void GMainWindow::OnEmulationStopped() {
|
||||||
emu_frametime_label->setVisible(false);
|
emu_frametime_label->setVisible(false);
|
||||||
renderer_status_button->setEnabled(!UISettings::values.has_broken_vulkan);
|
renderer_status_button->setEnabled(!UISettings::values.has_broken_vulkan);
|
||||||
|
|
||||||
|
if (!firmware_label->text().isEmpty()) {
|
||||||
|
firmware_label->setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
current_game_path.clear();
|
current_game_path.clear();
|
||||||
|
|
||||||
// When closing the game, destroy the GLWindow to clear the context after the game is closed
|
// When closing the game, destroy the GLWindow to clear the context after the game is closed
|
||||||
|
@ -4591,6 +4589,7 @@ void GMainWindow::UpdateStatusBar() {
|
||||||
emu_speed_label->setVisible(!Settings::values.use_multi_core.GetValue());
|
emu_speed_label->setVisible(!Settings::values.use_multi_core.GetValue());
|
||||||
game_fps_label->setVisible(true);
|
game_fps_label->setVisible(true);
|
||||||
emu_frametime_label->setVisible(true);
|
emu_frametime_label->setVisible(true);
|
||||||
|
firmware_label->setVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::UpdateGPUAccuracyButton() {
|
void GMainWindow::UpdateGPUAccuracyButton() {
|
||||||
|
@ -4700,26 +4699,10 @@ void GMainWindow::ShowMouseCursor() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::CenterMouseCursor() {
|
|
||||||
if (emu_thread == nullptr || !Settings::values.mouse_panning) {
|
|
||||||
mouse_center_timer.stop();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!this->isActiveWindow()) {
|
|
||||||
mouse_center_timer.stop();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const int center_x = render_window->width() / 2;
|
|
||||||
const int center_y = render_window->height() / 2;
|
|
||||||
|
|
||||||
QCursor::setPos(mapToGlobal(QPoint{center_x, center_y}));
|
|
||||||
}
|
|
||||||
|
|
||||||
void GMainWindow::OnMouseActivity() {
|
void GMainWindow::OnMouseActivity() {
|
||||||
if (!Settings::values.mouse_panning) {
|
if (!Settings::values.mouse_panning) {
|
||||||
ShowMouseCursor();
|
ShowMouseCursor();
|
||||||
}
|
}
|
||||||
mouse_center_timer.stop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::OnReinitializeKeys(ReinitializeKeyBehavior behavior) {
|
void GMainWindow::OnReinitializeKeys(ReinitializeKeyBehavior behavior) {
|
||||||
|
@ -4810,6 +4793,8 @@ void GMainWindow::OnReinitializeKeys(ReinitializeKeyBehavior behavior) {
|
||||||
"games."));
|
"games."));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SetFirmwareVersion();
|
||||||
|
|
||||||
if (behavior == ReinitializeKeyBehavior::Warning) {
|
if (behavior == ReinitializeKeyBehavior::Warning) {
|
||||||
game_list->PopulateAsync(UISettings::values.game_dirs);
|
game_list->PopulateAsync(UISettings::values.game_dirs);
|
||||||
}
|
}
|
||||||
|
@ -4837,7 +4822,7 @@ bool GMainWindow::CheckSystemArchiveDecryption() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GMainWindow::CheckFirmwarePresence() {
|
bool GMainWindow::CheckFirmwarePresence() {
|
||||||
constexpr u64 MiiEditId = 0x0100000000001009ull;
|
constexpr u64 MiiEditId = static_cast<u64>(Service::AM::Applets::AppletProgramId::MiiEdit);
|
||||||
|
|
||||||
auto bis_system = system->GetFileSystemController().GetSystemNANDContents();
|
auto bis_system = system->GetFileSystemController().GetSystemNANDContents();
|
||||||
if (!bis_system) {
|
if (!bis_system) {
|
||||||
|
@ -4852,6 +4837,28 @@ bool GMainWindow::CheckFirmwarePresence() {
|
||||||
return true;
|
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,
|
bool GMainWindow::SelectRomFSDumpTarget(const FileSys::ContentProvider& installed, u64 program_id,
|
||||||
u64* selected_title_id, u8* selected_content_record_type) {
|
u64* selected_title_id, u8* selected_content_record_type) {
|
||||||
using ContentInfo = std::tuple<u64, FileSys::TitleType, FileSys::ContentRecordType>;
|
using ContentInfo = std::tuple<u64, FileSys::TitleType, FileSys::ContentRecordType>;
|
||||||
|
@ -4996,22 +5003,6 @@ void GMainWindow::dragMoveEvent(QDragMoveEvent* event) {
|
||||||
AcceptDropEvent(event);
|
AcceptDropEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::leaveEvent(QEvent* event) {
|
|
||||||
if (Settings::values.mouse_panning) {
|
|
||||||
const QRect& rect = geometry();
|
|
||||||
QPoint position = QCursor::pos();
|
|
||||||
|
|
||||||
qint32 x = qBound(rect.left(), position.x(), rect.right());
|
|
||||||
qint32 y = qBound(rect.top(), position.y(), rect.bottom());
|
|
||||||
// Only start the timer if the mouse has left the window bound.
|
|
||||||
// The leave event is also triggered when the window looses focus.
|
|
||||||
if (x != position.x() || y != position.y()) {
|
|
||||||
mouse_center_timer.start();
|
|
||||||
}
|
|
||||||
event->accept();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GMainWindow::ConfirmChangeGame() {
|
bool GMainWindow::ConfirmChangeGame() {
|
||||||
if (emu_thread == nullptr)
|
if (emu_thread == nullptr)
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -451,13 +451,13 @@ private:
|
||||||
void UpdateInputDrivers();
|
void UpdateInputDrivers();
|
||||||
void HideMouseCursor();
|
void HideMouseCursor();
|
||||||
void ShowMouseCursor();
|
void ShowMouseCursor();
|
||||||
void CenterMouseCursor();
|
|
||||||
void OpenURL(const QUrl& url);
|
void OpenURL(const QUrl& url);
|
||||||
void LoadTranslation();
|
void LoadTranslation();
|
||||||
void OpenPerGameConfiguration(u64 title_id, const std::string& file_name);
|
void OpenPerGameConfiguration(u64 title_id, const std::string& file_name);
|
||||||
bool CheckDarkMode();
|
bool CheckDarkMode();
|
||||||
bool CheckSystemArchiveDecryption();
|
bool CheckSystemArchiveDecryption();
|
||||||
bool CheckFirmwarePresence();
|
bool CheckFirmwarePresence();
|
||||||
|
void SetFirmwareVersion();
|
||||||
void ConfigureFilesystemProvider(const std::string& filepath);
|
void ConfigureFilesystemProvider(const std::string& filepath);
|
||||||
/**
|
/**
|
||||||
* Open (or not) the right confirm dialog based on current setting and game exit lock
|
* Open (or not) the right confirm dialog based on current setting and game exit lock
|
||||||
|
@ -512,6 +512,7 @@ private:
|
||||||
QLabel* game_fps_label = nullptr;
|
QLabel* game_fps_label = nullptr;
|
||||||
QLabel* emu_frametime_label = nullptr;
|
QLabel* emu_frametime_label = nullptr;
|
||||||
QLabel* tas_label = nullptr;
|
QLabel* tas_label = nullptr;
|
||||||
|
QLabel* firmware_label = nullptr;
|
||||||
QPushButton* gpu_accuracy_button = nullptr;
|
QPushButton* gpu_accuracy_button = nullptr;
|
||||||
QPushButton* renderer_status_button = nullptr;
|
QPushButton* renderer_status_button = nullptr;
|
||||||
QPushButton* dock_status_button = nullptr;
|
QPushButton* dock_status_button = nullptr;
|
||||||
|
@ -533,7 +534,6 @@ private:
|
||||||
bool auto_paused = false;
|
bool auto_paused = false;
|
||||||
bool auto_muted = false;
|
bool auto_muted = false;
|
||||||
QTimer mouse_hide_timer;
|
QTimer mouse_hide_timer;
|
||||||
QTimer mouse_center_timer;
|
|
||||||
QTimer update_input_timer;
|
QTimer update_input_timer;
|
||||||
|
|
||||||
QString startup_icon_theme;
|
QString startup_icon_theme;
|
||||||
|
@ -590,5 +590,4 @@ protected:
|
||||||
void dropEvent(QDropEvent* event) override;
|
void dropEvent(QDropEvent* event) override;
|
||||||
void dragEnterEvent(QDragEnterEvent* event) override;
|
void dragEnterEvent(QDragEnterEvent* event) override;
|
||||||
void dragMoveEvent(QDragMoveEvent* event) override;
|
void dragMoveEvent(QDragMoveEvent* event) override;
|
||||||
void leaveEvent(QEvent* event) override;
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue