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