diff options
Diffstat (limited to '')
-rw-r--r-- | src/core/file_sys/fsmitm_romfsbuild.cpp | 4 | ||||
-rw-r--r-- | src/core/file_sys/fsmitm_romfsbuild.h | 2 | ||||
-rw-r--r-- | src/core/file_sys/vfs_concat.cpp | 8 | ||||
-rw-r--r-- | src/core/file_sys/vfs_concat.h | 6 | ||||
-rw-r--r-- | src/core/hle/service/filesystem/filesystem.cpp | 4 | ||||
-rw-r--r-- | src/core/hle/service/mii/manager.cpp | 113 | ||||
-rw-r--r-- | src/core/memory/dmnt_cheat_vm.cpp | 29 | ||||
-rw-r--r-- | src/core/memory/dmnt_cheat_vm.h | 14 | ||||
-rw-r--r-- | src/core/settings.cpp | 2 | ||||
-rw-r--r-- | src/core/settings.h | 1 | ||||
-rw-r--r-- | src/core/telemetry_session.cpp | 2 |
11 files changed, 118 insertions, 67 deletions
diff --git a/src/core/file_sys/fsmitm_romfsbuild.cpp b/src/core/file_sys/fsmitm_romfsbuild.cpp index d126ae8dd..2aff2708a 100644 --- a/src/core/file_sys/fsmitm_romfsbuild.cpp +++ b/src/core/file_sys/fsmitm_romfsbuild.cpp @@ -240,7 +240,7 @@ RomFSBuildContext::RomFSBuildContext(VirtualDir base_, VirtualDir ext_) RomFSBuildContext::~RomFSBuildContext() = default; -std::map<u64, VirtualFile> RomFSBuildContext::Build() { +std::multimap<u64, VirtualFile> RomFSBuildContext::Build() { const u64 dir_hash_table_entry_count = romfs_get_hash_table_count(num_dirs); const u64 file_hash_table_entry_count = romfs_get_hash_table_count(num_files); dir_hash_table_size = 4 * dir_hash_table_entry_count; @@ -294,7 +294,7 @@ std::map<u64, VirtualFile> RomFSBuildContext::Build() { cur_dir->parent->child = cur_dir; } - std::map<u64, VirtualFile> out; + std::multimap<u64, VirtualFile> out; // Populate file tables. for (const auto& it : files) { diff --git a/src/core/file_sys/fsmitm_romfsbuild.h b/src/core/file_sys/fsmitm_romfsbuild.h index a62502193..049de180b 100644 --- a/src/core/file_sys/fsmitm_romfsbuild.h +++ b/src/core/file_sys/fsmitm_romfsbuild.h @@ -43,7 +43,7 @@ public: ~RomFSBuildContext(); // This finalizes the context. - std::map<u64, VirtualFile> Build(); + std::multimap<u64, VirtualFile> Build(); private: VirtualDir base; diff --git a/src/core/file_sys/vfs_concat.cpp b/src/core/file_sys/vfs_concat.cpp index 16d801c0c..e0ff70174 100644 --- a/src/core/file_sys/vfs_concat.cpp +++ b/src/core/file_sys/vfs_concat.cpp @@ -11,7 +11,7 @@ namespace FileSys { -static bool VerifyConcatenationMapContinuity(const std::map<u64, VirtualFile>& map) { +static bool VerifyConcatenationMapContinuity(const std::multimap<u64, VirtualFile>& map) { const auto last_valid = --map.end(); for (auto iter = map.begin(); iter != last_valid;) { const auto old = iter++; @@ -27,12 +27,12 @@ ConcatenatedVfsFile::ConcatenatedVfsFile(std::vector<VirtualFile> files_, std::s : name(std::move(name)) { std::size_t next_offset = 0; for (const auto& file : files_) { - files[next_offset] = file; + files.emplace(next_offset, file); next_offset += file->GetSize(); } } -ConcatenatedVfsFile::ConcatenatedVfsFile(std::map<u64, VirtualFile> files_, std::string name) +ConcatenatedVfsFile::ConcatenatedVfsFile(std::multimap<u64, VirtualFile> files_, std::string name) : files(std::move(files_)), name(std::move(name)) { ASSERT(VerifyConcatenationMapContinuity(files)); } @@ -50,7 +50,7 @@ VirtualFile ConcatenatedVfsFile::MakeConcatenatedFile(std::vector<VirtualFile> f } VirtualFile ConcatenatedVfsFile::MakeConcatenatedFile(u8 filler_byte, - std::map<u64, VirtualFile> files, + std::multimap<u64, VirtualFile> files, std::string name) { if (files.empty()) return nullptr; diff --git a/src/core/file_sys/vfs_concat.h b/src/core/file_sys/vfs_concat.h index c90f9d5d1..7a26343c0 100644 --- a/src/core/file_sys/vfs_concat.h +++ b/src/core/file_sys/vfs_concat.h @@ -15,7 +15,7 @@ namespace FileSys { // read-only. class ConcatenatedVfsFile : public VfsFile { ConcatenatedVfsFile(std::vector<VirtualFile> files, std::string name); - ConcatenatedVfsFile(std::map<u64, VirtualFile> files, std::string name); + ConcatenatedVfsFile(std::multimap<u64, VirtualFile> files, std::string name); public: ~ConcatenatedVfsFile() override; @@ -25,7 +25,7 @@ public: /// Convenience function that turns a map of offsets to files into a concatenated file, filling /// gaps with a given filler byte. - static VirtualFile MakeConcatenatedFile(u8 filler_byte, std::map<u64, VirtualFile> files, + static VirtualFile MakeConcatenatedFile(u8 filler_byte, std::multimap<u64, VirtualFile> files, std::string name); std::string GetName() const override; @@ -40,7 +40,7 @@ public: private: // Maps starting offset to file -- more efficient. - std::map<u64, VirtualFile> files; + std::multimap<u64, VirtualFile> files; std::string name; }; diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp index cadc03805..c66124998 100644 --- a/src/core/hle/service/filesystem/filesystem.cpp +++ b/src/core/hle/service/filesystem/filesystem.cpp @@ -55,6 +55,10 @@ std::string VfsDirectoryServiceWrapper::GetName() const { ResultCode VfsDirectoryServiceWrapper::CreateFile(const std::string& path_, u64 size) const { std::string path(FileUtil::SanitizePath(path_)); auto dir = GetDirectoryRelativeWrapped(backing, FileUtil::GetParentPath(path)); + // dir can be nullptr if path contains subdirectories, create those prior to creating the file. + if (dir == nullptr) { + dir = backing->CreateSubdirectory(FileUtil::GetParentPath(path)); + } auto file = dir->CreateFile(FileUtil::GetFilename(path)); if (file == nullptr) { // TODO(DarkLordZach): Find a better error code for this diff --git a/src/core/hle/service/mii/manager.cpp b/src/core/hle/service/mii/manager.cpp index 4a1d1182e..4730070cb 100644 --- a/src/core/hle/service/mii/manager.cpp +++ b/src/core/hle/service/mii/manager.cpp @@ -47,66 +47,67 @@ std::array<T, DestArraySize> ResizeArray(const std::array<T, SourceArraySize>& i MiiInfo ConvertStoreDataToInfo(const MiiStoreData& data) { MiiStoreBitFields bf; std::memcpy(&bf, data.data.data.data(), sizeof(MiiStoreBitFields)); - MiiInfo info{}; - info.name = ResizeArray<char16_t, 10, 11>(data.data.name); - info.uuid = data.data.uuid; - info.font_region = static_cast<u8>(bf.font_region.Value()); - info.favorite_color = static_cast<u8>(bf.favorite_color.Value()); - info.gender = static_cast<u8>(bf.gender.Value()); - info.height = static_cast<u8>(bf.height.Value()); - info.build = static_cast<u8>(bf.build.Value()); - info.type = static_cast<u8>(bf.type.Value()); - info.region_move = static_cast<u8>(bf.region_move.Value()); - info.faceline_type = static_cast<u8>(bf.faceline_type.Value()); - info.faceline_color = static_cast<u8>(bf.faceline_color.Value()); - info.faceline_wrinkle = static_cast<u8>(bf.faceline_wrinkle.Value()); - info.faceline_make = static_cast<u8>(bf.faceline_makeup.Value()); - info.hair_type = static_cast<u8>(bf.hair_type.Value()); - info.hair_color = static_cast<u8>(bf.hair_color.Value()); - info.hair_flip = static_cast<u8>(bf.hair_flip.Value()); - info.eye_type = static_cast<u8>(bf.eye_type.Value()); - info.eye_color = static_cast<u8>(bf.eye_color.Value()); - info.eye_scale = static_cast<u8>(bf.eye_scale.Value()); - info.eye_aspect = static_cast<u8>(bf.eye_aspect.Value()); - info.eye_rotate = static_cast<u8>(bf.eye_rotate.Value()); - info.eye_x = static_cast<u8>(bf.eye_x.Value()); - info.eye_y = static_cast<u8>(bf.eye_y.Value()); - info.eyebrow_type = static_cast<u8>(bf.eyebrow_type.Value()); - info.eyebrow_color = static_cast<u8>(bf.eyebrow_color.Value()); - info.eyebrow_scale = static_cast<u8>(bf.eyebrow_scale.Value()); - info.eyebrow_aspect = static_cast<u8>(bf.eyebrow_aspect.Value()); - info.eyebrow_rotate = static_cast<u8>(bf.eyebrow_rotate.Value()); - info.eyebrow_x = static_cast<u8>(bf.eyebrow_x.Value()); - info.eyebrow_y = static_cast<u8>(bf.eyebrow_y.Value() + 3); - info.nose_type = static_cast<u8>(bf.nose_type.Value()); - info.nose_scale = static_cast<u8>(bf.nose_scale.Value()); - info.nose_y = static_cast<u8>(bf.nose_y.Value()); - info.mouth_type = static_cast<u8>(bf.mouth_type.Value()); - info.mouth_color = static_cast<u8>(bf.mouth_color.Value()); - info.mouth_scale = static_cast<u8>(bf.mouth_scale.Value()); - info.mouth_aspect = static_cast<u8>(bf.mouth_aspect.Value()); - info.mouth_y = static_cast<u8>(bf.mouth_y.Value()); - info.beard_color = static_cast<u8>(bf.beard_color.Value()); - info.beard_type = static_cast<u8>(bf.beard_type.Value()); - info.mustache_type = static_cast<u8>(bf.mustache_type.Value()); - info.mustache_scale = static_cast<u8>(bf.mustache_scale.Value()); - info.mustache_y = static_cast<u8>(bf.mustache_y.Value()); - info.glasses_type = static_cast<u8>(bf.glasses_type.Value()); - info.glasses_color = static_cast<u8>(bf.glasses_color.Value()); - info.glasses_scale = static_cast<u8>(bf.glasses_scale.Value()); - info.glasses_y = static_cast<u8>(bf.glasses_y.Value()); - info.mole_type = static_cast<u8>(bf.mole_type.Value()); - info.mole_scale = static_cast<u8>(bf.mole_scale.Value()); - info.mole_x = static_cast<u8>(bf.mole_x.Value()); - info.mole_y = static_cast<u8>(bf.mole_y.Value()); - return info; + + return { + .uuid = data.data.uuid, + .name = ResizeArray<char16_t, 10, 11>(data.data.name), + .font_region = static_cast<u8>(bf.font_region.Value()), + .favorite_color = static_cast<u8>(bf.favorite_color.Value()), + .gender = static_cast<u8>(bf.gender.Value()), + .height = static_cast<u8>(bf.height.Value()), + .build = static_cast<u8>(bf.build.Value()), + .type = static_cast<u8>(bf.type.Value()), + .region_move = static_cast<u8>(bf.region_move.Value()), + .faceline_type = static_cast<u8>(bf.faceline_type.Value()), + .faceline_color = static_cast<u8>(bf.faceline_color.Value()), + .faceline_wrinkle = static_cast<u8>(bf.faceline_wrinkle.Value()), + .faceline_make = static_cast<u8>(bf.faceline_makeup.Value()), + .hair_type = static_cast<u8>(bf.hair_type.Value()), + .hair_color = static_cast<u8>(bf.hair_color.Value()), + .hair_flip = static_cast<u8>(bf.hair_flip.Value()), + .eye_type = static_cast<u8>(bf.eye_type.Value()), + .eye_color = static_cast<u8>(bf.eye_color.Value()), + .eye_scale = static_cast<u8>(bf.eye_scale.Value()), + .eye_aspect = static_cast<u8>(bf.eye_aspect.Value()), + .eye_rotate = static_cast<u8>(bf.eye_rotate.Value()), + .eye_x = static_cast<u8>(bf.eye_x.Value()), + .eye_y = static_cast<u8>(bf.eye_y.Value()), + .eyebrow_type = static_cast<u8>(bf.eyebrow_type.Value()), + .eyebrow_color = static_cast<u8>(bf.eyebrow_color.Value()), + .eyebrow_scale = static_cast<u8>(bf.eyebrow_scale.Value()), + .eyebrow_aspect = static_cast<u8>(bf.eyebrow_aspect.Value()), + .eyebrow_rotate = static_cast<u8>(bf.eyebrow_rotate.Value()), + .eyebrow_x = static_cast<u8>(bf.eyebrow_x.Value()), + .eyebrow_y = static_cast<u8>(bf.eyebrow_y.Value() + 3), + .nose_type = static_cast<u8>(bf.nose_type.Value()), + .nose_scale = static_cast<u8>(bf.nose_scale.Value()), + .nose_y = static_cast<u8>(bf.nose_y.Value()), + .mouth_type = static_cast<u8>(bf.mouth_type.Value()), + .mouth_color = static_cast<u8>(bf.mouth_color.Value()), + .mouth_scale = static_cast<u8>(bf.mouth_scale.Value()), + .mouth_aspect = static_cast<u8>(bf.mouth_aspect.Value()), + .mouth_y = static_cast<u8>(bf.mouth_y.Value()), + .beard_color = static_cast<u8>(bf.beard_color.Value()), + .beard_type = static_cast<u8>(bf.beard_type.Value()), + .mustache_type = static_cast<u8>(bf.mustache_type.Value()), + .mustache_scale = static_cast<u8>(bf.mustache_scale.Value()), + .mustache_y = static_cast<u8>(bf.mustache_y.Value()), + .glasses_type = static_cast<u8>(bf.glasses_type.Value()), + .glasses_color = static_cast<u8>(bf.glasses_color.Value()), + .glasses_scale = static_cast<u8>(bf.glasses_scale.Value()), + .glasses_y = static_cast<u8>(bf.glasses_y.Value()), + .mole_type = static_cast<u8>(bf.mole_type.Value()), + .mole_scale = static_cast<u8>(bf.mole_scale.Value()), + .mole_x = static_cast<u8>(bf.mole_x.Value()), + .mole_y = static_cast<u8>(bf.mole_y.Value()), + }; } u16 GenerateCrc16(const void* data, std::size_t size) { s32 crc{}; - for (int i = 0; i < size; i++) { - crc ^= reinterpret_cast<const u8*>(data)[i] << 8; - for (int j = 0; j < 8; j++) { + for (std::size_t i = 0; i < size; i++) { + crc ^= static_cast<const u8*>(data)[i] << 8; + for (std::size_t j = 0; j < 8; j++) { crc <<= 1; if ((crc & 0x10000) != 0) { crc = (crc ^ 0x1021) & 0xFFFF; diff --git a/src/core/memory/dmnt_cheat_vm.cpp b/src/core/memory/dmnt_cheat_vm.cpp index fb9f36bfd..2e7da23fe 100644 --- a/src/core/memory/dmnt_cheat_vm.cpp +++ b/src/core/memory/dmnt_cheat_vm.cpp @@ -190,6 +190,15 @@ void DmntCheatVm::LogOpcode(const CheatVmOpcode& opcode) { callbacks->CommandLog( fmt::format("Act[{:02X}]: {:d}", i, save_restore_regmask->should_operate[i])); } + } else if (auto rw_static_reg = std::get_if<ReadWriteStaticRegisterOpcode>(&opcode.opcode)) { + callbacks->CommandLog("Opcode: Read/Write Static Register"); + if (rw_static_reg->static_idx < NumReadableStaticRegisters) { + callbacks->CommandLog("Op Type: ReadStaticRegister"); + } else { + callbacks->CommandLog("Op Type: WriteStaticRegister"); + } + callbacks->CommandLog(fmt::format("Reg Idx {:X}", rw_static_reg->idx)); + callbacks->CommandLog(fmt::format("Stc Idx {:X}", rw_static_reg->static_idx)); } else if (auto debug_log = std::get_if<DebugLogOpcode>(&opcode.opcode)) { callbacks->CommandLog("Opcode: Debug Log"); callbacks->CommandLog(fmt::format("Bit Width: {:X}", debug_log->bit_width)); @@ -544,6 +553,16 @@ bool DmntCheatVm::DecodeNextOpcode(CheatVmOpcode& out) { } opcode.opcode = save_restore_regmask; } break; + case CheatVmOpcodeType::ReadWriteStaticRegister: { + ReadWriteStaticRegisterOpcode rw_static_reg{}; + // C3000XXx + // C3 = opcode 0xC3. + // XX = static register index. + // x = register index. + rw_static_reg.static_idx = ((first_dword >> 4) & 0xFF); + rw_static_reg.idx = (first_dword & 0xF); + opcode.opcode = rw_static_reg; + } break; case CheatVmOpcodeType::DebugLog: { DebugLogOpcode debug_log{}; // FFFTIX## @@ -667,6 +686,7 @@ void DmntCheatVm::ResetState() { registers.fill(0); saved_values.fill(0); loop_tops.fill(0); + static_registers.fill(0); instruction_ptr = 0; condition_depth = 0; decode_success = true; @@ -1153,6 +1173,15 @@ void DmntCheatVm::Execute(const CheatProcessMetadata& metadata) { } } } + } else if (auto rw_static_reg = + std::get_if<ReadWriteStaticRegisterOpcode>(&cur_opcode.opcode)) { + if (rw_static_reg->static_idx < NumReadableStaticRegisters) { + // Load a register with a static register. + registers[rw_static_reg->idx] = static_registers[rw_static_reg->static_idx]; + } else { + // Store a register to a static register. + static_registers[rw_static_reg->static_idx] = registers[rw_static_reg->idx]; + } } else if (auto debug_log = std::get_if<DebugLogOpcode>(&cur_opcode.opcode)) { // Read value from memory. u64 log_value = 0; diff --git a/src/core/memory/dmnt_cheat_vm.h b/src/core/memory/dmnt_cheat_vm.h index 8351fd798..21b86b72c 100644 --- a/src/core/memory/dmnt_cheat_vm.h +++ b/src/core/memory/dmnt_cheat_vm.h @@ -56,6 +56,7 @@ enum class CheatVmOpcodeType : u32 { BeginRegisterConditionalBlock = 0xC0, SaveRestoreRegister = 0xC1, SaveRestoreRegisterMask = 0xC2, + ReadWriteStaticRegister = 0xC3, // This is a meta entry, and not a real opcode. // This is to facilitate multi-nybble instruction decoding. @@ -237,6 +238,11 @@ struct SaveRestoreRegisterMaskOpcode { std::array<bool, 0x10> should_operate{}; }; +struct ReadWriteStaticRegisterOpcode { + u32 static_idx{}; + u32 idx{}; +}; + struct DebugLogOpcode { u32 bit_width{}; u32 log_id{}; @@ -259,7 +265,8 @@ struct CheatVmOpcode { PerformArithmeticStaticOpcode, BeginKeypressConditionalOpcode, PerformArithmeticRegisterOpcode, StoreRegisterToAddressOpcode, BeginRegisterConditionalOpcode, SaveRestoreRegisterOpcode, - SaveRestoreRegisterMaskOpcode, DebugLogOpcode, UnrecognizedInstruction> + SaveRestoreRegisterMaskOpcode, ReadWriteStaticRegisterOpcode, DebugLogOpcode, + UnrecognizedInstruction> opcode{}; }; @@ -281,6 +288,10 @@ public: static constexpr std::size_t MaximumProgramOpcodeCount = 0x400; static constexpr std::size_t NumRegisters = 0x10; + static constexpr std::size_t NumReadableStaticRegisters = 0x80; + static constexpr std::size_t NumWritableStaticRegisters = 0x80; + static constexpr std::size_t NumStaticRegisters = + NumReadableStaticRegisters + NumWritableStaticRegisters; explicit DmntCheatVm(std::unique_ptr<Callbacks> callbacks); ~DmntCheatVm(); @@ -302,6 +313,7 @@ private: std::array<u32, MaximumProgramOpcodeCount> program{}; std::array<u64, NumRegisters> registers{}; std::array<u64, NumRegisters> saved_values{}; + std::array<u64, NumStaticRegisters> static_registers{}; std::array<std::size_t, NumRegisters> loop_tops{}; bool DecodeNextOpcode(CheatVmOpcode& out); diff --git a/src/core/settings.cpp b/src/core/settings.cpp index e8a6f2a6e..44252dd81 100644 --- a/src/core/settings.cpp +++ b/src/core/settings.cpp @@ -115,6 +115,7 @@ void LogSettings() { values.use_asynchronous_gpu_emulation.GetValue()); log_setting("Renderer_UseVsync", values.use_vsync.GetValue()); log_setting("Renderer_UseAssemblyShaders", values.use_assembly_shaders.GetValue()); + log_setting("Renderer_UseAsynchronousShaders", values.use_asynchronous_shaders.GetValue()); log_setting("Renderer_AnisotropicFilteringLevel", values.max_anisotropy.GetValue()); log_setting("Audio_OutputEngine", values.sink_id); log_setting("Audio_EnableAudioStretching", values.enable_audio_stretching.GetValue()); @@ -170,6 +171,7 @@ void RestoreGlobalState() { values.use_asynchronous_gpu_emulation.SetGlobal(true); values.use_vsync.SetGlobal(true); values.use_assembly_shaders.SetGlobal(true); + values.use_asynchronous_shaders.SetGlobal(true); values.use_fast_gpu_time.SetGlobal(true); values.force_30fps_mode.SetGlobal(true); values.bg_red.SetGlobal(true); diff --git a/src/core/settings.h b/src/core/settings.h index a64debd25..386233fdf 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -434,6 +434,7 @@ struct Values { Setting<bool> use_asynchronous_gpu_emulation; Setting<bool> use_vsync; Setting<bool> use_assembly_shaders; + Setting<bool> use_asynchronous_shaders; Setting<bool> force_30fps_mode; Setting<bool> use_fast_gpu_time; diff --git a/src/core/telemetry_session.cpp b/src/core/telemetry_session.cpp index 78915e6db..5a30c75da 100644 --- a/src/core/telemetry_session.cpp +++ b/src/core/telemetry_session.cpp @@ -207,6 +207,8 @@ void TelemetrySession::AddInitialInfo(Loader::AppLoader& app_loader) { AddField(field_type, "Renderer_UseVsync", Settings::values.use_vsync.GetValue()); AddField(field_type, "Renderer_UseAssemblyShaders", Settings::values.use_assembly_shaders.GetValue()); + AddField(field_type, "Renderer_UseAsynchronousShaders", + Settings::values.use_asynchronous_shaders.GetValue()); AddField(field_type, "System_UseDockedMode", Settings::values.use_docked_mode); } |