diff options
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/arm/interpreter/armemu.cpp | 56 | ||||
| -rw-r--r-- | src/core/file_sys/archive_backend.h | 11 | ||||
| -rw-r--r-- | src/core/file_sys/archive_romfs.cpp | 5 | ||||
| -rw-r--r-- | src/core/hle/kernel/semaphore.cpp | 8 | ||||
| -rw-r--r-- | src/core/hle/kernel/semaphore.h | 2 | ||||
| -rw-r--r-- | src/core/hle/service/fs/archive.cpp | 13 | ||||
| -rw-r--r-- | src/core/hle/service/fs/fs_user.cpp | 33 | ||||
| -rw-r--r-- | src/core/loader/3dsx.cpp | 4 | ||||
| -rw-r--r-- | src/core/loader/loader.cpp | 6 |
9 files changed, 94 insertions, 44 deletions
diff --git a/src/core/arm/interpreter/armemu.cpp b/src/core/arm/interpreter/armemu.cpp index 4e11e068f..b21d97e12 100644 --- a/src/core/arm/interpreter/armemu.cpp +++ b/src/core/arm/interpreter/armemu.cpp | |||
| @@ -5681,11 +5681,8 @@ L_stm_s_takeabort: | |||
| 5681 | /* Attempt to emulate an ARMv6 instruction. | 5681 | /* Attempt to emulate an ARMv6 instruction. |
| 5682 | Returns non-zero upon success. */ | 5682 | Returns non-zero upon success. */ |
| 5683 | 5683 | ||
| 5684 | static int | 5684 | static int handle_v6_insn(ARMul_State* state, ARMword instr) { |
| 5685 | handle_v6_insn (ARMul_State * state, ARMword instr) { | 5685 | switch (BITS(20, 27)) { |
| 5686 | ARMword lhs, temp; | ||
| 5687 | |||
| 5688 | switch (BITS (20, 27)) { | ||
| 5689 | case 0x03: | 5686 | case 0x03: |
| 5690 | printf ("Unhandled v6 insn: ldr\n"); | 5687 | printf ("Unhandled v6 insn: ldr\n"); |
| 5691 | break; | 5688 | break; |
| @@ -5719,7 +5716,7 @@ L_stm_s_takeabort: | |||
| 5719 | /* strex */ | 5716 | /* strex */ |
| 5720 | u32 l = LHSReg; | 5717 | u32 l = LHSReg; |
| 5721 | u32 r = RHSReg; | 5718 | u32 r = RHSReg; |
| 5722 | lhs = LHS; | 5719 | u32 lhs = LHS; |
| 5723 | 5720 | ||
| 5724 | bool enter = false; | 5721 | bool enter = false; |
| 5725 | 5722 | ||
| @@ -5744,7 +5741,7 @@ L_stm_s_takeabort: | |||
| 5744 | case 0x19: | 5741 | case 0x19: |
| 5745 | /* ldrex */ | 5742 | /* ldrex */ |
| 5746 | if (BITS(4, 7) == 0x9) { | 5743 | if (BITS(4, 7) == 0x9) { |
| 5747 | lhs = LHS; | 5744 | u32 lhs = LHS; |
| 5748 | 5745 | ||
| 5749 | state->currentexaddr = lhs; | 5746 | state->currentexaddr = lhs; |
| 5750 | state->currentexval = ARMul_ReadWord(state, lhs); | 5747 | state->currentexval = ARMul_ReadWord(state, lhs); |
| @@ -5763,7 +5760,7 @@ L_stm_s_takeabort: | |||
| 5763 | case 0x1c: | 5760 | case 0x1c: |
| 5764 | if (BITS(4, 7) == 0x9) { | 5761 | if (BITS(4, 7) == 0x9) { |
| 5765 | /* strexb */ | 5762 | /* strexb */ |
| 5766 | lhs = LHS; | 5763 | u32 lhs = LHS; |
| 5767 | 5764 | ||
| 5768 | bool enter = false; | 5765 | bool enter = false; |
| 5769 | 5766 | ||
| @@ -5793,11 +5790,11 @@ L_stm_s_takeabort: | |||
| 5793 | case 0x1d: | 5790 | case 0x1d: |
| 5794 | if ((BITS(4, 7)) == 0x9) { | 5791 | if ((BITS(4, 7)) == 0x9) { |
| 5795 | /* ldrexb */ | 5792 | /* ldrexb */ |
| 5796 | temp = LHS; | 5793 | u32 lhs = LHS; |
| 5797 | LoadByte(state, instr, temp, LUNSIGNED); | 5794 | LoadByte(state, instr, lhs, LUNSIGNED); |
| 5798 | 5795 | ||
| 5799 | state->currentexaddr = temp; | 5796 | state->currentexaddr = lhs; |
| 5800 | state->currentexval = (u32)ARMul_ReadByte(state, temp); | 5797 | state->currentexval = (u32)ARMul_ReadByte(state, lhs); |
| 5801 | 5798 | ||
| 5802 | //state->Reg[BITS(12, 15)] = ARMul_LoadByte(state, state->Reg[BITS(16, 19)]); | 5799 | //state->Reg[BITS(12, 15)] = ARMul_LoadByte(state, state->Reg[BITS(16, 19)]); |
| 5803 | //printf("ldrexb\n"); | 5800 | //printf("ldrexb\n"); |
| @@ -5885,8 +5882,10 @@ L_stm_s_takeabort: | |||
| 5885 | printf("Unhandled v6 insn: %08x", BITS(20, 27)); | 5882 | printf("Unhandled v6 insn: %08x", BITS(20, 27)); |
| 5886 | } | 5883 | } |
| 5887 | break; | 5884 | break; |
| 5888 | case 0x62: // QSUB16 and QADD16 | 5885 | case 0x62: // QADD16, QASX, QSAX, and QSUB16 |
| 5889 | if ((instr & 0xFF0) == 0xf70 || (instr & 0xFF0) == 0xf10) { | 5886 | if ((instr & 0xFF0) == 0xf10 || (instr & 0xFF0) == 0xf30 || |
| 5887 | (instr & 0xFF0) == 0xf50 || (instr & 0xFF0) == 0xf70) | ||
| 5888 | { | ||
| 5890 | const u8 rd_idx = BITS(12, 15); | 5889 | const u8 rd_idx = BITS(12, 15); |
| 5891 | const u8 rn_idx = BITS(16, 19); | 5890 | const u8 rn_idx = BITS(16, 19); |
| 5892 | const u8 rm_idx = BITS(0, 3); | 5891 | const u8 rm_idx = BITS(0, 3); |
| @@ -5898,15 +5897,26 @@ L_stm_s_takeabort: | |||
| 5898 | s32 lo_result; | 5897 | s32 lo_result; |
| 5899 | s32 hi_result; | 5898 | s32 hi_result; |
| 5900 | 5899 | ||
| 5900 | // QADD16 | ||
| 5901 | if ((instr & 0xFF0) == 0xf10) { | ||
| 5902 | lo_result = (rn_lo + rm_lo); | ||
| 5903 | hi_result = (rn_hi + rm_hi); | ||
| 5904 | } | ||
| 5905 | // QASX | ||
| 5906 | else if ((instr & 0xFF0) == 0xf30) { | ||
| 5907 | lo_result = (rn_lo - rm_hi); | ||
| 5908 | hi_result = (rn_hi + rm_lo); | ||
| 5909 | } | ||
| 5910 | // QSAX | ||
| 5911 | else if ((instr & 0xFF0) == 0xf50) { | ||
| 5912 | lo_result = (rn_lo + rm_hi); | ||
| 5913 | hi_result = (rn_hi - rm_lo); | ||
| 5914 | } | ||
| 5901 | // QSUB16 | 5915 | // QSUB16 |
| 5902 | if ((instr & 0xFF0) == 0xf70) { | 5916 | else { |
| 5903 | lo_result = (rn_lo - rm_lo); | 5917 | lo_result = (rn_lo - rm_lo); |
| 5904 | hi_result = (rn_hi - rm_hi); | 5918 | hi_result = (rn_hi - rm_hi); |
| 5905 | } | 5919 | } |
| 5906 | else { // QADD16 | ||
| 5907 | lo_result = (rn_lo + rm_lo); | ||
| 5908 | hi_result = (rn_hi + rm_hi); | ||
| 5909 | } | ||
| 5910 | 5920 | ||
| 5911 | if (lo_result > 0x7FFF) | 5921 | if (lo_result > 0x7FFF) |
| 5912 | lo_result = 0x7FFF; | 5922 | lo_result = 0x7FFF; |
| @@ -6109,7 +6119,7 @@ L_stm_s_takeabort: | |||
| 6109 | break; | 6119 | break; |
| 6110 | } | 6120 | } |
| 6111 | 6121 | ||
| 6112 | Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFF) | ((state->Reg[BITS(0, 3)] << (32 - ror)) & 0xFF) & 0xFF; | 6122 | Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFF) | (((state->Reg[BITS(0, 3)] << (32 - ror)) & 0xFF) & 0xFF); |
| 6113 | if (Rm & 0x80) | 6123 | if (Rm & 0x80) |
| 6114 | Rm |= 0xffffff00; | 6124 | Rm |= 0xffffff00; |
| 6115 | 6125 | ||
| @@ -6154,7 +6164,7 @@ L_stm_s_takeabort: | |||
| 6154 | if (ror == -1) | 6164 | if (ror == -1) |
| 6155 | break; | 6165 | break; |
| 6156 | 6166 | ||
| 6157 | Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFFFF) | ((state->Reg[BITS(0, 3)] << (32 - ror)) & 0xFFFF) & 0xFFFF; | 6167 | Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFFFF) | (((state->Reg[BITS(0, 3)] << (32 - ror)) & 0xFFFF) & 0xFFFF); |
| 6158 | if (Rm & 0x8000) | 6168 | if (Rm & 0x8000) |
| 6159 | Rm |= 0xffff0000; | 6169 | Rm |= 0xffff0000; |
| 6160 | 6170 | ||
| @@ -6250,7 +6260,7 @@ L_stm_s_takeabort: | |||
| 6250 | break; | 6260 | break; |
| 6251 | } | 6261 | } |
| 6252 | 6262 | ||
| 6253 | Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFF) | ((state->Reg[BITS(0, 3)] << (32 - ror)) & 0xFF) & 0xFF; | 6263 | Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFF) | (((state->Reg[BITS(0, 3)] << (32 - ror)) & 0xFF) & 0xFF); |
| 6254 | 6264 | ||
| 6255 | if (BITS(16, 19) == 0xf) | 6265 | if (BITS(16, 19) == 0xf) |
| 6256 | /* UXTB */ | 6266 | /* UXTB */ |
| @@ -6294,7 +6304,7 @@ L_stm_s_takeabort: | |||
| 6294 | if (ror == -1) | 6304 | if (ror == -1) |
| 6295 | break; | 6305 | break; |
| 6296 | 6306 | ||
| 6297 | Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFFFF) | ((state->Reg[BITS(0, 3)] << (32 - ror)) & 0xFFFF) & 0xFFFF; | 6307 | Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFFFF) | (((state->Reg[BITS(0, 3)] << (32 - ror)) & 0xFFFF) & 0xFFFF); |
| 6298 | 6308 | ||
| 6299 | /* UXT */ | 6309 | /* UXT */ |
| 6300 | /* state->Reg[BITS (12, 15)] = Rm; */ | 6310 | /* state->Reg[BITS (12, 15)] = Rm; */ |
diff --git a/src/core/file_sys/archive_backend.h b/src/core/file_sys/archive_backend.h index 18c314884..d7959b2ca 100644 --- a/src/core/file_sys/archive_backend.h +++ b/src/core/file_sys/archive_backend.h | |||
| @@ -143,7 +143,16 @@ public: | |||
| 143 | case Char: | 143 | case Char: |
| 144 | return std::vector<u8>(string.begin(), string.end()); | 144 | return std::vector<u8>(string.begin(), string.end()); |
| 145 | case Wchar: | 145 | case Wchar: |
| 146 | return std::vector<u8>(u16str.begin(), u16str.end()); | 146 | { |
| 147 | // use two u8 for each character of u16str | ||
| 148 | std::vector<u8> to_return(u16str.size() * 2); | ||
| 149 | for (size_t i = 0; i < u16str.size(); ++i) { | ||
| 150 | u16 tmp_char = u16str.at(i); | ||
| 151 | to_return[i*2] = (tmp_char & 0xFF00) >> 8; | ||
| 152 | to_return[i*2 + 1] = (tmp_char & 0x00FF); | ||
| 153 | } | ||
| 154 | return to_return; | ||
| 155 | } | ||
| 147 | case Empty: | 156 | case Empty: |
| 148 | return {}; | 157 | return {}; |
| 149 | default: | 158 | default: |
diff --git a/src/core/file_sys/archive_romfs.cpp b/src/core/file_sys/archive_romfs.cpp index 0709b62a1..1e3e9dc60 100644 --- a/src/core/file_sys/archive_romfs.cpp +++ b/src/core/file_sys/archive_romfs.cpp | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #include <memory> | 5 | #include <memory> |
| 6 | 6 | ||
| 7 | #include "common/common_types.h" | 7 | #include "common/common_types.h" |
| 8 | #include "common/make_unique.h" | ||
| 8 | 9 | ||
| 9 | #include "core/file_sys/archive_romfs.h" | 10 | #include "core/file_sys/archive_romfs.h" |
| 10 | #include "core/file_sys/directory_romfs.h" | 11 | #include "core/file_sys/directory_romfs.h" |
| @@ -29,7 +30,7 @@ Archive_RomFS::Archive_RomFS(const Loader::AppLoader& app_loader) { | |||
| 29 | * @return Opened file, or nullptr | 30 | * @return Opened file, or nullptr |
| 30 | */ | 31 | */ |
| 31 | std::unique_ptr<FileBackend> Archive_RomFS::OpenFile(const Path& path, const Mode mode) const { | 32 | std::unique_ptr<FileBackend> Archive_RomFS::OpenFile(const Path& path, const Mode mode) const { |
| 32 | return std::make_unique<File_RomFS>(this); | 33 | return Common::make_unique<File_RomFS>(this); |
| 33 | } | 34 | } |
| 34 | 35 | ||
| 35 | /** | 36 | /** |
| @@ -78,7 +79,7 @@ bool Archive_RomFS::RenameDirectory(const FileSys::Path& src_path, const FileSys | |||
| 78 | * @return Opened directory, or nullptr | 79 | * @return Opened directory, or nullptr |
| 79 | */ | 80 | */ |
| 80 | std::unique_ptr<DirectoryBackend> Archive_RomFS::OpenDirectory(const Path& path) const { | 81 | std::unique_ptr<DirectoryBackend> Archive_RomFS::OpenDirectory(const Path& path) const { |
| 81 | return std::make_unique<Directory_RomFS>(); | 82 | return Common::make_unique<Directory_RomFS>(); |
| 82 | } | 83 | } |
| 83 | 84 | ||
| 84 | } // namespace FileSys | 85 | } // namespace FileSys |
diff --git a/src/core/hle/kernel/semaphore.cpp b/src/core/hle/kernel/semaphore.cpp index 6f56da8a9..f955d1957 100644 --- a/src/core/hle/kernel/semaphore.cpp +++ b/src/core/hle/kernel/semaphore.cpp | |||
| @@ -20,8 +20,8 @@ public: | |||
| 20 | static Kernel::HandleType GetStaticHandleType() { return Kernel::HandleType::Semaphore; } | 20 | static Kernel::HandleType GetStaticHandleType() { return Kernel::HandleType::Semaphore; } |
| 21 | Kernel::HandleType GetHandleType() const override { return Kernel::HandleType::Semaphore; } | 21 | Kernel::HandleType GetHandleType() const override { return Kernel::HandleType::Semaphore; } |
| 22 | 22 | ||
| 23 | u32 max_count; ///< Maximum number of simultaneous holders the semaphore can have | 23 | s32 max_count; ///< Maximum number of simultaneous holders the semaphore can have |
| 24 | u32 available_count; ///< Number of free slots left in the semaphore | 24 | s32 available_count; ///< Number of free slots left in the semaphore |
| 25 | std::queue<Handle> waiting_threads; ///< Threads that are waiting for the semaphore | 25 | std::queue<Handle> waiting_threads; ///< Threads that are waiting for the semaphore |
| 26 | std::string name; ///< Name of semaphore (optional) | 26 | std::string name; ///< Name of semaphore (optional) |
| 27 | 27 | ||
| @@ -49,8 +49,8 @@ public: | |||
| 49 | 49 | ||
| 50 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 50 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| 51 | 51 | ||
| 52 | ResultCode CreateSemaphore(Handle* handle, u32 initial_count, | 52 | ResultCode CreateSemaphore(Handle* handle, s32 initial_count, |
| 53 | u32 max_count, const std::string& name) { | 53 | s32 max_count, const std::string& name) { |
| 54 | 54 | ||
| 55 | if (initial_count > max_count) | 55 | if (initial_count > max_count) |
| 56 | return ResultCode(ErrorDescription::InvalidCombination, ErrorModule::Kernel, | 56 | return ResultCode(ErrorDescription::InvalidCombination, ErrorModule::Kernel, |
diff --git a/src/core/hle/kernel/semaphore.h b/src/core/hle/kernel/semaphore.h index f0075fdb8..ad474b875 100644 --- a/src/core/hle/kernel/semaphore.h +++ b/src/core/hle/kernel/semaphore.h | |||
| @@ -18,7 +18,7 @@ namespace Kernel { | |||
| 18 | * @param name Optional name of semaphore | 18 | * @param name Optional name of semaphore |
| 19 | * @return ResultCode of the error | 19 | * @return ResultCode of the error |
| 20 | */ | 20 | */ |
| 21 | ResultCode CreateSemaphore(Handle* handle, u32 initial_count, u32 max_count, const std::string& name = "Unknown"); | 21 | ResultCode CreateSemaphore(Handle* handle, s32 initial_count, s32 max_count, const std::string& name = "Unknown"); |
| 22 | 22 | ||
| 23 | /** | 23 | /** |
| 24 | * Releases a certain number of slots from a semaphore. | 24 | * Releases a certain number of slots from a semaphore. |
diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index 5ab82729c..510d7320c 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | 7 | ||
| 8 | #include "common/common_types.h" | 8 | #include "common/common_types.h" |
| 9 | #include "common/file_util.h" | 9 | #include "common/file_util.h" |
| 10 | #include "common/make_unique.h" | ||
| 10 | #include "common/math_util.h" | 11 | #include "common/math_util.h" |
| 11 | 12 | ||
| 12 | #include "core/file_sys/archive_savedata.h" | 13 | #include "core/file_sys/archive_savedata.h" |
| @@ -260,7 +261,7 @@ ResultCode CloseArchive(ArchiveHandle handle) { | |||
| 260 | // TODO(yuriks): This might be what the fs:REG service is for. See the Register/Unregister calls in | 261 | // TODO(yuriks): This might be what the fs:REG service is for. See the Register/Unregister calls in |
| 261 | // http://3dbrew.org/wiki/Filesystem_services#ProgramRegistry_service_.22fs:REG.22 | 262 | // http://3dbrew.org/wiki/Filesystem_services#ProgramRegistry_service_.22fs:REG.22 |
| 262 | ResultCode CreateArchive(std::unique_ptr<FileSys::ArchiveBackend>&& backend, ArchiveIdCode id_code) { | 263 | ResultCode CreateArchive(std::unique_ptr<FileSys::ArchiveBackend>&& backend, ArchiveIdCode id_code) { |
| 263 | auto result = id_code_map.emplace(id_code, std::make_unique<Archive>(std::move(backend), id_code)); | 264 | auto result = id_code_map.emplace(id_code, Common::make_unique<Archive>(std::move(backend), id_code)); |
| 264 | 265 | ||
| 265 | bool inserted = result.second; | 266 | bool inserted = result.second; |
| 266 | _dbg_assert_msg_(Service_FS, inserted, "Tried to register more than one archive with same id code"); | 267 | _dbg_assert_msg_(Service_FS, inserted, "Tried to register more than one archive with same id code"); |
| @@ -281,7 +282,7 @@ ResultVal<Handle> OpenFileFromArchive(ArchiveHandle archive_handle, const FileSy | |||
| 281 | ErrorSummary::NotFound, ErrorLevel::Status); | 282 | ErrorSummary::NotFound, ErrorLevel::Status); |
| 282 | } | 283 | } |
| 283 | 284 | ||
| 284 | auto file = std::make_unique<File>(std::move(backend), path); | 285 | auto file = Common::make_unique<File>(std::move(backend), path); |
| 285 | Handle handle = Kernel::g_object_pool.Create(file.release()); | 286 | Handle handle = Kernel::g_object_pool.Create(file.release()); |
| 286 | return MakeResult<Handle>(handle); | 287 | return MakeResult<Handle>(handle); |
| 287 | } | 288 | } |
| @@ -378,7 +379,7 @@ ResultVal<Handle> OpenDirectoryFromArchive(ArchiveHandle archive_handle, const F | |||
| 378 | ErrorSummary::NotFound, ErrorLevel::Permanent); | 379 | ErrorSummary::NotFound, ErrorLevel::Permanent); |
| 379 | } | 380 | } |
| 380 | 381 | ||
| 381 | auto directory = std::make_unique<Directory>(std::move(backend), path); | 382 | auto directory = Common::make_unique<Directory>(std::move(backend), path); |
| 382 | Handle handle = Kernel::g_object_pool.Create(directory.release()); | 383 | Handle handle = Kernel::g_object_pool.Create(directory.release()); |
| 383 | return MakeResult<Handle>(handle); | 384 | return MakeResult<Handle>(handle); |
| 384 | } | 385 | } |
| @@ -392,7 +393,7 @@ ResultCode FormatSaveData() { | |||
| 392 | 393 | ||
| 393 | // Create the SaveData archive | 394 | // Create the SaveData archive |
| 394 | std::string savedata_directory = FileUtil::GetUserPath(D_SAVEDATA_IDX); | 395 | std::string savedata_directory = FileUtil::GetUserPath(D_SAVEDATA_IDX); |
| 395 | auto savedata_archive = std::make_unique<FileSys::Archive_SaveData>(savedata_directory, | 396 | auto savedata_archive = Common::make_unique<FileSys::Archive_SaveData>(savedata_directory, |
| 396 | Kernel::g_program_id); | 397 | Kernel::g_program_id); |
| 397 | 398 | ||
| 398 | if (savedata_archive->Initialize()) { | 399 | if (savedata_archive->Initialize()) { |
| @@ -414,14 +415,14 @@ void ArchiveInit() { | |||
| 414 | // archive type is SDMC, so it is the only one getting exposed. | 415 | // archive type is SDMC, so it is the only one getting exposed. |
| 415 | 416 | ||
| 416 | std::string sdmc_directory = FileUtil::GetUserPath(D_SDMC_IDX); | 417 | std::string sdmc_directory = FileUtil::GetUserPath(D_SDMC_IDX); |
| 417 | auto sdmc_archive = std::make_unique<FileSys::Archive_SDMC>(sdmc_directory); | 418 | auto sdmc_archive = Common::make_unique<FileSys::Archive_SDMC>(sdmc_directory); |
| 418 | if (sdmc_archive->Initialize()) | 419 | if (sdmc_archive->Initialize()) |
| 419 | CreateArchive(std::move(sdmc_archive), ArchiveIdCode::SDMC); | 420 | CreateArchive(std::move(sdmc_archive), ArchiveIdCode::SDMC); |
| 420 | else | 421 | else |
| 421 | LOG_ERROR(Service_FS, "Can't instantiate SDMC archive with path %s", sdmc_directory.c_str()); | 422 | LOG_ERROR(Service_FS, "Can't instantiate SDMC archive with path %s", sdmc_directory.c_str()); |
| 422 | 423 | ||
| 423 | std::string systemsavedata_directory = FileUtil::GetUserPath(D_SYSSAVEDATA_IDX); | 424 | std::string systemsavedata_directory = FileUtil::GetUserPath(D_SYSSAVEDATA_IDX); |
| 424 | auto systemsavedata_archive = std::make_unique<FileSys::Archive_SDMC>(systemsavedata_directory); | 425 | auto systemsavedata_archive = Common::make_unique<FileSys::Archive_SDMC>(systemsavedata_directory); |
| 425 | if (systemsavedata_archive->Initialize()) { | 426 | if (systemsavedata_archive->Initialize()) { |
| 426 | CreateArchive(std::move(systemsavedata_archive), ArchiveIdCode::SystemSaveData); | 427 | CreateArchive(std::move(systemsavedata_archive), ArchiveIdCode::SystemSaveData); |
| 427 | } else { | 428 | } else { |
diff --git a/src/core/hle/service/fs/fs_user.cpp b/src/core/hle/service/fs/fs_user.cpp index f99d84b2f..8b908d691 100644 --- a/src/core/hle/service/fs/fs_user.cpp +++ b/src/core/hle/service/fs/fs_user.cpp | |||
| @@ -397,16 +397,44 @@ static void IsSdmcDetected(Service::Interface* self) { | |||
| 397 | } | 397 | } |
| 398 | 398 | ||
| 399 | /** | 399 | /** |
| 400 | * FS_User::FormatSaveData service function | 400 | * FS_User::FormatSaveData service function, |
| 401 | * formats the SaveData specified by the input path. | ||
| 401 | * Inputs: | 402 | * Inputs: |
| 403 | * 0 : 0x084C0242 | ||
| 404 | * 1 : Archive ID | ||
| 405 | * 2 : Archive low path type | ||
| 406 | * 3 : Archive low path size | ||
| 407 | * 10 : (LowPathSize << 14) | 2 | ||
| 408 | * 11 : Archive low path | ||
| 402 | * Outputs: | 409 | * Outputs: |
| 403 | * 1 : Result of function, 0 on success, otherwise error code | 410 | * 1 : Result of function, 0 on success, otherwise error code |
| 404 | */ | 411 | */ |
| 405 | static void FormatSaveData(Service::Interface* self) { | 412 | static void FormatSaveData(Service::Interface* self) { |
| 413 | // TODO(Subv): Find out what the other inputs and outputs of this function are | ||
| 406 | u32* cmd_buff = Kernel::GetCommandBuffer(); | 414 | u32* cmd_buff = Kernel::GetCommandBuffer(); |
| 407 | LOG_DEBUG(Service_FS, "(STUBBED)"); | 415 | LOG_DEBUG(Service_FS, "(STUBBED)"); |
| 408 | 416 | ||
| 409 | // TODO(Subv): Find out what the inputs and outputs of this function are | 417 | auto archive_id = static_cast<FS::ArchiveIdCode>(cmd_buff[1]); |
| 418 | auto archivename_type = static_cast<FileSys::LowPathType>(cmd_buff[2]); | ||
| 419 | u32 archivename_size = cmd_buff[3]; | ||
| 420 | u32 archivename_ptr = cmd_buff[11]; | ||
| 421 | FileSys::Path archive_path(archivename_type, archivename_size, archivename_ptr); | ||
| 422 | |||
| 423 | LOG_DEBUG(Service_FS, "archive_path=%s", archive_path.DebugStr().c_str()); | ||
| 424 | |||
| 425 | if (archive_id != FS::ArchiveIdCode::SaveData) { | ||
| 426 | // TODO(Subv): What should happen if somebody attempts to format a different archive? | ||
| 427 | LOG_ERROR(Service_FS, "tried to format an archive different than SaveData, %u", cmd_buff[1]); | ||
| 428 | cmd_buff[1] = UnimplementedFunction(ErrorModule::FS).raw; | ||
| 429 | return; | ||
| 430 | } | ||
| 431 | |||
| 432 | if (archive_path.GetType() != FileSys::LowPathType::Empty) { | ||
| 433 | // TODO(Subv): Implement formatting the SaveData of other games | ||
| 434 | LOG_ERROR(Service_FS, "archive LowPath type other than empty is currently unsupported"); | ||
| 435 | cmd_buff[1] = UnimplementedFunction(ErrorModule::FS).raw; | ||
| 436 | return; | ||
| 437 | } | ||
| 410 | 438 | ||
| 411 | cmd_buff[1] = FormatSaveData().raw; | 439 | cmd_buff[1] = FormatSaveData().raw; |
| 412 | } | 440 | } |
| @@ -414,6 +442,7 @@ static void FormatSaveData(Service::Interface* self) { | |||
| 414 | /** | 442 | /** |
| 415 | * FS_User::FormatThisUserSaveData service function | 443 | * FS_User::FormatThisUserSaveData service function |
| 416 | * Inputs: | 444 | * Inputs: |
| 445 | * 0: 0x080F0180 | ||
| 417 | * Outputs: | 446 | * Outputs: |
| 418 | * 1 : Result of function, 0 on success, otherwise error code | 447 | * 1 : Result of function, 0 on success, otherwise error code |
| 419 | */ | 448 | */ |
diff --git a/src/core/loader/3dsx.cpp b/src/core/loader/3dsx.cpp index 0437e5374..3d84fc5da 100644 --- a/src/core/loader/3dsx.cpp +++ b/src/core/loader/3dsx.cpp | |||
| @@ -223,9 +223,7 @@ int THREEDSXReader::Load3DSXFile(const std::string& filename, u32 base_addr) | |||
| 223 | LOG_INFO(Loader, "Loading 3DSX file %s...", filename.c_str()); | 223 | LOG_INFO(Loader, "Loading 3DSX file %s...", filename.c_str()); |
| 224 | FileUtil::IOFile file(filename, "rb"); | 224 | FileUtil::IOFile file(filename, "rb"); |
| 225 | if (file.IsOpen()) { | 225 | if (file.IsOpen()) { |
| 226 | 226 | THREEDSXReader::Load3DSXFile(filename, 0x00100000); | |
| 227 | THREEDSXReader reader; | ||
| 228 | reader.Load3DSXFile(filename, 0x00100000); | ||
| 229 | Kernel::LoadExec(0x00100000); | 227 | Kernel::LoadExec(0x00100000); |
| 230 | } else { | 228 | } else { |
| 231 | return ResultStatus::Error; | 229 | return ResultStatus::Error; |
diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp index 480274d23..b3b58da72 100644 --- a/src/core/loader/loader.cpp +++ b/src/core/loader/loader.cpp | |||
| @@ -2,7 +2,9 @@ | |||
| 2 | // Licensed under GPLv2 | 2 | // Licensed under GPLv2 |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <memory> | 5 | #include <string> |
| 6 | |||
| 7 | #include "common/make_unique.h" | ||
| 6 | 8 | ||
| 7 | #include "core/file_sys/archive_romfs.h" | 9 | #include "core/file_sys/archive_romfs.h" |
| 8 | #include "core/loader/3dsx.h" | 10 | #include "core/loader/3dsx.h" |
| @@ -75,7 +77,7 @@ ResultStatus LoadFile(const std::string& filename) { | |||
| 75 | // Load application and RomFS | 77 | // Load application and RomFS |
| 76 | if (ResultStatus::Success == app_loader.Load()) { | 78 | if (ResultStatus::Success == app_loader.Load()) { |
| 77 | Kernel::g_program_id = app_loader.GetProgramId(); | 79 | Kernel::g_program_id = app_loader.GetProgramId(); |
| 78 | Service::FS::CreateArchive(std::make_unique<FileSys::Archive_RomFS>(app_loader), Service::FS::ArchiveIdCode::RomFS); | 80 | Service::FS::CreateArchive(Common::make_unique<FileSys::Archive_RomFS>(app_loader), Service::FS::ArchiveIdCode::RomFS); |
| 79 | return ResultStatus::Success; | 81 | return ResultStatus::Success; |
| 80 | } | 82 | } |
| 81 | break; | 83 | break; |