Add save file restoring (#68)

* Remove `using namespace std`

* Improve extension function and use more

* Add save restoring

and remove fstream to save ~300KB
This commit is contained in:
Pk11 2020-08-20 20:09:20 -05:00 committed by GitHub
parent 2ae90b4fff
commit 5437be1a2e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 276 additions and 161 deletions

View File

@ -54,7 +54,7 @@ size_t GetDate(DateFormat format, char *buf, size_t size)
* Get the current time formatted for the top bar. * Get the current time formatted for the top bar.
* @return std::string containing the time. * @return std::string containing the time.
*/ */
string RetTime() std::string RetTime()
{ {
time_t Raw; time_t Raw;
time(&Raw); time(&Raw);
@ -63,14 +63,14 @@ string RetTime()
char Tmp[8]; char Tmp[8];
strftime(Tmp, sizeof(Tmp), "%k:%M", Time); strftime(Tmp, sizeof(Tmp), "%k:%M", Time);
return string(Tmp); return std::string(Tmp);
} }
/** /**
* Get the current time formatted for filenames. * Get the current time formatted for filenames.
* @return std::string containing the time. * @return std::string containing the time.
*/ */
string RetTimeForFilename() std::string RetTimeForFilename()
{ {
time_t Raw; time_t Raw;
time(&Raw); time(&Raw);
@ -79,7 +79,7 @@ string RetTimeForFilename()
char Tmp[8]; char Tmp[8];
strftime(Tmp, sizeof(Tmp), "%k%M%S", Time); strftime(Tmp, sizeof(Tmp), "%k%M%S", Time);
return string(Tmp); return std::string(Tmp);
} }
/** /**

View File

@ -41,8 +41,6 @@
#define sizeOfdmAssignedOp 8 #define sizeOfdmAssignedOp 8
using namespace std;
//static bool ramDumped = false; //static bool ramDumped = false;
bool flashcardMountSkipped = true; bool flashcardMountSkipped = true;

View File

@ -4,7 +4,6 @@
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <dirent.h> #include <dirent.h>
#include <fstream>
#include "auxspi.h" #include "auxspi.h"
#include "date.h" #include "date.h"
@ -22,16 +21,16 @@ extern PrintConsole topConsole, bottomConsole;
static sNDSHeaderExt ndsCardHeader; static sNDSHeaderExt ndsCardHeader;
void ndsCardSaveDump(const char* filename) { void ndsCardSaveDump(const char* filename) {
std::ofstream output(filename, std::ofstream::binary); FILE *out = fopen(filename, "wb");
if(output.is_open()) { if(out) {
auxspi_extra card_type = auxspi_has_extra();
consoleClear(); consoleClear();
printf("Dumping save...\n"); printf("Dumping save...\n");
printf("Do not remove the NDS card.\n"); printf("Do not remove the NDS card.\n");
unsigned char* buffer; unsigned char *buffer;
auxspi_extra card_type = auxspi_has_extra();
if(card_type == AUXSPI_INFRARED) { if(card_type == AUXSPI_INFRARED) {
int size = auxspi_save_size_log_2(card_type); int size = auxspi_save_size_log_2(card_type);
int size_blocks = 1 << std::max(0, (int8(size) - 18)); int size_blocks;
int type = auxspi_save_type(card_type); int type = auxspi_save_type(card_type);
if(size < 16) if(size < 16)
size_blocks = 1; size_blocks = 1;
@ -40,17 +39,136 @@ void ndsCardSaveDump(const char* filename) {
u32 LEN = std::min(1 << size, 1 << 16); u32 LEN = std::min(1 << size, 1 << 16);
buffer = new unsigned char[LEN*size_blocks]; buffer = new unsigned char[LEN*size_blocks];
auxspi_read_data(0, buffer, LEN*size_blocks, type, card_type); auxspi_read_data(0, buffer, LEN*size_blocks, type, card_type);
output.write((char*)buffer, LEN*size_blocks); fwrite(buffer, 1, LEN*size_blocks, out);
} else { } else {
int type = cardEepromGetType(); int type = cardEepromGetType();
int size = cardEepromGetSize(); int size = cardEepromGetSize();
buffer = new unsigned char[size]; buffer = new unsigned char[size];
cardReadEeprom(0, buffer, size, type); cardReadEeprom(0, buffer, size, type);
output.write((char*)buffer, size); fwrite(buffer, 1, size, out);
} }
delete[] buffer; delete[] buffer;
fclose(out);
}
}
void ndsCardSaveRestore(const char *filename) {
consoleSelect(&bottomConsole);
consoleClear();
printf ("\x1B[47m"); // Print foreground white color
printf("Restore the selected save to the"); // Line is 32 chars
printf("inserted game card?\n"); // Line is 32 chars
printf("(<A> yes, <B> no)\n");
consoleSelect(&topConsole);
printf ("\x1B[30m"); // Print black color
// Power saving loop. Only poll the keys once per frame and sleep the CPU if there is nothing else to do
u16 pressed;
do {
// Move to right side of screen
printf ("\x1b[0;26H");
// Print time
printf (" %s" ,RetTime().c_str());
scanKeys();
pressed = keysDownRepeat();
swiWaitForVBlank();
} while (!(pressed & (KEY_A | KEY_B)));
if(pressed & KEY_A) {
consoleSelect(&bottomConsole);
consoleClear();
auxspi_extra card_type = auxspi_has_extra();
bool auxspi = card_type == AUXSPI_INFRARED;
FILE *in = fopen(filename, "rb");
if(in) {
unsigned char *buffer;
int size;
int type;
int length;
unsigned int num_blocks = 0, shift = 0, LEN = 0;
if(auxspi) {
size = auxspi_save_size_log_2(card_type);
type = auxspi_save_type(card_type);
switch(type) {
case 1:
shift = 4; // 16 bytes
break;
case 2:
shift = 5; // 32 bytes
break;
case 3:
shift = 8; // 256 bytes
break;
default:
return;
}
LEN = 1 << shift;
num_blocks = 1 << (size - shift);
} else {
type = cardEepromGetType();
size = cardEepromGetSize();
}
fseek(in, 0, SEEK_END);
length = ftell(in);
fseek(in, 0, SEEK_SET);
if(length != (auxspi ? (int)(LEN*num_blocks) : size)) {
fclose(in);
printf("\x1B[41m"); // Print foreground red color
printf("The size of this save doesn't\n");
printf("match the size of the size of\n");
printf("the inserted game card.\n\n");
printf("Write cancelled!\n");
printf("\x1B[47m"); // Print foreground white color
printf("(<A> OK)\n");
consoleSelect(&topConsole);
printf ("\x1B[30m"); // Print black color
do {
// Move to right side of screen
printf ("\x1b[0;26H");
// Print time
printf (" %s" ,RetTime().c_str());
scanKeys();
pressed = keysDownRepeat();
swiWaitForVBlank();
} while (!(pressed & KEY_A));
return;
}
printf("Restoring save...\nDo not remove the NDS card.\n\n\n\n\n\n\nProgress:");
if(type == 3) {
if(auxspi)
auxspi_erase(card_type);
else
cardEepromChipErase();
}
if(auxspi){
buffer = new unsigned char[LEN];
for(unsigned int i = 0; i < num_blocks; i++) {
printf ("\x1b[9;0H");
printf ("%d/%d Bytes", i * LEN, length);
fread(buffer, 1, LEN, in);
auxspi_write_data(i << shift, buffer, LEN, type, card_type);
}
} else {
int blocks = size / 32;
int written = 0;
buffer = new unsigned char[blocks];
for(unsigned int i = 0; i < 32; i++) {
printf ("\x1b[9;0H");
printf ("%d/%d Bytes", i * blocks, length);
fread(buffer, 1, blocks, in);
cardWriteEeprom(written, buffer, blocks, type);
written += blocks;
}
}
delete[] buffer;
fclose(in);
}
} }
output.close();
} }
void ndsCardDump(void) { void ndsCardDump(void) {
@ -77,7 +195,7 @@ void ndsCardDump(void) {
scanKeys(); scanKeys();
pressed = keysDownRepeat(); pressed = keysDownRepeat();
swiWaitForVBlank(); swiWaitForVBlank();
} while (!(pressed & KEY_A) && !(pressed & KEY_Y) && !(pressed & KEY_B) && !(pressed & KEY_X)); } while (!(pressed & (KEY_A | KEY_Y | KEY_B | KEY_X)));
consoleSelect(&bottomConsole); consoleSelect(&bottomConsole);
printf ("\x1B[47m"); // Print foreground white color printf ("\x1B[47m"); // Print foreground white color

View File

@ -1,7 +1,9 @@
#ifndef DUMPING_H #ifndef DUMPING_H
#define DUMPING_H #define DUMPING_H
extern void ndsCardDump(void); void ndsCardSaveRestore(const char *filename);
extern void gbaCartDump(void);
void ndsCardDump(void);
void gbaCartDump(void);
#endif //DUMPING_H #endif //DUMPING_H

View File

@ -8,15 +8,13 @@
#include "date.h" #include "date.h"
#include "file_browse.h" #include "file_browse.h"
using namespace std;
#define copyBufSize 0x8000 #define copyBufSize 0x8000
u32 copyBuf[copyBufSize]; u32 copyBuf[copyBufSize];
extern PrintConsole topConsole, bottomConsole; extern PrintConsole topConsole, bottomConsole;
vector<ClipboardFile> clipboard; std::vector<ClipboardFile> clipboard;
bool clipboardOn = false; bool clipboardOn = false;
bool clipboardUsed = false; bool clipboardUsed = false;
@ -77,7 +75,7 @@ off_t getFileSize(const char *fileName)
} }
void dirCopy(DirEntry* entry, int i, const char *destinationPath, const char *sourcePath) { void dirCopy(DirEntry* entry, int i, const char *destinationPath, const char *sourcePath) {
vector<DirEntry> dirContents; std::vector<DirEntry> dirContents;
dirContents.clear(); dirContents.clear();
if (entry->isDirectory) chdir((sourcePath + ("/" + entry->name)).c_str()); if (entry->isDirectory) chdir((sourcePath + ("/" + entry->name)).c_str());
getDirectoryContents(dirContents); getDirectoryContents(dirContents);
@ -94,7 +92,7 @@ int fcopy(const char *sourcePath, const char *destinationPath)
// Source path is a directory // Source path is a directory
chdir(sourcePath); chdir(sourcePath);
vector<DirEntry> dirContents; std::vector<DirEntry> dirContents;
getDirectoryContents(dirContents); getDirectoryContents(dirContents);
DirEntry* entry = NULL; DirEntry* entry = NULL;

View File

@ -15,7 +15,7 @@ struct ClipboardFile {
ClipboardFile(const char *path, const char *name, bool folder, int drive, bool nitro); ClipboardFile(const char *path, const char *name, bool folder, int drive, bool nitro);
}; };
extern vector<ClipboardFile> clipboard; extern std::vector<ClipboardFile> clipboard;
extern bool clipboardOn; extern bool clipboardOn;
extern bool clipboardUsed; extern bool clipboardUsed;

View File

@ -37,6 +37,7 @@
#include "fileOperations.h" #include "fileOperations.h"
#include "driveMenu.h" #include "driveMenu.h"
#include "driveOperations.h" #include "driveOperations.h"
#include "dumpOperations.h"
#include "nitrofs.h" #include "nitrofs.h"
#define SCREEN_COLS 22 #define SCREEN_COLS 22
@ -55,11 +56,13 @@ extern void reinitConsoles(void);
static char path[PATH_MAX]; static char path[PATH_MAX];
bool nameEndsWith (const string& name) { bool extension(const std::string &filename, const std::vector<std::string> &extensions) {
for(const std::string &ext : extensions) {
if(filename.length() > ext.length() && strcasecmp(filename.substr(filename.length() - ext.length()).data(), ext.data()) == 0)
return true;
}
if (name.size() == 0) return false; return false;
return true;
} }
void OnKeyPressed(int key) { void OnKeyPressed(int key) {
@ -78,7 +81,7 @@ bool dirEntryPredicate (const DirEntry& lhs, const DirEntry& rhs) {
return strcasecmp(lhs.name.c_str(), rhs.name.c_str()) < 0; return strcasecmp(lhs.name.c_str(), rhs.name.c_str()) < 0;
} }
void getDirectoryContents (vector<DirEntry>& dirContents) { void getDirectoryContents (std::vector<DirEntry>& dirContents) {
struct stat st; struct stat st;
dirContents.clear(); dirContents.clear();
@ -102,27 +105,15 @@ void getDirectoryContents (vector<DirEntry>& dirContents) {
if (!dirEntry.isDirectory) { if (!dirEntry.isDirectory) {
dirEntry.size = getFileSize(dirEntry.name.c_str()); dirEntry.size = getFileSize(dirEntry.name.c_str());
} }
if ((dirEntry.name.substr(dirEntry.name.find_last_of(".") + 1) == "nds") if (extension(dirEntry.name, {"nds", "argv", "dsi", "ids", "app"})) {
|| (dirEntry.name.substr(dirEntry.name.find_last_of(".") + 1) == "NDS")
|| (dirEntry.name.substr(dirEntry.name.find_last_of(".") + 1) == "argv")
|| (dirEntry.name.substr(dirEntry.name.find_last_of(".") + 1) == "ARGV")
|| (dirEntry.name.substr(dirEntry.name.find_last_of(".") + 1) == "dsi")
|| (dirEntry.name.substr(dirEntry.name.find_last_of(".") + 1) == "DSI")
|| (dirEntry.name.substr(dirEntry.name.find_last_of(".") + 1) == "ids")
|| (dirEntry.name.substr(dirEntry.name.find_last_of(".") + 1) == "IDS")
|| (dirEntry.name.substr(dirEntry.name.find_last_of(".") + 1) == "app")
|| (dirEntry.name.substr(dirEntry.name.find_last_of(".") + 1) == "APP"))
{
dirEntry.isApp = ((currentDrive == 0 && sdMounted) || (currentDrive == 1 && flashcardMounted)); dirEntry.isApp = ((currentDrive == 0 && sdMounted) || (currentDrive == 1 && flashcardMounted));
} else if ((dirEntry.name.substr(dirEntry.name.find_last_of(".") + 1) == "firm") } else if (extension(dirEntry.name, {"firm"})) {
|| (dirEntry.name.substr(dirEntry.name.find_last_of(".") + 1) == "FIRM"))
{
dirEntry.isApp = (isDSiMode() && is3DS && sdMounted); dirEntry.isApp = (isDSiMode() && is3DS && sdMounted);
} else { } else {
dirEntry.isApp = false; dirEntry.isApp = false;
} }
if (dirEntry.name.compare(".") != 0 && (dirEntry.isDirectory || nameEndsWith(dirEntry.name))) { if (dirEntry.name.compare(".") != 0) {
dirContents.push_back (dirEntry); dirContents.push_back (dirEntry);
} }
} }
@ -141,7 +132,7 @@ void getDirectoryContents (vector<DirEntry>& dirContents) {
dirContents.insert (dirContents.begin(), dirEntry); // Add ".." to top of list dirContents.insert (dirContents.begin(), dirEntry); // Add ".." to top of list
} }
void showDirectoryContents (const vector<DirEntry>& dirContents, int fileOffset, int startRow) { void showDirectoryContents (const std::vector<DirEntry>& dirContents, int fileOffset, int startRow) {
getcwd(path, PATH_MAX); getcwd(path, PATH_MAX);
consoleClear(); consoleClear();
@ -192,9 +183,9 @@ void showDirectoryContents (const vector<DirEntry>& dirContents, int fileOffset,
printf ("\x1B[47m"); // Print foreground white color printf ("\x1B[47m"); // Print foreground white color
} }
int fileBrowse_A(DirEntry* entry, char path[PATH_MAX]) { FileOperation fileBrowse_A(DirEntry* entry, char path[PATH_MAX]) {
int pressed = 0; int pressed = 0;
int assignedOp[4] = {0}; FileOperation assignedOp[4] = {FileOperation::none};
int optionOffset = 0; int optionOffset = 0;
int cursorScreenPos = 0; int cursorScreenPos = 0;
int maxCursors = -1; int maxCursors = -1;
@ -218,44 +209,39 @@ int fileBrowse_A(DirEntry* entry, char path[PATH_MAX]) {
if (!entry->isDirectory) { if (!entry->isDirectory) {
if (entry->isApp) { if (entry->isApp) {
maxCursors++; maxCursors++;
assignedOp[maxCursors] = 0; assignedOp[maxCursors] = FileOperation::bootFile;
printf(" Boot file\n"); printf(" Boot file\n");
} }
if((entry->name.substr(entry->name.find_last_of(".") + 1) == "nds") if(extension(entry->name, {"nds", "dsi", "ids", "app"}))
|| (entry->name.substr(entry->name.find_last_of(".") + 1) == "NDS")
|| (entry->name.substr(entry->name.find_last_of(".") + 1) == "dsi")
|| (entry->name.substr(entry->name.find_last_of(".") + 1) == "DSI")
|| (entry->name.substr(entry->name.find_last_of(".") + 1) == "ids")
|| (entry->name.substr(entry->name.find_last_of(".") + 1) == "IDS")
|| (entry->name.substr(entry->name.find_last_of(".") + 1) == "app")
|| (entry->name.substr(entry->name.find_last_of(".") + 1) == "APP"))
{ {
maxCursors++; maxCursors++;
assignedOp[maxCursors] = 3; assignedOp[maxCursors] = FileOperation::mountNitroFS;
printf(" Mount NitroFS\n"); printf(" Mount NitroFS\n");
} }
else else if(extension(entry->name, {"sav"}))
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++; maxCursors++;
assignedOp[maxCursors] = 5; assignedOp[maxCursors] = FileOperation::restoreSave;
printf(" Restore save\n");
}
else if(extension(entry->name, {"img", "sd"}))
{
maxCursors++;
assignedOp[maxCursors] = FileOperation::mountImg;
printf(" Mount as FAT image\n"); printf(" Mount as FAT image\n");
} }
} }
maxCursors++; maxCursors++;
assignedOp[maxCursors] = 4; assignedOp[maxCursors] = FileOperation::showInfo;
printf(entry->isDirectory ? " Show directory info\n" : " Show file info\n"); printf(entry->isDirectory ? " Show directory info\n" : " Show file info\n");
if (sdMounted && (strcmp (path, "sd:/gm9i/out/") != 0)) { if (sdMounted && (strcmp (path, "sd:/gm9i/out/") != 0)) {
maxCursors++; maxCursors++;
assignedOp[maxCursors] = 1; assignedOp[maxCursors] = FileOperation::copySdOut;
printf(" Copy to sd:/gm9i/out\n"); printf(" Copy to sd:/gm9i/out\n");
} }
if (flashcardMounted && (strcmp (path, "fat:/gm9i/out/") != 0)) { if (flashcardMounted && (strcmp (path, "fat:/gm9i/out/") != 0)) {
maxCursors++; maxCursors++;
assignedOp[maxCursors] = 2; assignedOp[maxCursors] = FileOperation::copyFatOut;
printf(" Copy to fat:/gm9i/out\n"); printf(" Copy to fat:/gm9i/out\n");
} }
printf("\n"); printf("\n");
@ -295,75 +281,88 @@ int fileBrowse_A(DirEntry* entry, char path[PATH_MAX]) {
if (optionOffset > maxCursors) optionOffset = 0; // Wrap around to top of list if (optionOffset > maxCursors) optionOffset = 0; // Wrap around to top of list
if (pressed & KEY_A) { if (pressed & KEY_A) {
if (assignedOp[optionOffset] == 0) { switch(assignedOp[optionOffset]) {
applaunch = true; case FileOperation::bootFile: {
iprintf ("\x1b[%d;3H", optionOffset + OPTIONS_ENTRIES_START_ROW+cursorScreenPos); applaunch = true;
printf("Now loading...");
} else if (assignedOp[optionOffset] == 1) {
if (access("sd:/gm9i", F_OK) != 0) {
iprintf ("\x1b[%d;3H", optionOffset + OPTIONS_ENTRIES_START_ROW+cursorScreenPos); iprintf ("\x1b[%d;3H", optionOffset + OPTIONS_ENTRIES_START_ROW+cursorScreenPos);
printf("Creating directory..."); printf("Now loading...");
mkdir("sd:/gm9i", 0777); break;
} } case FileOperation::restoreSave: {
if (access("sd:/gm9i/out", F_OK) != 0) { ndsCardSaveRestore(entry->name.c_str());
break;
} case FileOperation::copySdOut: {
if (access("sd:/gm9i", F_OK) != 0) {
iprintf ("\x1b[%d;3H", optionOffset + OPTIONS_ENTRIES_START_ROW+cursorScreenPos);
printf("Creating directory...");
mkdir("sd:/gm9i", 0777);
}
if (access("sd:/gm9i/out", F_OK) != 0) {
iprintf ("\x1b[%d;3H", optionOffset + OPTIONS_ENTRIES_START_ROW+cursorScreenPos);
printf("Creating directory...");
mkdir("sd:/gm9i/out", 0777);
}
char destPath[256];
snprintf(destPath, sizeof(destPath), "sd:/gm9i/out/%s", entry->name.c_str());
iprintf ("\x1b[%d;3H", optionOffset + OPTIONS_ENTRIES_START_ROW+cursorScreenPos); iprintf ("\x1b[%d;3H", optionOffset + OPTIONS_ENTRIES_START_ROW+cursorScreenPos);
printf("Creating directory..."); printf("Copying... ");
mkdir("sd:/gm9i/out", 0777); remove(destPath);
} char sourceFolder[PATH_MAX];
char destPath[256]; getcwd(sourceFolder, PATH_MAX);
snprintf(destPath, sizeof(destPath), "sd:/gm9i/out/%s", entry->name.c_str()); char sourcePath[PATH_MAX];
iprintf ("\x1b[%d;3H", optionOffset + OPTIONS_ENTRIES_START_ROW+cursorScreenPos); snprintf(sourcePath, sizeof(sourcePath), "%s%s", sourceFolder, entry->name.c_str());
printf("Copying... "); fcopy(sourcePath, destPath);
remove(destPath); chdir(sourceFolder); // For after copying a folder
char sourceFolder[PATH_MAX]; break;
getcwd(sourceFolder, PATH_MAX); } case FileOperation::copyFatOut: {
char sourcePath[PATH_MAX]; if (access("fat:/gm9i", F_OK) != 0) {
snprintf(sourcePath, sizeof(sourcePath), "%s%s", sourceFolder, entry->name.c_str()); iprintf ("\x1b[%d;3H", optionOffset + OPTIONS_ENTRIES_START_ROW+cursorScreenPos);
fcopy(sourcePath, destPath); printf("Creating directory...");
chdir(sourceFolder); // For after copying a folder mkdir("fat:/gm9i", 0777);
} else if (assignedOp[optionOffset] == 2) { }
if (access("fat:/gm9i", F_OK) != 0) { if (access("fat:/gm9i/out", F_OK) != 0) {
iprintf ("\x1b[%d;3H", optionOffset + OPTIONS_ENTRIES_START_ROW+cursorScreenPos);
printf("Creating directory...");
mkdir("fat:/gm9i/out", 0777);
}
char destPath[256];
snprintf(destPath, sizeof(destPath), "fat:/gm9i/out/%s", entry->name.c_str());
iprintf ("\x1b[%d;3H", optionOffset + OPTIONS_ENTRIES_START_ROW+cursorScreenPos); iprintf ("\x1b[%d;3H", optionOffset + OPTIONS_ENTRIES_START_ROW+cursorScreenPos);
printf("Creating directory..."); printf("Copying... ");
mkdir("fat:/gm9i", 0777); remove(destPath);
} char sourceFolder[PATH_MAX];
if (access("fat:/gm9i/out", F_OK) != 0) { getcwd(sourceFolder, PATH_MAX);
iprintf ("\x1b[%d;3H", optionOffset + OPTIONS_ENTRIES_START_ROW+cursorScreenPos); char sourcePath[PATH_MAX];
printf("Creating directory..."); snprintf(sourcePath, sizeof(sourcePath), "%s%s", sourceFolder, entry->name.c_str());
mkdir("fat:/gm9i/out", 0777); fcopy(sourcePath, destPath);
} chdir(sourceFolder); // For after copying a folder
char destPath[256]; break;
snprintf(destPath, sizeof(destPath), "fat:/gm9i/out/%s", entry->name.c_str()); } case FileOperation::mountNitroFS: {
iprintf ("\x1b[%d;3H", optionOffset + OPTIONS_ENTRIES_START_ROW+cursorScreenPos); nitroMounted = nitroFSInit(entry->name.c_str());
printf("Copying... "); if (nitroMounted) {
remove(destPath); chdir("nitro:/");
char sourceFolder[PATH_MAX]; nitroCurrentDrive = currentDrive;
getcwd(sourceFolder, PATH_MAX); currentDrive = 5;
char sourcePath[PATH_MAX]; }
snprintf(sourcePath, sizeof(sourcePath), "%s%s", sourceFolder, entry->name.c_str()); break;
fcopy(sourcePath, destPath); } case FileOperation::showInfo: {
chdir(sourceFolder); // For after copying a folder changeFileAttribs(entry);
} else if (assignedOp[optionOffset] == 3) { break;
nitroMounted = nitroFSInit(entry->name.c_str()); } case FileOperation::mountImg: {
if (nitroMounted) { imgMounted = imgMount(entry->name.c_str());
chdir("nitro:/"); if (imgMounted) {
nitroCurrentDrive = currentDrive; chdir("img:/");
currentDrive = 5; imgCurrentDrive = currentDrive;
} currentDrive = 6;
} else if (assignedOp[optionOffset] == 4) { }
changeFileAttribs(entry); break;
} else if (assignedOp[optionOffset] == 5) { } case FileOperation::none: {
imgMounted = imgMount(entry->name.c_str()); break;
if (imgMounted) {
chdir("img:/");
imgCurrentDrive = currentDrive;
currentDrive = 6;
} }
} }
return assignedOp[optionOffset]; return assignedOp[optionOffset];
} }
if (pressed & KEY_B) { if (pressed & KEY_B) {
return -1; return FileOperation::none;
} }
} }
} }
@ -519,12 +518,12 @@ void fileBrowse_drawBottomScreen(DirEntry* entry) {
} }
} }
string browseForFile (void) { std::string browseForFile (void) {
int pressed = 0; int pressed = 0;
int held = 0; int held = 0;
int screenOffset = 0; int screenOffset = 0;
int fileOffset = 0; int fileOffset = 0;
vector<DirEntry> dirContents; std::vector<DirEntry> dirContents;
getDirectoryContents (dirContents); getDirectoryContents (dirContents);
@ -607,17 +606,21 @@ string browseForFile (void) {
screenOffset = 0; screenOffset = 0;
fileOffset = 0; fileOffset = 0;
} else { } else {
int getOp = fileBrowse_A(entry, path); FileOperation getOp = fileBrowse_A(entry, path);
if (getOp == 0) { if(getOp == FileOperation::bootFile) {
// Return the chosen file // Return the chosen file
return entry->name; return entry->name;
} else if (getOp == 1 || getOp == 2 || (getOp == 3 && nitroMounted) || (getOp == 5 && imgMounted)) { } else if (getOp == FileOperation::copySdOut
getDirectoryContents (dirContents); // Refresh directory listing || getOp == FileOperation::copyFatOut
if ((getOp == 3 && nitroMounted) || (getOp == 5 && imgMounted)) { || (getOp == FileOperation::mountNitroFS && nitroMounted)
|| (getOp == FileOperation::mountImg && imgMounted)) {
getDirectoryContents(dirContents); // Refresh directory listing
if ((getOp == FileOperation::mountNitroFS && nitroMounted)
|| (getOp == FileOperation::mountImg && imgMounted)) {
screenOffset = 0; screenOffset = 0;
fileOffset = 0; fileOffset = 0;
} }
} else if (getOp == 4) { } else if(getOp == FileOperation::showInfo) {
for (int i = 0; i < 15; i++) swiWaitForVBlank(); for (int i = 0; i < 15; i++) swiWaitForVBlank();
} }
} }
@ -629,14 +632,10 @@ string browseForFile (void) {
screenMode = 0; screenMode = 0;
return "null"; return "null";
} else { } else {
int getOp = fileBrowse_A(entry, path); FileOperation getOp = fileBrowse_A(entry, path);
if (getOp == 1 || getOp == 2) { if (getOp == FileOperation::copySdOut || getOp == FileOperation::copyFatOut) {
getDirectoryContents (dirContents); // Refresh directory listing getDirectoryContents (dirContents); // Refresh directory listing
if (getOp == 3 && nitroMounted) { } else if (getOp == FileOperation::showInfo) {
screenOffset = 0;
fileOffset = 0;
}
} else if (getOp == 4) {
for (int i = 0; i < 15; i++) swiWaitForVBlank(); for (int i = 0; i < 15; i++) swiWaitForVBlank();
} }
} }

View File

@ -25,17 +25,28 @@
#include <string> #include <string>
#include <vector> #include <vector>
using namespace std;
struct DirEntry { struct DirEntry {
string name; std::string name;
size_t size; size_t size;
bool isDirectory; bool isDirectory;
bool isApp; bool isApp;
} ; };
enum class FileOperation {
none,
bootFile,
mountNitroFS,
mountImg,
restoreSave,
showInfo,
copySdOut,
copyFatOut,
};
bool extension(const std::string &filename, const std::vector<std::string> &extensions);
std::string browseForFile (void); std::string browseForFile (void);
void getDirectoryContents (vector<DirEntry>& dirContents); void getDirectoryContents (std::vector<DirEntry>& dirContents);

View File

@ -54,8 +54,6 @@ static int bg3;
PrintConsole topConsoleBG, topConsole, bottomConsoleBG, bottomConsole; PrintConsole topConsoleBG, topConsole, bottomConsoleBG, bottomConsole;
using namespace std;
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
void stop (void) { void stop (void) {
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
@ -66,14 +64,6 @@ void stop (void) {
char filePath[PATH_MAX]; char filePath[PATH_MAX];
bool extention(const std::string& filename, const char* ext) {
if(strcasecmp(filename.c_str() + filename.size() - strlen(ext), ext)) {
return false;
} else {
return true;
}
}
void printBorderTop(void) { void printBorderTop(void) {
consoleSelect(&topConsoleBG); consoleSelect(&topConsoleBG);
printf ("\x1B[42m"); // Print green color printf ("\x1B[42m"); // Print green color
@ -275,7 +265,7 @@ int main(int argc, char **argv) {
// Construct a command line // Construct a command line
getcwd (filePath, PATH_MAX); getcwd (filePath, PATH_MAX);
pathLen = strlen (filePath); pathLen = strlen (filePath);
vector<char*> argarray; std::vector<char*> argarray;
if ((strcasecmp (filename.c_str() + filename.size() - 5, ".argv") == 0) if ((strcasecmp (filename.c_str() + filename.size() - 5, ".argv") == 0)
|| (strcasecmp (filename.c_str() + filename.size() - 5, ".ARGV") == 0)) { || (strcasecmp (filename.c_str() + filename.size() - 5, ".ARGV") == 0)) {
@ -303,8 +293,7 @@ int main(int argc, char **argv) {
argarray.push_back(strdup(filename.c_str())); argarray.push_back(strdup(filename.c_str()));
} }
if (extention(filename, ".nds") || extention(filename, ".dsi") if (extension(filename, {"nds", "dsi", "ids", "app"})) {
|| extention(filename, ".ids") || extention(filename, ".app")) {
char *name = argarray.at(0); char *name = argarray.at(0);
strcpy (filePath + pathLen, name); strcpy (filePath + pathLen, name);
free(argarray.at(0)); free(argarray.at(0));
@ -315,7 +304,7 @@ int main(int argc, char **argv) {
iprintf ("\x1b[31mStart failed. Error %i\n", err); iprintf ("\x1b[31mStart failed. Error %i\n", err);
} }
if (extention(filename, ".firm")) { if (extension(filename, {"firm"})) {
char *name = argarray.at(0); char *name = argarray.at(0);
strcpy (filePath + pathLen, name); strcpy (filePath + pathLen, name);
free(argarray.at(0)); free(argarray.at(0));