diff --git a/arm9/source/driveMenu.cpp b/arm9/source/driveMenu.cpp index 9c6c92e..78b5e35 100644 --- a/arm9/source/driveMenu.cpp +++ b/arm9/source/driveMenu.cpp @@ -49,6 +49,7 @@ enum class DriveMenuOperation { flashcard, ramDrive, sysNand, + sysNandPhoto, nitroFs, fatImage, gbaCart, @@ -103,6 +104,11 @@ void dm_drawTopScreen(void) { if(!driveWritable(Drive::nand)) font->print(lastCol, i + 1, true, "[R]", alignEnd, pal); break; + case DriveMenuOperation::sysNandPhoto: + font->print(firstCol, i + 1, true, STR_SYSNAND_PHOTO_LABEL, alignStart, pal); + if(!driveWritable(Drive::nandPhoto)) + font->print(lastCol, i + 1, true, "[R]", alignEnd, pal); + break; case DriveMenuOperation::nitroFs: font->print(firstCol, i + 1, true, STR_NITROFS_LABEL, alignStart, pal); font->print(lastCol, i + 1, true, "[R]", alignEnd, pal); @@ -194,6 +200,11 @@ void dm_drawBottomScreen(void) { font->printf(firstCol, 1, false, alignStart, Palette::white, STR_SYSNAND_FAT.c_str(), getBytes(nandSize).c_str()); font->printf(firstCol, 2, false, alignStart, Palette::white, STR_N_FREE.c_str(), getBytes(driveSizeFree(Drive::nand)).c_str()); break; + case DriveMenuOperation::sysNandPhoto: + font->print(firstCol, 0, false, STR_SYSNAND_LABEL, alignStart); + font->printf(firstCol, 1, false, alignStart, Palette::white, STR_SYSNAND_FAT.c_str(), getBytes(photoSize).c_str()); + font->printf(firstCol, 2, false, alignStart, Palette::white, STR_N_FREE.c_str(), getBytes(driveSizeFree(Drive::nandPhoto)).c_str()); + break; case DriveMenuOperation::fatImage: font->printf(firstCol, 0, false, alignStart, Palette::white, STR_FAT_LABEL.c_str(), imgLabel[0] == 0 ? STR_UNTITLED.c_str() : imgLabel); font->printf(firstCol, 1, false, alignStart, Palette::white, STR_FAT_IMAGE.c_str(), getBytes(imgSize).c_str()); @@ -220,6 +231,8 @@ void driveMenu (void) { dmOperations.push_back(DriveMenuOperation::sdCard); if (nandMounted) dmOperations.push_back(DriveMenuOperation::sysNand); + if (photoMounted) + dmOperations.push_back(DriveMenuOperation::sysNandPhoto); if (flashcardMounted && !driveRemoved(Drive::flashcard)) dmOperations.push_back(DriveMenuOperation::flashcard); if (ramdriveMounted) @@ -343,6 +356,7 @@ void driveMenu (void) { || (flashcardMounted && nitroCurrentDrive == Drive::flashcard) || (ramdriveMounted && nitroCurrentDrive == Drive::ramDrive) || (nandMounted && nitroCurrentDrive == Drive::nand) + || (nandMounted && nitroCurrentDrive == Drive::nandPhoto) || (imgMounted && nitroCurrentDrive == Drive::fatImg)) { currentDrive = Drive::nitroFS; @@ -362,11 +376,17 @@ void driveMenu (void) { chdir("nand:/"); screenMode = 1; break; + } else if (dmOperations[dmCursorPosition] == DriveMenuOperation::sysNandPhoto && photoMounted) { + currentDrive = Drive::nandPhoto; + chdir("photo:/"); + screenMode = 1; + break; } else if (dmOperations[dmCursorPosition] == DriveMenuOperation::fatImage && imgMounted) { if ((sdMounted && imgCurrentDrive == Drive::sdCard) || (flashcardMounted && imgCurrentDrive == Drive::flashcard) || (ramdriveMounted && imgCurrentDrive == Drive::ramDrive) - || (nandMounted && imgCurrentDrive == Drive::nand)) + || (nandMounted && imgCurrentDrive == Drive::nand) + || (nandMounted && imgCurrentDrive == Drive::nandPhoto)) { currentDrive = Drive::fatImg; chdir("img:/"); diff --git a/arm9/source/driveOperations.cpp b/arm9/source/driveOperations.cpp index 42a79bd..b63c288 100644 --- a/arm9/source/driveOperations.cpp +++ b/arm9/source/driveOperations.cpp @@ -18,6 +18,7 @@ #include "imgio.h" #include "tonccpy.h" #include "language.h" +#include "sector0.h" #include "io_m3_common.h" #include "io_g6_common.h" @@ -29,6 +30,7 @@ static sNDSHeader nds; static bool slot1Enabled = true; bool nandMounted = false; +bool photoMounted = false; bool sdMounted = false; bool sdMountedDone = false; // true if SD mount is successful once bool flashcardMounted = false; @@ -45,6 +47,7 @@ char fatLabel[12]; char imgLabel[12]; u32 nandSize = 0; +u32 photoSize = 0; u64 sdSize = 0; u64 fatSize = 0; u64 imgSize = 0; @@ -60,6 +63,8 @@ const char* getDrivePath(void) { return "ram:/"; case Drive::nand: return "nand:/"; + case Drive::nandPhoto: + return "photo:/"; case Drive::nitroFS: return "nitro:/"; case Drive::fatImg: @@ -81,6 +86,10 @@ bool nandFound(void) { return (access("nand:/", F_OK) == 0); } +bool photoFound(void) { + return (access("photo:/", F_OK) == 0); +} + bool sdFound(void) { return (access("sd:/", F_OK) == 0); } @@ -107,14 +116,29 @@ bool nandMount(void) { struct statvfs st; if (statvfs("nand:/", &st) == 0) { nandSize = st.f_bsize * st.f_blocks; + nandMounted = true; + } + + // Photo partition + mbr_t mbr; + io_dsi_nand.readSectors(0, 1, &mbr); + fatMount("photo", &io_dsi_nand, mbr.partitions[1].offset, 16, 8); + + if (photoFound() && statvfs("photo:/", &st) == 0) { + photoSize = st.f_bsize * st.f_blocks; + photoMounted = true; } - return true; } - return false; + + + return nandMounted && photoMounted; } void nandUnmount(void) { - fatUnmount("nand"); + if(nandMounted) + fatUnmount("nand"); + if(photoMounted) + fatUnmount("photo"); nandSize = 0; nandMounted = false; } @@ -415,6 +439,7 @@ bool driveWritable(Drive drive) { case Drive::ramDrive: return io_ram_drive.features & FEATURE_MEDIUM_CANWRITE; case Drive::nand: + case Drive::nandPhoto: return io_dsi_nand.features & FEATURE_MEDIUM_CANWRITE; case Drive::nitroFS: return false; @@ -435,6 +460,8 @@ bool driveRemoved(Drive drive) { return (isDSiMode() || REG_SCFG_EXT != 0) ? !ramdriveMounted : !(*(u16*)(0x020000C0) != 0 || *(vu16*)(0x08240000) == 1); case Drive::nand: return !nandMounted; + case Drive::nandPhoto: + return !photoMounted; case Drive::nitroFS: return driveRemoved(nitroCurrentDrive); case Drive::fatImg: @@ -454,6 +481,8 @@ u64 driveSizeFree(Drive drive) { return getBytesFree("ram:/"); case Drive::nand: return getBytesFree("nand:/"); + case Drive::nandPhoto: + return getBytesFree("photo:/"); case Drive::nitroFS: return 0; case Drive::fatImg: diff --git a/arm9/source/driveOperations.h b/arm9/source/driveOperations.h index b91a176..c44e789 100644 --- a/arm9/source/driveOperations.h +++ b/arm9/source/driveOperations.h @@ -9,11 +9,13 @@ enum class Drive : u8 { flashcard, ramDrive, nand, + nandPhoto, nitroFS, fatImg }; extern bool nandMounted; +extern bool photoMounted; extern bool sdMounted; extern bool sdMountedDone; // true if SD mount is successful once extern bool flashcardMounted; @@ -30,6 +32,7 @@ extern char fatLabel[12]; extern char imgLabel[12]; extern u32 nandSize; +extern u32 photoSize; extern u64 sdSize; extern u64 fatSize; extern u64 imgSize; @@ -38,6 +41,7 @@ extern u32 ramdSize; extern const char* getDrivePath(void); extern bool nandFound(void); +extern bool photoFound(void); extern bool sdFound(void); extern bool flashcardFound(void); extern bool bothSDandFlashcard(void); diff --git a/arm9/source/font.cpp b/arm9/source/font.cpp index 3134c4e..a838151 100644 --- a/arm9/source/font.cpp +++ b/arm9/source/font.cpp @@ -216,6 +216,7 @@ std::u16string Font::utf8to16(std::string_view text) { c |= text[i++] & 0x3F; } else { i++; // out of range or something (This only does up to U+FFFF since it goes to a U16 anyways) + continue; } out += c; } diff --git a/arm9/source/language.inl b/arm9/source/language.inl index 94cf40a..bbe080a 100644 --- a/arm9/source/language.inl +++ b/arm9/source/language.inl @@ -44,6 +44,7 @@ STRING(SDCARD_LABEL, "[sd:] SDCARD (%s)") STRING(FLASHCARD_LABEL, "[fat:] FLASHCARD (%s)") STRING(RAMDRIVE_LABEL, "[ram:] RAMDRIVE") STRING(SYSNAND_LABEL, "[nand:] SYSNAND") +STRING(SYSNAND_PHOTO_LABEL, "[photo:] SYSNAND (photo)") STRING(NITROFS_LABEL, "[nitro:] NDS GAME IMAGE") STRING(FAT_LABEL, "[img:] FAT IMAGE (%s)") STRING(GBA_GAMECART, "GBA GAMECART (%s)") diff --git a/arm9/source/main.cpp b/arm9/source/main.cpp index 3ad2154..7d5b1f0 100644 --- a/arm9/source/main.cpp +++ b/arm9/source/main.cpp @@ -188,7 +188,7 @@ int main(int argc, char **argv) { is3DS = fifoGetValue32(FIFO_USER_05) != 0xD2; } //if (!(keysHeld() & KEY_X)) { - nandMounted = nandMount(); + nandMount(); //} //is3DS = ((access("sd:/Nintendo 3DS", F_OK) == 0) && (*(vu32*)(0x0DFFFE0C) == 0x474D3969)); /*FILE* cidFile = fopen("sd:/gm9i/CID.bin", "wb"); @@ -204,7 +204,7 @@ int main(int argc, char **argv) { if (ram32MB) { is3DS = fifoGetValue32(FIFO_USER_05) != 0xD2; } - //nandMounted = nandMount(); + //nandMount(); } else if (isRegularDS && (io_dldi_data->ioInterface.features & FEATURE_SLOT_NDS)) { ramdriveMount(false); } diff --git a/arm9/source/sector0.c b/arm9/source/sector0.c index fb267b0..d1103c1 100644 --- a/arm9/source/sector0.c +++ b/arm9/source/sector0.c @@ -90,11 +90,13 @@ int parse_mbr(const uint8_t sector0[SECTOR_SIZE], int is3DS, int verbose) { } else { ref_ptable = ptable_3DS; } - // only test the 1st partition now, we've seen variations on the 3rd partition - // and after all we only care about the 1st partition - if (memcmp(ref_ptable, m->partitions, sizeof(mbr_partition_t))) { - //printf("invalid partition table\n"); - ret = -2; + // Only check the first two as those are the only ones we mount + // There's some variation in the 3rd + for(int i = 0; i < 2; i++) { + if (memcmp(&ref_ptable[i], &m->partitions[i], sizeof(mbr_partition_t))) { + //printf("invalid partition table\n"); + ret = -2; + } } return ret; } diff --git a/nitrofiles/languages/en-US/language.ini b/nitrofiles/languages/en-US/language.ini index 4977e38..e840b87 100644 --- a/nitrofiles/languages/en-US/language.ini +++ b/nitrofiles/languages/en-US/language.ini @@ -46,6 +46,7 @@ SDCARD_LABEL=[sd:] SDCARD (%s) FLASHCARD_LABEL=[fat:] FLASHCARD (%s) RAMDRIVE_LABEL=[ram:] RAMDRIVE SYSNAND_LABEL=[nand:] SYSNAND +SYSNAND_PHOTO_LABEL=[photo:] SYSNAND (photo) NITROFS_LABEL=[nitro:] NDS GAME IMAGE FAT_LABEL=[img:] FAT IMAGE (%s) GBA_GAMECART=GBA GAMECART (%s)