diff --git a/arm9/source/driveMenu.cpp b/arm9/source/driveMenu.cpp index 5a58a8f..db48859 100644 --- a/arm9/source/driveMenu.cpp +++ b/arm9/source/driveMenu.cpp @@ -39,6 +39,8 @@ #define ENTRIES_START_ROW 1 #define ENTRY_PAGE_LENGTH 10 +#define sizeOfdmAssignedOp 8 + using namespace std; //static bool ramDumped = false; @@ -47,7 +49,7 @@ bool flashcardMountSkipped = true; static bool flashcardMountRan = true; static bool dmTextPrinted = false; static int dmCursorPosition = 0; -static int dmAssignedOp[7] = {-1}; +static int dmAssignedOp[sizeOfdmAssignedOp] = {-1}; static int dmMaxCursors = -1; static u8 gbaFixedValue = 0; @@ -118,7 +120,8 @@ void dm_drawTopScreen(void) { || (flashcardMounted && nitroCurrentDrive==1) || (ramdrive1Mounted && nitroCurrentDrive==2) || (ramdrive2Mounted && nitroCurrentDrive==3) - || (nandMounted && nitroCurrentDrive==4)) + || (nandMounted && nitroCurrentDrive==4) + || (imgMounted && nitroCurrentDrive==6)) { // Do nothing } @@ -135,6 +138,23 @@ void dm_drawTopScreen(void) { printf ("[ram2:] RAMDRIVE"); } else if (dmAssignedOp[i] == 7) { printf ("[nand:] SYSNAND"); + } else if (dmAssignedOp[i] == 8) { + printf ("[img:] FAT IMAGE"); + if ((sdMounted && imgCurrentDrive==0) + || (flashcardMounted && imgCurrentDrive==1) + || (ramdrive1Mounted && imgCurrentDrive==2) + || (ramdrive2Mounted && imgCurrentDrive==3) + || (nandMounted && imgCurrentDrive==4)) + { + if (imgLabel[0] != '\0') { + iprintf (" (%s)", imgLabel); + } + } + else + { + iprintf ("\x1b[%d;29H", i + ENTRIES_START_ROW); + printf ("[x]"); + } } } } @@ -207,6 +227,11 @@ void dm_drawBottomScreen(void) { printf ("\n(SysNAND FAT, "); printDriveBytes(nandSize); printf(")"); + } else if (dmAssignedOp[dmCursorPosition] == 8) { + printf ("[img:] FAT IMAGE"); + printf ("\n(Image FAT, "); + printDriveBytes(imgSize); + printf(")"); } } @@ -219,7 +244,7 @@ void driveMenu (void) { gbaFixedValue = *(u8*)(0x080000B2); } - for (int i = 0; i < 6; i++) { + for (int i = 0; i < sizeOfdmAssignedOp; i++) { dmAssignedOp[i] = -1; } dmMaxCursors = -1; @@ -243,6 +268,10 @@ void driveMenu (void) { dmMaxCursors++; dmAssignedOp[dmMaxCursors] = 6; } + if (imgMounted) { + dmMaxCursors++; + dmAssignedOp[dmMaxCursors] = 8; + } if (expansionPakFound || (io_dldi_data->ioInterface.features & FEATURE_SLOT_GBA) || (isDSiMode() && !arm7SCFGLocked && !(REG_SCFG_MC & BIT(0)))) { @@ -334,10 +363,11 @@ void driveMenu (void) { || (flashcardMounted && nitroCurrentDrive==1) || (ramdrive1Mounted && nitroCurrentDrive==2) || (ramdrive2Mounted && nitroCurrentDrive==3) - || (nandMounted && nitroCurrentDrive==4)) + || (nandMounted && nitroCurrentDrive==4) + || (imgMounted && nitroCurrentDrive==6)) { dmTextPrinted = false; - currentDrive = nitroCurrentDrive; + currentDrive = 5; chdir("nitro:/"); screenMode = 1; break; @@ -363,6 +393,19 @@ void driveMenu (void) { chdir("nand:/"); screenMode = 1; break; + } else if (dmAssignedOp[dmCursorPosition] == 8 && imgMounted) { + if ((sdMounted && imgCurrentDrive==0) + || (flashcardMounted && imgCurrentDrive==1) + || (ramdrive1Mounted && imgCurrentDrive==2) + || (ramdrive2Mounted && imgCurrentDrive==3) + || (nandMounted && imgCurrentDrive==4)) + { + dmTextPrinted = false; + currentDrive = 6; + chdir("img:/"); + screenMode = 1; + break; + } } } diff --git a/arm9/source/driveOperations.cpp b/arm9/source/driveOperations.cpp index f96d32b..c4054f2 100644 --- a/arm9/source/driveOperations.cpp +++ b/arm9/source/driveOperations.cpp @@ -11,6 +11,7 @@ #include "ramd.h" #include "ramdrive-include.h" #include "nandio.h" +#include "imgio.h" #include "tonccpy.h" static sNDSHeader nds; @@ -20,23 +21,26 @@ u8 stored_SCFG_MC = 0; static bool slot1Enabled = true; bool nandMounted = false; -bool nandMountedDone = false; bool sdMounted = false; bool sdMountedDone = false; // true if SD mount is successful once bool flashcardMounted = false; bool ramdrive1Mounted = false; bool ramdrive2Mounted = false; +bool imgMounted = false; bool nitroMounted = false; -int currentDrive = 0; // 0 == SD card, 1 == Flashcard, 2 == RAMdrive 1, 3 == RAMdrive 2, 4 == NAND +int currentDrive = 0; // 0 == SD card, 1 == Flashcard, 2 == RAMdrive 1, 3 == RAMdrive 2, 4 == NAND, 5 == NitroFS, 6 == FAT IMG int nitroCurrentDrive = 0; +int imgCurrentDrive = 0; char sdLabel[12]; char fatLabel[12]; +char imgLabel[12]; u32 nandSize = 0; u64 sdSize = 0; u64 fatSize = 0; +u64 imgSize = 0; static int getGbNumber(u64 bytes) { int gbNumber = 0; @@ -87,28 +91,21 @@ const char* getDrivePath(void) { return "ram2:/"; case 4: return "nand:/"; + case 5: + return "nitro:/"; + case 6: + return "img:/"; } return ""; } -void fixLabel(bool fat) { - if (fat) { - for (int i = 0; i < 12; i++) { - if (((fatLabel[i] == ' ') && (fatLabel[i+1] == ' ') && (fatLabel[i+2] == ' ')) - || ((fatLabel[i] == ' ') && (fatLabel[i+1] == ' ')) - || (fatLabel[i] == ' ')) { - fatLabel[i] = '\0'; - break; - } - } - } else { - for (int i = 0; i < 12; i++) { - if (((sdLabel[i] == ' ') && (sdLabel[i+1] == ' ') && (sdLabel[i+2] == ' ')) - || ((sdLabel[i] == ' ') && (sdLabel[i+1] == ' ')) - || (sdLabel[i] == ' ')) { - sdLabel[i] = '\0'; - break; - } +void fixLabel(char* label) { + for (int i = 0; i < 12; i++) { + if (((label[i] == ' ') && (label[i+1] == ' ') && (label[i+2] == ' ')) + || ((label[i] == ' ') && (label[i+1] == ' ')) + || (label[i] == ' ')) { + label[i] = '\0'; + break; } } } @@ -133,10 +130,13 @@ bool bothSDandFlashcard(void) { } } +bool imgFound(void) { + return (access("img:/", F_OK) == 0); +} + TWL_CODE bool nandMount(void) { fatMountSimple("nand", &io_dsi_nand); if (nandFound()) { - nandMountedDone = true; struct statvfs st; if (statvfs("nand:/", &st) == 0) { nandSize = st.f_bsize * st.f_blocks; @@ -157,7 +157,7 @@ TWL_CODE bool sdMount(void) { if (sdFound()) { sdMountedDone = true; fatGetVolumeLabel("sd", sdLabel); - fixLabel(false); + fixLabel(&sdLabel[0]); struct statvfs st; if (statvfs("sd:/", &st) == 0) { sdSize = st.f_bsize * st.f_blocks; @@ -296,7 +296,7 @@ TWL_CODE bool twl_flashcardMount(void) { if (flashcardFound()) { fatGetVolumeLabel("fat", fatLabel); - fixLabel(true); + fixLabel(&fatLabel[0]); struct statvfs st; if (statvfs("fat:/", &st) == 0) { fatSize = st.f_bsize * st.f_blocks; @@ -312,7 +312,7 @@ bool flashcardMount(void) { fatInitDefault(); if (flashcardFound()) { fatGetVolumeLabel("fat", fatLabel); - fixLabel(true); + fixLabel(&fatLabel[0]); struct statvfs st; if (statvfs("fat:/", &st) == 0) { fatSize = st.f_bsize * st.f_blocks; @@ -343,3 +343,27 @@ TWL_CODE void ramdrive2Mount(void) { fatMountSimple("ram2", &io_ram_drive2); ramdrive2Mounted = (access("ram2:/", F_OK) == 0); } + +bool imgMount(const char* imgName) { + extern const char* currentImgName; + + currentImgName = imgName; + fatMountSimple("img", &io_img); + if (imgFound()) { + fatGetVolumeLabel("img", imgLabel); + fixLabel(&imgLabel[0]); + struct statvfs st; + if (statvfs("img:/", &st) == 0) { + imgSize = st.f_bsize * st.f_blocks; + } + return true; + } + return false; +} + +void imgUnmount(void) { + fatUnmount("img"); + imgLabel[0] = '\0'; + imgSize = 0; + imgMounted = false; +} diff --git a/arm9/source/driveOperations.h b/arm9/source/driveOperations.h index 70d1708..487a007 100644 --- a/arm9/source/driveOperations.h +++ b/arm9/source/driveOperations.h @@ -4,23 +4,26 @@ extern u8 stored_SCFG_MC; extern bool nandMounted; -extern bool nandMountedDone; extern bool sdMounted; extern bool sdMountedDone; // true if SD mount is successful once extern bool flashcardMounted; extern bool ramdrive1Mounted; extern bool ramdrive2Mounted; +extern bool imgMounted; extern bool nitroMounted; -extern int currentDrive; // 0 == SD card, 1 == Flashcard, 2 == RAMdrive 1, 3 == RAMdrive 2, 4 == NAND +extern int currentDrive; // 0 == SD card, 1 == Flashcard, 2 == RAMdrive 1, 3 == RAMdrive 2, 4 == NAND, 5 == NitroFS, 6 == FAT IMG extern int nitroCurrentDrive; +extern int imgCurrentDrive; extern char sdLabel[12]; extern char fatLabel[12]; +extern char imgLabel[12]; extern u32 nandSize; extern u64 sdSize; extern u64 fatSize; +extern u64 imgSize; extern void printDriveBytes(u64 bytes); extern const char* getDrivePath(void); @@ -29,6 +32,7 @@ extern bool nandFound(void); extern bool sdFound(void); extern bool flashcardFound(void); extern bool bothSDandFlashcard(void); +extern bool imgFound(void); extern bool nandMount(void); extern void nandUnmount(void); extern bool sdMount(void); @@ -37,5 +41,7 @@ extern bool flashcardMount(void); extern void flashcardUnmount(void); extern void ramdrive1Mount(void); extern void ramdrive2Mount(void); +extern bool imgMount(const char* imgName); +extern void imgUnmount(void); #endif //FLASHCARD_H diff --git a/arm9/source/file_browse.cpp b/arm9/source/file_browse.cpp index a41c132..168246b 100644 --- a/arm9/source/file_browse.cpp +++ b/arm9/source/file_browse.cpp @@ -234,6 +234,16 @@ int fileBrowse_A(DirEntry* entry, char path[PATH_MAX]) { assignedOp[maxCursors] = 3; printf(" Mount NitroFS\n"); } + else + if((entry->name.substr(entry->name.find_last_of(".") + 1) == "img") + || (entry->name.substr(entry->name.find_last_of(".") + 1) == "IMG") + || (entry->name.substr(entry->name.find_last_of(".") + 1) == "sd") + || (entry->name.substr(entry->name.find_last_of(".") + 1) == "SD")) + { + maxCursors++; + assignedOp[maxCursors] = 5; + printf(" Mount as FAT image\n"); + } } maxCursors++; assignedOp[maxCursors] = 4; @@ -328,9 +338,17 @@ int fileBrowse_A(DirEntry* entry, char path[PATH_MAX]) { if (nitroMounted) { chdir("nitro:/"); nitroCurrentDrive = currentDrive; + currentDrive = 5; } } else if (assignedOp[optionOffset] == 4) { changeFileAttribs(entry); + } else if (assignedOp[optionOffset] == 5) { + imgMounted = imgMount(entry->name.c_str()); + if (imgMounted) { + chdir("img:/"); + imgCurrentDrive = currentDrive; + currentDrive = 6; + } } return assignedOp[optionOffset]; } @@ -550,8 +568,7 @@ string browseForFile (void) { if ((!(held & KEY_R) && (pressed & KEY_A)) || (!entry->isDirectory && (held & KEY_R) && (pressed & KEY_A))) { - if (((strcmp (entry->name.c_str(), "..") == 0) && (strcmp (path, getDrivePath()) == 0)) - || ((strcmp (entry->name.c_str(), "..") == 0) && (strcmp (path, "nitro:/") == 0))) + if ((strcmp (entry->name.c_str(), "..") == 0) && (strcmp (path, getDrivePath()) == 0)) { screenMode = 0; return "null"; @@ -567,9 +584,9 @@ string browseForFile (void) { if (getOp == 0) { // Return the chosen file return entry->name; - } else if (getOp == 1 || getOp == 2 || (getOp == 3 && nitroMounted)) { + } else if (getOp == 1 || getOp == 2 || (getOp == 3 && nitroMounted) || (getOp == 5 && imgMounted)) { getDirectoryContents (dirContents); // Refresh directory listing - if (getOp == 3 && nitroMounted) { + if ((getOp == 3 && nitroMounted) || (getOp == 5 && imgMounted)) { screenOffset = 0; fileOffset = 0; } @@ -599,7 +616,7 @@ string browseForFile (void) { } if (pressed & KEY_B) { - if ((strcmp (path, getDrivePath()) == 0) || (strcmp (path, "nitro:/") == 0)) { + if (strcmp (path, getDrivePath()) == 0) { screenMode = 0; return "null"; } diff --git a/arm9/source/imgio.c b/arm9/source/imgio.c new file mode 100644 index 0000000..0741371 --- /dev/null +++ b/arm9/source/imgio.c @@ -0,0 +1,64 @@ + +#include +#include +#include + +#define SECTOR_SIZE 512 + +const char* currentImgName; +static FILE* imgFile[2]; + +bool img_startup() { + imgFile[0] = fopen(currentImgName, "rb"); + if (imgFile[0]) { + //imgFile[1] = fopen(currentImgName, "wb"); + return true; + } + return false; +} + +bool img_is_inserted() { + if (imgFile[0]) { + return true; + } + return false; +} + +bool img_read_sectors(sec_t sector, sec_t numSectors, void *buffer) { + if (!imgFile[0]) return false; + + fseek(imgFile[0], (sector << 9), SEEK_SET); + fread(buffer, 1, (numSectors << 9), imgFile[0]); + return true; +} + +bool img_write_sectors(sec_t sector, sec_t numSectors, const void *buffer) { + /*if (!imgFile[1]) return false; + + fseek(imgFile[1], (sector << 9), SEEK_SET); + fwrite(buffer, 1, (numSectors << 9), imgFile[1]); + return true;*/ + return false; +} + +bool img_clear_status() { + return true; +} + +bool img_shutdown() { + fclose(imgFile[0]); + fclose(imgFile[1]); + return true; +} + +const DISC_INTERFACE io_img = { + ('I' << 24) | ('M' << 16) | ('G' << 8) | 'F', + //FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE, + FEATURE_MEDIUM_CANREAD, + img_startup, + img_is_inserted, + img_read_sectors, + img_write_sectors, + img_clear_status, + img_shutdown +}; diff --git a/arm9/source/imgio.h b/arm9/source/imgio.h new file mode 100644 index 0000000..a203e7e --- /dev/null +++ b/arm9/source/imgio.h @@ -0,0 +1,6 @@ +#pragma once + +#include +#include + +extern const DISC_INTERFACE io_img; diff --git a/arm9/source/main.cpp b/arm9/source/main.cpp index d0358ed..3560c12 100644 --- a/arm9/source/main.cpp +++ b/arm9/source/main.cpp @@ -139,7 +139,7 @@ int main(int argc, char **argv) { bool yHeld = false; - sprintf(titleName, "GodMode9i v%i.%i.%i", 2, 2, 1); + sprintf(titleName, "GodMode9i v%i.%i.%i", 2, 3, 0); // initialize video mode videoSetMode(MODE_4_2D);