early-access version 4150

This commit is contained in:
pineappleEA 2024-02-19 04:18:11 +01:00
parent be0bf24d0e
commit 1feed0e508
22 changed files with 586 additions and 300 deletions

View file

@ -1,7 +1,7 @@
yuzu emulator early access yuzu emulator early access
============= =============
This is the source code for early-access 4149. This is the source code for early-access 4150.
## Legal Notice ## Legal Notice

View file

@ -384,6 +384,12 @@ struct Values {
AstcRecompression::Bc3, AstcRecompression::Bc3,
"astc_recompression", "astc_recompression",
Category::RendererAdvanced}; Category::RendererAdvanced};
SwitchableSetting<VramUsageMode, true> vram_usage_mode{linkage,
VramUsageMode::Conservative,
VramUsageMode::Conservative,
VramUsageMode::Aggressive,
"vram_usage_mode",
Category::RendererAdvanced};
SwitchableSetting<bool> async_presentation{linkage, SwitchableSetting<bool> async_presentation{linkage,
#ifdef ANDROID #ifdef ANDROID
true, true,

View file

@ -122,6 +122,8 @@ ENUM(AstcRecompression, Uncompressed, Bc1, Bc3);
ENUM(VSyncMode, Immediate, Mailbox, Fifo, FifoRelaxed); ENUM(VSyncMode, Immediate, Mailbox, Fifo, FifoRelaxed);
ENUM(VramUsageMode, Conservative, Aggressive);
ENUM(RendererBackend, OpenGL, Vulkan, Null); ENUM(RendererBackend, OpenGL, Vulkan, Null);
ENUM(ShaderBackend, Glsl, Glasm, SpirV); ENUM(ShaderBackend, Glsl, Glasm, SpirV);

View file

@ -543,6 +543,16 @@ add_library(core STATIC
hle/service/btdrv/btdrv.h hle/service/btdrv/btdrv.h
hle/service/btm/btm.cpp hle/service/btm/btm.cpp
hle/service/btm/btm.h hle/service/btm/btm.h
hle/service/btm/btm_debug.cpp
hle/service/btm/btm_debug.h
hle/service/btm/btm_system.cpp
hle/service/btm/btm_system.h
hle/service/btm/btm_system_core.cpp
hle/service/btm/btm_system_core.h
hle/service/btm/btm_user.cpp
hle/service/btm/btm_user.h
hle/service/btm/btm_user_core.cpp
hle/service/btm/btm_user_core.h
hle/service/caps/caps.cpp hle/service/caps/caps.cpp
hle/service/caps/caps.h hle/service/caps/caps.h
hle/service/caps/caps_a.cpp hle/service/caps/caps_a.cpp

View file

@ -70,7 +70,7 @@ public:
Result Read(s64 offset, void* buffer, size_t size) override { Result Read(s64 offset, void* buffer, size_t size) override {
R_TRY(ValidateOffset(offset, size, m_size)); R_TRY(ValidateOffset(offset, size, m_size));
m_memory.ReadBlock(m_trmem->GetSourceAddress(), buffer, size); m_memory.ReadBlock(m_trmem->GetSourceAddress() + offset, buffer, size);
R_SUCCEED(); R_SUCCEED();
} }
@ -79,7 +79,7 @@ public:
R_UNLESS(m_is_writable, ResultUnknown); R_UNLESS(m_is_writable, ResultUnknown);
R_TRY(ValidateOffset(offset, size, m_size)); R_TRY(ValidateOffset(offset, size, m_size));
m_memory.WriteBlock(m_trmem->GetSourceAddress(), buffer, size); m_memory.WriteBlock(m_trmem->GetSourceAddress() + offset, buffer, size);
R_SUCCEED(); R_SUCCEED();
} }

View file

@ -3,141 +3,18 @@
#include <memory> #include <memory>
#include "common/logging/log.h"
#include "core/core.h"
#include "core/hle/kernel/k_event.h"
#include "core/hle/service/btm/btm.h" #include "core/hle/service/btm/btm.h"
#include "core/hle/service/ipc_helpers.h" #include "core/hle/service/btm/btm_debug.h"
#include "core/hle/service/kernel_helpers.h" #include "core/hle/service/btm/btm_system.h"
#include "core/hle/service/btm/btm_user.h"
#include "core/hle/service/server_manager.h" #include "core/hle/service/server_manager.h"
#include "core/hle/service/service.h" #include "core/hle/service/service.h"
namespace Service::BTM { namespace Service::BTM {
class IBtmUserCore final : public ServiceFramework<IBtmUserCore> { class IBtm final : public ServiceFramework<IBtm> {
public: public:
explicit IBtmUserCore(Core::System& system_) explicit IBtm(Core::System& system_) : ServiceFramework{system_, "btm"} {
: ServiceFramework{system_, "IBtmUserCore"}, service_context{system_, "IBtmUserCore"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, &IBtmUserCore::AcquireBleScanEvent, "AcquireBleScanEvent"},
{1, nullptr, "GetBleScanFilterParameter"},
{2, nullptr, "GetBleScanFilterParameter2"},
{3, nullptr, "StartBleScanForGeneral"},
{4, nullptr, "StopBleScanForGeneral"},
{5, nullptr, "GetBleScanResultsForGeneral"},
{6, nullptr, "StartBleScanForPaired"},
{7, nullptr, "StopBleScanForPaired"},
{8, nullptr, "StartBleScanForSmartDevice"},
{9, nullptr, "StopBleScanForSmartDevice"},
{10, nullptr, "GetBleScanResultsForSmartDevice"},
{17, &IBtmUserCore::AcquireBleConnectionEvent, "AcquireBleConnectionEvent"},
{18, nullptr, "BleConnect"},
{19, nullptr, "BleDisconnect"},
{20, nullptr, "BleGetConnectionState"},
{21, nullptr, "AcquireBlePairingEvent"},
{22, nullptr, "BlePairDevice"},
{23, nullptr, "BleUnPairDevice"},
{24, nullptr, "BleUnPairDevice2"},
{25, nullptr, "BleGetPairedDevices"},
{26, &IBtmUserCore::AcquireBleServiceDiscoveryEvent, "AcquireBleServiceDiscoveryEvent"},
{27, nullptr, "GetGattServices"},
{28, nullptr, "GetGattService"},
{29, nullptr, "GetGattIncludedServices"},
{30, nullptr, "GetBelongingGattService"},
{31, nullptr, "GetGattCharacteristics"},
{32, nullptr, "GetGattDescriptors"},
{33, &IBtmUserCore::AcquireBleMtuConfigEvent, "AcquireBleMtuConfigEvent"},
{34, nullptr, "ConfigureBleMtu"},
{35, nullptr, "GetBleMtu"},
{36, nullptr, "RegisterBleGattDataPath"},
{37, nullptr, "UnregisterBleGattDataPath"},
};
// clang-format on
RegisterHandlers(functions);
scan_event = service_context.CreateEvent("IBtmUserCore:ScanEvent");
connection_event = service_context.CreateEvent("IBtmUserCore:ConnectionEvent");
service_discovery_event = service_context.CreateEvent("IBtmUserCore:DiscoveryEvent");
config_event = service_context.CreateEvent("IBtmUserCore:ConfigEvent");
}
~IBtmUserCore() override {
service_context.CloseEvent(scan_event);
service_context.CloseEvent(connection_event);
service_context.CloseEvent(service_discovery_event);
service_context.CloseEvent(config_event);
}
private:
void AcquireBleScanEvent(HLERequestContext& ctx) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 3, 1};
rb.Push(ResultSuccess);
rb.Push(true);
rb.PushCopyObjects(scan_event->GetReadableEvent());
}
void AcquireBleConnectionEvent(HLERequestContext& ctx) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 3, 1};
rb.Push(ResultSuccess);
rb.Push(true);
rb.PushCopyObjects(connection_event->GetReadableEvent());
}
void AcquireBleServiceDiscoveryEvent(HLERequestContext& ctx) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 3, 1};
rb.Push(ResultSuccess);
rb.Push(true);
rb.PushCopyObjects(service_discovery_event->GetReadableEvent());
}
void AcquireBleMtuConfigEvent(HLERequestContext& ctx) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 3, 1};
rb.Push(ResultSuccess);
rb.Push(true);
rb.PushCopyObjects(config_event->GetReadableEvent());
}
KernelHelpers::ServiceContext service_context;
Kernel::KEvent* scan_event;
Kernel::KEvent* connection_event;
Kernel::KEvent* service_discovery_event;
Kernel::KEvent* config_event;
};
class BTM_USR final : public ServiceFramework<BTM_USR> {
public:
explicit BTM_USR(Core::System& system_) : ServiceFramework{system_, "btm:u"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, &BTM_USR::GetCore, "GetCore"},
};
// clang-format on
RegisterHandlers(functions);
}
private:
void GetCore(HLERequestContext& ctx) {
LOG_WARNING(Service_BTM, "called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
rb.PushIpcInterface<IBtmUserCore>(system);
}
};
class BTM final : public ServiceFramework<BTM> {
public:
explicit BTM(Core::System& system_) : ServiceFramework{system_, "btm"} {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, nullptr, "GetState"}, {0, nullptr, "GetState"},
@ -232,144 +109,13 @@ public:
} }
}; };
class BTM_DBG final : public ServiceFramework<BTM_DBG> {
public:
explicit BTM_DBG(Core::System& system_) : ServiceFramework{system_, "btm:dbg"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "AcquireDiscoveryEvent"},
{1, nullptr, "StartDiscovery"},
{2, nullptr, "CancelDiscovery"},
{3, nullptr, "GetDeviceProperty"},
{4, nullptr, "CreateBond"},
{5, nullptr, "CancelBond"},
{6, nullptr, "SetTsiMode"},
{7, nullptr, "GeneralTest"},
{8, nullptr, "HidConnect"},
{9, nullptr, "GeneralGet"},
{10, nullptr, "GetGattClientDisconnectionReason"},
{11, nullptr, "GetBleConnectionParameter"},
{12, nullptr, "GetBleConnectionParameterRequest"},
{13, nullptr, "Unknown13"},
};
// clang-format on
RegisterHandlers(functions);
}
};
class IBtmSystemCore final : public ServiceFramework<IBtmSystemCore> {
public:
explicit IBtmSystemCore(Core::System& system_) : ServiceFramework{system_, "IBtmSystemCore"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, &IBtmSystemCore::StartGamepadPairing, "StartGamepadPairing"},
{1, &IBtmSystemCore::CancelGamepadPairing, "CancelGamepadPairing"},
{2, nullptr, "ClearGamepadPairingDatabase"},
{3, nullptr, "GetPairedGamepadCount"},
{4, nullptr, "EnableRadio"},
{5, nullptr, "DisableRadio"},
{6, &IBtmSystemCore::IsRadioEnabled, "IsRadioEnabled"},
{7, nullptr, "AcquireRadioEvent"},
{8, nullptr, "AcquireGamepadPairingEvent"},
{9, nullptr, "IsGamepadPairingStarted"},
{10, nullptr, "StartAudioDeviceDiscovery"},
{11, nullptr, "StopAudioDeviceDiscovery"},
{12, nullptr, "IsDiscoveryingAudioDevice"},
{13, nullptr, "GetDiscoveredAudioDevice"},
{14, nullptr, "AcquireAudioDeviceConnectionEvent"},
{15, nullptr, "ConnectAudioDevice"},
{16, nullptr, "IsConnectingAudioDevice"},
{17, &IBtmSystemCore::GetConnectedAudioDevices, "GetConnectedAudioDevices"},
{18, nullptr, "DisconnectAudioDevice"},
{19, nullptr, "AcquirePairedAudioDeviceInfoChangedEvent"},
{20, &IBtmSystemCore::GetPairedAudioDevices, "GetPairedAudioDevices"},
{21, nullptr, "RemoveAudioDevicePairing"},
{22, &IBtmSystemCore::RequestAudioDeviceConnectionRejection, "RequestAudioDeviceConnectionRejection"},
{23, &IBtmSystemCore::CancelAudioDeviceConnectionRejection, "CancelAudioDeviceConnectionRejection"}
};
// clang-format on
RegisterHandlers(functions);
}
private:
void IsRadioEnabled(HLERequestContext& ctx) {
LOG_DEBUG(Service_BTM, "(STUBBED) called"); // Spams a lot when controller applet is running
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push(true);
}
void StartGamepadPairing(HLERequestContext& ctx) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void CancelGamepadPairing(HLERequestContext& ctx) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void CancelAudioDeviceConnectionRejection(HLERequestContext& ctx) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void GetConnectedAudioDevices(HLERequestContext& ctx) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push<u32>(0);
}
void GetPairedAudioDevices(HLERequestContext& ctx) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push<u32>(0);
}
void RequestAudioDeviceConnectionRejection(HLERequestContext& ctx) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
};
class BTM_SYS final : public ServiceFramework<BTM_SYS> {
public:
explicit BTM_SYS(Core::System& system_) : ServiceFramework{system_, "btm:sys"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, &BTM_SYS::GetCore, "GetCore"},
};
// clang-format on
RegisterHandlers(functions);
}
private:
void GetCore(HLERequestContext& ctx) {
LOG_WARNING(Service_BTM, "called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
rb.PushIpcInterface<IBtmSystemCore>(system);
}
};
void LoopProcess(Core::System& system) { void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system); auto server_manager = std::make_unique<ServerManager>(system);
server_manager->RegisterNamedService("btm", std::make_shared<BTM>(system)); server_manager->RegisterNamedService("btm", std::make_shared<IBtm>(system));
server_manager->RegisterNamedService("btm:dbg", std::make_shared<BTM_DBG>(system)); server_manager->RegisterNamedService("btm:dbg", std::make_shared<IBtmDebug>(system));
server_manager->RegisterNamedService("btm:sys", std::make_shared<BTM_SYS>(system)); server_manager->RegisterNamedService("btm:sys", std::make_shared<IBtmSystem>(system));
server_manager->RegisterNamedService("btm:u", std::make_shared<BTM_USR>(system)); server_manager->RegisterNamedService("btm:u", std::make_shared<IBtmUser>(system));
ServerManager::RunServer(std::move(server_manager)); ServerManager::RunServer(std::move(server_manager));
} }

View file

@ -3,10 +3,6 @@
#pragma once #pragma once
namespace Service::SM {
class ServiceManager;
}
namespace Core { namespace Core {
class System; class System;
}; };

View file

@ -0,0 +1,33 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include "core/hle/service/btm/btm_debug.h"
namespace Service::BTM {
IBtmDebug::IBtmDebug(Core::System& system_) : ServiceFramework{system_, "btm:dbg"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "AcquireDiscoveryEvent"},
{1, nullptr, "StartDiscovery"},
{2, nullptr, "CancelDiscovery"},
{3, nullptr, "GetDeviceProperty"},
{4, nullptr, "CreateBond"},
{5, nullptr, "CancelBond"},
{6, nullptr, "SetTsiMode"},
{7, nullptr, "GeneralTest"},
{8, nullptr, "HidConnect"},
{9, nullptr, "GeneralGet"},
{10, nullptr, "GetGattClientDisconnectionReason"},
{11, nullptr, "GetBleConnectionParameter"},
{12, nullptr, "GetBleConnectionParameterRequest"},
{13, nullptr, "Unknown13"},
};
// clang-format on
RegisterHandlers(functions);
}
IBtmDebug::~IBtmDebug() = default;
} // namespace Service::BTM

View file

@ -0,0 +1,21 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include "core/hle/service/cmif_types.h"
#include "core/hle/service/service.h"
namespace Core {
class System;
}
namespace Service::BTM {
class IBtmDebug final : public ServiceFramework<IBtmDebug> {
public:
explicit IBtmDebug(Core::System& system_);
~IBtmDebug() override;
};
} // namespace Service::BTM

View file

@ -0,0 +1,31 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include "common/logging/log.h"
#include "core/hle/service/btm/btm_system.h"
#include "core/hle/service/btm/btm_system_core.h"
#include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/service.h"
namespace Service::BTM {
IBtmSystem::IBtmSystem(Core::System& system_) : ServiceFramework{system_, "btm:sys"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, C<&IBtmSystem::GetCore>, "GetCore"},
};
// clang-format on
RegisterHandlers(functions);
}
IBtmSystem::~IBtmSystem() = default;
Result IBtmSystem::GetCore(OutInterface<IBtmSystemCore> out_interface) {
LOG_WARNING(Service_BTM, "called");
*out_interface = std::make_shared<IBtmSystemCore>(system);
R_SUCCEED();
}
} // namespace Service::BTM

View file

@ -0,0 +1,25 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include "core/hle/service/cmif_types.h"
#include "core/hle/service/service.h"
namespace Core {
class System;
}
namespace Service::BTM {
class IBtmSystemCore;
class IBtmSystem final : public ServiceFramework<IBtmSystem> {
public:
explicit IBtmSystem(Core::System& system_);
~IBtmSystem() override;
private:
Result GetCore(OutInterface<IBtmSystemCore> out_interface);
};
} // namespace Service::BTM

View file

@ -0,0 +1,127 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include "common/logging/log.h"
#include "core/hle/service/btm/btm_system_core.h"
#include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/set/system_settings_server.h"
#include "core/hle/service/sm/sm.h"
namespace Service::BTM {
IBtmSystemCore::IBtmSystemCore(Core::System& system_)
: ServiceFramework{system_, "IBtmSystemCore"}, service_context{system_, "IBtmSystemCore"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, C<&IBtmSystemCore::StartGamepadPairing>, "StartGamepadPairing"},
{1, C<&IBtmSystemCore::CancelGamepadPairing>, "CancelGamepadPairing"},
{2, nullptr, "ClearGamepadPairingDatabase"},
{3, nullptr, "GetPairedGamepadCount"},
{4, C<&IBtmSystemCore::EnableRadio>, "EnableRadio"},
{5, C<&IBtmSystemCore::DisableRadio>, "DisableRadio"},
{6, C<&IBtmSystemCore::IsRadioEnabled>, "IsRadioEnabled"},
{7, C<&IBtmSystemCore::AcquireRadioEvent>, "AcquireRadioEvent"},
{8, nullptr, "AcquireGamepadPairingEvent"},
{9, nullptr, "IsGamepadPairingStarted"},
{10, nullptr, "StartAudioDeviceDiscovery"},
{11, nullptr, "StopAudioDeviceDiscovery"},
{12, nullptr, "IsDiscoveryingAudioDevice"},
{13, nullptr, "GetDiscoveredAudioDevice"},
{14, C<&IBtmSystemCore::AcquireAudioDeviceConnectionEvent>, "AcquireAudioDeviceConnectionEvent"},
{15, nullptr, "ConnectAudioDevice"},
{16, nullptr, "IsConnectingAudioDevice"},
{17, C<&IBtmSystemCore::GetConnectedAudioDevices>, "GetConnectedAudioDevices"},
{18, nullptr, "DisconnectAudioDevice"},
{19, nullptr, "AcquirePairedAudioDeviceInfoChangedEvent"},
{20, C<&IBtmSystemCore::GetPairedAudioDevices>, "GetPairedAudioDevices"},
{21, nullptr, "RemoveAudioDevicePairing"},
{22, C<&IBtmSystemCore::RequestAudioDeviceConnectionRejection>, "RequestAudioDeviceConnectionRejection"},
{23, C<&IBtmSystemCore::CancelAudioDeviceConnectionRejection>, "CancelAudioDeviceConnectionRejection"}
};
// clang-format on
RegisterHandlers(functions);
radio_event = service_context.CreateEvent("IBtmSystemCore::RadioEvent");
audio_device_connection_event =
service_context.CreateEvent("IBtmSystemCore::AudioDeviceConnectionEvent");
m_set_sys =
system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys", true);
}
IBtmSystemCore::~IBtmSystemCore() {
service_context.CloseEvent(radio_event);
service_context.CloseEvent(audio_device_connection_event);
}
Result IBtmSystemCore::StartGamepadPairing() {
LOG_WARNING(Service_BTM, "(STUBBED) called");
R_SUCCEED();
}
Result IBtmSystemCore::CancelGamepadPairing() {
LOG_WARNING(Service_BTM, "(STUBBED) called");
R_SUCCEED();
}
Result IBtmSystemCore::EnableRadio() {
LOG_DEBUG(Service_BTM, "called");
R_RETURN(m_set_sys->SetBluetoothEnableFlag(true));
}
Result IBtmSystemCore::DisableRadio() {
LOG_DEBUG(Service_BTM, "called");
R_RETURN(m_set_sys->SetBluetoothEnableFlag(false));
}
Result IBtmSystemCore::IsRadioEnabled(Out<bool> out_is_enabled) {
LOG_DEBUG(Service_BTM, "called");
R_RETURN(m_set_sys->GetBluetoothEnableFlag(out_is_enabled));
}
Result IBtmSystemCore::AcquireRadioEvent(Out<bool> out_is_valid,
OutCopyHandle<Kernel::KReadableEvent> out_event) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
*out_is_valid = true;
*out_event = &radio_event->GetReadableEvent();
R_SUCCEED();
}
Result IBtmSystemCore::AcquireAudioDeviceConnectionEvent(
OutCopyHandle<Kernel::KReadableEvent> out_event) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
*out_event = &audio_device_connection_event->GetReadableEvent();
R_SUCCEED();
}
Result IBtmSystemCore::GetConnectedAudioDevices(
Out<s32> out_count, OutArray<std::array<u8, 0xFF>, BufferAttr_HipcPointer> out_audio_devices) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
*out_count = 0;
R_SUCCEED();
}
Result IBtmSystemCore::GetPairedAudioDevices(
Out<s32> out_count, OutArray<std::array<u8, 0xFF>, BufferAttr_HipcPointer> out_audio_devices) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
*out_count = 0;
R_SUCCEED();
}
Result IBtmSystemCore::RequestAudioDeviceConnectionRejection(ClientAppletResourceUserId aruid) {
LOG_WARNING(Service_BTM, "(STUBBED) called, applet_resource_user_id={}", aruid.pid);
R_SUCCEED();
}
Result IBtmSystemCore::CancelAudioDeviceConnectionRejection(ClientAppletResourceUserId aruid) {
LOG_WARNING(Service_BTM, "(STUBBED) called, applet_resource_user_id={}", aruid.pid);
R_SUCCEED();
}
} // namespace Service::BTM

View file

@ -0,0 +1,60 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include "core/hle/service/cmif_types.h"
#include "core/hle/service/kernel_helpers.h"
#include "core/hle/service/service.h"
namespace Kernel {
class KEvent;
class KReadableEvent;
} // namespace Kernel
namespace Core {
class System;
}
namespace Service::Set {
class ISystemSettingsServer;
}
namespace Service::BTM {
class IBtmSystemCore final : public ServiceFramework<IBtmSystemCore> {
public:
explicit IBtmSystemCore(Core::System& system_);
~IBtmSystemCore() override;
private:
Result StartGamepadPairing();
Result CancelGamepadPairing();
Result EnableRadio();
Result DisableRadio();
Result IsRadioEnabled(Out<bool> out_is_enabled);
Result AcquireRadioEvent(Out<bool> out_is_valid,
OutCopyHandle<Kernel::KReadableEvent> out_event);
Result AcquireAudioDeviceConnectionEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
Result GetConnectedAudioDevices(
Out<s32> out_count,
OutArray<std::array<u8, 0xFF>, BufferAttr_HipcPointer> out_audio_devices);
Result GetPairedAudioDevices(
Out<s32> out_count,
OutArray<std::array<u8, 0xFF>, BufferAttr_HipcPointer> out_audio_devices);
Result RequestAudioDeviceConnectionRejection(ClientAppletResourceUserId aruid);
Result CancelAudioDeviceConnectionRejection(ClientAppletResourceUserId aruid);
KernelHelpers::ServiceContext service_context;
Kernel::KEvent* radio_event;
Kernel::KEvent* audio_device_connection_event;
std::shared_ptr<Service::Set::ISystemSettingsServer> m_set_sys;
};
} // namespace Service::BTM

View file

@ -0,0 +1,30 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include "common/logging/log.h"
#include "core/hle/service/btm/btm_user.h"
#include "core/hle/service/btm/btm_user_core.h"
#include "core/hle/service/cmif_serialization.h"
namespace Service::BTM {
IBtmUser::IBtmUser(Core::System& system_) : ServiceFramework{system_, "btm:u"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, C<&IBtmUser::GetCore>, "GetCore"},
};
// clang-format on
RegisterHandlers(functions);
}
IBtmUser::~IBtmUser() = default;
Result IBtmUser::GetCore(OutInterface<IBtmUserCore> out_interface) {
LOG_WARNING(Service_BTM, "called");
*out_interface = std::make_shared<IBtmUserCore>(system);
R_SUCCEED();
}
} // namespace Service::BTM

View file

@ -0,0 +1,25 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include "core/hle/service/cmif_types.h"
#include "core/hle/service/service.h"
namespace Core {
class System;
}
namespace Service::BTM {
class IBtmUserCore;
class IBtmUser final : public ServiceFramework<IBtmUser> {
public:
explicit IBtmUser(Core::System& system_);
~IBtmUser() override;
private:
Result GetCore(OutInterface<IBtmUserCore> out_interface);
};
} // namespace Service::BTM

View file

@ -0,0 +1,103 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include <memory>
#include "common/logging/log.h"
#include "core/core.h"
#include "core/hle/kernel/k_event.h"
#include "core/hle/service/btm/btm_user_core.h"
#include "core/hle/service/cmif_serialization.h"
namespace Service::BTM {
IBtmUserCore::IBtmUserCore(Core::System& system_)
: ServiceFramework{system_, "IBtmUserCore"}, service_context{system_, "IBtmUserCore"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, C<&IBtmUserCore::AcquireBleScanEvent>, "AcquireBleScanEvent"},
{1, nullptr, "GetBleScanFilterParameter"},
{2, nullptr, "GetBleScanFilterParameter2"},
{3, nullptr, "StartBleScanForGeneral"},
{4, nullptr, "StopBleScanForGeneral"},
{5, nullptr, "GetBleScanResultsForGeneral"},
{6, nullptr, "StartBleScanForPaired"},
{7, nullptr, "StopBleScanForPaired"},
{8, nullptr, "StartBleScanForSmartDevice"},
{9, nullptr, "StopBleScanForSmartDevice"},
{10, nullptr, "GetBleScanResultsForSmartDevice"},
{17, C<&IBtmUserCore::AcquireBleConnectionEvent>, "AcquireBleConnectionEvent"},
{18, nullptr, "BleConnect"},
{19, nullptr, "BleDisconnect"},
{20, nullptr, "BleGetConnectionState"},
{21, nullptr, "AcquireBlePairingEvent"},
{22, nullptr, "BlePairDevice"},
{23, nullptr, "BleUnPairDevice"},
{24, nullptr, "BleUnPairDevice2"},
{25, nullptr, "BleGetPairedDevices"},
{26, C<&IBtmUserCore::AcquireBleServiceDiscoveryEvent>, "AcquireBleServiceDiscoveryEvent"},
{27, nullptr, "GetGattServices"},
{28, nullptr, "GetGattService"},
{29, nullptr, "GetGattIncludedServices"},
{30, nullptr, "GetBelongingGattService"},
{31, nullptr, "GetGattCharacteristics"},
{32, nullptr, "GetGattDescriptors"},
{33, C<&IBtmUserCore::AcquireBleMtuConfigEvent>, "AcquireBleMtuConfigEvent"},
{34, nullptr, "ConfigureBleMtu"},
{35, nullptr, "GetBleMtu"},
{36, nullptr, "RegisterBleGattDataPath"},
{37, nullptr, "UnregisterBleGattDataPath"},
};
// clang-format on
RegisterHandlers(functions);
scan_event = service_context.CreateEvent("IBtmUserCore:ScanEvent");
connection_event = service_context.CreateEvent("IBtmUserCore:ConnectionEvent");
service_discovery_event = service_context.CreateEvent("IBtmUserCore:DiscoveryEvent");
config_event = service_context.CreateEvent("IBtmUserCore:ConfigEvent");
}
IBtmUserCore::~IBtmUserCore() {
service_context.CloseEvent(scan_event);
service_context.CloseEvent(connection_event);
service_context.CloseEvent(service_discovery_event);
service_context.CloseEvent(config_event);
}
Result IBtmUserCore::AcquireBleScanEvent(Out<bool> out_is_valid,
OutCopyHandle<Kernel::KReadableEvent> out_event) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
*out_is_valid = true;
*out_event = &scan_event->GetReadableEvent();
R_SUCCEED();
}
Result IBtmUserCore::AcquireBleConnectionEvent(Out<bool> out_is_valid,
OutCopyHandle<Kernel::KReadableEvent> out_event) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
*out_is_valid = true;
*out_event = &connection_event->GetReadableEvent();
R_SUCCEED();
}
Result IBtmUserCore::AcquireBleServiceDiscoveryEvent(
Out<bool> out_is_valid, OutCopyHandle<Kernel::KReadableEvent> out_event) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
*out_is_valid = true;
*out_event = &service_discovery_event->GetReadableEvent();
R_SUCCEED();
}
Result IBtmUserCore::AcquireBleMtuConfigEvent(Out<bool> out_is_valid,
OutCopyHandle<Kernel::KReadableEvent> out_event) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
*out_is_valid = true;
*out_event = &config_event->GetReadableEvent();
R_SUCCEED();
}
} // namespace Service::BTM

View file

@ -0,0 +1,47 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include "core/hle/service/cmif_types.h"
#include "core/hle/service/kernel_helpers.h"
#include "core/hle/service/service.h"
namespace Kernel {
class KEvent;
class KReadableEvent;
} // namespace Kernel
namespace Core {
class System;
}
namespace Service::BTM {
class IBtmUserCore final : public ServiceFramework<IBtmUserCore> {
public:
explicit IBtmUserCore(Core::System& system_);
~IBtmUserCore() override;
private:
Result AcquireBleScanEvent(Out<bool> out_is_valid,
OutCopyHandle<Kernel::KReadableEvent> out_event);
Result AcquireBleConnectionEvent(Out<bool> out_is_valid,
OutCopyHandle<Kernel::KReadableEvent> out_event);
Result AcquireBleServiceDiscoveryEvent(Out<bool> out_is_valid,
OutCopyHandle<Kernel::KReadableEvent> out_event);
Result AcquireBleMtuConfigEvent(Out<bool> out_is_valid,
OutCopyHandle<Kernel::KReadableEvent> out_event);
KernelHelpers::ServiceContext service_context;
Kernel::KEvent* scan_event;
Kernel::KEvent* connection_event;
Kernel::KEvent* service_discovery_event;
Kernel::KEvent* config_event;
};
} // namespace Service::BTM

View file

@ -441,12 +441,13 @@ Result IApplicationManagerInterface::GetApplicationRightsOnClient(
flags, application_id, account_id.FormattedString()); flags, application_id, account_id.FormattedString());
if (!out_rights.empty()) { if (!out_rights.empty()) {
out_rights[0] = { ApplicationRightsOnClient rights{};
.application_id = application_id, rights.application_id = application_id;
.uid = account_id, rights.uid = account_id;
.flags = 0, rights.flags = 0;
.flags2 = 0, rights.flags2 = 0;
};
out_rights[0] = rights;
*out_count = 1; *out_count = 1;
} else { } else {
*out_count = 0; *out_count = 0;

View file

@ -13,8 +13,8 @@ enum class ApplicationRecordType : u8 {
Installing = 2, Installing = 2,
Installed = 3, Installed = 3,
GameCardNotInserted = 5, GameCardNotInserted = 5,
Archived = 0xB, Archived = 11,
GameCard = 0x10, GameCard = 16,
}; };
enum class ApplicationControlSource : u8 { enum class ApplicationControlSource : u8 {
@ -37,31 +37,34 @@ struct ApplicationRecord {
u8 unknown2; u8 unknown2;
INSERT_PADDING_BYTES_NOINIT(0x7); INSERT_PADDING_BYTES_NOINIT(0x7);
}; };
static_assert(sizeof(ApplicationRecord) == 0x18, "ApplicationRecord is an invalid size"); static_assert(sizeof(ApplicationRecord) == 0x18, "ApplicationRecord has incorrect size.");
/// ApplicationView /// ApplicationView
struct ApplicationView { struct ApplicationView {
u64 application_id; ///< ApplicationId. u64 application_id; ///< ApplicationId.
u32 unk; ///< Unknown. u32 unk; ///< Unknown.
u32 flags; ///< Flags. u32 flags; ///< Flags.
u8 unk_x10[0x10]; ///< Unknown. std::array<u8, 0x10> unk_x10; ///< Unknown.
u32 unk_x20; ///< Unknown. u32 unk_x20; ///< Unknown.
u16 unk_x24; ///< Unknown. u16 unk_x24; ///< Unknown.
u8 unk_x26[0x2]; ///< Unknown. std::array<u8, 0x2> unk_x26; ///< Unknown.
u8 unk_x28[0x8]; ///< Unknown. std::array<u8, 0x8> unk_x28; ///< Unknown.
u8 unk_x30[0x10]; ///< Unknown. std::array<u8, 0x10> unk_x30; ///< Unknown.
u32 unk_x40; ///< Unknown. u32 unk_x40; ///< Unknown.
u8 unk_x44; ///< Unknown. u8 unk_x44; ///< Unknown.
u8 unk_x45[0xb]; ///< Unknown. std::array<u8, 0xb> unk_x45; ///< Unknown.
}; };
static_assert(sizeof(ApplicationView) == 0x50, "ApplicationView has incorrect size.");
struct ApplicationRightsOnClient { struct ApplicationRightsOnClient {
u64 application_id; u64 application_id;
Common::UUID uid; Common::UUID uid;
u8 flags; u8 flags;
u8 flags2; u8 flags2;
INSERT_PADDING_BYTES(0x6); INSERT_PADDING_BYTES_NOINIT(0x6);
}; };
static_assert(sizeof(ApplicationRightsOnClient) == 0x20,
"ApplicationRightsOnClient has incorrect size.");
/// NsPromotionInfo /// NsPromotionInfo
struct PromotionInfo { struct PromotionInfo {
@ -74,12 +77,15 @@ struct PromotionInfo {
///< remaining_time is set. ///< remaining_time is set.
INSERT_PADDING_BYTES_NOINIT(0x3); INSERT_PADDING_BYTES_NOINIT(0x3);
}; };
static_assert(sizeof(PromotionInfo) == 0x20, "PromotionInfo has incorrect size.");
/// NsApplicationViewWithPromotionInfo /// NsApplicationViewWithPromotionInfo
struct ApplicationViewWithPromotionInfo { struct ApplicationViewWithPromotionInfo {
ApplicationView view; ///< \ref NsApplicationView ApplicationView view; ///< \ref NsApplicationView
PromotionInfo promotion; ///< \ref NsPromotionInfo PromotionInfo promotion; ///< \ref NsPromotionInfo
}; };
static_assert(sizeof(ApplicationViewWithPromotionInfo) == 0x70,
"ApplicationViewWithPromotionInfo has incorrect size.");
struct ApplicationOccupiedSizeEntity { struct ApplicationOccupiedSizeEntity {
FileSys::StorageId storage_id; FileSys::StorageId storage_id;
@ -93,10 +99,13 @@ static_assert(sizeof(ApplicationOccupiedSizeEntity) == 0x20,
struct ApplicationOccupiedSize { struct ApplicationOccupiedSize {
std::array<ApplicationOccupiedSizeEntity, 4> entities; std::array<ApplicationOccupiedSizeEntity, 4> entities;
}; };
static_assert(sizeof(ApplicationOccupiedSize) == 0x80,
"ApplicationOccupiedSize has incorrect size.");
struct ContentPath { struct ContentPath {
u8 file_system_proxy_type; u8 file_system_proxy_type;
u64 program_id; u64 program_id;
}; };
static_assert(sizeof(ContentPath) == 0x10, "ContentPath has incorrect size.");
} // namespace Service::NS } // namespace Service::NS

View file

@ -43,7 +43,7 @@ Result IReadOnlyApplicationControlDataInterface::GetApplicationControlData(
const auto size = out_buffer.size(); const auto size = out_buffer.size();
const auto icon_size = control.second ? control.second->GetSize() : 0; const auto icon_size = control.second ? control.second->GetSize() : 0;
const auto total_size = 0x4000 + icon_size; const auto total_size = sizeof(FileSys::RawNACP) + icon_size;
if (size < total_size) { if (size < total_size) {
LOG_ERROR(Service_NS, "output buffer is too small! (actual={:016X}, expected_min=0x4000)", LOG_ERROR(Service_NS, "output buffer is too small! (actual={:016X}, expected_min=0x4000)",
@ -57,11 +57,11 @@ Result IReadOnlyApplicationControlDataInterface::GetApplicationControlData(
} else { } else {
LOG_WARNING(Service_NS, "missing NACP data for application_id={:016X}, defaulting to zero", LOG_WARNING(Service_NS, "missing NACP data for application_id={:016X}, defaulting to zero",
application_id); application_id);
std::memset(out_buffer.data(), 0, 0x4000); std::memset(out_buffer.data(), 0, sizeof(FileSys::RawNACP));
} }
if (control.second != nullptr) { if (control.second != nullptr) {
control.second->Read(out_buffer.data() + 0x4000, icon_size); control.second->Read(out_buffer.data() + sizeof(FileSys::RawNACP), icon_size);
} else { } else {
LOG_WARNING(Service_NS, "missing icon data for application_id={:016X}", application_id); LOG_WARNING(Service_NS, "missing icon data for application_id={:016X}", application_id);
} }

View file

@ -1290,10 +1290,6 @@ u64 Device::GetDeviceMemoryUsage() const {
} }
void Device::CollectPhysicalMemoryInfo() { void Device::CollectPhysicalMemoryInfo() {
// Account for resolution scaling in memory limits
const size_t normal_memory = 6_GiB;
const size_t scaler_memory = 1_GiB * Settings::values.resolution_info.ScaleUp(1);
// Calculate limits using memory budget // Calculate limits using memory budget
VkPhysicalDeviceMemoryBudgetPropertiesEXT budget{}; VkPhysicalDeviceMemoryBudgetPropertiesEXT budget{};
budget.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT; budget.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT;
@ -1324,7 +1320,15 @@ void Device::CollectPhysicalMemoryInfo() {
if (!is_integrated) { if (!is_integrated) {
const u64 reserve_memory = std::min<u64>(device_access_memory / 8, 1_GiB); const u64 reserve_memory = std::min<u64>(device_access_memory / 8, 1_GiB);
device_access_memory -= reserve_memory; device_access_memory -= reserve_memory;
device_access_memory = std::min<u64>(device_access_memory, normal_memory + scaler_memory);
if (Settings::values.vram_usage_mode.GetValue() != Settings::VramUsageMode::Aggressive) {
// Account for resolution scaling in memory limits
const size_t normal_memory = 6_GiB;
const size_t scaler_memory = 1_GiB * Settings::values.resolution_info.ScaleUp(1);
device_access_memory =
std::min<u64>(device_access_memory, normal_memory + scaler_memory);
}
return; return;
} }
const s64 available_memory = static_cast<s64>(device_access_memory - device_initial_usage); const s64 available_memory = static_cast<s64>(device_access_memory - device_initial_usage);

View file

@ -164,6 +164,11 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent) {
"the emulator to decompress to an intermediate format any card supports, RGBA8.\n" "the emulator to decompress to an intermediate format any card supports, RGBA8.\n"
"This option recompresses RGBA8 to either the BC1 or BC3 format, saving VRAM but " "This option recompresses RGBA8 to either the BC1 or BC3 format, saving VRAM but "
"negatively affecting image quality.")); "negatively affecting image quality."));
INSERT(Settings, vram_usage_mode, tr("VRAM Usage Mode:"),
tr("Selects whether the emulator should prefer to conserve memory or make maximum usage "
"of available video memory for performance. Has no effect on integrated graphics. "
"Aggressive mode may severely impact the performance of other applications such as "
"recording software."));
INSERT( INSERT(
Settings, vsync_mode, tr("VSync Mode:"), Settings, vsync_mode, tr("VSync Mode:"),
tr("FIFO (VSync) does not drop frames or exhibit tearing but is limited by the screen " tr("FIFO (VSync) does not drop frames or exhibit tearing but is limited by the screen "
@ -315,6 +320,11 @@ std::unique_ptr<ComboboxTranslationMap> ComboboxEnumeration(QWidget* parent) {
PAIR(AstcRecompression, Bc1, tr("BC1 (Low quality)")), PAIR(AstcRecompression, Bc1, tr("BC1 (Low quality)")),
PAIR(AstcRecompression, Bc3, tr("BC3 (Medium quality)")), PAIR(AstcRecompression, Bc3, tr("BC3 (Medium quality)")),
}}); }});
translations->insert({Settings::EnumMetadata<Settings::VramUsageMode>::Index(),
{
PAIR(VramUsageMode, Conservative, tr("Conservative")),
PAIR(VramUsageMode, Aggressive, tr("Aggressive")),
}});
translations->insert({Settings::EnumMetadata<Settings::RendererBackend>::Index(), translations->insert({Settings::EnumMetadata<Settings::RendererBackend>::Index(),
{ {
#ifdef HAS_OPENGL #ifdef HAS_OPENGL