Compare commits
28 Commits
__refs_pul
...
__refs_pul
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f64ab04ac6 | ||
|
|
bec7e3b7d9 | ||
|
|
727ba2f2d0 | ||
|
|
11e39da02b | ||
|
|
23cabc98db | ||
|
|
658489ebf7 | ||
|
|
9293c3a0f2 | ||
|
|
04b838c857 | ||
|
|
2382bbe3ac | ||
|
|
b5138f3c35 | ||
|
|
a81bd962ab | ||
|
|
3d0cde6a75 | ||
|
|
ce20ed8e4e | ||
|
|
3c6557c235 | ||
|
|
d3651b0b82 | ||
|
|
c7698d0bc8 | ||
|
|
a14d202ac2 | ||
|
|
28fece8e9b | ||
|
|
2ec5b55ee3 | ||
|
|
6c8f28813c | ||
|
|
fa31e5b868 | ||
|
|
538ddd220e | ||
|
|
961fe4d19b | ||
|
|
f19c1a7cda | ||
|
|
2fb0bbff29 | ||
|
|
2dc469ceba | ||
|
|
bd2aff3e26 | ||
|
|
bb207fe27a |
@@ -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");
|
||||
|
||||
@@ -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>;
|
||||
|
||||
@@ -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__)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -29,7 +29,7 @@ struct SpecialRegion {
|
||||
enum class Type {
|
||||
DebugHook,
|
||||
IODevice,
|
||||
} type;
|
||||
} type{};
|
||||
|
||||
MemoryHookPointer handler;
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ struct WebResult {
|
||||
WrongContent,
|
||||
NoWebservice,
|
||||
};
|
||||
Code result_code;
|
||||
Code result_code{};
|
||||
std::string result_string;
|
||||
std::string returned_data;
|
||||
};
|
||||
|
||||
@@ -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{};
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.");
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.");
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -22,8 +22,8 @@ enum class BreakpointType {
|
||||
};
|
||||
|
||||
struct BreakpointAddress {
|
||||
VAddr address;
|
||||
BreakpointType type;
|
||||
VAddr address{};
|
||||
BreakpointType type{};
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.");
|
||||
|
||||
@@ -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();
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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{};
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.");
|
||||
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.");
|
||||
|
||||
|
||||
@@ -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.");
|
||||
|
||||
|
||||
@@ -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.");
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.");
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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.");
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
namespace Service::Glue {
|
||||
|
||||
struct ARPManager::MapEntry {
|
||||
ApplicationLaunchProperty launch;
|
||||
ApplicationLaunchProperty launch{};
|
||||
std::vector<u8> control;
|
||||
};
|
||||
|
||||
|
||||
@@ -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.");
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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{};
|
||||
|
||||
@@ -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{};
|
||||
};
|
||||
|
||||
@@ -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{};
|
||||
|
||||
@@ -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{};
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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"} {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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{
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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(¶ms, input.data(), sizeof(IoctlSetNvmapFD));
|
||||
std::memcpy(¶ms, 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(¶ms, input.data(), sizeof(IoctlSubmit));
|
||||
LOG_WARNING(Service_NVDRV, "(STUBBED) called");
|
||||
std::memcpy(output.data(), ¶ms, sizeof(IoctlSubmit));
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 nvhost_nvdec::GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
IoctlGetSyncpoint params{};
|
||||
std::memcpy(¶ms, 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(), ¶ms, sizeof(IoctlGetSyncpoint));
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 nvhost_nvdec::GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
IoctlGetWaitbase params{};
|
||||
std::memcpy(¶ms, 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(), ¶ms, sizeof(IoctlGetWaitbase));
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 nvhost_nvdec::MapBuffer(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
IoctlMapBuffer params{};
|
||||
std::memcpy(¶ms, 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(), ¶ms, sizeof(IoctlMapBuffer));
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 nvhost_nvdec::MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
IoctlMapBufferEx params{};
|
||||
std::memcpy(¶ms, 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(), ¶ms, sizeof(IoctlMapBufferEx));
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 nvhost_nvdec::UnmapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
IoctlUnmapBufferEx params{};
|
||||
std::memcpy(¶ms, input.data(), sizeof(IoctlUnmapBufferEx));
|
||||
LOG_WARNING(Service_NVDRV, "(STUBBED) called");
|
||||
std::memcpy(output.data(), ¶ms, sizeof(IoctlUnmapBufferEx));
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace Service::Nvidia::Devices
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -26,7 +26,7 @@ private:
|
||||
};
|
||||
|
||||
struct IoctlSetNvmapFD {
|
||||
u32_le nvmap_fd;
|
||||
u32_le nvmap_fd{};
|
||||
};
|
||||
static_assert(sizeof(IoctlSetNvmapFD) == 4, "IoctlSetNvmapFD is incorrect size");
|
||||
|
||||
|
||||
@@ -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(¶ms, input.data(), sizeof(IoctlSetNvmapFD));
|
||||
std::memcpy(¶ms, 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(¶ms, input.data(), sizeof(IoctlSubmit));
|
||||
LOG_WARNING(Service_NVDRV, "(STUBBED) called");
|
||||
std::memcpy(output.data(), ¶ms, sizeof(IoctlSubmit));
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 nvhost_vic::GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
IoctlGetSyncpoint params{};
|
||||
std::memcpy(¶ms, 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(), ¶ms, sizeof(IoctlGetSyncpoint));
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 nvhost_vic::GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
IoctlGetWaitbase params{};
|
||||
std::memcpy(¶ms, 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(), ¶ms, sizeof(IoctlGetWaitbase));
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 nvhost_vic::MapBuffer(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
IoctlMapBuffer params{};
|
||||
std::memcpy(¶ms, 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(), ¶ms, sizeof(IoctlMapBuffer));
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 nvhost_vic::MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
IoctlMapBufferEx params{};
|
||||
std::memcpy(¶ms, 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(), ¶ms, sizeof(IoctlMapBufferEx));
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 nvhost_vic::UnmapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
IoctlUnmapBufferEx params{};
|
||||
std::memcpy(¶ms, input.data(), sizeof(IoctlUnmapBufferEx));
|
||||
LOG_WARNING(Service_NVDRV, "(STUBBED) called");
|
||||
std::memcpy(output.data(), ¶ms, sizeof(IoctlUnmapBufferEx));
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace Service::Nvidia::Devices
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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{};
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -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>>;
|
||||
|
||||
|
||||
@@ -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.");
|
||||
|
||||
|
||||
@@ -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.");
|
||||
|
||||
|
||||
@@ -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.");
|
||||
|
||||
|
||||
@@ -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{};
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user