This commit is contained in:
Mark Klara 2020-03-09 22:02:05 +01:00 committed by GitHub
commit 9c1ac9588d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
45 changed files with 10621 additions and 7728 deletions

10
.gitignore vendored Normal file
View File

@ -0,0 +1,10 @@
arm7/build
arm7/savegame_manager.elf
arm9/build
arm9/savegame_manager.elf
savegame_manager.nds
*.exe
*.dldi
*.elf
*.nds
*.DS_Store

View File

@ -11,7 +11,6 @@ Main program (ARM9):
- gba.h, gba.cpp: This implements the eeprom functions for GBA games, however tailored to work on a DS phat/lite.
- hardware.h, hardware.cpp: This is a happy collection of functions working with hardware. No low-level functions (they are found in different files), but instead working methods to access the save and write it back. Basically, this is what the event handlers in main.cpp do call. Hardware detection has also been moved here.
- fileselect.h, fileselect.cpp: This is a file select function written from scratch, that works both with libfat filesystems and a remote FTP server. It is somewhat tailored to the program (but could probably be recycled for other projects).
- dsi.h, dsi.cpp: A collection of functions exclusive to the DSi. Right now, it does not do anything noteworthy.
- display.h, display.cpp: A collection of functions that are used to write most text used by the program, in a somewhat intependent version. This is where to start if you want to change the GUI.
- strings.h, strings.cpp: The new translation interface. If you use these functions, you are able to swap out strings by providing an external ini file.
- globals.h, globals.cpp: All global variables are defined and implemented here.

View File

@ -7,7 +7,7 @@ endif
include $(DEVKITARM)/ds_rules
export TARGET := savegame_manager
export TARGET := NDSEventTool
export TOPDIR := $(CURDIR)

75
README.md Normal file
View File

@ -0,0 +1,75 @@
# NDSEventTool - Nintendo DS Mystery Event Distributor
This is based on nds-savegame-manager, a NDS homebrew tool by Pokedoc to rip and restore saves from DS and GBA games.
This modification works with Pokémon GBA games and allows to inject official Nintendo Events to the savegames in the cartridge.
Please, consider making a backup with the standard homebrew by Pokedoc (https://code.google.com/p/savegame-manager/).
The code is published under the GNU GPL v2.
Below is a copy of the project description at https://code.google.com/p/savegame-manager/
## Build Instructions
### Windows
#### Install Dependencies
- Install [cygwin](https://cygwin.com/install.html) for Windows. Make sure to also install the `make` command,
which is not part of the minimal `cygwin` install.
- Install [devkitPro](https://devkitpro.org/wiki/Getting_Started).
#### Build
Open a `command prompt` to this directory and run the `make` command.
To delete all build products, run `make clean`.
### Mac
#### Install Dependencies
- Install [homebrew](https://brew.sh/).
- Install `xz`:
```
brew install xz
```
- Install [pacman](https://github.com/devkitPro/pacman/releases/latest) devkitPro utilities for Mac.
- Run the following command to install the NDS (Nintendo DS) tools
```
sudo /opt/devkitpro/pacman/bin/pacman -S nds-dev
```
When prompted to install specific options, just press `enter` to default to "all".
#### Configure Environment Variables
Open up `~/.bash_profile`.
Add the following lines:
```
export DEVKITPRO=/opt/devkitpro
export DEVKITARM=${DEVKITPRO}/devkitARM
```
Lastly, run the following command to reload the file:
```
source ~/.bash_profile
```
#### Build
Open `terminal` to this directory and run the `make` command.
To delete all build products, run `make clean`.

View File

@ -1,35 +1,35 @@
/*---------------------------------------------------------------------------------
derived from the default ARM7 core
derived from the default ARM7 core
Copyright (C) 2005 - 2010
Michael Noland (joat)
Jason Rogers (dovoto)
Dave Murphy (WinterMute)
Copyright (C) 2005 - 2010
Michael Noland (joat)
Jason Rogers (dovoto)
Dave Murphy (WinterMute)
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
3. This notice may not be removed or altered from any source
distribution.
---------------------------------------------------------------------------------*/
#include <nds.h>
#include <dswifi7.h>
#include <maxmod7.h>
#include <nds.h>
#include <nds/bios.h>
void disableIRQ();
@ -37,57 +37,56 @@ void enableIRQ();
//---------------------------------------------------------------------------------
void VblankHandler(void) {
//---------------------------------------------------------------------------------
Wifi_Update();
//---------------------------------------------------------------------------------
Wifi_Update();
}
//---------------------------------------------------------------------------------
void VcountHandler() {
//---------------------------------------------------------------------------------
inputGetAndSend();
//---------------------------------------------------------------------------------
inputGetAndSend();
}
volatile bool exitflag = false;
//---------------------------------------------------------------------------------
void powerButtonCB() {
//---------------------------------------------------------------------------------
exitflag = true;
//---------------------------------------------------------------------------------
exitflag = true;
}
//---------------------------------------------------------------------------------
int main() {
//---------------------------------------------------------------------------------
readUserSettings();
//---------------------------------------------------------------------------------
readUserSettings();
irqInit();
fifoInit();
irqInit();
fifoInit();
mmInstall(FIFO_MAXMOD);
// Start the RTC tracking IRQ
initClockIRQ();
mmInstall(FIFO_MAXMOD);
// Start the RTC tracking IRQ
initClockIRQ();
SetYtrigger(80);
SetYtrigger(80);
installWifiFIFO();
installSoundFIFO();
installWifiFIFO();
installSoundFIFO();
installSystemFIFO();
installSystemFIFO();
irqSet(IRQ_VCOUNT, VcountHandler);
irqSet(IRQ_VBLANK, VblankHandler);
irqSet(IRQ_VCOUNT, VcountHandler);
irqSet(IRQ_VBLANK, VblankHandler);
irqEnable( IRQ_VBLANK | IRQ_VCOUNT | IRQ_NETWORK);
irqEnable(IRQ_VBLANK | IRQ_VCOUNT | IRQ_NETWORK);
setPowerButtonCB(powerButtonCB);
setPowerButtonCB(powerButtonCB);
//u32 ime = 0;
// Keep the ARM7 mostly idle
while (!exitflag) {
if ( 0 == (REG_KEYINPUT & (KEY_SELECT | KEY_START | KEY_L | KEY_R))) {
exitflag = true;
}
}
return 0;
// u32 ime = 0;
// Keep the ARM7 mostly idle
while (!exitflag) {
if (0 == (REG_KEYINPUT & (KEY_SELECT | KEY_START | KEY_L | KEY_R))) {
exitflag = true;
}
}
return 0;
}

View File

@ -8,416 +8,380 @@
*
* Copyright (C) Pokedoc (2010)
*/
/*
* 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
/*
* 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.
*
* This program 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 General Public License
*
* This program 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 General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "auxspi.h"
#include "hardware.h"
#include "globals.h"
#include "display.h"
#include <algorithm>
#include "display.h"
#include "globals.h"
#include "hardware.h"
using std::max;
#include "auxspi_core.inc"
// ========================================================
// local functions
uint8 jedec_table(uint32 id)
{
switch (id) {
// 256 kB
case 0x204012:
case 0x621600:
return 0x12;
// 512 kB
case 0x204013:
case 0x621100:
return 0x13;
// 1 MB
case 0x204014:
return 0x14;
// 2 MB (not sure if this exists, but I vaguely remember something...)
case 0x204015:
return 0x15;
// 8 MB (Band Brothers DX)
case 0x202017: // which one? (more work is required to unlock this save chip!)
case 0x204017:
return 0x17;
default: {
for (int i = 0; i < EXTRA_ARRAY_SIZE; i++) {
if (extra_id[i] == id)
return extra_size[i];
}
return 0; // unknown save type!
}
};
uint8 jedec_table(uint32 id) {
switch (id) {
// 256 kB
case 0x204012:
case 0x621600:
return 0x12;
// 512 kB
case 0x204013:
case 0x621100:
return 0x13;
// 1 MB
case 0x204014:
return 0x14;
// 2 MB (not sure if this exists, but I vaguely remember something...)
case 0x204015:
return 0x15;
// 8 MB (Band Brothers DX)
case 0x202017: // which one? (more work is required to unlock this save
// chip!)
case 0x204017:
return 0x17;
default: {
for (int i = 0; i < EXTRA_ARRAY_SIZE; i++) {
if (extra_id[i] == id) return extra_size[i];
}
return 0; // unknown save type!
}
};
}
uint8 type2_size(auxspi_extra extra)
{
static const uint32 offset0 = (8*1024-1); // 8KB
static const uint32 offset1 = (2*8*1024-1); // 16KB
u8 buf1; // +0k data read -> write
u8 buf2; // +8k data read -> read
u8 buf3; // +0k ~data write
u8 buf4; // +8k data new comp buf2
auxspi_read_data(offset0, &buf1, 1, 2, extra);
auxspi_read_data(offset1, &buf2, 1, 2, extra);
buf3=~buf1;
auxspi_write_data(offset0, &buf3, 1, 2, extra);
auxspi_read_data (offset1, &buf4, 1, 2, extra);
auxspi_write_data(offset0, &buf1, 1, 2, extra);
if(buf4!=buf2) // +8k
return 0x0d; // 8KB(64kbit)
else
return 0x10; // 64KB(512kbit)
uint8 type2_size(auxspi_extra extra) {
static const uint32 offset0 = (8 * 1024 - 1); // 8KB
static const uint32 offset1 = (2 * 8 * 1024 - 1); // 16KB
u8 buf1; // +0k data read -> write
u8 buf2; // +8k data read -> read
u8 buf3; // +0k ~data write
u8 buf4; // +8k data new comp buf2
auxspi_read_data(offset0, &buf1, 1, 2, extra);
auxspi_read_data(offset1, &buf2, 1, 2, extra);
buf3 = ~buf1;
auxspi_write_data(offset0, &buf3, 1, 2, extra);
auxspi_read_data(offset1, &buf4, 1, 2, extra);
auxspi_write_data(offset0, &buf1, 1, 2, extra);
if (buf4 != buf2) // +8k
return 0x0d; // 8KB(64kbit)
else
return 0x10; // 64KB(512kbit)
}
// ========================================================
uint8 auxspi_save_type(auxspi_extra extra)
{
uint32 jedec = auxspi_save_jedec_id(extra); // 9f
int8 sr = auxspi_save_status_register(extra); // 05
if ((sr & 0xfd) == 0xF0 && (jedec == 0x00ffffff)) return 1;
if ((sr & 0xfd) == 0x00 && (jedec == 0x00ffffff)) return 2;
if ((sr & 0xfd) == 0x00 && (jedec != 0x00ffffff)) return 3;
return 0;
uint8 auxspi_save_type(auxspi_extra extra) {
uint32 jedec = auxspi_save_jedec_id(extra); // 9f
int8 sr = auxspi_save_status_register(extra); // 05
if ((sr & 0xfd) == 0xF0 && (jedec == 0x00ffffff)) return 1;
if ((sr & 0xfd) == 0x00 && (jedec == 0x00ffffff)) return 2;
if ((sr & 0xfd) == 0x00 && (jedec != 0x00ffffff)) return 3;
return 0;
}
uint32 auxspi_save_size(auxspi_extra extra)
{
return 1 << auxspi_save_size_log_2(extra);
uint32 auxspi_save_size(auxspi_extra extra) {
return 1 << auxspi_save_size_log_2(extra);
}
uint8 auxspi_save_size_log_2(auxspi_extra extra)
{
uint8 type = auxspi_save_type(extra);
switch (type) {
case 1:
return 0x09; // 512 bytes
break;
case 2:
return type2_size(extra);
break;
case 3:
return jedec_table(auxspi_save_jedec_id(extra));
break;
default:
return 0;
}
uint8 auxspi_save_size_log_2(auxspi_extra extra) {
uint8 type = auxspi_save_type(extra);
switch (type) {
case 1:
return 0x09; // 512 bytes
break;
case 2:
return type2_size(extra);
break;
case 3:
return jedec_table(auxspi_save_jedec_id(extra));
break;
default:
return 0;
}
}
uint32 auxspi_save_jedec_id(auxspi_extra extra)
{
uint32 id = 0;
if (extra)
auxspi_disable_extra(extra);
auxspi_open(0);
auxspi_write(0x9f);
id |= auxspi_read() << 16;
id |= auxspi_read() << 8;
id |= auxspi_read();
auxspi_close();
return id;
uint32 auxspi_save_jedec_id(auxspi_extra extra) {
uint32 id = 0;
if (extra) auxspi_disable_extra(extra);
auxspi_open(0);
auxspi_write(0x9f);
id |= auxspi_read() << 16;
id |= auxspi_read() << 8;
id |= auxspi_read();
auxspi_close();
return id;
}
uint8 auxspi_save_status_register(auxspi_extra extra)
{
uint8 sr = 0;
if (extra)
auxspi_disable_extra(extra);
auxspi_open(0);
auxspi_write(0x05);
sr = auxspi_read();
auxspi_close();
return sr;
uint8 auxspi_save_status_register(auxspi_extra extra) {
uint8 sr = 0;
if (extra) auxspi_disable_extra(extra);
auxspi_open(0);
auxspi_write(0x05);
sr = auxspi_read();
auxspi_close();
return sr;
}
void auxspi_read_data(uint32 addr, uint8* buf, uint16 cnt, uint8 type, auxspi_extra extra)
{
if (type == 0)
type = auxspi_save_type(extra);
if (type == 0)
return;
void auxspi_read_data(uint32 addr, uint8* buf, uint16 cnt, uint8 type,
auxspi_extra extra) {
if (type == 0) type = auxspi_save_type(extra);
if (type == 0) return;
if (extra)
auxspi_disable_extra(extra);
auxspi_open(0);
auxspi_write(0x03 | ((type == 1) ? addr>>8<<3 : 0));
if (extra) auxspi_disable_extra(extra);
auxspi_open(0);
auxspi_write(0x03 | ((type == 1) ? addr >> 8 << 3 : 0));
if (type == 3) {
auxspi_write((addr >> 16) & 0xFF);
}
if (type >= 2) {
auxspi_write((addr >> 8) & 0xFF);
if (type == 3) {
auxspi_write((addr >> 16) & 0xFF);
}
if (type >= 2) {
auxspi_write((addr >> 8) & 0xFF);
}
auxspi_write(addr & 0xFF);
while (cnt > 0) {
*buf++ = auxspi_read();
cnt--;
}
auxspi_close();
}
void auxspi_write_data(uint32 addr, uint8* buf, uint16 cnt, uint8 type,
auxspi_extra extra) {
if (type == 0) type = auxspi_save_type();
if (type == 0) return;
uint32 addr_end = addr + cnt;
int i;
int maxblocks = 32;
if (type == 1) maxblocks = 16;
if (type == 2) maxblocks = 32;
if (type == 3) maxblocks = 256;
// we can only write a finite amount of data at once, so we need a separate
// loop
// for multiple passes.
while (addr < addr_end) {
if (extra) auxspi_disable_extra(extra);
auxspi_open(0);
// set WEL (Write Enable Latch)
auxspi_write(0x06);
auxspi_close_lite();
if (extra) auxspi_disable_extra(extra);
auxspi_open(0);
// send initial "write" command
if (type == 1) {
auxspi_write(0x02 | (addr & BIT(8)) >> (8 - 3));
auxspi_write(addr & 0xFF);
} else if (type == 2) {
auxspi_write(0x02);
auxspi_write((addr >> 8) & 0xff);
auxspi_write(addr & 0xFF);
} else if (type == 3) {
auxspi_write(0x02);
auxspi_write((addr >> 16) & 0xff);
auxspi_write((addr >> 8) & 0xff);
auxspi_write(addr & 0xFF);
}
auxspi_write(addr & 0xFF);
while (cnt > 0) {
*buf++ = auxspi_read();
cnt--;
for (i = 0; addr < addr_end && i < maxblocks; i++, addr++) {
auxspi_write(*buf++);
}
auxspi_close();
auxspi_close_lite();
// wait programming to finish
if (extra) auxspi_disable_extra(extra);
auxspi_open(0);
auxspi_write(5);
auxspi_wait_wip();
auxspi_wait_busy();
auxspi_close();
}
}
void auxspi_write_data(uint32 addr, uint8 *buf, uint16 cnt, uint8 type, auxspi_extra extra)
{
if (type == 0)
type = auxspi_save_type();
if (type == 0)
return;
uint32 addr_end = addr + cnt;
int i;
int maxblocks = 32;
if(type == 1) maxblocks = 16;
if(type == 2) maxblocks = 32;
if(type == 3) maxblocks = 256;
// we can only write a finite amount of data at once, so we need a separate loop
// for multiple passes.
while (addr < addr_end) {
if (extra)
auxspi_disable_extra(extra);
auxspi_open(0);
// set WEL (Write Enable Latch)
auxspi_write(0x06);
auxspi_close_lite();
if (extra)
auxspi_disable_extra(extra);
auxspi_open(0);
// send initial "write" command
if(type == 1) {
auxspi_write(0x02 | (addr & BIT(8)) >> (8-3));
auxspi_write(addr & 0xFF);
}
else if(type == 2) {
auxspi_write(0x02);
auxspi_write((addr >> 8) & 0xff);
auxspi_write(addr & 0xFF);
}
else if(type == 3) {
auxspi_write(0x02);
auxspi_write((addr >> 16) & 0xff);
auxspi_write((addr >> 8) & 0xff);
auxspi_write(addr & 0xFF);
}
for (i=0; addr < addr_end && i < maxblocks; i++, addr++) {
auxspi_write(*buf++);
}
auxspi_close_lite();
// wait programming to finish
if (extra)
auxspi_disable_extra(extra);
auxspi_open(0);
auxspi_write(5);
auxspi_wait_wip();
auxspi_wait_busy();
auxspi_close();
}
void auxspi_disable_extra(auxspi_extra extra) {
switch (extra) {
case AUXSPI_INFRARED:
auxspi_disable_infrared_core();
break;
case AUXSPI_BBDX:
// TODO:
auxspi_disable_big_protection();
break;
case AUXSPI_BLUETOOTH:
// TODO
// auxspi_disable_bluetooth();
break;
default:;
}
}
void auxspi_disable_extra(auxspi_extra extra)
{
switch (extra) {
case AUXSPI_INFRARED:
auxspi_disable_infrared_core();
break;
case AUXSPI_BBDX:
// TODO:
auxspi_disable_big_protection();
break;
case AUXSPI_BLUETOOTH:
// TODO
//auxspi_disable_bluetooth();
break;
default:;
}
void auxspi_disable_infrared() { auxspi_disable_infrared_core(); }
void auxspi_disable_big_protection() {
static bool doonce = false;
if (doonce) return;
doonce = true;
sysSetBusOwners(true, true);
auxspi_open(3);
auxspi_write(0xf1);
auxspi_wait_busy();
auxspi_close_lite();
auxspi_open(3);
auxspi_write(0x6);
auxspi_wait_busy();
auxspi_close_lite();
auxspi_open(3);
auxspi_write(0xfa);
auxspi_wait_busy();
auxspi_write(0x1);
auxspi_wait_busy();
auxspi_write(0x31);
auxspi_wait_busy();
auxspi_close();
// --
auxspi_open(3);
auxspi_write(0x14);
auxspi_wait_busy();
auxspi_close_lite();
auxspi_open(3);
auxspi_write(0x6);
auxspi_wait_busy();
auxspi_close_lite();
auxspi_open(3);
auxspi_write(0xf8);
auxspi_wait_busy();
auxspi_write(0x1);
auxspi_wait_busy();
auxspi_write(0x0);
auxspi_wait_busy();
auxspi_close();
// --
auxspi_open(3);
auxspi_write(0xe);
auxspi_wait_busy();
auxspi_close();
}
void auxspi_disable_infrared()
{
auxspi_disable_infrared_core();
}
auxspi_extra auxspi_has_extra() {
sysSetBusOwners(true, true);
void auxspi_disable_big_protection()
{
static bool doonce = false;
if (doonce)
return;
doonce = true;
sysSetBusOwners(true, true);
auxspi_open(3);
auxspi_write(0xf1);
auxspi_wait_busy();
auxspi_close_lite();
// Trying to read the save size in IR mode will fail on non-IR devices.
// If we have success, it is an IR device.
u8 size2 = auxspi_save_size_log_2(AUXSPI_INFRARED);
if (size2 > 0) return AUXSPI_INFRARED;
auxspi_open(3);
auxspi_write(0x6);
auxspi_wait_busy();
auxspi_close_lite();
auxspi_open(3);
auxspi_write(0xfa);
auxspi_wait_busy();
auxspi_write(0x1);
auxspi_wait_busy();
auxspi_write(0x31);
auxspi_wait_busy();
auxspi_close();
// --
auxspi_open(3);
auxspi_write(0x14);
auxspi_wait_busy();
auxspi_close_lite();
auxspi_open(3);
auxspi_write(0x6);
auxspi_wait_busy();
auxspi_close_lite();
auxspi_open(3);
auxspi_write(0xf8);
auxspi_wait_busy();
auxspi_write(0x1);
auxspi_wait_busy();
auxspi_write(0x0);
auxspi_wait_busy();
auxspi_close();
// --
auxspi_open(3);
auxspi_write(0xe);
auxspi_wait_busy();
auxspi_close();
}
auxspi_extra auxspi_has_extra()
{
sysSetBusOwners(true, true);
// Trying to read the save size in IR mode will fail on non-IR devices.
// If we have success, it is an IR device.
u8 size2 = auxspi_save_size_log_2(AUXSPI_INFRARED);
if (size2 > 0)
return AUXSPI_INFRARED;
// It is not an IR game, so maybe it is a regular game.
u8 size1 = auxspi_save_size_log_2();
if (size1 > 0)
return AUXSPI_DEFAULT;
// It is not an IR game, so maybe it is a regular game.
u8 size1 = auxspi_save_size_log_2();
if (size1 > 0) return AUXSPI_DEFAULT;
#if 0
// EXPERIMENTAL: verify that flash cards do not answer with the same signature!
// Look for BBDX (which always returns "ff" on every command)
uint32 jedec = auxspi_save_jedec_id(); // 9f
//int8 sr = auxspi_save_status_register(); // 05
if (jedec == 0x00ffffff)
return AUXSPI_BBDX;
// EXPERIMENTAL: verify that flash cards do not answer with the same signature!
// Look for BBDX (which always returns "ff" on every command)
uint32 jedec = auxspi_save_jedec_id(); // 9f
//int8 sr = auxspi_save_status_register(); // 05
if (jedec == 0x00ffffff)
return AUXSPI_BBDX;
#endif
// TODO: add support for Pokemon Typing DS (as soon as we figure out how)
return AUXSPI_FLASH_CARD;
// TODO: add support for Pokemon Typing DS (as soon as we figure out how)
return AUXSPI_FLASH_CARD;
}
void auxspi_erase(auxspi_extra extra)
{
uint8 type = auxspi_save_type(extra);
if (type == 3) {
uint8 size;
size = 1 << (auxspi_save_size_log_2(extra) - 16);
for (int i = 0; i < size; i++) {
if (extra)
auxspi_disable_extra(extra);
auxspi_open(0);
// set WEL (Write Enable Latch)
auxspi_write(0x06);
auxspi_close_lite();
if (extra)
auxspi_disable_extra(extra);
auxspi_open(0);
auxspi_write(0xd8);
auxspi_write(i);
auxspi_write(0);
auxspi_write(0);
auxspi_close_lite();
// wait for programming to finish
if (extra)
auxspi_disable_extra(extra);
auxspi_open(0);
auxspi_write(5);
auxspi_wait_wip();
auxspi_wait_busy();
auxspi_close();
}
} else {
int8 size = 1 << max(0, (auxspi_save_size_log_2(extra) - 15));
memset(data, 0, 0x8000);
for (int i = 0; i < size; i++) {
auxspi_write_data(i << 15, data, 0x8000, type, extra);
}
}
void auxspi_erase(auxspi_extra extra) {
uint8 type = auxspi_save_type(extra);
if (type == 3) {
uint8 size;
size = 1 << (auxspi_save_size_log_2(extra) - 16);
for (int i = 0; i < size; i++) {
if (extra) auxspi_disable_extra(extra);
auxspi_open(0);
// set WEL (Write Enable Latch)
auxspi_write(0x06);
auxspi_close_lite();
if (extra) auxspi_disable_extra(extra);
auxspi_open(0);
auxspi_write(0xd8);
auxspi_write(i);
auxspi_write(0);
auxspi_write(0);
auxspi_close_lite();
// wait for programming to finish
if (extra) auxspi_disable_extra(extra);
auxspi_open(0);
auxspi_write(5);
auxspi_wait_wip();
auxspi_wait_busy();
auxspi_close();
}
} else {
int8 size = 1 << max(0, (auxspi_save_size_log_2(extra) - 15));
memset(data, 0, 0x8000);
for (int i = 0; i < size; i++) {
auxspi_write_data(i << 15, data, 0x8000, type, extra);
}
}
}
void auxspi_erase_sector(u32 sector, auxspi_extra extra)
{
uint8 type = auxspi_save_type(extra);
if (type == 3) {
if (extra)
auxspi_disable_extra(extra);
auxspi_open(0);
// set WEL (Write Enable Latch)
auxspi_write(0x06);
auxspi_close_lite();
if (extra)
auxspi_disable_extra(extra);
auxspi_open(0);
auxspi_write(0xd8);
auxspi_write(sector & 0xff);
auxspi_write((sector >> 8) & 0xff);
auxspi_write((sector >> 8) & 0xff);
auxspi_close_lite();
// wait for programming to finish
if (extra)
auxspi_disable_extra(extra);
auxspi_open(0);
auxspi_write(5);
auxspi_wait_wip();
auxspi_wait_busy();
auxspi_close();
}
void auxspi_erase_sector(u32 sector, auxspi_extra extra) {
uint8 type = auxspi_save_type(extra);
if (type == 3) {
if (extra) auxspi_disable_extra(extra);
auxspi_open(0);
// set WEL (Write Enable Latch)
auxspi_write(0x06);
auxspi_close_lite();
if (extra) auxspi_disable_extra(extra);
auxspi_open(0);
auxspi_write(0xd8);
auxspi_write(sector & 0xff);
auxspi_write((sector >> 8) & 0xff);
auxspi_write((sector >> 8) & 0xff);
auxspi_close_lite();
// wait for programming to finish
if (extra) auxspi_disable_extra(extra);
auxspi_open(0);
auxspi_write(5);
auxspi_wait_wip();
auxspi_wait_busy();
auxspi_close();
}
}

View File

@ -7,24 +7,25 @@
*
* Copyright (C) Pokedoc (2010)
*/
/*
* 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
/*
* 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.
*
* This program 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 General Public License
*
* This program 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 General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
This is a thin reimplementation of the AUXSPI protocol at low levels.
It is used to implement various experimental procedures to test accessing the HG/SS save chip. */
It is used to implement various experimental procedures to test accessing the
HG/SS save chip. */
#ifndef SPI_BUS_H
#define SPI_BUS_H
@ -40,42 +41,49 @@
// - Pokemon HeartGold/SoulSilver/Black/White
// AUXSPI_BBDX: A game with what seems to be an extra protection against reading
// out the chip. Exclusively found on Band Brothers DX.
// AUXSPI_BLUETOOTH: A game with a Bluetooth transceiver. The only game using this
// AUXSPI_BLUETOOTH: A game with a Bluetooth transceiver. The only game using
// this
// hardware is Pokemon Typing DS.
//
// NOTE: This library does *not* support BBDX (I do have the game, but did not find the
// time to reverse engineer this; besides, a separate homebrew for this game already exists),
// and also *not* BLUETOOTH (the game is Japan-only, and I am from Europe. Plus I can't
// read Japanese. And it is unlikely that this game will ever make it here.)
// NOTE: This library does *not* support BBDX (I do have the game, but did not
// find the
// time to reverse engineer this; besides, a separate homebrew for this game
// already exists), and also *not* BLUETOOTH (the game is Japan-only, and I am
// from Europe. Plus I can't read Japanese. And it is unlikely that this game
// will ever make it here.)
//
typedef enum {
AUXSPI_DEFAULT,
AUXSPI_INFRARED,
AUXSPI_BBDX,
AUXSPI_BLUETOOTH,
AUXSPI_FLASH_CARD = 999
AUXSPI_DEFAULT,
AUXSPI_INFRARED,
AUXSPI_BBDX,
AUXSPI_BLUETOOTH,
AUXSPI_FLASH_CARD = 999
} auxspi_extra;
// These functions reimplement relevant parts of "card.cpp", in a way that is easier to modify.
// These functions reimplement relevant parts of "card.cpp", in a way that is
// easier to modify.
uint8 auxspi_save_type(auxspi_extra extra = AUXSPI_DEFAULT);
uint32 auxspi_save_size(auxspi_extra extra = AUXSPI_DEFAULT);
uint8 auxspi_save_size_log_2(auxspi_extra extra = AUXSPI_DEFAULT);
uint32 auxspi_save_jedec_id(auxspi_extra extra = AUXSPI_DEFAULT);
uint8 auxspi_save_status_register(auxspi_extra extra = AUXSPI_DEFAULT);
void auxspi_read_data(uint32 addr, uint8* buf, uint16 cnt, uint8 type = 0,auxspi_extra extra = AUXSPI_DEFAULT);
void auxspi_write_data(uint32 addr, uint8 *buf, uint16 cnt, uint8 type = 0,auxspi_extra extra = AUXSPI_DEFAULT);
void auxspi_read_data(uint32 addr, uint8* buf, uint16 cnt, uint8 type = 0,
auxspi_extra extra = AUXSPI_DEFAULT);
void auxspi_write_data(uint32 addr, uint8* buf, uint16 cnt, uint8 type = 0,
auxspi_extra extra = AUXSPI_DEFAULT);
void auxspi_erase(auxspi_extra extra = AUXSPI_DEFAULT);
void auxspi_erase_sector(u32 sector, auxspi_extra extra = AUXSPI_DEFAULT);
// These functions are used to identify exotic hardware.
auxspi_extra auxspi_has_extra();
//bool auxspi_has_infrared();
// bool auxspi_has_infrared();
void auxspi_disable_extra(auxspi_extra extra = AUXSPI_DEFAULT);
void auxspi_disable_infrared();
void auxspi_disable_big_protection();
// The following function returns true if this is a type 3 save (big saves, Flash memory), but
// The following function returns true if this is a type 3 save (big saves,
// Flash memory), but
// the JEDEC ID is not known.
bool auxspi_is_unknown_type3(auxspi_extra extra = AUXSPI_DEFAULT);

View File

@ -8,19 +8,19 @@
*
* Copyright (C) Pokedoc (2010)
*/
/*
* 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
/*
* 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.
*
* This program 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 General Public License
*
* This program 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 General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
@ -28,66 +28,55 @@
#include "globals.h"
inline void auxspi_wait_busy()
{
while (REG_AUXSPICNT & 0x80);
inline void auxspi_wait_busy() {
while (REG_AUXSPICNT & 0x80)
;
}
inline void auxspi_wait_wip()
{
do { REG_AUXSPIDATA = 0; auxspi_wait_busy(); } while (REG_AUXSPIDATA & 0x01); // WIP (Write In Progress) ?
inline void auxspi_wait_wip() {
do {
REG_AUXSPIDATA = 0;
auxspi_wait_busy();
} while (REG_AUXSPIDATA & 0x01); // WIP (Write In Progress) ?
}
inline void auxspi_open(uint8 device)
{
REG_AUXSPICNT = 0xa040 | (device & 3);
auxspi_wait_busy();
inline void auxspi_open(uint8 device) {
REG_AUXSPICNT = 0xa040 | (device & 3);
auxspi_wait_busy();
}
inline void auxspi_close()
{
REG_AUXSPIDATA = 0;
auxspi_wait_busy();
REG_AUXSPICNT = 0;
auxspi_wait_busy();
inline void auxspi_close() {
REG_AUXSPIDATA = 0;
auxspi_wait_busy();
REG_AUXSPICNT = 0;
auxspi_wait_busy();
}
inline void auxspi_close_lite()
{
REG_AUXSPICNT = 0x40;
auxspi_wait_busy();
inline void auxspi_close_lite() {
REG_AUXSPICNT = 0x40;
auxspi_wait_busy();
}
inline uint8 auxspi_transfer(uint8 out)
{
REG_AUXSPIDATA = out;
auxspi_wait_busy();
return REG_AUXSPIDATA;
inline uint8 auxspi_transfer(uint8 out) {
REG_AUXSPIDATA = out;
auxspi_wait_busy();
return REG_AUXSPIDATA;
}
inline void auxspi_write(uint8 out)
{
auxspi_transfer(out);
inline void auxspi_write(uint8 out) { auxspi_transfer(out); }
inline uint8 auxspi_read() { return auxspi_transfer(0); }
inline uint16 auxspi_read_16() {
REG_AUXSPIDATA = 0;
auxspi_wait_busy();
return REG_AUXSPIDATA;
}
inline uint8 auxspi_read()
{
return auxspi_transfer(0);
}
inline uint16 auxspi_read_16()
{
REG_AUXSPIDATA = 0;
auxspi_wait_busy();
return REG_AUXSPIDATA;
}
inline void auxspi_disable_infrared_core()
{
auxspi_open(0);
swiDelay(ir_delay);
auxspi_open(2);
auxspi_write(0);
swiDelay(ir_delay);
inline void auxspi_disable_infrared_core() {
auxspi_open(0);
swiDelay(ir_delay);
auxspi_open(2);
auxspi_write(0);
swiDelay(ir_delay);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,58 +1,62 @@
/*
* savegame_manager: a tool to backup and restore savegames from Nintendo
* DS cartridges. Nintendo DS and all derivative names are trademarks
* by Nintendo. EZFlash 3-in-1 is a trademark by EZFlash.
*
* display.h: header file for display.cpp
*
* Copyright (C) Pokedoc (2010)
*/
/*
* 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.
*
* This program 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 General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* savegame_manager: a tool to backup and restore savegames from Nintendo
* DS cartridges. Nintendo DS and all derivative names are trademarks
* by Nintendo. EZFlash 3-in-1 is a trademark by EZFlash.
*
* display.h: header file for display.cpp
*
* Copyright (C) Pokedoc (2010)
*/
/*
* 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.
*
* This program 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 General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef SAVE_DISPLAY_H
#define SAVE_DISPLAY_H
#include <nds.h>
#include <nds/arm9/console.h>
#include <stdarg.h>
extern PrintConsole upperScreen;
extern PrintConsole lowerScreen;
void displayInit();
void displayTitle();
// Set "first" to true to tell the program that it has just booted, before anything was swapped.
// This is a workaround for the Cyclops iEvolution, and an attempt to prevent
void displayPrintUpper(bool fc = false);
void displayPrintLower();
void displayMessageF(int id, ...);
void displayMessage2F(int id, ...);
void displayWarning2F(int id, ...);
void displayStateF(int id, ...);
void displayProgressBar(int cur, int max0);
void displayDebugF(const char *format, ...);
#include <nds.h>
#include <nds/arm9/console.h>
#include <stdarg.h>
#include "supported_games.h"
#include "languages.h"
extern PrintConsole upperScreen;
extern PrintConsole lowerScreen;
void displayInit();
void displayTitle();
// Set "first" to true to tell the program that it has just booted, before
// anything was swapped.
// This is a workaround for the Cyclops iEvolution, and an attempt to prevent
void displayPrintUpper(bool fc = false);
void displayPrintLower(int cursor_position);
void displayPrintTicketError(int error);
void displayPrintTickets(int cursor_position, SupportedGames games, Language language);
void displayChangeCart(int mode);
void displayLoadingCart();
void displayMessageF(int id, ...);
void displayMessage2F(int id, ...);
void displayWarning2F(int id, ...);
void displayStateF(int id, ...);
void displayProgressBar(int cur, int max0);
void displayDebugF(const char *format, ...);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -8,28 +8,28 @@
* Copyright (C) EZFlash Group (2006)
* Copyright (C) Pokedoc (2010)
*/
/*
* 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
/*
* 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.
*
* This program 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 General Public License
*
* This program 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 General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/**************************************************************************************************************
* dsCard.h
* dsCard.h
* 200611271133 version 1.0
* aladdin
* CopyRight : EZFlash Group
*
*
**************************************************************************************************************/
#ifndef NDS_DSCARD_V2_INCLUDE
@ -37,9 +37,9 @@
#include "nds.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifndef BYTE
typedef unsigned char BYTE;
@ -54,43 +54,39 @@ typedef unsigned long DWORD;
#endif
#ifndef BOOL
typedef bool BOOL ;
typedef bool BOOL;
#endif
// export interface
//---------------------------------------------------
//DS 卡 基本操作
//Arm9 方面基本操作容许ARM7访问slot1
void Enable_Arm7DS(void);
// DS 卡 基本操作
// Arm9 方面基本操作容许ARM7访问slot1
void Enable_Arm7DS(void);
//Arm9 方面基本操作容许ARM9访问slot1
void Enable_Arm9DS(void);
// Arm9 方面基本操作容许ARM9访问slot1
void Enable_Arm9DS(void);
//下面是访问震动卡的函数
#define FlashBase 0x08000000
#define _Ez5PsRAM 0x08000000
void OpenNorWrite();
void CloseNorWrite();
void SetRompage(u16 page);
void SetRampage(u16 page);
void OpenRamWrite();
void CloseRamWrite();
void SetSerialMode();
uint32 ReadNorFlashID();
void chip_reset();
void Block_Erase(u32 blockAdd);
void ReadNorFlash(u8* pBuf,u32 address,u16 len);
void WriteNorFlash(u32 address,u8 *buffer,u32 size);
void WriteSram(uint32 address, u8* data , uint32 size );
void ReadSram(uint32 address, u8* data , uint32 size );
void SetShake(u16 data);
void WritePSram(u8* address, u8* data , uint32 length );
void ReadPSram(u8* address, u8* data , uint32 length );
#ifdef __cplusplus
}
#endif
//下面是访问震动卡的函数
#define FlashBase 0x08000000
#define _Ez5PsRAM 0x08000000
void OpenNorWrite();
void CloseNorWrite();
void SetRompage(u16 page);
void SetRampage(u16 page);
void OpenRamWrite();
void CloseRamWrite();
void SetSerialMode();
uint32 ReadNorFlashID();
void chip_reset();
void Block_Erase(u32 blockAdd);
void ReadNorFlash(u8* pBuf, u32 address, u16 len);
void WriteNorFlash(u32 address, u8* buffer, u32 size);
void WriteSram(uint32 address, u8* data, uint32 size);
void ReadSram(uint32 address, u8* data, uint32 size);
void SetShake(u16 data);
void WritePSram(u8* address, u8* data, uint32 length);
void ReadPSram(u8* address, u8* data, uint32 length);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,41 +0,0 @@
/*
* savegame_manager: a tool to backup and restore savegames from Nintendo
* DS cartridges. Nintendo DS and all derivative names are trademarks
* by Nintendo. EZFlash 3-in-1 is a trademark by EZFlash.
*
* dsi.cpp: A happy collection of functions dealing with DSi-specific things
*
* Copyright (C) Pokedoc (2010)
*/
/*
* 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.
*
* This program 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 General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdio.h>
#include <nds.h>
#include "display.h"
#include "dsi.h"
bool isDsi()
{
return (REG_DSIMODE != 0) ? true : false;
}
bool dsiUnlockSlot1()
{
// we don't know how to fix this yet...
return false;
}

View File

@ -1,33 +0,0 @@
/*
* savegame_manager: a tool to backup and restore savegames from Nintendo
* DS cartridges. Nintendo DS and all derivative names are trademarks
* by Nintendo. EZFlash 3-in-1 is a trademark by EZFlash.
*
* dsi.h: header file for dsi.cpp
*
* Copyright (C) Pokedoc (2010)
*/
/*
* 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.
*
* This program 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 General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef HEADER_DSI
#define HEADER_DSI
bool isDsi();
bool dsiUnlockSlot1();
#endif

View File

@ -8,295 +8,296 @@
*
* Copyright (C) Pokedoc (2010)
*/
/*
* 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
/*
* 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.
*
* This program 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 General Public License
*
* This program 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 General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <nds.h>
#include "fileselect.h"
#include <dirent.h>
#include <fat.h>
#include <nds.h>
#include <nds/arm9/console.h>
#include <stdio.h>
#include <sys/dir.h>
#include <sys/unistd.h>
#include <stdio.h>
#include <dirent.h>
#include <cstdio>
#include "display.h"
#include "strings.h"
#include "globals.h"
#include "strings.h"
#include "fileselect.h"
//extern u8 *data;
//extern u32 size_buf;
// extern u8 *data;
// extern u32 size_buf;
// ---------------------------------------------------------------------------------
void ftpGetFileList(const char *dir, netbuf *ctrl, int &num)
{
char *buf = (char*)data;
memset(buf, 0, size_buf);
FtpDirBuf((char*)data, size_buf, "/", 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 ftpGetFileList(const char *dir, netbuf *ctrl, int &num) {
char *buf = (char *)data;
memset(buf, 0, size_buf);
FtpDirBuf((char *)data, size_buf, "/", 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, int &num)
{
char *buf = (char*)data;
int idx = 0;
memset(buf, 0, size_buf);
DIR *pdir;
struct dirent *pent;
num = 0;
pdir=opendir(dir);
if (pdir) {
while ((pent=readdir(pdir)) !=NULL) {
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) < size_buf-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)
closedir(pdir);
void fileGetFileList(const char *dir, int &num) {
char *buf = (char *)data;
int idx = 0;
memset(buf, 0, size_buf);
DIR *pdir;
struct dirent *pent;
num = 0;
pdir = opendir(dir);
if (pdir) {
while ((pent = readdir(pdir)) != NULL) {
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) < size_buf - 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) closedir(pdir);
}
void filePrintFileList(const char *dir, int first, int select, int count, bool cancel = false)
{
if (select < first)
select = first;
void filePrintFileList(const char *dir, int first, int select, int count,
bool cancel = false) {
if (select < first) select = first;
consoleSelect(&lowerScreen);
consoleSetWindow(&lowerScreen, 0, 0, 32, 19);
consoleClear();
consoleSelect(&lowerScreen);
consoleSetWindow(&lowerScreen, 0, 0, 32, 19);
consoleClear();
char *buf = (char*)data;
for (int i = 0; i < first; i++) {
buf = strchr(buf, '\n') + 1;
}
char *buf = (char *)data;
for (int i = 0; i < first; i++) {
buf = strchr(buf, '\n') + 1;
}
for (int i = first; (i < first + 18) && (i < count); i++) {
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("================================");
if (cancel)
iprintf(stringsGetMessageString(STR_FS_WRITE));
else
iprintf(stringsGetMessageString(STR_FS_READ));
for (int i = first; (i < first + 18) && (i < count); i++) {
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("================================");
if (cancel)
iprintf(stringsGetMessageString(STR_FS_WRITE));
else
iprintf(stringsGetMessageString(STR_FS_READ));
}
// ========================***************************==============================
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;
int num_files = 0;
int sel_file = 0;
int first_file = 0;
// get list of files in current dir
if (buf)
ftpGetFileList("/", buf, num_files);
else
fileGetFileList(startdir, num_files);
filePrintFileList(startdir, first_file, sel_file, num_files, allow_cancel);
while (!select) {
// get_event
uint32 keys = keysCurrent();
// handle_event
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);
}
} else if (keys & KEY_UP) {
if (sel_file > 0) {
sel_file--;
if (sel_file < first_file)
first_file = sel_file;
filePrintFileList(startdir, first_file, sel_file, num_files, allow_cancel);
}
} else if (keys & KEY_A) {
// get selected file name
char *buf2 = (char*)data;
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, fname);
struct stat statbuf;
stat(fullname, &statbuf);
if (c == 'd') {
char fullpath[512];
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", fname);
while (keysCurrent() & (KEY_A | KEY_B));
return;
}
} 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;
return;
}
}
for (int i = 0; i < 5; i++)
swiWaitForVBlank();
}
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;
int num_files = 0;
int sel_file = 0;
int first_file = 0;
// get list of files in current dir
if (buf)
ftpGetFileList("/", buf, num_files);
else
fileGetFileList(startdir, num_files);
filePrintFileList(startdir, first_file, sel_file, num_files, allow_cancel);
while (!select) {
// get_event
uint32 keys = keysCurrent();
// handle_event
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);
} else {
// wrap around to top of list
sel_file = 0;
first_file = 0;
filePrintFileList(startdir, first_file, sel_file, num_files,
allow_cancel);
}
} else if (keys & KEY_UP) {
if (sel_file > 0) {
sel_file--;
if (sel_file < first_file) first_file = sel_file;
filePrintFileList(startdir, first_file, sel_file, num_files,
allow_cancel);
} else {
// wrap around to bottom of list
sel_file = num_files - 1;
first_file = sel_file - (size_list - 1);
filePrintFileList(startdir, first_file, sel_file, num_files,
allow_cancel);
}
} else if (keys & KEY_A) {
// get selected file name
char *buf2 = (char *)data;
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 (strcasecmp(fname, ".") == 0)
// don't do anything
continue;
if (strcasecmp(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, fname);
struct stat statbuf;
stat(fullname, &statbuf);
if (c == 'd') {
char fullpath[512];
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", fname);
while (keysCurrent() & (KEY_A | KEY_B))
;
return;
}
} 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;
return;
}
}
for (int i = 0; i < 5; i++) swiWaitForVBlank();
}
}
// -------------------------------------------------------
// This is a standard textbook-style "fileExists" function.
bool fileExists(const char *fname)
{
struct stat statbuf;
memset(&statbuf, 0, sizeof(statbuf));
if (stat(fname, &statbuf) != 0)
return false;
else {
// on dsiwarehaxx, this additional check is required
if (statbuf.st_size)
return true;
else
return false;
}
bool fileExists(const char *fname) {
struct stat statbuf;
memset(&statbuf, 0, sizeof(statbuf));
if (stat(fname, &statbuf) != 0)
return false;
else {
// on dsiwarehaxx, this additional check is required
if (statbuf.st_size)
return true;
else
return false;
}
}
uint32 fileSize(const char *fname)
{
struct stat statbuf;
if (stat(fname, &statbuf) == 0)
return statbuf.st_size;
else
return 0;
uint32 fileSize(const char *fname) {
struct stat statbuf;
if (stat(fname, &statbuf) == 0)
return statbuf.st_size;
else
return 0;
}

View File

@ -7,54 +7,54 @@
*
* Copyright (C) Pokedoc (2010)
*/
/*
* 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
/*
* 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.
*
* This program 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 General Public License
*
* This program 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 General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _FILE_SELECT
#define _FILE_SELECT
#define CONFIRMDELETE 5
#define LOADBIN 4
#define MAXBROWSERCYCLES 4
#define MAX_CUSTOM_LIST 8192
#include <nds.h>
#include <unistd.h>
//#endif
//#if defined(_WIN32)
//#include <windows.h>
//#endif
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
//#if defined(__unix__)
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#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);
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);

File diff suppressed because it is too large Load Diff

View File

@ -1,24 +1,24 @@
/***************************************************************************/
/* */
/* */
/* 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. */
/* */
/* 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)
@ -81,7 +81,7 @@ 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 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)
@ -103,7 +103,7 @@ 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);
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);
@ -119,22 +119,23 @@ 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);
netbuf *nControl);
GLOBALREF int FtpPut(const char *input, const char *path, char mode,
netbuf *nControl);
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);
GLOBALREF 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);
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);
// added by Pokedoc
GLOBALREF int FtpAccessPos(const char *path, int typ, int pos, int mode, netbuf *nControl,
netbuf **nData);
GLOBALREF int FtpAccessPos(const char *path, int typ, int pos, int mode,
netbuf *nControl, netbuf **nData);
GLOBALREF int FtpCloseAccess(netbuf *nControl, netbuf *nData);
#ifdef __cplusplus

File diff suppressed because it is too large Load Diff

View File

@ -7,55 +7,56 @@
*
* Copyright (C) Pokedoc (2010)
*/
/*
* 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
/*
* 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.
*
* This program 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 General Public License
*
* This program 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 General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __SLOT2_H__
#define __SLOT2_H__
#include <nds.h>
enum cartTypeGBA {
CART_GBA_NONE = 0,
CART_GBA_GAME,
CART_GBA_EMULATOR,
CART_GBA_3IN1_256_V1,
CART_GBA_3IN1_256_V2,
CART_GBA_3IN1_512_V3,
CART_GBA_FLASH
CART_GBA_NONE = 0,
CART_GBA_GAME,
CART_GBA_EMULATOR,
CART_GBA_3IN1_256_V1,
CART_GBA_3IN1_256_V2,
CART_GBA_3IN1_512_V3,
CART_GBA_FLASH
};
enum saveTypeGBA {
SAVE_GBA_NONE = 0,
SAVE_GBA_EEPROM_05, // 512 bytes
SAVE_GBA_EEPROM_8, // 8k
SAVE_GBA_SRAM_32, // 32k
SAVE_GBA_FLASH_64, // 64k
SAVE_GBA_FLASH_128 // 128k
SAVE_GBA_NONE = 0,
SAVE_GBA_EEPROM_05, // 512 bytes
SAVE_GBA_EEPROM_8, // 8k
SAVE_GBA_SRAM_32, // 32k
SAVE_GBA_FLASH_64, // 64k
SAVE_GBA_FLASH_128 // 128k
};
struct dataSlot2 {
cartTypeGBA type;
saveTypeGBA save;
uint32 ez_ID;
union {
char cid[5];
uint32 iid;
};
char name[13];
cartTypeGBA type;
saveTypeGBA save;
uint32 ez_ID;
union {
char cid[5];
uint32 iid;
};
char name[13];
};
cartTypeGBA GetSlot2Type(uint32 id);
saveTypeGBA GetSlot2SaveType(cartTypeGBA type);
@ -69,5 +70,4 @@ bool gbaReadSave(u8 *dst, u32 src, u32 len, u8 type);
bool gbaWriteSave(u32 dst, u8 *src, u32 len, u8 type);
bool gbaFormatSave(u8 type);
#endif // __SLOT2_H__
#endif // __SLOT2_H__

View File

@ -7,19 +7,19 @@
*
* Copyright (C) Pokedoc (2011)
*/
/*
* 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
/*
* 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.
*
* This program 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 General Public License
*
* This program 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 General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

View File

@ -7,19 +7,19 @@
*
* Copyright (C) Pokedoc (2011)
*/
/*
* 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
/*
* 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.
*
* This program 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 General Public License
*
* This program 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 General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
@ -27,14 +27,16 @@
#define GLOBALS_H
#include <nds.h>
#include "auxspi.h"
#define VERSION_MAJOR 0
#define VERSION_MINOR 3
#define VERSION_MAJOR 1
#define VERSION_MINOR 0
#define VERSION_MICRO 0
#define VERSION_EXTRA "RC2"
#define VERSION_EXTRA ""
// this enables a custom font. it does not work yet, stuff is missing, so please uncomment
// this enables a custom font. it does not work yet, stuff is missing, so please
// uncomment
// this line only for testing and development purposes!
//#define ENABLE_CUSTOM_FONT
@ -51,7 +53,8 @@ extern bool ftp_active;
extern int ir_delay;
// all libfat access will be using this device. default value = "/", i.e. "default" DLDI device
// all libfat access will be using this device. default value = "/", i.e.
// "default" DLDI device
extern char device[16];
// text buffer for composing various messages
@ -70,4 +73,4 @@ extern bool sdslot;
extern u32 extra_id[EXTRA_ARRAY_SIZE];
extern u8 extra_size[EXTRA_ARRAY_SIZE];
#endif // GLOBALS_H
#endif // GLOBALS_H

File diff suppressed because it is too large Load Diff

View File

@ -7,47 +7,49 @@
*
* Copyright (C) Pokedoc (2010)
*/
/*
* 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
/*
* 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.
*
* This program 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 General Public License
*
* This program 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 General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef HARDWARE_H
#define HARDWARE_H
#include <nds.h>
#include <fat.h>
#include <nds.h>
#include <sys/unistd.h>
#define RS_BACKUP 0x4b434142
#include "languages.h"
#include "supported_games.h"
#define RS_BACKUP 0x4b434142
extern uint32 boot;
extern bool flash_card;
struct dsCardData
{
uint32 data[4];
char name[12];
struct dsCardData {
uint32 data[4];
char name[12];
};
void do_dump_nds_save_stage_1();
void do_dump_nds_save_stage_2(int size);
void do_dump_nds_save_stage_1();
void do_dump_nds_save_stage_2(int size);
void do_restore_nds_save();
bool swap_cart();
//u32 get_slot1_type();
bool swap_cart(bool allow_cancel = false);
// u32 get_slot1_type();
// This function was previously found in the main function.
// Return values:
@ -56,12 +58,13 @@ bool swap_cart();
// 2 - EZFlash 3in1 in Slot 2
// 3 - running in DSi mode
// 4 - running from Slot 2 flash card
// 5 - running from download play or another exploit that does not need a flash card in Slot 1
// 5 - running from download play or another exploit that does not need a flash
// card in Slot 1
//
u32 hwDetect();
void hwBackup3in1();
void hwDump3in1(uint32 size, const char *gamename);
void hwDump3in1(uint32 size, const char* gamename);
void hwRestore3in1();
void hwRestore3in1_b(uint32 size_file);
void hwErase();
@ -72,6 +75,7 @@ void hwRestoreDSi();
void hwBackupFTP(bool dlp = false);
void hwRestoreFTP(bool dlp = false);
void GBA_read_inject_restore(u8 type, char* ticket, SupportedGames games, Language language);
void hwBackupGBA(u8 type);
void hwRestoreGBA();
void hwEraseGBA();

View File

@ -19,359 +19,313 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "iniheadings.h"
#if defined(HAVE_STRINGS_H)
# include <strings.h>
#include <strings.h>
#endif
#ifndef HAVE_STRCASECMP
# define strcasecmp stricmp
#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
* 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;
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);
// 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);
/* 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;
// 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
* 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.
* 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;
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';
}
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;
}
section = __ini_createHeading(ini, str);
// Make sure heading was created
if (!section) {
free(str);
return NULL;
}
return section;
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
* 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;
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;
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
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;
}
ini->selected = pNew;
return 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.
* 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;
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);
}
// 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;
// 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;
// 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
// 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);
}
// 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.
* 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;
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);
// 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;
}
// 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
// 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;
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.
* 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;
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.
* 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;
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;
if (!heading) return -1;
section = __ini_locateHeading (ini, heading);
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
// 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;
}
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);
// 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;
// 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
@ -380,15 +334,12 @@ int INI_LINKAGE ini_locateHeading (ini_fd_t fd, const char *heading)
* 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;
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;
if (!ini) return NULL;
section = ini->selected;
if (!section) return NULL;
return section->heading;
}

File diff suppressed because it is too large Load Diff

View File

@ -21,56 +21,56 @@
#define INI_USE_HASH_TABLE
#include "libini.h"
#include "inikeys.h"
#include "iniheadings.h"
#include "inikeys.h"
#include "libini.h"
#ifdef INI_ADD_LIST_SUPPORT
# include "inilist.h"
#include "inilist.h"
#endif
typedef enum {INI_NEW, INI_EXIST, INI_READ} ini_mode_t;
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
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;
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;
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];
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
// 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);
static void __ini_strtrim(char *str);
#ifdef INI_USE_HASH_TABLE
static unsigned long __ini_createCrc32 (const char *str, bool strcase);
static unsigned long __ini_createCrc32(const char *str, bool strcase);
#endif
#endif // _ini_h_
#endif // _ini_h_

View File

@ -17,7 +17,7 @@
#define HAVE_STDLIB_H 1
/* Define if you have the strcasecmp function. */
#define HAVE_STRCASECMP
#define HAVE_STRCASECMP
/* Define if you have the <strings.h> header file. */
//#define HAVE_STRINGS_H 1

View File

@ -20,6 +20,7 @@
#define _headings_h_
#include <stdio.h>
#include "ini.h"
//*******************************************************************************************************************
@ -29,27 +30,29 @@ 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;
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
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);
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_
#endif // _headings_h_

View File

@ -20,6 +20,7 @@
#define _keys_h_
#include <stdio.h>
#include "ini.h"
//*******************************************************************************************************************
@ -29,26 +30,26 @@ 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;
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
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);
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_
#endif // _keys_h_

View File

@ -23,10 +23,10 @@
#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);
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_
#endif // INI_ADD_LIST_SUPPORT
#endif // _list_h_

View File

@ -19,57 +19,53 @@
#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>
#include <strings.h>
#endif
#ifndef HAVE_STRCASECMP
# define strcasecmp stricmp
#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.
* 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;
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;
// 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;
// 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.
@ -78,155 +74,140 @@ struct key_tag *__ini_addKey (ini_t *ini, char *key)
* Globals Modified :
* Description : Finds average key length for aligning equals.
********************************************************************************************************************/
size_t __ini_averageLengthKey (struct section_tag *current_h)
{
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;
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;
}
// 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;
if (!count) return 0;
average /= count;
equal_pos = (equal_max = average);
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;
// 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;
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
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.
* 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;
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);
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 = __ini_createKey(ini, str);
if (!_key) {
free(str);
return NULL;
}
_key->pos = pos + (long) length;
return _key;
_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.
* 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;
struct key_tag *__ini_createKey(ini_t *ini, char *key) {
struct section_tag *section;
struct key_tag *pNew;
long pos;
if (!*key)
return NULL;
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;
}
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
{ // 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;
section->last->pNext = pNew;
if (!section->first)
section->first = pNew;
else
section->last->pNext = pNew;
pNew->pPrev = section->last;
section->last = pNew;
section->selected = 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;
{ // 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
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;
section->selected = pNew;
return pNew;
}
/********************************************************************************************************************
* Function : __ini_deleteKey
* Parameters : ini - pointer to ini file database. key - key name
@ -234,50 +215,46 @@ struct key_tag *__ini_createKey (ini_t *ini, char *key)
* 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.
* : 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;
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;
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;
// 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
// 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);
}
// Delete Key
free(current_k->key);
free(current_k);
}
}
/********************************************************************************************************************
* Function : __ini_locateKey
* Parameters : ini - pointer to ini file database. key - key name
@ -290,77 +267,63 @@ void __ini_deleteKey (ini_t *ini)
* 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;
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);
{ // 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;
}
}
// 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;
}
{ // 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
}
#endif // INI_USE_HASH_TABLE
section->selected = current_k;
return current_k;
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
* 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
* 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;
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
@ -369,49 +332,40 @@ int INI_LINKAGE ini_deleteKey (ini_fd_t fd)
* 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;
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;
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);
// 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
// Rev 1.1 - Remove buffered list
if (ini->list) {
free(ini->list);
ini->list = NULL;
}
#endif // INI_ADD_LIST_SUPPORT
if (_key)
return 0;
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);
// 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;
// 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
@ -420,19 +374,15 @@ int INI_LINKAGE ini_locateKey (ini_fd_t fd, const char *key)
* 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;
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;
if (!ini) return NULL;
section = ini->selected;
if (!section) return NULL;
key = section->selected;
if (!key) return NULL;
return key->key;
}

13
arm9/source/languages.h Normal file
View File

@ -0,0 +1,13 @@
#ifndef LANGUAGE_H
#define LANGUAGE_H
enum Language {
JAPANESE = 1,
ENGLISH = 2,
FRENCH = 3,
ITALIAN = 4,
GERMAN = 5,
SPANISH = 6
};
#endif /* LANGUAGE_H */

View File

@ -40,104 +40,102 @@ extern "C" {
#endif /* SWIG */
#ifdef _WINDOWS
# define INI_LINKAGE __stdcall
#define INI_LINKAGE __stdcall
#else
# define INI_LINKAGE
#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
#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
#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;
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);
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);
/* 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);
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);
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);
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);
/* 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);
/* 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);
/* 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.
*/
/* 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);
/* 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>
#include <stdio.h>
#define INI_STATIC static
typedef struct
{

View File

@ -18,6 +18,7 @@
#include <stdlib.h>
#include <string.h>
#include "inilist.h"
#ifdef INI_ADD_LIST_SUPPORT
@ -28,95 +29,85 @@
* 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
* 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;
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;
}
// 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;
}
// 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;
// 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);
{ // 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;
}
// 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;
}
lastch = ch;
}
// Seperate strings
ini->list[length] = (ch = '\0');
count++;
break;
}
}
lastch = ch;
}
}
ini->listLength = count;
ini->listIndexPtr = ini->list;
ini->listIndex = 0;
return count;
ini->listLength = count;
ini->listIndexPtr = ini->list;
ini->listIndex = 0;
return count;
}
/********************************************************************************************************************
* Function : __ini_listRead
* Parameters : ini - pointer to ini file database.
@ -129,185 +120,150 @@ int __ini_listEval (ini_t *ini)
* Rev | Date | By | Comment
* ----------------------------------------------------------------------------------------------------------------
********************************************************************************************************************/
char *__ini_listRead (ini_t *ini)
{
char *p;
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 "";
}
// 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;
// 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
* 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;
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 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);
// Check to see if we have moved to a new key
if (!ini->list) return __ini_listEval(ini);
return ini->listLength;
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)
* 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;
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;
}
// 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;
// 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)
* 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);
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)
* 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;
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;
// 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;
}
// 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;
// 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);
}
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;
}
ini->listIndex = count;
ini->listIndexPtr = p;
return 0;
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 :
* Returns :
* Globals Used :
* Globals Modified :
* Description : Returns the length the indexed sub string
@ -315,18 +271,14 @@ int INI_LINKAGE ini_listIndex (ini_fd_t fd, unsigned long index)
* 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;
}
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);
// Now return length
return strlen(ini->listIndexPtr);
}
#endif // INI_ADD_LIST_SUPPORT
#endif // INI_ADD_LIST_SUPPORT

File diff suppressed because it is too large Load Diff

2622
arm9/source/me.h Normal file

File diff suppressed because it is too large Load Diff

373
arm9/source/poke.cpp Normal file
View File

@ -0,0 +1,373 @@
/*
Most of the following code is based of:
MirageIslandValue v1.5 - Tool to find the specific Mirage Island Value in
RSE save files Copyright (C) 2015 BlackShark
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 3 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <math.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "languages.h"
#include "supported_games.h"
#define WC_OFFSET_E 0x56C;
#define WC_SCRIPT_OFFSET_E 0x8A8;
#define WC_OFFSET_FRLG 0x460;
#define WC_SCRIPT_OFFSET_FRLG 0x79C;
#define WC_OFFSET_E_JAP 0x490;
#define WC_SCRIPT_OFFSET_E_JAP 0x8A8;
#define WC_OFFSET_FRLG_JAP 0x384;
#define WC_SCRIPT_OFFSET_FRLG_JAP 0x79C;
#define ME3_OFFSET_E 0x8A8;
#define ME3_SIZE_E 1012;
#define ME3_SCRIPT_SIZE_E ME3_SIZE_E - 8;
#define ME3_OFFSET_RS 0x810;
#define ME3_SIZE_RS 1012;
#define ME3_SCRIPT_SIZE_RS 1004;
#define ME3_ITEM_SIZE 8;
#define ME3_SIZE 1012;
// check for the nocash signature
unsigned int checkNocash(char *sav) {
unsigned int noCash;
if (sav[0x0] == 0x4E && sav[0x01] == 0x6F && sav[0x02] == 0x63 &&
sav[0x03] == 0x61 && sav[0x04] == 0x73 && sav[0x05] == 0x68) {
noCash = 0x4C;
} else {
noCash = 0x0;
}
return noCash;
}
// find current save by comparing both save counters from first and second save
// block
int oldSav = 0;
unsigned int checkCurrentSav(char *sav) {
unsigned long savIndex1, savIndex2;
unsigned int currentSav, nocash;
nocash = checkNocash(sav);
savIndex1 = (sav[0xFFF + nocash] << 24 & 0xFFFFFFFF) +
(sav[0xFFE + nocash] << 16 & 0xFFFFFF) +
(sav[0xFFD + nocash] << 8 & 0xFFFF) +
(sav[0xFFC + nocash] & 0xFF);
savIndex2 = (sav[0xEFFF + nocash] << 24 & 0xFFFFFFFF) +
(sav[0xEFFE + nocash] << 16 & 0xFFFFFF) +
(sav[0xEFFD + nocash] << 8 & 0xFFFF) +
(sav[0xEFFC + nocash] & 0xFF);
if (savIndex1 >= savIndex2) {
currentSav = 0x0 + nocash;
oldSav = 0xE000 + nocash;
} else if (savIndex1 < savIndex2) {
currentSav = 0xE000 + nocash;
oldSav = 0x0 + nocash;
}
return currentSav;
}
#define DATALEN 3968
// From Kaphoticc's PSavFixV2
int Chksum(int length, int *Data) {
int Chk, i, tmp;
length = length >> 2;
Chk = 0;
for (i = 0; i < length; i++) Chk += Data[i];
tmp = Chk >> 16;
tmp += Chk;
Chk = (tmp & 0xFFFF);
return Chk;
}
int wc_inject(char *sav, char *wc3, SupportedGames games, Language language)
{
unsigned int currentSav = 0, sec[14] = {}, sec0, s0, sx, x;
int wc_offset = 0x0;
int wc_script_offset = 0x0;
switch (language) {
case JAPANESE:
switch (games) {
case EMERALD:
wc_offset = WC_OFFSET_E_JAP;
wc_script_offset = WC_SCRIPT_OFFSET_E_JAP;
break;
case FIRE_RED_AND_LEAF_GREEN:
wc_offset = WC_OFFSET_FRLG_JAP;
wc_script_offset = WC_SCRIPT_OFFSET_FRLG_JAP;
break;
}
break;
default:
switch (games) {
case EMERALD:
wc_offset = WC_OFFSET_E;
wc_script_offset = WC_SCRIPT_OFFSET_E;
break;
case FIRE_RED_AND_LEAF_GREEN:
wc_offset = WC_OFFSET_FRLG;
wc_script_offset = WC_SCRIPT_OFFSET_FRLG;
break;
}
break;
}
// check where the current save is
currentSav = checkCurrentSav(sav);
// get section locations in current save
for (s0 = 0; s0 <= 13; s0++) {
sec0 = sav[0x0FF4 + 0x1000 * s0 + currentSav];
if (sec0 == 0x0) {
for (sx = 0; sx <= 13; sx++) {
if ((s0 + sx) <= 13) {
sec[sx] = s0 + sx;
} else {
sec[sx] = s0 + sx - 14;
}
}
break;
}
}
// check if all sections were found
for (x = 0; x <= 13; x++) {
if (sav[0x0FF4 + 0x1000 * sec[x] + currentSav] != x) {
printf("This is not a valid Ru/Sa/Em/FR/LG save file!\n");
return -1;
}
}
// Check if save has enabled mistery gift
switch (games) {
case RUBY_AND_SAPPHIRE: // not that it has wondercards...but let's see the code for it
/*
if ( (sav[0x3A9 + 0x1000 * sec[2] + currentSav]&0x10) == 0)
{
printf("Mistery Event is not enabled in savegame!\n");
goto exit_app;
return -2;
}
break;
*/
case EMERALD:
/*
//Mistery Event (only really used by japanese)
if ( (sav[0x405 + 0x1000 * sec[2] + currentSav]&0x10) == 0)
{
printf("Mistery Event is not enabled in savegame!\n");
goto exit_app;
return -2;
}
*/
// Mistery Gift
if ((sav[0x40B + 0x1000 * sec[2] + currentSav] & 0x8) == 0) {
printf("Mistery Gift is not enabled in savegame!\n");
return -3;
}
break;
case FIRE_RED_AND_LEAF_GREEN:
// Mistery Gift
if ((sav[0x67 + 0x1000 * sec[2] + currentSav] & 0x2) == 0) {
printf("Mistery Gift is not enabled in savegame!\n");
return -3;
}
break;
}
// Inject WC
if (language == JAPANESE) {
memcpy(sav + (wc_offset + 0x1000 * sec[4] + currentSav), wc3,
0x4 + 0xA4); // checksum+WC
memcpy(
sav + ((wc_offset + 0x4 + 0xA4 + 0xA) + 0x1000 * sec[4] + currentSav),
wc3 + 0x4 + 0xA4 + 0xA, 2); // Icon
memcpy(sav + (wc_script_offset + 0x1000 * sec[4] + currentSav),
wc3 + 0x4 + 0xA4 + 0x28 + 0x28,
1004); // Script data (chk(4) + association(4) + script(996))
} else {
memcpy(sav + (wc_offset + 0x1000 * sec[4] + currentSav), wc3,
0x4 + 0x14C); // checksum+WC
memcpy(
sav + ((wc_offset + 0x4 + 0x14C + 0xA) + 0x1000 * sec[4] + currentSav),
wc3 + 0x4 + 0x14C + 0xA, 2); // Icon
memcpy(sav + (wc_script_offset + 0x1000 * sec[4] + currentSav),
wc3 + 0x4 + 0x14C + 0x28 + 0x28,
1004); // Script data (chk(4) + association(4) + script(996))
}
// Update section 4 checksums
char *ptr = sav + (0x1000 * sec[4] + currentSav);
int chk = Chksum(DATALEN, (int *)ptr);
sav[(0xFF6 + 0x1000 * sec[4] + currentSav)] = chk & 0x000000FF;
sav[(0xFF7 + 0x1000 * sec[4] + currentSav)] = (chk & 0x0000FF00) >> 8;
printf("Updating savegame section 4 checksum...(%04X)...", chk);
return 1;
}
int me_inject(char *sav, char *me3, SupportedGames games, Language language)
{
if (me3 == NULL && language != 0 &&
games != EMERALD) // Only allow NULL card for emerald eon ticket JAP
return -4;
unsigned int currentSav = 0, sec[14] = {}, sec0, s0, sx, x;
int me_offset = 0x0;
switch (language) {
case JAPANESE:
switch (games) {
case RUBY_AND_SAPPHIRE:
me_offset = ME3_OFFSET_RS;
break;
case EMERALD:
me_offset = ME3_OFFSET_E;
break;
}
break;
default:
switch (games) {
case RUBY_AND_SAPPHIRE:
me_offset = ME3_OFFSET_RS;
break;
case EMERALD:
me_offset = ME3_OFFSET_E;
break;
}
break;
}
// check where the current save is
currentSav = checkCurrentSav(sav);
// get section locations in current save
for (s0 = 0; s0 <= 13; s0++) {
sec0 = sav[0x0FF4 + 0x1000 * s0 + currentSav];
if (sec0 == 0x0) {
for (sx = 0; sx <= 13; sx++) {
if ((s0 + sx) <= 13) {
sec[sx] = s0 + sx;
} else {
sec[sx] = s0 + sx - 14;
}
}
break;
}
}
// check if all sections were found
for (x = 0; x <= 13; x++) {
if (sav[0x0FF4 + 0x1000 * sec[x] + currentSav] != x) {
printf("This is not a valid Ru/Sa/Em/FR/LG save file!\n");
return -1;
}
}
// Check if save has enabled mistery gift
switch (games) {
case RUBY_AND_SAPPHIRE:
if ((sav[0x3A9 + 0x1000 * sec[2] + currentSav] & 0x10) == 0) {
printf("Mistery Event is not enabled in savegame!\n");
return -2;
}
break;
case EMERALD:
// Mistery Event (only really used by japanese)
if ((sav[0x405 + 0x1000 * sec[2] + currentSav] & 0x10) == 0) {
printf("Mistery Event is not enabled in savegame!\n");
return -2;
}
/*
//Mistery Gift
if ( (sav[0x40B + 0x1000 * sec[2] + currentSav]&0x8) == 0)
{
printf("Mistery Gift is not enabled in savegame!\n");
return -3;
}
*/
break;
}
if (games == EMERALD && me3 == NULL) // Emerald Eon Ticket is an in-game event
{
// Enable flag
sav[(0x49A + 0x1000 * sec[2] + currentSav)] |= 0x01;
// Input distro item chk
sav[(0xC94 + 0x1000 * sec[4] + currentSav)] = 0xAC;
sav[(0xC95 + 0x1000 * sec[4] + currentSav)] = 0x0;
sav[(0xC96 + 0x1000 * sec[4] + currentSav)] = 0x0;
sav[(0xC97 + 0x1000 * sec[4] + currentSav)] = 0x0;
// Input distro item
sav[(0xC98 + 0x1000 * sec[4] + currentSav)] = 0x01;
sav[(0xC99 + 0x1000 * sec[4] + currentSav)] = 0x97;
sav[(0xC9A + 0x1000 * sec[4] + currentSav)] = 0x13;
sav[(0xC9B + 0x1000 * sec[4] + currentSav)] = 0x01;
// Update section 2 checksums
char *ptr = sav + (0x1000 * sec[2] + currentSav);
int chk = Chksum(DATALEN, (int *)ptr);
sav[(0xFF6 + 0x1000 * sec[2] + currentSav)] = chk & 0x000000FF;
sav[(0xFF7 + 0x1000 * sec[2] + currentSav)] = (chk & 0x0000FF00) >> 8;
printf("Updating savegame section 2 checksum...(%04X)...", chk);
// Update section 4 checksums
ptr = sav + (0x1000 * sec[4] + currentSav);
chk = Chksum(DATALEN, (int *)ptr);
sav[(0xFF6 + 0x1000 * sec[4] + currentSav)] = chk & 0x000000FF;
sav[(0xFF7 + 0x1000 * sec[4] + currentSav)] = (chk & 0x0000FF00) >> 8;
printf("Updating savegame section 4 checksum...(%04X)...", chk);
} else {
// Inject Mistery Event
if (language == JAPANESE) {
memcpy(sav + (me_offset + 0x1000 * sec[4] + currentSav), me3,
1012); // Script data (chk(4) + association(4) + script(996)) +
// item data (8)
} else {
memcpy(sav + (me_offset + 0x1000 * sec[4] + currentSav), me3,
1012); // Script data (chk(4) + association(4) + script(996)) +
// item data (8)
}
// Update section 4 checksums
char *ptr = sav + (0x1000 * sec[4] + currentSav);
int chk = Chksum(DATALEN, (int *)ptr);
sav[(0xFF6 + 0x1000 * sec[4] + currentSav)] = chk & 0x000000FF;
sav[(0xFF7 + 0x1000 * sec[4] + currentSav)] = (chk & 0x0000FF00) >> 8;
printf("Updating savegame section 4 checksum...(%04X)...", chk);
}
return 1;
}

5
arm9/source/poke.h Normal file
View File

@ -0,0 +1,5 @@
#include "languages.h"
#include "supported_games.h"
int wc_inject(char* sav, char* wc3, SupportedGames games, Language language);
int me_inject(char* sav, char* me3, SupportedGames games, Language language);

View File

@ -7,32 +7,34 @@
*
* Copyright (C) Pokedoc (2010)
*/
/*
* 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
/*
* 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.
*
* This program 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 General Public License
*
* This program 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 General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
This file implements the functions and data structures required for localised messages.
This file implements the functions and data structures required for localised
messages.
*/
#include "strings.h"
#include "libini.h"
#include <nds.h>
#include "display.h"
#include "fileselect.h"
#include "globals.h"
#include "display.h"
#include "libini.h"
// fallback string resources
#include "strings_fallback.inc"
@ -46,163 +48,161 @@ char **message_strings;
// local functions
//
void AddString(uint32 id, ini_fd_t ini)
{
// first, try to read string from ini file
sprintf(txt, "%i", id);
bool found = false;
if (ini) {
if (ini_locateKey(ini, txt) == 0) {
if (ini_readString(ini, txt, 256) > 0) {
found = true;
}
}
}
void AddString(uint32 id, ini_fd_t ini) {
// first, try to read string from ini file
sprintf(txt, "%lu", id);
bool found = false;
if (ini) {
if (ini_locateKey(ini, txt) == 0) {
if (ini_readString(ini, txt, 256) > 0) {
found = true;
}
}
}
if (!found) {
// if no ini file was found, use the fallback striung provided here
message_strings[id] = const_cast<char*>(strings_fallback[id]);
} else {
// did load string, so prepare a buffer for it and move text
message_strings[id] = new char[strlen(txt)+1];
memcpy(message_strings[id], txt, strlen(txt)+1);
}
if (!found) {
// if no ini file was found, use the fallback striung provided here
message_strings[id] = const_cast<char *>(strings_fallback[id]);
} else {
// did load string, so prepare a buffer for it and move text
message_strings[id] = new char[strlen(txt) + 1];
memcpy(message_strings[id], txt, strlen(txt) + 1);
}
}
// ---------------------------------------------------
// global functions
//
bool stringsLoadFile(const char *fname)
{
bool stringsLoadFile(const char *fname) {
#ifdef DEBUG
iprintf("Trying to access strings file.\n");
iprintf("Trying to access strings file.\n");
#endif
// load ini file...
ini_fd_t ini = 0;
if (fileExists(fname))
ini = ini_open(fname, "r", "");
// On the DSi/sudokuhax platform, "fileExists" always returns true, so we need to test if
// we actually got something. This is merged in the macro, but we keep some debug output.
// load ini file...
ini_fd_t ini = 0;
if (fileExists(fname)) ini = ini_open(fname, "r", "");
// On the DSi/sudokuhax platform, "fileExists" always returns true, so we
// need to test if
// we actually got something. This is merged in the macro, but we keep some
// debug output.
#ifdef DEBUG
if (!ini) {
iprintf("Parsing %s failed!\n", fname);
}
if (!ini) {
iprintf("Parsing %s failed!\n", fname);
}
#endif
message_strings = new char*[STR_LAST];
if (ini)
ini_locateHeading(ini, "");
message_strings = new char *[STR_LAST];
if (ini) ini_locateHeading(ini, "");
#if 0
//#ifdef ENABLE_CUSTOM_FONT
// EXPERIMENTAL: load and init a custom font
if (ini_locateKey(ini, "font") == 0) {
ini_readString(ini, txt, 256);
if (strlen(txt)) {
if (fileExists(txt)) {
// load and init custon font; code borrowed from custom_font demo
u32 fs = fileSize(txt);
static u32 min_fs = 32*256;
if (fs >= min_fs) {
// TODO: maybe this should be a fixed size?
void *font0 = malloc(fileSize(txt));
FILE *file = fopen(txt, "rb");
fread(font0, 1, fs, file);
fclose(file);
// EXPERIMENTAL: load and init a custom font
if (ini_locateKey(ini, "font") == 0) {
ini_readString(ini, txt, 256);
if (strlen(txt)) {
if (fileExists(txt)) {
// load and init custon font; code borrowed from custom_font demo
u32 fs = fileSize(txt);
static u32 min_fs = 32*256;
if (fs >= min_fs) {
// TODO: maybe this should be a fixed size?
void *font0 = malloc(fileSize(txt));
FILE *file = fopen(txt, "rb");
fread(font0, 1, fs, file);
fclose(file);
// borrowed from libnds source
ConsoleFont font;
font.gfx = (u16*)font0 + (fs - 16*256); // 16 bit-pointer, so only "16*"
font.pal = 0; // single color!
font.numColors = 0;
font.numChars = 256; // this is fixed; it should be enough for everybody
font.bpp = 4; // 4 bits per pixel
font.asciiOffset = 0; // we cover 256 letters (well, we try)
font.convertSingleColor = true; // for now, we only want one color!
consoleSetFont(&upperScreen, &font);
consoleSetFont(&lowerScreen, &font);
free(font0);
}
}
}
}
// borrowed from libnds source
ConsoleFont font;
font.gfx = (u16*)font0 + (fs - 16*256); // 16 bit-pointer, so only "16*"
font.pal = 0; // single color!
font.numColors = 0;
font.numChars = 256; // this is fixed; it should be enough for everybody
font.bpp = 4; // 4 bits per pixel
font.asciiOffset = 0; // we cover 256 letters (well, we try)
font.convertSingleColor = true; // for now, we only want one color!
consoleSetFont(&upperScreen, &font);
consoleSetFont(&lowerScreen, &font);
free(font0);
}
}
}
}
#endif
AddString(STR_EMPTY, ini);
AddString(STR_STR, ini);
//
AddString(STR_MM_WIPE, ini);
AddString(STR_TITLE_MSG, ini);
AddString(STR_BOOT_NO_INI, ini);
AddString(STR_BOOT_MODE_UNSUPPORTED, ini);
AddString(STR_BOOT_DLDI_ERROR, ini);
//
AddString(STR_HW_SWAP_CARD, ini);
AddString(STR_HW_CARD_UNREADABLE, ini);
AddString(STR_HW_WRONG_GAME, ini);
AddString(STR_HW_PLEASE_REBOOT, ini);
//
AddString(STR_HW_SELECT_FILE, ini);
AddString(STR_HW_SELECT_FILE_OW, ini);
AddString(STR_HW_SEEK_UNUSED_FNAME, ini);
AddString(STR_ERR_NO_FNAME, ini);
//
AddString(STR_HW_FORMAT_GAME, ini);
AddString(STR_HW_WRITE_GAME, ini);
AddString(STR_HW_READ_GAME, ini);
AddString(STR_HW_WRITE_FILE, ini);
AddString(STR_HW_READ_FILE, ini);
//
AddString(STR_HW_3IN1_FORMAT_NOR, ini);
AddString(STR_HW_3IN1_PREPARE_REBOOT, ini);
AddString(STR_HW_3IN1_PLEASE_REBOOT, ini);
AddString(STR_HW_3IN1_CLEAR_FLAG, ini);
AddString(STR_HW_3IN1_DONE_DUMP, ini);
AddString(STR_HW_3IN1_ERR_IDMODE, ini);
AddString(STR_HW_3IN1_ERR_NOR, ini);
//
AddString(STR_HW_FTP_SEEK_AP, ini);
AddString(STR_HW_FTP_ERR_AP, ini);
AddString(STR_HW_FTP_SEEK_FTP, ini);
AddString(STR_HW_FTP_ERR_FTP, ini);
AddString(STR_HW_FTP_LOGIN, ini);
AddString(STR_HW_FTP_ERR_LOGIN, ini);
AddString(STR_HW_FTP_DIR, ini);
AddString(STR_HW_FTP_SLOW, ini);
AddString(STR_HW_FTP_READ_ONLY, ini);
//
AddString(STR_HW_WARN_DELETE, ini);
AddString(STR_HW_DID_DELETE, ini);
//
AddString(STR_FS_READ, ini);
AddString(STR_FS_WRITE, ini);
//
AddString(STR_EMPTY, ini);
AddString(STR_STR, ini);
//
AddString(STR_TITLE_MSG, ini);
AddString(STR_BOOT_NO_INI, ini);
AddString(STR_BOOT_MODE_UNSUPPORTED, ini);
AddString(STR_BOOT_DLDI_ERROR, ini);
//
AddString(STR_HW_SWAP_CARD, ini);
AddString(STR_HW_SWAP_CARD_CANCEL, ini);
AddString(STR_HW_CARD_UNREADABLE, ini);
AddString(STR_HW_WRONG_GAME, ini);
AddString(STR_HW_PLEASE_REBOOT, ini);
//
AddString(STR_HW_SELECT_FILE, ini);
AddString(STR_HW_SELECT_FILE_OW, ini);
AddString(STR_HW_SEEK_UNUSED_FNAME, ini);
AddString(STR_ERR_NO_FNAME, ini);
//
AddString(STR_HW_FORMAT_GAME, ini);
AddString(STR_HW_WRITE_GAME, ini);
AddString(STR_HW_READ_GAME, ini);
AddString(STR_HW_WRITE_FILE, ini);
AddString(STR_HW_READ_FILE, ini);
//
AddString(STR_HW_3IN1_FORMAT_NOR, ini);
AddString(STR_HW_3IN1_PREPARE_REBOOT, ini);
AddString(STR_HW_3IN1_PLEASE_REBOOT, ini);
AddString(STR_HW_3IN1_CLEAR_FLAG, ini);
AddString(STR_HW_3IN1_DONE_DUMP, ini);
AddString(STR_HW_3IN1_ERR_IDMODE, ini);
AddString(STR_HW_3IN1_ERR_NOR, ini);
//
AddString(STR_HW_FTP_SEEK_AP, ini);
AddString(STR_HW_FTP_ERR_AP, ini);
AddString(STR_HW_FTP_SEEK_FTP, ini);
AddString(STR_HW_FTP_ERR_FTP, ini);
AddString(STR_HW_FTP_LOGIN, ini);
AddString(STR_HW_FTP_ERR_LOGIN, ini);
AddString(STR_HW_FTP_DIR, ini);
AddString(STR_HW_FTP_SLOW, ini);
AddString(STR_HW_FTP_READ_ONLY, ini);
//
AddString(STR_HW_WARN_DELETE, ini);
AddString(STR_HW_DID_DELETE, ini);
//
AddString(STR_FS_READ, ini);
AddString(STR_FS_WRITE, ini);
//
AddString(STR_MM_WIPE, ini);
// delete temp file (which is a remnant of inilib)
remove("/tmpfile");
// Convert manual newline commands added as plaintext in the translation file.
for (int i = 0; i < STR_LAST; i++) {
char *ptr = message_strings[i];
while ((ptr = strchr(ptr, '\\')) != NULL) {
if (strlen(ptr+1)) {
if (ptr[1] == 'n') {
ptr[0] = '\n';
memmove(ptr+1, ptr+2, strlen(ptr)-1);
}
}
}
}
return true;
// delete temp file (which is a remnant of inilib)
remove("/tmpfile");
// Convert manual newline commands added as plaintext in the translation file.
for (int i = 0; i < STR_LAST; i++) {
char *ptr = message_strings[i];
while ((ptr = strchr(ptr, '\\')) != NULL) {
if (strlen(ptr + 1)) {
if (ptr[1] == 'n') {
ptr[0] = '\n';
memmove(ptr + 1, ptr + 2, strlen(ptr) - 1);
}
}
}
}
return true;
}
const char *stringsGetMessageString(int id)
{
if (id > STR_LAST)
return 0;
else
return message_strings[id];
const char *stringsGetMessageString(int id) {
if (id > STR_LAST)
return 0;
else
return message_strings[id];
}

View File

@ -7,19 +7,19 @@
*
* Copyright (C) Pokedoc (2010)
*/
/*
* 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
/*
* 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.
*
* This program 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 General Public License
*
* This program 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 General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
@ -31,69 +31,71 @@
#define STRINGS_H
enum {
// internal message IDs (do not translate!)
STR_EMPTY,
STR_STR,
//
// boot messages (2-5)
STR_TITLE_MSG,
STR_BOOT_NO_INI,
STR_BOOT_MODE_UNSUPPORTED,
STR_BOOT_DLDI_ERROR,
//
// swap card messages (6-9)
STR_HW_SWAP_CARD,
STR_HW_WRONG_GAME,
STR_HW_CARD_UNREADABLE,
STR_HW_PLEASE_REBOOT,
//
// file select messages (10-13)
STR_HW_SELECT_FILE,
STR_HW_SELECT_FILE_OW,
STR_HW_SEEK_UNUSED_FNAME,
STR_ERR_NO_FNAME,
//
// shared messages messages (14-18)
STR_HW_FORMAT_GAME,
STR_HW_WRITE_GAME,
STR_HW_READ_GAME,
STR_HW_WRITE_FILE,
STR_HW_READ_FILE,
//
// 3in1 messages (19-25)
STR_HW_3IN1_FORMAT_NOR,
STR_HW_3IN1_PREPARE_REBOOT,
STR_HW_3IN1_PLEASE_REBOOT,
STR_HW_3IN1_CLEAR_FLAG,
STR_HW_3IN1_DONE_DUMP,
STR_HW_3IN1_ERR_IDMODE,
STR_HW_3IN1_ERR_NOR,
//
// FTP specific messages (26-3)
STR_HW_FTP_SEEK_AP,
STR_HW_FTP_ERR_AP,
STR_HW_FTP_SEEK_FTP,
STR_HW_FTP_ERR_FTP,
STR_HW_FTP_LOGIN,
STR_HW_FTP_ERR_LOGIN,
STR_HW_FTP_DIR,
STR_HW_FTP_SLOW,
STR_HW_FTP_READ_ONLY,
//
// delete messages (35-36)
STR_HW_WARN_DELETE,
STR_HW_DID_DELETE,
//
// more messages for the file select widget (37-38)
STR_FS_READ,
STR_FS_WRITE,
// messages for the main menu (39)
STR_MM_WIPE,
//
STR_LAST
// internal message IDs (do not translate!)
STR_EMPTY,
STR_STR,
//
// boot messages (2-5)
STR_TITLE_MSG,
STR_BOOT_NO_INI,
STR_BOOT_MODE_UNSUPPORTED,
STR_BOOT_DLDI_ERROR,
//
// swap card messages (6-9)
STR_HW_SWAP_CARD,
STR_HW_SWAP_CARD_CANCEL,
STR_HW_CARD_UNREADABLE,
STR_HW_WRONG_GAME,
STR_HW_PLEASE_REBOOT,
//
// file select messages (10-13)
STR_HW_SELECT_FILE,
STR_HW_SELECT_FILE_OW,
STR_HW_SEEK_UNUSED_FNAME,
STR_ERR_NO_FNAME,
//
// shared messages messages (14-18)
STR_HW_FORMAT_GAME,
STR_HW_WRITE_GAME,
STR_HW_READ_GAME,
STR_HW_WRITE_FILE,
STR_HW_READ_FILE,
//
// 3in1 messages (19-25)
STR_HW_3IN1_FORMAT_NOR,
STR_HW_3IN1_PREPARE_REBOOT,
STR_HW_3IN1_PLEASE_REBOOT,
STR_HW_3IN1_CLEAR_FLAG,
STR_HW_3IN1_DONE_DUMP,
STR_HW_3IN1_ERR_IDMODE,
STR_HW_3IN1_ERR_NOR,
//
// FTP specific messages (26-3)
STR_HW_FTP_SEEK_AP,
STR_HW_FTP_ERR_AP,
STR_HW_FTP_SEEK_FTP,
STR_HW_FTP_ERR_FTP,
STR_HW_FTP_LOGIN,
STR_HW_FTP_ERR_LOGIN,
STR_HW_FTP_DIR,
STR_HW_FTP_SLOW,
STR_HW_FTP_READ_ONLY,
//
// delete messages (35-36)
STR_HW_WARN_DELETE,
STR_HW_DID_DELETE,
//
// more messages for the file select widget (37-38)
STR_FS_READ,
STR_FS_WRITE,
//
// messages for the main menu (39)
STR_MM_WIPE,
//
STR_LAST
};
bool stringsLoadFile(const char *fname);
const char *stringsGetMessageString(int id = 0);
#endif // STRINGS_H
#endif // STRINGS_H

View File

@ -3,23 +3,24 @@
* DS cartridges. Nintendo DS and all derivative names are trademarks
* by Nintendo. EZFlash 3-in-1 is a trademark by EZFlash.
*
* strings_fallback.inc: Hard-coded strings to be used if no translation is provided
* strings_fallback.inc: Hard-coded strings to be used if no translation is
* provided
*
* Copyright (C) Pokedoc (2010)
*/
/*
* 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
/*
* 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.
*
* This program 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 General Public License
*
* This program 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 General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
@ -27,53 +28,93 @@
*/
const char *strings_fallback[STR_LAST] = {
/* STR_EMPTY */ "",
/* STR_STR */ "%s",
//
/* STR_MM_WIPE */ "\n WIPES OUT ALL SAVE DATA\n ON YOUR GAME !",
/* STR_TITLE_MSG */ "DS savegame manager\nVersion %i.%i.%i%s\nBy Pokedoc",
/* STR_BOOT_NO_INI */ "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.",
/* STR_BOOT_MODE_UNSUPPORTED */ "This mode is DISABLED.\nPlease restart the system.",
/* STR_BOOT_DLDI_ERROR */ "DLDI initialisation error!",
//
/* STR_HW_SWAP_CARD */ "Please take out Slot 1 flash card and insert a game.\nPress A when done.",
/* STR_HW_CARD_UNREADABLE */ "I can't read the game inserted in slot 1.\nPlease eject and retry.",
/* STR_HW_WRONG_GAME */ "This game has a save chip that is bigger than the save you are going to write. Please insert a different game.\nPress A when done.",
/* STR_HW_PLEASE_REBOOT */ "Done! Please power off\n(and restart if you want to do more).",
//
/* STR_HW_SELECT_FILE */ "Please select a .sav file.",
/* STR_HW_SELECT_FILE_OW */ "Please select a file to overwrite, or press L+R in a folder to create a new file.",
/* STR_HW_SEEK_UNUSED_FNAME */ "Please wait... searching for an unused filename.\nTrying: %s",
/* STR_ERR_NO_FNAME */ "ERROR: Unable to get an unused nfilename! This means that you have more than 65536 saves!\n(wow!)",
//
/* STR_HW_FORMAT_GAME */ "Preparing to write to your game.\nPlease wait...",
/* STR_HW_WRITE_GAME */ "Writing save to your game.\nPlease wait...",
/* STR_HW_READ_GAME */ "Reading save from your game.\nPlease wait...",
/* STR_HW_WRITE_FILE */ "Writing file:\n%s",
/* STR_HW_READ_FILE */ "Reading file:\n%s",
//
/* STR_HW_3IN1_FORMAT_NOR */ "Preparing to write to the 3in1.\nPlease wait...",
/* STR_HW_3IN1_PREPARE_REBOOT */ "Preparing reboot...",
/* STR_HW_3IN1_PLEASE_REBOOT */ "Save has been written to the 3in1. Please power off and restart this tool to finish the dump.",
/* STR_HW_3IN1_CLEAR_FLAG */ "Preparing to dump your save...\nPlease wait...",
/* STR_HW_3IN1_DONE_DUMP */ "Done. Your game save has been dumped using your 3in1. Filename:\n%s\nPress (B) to continue.",
/* STR_HW_3IN1_ERR_IDMODE */ "ERROR!\nID mode still active!",
/* STR_HW_3IN1_ERR_NOR */ "ERROR!\nWriting to NOR failed!",
//
/* STR_HW_FTP_SEEK_AP */ "Connecting to an access point...\nplease wait...",
/* STR_HW_FTP_ERR_AP */ "ERROR!\nCould not find a compatible Access Point. Please configure your WiFi Connection from a WiFi-enabled game!",
/* STR_HW_FTP_SEEK_FTP */ "Connecting to an FTP server...\nplease wait...",
/* STR_HW_FTP_ERR_FTP */ "ERROR!\nCould not find an FTP server. Please refer to the documentation.",
/* STR_HW_FTP_LOGIN */ "Logging in...",
/* STR_HW_FTP_ERR_LOGIN */ "ERROR!\nCould not log in to the FTP server. Please verify your username and password are correct in your ini file.",
/* STR_HW_FTP_DIR */ "Reading FTP directory...",
/* STR_HW_FTP_SLOW */ "FTP is slow, please wait...",
/* STR_HW_FTP_READ_ONLY */ "WARNING:\nCould not write to your FTP server! Maybe you forgot to enable write access?",
//
/* STR_HW_WARN_DELETE */ "This will WIPE OUT your entire save! ARE YOU SURE?\n\nPress R+up+Y to confim!",
/* STR_HW_DID_DELETE */ "Done. Your game save has been PERMANENTLY deleted.\n\nPlease restart your DS.",
//
/* STR_FS_READ */ "Please select a .sav file\n (A) Select\n (B) One directory up\n",
/* STR_FS_WRITE */ "Please select a .sav file\n (A) Select\n (B) One directory up\n (L+R) cancel (new file)"
/* STR_EMPTY */ "",
/* STR_STR */ "%s",
//
/* f */
"Pokemon Generation 3 Event Distribution by suloku.\nVersion %i.%i.%i%s by "
"mrhappyasthma\n\nBased on DS savegame manager by Pokedoc",
/* STR_BOOT_NO_INI */
"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.",
/* STR_BOOT_MODE_UNSUPPORTED */
"This mode is DISABLED.\nPlease restart the system.",
/* STR_BOOT_DLDI_ERROR */ "DLDI initialisation error!",
//
/* STR_HW_SWAP_CARD */
"Please take out Slot 1 flash card and insert a game.\nPress A when done.",
/* STR_HW_SWAP_CARD_CANCEL */
"Please take out Slot 1 flash card and insert a game.\nPress A when "
"done.\nPress B to cancel.",
/* STR_HW_CARD_UNREADABLE */
"Can't read the game inserted in slot 1.\nPlease eject and reinsert "
"game.\nPress A when done.",
/* STR_HW_WRONG_GAME */
"This game has a save chip that is bigger than the save you are going to "
"write. Please insert a different game.\nPress A when done.",
/* STR_HW_PLEASE_REBOOT */
"Done! Please power off\n(and restart if you want to do more).",
//
/* STR_HW_SELECT_FILE */ "Please select a .sav file.",
/* STR_HW_SELECT_FILE_OW */
"Please select a file to overwrite, or press L+R in a folder to create a "
"new file.",
/* STR_HW_SEEK_UNUSED_FNAME */
"Please wait... searching for an unused filename.\nTrying: %s",
/* STR_ERR_NO_FNAME */
"ERROR: Unable to get an unused nfilename! This means that you have more "
"than 65536 saves!\n(wow!)",
//
/* STR_HW_FORMAT_GAME */ "Preparing to write to your game.\nPlease wait...",
/* STR_HW_WRITE_GAME */ "Writing save to your game.\nPlease wait...",
/* STR_HW_READ_GAME */ "Reading save from your game.\nPlease wait...",
/* STR_HW_WRITE_FILE */ "Writing file:\n%s",
/* STR_HW_READ_FILE */ "Reading file:\n%s",
//
/* STR_HW_3IN1_FORMAT_NOR */
"Preparing to write to the 3in1.\nPlease wait...",
/* STR_HW_3IN1_PREPARE_REBOOT */ "Preparing reboot...",
/* STR_HW_3IN1_PLEASE_REBOOT */
"Save has been written to the 3in1. Please power off and restart this tool "
"to finish the dump.",
/* STR_HW_3IN1_CLEAR_FLAG */
"Preparing to dump your save...\nPlease wait...",
/* STR_HW_3IN1_DONE_DUMP */
"Done. Your game save has been dumped using your 3in1. "
"Filename:\n%s\nPress (B) to continue.",
/* STR_HW_3IN1_ERR_IDMODE */ "ERROR!\nID mode still active!",
/* STR_HW_3IN1_ERR_NOR */ "ERROR!\nWriting to NOR failed!",
//
/* STR_HW_FTP_SEEK_AP */ "Connecting to an access point...\nplease wait...",
/* STR_HW_FTP_ERR_AP */
"ERROR!\nCould not find a compatible Access Point. Please configure your "
"WiFi Connection from a WiFi-enabled game!",
/* STR_HW_FTP_SEEK_FTP */ "Connecting to an FTP server...\nplease wait...",
/* STR_HW_FTP_ERR_FTP */
"ERROR!\nCould not find an FTP server. Please refer to the documentation.",
/* STR_HW_FTP_LOGIN */ "Logging in...",
/* STR_HW_FTP_ERR_LOGIN */
"ERROR!\nCould not log in to the FTP server. Please verify your username "
"and password are correct in your ini file.",
/* STR_HW_FTP_DIR */ "Reading FTP directory...",
/* STR_HW_FTP_SLOW */ "FTP is slow, please wait...",
/* STR_HW_FTP_READ_ONLY */
"WARNING:\nCould not write to your FTP server! Maybe you forgot to enable "
"write access?",
//
/* STR_HW_WARN_DELETE */
"This will WIPE OUT your entire save! ARE YOU SURE?\n\nPress R+up+Y to "
"confim!",
/* STR_HW_DID_DELETE */
"Done. Your game save has been PERMANENTLY deleted.\n\nPlease restart your "
"DS.",
//
/* STR_FS_READ */
"Please select a .sav file\n (A) Select\n (B) One directory up\n",
/* STR_FS_WRITE */
"Please select a .sav file\n (A) Select\n (B) One directory up\n "
"(L+R) cancel (new file)",
//
/* STR_MM_WIPE */ "\n WIPES OUT ALL SAVE DATA\n ON YOUR GAME !",
};

View File

@ -0,0 +1,11 @@
#ifndef SUPPORTED_GAMES_H
#define SUPPORTED_GAMES_H
enum SupportedGames {
UNKNOWN_GAMES = -1,
RUBY_AND_SAPPHIRE = 0,
EMERALD = 1,
FIRE_RED_AND_LEAF_GREEN = 2,
};
#endif /* SUPPORTED_GAMES_H */

View File

@ -21,42 +21,34 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ini.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
* 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;
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 (!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;
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
@ -69,54 +61,44 @@ static int __ini_read (ini_t *ini, size_t *size)
* 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);
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
#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 :
* 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
* 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;
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;
// 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;
// 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);
// 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.
@ -129,40 +111,32 @@ static struct key_tag *__ini_write (ini_t *ini)
* Rev | Date | By | Comment
* ----------------------------------------------------------------------------------------------------------------
********************************************************************************************************************/
int INI_LINKAGE ini_readString (ini_fd_t fd, char *str, size_t size)
{
ini_t *ini = (ini_t *) fd;
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;
// 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);
}
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;
str[size] = '\0';
__ini_strtrim(str);
return (int)size;
}
/********************************************************************************************************************
* Function : ini_writeString
* Parameters : ini - pointer to ini file database.
@ -171,28 +145,25 @@ int INI_LINKAGE ini_readString (ini_fd_t fd, char *str, size_t size)
* 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
* : 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;
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;
_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;
// 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.
@ -205,35 +176,27 @@ int INI_LINKAGE ini_writeString (ini_fd_t fd, const char *str)
* Rev | Date | By | Comment
* ----------------------------------------------------------------------------------------------------------------
********************************************************************************************************************/
int INI_LINKAGE ini_readInt (ini_fd_t fd, int *value)
{
ini_t *ini = (ini_t *) fd;
int ret = 0;
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 (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;
if (ret == 1) return 0;
return -1;
}
#ifdef INI_ADD_EXTRAS
/********************************************************************************************************************
@ -248,35 +211,27 @@ int INI_LINKAGE ini_readInt (ini_fd_t fd, int *value)
* Rev | Date | By | Comment
* ----------------------------------------------------------------------------------------------------------------
********************************************************************************************************************/
int INI_LINKAGE ini_readLong (ini_fd_t fd, long *value)
{
ini_t *ini = (ini_t *) fd;
int ret = 0;
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 (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;
if (ret == 1) return 0;
return -1;
}
/********************************************************************************************************************
* Function : ini_readDouble
* Parameters : ini - pointer to ini file database.
@ -284,40 +239,33 @@ int INI_LINKAGE ini_readLong (ini_fd_t fd, long *value)
* 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)
* 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;
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 (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;
if (ret == 1) return 0;
return -1;
}
/********************************************************************************************************************
* Function : ini_readBool
* Parameters : ini - pointer to ini file database.
@ -325,74 +273,64 @@ int INI_LINKAGE ini_readDouble (ini_fd_t fd, double *value)
* 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.
* 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] = "";
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);
}
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++;
}
{ // Convert string to lower case
char *p = buffer;
while (*p != '\0') {
*p = (char)tolower(*p);
p++;
}
}
// Decode supported bool types
switch (*buffer)
{
// Decode supported bool types
switch (*buffer) {
case '0':
case '1':
if (buffer[1] != '\0')
return -1;
*value = *buffer - '0';
break;
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;
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.
@ -406,25 +344,22 @@ int INI_LINKAGE ini_readBool (ini_fd_t fd, int *value)
* 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;
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;
_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;
// 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.
@ -438,25 +373,22 @@ int INI_LINKAGE ini_writeInt (ini_fd_t fd, int value)
* 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;
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;
_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;
// 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.
@ -470,25 +402,22 @@ int INI_LINKAGE ini_writeLong (ini_fd_t fd, long value)
* 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;
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;
_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;
// 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.
@ -502,29 +431,26 @@ int INI_LINKAGE ini_writeDouble (ini_fd_t fd, double value)
* 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;
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;
// Check if value is legal
if ((value < 0) || (value > 1)) return -1;
_key = __ini_write (ini);
if (!_key)
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;
// 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
#endif // INI_ADD_EXTRAS

View File

@ -1 +0,0 @@
<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="display.d"></File><File path="display.o"></File><File path="dsCard.d"></File><File path="dsCard.o"></File><File path="dsi.d"></File><File path="dsi.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="globals.d"></File><File path="globals.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><File path="strings.d"></File><File path="strings.o"></File></MagicFolder><MagicFolder excludeFolders="CVS;.svn" filter="*" name="debug" path="debug\"></MagicFolder><MagicFolder excludeFolders="CVS;.svn" filter="*" name="source" path="source\"><File path="auxspi.cpp"></File><File path="auxspi.h"></File><File path="auxspi_core.inc"></File><File path="display.cpp"></File><File path="display.h"></File><File path="dsCard.cpp"></File><File path="dsCard.h"></File><File path="dsi.cpp"></File><File path="dsi.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="globals.cpp"></File><File path="globals.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="strings.cpp"></File><File path="strings.h"></File><File path="strings_fallback.inc"></File><File path="types.i"></File></MagicFolder><File path="Makefile"></File><File path="Makefile.debug"></File><File path="savegame_manager.elf"></File></MagicFolder><MagicFolder excludeFolders="CVS;.svn" filter="*" name="arm7" path="arm7\"><MagicFolder excludeFolders="CVS;.svn" filter="*" name="build" path="build\"><File path=".map"></File><File path="arm7.d"></File><File path="arm7.o"></File></MagicFolder><MagicFolder excludeFolders="CVS;.svn" filter="*" name="debug" path="debug\"></MagicFolder><MagicFolder excludeFolders="CVS;.svn" filter="*" name="source" path="source\"><File path="arm7.c"></File></MagicFolder><File path="Makefile"></File><File path="Makefile.debug"></File><File path="savegame_manager.elf"></File></MagicFolder><File path="Makefile"></File></Project>