Compare commits

..

28 Commits

Author SHA1 Message Date
David Marcec
f64ab04ac6 Initialize various struct members
This PR doesn't change anything in file_sys or video core. Most of core is complete, however there might be a few things missing. This is done to make emulation more deterministic and not rely on possible uninitialized data
2019-11-03 22:30:13 +11:00
bunnei
bec7e3b7d9 Merge pull request #3058 from FearlessTobi/port-4948
Port citra-emu/citra#4948: "citra_qt: add amiibo drag and drop support"
2019-11-03 01:55:21 -04:00
FearlessTobi
727ba2f2d0 citra_qt: add amiibo drag and drop support
Co-Authored-By: Valentin Vanelslande <vvanelslandedev@gmail.com>
2019-11-03 05:24:47 +01:00
Rodrigo Locatti
11e39da02b Merge pull request #3054 from FernandoS27/fix-tld4-2
shader_ir: Fix regression on TLD4
2019-10-31 01:56:29 +00:00
Fernando Sahmkow
23cabc98db Shader_IR: Fix regression on TLD4
Originally on the last commit I thought TLD4 acted the same as TLD4S and 
didn't have a mask. It actually does have a component mask. This commit 
corrects that.
2019-10-30 21:14:57 -04:00
Rodrigo Locatti
658489ebf7 Merge pull request #3050 from FernandoS27/fix-tld4
shader_ir: Fix TLD4 and add bindless variant
2019-10-30 18:37:17 +00:00
Fernando Sahmkow
9293c3a0f2 Shader_IR: Fix TLD4 and add Bindless Variant.
This commit fixes an issue where not all 4 results of tld4 were being
written, the color component was defaulted to red, among other things.
It also implements the bindless variant.
2019-10-30 12:02:03 -04:00
Rodrigo Locatti
04b838c857 Merge pull request #3038 from lioncash/docs
kernel/scheduler: Minor changes
2019-10-30 03:47:28 +00:00
bunnei
2382bbe3ac Merge pull request #3046 from ReinUsesLisp/clean-gl-state
gl_state: Miscellaneous clean up
2019-10-29 22:50:04 -04:00
bunnei
b5138f3c35 Merge pull request #3035 from ReinUsesLisp/rasterizer-accelerated
rasterizer_accelerated: Add intermediary for GPU rasterizers
2019-10-29 22:06:41 -04:00
bunnei
a81bd962ab Merge pull request #3007 from DarkLordZach/fsc-regress
savedata_factory: Automatically create certain savedata
2019-10-29 22:05:09 -04:00
Rodrigo Locatti
3d0cde6a75 gl_state: Use std::array::fill instead of std::fill
Co-Authored-By: Mat M. <mathew1800@gmail.com>
2019-10-30 01:30:31 +00:00
ReinUsesLisp
ce20ed8e4e gl_state: Move dirty checks to individual apply calls instead of Apply
This requires removing constness from some methods, but for consistency
it's removed in all methods.
2019-10-29 21:27:25 -03:00
ReinUsesLisp
3c6557c235 gl_state: Remove ApplyDefaultState
OpenGL has defaults values we can trust. Remove these.
2019-10-29 21:27:25 -03:00
ReinUsesLisp
d3651b0b82 gl_state: Change SetDefaultViewports to use default constructor 2019-10-29 21:27:24 -03:00
ReinUsesLisp
c7698d0bc8 gl_state: Minor style changes 2019-10-29 21:27:24 -03:00
ReinUsesLisp
a14d202ac2 gl_state: Remove unused Citra TextureUnits 2019-10-29 21:27:24 -03:00
ReinUsesLisp
28fece8e9b gl_state: Move initializers from constructor to class declaration 2019-10-29 21:27:23 -03:00
Rodrigo Locatti
2ec5b55ee3 Merge pull request #3004 from ReinUsesLisp/maxwell3d-cleanup
maxwell_3d: Remove unused entries
2019-10-29 23:46:33 +00:00
Lioncash
6c8f28813c scheduler: Mark parameter of AskForReselectionOrMarkRedundant() as const
This is only compared against, so it can be made const.
2019-10-27 23:35:50 -04:00
ReinUsesLisp
fa31e5b868 maxwell_3d/kepler_compute: Remove unused arguments in GetTexture 2019-10-28 00:23:42 -03:00
ReinUsesLisp
538ddd220e video_core/textures: Remove unused index entry in FullTextureInfo 2019-10-28 00:14:38 -03:00
ReinUsesLisp
961fe4d19b maxwell_3d: Remove unused method GetStageTextures 2019-10-28 00:14:29 -03:00
Lioncash
f19c1a7cda scheduler: Silence sign conversion warnings 2019-10-27 22:44:52 -04:00
Lioncash
2fb0bbff29 scheduler: Initialize class members directly where applicable
Reduces the overall amount of code.
2019-10-27 22:13:55 -04:00
Lioncash
2dc469ceba scheduler: Amend documentation comments
Adjusts the formatting of a few of the comments an ensures they get
recognized as proper Doxygen comments.
2019-10-27 22:12:32 -04:00
ReinUsesLisp
bd2aff3e26 rasterizer_accelerated: Add intermediary for GPU rasterizers
Add an intermediary class that implements common functions across GPU
accelerated rasterizers. This avoids code repetition on different
backends.
2019-10-27 03:40:08 -03:00
Zach Hilman
bb207fe27a savedata_factory: Automatically create certain savedata
After further hardware investigation, it appears that some games, perhaps those more lazily coded, will not call EnsureSaveData, meaning that they expect the normal (current) save to be automatically made. Additionally, some games do not create a cache or temporary save before use.
In these 3 specific instances, the save is created automatically for the game if it doesn't exist.
2019-10-22 15:47:38 -04:00
128 changed files with 1735 additions and 3208 deletions

View File

@@ -43,22 +43,22 @@ enum class EffectStatus : u8 {
};
struct AudioRendererParameter {
u32_le sample_rate;
u32_le sample_count;
u32_le mix_buffer_count;
u32_le submix_count;
u32_le voice_count;
u32_le sink_count;
u32_le effect_count;
u32_le performance_frame_count;
u8 is_voice_drop_enabled;
u8 unknown_21;
u8 unknown_22;
u8 execution_mode;
u32_le splitter_count;
u32_le num_splitter_send_channels;
u32_le unknown_30;
u32_le revision;
u32_le sample_rate{};
u32_le sample_count{};
u32_le mix_buffer_count{};
u32_le submix_count{};
u32_le voice_count{};
u32_le sink_count{};
u32_le effect_count{};
u32_le performance_frame_count{};
u8 is_voice_drop_enabled{};
u8 unknown_21{};
u8 unknown_22{};
u8 execution_mode{};
u32_le splitter_count{};
u32_le num_splitter_send_channels{};
u32_le unknown_30{};
u32_le revision{};
};
static_assert(sizeof(AudioRendererParameter) == 52, "AudioRendererParameter is an invalid size");
@@ -73,111 +73,111 @@ enum class MemoryPoolStates : u32 { // Should be LE
};
struct MemoryPoolEntry {
MemoryPoolStates state;
u32_le unknown_4;
u32_le unknown_8;
u32_le unknown_c;
MemoryPoolStates state{};
u32_le unknown_4{};
u32_le unknown_8{};
u32_le unknown_c{};
};
static_assert(sizeof(MemoryPoolEntry) == 0x10, "MemoryPoolEntry has wrong size");
struct MemoryPoolInfo {
u64_le pool_address;
u64_le pool_size;
MemoryPoolStates pool_state;
INSERT_PADDING_WORDS(3); // Unknown
u64_le pool_address{};
u64_le pool_size{};
MemoryPoolStates pool_state{};
INSERT_PADDING_WORDS(3){}; // Unknown
};
static_assert(sizeof(MemoryPoolInfo) == 0x20, "MemoryPoolInfo has wrong size");
struct BiquadFilter {
u8 enable;
INSERT_PADDING_BYTES(1);
std::array<s16_le, 3> numerator;
std::array<s16_le, 2> denominator;
u8 enable{};
INSERT_PADDING_BYTES(1){};
std::array<s16_le, 3> numerator{};
std::array<s16_le, 2> denominator{};
};
static_assert(sizeof(BiquadFilter) == 0xc, "BiquadFilter has wrong size");
struct WaveBuffer {
u64_le buffer_addr;
u64_le buffer_sz;
s32_le start_sample_offset;
s32_le end_sample_offset;
u8 is_looping;
u8 end_of_stream;
u8 sent_to_server;
INSERT_PADDING_BYTES(5);
u64 context_addr;
u64 context_sz;
INSERT_PADDING_BYTES(8);
u64_le buffer_addr{};
u64_le buffer_sz{};
s32_le start_sample_offset{};
s32_le end_sample_offset{};
u8 is_looping{};
u8 end_of_stream{};
u8 sent_to_server{};
INSERT_PADDING_BYTES(5){};
u64 context_addr{};
u64 context_sz{};
INSERT_PADDING_BYTES(8){};
};
static_assert(sizeof(WaveBuffer) == 0x38, "WaveBuffer has wrong size");
struct VoiceInfo {
u32_le id;
u32_le node_id;
u8 is_new;
u8 is_in_use;
PlayState play_state;
u8 sample_format;
u32_le sample_rate;
u32_le priority;
u32_le sorting_order;
u32_le channel_count;
float_le pitch;
float_le volume;
std::array<BiquadFilter, 2> biquad_filter;
u32_le wave_buffer_count;
u32_le wave_buffer_head;
INSERT_PADDING_WORDS(1);
u64_le additional_params_addr;
u64_le additional_params_sz;
u32_le mix_id;
u32_le splitter_info_id;
std::array<WaveBuffer, 4> wave_buffer;
std::array<u32_le, 6> voice_channel_resource_ids;
INSERT_PADDING_BYTES(24);
u32_le id{};
u32_le node_id{};
u8 is_new{};
u8 is_in_use{};
PlayState play_state{};
u8 sample_format{};
u32_le sample_rate{};
u32_le priority{};
u32_le sorting_order{};
u32_le channel_count{};
float_le pitch{};
float_le volume{};
std::array<BiquadFilter, 2> biquad_filter{};
u32_le wave_buffer_count{};
u32_le wave_buffer_head{};
INSERT_PADDING_WORDS(1){};
u64_le additional_params_addr{};
u64_le additional_params_sz{};
u32_le mix_id{};
u32_le splitter_info_id{};
std::array<WaveBuffer, 4> wave_buffer{};
std::array<u32_le, 6> voice_channel_resource_ids{};
INSERT_PADDING_BYTES(24){};
};
static_assert(sizeof(VoiceInfo) == 0x170, "VoiceInfo is wrong size");
struct VoiceOutStatus {
u64_le played_sample_count;
u32_le wave_buffer_consumed;
u32_le voice_drops_count;
u64_le played_sample_count{};
u32_le wave_buffer_consumed{};
u32_le voice_drops_count{};
};
static_assert(sizeof(VoiceOutStatus) == 0x10, "VoiceOutStatus has wrong size");
struct AuxInfo {
std::array<u8, 24> input_mix_buffers;
std::array<u8, 24> output_mix_buffers;
u32_le mix_buffer_count;
u32_le sample_rate; // Stored in the aux buffer currently
u32_le sample_count;
u64_le send_buffer_info;
u64_le send_buffer_base;
std::array<u8, 24> input_mix_buffers{};
std::array<u8, 24> output_mix_buffers{};
u32_le mix_buffer_count{};
u32_le sample_rate{}; // Stored in the aux buffer currently
u32_le sample_count{};
u64_le send_buffer_info{};
u64_le send_buffer_base{};
u64_le return_buffer_info;
u64_le return_buffer_base;
u64_le return_buffer_info{};
u64_le return_buffer_base{};
};
static_assert(sizeof(AuxInfo) == 0x60, "AuxInfo is an invalid size");
struct EffectInStatus {
Effect type;
u8 is_new;
u8 is_enabled;
INSERT_PADDING_BYTES(1);
u32_le mix_id;
u64_le buffer_base;
u64_le buffer_sz;
s32_le priority;
INSERT_PADDING_BYTES(4);
Effect type{};
u8 is_new{};
u8 is_enabled{};
INSERT_PADDING_BYTES(1){};
u32_le mix_id{};
u64_le buffer_base{};
u64_le buffer_sz{};
s32_le priority{};
INSERT_PADDING_BYTES(4){};
union {
std::array<u8, 0xa0> raw;
std::array<u8, 0xa0> raw{};
AuxInfo aux_info;
};
};
static_assert(sizeof(EffectInStatus) == 0xc0, "EffectInStatus is an invalid size");
struct EffectOutStatus {
EffectStatus state;
INSERT_PADDING_BYTES(0xf);
EffectStatus state{};
INSERT_PADDING_BYTES(0xf){};
};
static_assert(sizeof(EffectOutStatus) == 0x10, "EffectOutStatus is an invalid size");
@@ -208,9 +208,9 @@ struct UpdateDataHeader {
u32_le mixes_size{};
u32_le sinks_size{};
u32_le performance_manager_size{};
INSERT_PADDING_WORDS(1);
INSERT_PADDING_WORDS(1){};
u32_le frame_count{};
INSERT_PADDING_WORDS(4);
INSERT_PADDING_WORDS(4){};
u32_le total_size{};
};
static_assert(sizeof(UpdateDataHeader) == 0x40, "UpdateDataHeader has wrong size");

View File

@@ -25,8 +25,8 @@ enum class PcmFormat : u32 {
struct ADPCMState {
// Two historical samples from previous processed buffer,
// required for ADPCM decoding
s16 yn1; ///< y[n-1]
s16 yn2; ///< y[n-2]
s16 yn1{}; ///< y[n-1]
s16 yn2{}; ///< y[n-2]
};
using ADPCM_Coeff = std::array<s16, 16>;

View File

@@ -28,14 +28,18 @@ __declspec(noinline, noreturn)
}
#define ASSERT(_a_) \
if (!(_a_)) { \
LOG_CRITICAL(Debug, "Assertion Failed!"); \
}
do \
if (!(_a_)) { \
assert_noinline_call([] { LOG_CRITICAL(Debug, "Assertion Failed!"); }); \
} \
while (0)
#define ASSERT_MSG(_a_, ...) \
if (!(_a_)) { \
LOG_CRITICAL(Debug, "Assertion Failed! " __VA_ARGS__); \
}
do \
if (!(_a_)) { \
assert_noinline_call([&] { LOG_CRITICAL(Debug, "Assertion Failed!\n" __VA_ARGS__); }); \
} \
while (0)
#define UNREACHABLE() ASSERT_MSG(false, "Unreachable code!")
#define UNREACHABLE_MSG(...) ASSERT_MSG(false, __VA_ARGS__)

View File

@@ -20,11 +20,11 @@ class Filter;
* formatting on different frontends, as well as facilitating filtering and aggregation.
*/
struct Entry {
std::chrono::microseconds timestamp;
Class log_class;
Level log_level;
std::chrono::microseconds timestamp{};
Class log_class{};
Level log_level{};
std::string filename;
unsigned int line_num;
unsigned int line_num{};
std::string function;
std::string message;
bool final_entry = false;
@@ -141,4 +141,4 @@ const char* GetLevelName(Level log_level);
* never get the message
*/
void SetGlobalFilter(const Filter& filter);
} // namespace Log
} // namespace Log

View File

@@ -29,7 +29,7 @@ struct SpecialRegion {
enum class Type {
DebugHook,
IODevice,
} type;
} type{};
MemoryHookPointer handler;

View File

@@ -38,10 +38,10 @@ void SetCurrentThreadName(const char* name) {
#pragma pack(push, 8)
struct THREADNAME_INFO {
DWORD dwType; // must be 0x1000
LPCSTR szName; // pointer to name (in user addr space)
DWORD dwThreadID; // thread ID (-1=caller thread)
DWORD dwFlags; // reserved for future use, must be zero
DWORD dwType{}; // must be 0x1000
LPCSTR szName; // pointer to name (in user addr space)
DWORD dwThreadID{}; // thread ID (-1=caller thread)
DWORD dwFlags{}; // reserved for future use, must be zero
} info;
#pragma pack(pop)

View File

@@ -18,7 +18,7 @@ struct WebResult {
WrongContent,
NoWebservice,
};
Code result_code;
Code result_code{};
std::string result_string;
std::string returned_data;
};

View File

@@ -17,38 +17,38 @@ enum class CPUVendor {
/// x86/x64 CPU capabilities that may be detected by this module
struct CPUCaps {
CPUVendor vendor;
char cpu_string[0x21];
char brand_string[0x41];
int num_cores;
bool sse;
bool sse2;
bool sse3;
bool ssse3;
bool sse4_1;
bool sse4_2;
bool lzcnt;
bool avx;
bool avx2;
bool bmi1;
bool bmi2;
bool fma;
bool fma4;
bool aes;
CPUVendor vendor{};
char cpu_string[0x21]{};
char brand_string[0x41]{};
int num_cores{};
bool sse{};
bool sse2{};
bool sse3{};
bool ssse3{};
bool sse4_1{};
bool sse4_2{};
bool lzcnt{};
bool avx{};
bool avx2{};
bool bmi1{};
bool bmi2{};
bool fma{};
bool fma4{};
bool aes{};
// Support for the FXSAVE and FXRSTOR instructions
bool fxsave_fxrstor;
bool fxsave_fxrstor{};
bool movbe;
bool movbe{};
// This flag indicates that the hardware supports some mode in which denormal inputs and outputs
// are automatically set to (signed) zero.
bool flush_to_zero;
bool flush_to_zero{};
// Support for LAHF and SAHF instructions in 64-bit mode
bool lahf_sahf_64;
bool lahf_sahf_64{};
bool long_mode;
bool long_mode{};
};
/**

View File

@@ -108,8 +108,6 @@ add_library(core STATIC
file_sys/vfs_offset.h
file_sys/vfs_real.cpp
file_sys/vfs_real.h
file_sys/vfs_ro_layer.cpp
file_sys/vfs_ro_layer.h
file_sys/vfs_static.h
file_sys/vfs_types.h
file_sys/vfs_vector.cpp

View File

@@ -45,17 +45,17 @@ enum class ELFSymbolVisibility : u8 {
};
struct ELFSymbol {
u32 name_index;
u32 name_index{};
union {
u8 info;
u8 info{};
BitField<0, 4, ELFSymbolType> type;
BitField<4, 4, ELFSymbolBinding> binding;
};
ELFSymbolVisibility visibility;
u16 sh_index;
u64 value;
u64 size;
ELFSymbolVisibility visibility{};
u16 sh_index{};
u64 value{};
u64 size{};
};
static_assert(sizeof(ELFSymbol) == 0x18, "ELFSymbol has incorrect size.");

View File

@@ -148,9 +148,9 @@ public:
struct BacktraceEntry {
std::string module;
u64 address;
u64 original_address;
u64 offset;
u64 address{};
u64 original_address{};
u64 offset{};
std::string name;
};

View File

@@ -18,9 +18,9 @@ namespace Core::Timing {
constexpr int MAX_SLICE_LENGTH = 10000;
struct CoreTiming::Event {
s64 time;
u64 fifo_order;
u64 userdata;
s64 time{};
u64 fifo_order{};
u64 userdata{};
const EventType* type;
// Sort by time, unless the times are the same, in which case sort by

View File

@@ -51,9 +51,9 @@ enum class TitleKeyType : u8 {
};
struct TicketData {
std::array<u8, 0x40> issuer;
std::array<u8, 0x40> issuer{};
union {
std::array<u8, 0x100> title_key_block;
std::array<u8, 0x100> title_key_block{};
struct {
Key128 title_key_common;
@@ -61,38 +61,38 @@ struct TicketData {
};
};
INSERT_PADDING_BYTES(0x1);
TitleKeyType type;
INSERT_PADDING_BYTES(0x3);
u8 revision;
INSERT_PADDING_BYTES(0xA);
u64 ticket_id;
u64 device_id;
std::array<u8, 0x10> rights_id;
u32 account_id;
INSERT_PADDING_BYTES(0x14C);
INSERT_PADDING_BYTES(0x1){};
TitleKeyType type{};
INSERT_PADDING_BYTES(0x3){};
u8 revision{};
INSERT_PADDING_BYTES(0xA){};
u64 ticket_id{};
u64 device_id{};
std::array<u8, 0x10> rights_id{};
u32 account_id{};
INSERT_PADDING_BYTES(0x14C){};
};
static_assert(sizeof(TicketData) == 0x2C0, "TicketData has incorrect size.");
struct RSA4096Ticket {
SignatureType sig_type;
std::array<u8, 0x200> sig_data;
INSERT_PADDING_BYTES(0x3C);
TicketData data;
SignatureType sig_type{};
std::array<u8, 0x200> sig_data{};
INSERT_PADDING_BYTES(0x3C){};
TicketData data{};
};
struct RSA2048Ticket {
SignatureType sig_type;
std::array<u8, 0x100> sig_data;
INSERT_PADDING_BYTES(0x3C);
TicketData data;
SignatureType sig_type{};
std::array<u8, 0x100> sig_data{};
INSERT_PADDING_BYTES(0x3C){};
TicketData data{};
};
struct ECDSATicket {
SignatureType sig_type;
std::array<u8, 0x3C> sig_data;
INSERT_PADDING_BYTES(0x40);
TicketData data;
SignatureType sig_type{};
std::array<u8, 0x3C> sig_data{};
INSERT_PADDING_BYTES(0x40){};
TicketData data{};
};
struct Ticket {
@@ -111,10 +111,10 @@ static_assert(sizeof(Key256) == 32, "Key256 must be 256 bytes big.");
template <size_t bit_size, size_t byte_size = (bit_size >> 3)>
struct RSAKeyPair {
std::array<u8, byte_size> encryption_key;
std::array<u8, byte_size> decryption_key;
std::array<u8, byte_size> modulus;
std::array<u8, 4> exponent;
std::array<u8, byte_size> encryption_key{};
std::array<u8, byte_size> decryption_key{};
std::array<u8, byte_size> modulus{};
std::array<u8, 4> exponent{};
};
template <size_t bit_size, size_t byte_size>
@@ -202,9 +202,9 @@ enum class RSAKekType : u8 {
template <typename KeyType>
struct KeyIndex {
KeyType type;
u64 field1;
u64 field2;
KeyType type{};
u64 field1{};
u64 field2{};
std::string DebugInfo() const {
u8 key_size = 16;

View File

@@ -32,18 +32,18 @@ using namespace Common;
namespace Core::Crypto {
struct Package2Header {
std::array<u8, 0x100> signature;
Key128 header_ctr;
std::array<Key128, 4> section_ctr;
u32_le magic;
u32_le base_offset;
INSERT_PADDING_BYTES(4);
u8 version_max;
u8 version_min;
INSERT_PADDING_BYTES(2);
std::array<u32_le, 4> section_size;
std::array<u32_le, 4> section_offset;
std::array<SHA256Hash, 4> section_hash;
std::array<u8, 0x100> signature{};
Key128 header_ctr{};
std::array<Key128, 4> section_ctr{};
u32_le magic{};
u32_le base_offset{};
INSERT_PADDING_BYTES(4){};
u8 version_max{};
u8 version_min{};
INSERT_PADDING_BYTES(2){};
std::array<u32_le, 4> section_size{};
std::array<u32_le, 4> section_offset{};
std::array<SHA256Hash, 4> section_hash{};
};
static_assert(sizeof(Package2Header) == 0x200, "Package2Header has incorrect size.");

View File

@@ -1,202 +0,0 @@
// Copyright 2019 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "core/file_sys/vfs_ro_layer.h"
namespace FileSys {
ReadOnlyVfsFileLayer::ReadOnlyVfsFileLayer(VirtualFile base) : base(std::move(base)) {}
ReadOnlyVfsFileLayer::~ReadOnlyVfsFileLayer() = default;
std::string ReadOnlyVfsFileLayer::GetName() const {
return base->GetName();
}
std::size_t ReadOnlyVfsFileLayer::GetSize() const {
return base->GetSize();
}
bool ReadOnlyVfsFileLayer::Resize(std::size_t new_size) {
return false;
}
std::shared_ptr<VfsDirectory> ReadOnlyVfsFileLayer::GetContainingDirectory() const {
// Make containing read-only to prevent escaping the layer by getting containing and then
// getting this file again.
return std::make_shared<ReadOnlyVfsDirectoryLayer>(base->GetContainingDirectory());
}
bool ReadOnlyVfsFileLayer::IsWritable() const {
return false;
}
bool ReadOnlyVfsFileLayer::IsReadable() const {
return base->IsReadable();
}
std::size_t ReadOnlyVfsFileLayer::Read(u8* data, std::size_t length, std::size_t offset) const {
return base->Read(data, length, offset);
}
std::size_t ReadOnlyVfsFileLayer::Write(const u8* data, std::size_t length, std::size_t offset) {
return 0;
}
bool ReadOnlyVfsFileLayer::Rename(std::string_view name) {
return false;
}
std::string ReadOnlyVfsFileLayer::GetFullPath() const {
return base->GetFullPath();
}
ReadOnlyVfsDirectoryLayer::ReadOnlyVfsDirectoryLayer(VirtualDir base) : base(std::move(base)) {}
ReadOnlyVfsDirectoryLayer::~ReadOnlyVfsDirectoryLayer() = default;
std::vector<std::shared_ptr<VfsFile>> ReadOnlyVfsDirectoryLayer::GetFiles() const {
std::vector<VirtualFile> out;
const auto in = base->GetFiles();
std::transform(in.begin(), in.end(), std::back_inserter(out),
[](const VirtualFile& i) { return std::make_shared<ReadOnlyVfsFileLayer>(i); });
return out;
}
std::vector<std::shared_ptr<VfsDirectory>> ReadOnlyVfsDirectoryLayer::GetSubdirectories() const {
std::vector<VirtualDir> out;
const auto in = base->GetSubdirectories();
std::transform(in.begin(), in.end(), std::back_inserter(out), [](const VirtualDir& i) {
return std::make_shared<ReadOnlyVfsDirectoryLayer>(i);
});
return out;
}
std::string ReadOnlyVfsDirectoryLayer::GetName() const {
return base->GetName();
}
std::shared_ptr<VfsDirectory> ReadOnlyVfsDirectoryLayer::GetParentDirectory() const {
auto out = base->GetParentDirectory();
if (out == nullptr)
return nullptr;
return std::make_shared<ReadOnlyVfsDirectoryLayer>(out);
}
std::shared_ptr<VfsFile> ReadOnlyVfsDirectoryLayer::GetFileRelative(std::string_view path) const {
auto out = base->GetFileRelative(path);
if (out == nullptr)
return nullptr;
return std::make_shared<ReadOnlyVfsFileLayer>(out);
}
std::shared_ptr<VfsFile> ReadOnlyVfsDirectoryLayer::GetFileAbsolute(std::string_view path) const {
auto out = base->GetFileAbsolute(path);
if (out == nullptr)
return nullptr;
return std::make_shared<ReadOnlyVfsFileLayer>(out);
}
std::shared_ptr<VfsDirectory> ReadOnlyVfsDirectoryLayer::GetDirectoryRelative(
std::string_view path) const {
auto out = base->GetDirectoryRelative(path);
if (out == nullptr)
return nullptr;
return std::make_shared<ReadOnlyVfsDirectoryLayer>(out);
}
std::shared_ptr<VfsDirectory> ReadOnlyVfsDirectoryLayer::GetDirectoryAbsolute(
std::string_view path) const {
auto out = base->GetDirectoryAbsolute(path);
if (out == nullptr)
return nullptr;
return std::make_shared<ReadOnlyVfsDirectoryLayer>(out);
}
std::shared_ptr<VfsFile> ReadOnlyVfsDirectoryLayer::GetFile(std::string_view name) const {
auto out = base->GetFile(name);
if (out == nullptr)
return nullptr;
return std::make_shared<ReadOnlyVfsFileLayer>(out);
}
std::shared_ptr<VfsDirectory> ReadOnlyVfsDirectoryLayer::GetSubdirectory(
std::string_view name) const {
auto out = base->GetSubdirectory(name);
if (out == nullptr)
return nullptr;
return std::make_shared<ReadOnlyVfsDirectoryLayer>(out);
}
bool ReadOnlyVfsDirectoryLayer::IsRoot() const {
return base->IsRoot();
}
std::size_t ReadOnlyVfsDirectoryLayer::GetSize() const {
return base->GetSize();
}
bool ReadOnlyVfsDirectoryLayer::Copy(std::string_view src, std::string_view dest) {
return false;
}
std::string ReadOnlyVfsDirectoryLayer::GetFullPath() const {
return base->GetFullPath();
}
bool ReadOnlyVfsDirectoryLayer::IsWritable() const {
return false;
}
bool ReadOnlyVfsDirectoryLayer::IsReadable() const {
return base->IsReadable();
}
std::shared_ptr<VfsDirectory> ReadOnlyVfsDirectoryLayer::CreateSubdirectory(std::string_view name) {
return nullptr;
}
std::shared_ptr<VfsFile> ReadOnlyVfsDirectoryLayer::CreateFile(std::string_view name) {
return nullptr;
}
std::shared_ptr<VfsFile> ReadOnlyVfsDirectoryLayer::CreateFileAbsolute(std::string_view path) {
return nullptr;
}
std::shared_ptr<VfsFile> ReadOnlyVfsDirectoryLayer::CreateFileRelative(std::string_view path) {
return nullptr;
}
std::shared_ptr<VfsDirectory> ReadOnlyVfsDirectoryLayer::CreateDirectoryAbsolute(
std::string_view path) {
return nullptr;
}
std::shared_ptr<VfsDirectory> ReadOnlyVfsDirectoryLayer::CreateDirectoryRelative(
std::string_view path) {
return nullptr;
}
bool ReadOnlyVfsDirectoryLayer::DeleteSubdirectory(std::string_view name) {
return false;
}
bool ReadOnlyVfsDirectoryLayer::DeleteSubdirectoryRecursive(std::string_view name) {
return false;
}
bool ReadOnlyVfsDirectoryLayer::CleanSubdirectoryRecursive(std::string_view name) {
return false;
}
bool ReadOnlyVfsDirectoryLayer::DeleteFile(std::string_view name) {
return false;
}
bool ReadOnlyVfsDirectoryLayer::Rename(std::string_view name) {
return false;
}
} // namespace FileSys

View File

@@ -1,73 +0,0 @@
// Copyright 2019 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <memory>
#include "core/file_sys/vfs.h"
namespace FileSys {
// Class that wraps a VfsFile making it read-only
class ReadOnlyVfsFileLayer : public VfsFile {
public:
explicit ReadOnlyVfsFileLayer(VirtualFile base);
~ReadOnlyVfsFileLayer() override;
std::string GetName() const override;
std::size_t GetSize() const override;
bool Resize(std::size_t new_size) override;
std::shared_ptr<VfsDirectory> GetContainingDirectory() const override;
bool IsWritable() const override;
bool IsReadable() const override;
std::size_t Read(u8* data, std::size_t length, std::size_t offset) const override;
std::size_t Write(const u8* data, std::size_t length, std::size_t offset) override;
bool Rename(std::string_view name) override;
std::string GetFullPath() const override;
private:
VirtualFile base;
};
// Class that wraps a VfsDirectory making it and its children read only.
class ReadOnlyVfsDirectoryLayer : public ReadOnlyVfsDirectory {
public:
explicit ReadOnlyVfsDirectoryLayer(VirtualDir base);
~ReadOnlyVfsDirectoryLayer() override;
std::vector<std::shared_ptr<VfsFile>> GetFiles() const override;
std::vector<std::shared_ptr<VfsDirectory>> GetSubdirectories() const override;
std::string GetName() const override;
std::shared_ptr<VfsDirectory> GetParentDirectory() const override;
std::shared_ptr<VfsFile> GetFileRelative(std::string_view path) const override;
std::shared_ptr<VfsFile> GetFileAbsolute(std::string_view path) const override;
std::shared_ptr<VfsDirectory> GetDirectoryRelative(std::string_view path) const override;
std::shared_ptr<VfsDirectory> GetDirectoryAbsolute(std::string_view path) const override;
std::shared_ptr<VfsFile> GetFile(std::string_view name) const override;
std::shared_ptr<VfsDirectory> GetSubdirectory(std::string_view name) const override;
bool IsRoot() const override;
std::size_t GetSize() const override;
bool Copy(std::string_view src, std::string_view dest) override;
std::string GetFullPath() const override;
bool IsWritable() const override;
bool IsReadable() const override;
std::shared_ptr<VfsDirectory> CreateSubdirectory(std::string_view name) override;
std::shared_ptr<VfsFile> CreateFile(std::string_view name) override;
std::shared_ptr<VfsFile> CreateFileAbsolute(std::string_view path) override;
std::shared_ptr<VfsFile> CreateFileRelative(std::string_view path) override;
std::shared_ptr<VfsDirectory> CreateDirectoryAbsolute(std::string_view path) override;
std::shared_ptr<VfsDirectory> CreateDirectoryRelative(std::string_view path) override;
bool DeleteSubdirectory(std::string_view name) override;
bool DeleteSubdirectoryRecursive(std::string_view name) override;
bool CleanSubdirectoryRecursive(std::string_view name) override;
bool DeleteFile(std::string_view name) override;
bool Rename(std::string_view name) override;
private:
VirtualDir base;
};
} // namespace FileSys

View File

@@ -17,12 +17,12 @@ struct SoftwareKeyboardParameters {
std::u16string sub_text;
std::u16string guide_text;
std::u16string initial_text;
std::size_t max_length;
bool password;
bool cursor_at_beginning;
std::size_t max_length{};
bool password{};
bool cursor_at_beginning{};
union {
u8 value;
u8 value{};
BitField<1, 1, u8> disable_space;
BitField<2, 1, u8> disable_address;

View File

@@ -23,7 +23,7 @@ struct FramebufferLayout {
u32 width{ScreenUndocked::Width};
u32 height{ScreenUndocked::Height};
Common::Rectangle<u32> screen;
Common::Rectangle<u32> screen{};
/**
* Returns the ration of pixel size of the screen, compared to the native size of the undocked

View File

@@ -168,10 +168,10 @@ WSADATA InitData;
#endif
struct Breakpoint {
bool active;
VAddr addr;
u64 len;
std::array<u8, 4> inst;
bool active{};
VAddr addr{};
u64 len{};
std::array<u8, 4> inst{};
};
using BreakpointMap = std::map<VAddr, Breakpoint>;
@@ -181,8 +181,8 @@ BreakpointMap breakpoints_write;
struct Module {
std::string name;
VAddr beg;
VAddr end;
VAddr beg{};
VAddr end{};
};
std::vector<Module> modules;

View File

@@ -22,8 +22,8 @@ enum class BreakpointType {
};
struct BreakpointAddress {
VAddr address;
BreakpointType type;
VAddr address{};
BreakpointType type{};
};
/**

View File

@@ -37,7 +37,7 @@ enum class CommandType : u32 {
struct CommandHeader {
union {
u32_le raw_low;
u32_le raw_low{};
BitField<0, 16, CommandType> type;
BitField<16, 4, u32> num_buf_x_descriptors;
BitField<20, 4, u32> num_buf_a_descriptors;
@@ -52,7 +52,7 @@ struct CommandHeader {
};
union {
u32_le raw_high;
u32_le raw_high{};
BitField<0, 10, u32> data_size;
BitField<10, 4, BufferDescriptorCFlag> buf_c_descriptor_flags;
BitField<31, 1, u32> enable_handle_descriptor;
@@ -77,7 +77,7 @@ struct BufferDescriptorX {
BitField<16, 16, u32> size;
};
u32_le address_bits_0_31;
u32_le address_bits_0_31{};
u32_le Counter() const {
u32_le counter{counter_bits_0_5};
@@ -99,8 +99,8 @@ struct BufferDescriptorX {
static_assert(sizeof(BufferDescriptorX) == 8, "BufferDescriptorX size is incorrect");
struct BufferDescriptorABW {
u32_le size_bits_0_31;
u32_le address_bits_0_31;
u32_le size_bits_0_31{};
u32_le address_bits_0_31{};
union {
BitField<0, 2, u32> flags;
@@ -125,7 +125,7 @@ struct BufferDescriptorABW {
static_assert(sizeof(BufferDescriptorABW) == 12, "BufferDescriptorABW size is incorrect");
struct BufferDescriptorC {
u32_le address_bits_0_31;
u32_le address_bits_0_31{};
union {
BitField<0, 16, u32> address_bits_32_47;
@@ -145,8 +145,8 @@ struct BufferDescriptorC {
static_assert(sizeof(BufferDescriptorC) == 8, "BufferDescriptorC size is incorrect");
struct DataPayloadHeader {
u32_le magic;
INSERT_PADDING_WORDS(1);
u32_le magic{};
INSERT_PADDING_WORDS(1){};
};
static_assert(sizeof(DataPayloadHeader) == 8, "DataPayloadHeader size is incorrect");

View File

@@ -7,7 +7,6 @@
#include "common/assert.h"
#include "core/core.h"
#include "core/core_cpu.h"
#include "core/hle/kernel/errors.h"
#include "core/hle/kernel/handle_table.h"
#include "core/hle/kernel/kernel.h"
@@ -79,7 +78,7 @@ ResultCode Mutex::TryAcquire(VAddr address, Handle holding_thread_handle,
// thread.
ASSERT(requesting_thread == current_thread);
u32 addr_value = Memory::Read32(address);
const u32 addr_value = Memory::Read32(address);
// If the mutex isn't being held, just return success.
if (addr_value != (holding_thread_handle | Mutex::MutexHasWaitersFlag)) {
@@ -90,20 +89,6 @@ ResultCode Mutex::TryAcquire(VAddr address, Handle holding_thread_handle,
return ERR_INVALID_HANDLE;
}
// This a workaround where an unknown bug writes the mutex value to give ownership to a cond var
// waiting thread.
if (holding_thread->GetStatus() == ThreadStatus::WaitCondVar) {
if (holding_thread->GetMutexWaitAddress() == address) {
Release(address, holding_thread.get());
addr_value = Memory::Read32(address);
if (addr_value == 0)
return RESULT_SUCCESS;
else {
holding_thread = handle_table.Get<Thread>(addr_value & Mutex::MutexOwnerMask);
}
}
}
// Wait until the mutex is released
current_thread->SetMutexWaitAddress(address);
current_thread->SetWaitHandle(requesting_thread_handle);
@@ -119,13 +104,14 @@ ResultCode Mutex::TryAcquire(VAddr address, Handle holding_thread_handle,
return RESULT_SUCCESS;
}
ResultCode Mutex::Release(VAddr address, Thread* holding_thread) {
ResultCode Mutex::Release(VAddr address) {
// The mutex address must be 4-byte aligned
if ((address % sizeof(u32)) != 0) {
return ERR_INVALID_ADDRESS;
}
auto [thread, num_waiters] = GetHighestPriorityMutexWaitingThread(holding_thread, address);
auto* const current_thread = system.CurrentScheduler().GetCurrentThread();
auto [thread, num_waiters] = GetHighestPriorityMutexWaitingThread(current_thread, address);
// There are no more threads waiting for the mutex, release it completely.
if (thread == nullptr) {
@@ -134,7 +120,7 @@ ResultCode Mutex::Release(VAddr address, Thread* holding_thread) {
}
// Transfer the ownership of the mutex from the previous owner to the new one.
TransferMutexOwnership(address, holding_thread, thread);
TransferMutexOwnership(address, current_thread, thread);
u32 mutex_value = thread->GetWaitHandle();
@@ -155,10 +141,7 @@ ResultCode Mutex::Release(VAddr address, Thread* holding_thread) {
thread->SetWaitHandle(0);
thread->SetWaitSynchronizationResult(RESULT_SUCCESS);
if (thread->GetProcessorID() >= 0)
system.CpuCore(thread->GetProcessorID()).PrepareReschedule();
if (holding_thread->GetProcessorID() >= 0)
system.CpuCore(holding_thread->GetProcessorID()).PrepareReschedule();
system.PrepareReschedule();
return RESULT_SUCCESS;
}

View File

@@ -29,7 +29,7 @@ public:
Handle requesting_thread_handle);
/// Releases the mutex at the specified address.
ResultCode Release(VAddr address, Thread* holding_thread);
ResultCode Release(VAddr address);
private:
Core::System& system;

View File

@@ -22,9 +22,9 @@
namespace Kernel {
GlobalScheduler::GlobalScheduler(Core::System& system) : system{system} {
is_reselection_pending = false;
}
GlobalScheduler::GlobalScheduler(Core::System& system) : system{system} {}
GlobalScheduler::~GlobalScheduler() = default;
void GlobalScheduler::AddThread(SharedPtr<Thread> thread) {
thread_list.push_back(std::move(thread));
@@ -35,24 +35,11 @@ void GlobalScheduler::RemoveThread(const Thread* thread) {
thread_list.end());
}
/*
* UnloadThread selects a core and forces it to unload its current thread's context
*/
void GlobalScheduler::UnloadThread(s32 core) {
Scheduler& sched = system.Scheduler(core);
sched.UnloadThread();
}
/*
* SelectThread takes care of selecting the new scheduled thread.
* It does it in 3 steps:
* - First a thread is selected from the top of the priority queue. If no thread
* is obtained then we move to step two, else we are done.
* - Second we try to get a suggested thread that's not assigned to any core or
* that is not the top thread in that core.
* - Third is no suggested thread is found, we do a second pass and pick a running
* thread in another core and swap it with its current thread.
*/
void GlobalScheduler::SelectThread(u32 core) {
const auto update_thread = [](Thread* thread, Scheduler& sched) {
if (thread != sched.selected_thread) {
@@ -114,30 +101,19 @@ void GlobalScheduler::SelectThread(u32 core) {
update_thread(current_thread, sched);
}
/*
* YieldThread takes a thread and moves it to the back of the it's priority list
* This operation can be redundant and no scheduling is changed if marked as so.
*/
bool GlobalScheduler::YieldThread(Thread* yielding_thread) {
// Note: caller should use critical section, etc.
const u32 core_id = static_cast<u32>(yielding_thread->GetProcessorID());
const u32 priority = yielding_thread->GetPriority();
// Yield the thread
ASSERT_MSG(yielding_thread == scheduled_queue[core_id].front(priority),
"Thread yielding without being in front");
const Thread* const winner = scheduled_queue[core_id].front(priority);
ASSERT_MSG(yielding_thread == winner, "Thread yielding without being in front");
scheduled_queue[core_id].yield(priority);
Thread* winner = scheduled_queue[core_id].front(priority);
return AskForReselectionOrMarkRedundant(yielding_thread, winner);
}
/*
* YieldThreadAndBalanceLoad takes a thread and moves it to the back of the it's priority list.
* Afterwards, tries to pick a suggested thread from the suggested queue that has worse time or
* a better priority than the next thread in the core.
* This operation can be redundant and no scheduling is changed if marked as so.
*/
bool GlobalScheduler::YieldThreadAndBalanceLoad(Thread* yielding_thread) {
// Note: caller should check if !thread.IsSchedulerOperationRedundant and use critical section,
// etc.
@@ -189,12 +165,6 @@ bool GlobalScheduler::YieldThreadAndBalanceLoad(Thread* yielding_thread) {
return AskForReselectionOrMarkRedundant(yielding_thread, winner);
}
/*
* YieldThreadAndWaitForLoadBalancing takes a thread and moves it out of the scheduling queue
* and into the suggested queue. If no thread can be squeduled afterwards in that core,
* a suggested thread is obtained instead.
* This operation can be redundant and no scheduling is changed if marked as so.
*/
bool GlobalScheduler::YieldThreadAndWaitForLoadBalancing(Thread* yielding_thread) {
// Note: caller should check if !thread.IsSchedulerOperationRedundant and use critical section,
// etc.
@@ -280,7 +250,7 @@ void GlobalScheduler::PreemptThreads() {
if (winner->IsRunning()) {
UnloadThread(winner->GetProcessorID());
}
TransferToCore(winner->GetPriority(), core_id, winner);
TransferToCore(winner->GetPriority(), s32(core_id), winner);
current_thread =
winner->GetPriority() <= current_thread->GetPriority() ? winner : current_thread;
}
@@ -313,7 +283,7 @@ void GlobalScheduler::PreemptThreads() {
if (winner->IsRunning()) {
UnloadThread(winner->GetProcessorID());
}
TransferToCore(winner->GetPriority(), core_id, winner);
TransferToCore(winner->GetPriority(), s32(core_id), winner);
current_thread = winner;
}
}
@@ -331,12 +301,12 @@ void GlobalScheduler::Unsuggest(u32 priority, u32 core, Thread* thread) {
}
void GlobalScheduler::Schedule(u32 priority, u32 core, Thread* thread) {
ASSERT_MSG(thread->GetProcessorID() == core, "Thread must be assigned to this core.");
ASSERT_MSG(thread->GetProcessorID() == s32(core), "Thread must be assigned to this core.");
scheduled_queue[core].add(thread, priority);
}
void GlobalScheduler::SchedulePrepend(u32 priority, u32 core, Thread* thread) {
ASSERT_MSG(thread->GetProcessorID() == core, "Thread must be assigned to this core.");
ASSERT_MSG(thread->GetProcessorID() == s32(core), "Thread must be assigned to this core.");
scheduled_queue[core].add(thread, priority, false);
}
@@ -368,7 +338,8 @@ void GlobalScheduler::TransferToCore(u32 priority, s32 destination_core, Thread*
}
}
bool GlobalScheduler::AskForReselectionOrMarkRedundant(Thread* current_thread, Thread* winner) {
bool GlobalScheduler::AskForReselectionOrMarkRedundant(Thread* current_thread,
const Thread* winner) {
if (current_thread == winner) {
current_thread->IncrementYieldCount();
return true;
@@ -386,8 +357,6 @@ void GlobalScheduler::Shutdown() {
thread_list.clear();
}
GlobalScheduler::~GlobalScheduler() = default;
Scheduler::Scheduler(Core::System& system, Core::ARM_Interface& cpu_core, u32 core_id)
: system(system), cpu_core(cpu_core), core_id(core_id) {}
@@ -470,7 +439,7 @@ void Scheduler::SwitchContext() {
// Load context of new thread
if (new_thread) {
ASSERT_MSG(new_thread->GetProcessorID() == this->core_id,
ASSERT_MSG(new_thread->GetProcessorID() == s32(this->core_id),
"Thread must be assigned to this core.");
ASSERT_MSG(new_thread->GetStatus() == ThreadStatus::Ready,
"Thread must be ready to become running.");

View File

@@ -26,6 +26,7 @@ public:
explicit GlobalScheduler(Core::System& system);
~GlobalScheduler();
/// Adds a new thread to the scheduler
void AddThread(SharedPtr<Thread> thread);
@@ -37,47 +38,57 @@ public:
return thread_list;
}
// Add a thread to the suggested queue of a cpu core. Suggested threads may be
// picked if no thread is scheduled to run on the core.
/**
* Add a thread to the suggested queue of a cpu core. Suggested threads may be
* picked if no thread is scheduled to run on the core.
*/
void Suggest(u32 priority, u32 core, Thread* thread);
// Remove a thread to the suggested queue of a cpu core. Suggested threads may be
// picked if no thread is scheduled to run on the core.
/**
* Remove a thread to the suggested queue of a cpu core. Suggested threads may be
* picked if no thread is scheduled to run on the core.
*/
void Unsuggest(u32 priority, u32 core, Thread* thread);
// Add a thread to the scheduling queue of a cpu core. The thread is added at the
// back the queue in its priority level
/**
* Add a thread to the scheduling queue of a cpu core. The thread is added at the
* back the queue in its priority level.
*/
void Schedule(u32 priority, u32 core, Thread* thread);
// Add a thread to the scheduling queue of a cpu core. The thread is added at the
// front the queue in its priority level
/**
* Add a thread to the scheduling queue of a cpu core. The thread is added at the
* front the queue in its priority level.
*/
void SchedulePrepend(u32 priority, u32 core, Thread* thread);
// Reschedule an already scheduled thread based on a new priority
/// Reschedule an already scheduled thread based on a new priority
void Reschedule(u32 priority, u32 core, Thread* thread);
// Unschedule a thread.
/// Unschedules a thread.
void Unschedule(u32 priority, u32 core, Thread* thread);
// Transfers a thread into an specific core. If the destination_core is -1
// it will be unscheduled from its source code and added into its suggested
// queue.
/**
* Transfers a thread into an specific core. If the destination_core is -1
* it will be unscheduled from its source code and added into its suggested
* queue.
*/
void TransferToCore(u32 priority, s32 destination_core, Thread* thread);
/*
* UnloadThread selects a core and forces it to unload its current thread's context
*/
/// Selects a core and forces it to unload its current thread's context
void UnloadThread(s32 core);
/*
* SelectThread takes care of selecting the new scheduled thread.
* It does it in 3 steps:
* - First a thread is selected from the top of the priority queue. If no thread
* is obtained then we move to step two, else we are done.
* - Second we try to get a suggested thread that's not assigned to any core or
* that is not the top thread in that core.
* - Third is no suggested thread is found, we do a second pass and pick a running
* thread in another core and swap it with its current thread.
/**
* Takes care of selecting the new scheduled thread in three steps:
*
* 1. First a thread is selected from the top of the priority queue. If no thread
* is obtained then we move to step two, else we are done.
*
* 2. Second we try to get a suggested thread that's not assigned to any core or
* that is not the top thread in that core.
*
* 3. Third is no suggested thread is found, we do a second pass and pick a running
* thread in another core and swap it with its current thread.
*/
void SelectThread(u32 core);
@@ -85,33 +96,37 @@ public:
return !scheduled_queue[core_id].empty();
}
/*
* YieldThread takes a thread and moves it to the back of the it's priority list
* This operation can be redundant and no scheduling is changed if marked as so.
/**
* Takes a thread and moves it to the back of the it's priority list.
*
* @note This operation can be redundant and no scheduling is changed if marked as so.
*/
bool YieldThread(Thread* thread);
/*
* YieldThreadAndBalanceLoad takes a thread and moves it to the back of the it's priority list.
/**
* Takes a thread and moves it to the back of the it's priority list.
* Afterwards, tries to pick a suggested thread from the suggested queue that has worse time or
* a better priority than the next thread in the core.
* This operation can be redundant and no scheduling is changed if marked as so.
*
* @note This operation can be redundant and no scheduling is changed if marked as so.
*/
bool YieldThreadAndBalanceLoad(Thread* thread);
/*
* YieldThreadAndWaitForLoadBalancing takes a thread and moves it out of the scheduling queue
* and into the suggested queue. If no thread can be squeduled afterwards in that core,
/**
* Takes a thread and moves it out of the scheduling queue.
* and into the suggested queue. If no thread can be scheduled afterwards in that core,
* a suggested thread is obtained instead.
* This operation can be redundant and no scheduling is changed if marked as so.
*
* @note This operation can be redundant and no scheduling is changed if marked as so.
*/
bool YieldThreadAndWaitForLoadBalancing(Thread* thread);
/*
* PreemptThreads this operation rotates the scheduling queues of threads at
* a preemption priority and then does some core rebalancing. Preemption priorities
* can be found in the array 'preemption_priorities'. This operation happens
* every 10ms.
/**
* Rotates the scheduling queues of threads at a preemption priority and then does
* some core rebalancing. Preemption priorities can be found in the array
* 'preemption_priorities'.
*
* @note This operation happens every 10ms.
*/
void PreemptThreads();
@@ -130,15 +145,15 @@ public:
void Shutdown();
private:
bool AskForReselectionOrMarkRedundant(Thread* current_thread, Thread* winner);
bool AskForReselectionOrMarkRedundant(Thread* current_thread, const Thread* winner);
static constexpr u32 min_regular_priority = 2;
std::array<Common::MultiLevelQueue<Thread*, THREADPRIO_COUNT>, NUM_CPU_CORES> scheduled_queue;
std::array<Common::MultiLevelQueue<Thread*, THREADPRIO_COUNT>, NUM_CPU_CORES> suggested_queue;
std::atomic<bool> is_reselection_pending;
std::atomic<bool> is_reselection_pending{false};
// `preemption_priorities` are the priority levels at which the global scheduler
// preempts threads every 10 ms. They are ordered from Core 0 to Core 3
// The priority levels at which the global scheduler preempts threads every 10 ms. They are
// ordered from Core 0 to Core 3.
std::array<u32, NUM_CPU_CORES> preemption_priorities = {59, 59, 59, 62};
/// Lists all thread ids that aren't deleted/etc.
@@ -181,10 +196,8 @@ public:
private:
friend class GlobalScheduler;
/**
* Switches the CPU's active thread context to that of the specified thread
* @param new_thread The thread to switch to
*/
/// Switches the CPU's active thread context to that of the specified thread
void SwitchContext();
/**

View File

@@ -578,8 +578,7 @@ static ResultCode ArbitrateUnlock(Core::System& system, VAddr mutex_addr) {
}
auto* const current_process = system.Kernel().CurrentProcess();
return current_process->GetMutex().Release(mutex_addr,
system.CurrentScheduler().GetCurrentThread());
return current_process->GetMutex().Release(mutex_addr);
}
enum class BreakType : u32 {
@@ -594,7 +593,7 @@ enum class BreakType : u32 {
struct BreakReason {
union {
u32 raw;
u32 raw{};
BitField<0, 30, BreakType> break_type;
BitField<31, 1, u32> signal_debugger;
};
@@ -1616,14 +1615,12 @@ static ResultCode WaitProcessWideKeyAtomic(Core::System& system, VAddr mutex_add
SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle);
ASSERT(thread);
SharedPtr<Thread> current_thread = system.CurrentScheduler().GetCurrentThread();
const auto release_result =
current_process->GetMutex().Release(mutex_addr, current_thread.get());
const auto release_result = current_process->GetMutex().Release(mutex_addr);
if (release_result.IsError()) {
return release_result;
}
SharedPtr<Thread> current_thread = system.CurrentScheduler().GetCurrentThread();
current_thread->SetCondVarWaitAddress(condition_variable_addr);
current_thread->SetMutexWaitAddress(mutex_addr);
current_thread->SetWaitHandle(thread_handle);
@@ -2350,7 +2347,7 @@ namespace {
struct FunctionDef {
using Func = void(Core::System&);
u32 id;
u32 id{};
Func* func;
const char* name;
};

View File

@@ -23,8 +23,6 @@ SharedPtr<TransferMemory> TransferMemory::Create(KernelCore& kernel, VAddr base_
transfer_memory->owner_permissions = permissions;
transfer_memory->owner_process = kernel.CurrentProcess();
transfer_memory->MapMemory(base_address, size, permissions);
return transfer_memory;
}

View File

@@ -249,18 +249,18 @@ constexpr u32 ToSvcMemoryState(MemoryState state) {
}
struct MemoryInfo {
u64 base_address;
u64 size;
u32 state;
u32 attributes;
u32 permission;
u32 ipc_ref_count;
u32 device_ref_count;
u64 base_address{};
u64 size{};
u32 state{};
u32 attributes{};
u32 permission{};
u32 ipc_ref_count{};
u32 device_ref_count{};
};
static_assert(sizeof(MemoryInfo) == 0x28, "MemoryInfo has incorrect size.");
struct PageInfo {
u32 flags;
u32 flags{};
};
/**

View File

@@ -51,8 +51,17 @@ SharedPtr<Thread> WaitObject::GetHighestPriorityReadyThread() const {
if (ShouldWait(thread.get()))
continue;
candidate = thread.get();
candidate_priority = thread->GetPriority();
// A thread is ready to run if it's either in ThreadStatus::WaitSynch
// and the rest of the objects it is waiting on are ready.
bool ready_to_run = true;
if (thread_status == ThreadStatus::WaitSynch) {
ready_to_run = thread->AllWaitObjectsReady();
}
if (ready_to_run) {
candidate = thread.get();
candidate_priority = thread->GetPriority();
}
}
return candidate;

View File

@@ -44,8 +44,8 @@ public:
};
struct ApplicationInfo {
Service::Glue::ApplicationLaunchProperty launch_property;
ApplicationType application_type;
Service::Glue::ApplicationLaunchProperty launch_property{};
ApplicationType application_type{};
constexpr explicit operator bool() const {
return launch_property.title_id != 0x0;

View File

@@ -16,17 +16,17 @@ namespace Service::Account {
using Common::UUID;
struct UserRaw {
UUID uuid;
UUID uuid2;
u64 timestamp;
ProfileUsername username;
ProfileData extra_data;
UUID uuid{};
UUID uuid2{};
u64 timestamp{};
ProfileUsername username{};
ProfileData extra_data{};
};
static_assert(sizeof(UserRaw) == 0xC8, "UserRaw has incorrect size.");
struct ProfileDataRaw {
INSERT_PADDING_BYTES(0x10);
std::array<UserRaw, MAX_USERS> users;
INSERT_PADDING_BYTES(0x10){};
std::array<UserRaw, MAX_USERS> users{};
};
static_assert(sizeof(ProfileDataRaw) == 0x650, "ProfileDataRaw has incorrect size.");

View File

@@ -22,29 +22,29 @@ using UserIDArray = std::array<Common::UUID, MAX_USERS>;
/// Contains extra data related to a user.
/// TODO: RE this structure
struct ProfileData {
INSERT_PADDING_WORDS(1);
u32 icon_id;
u8 bg_color_id;
INSERT_PADDING_BYTES(0x7);
INSERT_PADDING_BYTES(0x10);
INSERT_PADDING_BYTES(0x60);
INSERT_PADDING_WORDS(1){};
u32 icon_id{};
u8 bg_color_id{};
INSERT_PADDING_BYTES(0x7){};
INSERT_PADDING_BYTES(0x10){};
INSERT_PADDING_BYTES(0x60){};
};
static_assert(sizeof(ProfileData) == 0x80, "ProfileData structure has incorrect size");
/// This holds general information about a users profile. This is where we store all the information
/// based on a specific user
struct ProfileInfo {
Common::UUID user_uuid;
ProfileUsername username;
u64 creation_time;
ProfileData data; // TODO(ognik): Work out what this is
bool is_open;
Common::UUID user_uuid{};
ProfileUsername username{};
u64 creation_time{};
ProfileData data{}; // TODO(ognik): Work out what this is
bool is_open{};
};
struct ProfileBase {
Common::UUID user_uuid;
u64_le timestamp;
ProfileUsername username;
Common::UUID user_uuid{};
u64_le timestamp{};
ProfileUsername username{};
// Zero out all the fields to make the profile slot considered "Empty"
void Invalidate() {

View File

@@ -55,10 +55,10 @@ enum class LaunchParameterKind : u32 {
constexpr u32 LAUNCH_PARAMETER_ACCOUNT_PRESELECTED_USER_MAGIC = 0xC79497CA;
struct LaunchParameterAccountPreselectedUser {
u32_le magic;
u32_le is_account_selected;
u128 current_user;
INSERT_PADDING_BYTES(0x70);
u32_le magic{};
u32_le is_account_selected{};
u128 current_user{};
INSERT_PADDING_BYTES(0x70){};
};
static_assert(sizeof(LaunchParameterAccountPreselectedUser) == 0x88);
@@ -146,8 +146,8 @@ void IAudioController::GetLibraryAppletExpectedMasterVolume(Kernel::HLERequestCo
void IAudioController::ChangeMainAppletMasterVolume(Kernel::HLERequestContext& ctx) {
struct Parameters {
float volume;
s64 fade_time_ns;
float volume{};
s64 fade_time_ns{};
};
static_assert(sizeof(Parameters) == 16);
@@ -398,9 +398,9 @@ void ISelfController::SetFocusHandlingMode(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
struct FocusHandlingModeParams {
u8 unknown0;
u8 unknown1;
u8 unknown2;
u8 unknown0{};
u8 unknown1{};
u8 unknown2{};
};
const auto flags = rp.PopRaw<FocusHandlingModeParams>();
@@ -847,16 +847,17 @@ private:
void PopInteractiveOutData(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_AM, "called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
const auto storage = applet->GetBroker().PopInteractiveDataToGame();
if (storage == nullptr) {
LOG_ERROR(Service_AM,
"storage is a nullptr. There is no data in the current interactive channel");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ERR_NO_DATA_IN_CHANNEL);
return;
}
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IStorage>(std::move(*storage));
}

View File

@@ -27,9 +27,9 @@ AppletDataBroker::AppletDataBroker(Kernel::KernelCore& kernel) {
state_changed_event = Kernel::WritableEvent::CreateEventPair(
kernel, Kernel::ResetType::Manual, "ILibraryAppletAccessor:StateChangedEvent");
pop_out_data_event = Kernel::WritableEvent::CreateEventPair(
kernel, Kernel::ResetType::Automatic, "ILibraryAppletAccessor:PopDataOutEvent");
kernel, Kernel::ResetType::Manual, "ILibraryAppletAccessor:PopDataOutEvent");
pop_interactive_out_data_event = Kernel::WritableEvent::CreateEventPair(
kernel, Kernel::ResetType::Automatic, "ILibraryAppletAccessor:PopInteractiveDataOutEvent");
kernel, Kernel::ResetType::Manual, "ILibraryAppletAccessor:PopInteractiveDataOutEvent");
}
AppletDataBroker::~AppletDataBroker() = default;

View File

@@ -140,12 +140,12 @@ public:
protected:
struct CommonArguments {
u32_le arguments_version;
u32_le size;
u32_le library_version;
u32_le theme_color;
u8 play_startup_sound;
u64_le system_tick;
u32_le arguments_version{};
u32_le size{};
u32_le library_version{};
u32_le theme_color{};
u8 play_startup_sound{};
u64_le system_tick{};
};
static_assert(sizeof(CommonArguments) == 0x20, "CommonArguments has incorrect size.");

View File

@@ -52,12 +52,12 @@ void Auth::Initialize() {
ASSERT(data.size() >= 0xC);
struct Arg {
INSERT_PADDING_BYTES(4);
AuthAppletType type;
u8 arg0;
u8 arg1;
u8 arg2;
INSERT_PADDING_BYTES(1);
INSERT_PADDING_BYTES(4){};
AuthAppletType type{};
u8 arg0{};
u8 arg1{};
u8 arg2{};
INSERT_PADDING_BYTES(1){};
};
static_assert(sizeof(Arg) == 0xC, "Arg (AuthApplet) has incorrect size.");

View File

@@ -21,13 +21,13 @@ struct UserSelectionConfig {
// TODO(DarkLordZach): RE this structure
// It seems to be flags and the like that determine the UI of the applet on the switch... from
// my research this is safe to ignore for now.
INSERT_PADDING_BYTES(0xA0);
INSERT_PADDING_BYTES(0xA0){};
};
static_assert(sizeof(UserSelectionConfig) == 0xA0, "UserSelectionConfig has incorrect size.");
struct UserSelectionOutput {
u64 result;
u128 uuid_selected;
u64 result{};
u128 uuid_selected{};
};
static_assert(sizeof(UserSelectionOutput) == 0x18, "UserSelectionOutput has incorrect size.");

View File

@@ -91,7 +91,6 @@ void SoftwareKeyboard::ExecuteInteractive() {
if (status == INTERACTIVE_STATUS_OK) {
complete = true;
broker.SignalStateChanged();
} else {
std::array<char16_t, SWKBD_OUTPUT_INTERACTIVE_BUFFER_SIZE / 2 - 2> string;
std::memcpy(string.data(), data.data() + 4, string.size() * 2);

View File

@@ -32,28 +32,28 @@ enum class KeysetDisable : u32 {
};
struct KeyboardConfig {
INSERT_PADDING_BYTES(4);
std::array<char16_t, 9> submit_text;
u16_le left_symbol_key;
u16_le right_symbol_key;
INSERT_PADDING_BYTES(1);
KeysetDisable keyset_disable_bitmask;
u32_le initial_cursor_position;
std::array<char16_t, 65> header_text;
std::array<char16_t, 129> sub_text;
std::array<char16_t, 257> guide_text;
u32_le length_limit;
INSERT_PADDING_BYTES(4);
u32_le is_password;
INSERT_PADDING_BYTES(5);
bool utf_8;
bool draw_background;
u32_le initial_string_offset;
u32_le initial_string_size;
u32_le user_dictionary_offset;
u32_le user_dictionary_size;
bool text_check;
u64_le text_check_callback;
INSERT_PADDING_BYTES(4){};
std::array<char16_t, 9> submit_text{};
u16_le left_symbol_key{};
u16_le right_symbol_key{};
INSERT_PADDING_BYTES(1){};
KeysetDisable keyset_disable_bitmask{};
u32_le initial_cursor_position{};
std::array<char16_t, 65> header_text{};
std::array<char16_t, 129> sub_text{};
std::array<char16_t, 257> guide_text{};
u32_le length_limit{};
INSERT_PADDING_BYTES(4){};
u32_le is_password{};
INSERT_PADDING_BYTES(5){};
bool utf_8{};
bool draw_background{};
u32_le initial_string_offset{};
u32_le initial_string_size{};
u32_le user_dictionary_offset{};
u32_le user_dictionary_size{};
bool text_check{};
u64_le text_check_callback{};
};
static_assert(sizeof(KeyboardConfig) == 0x3E0, "KeyboardConfig has incorrect size.");

View File

@@ -117,39 +117,39 @@ namespace {
constexpr std::size_t SHIM_KIND_COUNT = 0x8;
struct WebArgHeader {
u16 count;
INSERT_PADDING_BYTES(2);
ShimKind kind;
u16 count{};
INSERT_PADDING_BYTES(2){};
ShimKind kind{};
};
static_assert(sizeof(WebArgHeader) == 0x8, "WebArgHeader has incorrect size.");
struct WebArgTLV {
WebArgTLVType type;
u16 size;
u32 offset;
WebArgTLVType type{};
u16 size{};
u32 offset{};
};
static_assert(sizeof(WebArgTLV) == 0x8, "WebArgTLV has incorrect size.");
struct WebCommonReturnValue {
u32 result_code;
u32 result_code{};
INSERT_PADDING_BYTES(0x4);
std::array<char, 0x1000> last_url;
u64 last_url_size;
std::array<char, 0x1000> last_url{};
u64 last_url_size{};
};
static_assert(sizeof(WebCommonReturnValue) == 0x1010, "WebCommonReturnValue has incorrect size.");
struct WebWifiPageArg {
INSERT_PADDING_BYTES(4);
std::array<char, 0x100> connection_test_url;
std::array<char, 0x400> initial_url;
std::array<u8, 0x10> nifm_network_uuid;
u32 nifm_requirement;
INSERT_PADDING_BYTES(4){};
std::array<char, 0x100> connection_test_url{};
std::array<char, 0x400> initial_url{};
std::array<u8, 0x10> nifm_network_uuid{};
u32 nifm_requirement{};
};
static_assert(sizeof(WebWifiPageArg) == 0x518, "WebWifiPageArg has incorrect size.");
struct WebWifiReturnValue {
INSERT_PADDING_BYTES(4);
u32 result;
INSERT_PADDING_BYTES(4){};
u32 result{};
};
static_assert(sizeof(WebWifiReturnValue) == 0x8, "WebWifiReturnValue has incorrect size.");
@@ -545,7 +545,8 @@ void WebBrowser::ExecuteShop() {
}
void WebBrowser::ExecuteOffline() {
frontend.OpenPageLocal(filename, [this] { UnpackRomFS(); }, [this] { Finalize(); });
frontend.OpenPageLocal(
filename, [this] { UnpackRomFS(); }, [this] { Finalize(); });
}
} // namespace Service::AM::Applets

View File

@@ -75,7 +75,7 @@ AOC_U::~AOC_U() = default;
void AOC_U::CountAddOnContent(Kernel::HLERequestContext& ctx) {
struct Parameters {
u64 process_id;
u64 process_id{};
};
static_assert(sizeof(Parameters) == 8);
@@ -102,9 +102,9 @@ void AOC_U::CountAddOnContent(Kernel::HLERequestContext& ctx) {
void AOC_U::ListAddOnContent(Kernel::HLERequestContext& ctx) {
struct Parameters {
u32 offset;
u32 count;
u64 process_id;
u32 offset{};
u32 count{};
u64 process_id{};
};
static_assert(sizeof(Parameters) == 16);
@@ -148,7 +148,7 @@ void AOC_U::ListAddOnContent(Kernel::HLERequestContext& ctx) {
void AOC_U::GetAddOnContentBaseId(Kernel::HLERequestContext& ctx) {
struct Parameters {
u64 process_id;
u64 process_id{};
};
static_assert(sizeof(Parameters) == 8);
@@ -174,8 +174,8 @@ void AOC_U::GetAddOnContentBaseId(Kernel::HLERequestContext& ctx) {
void AOC_U::PrepareAddOnContent(Kernel::HLERequestContext& ctx) {
struct Parameters {
s32 addon_index;
u64 process_id;
s32 addon_index{};
u64 process_id{};
};
static_assert(sizeof(Parameters) == 16);

View File

@@ -27,9 +27,9 @@ constexpr std::array<char, 10> DefaultDevice{{"DeviceOut"}};
constexpr int DefaultSampleRate{48000};
struct AudoutParams {
s32_le sample_rate;
u16_le channel_count;
INSERT_PADDING_BYTES(2);
s32_le sample_rate{};
u16_le channel_count{};
INSERT_PADDING_BYTES(2){};
};
static_assert(sizeof(AudoutParams) == 0x8, "AudoutParams is an invalid size");
@@ -75,11 +75,11 @@ public:
private:
struct AudioBuffer {
u64_le next;
u64_le buffer;
u64_le buffer_capacity;
u64_le buffer_size;
u64_le offset;
u64_le next{};
u64_le buffer{};
u64_le buffer_capacity{};
u64_le buffer_size{};
u64_le offset{};
};
static_assert(sizeof(AudioBuffer) == 0x28, "AudioBuffer is an invalid size");
@@ -205,7 +205,7 @@ private:
AudioCore::StreamPtr stream;
std::string device_name;
[[maybe_unused]] AudoutParams audio_params {};
[[maybe_unused]] AudoutParams audio_params{};
/// This is the event handle used to check if the audio buffer was released
Kernel::EventPair buffer_event;

View File

@@ -661,8 +661,8 @@ void AudRenU::OpenAudioRendererAuto(Kernel::HLERequestContext& ctx) {
void AudRenU::GetAudioDeviceServiceWithRevisionInfo(Kernel::HLERequestContext& ctx) {
struct Parameters {
u32 revision;
u64 aruid;
u32 revision{};
u64 aruid{};
};
IPC::RequestParser rp{ctx};

View File

@@ -28,9 +28,9 @@ using OpusDecoderPtr = std::unique_ptr<OpusMSDecoder, OpusDeleter>;
struct OpusPacketHeader {
// Packet size in bytes.
u32_be size;
u32_be size{};
// Indicates the final range of the codec's entropy coder.
u32_be final_range;
u32_be final_range{};
};
static_assert(sizeof(OpusPacketHeader) == 0x8, "OpusHeader is an invalid size");

View File

@@ -31,8 +31,8 @@ using DirectoryGetter = std::function<FileSys::VirtualDir(u64)>;
using Passphrase = std::array<u8, 0x20>;
struct TitleIDVersion {
u64 title_id;
u64 build_id;
u64 title_id{};
u64 build_id{};
};
using DirectoryName = std::array<char, 0x20>;
@@ -49,16 +49,16 @@ struct DeliveryCacheProgressImpl {
Done = 0x9,
};
Status status;
Status status{};
ResultCode result = RESULT_SUCCESS;
DirectoryName current_directory;
FileName current_file;
s64 current_downloaded_bytes; ///< Bytes downloaded on current file.
s64 current_total_bytes; ///< Bytes total on current file.
s64 total_downloaded_bytes; ///< Bytes downloaded on overall download.
s64 total_bytes; ///< Bytes total on overall download.
DirectoryName current_directory{};
FileName current_file{};
s64 current_downloaded_bytes{}; ///< Bytes downloaded on current file.
s64 current_total_bytes{}; ///< Bytes total on current file.
s64 total_downloaded_bytes{}; ///< Bytes downloaded on overall download.
s64 total_bytes{}; ///< Bytes total on overall download.
INSERT_PADDING_BYTES(
0x198); ///< Appears to be unused in official code, possibly reserved for future use.
0x198){}; ///< Appears to be unused in official code, possibly reserved for future use.
};
static_assert(sizeof(DeliveryCacheProgressImpl) == 0x200,
"DeliveryCacheProgressImpl has incorrect size.");

View File

@@ -80,9 +80,9 @@ bool VerifyNameValidFile(Kernel::HLERequestContext& ctx, FileName name) {
} // Anonymous namespace
struct DeliveryCacheDirectoryEntry {
FileName name;
u64 size;
BCATDigest digest;
FileName name{};
u64 size{};
BCATDigest digest{};
};
class IDeliveryCacheProgressService final : public ServiceFramework<IDeliveryCacheProgressService> {

View File

@@ -40,10 +40,7 @@ static FileSys::VirtualDir GetDirectoryRelativeWrapped(FileSys::VirtualDir base,
if (dir_name.empty() || dir_name == "." || dir_name == "/" || dir_name == "\\")
return base;
const auto res = base->GetDirectoryRelative(dir_name);
if (res == nullptr)
return base->CreateDirectoryRelative(dir_name);
return res;
return base->GetDirectoryRelative(dir_name);
}
VfsDirectoryServiceWrapper::VfsDirectoryServiceWrapper(FileSys::VirtualDir backing_)
@@ -725,7 +722,8 @@ void FileSystemController::CreateFactories(FileSys::VfsFilesystem& vfs, bool ove
void InstallInterfaces(Core::System& system) {
std::make_shared<FSP_LDR>()->InstallAsService(system.ServiceManager());
std::make_shared<FSP_PR>()->InstallAsService(system.ServiceManager());
std::make_shared<FSP_SRV>(system)->InstallAsService(system.ServiceManager());
std::make_shared<FSP_SRV>(system.GetFileSystemController(), system.GetReporter())
->InstallAsService(system.ServiceManager());
}
} // namespace Service::FileSystem

View File

@@ -14,22 +14,17 @@
#include "common/hex_util.h"
#include "common/logging/log.h"
#include "common/string_util.h"
#include "core/file_sys/content_archive.h"
#include "core/file_sys/directory.h"
#include "core/file_sys/errors.h"
#include "core/file_sys/mode.h"
#include "core/file_sys/nca_metadata.h"
#include "core/file_sys/patch_manager.h"
#include "core/file_sys/registered_cache.h"
#include "core/file_sys/romfs.h"
#include "core/file_sys/romfs_factory.h"
#include "core/file_sys/savedata_factory.h"
#include "core/file_sys/system_archive/system_archive.h"
#include "core/file_sys/vfs.h"
#include "core/file_sys/vfs_ro_layer.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/process.h"
#include "core/hle/kernel/readable_event.h"
#include "core/hle/service/filesystem/filesystem.h"
#include "core/hle/service/filesystem/fsp_srv.h"
#include "core/reporter.h"
@@ -59,12 +54,6 @@ enum class FileSystemType : u8 {
ApplicationPackage = 7,
};
enum class SaveDataOpenMode {
Normal,
ReadOnly,
System,
};
class IStorage final : public ServiceFramework<IStorage> {
public:
explicit IStorage(FileSys::VirtualFile backend_)
@@ -267,8 +256,8 @@ public:
// TODO(DarkLordZach): Verify that this is the correct behavior.
// Build entry index now to save time later.
BuildEntryIndex(entries, backend->GetFiles(), FileSys::File);
BuildEntryIndex(entries, backend->GetSubdirectories(), FileSys::Directory);
BuildEntryIndex(entries, backend->GetFiles(), FileSys::EntryType::File);
BuildEntryIndex(entries, backend->GetSubdirectories(), FileSys::EntryType::Directory);
}
private:
@@ -514,17 +503,14 @@ private:
class ISaveDataInfoReader final : public ServiceFramework<ISaveDataInfoReader> {
public:
explicit ISaveDataInfoReader(FileSystemController& fsc,
std::vector<FileSys::SaveDataSpaceId> spaces)
explicit ISaveDataInfoReader(FileSys::SaveDataSpaceId space, FileSystemController& fsc)
: ServiceFramework("ISaveDataInfoReader"), fsc(fsc) {
static const FunctionInfo functions[] = {
{0, &ISaveDataInfoReader::ReadSaveDataInfo, "ReadSaveDataInfo"},
};
RegisterHandlers(functions);
for (const auto& space : spaces) {
FindAllSaves(space);
}
FindAllSaves(space);
}
void ReadSaveDataInfo(Kernel::HLERequestContext& ctx) {
@@ -645,17 +631,17 @@ private:
}
struct SaveDataInfo {
u64_le save_id_unknown;
FileSys::SaveDataSpaceId space;
FileSys::SaveDataType type;
INSERT_PADDING_BYTES(0x6);
std::array<u8, 0x10> user_id;
u64_le save_id;
u64_le title_id;
u64_le save_image_size;
u16_le index;
FileSys::SaveDataRank rank;
INSERT_PADDING_BYTES(0x25);
u64_le save_id_unknown{};
FileSys::SaveDataSpaceId space{};
FileSys::SaveDataType type{};
INSERT_PADDING_BYTES(0x6){};
std::array<u8, 0x10> user_id{};
u64_le save_id{};
u64_le title_id{};
u64_le save_image_size{};
u16_le index{};
FileSys::SaveDataRank rank{};
INSERT_PADDING_BYTES(0x25){};
};
static_assert(sizeof(SaveDataInfo) == 0x60, "SaveDataInfo has incorrect size.");
@@ -664,31 +650,8 @@ private:
u64 next_entry_index = 0;
};
class IEventNotifier final : public ServiceFramework<IEventNotifier> {
public:
explicit IEventNotifier(Kernel::SharedPtr<Kernel::ReadableEvent> event)
: ServiceFramework{"IEventNotifier"}, event(std::move(event)) {
static const FunctionInfo functions[] = {
{0, &IEventNotifier::GetEventHandle, "GetEventHandle"},
};
RegisterHandlers(functions);
}
private:
void GetEventHandle(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_FS, "called");
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(event);
}
Kernel::SharedPtr<Kernel::ReadableEvent> event;
};
FSP_SRV::FSP_SRV(Core::System& system)
: ServiceFramework("fsp-srv"), system(system), fsc(system.GetFileSystemController()) {
FSP_SRV::FSP_SRV(FileSystemController& fsc, const Core::Reporter& reporter)
: ServiceFramework("fsp-srv"), fsc(fsc), reporter(reporter) {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "OpenFileSystem"},
@@ -697,15 +660,15 @@ FSP_SRV::FSP_SRV(Core::System& system)
{7, &FSP_SRV::OpenFileSystemWithPatch, "OpenFileSystemWithPatch"},
{8, nullptr, "OpenFileSystemWithId"},
{9, nullptr, "OpenDataFileSystemByApplicationId"},
{11, &FSP_SRV::OpenBisFileSystem, "OpenBisFileSystem"},
{12, &FSP_SRV::OpenBisStorage, "OpenBisStorage"},
{13, &FSP_SRV::InvalidateBisCache, "InvalidateBisCache"},
{11, nullptr, "OpenBisFileSystem"},
{12, nullptr, "OpenBisStorage"},
{13, nullptr, "InvalidateBisCache"},
{17, nullptr, "OpenHostFileSystem"},
{18, &FSP_SRV::OpenSdCardFileSystem, "OpenSdCardFileSystem"},
{19, nullptr, "FormatSdCardFileSystem"},
{21, nullptr, "DeleteSaveDataFileSystem"},
{22, &FSP_SRV::CreateSaveDataFileSystem, "CreateSaveDataFileSystem"},
{23, &FSP_SRV::CreateSaveDataFileSystemBySystemSaveDataId, "CreateSaveDataFileSystemBySystemSaveDataId"},
{23, nullptr, "CreateSaveDataFileSystemBySystemSaveDataId"},
{24, nullptr, "RegisterSaveDataFileSystemAtomicDeletion"},
{25, nullptr, "DeleteSaveDataFileSystemBySaveDataSpaceId"},
{26, nullptr, "FormatSdCardDryRun"},
@@ -718,12 +681,12 @@ FSP_SRV::FSP_SRV(Core::System& system)
{34, nullptr, "GetCacheStorageSize"},
{35, nullptr, "CreateSaveDataFileSystemByHashSalt"},
{51, &FSP_SRV::OpenSaveDataFileSystem, "OpenSaveDataFileSystem"},
{52, &FSP_SRV::OpenSaveDataFileSystemBySystemSaveDataId, "OpenSaveDataFileSystemBySystemSaveDataId"},
{52, nullptr, "OpenSaveDataFileSystemBySystemSaveDataId"},
{53, &FSP_SRV::OpenReadOnlySaveDataFileSystem, "OpenReadOnlySaveDataFileSystem"},
{57, nullptr, "ReadSaveDataFileSystemExtraDataBySaveDataSpaceId"},
{58, nullptr, "ReadSaveDataFileSystemExtraData"},
{59, nullptr, "WriteSaveDataFileSystemExtraData"},
{60, &FSP_SRV::OpenSaveDataInfoReader, "OpenSaveDataInfoReader"},
{60, nullptr, "OpenSaveDataInfoReader"},
{61, &FSP_SRV::OpenSaveDataInfoReaderBySaveDataSpaceId, "OpenSaveDataInfoReaderBySaveDataSpaceId"},
{62, nullptr, "OpenCacheStorageList"},
{64, nullptr, "OpenSaveDataInternalStorageFileSystem"},
@@ -736,8 +699,8 @@ FSP_SRV::FSP_SRV(Core::System& system)
{82, nullptr, "OpenSaveDataTransferManagerVersion2"},
{83, nullptr, "OpenSaveDataTransferProhibiterForCloudBackUp"},
{84, nullptr, "ListApplicationAccessibleSaveDataOwnerId"},
{100, &FSP_SRV::OpenImageDirectoryFileSystem, "OpenImageDirectoryFileSystem"},
{110, &FSP_SRV::OpenContentStorageFileSystem, "OpenContentStorageFileSystem"},
{100, nullptr, "OpenImageDirectoryFileSystem"},
{110, nullptr, "OpenContentStorageFileSystem"},
{120, nullptr, "OpenCloudBackupWorkStorageFileSystem"},
{130, nullptr, "OpenCustomStorageFileSystem"},
{200, &FSP_SRV::OpenDataStorageByCurrentProcess, "OpenDataStorageByCurrentProcess"},
@@ -747,8 +710,8 @@ FSP_SRV::FSP_SRV(Core::System& system)
{204, nullptr, "OpenDataFileSystemByProgramIndex"},
{205, nullptr, "OpenDataStorageByProgramIndex"},
{400, nullptr, "OpenDeviceOperator"},
{500, &FSP_SRV::OpenSdCardDetectionEventNotifier, "OpenSdCardDetectionEventNotifier"},
{501, &FSP_SRV::OpenGameCardDetectionEventNotifier, "OpenGameCardDetectionEventNotifier"},
{500, nullptr, "OpenSdCardDetectionEventNotifier"},
{501, nullptr, "OpenGameCardDetectionEventNotifier"},
{510, nullptr, "OpenSystemDataUpdateEventNotifier"},
{511, nullptr, "NotifySystemDataUpdateEvent"},
{520, nullptr, "SimulateGameCardDetectionEvent"},
@@ -770,7 +733,7 @@ FSP_SRV::FSP_SRV(Core::System& system)
{615, nullptr, "QuerySaveDataInternalStorageTotalSize"},
{616, nullptr, "GetSaveDataCommitId"},
{617, nullptr, "UnregisterExternalKey"},
{620, &FSP_SRV::SetSdCardEncryptionSeed, "SetSdCardEncryptionSeed"},
{620, nullptr, "SetSdCardEncryptionSeed"},
{630, nullptr, "SetSdCardAccessibility"},
{631, nullptr, "IsSdCardAccessible"},
{640, nullptr, "IsSignedSystemPartitionOnSdCardValid"},
@@ -799,12 +762,6 @@ FSP_SRV::FSP_SRV(Core::System& system)
};
// clang-format on
RegisterHandlers(functions);
auto& kernel{system.Kernel()};
sd_card_detection_event = Kernel::WritableEvent::CreateEventPair(
kernel, Kernel::ResetType::Automatic, "fsp-srv:SdCardDetectionEvent");
game_card_detection_event = Kernel::WritableEvent::CreateEventPair(
kernel, Kernel::ResetType::Automatic, "fsp-srv:GameCardDetectionEvent");
}
FSP_SRV::~FSP_SRV() = default;
@@ -824,134 +781,11 @@ void FSP_SRV::OpenFileSystemWithPatch(Kernel::HLERequestContext& ctx) {
const auto type = rp.PopRaw<FileSystemType>();
const auto title_id = rp.PopRaw<u64>();
LOG_DEBUG(Service_FS, "called with type={}, title_id={:016X}", static_cast<u8>(type), title_id);
LOG_WARNING(Service_FS, "(STUBBED) called with type={}, title_id={:016X}",
static_cast<u8>(type), title_id);
const auto& prov{system.GetContentProvider()};
FileSys::PatchManager pm{title_id};
FileSys::ContentRecordType cr_type;
switch (type) {
case FileSystemType::ApplicationPackage:
case FileSystemType::Logo:
cr_type = FileSys::ContentRecordType::Program;
break;
case FileSystemType::ContentControl:
cr_type = FileSys::ContentRecordType::Control;
break;
case FileSystemType::ContentManual:
cr_type = FileSys::ContentRecordType::HtmlDocument;
break;
case FileSystemType::ContentMeta:
cr_type = FileSys::ContentRecordType::Meta;
break;
case FileSystemType::ContentData:
cr_type = FileSys::ContentRecordType::Data;
break;
default:
LOG_WARNING(Service_FS, "called with invalid filesystem type!");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(FileSys::ERROR_INVALID_ARGUMENT);
return;
}
const auto& nca{prov.GetEntry(title_id, cr_type)};
if (nca == nullptr) {
LOG_WARNING(Service_FS, "NCA requested doesn't exist in content provider!");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(FileSys::ERROR_INVALID_ARGUMENT);
return;
}
FileSys::VirtualDir dir;
if (type == FileSystemType::ApplicationPackage) {
dir = nca->GetExeFS();
if (dir != nullptr)
dir = pm.PatchExeFS(dir);
} else if (type == FileSystemType::Logo) {
dir = nca->GetSubdirectories()[1];
} else if (type == FileSystemType::ContentControl || type == FileSystemType::ContentManual ||
type == FileSystemType::ContentData) {
if (nca->GetRomFS() != nullptr) {
const auto romfs = pm.PatchRomFS(nca->GetRomFS(), nca->GetBaseIVFCOffset(), cr_type);
if (romfs != nullptr)
dir = FileSys::ExtractRomFS(romfs);
}
} else {
dir = nca->GetSubdirectories()[0];
}
if (dir == nullptr) {
LOG_WARNING(Service_FS, "couldn't get requested NCA section!");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(FileSys::ERROR_INVALID_ARGUMENT);
return;
}
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface(std::make_shared<IFileSystem>(
dir, SizeGetter::FromStorageId(fsc, FileSys::StorageId::Host)));
}
void FSP_SRV::OpenBisFileSystem(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto partition = rp.PopRaw<FileSys::BisPartitionId>();
LOG_DEBUG(Service_FS, "called with partition_id={:08X}", static_cast<u32>(partition));
auto dir = fsc.OpenBISPartition(partition);
if (dir.Failed()) {
LOG_ERROR(Service_FS,
"Failed to mount BIS filesystem for partition_id={:08X}! Could be invalid "
"argument or uninitialized system.",
static_cast<u32>(partition));
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(dir.Code());
return;
}
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
IFileSystem fs(dir.Unwrap(), SizeGetter::FromStorageId(fsc, FileSys::StorageId::Host));
rb.PushIpcInterface<IFileSystem>(std::move(fs));
}
void FSP_SRV::OpenBisStorage(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto partition = rp.PopRaw<FileSys::BisPartitionId>();
LOG_DEBUG(Service_FS, "called with partition_id={:08X}", static_cast<u32>(partition));
auto file = fsc.OpenBISPartitionStorage(partition);
if (file.Failed()) {
LOG_ERROR(Service_FS,
"Failed to mount BIS storage for partition_id={:08X}! Could be invalid "
"argument or uninitialized system.",
static_cast<u32>(partition));
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(file.Code());
return;
}
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
IStorage fs(file.Unwrap());
rb.PushIpcInterface<IStorage>(std::move(fs));
}
void FSP_SRV::InvalidateBisCache(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_FS, "called");
// Exists for SDK compatibility -- We do not emulate a BIS cache.
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
IPC::ResponseBuilder rb{ctx, 2, 0, 0};
rb.Push(ResultCode(-1));
}
void FSP_SRV::OpenSdCardFileSystem(Kernel::HLERequestContext& ctx) {
@@ -981,103 +815,44 @@ void FSP_SRV::CreateSaveDataFileSystem(Kernel::HLERequestContext& ctx) {
rb.Push(RESULT_SUCCESS);
}
void FSP_SRV::CreateSaveDataFileSystemBySystemSaveDataId(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
auto save_struct = rp.PopRaw<FileSys::SaveDataDescriptor>();
auto save_create_struct = rp.PopRaw<std::array<u8, 0x40>>();
LOG_DEBUG(Service_FS, "called save_struct = {}", save_struct.DebugInfo());
const auto dir = fsc.CreateSaveData(FileSys::SaveDataSpaceId::NandSystem, save_struct);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(dir.Code());
}
namespace {
FileSys::StorageId StorageFromSaveDataSpace(FileSys::SaveDataSpaceId space) {
switch (space) {
case FileSys::SaveDataSpaceId::NandSystem:
case FileSys::SaveDataSpaceId::ProperSystem:
case FileSys::SaveDataSpaceId::TemporaryStorage:
return FileSys::StorageId::NandSystem;
case FileSys::SaveDataSpaceId::NandUser:
return FileSys::StorageId::NandUser;
case FileSys::SaveDataSpaceId::SdCardSystem:
case FileSys::SaveDataSpaceId::SdCardUser:
return FileSys::StorageId::SdCard;
default:
return FileSys::StorageId::None;
}
}
template <SaveDataOpenMode mode>
void OpenSaveDataFileSystemGeneric(Kernel::HLERequestContext& ctx, FileSystemController& fsc) {
IPC::RequestParser rp{ctx};
void FSP_SRV::OpenSaveDataFileSystem(Kernel::HLERequestContext& ctx) {
LOG_INFO(Service_FS, "called.");
struct Parameters {
FileSys::SaveDataSpaceId save_data_space_id;
FileSys::SaveDataDescriptor descriptor;
FileSys::SaveDataSpaceId save_data_space_id{};
FileSys::SaveDataDescriptor descriptor{};
};
IPC::RequestParser rp{ctx};
const auto parameters = rp.PopRaw<Parameters>();
auto dir = fsc.OpenSaveData(parameters.save_data_space_id, parameters.descriptor);
if (dir.Failed()) {
IPC::ResponseBuilder rb{ctx, 2};
IPC::ResponseBuilder rb{ctx, 2, 0, 0};
rb.Push(FileSys::ERROR_ENTITY_NOT_FOUND);
return;
}
auto diru = dir.Unwrap();
if (diru == nullptr) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(FileSys::ERROR_ENTITY_NOT_FOUND);
return;
FileSys::StorageId id;
if (parameters.save_data_space_id == FileSys::SaveDataSpaceId::NandUser) {
id = FileSys::StorageId::NandUser;
} else if (parameters.save_data_space_id == FileSys::SaveDataSpaceId::SdCardSystem ||
parameters.save_data_space_id == FileSys::SaveDataSpaceId::SdCardUser) {
id = FileSys::StorageId::SdCard;
} else {
id = FileSys::StorageId::NandSystem;
}
if constexpr (mode == SaveDataOpenMode::ReadOnly) {
diru = std::make_shared<FileSys::ReadOnlyVfsDirectoryLayer>(diru);
}
IFileSystem filesystem(
std::move(diru),
SizeGetter::FromStorageId(fsc, StorageFromSaveDataSpace(parameters.save_data_space_id)));
IFileSystem filesystem(std::move(dir.Unwrap()), SizeGetter::FromStorageId(fsc, id));
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IFileSystem>(std::move(filesystem));
}
} // namespace
void FSP_SRV::OpenSaveDataFileSystem(Kernel::HLERequestContext& ctx) {
OpenSaveDataFileSystemGeneric<SaveDataOpenMode::Normal>(ctx, fsc);
}
void FSP_SRV::OpenReadOnlySaveDataFileSystem(Kernel::HLERequestContext& ctx) {
OpenSaveDataFileSystemGeneric<SaveDataOpenMode::ReadOnly>(ctx, fsc);
}
void FSP_SRV::OpenSaveDataFileSystemBySystemSaveDataId(Kernel::HLERequestContext& ctx) {
OpenSaveDataFileSystemGeneric<SaveDataOpenMode::System>(ctx, fsc);
}
void FSP_SRV::OpenSaveDataInfoReader(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_FS, "called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<ISaveDataInfoReader>(
std::make_shared<ISaveDataInfoReader>(fsc, std::vector<FileSys::SaveDataSpaceId>{
FileSys::SaveDataSpaceId::NandSystem,
FileSys::SaveDataSpaceId::NandUser,
FileSys::SaveDataSpaceId::TemporaryStorage,
FileSys::SaveDataSpaceId::SdCardUser,
}));
LOG_WARNING(Service_FS, "(STUBBED) called, delegating to 51 OpenSaveDataFilesystem");
OpenSaveDataFileSystem(ctx);
}
void FSP_SRV::OpenSaveDataInfoReaderBySaveDataSpaceId(Kernel::HLERequestContext& ctx) {
@@ -1087,64 +862,7 @@ void FSP_SRV::OpenSaveDataInfoReaderBySaveDataSpaceId(Kernel::HLERequestContext&
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<ISaveDataInfoReader>(
std::make_shared<ISaveDataInfoReader>(fsc, std::vector<FileSys::SaveDataSpaceId>{space}));
}
void FSP_SRV::OpenImageDirectoryFileSystem(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto storage = rp.PopRaw<ImageDirectoryId>();
LOG_DEBUG(Service_FS, "called, storage={:08X}", static_cast<u32>(storage));
auto dir = fsc.GetImageDirectory(storage);
if (dir == nullptr) {
LOG_ERROR(Service_FS, "The image directory requested was invalid!");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(FileSys::ERROR_INVALID_ARGUMENT);
return;
}
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface(std::make_shared<IFileSystem>(
std::move(dir), SizeGetter::FromStorageId(fsc, storage == ImageDirectoryId::NAND
? FileSys::StorageId::NandUser
: FileSys::StorageId::SdCard)));
}
void FSP_SRV::OpenContentStorageFileSystem(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto storage = rp.PopRaw<ContentStorageId>();
LOG_DEBUG(Service_FS, "called, storage={:08X}", static_cast<u32>(storage));
auto dir = fsc.GetContentDirectory(storage);
if (dir == nullptr) {
LOG_ERROR(Service_FS, "The content storage requested was invalid!");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(FileSys::ERROR_INVALID_ARGUMENT);
return;
}
FileSys::StorageId storage_id = FileSys::StorageId::None;
switch (storage) {
case ContentStorageId::SdCard:
storage_id = FileSys::StorageId::SdCard;
break;
case ContentStorageId::User:
storage_id = FileSys::StorageId::NandUser;
break;
case ContentStorageId::System:
storage_id = FileSys::StorageId::NandSystem;
break;
}
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface(
std::make_shared<IFileSystem>(std::move(dir), SizeGetter::FromStorageId(fsc, storage_id)));
rb.PushIpcInterface<ISaveDataInfoReader>(std::make_shared<ISaveDataInfoReader>(space, fsc));
}
void FSP_SRV::SetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) {
@@ -1243,7 +961,7 @@ void FSP_SRV::OutputAccessLogToSdCard(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_FS, "called, log='{}'", log);
system.GetReporter().SaveFilesystemAccessReport(log_mode, std::move(log));
reporter.SaveFilesystemAccessReport(log_mode, std::move(log));
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
@@ -1258,30 +976,4 @@ void FSP_SRV::GetAccessLogVersionInfo(Kernel::HLERequestContext& ctx) {
rb.Push(access_log_program_index);
}
void FSP_SRV::OpenSdCardDetectionEventNotifier(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_FS, "called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface(std::make_shared<IEventNotifier>(sd_card_detection_event.readable));
}
void FSP_SRV::OpenGameCardDetectionEventNotifier(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_FS, "called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface(std::make_shared<IEventNotifier>(game_card_detection_event.readable));
}
void FSP_SRV::SetSdCardEncryptionSeed(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto seed = rp.PopRaw<u128>();
LOG_INFO(Service_FS, "called with seed={:016X}{:016X}", seed[1], seed[0]);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
} // namespace Service::FileSystem

View File

@@ -5,7 +5,6 @@
#pragma once
#include <memory>
#include "core/hle/kernel/writable_event.h"
#include "core/hle/service/service.h"
namespace Core {
@@ -33,25 +32,17 @@ enum class LogMode : u32 {
class FSP_SRV final : public ServiceFramework<FSP_SRV> {
public:
explicit FSP_SRV(Core::System& system);
explicit FSP_SRV(FileSystemController& fsc, const Core::Reporter& reporter);
~FSP_SRV() override;
private:
void SetCurrentProcess(Kernel::HLERequestContext& ctx);
void OpenFileSystemWithPatch(Kernel::HLERequestContext& ctx);
void OpenBisFileSystem(Kernel::HLERequestContext& ctx);
void OpenBisStorage(Kernel::HLERequestContext& ctx);
void InvalidateBisCache(Kernel::HLERequestContext& ctx);
void OpenSdCardFileSystem(Kernel::HLERequestContext& ctx);
void CreateSaveDataFileSystem(Kernel::HLERequestContext& ctx);
void CreateSaveDataFileSystemBySystemSaveDataId(Kernel::HLERequestContext& ctx);
void OpenSaveDataFileSystem(Kernel::HLERequestContext& ctx);
void OpenSaveDataFileSystemBySystemSaveDataId(Kernel::HLERequestContext& ctx);
void OpenReadOnlySaveDataFileSystem(Kernel::HLERequestContext& ctx);
void OpenSaveDataInfoReader(Kernel::HLERequestContext& ctx);
void OpenSaveDataInfoReaderBySaveDataSpaceId(Kernel::HLERequestContext& ctx);
void OpenImageDirectoryFileSystem(Kernel::HLERequestContext& ctx);
void OpenContentStorageFileSystem(Kernel::HLERequestContext& ctx);
void SetGlobalAccessLogMode(Kernel::HLERequestContext& ctx);
void GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx);
void OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx);
@@ -59,11 +50,7 @@ private:
void OpenPatchDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx);
void OutputAccessLogToSdCard(Kernel::HLERequestContext& ctx);
void GetAccessLogVersionInfo(Kernel::HLERequestContext& ctx);
void OpenSdCardDetectionEventNotifier(Kernel::HLERequestContext& ctx);
void OpenGameCardDetectionEventNotifier(Kernel::HLERequestContext& ctx);
void SetSdCardEncryptionSeed(Kernel::HLERequestContext& ctx);
Core::System& system;
FileSystemController& fsc;
FileSys::VirtualFile romfs;
@@ -71,8 +58,7 @@ private:
u32 access_log_program_index = 0;
LogMode log_mode = LogMode::LogToSdCard;
Kernel::EventPair sd_card_detection_event;
Kernel::EventPair game_card_detection_event;
const Core::Reporter& reporter;
};
} // namespace Service::FileSystem

View File

@@ -107,12 +107,12 @@ private:
};
struct SizedFriendFilter {
PresenceFilter presence;
u8 is_favorite;
u8 same_app;
u8 same_app_played;
u8 arbitary_app_played;
u64 group_id;
PresenceFilter presence{};
u8 is_favorite{};
u8 same_app{};
u8 same_app_played{};
u8 arbitary_app_played{};
u64 group_id{};
};
static_assert(sizeof(SizedFriendFilter) == 0x10, "SizedFriendFilter is an invalid size");
@@ -223,17 +223,17 @@ private:
};
struct SizedNotificationInfo {
NotificationTypes notification_type;
NotificationTypes notification_type{};
INSERT_PADDING_WORDS(
1); // TODO(ogniK): This doesn't seem to be used within any IPC returns as of now
u64_le account_id;
1){}; // TODO(ogniK): This doesn't seem to be used within any IPC returns as of now
u64_le account_id{};
};
static_assert(sizeof(SizedNotificationInfo) == 0x10,
"SizedNotificationInfo is an incorrect size");
struct States {
bool has_updated_friends;
bool has_received_friend_request;
bool has_updated_friends{};
bool has_received_friend_request{};
};
Common::UUID uuid;

View File

@@ -8,7 +8,7 @@
namespace Service::Glue {
struct ARPManager::MapEntry {
ApplicationLaunchProperty launch;
ApplicationLaunchProperty launch{};
std::vector<u8> control;
};

View File

@@ -14,12 +14,12 @@
namespace Service::Glue {
struct ApplicationLaunchProperty {
u64 title_id;
u32 version;
FileSys::StorageId base_game_storage_id;
FileSys::StorageId update_storage_id;
u8 program_index;
u8 reserved;
u64 title_id{};
u32 version{};
FileSys::StorageId base_game_storage_id{};
FileSys::StorageId update_storage_id{};
u8 program_index{};
u8 reserved{};
};
static_assert(sizeof(ApplicationLaunchProperty) == 0x10,
"ApplicationLaunchProperty has incorrect size.");

View File

@@ -44,10 +44,10 @@ protected:
bool is_activated{false};
struct CommonHeader {
s64_le timestamp;
s64_le total_entry_count;
s64_le last_entry_index;
s64_le entry_count;
s64_le timestamp{};
s64_le total_entry_count{};
s64_le last_entry_index{};
s64_le entry_count{};
};
static_assert(sizeof(CommonHeader) == 0x20, "CommonHeader is an invalid size");

View File

@@ -33,8 +33,8 @@ public:
private:
struct AnalogStick {
s32_le x;
s32_le y;
s32_le x{};
s32_le y{};
};
static_assert(sizeof(AnalogStick) == 0x8);
@@ -68,19 +68,19 @@ private:
static_assert(sizeof(Attributes) == 0x4, "Attributes is an invalid size");
struct PadStates {
s64_le sampling_number;
s64_le sampling_number2;
Attributes attribute;
PadState pad_state;
AnalogStick r_stick;
AnalogStick l_stick;
s64_le sampling_number{};
s64_le sampling_number2{};
Attributes attribute{};
PadState pad_state{};
AnalogStick r_stick{};
AnalogStick l_stick{};
};
static_assert(sizeof(PadStates) == 0x28, "PadStates is an invalid state");
struct SharedMemory {
CommonHeader header;
std::array<PadStates, 17> pad_states;
INSERT_PADDING_BYTES(0x138);
CommonHeader header{};
std::array<PadStates, 17> pad_states{};
INSERT_PADDING_BYTES(0x138){};
};
static_assert(sizeof(SharedMemory) == 0x400, "SharedMemory is an invalid size");
SharedMemory shared_memory{};

View File

@@ -29,34 +29,34 @@ public:
private:
struct Locations {
s32_le x;
s32_le y;
s32_le x{};
s32_le y{};
};
struct GestureState {
s64_le sampling_number;
s64_le sampling_number2;
s64_le sampling_number{};
s64_le sampling_number2{};
s64_le detection_count;
s32_le type;
s32_le dir;
s32_le x;
s32_le y;
s32_le delta_x;
s32_le delta_y;
f32 vel_x;
f32 vel_y;
s32_le attributes;
f32 scale;
f32 rotation;
s32_le location_count;
std::array<Locations, 4> locations;
s64_le detection_count{};
s32_le type{};
s32_le dir{};
s32_le x{};
s32_le y{};
s32_le delta_x{};
s32_le delta_y{};
f32 vel_x{};
f32 vel_y{};
s32_le attributes{};
f32 scale{};
f32 rotation{};
s32_le location_count{};
std::array<Locations, 4> locations{};
};
static_assert(sizeof(GestureState) == 0x68, "GestureState is an invalid size");
struct SharedMemory {
CommonHeader header;
std::array<GestureState, 17> gesture_states;
CommonHeader header{};
std::array<GestureState, 17> gesture_states{};
};
SharedMemory shared_memory{};
};

View File

@@ -32,19 +32,19 @@ public:
private:
struct KeyboardState {
s64_le sampling_number;
s64_le sampling_number2;
s64_le sampling_number{};
s64_le sampling_number2{};
s32_le modifier;
s32_le attribute;
std::array<u8, 32> key;
s32_le modifier{};
s32_le attribute{};
std::array<u8, 32> key{};
};
static_assert(sizeof(KeyboardState) == 0x38, "KeyboardState is an invalid size");
struct SharedMemory {
CommonHeader header;
std::array<KeyboardState, 17> pad_states;
INSERT_PADDING_BYTES(0x28);
CommonHeader header{};
std::array<KeyboardState, 17> pad_states{};
INSERT_PADDING_BYTES(0x28){};
};
static_assert(sizeof(SharedMemory) == 0x400, "SharedMemory is an invalid size");
SharedMemory shared_memory{};

View File

@@ -31,22 +31,22 @@ public:
private:
struct MouseState {
s64_le sampling_number;
s64_le sampling_number2;
s32_le x;
s32_le y;
s32_le delta_x;
s32_le delta_y;
s32_le mouse_wheel_x;
s32_le mouse_wheel_y;
s32_le button;
s32_le attribute;
s64_le sampling_number{};
s64_le sampling_number2{};
s32_le x{};
s32_le y{};
s32_le delta_x{};
s32_le delta_y{};
s32_le mouse_wheel_x{};
s32_le mouse_wheel_y{};
s32_le button{};
s32_le attribute{};
};
static_assert(sizeof(MouseState) == 0x30, "MouseState is an invalid size");
struct SharedMemory {
CommonHeader header;
std::array<MouseState, 17> mouse_states;
CommonHeader header{};
std::array<MouseState, 17> mouse_states{};
};
SharedMemory shared_memory{};

View File

@@ -51,10 +51,10 @@ public:
static_assert(sizeof(NPadType) == 4, "NPadType is an invalid size");
struct Vibration {
f32 amp_low;
f32 freq_low;
f32 amp_high;
f32 freq_high;
f32 amp_low{};
f32 freq_low{};
f32 amp_high{};
f32 freq_high{};
};
static_assert(sizeof(Vibration) == 0x10, "Vibration is an invalid size");
@@ -138,16 +138,16 @@ public:
private:
struct CommonHeader {
s64_le timestamp;
s64_le total_entry_count;
s64_le last_entry_index;
s64_le entry_count;
s64_le timestamp{};
s64_le total_entry_count{};
s64_le last_entry_index{};
s64_le entry_count{};
};
static_assert(sizeof(CommonHeader) == 0x20, "CommonHeader is an invalid size");
struct ControllerColor {
u32_le body_color;
u32_le button_color;
u32_le body_color{};
u32_le button_color{};
};
static_assert(sizeof(ControllerColor) == 8, "ControllerColor is an invalid size");
@@ -197,8 +197,8 @@ private:
static_assert(sizeof(ControllerPadState) == 8, "ControllerPadState is an invalid size");
struct AnalogPosition {
s32_le x;
s32_le y;
s32_le x{};
s32_le y{};
};
static_assert(sizeof(AnalogPosition) == 8, "AnalogPosition is an invalid size");
@@ -216,23 +216,23 @@ private:
static_assert(sizeof(ConnectionState) == 4, "ConnectionState is an invalid size");
struct ControllerPad {
ControllerPadState pad_states;
AnalogPosition l_stick;
AnalogPosition r_stick;
ControllerPadState pad_states{};
AnalogPosition l_stick{};
AnalogPosition r_stick{};
};
static_assert(sizeof(ControllerPad) == 0x18, "ControllerPad is an invalid size");
struct GenericStates {
s64_le timestamp;
s64_le timestamp2;
ControllerPad pad;
ConnectionState connection_status;
s64_le timestamp{};
s64_le timestamp2{};
ControllerPad pad{};
ConnectionState connection_status{};
};
static_assert(sizeof(GenericStates) == 0x30, "NPadGenericStates is an invalid size");
struct NPadGeneric {
CommonHeader common;
std::array<GenericStates, 17> npad;
CommonHeader common{};
std::array<GenericStates, 17> npad{};
};
static_assert(sizeof(NPadGeneric) == 0x350, "NPadGeneric is an invalid size");
@@ -266,39 +266,39 @@ private:
};
struct NPadEntry {
NPadType joy_styles;
NPadAssignments pad_assignment;
NPadType joy_styles{};
NPadAssignments pad_assignment{};
ColorReadError single_color_error;
ControllerColor single_color;
ColorReadError single_color_error{};
ControllerColor single_color{};
ColorReadError dual_color_error;
ControllerColor left_color;
ControllerColor right_color;
ColorReadError dual_color_error{};
ControllerColor left_color{};
ControllerColor right_color{};
NPadGeneric main_controller_states;
NPadGeneric handheld_states;
NPadGeneric dual_states;
NPadGeneric left_joy_states;
NPadGeneric right_joy_states;
NPadGeneric pokeball_states;
NPadGeneric libnx; // TODO(ogniK): Find out what this actually is, libnx seems to only be
// relying on this for the time being
NPadGeneric main_controller_states{};
NPadGeneric handheld_states{};
NPadGeneric dual_states{};
NPadGeneric left_joy_states{};
NPadGeneric right_joy_states{};
NPadGeneric pokeball_states{};
NPadGeneric libnx{}; // TODO(ogniK): Find out what this actually is, libnx seems to only be
// relying on this for the time being
INSERT_PADDING_BYTES(
0x708 *
6); // TODO(ogniK): SixAxis states, require more information before implementation
NPadDevice device_type;
NPadProperties properties;
INSERT_PADDING_WORDS(1);
std::array<u32, 3> battery_level;
INSERT_PADDING_BYTES(0x5c);
INSERT_PADDING_BYTES(0xdf8);
6){}; // TODO(ogniK): SixAxis states, require more information before implementation
NPadDevice device_type{};
NPadProperties properties{};
INSERT_PADDING_WORDS(1){};
std::array<u32, 3> battery_level{};
INSERT_PADDING_BYTES(0x5c){};
INSERT_PADDING_BYTES(0xdf8){};
};
static_assert(sizeof(NPadEntry) == 0x5000, "NPadEntry is an invalid size");
struct ControllerHolder {
NPadControllerType type;
bool is_connected;
NPadControllerType type{};
bool is_connected{};
};
void InitNewlyAddedControler(std::size_t controller_idx);

View File

@@ -40,29 +40,29 @@ private:
static_assert(sizeof(Attributes) == 0x4, "Attributes is an invalid size");
struct TouchState {
u64_le delta_time;
Attributes attribute;
u32_le finger;
u32_le x;
u32_le y;
u32_le diameter_x;
u32_le diameter_y;
u32_le rotation_angle;
u64_le delta_time{};
Attributes attribute{};
u32_le finger{};
u32_le x{};
u32_le y{};
u32_le diameter_x{};
u32_le diameter_y{};
u32_le rotation_angle{};
};
static_assert(sizeof(TouchState) == 0x28, "Touchstate is an invalid size");
struct TouchScreenEntry {
s64_le sampling_number;
s64_le sampling_number2;
s32_le entry_count;
std::array<TouchState, 16> states;
s64_le sampling_number{};
s64_le sampling_number2{};
s32_le entry_count{};
std::array<TouchState, 16> states{};
};
static_assert(sizeof(TouchScreenEntry) == 0x298, "TouchScreenEntry is an invalid size");
struct TouchScreenSharedMemory {
CommonHeader header;
CommonHeader header{};
std::array<TouchScreenEntry, 17> shared_memory_entries{};
INSERT_PADDING_BYTES(0x3c8);
INSERT_PADDING_BYTES(0x3c8){};
};
static_assert(sizeof(TouchScreenSharedMemory) == 0x3000,
"TouchScreenSharedMemory is an invalid size");

View File

@@ -29,25 +29,25 @@ public:
private:
struct AnalogStick {
s32_le x;
s32_le y;
s32_le x{};
s32_le y{};
};
static_assert(sizeof(AnalogStick) == 0x8, "AnalogStick is an invalid size");
struct XPadState {
s64_le sampling_number;
s64_le sampling_number2;
s32_le attributes;
u32_le pad_states;
AnalogStick x_stick;
AnalogStick y_stick;
s64_le sampling_number{};
s64_le sampling_number2{};
s32_le attributes{};
u32_le pad_states{};
AnalogStick x_stick{};
AnalogStick y_stick{};
};
static_assert(sizeof(XPadState) == 0x28, "XPadState is an invalid size");
struct XPadEntry {
CommonHeader header;
CommonHeader header{};
std::array<XPadState, 17> pad_states{};
INSERT_PADDING_BYTES(0x138);
INSERT_PADDING_BYTES(0x138){};
};
static_assert(sizeof(XPadEntry) == 0x400, "XPadEntry is an invalid size");

View File

@@ -203,13 +203,13 @@ Hid::Hid(Core::System& system) : ServiceFramework("hid"), system(system) {
{120, &Hid::SetNpadJoyHoldType, "SetNpadJoyHoldType"},
{121, &Hid::GetNpadJoyHoldType, "GetNpadJoyHoldType"},
{122, &Hid::SetNpadJoyAssignmentModeSingleByDefault, "SetNpadJoyAssignmentModeSingleByDefault"},
{123, &Hid::SetNpadJoyAssignmentModeSingle, "SetNpadJoyAssignmentModeSingle"},
{123, nullptr, "SetNpadJoyAssignmentModeSingleByDefault"},
{124, &Hid::SetNpadJoyAssignmentModeDual, "SetNpadJoyAssignmentModeDual"},
{125, &Hid::MergeSingleJoyAsDualJoy, "MergeSingleJoyAsDualJoy"},
{126, &Hid::StartLrAssignmentMode, "StartLrAssignmentMode"},
{127, &Hid::StopLrAssignmentMode, "StopLrAssignmentMode"},
{128, &Hid::SetNpadHandheldActivationMode, "SetNpadHandheldActivationMode"},
{129, &Hid::GetNpadHandheldActivationMode, "GetNpadHandheldActivationMode"},
{129, nullptr, "GetNpadHandheldActivationMode"},
{130, &Hid::SwapNpadAssignment, "SwapNpadAssignment"},
{131, nullptr, "IsUnintendedHomeButtonInputProtectionEnabled"},
{132, nullptr, "EnableUnintendedHomeButtonInputProtection"},
@@ -557,126 +557,10 @@ void Hid::SetNpadJoyAssignmentModeSingleByDefault(Kernel::HLERequestContext& ctx
LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}", npad_id,
applet_resource_user_id);
auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
controller.SetNpadMode(npad_id, Controller_NPad::NPadAssignments::Single);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void Hid::SetNpadJoyAssignmentModeSingle(Kernel::HLERequestContext& ctx) {
// TODO: Check the differences between this and SetNpadJoyAssignmentModeSingleByDefault
IPC::RequestParser rp{ctx};
const auto npad_id{rp.Pop<u32>()};
const auto applet_resource_user_id{rp.Pop<u64>()};
const auto npad_joy_device_type{rp.Pop<u64>()};
LOG_WARNING(Service_HID,
"(STUBBED) called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}",
npad_id, applet_resource_user_id, npad_joy_device_type);
auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
controller.SetNpadMode(npad_id, Controller_NPad::NPadAssignments::Single);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void Hid::SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto npad_id{rp.Pop<u32>()};
const auto applet_resource_user_id{rp.Pop<u64>()};
LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", npad_id,
applet_resource_user_id);
auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
controller.SetNpadMode(npad_id, Controller_NPad::NPadAssignments::Dual);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void Hid::MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto unknown_1{rp.Pop<u32>()};
const auto unknown_2{rp.Pop<u32>()};
const auto applet_resource_user_id{rp.Pop<u64>()};
LOG_WARNING(Service_HID,
"(STUBBED) called, unknown_1={}, unknown_2={}, applet_resource_user_id={}",
unknown_1, unknown_2, applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void Hid::StartLrAssignmentMode(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
controller.StartLRAssignmentMode();
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void Hid::StopLrAssignmentMode(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
controller.StopLRAssignmentMode();
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void Hid::SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
const auto mode{rp.Pop<u64>()};
LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}, mode={}",
applet_resource_user_id, mode);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void Hid::GetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}",
applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void Hid::SwapNpadAssignment(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto npad_1{rp.Pop<u32>()};
const auto npad_2{rp.Pop<u32>()};
const auto applet_resource_user_id{rp.Pop<u64>()};
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, npad_1={}, npad_2={}",
applet_resource_user_id, npad_1, npad_2);
auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
IPC::ResponseBuilder rb{ctx, 2};
if (controller.SwapNpadAssignment(npad_1, npad_2)) {
rb.Push(RESULT_SUCCESS);
} else {
LOG_ERROR(Service_HID, "Npads are not connected!");
rb.Push(ERR_NPAD_NOT_CONNECTED);
}
}
void Hid::BeginPermitVibrationSession(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
@@ -751,6 +635,47 @@ void Hid::GetActualVibrationValue(Kernel::HLERequestContext& ctx) {
applet_resource->GetController<Controller_NPad>(HidController::NPad).GetLastVibration());
}
void Hid::SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto npad_id{rp.Pop<u32>()};
const auto applet_resource_user_id{rp.Pop<u64>()};
LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", npad_id,
applet_resource_user_id);
auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
controller.SetNpadMode(npad_id, Controller_NPad::NPadAssignments::Dual);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void Hid::MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto unknown_1{rp.Pop<u32>()};
const auto unknown_2{rp.Pop<u32>()};
const auto applet_resource_user_id{rp.Pop<u64>()};
LOG_WARNING(Service_HID,
"(STUBBED) called, unknown_1={}, unknown_2={}, applet_resource_user_id={}",
unknown_1, unknown_2, applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void Hid::SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
const auto mode{rp.Pop<u64>()};
LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}, mode={}",
applet_resource_user_id, mode);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void Hid::GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_HID, "called");
@@ -844,6 +769,49 @@ void Hid::SetPalmaBoostMode(Kernel::HLERequestContext& ctx) {
rb.Push(RESULT_SUCCESS);
}
void Hid::StartLrAssignmentMode(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
controller.StartLRAssignmentMode();
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void Hid::StopLrAssignmentMode(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
controller.StopLRAssignmentMode();
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void Hid::SwapNpadAssignment(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto npad_1{rp.Pop<u32>()};
const auto npad_2{rp.Pop<u32>()};
const auto applet_resource_user_id{rp.Pop<u64>()};
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, npad_1={}, npad_2={}",
applet_resource_user_id, npad_1, npad_2);
auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
IPC::ResponseBuilder rb{ctx, 2};
if (controller.SwapNpadAssignment(npad_1, npad_2)) {
rb.Push(RESULT_SUCCESS);
} else {
LOG_ERROR(Service_HID, "Npads are not connected!");
rb.Push(ERR_NPAD_NOT_CONNECTED);
}
}
class HidDbg final : public ServiceFramework<HidDbg> {
public:
explicit HidDbg() : ServiceFramework{"hid:dbg"} {

View File

@@ -106,19 +106,14 @@ private:
void SetNpadJoyHoldType(Kernel::HLERequestContext& ctx);
void GetNpadJoyHoldType(Kernel::HLERequestContext& ctx);
void SetNpadJoyAssignmentModeSingleByDefault(Kernel::HLERequestContext& ctx);
void SetNpadJoyAssignmentModeSingle(Kernel::HLERequestContext& ctx);
void SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx);
void MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx);
void StartLrAssignmentMode(Kernel::HLERequestContext& ctx);
void StopLrAssignmentMode(Kernel::HLERequestContext& ctx);
void SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx);
void GetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx);
void SwapNpadAssignment(Kernel::HLERequestContext& ctx);
void BeginPermitVibrationSession(Kernel::HLERequestContext& ctx);
void EndPermitVibrationSession(Kernel::HLERequestContext& ctx);
void SendVibrationValue(Kernel::HLERequestContext& ctx);
void SendVibrationValues(Kernel::HLERequestContext& ctx);
void GetActualVibrationValue(Kernel::HLERequestContext& ctx);
void SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx);
void MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx);
void SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx);
void GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx);
void CreateActiveVibrationDeviceList(Kernel::HLERequestContext& ctx);
void PermitVibration(Kernel::HLERequestContext& ctx);
@@ -128,6 +123,9 @@ private:
void StopSixAxisSensor(Kernel::HLERequestContext& ctx);
void SetIsPalmaAllConnectable(Kernel::HLERequestContext& ctx);
void SetPalmaBoostMode(Kernel::HLERequestContext& ctx);
void StartLrAssignmentMode(Kernel::HLERequestContext& ctx);
void StopLrAssignmentMode(Kernel::HLERequestContext& ctx);
void SwapNpadAssignment(Kernel::HLERequestContext& ctx);
std::shared_ptr<IAppletResource> applet_resource;
Core::System& system;

View File

@@ -10,8 +10,6 @@
#include "core/hle/service/lbl/lbl.h"
#include "core/hle/service/service.h"
#include "core/hle/service/sm/sm.h"
#include "core/settings.h"
#include "video_core/renderer_base.h"
namespace Service::LBL {
@@ -20,21 +18,21 @@ public:
explicit LBL() : ServiceFramework{"lbl"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, &LBL::SaveCurrentSetting, "SaveCurrentSetting"},
{1, &LBL::LoadCurrentSetting, "LoadCurrentSetting"},
{2, &LBL::SetCurrentBrightnessSetting, "SetCurrentBrightnessSetting"},
{3, &LBL::GetCurrentBrightnessSetting, "GetCurrentBrightnessSetting"},
{4, &LBL::ApplyCurrentBrightnessSettingToBacklight, "ApplyCurrentBrightnessSettingToBacklight"},
{5, &LBL::GetBrightnessSettingAppliedToBacklight, "GetBrightnessSettingAppliedToBacklight"},
{6, &LBL::SwitchBacklightOn, "SwitchBacklightOn"},
{7, &LBL::SwitchBacklightOff, "SwitchBacklightOff"},
{8, &LBL::GetBacklightSwitchStatus, "GetBacklightSwitchStatus"},
{9, &LBL::EnableDimming, "EnableDimming"},
{10, &LBL::DisableDimming, "DisableDimming"},
{11, &LBL::IsDimmingEnabled, "IsDimmingEnabled"},
{12, &LBL::EnableAutoBrightnessControl, "EnableAutoBrightnessControl"},
{13, &LBL::DisableAutoBrightnessControl, "DisableAutoBrightnessControl"},
{14, &LBL::IsAutoBrightnessControlEnabled, "IsAutoBrightnessControlEnabled"},
{0, nullptr, "SaveCurrentSetting"},
{1, nullptr, "LoadCurrentSetting"},
{2, nullptr, "SetCurrentBrightnessSetting"},
{3, nullptr, "GetCurrentBrightnessSetting"},
{4, nullptr, "ApplyCurrentBrightnessSettingToBacklight"},
{5, nullptr, "GetBrightnessSettingAppliedToBacklight"},
{6, nullptr, "SwitchBacklightOn"},
{7, nullptr, "SwitchBacklightOff"},
{8, nullptr, "GetBacklightSwitchStatus"},
{9, nullptr, "EnableDimming"},
{10, nullptr, "DisableDimming"},
{11, nullptr, "IsDimmingEnabled"},
{12, nullptr, "EnableAutoBrightnessControl"},
{13, nullptr, "DisableAutoBrightnessControl"},
{14, nullptr, "IsAutoBrightnessControlEnabled"},
{15, nullptr, "SetAmbientLightSensorValue"},
{16, nullptr, "GetAmbientLightSensorValue"},
{17, nullptr, "SetBrightnessReflectionDelayLevel"},
@@ -44,8 +42,8 @@ public:
{21, nullptr, "SetCurrentAmbientLightSensorMapping"},
{22, nullptr, "GetCurrentAmbientLightSensorMapping"},
{23, nullptr, "IsAmbientLightSensorAvailable"},
{24, &LBL::SetCurrentBrightnessSettingForVrMode, "SetCurrentBrightnessSettingForVrMode"},
{25, &LBL::GetCurrentBrightnessSettingForVrMode, "GetCurrentBrightnessSettingForVrMode"},
{24, nullptr, "SetCurrentBrightnessSettingForVrMode"},
{25, nullptr, "GetCurrentBrightnessSettingForVrMode"},
{26, &LBL::EnableVrMode, "EnableVrMode"},
{27, &LBL::DisableVrMode, "DisableVrMode"},
{28, &LBL::IsVrModeEnabled, "IsVrModeEnabled"},
@@ -55,209 +53,13 @@ public:
RegisterHandlers(functions);
}
void LoadFromSettings() {
current_brightness = Settings::values.backlight_brightness;
current_vr_mode_brightness = Settings::values.backlight_brightness;
if (auto_brightness_enabled) {
return;
}
if (vr_mode_enabled) {
Renderer().SetCurrentBrightness(current_vr_mode_brightness);
} else {
Renderer().SetCurrentBrightness(current_brightness);
}
}
private:
f32 GetAutoBrightnessValue() const {
return 0.5f;
}
VideoCore::RendererBase& Renderer() {
return Core::System::GetInstance().Renderer();
}
void SaveCurrentSetting(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_LBL, "called");
Settings::values.backlight_brightness = current_brightness;
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void LoadCurrentSetting(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_LBL, "called");
LoadFromSettings();
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void SetCurrentBrightnessSetting(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto value = rp.PopRaw<f32>();
LOG_DEBUG(Service_LBL, "called, value={:.3f}", value);
current_brightness = std::clamp(value, 0.0f, 1.0f);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void GetCurrentBrightnessSetting(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_LBL, "called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push(current_brightness);
}
void ApplyCurrentBrightnessSettingToBacklight(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_LBL, "called");
if (!auto_brightness_enabled) {
Renderer().SetCurrentBrightness(vr_mode_enabled ? current_vr_mode_brightness
: current_brightness);
}
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void GetBrightnessSettingAppliedToBacklight(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_LBL, "called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push(Renderer().GetCurrentResultantBrightness());
}
void SwitchBacklightOn(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto fade_time = rp.PopRaw<u64>();
LOG_DEBUG(Service_LBL, "called, fade_time={:016X}", fade_time);
Renderer().SetBacklightStatus(true, fade_time);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void SwitchBacklightOff(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto fade_time = rp.PopRaw<u64>();
LOG_DEBUG(Service_LBL, "called, fade_time={:016X}", fade_time);
Renderer().SetBacklightStatus(false, fade_time);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void GetBacklightSwitchStatus(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_LBL, "called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push<u8>(Renderer().GetBacklightStatus());
}
void EnableDimming(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_LBL, "called");
dimming_enabled = true;
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void DisableDimming(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_LBL, "callled");
dimming_enabled = false;
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void IsDimmingEnabled(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_LBL, "called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push<u8>(dimming_enabled);
}
void EnableAutoBrightnessControl(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_LBL, "called");
auto_brightness_enabled = true;
Renderer().SetCurrentBrightness(GetAutoBrightnessValue());
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void DisableAutoBrightnessControl(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_LBL, "called");
auto_brightness_enabled = false;
Renderer().SetCurrentBrightness(current_brightness);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void IsAutoBrightnessControlEnabled(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_LBL, "called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push<u8>(auto_brightness_enabled);
}
void SetCurrentBrightnessSettingForVrMode(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto value = rp.PopRaw<f32>();
LOG_DEBUG(Service_LBL, "called, value={:.3f}", value);
current_vr_mode_brightness = std::clamp(value, 0.0f, 1.0f);
if (vr_mode_enabled && !auto_brightness_enabled) {
Renderer().SetCurrentBrightness(value);
}
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void GetCurrentBrightnessSettingForVrMode(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_LBL, "called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push(current_vr_mode_brightness);
}
void EnableVrMode(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_LBL, "called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
if (!vr_mode_enabled && !auto_brightness_enabled &&
current_brightness != current_vr_mode_brightness) {
Renderer().SetCurrentBrightness(current_vr_mode_brightness);
}
vr_mode_enabled = true;
}
@@ -267,11 +69,6 @@ private:
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
if (vr_mode_enabled && !auto_brightness_enabled &&
current_brightness != current_vr_mode_brightness) {
Renderer().SetCurrentBrightness(current_brightness);
}
vr_mode_enabled = false;
}
@@ -283,27 +80,9 @@ private:
rb.Push(vr_mode_enabled);
}
bool auto_brightness_enabled = false;
bool dimming_enabled = true;
f32 current_brightness = GetAutoBrightnessValue();
f32 current_vr_mode_brightness = GetAutoBrightnessValue();
bool vr_mode_enabled = false;
};
void RequestLoadCurrentSetting(SM::ServiceManager& sm) {
if (&sm == nullptr) {
return;
}
const auto lbl = sm.GetService<LBL>("lbl");
if (lbl) {
lbl->LoadFromSettings();
}
}
void InstallInterfaces(SM::ServiceManager& sm) {
std::make_shared<LBL>()->InstallAsService(sm);
}

View File

@@ -10,9 +10,6 @@ class ServiceManager;
namespace Service::LBL {
// Requests the LBL service passed to load brightness values from Settings
void RequestLoadCurrentSetting(SM::ServiceManager& sm);
void InstallInterfaces(SM::ServiceManager& sm);
} // namespace Service::LBL

View File

@@ -95,9 +95,9 @@ public:
void LoadNrr(Kernel::HLERequestContext& ctx) {
struct Parameters {
u64_le process_id;
u64_le nrr_address;
u64_le nrr_size;
u64_le process_id{};
u64_le nrr_address{};
u64_le nrr_size{};
};
IPC::RequestParser rp{ctx};
@@ -198,8 +198,8 @@ public:
}
struct Parameters {
u64_le process_id;
u64_le nrr_address;
u64_le process_id{};
u64_le nrr_address{};
};
IPC::RequestParser rp{ctx};
@@ -233,11 +233,11 @@ public:
void LoadNro(Kernel::HLERequestContext& ctx) {
struct Parameters {
u64_le process_id;
u64_le image_address;
u64_le image_size;
u64_le bss_address;
u64_le bss_size;
u64_le process_id{};
u64_le image_address{};
u64_le image_size{};
u64_le bss_address{};
u64_le bss_size{};
};
IPC::RequestParser rp{ctx};
@@ -383,8 +383,8 @@ public:
}
struct Parameters {
u64_le process_id;
u64_le nro_address;
u64_le process_id{};
u64_le nro_address{};
};
IPC::RequestParser rp{ctx};
@@ -450,50 +450,50 @@ private:
using SHA256Hash = std::array<u8, 0x20>;
struct NROHeader {
INSERT_PADDING_WORDS(1);
u32_le mod_offset;
INSERT_PADDING_WORDS(2);
u32_le magic;
u32_le version;
u32_le nro_size;
u32_le flags;
u32_le text_offset;
u32_le text_size;
u32_le ro_offset;
u32_le ro_size;
u32_le rw_offset;
u32_le rw_size;
u32_le bss_size;
INSERT_PADDING_WORDS(1);
std::array<u8, 0x20> build_id;
INSERT_PADDING_BYTES(0x20);
INSERT_PADDING_WORDS(1){};
u32_le mod_offset{};
INSERT_PADDING_WORDS(2){};
u32_le magic{};
u32_le version{};
u32_le nro_size{};
u32_le flags{};
u32_le text_offset{};
u32_le text_size{};
u32_le ro_offset{};
u32_le ro_size{};
u32_le rw_offset{};
u32_le rw_size{};
u32_le bss_size{};
INSERT_PADDING_WORDS(1){};
std::array<u8, 0x20> build_id{};
INSERT_PADDING_BYTES(0x20){};
};
static_assert(sizeof(NROHeader) == 0x80, "NROHeader has invalid size.");
struct NRRHeader {
u32_le magic;
INSERT_PADDING_BYTES(12);
u64_le title_id_mask;
u64_le title_id_pattern;
INSERT_PADDING_BYTES(16);
std::array<u8, 0x100> modulus;
std::array<u8, 0x100> signature_1;
std::array<u8, 0x100> signature_2;
u64_le title_id;
u32_le size;
INSERT_PADDING_BYTES(4);
u32_le hash_offset;
u32_le hash_count;
INSERT_PADDING_BYTES(8);
u32_le magic{};
INSERT_PADDING_BYTES(12){};
u64_le title_id_mask{};
u64_le title_id_pattern{};
INSERT_PADDING_BYTES(16){};
std::array<u8, 0x100> modulus{};
std::array<u8, 0x100> signature_1{};
std::array<u8, 0x100> signature_2{};
u64_le title_id{};
u32_le size{};
INSERT_PADDING_BYTES(4){};
u32_le hash_offset{};
u32_le hash_count{};
INSERT_PADDING_BYTES(8){};
};
static_assert(sizeof(NRRHeader) == 0x350, "NRRHeader has incorrect size.");
struct NROInfo {
SHA256Hash hash;
VAddr nro_address;
u64 nro_size;
VAddr bss_address;
u64 bss_size;
SHA256Hash hash{};
VAddr nro_address{};
u64 nro_size{};
VAddr bss_address{};
u64 bss_size{};
};
bool initialized = false;

View File

@@ -38,14 +38,14 @@ struct MessageHeader {
Critical,
};
u64_le pid;
u64_le thread_context;
u64_le pid{};
u64_le thread_context{};
union {
BitField<0, 16, Flags> flags;
BitField<16, 8, Severity> severity;
BitField<24, 8, u32> verbosity;
};
u32_le payload_size;
u32_le payload_size{};
bool IsHeadLog() const {
return flags & IsHead;
@@ -73,8 +73,8 @@ std::ostream& operator<<(std::ostream& os, Field field);
using FieldMap = std::map<Field, std::vector<u8>>;
struct LogMessage {
MessageHeader header;
FieldMap fields;
MessageHeader header{};
FieldMap fields{};
};
std::string FormatField(Field type, const std::vector<u8>& data);

View File

@@ -14,9 +14,9 @@ constexpr std::size_t MAX_MIIS = 100;
constexpr u32 INVALID_INDEX = 0xFFFFFFFF;
struct RandomParameters {
u32 unknown_1;
u32 unknown_2;
u32 unknown_3;
u32 unknown_1{};
u32 unknown_2{};
u32 unknown_3{};
};
static_assert(sizeof(RandomParameters) == 0xC, "RandomParameters has incorrect size.");
@@ -30,58 +30,58 @@ enum class Source : u32 {
std::ostream& operator<<(std::ostream& os, Source source);
struct MiiInfo {
Common::UUID uuid;
std::array<char16_t, 11> name;
u8 font_region;
u8 favorite_color;
u8 gender;
u8 height;
u8 weight;
u8 mii_type;
u8 mii_region;
u8 face_type;
u8 face_color;
u8 face_wrinkle;
u8 face_makeup;
u8 hair_type;
u8 hair_color;
bool hair_flip;
u8 eye_type;
u8 eye_color;
u8 eye_scale;
u8 eye_aspect_ratio;
u8 eye_rotate;
u8 eye_x;
u8 eye_y;
u8 eyebrow_type;
u8 eyebrow_color;
u8 eyebrow_scale;
u8 eyebrow_aspect_ratio;
u8 eyebrow_rotate;
u8 eyebrow_x;
u8 eyebrow_y;
u8 nose_type;
u8 nose_scale;
u8 nose_y;
u8 mouth_type;
u8 mouth_color;
u8 mouth_scale;
u8 mouth_aspect_ratio;
u8 mouth_y;
u8 facial_hair_color;
u8 beard_type;
u8 mustache_type;
u8 mustache_scale;
u8 mustache_y;
u8 glasses_type;
u8 glasses_color;
u8 glasses_scale;
u8 glasses_y;
u8 mole_type;
u8 mole_scale;
u8 mole_x;
u8 mole_y;
INSERT_PADDING_BYTES(1);
Common::UUID uuid{};
std::array<char16_t, 11> name{};
u8 font_region{};
u8 favorite_color{};
u8 gender{};
u8 height{};
u8 weight{};
u8 mii_type{};
u8 mii_region{};
u8 face_type{};
u8 face_color{};
u8 face_wrinkle{};
u8 face_makeup{};
u8 hair_type{};
u8 hair_color{};
bool hair_flip{};
u8 eye_type{};
u8 eye_color{};
u8 eye_scale{};
u8 eye_aspect_ratio{};
u8 eye_rotate{};
u8 eye_x{};
u8 eye_y{};
u8 eyebrow_type{};
u8 eyebrow_color{};
u8 eyebrow_scale{};
u8 eyebrow_aspect_ratio{};
u8 eyebrow_rotate{};
u8 eyebrow_x{};
u8 eyebrow_y{};
u8 nose_type{};
u8 nose_scale{};
u8 nose_y{};
u8 mouth_type{};
u8 mouth_color{};
u8 mouth_scale{};
u8 mouth_aspect_ratio{};
u8 mouth_y{};
u8 facial_hair_color{};
u8 beard_type{};
u8 mustache_type{};
u8 mustache_scale{};
u8 mustache_y{};
u8 glasses_type{};
u8 glasses_color{};
u8 glasses_scale{};
u8 glasses_y{};
u8 mole_type{};
u8 mole_scale{};
u8 mole_x{};
u8 mole_y{};
INSERT_PADDING_BYTES(1){};
std::u16string Name() const;
};
@@ -94,14 +94,14 @@ bool operator!=(const MiiInfo& lhs, const MiiInfo& rhs);
#pragma pack(push, 4)
struct MiiInfoElement {
MiiInfo info;
Source source;
MiiInfo info{};
Source source{};
};
static_assert(sizeof(MiiInfoElement) == 0x5C, "MiiInfoElement has incorrect size.");
struct MiiStoreBitFields {
union {
u32 word_0;
u32 word_0{};
BitField<24, 8, u32> hair_type;
BitField<23, 1, u32> mole_type;
@@ -112,7 +112,7 @@ struct MiiStoreBitFields {
};
union {
u32 word_1;
u32 word_1{};
BitField<31, 1, u32> gender;
BitField<24, 7, u32> eye_color;
@@ -122,7 +122,7 @@ struct MiiStoreBitFields {
};
union {
u32 word_2;
u32 word_2{};
BitField<31, 1, u32> mii_type;
BitField<24, 7, u32> glasses_color;
@@ -135,7 +135,7 @@ struct MiiStoreBitFields {
};
union {
u32 word_3;
u32 word_3{};
BitField<29, 3, u32> mustache_type;
BitField<24, 5, u32> eyebrow_type;
@@ -148,7 +148,7 @@ struct MiiStoreBitFields {
};
union {
u32 word_4;
u32 word_4{};
BitField<29, 3, u32> eye_rotate;
BitField<24, 5, u32> mustache_y;
@@ -160,7 +160,7 @@ struct MiiStoreBitFields {
};
union {
u32 word_5;
u32 word_5{};
BitField<24, 5, u32> glasses_type;
BitField<20, 4, u32> face_type;
@@ -172,7 +172,7 @@ struct MiiStoreBitFields {
};
union {
u32 word_6;
u32 word_6{};
BitField<28, 4, u32> eyebrow_rotate;
BitField<24, 4, u32> eyebrow_scale;
@@ -192,30 +192,30 @@ struct MiiStoreData {
// This corresponds to the above structure MiiStoreBitFields. I did it like this because the
// BitField<> type makes this (and any thing that contains it) not trivially copyable, which is
// not suitable for our uses.
std::array<u8, 0x1C> data;
std::array<u8, 0x1C> data{};
static_assert(sizeof(MiiStoreBitFields) == sizeof(data), "data field has incorrect size.");
std::array<char16_t, 10> name;
Common::UUID uuid;
u16 crc_1;
u16 crc_2;
std::array<char16_t, 10> name{};
Common::UUID uuid{};
u16 crc_1{};
u16 crc_2{};
std::u16string Name() const;
};
static_assert(sizeof(MiiStoreData) == 0x44, "MiiStoreData has incorrect size.");
struct MiiStoreDataElement {
MiiStoreData data;
Source source;
MiiStoreData data{};
Source source{};
};
static_assert(sizeof(MiiStoreDataElement) == 0x48, "MiiStoreDataElement has incorrect size.");
struct MiiDatabase {
u32 magic; // 'NFDB'
std::array<MiiStoreData, MAX_MIIS> miis;
INSERT_PADDING_BYTES(1);
u8 count;
u16 crc;
u32 magic{}; // 'NFDB'
std::array<MiiStoreData, MAX_MIIS> miis{};
INSERT_PADDING_BYTES(1){};
u8 count{};
u16 crc{};
};
static_assert(sizeof(MiiDatabase) == 0x1A98, "MiiDatabase has incorrect size.");
#pragma pack(pop)

View File

@@ -74,13 +74,13 @@ public:
private:
struct TagInfo {
std::array<u8, 10> uuid;
u8 uuid_length; // TODO(ogniK): Figure out if this is actual the uuid length or does it
// mean something else
INSERT_PADDING_BYTES(0x15);
u32_le protocol;
u32_le tag_type;
INSERT_PADDING_BYTES(0x2c);
std::array<u8, 10> uuid{};
u8 uuid_length{}; // TODO(ogniK): Figure out if this is actual the uuid length or does it
// mean something else
INSERT_PADDING_BYTES(0x15){};
u32_le protocol{};
u32_le tag_type{};
INSERT_PADDING_BYTES(0x2c){};
};
static_assert(sizeof(TagInfo) == 0x54, "TagInfo is an invalid size");
@@ -100,13 +100,13 @@ private:
};
struct CommonInfo {
u16_be last_write_year;
u8 last_write_month;
u8 last_write_day;
u16_be write_counter;
u16_be version;
u32_be application_area_size;
INSERT_PADDING_BYTES(0x34);
u16_be last_write_year{};
u8 last_write_month{};
u8 last_write_day{};
u16_be write_counter{};
u16_be version{};
u32_be application_area_size{};
INSERT_PADDING_BYTES(0x34){};
};
static_assert(sizeof(CommonInfo) == 0x40, "CommonInfo is an invalid size");

View File

@@ -20,15 +20,15 @@ public:
~Interface() override;
struct ModelInfo {
std::array<u8, 0x8> amiibo_identification_block;
INSERT_PADDING_BYTES(0x38);
std::array<u8, 0x8> amiibo_identification_block{};
INSERT_PADDING_BYTES(0x38){};
};
static_assert(sizeof(ModelInfo) == 0x40, "ModelInfo is an invalid size");
struct AmiiboFile {
std::array<u8, 10> uuid;
INSERT_PADDING_BYTES(0x4a);
ModelInfo model_info;
std::array<u8, 10> uuid{};
INSERT_PADDING_BYTES(0x4a){};
ModelInfo model_info{};
};
static_assert(sizeof(AmiiboFile) == 0x94, "AmiiboFile is an invalid size");

View File

@@ -9,7 +9,6 @@
#include "core/hle/kernel/writable_event.h"
#include "core/hle/service/nifm/nifm.h"
#include "core/hle/service/service.h"
#include "core/settings.h"
namespace Service::NIFM {
@@ -89,12 +88,7 @@ private:
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
if (Settings::values.bcat_backend == "none") {
rb.PushEnum(RequestState::NotSubmitted);
} else {
rb.PushEnum(RequestState::Connected);
}
rb.PushEnum(RequestState::Connected);
}
void GetResult(Kernel::HLERequestContext& ctx) {
@@ -202,22 +196,14 @@ private:
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
if (Settings::values.bcat_backend == "none") {
rb.Push<u8>(0);
} else {
rb.Push<u8>(1);
}
rb.Push<u8>(1);
}
void IsAnyInternetRequestAccepted(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_NIFM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
if (Settings::values.bcat_backend == "none") {
rb.Push<u8>(0);
} else {
rb.Push<u8>(1);
}
rb.Push<u8>(1);
}
Core::System& system;
};

View File

@@ -35,8 +35,8 @@ enum class FontArchives : u64 {
};
struct FontRegion {
u32 offset;
u32 size;
u32 offset{};
u32 size{};
};
constexpr std::array<std::pair<FontArchives, const char*>, 7> SHARED_FONTS{

View File

@@ -36,80 +36,80 @@ private:
};
struct IoctlInitalizeEx {
u32_le big_page_size; // depends on GPU's available_big_page_sizes; 0=default
s32_le as_fd; // ignored; passes 0
u32_le flags; // passes 0
u32_le reserved; // ignored; passes 0
u64_le unk0;
u64_le unk1;
u64_le unk2;
u32_le big_page_size{}; // depends on GPU's available_big_page_sizes; 0=default
s32_le as_fd{}; // ignored; passes 0
u32_le flags{}; // passes 0
u32_le reserved{}; // ignored; passes 0
u64_le unk0{};
u64_le unk1{};
u64_le unk2{};
};
static_assert(sizeof(IoctlInitalizeEx) == 40, "IoctlInitalizeEx is incorrect size");
struct IoctlAllocSpace {
u32_le pages;
u32_le page_size;
u32_le flags;
INSERT_PADDING_WORDS(1);
u32_le pages{};
u32_le page_size{};
u32_le flags{};
INSERT_PADDING_WORDS(1){};
union {
u64_le offset;
u64_le offset{};
u64_le align;
};
};
static_assert(sizeof(IoctlAllocSpace) == 24, "IoctlInitalizeEx is incorrect size");
struct IoctlRemapEntry {
u16_le flags;
u16_le kind;
u32_le nvmap_handle;
INSERT_PADDING_WORDS(1);
u32_le offset;
u32_le pages;
u16_le flags{};
u16_le kind{};
u32_le nvmap_handle{};
INSERT_PADDING_WORDS(1){};
u32_le offset{};
u32_le pages{};
};
static_assert(sizeof(IoctlRemapEntry) == 20, "IoctlRemapEntry is incorrect size");
struct IoctlMapBufferEx {
u32_le flags; // bit0: fixed_offset, bit2: cacheable
u32_le kind; // -1 is default
u32_le nvmap_handle;
u32_le page_size; // 0 means don't care
u64_le buffer_offset;
u64_le mapping_size;
u64_le offset;
u32_le flags{}; // bit0: fixed_offset, bit2: cacheable
u32_le kind{}; // -1 is default
u32_le nvmap_handle{};
u32_le page_size{}; // 0 means don't care
u64_le buffer_offset{};
u64_le mapping_size{};
u64_le offset{};
};
static_assert(sizeof(IoctlMapBufferEx) == 40, "IoctlMapBufferEx is incorrect size");
struct IoctlUnmapBuffer {
u64_le offset;
u64_le offset{};
};
static_assert(sizeof(IoctlUnmapBuffer) == 8, "IoctlUnmapBuffer is incorrect size");
struct IoctlBindChannel {
u32_le fd;
u32_le fd{};
};
static_assert(sizeof(IoctlBindChannel) == 4, "IoctlBindChannel is incorrect size");
struct IoctlVaRegion {
u64_le offset;
u32_le page_size;
INSERT_PADDING_WORDS(1);
u64_le pages;
u64_le offset{};
u32_le page_size{};
INSERT_PADDING_WORDS(1){};
u64_le pages{};
};
static_assert(sizeof(IoctlVaRegion) == 24, "IoctlVaRegion is incorrect size");
struct IoctlGetVaRegions {
u64_le buf_addr; // (contained output user ptr on linux, ignored)
u32_le buf_size; // forced to 2*sizeof(struct va_region)
u32_le reserved;
IoctlVaRegion regions[2];
u64_le buf_addr{}; // (contained output user ptr on linux, ignored)
u32_le buf_size{}; // forced to 2*sizeof(struct va_region)
u32_le reserved{};
IoctlVaRegion regions[2]{};
};
static_assert(sizeof(IoctlGetVaRegions) == 16 + sizeof(IoctlVaRegion) * 2,
"IoctlGetVaRegions is incorrect size");
struct BufferMapping {
u64 offset;
u64 size;
u32 nvmap_handle;
u64 offset{};
u64 size{};
u32 nvmap_handle{};
};
/// Map containing the nvmap object mappings in GPU memory.

View File

@@ -39,97 +39,97 @@ private:
IocCtrlEventKillCommand = 0x40080021,
};
struct IocSyncptReadParams {
u32_le id;
u32_le value;
u32_le id{};
u32_le value{};
};
static_assert(sizeof(IocSyncptReadParams) == 8, "IocSyncptReadParams is incorrect size");
struct IocSyncptIncrParams {
u32_le id;
u32_le id{};
};
static_assert(sizeof(IocSyncptIncrParams) == 4, "IocSyncptIncrParams is incorrect size");
struct IocSyncptWaitParams {
u32_le id;
u32_le thresh;
s32_le timeout;
u32_le id{};
u32_le thresh{};
s32_le timeout{};
};
static_assert(sizeof(IocSyncptWaitParams) == 12, "IocSyncptWaitParams is incorrect size");
struct IocModuleMutexParams {
u32_le id;
u32_le lock; // (0 = unlock and 1 = lock)
u32_le id{};
u32_le lock{}; // (0 = unlock and 1 = lock)
};
static_assert(sizeof(IocModuleMutexParams) == 8, "IocModuleMutexParams is incorrect size");
struct IocModuleRegRDWRParams {
u32_le id;
u32_le num_offsets;
u32_le block_size;
u32_le offsets;
u32_le values;
u32_le write;
u32_le id{};
u32_le num_offsets{};
u32_le block_size{};
u32_le offsets{};
u32_le values{};
u32_le write{};
};
static_assert(sizeof(IocModuleRegRDWRParams) == 24, "IocModuleRegRDWRParams is incorrect size");
struct IocSyncptWaitexParams {
u32_le id;
u32_le thresh;
s32_le timeout;
u32_le value;
u32_le id{};
u32_le thresh{};
s32_le timeout{};
u32_le value{};
};
static_assert(sizeof(IocSyncptWaitexParams) == 16, "IocSyncptWaitexParams is incorrect size");
struct IocSyncptReadMaxParams {
u32_le id;
u32_le value;
u32_le id{};
u32_le value{};
};
static_assert(sizeof(IocSyncptReadMaxParams) == 8, "IocSyncptReadMaxParams is incorrect size");
struct IocGetConfigParams {
std::array<char, 0x41> domain_str;
std::array<char, 0x41> param_str;
std::array<char, 0x101> config_str;
std::array<char, 0x41> domain_str{};
std::array<char, 0x41> param_str{};
std::array<char, 0x101> config_str{};
};
static_assert(sizeof(IocGetConfigParams) == 387, "IocGetConfigParams is incorrect size");
struct IocCtrlEventSignalParams {
u32_le user_event_id;
u32_le user_event_id{};
};
static_assert(sizeof(IocCtrlEventSignalParams) == 4,
"IocCtrlEventSignalParams is incorrect size");
struct IocCtrlEventWaitParams {
u32_le syncpt_id;
u32_le threshold;
s32_le timeout;
u32_le value;
u32_le syncpt_id{};
u32_le threshold{};
s32_le timeout{};
u32_le value{};
};
static_assert(sizeof(IocCtrlEventWaitParams) == 16, "IocCtrlEventWaitParams is incorrect size");
struct IocCtrlEventWaitAsyncParams {
u32_le syncpt_id;
u32_le threshold;
u32_le timeout;
u32_le value;
u32_le syncpt_id{};
u32_le threshold{};
u32_le timeout{};
u32_le value{};
};
static_assert(sizeof(IocCtrlEventWaitAsyncParams) == 16,
"IocCtrlEventWaitAsyncParams is incorrect size");
struct IocCtrlEventRegisterParams {
u32_le user_event_id;
u32_le user_event_id{};
};
static_assert(sizeof(IocCtrlEventRegisterParams) == 4,
"IocCtrlEventRegisterParams is incorrect size");
struct IocCtrlEventUnregisterParams {
u32_le user_event_id;
u32_le user_event_id{};
};
static_assert(sizeof(IocCtrlEventUnregisterParams) == 4,
"IocCtrlEventUnregisterParams is incorrect size");
struct IocCtrlEventKill {
u64_le user_events;
u64_le user_events{};
};
static_assert(sizeof(IocCtrlEventKill) == 8, "IocCtrlEventKill is incorrect size");

View File

@@ -43,50 +43,50 @@ private:
};
struct IoctlGpuCharacteristics {
u32_le arch; // 0x120 (NVGPU_GPU_ARCH_GM200)
u32_le impl; // 0xB (NVGPU_GPU_IMPL_GM20B)
u32_le rev; // 0xA1 (Revision A1)
u32_le num_gpc; // 0x1
u64_le l2_cache_size; // 0x40000
u64_le on_board_video_memory_size; // 0x0 (not used)
u32_le num_tpc_per_gpc; // 0x2
u32_le bus_type; // 0x20 (NVGPU_GPU_BUS_TYPE_AXI)
u32_le big_page_size; // 0x20000
u32_le compression_page_size; // 0x20000
u32_le pde_coverage_bit_count; // 0x1B
u32_le available_big_page_sizes; // 0x30000
u32_le gpc_mask; // 0x1
u32_le sm_arch_sm_version; // 0x503 (Maxwell Generation 5.0.3?)
u32_le sm_arch_spa_version; // 0x503 (Maxwell Generation 5.0.3?)
u32_le sm_arch_warp_count; // 0x80
u32_le gpu_va_bit_count; // 0x28
u32_le reserved; // NULL
u64_le flags; // 0x55
u32_le twod_class; // 0x902D (FERMI_TWOD_A)
u32_le threed_class; // 0xB197 (MAXWELL_B)
u32_le compute_class; // 0xB1C0 (MAXWELL_COMPUTE_B)
u32_le gpfifo_class; // 0xB06F (MAXWELL_CHANNEL_GPFIFO_A)
u32_le inline_to_memory_class; // 0xA140 (KEPLER_INLINE_TO_MEMORY_B)
u32_le dma_copy_class; // 0xB0B5 (MAXWELL_DMA_COPY_A)
u32_le max_fbps_count; // 0x1
u32_le fbp_en_mask; // 0x0 (disabled)
u32_le max_ltc_per_fbp; // 0x2
u32_le max_lts_per_ltc; // 0x1
u32_le max_tex_per_tpc; // 0x0 (not supported)
u32_le max_gpc_count; // 0x1
u32_le rop_l2_en_mask_0; // 0x21D70 (fuse_status_opt_rop_l2_fbp_r)
u32_le rop_l2_en_mask_1; // 0x0
u64_le chipname; // 0x6230326D67 ("gm20b")
u64_le gr_compbit_store_base_hw; // 0x0 (not supported)
u32_le arch{}; // 0x120 (NVGPU_GPU_ARCH_GM200)
u32_le impl{}; // 0xB (NVGPU_GPU_IMPL_GM20B)
u32_le rev{}; // 0xA1 (Revision A1)
u32_le num_gpc{}; // 0x1
u64_le l2_cache_size{}; // 0x40000
u64_le on_board_video_memory_size{}; // 0x0 (not used)
u32_le num_tpc_per_gpc{}; // 0x2
u32_le bus_type{}; // 0x20 (NVGPU_GPU_BUS_TYPE_AXI)
u32_le big_page_size{}; // 0x20000
u32_le compression_page_size{}; // 0x20000
u32_le pde_coverage_bit_count{}; // 0x1B
u32_le available_big_page_sizes{}; // 0x30000
u32_le gpc_mask{}; // 0x1
u32_le sm_arch_sm_version{}; // 0x503 (Maxwell Generation 5.0.3?)
u32_le sm_arch_spa_version{}; // 0x503 (Maxwell Generation 5.0.3?)
u32_le sm_arch_warp_count{}; // 0x80
u32_le gpu_va_bit_count{}; // 0x28
u32_le reserved{}; // NULL
u64_le flags{}; // 0x55
u32_le twod_class{}; // 0x902D (FERMI_TWOD_A)
u32_le threed_class{}; // 0xB197 (MAXWELL_B)
u32_le compute_class{}; // 0xB1C0 (MAXWELL_COMPUTE_B)
u32_le gpfifo_class{}; // 0xB06F (MAXWELL_CHANNEL_GPFIFO_A)
u32_le inline_to_memory_class{}; // 0xA140 (KEPLER_INLINE_TO_MEMORY_B)
u32_le dma_copy_class{}; // 0xB0B5 (MAXWELL_DMA_COPY_A)
u32_le max_fbps_count{}; // 0x1
u32_le fbp_en_mask{}; // 0x0 (disabled)
u32_le max_ltc_per_fbp{}; // 0x2
u32_le max_lts_per_ltc{}; // 0x1
u32_le max_tex_per_tpc{}; // 0x0 (not supported)
u32_le max_gpc_count{}; // 0x1
u32_le rop_l2_en_mask_0{}; // 0x21D70 (fuse_status_opt_rop_l2_fbp_r)
u32_le rop_l2_en_mask_1{}; // 0x0
u64_le chipname{}; // 0x6230326D67 ("gm20b")
u64_le gr_compbit_store_base_hw{}; // 0x0 (not supported)
};
static_assert(sizeof(IoctlGpuCharacteristics) == 160,
"IoctlGpuCharacteristics is incorrect size");
struct IoctlCharacteristics {
u64_le gpu_characteristics_buf_size; // must not be NULL, but gets overwritten with
// 0xA0=max_size
u64_le gpu_characteristics_buf_addr; // ignored, but must not be NULL
IoctlGpuCharacteristics gc;
u64_le gpu_characteristics_buf_size{}; // must not be NULL, but gets overwritten with
// 0xA0=max_size
u64_le gpu_characteristics_buf_addr{}; // ignored, but must not be NULL
IoctlGpuCharacteristics gc{};
};
static_assert(sizeof(IoctlCharacteristics) == 16 + sizeof(IoctlGpuCharacteristics),
"IoctlCharacteristics is incorrect size");
@@ -95,71 +95,71 @@ private:
/// [in] TPC mask buffer size reserved by userspace. Should be at least
/// sizeof(__u32) * fls(gpc_mask) to receive TPC mask for each GPC.
/// [out] full kernel buffer size
u32_le mask_buf_size;
u32_le reserved;
u32_le mask_buf_size{};
u32_le reserved{};
/// [in] pointer to TPC mask buffer. It will receive one 32-bit TPC mask per GPC or 0 if
/// GPC is not enabled or not present. This parameter is ignored if mask_buf_size is 0.
u64_le mask_buf_addr;
u64_le tpc_mask_size; // Nintendo add this?
u64_le mask_buf_addr{};
u64_le tpc_mask_size{}; // Nintendo add this?
};
static_assert(sizeof(IoctlGpuGetTpcMasksArgs) == 24,
"IoctlGpuGetTpcMasksArgs is incorrect size");
struct IoctlActiveSlotMask {
u32_le slot; // always 0x07
u32_le mask;
u32_le slot{}; // always 0x07
u32_le mask{};
};
static_assert(sizeof(IoctlActiveSlotMask) == 8, "IoctlActiveSlotMask is incorrect size");
struct IoctlZcullGetCtxSize {
u32_le size;
u32_le size{};
};
static_assert(sizeof(IoctlZcullGetCtxSize) == 4, "IoctlZcullGetCtxSize is incorrect size");
struct IoctlNvgpuGpuZcullGetInfoArgs {
u32_le width_align_pixels;
u32_le height_align_pixels;
u32_le pixel_squares_by_aliquots;
u32_le aliquot_total;
u32_le region_byte_multiplier;
u32_le region_header_size;
u32_le subregion_header_size;
u32_le subregion_width_align_pixels;
u32_le subregion_height_align_pixels;
u32_le subregion_count;
u32_le width_align_pixels{};
u32_le height_align_pixels{};
u32_le pixel_squares_by_aliquots{};
u32_le aliquot_total{};
u32_le region_byte_multiplier{};
u32_le region_header_size{};
u32_le subregion_header_size{};
u32_le subregion_width_align_pixels{};
u32_le subregion_height_align_pixels{};
u32_le subregion_count{};
};
static_assert(sizeof(IoctlNvgpuGpuZcullGetInfoArgs) == 40,
"IoctlNvgpuGpuZcullGetInfoArgs is incorrect size");
struct IoctlZbcSetTable {
u32_le color_ds[4];
u32_le color_l2[4];
u32_le depth;
u32_le format;
u32_le type;
u32_le color_ds[4]{};
u32_le color_l2[4]{};
u32_le depth{};
u32_le format{};
u32_le type{};
};
static_assert(sizeof(IoctlZbcSetTable) == 44, "IoctlZbcSetTable is incorrect size");
struct IoctlZbcQueryTable {
u32_le color_ds[4];
u32_le color_l2[4];
u32_le depth;
u32_le ref_cnt;
u32_le format;
u32_le type;
u32_le index_size;
u32_le color_ds[4]{};
u32_le color_l2[4]{};
u32_le depth{};
u32_le ref_cnt{};
u32_le format{};
u32_le type{};
u32_le index_size{};
};
static_assert(sizeof(IoctlZbcQueryTable) == 52, "IoctlZbcQueryTable is incorrect size");
struct IoctlFlushL2 {
u32_le flush; // l2_flush | l2_invalidate << 1 | fb_flush << 2
u32_le reserved;
u32_le flush{}; // l2_flush | l2_invalidate << 1 | fb_flush << 2
u32_le reserved{};
};
static_assert(sizeof(IoctlFlushL2) == 8, "IoctlFlushL2 is incorrect size");
struct IoctlGetGpuTime {
u64_le gpu_time;
u64_le gpu_time{};
};
static_assert(sizeof(IoctlGetGpuTime) == 8, "IoctlGetGpuTime is incorrect size");

View File

@@ -60,58 +60,58 @@ private:
};
struct IoctlSetNvmapFD {
u32_le nvmap_fd;
u32_le nvmap_fd{};
};
static_assert(sizeof(IoctlSetNvmapFD) == 4, "IoctlSetNvmapFD is incorrect size");
struct IoctlChannelSetTimeout {
u32_le timeout;
u32_le timeout{};
};
static_assert(sizeof(IoctlChannelSetTimeout) == 4, "IoctlChannelSetTimeout is incorrect size");
struct IoctlAllocGPFIFO {
u32_le num_entries;
u32_le flags;
u32_le num_entries{};
u32_le flags{};
};
static_assert(sizeof(IoctlAllocGPFIFO) == 8, "IoctlAllocGPFIFO is incorrect size");
struct IoctlClientData {
u64_le data;
u64_le data{};
};
static_assert(sizeof(IoctlClientData) == 8, "IoctlClientData is incorrect size");
struct IoctlZCullBind {
u64_le gpu_va;
u32_le mode; // 0=global, 1=no_ctxsw, 2=separate_buffer, 3=part_of_regular_buf
INSERT_PADDING_WORDS(1);
u64_le gpu_va{};
u32_le mode{}; // 0=global, 1=no_ctxsw, 2=separate_buffer, 3=part_of_regular_buf
INSERT_PADDING_WORDS(1){};
};
static_assert(sizeof(IoctlZCullBind) == 16, "IoctlZCullBind is incorrect size");
struct IoctlSetErrorNotifier {
u64_le offset;
u64_le size;
u32_le mem; // nvmap object handle
INSERT_PADDING_WORDS(1);
u64_le offset{};
u64_le size{};
u32_le mem{}; // nvmap object handle
INSERT_PADDING_WORDS(1){};
};
static_assert(sizeof(IoctlSetErrorNotifier) == 24, "IoctlSetErrorNotifier is incorrect size");
struct IoctlChannelSetPriority {
u32_le priority;
u32_le priority{};
};
static_assert(sizeof(IoctlChannelSetPriority) == 4,
"IoctlChannelSetPriority is incorrect size");
struct IoctlEventIdControl {
u32_le cmd; // 0=disable, 1=enable, 2=clear
u32_le id;
u32_le cmd{}; // 0=disable, 1=enable, 2=clear
u32_le id{};
};
static_assert(sizeof(IoctlEventIdControl) == 8, "IoctlEventIdControl is incorrect size");
struct IoctlGetErrorNotification {
u64_le timestamp;
u32_le info32;
u16_le info16;
u16_le status; // always 0xFFFF
u64_le timestamp{};
u32_le info32{};
u16_le info16{};
u16_le status{}; // always 0xFFFF
};
static_assert(sizeof(IoctlGetErrorNotification) == 16,
"IoctlGetErrorNotification is incorrect size");
@@ -119,54 +119,54 @@ private:
static_assert(sizeof(Fence) == 8, "Fence is incorrect size");
struct IoctlAllocGpfifoEx {
u32_le num_entries;
u32_le flags;
u32_le unk0;
u32_le unk1;
u32_le unk2;
u32_le unk3;
u32_le unk4;
u32_le unk5;
u32_le num_entries{};
u32_le flags{};
u32_le unk0{};
u32_le unk1{};
u32_le unk2{};
u32_le unk3{};
u32_le unk4{};
u32_le unk5{};
};
static_assert(sizeof(IoctlAllocGpfifoEx) == 32, "IoctlAllocGpfifoEx is incorrect size");
struct IoctlAllocGpfifoEx2 {
u32_le num_entries; // in
u32_le flags; // in
u32_le unk0; // in (1 works)
Fence fence_out; // out
u32_le unk1; // in
u32_le unk2; // in
u32_le unk3; // in
u32_le num_entries{}; // in
u32_le flags{}; // in
u32_le unk0{}; // in (1 works)
Fence fence_out{}; // out
u32_le unk1{}; // in
u32_le unk2{}; // in
u32_le unk3{}; // in
};
static_assert(sizeof(IoctlAllocGpfifoEx2) == 32, "IoctlAllocGpfifoEx2 is incorrect size");
struct IoctlAllocObjCtx {
u32_le class_num; // 0x902D=2d, 0xB197=3d, 0xB1C0=compute, 0xA140=kepler, 0xB0B5=DMA,
// 0xB06F=channel_gpfifo
u32_le flags;
u64_le obj_id; // (ignored) used for FREE_OBJ_CTX ioctl, which is not supported
u32_le class_num{}; // 0x902D=2d, 0xB197=3d, 0xB1C0=compute, 0xA140=kepler, 0xB0B5=DMA,
// 0xB06F=channel_gpfifo
u32_le flags{};
u64_le obj_id{}; // (ignored) used for FREE_OBJ_CTX ioctl, which is not supported
};
static_assert(sizeof(IoctlAllocObjCtx) == 16, "IoctlAllocObjCtx is incorrect size");
struct IoctlSubmitGpfifo {
u64_le address; // pointer to gpfifo entry structs
u32_le num_entries; // number of fence objects being submitted
u64_le address{}; // pointer to gpfifo entry structs
u32_le num_entries{}; // number of fence objects being submitted
union {
u32_le raw;
u32_le raw{};
BitField<0, 1, u32_le> add_wait; // append a wait sync_point to the list
BitField<1, 1, u32_le> add_increment; // append an increment to the list
BitField<2, 1, u32_le> new_hw_format; // Mostly ignored
BitField<8, 1, u32_le> increment; // increment the returned fence
} flags;
Fence fence_out; // returned new fence object for others to wait on
} flags{};
Fence fence_out{}; // returned new fence object for others to wait on
};
static_assert(sizeof(IoctlSubmitGpfifo) == 16 + sizeof(Fence),
"IoctlSubmitGpfifo is incorrect size");
struct IoctlGetWaitbase {
u32 unknown; // seems to be ignored? Nintendo added this
u32 value;
u32 unknown{}; // seems to be ignored? Nintendo added this
u32 value{};
};
static_assert(sizeof(IoctlGetWaitbase) == 8, "IoctlGetWaitbase is incorrect size");

View File

@@ -22,18 +22,6 @@ u32 nvhost_nvdec::ioctl(Ioctl command, const std::vector<u8>& input, const std::
switch (static_cast<IoctlCommand>(command.raw)) {
case IoctlCommand::IocSetNVMAPfdCommand:
return SetNVMAPfd(input, output);
case IoctlCommand::IocSubmit:
return Submit(input, output);
case IoctlCommand::IocGetSyncpoint:
return GetSyncpoint(input, output);
case IoctlCommand::IocGetWaitbase:
return GetWaitbase(input, output);
case IoctlCommand::IocMapBuffer:
return MapBuffer(input, output);
case IoctlCommand::IocMapBufferEx:
return MapBufferEx(input, output);
case IoctlCommand::IocUnmapBufferEx:
return UnmapBufferEx(input, output);
}
UNIMPLEMENTED_MSG("Unimplemented ioctl");
@@ -42,67 +30,11 @@ u32 nvhost_nvdec::ioctl(Ioctl command, const std::vector<u8>& input, const std::
u32 nvhost_nvdec::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) {
IoctlSetNvmapFD params{};
std::memcpy(&params, input.data(), sizeof(IoctlSetNvmapFD));
std::memcpy(&params, input.data(), input.size());
LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd);
nvmap_fd = params.nvmap_fd;
return 0;
}
u32 nvhost_nvdec::Submit(const std::vector<u8>& input, std::vector<u8>& output) {
IoctlSubmit params{};
std::memcpy(&params, input.data(), sizeof(IoctlSubmit));
LOG_WARNING(Service_NVDRV, "(STUBBED) called");
std::memcpy(output.data(), &params, sizeof(IoctlSubmit));
return 0;
}
u32 nvhost_nvdec::GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output) {
IoctlGetSyncpoint params{};
std::memcpy(&params, input.data(), sizeof(IoctlGetSyncpoint));
LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown);
params.value = 0; // Seems to be hard coded at 0
std::memcpy(output.data(), &params, sizeof(IoctlGetSyncpoint));
return 0;
}
u32 nvhost_nvdec::GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output) {
IoctlGetWaitbase params{};
std::memcpy(&params, input.data(), sizeof(IoctlGetWaitbase));
LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown);
params.value = 0; // Seems to be hard coded at 0
std::memcpy(output.data(), &params, sizeof(IoctlGetWaitbase));
return 0;
}
u32 nvhost_nvdec::MapBuffer(const std::vector<u8>& input, std::vector<u8>& output) {
IoctlMapBuffer params{};
std::memcpy(&params, input.data(), sizeof(IoctlMapBuffer));
LOG_WARNING(Service_NVDRV, "(STUBBED) called with address={:08X}{:08X}", params.address_2,
params.address_1);
params.address_1 = 0;
params.address_2 = 0;
std::memcpy(output.data(), &params, sizeof(IoctlMapBuffer));
return 0;
}
u32 nvhost_nvdec::MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) {
IoctlMapBufferEx params{};
std::memcpy(&params, input.data(), sizeof(IoctlMapBufferEx));
LOG_WARNING(Service_NVDRV, "(STUBBED) called with address={:08X}{:08X}", params.address_2,
params.address_1);
params.address_1 = 0;
params.address_2 = 0;
std::memcpy(output.data(), &params, sizeof(IoctlMapBufferEx));
return 0;
}
u32 nvhost_nvdec::UnmapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) {
IoctlUnmapBufferEx params{};
std::memcpy(&params, input.data(), sizeof(IoctlUnmapBufferEx));
LOG_WARNING(Service_NVDRV, "(STUBBED) called");
std::memcpy(output.data(), &params, sizeof(IoctlUnmapBufferEx));
return 0;
}
} // namespace Service::Nvidia::Devices

View File

@@ -23,66 +23,16 @@ public:
private:
enum class IoctlCommand : u32_le {
IocSetNVMAPfdCommand = 0x40044801,
IocSubmit = 0xC0400001,
IocGetSyncpoint = 0xC0080002,
IocGetWaitbase = 0xC0080003,
IocMapBuffer = 0xC01C0009,
IocMapBufferEx = 0xC0A40009,
IocUnmapBufferEx = 0xC0A4000A,
};
struct IoctlSetNvmapFD {
u32_le nvmap_fd;
u32_le nvmap_fd{};
};
static_assert(sizeof(IoctlSetNvmapFD) == 0x4, "IoctlSetNvmapFD is incorrect size");
struct IoctlSubmit {
INSERT_PADDING_BYTES(0x40); // TODO(DarkLordZach): RE this structure
};
static_assert(sizeof(IoctlSubmit) == 0x40, "IoctlSubmit has incorrect size");
struct IoctlGetSyncpoint {
u32 unknown; // seems to be ignored? Nintendo added this
u32 value;
};
static_assert(sizeof(IoctlGetSyncpoint) == 0x08, "IoctlGetSyncpoint has incorrect size");
struct IoctlGetWaitbase {
u32 unknown; // seems to be ignored? Nintendo added this
u32 value;
};
static_assert(sizeof(IoctlGetWaitbase) == 0x08, "IoctlGetWaitbase has incorrect size");
struct IoctlMapBuffer {
u32 unknown;
u32 address_1;
u32 address_2;
INSERT_PADDING_BYTES(0x10); // TODO(DarkLordZach): RE this structure
};
static_assert(sizeof(IoctlMapBuffer) == 0x1C, "IoctlMapBuffer is incorrect size");
struct IoctlMapBufferEx {
u32 unknown;
u32 address_1;
u32 address_2;
INSERT_PADDING_BYTES(0x98); // TODO(DarkLordZach): RE this structure
};
static_assert(sizeof(IoctlMapBufferEx) == 0xA4, "IoctlMapBufferEx has incorrect size");
struct IoctlUnmapBufferEx {
INSERT_PADDING_BYTES(0xA4); // TODO(DarkLordZach): RE this structure
};
static_assert(sizeof(IoctlUnmapBufferEx) == 0xA4, "IoctlUnmapBufferEx has incorrect size");
static_assert(sizeof(IoctlSetNvmapFD) == 4, "IoctlSetNvmapFD is incorrect size");
u32_le nvmap_fd{};
u32 SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output);
u32 Submit(const std::vector<u8>& input, std::vector<u8>& output);
u32 GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output);
u32 GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output);
u32 MapBuffer(const std::vector<u8>& input, std::vector<u8>& output);
u32 MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output);
u32 UnmapBufferEx(const std::vector<u8>& input, std::vector<u8>& output);
};
} // namespace Service::Nvidia::Devices

View File

@@ -26,7 +26,7 @@ private:
};
struct IoctlSetNvmapFD {
u32_le nvmap_fd;
u32_le nvmap_fd{};
};
static_assert(sizeof(IoctlSetNvmapFD) == 4, "IoctlSetNvmapFD is incorrect size");

View File

@@ -22,18 +22,6 @@ u32 nvhost_vic::ioctl(Ioctl command, const std::vector<u8>& input, const std::ve
switch (static_cast<IoctlCommand>(command.raw)) {
case IoctlCommand::IocSetNVMAPfdCommand:
return SetNVMAPfd(input, output);
case IoctlCommand::IocSubmit:
return Submit(input, output);
case IoctlCommand::IocGetSyncpoint:
return GetSyncpoint(input, output);
case IoctlCommand::IocGetWaitbase:
return GetWaitbase(input, output);
case IoctlCommand::IocMapBuffer:
return MapBuffer(input, output);
case IoctlCommand::IocMapBufferEx:
return MapBuffer(input, output);
case IoctlCommand::IocUnmapBufferEx:
return UnmapBufferEx(input, output);
}
UNIMPLEMENTED_MSG("Unimplemented ioctl");
@@ -42,67 +30,11 @@ u32 nvhost_vic::ioctl(Ioctl command, const std::vector<u8>& input, const std::ve
u32 nvhost_vic::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) {
IoctlSetNvmapFD params{};
std::memcpy(&params, input.data(), sizeof(IoctlSetNvmapFD));
std::memcpy(&params, input.data(), input.size());
LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd);
nvmap_fd = params.nvmap_fd;
return 0;
}
u32 nvhost_vic::Submit(const std::vector<u8>& input, std::vector<u8>& output) {
IoctlSubmit params{};
std::memcpy(&params, input.data(), sizeof(IoctlSubmit));
LOG_WARNING(Service_NVDRV, "(STUBBED) called");
std::memcpy(output.data(), &params, sizeof(IoctlSubmit));
return 0;
}
u32 nvhost_vic::GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output) {
IoctlGetSyncpoint params{};
std::memcpy(&params, input.data(), sizeof(IoctlGetSyncpoint));
LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown);
params.value = 0; // Seems to be hard coded at 0
std::memcpy(output.data(), &params, sizeof(IoctlGetSyncpoint));
return 0;
}
u32 nvhost_vic::GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output) {
IoctlGetWaitbase params{};
std::memcpy(&params, input.data(), sizeof(IoctlGetWaitbase));
LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown);
params.value = 0; // Seems to be hard coded at 0
std::memcpy(output.data(), &params, sizeof(IoctlGetWaitbase));
return 0;
}
u32 nvhost_vic::MapBuffer(const std::vector<u8>& input, std::vector<u8>& output) {
IoctlMapBuffer params{};
std::memcpy(&params, input.data(), sizeof(IoctlMapBuffer));
LOG_WARNING(Service_NVDRV, "(STUBBED) called with address={:08X}{:08X}", params.address_2,
params.address_1);
params.address_1 = 0;
params.address_2 = 0;
std::memcpy(output.data(), &params, sizeof(IoctlMapBuffer));
return 0;
}
u32 nvhost_vic::MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) {
IoctlMapBufferEx params{};
std::memcpy(&params, input.data(), sizeof(IoctlMapBufferEx));
LOG_WARNING(Service_NVDRV, "(STUBBED) called with address={:08X}{:08X}", params.address_2,
params.address_1);
params.address_1 = 0;
params.address_2 = 0;
std::memcpy(output.data(), &params, sizeof(IoctlMapBufferEx));
return 0;
}
u32 nvhost_vic::UnmapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) {
IoctlUnmapBufferEx params{};
std::memcpy(&params, input.data(), sizeof(IoctlUnmapBufferEx));
LOG_WARNING(Service_NVDRV, "(STUBBED) called");
std::memcpy(output.data(), &params, sizeof(IoctlUnmapBufferEx));
return 0;
}
} // namespace Service::Nvidia::Devices

View File

@@ -23,66 +23,16 @@ public:
private:
enum class IoctlCommand : u32_le {
IocSetNVMAPfdCommand = 0x40044801,
IocSubmit = 0xC0400001,
IocGetSyncpoint = 0xC0080002,
IocGetWaitbase = 0xC0080003,
IocMapBuffer = 0xC01C0009,
IocMapBufferEx = 0xC03C0009,
IocUnmapBufferEx = 0xC03C000A,
};
struct IoctlSetNvmapFD {
u32_le nvmap_fd;
u32_le nvmap_fd{};
};
static_assert(sizeof(IoctlSetNvmapFD) == 4, "IoctlSetNvmapFD is incorrect size");
struct IoctlSubmit {
INSERT_PADDING_BYTES(0x40); // TODO(DarkLordZach): RE this structure
};
static_assert(sizeof(IoctlSubmit) == 0x40, "IoctlSubmit is incorrect size");
struct IoctlGetSyncpoint {
u32 unknown; // seems to be ignored? Nintendo added this
u32 value;
};
static_assert(sizeof(IoctlGetSyncpoint) == 0x8, "IoctlGetSyncpoint is incorrect size");
struct IoctlGetWaitbase {
u32 unknown; // seems to be ignored? Nintendo added this
u32 value;
};
static_assert(sizeof(IoctlGetWaitbase) == 0x8, "IoctlGetWaitbase is incorrect size");
struct IoctlMapBuffer {
u32 unknown;
u32 address_1;
u32 address_2;
INSERT_PADDING_BYTES(0x10); // TODO(DarkLordZach): RE this structure
};
static_assert(sizeof(IoctlMapBuffer) == 0x1C, "IoctlMapBuffer is incorrect size");
struct IoctlMapBufferEx {
u32 unknown;
u32 address_1;
u32 address_2;
INSERT_PADDING_BYTES(0x30); // TODO(DarkLordZach): RE this structure
};
static_assert(sizeof(IoctlMapBufferEx) == 0x3C, "IoctlMapBufferEx is incorrect size");
struct IoctlUnmapBufferEx {
INSERT_PADDING_BYTES(0x3C); // TODO(DarkLordZach): RE this structure
};
static_assert(sizeof(IoctlUnmapBufferEx) == 0x3C, "IoctlUnmapBufferEx is incorrect size");
u32_le nvmap_fd{};
u32 SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output);
u32 Submit(const std::vector<u8>& input, std::vector<u8>& output);
u32 GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output);
u32 GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output);
u32 MapBuffer(const std::vector<u8>& input, std::vector<u8>& output);
u32 MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output);
u32 UnmapBufferEx(const std::vector<u8>& input, std::vector<u8>& output);
};
} // namespace Service::Nvidia::Devices

View File

@@ -29,14 +29,14 @@ public:
/// Represents an nvmap object.
struct Object {
enum class Status { Created, Allocated };
u32 id;
u32 size;
u32 flags;
u32 align;
u8 kind;
VAddr addr;
Status status;
u32 refcount;
u32 id{};
u32 size{};
u32 flags{};
u32 align{};
u8 kind{};
VAddr addr{};
Status status{};
u32 refcount{};
};
std::shared_ptr<Object> GetObject(u32 handle) const {
@@ -67,55 +67,55 @@ private:
};
struct IocCreateParams {
// Input
u32_le size;
u32_le size{};
// Output
u32_le handle;
u32_le handle{};
};
static_assert(sizeof(IocCreateParams) == 8, "IocCreateParams has wrong size");
struct IocFromIdParams {
// Input
u32_le id;
u32_le id{};
// Output
u32_le handle;
u32_le handle{};
};
static_assert(sizeof(IocFromIdParams) == 8, "IocFromIdParams has wrong size");
struct IocAllocParams {
// Input
u32_le handle;
u32_le heap_mask;
u32_le flags;
u32_le align;
u8 kind;
INSERT_PADDING_BYTES(7);
u64_le addr;
u32_le handle{};
u32_le heap_mask{};
u32_le flags{};
u32_le align{};
u8 kind{};
INSERT_PADDING_BYTES(7){};
u64_le addr{};
};
static_assert(sizeof(IocAllocParams) == 32, "IocAllocParams has wrong size");
struct IocFreeParams {
u32_le handle;
INSERT_PADDING_BYTES(4);
u64_le address;
u32_le size;
u32_le flags;
u32_le handle{};
INSERT_PADDING_BYTES(4){};
u64_le address{};
u32_le size{};
u32_le flags{};
};
static_assert(sizeof(IocFreeParams) == 24, "IocFreeParams has wrong size");
struct IocParamParams {
// Input
u32_le handle;
u32_le param;
u32_le handle{};
u32_le param{};
// Output
u32_le result;
u32_le result{};
};
static_assert(sizeof(IocParamParams) == 12, "IocParamParams has wrong size");
struct IocGetIdParams {
// Output
u32_le id;
u32_le id{};
// Input
u32_le handle;
u32_le handle{};
};
static_assert(sizeof(IocGetIdParams) == 8, "IocGetIdParams has wrong size");

View File

@@ -9,15 +9,15 @@ constexpr u32 MaxSyncPoints = 192;
constexpr u32 MaxNvEvents = 64;
struct Fence {
s32 id;
u32 value;
s32 id{};
u32 value{};
};
static_assert(sizeof(Fence) == 8, "Fence has wrong size");
struct MultiFence {
u32 num_fences;
std::array<Fence, 4> fences;
u32 num_fences{};
std::array<Fence, 4> fences{};
};
enum NvResult : u32 {

View File

@@ -30,7 +30,7 @@ struct EventInterface {
// Mask representing currently busy events
u64 events_mask{};
// Each kernel event associated to an NV event
std::array<Kernel::EventPair, MaxNvEvents> events;
std::array<Kernel::EventPair, MaxNvEvents> events{};
// The status of the current NVEvent
std::array<EventState, MaxNvEvents> status{};
// Tells if an NVEvent is registered or not

View File

@@ -22,20 +22,20 @@ class KernelCore;
namespace Service::NVFlinger {
struct IGBPBuffer {
u32_le magic;
u32_le width;
u32_le height;
u32_le stride;
u32_le format;
u32_le usage;
INSERT_PADDING_WORDS(1);
u32_le index;
INSERT_PADDING_WORDS(3);
u32_le gpu_buffer_id;
INSERT_PADDING_WORDS(17);
u32_le nvmap_handle;
u32_le offset;
INSERT_PADDING_WORDS(60);
u32_le magic{};
u32_le width{};
u32_le height{};
u32_le stride{};
u32_le format{};
u32_le usage{};
INSERT_PADDING_WORDS(1){};
u32_le index{};
INSERT_PADDING_WORDS(3){};
u32_le gpu_buffer_id{};
INSERT_PADDING_WORDS(17){};
u32_le nvmap_handle{};
u32_le offset{};
INSERT_PADDING_WORDS(60){};
};
static_assert(sizeof(IGBPBuffer) == 0x16C, "IGBPBuffer has wrong size");
@@ -69,13 +69,13 @@ public:
struct Buffer {
enum class Status { Free = 0, Queued = 1, Dequeued = 2, Acquired = 3 };
u32 slot;
u32 slot{};
Status status = Status::Free;
IGBPBuffer igbp_buffer;
BufferTransformFlags transform;
Common::Rectangle<int> crop_rect;
u32 swap_interval;
Service::Nvidia::MultiFence multi_fence;
IGBPBuffer igbp_buffer{};
BufferTransformFlags transform{};
Common::Rectangle<int> crop_rect{};
u32 swap_interval{};
Service::Nvidia::MultiFence multi_fence{};
};
void SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer);

View File

@@ -81,7 +81,7 @@ private:
friend class ServiceFramework;
struct FunctionInfoBase {
u32 expected_header;
u32 expected_header{};
HandlerFnP<ServiceFrameworkBase> handler_callback;
const char* name;
};
@@ -98,7 +98,7 @@ private:
/// Identifier string used to connect to the service.
std::string service_name;
/// Maximum number of concurrent sessions that this service can handle.
u32 max_sessions;
u32 max_sessions{};
/// Flag to store if a port was already create/installed to detect multiple install attempts,
/// which is not supported.

View File

@@ -9,9 +9,9 @@ namespace Service::Sockets {
void SFDNSRES::GetAddrInfo(Kernel::HLERequestContext& ctx) {
struct Parameters {
u8 use_nsd_resolve;
u32 unknown;
u64 process_id;
u8 use_nsd_resolve{};
u32 unknown{};
u64 process_id{};
};
IPC::RequestParser rp{ctx};

View File

@@ -68,8 +68,8 @@ public:
private:
void SetOption(Kernel::HLERequestContext& ctx) {
struct Parameters {
u8 enable;
u32 option;
u8 enable{};
u32 option{};
};
IPC::RequestParser rp{ctx};

View File

@@ -13,33 +13,33 @@ namespace Service::Time {
class SharedMemory;
struct LocationName {
std::array<u8, 0x24> name;
std::array<u8, 0x24> name{};
};
static_assert(sizeof(LocationName) == 0x24, "LocationName is incorrect size");
struct CalendarTime {
u16_le year;
u8 month; // Starts at 1
u8 day; // Starts at 1
u8 hour;
u8 minute;
u8 second;
u16_le year{};
u8 month{}; // Starts at 1
u8 day{}; // Starts at 1
u8 hour{};
u8 minute{};
u8 second{};
};
static_assert(sizeof(CalendarTime) == 0x8, "CalendarTime structure has incorrect size");
struct CalendarAdditionalInfo {
u32_le day_of_week;
u32_le day_of_year;
std::array<u8, 8> name;
u8 is_dst;
s32_le utc_offset;
u32_le day_of_week{};
u32_le day_of_year{};
std::array<u8, 8> name{};
u8 is_dst{};
s32_le utc_offset{};
};
static_assert(sizeof(CalendarAdditionalInfo) == 0x18,
"CalendarAdditionalInfo structure has incorrect size");
// TODO(mailwl) RE this structure
struct TimeZoneRule {
INSERT_PADDING_BYTES(0x4000);
INSERT_PADDING_BYTES(0x4000){};
};
struct SteadyClockTimePoint {
@@ -58,20 +58,20 @@ static_assert(sizeof(SystemClockContext) == 0x20,
"SystemClockContext structure has incorrect size");
struct ClockSnapshot {
SystemClockContext user_clock_context;
SystemClockContext network_clock_context;
s64_le system_posix_time;
s64_le network_posix_time;
CalendarTime system_calendar_time;
CalendarTime network_calendar_time;
CalendarAdditionalInfo system_calendar_info;
CalendarAdditionalInfo network_calendar_info;
SteadyClockTimePoint steady_clock_timepoint;
LocationName location_name;
u8 clock_auto_adjustment_enabled;
u8 type;
u8 version;
INSERT_PADDING_BYTES(1);
SystemClockContext user_clock_context{};
SystemClockContext network_clock_context{};
s64_le system_posix_time{};
s64_le network_posix_time{};
CalendarTime system_calendar_time{};
CalendarTime network_calendar_time{};
CalendarAdditionalInfo system_calendar_info{};
CalendarAdditionalInfo network_calendar_info{};
SteadyClockTimePoint steady_clock_timepoint{};
LocationName location_name{};
u8 clock_auto_adjustment_enabled{};
u8 type{};
u8 version{};
INSERT_PADDING_BYTES(1){};
};
static_assert(sizeof(ClockSnapshot) == 0xd0, "ClockSnapshot is an invalid size");

View File

@@ -61,7 +61,7 @@ public:
MemoryBarrier<SystemClockContext, 0x38> standard_local_system_clock_context;
MemoryBarrier<SystemClockContext, 0x80> standard_network_system_clock_context;
MemoryBarrier<bool, 0xc8> standard_user_system_clock_automatic_correction;
u32_le format_version;
u32_le format_version{};
};
static_assert(sizeof(Format) == 0xd8, "Format is an invalid size");

View File

@@ -45,7 +45,7 @@ struct DisplayInfo {
/// Whether or not the display has a limited number of layers.
u8 has_limited_layers{1};
INSERT_PADDING_BYTES(7){};
INSERT_PADDING_BYTES(7);
/// Indicates the total amount of layers supported by the display.
/// @note This is only valid if has_limited_layers is set.
@@ -172,10 +172,10 @@ protected:
private:
struct Header {
u32_le data_size;
u32_le data_offset;
u32_le objects_size;
u32_le objects_offset;
u32_le data_size{};
u32_le data_offset{};
u32_le objects_size{};
u32_le objects_offset{};
};
static_assert(sizeof(Header) == 16, "ParcelHeader has wrong size");
@@ -200,10 +200,10 @@ private:
struct Data {
u32_le magic = 2;
u32_le process_id = 1;
u32_le id;
INSERT_PADDING_WORDS(3);
u32_le id{};
INSERT_PADDING_WORDS(3){};
std::array<u8, 8> dispdrv = {'d', 'i', 's', 'p', 'd', 'r', 'v', '\0'};
INSERT_PADDING_WORDS(2);
INSERT_PADDING_WORDS(2){};
};
static_assert(sizeof(Data) == 0x28, "ParcelData has wrong size");
@@ -223,12 +223,12 @@ public:
}
struct Data {
u32_le unk;
u32_le api;
u32_le producer_controlled_by_app;
u32_le unk{};
u32_le api{};
u32_le producer_controlled_by_app{};
};
Data data;
Data data{};
};
class IGBPConnectResponseParcel : public Parcel {
@@ -246,11 +246,11 @@ protected:
private:
struct Data {
u32_le width;
u32_le height;
u32_le transform_hint;
u32_le num_pending_buffers;
u32_le status;
u32_le width{};
u32_le height{};
u32_le transform_hint{};
u32_le num_pending_buffers{};
u32_le status{};
};
static_assert(sizeof(Data) == 20, "ParcelData has wrong size");
@@ -267,7 +267,7 @@ protected:
private:
struct Data {
u32_le unk_0;
u32_le unk_0{};
};
Data data{};
@@ -288,13 +288,13 @@ public:
}
struct Data {
u32_le slot;
INSERT_PADDING_WORDS(1);
u32_le graphic_buffer_length;
INSERT_PADDING_WORDS(1);
u32_le slot{};
INSERT_PADDING_WORDS(1){};
u32_le graphic_buffer_length{};
INSERT_PADDING_WORDS(1){};
};
Data data;
Data data{};
NVFlinger::IGBPBuffer buffer;
};
@@ -319,14 +319,14 @@ public:
}
struct Data {
u32_le pixel_format;
u32_le width;
u32_le height;
u32_le get_frame_timestamps;
u32_le usage;
u32_le pixel_format{};
u32_le width{};
u32_le height{};
u32_le get_frame_timestamps{};
u32_le usage{};
};
Data data;
Data data{};
};
class IGBPDequeueBufferResponseParcel : public Parcel {
@@ -392,20 +392,20 @@ public:
}
struct Data {
u32_le slot;
INSERT_PADDING_WORDS(3);
u32_le timestamp;
s32_le is_auto_timestamp;
s32_le crop_top;
s32_le crop_left;
s32_le crop_right;
s32_le crop_bottom;
s32_le scaling_mode;
NVFlinger::BufferQueue::BufferTransformFlags transform;
u32_le sticky_transform;
INSERT_PADDING_WORDS(1);
u32_le swap_interval;
Service::Nvidia::MultiFence multi_fence;
u32_le slot{};
INSERT_PADDING_WORDS(3){};
u32_le timestamp{};
s32_le is_auto_timestamp{};
s32_le crop_top{};
s32_le crop_left{};
s32_le crop_right{};
s32_le crop_bottom{};
s32_le scaling_mode{};
NVFlinger::BufferQueue::BufferTransformFlags transform{};
u32_le sticky_transform{};
INSERT_PADDING_WORDS(1){};
u32_le swap_interval{};
Service::Nvidia::MultiFence multi_fence{};
Common::Rectangle<int> GetCropRect() const {
return {crop_left, crop_top, crop_right, crop_bottom};
@@ -413,7 +413,7 @@ public:
};
static_assert(sizeof(Data) == 96, "ParcelData has wrong size");
Data data;
Data data{};
};
class IGBPQueueBufferResponseParcel : public Parcel {
@@ -431,11 +431,11 @@ protected:
private:
struct Data {
u32_le width;
u32_le height;
u32_le transform_hint;
u32_le num_pending_buffers;
u32_le status;
u32_le width{};
u32_le height{};
u32_le transform_hint{};
u32_le num_pending_buffers{};
u32_le status{};
};
static_assert(sizeof(Data) == 20, "ParcelData has wrong size");

View File

@@ -111,62 +111,62 @@ typedef unsigned int Elf32_Word;
// ELF file header
struct Elf32_Ehdr {
unsigned char e_ident[EI_NIDENT];
Elf32_Half e_type;
Elf32_Half e_machine;
Elf32_Word e_version;
Elf32_Addr e_entry;
Elf32_Off e_phoff;
Elf32_Off e_shoff;
Elf32_Word e_flags;
Elf32_Half e_ehsize;
Elf32_Half e_phentsize;
Elf32_Half e_phnum;
Elf32_Half e_shentsize;
Elf32_Half e_shnum;
Elf32_Half e_shstrndx;
unsigned char e_ident[EI_NIDENT]{};
Elf32_Half e_type{};
Elf32_Half e_machine{};
Elf32_Word e_version{};
Elf32_Addr e_entry{};
Elf32_Off e_phoff{};
Elf32_Off e_shoff{};
Elf32_Word e_flags{};
Elf32_Half e_ehsize{};
Elf32_Half e_phentsize{};
Elf32_Half e_phnum{};
Elf32_Half e_shentsize{};
Elf32_Half e_shnum{};
Elf32_Half e_shstrndx{};
};
// Section header
struct Elf32_Shdr {
Elf32_Word sh_name;
Elf32_Word sh_type;
Elf32_Word sh_flags;
Elf32_Addr sh_addr;
Elf32_Off sh_offset;
Elf32_Word sh_size;
Elf32_Word sh_link;
Elf32_Word sh_info;
Elf32_Word sh_addralign;
Elf32_Word sh_entsize;
Elf32_Word sh_name{};
Elf32_Word sh_type{};
Elf32_Word sh_flags{};
Elf32_Addr sh_addr{};
Elf32_Off sh_offset{};
Elf32_Word sh_size{};
Elf32_Word sh_link{};
Elf32_Word sh_info{};
Elf32_Word sh_addralign{};
Elf32_Word sh_entsize{};
};
// Segment header
struct Elf32_Phdr {
Elf32_Word p_type;
Elf32_Off p_offset;
Elf32_Addr p_vaddr;
Elf32_Addr p_paddr;
Elf32_Word p_filesz;
Elf32_Word p_memsz;
Elf32_Word p_flags;
Elf32_Word p_align;
Elf32_Word p_type{};
Elf32_Off p_offset{};
Elf32_Addr p_vaddr{};
Elf32_Addr p_paddr{};
Elf32_Word p_filesz{};
Elf32_Word p_memsz{};
Elf32_Word p_flags{};
Elf32_Word p_align{};
};
// Symbol table entry
struct Elf32_Sym {
Elf32_Word st_name;
Elf32_Addr st_value;
Elf32_Word st_size;
unsigned char st_info;
unsigned char st_other;
Elf32_Half st_shndx;
Elf32_Word st_name{};
Elf32_Addr st_value{};
Elf32_Word st_size{};
unsigned char st_info{};
unsigned char st_other{};
Elf32_Half st_shndx{};
};
// Relocation entries
struct Elf32_Rel {
Elf32_Addr r_offset;
Elf32_Word r_info;
Elf32_Addr r_offset{};
Elf32_Word r_info{};
};
////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@@ -137,8 +137,8 @@ std::ostream& operator<<(std::ostream& os, ResultStatus status);
class AppLoader : NonCopyable {
public:
struct LoadParameters {
s32 main_thread_priority;
u64 main_thread_stack_size;
s32 main_thread_priority{};
u64 main_thread_stack_size{};
};
using LoadResult = std::pair<ResultStatus, std::optional<LoadParameters>>;

View File

@@ -27,48 +27,49 @@
namespace Loader {
struct NroSegmentHeader {
u32_le offset;
u32_le size;
u32_le offset{};
u32_le size{};
};
static_assert(sizeof(NroSegmentHeader) == 0x8, "NroSegmentHeader has incorrect size.");
struct NroHeader {
INSERT_PADDING_BYTES(0x4);
u32_le module_header_offset;
INSERT_PADDING_BYTES(0x8);
u32_le magic;
INSERT_PADDING_BYTES(0x4);
u32_le file_size;
INSERT_PADDING_BYTES(0x4);
std::array<NroSegmentHeader, 3> segments; // Text, RoData, Data (in that order)
u32_le bss_size;
INSERT_PADDING_BYTES(0x44);
INSERT_PADDING_BYTES(0x4){};
u32_le module_header_offset{};
INSERT_PADDING_BYTES(0x8){};
u32_le magic{};
INSERT_PADDING_BYTES(0x4){};
u32_le file_size{};
INSERT_PADDING_BYTES(0x4){};
std::array<NroSegmentHeader, 3> segments{}; // Text, RoData, Data (in that order)
u32_le bss_size{};
INSERT_PADDING_BYTES(0x44){};
};
static_assert(sizeof(NroHeader) == 0x80, "NroHeader has incorrect size.");
struct ModHeader {
u32_le magic;
u32_le dynamic_offset;
u32_le bss_start_offset;
u32_le bss_end_offset;
u32_le unwind_start_offset;
u32_le unwind_end_offset;
u32_le module_offset; // Offset to runtime-generated module object. typically equal to .bss base
u32_le magic{};
u32_le dynamic_offset{};
u32_le bss_start_offset{};
u32_le bss_end_offset{};
u32_le unwind_start_offset{};
u32_le unwind_end_offset{};
u32_le
module_offset{}; // Offset to runtime-generated module object. typically equal to .bss base
};
static_assert(sizeof(ModHeader) == 0x1c, "ModHeader has incorrect size.");
struct AssetSection {
u64_le offset;
u64_le size;
u64_le offset{};
u64_le size{};
};
static_assert(sizeof(AssetSection) == 0x10, "AssetSection has incorrect size.");
struct AssetHeader {
u32_le magic;
u32_le format_version;
AssetSection icon;
AssetSection nacp;
AssetSection romfs;
u32_le magic{};
u32_le format_version{};
AssetSection icon{};
AssetSection nacp{};
AssetSection romfs{};
};
static_assert(sizeof(AssetHeader) == 0x38, "AssetHeader has incorrect size.");

View File

@@ -24,13 +24,14 @@
namespace Loader {
namespace {
struct MODHeader {
u32_le magic;
u32_le dynamic_offset;
u32_le bss_start_offset;
u32_le bss_end_offset;
u32_le eh_frame_hdr_start_offset;
u32_le eh_frame_hdr_end_offset;
u32_le module_offset; // Offset to runtime-generated module object. typically equal to .bss base
u32_le magic{};
u32_le dynamic_offset{};
u32_le bss_start_offset{};
u32_le bss_end_offset{};
u32_le eh_frame_hdr_start_offset{};
u32_le eh_frame_hdr_end_offset{};
u32_le
module_offset{}; // Offset to runtime-generated module object. typically equal to .bss base
};
static_assert(sizeof(MODHeader) == 0x1c, "MODHeader has incorrect size.");

View File

@@ -19,11 +19,11 @@ class Process;
namespace Loader {
struct NSOSegmentHeader {
u32_le offset;
u32_le location;
u32_le size;
u32_le offset{};
u32_le location{};
u32_le size{};
union {
u32_le alignment;
u32_le alignment{};
u32_le bss_size;
};
};
@@ -33,22 +33,22 @@ struct NSOHeader {
using SHA256Hash = std::array<u8, 0x20>;
struct RODataRelativeExtent {
u32_le data_offset;
u32_le size;
u32_le data_offset{};
u32_le size{};
};
u32_le magic;
u32_le version;
u32 reserved;
u32_le flags;
std::array<NSOSegmentHeader, 3> segments; // Text, RoData, Data (in that order)
std::array<u8, 0x20> build_id;
std::array<u32_le, 3> segments_compressed_size;
std::array<u8, 0x1C> padding;
RODataRelativeExtent api_info_extent;
RODataRelativeExtent dynstr_extent;
RODataRelativeExtent dynsyn_extent;
std::array<SHA256Hash, 3> segment_hashes;
u32_le magic{};
u32_le version{};
u32 reserved{};
u32_le flags{};
std::array<NSOSegmentHeader, 3> segments{}; // Text, RoData, Data (in that order)
std::array<u8, 0x20> build_id{};
std::array<u32_le, 3> segments_compressed_size{};
std::array<u8, 0x1C> padding{};
RODataRelativeExtent api_info_extent{};
RODataRelativeExtent dynstr_extent{};
RODataRelativeExtent dynsyn_extent{};
std::array<SHA256Hash, 3> segment_hashes{};
bool IsSegmentCompressed(size_t segment_num) const;
};
@@ -58,9 +58,9 @@ static_assert(std::is_trivially_copyable_v<NSOHeader>, "NSOHeader must be trivia
constexpr u64 NSO_ARGUMENT_DATA_ALLOCATION_SIZE = 0x9000;
struct NSOArgumentHeader {
u32_le allocated_size;
u32_le actual_size;
INSERT_PADDING_BYTES(0x18);
u32_le allocated_size{};
u32_le actual_size{};
INSERT_PADDING_BYTES(0x18){};
};
static_assert(sizeof(NSOArgumentHeader) == 0x20, "NSOArgumentHeader has incorrect size.");

View File

@@ -14,13 +14,13 @@ namespace Core {
struct PerfStatsResults {
/// System FPS (LCD VBlanks) in Hz
double system_fps;
double system_fps{};
/// Game FPS (GSP frame submissions) in Hz
double game_fps;
double game_fps{};
/// Walltime per system frame, in seconds, excluding any waits
double frametime;
double frametime{};
/// Ratio of walltime / emulated time elapsed
double emulation_speed;
double emulation_speed{};
};
/**

View File

@@ -6,8 +6,6 @@
#include "core/core.h"
#include "core/gdbstub/gdbstub.h"
#include "core/hle/service/hid/hid.h"
#include "core/hle/service/lbl/lbl.h"
#include "core/hle/service/sm/sm.h"
#include "core/settings.h"
#include "video_core/renderer_base.h"
@@ -72,7 +70,6 @@ void Apply() {
auto& system_instance = Core::System::GetInstance();
if (system_instance.IsPoweredOn()) {
system_instance.Renderer().RefreshBaseSettings();
Service::LBL::RequestLoadCurrentSetting(system_instance.ServiceManager());
}
Service::HID::ReloadInputDevices();

View File

@@ -325,25 +325,25 @@ enum class ControllerType {
};
struct PlayerInput {
bool connected;
ControllerType type;
ButtonsRaw buttons;
AnalogsRaw analogs;
bool connected{};
ControllerType type{};
ButtonsRaw buttons{};
AnalogsRaw analogs{};
u32 body_color_right;
u32 button_color_right;
u32 body_color_left;
u32 button_color_left;
u32 body_color_right{};
u32 button_color_right{};
u32 body_color_left{};
u32 button_color_left{};
};
struct TouchscreenInput {
bool enabled;
bool enabled{};
std::string device;
u32 finger;
u32 diameter_x;
u32 diameter_y;
u32 rotation_angle;
u32 finger{};
u32 diameter_x{};
u32 diameter_y{};
u32 rotation_angle{};
};
enum class NANDTotalSize : u64 {
@@ -428,8 +428,6 @@ struct Values {
float bg_green;
float bg_blue;
float backlight_brightness = 0.5f;
std::string log_filter;
bool use_dev_keys;

View File

@@ -28,9 +28,9 @@ namespace Tools {
class Freezer {
public:
struct Entry {
VAddr address;
u32 width;
u64 value;
VAddr address{};
u32 width{};
u64 value{};
};
explicit Freezer(Core::Timing::CoreTiming& core_timing);

View File

@@ -29,7 +29,7 @@ private:
};
struct KeyButtonPair {
int key_code;
int key_code{};
KeyButton* key_button;
};

Some files were not shown because too many files have changed in this diff Show More