mirror of
https://github.com/rvtr/GodMode9i.git
synced 2025-11-02 00:11:07 -04:00
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:
parent
2ae90b4fff
commit
5437be1a2e
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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;
|
||||||
|
|
||||||
|
|||||||
@ -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;
|
||||||
|
|
||||||
|
|||||||
@ -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,13 +56,15 @@ 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 (name.size() == 0) return false;
|
if(filename.length() > ext.length() && strcasecmp(filename.substr(filename.length() - ext.length()).data(), ext.data()) == 0)
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void OnKeyPressed(int key) {
|
void OnKeyPressed(int key) {
|
||||||
if(key > 0)
|
if(key > 0)
|
||||||
iprintf("%c", key);
|
iprintf("%c", 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,11 +281,16 @@ 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]) {
|
||||||
|
case FileOperation::bootFile: {
|
||||||
applaunch = true;
|
applaunch = true;
|
||||||
iprintf ("\x1b[%d;3H", optionOffset + OPTIONS_ENTRIES_START_ROW+cursorScreenPos);
|
iprintf ("\x1b[%d;3H", optionOffset + OPTIONS_ENTRIES_START_ROW+cursorScreenPos);
|
||||||
printf("Now loading...");
|
printf("Now loading...");
|
||||||
} else if (assignedOp[optionOffset] == 1) {
|
break;
|
||||||
|
} case FileOperation::restoreSave: {
|
||||||
|
ndsCardSaveRestore(entry->name.c_str());
|
||||||
|
break;
|
||||||
|
} case FileOperation::copySdOut: {
|
||||||
if (access("sd:/gm9i", F_OK) != 0) {
|
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("Creating directory...");
|
||||||
@ -321,7 +312,8 @@ int fileBrowse_A(DirEntry* entry, char path[PATH_MAX]) {
|
|||||||
snprintf(sourcePath, sizeof(sourcePath), "%s%s", sourceFolder, entry->name.c_str());
|
snprintf(sourcePath, sizeof(sourcePath), "%s%s", sourceFolder, entry->name.c_str());
|
||||||
fcopy(sourcePath, destPath);
|
fcopy(sourcePath, destPath);
|
||||||
chdir(sourceFolder); // For after copying a folder
|
chdir(sourceFolder); // For after copying a folder
|
||||||
} else if (assignedOp[optionOffset] == 2) {
|
break;
|
||||||
|
} case FileOperation::copyFatOut: {
|
||||||
if (access("fat:/gm9i", F_OK) != 0) {
|
if (access("fat:/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("Creating directory...");
|
||||||
@ -343,27 +335,34 @@ int fileBrowse_A(DirEntry* entry, char path[PATH_MAX]) {
|
|||||||
snprintf(sourcePath, sizeof(sourcePath), "%s%s", sourceFolder, entry->name.c_str());
|
snprintf(sourcePath, sizeof(sourcePath), "%s%s", sourceFolder, entry->name.c_str());
|
||||||
fcopy(sourcePath, destPath);
|
fcopy(sourcePath, destPath);
|
||||||
chdir(sourceFolder); // For after copying a folder
|
chdir(sourceFolder); // For after copying a folder
|
||||||
} else if (assignedOp[optionOffset] == 3) {
|
break;
|
||||||
|
} case FileOperation::mountNitroFS: {
|
||||||
nitroMounted = nitroFSInit(entry->name.c_str());
|
nitroMounted = nitroFSInit(entry->name.c_str());
|
||||||
if (nitroMounted) {
|
if (nitroMounted) {
|
||||||
chdir("nitro:/");
|
chdir("nitro:/");
|
||||||
nitroCurrentDrive = currentDrive;
|
nitroCurrentDrive = currentDrive;
|
||||||
currentDrive = 5;
|
currentDrive = 5;
|
||||||
}
|
}
|
||||||
} else if (assignedOp[optionOffset] == 4) {
|
break;
|
||||||
|
} case FileOperation::showInfo: {
|
||||||
changeFileAttribs(entry);
|
changeFileAttribs(entry);
|
||||||
} else if (assignedOp[optionOffset] == 5) {
|
break;
|
||||||
|
} case FileOperation::mountImg: {
|
||||||
imgMounted = imgMount(entry->name.c_str());
|
imgMounted = imgMount(entry->name.c_str());
|
||||||
if (imgMounted) {
|
if (imgMounted) {
|
||||||
chdir("img:/");
|
chdir("img:/");
|
||||||
imgCurrentDrive = currentDrive;
|
imgCurrentDrive = currentDrive;
|
||||||
currentDrive = 6;
|
currentDrive = 6;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
} case FileOperation::none: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
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
|
||||||
|
|| getOp == FileOperation::copyFatOut
|
||||||
|
|| (getOp == FileOperation::mountNitroFS && nitroMounted)
|
||||||
|
|| (getOp == FileOperation::mountImg && imgMounted)) {
|
||||||
getDirectoryContents(dirContents); // Refresh directory listing
|
getDirectoryContents(dirContents); // Refresh directory listing
|
||||||
if ((getOp == 3 && nitroMounted) || (getOp == 5 && imgMounted)) {
|
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -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));
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user