early-access version 2901

This commit is contained in:
pineappleEA 2022-08-13 04:14:43 +02:00
parent 7ce78aaa94
commit 7a7b98c00a
16 changed files with 734 additions and 65 deletions

View file

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

View file

@ -185,6 +185,9 @@ public:
constexpr s32 max{std::numeric_limits<s16>::max()}; constexpr s32 max{std::numeric_limits<s16>::max()};
auto yuzu_volume{Settings::Volume()}; auto yuzu_volume{Settings::Volume()};
if (yuzu_volume > 1.0f) {
yuzu_volume = 0.6f + 20 * std::log10(yuzu_volume);
}
auto volume{system_volume * device_volume * yuzu_volume}; auto volume{system_volume * device_volume * yuzu_volume};
if (system_channels == 6 && device_channels == 2) { if (system_channels == 6 && device_channels == 2) {

View file

@ -105,7 +105,7 @@ float Volume() {
if (values.audio_muted) { if (values.audio_muted) {
return 0.0f; return 0.0f;
} }
return values.volume.GetValue() / 100.0f; return values.volume.GetValue() / static_cast<f32>(values.volume.GetDefault());
} }
void UpdateRescalingInfo() { void UpdateRescalingInfo() {

View file

@ -374,7 +374,7 @@ struct Values {
Setting<std::string> audio_output_device_id{"auto", "output_device"}; Setting<std::string> audio_output_device_id{"auto", "output_device"};
Setting<std::string> audio_input_device_id{"auto", "input_device"}; Setting<std::string> audio_input_device_id{"auto", "input_device"};
Setting<bool> audio_muted{false, "audio_muted"}; Setting<bool> audio_muted{false, "audio_muted"};
SwitchableSetting<u8, true> volume{100, 0, 100, "volume"}; SwitchableSetting<u8, true> volume{100, 0, 200, "volume"};
Setting<bool> dump_audio_commands{false, "dump_audio_commands"}; Setting<bool> dump_audio_commands{false, "dump_audio_commands"};
// Core // Core

View file

@ -500,9 +500,10 @@ add_library(core STATIC
hle/service/jit/jit.h hle/service/jit/jit.h
hle/service/lbl/lbl.cpp hle/service/lbl/lbl.cpp
hle/service/lbl/lbl.h hle/service/lbl/lbl.h
hle/service/ldn/errors.h hle/service/ldn/ldn_results.h
hle/service/ldn/ldn.cpp hle/service/ldn/ldn.cpp
hle/service/ldn/ldn.h hle/service/ldn/ldn.h
hle/service/ldn/ldn_types.h
hle/service/ldr/ldr.cpp hle/service/ldr/ldr.cpp
hle/service/ldr/ldr.h hle/service/ldr/ldr.h
hle/service/lm/lm.cpp hle/service/lm/lm.cpp

View file

@ -287,7 +287,8 @@ void IPSwitchCompiler::Parse() {
std::copy(value.begin(), value.end(), std::back_inserter(replace)); std::copy(value.begin(), value.end(), std::back_inserter(replace));
} else { } else {
// hex replacement // hex replacement
const auto value = patch_line.substr(9); const auto value =
patch_line.substr(9, patch_line.find_first_of(" /\r\n", 9) - 9);
replace = Common::HexStringToVector(value, is_little_endian); replace = Common::HexStringToVector(value, is_little_endian);
} }

View file

@ -3,11 +3,15 @@
#include <memory> #include <memory>
#include "core/hle/ipc_helpers.h" #include "core/core.h"
#include "core/hle/result.h"
#include "core/hle/service/ldn/errors.h"
#include "core/hle/service/ldn/ldn.h" #include "core/hle/service/ldn/ldn.h"
#include "core/hle/service/sm/sm.h" #include "core/hle/service/ldn/ldn_results.h"
#include "core/hle/service/ldn/ldn_types.h"
#include "core/internal_network/network.h"
#include "core/internal_network/network_interface.h"
// This is defined by synchapi.h and conflicts with ServiceContext::CreateEvent
#undef CreateEvent
namespace Service::LDN { namespace Service::LDN {
@ -100,74 +104,418 @@ class IUserLocalCommunicationService final
: public ServiceFramework<IUserLocalCommunicationService> { : public ServiceFramework<IUserLocalCommunicationService> {
public: public:
explicit IUserLocalCommunicationService(Core::System& system_) explicit IUserLocalCommunicationService(Core::System& system_)
: ServiceFramework{system_, "IUserLocalCommunicationService"} { : ServiceFramework{system_, "IUserLocalCommunicationService", ServiceThreadType::CreateNew},
service_context{system, "IUserLocalCommunicationService"}, room_network{
system_.GetRoomNetwork()} {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, &IUserLocalCommunicationService::GetState, "GetState"}, {0, &IUserLocalCommunicationService::GetState, "GetState"},
{1, nullptr, "GetNetworkInfo"}, {1, &IUserLocalCommunicationService::GetNetworkInfo, "GetNetworkInfo"},
{2, nullptr, "GetIpv4Address"}, {2, nullptr, "GetIpv4Address"},
{3, nullptr, "GetDisconnectReason"}, {3, &IUserLocalCommunicationService::GetDisconnectReason, "GetDisconnectReason"},
{4, nullptr, "GetSecurityParameter"}, {4, &IUserLocalCommunicationService::GetSecurityParameter, "GetSecurityParameter"},
{5, nullptr, "GetNetworkConfig"}, {5, &IUserLocalCommunicationService::GetNetworkConfig, "GetNetworkConfig"},
{100, nullptr, "AttachStateChangeEvent"}, {100, &IUserLocalCommunicationService::AttachStateChangeEvent, "AttachStateChangeEvent"},
{101, nullptr, "GetNetworkInfoLatestUpdate"}, {101, &IUserLocalCommunicationService::GetNetworkInfoLatestUpdate, "GetNetworkInfoLatestUpdate"},
{102, nullptr, "Scan"}, {102, &IUserLocalCommunicationService::Scan, "Scan"},
{103, nullptr, "ScanPrivate"}, {103, &IUserLocalCommunicationService::ScanPrivate, "ScanPrivate"},
{104, nullptr, "SetWirelessControllerRestriction"}, {104, nullptr, "SetWirelessControllerRestriction"},
{200, nullptr, "OpenAccessPoint"}, {200, &IUserLocalCommunicationService::OpenAccessPoint, "OpenAccessPoint"},
{201, nullptr, "CloseAccessPoint"}, {201, &IUserLocalCommunicationService::CloseAccessPoint, "CloseAccessPoint"},
{202, nullptr, "CreateNetwork"}, {202, &IUserLocalCommunicationService::CreateNetwork, "CreateNetwork"},
{203, nullptr, "CreateNetworkPrivate"}, {203, &IUserLocalCommunicationService::CreateNetworkPrivate, "CreateNetworkPrivate"},
{204, nullptr, "DestroyNetwork"}, {204, &IUserLocalCommunicationService::DestroyNetwork, "DestroyNetwork"},
{205, nullptr, "Reject"}, {205, nullptr, "Reject"},
{206, nullptr, "SetAdvertiseData"}, {206, &IUserLocalCommunicationService::SetAdvertiseData, "SetAdvertiseData"},
{207, nullptr, "SetStationAcceptPolicy"}, {207, &IUserLocalCommunicationService::SetStationAcceptPolicy, "SetStationAcceptPolicy"},
{208, nullptr, "AddAcceptFilterEntry"}, {208, &IUserLocalCommunicationService::AddAcceptFilterEntry, "AddAcceptFilterEntry"},
{209, nullptr, "ClearAcceptFilter"}, {209, nullptr, "ClearAcceptFilter"},
{300, nullptr, "OpenStation"}, {300, &IUserLocalCommunicationService::OpenStation, "OpenStation"},
{301, nullptr, "CloseStation"}, {301, &IUserLocalCommunicationService::CloseStation, "CloseStation"},
{302, nullptr, "Connect"}, {302, &IUserLocalCommunicationService::Connect, "Connect"},
{303, nullptr, "ConnectPrivate"}, {303, nullptr, "ConnectPrivate"},
{304, nullptr, "Disconnect"}, {304, &IUserLocalCommunicationService::Disconnect, "Disconnect"},
{400, nullptr, "Initialize"}, {400, &IUserLocalCommunicationService::Initialize, "Initialize"},
{401, nullptr, "Finalize"}, {401, &IUserLocalCommunicationService::Finalize, "Finalize"},
{402, &IUserLocalCommunicationService::Initialize2, "Initialize2"}, // 7.0.0+ {402, &IUserLocalCommunicationService::Initialize2, "Initialize2"},
}; };
// clang-format on // clang-format on
RegisterHandlers(functions); RegisterHandlers(functions);
state_change_event =
service_context.CreateEvent("IUserLocalCommunicationService:StateChangeEvent");
}
~IUserLocalCommunicationService() {
service_context.CloseEvent(state_change_event);
}
void OnEventFired() {
state_change_event->GetWritableEvent().Signal();
} }
void GetState(Kernel::HLERequestContext& ctx) { void GetState(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_LDN, "(STUBBED) called"); State state = State::Error;
LOG_WARNING(Service_LDN, "(STUBBED) called, state = {}", state);
IPC::ResponseBuilder rb{ctx, 3}; IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.PushEnum(state);
}
// Indicate a network error, as we do not actually emulate LDN void GetNetworkInfo(Kernel::HLERequestContext& ctx) {
rb.Push(static_cast<u32>(State::Error)); const auto write_buffer_size = ctx.GetWriteBufferSize();
if (write_buffer_size != sizeof(NetworkInfo)) {
LOG_ERROR(Service_LDN, "Invalid buffer size {}", write_buffer_size);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultBadInput);
return;
}
NetworkInfo network_info{};
const auto rc = ResultSuccess;
if (rc.IsError()) {
LOG_ERROR(Service_LDN, "NetworkInfo is not valid {}", rc.raw);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(rc);
return;
}
LOG_WARNING(Service_LDN, "(STUBBED) called, ssid='{}', nodes={}",
network_info.common.ssid.GetStringValue(), network_info.ldn.node_count);
ctx.WriteBuffer<NetworkInfo>(network_info);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(rc);
}
void GetDisconnectReason(Kernel::HLERequestContext& ctx) {
const auto disconnect_reason = DisconnectReason::None;
LOG_WARNING(Service_LDN, "(STUBBED) called, disconnect_reason={}", disconnect_reason);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.PushEnum(disconnect_reason);
}
void GetSecurityParameter(Kernel::HLERequestContext& ctx) {
SecurityParameter security_parameter{};
NetworkInfo info{};
const Result rc = ResultSuccess;
if (rc.IsError()) {
LOG_ERROR(Service_LDN, "NetworkInfo is not valid {}", rc.raw);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(rc);
return;
}
security_parameter.session_id = info.network_id.session_id;
std::memcpy(security_parameter.data.data(), info.ldn.security_parameter.data(),
sizeof(SecurityParameter::data));
LOG_WARNING(Service_LDN, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 10};
rb.Push(rc);
rb.PushRaw<SecurityParameter>(security_parameter);
}
void GetNetworkConfig(Kernel::HLERequestContext& ctx) {
NetworkConfig config{};
NetworkInfo info{};
const Result rc = ResultSuccess;
if (rc.IsError()) {
LOG_ERROR(Service_LDN, "NetworkConfig is not valid {}", rc.raw);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(rc);
return;
}
config.intent_id = info.network_id.intent_id;
config.channel = info.common.channel;
config.node_count_max = info.ldn.node_count_max;
config.local_communication_version = info.ldn.nodes[0].local_communication_version;
LOG_WARNING(Service_LDN,
"(STUBBED) called, intent_id={}/{}, channel={}, node_count_max={}, "
"local_communication_version={}",
config.intent_id.local_communication_id, config.intent_id.scene_id,
config.channel, config.node_count_max, config.local_communication_version);
IPC::ResponseBuilder rb{ctx, 10};
rb.Push(rc);
rb.PushRaw<NetworkConfig>(config);
}
void AttachStateChangeEvent(Kernel::HLERequestContext& ctx) {
LOG_INFO(Service_LDN, "called");
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(ResultSuccess);
rb.PushCopyObjects(state_change_event->GetReadableEvent());
}
void GetNetworkInfoLatestUpdate(Kernel::HLERequestContext& ctx) {
const std::size_t network_buffer_size = ctx.GetWriteBufferSize(0);
const std::size_t node_buffer_count = ctx.GetWriteBufferSize(1) / sizeof(NodeLatestUpdate);
if (node_buffer_count == 0 || network_buffer_size != sizeof(NetworkInfo)) {
LOG_ERROR(Service_LDN, "Invalid buffer size {}, {}", network_buffer_size,
node_buffer_count);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultBadInput);
return;
}
NetworkInfo info;
std::vector<NodeLatestUpdate> latest_update(node_buffer_count);
const auto rc = ResultSuccess;
if (rc.IsError()) {
LOG_ERROR(Service_LDN, "NetworkInfo is not valid {}", rc.raw);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(rc);
return;
}
LOG_WARNING(Service_LDN, "(STUBBED) called, ssid='{}', nodes={}",
info.common.ssid.GetStringValue(), info.ldn.node_count);
ctx.WriteBuffer(info, 0);
ctx.WriteBuffer(latest_update, 1);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void Scan(Kernel::HLERequestContext& ctx) {
ScanImpl(ctx);
}
void ScanPrivate(Kernel::HLERequestContext& ctx) {
ScanImpl(ctx, true);
}
void ScanImpl(Kernel::HLERequestContext& ctx, bool is_private = false) {
IPC::RequestParser rp{ctx};
const auto channel{rp.PopEnum<WifiChannel>()};
const auto scan_filter{rp.PopRaw<ScanFilter>()};
const std::size_t network_info_size = ctx.GetWriteBufferSize() / sizeof(NetworkInfo);
if (network_info_size == 0) {
LOG_ERROR(Service_LDN, "Invalid buffer size {}", network_info_size);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultBadInput);
return;
}
u16 count = 0;
std::vector<NetworkInfo> network_infos(network_info_size);
LOG_WARNING(Service_LDN,
"(STUBBED) called, channel={}, filter_scan_flag={}, filter_network_type={}",
channel, scan_filter.flag, scan_filter.network_type);
ctx.WriteBuffer(network_infos);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push<u32>(count);
}
void OpenAccessPoint(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_LDN, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void CloseAccessPoint(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_LDN, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void CreateNetwork(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
struct Parameters {
SecurityConfig security_config;
UserConfig user_config;
INSERT_PADDING_WORDS_NOINIT(1);
NetworkConfig network_config;
};
static_assert(sizeof(Parameters) == 0x98, "Parameters has incorrect size.");
const auto parameters{rp.PopRaw<Parameters>()};
LOG_WARNING(Service_LDN,
"(STUBBED) called, passphrase_size={}, security_mode={}, "
"local_communication_version={}",
parameters.security_config.passphrase_size,
parameters.security_config.security_mode,
parameters.network_config.local_communication_version);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void CreateNetworkPrivate(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
struct Parameters {
SecurityConfig security_config;
SecurityParameter security_parameter;
UserConfig user_config;
NetworkConfig network_config;
};
static_assert(sizeof(Parameters) == 0xB8, "Parameters has incorrect size.");
const auto parameters{rp.PopRaw<Parameters>()};
LOG_WARNING(Service_LDN,
"(STUBBED) called, passphrase_size={}, security_mode={}, "
"local_communication_version={}",
parameters.security_config.passphrase_size,
parameters.security_config.security_mode,
parameters.network_config.local_communication_version);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void DestroyNetwork(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_LDN, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void SetAdvertiseData(Kernel::HLERequestContext& ctx) {
std::vector<u8> read_buffer = ctx.ReadBuffer();
LOG_WARNING(Service_LDN, "(STUBBED) called, size {}", read_buffer.size());
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void SetStationAcceptPolicy(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_LDN, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void AddAcceptFilterEntry(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_LDN, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void OpenStation(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_LDN, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void CloseStation(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_LDN, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void Connect(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
struct Parameters {
SecurityConfig security_config;
UserConfig user_config;
u32 local_communication_version;
u32 option;
};
static_assert(sizeof(Parameters) == 0x7C, "Parameters has incorrect size.");
const auto parameters{rp.PopRaw<Parameters>()};
LOG_WARNING(Service_LDN,
"(STUBBED) called, passphrase_size={}, security_mode={}, "
"local_communication_version={}",
parameters.security_config.passphrase_size,
parameters.security_config.security_mode,
parameters.local_communication_version);
const std::vector<u8> read_buffer = ctx.ReadBuffer();
NetworkInfo network_info{};
if (read_buffer.size() != sizeof(NetworkInfo)) {
LOG_ERROR(Frontend, "NetworkInfo doesn't match read_buffer size!");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultBadInput);
return;
}
std::memcpy(&network_info, read_buffer.data(), read_buffer.size());
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void Disconnect(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_LDN, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void Initialize(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_LDN, "(STUBBED) called");
const auto rc = InitializeImpl(ctx);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(rc);
}
void Finalize(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_LDN, "(STUBBED) called");
is_initialized = false;
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess); rb.Push(ResultSuccess);
} }
void Initialize2(Kernel::HLERequestContext& ctx) { void Initialize2(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_LDN, "called"); LOG_WARNING(Service_LDN, "(STUBBED) called");
is_initialized = true; const auto rc = InitializeImpl(ctx);
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ERROR_DISABLED); rb.Push(rc);
} }
private: Result InitializeImpl(Kernel::HLERequestContext& ctx) {
enum class State { const auto network_interface = Network::GetSelectedNetworkInterface();
None, if (!network_interface) {
Initialized, LOG_ERROR(Service_LDN, "No network interface is set");
AccessPointOpened, return ResultAirplaneModeEnabled;
AccessPointCreated, }
StationOpened,
StationConnected, is_initialized = true;
Error, // TODO (flTobi): Change this to ResultSuccess when LDN is fully implemented
}; return ResultAirplaneModeEnabled;
}
KernelHelpers::ServiceContext service_context;
Kernel::KEvent* state_change_event;
Network::RoomNetwork& room_network;
bool is_initialized{}; bool is_initialized{};
}; };
@ -273,7 +621,7 @@ public:
LOG_WARNING(Service_LDN, "(STUBBED) called"); LOG_WARNING(Service_LDN, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ERROR_DISABLED); rb.Push(ResultDisabled);
} }
}; };

View file

@ -3,6 +3,12 @@
#pragma once #pragma once
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/k_event.h"
#include "core/hle/result.h"
#include "core/hle/service/kernel_helpers.h"
#include "core/hle/service/sm/sm.h"
namespace Core { namespace Core {
class System; class System;
} }

View file

@ -0,0 +1,27 @@
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include "core/hle/result.h"
namespace Service::LDN {
constexpr Result ResultAdvertiseDataTooLarge{ErrorModule::LDN, 10};
constexpr Result ResultAuthenticationFailed{ErrorModule::LDN, 20};
constexpr Result ResultDisabled{ErrorModule::LDN, 22};
constexpr Result ResultAirplaneModeEnabled{ErrorModule::LDN, 23};
constexpr Result ResultInvalidNodeCount{ErrorModule::LDN, 30};
constexpr Result ResultConnectionFailed{ErrorModule::LDN, 31};
constexpr Result ResultBadState{ErrorModule::LDN, 32};
constexpr Result ResultNoIpAddress{ErrorModule::LDN, 33};
constexpr Result ResultInvalidBufferCount{ErrorModule::LDN, 50};
constexpr Result ResultAccessPointConnectionFailed{ErrorModule::LDN, 65};
constexpr Result ResultAuthenticationTimeout{ErrorModule::LDN, 66};
constexpr Result ResultMaximumNodeCount{ErrorModule::LDN, 67};
constexpr Result ResultBadInput{ErrorModule::LDN, 96};
constexpr Result ResultLocalCommunicationIdNotFound{ErrorModule::LDN, 97};
constexpr Result ResultLocalCommunicationVersionTooLow{ErrorModule::LDN, 113};
constexpr Result ResultLocalCommunicationVersionTooHigh{ErrorModule::LDN, 114};
} // namespace Service::LDN

View file

@ -0,0 +1,284 @@
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include <fmt/format.h>
#include "common/common_funcs.h"
#include "common/common_types.h"
#include "network/network.h"
namespace Service::LDN {
constexpr size_t SsidLengthMax = 32;
constexpr size_t AdvertiseDataSizeMax = 384;
constexpr size_t UserNameBytesMax = 32;
constexpr int NodeCountMax = 8;
constexpr int StationCountMax = NodeCountMax - 1;
constexpr size_t PassphraseLengthMax = 64;
enum class SecurityMode : u16 {
All,
Retail,
Debug,
};
enum class NodeStateChange : u8 {
None,
Connect,
Disconnect,
DisconnectAndConnect,
};
enum class ScanFilterFlag : u32 {
None = 0,
LocalCommunicationId = 1 << 0,
SessionId = 1 << 1,
NetworkType = 1 << 2,
Ssid = 1 << 4,
SceneId = 1 << 5,
IntentId = LocalCommunicationId | SceneId,
NetworkId = IntentId | SessionId,
};
enum class NetworkType : u32 {
None,
General,
Ldn,
All,
};
enum class PackedNetworkType : u8 {
None,
General,
Ldn,
All,
};
enum class State : u32 {
None,
Initialized,
AccessPointOpened,
AccessPointCreated,
StationOpened,
StationConnected,
Error,
};
enum class DisconnectReason : s16 {
Unknown = -1,
None,
DisconnectedByUser,
DisconnectedBySystem,
DestroyedByUser,
DestroyedBySystem,
Rejected,
SignalLost,
};
enum class NetworkError {
Unknown = -1,
None = 0,
PortUnreachable,
TooManyPlayers,
VersionTooLow,
VersionTooHigh,
ConnectFailure,
ConnectNotFound,
ConnectTimeout,
ConnectRejected,
RejectFailed,
};
enum class AcceptPolicy : u8 {
AcceptAll,
RejectAll,
BlackList,
WhiteList,
};
enum class WifiChannel : s16 {
Default = 0,
wifi24_1 = 1,
wifi24_6 = 6,
wifi24_11 = 11,
wifi50_36 = 36,
wifi50_40 = 40,
wifi50_44 = 44,
wifi50_48 = 48,
};
enum class LinkLevel : s8 {
Bad,
Low,
Good,
Excelent,
};
struct NodeLatestUpdate {
NodeStateChange state_change;
INSERT_PADDING_BYTES(0x7); // Unknown
};
static_assert(sizeof(NodeLatestUpdate) == 0x8, "NodeLatestUpdate is an invalid size");
struct SessionId {
u64 high;
u64 low;
bool operator==(const SessionId&) const = default;
};
static_assert(sizeof(SessionId) == 0x10, "SessionId is an invalid size");
struct IntentId {
u64 local_communication_id;
INSERT_PADDING_BYTES(0x2); // Reserved
u16 scene_id;
INSERT_PADDING_BYTES(0x4); // Reserved
};
static_assert(sizeof(IntentId) == 0x10, "IntentId is an invalid size");
struct NetworkId {
IntentId intent_id;
SessionId session_id;
};
static_assert(sizeof(NetworkId) == 0x20, "NetworkId is an invalid size");
struct Ssid {
u8 length;
std::array<char, SsidLengthMax + 1> raw;
std::string GetStringValue() const {
return std::string(raw.data(), length);
}
};
static_assert(sizeof(Ssid) == 0x22, "Ssid is an invalid size");
struct Ipv4Address {
union {
u32 raw{};
std::array<u8, 4> bytes;
};
std::string GetStringValue() const {
return fmt::format("{}.{}.{}.{}", bytes[3], bytes[2], bytes[1], bytes[0]);
}
};
static_assert(sizeof(Ipv4Address) == 0x4, "Ipv4Address is an invalid size");
struct MacAddress {
std::array<u8, 6> raw{};
friend bool operator==(const MacAddress& lhs, const MacAddress& rhs) = default;
};
static_assert(sizeof(MacAddress) == 0x6, "MacAddress is an invalid size");
struct ScanFilter {
NetworkId network_id;
NetworkType network_type;
MacAddress mac_address;
Ssid ssid;
INSERT_PADDING_BYTES(0x10);
ScanFilterFlag flag;
};
static_assert(sizeof(ScanFilter) == 0x60, "ScanFilter is an invalid size");
struct CommonNetworkInfo {
MacAddress bssid;
Ssid ssid;
WifiChannel channel;
LinkLevel link_level;
PackedNetworkType network_type;
INSERT_PADDING_BYTES(0x4);
};
static_assert(sizeof(CommonNetworkInfo) == 0x30, "CommonNetworkInfo is an invalid size");
struct NodeInfo {
Ipv4Address ipv4_address;
MacAddress mac_address;
s8 node_id;
u8 is_connected;
std::array<u8, UserNameBytesMax + 1> user_name;
INSERT_PADDING_BYTES(0x1); // Reserved
s16 local_communication_version;
INSERT_PADDING_BYTES(0x10); // Reserved
};
static_assert(sizeof(NodeInfo) == 0x40, "NodeInfo is an invalid size");
struct LdnNetworkInfo {
std::array<u8, 0x10> security_parameter;
SecurityMode security_mode;
AcceptPolicy station_accept_policy;
u8 has_action_frame;
INSERT_PADDING_BYTES(0x2); // Padding
u8 node_count_max;
u8 node_count;
std::array<NodeInfo, NodeCountMax> nodes;
INSERT_PADDING_BYTES(0x2); // Reserved
u16 advertise_data_size;
std::array<u8, AdvertiseDataSizeMax> advertise_data;
INSERT_PADDING_BYTES(0x8C); // Reserved
u64 random_authentication_id;
};
static_assert(sizeof(LdnNetworkInfo) == 0x430, "LdnNetworkInfo is an invalid size");
struct NetworkInfo {
NetworkId network_id;
CommonNetworkInfo common;
LdnNetworkInfo ldn;
};
static_assert(sizeof(NetworkInfo) == 0x480, "NetworkInfo is an invalid size");
struct SecurityConfig {
SecurityMode security_mode;
u16 passphrase_size;
std::array<u8, PassphraseLengthMax> passphrase;
};
static_assert(sizeof(SecurityConfig) == 0x44, "SecurityConfig is an invalid size");
struct UserConfig {
std::array<u8, UserNameBytesMax + 1> user_name;
INSERT_PADDING_BYTES(0xF); // Reserved
};
static_assert(sizeof(UserConfig) == 0x30, "UserConfig is an invalid size");
#pragma pack(push, 4)
struct ConnectRequest {
SecurityConfig security_config;
UserConfig user_config;
u32 local_communication_version;
u32 option_unknown;
NetworkInfo network_info;
};
static_assert(sizeof(ConnectRequest) == 0x4FC, "ConnectRequest is an invalid size");
#pragma pack(pop)
struct SecurityParameter {
std::array<u8, 0x10> data; // Data, used with the same key derivation as SecurityConfig
SessionId session_id;
};
static_assert(sizeof(SecurityParameter) == 0x20, "SecurityParameter is an invalid size");
struct NetworkConfig {
IntentId intent_id;
WifiChannel channel;
u8 node_count_max;
INSERT_PADDING_BYTES(0x1); // Reserved
u16 local_communication_version;
INSERT_PADDING_BYTES(0xA); // Reserved
};
static_assert(sizeof(NetworkConfig) == 0x20, "NetworkConfig is an invalid size");
struct AddressEntry {
Ipv4Address ipv4_address;
MacAddress mac_address;
INSERT_PADDING_BYTES(0x2); // Reserved
};
static_assert(sizeof(AddressEntry) == 0xC, "AddressEntry is an invalid size");
struct AddressList {
std::array<AddressEntry, 0x8> addresses;
};
static_assert(sizeof(AddressList) == 0x60, "AddressList is an invalid size");
} // namespace Service::LDN

View file

@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>616</width> <width>616</width>
<height>261</height> <height>294</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -165,6 +165,7 @@ p, li { white-space: pre-wrap; }
</widget> </widget>
<resources> <resources>
<include location="../../dist/qt_themes_default/default/default.qrc"/> <include location="../../dist/qt_themes_default/default/default.qrc"/>
<include location="../../dist/qt_themes/default/default.qrc"/>
</resources> </resources>
<connections> <connections>
<connection> <connection>

View file

@ -73,7 +73,7 @@ const std::array<int, 2> Config::default_ringcon_analogs{{
const std::array<UISettings::Shortcut, 22> Config::default_hotkeys{{ const std::array<UISettings::Shortcut, 22> Config::default_hotkeys{{
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Audio Mute/Unmute")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+M"), QStringLiteral("Home+Dpad_Right"), Qt::WindowShortcut}}, {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Audio Mute/Unmute")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+M"), QStringLiteral("Home+Dpad_Right"), Qt::WindowShortcut}},
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Audio Volume Down")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("-"), QStringLiteral("Home+Dpad_Down"), Qt::ApplicationShortcut}}, {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Audio Volume Down")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("-"), QStringLiteral("Home+Dpad_Down"), Qt::ApplicationShortcut}},
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Audio Volume Up")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("+"), QStringLiteral("Home+Dpad_Up"), Qt::ApplicationShortcut}}, {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Audio Volume Up")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("="), QStringLiteral("Home+Dpad_Up"), Qt::ApplicationShortcut}},
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Capture Screenshot")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+P"), QStringLiteral("Screenshot"), Qt::WidgetWithChildrenShortcut}}, {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Capture Screenshot")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+P"), QStringLiteral("Screenshot"), Qt::WidgetWithChildrenShortcut}},
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Change Adapting Filter")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F8"), QStringLiteral("Home+L"), Qt::ApplicationShortcut}}, {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Change Adapting Filter")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F8"), QStringLiteral("Home+L"), Qt::ApplicationShortcut}},
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Change Docked Mode")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F10"), QStringLiteral("Home+X"), Qt::ApplicationShortcut}}, {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Change Docked Mode")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F10"), QStringLiteral("Home+X"), Qt::ApplicationShortcut}},

View file

@ -120,10 +120,10 @@
</sizepolicy> </sizepolicy>
</property> </property>
<property name="maximum"> <property name="maximum">
<number>100</number> <number>200</number>
</property> </property>
<property name="pageStep"> <property name="pageStep">
<number>10</number> <number>5</number>
</property> </property>
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>

View file

@ -258,7 +258,7 @@ static QString PrettyProductName() {
return QSysInfo::prettyProductName(); return QSysInfo::prettyProductName();
} }
bool GMainWindow::check_dark_mode() { bool GMainWindow::CheckDarkMode() {
#ifdef __linux__ #ifdef __linux__
const QPalette test_palette(qApp->palette()); const QPalette test_palette(qApp->palette());
const QColor text_color = test_palette.color(QPalette::Active, QPalette::Text); const QColor text_color = test_palette.color(QPalette::Active, QPalette::Text);
@ -288,7 +288,7 @@ GMainWindow::GMainWindow(bool has_broken_vulkan)
statusBar()->hide(); statusBar()->hide();
// Check dark mode before a theme is loaded // Check dark mode before a theme is loaded
os_dark_mode = check_dark_mode(); os_dark_mode = CheckDarkMode();
startup_icon_theme = QIcon::themeName(); startup_icon_theme = QIcon::themeName();
// fallback can only be set once, colorful theme icons are okay on both light/dark // fallback can only be set once, colorful theme icons are okay on both light/dark
QIcon::setFallbackThemeName(QStringLiteral("colorful")); QIcon::setFallbackThemeName(QStringLiteral("colorful"));
@ -1095,7 +1095,7 @@ void GMainWindow::InitializeHotkeys() {
connect_shortcut(QStringLiteral("Audio Mute/Unmute"), connect_shortcut(QStringLiteral("Audio Mute/Unmute"),
[] { Settings::values.audio_muted = !Settings::values.audio_muted; }); [] { Settings::values.audio_muted = !Settings::values.audio_muted; });
connect_shortcut(QStringLiteral("Audio Volume Down"), [] { connect_shortcut(QStringLiteral("Audio Volume Down"), [] {
const auto current_volume = static_cast<int>(Settings::values.volume.GetValue()); const auto current_volume = static_cast<s32>(Settings::values.volume.GetValue());
int step = 5; int step = 5;
if (current_volume <= 30) { if (current_volume <= 30) {
step = 2; step = 2;
@ -1103,11 +1103,10 @@ void GMainWindow::InitializeHotkeys() {
if (current_volume <= 6) { if (current_volume <= 6) {
step = 1; step = 1;
} }
const auto new_volume = std::max(current_volume - step, 0); Settings::values.volume.SetValue(std::max(current_volume - step, 0));
Settings::values.volume.SetValue(static_cast<u8>(new_volume));
}); });
connect_shortcut(QStringLiteral("Audio Volume Up"), [] { connect_shortcut(QStringLiteral("Audio Volume Up"), [] {
const auto current_volume = static_cast<int>(Settings::values.volume.GetValue()); const auto current_volume = static_cast<s32>(Settings::values.volume.GetValue());
int step = 5; int step = 5;
if (current_volume < 30) { if (current_volume < 30) {
step = 2; step = 2;
@ -1115,8 +1114,7 @@ void GMainWindow::InitializeHotkeys() {
if (current_volume < 6) { if (current_volume < 6) {
step = 1; step = 1;
} }
const auto new_volume = std::min(current_volume + step, 100); Settings::values.volume.SetValue(current_volume + step);
Settings::values.volume.SetValue(static_cast<u8>(new_volume));
}); });
connect_shortcut(QStringLiteral("Toggle Framerate Limit"), [] { connect_shortcut(QStringLiteral("Toggle Framerate Limit"), [] {
Settings::values.use_speed_limit.SetValue(!Settings::values.use_speed_limit.GetValue()); Settings::values.use_speed_limit.SetValue(!Settings::values.use_speed_limit.GetValue());
@ -3986,7 +3984,7 @@ void GMainWindow::UpdateUITheme() {
QIcon::setThemeName(current_theme == QStringLiteral("colorful") ? current_theme QIcon::setThemeName(current_theme == QStringLiteral("colorful") ? current_theme
: startup_icon_theme); : startup_icon_theme);
QIcon::setThemeSearchPaths(theme_paths); QIcon::setThemeSearchPaths(theme_paths);
if (check_dark_mode()) { if (CheckDarkMode()) {
current_theme = QStringLiteral("default_dark"); current_theme = QStringLiteral("default_dark");
} }
} else { } else {

View file

@ -348,6 +348,7 @@ private:
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();
QString GetTasStateDescription() const; QString GetTasStateDescription() const;
@ -395,7 +396,6 @@ private:
QString startup_icon_theme; QString startup_icon_theme;
bool os_dark_mode = false; bool os_dark_mode = false;
bool check_dark_mode();
// FS // FS
std::shared_ptr<FileSys::VfsFilesystem> vfs; std::shared_ptr<FileSys::VfsFilesystem> vfs;

View file

@ -83,7 +83,7 @@
<number>5</number> <number>5</number>
</property> </property>
<property name="placeholderText"> <property name="placeholderText">
<string>24872</string> <string notr="true" extracomment="placeholder string that tells user default port">24872</string>
</property> </property>
</widget> </widget>
</item> </item>