The source for the 0.2.0 release (12-30-2010).

This commit is contained in:
msiewert76
2011-04-25 20:06:13 +00:00
parent ed7bc5c26d
commit 8eddf850f2
23 changed files with 5605 additions and 104 deletions

View File

@@ -40,7 +40,7 @@ LDFLAGS = -specs=ds_arm9.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
#---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project
#---------------------------------------------------------------------------------
LIBS := -lfat -lnds9
LIBS := -lfat -ldswifi9 -lnds9
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing

View File

@@ -28,6 +28,12 @@
#include "auxspi_core.cpp"
#include "hardware.h"
#include <algorithm>
using std::max;
extern u8 data[0x8000];
// ========================================================
// local functions
@@ -265,9 +271,13 @@ void auxspi_erase()
auxspi_wait_busy();
auxspi_close();
}
} else {
int8 size = 1 << max(0, (auxspi_save_size_log_2() - 15));
memset(data, 0, 0x8000);
for (int i = 0; i < size; i++) {
auxspi_write_data(i << 15, data, 0x8000, type);
}
}
// FIXME: do something for other types as well!
}
void auxspi_wait_wip()

View File

@@ -55,7 +55,7 @@ void displayInit()
consoleInit(&lowerScreen, 3,BgType_Text4bpp, BgSize_T_256x256, 31, 0, false, true);
consoleSelect(&upperScreen);
displayMessage("DS savegame manager\nVersion 0.1.1 Beta\nBy Pokedoc");
iprintf("\n\n\n\n\nDS savegame manager\nVersion 0.2 Beta\nBy Pokedoc");
displayPrintState("Press (B) to continue");
while (!(keysCurrent() & KEY_B));
@@ -63,6 +63,11 @@ void displayInit()
void displayPrintUpper()
{
extern uint32 ezflash;
extern bool gba;
extern uint32 dstype;
extern bool slot2;
// print upper screen (background)
consoleSelect(&upperScreen);
consoleSetWindow(&upperScreen, 0, 0, 32, 24);
@@ -73,16 +78,20 @@ void displayPrintUpper()
iprintf("Game name:\n");
iprintf("Game save:\n");
iprintf("Special :\n");
#if 0
iprintf("--- SLOT 2 ---------------------");
iprintf("Game ID :\n");
iprintf("Game name:\n");
iprintf("Game save:\n");
iprintf("Special :\n");
#endif
if (dstype > 0)
iprintf("This device has no Slot-2");
else {
iprintf("Game ID :\n");
iprintf("Game name:\n");
iprintf("Game save:\n");
iprintf("Special :\n");
}
// print upper screen
consoleSetWindow(&upperScreen, 10, 2, 12, 4);
consoleSetWindow(&upperScreen, 10, 2, 22, 4);
consoleClear();
consoleSetWindow(&upperScreen, 10, 7, 22, 4);
consoleClear();
// fetch cartridge header (maybe, calling "cardReadHeader" on a FC messes with libfat!)
@@ -108,12 +117,15 @@ void displayPrintUpper()
case 3:
sprintf(&name[0], "DSi/SD");
break;
case 4:
sprintf(&name[0], "Slot 2");
break;
}
consoleClear();
iprintf("%s", name);
// 1) The cart id.
consoleSetWindow(&upperScreen, 10, 2, 20, 1);
consoleSetWindow(&upperScreen, 10, 2, 22, 1);
sprintf(&name[0], "----");
if (flash_card) {
sprintf(&name[0], "Flash Card");
@@ -125,7 +137,7 @@ void displayPrintUpper()
iprintf("%s", name);
// 2) The cart name.
consoleSetWindow(&upperScreen, 10, 3, 20, 1);
consoleSetWindow(&upperScreen, 10, 3, 22, 1);
sprintf(&name[0], "----");
if (flash_card) {
sprintf(&name[0], "Flash Card");
@@ -137,7 +149,7 @@ void displayPrintUpper()
iprintf("%s", name);
// 3) The save type
consoleSetWindow(&upperScreen, 10, 4, 20, 1);
consoleSetWindow(&upperScreen, 10, 4, 22, 1);
sprintf(&name[0], "----");
if (flash_card) {
sprintf(&name[0], "Flash Card");
@@ -146,10 +158,10 @@ void displayPrintUpper()
uint32 size = auxspi_save_size();
switch (type) {
case 1:
sprintf(&name[0], "Type 1 (%i Bytes)", size);
sprintf(&name[0], "Eeprom (%i Bytes)", size);
break;
case 2:
sprintf(&name[0], "Type 2 (%i kB)", size >> 10);
sprintf(&name[0], "FRAM (%i kB)", size >> 10);
break;
case 3:
sprintf(&name[0], "Flash (%i kB)", size >> 10);
@@ -163,17 +175,81 @@ void displayPrintUpper()
iprintf("%s", name);
// 4) Special properties (infrared device...)
consoleSetWindow(&upperScreen, 10, 5, 24, 1);
consoleSetWindow(&upperScreen, 10, 5, 22, 1);
consoleClear();
memset(&name[0], 0, MAXPATHLEN);
//if (auxspi_has_infrared()) {
if (ir) {
sprintf(&name[0], "Infrared");
} else {
sprintf(&name[0], "---");
sprintf(&name[0], "----");
}
iprintf("%s", name);
// Slot 2 status
// 5) GBA game id
consoleSetWindow(&upperScreen, 10, 7, 22, 1);
consoleClear();
memset(&name[0], 0, MAXPATHLEN);
if (ezflash) {
if (ezflash == 0x89168916)
sprintf(name, "3in1 (512M)");
else
sprintf(name, "3in1 (256M)");
} else if (gba)
sprintf(name, "%.4s", (char*)0x080000ac);
else if (slot2)
sprintf(name, "Flash Card");
else if (dstype == 0)
sprintf(name, "----");
if (dstype == 0)
iprintf("%s", name);
// 6) GBA game name
consoleSetWindow(&upperScreen, 10, 8, 22, 1);
consoleClear();
memset(&name[0], 0, MAXPATHLEN);
if (ezflash)
sprintf(name, "3in1");
else if (gba)
sprintf(name, "%.12s", (char*)0x080000a0);
else if (slot2)
sprintf(name, "Flash Card");
else if (dstype == 0)
sprintf(name, "----");
if (dstype == 0)
iprintf(name);
// 7) GBA save size
consoleSetWindow(&upperScreen, 10, 9, 22, 1);
consoleClear();
memset(&name[0], 0, MAXPATHLEN);
if (ezflash)
sprintf(name, "SRAM");
else if (gba)
sprintf(name, "(unsupported)");
else if (slot2)
sprintf(name, "Flash Card");
else if (dstype == 0)
sprintf(name, "----");
if (dstype == 0)
iprintf(name);
// 8) GBA special stuff
consoleSetWindow(&upperScreen, 10, 10, 22, 1);
consoleClear();
memset(&name[0], 0, MAXPATHLEN);
if (ezflash)
sprintf(name, "NOR + PSRAM");
else if (gba)
sprintf(name, "(unsupported)");
else if (slot2)
sprintf(name, "----");
else if (dstype == 0)
sprintf(name, "----");
if (dstype == 0)
iprintf(name);
#if 0
// hack: some tests to debug new hardware.
uint8 data[512];

View File

@@ -33,25 +33,84 @@
#include <stdio.h>
#include <dirent.h>
#include <cstdio>
#include "display.h"
char fnames[256][256];
#include "fileselect.h"
extern u8 data[0x8000];
// ---------------------------------------------------------------------------------
void ftpGetFileList(const char *dir, netbuf *ctrl, uint32 &num)
{
char *buf = (char*)data;
memset(buf, 0, 0x8000);
FtpDirBuf((char*)data, 0x8000, "/", ctrl);
//FtpDir("/dir.txt", "/", ctrl);
char *ptr = buf; // scan pointer
char *ptr2 = buf; // write pointer
// count number of entries and condense them for further use
char *begin = 0, *end;
while ((end = strchr(ptr, '\n')) != NULL) {
char c;
char fname[512];
if (!strlen(ptr))
break;
sscanf(ptr, "%c%*s %*s %*s %*s %*s %*s %*s %*s %[^\n]", &c, fname); // gets 'd' or 'f' - dir or file
begin = strstr(ptr, fname);
if (!begin)
break;
int flen = end - begin + 1;
if (flen <= 1)
break; // some FTP servers send an empty line at the end, so prevent an integer overflow
if (c == 'd')
*ptr2 = 'd';
else
*ptr2 = 'f';
ptr2++;
memcpy(ptr2, begin, flen);
ptr = end + 1;
ptr2 += flen;
num++;
}
}
void fileGetFileList(const char *dir, uint32 &num)
{
char *buf = (char*)data;
int idx = 0;
memset(buf, 0, 0x8000);
DIR *pdir;
struct dirent *pent;
num = 0;
pdir=opendir(dir);
char name[128];
if (pdir) {
while ((pent=readdir(pdir)) !=NULL) {
sprintf(&fnames[num][0], "%s", pent->d_name);
num++;
if (num == 256)
char fullname[256];
sprintf(fullname, "%s/%s", dir, pent->d_name);
struct stat statbuf;
stat(fullname, &statbuf);
// TODO: check for buffer overflow!
if (idx + strlen(pent->d_name) < 0x8000-2) {
if (S_ISDIR(statbuf.st_mode)) {
int len = sprintf(buf, "d%s\n", pent->d_name);
buf += len;
idx += len;
} else {
int len = sprintf(buf, "f%s\n", pent->d_name);
buf += len;
idx += len;
}
num++;
} else {
// buffer overflow imminent
break;
}
}
}
if (pdir)
@@ -67,45 +126,65 @@ void filePrintFileList(const char *dir, uint32 first, uint32 select, uint32 coun
consoleSetWindow(&lowerScreen, 0, 0, 32, 19);
consoleClear();
for (uint32 i = first; (i < first + 18) && (i < count); i++) {
struct stat statbuf;
char fullpath[512];
sprintf(fullpath, "%s/%s", dir, fnames[i]);
stat(fullpath, &statbuf);
if (S_ISDIR(statbuf.st_mode)) {
if (i != select)
iprintf("[%.29s]\n", fnames[i]);
else
iprintf("-->[%.26s]\n", fnames[i]);
} else {
if (i != select)
iprintf("%.31s\n", fnames[i]);
else
iprintf("-->%.28s\n", fnames[i]);
}
char *buf = (char*)data;
int idx = 0;
int len = strlen(buf);
for (int i = 0; i < first; i++) {
buf = strchr(buf, '\n') + 1;
}
for (uint32 i = first; (i < first + 18) && (i < count); i++) {
struct stat statbuf;
char dir;
u32 size;
char fname[128];
char fname2[128];
char *newline = strchr(buf, '\n');
int linelen = newline - buf;
*newline = 0;
if (*buf == 'd') {
if (i != select)
iprintf("[%.29s]\n", buf+1);
else
iprintf("-->[%.26s]\n", buf+1);
} else {
if (i != select)
iprintf("%.31s\n", buf+1);
else
iprintf("-->%.28s\n", buf+1);
}
*newline = '\n';
buf += linelen+1;
}
consoleSelect(&lowerScreen);
consoleSetWindow(&lowerScreen, 0, 18, 32, 6);
consoleClear();
iprintf("================================");
iprintf("Please select a .sav file\n");
iprintf(" (A) Select\n");
iprintf(" (B) One directory up\n");
if (cancel)
iprintf(" (B) cancel");
iprintf(" (L+R) cancel (new file)");
}
// ========================***************************==============================
void fileSelect(const char *startdir, char *out_dir, char *out_fname, bool allow_cancel)
void fileSelect(const char *startdir, char *out_dir, char *out_fname, netbuf *buf,
bool allow_cancel, bool allow_up)
{
bool select = false;
static int size_list = 18;
uint32 num_files = 0;
uint32 sel_file = 0;
uint32 first_file = 0;
// get list of files in current dir
fileGetFileList(startdir, num_files);
if (buf)
ftpGetFileList("/", buf, num_files);
else
fileGetFileList(startdir, num_files);
filePrintFileList(startdir, first_file, sel_file, num_files, allow_cancel);
while (!select) {
@@ -116,49 +195,82 @@ void fileSelect(const char *startdir, char *out_dir, char *out_fname, bool allow
if (keys & KEY_DOWN) {
if (sel_file < num_files-1) {
sel_file++;
if (sel_file >= first_file + size_list - 1)
first_file = sel_file - (size_list - 1);
filePrintFileList(startdir, first_file, sel_file, num_files, allow_cancel);
if (sel_file > first_file + 18)
first_file = sel_file - 18;
}
} else if (keys & KEY_UP) {
if (sel_file > 0) {
sel_file--;
filePrintFileList(startdir, first_file, sel_file, num_files, allow_cancel);
if (sel_file < first_file)
first_file = sel_file;
filePrintFileList(startdir, first_file, sel_file, num_files, allow_cancel);
}
} else if (keys & KEY_A) {
// TODO: Okay, my first attempt at implementing a fuill file browser
// failed, so I am disabling changing directory for now. If anybody
// feels inclined to fix it, go ahead.
if (stricmp(fnames[sel_file], ".") == 0)
continue;
if (stricmp(fnames[sel_file], "..") == 0)
//return;
// get selected file name
char *buf2 = (char*)data;
int idx = 0;
int len = strlen(buf2);
char fname[128];
for (int i = 0; i < sel_file; i++) {
buf2 = strchr(buf2, '\n') + 1;
}
char c;
sscanf(buf2, "%c%[^\n]", &c, fname); // gets 'd' or 'f' - dir or file
// special cases
if (stricmp(fname, ".") == 0)
// don't do anything
continue;
if (stricmp(fname, "..") == 0) {
// return to parent function (usually results in "back to higher level")
while (keysCurrent() & (KEY_A | KEY_B));
if (!allow_up)
continue;
if (buf)
FtpChdir("..", buf);
return;
}
// get selected file properties
char fullname[512];
sprintf(fullname, "%s/%s", startdir, fnames[sel_file]);
sprintf(fullname, "%s%s", startdir, fname);
struct stat statbuf;
stat(fullname, &statbuf);
if (S_ISDIR(statbuf.st_mode)) {
/*
if (c == 'd') {
char fullpath[512];
sprintf(fullpath, "%s/%s", startdir, fnames[sel_file]);
fileSelect(fullpath, out_dir, out_fname, allow_cancel);
for (int i = 0; i < 5; i++)
swiWaitForVBlank();
sprintf(fullpath, "%s%s/", startdir, fname);
if (buf)
FtpChdir(fname, buf);
fileSelect(fullpath, out_dir, out_fname, buf, allow_cancel, true);
if ((keysCurrent() & (KEY_L | KEY_R)) && allow_cancel)
return;
while (keysCurrent() & (KEY_A | KEY_B));
// did we select a file? if so, keep returning to parent calling function
if (strlen(out_fname))
return;
*/
// we did not select anything, so regenerate the old list
num_files = 0;
if (buf)
ftpGetFileList("/", buf, num_files);
else
fileGetFileList(startdir, num_files);
filePrintFileList(startdir, first_file, sel_file, num_files, allow_cancel);
continue;
} else {
sprintf(out_dir, "%s", startdir);
sprintf(out_fname, "%s", fnames[sel_file]);
sprintf(out_fname, "%s", fname);
while (keysCurrent() & (KEY_A | KEY_B));
return;
}
select = true;
} else if (keys & KEY_B) {
if (!allow_up)
continue;
if (buf)
FtpChdir("..", buf);
return;
} else if (keys & (KEY_L | KEY_R)) {
if (allow_cancel) {
sprintf(out_dir, "%s", startdir);
out_fname[0] = 0;

View File

@@ -33,8 +33,28 @@
#define MAX_CUSTOM_LIST 8192
#include <unistd.h>
//#endif
//#if defined(_WIN32)
//#include <windows.h>
//#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
//#if defined(__unix__)
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
void fileSelect(const char *startdir, char *out_dir, char *out_fname, bool allow_cancel = false);
#include "ftplib.h"
void fileSelect(const char *startdir, char *out_dir, char *out_fname, netbuf *buf = 0,
bool allow_cancel = false, bool allow_up = true);
bool fileExists(const char *fname);
uint32 fileSize(const char *fname);

1452
arm9/source/ftplib.c Normal file

File diff suppressed because it is too large Load Diff

139
arm9/source/ftplib.h Normal file
View File

@@ -0,0 +1,139 @@
/***************************************************************************/
/* */
/* ftplib.h - header file for callable ftp access routines */
/* Copyright (C) 1996, 1997 Thomas Pfau, pfau@cnj.digex.net */
/* 73 Catherine Street, South Bound Brook, NJ, 08880 */
/* */
/* This library is free software; you can redistribute it and/or */
/* modify it under the terms of the GNU Library General Public */
/* License as published by the Free Software Foundation; either */
/* version 2 of the License, or (at your option) any later version. */
/* */
/* This library is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
/* Library General Public License for more details. */
/* */
/* You should have received a copy of the GNU Library General Public */
/* License along with this progam; if not, write to the */
/* Free Software Foundation, Inc., 59 Temple Place - Suite 330, */
/* Boston, MA 02111-1307, USA. */
/* */
/***************************************************************************/
#if !defined(__FTPLIB_H)
#define __FTPLIB_H
//#define __unix__
/*
#if defined(__unix__) || defined(VMS)
#define GLOBALDEF
#define GLOBALREF extern
#elif defined(_WIN32)
#if defined BUILDING_LIBRARY
#define GLOBALDEF __declspec(dllexport)
#define GLOBALREF __declspec(dllexport)
#else
#define GLOBALREF __declspec(dllimport)
#endif
#endif
*/
#define GLOBALDEF
#define GLOBALREF
/* FtpAccess() type codes */
#define FTPLIB_DIR 1
#define FTPLIB_DIR_VERBOSE 2
#define FTPLIB_FILE_READ 3
#define FTPLIB_FILE_WRITE 4
/* FtpAccess() mode codes */
#define FTPLIB_ASCII 'A'
#define FTPLIB_IMAGE 'I'
#define FTPLIB_TEXT FTPLIB_ASCII
#define FTPLIB_BINARY FTPLIB_IMAGE
/* connection modes */
#define FTPLIB_PASSIVE 1
#define FTPLIB_PORT 2
/* connection option names */
#define FTPLIB_CONNMODE 1
#define FTPLIB_CALLBACK 2
#define FTPLIB_IDLETIME 3
#define FTPLIB_CALLBACKARG 4
#define FTPLIB_CALLBACKBYTES 5
#ifdef __cplusplus
extern "C" {
#endif
typedef struct NetBuf netbuf;
typedef int (*FtpCallback)(netbuf *nControl, int xfered, void *arg);
/* v1 compatibility stuff */
#define _FTPLIB_NO_COMPAT
#if !defined(_FTPLIB_NO_COMPAT)
extern netbuf *DefaultNetbuf;
#define ftplib_lastresp FtpLastResponse(DefaultNetbuf)
#define ftpInit FtpInit
#define ftpOpen(x) FtpConnect(x, &DefaultNetbuf)
#define ftpLogin(x,y) FtpLogin(x, y, DefaultNetbuf)
#define ftpSite(x) FtpSite(x, DefaultNetbuf)
#define ftpMkdir(x) FtpMkdir(x, DefaultNetbuf)
#define ftpChdir(x) FtpChdir(x, DefaultNetbuf)
#define ftpRmdir(x) FtpRmdir(x, DefaultNetbuf)
#define ftpNlst(x, y) FtpNlst(x, y, DefaultNetbuf)
#define ftpDir(x, y) FtpDir(x, y, DefaultNetbuf)
#define ftpGet(x, y, z) FtpGet(x, y, z, DefaultNetbuf)
#define ftpPut(x, y, z) FtpPut(x, y, z, DefaultNetbuf)
#define ftpRename(x, y) FtpRename(x, y, DefaultNetbuf)
#define ftpDelete(x) FtpDelete(x, DefaultNetbuf)
#define ftpQuit() FtpQuit(DefaultNetbuf)
#endif /* (_FTPLIB_NO_COMPAT) */
/* end v1 compatibility stuff */
extern int ftplib_debug;
GLOBALREF void FtpInit(void);
GLOBALREF char *FtpLastResponse(netbuf *nControl);
GLOBALREF int FtpConnect(const char *host, netbuf **nControl);
GLOBALREF int FtpOptions(int opt, long val, netbuf *nControl);
GLOBALREF int FtpLogin(const char *user, const char *pass, netbuf *nControl);
GLOBALREF int FtpAccess(const char *path, int typ, int mode, netbuf *nControl,
netbuf **nData);
GLOBALREF int FtpRead(void *buf, int max, netbuf *nData);
GLOBALREF int FtpWrite(void *buf, int len, netbuf *nData);
GLOBALREF int FtpClose(netbuf *nData);
GLOBALREF int FtpSite(const char *cmd, netbuf *nControl);
GLOBALREF int FtpSysType(char *buf, int max, netbuf *nControl);
GLOBALREF int FtpMkdir(const char *path, netbuf *nControl);
GLOBALREF int FtpChdir(const char *path, netbuf *nControl);
GLOBALREF int FtpCDUp(netbuf *nControl);
GLOBALREF int FtpRmdir(const char *path, netbuf *nControl);
GLOBALREF int FtpPwd(char *path, int max, netbuf *nControl);
GLOBALREF int FtpNlst(const char *output, const char *path, netbuf *nControl);
GLOBALREF int FtpDir(const char *output, const char *path, netbuf *nControl);
GLOBALREF int FtpSize(const char *path, int *size, char mode, netbuf *nControl);
GLOBALREF int FtpModDate(const char *path, char *dt, int max, netbuf *nControl);
GLOBALREF int FtpGet(const char *output, const char *path, char mode,
netbuf *nControl);
GLOBALREF int FtpPut(const char *input, const char *path, char mode,
netbuf *nControl);
GLOBALREF int FtpRename(const char *src, const char *dst, netbuf *nControl);
GLOBALREF int FtpDelete(const char *fnm, netbuf *nControl);
GLOBALREF void FtpQuit(netbuf *nControl);
static int FtpSendCmd(const char *cmd, char expresp, netbuf *nControl);
GLOBALREF int FtpAccessBuf(const char *path, int typ, int mode, netbuf *nControl,
netbuf **nData);
GLOBALREF int FtpDirBuf(char *buf, int size, const char *path, netbuf *nControl);
#ifdef __cplusplus
};
#endif
#endif /* __FTPLIB_H */

View File

@@ -29,12 +29,14 @@
#include <nds/arm9/console.h>
#include <sys/dir.h>
#include <sys/unistd.h>
#include <dswifi9.h>
#include <stdio.h>
#include <algorithm>
#include "display.h"
#include "dsCard.h"
#include "ftplib.h"
#include "gba.h"
#include "hardware.h"
@@ -50,6 +52,11 @@ uint32 boot;
bool flash_card = true; // the homebrew will always start with a FC inserted
bool with_infrared = false; // ... which does not have an IR device
extern char ftp_ip[16];
extern char ftp_user[64];
extern char ftp_pass[64];
extern int ftp_port;
u8 data[0x8000];
// ---------------------------------------------------------------------
@@ -134,6 +141,7 @@ void hwBackup3in1()
// Dump save and write it to NOR
chip_reset();
OpenNorWrite();
SetSerialMode();
displayPrintState("Writing save to NOR");
if (size < 15)
size_blocks = 1;
@@ -159,8 +167,6 @@ void hwBackup3in1()
WriteSram(0x0a000000, (u8*)&data2, sizeof(data2));
char txt[128];
sprintf(txt, "%.12s", &nds.gameTitle[0]);
//memcpy(&txt[0], &nds.gameTitle[0], 12);
//displayPrintState(txt);
displayMessage("Save has been written to 3in1.\nPlease power off and restart\nthis tool.");
@@ -175,8 +181,8 @@ void hwDump3in1(uint32 size, const char *gamename)
char path[256];
char fname[256] = "";
//fileSelect("/", path, fname/*, true*/);
//if (!fname[0]) {
fileSelect("/", path, fname, 0, true, false);
if (!fname[0]) {
uint32 cnt = 0;
sprintf(fname, "/%s.%i.sav", gamename, cnt);
while (fileExists(fname)) {
@@ -188,14 +194,14 @@ void hwDump3in1(uint32 size, const char *gamename)
}
sprintf(fname, "/%s.%i.sav", gamename, cnt);
}
//}
}
char fullpath[512];
//sprintf(fullpath, "%s/%s", path, fname);
sprintf(fullpath, "%s", fname);
displayMessage(fullpath);
sprintf(fullpath, "%s/%s", path, fname);
//sprintf(fullpath, "%s", fname);
displayMessage(fname);
// TODO: add support for smaller files!
FILE *file = fopen(fullpath, "wb");
//u8 *data = (u8*)malloc(0x8000);
if (size < 15)
size_blocks = 1;
else
@@ -205,8 +211,6 @@ void hwDump3in1(uint32 size, const char *gamename)
u32 LEN = 0x8000;
ReadNorFlash(data, i << 15, LEN);
fwrite(data, 1, LEN, file);
//if (j != LEN)
//iprintf ("WRITE ERROR %i\n", errno);
}
//free(data);
fclose(file);
@@ -219,8 +223,9 @@ void hwRestore3in1()
{
char path[256];
char fname[256];
memset(fname, 0, 256);
displayMessage("Please select a .sav file.");
fileSelect("/", path, fname);
fileSelect("/", path, fname, 0, false, false);
displayMessage("");
char msg[256];
sprintf(msg, "%s%s", path, fname);
@@ -310,11 +315,9 @@ void hwRestore3in1_b(uint32 size_file)
}
LEN = 1 << shift;
num_blocks = 1 << (size - shift);
//data = (u8*)malloc(LEN);
chip_reset();
OpenNorWrite();
SetSerialMode();
for (unsigned int i = 0; i < num_blocks; i++) {
if (i % (num_blocks >> 6) == 0)
displayProgressBar(i+1, num_blocks);
@@ -330,13 +333,224 @@ void hwRestore3in1_b(uint32 size_file)
while (1) {};
}
// ------------------------------------------------------------
void hwErase()
{
displayMessage("This will WIPE OUT your entire\nsave! ARE YOU SURE?\n\nPress R+up+Y to confim!");
while (!(keysCurrent() & (KEY_UP | KEY_R | KEY_Y))) {};
auxspi_erase();
displayMessage("Done! Your save is gone!");
while(0);
while(1);
}
// ------------------------------------------------------------
void hwBackupFTP()
{
netbuf *buf, *ndata;
int j;
static int jmax = 10;
// Dump save and write it to FTP server
// First: swap card
swap_cart();
displayPrintUpper();
uint8 size = auxspi_save_size_log_2();
int size_blocks = 1 << max(0, (int8(size) - 18)); // ... in units of 0x40000 bytes - that's 256 kB
uint8 type = auxspi_save_type();
if (size < 15)
size_blocks = 1;
else
size_blocks = 1 << (uint8(size) - 15);
// Second: connect to FTP server
displayPrintState("FTP: connecting to AP");
if (!Wifi_InitDefault(true)) {
displayPrintState("FTP: ERROR: AP not found");
while(1);
}
displayPrintState("FTP: connecting to FTP server");
char fullname[512];
sprintf(fullname, "%s:%i", ftp_ip, ftp_port);
j = 0;
while (!FtpConnect(fullname, &buf)) {
j++;
if (j >= jmax) {
displayPrintState("FTP: ERROR: FTP server missing");
while(1);
}
swiDelay(10000);
}
displayPrintState("FTP: login");
j = 0;
while (!FtpLogin(ftp_user, ftp_pass, buf)) {
j++;
if (j >= jmax) {
displayPrintState("FTP: ERROR: login failed");
while(1);
}
swiDelay(10000);
}
char fdir[256] = "";
char fname[256] ="";
memset(fname, 0, 256);
displayMessage("Please select a file name to\noverwrite, or press L+R in a\nfolder to create a new file.");
displayPrintState("FTP: dir");
fileSelect("/", fdir, fname, buf, true, false);
bool newfile;
if (!fname[0])
newfile = true;
else
newfile = false;
// Third: get a new target filename
FtpChdir(fdir, buf);
if (!fname[0]) {
displayMessage("Looking for an unused filename");
sNDSHeader nds;
cardReadHeader((u8*)&nds);
uint32 cnt = 0;
int tsize = 0;
sprintf(fname, "%.12s.%i.sav", nds.gameTitle, cnt);
while (FtpSize(fname, &tsize, FTPLIB_IMAGE, buf) != 0) {
if (cnt < 65536)
cnt++;
else {
displayMessage("Unable to get a filename!\nThis means that you have more\nthan 65536 saves! (wow!)\nOops!");
while(1);
}
sprintf(fname, "%.12s.%i.sav", nds.gameTitle, cnt);
displayPrintState(fname);
}
}
// Fourth: dump save
displayPrintState("");
sprintf(fullname, "Writing file:\n%s%s", fdir, fname);
displayMessage(fullname);
FtpAccess(fname, FTPLIB_FILE_WRITE, FTPLIB_IMAGE, buf, &ndata);
u32 length = 0x200;
if (size < 9)
length = 1 << size;
for (int i = 0; i < (1 << (size - 9)); i++) {
displayProgressBar(i+1, (size_blocks << 6));
auxspi_read_data(i << 9, (u8*)&data[0], length, type);
int out;
if ((out = FtpWrite((u8*)&data[0], length, ndata)) < length) {
char dings[512];
sprintf(dings, "Error: wrote %i, got %i", length, out);
displayPrintState(dings);
while(1);
}
}
FtpClose(ndata);
FtpQuit(ndata);
Wifi_DisconnectAP();
displayMessage("Done! Please turn off your DS.");
while(1);
}
void hwRestoreFTP()
{
netbuf *buf, *ndata;
int j;
static int jmax = 10;
// Dump save and write it to FTP server
// First: connect to FTP server
displayPrintState("FTP: connecting to AP");
if (!Wifi_InitDefault(true)) {
displayPrintState("FTP: ERROR: AP not found");
while(1);
}
displayPrintState("FTP: connecting to FTP server");
char fullname[512];
sprintf(fullname, "%s:%i", ftp_ip, ftp_port);
j = 0;
while (!FtpConnect(fullname, &buf)) {
j++;
if (j >= jmax) {
displayPrintState("FTP: ERROR: FTP server missing");
while(1);
}
swiDelay(10000);
}
displayPrintState("FTP: login");
j = 0;
while (!FtpLogin(ftp_user, ftp_pass, buf)) {
j++;
if (j >= jmax) {
displayPrintState("FTP: ERROR: login failed");
while(1);
}
swiDelay(10000);
}
// Second: select a filename
char fdir[256] = "";
char fname[256] ="";
memset(fname, 0, 256);
displayMessage("Please select a file name to\nrestore.");
displayPrintState("FTP: dir");
fileSelect("/", fdir, fname, buf, true, false);
/*char fn[512];
displayMessage(fname);
while(1);*/
// Third: swap card
swap_cart();
displayPrintUpper();
uint8 size = auxspi_save_size_log_2();
int size_blocks = 1 << (size - 9); // ... in units of 512 bytes
uint8 type = auxspi_save_type();
if (type == 3) {
displayPrintState("Formating Flash chip");
auxspi_erase();
}
displayPrintState("");
FtpChdir(fdir, buf);
sprintf(fullname, "Reading file:\n%s%s", fdir, fname);
displayMessage(fullname);
FtpAccess(fname, FTPLIB_FILE_READ, FTPLIB_IMAGE, buf, &ndata);
u32 LEN = 0, num_blocks = 0, shift = 0;
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;
int num_blocks_ftp = 1 << (size - 9);
num_blocks = 1 << (size - shift);
for (int i = 0; i < num_blocks_ftp; i++) {
displayProgressBar(i+1, num_blocks_ftp);
int out;
if ((out = FtpRead((u8*)data, 512, ndata)) < 512) {
char dings[512];
sprintf(dings, "Error: requested 512, got %i", out);
while(1);
}
for (int j = 0; j < 1 << (9-shift); j++) {
auxspi_write_data((i << 9)+(j << shift), ((u8*)data)+(j<<shift), LEN, type);
}
}
FtpClose(ndata);
FtpQuit(ndata);
Wifi_DisconnectAP();
displayMessage("Done! Please turn off your DS.");
while(1);
}
// ------------------------------------------------------------

View File

@@ -54,6 +54,9 @@ void hwRestore3in1();
void hwRestore3in1_b(uint32 size_file);
void hwErase();
void hwBackupFTP();
void hwRestoreFTP();
void hwBackupGBA();
void hwRestoreGBA();
void hwEraseGBA();

394
arm9/source/headings.i Normal file
View File

@@ -0,0 +1,394 @@
/***************************************************************************
headings.i - Section Heading Manipulation Functions
-------------------
begin : Fri Apr 21 2000
copyright : (C) 2000 by Simon White
email : s_a_white@email.com
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "iniheadings.h"
#if defined(HAVE_STRINGS_H)
# include <strings.h>
#endif
#ifndef HAVE_STRCASECMP
# define strcasecmp stricmp
#endif
/********************************************************************************************************************
* Function : __ini_addHeading
* Parameters : ini - pointer to ini file database. heading - heading name
* Returns : Pointer to new heading.
* Globals Used :
* Globals Modified :
* Description : Adds a new heading to the ini file database and updates the temporary workfile
********************************************************************************************************************
* Rev | Date | By | Comment
* ----------------------------------------------------------------------------------------------------------------
********************************************************************************************************************/
struct section_tag *__ini_addHeading (ini_t *ini, char *heading)
{
struct section_tag *section;
size_t length;
long pos;
// Format heading for storing
__ini_strtrim (heading);
/* Create a backup of the file we are about to edit */
if (ini->heading == heading)
return __ini_locateHeading (ini, heading);
// Add new heading to work file and read it in
// using file add
fseek (ini->ftmp, 0, SEEK_END);
fputs ("\n[", ini->ftmp);
pos = ftell (ini->ftmp);
fputs (heading, ini->ftmp);
length = (size_t) (ftell (ini->ftmp) - pos);
section = __ini_faddHeading (ini, ini->ftmp, pos, length);
fseek (ini->ftmp, 0, SEEK_END);
fputs ("]\n", ini->ftmp);
ini->heading = section->heading;
if (section)
ini->flags |= INI_MODIFIED;
return section;
}
/********************************************************************************************************************
* Function : __ini_faddheading
* Parameters : ini - pointer to ini file database, file - ini file to read heading from
* : pos - heading position in file, length - heading length
* Returns : Pointer to new heading.
* Globals Used :
* Globals Modified :
* Description : Adds a new heading to the ini file database from the input file.
********************************************************************************************************************
* Rev | Date | By | Comment
* ----------------------------------------------------------------------------------------------------------------
********************************************************************************************************************/
struct section_tag *__ini_faddHeading (ini_t *ini, FILE *file, long pos, size_t length)
{
struct section_tag *section;
char *str;
if (length)
{
length++;
str = (char *) malloc (sizeof(char) * length);
assert (str);
fseek (file, pos, SEEK_SET);
fgets (str, (int) length, file);
__ini_strtrim (str);
}
else
{
str = (char *) malloc (sizeof(char));
assert (str);
*str = '\0';
}
section = __ini_createHeading (ini, str);
// Make sure heading was created
if (!section)
{
free (str);
return NULL;
}
return section;
}
/********************************************************************************************************************
* Function : __ini_createHeading
* Parameters : ini - pointer to ini file database. heading - heading name
* Returns : Pointer to new heading.
* Globals Used :
* Globals Modified :
* Description : Adds an entry into the heading linked list ready for formating by the addHeading commands
********************************************************************************************************************
* Rev | Date | By | Comment
* ----------------------------------------------------------------------------------------------------------------
********************************************************************************************************************/
struct section_tag *__ini_createHeading (ini_t *ini, char *heading)
{
struct section_tag *pNew;
pNew = __ini_locateHeading (ini, heading);
// Check to see if heading already exists
if (pNew)
free (heading);
else
{ // Create a new heading as dosen't exist
pNew = (struct section_tag *) malloc (sizeof (struct section_tag));
if (!pNew)
return NULL;
memset (pNew, 0, sizeof (struct section_tag));
pNew->heading = heading;
if (*heading)
{ // Found a named heading
pNew->pPrev = ini->last;
ini->last = pNew;
if (pNew->pPrev)
pNew->pPrev->pNext = pNew;
else
ini->first = pNew;
}
else
{ // Anonymous heading (special case),
// always comes first
pNew->pNext = ini->first;
ini->first = pNew;
if (pNew->pNext)
pNew->pNext->pPrev = pNew;
else
ini->last = pNew;
}
#ifdef INI_USE_HASH_TABLE
{ // Rev 1.3 - Added
struct section_tag *pOld;
unsigned long crc32;
unsigned char accel;
crc32 = __ini_createCrc32 (heading, (ini->flags & INI_CASE) != 0);
pNew->crc = crc32;
// Rev 1.3 - Add accelerator list
accel = (unsigned char) crc32 & 0x0FF;
pNew->pPrev_Acc = NULL;
pOld = ini->sections[accel];
ini->sections[accel] = pNew;
if (pOld) pOld->pPrev_Acc = pNew;
pNew->pNext_Acc = pOld;
}
#endif // INI_USE_HASH_TABLE
}
ini->selected = pNew;
return pNew;
}
/********************************************************************************************************************
* Function : __ini_deleteHeading
* Parameters : ini - pointer to ini file database. heading - heading name
* Returns :
* Globals Used :
* Globals Modified :
* Description : Removes a heading from the database only.
* : This change does not occur in the file until ini_close is called.
********************************************************************************************************************
* Rev | Date | By | Comment
* ----------------------------------------------------------------------------------------------------------------
********************************************************************************************************************/
void __ini_deleteHeading (ini_t *ini)
{
struct section_tag *current_h;
// Delete Heading
current_h = ini->selected;
if (current_h)
{ // Delete Keys
while (current_h->first)
{
current_h->selected = current_h->first;
__ini_deleteKey (ini);
}
// Tidy up all users of this heading
ini->selected = NULL;
if (ini->last == current_h)
ini->last = current_h->pPrev;
// Break heading out of list
if (!current_h->pPrev)
ini->first = current_h->pNext;
else
current_h->pPrev->pNext = current_h->pNext;
if (current_h->pNext)
current_h->pNext->pPrev = current_h->pPrev;
#ifdef INI_USE_HASH_TABLE
// Rev 1.3 - Take member out of accelerator list
if (!current_h->pPrev_Acc)
ini->sections[(unsigned char) current_h->crc & 0x0FF] = current_h->pNext_Acc;
else
current_h->pPrev_Acc->pNext_Acc = current_h->pNext_Acc;
if (current_h->pNext_Acc)
current_h->pNext_Acc->pPrev_Acc = current_h->pPrev_Acc;
#endif // INI_USE_HASH_TABLE
// Delete Heading
free (current_h->heading);
free (current_h);
}
}
/********************************************************************************************************************
* Function : __ini_locateHeading
* Parameters : ini - pointer to ini file database. heading - heading name
* Returns : Pointer to heading.
* Globals Used :
* Globals Modified :
* Description : Locates a heading entry in the database.
********************************************************************************************************************
* Rev | Date | By | Comment
* ----------------------------------------------------------------------------------------------------------------
********************************************************************************************************************/
struct section_tag *__ini_locateHeading (ini_t *ini, const char *heading)
{
struct section_tag *current_h;
#ifdef INI_USE_HASH_TABLE
// Rev 1.3 - Revised to use new accelerator
unsigned long crc32;
crc32 = __ini_createCrc32 (heading, (ini->flags & INI_CASE) != 0);
// Search for heading
for (current_h = ini->sections[(unsigned char) crc32 & 0x0FF]; current_h; current_h = current_h->pNext_Acc)
{
if (current_h->crc == crc32)
{
if (ini->flags & INI_CASE)
{
if (!strcmp (current_h->heading, heading))
break;
}
else if (!strcasecmp (current_h->heading, heading))
break;
}
}
#else
// Search for heading
for (current_h = ini->first; current_h; current_h = current_h->pNext)
{
if (ini->flags & INI_CASE)
{
if (!strcmp (current_h->heading, heading))
break;
}
else if (!strcasecmp (current_h->heading, heading))
break;
}
#endif // INI_USE_HASH_TABLE
ini->selected = current_h;
return current_h;
}
/********************************************************************************************************************
* Function : (public) ini_deleteHeading
* Parameters : ini - pointer to ini file descriptor
* Returns : -1 for Error and 0 on success
* Globals Used :
* Globals Modified :
* Description : Equivalent Microsoft write string API call where both data & key are set to NULL.
********************************************************************************************************************/
int INI_LINKAGE ini_deleteHeading (ini_fd_t fd)
{
ini_t *ini = (ini_t *) fd;
if (!ini->selected)
return -1;
// Is file read only?
if (ini->mode == INI_READ)
return -1;
// Can't delete a temporary section
if (ini->selected == &(ini->tmpSection))
return -1;
__ini_deleteHeading (ini);
ini->flags |= INI_MODIFIED;
return 0;
}
/********************************************************************************************************************
* Function : (public) ini_locateHeading
* Parameters : fd - pointer to ini file descriptor
* Returns : -1 for Error and 0 on success
* Globals Used :
* Globals Modified :
* Description : Equivalent Microsoft write string API call where both data & key are set to NULL.
********************************************************************************************************************/
int INI_LINKAGE ini_locateHeading (ini_fd_t fd, const char *heading)
{
ini_t *ini = (ini_t *) fd;
struct section_tag *section;
if (!heading)
return -1;
section = __ini_locateHeading (ini, heading);
#ifdef INI_ADD_LIST_SUPPORT
// Rev 1.1 - Remove buffered list
if (ini->list)
{
free (ini->list);
ini->list = NULL;
}
#endif // INI_ADD_LIST_SUPPORT
if (section)
{
section->selected = NULL;
return 0;
}
// Ok no section was found, but maybe the user is wanting to create a
// new one so create it temporarily and see what actually happens later
{ // Remove old heading
section = &(ini->tmpSection);
if (section->heading)
free (section->heading);
// Add new heading
section->heading = strdup (heading);
if (!section->heading)
return -1;
section->selected = NULL;
ini->selected = section;
}
return -1;
}
/********************************************************************************************************************
* Function : (public) ini_currentHeading
* Parameters : fd - pointer to ini file descriptor
* Returns : NULL for Error and on success pointer to heading
* Globals Used :
* Globals Modified :
* Description : Returns currently selected heading
********************************************************************************************************************/
const char * INI_LINKAGE ini_currentHeading (ini_fd_t fd)
{
ini_t *ini = (ini_t *) fd;
struct section_tag *section;
if (!ini)
return NULL;
section = ini->selected;
if (!section)
return NULL;
return section->heading;
}

1165
arm9/source/ini.cpp Normal file

File diff suppressed because it is too large Load Diff

76
arm9/source/ini.h Normal file
View File

@@ -0,0 +1,76 @@
/***************************************************************************
ini.h - Ini database definition
-------------------
begin : Fri Apr 21 2000
copyright : (C) 2000 by Simon White
email : s_a_white@email.com
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef _ini_h_
#define _ini_h_
#define INI_USE_HASH_TABLE
#include "libini.h"
#include "inikeys.h"
#include "iniheadings.h"
#ifdef INI_ADD_LIST_SUPPORT
# include "inilist.h"
#endif
typedef enum {INI_NEW, INI_EXIST, INI_READ} ini_mode_t;
enum
{
INI_NONE = 0,
INI_MODIFIED = 1 << 0,
INI_NEWFILE = 1 << 1,
INI_BACKUP = 1 << 2, // Create backup file
INI_CASE = 1 << 3 // Case sensitive
};
// Database containing all information about an ini file.
typedef struct ini_t
{
char *filename;
FILE *ftmp; // Temporary work file
ini_mode_t mode; // Access mode
int flags;
struct section_tag *first;
struct section_tag *last;
struct section_tag *selected;
char *heading; // Last written section in tmp file.
struct section_tag tmpSection;
struct key_tag tmpKey;
#ifdef INI_USE_HASH_TABLE
struct section_tag *sections[256];
#endif
#ifdef INI_ADD_LIST_SUPPORT
// Rev 1.1 Added - New for list accessing
char *list; // Accelerator for accessing same list (When all list read, will be freed)
char *listDelims; // list sperators
char *listIndexPtr; // current element we wish to access (will auto increment)
unsigned int listLength;
unsigned int listIndex;
#endif // INI_ADD_LIST_SUPPORT
} ini_t;
static void __ini_strtrim (char *str);
#ifdef INI_USE_HASH_TABLE
static unsigned long __ini_createCrc32 (const char *str, bool strcase);
#endif
#endif // _ini_h_

59
arm9/source/iniconfig.h Normal file
View File

@@ -0,0 +1,59 @@
/* include/config.h. Generated by configure. */
/* include/config.h.in. Generated from configure.in by autoheader. */
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define if you have the strcasecmp function. */
#define HAVE_STRCASECMP
/* Define if you have the <strings.h> header file. */
//#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Name of package */
#define PACKAGE "libini"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT ""
/* Define to the full name of this package. */
#define PACKAGE_NAME ""
/* Define to the full name and version of this package. */
#define PACKAGE_STRING ""
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME ""
/* Define to the version of this package. */
#define PACKAGE_VERSION ""
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Version number of package */
#define VERSION "1.1.10"

55
arm9/source/iniheadings.h Normal file
View File

@@ -0,0 +1,55 @@
/***************************************************************************
headings.h - Section Heading Manipulation Functions
-------------------
begin : Fri Apr 21 2000
copyright : (C) 2000 by Simon White
email : s_a_white@email.com
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef _headings_h_
#define _headings_h_
#include <stdio.h>
#include "ini.h"
//*******************************************************************************************************************
// Data structure definitions
//*******************************************************************************************************************
struct keys_tag;
struct ini_t;
// Linked list structure for holding section/heading information.
struct section_tag
{
char *heading;
struct key_tag *first;
struct key_tag *last;
struct key_tag *selected;
struct section_tag *pNext;
struct section_tag *pPrev;
#ifdef INI_USE_HASH_TABLE
unsigned long crc;
struct key_tag *keys[256];
struct section_tag *pNext_Acc;
struct section_tag *pPrev_Acc;
#endif // INI_USE_HASH_TABLE
};
static struct section_tag *__ini_addHeading (struct ini_t *ini, char *heading);
static struct section_tag *__ini_faddHeading (struct ini_t *ini, FILE *file, long pos, size_t length);
static struct section_tag *__ini_createHeading (struct ini_t *ini, char *heading);
static void __ini_deleteHeading (struct ini_t *ini);
static struct section_tag *__ini_locateHeading (struct ini_t *ini, const char *heading);
#endif // _headings_h_

54
arm9/source/inikeys.h Normal file
View File

@@ -0,0 +1,54 @@
/***************************************************************************
keys.h - Key Manipulation Functions
-------------------
begin : Fri Apr 21 2000
copyright : (C) 2000 by Simon White
email : s_a_white@email.com
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef _keys_h_
#define _keys_h_
#include <stdio.h>
#include "ini.h"
//*******************************************************************************************************************
// Data structure definitions
//*******************************************************************************************************************
struct ini_t;
struct section_tag;
// Linked list structure for holding key information.
struct key_tag
{
char *key;
long pos;
size_t length;
struct key_tag *pNext;
struct key_tag *pPrev;
#ifdef INI_USE_HASH_TABLE
unsigned long crc;
struct key_tag *pNext_Acc;
struct key_tag *pPrev_Acc;
#endif // INI_USE_HASH_TABLE
};
static struct key_tag *__ini_addKey (struct ini_t *ini, char *key);
static struct key_tag *__ini_faddKey (struct ini_t *ini, FILE *file, long pos, size_t length);
static struct key_tag *__ini_createKey (struct ini_t *ini, char *key);
static void __ini_deleteKey (struct ini_t *ini);
static struct key_tag *__ini_locateKey (struct ini_t *ini, const char *key);
static size_t __ini_averageLengthKey (struct section_tag *current_h);
#endif // _keys_h_

32
arm9/source/inilist.h Normal file
View File

@@ -0,0 +1,32 @@
/***************************************************************************
list.h - Adds list support to ini files
-------------------
begin : Fri Apr 21 2000
copyright : (C) 2000 by Simon White
email : s_a_white@email.com
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef _list_h_
#define _list_h_
#include "ini.h"
#ifdef INI_ADD_LIST_SUPPORT
struct ini_t;
static int __ini_listEval (struct ini_t *ini);
static char *__ini_listRead (struct ini_t *ini);
static int __ini_listIndexLength (struct ini_t *ini);
static int __ini_listDelims (struct ini_t *ini, const char *delims);
#endif // INI_ADD_LIST_SUPPORT
#endif // _list_h_

438
arm9/source/keys.i Normal file
View File

@@ -0,0 +1,438 @@
/***************************************************************************
keys.i - Key Manipulation Functions
-------------------
begin : Fri Apr 21 2000
copyright : (C) 2000 by Simon White
email : s_a_white@email.com
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "inikeys.h"
#define INI_EQUALS_ALIGN 10
#if defined(HAVE_STRINGS_H)
# include <strings.h>
#endif
#ifndef HAVE_STRCASECMP
# define strcasecmp stricmp
#endif
/********************************************************************************************************************
* Function : __ini_addKey
* Parameters : ini - pointer to ini file database. key - key name
* Returns : Pointer to key.
* Globals Used :
* Globals Modified :
* Description : Adds a new key to the ini file database and updates the temporary workfile.
* : A heading operation must be called before this function.
********************************************************************************************************************
* Rev | Date | By | Comment
* ----------------------------------------------------------------------------------------------------------------
********************************************************************************************************************/
struct key_tag *__ini_addKey (ini_t *ini, char *key)
{
struct key_tag *_key;
size_t length;
long pos;
// Format heading for storing
__ini_strtrim (key);
if (!*key)
return NULL;
// Add new key to work file and read it in
// using file add
fseek (ini->ftmp, 0, SEEK_END);
pos = ftell (ini->ftmp);
fputs (key, ini->ftmp);
length = (size_t) (ftell (ini->ftmp) - pos);
_key = __ini_faddKey (ini, ini->ftmp, pos, length);
fseek (ini->ftmp, 0, SEEK_END);
fputc ('=', ini->ftmp);
if (_key)
ini->flags |= INI_MODIFIED;
return _key;
}
/********************************************************************************************************************
* Function : __ini_averageLengthKey
* Parameters : current_h - pointer to current header.
* Returns : Returns the average key length
* Globals Used :
* Globals Modified :
* Description : Finds average key length for aligning equals.
********************************************************************************************************************/
size_t __ini_averageLengthKey (struct section_tag *current_h)
{
#ifdef INI_EQUALS_ALIGN
size_t equal_pos, equal_max, keylength;
size_t average = 0, count = 0;
struct key_tag *current_k;
// Rev 1.1 Added - Line up equals characters for keys
// Calculate Average
current_k = current_h->first;
while (current_k)
{
count++;
average += strlen (current_k->key);
current_k = current_k->pNext;
}
if (!count)
return 0;
average /= count;
equal_pos = (equal_max = average);
#if INI_EQUALS_ALIGN > 0
// Work out the longest key in that range
current_k = current_h->first;
while (current_k)
{
keylength = strlen (current_k->key);
equal_max = average + INI_EQUALS_ALIGN;
if ((equal_max > keylength) && (keylength > equal_pos))
equal_pos = keylength;
current_k = current_k->pNext;
}
#endif // INI_EQUALS_ALIGN > 0
return equal_pos;
#else
return 0;
#endif // INI_EQUALS_ALIGN
}
/********************************************************************************************************************
* Function : __ini_faddKey
* Parameters : ini - pointer to ini file database, file - ini file to read key from
* : pos - key position in file, length - key length
* Returns : Pointer to key.
* Globals Used :
* Globals Modified :
* Description : Adds a new key to the ini file database from the input file.
* : A heading operation must be called before this function.
********************************************************************************************************************
* Rev | Date | By | Comment
* ----------------------------------------------------------------------------------------------------------------
********************************************************************************************************************/
struct key_tag *__ini_faddKey (ini_t *ini, FILE *file, long pos, size_t length)
{
struct key_tag *_key;
char *str;
length++;
str = (char *) malloc (sizeof(char) * length);
assert (str);
fseek (file, pos, SEEK_SET);
fgets (str, (int) length, file);
__ini_strtrim (str);
_key = __ini_createKey (ini, str);
if (!_key)
{ free (str);
return NULL;
}
_key->pos = pos + (long) length;
return _key;
}
/********************************************************************************************************************
* Function : __ini_createKey
* Parameters : ini - pointer to ini file database. key - key name
* Returns : Pointer to key.
* Globals Used :
* Globals Modified :
* Description : Adds an entry into the key linked list ready for formating by the addKey commands
* : A heading operation must be called before this function.
********************************************************************************************************************
* Rev | Date | By | Comment
* ----------------------------------------------------------------------------------------------------------------
********************************************************************************************************************/
struct key_tag *__ini_createKey (ini_t *ini, char *key)
{
struct section_tag *section;
struct key_tag *pNew;
long pos;
if (!*key)
return NULL;
section = ini->selected;
pNew = __ini_locateKey (ini, key);
if (pNew)
{ // Reset details of existing key
free (pNew->key);
pNew->key = key;
pos = 0;
}
else
{ // Create a new key and add at end;
pNew = (struct key_tag *) malloc (sizeof (struct key_tag));
if (!pNew)
return NULL;
memset (pNew, 0, sizeof (struct key_tag));
pNew->key = key;
if (!section->first)
section->first = pNew;
else
section->last->pNext = pNew;
pNew->pPrev = section->last;
section->last = pNew;
section->selected = pNew;
#ifdef INI_USE_HASH_TABLE
{ // Rev 1.3 - Added
struct key_tag *pOld;
unsigned long crc32;
unsigned char accel;
crc32 = __ini_createCrc32 (key, (ini->flags & INI_CASE) != 0);
pNew->crc = crc32;
// Rev 1.3 - Add accelerator list
accel = (unsigned char) crc32 & 0x0FF;
pNew->pPrev_Acc = NULL;
pOld = section->keys[accel];
section->keys[accel] = pNew;
if (pOld) pOld->pPrev_Acc = pNew;
pNew->pNext_Acc = pOld;
}
#endif
}
section->selected = pNew;
return pNew;
}
/********************************************************************************************************************
* Function : __ini_deleteKey
* Parameters : ini - pointer to ini file database. key - key name
* Returns :
* Globals Used :
* Globals Modified :
* Description : Removes a key from the database only.
* : This change does not occur in the file until ini_close is called.
* : A heading operation must be called before this function.
********************************************************************************************************************
* Rev | Date | By | Comment
* ----------------------------------------------------------------------------------------------------------------
********************************************************************************************************************/
void __ini_deleteKey (ini_t *ini)
{
struct key_tag *current_k;
struct section_tag *section = ini->selected;
current_k = section->selected;
if (current_k)
{
// Tidy up all users of this key
section->selected = NULL;
if (section->last == current_k)
section->last = current_k->pPrev;
// Check to see if all keys were removed
if (!current_k->pPrev)
section->first = current_k->pNext;
else
current_k->pPrev->pNext = current_k->pNext;
if (current_k->pNext)
current_k->pNext->pPrev = current_k->pPrev;
#ifdef INI_USE_HASH_TABLE
// Rev 1.3 - Take member out of accelerator list
if (!current_k->pPrev_Acc)
section->keys[(unsigned char) current_k->crc & 0x0FF] = current_k->pNext_Acc;
else
current_k->pPrev_Acc->pNext_Acc = current_k->pNext_Acc;
if (current_k->pNext_Acc)
current_k->pNext_Acc->pPrev_Acc = current_k->pPrev_Acc;
#endif // INI_USE_HASH_TABLE
// Delete Key
free (current_k->key);
free (current_k);
}
}
/********************************************************************************************************************
* Function : __ini_locateKey
* Parameters : ini - pointer to ini file database. key - key name
* Returns : Pointer to key.
* Globals Used :
* Globals Modified :
* Description : Locates a key entry in the database.
* : A heading operation must be called before this function.
********************************************************************************************************************
* Rev | Date | By | Comment
* ----------------------------------------------------------------------------------------------------------------
********************************************************************************************************************/
struct key_tag *__ini_locateKey (ini_t *ini, const char *key)
{
struct key_tag *current_k;
struct section_tag *section;
section = ini->selected;
#ifdef INI_USE_HASH_TABLE
{ // Rev 1.3 - Added
unsigned long crc32;
crc32 = __ini_createCrc32 (key, (ini->flags & INI_CASE) != 0);
// Search for key
for (current_k = section->keys[(unsigned char) crc32 & 0x0FF]; current_k; current_k = current_k->pNext_Acc)
{
if (current_k->crc == crc32)
{
if (ini->flags & INI_CASE)
{
if (!strcmp (current_k->key, key))
break;
}
else if (!strcasecmp (current_k->key, key))
break;
}
}
}
#else
{ // Search for key
for (current_k = section->first; current_k; current_k = current_k->pNext)
{
if (ini->flags & INI_CASE)
{
if (!strcmp (current_k->key, key))
break;
}
else if (!strcasecmp (current_k->key, key))
break;
}
}
#endif // INI_USE_HASH_TABLE
section->selected = current_k;
return current_k;
}
/********************************************************************************************************************
* Function : (public) ini_deleteKey
* Parameters : ini - pointer to ini file database. heading - heading name. key - key name.
* Returns : -1 for Error and 0 on success
* Globals Used :
* Globals Modified :
* Description : Equivalent Microsoft write string API call where data set to NULL
********************************************************************************************************************/
int INI_LINKAGE ini_deleteKey (ini_fd_t fd)
{
ini_t *ini = (ini_t *) fd;
if (!ini->selected || !ini->selected->selected)
return -1;
// Can't delete a temporary key
if (ini->selected->selected == &(ini->tmpKey))
return -1;
// Is file read only?
if (ini->mode == INI_READ)
return -1;
__ini_deleteKey (ini);
ini->flags |= INI_MODIFIED;
return 0;
}
/********************************************************************************************************************
* Function : (public) ini_locateKey
* Parameters : fd - pointer to ini file descriptor
* Returns : -1 for Error and 0 on success
* Globals Used :
* Globals Modified :
* Description :
********************************************************************************************************************/
int INI_LINKAGE ini_locateKey (ini_fd_t fd, const char *key)
{
ini_t *ini = (ini_t *) fd;
struct key_tag *_key = NULL;
if (!key)
return -1;
if (!ini->selected)
return -1;
// Can't search for a key in a temporary heading
if (ini->selected != &(ini->tmpSection))
_key = __ini_locateKey (ini, key);
#ifdef INI_ADD_LIST_SUPPORT
// Rev 1.1 - Remove buffered list
if (ini->list)
{
free (ini->list);
ini->list = NULL;
}
#endif // INI_ADD_LIST_SUPPORT
if (_key)
return 0;
// Ok no key was found, but maybe the user is wanting to create a
// new one so create it temporarily and see what actually happens later
{ // Remove all key
_key = &(ini->tmpKey);
if (_key->key)
free (_key->key);
// Add new key
_key->key = strdup (key);
if (!_key)
return -1;
ini->selected->selected = _key;
}
return -1;
}
/********************************************************************************************************************
* Function : (public) ini_currentKey
* Parameters : fd - pointer to ini file descriptor
* Returns : NULL for Error and on success pointer to key
* Globals Used :
* Globals Modified :
* Description :
********************************************************************************************************************/
const char * INI_LINKAGE ini_currentKey (ini_fd_t fd)
{
ini_t *ini = (ini_t *) fd;
struct section_tag *section;
struct key_tag *key;
if (!ini)
return NULL;
section = ini->selected;
if (!section)
return NULL;
key = section->selected;
if (!key)
return NULL;
return key->key;
}

219
arm9/source/libini.h Normal file
View File

@@ -0,0 +1,219 @@
/***************************************************************************
libini.h - Header file of functions to
manipulate an ini file.
-------------------
begin : Fri Apr 21 2000
copyright : (C) 2000 by Simon White
email : s_a_white@email.com
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef _libini_h_
#define _libini_h_
#ifdef __cplusplus
extern "C" {
#endif
#include <string.h>
#define INI_ADD_EXTRAS
#define INI_ADD_LIST_SUPPORT
#ifdef SWIG
%ignore ini_readString;
%include typemaps.i
%apply int *INOUT { int *value };
%apply long *INOUT { long *value };
%apply double *INOUT { double *value };
%rename (ini_readString) ini_readFileToBuffer;
#define INI_EXTERN
#define INI_STATIC
#endif /* SWIG */
#ifdef _WINDOWS
# define INI_LINKAGE __stdcall
#else
# define INI_LINKAGE
#endif
/* DLL building support on win32 hosts */
#ifndef INI_EXTERN
# ifdef DLL_EXPORT /* defined by libtool (if required) */
# define INI_EXTERN __declspec(dllexport)
# endif
# ifdef LIBINI_DLL_IMPORT /* define if linking with this dll */
# define INI_EXTERN extern __declspec(dllimport)
# endif
# ifndef INI_EXTERN /* static linking or !_WIN32 */
# define INI_EXTERN extern
# endif
#endif
#ifndef INI_ADD_EXTRAS
#undef INI_ADD_LIST_SUPPORT
#endif
/* Compatibility with future C++ code */
#ifndef ini_fd_t
#define ini_fd_t ini_fd_t
typedef void* ini_fd_t;
#endif
/* Rev 1.2 Added new fuction */
INI_EXTERN ini_fd_t INI_LINKAGE ini_open (const char *name, const char *mode,
const char *comment);
INI_EXTERN int INI_LINKAGE ini_close (ini_fd_t fd);
INI_EXTERN int INI_LINKAGE ini_flush (ini_fd_t fd);
INI_EXTERN int INI_LINKAGE ini_delete (ini_fd_t fd);
/* Rev 1.2 Added these functions to make life a bit easier, can still be implemented
* through ini_writeString though. */
INI_EXTERN int INI_LINKAGE ini_locateKey (ini_fd_t fd, const char *key);
INI_EXTERN int INI_LINKAGE ini_locateHeading (ini_fd_t fd, const char *heading);
INI_EXTERN int INI_LINKAGE ini_deleteKey (ini_fd_t fd);
INI_EXTERN int INI_LINKAGE ini_deleteHeading (ini_fd_t fd);
INI_EXTERN const char * INI_LINKAGE ini_currentKey (ini_fd_t fd);
INI_EXTERN const char * INI_LINKAGE ini_currentHeading (ini_fd_t fd);
/* Returns the number of bytes required to be able to read the key as a
* string from the file. (1 should be added to this length to account
* for a NULL character). If delimiters are used, returns the length
* of the next data element in the key to be read */
INI_EXTERN int INI_LINKAGE ini_dataLength (ini_fd_t fd);
/* Default Data Type Operations
* Arrays implemented to help with reading, for writing you should format the
* complete array as a string and perform an ini_writeString. */
INI_EXTERN int INI_LINKAGE ini_readString (ini_fd_t fd, char *str, size_t size);
INI_EXTERN int INI_LINKAGE ini_writeString (ini_fd_t fd, const char *str);
INI_EXTERN int INI_LINKAGE ini_readInt (ini_fd_t fd, int *value);
#ifdef INI_ADD_EXTRAS
/* Read Operations */
INI_EXTERN int INI_LINKAGE ini_readLong (ini_fd_t fd, long *value);
INI_EXTERN int INI_LINKAGE ini_readDouble (ini_fd_t fd, double *value);
INI_EXTERN int INI_LINKAGE ini_readBool (ini_fd_t fd, int *value);
/* Write Operations */
INI_EXTERN int INI_LINKAGE ini_writeInt (ini_fd_t fd, int value);
INI_EXTERN int INI_LINKAGE ini_writeLong (ini_fd_t fd, long value);
INI_EXTERN int INI_LINKAGE ini_writeDouble (ini_fd_t fd, double value);
INI_EXTERN int INI_LINKAGE ini_writeBool (ini_fd_t fd, int value);
/* Extra Functions */
INI_EXTERN int INI_LINKAGE ini_append (ini_fd_t fddst, ini_fd_t fdsrc);
#endif /* INI_ADD_EXTRAS */
#ifdef INI_ADD_LIST_SUPPORT
/* Rev 1.1 Added - List Operations (Used for read operations only)
* Be warned, once delimiters are set, every key that is read will be checked for the
* presence of sub strings. This will incure a speed hit and therefore once a line
* has been read and list/array functionality is not required, set delimiters
* back to NULL.
*/
/* Returns the number of elements in an list being seperated by the provided delimiters */
INI_EXTERN int INI_LINKAGE ini_listLength (ini_fd_t fd);
/* Change delimiters, default "" */
INI_EXTERN int INI_LINKAGE ini_listDelims (ini_fd_t fd, const char *delims);
/* Set index to access in a list. When read the index will automatically increment */
INI_EXTERN int INI_LINKAGE ini_listIndex (ini_fd_t fd, unsigned long index);
#endif /* INI_ADD_LIST_SUPPORT */
#ifdef SWIG
%{
#include <stdio.h>
#include <libini.h>
#define INI_STATIC static
typedef struct
{
char *buffer;
size_t size;
} ini_buffer_t;
%}
%inline %{
/*************************************************************
* SWIG helper functions to create C compatible string buffers
*************************************************************/
INI_STATIC ini_buffer_t *ini_createBuffer (unsigned int size)
{
ini_buffer_t *b;
/* Allocate memory to structure */
if (size == ( ((unsigned) -1 << 1) >> 1 ))
return 0; /* Size is too big */
b = malloc (sizeof (ini_buffer_t));
if (!b)
return 0;
/* Allocate memory to buffer */
b->buffer = malloc (sizeof (char) * (size + 1));
if (!b->buffer)
{
free (b);
return 0;
}
b->size = size;
b->buffer[0] = '\0';
/* Returns address to tcl */
return b;
}
INI_STATIC void ini_deleteBuffer (ini_buffer_t *buffer)
{
if (!buffer)
return;
free (buffer->buffer);
free (buffer);
}
INI_STATIC int ini_readFileToBuffer (ini_fd_t fd, ini_buffer_t *buffer)
{
if (!buffer)
return -1;
return ini_readString (fd, buffer->buffer, buffer->size + 1);
}
INI_STATIC char *ini_getBuffer (ini_buffer_t *buffer)
{
if (!buffer)
return "";
return buffer->buffer;
}
INI_STATIC int ini_setBuffer (ini_buffer_t *buffer, const char *str)
{
size_t len;
if (!buffer)
return -1;
len = strlen (str);
if (len > buffer->size)
len = buffer->size;
memcpy (buffer->buffer, str, len);
buffer->buffer[len] = '\0';
return len;
}
%}
#endif /* SWIG */
#ifdef __cplusplus
}
#endif
#endif /* _libini_h_ */

332
arm9/source/list.i Normal file
View File

@@ -0,0 +1,332 @@
/***************************************************************************
list.i - Adds list support to ini files
-------------------
begin : Fri Apr 21 2000
copyright : (C) 2000 by Simon White
email : s_a_white@email.com
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include <stdlib.h>
#include <string.h>
#include "inilist.h"
#ifdef INI_ADD_LIST_SUPPORT
/********************************************************************************************************************
* Function : ini_listEval
* Parameters : ini - pointer to ini file database.
* Returns : -1 for Error or the numbers of list items found
* Globals Used :
* Globals Modified :
* Description : Uses the currently specified delimiters to calculate the number of eliments in a list
********************************************************************************************************************
* Rev | Date | By | Comment
* ----------------------------------------------------------------------------------------------------------------
********************************************************************************************************************/
int __ini_listEval (ini_t *ini)
{
int length, count, i, ret;
int ldelim;
char ch;
// Remove old list
if (ini->list)
{
free (ini->list);
ini->list = NULL;
}
// Re-evaluate with new settings
length = ini->selected->selected->length;
if (length < 0)
return -1;
if (!length)
{
ini->listIndex = 0;
ini->listLength = 0;
if (ini->selected->selected == &ini->tmpKey)
return -1; // Can't read tmpKey
return 0;
}
// See if there are any chars which can be used to split the string into sub ones
if (!ini->listDelims)
return -1;
ldelim = (int) strlen (ini->listDelims);
// Buffer string for faster access
ini->list = (char *) malloc (length + 1);
if (!ini->list)
return -1;
{ // Backup up delims to avoid causing problems with readString
char *delims = ini->listDelims;
ini->listDelims = NULL;
ret = ini_readString ((ini_fd_t) ini, ini->list, length + 1);
ini->listDelims = delims;
if (ret < 0)
return -1;
}
// Process buffer string to find number of sub strings
{
char lastch = '\0';
count = 1;
while (length)
{
length--;
ch = ini->list[length];
for (i = 0; i < ldelim; i++)
{
if ((char) ch == ini->listDelims[i])
{ // Prevent lots of NULL strings on multiple
// whitespace
if (lastch == '\0')
{
if (isspace (ch))
{
ch = '\0';
break;
}
}
// Seperate strings
ini->list[length] = (ch = '\0');
count++;
break;
}
}
lastch = ch;
}
}
ini->listLength = count;
ini->listIndexPtr = ini->list;
ini->listIndex = 0;
return count;
}
/********************************************************************************************************************
* Function : __ini_listRead
* Parameters : ini - pointer to ini file database.
* Returns : NULL for error, string point otherwise
* Globals Used :
* Globals Modified :
* Description : Reads the indexed parameter from the list and auto
* : increments
********************************************************************************************************************
* Rev | Date | By | Comment
* ----------------------------------------------------------------------------------------------------------------
********************************************************************************************************************/
char *__ini_listRead (ini_t *ini)
{
char *p;
// we must read an element from the list
// Rev 1.2 Changed order of these two ifs as test was performed
// sometimes before anything was read
if (!ini->list)
{
if (__ini_listEval (ini) < 0)
return NULL;
// Handle an empty list
if (!ini->listLength)
return "";
}
// Check to see if we are trying to get a value beyond the end of the list
if (ini->listIndex >= ini->listLength)
return NULL;
p = ini->listIndexPtr;
// Auto increment pointers to next index
ini->listIndexPtr += (strlen (ini->listIndexPtr) + 1);
ini->listIndex++;
return p;
}
/********************************************************************************************************************
* Function : ini_listLength
* Parameters : ini - pointer to ini file database. heading - heading name. key - key name.
* Returns : -1 for Error or the numbers of list items found
* Globals Used :
* Globals Modified :
* Description : Uses the currently specified delimiters to calculate the number of eliments in a list
********************************************************************************************************************
* Rev | Date | By | Comment
* ----------------------------------------------------------------------------------------------------------------
********************************************************************************************************************/
int INI_LINKAGE ini_listLength (ini_fd_t fd)
{
ini_t *ini = (ini_t *) fd;
// Check to make sure a section/key has
// been asked for by the user
if (!ini->selected)
return -1;
if (!ini->selected->selected)
return -1;
// Check to see if we have moved to a new key
if (!ini->list)
return __ini_listEval (ini);
return ini->listLength;
}
/********************************************************************************************************************
* Function : __ini_listDelims
* Parameters : ini - pointer to ini file database. delims - string of delimitor chars
* Returns : -1 for Error or 0 for success
* Globals Used :
* Globals Modified :
* Description : Sets the delimiters used for list accessing, (default delim is NULL)
********************************************************************************************************************
* Rev | Date | By | Comment
* ----------------------------------------------------------------------------------------------------------------
********************************************************************************************************************/
int __ini_listDelims (struct ini_t *ini, const char *delims)
{
if (ini->listDelims)
free (ini->listDelims);
ini->listDelims = NULL;
// Make sure we have something to copy
if (delims)
{
if (*delims)
{ // Store delims for later use
ini->listDelims = strdup (delims);
if (!ini->listDelims)
return -1;
}
}
// List will need recalculating at some point
if (ini->list)
{
free (ini->list);
ini->list = NULL;
}
return 0;
}
/********************************************************************************************************************
* Function : ini_listDelims
* Parameters : fd - pointer to ini file database. delims - string of delimitor chars
* Returns : -1 for Error or 0 for success
* Globals Used :
* Globals Modified :
* Description : Sets the delimiters used for list accessing, (default delim is NULL)
********************************************************************************************************************
* Rev | Date | By | Comment
* ----------------------------------------------------------------------------------------------------------------
********************************************************************************************************************/
int INI_LINKAGE ini_listDelims (ini_fd_t fd, const char *delims)
{
return __ini_listDelims ((ini_t *) fd, delims);
}
/********************************************************************************************************************
* Function : ini_listIndex
* Parameters : ini - pointer to ini file database. delims - string of delimitor chars
* Returns :
* Globals Used :
* Globals Modified :
* Description : Sets the index that the next call to any of the read function will obtain (default 0)
********************************************************************************************************************
* Rev | Date | By | Comment
* ----------------------------------------------------------------------------------------------------------------
********************************************************************************************************************/
int INI_LINKAGE ini_listIndex (ini_fd_t fd, unsigned long index)
{
ini_t *ini = (ini_t *) fd;
unsigned int count;
char *p;
// Check to make sure a section/key has
// been asked for by the user
if (!ini->selected)
return -1;
if (!ini->selected->selected)
return -1;
// Pull in new list
if (!ini->list)
{
if (__ini_listEval (ini) < 0)
return -1;
}
// Now scroll through to required index
if (!ini->listLength)
return -1;
if (index == ini->listIndex)
return 0;
if (index > ini->listIndex)
{ // Continue search from the from current position
count = ini->listIndex;
p = ini->listIndexPtr;
}
else
{ // Reset list and search from beginning
count = 0;
p = ini->list;
}
while (count != index)
{
count++;
if (count >= ini->listLength)
return -1;
// Jump to next sub string
p += (strlen (p) + 1);
}
ini->listIndex = count;
ini->listIndexPtr = p;
return 0;
}
/********************************************************************************************************************
* Function : __ini_listIndexLength
* Parameters : ini - pointer to ini file database
* Returns :
* Globals Used :
* Globals Modified :
* Description : Returns the length the indexed sub string
********************************************************************************************************************
* Rev | Date | By | Comment
* ----------------------------------------------------------------------------------------------------------------
********************************************************************************************************************/
int __ini_listIndexLength (ini_t *ini)
{
if (!ini->list)
{ // No list yet. So try to get one
if (__ini_listEval (ini) < 0)
return -1;
if (!ini->listLength)
return 0;
}
// Now return length
return strlen (ini->listIndexPtr);
}
#endif // INI_ADD_LIST_SUPPORT

View File

@@ -42,13 +42,22 @@
#include "hardware.h"
#include "fileselect.h"
#include "libini.h"
uint32 ezflash = 0;
uint32 dstype = 0;
bool gba = 0;
uint32 mode = 0;
bool slot2 = false;
char ftp_ip[16] = "ftp_ip";
char ftp_user[64] = "ftp_user";
char ftp_pass[64] = "ftp_pass";
int ftp_port = 0;
char bootdir[256] = "/";
// ============================================================================
@@ -59,9 +68,45 @@ void mode_dsi()
while (1);
}
void mode_slot2()
{
// use slot2 DLDI device to store data
displayPrintState("");
displayPrintUpper();
displayPrintLower();
displayMessage("This mode is DISABLED.\nPlease remove Slot-2 module\nand restart this tool.");
while(1);
touchPosition touchXY;
while(1) {
swiWaitForVBlank();
touchRead(&touchXY);
// backup
if ((touchXY.py > 8*0) && (touchXY.py < 8*8)) {
//displayPrintUpper();
//hwBackupGBA();
}
// restore
if ((touchXY.py > 8*8) && (touchXY.py < 8*16)) {
//displayPrintUpper();
//hwRestoreGBA();
}
// erase
if ((touchXY.py > 8*16) && (touchXY.py < 8*24)) {
//displayPrintUpper();
//hwEraseGBA();
}
}
}
void mode_3in1()
{
displayPrintUpper();
displayPrintLower();
dsCardData data2;
ReadSram(0x0a000000, (u8*)&data2, sizeof(data2));
@@ -83,11 +128,6 @@ void mode_3in1()
hwRestore3in1_b(size);
}
// use 3in1 to buffer data
displayPrintState("3in1 mode");
displayPrintUpper();
displayPrintLower();
touchPosition touchXY;
while(1) {
swiWaitForVBlank();
@@ -117,7 +157,44 @@ void mode_3in1()
void mode_gba()
{
// use 3in1 to buffer data
displayPrintState("gba mode");
displayPrintState("");
displayPrintUpper();
displayPrintLower();
displayMessage("This mode is DISABLED.\nPlease remove Slot-2 module\nand restart this tool.");
while(1);
touchPosition touchXY;
while(1) {
swiWaitForVBlank();
touchRead(&touchXY);
// backup
if ((touchXY.py > 8*0) && (touchXY.py < 8*8)) {
//displayPrintUpper();
//hwBackupGBA();
}
// restore
if ((touchXY.py > 8*8) && (touchXY.py < 8*16)) {
//displayPrintUpper();
//hwRestoreGBA();
}
// erase
if ((touchXY.py > 8*16) && (touchXY.py < 8*24)) {
//displayPrintUpper();
//hwEraseGBA();
}
}
}
void mode_wifi()
{
displayPrintUpper();
// use 3in1 to buffer data
displayPrintState("");
displayPrintUpper();
displayPrintLower();
@@ -128,33 +205,24 @@ void mode_gba()
// backup
if ((touchXY.py > 8*0) && (touchXY.py < 8*8)) {
displayPrintUpper();
hwBackupGBA();
//hwBackup3in1();
hwBackupFTP();
}
// restore
if ((touchXY.py > 8*8) && (touchXY.py < 8*16)) {
displayPrintUpper();
hwRestoreGBA();
hwRestoreFTP();
}
// erase
if ((touchXY.py > 8*16) && (touchXY.py < 8*24)) {
swap_cart();
displayPrintUpper();
hwEraseGBA();
hwErase();
}
}
}
void mode_wifi()
{
// read/write to ftp server, does nothing at the moment
displayPrintState("FTP mode - unsupported!");
while (1);
}
int main(void)
int main(int argc, char* argv[])
{
sysSetBusOwners(true, true);
@@ -168,20 +236,73 @@ int main(void)
while (1) {};
}
// TODO: load ini file...
// load ini file...
ini_fd_t ini = 0;
char inipath[256];
if (argv[0]) {
char *last = strrchr(argv[0], '/');
int len = (last - argv[0])+1;
strncpy(bootdir, argv[0], len);
sprintf(inipath, "%s/savegame_manager.ini", bootdir);
if (fileExists(inipath))
ini = ini_open(inipath, "r", "");
}
if (!ini) {
sprintf(inipath, "/savegame_manager.ini");
if (fileExists(inipath))
ini = ini_open(inipath, "r", "");
}
if (!ini) {
displayMessage("Unable to open ini file!\nPlease make sure that it is\n1. in this apps folder, or"
"\n2. in the root folder\nIf 1. does not work, use 2.");
while (1);
}
ini_locateHeading(ini, "");
ini_locateKey(ini, "ftp_ip");
ini_readString(ini, ftp_ip, 16);
ini_locateKey(ini, "ftp_user");
ini_readString(ini, ftp_user, 64);
ini_locateKey(ini, "ftp_pass");
ini_readString(ini, ftp_pass, 64);
ini_locateKey(ini, "ftp_port");
ini_readInt(ini, &ftp_port);
ini_close(ini);
//displayPrintState(ftp_user);
//while (1);
// Identify hardware and branch to corresponding mode
displayPrintState("Identifying hardware...");
chip_reset();
OpenNorWrite();
ezflash = ReadNorFlashID();
CloseNorWrite();
dstype = 0; // DS/DSL, no idea how to identify DSi etc.
gba = gbaIsGame();
// Try to identify slot-2 device. Try opening slot-2 root directory
// Nope, does not work: CyclopsDS mounts itself on fat1, fat2, fat3,... (didn't test more)
/*
DIR* pdir = opendir("fat2:/");
struct dirent *pent;
if (pdir) {
pent=readdir(pdir);
if (pent)
//char fullname[256];
displayMessage(pent->d_name);
//slot2=true;
}
*/
if (argv[0][3] == '2')
slot2 = true;
if (dstype == 1) {
// DSi/DSiXL, will branch to SD-card mode when cracked.
mode = 3;
mode_dsi();
} else if (slot2) {
mode = 4;
mode_slot2();
} else if (ezflash != 0) {
// DS with EZFlash found -> branch to 3in1 mode
mode = 2;

530
arm9/source/types.i Normal file
View File

@@ -0,0 +1,530 @@
/***************************************************************************
types.i - Libini supported data types
Use readString for others
-------------------
begin : Fri Apr 21 2000
copyright : (C) 2000 by Simon White
email : s_a_white@email.com
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ini.h"
/********************************************************************************************************************
* Function : __ini_read
* Parameters : ini - pointer to ini file database, size - key length returned here
* Returns : -1 for Error and 0 on success.
* Globals Used :
* Globals Modified :
* Description : Common read functionality
********************************************************************************************************************
* Rev | Date | By | Comment
* ----------------------------------------------------------------------------------------------------------------
********************************************************************************************************************/
static int __ini_read (ini_t *ini, size_t *size)
{
struct key_tag *_key;
if (!ini->selected)
return -1;
// Locate and read keys value
_key = ini->selected->selected;
if (!_key)
return -1;
if (_key->length)
{ // Locate and read back keys data
fseek (ini->ftmp, _key->pos, SEEK_SET);
}
else if (_key == &ini->tmpKey)
return -1; // Can't read tmpKey
*size = _key->length;
return 0;
}
#ifdef INI_ADD_LIST_SUPPORT
/********************************************************************************************************************
* Function : __ini_readList
* Parameters : ini - pointer to ini file database.
* Returns : Pointer to buffer holding data.
* Globals Used :
* Globals Modified :
* Description : Common read functionality from a list
********************************************************************************************************************
* Rev | Date | By | Comment
* ----------------------------------------------------------------------------------------------------------------
********************************************************************************************************************/
static char *__ini_readList (ini_t *ini)
{
if (!ini->selected)
return NULL;
// Locate and read keys value
if (!ini->selected->selected)
return NULL;
return __ini_listRead (ini);
}
#endif // INI_ADD_LIST_SUPPORT
/********************************************************************************************************************
* Function : __ini_write
* Parameters : ini - pointer to ini file database. heading - heading name. key - key name.
* Returns : Pointer to new key.
* Globals Used :
* Globals Modified :
* Description : Make calls to add a new key and appends a description of changes in the backup file
********************************************************************************************************************
* Rev | Date | By | Comment
* ----------------------------------------------------------------------------------------------------------------
********************************************************************************************************************/
static struct key_tag *__ini_write (ini_t *ini)
{
struct section_tag *section;
struct key_tag *key;
// Is file read only?
if (ini->mode == INI_READ)
return NULL;
// Check to make sure a section/key has
// been asked for by the user
section = ini->selected;
if (!section)
return NULL;
key = section->selected;
if (!key)
return NULL;
// Add or replace key
if (!__ini_addHeading (ini, section->heading))
return NULL;
return __ini_addKey (ini, key->key);
}
/********************************************************************************************************************
* Function : ini_readString
* Parameters : ini - pointer to ini file database.
* : value - keys data
* Returns : -1 for error or the number of chars read.
* Globals Used :
* Globals Modified :
* Description : Reads data part from a key and returns it as a string
********************************************************************************************************************
* Rev | Date | By | Comment
* ----------------------------------------------------------------------------------------------------------------
********************************************************************************************************************/
int INI_LINKAGE ini_readString (ini_fd_t fd, char *str, size_t size)
{
ini_t *ini = (ini_t *) fd;
// Check size and reserve space for NULL
if (size-- <= 0)
return -1;
#ifdef INI_ADD_LIST_SUPPORT
if (ini->listDelims)
{
char *data = __ini_readList (ini);
if (!data)
return -1;
strncpy (str, data, size);
}
else
#endif // INI_ADD_LIST_SUPPORT
{ // Locate and read back keys data (Index ignored)
// Check to make sure size is correct
size_t length;
if (__ini_read (ini, &length) < 0)
return -1;
if (size > length)
size = length;
size = fread (str, sizeof(char), size, ini->ftmp);
}
str[size] = '\0';
__ini_strtrim (str);
return (int) size;
}
/********************************************************************************************************************
* Function : ini_writeString
* Parameters : ini - pointer to ini file database.
* : value - keys data
* Returns : -1 for Error and 0 on success
* Globals Used :
* Globals Modified :
* Description : Writes data part to a key.
* : Conforms to Microsoft API call. E.g. use NULLS to remove headings/keys
* : Headings and keys will be created as necessary
********************************************************************************************************************
* Rev | Date | By | Comment
* ----------------------------------------------------------------------------------------------------------------
********************************************************************************************************************/
int INI_LINKAGE ini_writeString (ini_fd_t fd, const char *str)
{
ini_t *ini = (ini_t *) fd;
struct key_tag *_key;
_key = __ini_write (ini);
if (!_key)
return -1;
// Write data to bottom of backup file
_key->length = strlen (str);
fprintf (ini->ftmp, "%s\n", str);
return 0;
}
/********************************************************************************************************************
* Function : ini_readInt
* Parameters : ini - pointer to ini file database.
* : value - keys data
* Returns : -1 for error or the number of values read.
* Globals Used :
* Globals Modified :
* Description : Reads data part from a key and returns it as a int
********************************************************************************************************************
* Rev | Date | By | Comment
* ----------------------------------------------------------------------------------------------------------------
********************************************************************************************************************/
int INI_LINKAGE ini_readInt (ini_fd_t fd, int *value)
{
ini_t *ini = (ini_t *) fd;
int ret = 0;
#ifdef INI_ADD_LIST_SUPPORT
if (ini->listDelims)
{
char *data = __ini_readList (ini);
if (data)
sscanf (data, "%d", value);
}
else
#endif // INI_ADD_LIST_SUPPORT
{
size_t length;
if (__ini_read (ini, &length) >= 0)
{
if (length > 0)
ret = fscanf (ini->ftmp, "%d", value);
}
}
if (ret == 1)
return 0;
return -1;
}
#ifdef INI_ADD_EXTRAS
/********************************************************************************************************************
* Function : ini_readLong
* Parameters : ini - pointer to ini file database.
* : value - keys data
* Returns : -1 for error or the number of values read.
* Globals Used :
* Globals Modified :
* Description : Reads data part from a key and returns it as a long
********************************************************************************************************************
* Rev | Date | By | Comment
* ----------------------------------------------------------------------------------------------------------------
********************************************************************************************************************/
int INI_LINKAGE ini_readLong (ini_fd_t fd, long *value)
{
ini_t *ini = (ini_t *) fd;
int ret = 0;
#ifdef INI_ADD_LIST_SUPPORT
if (ini->listDelims)
{
char *data = __ini_readList (ini);
if (data)
ret = sscanf (data, "%ld", value);
}
else
#endif // INI_ADD_LIST_SUPPORT
{
size_t length;
if (__ini_read (ini, &length) >= 0)
{
if (length > 0)
ret = fscanf (ini->ftmp, "%ld", value);
}
}
if (ret == 1)
return 0;
return -1;
}
/********************************************************************************************************************
* Function : ini_readDouble
* Parameters : ini - pointer to ini file database.
* : value - keys data
* Returns : -1 for error or the number of values read.
* Globals Used :
* Globals Modified :
* Description : Reads data part from a key and returns it as a double (real)
********************************************************************************************************************
* Rev | Date | By | Comment
* ----------------------------------------------------------------------------------------------------------------
********************************************************************************************************************/
int INI_LINKAGE ini_readDouble (ini_fd_t fd, double *value)
{
ini_t *ini = (ini_t *) fd;
int ret = 0;
#ifdef INI_ADD_LIST_SUPPORT
if (ini->listDelims)
{
char *data = __ini_readList (ini);
if (data)
ret = sscanf (data, "%lf", value);
}
else
#endif // INI_ADD_LIST_SUPPORT
{
size_t length;
if (__ini_read (ini, &length) >= 0)
{
if (length > 0)
ret = fscanf (ini->ftmp, "%lf", value);
}
}
if (ret == 1)
return 0;
return -1;
}
/********************************************************************************************************************
* Function : ini_readBool
* Parameters : ini - pointer to ini file database.
* : value - keys data
* Returns : -1 for error or the number of values read.
* Globals Used :
* Globals Modified :
* Description : Reads data part from a key and returns it as a int. Supported bool strings are 0, 1, true
* : false.
********************************************************************************************************************
* Rev | Date | By | Comment
* ----------------------------------------------------------------------------------------------------------------
********************************************************************************************************************/
int INI_LINKAGE ini_readBool (ini_fd_t fd, int *value)
{
ini_t *ini = (ini_t *) fd;
char buffer[6] = "";
#ifdef INI_ADD_LIST_SUPPORT
if (ini->listDelims)
{
char *data = __ini_readList (ini);
if (!data)
return -1;
sscanf (data, "%5s", buffer);
}
else
#endif // INI_ADD_LIST_SUPPORT
{
size_t length;
if (__ini_read (ini, &length) < 0)
return -1;
if (length > 0)
fscanf (ini->ftmp, "%5s", buffer);
}
{ // Convert string to lower case
char *p = buffer;
while (*p != '\0')
{
*p = (char) tolower (*p);
p++;
}
}
// Decode supported bool types
switch (*buffer)
{
case '0':
case '1':
if (buffer[1] != '\0')
return -1;
*value = *buffer - '0';
break;
default:
if (!strcasecmp (buffer, "true"))
*value = 1;
else if (!strcasecmp (buffer, "false"))
*value = 0;
else if (!strcasecmp (buffer, "on"))
*value = 1;
else if (!strcasecmp (buffer, "off"))
*value = 0;
else if (!strcasecmp (buffer, "yes"))
*value = 1;
else if (!strcasecmp (buffer, "no"))
*value = 0;
else // No match
return -1;
break;
}
return 0;
}
/********************************************************************************************************************
* Function : ini_writeInt
* Parameters : ini - pointer to ini file database.
* : value - keys data
* Returns : -1 for Error and 0 on success
* Globals Used :
* Globals Modified :
* Description : Writes data part to a key.
* : Headings and keys will be created as necessary
********************************************************************************************************************
* Rev | Date | By | Comment
* ----------------------------------------------------------------------------------------------------------------
********************************************************************************************************************/
int INI_LINKAGE ini_writeInt (ini_fd_t fd, int value)
{
ini_t *ini = (ini_t *) fd;
struct key_tag *_key;
long pos;
_key = __ini_write (ini);
if (!_key)
return -1;
// Write data to bottom of backup file
fprintf (ini->ftmp, "%d", value);
pos = ftell (ini->ftmp);
_key->length = (size_t) (pos - _key->pos);
fprintf (ini->ftmp, "\n");
return 0;
}
/********************************************************************************************************************
* Function : ini_writeLong
* Parameters : ini - pointer to ini file database.
* : value - keys data
* Returns : -1 for Error and 0 on success
* Globals Used :
* Globals Modified :
* Description : Writes data part to a key.
* : Headings and keys will be created as necessary
********************************************************************************************************************
* Rev | Date | By | Comment
* ----------------------------------------------------------------------------------------------------------------
********************************************************************************************************************/
int INI_LINKAGE ini_writeLong (ini_fd_t fd, long value)
{
ini_t *ini = (ini_t *) fd;
struct key_tag *_key;
long pos;
_key = __ini_write (ini);
if (!_key)
return -1;
// Write data to bottom of backup file
fprintf (ini->ftmp, "%ld", value);
pos = ftell (ini->ftmp);
_key->length = (size_t) (pos - _key->pos);
fprintf (ini->ftmp, "\n");
return 0;
}
/********************************************************************************************************************
* Function : ini_writeDouble
* Parameters : ini - pointer to ini file database.
* : value - keys data
* Returns : -1 for Error and 0 on success
* Globals Used :
* Globals Modified :
* Description : Writes data part to a key.
* : Headings and keys will be created as necessary
********************************************************************************************************************
* Rev | Date | By | Comment
* ----------------------------------------------------------------------------------------------------------------
********************************************************************************************************************/
int INI_LINKAGE ini_writeDouble (ini_fd_t fd, double value)
{
ini_t *ini = (ini_t *) fd;
struct key_tag *_key;
long pos;
_key = __ini_write (ini);
if (!_key)
return -1;
// Write data to bottom of backup file
fprintf (ini->ftmp, "%f", value);
pos = ftell (ini->ftmp);
_key->length = (size_t) (pos - _key->pos);
fprintf (ini->ftmp, "\n");
return 0;
}
/********************************************************************************************************************
* Function : ini_writeBool
* Parameters : ini - pointer to ini file database.
* : value - keys data
* Returns : -1 for Error and 0 on success
* Globals Used :
* Globals Modified :
* Description : Writes data part to a key.
* : Headings and keys will be created as necessary
********************************************************************************************************************
* Rev | Date | By | Comment
* ----------------------------------------------------------------------------------------------------------------
********************************************************************************************************************/
int INI_LINKAGE ini_writeBool (ini_fd_t fd, int value)
{
ini_t *ini = (ini_t *) fd;
struct key_tag *_key;
long pos;
// Check if value is legal
if ((value < 0) || (value > 1))
return -1;
_key = __ini_write (ini);
if (!_key)
return -1;
// Write data to bottom of backup file
if (value)
fprintf (ini->ftmp, "true");
else
fprintf (ini->ftmp, "false");
pos = ftell (ini->ftmp);
_key->length = (size_t) (pos - _key->pos);
fprintf (ini->ftmp, "\n");
return 0;
}
#endif // INI_ADD_EXTRAS

View File

@@ -1 +1 @@
<Project name="Savegame Manager"><MagicFolder excludeFolders="CVS;.svn" filter="*" name="arm9" path="arm9\"><MagicFolder excludeFolders="CVS;.svn" filter="*" name="source" path="source\"><File path="auxspi.cpp"></File><File path="auxspi.h"></File><File path="auxspi_core.cpp"></File><File path="display.cpp"></File><File path="display.h"></File><File path="dsCard.cpp"></File><File path="dsCard.h"></File><File path="fileselect.cpp"></File><File path="fileselect.h"></File><File path="gba.cpp"></File><File path="gba.h"></File><File path="hardware.cpp"></File><File path="hardware.h"></File><File path="main.cpp"></File></MagicFolder><File path="Makefile"></File></MagicFolder><File path="Makefile"></File></Project>
<Project name="Savegame Manager"><MagicFolder excludeFolders="CVS;.svn" filter="*" name="arm9" path="arm9\"><MagicFolder excludeFolders="CVS;.svn" filter="*" name="build" path="build\"><File path=".map"></File><File path="auxspi.d"></File><File path="auxspi.o"></File><File path="auxspi_core.d"></File><File path="auxspi_core.o"></File><File path="display.d"></File><File path="display.o"></File><File path="dsCard.d"></File><File path="dsCard.o"></File><File path="fileselect.d"></File><File path="fileselect.o"></File><File path="ftplib.d"></File><File path="ftplib.o"></File><File path="gba.d"></File><File path="gba.o"></File><File path="hardware.d"></File><File path="hardware.o"></File><File path="ini.d"></File><File path="ini.o"></File><File path="main.d"></File><File path="main.o"></File></MagicFolder><MagicFolder excludeFolders="CVS;.svn" filter="*" name="source" path="source\"><File path="auxspi.cpp"></File><File path="auxspi.h"></File><File path="auxspi_core.cpp"></File><File path="display.cpp"></File><File path="display.h"></File><File path="dsCard.cpp"></File><File path="dsCard.h"></File><File path="fileselect.cpp"></File><File path="fileselect.h"></File><File path="ftplib.c"></File><File path="ftplib.h"></File><File path="gba.cpp"></File><File path="gba.h"></File><File path="hardware.cpp"></File><File path="hardware.h"></File><File path="headings.i"></File><File path="ini.cpp"></File><File path="ini.h"></File><File path="iniconfig.h"></File><File path="iniheadings.h"></File><File path="inikeys.h"></File><File path="inilist.h"></File><File path="keys.i"></File><File path="libini.h"></File><File path="list.i"></File><File path="main.cpp"></File><File path="types.i"></File></MagicFolder><File path="Makefile"></File><File path="savegame_manager.arm9.elf"></File></MagicFolder><File path="Makefile"></File></Project>

View File

@@ -1 +1 @@
<pd><ViewState><e p="Savegame Manager" x="true"></e><e p="Savegame Manager\arm9" x="true"></e><e p="Savegame Manager\arm9\source" x="true"></e></ViewState></pd>
<pd><ViewState><e p="Savegame Manager" x="true"></e><e p="Savegame Manager\arm9" x="true"></e><e p="Savegame Manager\arm9\build" x="false"></e><e p="Savegame Manager\arm9\source" x="true"></e></ViewState></pd>