mirror of
https://github.com/suloku/savegame-manager.git
synced 2026-04-24 15:07:06 -05:00
Merge 156c35969c into d9f885abe8
This commit is contained in:
commit
9c1ac9588d
10
.gitignore
vendored
Normal file
10
.gitignore
vendored
Normal 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
|
||||
|
|
@ -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.
|
||||
|
|
|
|||
2
Makefile
2
Makefile
|
|
@ -7,7 +7,7 @@ endif
|
|||
|
||||
include $(DEVKITARM)/ds_rules
|
||||
|
||||
export TARGET := savegame_manager
|
||||
export TARGET := NDSEventTool
|
||||
export TOPDIR := $(CURDIR)
|
||||
|
||||
|
||||
|
|
|
|||
75
README.md
Normal file
75
README.md
Normal 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`.
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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
|
|
@ -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 文件的第二版
|
||||
* 日期:2006年11月27日11点33分 第一版 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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
2206
arm9/source/ftplib.c
2206
arm9/source/ftplib.c
File diff suppressed because it is too large
Load Diff
|
|
@ -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
|
||||
|
|
|
|||
1001
arm9/source/gba.cpp
1001
arm9/source/gba.cpp
File diff suppressed because it is too large
Load Diff
|
|
@ -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__
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
1346
arm9/source/ini.cpp
1346
arm9/source/ini.cpp
File diff suppressed because it is too large
Load Diff
|
|
@ -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_
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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_
|
||||
|
|
|
|||
|
|
@ -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_
|
||||
|
|
|
|||
|
|
@ -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_
|
||||
|
|
|
|||
|
|
@ -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
13
arm9/source/languages.h
Normal 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 */
|
||||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
1412
arm9/source/main.cpp
1412
arm9/source/main.cpp
File diff suppressed because it is too large
Load Diff
2622
arm9/source/me.h
Normal file
2622
arm9/source/me.h
Normal file
File diff suppressed because it is too large
Load Diff
373
arm9/source/poke.cpp
Normal file
373
arm9/source/poke.cpp
Normal 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
5
arm9/source/poke.h
Normal 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);
|
||||
|
|
@ -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];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 !",
|
||||
};
|
||||
|
|
|
|||
11
arm9/source/supported_games.h
Normal file
11
arm9/source/supported_games.h
Normal 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 */
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
Loading…
Reference in New Issue
Block a user