diff options
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/core/arm/interpreter/armemu.cpp | 136 | ||||
| -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/file_sys/archive_savedata.h | 3 | ||||
| -rw-r--r-- | src/core/file_sys/archive_systemsavedata.cpp | 33 | ||||
| -rw-r--r-- | src/core/file_sys/archive_systemsavedata.h | 33 | ||||
| -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 | 20 | ||||
| -rw-r--r-- | src/core/hle/service/fs/fs_user.cpp | 33 | ||||
| -rw-r--r-- | src/core/hle/service/gsp_gpu.cpp | 26 | ||||
| -rw-r--r-- | src/core/loader/3dsx.cpp | 4 | ||||
| -rw-r--r-- | src/core/loader/loader.cpp | 6 |
14 files changed, 255 insertions, 67 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index f71232c1a..3381524e3 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -20,6 +20,7 @@ set(SRCS | |||
| 20 | file_sys/archive_romfs.cpp | 20 | file_sys/archive_romfs.cpp |
| 21 | file_sys/archive_savedata.cpp | 21 | file_sys/archive_savedata.cpp |
| 22 | file_sys/archive_sdmc.cpp | 22 | file_sys/archive_sdmc.cpp |
| 23 | file_sys/archive_systemsavedata.cpp | ||
| 23 | file_sys/disk_archive.cpp | 24 | file_sys/disk_archive.cpp |
| 24 | file_sys/file_romfs.cpp | 25 | file_sys/file_romfs.cpp |
| 25 | file_sys/directory_romfs.cpp | 26 | file_sys/directory_romfs.cpp |
| @@ -101,6 +102,7 @@ set(HEADERS | |||
| 101 | file_sys/archive_romfs.h | 102 | file_sys/archive_romfs.h |
| 102 | file_sys/archive_savedata.h | 103 | file_sys/archive_savedata.h |
| 103 | file_sys/archive_sdmc.h | 104 | file_sys/archive_sdmc.h |
| 105 | file_sys/archive_systemsavedata.h | ||
| 104 | file_sys/disk_archive.h | 106 | file_sys/disk_archive.h |
| 105 | file_sys/file_backend.h | 107 | file_sys/file_backend.h |
| 106 | file_sys/file_romfs.h | 108 | file_sys/file_romfs.h |
diff --git a/src/core/arm/interpreter/armemu.cpp b/src/core/arm/interpreter/armemu.cpp index 399ee0886..7408b6f08 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"); |
| @@ -5839,29 +5836,56 @@ L_stm_s_takeabort: | |||
| 5839 | const s16 rm_lo = (state->Reg[rm_idx] & 0xFFFF); | 5836 | const s16 rm_lo = (state->Reg[rm_idx] & 0xFFFF); |
| 5840 | const s16 rm_hi = ((state->Reg[rm_idx] >> 16) & 0xFFFF); | 5837 | const s16 rm_hi = ((state->Reg[rm_idx] >> 16) & 0xFFFF); |
| 5841 | 5838 | ||
| 5839 | s32 lo_result; | ||
| 5840 | s32 hi_result; | ||
| 5841 | |||
| 5842 | // SSUB16 | 5842 | // SSUB16 |
| 5843 | if ((instr & 0xFF0) == 0xf70) { | 5843 | if ((instr & 0xFF0) == 0xf70) { |
| 5844 | state->Reg[rd_idx] = ((rn_lo - rm_lo) & 0xFFFF) | (((rn_hi - rm_hi) & 0xFFFF) << 16); | 5844 | lo_result = (rn_lo - rm_lo); |
| 5845 | hi_result = (rn_hi - rm_hi); | ||
| 5845 | } | 5846 | } |
| 5846 | // SADD16 | 5847 | // SADD16 |
| 5847 | else if ((instr & 0xFF0) == 0xf10) { | 5848 | else if ((instr & 0xFF0) == 0xf10) { |
| 5848 | state->Reg[rd_idx] = ((rn_lo + rm_lo) & 0xFFFF) | (((rn_hi + rm_hi) & 0xFFFF) << 16); | 5849 | lo_result = (rn_lo + rm_lo); |
| 5850 | hi_result = (rn_hi + rm_hi); | ||
| 5849 | } | 5851 | } |
| 5850 | // SSAX | 5852 | // SSAX |
| 5851 | else if ((instr & 0xFF0) == 0xf50) { | 5853 | else if ((instr & 0xFF0) == 0xf50) { |
| 5852 | state->Reg[rd_idx] = ((rn_lo + rm_hi) & 0xFFFF) | (((rn_hi - rm_lo) & 0xFFFF) << 16); | 5854 | lo_result = (rn_lo + rm_hi); |
| 5855 | hi_result = (rn_hi - rm_lo); | ||
| 5853 | } | 5856 | } |
| 5854 | // SASX | 5857 | // SASX |
| 5855 | else { | 5858 | else { |
| 5856 | state->Reg[rd_idx] = ((rn_lo - rm_hi) & 0xFFFF) | (((rn_hi + rm_lo) & 0xFFFF) << 16); | 5859 | lo_result = (rn_lo - rm_hi); |
| 5860 | hi_result = (rn_hi + rm_lo); | ||
| 5861 | } | ||
| 5862 | |||
| 5863 | state->Reg[rd_idx] = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16); | ||
| 5864 | |||
| 5865 | if (lo_result >= 0) { | ||
| 5866 | state->Cpsr |= (1 << 16); | ||
| 5867 | state->Cpsr |= (1 << 17); | ||
| 5868 | } else { | ||
| 5869 | state->Cpsr &= ~(1 << 16); | ||
| 5870 | state->Cpsr &= ~(1 << 17); | ||
| 5871 | } | ||
| 5872 | |||
| 5873 | if (hi_result >= 0) { | ||
| 5874 | state->Cpsr |= (1 << 18); | ||
| 5875 | state->Cpsr |= (1 << 19); | ||
| 5876 | } else { | ||
| 5877 | state->Cpsr &= ~(1 << 18); | ||
| 5878 | state->Cpsr &= ~(1 << 19); | ||
| 5857 | } | 5879 | } |
| 5858 | return 1; | 5880 | return 1; |
| 5859 | } else { | 5881 | } else { |
| 5860 | printf("Unhandled v6 insn: %08x", BITS(20, 27)); | 5882 | printf("Unhandled v6 insn: %08x", BITS(20, 27)); |
| 5861 | } | 5883 | } |
| 5862 | break; | 5884 | break; |
| 5863 | case 0x62: // QSUB16 and QADD16 | 5885 | case 0x62: // QADD16, QASX, QSAX, and QSUB16 |
| 5864 | if ((instr & 0xFF0) == 0xf70 || (instr & 0xFF0) == 0xf10) { | 5886 | if ((instr & 0xFF0) == 0xf10 || (instr & 0xFF0) == 0xf30 || |
| 5887 | (instr & 0xFF0) == 0xf50 || (instr & 0xFF0) == 0xf70) | ||
| 5888 | { | ||
| 5865 | const u8 rd_idx = BITS(12, 15); | 5889 | const u8 rd_idx = BITS(12, 15); |
| 5866 | const u8 rn_idx = BITS(16, 19); | 5890 | const u8 rn_idx = BITS(16, 19); |
| 5867 | const u8 rm_idx = BITS(0, 3); | 5891 | const u8 rm_idx = BITS(0, 3); |
| @@ -5873,15 +5897,26 @@ L_stm_s_takeabort: | |||
| 5873 | s32 lo_result; | 5897 | s32 lo_result; |
| 5874 | s32 hi_result; | 5898 | s32 hi_result; |
| 5875 | 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 | } | ||
| 5876 | // QSUB16 | 5915 | // QSUB16 |
| 5877 | if ((instr & 0xFF0) == 0xf70) { | 5916 | else { |
| 5878 | lo_result = (rn_lo - rm_lo); | 5917 | lo_result = (rn_lo - rm_lo); |
| 5879 | hi_result = (rn_hi - rm_hi); | 5918 | hi_result = (rn_hi - rm_hi); |
| 5880 | } | 5919 | } |
| 5881 | else { // QADD16 | ||
| 5882 | lo_result = (rn_lo + rm_lo); | ||
| 5883 | hi_result = (rn_hi + rm_hi); | ||
| 5884 | } | ||
| 5885 | 5920 | ||
| 5886 | if (lo_result > 0x7FFF) | 5921 | if (lo_result > 0x7FFF) |
| 5887 | lo_result = 0x7FFF; | 5922 | lo_result = 0x7FFF; |
| @@ -6084,7 +6119,7 @@ L_stm_s_takeabort: | |||
| 6084 | break; | 6119 | break; |
| 6085 | } | 6120 | } |
| 6086 | 6121 | ||
| 6087 | 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); |
| 6088 | if (Rm & 0x80) | 6123 | if (Rm & 0x80) |
| 6089 | Rm |= 0xffffff00; | 6124 | Rm |= 0xffffff00; |
| 6090 | 6125 | ||
| @@ -6129,7 +6164,7 @@ L_stm_s_takeabort: | |||
| 6129 | if (ror == -1) | 6164 | if (ror == -1) |
| 6130 | break; | 6165 | break; |
| 6131 | 6166 | ||
| 6132 | 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); |
| 6133 | if (Rm & 0x8000) | 6168 | if (Rm & 0x8000) |
| 6134 | Rm |= 0xffff0000; | 6169 | Rm |= 0xffff0000; |
| 6135 | 6170 | ||
| @@ -6192,18 +6227,27 @@ L_stm_s_takeabort: | |||
| 6192 | //ichfly | 6227 | //ichfly |
| 6193 | //USAT16 | 6228 | //USAT16 |
| 6194 | { | 6229 | { |
| 6195 | u8 tar = BITS(12, 15); | 6230 | const u8 rd_idx = BITS(12, 15); |
| 6196 | u8 src = BITS(0, 3); | 6231 | const u8 rn_idx = BITS(0, 3); |
| 6197 | u8 val = BITS(16, 19); | 6232 | const u8 num_bits = BITS(16, 19); |
| 6198 | s16 a1 = (state->Reg[src]); | 6233 | const s16 max = 0xFFFF >> (16 - num_bits); |
| 6199 | s16 a2 = (state->Reg[src] >> 0x10); | 6234 | s16 rn_lo = (state->Reg[rn_idx]); |
| 6200 | s16 max = 0xFFFF >> (16 - val); | 6235 | s16 rn_hi = (state->Reg[rn_idx] >> 16); |
| 6201 | if (max < a1) a1 = max; | 6236 | |
| 6202 | if (max < a2) a2 = max; | 6237 | if (max < rn_lo) |
| 6203 | u32 temp2 = ((u32)(a2)) << 0x10; | 6238 | rn_lo = max; |
| 6204 | state->Reg[tar] = (a1 & 0xFFFF) | (temp2); | 6239 | else if (rn_lo < 0) |
| 6240 | rn_lo = 0; | ||
| 6241 | |||
| 6242 | if (max < rn_hi) | ||
| 6243 | rn_hi = max; | ||
| 6244 | else if (rn_hi < 0) | ||
| 6245 | rn_hi = 0; | ||
| 6246 | |||
| 6247 | state->Reg[rd_idx] = (rn_lo & 0xFFFF) | ((rn_hi << 16) & 0xFFFF); | ||
| 6248 | return 1; | ||
| 6205 | } | 6249 | } |
| 6206 | return 1; | 6250 | |
| 6207 | default: | 6251 | default: |
| 6208 | break; | 6252 | break; |
| 6209 | } | 6253 | } |
| @@ -6216,7 +6260,7 @@ L_stm_s_takeabort: | |||
| 6216 | break; | 6260 | break; |
| 6217 | } | 6261 | } |
| 6218 | 6262 | ||
| 6219 | 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); |
| 6220 | 6264 | ||
| 6221 | if (BITS(16, 19) == 0xf) | 6265 | if (BITS(16, 19) == 0xf) |
| 6222 | /* UXTB */ | 6266 | /* UXTB */ |
| @@ -6260,7 +6304,7 @@ L_stm_s_takeabort: | |||
| 6260 | if (ror == -1) | 6304 | if (ror == -1) |
| 6261 | break; | 6305 | break; |
| 6262 | 6306 | ||
| 6263 | 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); |
| 6264 | 6308 | ||
| 6265 | /* UXT */ | 6309 | /* UXT */ |
| 6266 | /* state->Reg[BITS (12, 15)] = Rm; */ | 6310 | /* state->Reg[BITS (12, 15)] = Rm; */ |
| @@ -6283,11 +6327,14 @@ L_stm_s_takeabort: | |||
| 6283 | } | 6327 | } |
| 6284 | case 0x70: | 6328 | case 0x70: |
| 6285 | // ichfly | 6329 | // ichfly |
| 6286 | // SMUAD, SMUSD, SMLAD | 6330 | // SMUAD, SMUSD, SMLAD, and SMLSD |
| 6287 | if ((instr & 0xf0d0) == 0xf010 || (instr & 0xf0d0) == 0xf050 || (instr & 0xd0) == 0x10) { | 6331 | if ((instr & 0xf0d0) == 0xf010 || (instr & 0xf0d0) == 0xf050 || |
| 6332 | (instr & 0xd0) == 0x10 || (instr & 0xd0) == 0x50) | ||
| 6333 | { | ||
| 6288 | const u8 rd_idx = BITS(16, 19); | 6334 | const u8 rd_idx = BITS(16, 19); |
| 6289 | const u8 rn_idx = BITS(0, 3); | 6335 | const u8 rn_idx = BITS(0, 3); |
| 6290 | const u8 rm_idx = BITS(8, 11); | 6336 | const u8 rm_idx = BITS(8, 11); |
| 6337 | const u8 ra_idx = BITS(12, 15); | ||
| 6291 | const bool do_swap = (BIT(5) == 1); | 6338 | const bool do_swap = (BIT(5) == 1); |
| 6292 | 6339 | ||
| 6293 | u32 rm_val = state->Reg[rm_idx]; | 6340 | u32 rm_val = state->Reg[rm_idx]; |
| @@ -6310,13 +6357,14 @@ L_stm_s_takeabort: | |||
| 6310 | state->Reg[rd_idx] = (rn_lo * rm_lo) - (rn_hi * rm_hi); | 6357 | state->Reg[rd_idx] = (rn_lo * rm_lo) - (rn_hi * rm_hi); |
| 6311 | } | 6358 | } |
| 6312 | // SMLAD | 6359 | // SMLAD |
| 6313 | else { | 6360 | else if ((instr & 0xd0) == 0x10) { |
| 6314 | const u8 ra_idx = BITS(12, 15); | ||
| 6315 | state->Reg[rd_idx] = (rn_lo * rm_lo) + (rn_hi * rm_hi) + (s32)state->Reg[ra_idx]; | 6361 | state->Reg[rd_idx] = (rn_lo * rm_lo) + (rn_hi * rm_hi) + (s32)state->Reg[ra_idx]; |
| 6316 | } | 6362 | } |
| 6363 | // SMLSD | ||
| 6364 | else { | ||
| 6365 | state->Reg[rd_idx] = ((rn_lo * rm_lo) - (rn_hi * rm_hi)) + (s32)state->Reg[ra_idx]; | ||
| 6366 | } | ||
| 6317 | return 1; | 6367 | return 1; |
| 6318 | } else { | ||
| 6319 | printf ("Unhandled v6 insn: smlsd\n"); | ||
| 6320 | } | 6368 | } |
| 6321 | break; | 6369 | break; |
| 6322 | case 0x74: | 6370 | case 0x74: |
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/file_sys/archive_savedata.h b/src/core/file_sys/archive_savedata.h index b3e561130..d394ad37e 100644 --- a/src/core/file_sys/archive_savedata.h +++ b/src/core/file_sys/archive_savedata.h | |||
| @@ -21,8 +21,7 @@ public: | |||
| 21 | 21 | ||
| 22 | /** | 22 | /** |
| 23 | * Initialize the archive. | 23 | * Initialize the archive. |
| 24 | * @return CreateSaveDataResult AlreadyExists if the SaveData folder already exists, | 24 | * @return true if it initialized successfully |
| 25 | * Success if it was created properly and Failure if there was any error | ||
| 26 | */ | 25 | */ |
| 27 | bool Initialize(); | 26 | bool Initialize(); |
| 28 | 27 | ||
diff --git a/src/core/file_sys/archive_systemsavedata.cpp b/src/core/file_sys/archive_systemsavedata.cpp new file mode 100644 index 000000000..dc2c23b41 --- /dev/null +++ b/src/core/file_sys/archive_systemsavedata.cpp | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2+ | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <sys/stat.h> | ||
| 6 | |||
| 7 | #include "common/common_types.h" | ||
| 8 | #include "common/file_util.h" | ||
| 9 | |||
| 10 | #include "core/file_sys/archive_systemsavedata.h" | ||
| 11 | #include "core/file_sys/disk_archive.h" | ||
| 12 | #include "core/settings.h" | ||
| 13 | |||
| 14 | //////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 15 | // FileSys namespace | ||
| 16 | |||
| 17 | namespace FileSys { | ||
| 18 | |||
| 19 | Archive_SystemSaveData::Archive_SystemSaveData(const std::string& mount_point) | ||
| 20 | : DiskArchive(mount_point) { | ||
| 21 | LOG_INFO(Service_FS, "Directory %s set as SystemSaveData.", this->mount_point.c_str()); | ||
| 22 | } | ||
| 23 | |||
| 24 | bool Archive_SystemSaveData::Initialize() { | ||
| 25 | if (!FileUtil::CreateFullPath(mount_point)) { | ||
| 26 | LOG_ERROR(Service_FS, "Unable to create SystemSaveData path."); | ||
| 27 | return false; | ||
| 28 | } | ||
| 29 | |||
| 30 | return true; | ||
| 31 | } | ||
| 32 | |||
| 33 | } // namespace FileSys | ||
diff --git a/src/core/file_sys/archive_systemsavedata.h b/src/core/file_sys/archive_systemsavedata.h new file mode 100644 index 000000000..360ed1e13 --- /dev/null +++ b/src/core/file_sys/archive_systemsavedata.h | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2+ | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "common/common_types.h" | ||
| 8 | |||
| 9 | #include "core/file_sys/disk_archive.h" | ||
| 10 | #include "core/loader/loader.h" | ||
| 11 | |||
| 12 | //////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 13 | // FileSys namespace | ||
| 14 | |||
| 15 | namespace FileSys { | ||
| 16 | |||
| 17 | /// File system interface to the SystemSaveData archive | ||
| 18 | /// TODO(Subv): This archive should point to a location in the NAND, | ||
| 19 | /// specifically nand:/data/<ID0>/sysdata/<SaveID-Low>/<SaveID-High> | ||
| 20 | class Archive_SystemSaveData final : public DiskArchive { | ||
| 21 | public: | ||
| 22 | Archive_SystemSaveData(const std::string& mount_point); | ||
| 23 | |||
| 24 | /** | ||
| 25 | * Initialize the archive. | ||
| 26 | * @return true if it initialized successfully | ||
| 27 | */ | ||
| 28 | bool Initialize(); | ||
| 29 | |||
| 30 | std::string GetName() const override { return "SystemSaveData"; } | ||
| 31 | }; | ||
| 32 | |||
| 33 | } // 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 9c3834733..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,11 +415,20 @@ 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()); |
| 423 | |||
| 424 | std::string systemsavedata_directory = FileUtil::GetUserPath(D_SYSSAVEDATA_IDX); | ||
| 425 | auto systemsavedata_archive = Common::make_unique<FileSys::Archive_SDMC>(systemsavedata_directory); | ||
| 426 | if (systemsavedata_archive->Initialize()) { | ||
| 427 | CreateArchive(std::move(systemsavedata_archive), ArchiveIdCode::SystemSaveData); | ||
| 428 | } else { | ||
| 429 | LOG_ERROR(Service_FS, "Can't instantiate SystemSaveData archive with path %s", | ||
| 430 | systemsavedata_directory.c_str()); | ||
| 431 | } | ||
| 422 | } | 432 | } |
| 423 | 433 | ||
| 424 | /// Shutdown archives | 434 | /// Shutdown archives |
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/hle/service/gsp_gpu.cpp b/src/core/hle/service/gsp_gpu.cpp index db8027142..8c9ad2712 100644 --- a/src/core/hle/service/gsp_gpu.cpp +++ b/src/core/hle/service/gsp_gpu.cpp | |||
| @@ -145,6 +145,30 @@ static void SetBufferSwap(Service::Interface* self) { | |||
| 145 | } | 145 | } |
| 146 | 146 | ||
| 147 | /** | 147 | /** |
| 148 | * GSP_GPU::FlushDataCache service function | ||
| 149 | * | ||
| 150 | * This Function is a no-op, We aren't emulating the CPU cache any time soon. | ||
| 151 | * | ||
| 152 | * Inputs: | ||
| 153 | * 1 : Address | ||
| 154 | * 2 : Size | ||
| 155 | * 3 : Value 0, some descriptor for the KProcess Handle | ||
| 156 | * 4 : KProcess handle | ||
| 157 | * Outputs: | ||
| 158 | * 1 : Result of function, 0 on success, otherwise error code | ||
| 159 | */ | ||
| 160 | static void FlushDataCache(Service::Interface* self) { | ||
| 161 | u32* cmd_buff = Kernel::GetCommandBuffer(); | ||
| 162 | u32 address = cmd_buff[1]; | ||
| 163 | u32 size = cmd_buff[2]; | ||
| 164 | u32 process = cmd_buff[4]; | ||
| 165 | |||
| 166 | // TODO(purpasmart96): Verify return header on HW | ||
| 167 | |||
| 168 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error | ||
| 169 | } | ||
| 170 | |||
| 171 | /** | ||
| 148 | * GSP_GPU::RegisterInterruptRelayQueue service function | 172 | * GSP_GPU::RegisterInterruptRelayQueue service function |
| 149 | * Inputs: | 173 | * Inputs: |
| 150 | * 1 : "Flags" field, purpose is unknown | 174 | * 1 : "Flags" field, purpose is unknown |
| @@ -335,7 +359,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 335 | {0x00050200, SetBufferSwap, "SetBufferSwap"}, | 359 | {0x00050200, SetBufferSwap, "SetBufferSwap"}, |
| 336 | {0x00060082, nullptr, "SetCommandList"}, | 360 | {0x00060082, nullptr, "SetCommandList"}, |
| 337 | {0x000700C2, nullptr, "RequestDma"}, | 361 | {0x000700C2, nullptr, "RequestDma"}, |
| 338 | {0x00080082, nullptr, "FlushDataCache"}, | 362 | {0x00080082, FlushDataCache, "FlushDataCache"}, |
| 339 | {0x00090082, nullptr, "InvalidateDataCache"}, | 363 | {0x00090082, nullptr, "InvalidateDataCache"}, |
| 340 | {0x000A0044, nullptr, "RegisterInterruptEvents"}, | 364 | {0x000A0044, nullptr, "RegisterInterruptEvents"}, |
| 341 | {0x000B0040, nullptr, "SetLcdForceBlack"}, | 365 | {0x000B0040, nullptr, "SetLcdForceBlack"}, |
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; |