Merge branch 'master' into online
This commit is contained in:
@@ -480,7 +480,6 @@ create_target_directory_groups(citra_core)
|
||||
target_link_libraries(citra_core PUBLIC citra_common PRIVATE audio_core network video_core)
|
||||
target_link_libraries(citra_core PRIVATE Boost::boost Boost::serialization Boost::iostreams httplib)
|
||||
target_link_libraries(citra_core PUBLIC dds-ktx PRIVATE cryptopp fmt::fmt lodepng open_source_archives)
|
||||
set_target_properties(citra_core PROPERTIES INTERPROCEDURAL_OPTIMIZATION ${ENABLE_LTO})
|
||||
|
||||
if (ENABLE_WEB_SERVICE)
|
||||
target_link_libraries(citra_core PRIVATE web_service)
|
||||
|
||||
@@ -35,8 +35,7 @@ public:
|
||||
const auto r = GetCpuRegister(i);
|
||||
ar << r;
|
||||
}
|
||||
std::size_t fpu_reg_count = file_version == 0 ? 16 : 64;
|
||||
for (std::size_t i = 0; i < fpu_reg_count; i++) {
|
||||
for (std::size_t i = 0; i < 64; i++) {
|
||||
const auto r = GetFpuRegister(i);
|
||||
ar << r;
|
||||
}
|
||||
@@ -55,8 +54,7 @@ public:
|
||||
ar >> r;
|
||||
SetCpuRegister(i, r);
|
||||
}
|
||||
std::size_t fpu_reg_count = file_version == 0 ? 16 : 64;
|
||||
for (std::size_t i = 0; i < fpu_reg_count; i++) {
|
||||
for (std::size_t i = 0; i < 64; i++) {
|
||||
ar >> r;
|
||||
SetFpuRegister(i, r);
|
||||
}
|
||||
@@ -268,8 +266,7 @@ private:
|
||||
ar << pc;
|
||||
const auto cpsr = GetCPSR();
|
||||
ar << cpsr;
|
||||
int vfp_reg_count = file_version == 0 ? 32 : 64;
|
||||
for (int i = 0; i < vfp_reg_count; i++) {
|
||||
for (int i = 0; i < 64; i++) {
|
||||
const auto r = GetVFPReg(i);
|
||||
ar << r;
|
||||
}
|
||||
@@ -316,8 +313,7 @@ private:
|
||||
SetPC(r);
|
||||
ar >> r;
|
||||
SetCPSR(r);
|
||||
int vfp_reg_count = file_version == 0 ? 32 : 64;
|
||||
for (int i = 0; i < vfp_reg_count; i++) {
|
||||
for (int i = 0; i < 64; i++) {
|
||||
ar >> r;
|
||||
SetVFPReg(i, r);
|
||||
}
|
||||
|
||||
@@ -365,7 +365,9 @@ void ARM_Dynarmic::ServeBreak() {
|
||||
std::unique_ptr<Dynarmic::A32::Jit> ARM_Dynarmic::MakeJit() {
|
||||
Dynarmic::A32::UserConfig config;
|
||||
config.callbacks = cb.get();
|
||||
config.page_table = ¤t_page_table->GetPointerArray();
|
||||
if (current_page_table) {
|
||||
config.page_table = ¤t_page_table->GetPointerArray();
|
||||
}
|
||||
config.coprocessors[15] = std::make_shared<DynarmicCP15>(cp15_state);
|
||||
config.define_unpredictable_behaviour = true;
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(add)(unsigned int inst, int index) {
|
||||
|
||||
return inst_base;
|
||||
}
|
||||
static ARM_INST_PTR INTERPRETER_TRANSLATE(and)(unsigned int inst, int index) {
|
||||
static ARM_INST_PTR INTERPRETER_TRANSLATE (and)(unsigned int inst, int index) {
|
||||
arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(and_inst));
|
||||
and_inst* inst_cream = (and_inst*)inst_base->component;
|
||||
|
||||
|
||||
@@ -197,9 +197,9 @@ GatewayCheat::CheatLine::CheatLine(const std::string& line) {
|
||||
if (type_temp == "D" || type_temp == "d")
|
||||
sub_type_temp = line.substr(1, 1);
|
||||
type = static_cast<CheatType>(std::stoi(type_temp + sub_type_temp, 0, 16));
|
||||
first = std::stoul(line.substr(0, 8), 0, 16);
|
||||
first = static_cast<u32>(std::stoul(line.substr(0, 8), 0, 16));
|
||||
address = first & 0x0FFFFFFF;
|
||||
value = std::stoul(line.substr(9, 8), 0, 16);
|
||||
value = static_cast<u32>(std::stoul(line.substr(9, 8), 0, 16));
|
||||
cheat_line = line;
|
||||
} catch (const std::logic_error&) {
|
||||
type = CheatType::Null;
|
||||
|
||||
+1
-3
@@ -717,9 +717,7 @@ void System::serialize(Archive& ar, const unsigned int file_version) {
|
||||
ar&* memory.get();
|
||||
ar&* kernel.get();
|
||||
VideoCore::serialize(ar, file_version);
|
||||
if (file_version >= 1) {
|
||||
ar& movie;
|
||||
}
|
||||
ar& movie;
|
||||
|
||||
// This needs to be set from somewhere - might as well be here!
|
||||
if (Archive::is_loading::value) {
|
||||
|
||||
@@ -513,7 +513,7 @@ bool FFmpegAudioStream::Init(FFmpegMuxer& muxer) {
|
||||
}
|
||||
|
||||
if (codec_context->frame_size) {
|
||||
frame_size = static_cast<u64>(codec_context->frame_size);
|
||||
frame_size = codec_context->frame_size;
|
||||
} else { // variable frame size support
|
||||
frame_size = std::tuple_size<AudioCore::StereoFrame16>::value;
|
||||
}
|
||||
|
||||
@@ -184,7 +184,7 @@ Loader::ResultStatus FileSys::Plugin3GXLoader::Map(
|
||||
const u32 block_size = mem_region_sizes[header.infos.flags.memory_region_size.Value()];
|
||||
const u32 exe_size = (sizeof(PluginHeader) + text_section.size() + rodata_section.size() +
|
||||
data_section.size() + header.executable.bss_size + 0x1000) &
|
||||
~0xFFF;
|
||||
~0xFFFu;
|
||||
|
||||
// Allocate the framebuffer block so that is in the highest FCRAM position possible
|
||||
auto offset_fb =
|
||||
|
||||
@@ -12,6 +12,10 @@
|
||||
#include "core/3ds.h"
|
||||
#include "core/frontend/framebuffer_layout.h"
|
||||
|
||||
namespace Common {
|
||||
class DynamicLibrary;
|
||||
}
|
||||
|
||||
namespace Frontend {
|
||||
|
||||
/// Information for the Graphics Backends signifying what type of screen pointer is in
|
||||
@@ -82,6 +86,11 @@ public:
|
||||
/// Releases (dunno if this is the "right" word) the context from the caller thread
|
||||
virtual void DoneCurrent(){};
|
||||
|
||||
/// Gets the GPU driver library (used by Android only)
|
||||
virtual std::shared_ptr<Common::DynamicLibrary> GetDriverLibrary() {
|
||||
return {};
|
||||
}
|
||||
|
||||
class Scoped {
|
||||
public:
|
||||
explicit Scoped(GraphicsContext& context_) : context(context_) {
|
||||
|
||||
@@ -509,7 +509,8 @@ void SendReply(const char* reply) {
|
||||
u8* ptr = command_buffer;
|
||||
u32 left = command_length + 4;
|
||||
while (left > 0) {
|
||||
int sent_size = send(gdbserver_socket, reinterpret_cast<char*>(ptr), left, 0);
|
||||
s32 sent_size =
|
||||
static_cast<s32>(send(gdbserver_socket, reinterpret_cast<char*>(ptr), left, 0));
|
||||
if (sent_size < 0) {
|
||||
LOG_ERROR(Debug_GDBStub, "gdb: send failed");
|
||||
return Shutdown();
|
||||
|
||||
@@ -90,7 +90,7 @@ MiiResult MiiSelector::GetStandardMiiResult() {
|
||||
// the LLEd Mii picker of version system version 11.8.0 to a file and then matching the values
|
||||
// to the members of the MiiResult struct
|
||||
Mii::MiiData mii_data;
|
||||
mii_data.magic = 0x03;
|
||||
mii_data.version = 0x03;
|
||||
mii_data.mii_options.raw = 0x00;
|
||||
mii_data.mii_pos.raw = 0x10;
|
||||
mii_data.console_identity.raw = 0x30;
|
||||
@@ -114,7 +114,7 @@ MiiResult MiiSelector::GetStandardMiiResult() {
|
||||
mii_data.beard_details.raw = 0x0029;
|
||||
mii_data.glasses_details.raw = 0x0052;
|
||||
mii_data.mole_details.raw = 0x4850;
|
||||
mii_data.author_name = {'f', 'l', 'T', 'o', 'b', 'i', 0x0, 0x0, 0x0, 0x0};
|
||||
mii_data.author_name = {u'f', u'l', u'T', u'o', u'b', u'i'};
|
||||
|
||||
MiiResult result;
|
||||
result.return_code = 0x0;
|
||||
|
||||
@@ -79,29 +79,13 @@ private:
|
||||
void WakeUp(ThreadWakeupReason reason, std::shared_ptr<Thread> thread,
|
||||
std::shared_ptr<WaitObject> object) override;
|
||||
|
||||
class DummyCallback : public WakeupCallback {
|
||||
public:
|
||||
void WakeUp(ThreadWakeupReason reason, std::shared_ptr<Thread> thread,
|
||||
std::shared_ptr<WaitObject> object) override {}
|
||||
};
|
||||
|
||||
friend class boost::serialization::access;
|
||||
template <class Archive>
|
||||
void serialize(Archive& ar, const unsigned int file_version) {
|
||||
ar& boost::serialization::base_object<Object>(*this);
|
||||
if (file_version == 1) {
|
||||
// This rigmarole is needed because in past versions, AddressArbiter inherited
|
||||
// WakeupCallback But it turns out this breaks shared_from_this, so we split it out.
|
||||
// Using a dummy class to deserialize a base_object allows compatibility to be
|
||||
// maintained.
|
||||
DummyCallback x;
|
||||
ar& boost::serialization::base_object<WakeupCallback>(x);
|
||||
}
|
||||
ar& name;
|
||||
ar& waiting_threads;
|
||||
if (file_version > 1) {
|
||||
ar& timeout_callback;
|
||||
}
|
||||
ar& timeout_callback;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+41
-36
@@ -11,10 +11,12 @@
|
||||
|
||||
namespace Mii {
|
||||
|
||||
using Nickname = std::array<char16_t, 10>;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
// Reference: https://github.com/devkitPro/libctru/blob/master/libctru/include/3ds/mii.h
|
||||
struct MiiData {
|
||||
u8 magic; ///< Always 3?
|
||||
u8 version; ///< Always 3?
|
||||
|
||||
/// Mii options
|
||||
union {
|
||||
@@ -52,23 +54,23 @@ struct MiiData {
|
||||
union {
|
||||
u16_be raw;
|
||||
|
||||
BitField<0, 1, u16> sex; ///< Sex of Mii (False=Male, True=Female)
|
||||
BitField<1, 4, u16> bday_month; ///< Month of Mii's birthday
|
||||
BitField<5, 5, u16> bday_day; ///< Day of Mii's birthday
|
||||
BitField<10, 4, u16> shirt_color; ///< Color of Mii's shirt
|
||||
BitField<14, 1, u16> favorite; ///< Whether the Mii is one of your 10 favorite Mii's
|
||||
BitField<0, 1, u16> gender; ///< Gender of Mii (0=Male, 1=Female)
|
||||
BitField<1, 4, u16> bday_month; ///< Month of Mii's birthday
|
||||
BitField<5, 5, u16> bday_day; ///< Day of Mii's birthday
|
||||
BitField<10, 4, u16> favorite_color; ///< Color of Mii's shirt
|
||||
BitField<14, 1, u16> favorite; ///< Whether the Mii is one of your 10 favorite Mii's
|
||||
} mii_details;
|
||||
|
||||
std::array<u16_le, 10> mii_name; ///< Name of Mii (Encoded using UTF16)
|
||||
u8 height; ///< How tall the Mii is
|
||||
u8 width; ///< How wide the Mii is
|
||||
Nickname mii_name; ///< Name of Mii (Encoded using UTF16)
|
||||
u8 height; ///< How tall the Mii is
|
||||
u8 width; ///< How wide the Mii is
|
||||
|
||||
/// Face style
|
||||
union {
|
||||
u8 raw;
|
||||
|
||||
BitField<0, 1, u8> disable_sharing; ///< Whether or not Sharing of the Mii is allowed
|
||||
BitField<1, 4, u8> shape; ///< Face shape
|
||||
BitField<1, 4, u8> type; ///< Face type
|
||||
BitField<5, 3, u8> skin_color; ///< Color of skin
|
||||
} face_style;
|
||||
|
||||
@@ -94,13 +96,13 @@ struct MiiData {
|
||||
union {
|
||||
u32_be raw;
|
||||
|
||||
BitField<0, 6, u32> style;
|
||||
BitField<0, 6, u32> type;
|
||||
BitField<6, 3, u32> color;
|
||||
BitField<9, 4, u32> scale;
|
||||
BitField<13, 3, u32> y_scale;
|
||||
BitField<16, 5, u32> rotation;
|
||||
BitField<21, 4, u32> x_spacing;
|
||||
BitField<25, 5, u32> y_position;
|
||||
BitField<13, 3, u32> aspect;
|
||||
BitField<16, 5, u32> rotate;
|
||||
BitField<21, 4, u32> x;
|
||||
BitField<25, 5, u32> y;
|
||||
} eye_details;
|
||||
|
||||
/// Eyebrow details
|
||||
@@ -110,72 +112,70 @@ struct MiiData {
|
||||
BitField<0, 5, u32> style;
|
||||
BitField<5, 3, u32> color;
|
||||
BitField<8, 4, u32> scale;
|
||||
BitField<12, 3, u32> y_scale;
|
||||
BitField<15, 1, u32> pad;
|
||||
BitField<16, 5, u32> rotation;
|
||||
BitField<21, 4, u32> x_spacing;
|
||||
BitField<25, 5, u32> y_position;
|
||||
BitField<12, 3, u32> aspect;
|
||||
BitField<16, 5, u32> rotate;
|
||||
BitField<21, 4, u32> x;
|
||||
BitField<25, 5, u32> y;
|
||||
} eyebrow_details;
|
||||
|
||||
/// Nose details
|
||||
union {
|
||||
u16_be raw;
|
||||
|
||||
BitField<0, 5, u16> style;
|
||||
BitField<0, 5, u16> type;
|
||||
BitField<5, 4, u16> scale;
|
||||
BitField<9, 5, u16> y_position;
|
||||
BitField<9, 5, u16> y;
|
||||
} nose_details;
|
||||
|
||||
/// Mouth details
|
||||
union {
|
||||
u16_be raw;
|
||||
|
||||
BitField<0, 6, u16> style;
|
||||
BitField<0, 6, u16> type;
|
||||
BitField<6, 3, u16> color;
|
||||
BitField<9, 4, u16> scale;
|
||||
BitField<13, 3, u16> y_scale;
|
||||
BitField<13, 3, u16> aspect;
|
||||
} mouth_details;
|
||||
|
||||
/// Mustache details
|
||||
union {
|
||||
u16_be raw;
|
||||
|
||||
BitField<0, 5, u16> mouth_yposition;
|
||||
BitField<5, 3, u16> mustach_style;
|
||||
BitField<8, 2, u16> pad;
|
||||
BitField<0, 5, u16> mouth_y;
|
||||
BitField<5, 3, u16> mustache_type;
|
||||
} mustache_details;
|
||||
|
||||
/// Beard details
|
||||
union {
|
||||
u16_be raw;
|
||||
|
||||
BitField<0, 3, u16> style;
|
||||
BitField<0, 3, u16> type;
|
||||
BitField<3, 3, u16> color;
|
||||
BitField<6, 4, u16> scale;
|
||||
BitField<10, 5, u16> y_pos;
|
||||
BitField<10, 5, u16> y;
|
||||
} beard_details;
|
||||
|
||||
/// Glasses details
|
||||
union {
|
||||
u16_be raw;
|
||||
|
||||
BitField<0, 4, u16> style;
|
||||
BitField<0, 4, u16> type;
|
||||
BitField<4, 3, u16> color;
|
||||
BitField<7, 4, u16> scale;
|
||||
BitField<11, 5, u16> y_pos;
|
||||
BitField<11, 5, u16> y;
|
||||
} glasses_details;
|
||||
|
||||
/// Mole details
|
||||
union {
|
||||
u16_be raw;
|
||||
|
||||
BitField<0, 1, u16> enable;
|
||||
BitField<1, 5, u16> scale;
|
||||
BitField<6, 5, u16> x_pos;
|
||||
BitField<11, 5, u16> y_pos;
|
||||
BitField<0, 1, u16> type;
|
||||
BitField<1, 4, u16> scale;
|
||||
BitField<5, 5, u16> x;
|
||||
BitField<10, 5, u16> y;
|
||||
} mole_details;
|
||||
|
||||
std::array<u16_le, 10> author_name; ///< Name of Mii's author (Encoded using UTF16)
|
||||
Nickname author_name; ///< Name of Mii's author (Encoded using UTF16)
|
||||
private:
|
||||
template <class Archive>
|
||||
void serialize(Archive& ar, const unsigned int) {
|
||||
@@ -209,6 +209,11 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
void SetMiiData(MiiData data) {
|
||||
mii_data = data;
|
||||
FixChecksum();
|
||||
}
|
||||
|
||||
operator MiiData() const {
|
||||
return mii_data;
|
||||
}
|
||||
|
||||
@@ -589,7 +589,7 @@ std::string GetTitleMetadataPath(Service::FS::MediaType media_type, u64 tid, boo
|
||||
Common::SplitPath(entry.virtualName, nullptr, &filename_filename, &filename_extension);
|
||||
|
||||
if (filename_extension == ".tmd") {
|
||||
const u32 id = std::stoul(filename_filename, nullptr, 16);
|
||||
const u32 id = static_cast<u32>(std::stoul(filename_filename, nullptr, 16));
|
||||
base_id = std::min(base_id, id);
|
||||
update_id = std::max(update_id, id);
|
||||
}
|
||||
|
||||
@@ -188,9 +188,7 @@ private:
|
||||
void serialize(Archive& ar, const unsigned int file_version) {
|
||||
ar& next_title_id;
|
||||
ar& next_media_type;
|
||||
if (file_version > 0) {
|
||||
ar& flags;
|
||||
}
|
||||
ar& flags;
|
||||
ar& current_title_id;
|
||||
ar& current_media_type;
|
||||
}
|
||||
@@ -517,25 +515,23 @@ private:
|
||||
void serialize(Archive& ar, const unsigned int file_version) {
|
||||
ar& next_parameter;
|
||||
ar& app_jump_parameters;
|
||||
if (file_version > 0) {
|
||||
ar& delayed_parameter;
|
||||
ar& app_start_parameters;
|
||||
ar& deliver_arg;
|
||||
ar& capture_info;
|
||||
ar& capture_buffer_info;
|
||||
ar& active_slot;
|
||||
ar& last_library_launcher_slot;
|
||||
ar& last_prepared_library_applet;
|
||||
ar& last_system_launcher_slot;
|
||||
ar& last_jump_to_home_slot;
|
||||
ar& ordered_to_close_sys_applet;
|
||||
ar& ordered_to_close_application;
|
||||
ar& application_cancelled;
|
||||
ar& application_close_target;
|
||||
ar& new_3ds_mode_blocked;
|
||||
ar& lock;
|
||||
ar& capture_info;
|
||||
}
|
||||
ar& delayed_parameter;
|
||||
ar& app_start_parameters;
|
||||
ar& deliver_arg;
|
||||
ar& capture_info;
|
||||
ar& capture_buffer_info;
|
||||
ar& active_slot;
|
||||
ar& last_library_launcher_slot;
|
||||
ar& last_prepared_library_applet;
|
||||
ar& last_system_launcher_slot;
|
||||
ar& last_jump_to_home_slot;
|
||||
ar& ordered_to_close_sys_applet;
|
||||
ar& ordered_to_close_application;
|
||||
ar& application_cancelled;
|
||||
ar& application_close_target;
|
||||
ar& new_3ds_mode_blocked;
|
||||
ar& lock;
|
||||
ar& capture_info;
|
||||
ar& applet_slots;
|
||||
ar& library_applet_closing_command;
|
||||
|
||||
|
||||
@@ -48,9 +48,7 @@ void Module::serialize(Archive& ar, const unsigned int file_version) {
|
||||
ar& cpu_percent;
|
||||
ar& screen_capture_post_permission;
|
||||
ar& applet_manager;
|
||||
if (file_version > 0) {
|
||||
ar& wireless_reboot_info;
|
||||
}
|
||||
ar& wireless_reboot_info;
|
||||
}
|
||||
|
||||
SERIALIZE_IMPL(Module)
|
||||
|
||||
@@ -30,11 +30,7 @@ void Module::serialize(Archive& ar, const unsigned int file_version) {
|
||||
ar& cameras;
|
||||
ar& ports;
|
||||
ar& is_camera_reload_pending;
|
||||
if (file_version > 0) {
|
||||
ar& initialized;
|
||||
} else {
|
||||
initialized = true;
|
||||
}
|
||||
ar& initialized;
|
||||
if (Archive::is_loading::value && initialized) {
|
||||
for (int i = 0; i < NumCameras; i++) {
|
||||
LoadCameraImplementation(cameras[i], i);
|
||||
|
||||
@@ -681,11 +681,6 @@ private:
|
||||
private:
|
||||
template <class Archive>
|
||||
void serialize(Archive& ar, const unsigned int file_version) {
|
||||
// For compatibility: put a nullptr here
|
||||
if (file_version == 0) {
|
||||
std::unique_ptr<Camera::CameraInterface> x;
|
||||
ar& x;
|
||||
}
|
||||
ar& contexts;
|
||||
ar& current_context;
|
||||
ar& frame_rate;
|
||||
|
||||
@@ -124,8 +124,9 @@ void Module::Interface::Open(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_CECD,
|
||||
"called, ncch_program_id={:#010x}, path_type={:#04x}, path={}, "
|
||||
"open_mode: raw={:#x}, unknown={}, read={}, write={}, create={}, check={}",
|
||||
ncch_program_id, path_type, path.AsString(), open_mode.raw, open_mode.unknown,
|
||||
open_mode.read, open_mode.write, open_mode.create, open_mode.check);
|
||||
ncch_program_id, path_type, path.AsString(), open_mode.raw, open_mode.unknown.Value(),
|
||||
open_mode.read.Value(), open_mode.write.Value(), open_mode.create.Value(),
|
||||
open_mode.check.Value());
|
||||
}
|
||||
|
||||
void Module::Interface::Read(Kernel::HLERequestContext& ctx) {
|
||||
@@ -139,9 +140,9 @@ void Module::Interface::Read(Kernel::HLERequestContext& ctx) {
|
||||
"path={}, open_mode: raw={:#x}, unknown={}, read={}, write={}, create={}, check={}",
|
||||
session_data->ncch_program_id, session_data->data_path_type,
|
||||
session_data->path.AsString(), session_data->open_mode.raw,
|
||||
session_data->open_mode.unknown, session_data->open_mode.read,
|
||||
session_data->open_mode.write, session_data->open_mode.create,
|
||||
session_data->open_mode.check);
|
||||
session_data->open_mode.unknown.Value(), session_data->open_mode.read.Value(),
|
||||
session_data->open_mode.write.Value(), session_data->open_mode.create.Value(),
|
||||
session_data->open_mode.check.Value());
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(2, 2);
|
||||
switch (session_data->data_path_type) {
|
||||
@@ -344,9 +345,9 @@ void Module::Interface::Write(Kernel::HLERequestContext& ctx) {
|
||||
"path={}, open_mode: raw={:#x}, unknown={}, read={}, write={}, create={}, check={}",
|
||||
session_data->ncch_program_id, session_data->data_path_type,
|
||||
session_data->path.AsString(), session_data->open_mode.raw,
|
||||
session_data->open_mode.unknown, session_data->open_mode.read,
|
||||
session_data->open_mode.write, session_data->open_mode.create,
|
||||
session_data->open_mode.check);
|
||||
session_data->open_mode.unknown.Value(), session_data->open_mode.read.Value(),
|
||||
session_data->open_mode.write.Value(), session_data->open_mode.create.Value(),
|
||||
session_data->open_mode.check.Value());
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
|
||||
switch (session_data->data_path_type) {
|
||||
@@ -778,8 +779,8 @@ void Module::Interface::OpenAndWrite(Kernel::HLERequestContext& ctx) {
|
||||
"called, ncch_program_id={:#010x}, path_type={:#04x}, path={}, buffer_size={:#x} "
|
||||
"open_mode: raw={:#x}, unknown={}, read={}, write={}, create={}, check={}",
|
||||
ncch_program_id, path_type, path.AsString(), buffer_size, open_mode.raw,
|
||||
open_mode.unknown, open_mode.read, open_mode.write, open_mode.create,
|
||||
open_mode.check);
|
||||
open_mode.unknown.Value(), open_mode.read.Value(), open_mode.write.Value(),
|
||||
open_mode.create.Value(), open_mode.check.Value());
|
||||
}
|
||||
|
||||
void Module::Interface::OpenAndRead(Kernel::HLERequestContext& ctx) {
|
||||
@@ -831,8 +832,8 @@ void Module::Interface::OpenAndRead(Kernel::HLERequestContext& ctx) {
|
||||
"called, ncch_program_id={:#010x}, path_type={:#04x}, path={}, buffer_size={:#x} "
|
||||
"open_mode: raw={:#x}, unknown={}, read={}, write={}, create={}, check={}",
|
||||
ncch_program_id, path_type, path.AsString(), buffer_size, open_mode.raw,
|
||||
open_mode.unknown, open_mode.read, open_mode.write, open_mode.create,
|
||||
open_mode.check);
|
||||
open_mode.unknown.Value(), open_mode.read.Value(), open_mode.write.Value(),
|
||||
open_mode.create.Value(), open_mode.check.Value());
|
||||
}
|
||||
|
||||
std::string Module::EncodeBase64(std::span<const u8> in) const {
|
||||
|
||||
@@ -309,7 +309,7 @@ void DSP_DSP::ForceHeadphoneOut(Kernel::HLERequestContext& ctx) {
|
||||
// that's waiting for an interrupt event. Immediately after this interrupt event, userland
|
||||
// normally updates the state in the next region and increments the relevant frame counter by two.
|
||||
void DSP_DSP::SignalInterrupt(InterruptType type, DspPipe pipe) {
|
||||
LOG_DEBUG(Service_DSP, "called, type={}, pipe={}", type, pipe);
|
||||
LOG_TRACE(Service_DSP, "called, type={}, pipe={}", type, pipe);
|
||||
const auto& event = GetInterruptEvent(type, pipe);
|
||||
if (event)
|
||||
event->Signal();
|
||||
|
||||
@@ -336,31 +336,31 @@ void GSP_GPU::SetBufferSwap(Kernel::HLERequestContext& ctx) {
|
||||
|
||||
void GSP_GPU::FlushDataCache(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx);
|
||||
u32 address = rp.Pop<u32>();
|
||||
u32 size = rp.Pop<u32>();
|
||||
auto process = rp.PopObject<Kernel::Process>();
|
||||
[[maybe_unused]] u32 address = rp.Pop<u32>();
|
||||
[[maybe_unused]] u32 size = rp.Pop<u32>();
|
||||
[[maybe_unused]] auto process = rp.PopObject<Kernel::Process>();
|
||||
|
||||
// TODO(purpasmart96): Verify return header on HW
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
LOG_DEBUG(Service_GSP, "(STUBBED) called address=0x{:08X}, size=0x{:08X}, process={}", address,
|
||||
LOG_TRACE(Service_GSP, "(STUBBED) called address=0x{:08X}, size=0x{:08X}, process={}", address,
|
||||
size, process->process_id);
|
||||
}
|
||||
|
||||
void GSP_GPU::InvalidateDataCache(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx);
|
||||
u32 address = rp.Pop<u32>();
|
||||
u32 size = rp.Pop<u32>();
|
||||
auto process = rp.PopObject<Kernel::Process>();
|
||||
[[maybe_unused]] u32 address = rp.Pop<u32>();
|
||||
[[maybe_unused]] u32 size = rp.Pop<u32>();
|
||||
[[maybe_unused]] auto process = rp.PopObject<Kernel::Process>();
|
||||
|
||||
// TODO(purpasmart96): Verify return header on HW
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
LOG_DEBUG(Service_GSP, "(STUBBED) called address=0x{:08X}, size=0x{:08X}, process={}", address,
|
||||
LOG_TRACE(Service_GSP, "(STUBBED) called address=0x{:08X}, size=0x{:08X}, process={}", address,
|
||||
size, process->process_id);
|
||||
}
|
||||
|
||||
@@ -840,14 +840,14 @@ void GSP_GPU::ReleaseRight(Kernel::HLERequestContext& ctx) {
|
||||
void GSP_GPU::StoreDataCache(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx);
|
||||
|
||||
u32 address = rp.Pop<u32>();
|
||||
u32 size = rp.Pop<u32>();
|
||||
[[maybe_unused]] u32 address = rp.Pop<u32>();
|
||||
[[maybe_unused]] u32 size = rp.Pop<u32>();
|
||||
auto process = rp.PopObject<Kernel::Process>();
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
LOG_DEBUG(Service_GSP, "(STUBBED) called address=0x{:08X}, size=0x{:08X}, process={}", address,
|
||||
LOG_TRACE(Service_GSP, "(STUBBED) called address=0x{:08X}, size=0x{:08X}, process={}", address,
|
||||
size, process->process_id);
|
||||
}
|
||||
|
||||
|
||||
@@ -46,9 +46,7 @@ void Module::serialize(Archive& ar, const unsigned int file_version) {
|
||||
if (Archive::is_loading::value) {
|
||||
LoadInputDevices();
|
||||
}
|
||||
if (file_version >= 1) {
|
||||
ar& state.hex;
|
||||
}
|
||||
ar& state.hex;
|
||||
// Update events are set in the constructor
|
||||
// Devices are set from the implementation (and are stateless afaik)
|
||||
}
|
||||
|
||||
@@ -400,18 +400,16 @@ private:
|
||||
ar& clamp;
|
||||
// mic interface set in constructor
|
||||
ar& state;
|
||||
if (file_version > 0) {
|
||||
// Maintain the internal mic state
|
||||
ar& encoding;
|
||||
bool is_sampling = mic && mic->IsSampling();
|
||||
ar& is_sampling;
|
||||
if (Archive::is_loading::value) {
|
||||
if (is_sampling) {
|
||||
CreateMic();
|
||||
StartSampling();
|
||||
} else if (mic) {
|
||||
mic->StopSampling();
|
||||
}
|
||||
// Maintain the internal mic state
|
||||
ar& encoding;
|
||||
bool is_sampling = mic && mic->IsSampling();
|
||||
ar& is_sampling;
|
||||
if (Archive::is_loading::value) {
|
||||
if (is_sampling) {
|
||||
CreateMic();
|
||||
StartSampling();
|
||||
} else if (mic) {
|
||||
mic->StopSampling();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,8 +155,8 @@ void ServiceFrameworkBase::ReportUnimplementedFunction(u32* cmd_buf, const Funct
|
||||
|
||||
std::string result =
|
||||
fmt::format("function '{}': port='{}' cmd_buf={{[0]={:#x} (0x{:04X}, {}, {})",
|
||||
function_name, service_name, header.raw, header.command_id,
|
||||
header.normal_params_size, header.translate_params_size);
|
||||
function_name, service_name, header.raw, header.command_id.Value(),
|
||||
header.normal_params_size.Value(), header.translate_params_size.Value());
|
||||
for (int i = 1; i <= num_params; ++i) {
|
||||
result += fmt::format(", [{}]={:#x}", i, cmd_buf[i]);
|
||||
}
|
||||
|
||||
@@ -982,11 +982,13 @@ void SOC_U::SendToOther(Kernel::HLERequestContext& ctx) {
|
||||
CTRSockAddr ctr_dest_addr;
|
||||
std::memcpy(&ctr_dest_addr, dest_addr_buffer.data(), sizeof(ctr_dest_addr));
|
||||
sockaddr dest_addr = CTRSockAddr::ToPlatform(ctr_dest_addr);
|
||||
ret = ::sendto(fd_info->second.socket_fd, reinterpret_cast<const char*>(input_buff.data()),
|
||||
len, flags, &dest_addr, sizeof(dest_addr));
|
||||
ret = static_cast<s32>(::sendto(fd_info->second.socket_fd,
|
||||
reinterpret_cast<const char*>(input_buff.data()), len,
|
||||
flags, &dest_addr, sizeof(dest_addr)));
|
||||
} else {
|
||||
ret = ::sendto(fd_info->second.socket_fd, reinterpret_cast<const char*>(input_buff.data()),
|
||||
len, flags, nullptr, 0);
|
||||
ret = static_cast<s32>(::sendto(fd_info->second.socket_fd,
|
||||
reinterpret_cast<const char*>(input_buff.data()), len,
|
||||
flags, nullptr, 0));
|
||||
}
|
||||
|
||||
const auto send_error = (ret == SOCKET_ERROR_VALUE) ? GET_ERRNO : 0;
|
||||
@@ -1040,11 +1042,13 @@ void SOC_U::SendTo(Kernel::HLERequestContext& ctx) {
|
||||
CTRSockAddr ctr_dest_addr;
|
||||
std::memcpy(&ctr_dest_addr, dest_addr_buff.data(), sizeof(ctr_dest_addr));
|
||||
sockaddr dest_addr = CTRSockAddr::ToPlatform(ctr_dest_addr);
|
||||
ret = ::sendto(fd_info->second.socket_fd, reinterpret_cast<const char*>(input_buff.data()),
|
||||
len, flags, &dest_addr, sizeof(dest_addr));
|
||||
ret = static_cast<s32>(::sendto(fd_info->second.socket_fd,
|
||||
reinterpret_cast<const char*>(input_buff.data()), len,
|
||||
flags, &dest_addr, sizeof(dest_addr)));
|
||||
} else {
|
||||
ret = ::sendto(fd_info->second.socket_fd, reinterpret_cast<const char*>(input_buff.data()),
|
||||
len, flags, nullptr, 0);
|
||||
ret = static_cast<s32>(::sendto(fd_info->second.socket_fd,
|
||||
reinterpret_cast<const char*>(input_buff.data()), len,
|
||||
flags, nullptr, 0));
|
||||
}
|
||||
|
||||
auto send_error = (ret == SOCKET_ERROR_VALUE) ? GET_ERRNO : 0;
|
||||
@@ -1818,7 +1822,11 @@ std::optional<SOC_U::InterfaceInfo> SOC_U::GetDefaultInterfaceInfo() {
|
||||
}
|
||||
|
||||
InterfaceInfo ret;
|
||||
s64 sock_fd = -1;
|
||||
#ifdef _WIN32
|
||||
SOCKET sock_fd = -1;
|
||||
#else
|
||||
int sock_fd = -1;
|
||||
#endif
|
||||
bool interface_found = false;
|
||||
struct sockaddr_in s_in = {.sin_family = AF_INET, .sin_port = htons(53), .sin_addr = {}};
|
||||
s_in.sin_addr.s_addr = inet_addr("8.8.8.8");
|
||||
|
||||
+9
-1
@@ -128,7 +128,7 @@ static void MemoryFill(const Regs::MemoryFillConfig& config) {
|
||||
|
||||
static void DisplayTransfer(const Regs::DisplayTransferConfig& config) {
|
||||
const PAddr src_addr = config.GetPhysicalInputAddress();
|
||||
const PAddr dst_addr = config.GetPhysicalOutputAddress();
|
||||
PAddr dst_addr = config.GetPhysicalOutputAddress();
|
||||
|
||||
// TODO: do hwtest with these cases
|
||||
if (!g_memory->IsValidPhysicalAddress(src_addr)) {
|
||||
@@ -164,6 +164,14 @@ static void DisplayTransfer(const Regs::DisplayTransferConfig& config) {
|
||||
if (VideoCore::g_renderer->Rasterizer()->AccelerateDisplayTransfer(config))
|
||||
return;
|
||||
|
||||
// Using flip_vertically alongside crop_input_lines produces skewed output on hardware.
|
||||
// We have to emulate this because some games rely on this behaviour to render correctly.
|
||||
if (config.flip_vertically && config.crop_input_lines &&
|
||||
config.input_width > config.output_width) {
|
||||
dst_addr += (config.input_width - config.output_width) * (config.output_height - 1) *
|
||||
GPU::Regs::BytesPerPixel(config.output_format);
|
||||
}
|
||||
|
||||
u8* src_pointer = g_memory->GetPhysicalPointer(src_addr);
|
||||
u8* dst_pointer = g_memory->GetPhysicalPointer(dst_addr);
|
||||
|
||||
|
||||
+1
-1
@@ -186,7 +186,7 @@ struct Regs {
|
||||
return fmt::format("from {:#x} to {:#x} with {} scaling and stride {}, width {}",
|
||||
GetPhysicalInputAddress(), GetPhysicalOutputAddress(),
|
||||
scaling == NoScale ? "no" : (scaling == ScaleX ? "X" : "XY"),
|
||||
input_width, output_width);
|
||||
input_width.Value(), output_width.Value());
|
||||
}
|
||||
|
||||
union {
|
||||
|
||||
+12
-19
@@ -153,37 +153,30 @@ void Movie::serialize(Archive& ar, const unsigned int file_version) {
|
||||
u64 _current_byte = static_cast<u64>(current_byte);
|
||||
ar& _current_byte;
|
||||
current_byte = static_cast<std::size_t>(_current_byte);
|
||||
|
||||
if (file_version > 0) {
|
||||
ar& current_input;
|
||||
}
|
||||
ar& current_input;
|
||||
|
||||
std::vector<u8> recorded_input_ = recorded_input;
|
||||
ar& recorded_input_;
|
||||
|
||||
ar& init_time;
|
||||
|
||||
if (file_version > 0) {
|
||||
if (Archive::is_loading::value) {
|
||||
u64 savestate_movie_id;
|
||||
ar& savestate_movie_id;
|
||||
if (id != savestate_movie_id) {
|
||||
if (savestate_movie_id == 0) {
|
||||
throw std::runtime_error("You must close your movie to load this state");
|
||||
} else {
|
||||
throw std::runtime_error("You must load the same movie to load this state");
|
||||
}
|
||||
if (Archive::is_loading::value) {
|
||||
u64 savestate_movie_id;
|
||||
ar& savestate_movie_id;
|
||||
if (id != savestate_movie_id) {
|
||||
if (savestate_movie_id == 0) {
|
||||
throw std::runtime_error("You must close your movie to load this state");
|
||||
} else {
|
||||
throw std::runtime_error("You must load the same movie to load this state");
|
||||
}
|
||||
} else {
|
||||
ar& id;
|
||||
}
|
||||
} else {
|
||||
ar& id;
|
||||
}
|
||||
|
||||
// Whether the state was made in MovieFinished state
|
||||
bool post_movie = play_mode == PlayMode::MovieFinished;
|
||||
if (file_version > 0) {
|
||||
ar& post_movie;
|
||||
}
|
||||
ar& post_movie;
|
||||
|
||||
if (Archive::is_loading::value && id != 0) {
|
||||
if (!read_only) {
|
||||
|
||||
Reference in New Issue
Block a user