mirror of
https://github.com/edo9300/unlaunch-installer.git
synced 2025-06-18 14:25:39 -04:00
Add giattributes
This commit is contained in:
parent
5f8f69c2ab
commit
d01ccfbf47
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@ -0,0 +1 @@
|
||||
* text=auto
|
1108
arm9/src/main.c
1108
arm9/src/main.c
File diff suppressed because it is too large
Load Diff
@ -1,25 +1,25 @@
|
||||
#ifndef MAIN_H
|
||||
#define MAIN_H
|
||||
|
||||
#include <nds.h>
|
||||
#include <fat.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern volatile bool programEnd;
|
||||
extern volatile bool charging;
|
||||
extern volatile u8 batteryLevel;
|
||||
|
||||
extern PrintConsole topScreen;
|
||||
extern PrintConsole bottomScreen;
|
||||
|
||||
void clearScreen(PrintConsole* screen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef MAIN_H
|
||||
#define MAIN_H
|
||||
|
||||
#include <nds.h>
|
||||
#include <fat.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern volatile bool programEnd;
|
||||
extern volatile bool charging;
|
||||
extern volatile u8 batteryLevel;
|
||||
|
||||
extern PrintConsole topScreen;
|
||||
extern PrintConsole bottomScreen;
|
||||
|
||||
void clearScreen(PrintConsole* screen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
472
arm9/src/menu.c
472
arm9/src/menu.c
@ -1,237 +1,237 @@
|
||||
#include "menu.h"
|
||||
#include "main.h"
|
||||
|
||||
#define sign(X) ( ((X) > 0) - ((X) < 0) )
|
||||
#define repeat(X) for (int _I_ = 0; _I_ < (X); _I_++)
|
||||
|
||||
Menu* newMenu()
|
||||
{
|
||||
Menu* m = (Menu*)malloc(sizeof(Menu));
|
||||
|
||||
m->cursor = 0;
|
||||
m->page = 0;
|
||||
m->itemCount = 0;
|
||||
m->nextPage = false;
|
||||
m->changePage = 0;
|
||||
m->header[0] = '\0';
|
||||
|
||||
for (int i = 0; i < ITEMS_PER_PAGE; i++)
|
||||
{
|
||||
m->items[i].directory = false;
|
||||
m->items[i].label = NULL;
|
||||
m->items[i].value = NULL;
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
void freeMenu(Menu* m)
|
||||
{
|
||||
if (!m) return;
|
||||
|
||||
clearMenu(m);
|
||||
|
||||
free(m);
|
||||
m = NULL;
|
||||
}
|
||||
|
||||
void addMenuItem(Menu* m, char const* label, char const* value, bool enabled, bool directory)
|
||||
{
|
||||
if (!m) return;
|
||||
|
||||
int i = m->itemCount;
|
||||
if (i >= ITEMS_PER_PAGE) return;
|
||||
|
||||
m->items[i].directory = directory;
|
||||
m->items[i].enabled = enabled;
|
||||
|
||||
if (label)
|
||||
{
|
||||
m->items[i].label = (char*)malloc(32);
|
||||
sprintf(m->items[i].label, "%.31s", label);
|
||||
}
|
||||
|
||||
if (value)
|
||||
{
|
||||
m->items[i].value = (char*)malloc(strlen(value)+1);
|
||||
sprintf(m->items[i].value, "%s", value);
|
||||
}
|
||||
|
||||
m->itemCount += 1;
|
||||
}
|
||||
|
||||
static int alphabeticalCompare(const void* a, const void* b)
|
||||
{
|
||||
const Item* itemA = (const Item*)a;
|
||||
const Item* itemB = (const Item*)b;
|
||||
|
||||
if (itemA->directory && !itemB->directory)
|
||||
return -1;
|
||||
else if (!itemA->directory && itemB->directory)
|
||||
return 1;
|
||||
else
|
||||
return strcasecmp(itemA->label, itemB->label);
|
||||
}
|
||||
|
||||
void sortMenuItems(Menu* m)
|
||||
{
|
||||
qsort(m->items, m->itemCount, sizeof(Item), alphabeticalCompare);
|
||||
}
|
||||
|
||||
void setMenuHeader(Menu* m, const char* str)
|
||||
{
|
||||
if (!m) return;
|
||||
|
||||
if (!str)
|
||||
{
|
||||
m->header[0] = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
const char* strPtr = str;
|
||||
|
||||
if (strlen(strPtr) > 30)
|
||||
strPtr = str + (strlen(strPtr) - 30);
|
||||
|
||||
sprintf(m->header, "%.30s", strPtr);
|
||||
}
|
||||
|
||||
void resetMenu(Menu* m)
|
||||
{
|
||||
m->cursor = 0;
|
||||
m->page = 0;
|
||||
m->changePage = 0;
|
||||
m->nextPage = 0;
|
||||
}
|
||||
|
||||
void clearMenu(Menu* m)
|
||||
{
|
||||
if (!m) return;
|
||||
|
||||
for (int i = 0; i < ITEMS_PER_PAGE; i++)
|
||||
{
|
||||
if (m->items[i].label)
|
||||
{
|
||||
free(m->items[i].label);
|
||||
m->items[i].label = NULL;
|
||||
}
|
||||
|
||||
if (m->items[i].value)
|
||||
{
|
||||
free(m->items[i].value);
|
||||
m->items[i].value = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
m->itemCount = 0;
|
||||
}
|
||||
|
||||
void printMenu(Menu* m)
|
||||
{
|
||||
clearScreen(&bottomScreen);
|
||||
|
||||
if (!m) return;
|
||||
|
||||
//header
|
||||
iprintf("\x1B[42m"); //green
|
||||
iprintf("%.30s\n\n", m->header);
|
||||
iprintf("\x1B[47m"); //white
|
||||
|
||||
if (m->itemCount <= 0)
|
||||
{
|
||||
iprintf("Back - [B]\n");
|
||||
return;
|
||||
}
|
||||
|
||||
//items
|
||||
for (int i = 0; i < m->itemCount; i++)
|
||||
{
|
||||
if (m->items[i].label)
|
||||
{
|
||||
if(!m->items[i].enabled)
|
||||
iprintf("\x1B[37m"); //gray
|
||||
|
||||
if (m->items[i].directory)
|
||||
iprintf(" [%.26s]\n", m->items[i].label);
|
||||
else
|
||||
iprintf(" %.28s\n", m->items[i].label);
|
||||
|
||||
if(!m->items[i].enabled)
|
||||
iprintf("\x1B[47m"); //white
|
||||
}
|
||||
else
|
||||
iprintf(" \n");
|
||||
}
|
||||
|
||||
//cursor
|
||||
iprintf("\x1b[%d;0H>", 2 + m->cursor);
|
||||
|
||||
//scroll arrows
|
||||
if (m->page > 0)
|
||||
iprintf("\x1b[2;31H^");
|
||||
|
||||
if (m->nextPage)
|
||||
iprintf("\x1b[21;31Hv");
|
||||
}
|
||||
|
||||
static void _moveCursor(Menu* m, int dir)
|
||||
{
|
||||
if (m->changePage != 0)
|
||||
return;
|
||||
|
||||
m->cursor += sign(dir);
|
||||
|
||||
if (m->cursor < 0)
|
||||
{
|
||||
if (m->page <= 0)
|
||||
m->cursor = 0;
|
||||
else
|
||||
{
|
||||
m->changePage = -1;
|
||||
m->cursor = ITEMS_PER_PAGE - 1;
|
||||
}
|
||||
}
|
||||
|
||||
else if (m->cursor > m->itemCount-1)
|
||||
{
|
||||
if (m->nextPage && m->cursor >= ITEMS_PER_PAGE)
|
||||
{
|
||||
m->changePage = 1;
|
||||
m->cursor = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m->cursor = m->itemCount-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool moveCursor(Menu* m)
|
||||
{
|
||||
if (!m) return false;
|
||||
|
||||
m->changePage = 0;
|
||||
int lastCursor = m->cursor;
|
||||
|
||||
u32 down = keysDownRepeat();
|
||||
|
||||
if (down & KEY_DOWN)
|
||||
_moveCursor(m, 1);
|
||||
|
||||
else if (down & KEY_UP)
|
||||
_moveCursor(m, -1);
|
||||
|
||||
if (down & KEY_RIGHT)
|
||||
{
|
||||
repeat(10)
|
||||
_moveCursor(m, 1);
|
||||
}
|
||||
|
||||
else if (down & KEY_LEFT)
|
||||
{
|
||||
repeat(10)
|
||||
_moveCursor(m, -1);
|
||||
}
|
||||
|
||||
return !(lastCursor == m->cursor);
|
||||
#include "menu.h"
|
||||
#include "main.h"
|
||||
|
||||
#define sign(X) ( ((X) > 0) - ((X) < 0) )
|
||||
#define repeat(X) for (int _I_ = 0; _I_ < (X); _I_++)
|
||||
|
||||
Menu* newMenu()
|
||||
{
|
||||
Menu* m = (Menu*)malloc(sizeof(Menu));
|
||||
|
||||
m->cursor = 0;
|
||||
m->page = 0;
|
||||
m->itemCount = 0;
|
||||
m->nextPage = false;
|
||||
m->changePage = 0;
|
||||
m->header[0] = '\0';
|
||||
|
||||
for (int i = 0; i < ITEMS_PER_PAGE; i++)
|
||||
{
|
||||
m->items[i].directory = false;
|
||||
m->items[i].label = NULL;
|
||||
m->items[i].value = NULL;
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
void freeMenu(Menu* m)
|
||||
{
|
||||
if (!m) return;
|
||||
|
||||
clearMenu(m);
|
||||
|
||||
free(m);
|
||||
m = NULL;
|
||||
}
|
||||
|
||||
void addMenuItem(Menu* m, char const* label, char const* value, bool enabled, bool directory)
|
||||
{
|
||||
if (!m) return;
|
||||
|
||||
int i = m->itemCount;
|
||||
if (i >= ITEMS_PER_PAGE) return;
|
||||
|
||||
m->items[i].directory = directory;
|
||||
m->items[i].enabled = enabled;
|
||||
|
||||
if (label)
|
||||
{
|
||||
m->items[i].label = (char*)malloc(32);
|
||||
sprintf(m->items[i].label, "%.31s", label);
|
||||
}
|
||||
|
||||
if (value)
|
||||
{
|
||||
m->items[i].value = (char*)malloc(strlen(value)+1);
|
||||
sprintf(m->items[i].value, "%s", value);
|
||||
}
|
||||
|
||||
m->itemCount += 1;
|
||||
}
|
||||
|
||||
static int alphabeticalCompare(const void* a, const void* b)
|
||||
{
|
||||
const Item* itemA = (const Item*)a;
|
||||
const Item* itemB = (const Item*)b;
|
||||
|
||||
if (itemA->directory && !itemB->directory)
|
||||
return -1;
|
||||
else if (!itemA->directory && itemB->directory)
|
||||
return 1;
|
||||
else
|
||||
return strcasecmp(itemA->label, itemB->label);
|
||||
}
|
||||
|
||||
void sortMenuItems(Menu* m)
|
||||
{
|
||||
qsort(m->items, m->itemCount, sizeof(Item), alphabeticalCompare);
|
||||
}
|
||||
|
||||
void setMenuHeader(Menu* m, const char* str)
|
||||
{
|
||||
if (!m) return;
|
||||
|
||||
if (!str)
|
||||
{
|
||||
m->header[0] = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
const char* strPtr = str;
|
||||
|
||||
if (strlen(strPtr) > 30)
|
||||
strPtr = str + (strlen(strPtr) - 30);
|
||||
|
||||
sprintf(m->header, "%.30s", strPtr);
|
||||
}
|
||||
|
||||
void resetMenu(Menu* m)
|
||||
{
|
||||
m->cursor = 0;
|
||||
m->page = 0;
|
||||
m->changePage = 0;
|
||||
m->nextPage = 0;
|
||||
}
|
||||
|
||||
void clearMenu(Menu* m)
|
||||
{
|
||||
if (!m) return;
|
||||
|
||||
for (int i = 0; i < ITEMS_PER_PAGE; i++)
|
||||
{
|
||||
if (m->items[i].label)
|
||||
{
|
||||
free(m->items[i].label);
|
||||
m->items[i].label = NULL;
|
||||
}
|
||||
|
||||
if (m->items[i].value)
|
||||
{
|
||||
free(m->items[i].value);
|
||||
m->items[i].value = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
m->itemCount = 0;
|
||||
}
|
||||
|
||||
void printMenu(Menu* m)
|
||||
{
|
||||
clearScreen(&bottomScreen);
|
||||
|
||||
if (!m) return;
|
||||
|
||||
//header
|
||||
iprintf("\x1B[42m"); //green
|
||||
iprintf("%.30s\n\n", m->header);
|
||||
iprintf("\x1B[47m"); //white
|
||||
|
||||
if (m->itemCount <= 0)
|
||||
{
|
||||
iprintf("Back - [B]\n");
|
||||
return;
|
||||
}
|
||||
|
||||
//items
|
||||
for (int i = 0; i < m->itemCount; i++)
|
||||
{
|
||||
if (m->items[i].label)
|
||||
{
|
||||
if(!m->items[i].enabled)
|
||||
iprintf("\x1B[37m"); //gray
|
||||
|
||||
if (m->items[i].directory)
|
||||
iprintf(" [%.26s]\n", m->items[i].label);
|
||||
else
|
||||
iprintf(" %.28s\n", m->items[i].label);
|
||||
|
||||
if(!m->items[i].enabled)
|
||||
iprintf("\x1B[47m"); //white
|
||||
}
|
||||
else
|
||||
iprintf(" \n");
|
||||
}
|
||||
|
||||
//cursor
|
||||
iprintf("\x1b[%d;0H>", 2 + m->cursor);
|
||||
|
||||
//scroll arrows
|
||||
if (m->page > 0)
|
||||
iprintf("\x1b[2;31H^");
|
||||
|
||||
if (m->nextPage)
|
||||
iprintf("\x1b[21;31Hv");
|
||||
}
|
||||
|
||||
static void _moveCursor(Menu* m, int dir)
|
||||
{
|
||||
if (m->changePage != 0)
|
||||
return;
|
||||
|
||||
m->cursor += sign(dir);
|
||||
|
||||
if (m->cursor < 0)
|
||||
{
|
||||
if (m->page <= 0)
|
||||
m->cursor = 0;
|
||||
else
|
||||
{
|
||||
m->changePage = -1;
|
||||
m->cursor = ITEMS_PER_PAGE - 1;
|
||||
}
|
||||
}
|
||||
|
||||
else if (m->cursor > m->itemCount-1)
|
||||
{
|
||||
if (m->nextPage && m->cursor >= ITEMS_PER_PAGE)
|
||||
{
|
||||
m->changePage = 1;
|
||||
m->cursor = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m->cursor = m->itemCount-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool moveCursor(Menu* m)
|
||||
{
|
||||
if (!m) return false;
|
||||
|
||||
m->changePage = 0;
|
||||
int lastCursor = m->cursor;
|
||||
|
||||
u32 down = keysDownRepeat();
|
||||
|
||||
if (down & KEY_DOWN)
|
||||
_moveCursor(m, 1);
|
||||
|
||||
else if (down & KEY_UP)
|
||||
_moveCursor(m, -1);
|
||||
|
||||
if (down & KEY_RIGHT)
|
||||
{
|
||||
repeat(10)
|
||||
_moveCursor(m, 1);
|
||||
}
|
||||
|
||||
else if (down & KEY_LEFT)
|
||||
{
|
||||
repeat(10)
|
||||
_moveCursor(m, -1);
|
||||
}
|
||||
|
||||
return !(lastCursor == m->cursor);
|
||||
}
|
@ -1,46 +1,46 @@
|
||||
#ifndef MENU_H
|
||||
#define MENU_H
|
||||
|
||||
#include <nds/ndstypes.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ITEMS_PER_PAGE 20
|
||||
|
||||
typedef struct {
|
||||
bool directory;
|
||||
bool enabled;
|
||||
char* label;
|
||||
char* value;
|
||||
} Item;
|
||||
|
||||
typedef struct {
|
||||
int cursor;
|
||||
int page;
|
||||
int itemCount;
|
||||
bool nextPage;
|
||||
int changePage;
|
||||
char header[32];
|
||||
Item items[ITEMS_PER_PAGE];
|
||||
} Menu;
|
||||
|
||||
Menu* newMenu();
|
||||
void freeMenu(Menu* m);
|
||||
|
||||
void addMenuItem(Menu* m, char const* label, char const* value, bool enabled, bool directory);
|
||||
void sortMenuItems(Menu* m);
|
||||
void setMenuHeader(Menu* m, const char* str);
|
||||
|
||||
void resetMenu(Menu* m);
|
||||
void clearMenu(Menu* m);
|
||||
void printMenu(Menu* m);
|
||||
|
||||
bool moveCursor(Menu* m);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef MENU_H
|
||||
#define MENU_H
|
||||
|
||||
#include <nds/ndstypes.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ITEMS_PER_PAGE 20
|
||||
|
||||
typedef struct {
|
||||
bool directory;
|
||||
bool enabled;
|
||||
char* label;
|
||||
char* value;
|
||||
} Item;
|
||||
|
||||
typedef struct {
|
||||
int cursor;
|
||||
int page;
|
||||
int itemCount;
|
||||
bool nextPage;
|
||||
int changePage;
|
||||
char header[32];
|
||||
Item items[ITEMS_PER_PAGE];
|
||||
} Menu;
|
||||
|
||||
Menu* newMenu();
|
||||
void freeMenu(Menu* m);
|
||||
|
||||
void addMenuItem(Menu* m, char const* label, char const* value, bool enabled, bool directory);
|
||||
void sortMenuItems(Menu* m);
|
||||
void setMenuHeader(Menu* m, const char* str);
|
||||
|
||||
void resetMenu(Menu* m);
|
||||
void clearMenu(Menu* m);
|
||||
void printMenu(Menu* m);
|
||||
|
||||
bool moveCursor(Menu* m);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1,161 +1,161 @@
|
||||
#include "message.h"
|
||||
#include "main.h"
|
||||
|
||||
void keyWait(u32 key)
|
||||
{
|
||||
while (!programEnd)
|
||||
{
|
||||
swiWaitForVBlank();
|
||||
scanKeys();
|
||||
|
||||
if (keysDown() & key)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool choiceBox(const char* message)
|
||||
{
|
||||
const int choiceRow = 10;
|
||||
int cursor = 0;
|
||||
|
||||
clearScreen(&bottomScreen);
|
||||
|
||||
iprintf("\x1B[33m"); //yellow
|
||||
iprintf("%s\n", message);
|
||||
iprintf("\x1B[47m"); //white
|
||||
iprintf("\x1b[%d;0H\tYes\n\tNo\n", choiceRow);
|
||||
|
||||
while (!programEnd)
|
||||
{
|
||||
swiWaitForVBlank();
|
||||
scanKeys();
|
||||
|
||||
//Clear cursor
|
||||
iprintf("\x1b[%d;0H ", choiceRow + cursor);
|
||||
|
||||
if (keysDown() & (KEY_UP | KEY_DOWN))
|
||||
cursor = !cursor;
|
||||
|
||||
//Print cursor
|
||||
iprintf("\x1b[%d;0H>", choiceRow + cursor);
|
||||
|
||||
if (keysDown() & (KEY_A | KEY_START))
|
||||
break;
|
||||
|
||||
if (keysDown() & KEY_B)
|
||||
{
|
||||
cursor = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
scanKeys();
|
||||
return (cursor == 0)? YES: NO;
|
||||
}
|
||||
|
||||
bool choicePrint(const char* message)
|
||||
{
|
||||
bool choice = NO;
|
||||
|
||||
iprintf("\x1B[33m"); //yellow
|
||||
iprintf("\n%s\n", message);
|
||||
iprintf("\x1B[47m"); //white
|
||||
iprintf("Yes - [A]\nNo - [B]\n");
|
||||
|
||||
while (!programEnd)
|
||||
{
|
||||
swiWaitForVBlank();
|
||||
scanKeys();
|
||||
|
||||
if (keysDown() & KEY_A)
|
||||
{
|
||||
choice = YES;
|
||||
break;
|
||||
}
|
||||
|
||||
else if (keysDown() & KEY_B)
|
||||
{
|
||||
choice = NO;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
scanKeys();
|
||||
return choice;
|
||||
}
|
||||
|
||||
const static u16 keys[] = {KEY_UP, KEY_DOWN, KEY_RIGHT, KEY_LEFT, KEY_A, KEY_B, KEY_X, KEY_Y};
|
||||
const static char *keysLabels[] = {"\x18", "\x19", "\x1A", "\x1B", "<A>", "<B>", "<X>", "<Y>"};
|
||||
|
||||
bool randomConfirmBox(const char* message)
|
||||
{
|
||||
const int choiceRow = 10;
|
||||
int sequencePosition = 0;
|
||||
|
||||
u8 sequence[8];
|
||||
for (int i = 0; i < sizeof(sequence); i++)
|
||||
{
|
||||
sequence[i] = rand() % (sizeof(keys) / sizeof(keys[0]));
|
||||
}
|
||||
|
||||
clearScreen(&bottomScreen);
|
||||
|
||||
iprintf("\x1B[43m"); //yellow
|
||||
iprintf("%s\n", message);
|
||||
iprintf("\x1B[47m"); //white
|
||||
iprintf("\n<START> cancel\n");
|
||||
|
||||
while (!programEnd && sequencePosition < sizeof(sequence))
|
||||
{
|
||||
swiWaitForVBlank();
|
||||
scanKeys();
|
||||
|
||||
//Print sequence
|
||||
iprintf("\x1b[%d;0H", choiceRow);
|
||||
for (int i = 0; i < sizeof(sequence); i++)
|
||||
{
|
||||
iprintf("\x1B[%0om", i < sequencePosition ? 032 : 047);
|
||||
iprintf("%s ", keysLabels[sequence[i]]);
|
||||
}
|
||||
|
||||
if (keysDown() & (KEY_UP | KEY_DOWN | KEY_RIGHT | KEY_LEFT | KEY_A | KEY_B | KEY_X | KEY_Y))
|
||||
{
|
||||
if (keysDown() & keys[sequence[sequencePosition]])
|
||||
sequencePosition++;
|
||||
else
|
||||
sequencePosition = 0;
|
||||
}
|
||||
|
||||
if (keysDown() & KEY_START)
|
||||
{
|
||||
sequencePosition = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
scanKeys();
|
||||
return sequencePosition == sizeof(sequence);
|
||||
}
|
||||
|
||||
void messageBox(const char* message)
|
||||
{
|
||||
clearScreen(&bottomScreen);
|
||||
messagePrint(message);
|
||||
}
|
||||
|
||||
void messagePrint(const char* message)
|
||||
{
|
||||
iprintf("%s\n", message);
|
||||
iprintf("\nOkay - [A]\n");
|
||||
|
||||
while (!programEnd)
|
||||
{
|
||||
swiWaitForVBlank();
|
||||
scanKeys();
|
||||
|
||||
if (keysDown() & (KEY_A | KEY_B | KEY_START))
|
||||
break;
|
||||
}
|
||||
|
||||
scanKeys();
|
||||
#include "message.h"
|
||||
#include "main.h"
|
||||
|
||||
void keyWait(u32 key)
|
||||
{
|
||||
while (!programEnd)
|
||||
{
|
||||
swiWaitForVBlank();
|
||||
scanKeys();
|
||||
|
||||
if (keysDown() & key)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool choiceBox(const char* message)
|
||||
{
|
||||
const int choiceRow = 10;
|
||||
int cursor = 0;
|
||||
|
||||
clearScreen(&bottomScreen);
|
||||
|
||||
iprintf("\x1B[33m"); //yellow
|
||||
iprintf("%s\n", message);
|
||||
iprintf("\x1B[47m"); //white
|
||||
iprintf("\x1b[%d;0H\tYes\n\tNo\n", choiceRow);
|
||||
|
||||
while (!programEnd)
|
||||
{
|
||||
swiWaitForVBlank();
|
||||
scanKeys();
|
||||
|
||||
//Clear cursor
|
||||
iprintf("\x1b[%d;0H ", choiceRow + cursor);
|
||||
|
||||
if (keysDown() & (KEY_UP | KEY_DOWN))
|
||||
cursor = !cursor;
|
||||
|
||||
//Print cursor
|
||||
iprintf("\x1b[%d;0H>", choiceRow + cursor);
|
||||
|
||||
if (keysDown() & (KEY_A | KEY_START))
|
||||
break;
|
||||
|
||||
if (keysDown() & KEY_B)
|
||||
{
|
||||
cursor = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
scanKeys();
|
||||
return (cursor == 0)? YES: NO;
|
||||
}
|
||||
|
||||
bool choicePrint(const char* message)
|
||||
{
|
||||
bool choice = NO;
|
||||
|
||||
iprintf("\x1B[33m"); //yellow
|
||||
iprintf("\n%s\n", message);
|
||||
iprintf("\x1B[47m"); //white
|
||||
iprintf("Yes - [A]\nNo - [B]\n");
|
||||
|
||||
while (!programEnd)
|
||||
{
|
||||
swiWaitForVBlank();
|
||||
scanKeys();
|
||||
|
||||
if (keysDown() & KEY_A)
|
||||
{
|
||||
choice = YES;
|
||||
break;
|
||||
}
|
||||
|
||||
else if (keysDown() & KEY_B)
|
||||
{
|
||||
choice = NO;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
scanKeys();
|
||||
return choice;
|
||||
}
|
||||
|
||||
const static u16 keys[] = {KEY_UP, KEY_DOWN, KEY_RIGHT, KEY_LEFT, KEY_A, KEY_B, KEY_X, KEY_Y};
|
||||
const static char *keysLabels[] = {"\x18", "\x19", "\x1A", "\x1B", "<A>", "<B>", "<X>", "<Y>"};
|
||||
|
||||
bool randomConfirmBox(const char* message)
|
||||
{
|
||||
const int choiceRow = 10;
|
||||
int sequencePosition = 0;
|
||||
|
||||
u8 sequence[8];
|
||||
for (int i = 0; i < sizeof(sequence); i++)
|
||||
{
|
||||
sequence[i] = rand() % (sizeof(keys) / sizeof(keys[0]));
|
||||
}
|
||||
|
||||
clearScreen(&bottomScreen);
|
||||
|
||||
iprintf("\x1B[43m"); //yellow
|
||||
iprintf("%s\n", message);
|
||||
iprintf("\x1B[47m"); //white
|
||||
iprintf("\n<START> cancel\n");
|
||||
|
||||
while (!programEnd && sequencePosition < sizeof(sequence))
|
||||
{
|
||||
swiWaitForVBlank();
|
||||
scanKeys();
|
||||
|
||||
//Print sequence
|
||||
iprintf("\x1b[%d;0H", choiceRow);
|
||||
for (int i = 0; i < sizeof(sequence); i++)
|
||||
{
|
||||
iprintf("\x1B[%0om", i < sequencePosition ? 032 : 047);
|
||||
iprintf("%s ", keysLabels[sequence[i]]);
|
||||
}
|
||||
|
||||
if (keysDown() & (KEY_UP | KEY_DOWN | KEY_RIGHT | KEY_LEFT | KEY_A | KEY_B | KEY_X | KEY_Y))
|
||||
{
|
||||
if (keysDown() & keys[sequence[sequencePosition]])
|
||||
sequencePosition++;
|
||||
else
|
||||
sequencePosition = 0;
|
||||
}
|
||||
|
||||
if (keysDown() & KEY_START)
|
||||
{
|
||||
sequencePosition = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
scanKeys();
|
||||
return sequencePosition == sizeof(sequence);
|
||||
}
|
||||
|
||||
void messageBox(const char* message)
|
||||
{
|
||||
clearScreen(&bottomScreen);
|
||||
messagePrint(message);
|
||||
}
|
||||
|
||||
void messagePrint(const char* message)
|
||||
{
|
||||
iprintf("%s\n", message);
|
||||
iprintf("\nOkay - [A]\n");
|
||||
|
||||
while (!programEnd)
|
||||
{
|
||||
swiWaitForVBlank();
|
||||
scanKeys();
|
||||
|
||||
if (keysDown() & (KEY_A | KEY_B | KEY_START))
|
||||
break;
|
||||
}
|
||||
|
||||
scanKeys();
|
||||
}
|
@ -1,26 +1,26 @@
|
||||
#ifndef MESSAGE_H
|
||||
#define MESSAGE_H
|
||||
|
||||
#include <nds/ndstypes.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum {
|
||||
YES = true,
|
||||
NO = false
|
||||
};
|
||||
|
||||
void keyWait(u32 key);
|
||||
bool choiceBox(const char* message);
|
||||
bool choicePrint(const char* message);
|
||||
bool randomConfirmBox(const char* message);
|
||||
void messageBox(const char* message);
|
||||
void messagePrint(const char* message);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef MESSAGE_H
|
||||
#define MESSAGE_H
|
||||
|
||||
#include <nds/ndstypes.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum {
|
||||
YES = true,
|
||||
NO = false
|
||||
};
|
||||
|
||||
void keyWait(u32 key);
|
||||
bool choiceBox(const char* message);
|
||||
bool choicePrint(const char* message);
|
||||
bool randomConfirmBox(const char* message);
|
||||
void messageBox(const char* message);
|
||||
void messagePrint(const char* message);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1,257 +1,257 @@
|
||||
#include "storage.h"
|
||||
#include "main.h"
|
||||
#include "message.h"
|
||||
#include <errno.h>
|
||||
#include <nds/sha1.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#define TITLE_LIMIT 39
|
||||
|
||||
//progress bar
|
||||
static int lastBars = 0;
|
||||
|
||||
static void printProgressBar(float percent)
|
||||
{
|
||||
if (percent < 0.f) percent = 0.f;
|
||||
if (percent > 1.f) percent = 1.f;
|
||||
|
||||
int bars = (int)(30.f * percent);
|
||||
|
||||
//skip redundant prints
|
||||
if (bars != lastBars)
|
||||
{
|
||||
consoleSelect(&topScreen);
|
||||
|
||||
iprintf("\x1B[42m"); //green
|
||||
|
||||
//Print frame
|
||||
if (lastBars <= 0)
|
||||
{
|
||||
iprintf("\x1b[23;0H[");
|
||||
iprintf("\x1b[23;31H]");
|
||||
}
|
||||
|
||||
//Print bars
|
||||
if (bars > 0)
|
||||
{
|
||||
for (int i = 0; i < bars; i++)
|
||||
iprintf("\x1b[23;%dH|", 1 + i);
|
||||
}
|
||||
|
||||
lastBars = bars;
|
||||
|
||||
iprintf("\x1B[47m"); //white
|
||||
}
|
||||
}
|
||||
|
||||
static void clearProgressBar()
|
||||
{
|
||||
lastBars = 0;
|
||||
consoleSelect(&topScreen);
|
||||
iprintf("\x1b[23;0H ");
|
||||
}
|
||||
|
||||
//files
|
||||
bool fileExists(char const* path)
|
||||
{
|
||||
return access(path, F_OK) == 0;
|
||||
}
|
||||
|
||||
int copyFile(char const* src, char const* dst)
|
||||
{
|
||||
if (!src) return 1;
|
||||
|
||||
unsigned long long size = getFileSizePath(src);
|
||||
return copyFilePart(src, 0, size, dst);
|
||||
}
|
||||
|
||||
int copyFilePart(char const* src, u32 offset, u32 size, char const* dst)
|
||||
{
|
||||
if (!src) return 1;
|
||||
if (!dst) return 2;
|
||||
|
||||
FILE* fin = fopen(src, "rb");
|
||||
|
||||
if (!fin)
|
||||
{
|
||||
fclose(fin);
|
||||
return 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fileExists(dst))
|
||||
remove(dst);
|
||||
|
||||
FILE* fout = fopen(dst, "wb");
|
||||
|
||||
if (!fout)
|
||||
{
|
||||
fclose(fin);
|
||||
fclose(fout);
|
||||
return 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
fseek(fin, offset, SEEK_SET);
|
||||
|
||||
consoleSelect(&topScreen);
|
||||
|
||||
int bytesRead;
|
||||
unsigned long long totalBytesRead = 0;
|
||||
|
||||
#define BUFF_SIZE 128 //Arbitrary. A value too large freezes the ds.
|
||||
char* buffer = (char*)malloc(BUFF_SIZE);
|
||||
|
||||
while (!programEnd)
|
||||
{
|
||||
unsigned int toRead = BUFF_SIZE;
|
||||
if (size - totalBytesRead < BUFF_SIZE)
|
||||
toRead = size - totalBytesRead;
|
||||
|
||||
bytesRead = fread(buffer, 1, toRead, fin);
|
||||
fwrite(buffer, bytesRead, 1, fout);
|
||||
|
||||
totalBytesRead += bytesRead;
|
||||
printProgressBar( ((float)totalBytesRead / (float)size) );
|
||||
|
||||
if (bytesRead != BUFF_SIZE)
|
||||
break;
|
||||
}
|
||||
|
||||
clearProgressBar();
|
||||
consoleSelect(&bottomScreen);
|
||||
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
fclose(fout);
|
||||
}
|
||||
|
||||
fclose(fin);
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long long getFileSize(FILE* f)
|
||||
{
|
||||
if (!f) return 0;
|
||||
|
||||
fseek(f, 0, SEEK_END);
|
||||
unsigned long long size = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
unsigned long long getFileSizePath(char const* path)
|
||||
{
|
||||
if (!path) return 0;
|
||||
|
||||
FILE* f = fopen(path, "rb");
|
||||
unsigned long long size = getFileSize(f);
|
||||
fclose(f);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
bool toggleFileReadOnly(const char* path, bool readOnly)
|
||||
{
|
||||
int fatAttributes = FAT_getAttr(path);
|
||||
if (readOnly)
|
||||
fatAttributes |= ATTR_READONLY;
|
||||
else
|
||||
fatAttributes &= ~ATTR_READONLY;
|
||||
return FAT_setAttr(path, fatAttributes) == 0;
|
||||
}
|
||||
|
||||
bool writeToFile(FILE* fd, const char* buffer, size_t size)
|
||||
{
|
||||
int toWrite = size;
|
||||
size_t written;
|
||||
//write the first 520 bytes as 0, as that's the size of a tmd, but it can be whatever content
|
||||
while (toWrite > 0 && (written = fwrite(buffer, sizeof(char), toWrite, fd)) > 0)
|
||||
{
|
||||
toWrite -= written;
|
||||
buffer += written;
|
||||
}
|
||||
return toWrite == 0;
|
||||
}
|
||||
|
||||
bool calculateFileSha1(FILE* f, void* digest)
|
||||
{
|
||||
fseek(f, 0, SEEK_SET);
|
||||
|
||||
swiSHA1context_t ctx;
|
||||
ctx.sha_block = 0; //this is weird but it has to be done
|
||||
swiSHA1Init(&ctx);
|
||||
|
||||
char buffer[512];
|
||||
size_t n = 0;
|
||||
while ((n = fread(buffer, sizeof(char), sizeof(buffer), f)) > 0)
|
||||
{
|
||||
swiSHA1Update(&ctx, buffer, n);
|
||||
}
|
||||
if (ferror(f) || !feof(f))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
swiSHA1Final(digest, &ctx);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool calculateFileSha1Path(const char* path, void* digest)
|
||||
{
|
||||
FILE* targetFile = fopen(path, "rb");
|
||||
if (!targetFile)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool res = calculateFileSha1(targetFile, digest);
|
||||
fclose(targetFile);
|
||||
return res;
|
||||
}
|
||||
|
||||
bool safeCreateDir(const char* path)
|
||||
{
|
||||
if (((mkdir(path, 0777) == 0) || errno == EEXIST))
|
||||
return true;
|
||||
|
||||
char errorStr[512];
|
||||
sprintf(errorStr, "\x1B[31mError:\x1B[33m Failed to create directory (%s)\n", path);
|
||||
|
||||
messageBox(errorStr);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool removeIfExists(const char* path)
|
||||
{
|
||||
return remove(path) == 0 || errno == ENOENT;
|
||||
}
|
||||
|
||||
// Filesystem type
|
||||
typedef enum {FS_UNKNOWN, FS_FAT12, FS_FAT16, FS_FAT32} FS_TYPE;
|
||||
//trimmed down PARTITION struct from libfat internals
|
||||
typedef struct {
|
||||
const void* disc;
|
||||
void* cache;
|
||||
// Info about the partition
|
||||
FS_TYPE filesysType;
|
||||
uint64_t totalSize;
|
||||
sec_t rootDirStart;
|
||||
uint32_t rootDirCluster;
|
||||
uint32_t numberOfSectors;
|
||||
sec_t dataStart;
|
||||
uint32_t bytesPerSector;
|
||||
uint32_t sectorsPerCluster;
|
||||
uint32_t bytesPerCluster;
|
||||
uint32_t fsInfoSector;
|
||||
} PARTITION;
|
||||
|
||||
extern PARTITION* _FAT_partition_getPartitionFromPath(const char* path);
|
||||
|
||||
u32 getClusterSizeForPartition(const char* path)
|
||||
{
|
||||
PARTITION* p = _FAT_partition_getPartitionFromPath(path);
|
||||
if(!p)
|
||||
return 0;
|
||||
return p->bytesPerCluster;
|
||||
}
|
||||
#include "storage.h"
|
||||
#include "main.h"
|
||||
#include "message.h"
|
||||
#include <errno.h>
|
||||
#include <nds/sha1.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#define TITLE_LIMIT 39
|
||||
|
||||
//progress bar
|
||||
static int lastBars = 0;
|
||||
|
||||
static void printProgressBar(float percent)
|
||||
{
|
||||
if (percent < 0.f) percent = 0.f;
|
||||
if (percent > 1.f) percent = 1.f;
|
||||
|
||||
int bars = (int)(30.f * percent);
|
||||
|
||||
//skip redundant prints
|
||||
if (bars != lastBars)
|
||||
{
|
||||
consoleSelect(&topScreen);
|
||||
|
||||
iprintf("\x1B[42m"); //green
|
||||
|
||||
//Print frame
|
||||
if (lastBars <= 0)
|
||||
{
|
||||
iprintf("\x1b[23;0H[");
|
||||
iprintf("\x1b[23;31H]");
|
||||
}
|
||||
|
||||
//Print bars
|
||||
if (bars > 0)
|
||||
{
|
||||
for (int i = 0; i < bars; i++)
|
||||
iprintf("\x1b[23;%dH|", 1 + i);
|
||||
}
|
||||
|
||||
lastBars = bars;
|
||||
|
||||
iprintf("\x1B[47m"); //white
|
||||
}
|
||||
}
|
||||
|
||||
static void clearProgressBar()
|
||||
{
|
||||
lastBars = 0;
|
||||
consoleSelect(&topScreen);
|
||||
iprintf("\x1b[23;0H ");
|
||||
}
|
||||
|
||||
//files
|
||||
bool fileExists(char const* path)
|
||||
{
|
||||
return access(path, F_OK) == 0;
|
||||
}
|
||||
|
||||
int copyFile(char const* src, char const* dst)
|
||||
{
|
||||
if (!src) return 1;
|
||||
|
||||
unsigned long long size = getFileSizePath(src);
|
||||
return copyFilePart(src, 0, size, dst);
|
||||
}
|
||||
|
||||
int copyFilePart(char const* src, u32 offset, u32 size, char const* dst)
|
||||
{
|
||||
if (!src) return 1;
|
||||
if (!dst) return 2;
|
||||
|
||||
FILE* fin = fopen(src, "rb");
|
||||
|
||||
if (!fin)
|
||||
{
|
||||
fclose(fin);
|
||||
return 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fileExists(dst))
|
||||
remove(dst);
|
||||
|
||||
FILE* fout = fopen(dst, "wb");
|
||||
|
||||
if (!fout)
|
||||
{
|
||||
fclose(fin);
|
||||
fclose(fout);
|
||||
return 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
fseek(fin, offset, SEEK_SET);
|
||||
|
||||
consoleSelect(&topScreen);
|
||||
|
||||
int bytesRead;
|
||||
unsigned long long totalBytesRead = 0;
|
||||
|
||||
#define BUFF_SIZE 128 //Arbitrary. A value too large freezes the ds.
|
||||
char* buffer = (char*)malloc(BUFF_SIZE);
|
||||
|
||||
while (!programEnd)
|
||||
{
|
||||
unsigned int toRead = BUFF_SIZE;
|
||||
if (size - totalBytesRead < BUFF_SIZE)
|
||||
toRead = size - totalBytesRead;
|
||||
|
||||
bytesRead = fread(buffer, 1, toRead, fin);
|
||||
fwrite(buffer, bytesRead, 1, fout);
|
||||
|
||||
totalBytesRead += bytesRead;
|
||||
printProgressBar( ((float)totalBytesRead / (float)size) );
|
||||
|
||||
if (bytesRead != BUFF_SIZE)
|
||||
break;
|
||||
}
|
||||
|
||||
clearProgressBar();
|
||||
consoleSelect(&bottomScreen);
|
||||
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
fclose(fout);
|
||||
}
|
||||
|
||||
fclose(fin);
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long long getFileSize(FILE* f)
|
||||
{
|
||||
if (!f) return 0;
|
||||
|
||||
fseek(f, 0, SEEK_END);
|
||||
unsigned long long size = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
unsigned long long getFileSizePath(char const* path)
|
||||
{
|
||||
if (!path) return 0;
|
||||
|
||||
FILE* f = fopen(path, "rb");
|
||||
unsigned long long size = getFileSize(f);
|
||||
fclose(f);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
bool toggleFileReadOnly(const char* path, bool readOnly)
|
||||
{
|
||||
int fatAttributes = FAT_getAttr(path);
|
||||
if (readOnly)
|
||||
fatAttributes |= ATTR_READONLY;
|
||||
else
|
||||
fatAttributes &= ~ATTR_READONLY;
|
||||
return FAT_setAttr(path, fatAttributes) == 0;
|
||||
}
|
||||
|
||||
bool writeToFile(FILE* fd, const char* buffer, size_t size)
|
||||
{
|
||||
int toWrite = size;
|
||||
size_t written;
|
||||
//write the first 520 bytes as 0, as that's the size of a tmd, but it can be whatever content
|
||||
while (toWrite > 0 && (written = fwrite(buffer, sizeof(char), toWrite, fd)) > 0)
|
||||
{
|
||||
toWrite -= written;
|
||||
buffer += written;
|
||||
}
|
||||
return toWrite == 0;
|
||||
}
|
||||
|
||||
bool calculateFileSha1(FILE* f, void* digest)
|
||||
{
|
||||
fseek(f, 0, SEEK_SET);
|
||||
|
||||
swiSHA1context_t ctx;
|
||||
ctx.sha_block = 0; //this is weird but it has to be done
|
||||
swiSHA1Init(&ctx);
|
||||
|
||||
char buffer[512];
|
||||
size_t n = 0;
|
||||
while ((n = fread(buffer, sizeof(char), sizeof(buffer), f)) > 0)
|
||||
{
|
||||
swiSHA1Update(&ctx, buffer, n);
|
||||
}
|
||||
if (ferror(f) || !feof(f))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
swiSHA1Final(digest, &ctx);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool calculateFileSha1Path(const char* path, void* digest)
|
||||
{
|
||||
FILE* targetFile = fopen(path, "rb");
|
||||
if (!targetFile)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool res = calculateFileSha1(targetFile, digest);
|
||||
fclose(targetFile);
|
||||
return res;
|
||||
}
|
||||
|
||||
bool safeCreateDir(const char* path)
|
||||
{
|
||||
if (((mkdir(path, 0777) == 0) || errno == EEXIST))
|
||||
return true;
|
||||
|
||||
char errorStr[512];
|
||||
sprintf(errorStr, "\x1B[31mError:\x1B[33m Failed to create directory (%s)\n", path);
|
||||
|
||||
messageBox(errorStr);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool removeIfExists(const char* path)
|
||||
{
|
||||
return remove(path) == 0 || errno == ENOENT;
|
||||
}
|
||||
|
||||
// Filesystem type
|
||||
typedef enum {FS_UNKNOWN, FS_FAT12, FS_FAT16, FS_FAT32} FS_TYPE;
|
||||
//trimmed down PARTITION struct from libfat internals
|
||||
typedef struct {
|
||||
const void* disc;
|
||||
void* cache;
|
||||
// Info about the partition
|
||||
FS_TYPE filesysType;
|
||||
uint64_t totalSize;
|
||||
sec_t rootDirStart;
|
||||
uint32_t rootDirCluster;
|
||||
uint32_t numberOfSectors;
|
||||
sec_t dataStart;
|
||||
uint32_t bytesPerSector;
|
||||
uint32_t sectorsPerCluster;
|
||||
uint32_t bytesPerCluster;
|
||||
uint32_t fsInfoSector;
|
||||
} PARTITION;
|
||||
|
||||
extern PARTITION* _FAT_partition_getPartitionFromPath(const char* path);
|
||||
|
||||
u32 getClusterSizeForPartition(const char* path)
|
||||
{
|
||||
PARTITION* p = _FAT_partition_getPartitionFromPath(path);
|
||||
if(!p)
|
||||
return 0;
|
||||
return p->bytesPerCluster;
|
||||
}
|
||||
|
@ -1,34 +1,34 @@
|
||||
#ifndef STORAGE_H
|
||||
#define STORAGE_H
|
||||
|
||||
#include <nds/ndstypes.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//Files
|
||||
bool fileExists(char const* path);
|
||||
int copyFile(char const* src, char const* dst);
|
||||
int copyFilePart(char const* src, u32 offset, u32 size, char const* dst);
|
||||
unsigned long long getFileSize(FILE* f);
|
||||
unsigned long long getFileSizePath(char const* path);
|
||||
bool toggleFileReadOnly(const char* path, bool readOnly);
|
||||
bool writeToFile(FILE* fd, const char* buffer, size_t size);
|
||||
bool calculateFileSha1(FILE* f, void* digest);
|
||||
bool calculateFileSha1Path(const char* path, void* digest);
|
||||
|
||||
//Directories
|
||||
bool safeCreateDir(const char* path);
|
||||
|
||||
//Files and directories
|
||||
bool removeIfExists(const char* path);
|
||||
|
||||
u32 getClusterSizeForPartition(const char* path);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef STORAGE_H
|
||||
#define STORAGE_H
|
||||
|
||||
#include <nds/ndstypes.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//Files
|
||||
bool fileExists(char const* path);
|
||||
int copyFile(char const* src, char const* dst);
|
||||
int copyFilePart(char const* src, u32 offset, u32 size, char const* dst);
|
||||
unsigned long long getFileSize(FILE* f);
|
||||
unsigned long long getFileSizePath(char const* path);
|
||||
bool toggleFileReadOnly(const char* path, bool readOnly);
|
||||
bool writeToFile(FILE* fd, const char* buffer, size_t size);
|
||||
bool calculateFileSha1(FILE* f, void* digest);
|
||||
bool calculateFileSha1Path(const char* path, void* digest);
|
||||
|
||||
//Directories
|
||||
bool safeCreateDir(const char* path);
|
||||
|
||||
//Files and directories
|
||||
bool removeIfExists(const char* path);
|
||||
|
||||
u32 getClusterSizeForPartition(const char* path);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user