Fixed a bug in XD: the map+script data was being wiped out.

Some refactoring in LibPkmGC.
This commit is contained in:
TuxSH 2015-09-26 23:31:23 +02:00
parent 7f27abdbcf
commit 4d29306c6f
43 changed files with 1097 additions and 379 deletions

View File

@ -1,3 +1,7 @@
###PkmGCTools v1.1.2:
Fixed a bug in XD: the map+script data was being wiped out.
Some refactoring in LibPkmGC.
###PkmGCTools v1.1.1:
Fixed a lot of critical bugs (affecting IVs, etc...). Money and Pokécoupons are now limited to 9,999,999. Bag items are limited to 99 again in Pokémon Colosseum Fixed a lot of critical bugs (affecting IVs, etc...)
(use the PC storage system to fix bag entries with more than 99 items).

View File

@ -39,7 +39,7 @@ public:
DaycareData* create(void) const;
DaycareData(XD::DaycareData const& other);
private:
protected:
void loadFields(void);
};

View File

@ -19,6 +19,7 @@
#ifndef _LIBPKMGC_XD_COMMON_EVERYTHING_H
#define _LIBPKMGC_XD_COMMON_EVERYTHING_H
#include <LibPkmGC/Colosseum/Common/GameConfigData.h>
#include <LibPkmGC/Colosseum/Common/PlayerData.h>
#include <LibPkmGC/Colosseum/Common/PCData.h>
#include <LibPkmGC/Colosseum/Common/PlayerData.h>

View File

@ -0,0 +1,66 @@
/*
* Copyright (C) TuxSH 2015
* This file is part of LibPkmGC.
*
* LibPkmGC is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LibPkmGC 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with LibPkmGC. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _LIBPKMGC_COLOSSEUM_GAME_CONFIG_DATA_H
#define _LIBPKMGC_COLOSSEUM_GAME_CONFIG_DATA_H
#include <LibPkmGC/GC/Common/GameConfigData.h>
namespace LibPkmGC {
namespace Colosseum {
/*
Game configuration substructure (off 0 (total 0xa8)) :
0x00: VersionInfo version
0x04: u32 headerChecksum
0x08: u64/u32[2] memcardUID : memcard[0:8] xor memcard[8:16] xor memcard[16:24] iirc
0x10: **ENCRYPTED DATA**
0x10: u32 storyModeSaveCount // saveCount minus the number of times the rules were saved
0x18: u32 = 0
0x29: u8 noRumble
0x2a: u16 titleScreenLanguage;
*/
class LIBPKMGC_DECL GameConfigData :
public GC::GameConfigData
{
public:
static const size_t size = 0x70;
GameConfigData(void);
GameConfigData(GameConfigData const& other);
GameConfigData(const u8* inData);
~GameConfigData(void);
GameConfigData* clone(void) const;
GameConfigData* create(void) const;
void save(void);
protected:
void loadFields(void);
private:
GameConfigData(XD::GameConfigData const& other);
};
}
}
#endif

View File

@ -20,17 +20,14 @@
#define _LIBPKMGC_COLOSSEUM_PLAYER_DATA_H
#include <LibPkmGC/GC/Common/PlayerData.h>
#include <LibPkmGC/Colosseum/Common/Pokemon.h>
#include <LibPkmGC/Colosseum/Common/TrainerData.h>
#include <LibPkmGC/Colosseum/Common/BagData.h>
namespace LibPkmGC {
namespace Colosseum {
/*
0x00 -- 0x2b: trainer name (10+1 chars) + copy
0x2c: u16 SID
0x2e: u16 TID
0x30: Pokémon Party (6*0xc4)
0x00: TrainerData trainer
0x780: bag

View File

@ -0,0 +1,49 @@
/*
* Copyright (C) TuxSH 2015
* This file is part of LibPkmGC.
*
* LibPkmGC is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LibPkmGC 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with LibPkmGC. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _LIBPKMGC_COLOSSEUM_TRAINER_DATA_H
#define _LIBPKMGC_COLOSSEUM_TRAINER_DATA_H
#include <LibPkmGC/GC/Common/TrainerData.h>
#include <LibPkmGC/Colosseum/Common/Pokemon.h>
namespace LibPkmGC {
namespace Colosseum {
class LIBPKMGC_DECL TrainerData :
public GC::TrainerData
{
public:
static const size_t size = 0x780;
TrainerData(void);
TrainerData(TrainerData const& other);
TrainerData(const u8* inData);
~TrainerData(void);
TrainerData* clone(void) const;
TrainerData* create(void) const;
TrainerData(XD::TrainerData const& other);
protected:
void loadFields(void);
};
}
}
#endif

View File

@ -31,25 +31,16 @@ namespace SaveEditing {
size = 0x1e000
0x00: u32 magic
0x04: u32 saveCount
** Metadata / game config
0x08: VersionInfo version
0x0c: u32 headerChecksum
0x10: u64/u32[2] memcardUID : memcard[0:8] xor memcard[8:16] xor memcard[16:24] iirc
0x08: **PARTIALLY UNENCRYPTED game config
0x18: **ENCRYPTED DATA**
0x78: game config end
0x18: u32 storyModeSaveCount // saveCount minus the number of times the rules were saved
0x20: u32 = 0
0x31: u8 noRumble
0x32: u16 titleScreenLanguage;
0x78: **END OF METADATA
0x78: other substructures. In Pokémon Colosseum, they are strictly contiguous with no trash bytes in between.
0x78: substructures. In Pokémon Colosseum, they are strictly contiguous with no trash bytes in between.
(end)-40: **END OF ENCRYPTED DATA**
(end)-60: **END OF ENCRYPTED DATA**
(end)-60: u8 checksum[20]; // sha1 digest
(end)-40: u8 randomBytes[40];
(end)-40: u8 checksum[20]; // sha1 digest
(end)-20: u8 randomBytes[20];
*/
@ -80,7 +71,6 @@ public:
void saveEncrypted(u8* outBuf);
s32 storyModeSaveCount;
u8 checksum[20]; // digest
void fixBugsAffectingPokemon(void);

View File

@ -22,7 +22,7 @@
#include <boost/config/warning_disable.hpp>
#include <boost/config.hpp>
#define LIBPKMGC_VERSION 1001001
#define LIBPKMGC_VERSION 1001002
#define LIBPKMGC_VERSION_MAJOR ((LIBPKMGC_VERSION / 1000000) % 1000)
#define LIBPKMGC_VERSION_MINOR ((LIBPKMGC_VERSION / 1000) % 1000)
#define LIBPKMGC_VERSION_BUILD (LIBPKMGC_VERSION % 1000)

View File

@ -95,6 +95,7 @@ for(int i__ = 0; i__ < sz; ++i__) ar##_tmp |= ((ar[i__]) ? 1U : 0U) << (8*sizeof
#define SV_SUBSTRUCTURE(type, fld, off) fld->save(); std::copy(fld->data, fld->data + type::size, data + off);
#define SV_SUBSTRUCTURE2(type, fld, off) fld->save(); std::copy(fld->data, fld->data + fld->getSize(), data + off);
#define SV_SUBSTRUCTURE_ARRAY(type, ar, sz, off) for(size_t i__ = 0; i__ < sz; ++i__) { SV_SUBSTRUCTURE(type, ar[i__], off+type::size*i__); }
#define SV_SUBSTRUCTURE_ARRAY2(type, ar, sz, off) for(size_t i__ = 0; i__ < sz; ++i__) { SV_SUBSTRUCTURE2(type, ar[i__], off+ar[0]->getSize()*i__); }

View File

@ -19,6 +19,7 @@
#ifndef _LIBPKMGC_GC_COMMON_EVERYTHING_H
#define _LIBPKMGC_GC_COMMON_EVERYTHING_H
#include <LibPkmGC/GC/Common/GameConfigData.h>
#include <LibPkmGC/GC/Common/PlayerData.h>
#include <LibPkmGC/GC/Common/PCData.h>
#include <LibPkmGC/GC/Common/PlayerData.h>

View File

@ -0,0 +1,63 @@
/*
* Copyright (C) TuxSH 2015
* This file is part of LibPkmGC.
*
* LibPkmGC is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LibPkmGC 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with LibPkmGC. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _LIBPKMGC_GC_GAME_CONFIG_DATA_H
#define _LIBPKMGC_GC_GAME_CONFIG_DATA_H
#include <LibPkmGC/Base/DataStruct.h>
#include <LibPkmGC/Core/PokemonInfo.h>
namespace LibPkmGC {
LIBPKMGC_FWD_DECL_GC_CLS(GameConfigData)
namespace GC {
class LIBPKMGC_DECL GameConfigData :
public Base::DataStruct
{
public:
GameConfigData(size_t inSize, const u8* inData = NULL);
virtual ~GameConfigData(void);
virtual GameConfigData* clone(void) const = 0;
virtual GameConfigData* create(void) const = 0;
virtual void swap(GameConfigData& other);
virtual GameConfigData& operator=(GameConfigData const& other);
VersionInfo version;
s32 headerChecksum; // definition and location vary across Colosseum and XD
u32 memcardUID[2]; // u64. memcard[0:8] xor memcard[8:16] xor memcard[16:24] iirc
s32 storyModeSaveCount;
LanguageIndex titleScreenLanguage;
bool noRumble;
virtual void save(void);
protected:
GameConfigData(GameConfigData const& other);
void deleteFields(void);
virtual void loadFields(void);
};
}
}
#endif

View File

@ -19,7 +19,7 @@
#ifndef _LIBPKMGC_GC_PLAYER_DATA_H
#define _LIBPKMGC_GC_PLAYER_DATA_H
#include <LibPkmGC/GC/Common/Pokemon.h>
#include <LibPkmGC/GC/Common/TrainerData.h>
#include <LibPkmGC/GC/Common/BagData.h>
namespace LibPkmGC {
@ -42,15 +42,9 @@ public:
void swap(PlayerData& other);
void swapPokemon(size_t n, size_t m);
virtual void save(void);
PokemonString* trainerName;
u16 SID, TID;
Pokemon* party[6];
TrainerData* trainer;
BagData* bag;
Gender trainerGender;
@ -61,7 +55,6 @@ protected:
PlayerData(PlayerData const& other);
virtual void deleteFields(void);
virtual void loadFields(void);
};
}

View File

@ -0,0 +1,68 @@
/*
* Copyright (C) TuxSH 2015
* This file is part of LibPkmGC.
*
* LibPkmGC is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LibPkmGC 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with LibPkmGC. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _LIBPKMGC_GC_TRAINER_DATA_H
#define _LIBPKMGC_GC_TRAINER_DATA_H
#include <LibPkmGC/GC/Common/Pokemon.h>
namespace LibPkmGC {
LIBPKMGC_FWD_DECL_GC_CLS(TrainerData)
namespace GC {
/*
For both Colosseum and XD:
0x00 -- 0x2b: trainer name (10+1 wide characters) + copy
0x2c: u16 SID
0x2e: u16 TID
0x30: Pokémon Party
*/
class LIBPKMGC_DECL TrainerData :
public Base::DataStruct
{
public:
TrainerData(size_t inSize, const u8* inData = NULL);
virtual ~TrainerData(void);
virtual TrainerData* clone(void) const = 0;
virtual TrainerData* create(void) const = 0;
virtual void swap(TrainerData& other);
virtual TrainerData& operator=(TrainerData const& other);
virtual void save(void);
PokemonString* trainerName;
u16 SID, TID;
Pokemon* party[6];
protected:
TrainerData(TrainerData const& other);
virtual void deleteFields(void);
virtual void loadFields(void);
};
}
}
#endif

View File

@ -63,20 +63,13 @@ public:
virtual void saveEncrypted(u8* outBuf) = 0;
SaveMagic magic; // 0x00 -- 0x04 (0x03 actually)
s32 headerChecksum; // definition and location vary across Colosseum and XD
s32 saveCount;//, totalSaveCount;
/* A bit inconsistent across versions */
u32 memcardUID[2]; // u64. memcard[0:8] xor memcard[8:16] xor memcard[16:24] iirc
VersionInfo version;
LanguageIndex titleScreenLanguage;
bool noRumble;
SaveMagic magic;
s32 saveCount;
const size_t nbRandomBytes;
u8* randomBytes;
GameConfigData* gameConfig;
PlayerData* player;
PCData* PC;
MailboxData* mailbox;

View File

@ -39,7 +39,7 @@ public:
DaycareData* create(void) const;
DaycareData(Colosseum::DaycareData const& other);
private:
protected:
void loadFields(void);
};

View File

@ -19,6 +19,7 @@
#ifndef _LIBPKMGC_COLOSSEUM_COMMON_EVERYTHING_H
#define _LIBPKMGC_COLOSSEUM_COMMON_EVERYTHING_H
#include <LibPkmGC/XD/Common/GameConfigData.h>
#include <LibPkmGC/XD/Common/PlayerData.h>
#include <LibPkmGC/XD/Common/PCData.h>
#include <LibPkmGC/XD/Common/PlayerData.h>

View File

@ -0,0 +1,63 @@
/*
* Copyright (C) TuxSH 2015
* This file is part of LibPkmGC.
*
* LibPkmGC is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LibPkmGC 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with LibPkmGC. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _LIBPKMGC_XD_GAME_CONFIG_DATA_H
#define _LIBPKMGC_XD_GAME_CONFIG_DATA_H
#include <LibPkmGC/GC/Common/GameConfigData.h>
namespace LibPkmGC {
namespace XD {
/*
Game configuration substructure (off 0 (total 0xa8)) :
0x00: VersionInfo version (game, region, language)
0x04--0x07: padding
0x08: u64 memcardUID (see GCSaveSlot.h)
0x10: s32 storyModeSaveCount
0x29: u8 noRumble
0x2a: u16 titleScreenLanguage
0x38: s32 headerChecksum
*/
class LIBPKMGC_DECL GameConfigData :
public GC::GameConfigData
{
public:
static const size_t size = 0x88;
GameConfigData(void);
GameConfigData(GameConfigData const& other);
GameConfigData(const u8* inData);
~GameConfigData(void);
GameConfigData* clone(void) const;
GameConfigData* create(void) const;
void save(void);
protected:
void loadFields(void);
private:
GameConfigData(Colosseum::GameConfigData const& other);
};
}
}
#endif

View File

@ -20,17 +20,14 @@
#define _LIBPKMGC_XD_PLAYER_DATA_H
#include <LibPkmGC/GC/Common/PlayerData.h>
#include <LibPkmGC/XD/Common/Pokemon.h>
#include <LibPkmGC/XD/Common/TrainerData.h>
#include <LibPkmGC/XD/Common/BagData.h>
namespace LibPkmGC {
namespace XD {
/*
0x00 -- 0x2b: trainer name (10+1 wide characters) + copy
0x2c: u16 SID
0x2e: u16 TID
0x30: Pokémon Party (6*0xc4)
0x00: TrainerData trainer
0x4c8: bag

View File

@ -0,0 +1,51 @@
/*
* Copyright (C) TuxSH 2015
* This file is part of LibPkmGC.
*
* LibPkmGC is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LibPkmGC 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with LibPkmGC. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _LIBPKMGC_XD_TRAINER_DATA_H
#define _LIBPKMGC_XD_TRAINER_DATA_H
#include <LibPkmGC/GC/Common/TrainerData.h>
#include <LibPkmGC/XD/Common/Pokemon.h>
namespace LibPkmGC {
namespace XD {
class LIBPKMGC_DECL TrainerData :
public GC::TrainerData
{
public:
static const size_t size = 0x4c8;
TrainerData(void);
TrainerData(TrainerData const& other);
TrainerData(const u8* inData);
~TrainerData(void);
TrainerData& operator=(TrainerData const& other);
TrainerData* clone(void) const;
TrainerData* create(void) const;
TrainerData(Colosseum::TrainerData const& other);
protected:
void loadFields(void);
};
}
}
#endif

View File

@ -18,7 +18,6 @@
#ifndef _LIBPKMGC_XD_SAVE_EDITING_SAVE_SLOT_H
#define _LIBPKMGC_XD_SAVE_EDITING_SAVE_SLOT_H
#include <LibPkmGC/GC/SaveEditing/SaveSlot.h>
#include <LibPkmGC/XD/Common/Everything.h>
@ -44,7 +43,7 @@ namespace SaveEditing {
/*
Substructures, in order :
- [0] metadata/game config, size=0x88 (for compat. w/ colosseum it is directly handled within GC::SaveSlot)
- [0] game config, size=0x88
- [1] party & player data
- [2] PC Storage
- [3] Mailbox
@ -52,10 +51,10 @@ namespace SaveEditing {
- [5] Strategy memo
- [6] Battle mode
- [7] Shadow Pokémon data (in Colosseum, this is apparently a PID list; the full shadow data SEEMS to be included in the Pokémon's data)
- ?
- ?
- map data / script state
- Purifier
- [8] Flags (not handled here)
- [9] Special ribbons description (will be handled soon)
- [15] map data / script state
- [14] Purifier
*/
@ -104,9 +103,9 @@ public:
u32 checksum[4];
u16 encryptionKeys[4];
u32 substructureSizes[16]; // there are actually 12 substructures
u16 substructureSizes[16]; // there are actually 12 substructures
u32 substructureOffsets[16]; // there are actually 12 substructures
u16 flagDataSubSizes[5];
protected:
void loadData(u32 flags = 0);
@ -118,6 +117,7 @@ private:
void _deleteFields_extension(void);
bool _other_corruption_flags;
SaveSlot(Colosseum::SaveEditing::SaveSlot const&);
};
}

View File

@ -0,0 +1,59 @@
/*
* Copyright (C) TuxSH 2015
* This file is part of LibPkmGC.
*
* LibPkmGC is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LibPkmGC 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with LibPkmGC. If not, see <http://www.gnu.org/licenses/>.
*/
#include <LibPkmGC/Colosseum/Common/GameConfigData.h>
namespace LibPkmGC {
namespace Colosseum {
GameConfigData::GameConfigData(void) : GC::GameConfigData(0x70) {
initWithEmptyData();
}
GameConfigData::GameConfigData(const u8* inData) : GC::GameConfigData(0x70, inData) {
load();
}
GameConfigData::GameConfigData(GameConfigData const& other) : GC::GameConfigData(other) {
}
GameConfigData::~GameConfigData(void) {
}
void GameConfigData::loadFields(void) {
GC::GameConfigData::loadFields();
LD_FIELD(s32, headerChecksum, 4);
}
void GameConfigData::save(void) {
GC::GameConfigData::save();
SV_FIELD(s32, headerChecksum, 4);
}
GameConfigData* GameConfigData::clone(void) const {
return new GameConfigData(*this);
}
GameConfigData* GameConfigData::create(void) const {
return new GameConfigData;
}
}
}

View File

@ -43,15 +43,13 @@ PlayerData* PlayerData::create(void) const {
}
void PlayerData::loadFields(void) {
GC::PlayerData::loadFields();
LD_SUBSTRUCTURE(TrainerData, trainer, 0);
LD_FIELD_E(u8, trainerGender, 0xa80, Gender);
if (trainerGender > Female) trainerGender = Male;
LD_FIELD_MAX(u32, money, 0xa84, 9999999);
LD_FIELD_MAX(u32, pkCoupons, 0xa88, 9999999);
LD_SUBSTRUCTURE_ARRAY(Pokemon, party, 6, 0x30);
LD_SUBSTRUCTURE(BagData, bag, 0x780);
}
@ -63,7 +61,6 @@ void PlayerData::save(void) {
SV_FIELD_MAX(u32, pkCoupons, 0xa88, 9999999);
SV_FIELD(u32, pkCoupons, 0xa8c);
SV_SUBSTRUCTURE_ARRAY(Pokemon, party, 6, 0x30);
SV_SUBSTRUCTURE(BagData, bag, 0x780);
}

View File

@ -0,0 +1,53 @@
/*
* Copyright (C) TuxSH 2015
* This file is part of LibPkmGC.
*
* LibPkmGC is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LibPkmGC 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with LibPkmGC. If not, see <http://www.gnu.org/licenses/>.
*/
#include <LibPkmGC/Colosseum/Common/TrainerData.h>
namespace LibPkmGC {
namespace Colosseum {
TrainerData::TrainerData(void) : GC::TrainerData(0x780) {
initWithEmptyData();
}
TrainerData::TrainerData(const u8* inData) : GC::TrainerData(0x780, inData) {
load();
}
TrainerData::TrainerData(TrainerData const& other) : GC::TrainerData(other) {}
TrainerData::~TrainerData(void) {
}
void TrainerData::loadFields(void) {
GC::TrainerData::loadFields();
LD_SUBSTRUCTURE_ARRAY(Pokemon, party, 6, 0x30);
}
TrainerData* TrainerData::clone(void) const {
return new TrainerData(*this);
}
TrainerData* TrainerData::create(void) const {
return new TrainerData;
}
}
}

View File

@ -92,7 +92,7 @@ SaveSlot::SaveSlot(const u8* inData, bool isDecrypted) : GC::SaveEditing::SaveSl
}
SaveSlot::SaveSlot(SaveSlot const& other) : GC::SaveEditing::SaveSlot(other), storyModeSaveCount(other.storyModeSaveCount) {
SaveSlot::SaveSlot(SaveSlot const& other) : GC::SaveEditing::SaveSlot(other) {
CP_ARRAY(checksum, 20);
}
@ -115,7 +115,6 @@ SaveSlot* SaveSlot::create(void) const {
void SaveSlot::swap(SaveSlot& other) {
GC::SaveEditing::SaveSlot::swap(other);
SW(storyModeSaveCount);
SW_ARRAY(checksum, 20);
}
@ -123,9 +122,11 @@ void SaveSlot::swap(SaveSlot& other) {
bool SaveSlot::checkChecksum(bool fix){
u8 newDigest[20];
s32 hc_tmp = 0;
LD_FIELD(s32, hc_tmp, 12);
std::fill(data + 12, data + 16, 0); // headerChecksum field
Crypto::sha1(data, data + 0x1dfd8, newDigest);
SV_FIELD(s32, headerChecksum, 12);
SV_FIELD(s32, hc_tmp, 12);
bool ret = std::equal(checksum, checksum + 20, newDigest);
if (!ret && fix) std::copy(newDigest, newDigest + 20, checksum);
@ -135,7 +136,9 @@ bool SaveSlot::checkChecksum(bool fix){
bool SaveSlot::checkHeaderChecksum(bool fix){
using namespace IntegerManip::BE;
u8 newDigest[20]; // when computing the header's checksum, words @0x18 @0x1c are already encrypted
std::fill(data + 12, data + 16, 0); // headerChecksum field
s32 hc_tmp = 0;
LD_FIELD(s32, hc_tmp, 12);
std::fill(data + 12, data + 16, 0);
Crypto::sha1(data, data + 0x1dfd8, newDigest);
u32 D[2], H[2];
@ -157,10 +160,10 @@ bool SaveSlot::checkHeaderChecksum(bool fix){
newHC -= (s32)toInteger<u32,u8*>(tmpBuf);
newHC -= (s32)toInteger<u32, u8*>(tmpBuf + 4);
SV_FIELD(s32, headerChecksum, 12);
SV_FIELD(s32, hc_tmp, 12);
bool ret = (newHC == headerChecksum);
if (!ret && fix) headerChecksum = newHC;
bool ret = (newHC == gameConfig->headerChecksum);
if (!ret && fix) gameConfig->headerChecksum = newHC;
return ret;
}
@ -169,7 +172,9 @@ std::pair<bool, bool> SaveSlot::checkBothChecksums(bool fixGlobalChecksum, bool
else {
using namespace IntegerManip::BE;
u8 newDigest[20]; // when computing the header's checksum, words @0x18 @0x1c are already encrypted
std::fill(data + 12, data + 16, 0); // headerChecksum field
s32 hc_tmp = 0;
LD_FIELD(s32, hc_tmp, 12);
std::fill(data + 12, data + 16, 0);
Crypto::sha1(data, data + 0x1dfd8, newDigest);
bool ret1 = std::equal(checksum, checksum + 20, newDigest);
@ -194,10 +199,10 @@ std::pair<bool, bool> SaveSlot::checkBothChecksums(bool fixGlobalChecksum, bool
newHC -= (s32)toInteger<u32, u8*>(tmpBuf);
newHC -= (s32)toInteger<u32, u8*>(tmpBuf + 4);
SV_FIELD(s32, headerChecksum, 12);
SV_FIELD(s32, hc_tmp, 12);
bool ret2 = (newHC == headerChecksum);
headerChecksum = newHC;
bool ret2 = (newHC == gameConfig->headerChecksum);
gameConfig->headerChecksum = newHC;
return std::pair<bool, bool>(ret1, ret2);
}
@ -219,7 +224,7 @@ inline void doFixBugsAffectingPokemon(Pokemon* pkm) {
}
void SaveSlot::fixBugsAffectingPokemon(void) {
for (size_t i = 0; i < 6; ++i)
doFixBugsAffectingPokemon((Pokemon*)player->party[i]);
doFixBugsAffectingPokemon((Pokemon*)player->trainer->party[i]);
for (size_t i = 0; i < 3; ++i) {
for (size_t j = 0; j < 30; ++j)
@ -242,19 +247,12 @@ void SaveSlot::loadFields(void) {
randomBytes = new u8[20];
LD_FIELD_E(u32, magic, 0, SaveMagic);
LD_FIELD(s32, saveCount, 4);
version.load(data + 8);
LD_FIELD(u32, headerChecksum, 12);
LD_ARRAY(u32, memcardUID, 2, 16);
LD_FIELD(u32, storyModeSaveCount, 24);
LD_FIELD_B(u8, noRumble, 0x31);
LD_FIELD_E(u16, titleScreenLanguage, 0x32, LanguageIndex);
size_t offset = 0x70 + 8;
size_t offset = 8;
#define LD_IMPLEMENTED_SUBSTRUCTURE(type, field) LD_SUBSTRUCTURE(type, field, offset); offset += type::size;
LD_IMPLEMENTED_SUBSTRUCTURE(GameConfigData, gameConfig);
LD_IMPLEMENTED_SUBSTRUCTURE(PlayerData, player);
LD_IMPLEMENTED_SUBSTRUCTURE(PCData, PC);
LD_IMPLEMENTED_SUBSTRUCTURE(MailboxData, mailbox);
@ -271,19 +269,13 @@ void SaveSlot::save(void) {
magic = ColosseumMagic;
SV_FIELD_E(u32, ColosseumMagic, 0, SaveMagic);
SV_FIELD(u32, saveCount, 4);
//deleteFields();
version.save(data + 8);
SV_ARRAY(u32, memcardUID, 2, 16);
SV_FIELD(s32, storyModeSaveCount, 24);
SV_FIELD_B(u8, noRumble, 0x31);
SV_FIELD_E(u16, titleScreenLanguage, 0x32, LanguageIndex);
size_t offset = 0x70 + 8;
size_t offset = 8;
#define SV_IMPLEMENTED_SUBSTRUCTURE(type, field) SV_SUBSTRUCTURE(type, field, offset); offset += type::size;
SV_IMPLEMENTED_SUBSTRUCTURE(GameConfigData, gameConfig);
SV_IMPLEMENTED_SUBSTRUCTURE(PlayerData, player);
SV_IMPLEMENTED_SUBSTRUCTURE(PCData, PC);
SV_IMPLEMENTED_SUBSTRUCTURE(MailboxData, mailbox);
@ -295,7 +287,8 @@ void SaveSlot::save(void) {
checkBothChecksums(true, true); // update checksums
SV_FIELD(u32, headerChecksum, 12);
offset = 8;
SV_IMPLEMENTED_SUBSTRUCTURE(GameConfigData, gameConfig);
std::copy(randomBytes, randomBytes + 20, data + 0x1dfd8);
std::copy(checksum, checksum + 20, data + 0x1dfec);

View File

@ -23,6 +23,7 @@
namespace LibPkmGC {
LIBPKMGC_GEN_CONVERTER_CTOR(DaycareData)
LIBPKMGC_GEN_CONVERTER_CTOR(TrainerData)
LIBPKMGC_GEN_CONVERTER_CTOR_W_GBA(Pokemon)
LIBPKMGC_GEN_CONVERTER_CTOR(StrategyMemoData)
LIBPKMGC_GEN_CONVERTER_CTOR(PokemonBox)

View File

@ -0,0 +1,86 @@
/*
* Copyright (C) TuxSH 2015
* This file is part of LibPkmGC.
*
* LibPkmGC is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LibPkmGC 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with LibPkmGC. If not, see <http://www.gnu.org/licenses/>.
*/
#include <LibPkmGC/GC/Common/GameConfigData.h>
namespace LibPkmGC {
namespace GC {
GameConfigData::GameConfigData(size_t inSize, const u8* inData) : Base::DataStruct(inSize, inData) {
}
void GameConfigData::deleteFields(void) {
}
GameConfigData::~GameConfigData(void) {
GameConfigData::deleteFields();
}
GameConfigData::GameConfigData(GameConfigData const& other) : Base::DataStruct(other){
CP(version);
CP(headerChecksum);
CP_ARRAY(memcardUID, 2);
CP(storyModeSaveCount);
CP(titleScreenLanguage);
CP(noRumble);
}
void GameConfigData::swap(GameConfigData& other) {
if (fixedSize != other.fixedSize) throw std::invalid_argument("fixedSize != other->fixedSize");
Base::DataStruct::swap(other);
SW(version);
SW(headerChecksum);
SW_ARRAY(memcardUID, 2);
SW(storyModeSaveCount);
SW(titleScreenLanguage);
SW(noRumble);
}
GameConfigData& GameConfigData::operator=(GameConfigData const& other) {
if (fixedSize != other.fixedSize) throw std::invalid_argument("fixedSize != other->fixedSize");
Base::DataStruct::operator=(other);
if (this != &other) {
CP(version);
CP(headerChecksum);
CP_ARRAY(memcardUID, 2);
CP(storyModeSaveCount);
CP(titleScreenLanguage);
CP(noRumble);
}
return *this;
}
void GameConfigData::loadFields(void) {
version.load(data);
LD_ARRAY(u32, memcardUID, 2, 8);
LD_FIELD(s32, storyModeSaveCount, 0x10);
LD_FIELD_B(u8, noRumble, 0x29);
LD_FIELD_E(u16, titleScreenLanguage, 0x2a, LanguageIndex);
}
void GameConfigData::save(void) {
version.save(data);
SV_ARRAY(u32, memcardUID, 2, 8);
SV_FIELD(s32, storyModeSaveCount, 0x10);
SV_FIELD_B(u8, noRumble, 0x29);
SV_FIELD_E(u16, titleScreenLanguage, 0x2a, LanguageIndex);
}
}
}

View File

@ -26,19 +26,17 @@ PlayerData::PlayerData(size_t inSize, const u8* inData) : Base::DataStruct(inSiz
void PlayerData::deleteFields(void) {
for (size_t i = 0; i < 6; ++i) delete party[i];
delete bag;
delete trainerName;
delete trainer;
}
PlayerData::~PlayerData(void) {
PlayerData::deleteFields();
}
PlayerData::PlayerData(PlayerData const& other) : Base::DataStruct(other), SID(other.SID), TID(other.TID), money(other.money), pkCoupons(other.pkCoupons),
PlayerData::PlayerData(PlayerData const& other) : Base::DataStruct(other), money(other.money), pkCoupons(other.pkCoupons),
trainerGender(other.trainerGender){
CL(trainerName);
CL_ARRAY(party, 6);
CL(trainer);
CL(bag);
}
@ -47,9 +45,8 @@ PlayerData& PlayerData::operator=(PlayerData const& other) {
Base::DataStruct::operator=(other);
if (this != &other) {
PlayerData::deleteFields();
CP(SID); CP(TID); CP(money); CP(pkCoupons);
CL(trainerName);
CL_ARRAY(party, 6);
CP(money); CP(pkCoupons);
CL(trainer);
CL(bag);
CP(trainerGender);
}
@ -59,29 +56,15 @@ PlayerData& PlayerData::operator=(PlayerData const& other) {
void PlayerData::swap(PlayerData& other) {
if (size != other.size) throw std::invalid_argument("Cannot assign because *this and other are of different types");
Base::DataStruct::swap(other);
SW(SID); SW(TID); SW(money); SW(pkCoupons);
CL(trainerName);
SW_ARRAY(party, 6);
SW(money); SW(pkCoupons);
CL(trainer);
SW(bag);
SW(trainerGender);
}
void PlayerData::loadFields(void) {
trainerName = new PokemonString(data, 10);
LD_FIELD(u16, SID, 0x2c);
LD_FIELD(u16, TID, 0x2e);
}
void PlayerData::save(void) {
trainerName->save(data, 10);
SV_FIELD(u16, SID, 0x2c);
SV_FIELD(u16, TID, 0x2e);
SV_SUBSTRUCTURE2(TrainerData, trainer, 0);
}
void PlayerData::swapPokemon(size_t n, size_t m) {
if ((n > 6) || (m > 6)) return;
std::swap(party[n], party[m]);
}
}
}

View File

@ -0,0 +1,74 @@
/*
* Copyright (C) TuxSH 2015
* This file is part of LibPkmGC.
*
* LibPkmGC is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LibPkmGC 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with LibPkmGC. If not, see <http://www.gnu.org/licenses/>.
*/
#include <LibPkmGC/GC/Common/TrainerData.h>
namespace LibPkmGC {
namespace GC {
TrainerData::TrainerData(size_t inSize, const u8* inData) : Base::DataStruct(inSize, inData) {
}
void TrainerData::deleteFields(void) {
for (size_t i = 0; i < 6; ++i) delete party[i];
delete trainerName;
}
TrainerData::~TrainerData(void) {
TrainerData::deleteFields();
}
TrainerData::TrainerData(TrainerData const& other) : Base::DataStruct(other) {
CL_ARRAY(party, 6);
CP(SID); CP(TID);
CL(trainerName);
}
void TrainerData::swap(TrainerData& other) {
Base::DataStruct::swap(other);
SW(SID); SW(TID);
SW(trainerName);
for (size_t i = 0; i < 6; ++i) party[i]->swap(*(other.party[i]));
}
TrainerData& TrainerData::operator=(TrainerData const& other) {
Base::DataStruct::operator=(other);
if (this != &other) {
CP(SID); CP(TID);
CL(trainerName);
for (size_t i = 0; i < 6; ++i) *party[i] = *(other.party[i]);
}
return *this;
}
void TrainerData::loadFields(void) {
trainerName = new PokemonString(data, 10);
LD_FIELD(u16, SID, 0x2c);
LD_FIELD(u16, TID, 0x2e);
}
void TrainerData::save(void) {
trainerName->save(data, 10);
trainerName->save(data + 22, 10);
SV_FIELD(u16, SID, 0x2c);
SV_FIELD(u16, TID, 0x2e);
SV_SUBSTRUCTURE_ARRAY2(Pokemon, party, 6, 0x30);
}
}
}

View File

@ -27,6 +27,7 @@ SaveSlot::SaveSlot(size_t inSize, size_t nb_random_bytes, const u8* inData) : Ba
void SaveSlot::deleteFields(void) {
delete[] randomBytes;
delete gameConfig;
delete player;
delete PC;
delete mailbox;
@ -39,14 +40,11 @@ SaveSlot::~SaveSlot(void) {
SaveSlot::deleteFields();
}
SaveSlot::SaveSlot(const SaveSlot& other) : Base::DataStruct(other),
magic(other.magic), headerChecksum(other.headerChecksum), saveCount(other.saveCount),
version(other.version), titleScreenLanguage(other.titleScreenLanguage), noRumble(other.noRumble), nbRandomBytes(other.nbRandomBytes){
SaveSlot::SaveSlot(const SaveSlot& other) : Base::DataStruct(other), magic(other.magic), saveCount(other.saveCount), nbRandomBytes(other.nbRandomBytes){
randomBytes = new u8[nbRandomBytes];
std::copy(other.randomBytes, other.randomBytes + nbRandomBytes, randomBytes);
std::copy(other.memcardUID, other.memcardUID + 2, memcardUID);
CL(gameConfig);
CL(player);
CL(PC);
CL(mailbox);
@ -62,14 +60,8 @@ void SaveSlot::swap(SaveSlot& other) {
if (nbRandomBytes != other.nbRandomBytes) throw std::invalid_argument("this->nbRandomBytes != other.nbRandomBytes");
Base::DataStruct::swap(other);
SW(magic);
SW(headerChecksum);
SW(saveCount);
SW(memcardUID[0]); SW(memcardUID[1]);
SW(version);
SW(titleScreenLanguage);
SW(noRumble);
SW(gameConfig);
SW(player);
SW(PC);
SW(mailbox);
@ -89,15 +81,9 @@ SaveSlot& SaveSlot::operator=(SaveSlot const& other) {
randomBytes = new u8[nbRandomBytes];
CP_ARRAY(randomBytes, nbRandomBytes);
CP(magic);
CP(headerChecksum);
CP(saveCount);
CP(memcardUID[0]); CP(memcardUID[1]);
CP(version);
CP(titleScreenLanguage);
CP(noRumble);
CL(gameConfig);
CL(player);
CL(PC);
CL(mailbox);

View File

@ -0,0 +1,60 @@
/*
* Copyright (C) TuxSH 2015
* This file is part of LibPkmGC.
*
* LibPkmGC is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LibPkmGC 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with LibPkmGC. If not, see <http://www.gnu.org/licenses/>.
*/
#include <LibPkmGC/XD/Common/GameConfigData.h>
namespace LibPkmGC {
namespace XD {
GameConfigData::GameConfigData(void) : GC::GameConfigData(0x88) {
initWithEmptyData();
}
GameConfigData::GameConfigData(const u8* inData) : GC::GameConfigData(0x88, inData) {
load();
}
GameConfigData::GameConfigData(GameConfigData const& other) : GC::GameConfigData(other) {
}
GameConfigData::~GameConfigData(void) {
}
void GameConfigData::loadFields(void) {
GC::GameConfigData::loadFields();
LD_FIELD(s32, headerChecksum, 0x38);
}
void GameConfigData::save(void) {
GC::GameConfigData::save();
std::fill(data + 4, data + 8, 0);
SV_FIELD(s32, headerChecksum, 0x38);
}
GameConfigData* GameConfigData::clone(void) const {
return new GameConfigData(*this);
}
GameConfigData* GameConfigData::create(void) const {
return new GameConfigData;
}
}
}

View File

@ -44,14 +44,13 @@ PlayerData* PlayerData::create(void) const {
}
void PlayerData::loadFields(void) {
GC::PlayerData::loadFields();
LD_SUBSTRUCTURE(TrainerData, trainer, 0);
LD_FIELD_E(u8, trainerGender, 0x8e0, Gender);
if (trainerGender > Female) trainerGender = Male;
LD_FIELD_MAX(u32, money, 0x8e4, 9999999);
LD_FIELD_MAX(u32, pkCoupons, 0x8e8, 9999999);
LD_SUBSTRUCTURE_ARRAY(Pokemon, party, 6, 0x30);
LD_SUBSTRUCTURE(BagData, bag, 0x4c8);
}
@ -64,9 +63,8 @@ void PlayerData::save(void) {
SV_FIELD_MAX(u32, pkCoupons, 0x8e8, 9999999);
SV_FIELD(u32, pkCoupons, 0x8ec);
SV_SUBSTRUCTURE_ARRAY(Pokemon, party, 6, 0x30);
SV_SUBSTRUCTURE(BagData, bag, 0x4c8);
//0x94a: total step counter
}
}

View File

@ -0,0 +1,53 @@
/*
* Copyright (C) TuxSH 2015
* This file is part of LibPkmGC.
*
* LibPkmGC is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LibPkmGC 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with LibPkmGC. If not, see <http://www.gnu.org/licenses/>.
*/
#include <LibPkmGC/XD/Common/TrainerData.h>
namespace LibPkmGC {
namespace XD {
TrainerData::TrainerData(void) : GC::TrainerData(0x4c8) {
initWithEmptyData();
}
TrainerData::TrainerData(const u8* inData) : GC::TrainerData(0x4c8, inData) {
load();
}
TrainerData::TrainerData(TrainerData const& other) : GC::TrainerData(other) {}
TrainerData::~TrainerData(void) {
}
void TrainerData::loadFields(void) {
GC::TrainerData::loadFields();
LD_SUBSTRUCTURE_ARRAY(Pokemon, party, 6, 0x30);
}
TrainerData* TrainerData::clone(void) const {
return new TrainerData(*this);
}
TrainerData* TrainerData::create(void) const {
return new TrainerData;
}
}
}

View File

@ -16,6 +16,7 @@
* along with LibPkmGC. If not, see <http://www.gnu.org/licenses/>.
*/
#define _SCL_SECURE_NO_WARNINGS
#include <LibPkmGC/XD/SaveEditing/SaveSlot.h>
namespace LibPkmGC {
@ -131,7 +132,10 @@ void SaveSlot::swap(SaveSlot& other) {
SW_ARRAY(encryptionKeys, 4);
SW_ARRAY(checksum, 4);
SW_ARRAY(substructureSizes, 16);
SW_ARRAY(substructureOffsets, 16);
SW_ARRAY(flagDataSubSizes, 5);
SW_ARRAY(unhandledSubstructures, 16);
SW(purifier);
@ -142,7 +146,9 @@ SaveSlot& SaveSlot::operator=(SaveSlot const & other) {
if (this != &other) {
CP_ARRAY(checksum, 4);
CP_ARRAY(encryptionKeys, 4);
CP_ARRAY(substructureSizes, 16);
CP_ARRAY(substructureOffsets, 16);
CP_ARRAY(flagDataSubSizes, 5);
for (size_t i = 0; i < 16; ++i) {
if (other.unhandledSubstructures[i] != NULL) unhandledSubstructures[i] = other.unhandledSubstructures[i]->clone();
else unhandledSubstructures[i] = NULL;
@ -160,6 +166,39 @@ void SaveSlot::loadData(u32 flags) {
if (!decrypted) decrypt_impl(data, data, encryptionKeys);
}
template<typename cls> cls* loadSubstructure(u8* data, u32 offset, u32 sz, u32 maxSize) {
if (offset + 0xa8 >= 0x28000) return new cls;
if (sz < maxSize) {
u8* dt = new u8[maxSize];
std::fill(dt, dt + maxSize, 0);
std::copy(data + 0xa8 + offset, data + 0xa8 + offset + sz, dt);
cls* ret = new cls(dt);
delete[] dt;
return ret;
}
else {
return new cls(data + 0xa8 + offset);
}
}
template<> Base::UnimplementedStruct* loadSubstructure<Base::UnimplementedStruct>(u8* data, u32 offset, u32 sz, u32 maxSize) {
typedef Base::UnimplementedStruct cls;
if (offset + 0xa8 >= 0x28000) return new cls(maxSize);
if (sz < maxSize) {
u8* dt = new u8[maxSize];
std::fill(dt, dt + maxSize, 0);
std::copy(data + 0xa8 + offset, data + 0xa8 + offset + sz, dt);
cls* ret = new cls(maxSize, dt);
delete[] dt;
return ret;
}
else {
return new cls(maxSize, data + 0xa8 + offset);
}
}
void SaveSlot::loadFields(void) {
randomBytes = new u8[40];
@ -174,9 +213,11 @@ void SaveSlot::loadFields(void) {
checksum[i] = ((u32)checksum_tmp[2 * i] << 16) | (u32)checksum_tmp[2 * i + 1];
u16 substructureSizes[16], substructureOffsetsTmp[32]; // the upper 16 bits of each offset are stored AFTER the lower ones
u16 substructureOffsetsTmp[32]; // the upper 16 bits of each offset are stored AFTER the lower ones
LD_ARRAY(u16, substructureSizes, 16, 0x20);
LD_ARRAY(u16, substructureOffsetsTmp, 32, 0x40);
LD_ARRAY(u16, flagDataSubSizes, 4, 0x80);
LD_FIELD(u16, flagDataSubSizes[4], 0x8a);
u8* start = data + 8 + 0xa0;
for (size_t i = 0; i < 16; ++i)
@ -186,25 +227,18 @@ void SaveSlot::loadFields(void) {
for (size_t i = 0; i < 16; ++i) {
s8 subscript = substructureOrder[i]; // substructure order if unshuffled
if ((subscript <= 6) || (subscript == 14)) {
if ((subscript != -1) && ((subscript <= 6) || (subscript == 15))) {
unhandledSubstructures[i] = NULL;
continue;
}
// the game uses the following condition instead : substructureSizes[n] = max(substructureSizes[n], substructureMaxSizes[n]); we won't
#define COND(n) substructureSizes[n] != substructureMaxSizes[n] || substructureOffsets[n] + 0xa8 >= size
unhandledSubstructures[i] = loadSubstructure<Base::UnimplementedStruct>(data, substructureOffsets[i], substructureSizes[i], substructureMaxSizes[i]);
if (COND(i))
unhandledSubstructures[i] = new Base::UnimplementedStruct(substructureMaxSizes[i]);
else
unhandledSubstructures[i] = new Base::UnimplementedStruct(substructureMaxSizes[i], start + substructureOffsets[i]);
}
#define LD_IMPLEMENTED_SUBSTRUCTURE(type, field, id) if(COND(id))\
field = new type;\
else\
field = new type(start + substructureOffsets[id]);
#define LD_IMPLEMENTED_SUBSTRUCTURE(type, field, id) field = loadSubstructure<type>(data, substructureOffsets[id], substructureSizes[id], substructureMaxSizes[id])
LD_IMPLEMENTED_SUBSTRUCTURE(GameConfigData, gameConfig, 0);
LD_IMPLEMENTED_SUBSTRUCTURE(PlayerData, player, 1);
LD_IMPLEMENTED_SUBSTRUCTURE(PCData, PC, 2);
LD_IMPLEMENTED_SUBSTRUCTURE(MailboxData, mailbox, 3);
@ -213,12 +247,14 @@ void SaveSlot::loadFields(void) {
LD_IMPLEMENTED_SUBSTRUCTURE(BattleModeData, battleMode, 6);
LD_IMPLEMENTED_SUBSTRUCTURE(PurifierData, purifier, 14);
version.load(start);
LD_ARRAY(u32, memcardUID, 2, 0xa8 + 8);
LD_FIELD_B(u8, noRumble, 0xa8 + 0x29);
LD_FIELD_E(u16, titleScreenLanguage, 0xa8 + 0x2a, LanguageIndex);
LD_FIELD(s32, headerChecksum, 0xa8 + 0x38);
{ // flags
u16 sz = 0;
for (size_t i = 0; i < 5; ++i) sz += flagDataSubSizes[i];
if (sz <= substructureMaxSizes[8] && substructureSizes[8] == substructureMaxSizes[8])
std::fill(unhandledSubstructures[8]->data + sz, unhandledSubstructures[8]->data + substructureMaxSizes[8], 0);
}
std::copy(substructureMaxSizes, substructureMaxSizes + 16, substructureSizes);
std::copy(data + size - 40, data + size, randomBytes);
}
@ -251,8 +287,8 @@ bool SaveSlot::checkHeaderChecksum(bool fix) {
s32 new_header_checksum = 0;
for (size_t i = 0; i < 8; ++i) new_header_checksum += (s32)(u32)data[i];
bool ret = new_header_checksum == headerChecksum;
if (!ret && fix) headerChecksum = new_header_checksum;
bool ret = new_header_checksum == gameConfig->headerChecksum;
if (!ret && fix) gameConfig->headerChecksum = new_header_checksum;
return ret;
}
@ -261,11 +297,11 @@ std::pair<bool, bool> SaveSlot::checkBothChecksums(bool fixGlobalChecksum, bool
if (!fixGlobalChecksum || !fixHeaderChecksum) return std::pair<bool, bool>(checkChecksum(fixGlobalChecksum), checkHeaderChecksum(fixHeaderChecksum));
else {
bool first, second;
s32 oldHC = headerChecksum;
s32 oldHC = gameConfig->headerChecksum;
first = checkHeaderChecksum(true);
SV_FIELD(s32, headerChecksum, 0xa8 + 0x38);
SV_FIELD(s32, gameConfig->headerChecksum, 0xa8 + substructureOffsets[0] + 0x38);
second = checkChecksum(true);
SV_FIELD(s32, oldHC, 0xa8 + 0x38);
SV_FIELD(s32, oldHC, 0xa8 + substructureOffsets[0] + 0x38);
return std::pair<bool, bool>(first, second);
}
}
@ -288,15 +324,26 @@ void SaveSlot::save(void) {
std::copy(randomBytes, randomBytes + 40, data + size - 40);
std::fill(start + substructureMaxSizes[0], data + size, 0); // clean the filler bytes
std::fill(start, data + size - 40, 0); // clean the filler bytes
std::copy(substructureMaxSizes, substructureMaxSizes + 16, substructureSizes);
{ // flags
u16 sz = 0;
for (size_t i = 0; i < 5; ++i) sz += flagDataSubSizes[i];
if (sz <= substructureMaxSizes[8])
std::fill(unhandledSubstructures[8]->data + sz, unhandledSubstructures[8]->data + substructureMaxSizes[8], 0);
}
for (size_t i = 0; i < 16; ++i) {
if (unhandledSubstructures[i] == NULL) continue;
else if (substructureOrder[i] == -1) std::fill(unhandledSubstructures[i]->data, unhandledSubstructures[i]->data + substructureMaxSizes[i], 0); // 100% trash data
std::copy(unhandledSubstructures[i]->data, unhandledSubstructures[i]->data + substructureMaxSizes[i], start + substructureOffsets[i]);
}
#define SV_IMPLEMENTED_SUBSTRUCTURE(type, field, id) field->save(); std::copy(field->data, field->data + substructureMaxSizes[id], start + substructureOffsets[id]);
SV_IMPLEMENTED_SUBSTRUCTURE(GameConfigData, gameConfig, 0);
SV_IMPLEMENTED_SUBSTRUCTURE(PlayerData, player, 1);
SV_IMPLEMENTED_SUBSTRUCTURE(PCData, PC, 2);
SV_IMPLEMENTED_SUBSTRUCTURE(MailboxData, mailbox, 3);
@ -307,7 +354,7 @@ void SaveSlot::save(void) {
u16 substructureSizes[16], substructureOffsetsTmp[32]; // the upper 16 bits of each offset are stored AFTER the lower ones
u16 substructureOffsetsTmp[32]; // the upper 16 bits of each offset are stored AFTER the lower ones
std::copy(substructureMaxSizes, substructureMaxSizes + 16, substructureSizes);
SV_ARRAY(u16, substructureSizes, 16, 0x20);
_other_corruption_flags = false;
@ -319,17 +366,12 @@ void SaveSlot::save(void) {
}
SV_ARRAY(u16, substructureOffsetsTmp, 32, 0x40);
SV_ARRAY(u16, flagDataSubSizes, 4, 0x80);
SV_FIELD(u16, flagDataSubSizes[4], 0x8a);
version.save(start);
SV_ARRAY(u32, memcardUID, 2, 0xa8 + 8);
SV_FIELD_B(u8, noRumble, 0xa8 + 0x29);
SV_FIELD_E(u16, titleScreenLanguage, 0xa8 + 0x2a, LanguageIndex);
checkHeaderChecksum(true);
SV_FIELD(u32, headerChecksum, 0xa8 + 0x38);
checkChecksum(true);
checkBothChecksums(true);
SV_IMPLEMENTED_SUBSTRUCTURE(GameConfigData, gameConfig, 0);
u16 checksum_tmp[8];

View File

@ -19,7 +19,7 @@
#ifndef _PKMGCSAVEEDITOR_GLOBALS_H
#define _PKMGCSAVEEDITOR_GLOBALS_H
#define PKMGCSAVEEDITOR_VERSION 1001001
#define PKMGCSAVEEDITOR_VERSION 1001002
#define PKMGCSAVEEDITOR_VERSION_MAJOR ((PKMGCSAVEEDITOR_VERSION / 1000000) % 1000)
#define PKMGCSAVEEDITOR_VERSION_MINOR ((PKMGCSAVEEDITOR_VERSION / 1000) % 1000)
#define PKMGCSAVEEDITOR_VERSION_BUILD (PKMGCSAVEEDITOR_VERSION % 1000)

View File

@ -20,10 +20,10 @@
#include <QMessageBox>
using namespace LibPkmGC;
using namespace GC::SaveEditing;
using namespace GC;
namespace GCUIs {
GameConfigUI::GameConfigUI(SaveSlot * inSaveSlot, QWidget * parent, Qt::WindowFlags f) : DataUI(parent, f), saveSlot_(inSaveSlot) {
GameConfigUI::GameConfigUI(GameConfigData * inGameConfig, QWidget * parent, Qt::WindowFlags f) : DataUI(parent, f), gameConfig(inGameConfig) {
init();
}
@ -60,37 +60,26 @@ void GameConfigUI::initWidget(void) {
}
void GameConfigUI::parseData(void) {
if (saveSlot_ == NULL) return;
SaveSlot* sl = saveSlot_;
isXD = LIBPKMGC_IS_XD(SaveEditing::SaveSlot, sl);
if (gameConfig == NULL) return;
isXD = LIBPKMGC_IS_XD(GameConfigData, gameConfig);
versionFld->disconnect(SIGNAL(versionChanged()), this);
versionFld->setInfo(sl->version);
versionFld->setInfo(gameConfig->version);
connect(versionFld, SIGNAL(versionChanged()), this, SLOT(versionChangeHandler()));
noRumbleFld->setChecked(sl->noRumble);
titleScreenLanguageFld->setCurrentIndex((int)sl->titleScreenLanguage);
noRumbleFld->setChecked(gameConfig->noRumble);
titleScreenLanguageFld->setCurrentIndex((int)gameConfig->titleScreenLanguage);
miscellaneousBox->setVisible(!isXD);
if (!isXD) {
Colosseum::SaveEditing::SaveSlot *sl_c = (Colosseum::SaveEditing::SaveSlot*) sl;
storyModeSaveCountFld->setUnsignedValue(sl_c->storyModeSaveCount);
}
storyModeSaveCountFld->setUnsignedValue(gameConfig->storyModeSaveCount);
versionChangeHandler();
}
void GameConfigUI::saveChanges(void) {
SaveSlot* sl = saveSlot_;
sl->version = versionFld->info();
sl->noRumble = noRumbleFld->isChecked();
sl->titleScreenLanguage = (LanguageIndex)titleScreenLanguageFld->currentIndex();
if (!isXD) {
Colosseum::SaveEditing::SaveSlot *sl_c = (Colosseum::SaveEditing::SaveSlot*) sl;
sl_c->storyModeSaveCount = storyModeSaveCountFld->unsignedValue();
}
void GameConfigUI::saveChanges(void) {
gameConfig->version = versionFld->info();
gameConfig->noRumble = noRumbleFld->isChecked();
gameConfig->titleScreenLanguage = (LanguageIndex)titleScreenLanguageFld->currentIndex();
gameConfig->storyModeSaveCount = storyModeSaveCountFld->unsignedValue();
}
void GameConfigUI::versionChangeHandler(void) {

View File

@ -31,9 +31,9 @@ namespace GCUIs {
class GameConfigUI : public DataUI {
Q_OBJECT
public:
GameConfigUI(LibPkmGC::GC::SaveEditing::SaveSlot *inSaveSlot = NULL, QWidget* parent = NULL, Qt::WindowFlags f = Qt::Window);
GameConfigUI(LibPkmGC::GC::GameConfigData *inGameConfig = NULL, QWidget* parent = NULL, Qt::WindowFlags f = Qt::Window);
LibPkmGC::GC::SaveEditing::SaveSlot* saveSlot_; // not using ::currentSaveSlot here
LibPkmGC::GC::GameConfigData* gameConfig;
void parseData(void);

View File

@ -79,7 +79,7 @@ void PlayerUI::parseData(void){
if (player == NULL) return;
isXD = LIBPKMGC_IS_XD(PlayerData, player);
trainerInfoFld->set(player->trainerName, player->TID, player->SID, player->trainerGender);
trainerInfoFld->set(player->trainer->trainerName, player->trainer->TID, player->trainer->SID, player->trainerGender);
moneyFld->setValue((int)player->money);
pkCouponsFld->setValue((int)player->pkCoupons);
@ -89,16 +89,16 @@ void PlayerUI::parseData(void){
for (size_t i = 0; i < 6; ++i) {
PokemonStorageInfo loc = { StoredInParty, i, 0 };
pkmFlds[i]->location = loc;
pkmFlds[i]->pkm = player->party[i];
pkmFlds[i]->pkm = player->trainer->party[i];
pkmFlds[i]->parseData();
}
}
void PlayerUI::saveChanges(void) {
trainerInfoFld->trainerName(player->trainerName);
player->TID = trainerInfoFld->TID();
player->SID = trainerInfoFld->SID();
trainerInfoFld->trainerName(player->trainer->trainerName);
player->trainer->TID = trainerInfoFld->TID();
player->trainer->SID = trainerInfoFld->SID();
player->trainerGender = trainerInfoFld->trainerGender();
player->money = moneyFld->unsignedValue();
player->pkCoupons = pkCouponsFld->unsignedValue();
@ -115,15 +115,15 @@ void PlayerUI::cancelChanges(void) {
void PlayerUI::pkmDeletionHandler(LibPkmGC::PokemonStorageInfo const & location) {
size_t i = location.index;
GC::Pokemon *party2[6] = { NULL };
GC::Pokemon *deltd = player->party[i];
std::copy(player->party, player->party + i, party2);
std::copy(player->party + i + 1, player->party + 6, party2 + i);
std::copy(party2, party2 + 5, player->party);
player->party[5] = deltd;
GC::Pokemon *deltd = player->trainer->party[i];
std::copy(player->trainer->party, player->trainer->party + i, party2);
std::copy(player->trainer->party + i + 1, player->trainer->party + 6, party2 + i);
std::copy(party2, party2 + 5, player->trainer->party);
player->trainer->party[5] = deltd;
for (size_t i = 0; i < 6; ++i) {
PokemonStorageInfo loc = { StoredInParty, i, 0 };
pkmFlds[i]->location = loc;
pkmFlds[i]->pkm = player->party[i];
pkmFlds[i]->pkm = player->trainer->party[i];
pkmFlds[i]->parseData();
}
}

View File

@ -80,7 +80,7 @@ private:
else *pkm = *importedPkm;
if (P::size == 100 && currentSaveSlot != NULL)
pkm->version.currentRegion = currentSaveSlot->version.currentRegion;
pkm->version.currentRegion = currentSaveSlot->gameConfig->version.currentRegion;
parseData();
lastPkmDirectory = QFileInfo(fileName).canonicalPath();

View File

@ -278,7 +278,8 @@ void PokemonUI::initWidget(void){
coreCaptureInfoLayout->addRow(tr("Fateful encounter (obedient)"), obedientFld);
coreCaptureInfoLayout->addRow(tr("Ball caught with"), ballCaughtWithFld);
coreCaptureInfoLayout->labelForField(obedientFld)->setToolTip(tr("Mew and Deoxys need this field to be checked so they can obey"));
coreCaptureInfoLayout->labelForField(obedientFld)->setToolTip(tr("Mew and Deoxys need this field to be checked so they can obey.\n"
"Pok\xc3\xa9mon caught in XD always have this field checked."));
coreCaptureInfoBox->setLayout(coreCaptureInfoLayout);
OTBox->setLayout(OTField);
versionBox->setLayout(versionFld);
@ -855,8 +856,8 @@ void PokemonUI::resetName(void) {
void PokemonUI::copyInfoFromSave(void) {
GC::PlayerData* pl = currentSaveSlot->player;
OTField->set(pl->trainerName, pl->TID, pl->SID, pl->trainerGender);
versionFld->setInfo(currentSaveSlot->version);
OTField->set(pl->trainer->trainerName, pl->trainer->TID, pl->trainer->SID, pl->trainerGender);
versionFld->setInfo(currentSaveSlot->gameConfig->version);
}
void PokemonUI::generateShinyIDs(void) {

View File

@ -63,7 +63,7 @@ dlg.exec();\
if(changesMade) ((QWidget*)parent())->setWindowTitle("PkmGCSaveEditor - " + currentSaveFileName + "*");\
}
GEN_GCUI_SLT(GameConfigUI, currentSaveSlot)
GEN_GCUI_SLT(GameConfigUI, currentSaveSlot->gameConfig)
GEN_GCUI_SLT(PlayerUI, currentSaveSlot->player)
GEN_GCUI_SLT(PCUI, currentSaveSlot->PC)
GEN_GCUI_SLT(DaycareUI, currentSaveSlot->daycare)
@ -486,8 +486,9 @@ void MainWindow::loadSettings(void) {
if (settings->value("LibPkmGCVersion").toInt() == 0 || settings->value("Version").toInt() == 0)
oldversionMax = 0;
if (settings->value("LibPkmGCVersion").toInt() < 1001001 || settings->value("Version").toInt() < 1001001)
else if (settings->value("LibPkmGCVersion").toInt() < 1001001 || settings->value("Version").toInt() < 1001001)
oldversionMax = 1001000;
else oldversionMax = 1001001;
}

View File

@ -105,12 +105,12 @@
<translation>Story mode save count</translation>
</message>
<message>
<location filename="../src/GCUIs/GameConfigUI.cpp" line="98"/>
<location filename="../src/GCUIs/GameConfigUI.cpp" line="87"/>
<source>Warning</source>
<translation>Warning</translation>
</message>
<message>
<location filename="../src/GCUIs/GameConfigUI.cpp" line="98"/>
<location filename="../src/GCUIs/GameConfigUI.cpp" line="87"/>
<source>The version info you specified is invalid, and will make the game unplayable.</source>
<translation>The version info you specified is invalid, and will make the game unplayable.</translation>
</message>
@ -580,11 +580,6 @@
<source>Happiness</source>
<translation>Happiness</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="281"/>
<source>Mew and Deoxys need this field to be checked so they can obey</source>
<translation>Mew and Deoxys need this field to be checked so they can obey</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="239"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="248"/>
@ -672,134 +667,141 @@
<translation>Fateful encounter (obedient)</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="309"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="281"/>
<source>Mew and Deoxys need this field to be checked so they can obey.
Pokémon caught in XD always have this field checked.</source>
<translation>Mew and Deoxys need this field to be checked so they can obey.
Pokémon caught in XD always have this field checked.</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="310"/>
<source>IV</source>
<translation>IV</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="310"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="311"/>
<source>EV</source>
<translation>EV</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="311"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="312"/>
<source>Stat</source>
<translation>Stat</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="314"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="315"/>
<source>Current HP</source>
<translation>Current HP</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="321"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="322"/>
<source>Update stats automatically</source>
<translation>Update stats automatically</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="333"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="334"/>
<source>Luster</source>
<translation>Luster</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="340"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="341"/>
<source>Main stats</source>
<translation>Main stats</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="341"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="342"/>
<source>Contest stats</source>
<translation>Contest stats</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="360"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="361"/>
<source>Contest ribbons</source>
<translation>Contest ribbons</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="373"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="374"/>
<source>Contest type</source>
<translation>Contest type</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="374"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="375"/>
<source>Achievement</source>
<translation>Achievement</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="378"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="379"/>
<source>Special ribbons</source>
<translation>Special ribbons</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="403"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="404"/>
<source>General</source>
<translation>General</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="404"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="405"/>
<source>Met/OT</source>
<translation>Met/OT</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="405"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="406"/>
<source>Stats</source>
<translation>Stats</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="406"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="407"/>
<source>Moves</source>
<translation>Moves</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="407"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="408"/>
<source>Ribbons</source>
<translation>Ribbons</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="614"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="615"/>
<source>Genderless</source>
<translation>Genderless</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="630"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="631"/>
<source>Unown form: </source>
<translation>Unown form: </translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="635"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="636"/>
<source>will evolve into: </source>
<translation>will evolve into: </translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="647"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="671"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="648"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="672"/>
<source>Invalid version info</source>
<translation>Invalid version info</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="650"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="674"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="651"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="675"/>
<source>&quot;Invalid Pokémon&quot; flag set</source>
<translation>&quot;Invalid Pokémon&quot; flag set</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="840"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="841"/>
<source>Location caught (see &lt;a href=&apos;http://bulbapedia.bulbagarden.net/wiki/List_of_locations_by_index_number_(Generation_III)&apos;&gt;here&lt;/a&gt;)</source>
<translation>Location caught (see &lt;a href=&apos;http://bulbapedia.bulbagarden.net/wiki/List_of_locations_by_index_number_(Generation_III)&apos;&gt;here&lt;/a&gt;)</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="842"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="843"/>
<source>Location caught (see &lt;a href=&apos;http://bulbapedia.bulbagarden.net/wiki/List_of_locations_by_index_number_(GCN)&apos;&gt;here&lt;/a&gt;)</source>
<translation>Location caught (see &lt;a href=&apos;http://bulbapedia.bulbagarden.net/wiki/List_of_locations_by_index_number_(GCN)&apos;&gt;here&lt;/a&gt;)</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="847"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="848"/>
<source>Warning</source>
<translation>Warning</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="847"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="848"/>
<source>The version info you specified is invalid. The game will therefore consider this Pokémon invalid.</source>
<translation>The version info you specified is invalid. The game will therefore consider this Pokémon invalid.</translation>
</message>
@ -928,158 +930,158 @@
<name>MainWindow</name>
<message>
<location filename="../src/MainWindow.cpp" line="82"/>
<location filename="../src/MainWindow.cpp" line="198"/>
<location filename="../src/MainWindow.cpp" line="205"/>
<source>&amp;File</source>
<translation>&amp;File</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="99"/>
<location filename="../src/MainWindow.cpp" line="205"/>
<location filename="../src/MainWindow.cpp" line="212"/>
<source>&amp;Options</source>
<translation>&amp;Options</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="100"/>
<location filename="../src/MainWindow.cpp" line="206"/>
<location filename="../src/MainWindow.cpp" line="213"/>
<source>&amp;Interface language</source>
<translation>&amp;Interface language</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="101"/>
<location filename="../src/MainWindow.cpp" line="207"/>
<location filename="../src/MainWindow.cpp" line="214"/>
<source>&amp;Dumped names language</source>
<translation>&amp;Dumped names language</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="105"/>
<location filename="../src/MainWindow.cpp" line="220"/>
<location filename="../src/MainWindow.cpp" line="227"/>
<source>&amp;Bug fixes</source>
<translation>&amp;Bug fixes</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="200"/>
<location filename="../src/MainWindow.cpp" line="207"/>
<source>&amp;Open...</source>
<translation>&amp;Open...</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="201"/>
<location filename="../src/MainWindow.cpp" line="208"/>
<source>&amp;Save</source>
<translation>&amp;Save</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="202"/>
<location filename="../src/MainWindow.cpp" line="209"/>
<source>Save &amp;as...</source>
<translation>Save &amp;as...</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="203"/>
<location filename="../src/MainWindow.cpp" line="210"/>
<source>&amp;Exit</source>
<translation>&amp;Exit</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="211"/>
<location filename="../src/MainWindow.cpp" line="212"/>
<location filename="../src/MainWindow.cpp" line="218"/>
<location filename="../src/MainWindow.cpp" line="219"/>
<source>Select &amp;automatically</source>
<translation>Select &amp;automatically</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="221"/>
<location filename="../src/MainWindow.cpp" line="228"/>
<source>Bugs affecting &amp;Pokémon (Colosseum, PkmGCSaveEditor 1.1.0)</source>
<translation>Bugs affecting &amp;Pokémon (Colosseum, PkmGCSaveEditor 1.1.0)</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="222"/>
<location filename="../src/MainWindow.cpp" line="229"/>
<source>&amp;Ignore data corruption</source>
<translation>&amp;Ignore data corruption</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="306"/>
<location filename="../src/MainWindow.cpp" line="332"/>
<location filename="../src/MainWindow.cpp" line="451"/>
<location filename="../src/MainWindow.cpp" line="313"/>
<location filename="../src/MainWindow.cpp" line="339"/>
<location filename="../src/MainWindow.cpp" line="458"/>
<source>GCI save files (*.gci)</source>
<translation>GCI save files (*.gci)</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="307"/>
<location filename="../src/MainWindow.cpp" line="333"/>
<location filename="../src/MainWindow.cpp" line="452"/>
<location filename="../src/MainWindow.cpp" line="314"/>
<location filename="../src/MainWindow.cpp" line="340"/>
<location filename="../src/MainWindow.cpp" line="459"/>
<source>Raw save files (*.bin)</source>
<translation>Raw save files (*.bin)</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="309"/>
<location filename="../src/MainWindow.cpp" line="316"/>
<source>The save file has been modified.</source>
<translation>The save file has been modified.</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="310"/>
<location filename="../src/MainWindow.cpp" line="317"/>
<source>Do you want to save your changes?</source>
<translation>Do you want to save your changes?</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="335"/>
<location filename="../src/MainWindow.cpp" line="342"/>
<source>Could not open file.</source>
<translation>Could not open file.</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="336"/>
<location filename="../src/MainWindow.cpp" line="343"/>
<source>An error occured while reading the specified save file.</source>
<translation>An error occured while reading the specified save file.</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="339"/>
<location filename="../src/MainWindow.cpp" line="346"/>
<source>Open save file</source>
<translation>Open save file</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="339"/>
<location filename="../src/MainWindow.cpp" line="346"/>
<source>All Files (*)</source>
<translation>All Files (*)</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="355"/>
<location filename="../src/MainWindow.cpp" line="361"/>
<location filename="../src/MainWindow.cpp" line="366"/>
<location filename="../src/MainWindow.cpp" line="390"/>
<location filename="../src/MainWindow.cpp" line="431"/>
<location filename="../src/MainWindow.cpp" line="442"/>
<location filename="../src/MainWindow.cpp" line="362"/>
<location filename="../src/MainWindow.cpp" line="368"/>
<location filename="../src/MainWindow.cpp" line="373"/>
<location filename="../src/MainWindow.cpp" line="397"/>
<location filename="../src/MainWindow.cpp" line="438"/>
<location filename="../src/MainWindow.cpp" line="449"/>
<source>Error</source>
<translation>Error</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="355"/>
<location filename="../src/MainWindow.cpp" line="362"/>
<source>Invalid file size.</source>
<translation>Invalid file size.</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="385"/>
<location filename="../src/MainWindow.cpp" line="387"/>
<location filename="../src/MainWindow.cpp" line="481"/>
<location filename="../src/MainWindow.cpp" line="133"/>
<location filename="../src/MainWindow.cpp" line="392"/>
<location filename="../src/MainWindow.cpp" line="394"/>
<source>Warning</source>
<translation>Warning</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="385"/>
<location filename="../src/MainWindow.cpp" line="392"/>
<source>The backup save slot was loaded because the most recent save slot is corrupt.</source>
<translation>The backup save slot was loaded because the most recent save slot is corrupt.</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="387"/>
<location filename="../src/MainWindow.cpp" line="394"/>
<source>The second backup save slot was loaded because the other ones are corrupt.</source>
<translation>The second backup save slot was loaded because the other ones are corrupt.</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="390"/>
<location filename="../src/MainWindow.cpp" line="397"/>
<source>All save slots are corrupt.</source>
<translation>All save slots are corrupt.</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="414"/>
<location filename="../src/MainWindow.cpp" line="421"/>
<source>No save file loaded</source>
<translation>No save file loaded</translation>
</message>
<message numerus="yes">
<location filename="../src/MainWindow.cpp" line="417"/>
<location filename="../src/MainWindow.cpp" line="424"/>
<source>%1, %n save(s)</source>
<translation>
<numerusform>%1, %n save</numerusform>
@ -1087,37 +1089,37 @@
</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="418"/>
<location filename="../src/MainWindow.cpp" line="425"/>
<source>Colosseum</source>
<translation>Colosseum</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="418"/>
<location filename="../src/MainWindow.cpp" line="425"/>
<source>XD</source>
<translation>XD</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="423"/>
<location filename="../src/MainWindow.cpp" line="430"/>
<source>Could not write to file.</source>
<translation>Could not write to file.</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="424"/>
<location filename="../src/MainWindow.cpp" line="431"/>
<source>An error occured while writing to the specified save file.</source>
<translation>An error occured while writing to the specified save file.</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="455"/>
<location filename="../src/MainWindow.cpp" line="462"/>
<source>All files (*)</source>
<translation>All files (*)</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="456"/>
<location filename="../src/MainWindow.cpp" line="463"/>
<source>Save save file</source>
<translation>Save save file</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="481"/>
<location filename="../src/MainWindow.cpp" line="133"/>
<source>You have used a version of PkmGCSaveEditor older than 1.1.1.&lt;br/&gt;Please consider the following points:&lt;ul&gt;&lt;li&gt;If and &lt;b&gt;only&lt;/b&gt; if you have modified a &lt;b&gt;Colosseum&lt;/b&gt; save file with that previous version, please load this save file again, and click &quot;Bugs affecting Pokémon...&quot;(in &quot;Options&quot;, &quot;Bug fixes&quot;). &lt;b&gt;Do it only once and only once&lt;/b&gt; (for each concerned save file).&lt;/li&gt;&lt;li&gt;If you have imported or exported a Pokémon in the GBA format, please check its status alteration, its EVs, and its game of origin.&lt;/li&gt;&lt;/ul&gt;</source>
<translation>You have used a version of PkmGCSaveEditor older than 1.1.1.&lt;br/&gt;Please consider the following points:&lt;ul&gt;&lt;li&gt;If and &lt;b&gt;only&lt;/b&gt; if you have modified a &lt;b&gt;Colosseum&lt;/b&gt; save file with that previous version, please load this save file again, and click &quot;Bugs affecting Pokémon...&quot;(in &quot;Options&quot;, &quot;Bug fixes&quot;). &lt;b&gt;Do it only once and only once&lt;/b&gt; (for each concerned save file).&lt;/li&gt;&lt;li&gt;If you have imported or exported a Pokémon in the GBA format, please check its status alteration, its EVs, and its game of origin.&lt;/li&gt;&lt;/ul&gt;</translation>
</message>

View File

@ -105,12 +105,12 @@
<translation>Nombre de sauvegardes en mode scénario</translation>
</message>
<message>
<location filename="../src/GCUIs/GameConfigUI.cpp" line="98"/>
<location filename="../src/GCUIs/GameConfigUI.cpp" line="87"/>
<source>Warning</source>
<translation>Avertissement</translation>
</message>
<message>
<location filename="../src/GCUIs/GameConfigUI.cpp" line="98"/>
<location filename="../src/GCUIs/GameConfigUI.cpp" line="87"/>
<source>The version info you specified is invalid, and will make the game unplayable.</source>
<translation>Les informations sur la version du jeu que vous avez entrées sont invalides, et rendront le jeu injouable.</translation>
</message>
@ -580,11 +580,6 @@
<source>Happiness</source>
<translation>Bonheur</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="281"/>
<source>Mew and Deoxys need this field to be checked so they can obey</source>
<translation>Cette case doit être cochée afin que Mew et Deoxys puissent obéir</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="239"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="248"/>
@ -672,134 +667,141 @@
<translation>Rencontré par hasard (obéissant)</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="309"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="281"/>
<source>Mew and Deoxys need this field to be checked so they can obey.
Pokémon caught in XD always have this field checked.</source>
<translation>Cette case doit être cochée afin que Mew et Deoxys puissent obéir.
Les Pokémon attrapés dans XD ont toujours cette case cochée.</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="310"/>
<source>IV</source>
<translation>IV</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="310"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="311"/>
<source>EV</source>
<translation>EV</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="311"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="312"/>
<source>Stat</source>
<translation>Statistique</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="314"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="315"/>
<source>Current HP</source>
<translation>PVs actuels</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="321"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="322"/>
<source>Update stats automatically</source>
<translation>Mettre à jour les statistiques automatiquement</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="333"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="334"/>
<source>Luster</source>
<translation>Lustre</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="340"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="341"/>
<source>Main stats</source>
<translation>Statistiques principales</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="341"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="342"/>
<source>Contest stats</source>
<translation>Statistiques de concours</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="360"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="361"/>
<source>Contest ribbons</source>
<translation>Rubans de concours</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="373"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="374"/>
<source>Contest type</source>
<translation>Type de concours</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="374"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="375"/>
<source>Achievement</source>
<translation>Avancement</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="378"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="379"/>
<source>Special ribbons</source>
<translation>Rubans spéciaux</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="403"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="404"/>
<source>General</source>
<translation>Général</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="404"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="405"/>
<source>Met/OT</source>
<translation>Infos de rencontre/D.O</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="405"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="406"/>
<source>Stats</source>
<translation>Statistiques</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="406"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="407"/>
<source>Moves</source>
<translation>Attaques</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="407"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="408"/>
<source>Ribbons</source>
<translation>Rubans</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="614"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="615"/>
<source>Genderless</source>
<translation>Asexué</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="630"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="631"/>
<source>Unown form: </source>
<translation>Forme Zarbi : </translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="635"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="636"/>
<source>will evolve into: </source>
<translation>évoluera en : </translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="647"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="671"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="648"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="672"/>
<source>Invalid version info</source>
<translation>Infos de version invalides</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="650"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="674"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="651"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="675"/>
<source>&quot;Invalid Pokémon&quot; flag set</source>
<translation>Drapeau &quot;Pokémon invalide&quot; activé</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="840"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="841"/>
<source>Location caught (see &lt;a href=&apos;http://bulbapedia.bulbagarden.net/wiki/List_of_locations_by_index_number_(Generation_III)&apos;&gt;here&lt;/a&gt;)</source>
<translation>Lieu de capture (cf. &lt;a href=&apos;http://bulbapedia.bulbagarden.net/wiki/List_of_locations_by_index_number_(Generation_III)&apos;&gt;Bulbapedia&lt;/a&gt;)</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="842"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="843"/>
<source>Location caught (see &lt;a href=&apos;http://bulbapedia.bulbagarden.net/wiki/List_of_locations_by_index_number_(GCN)&apos;&gt;here&lt;/a&gt;)</source>
<translation>Lieu de capture (cf. &lt;a href=&apos;http://bulbapedia.bulbagarden.net/wiki/List_of_locations_by_index_number_(GCN)&apos;&gt;Bulbapedia&lt;/a&gt;)</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="847"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="848"/>
<source>Warning</source>
<translation>Avertissement</translation>
</message>
<message>
<location filename="../src/GCUIs/PokemonUI.cpp" line="847"/>
<location filename="../src/GCUIs/PokemonUI.cpp" line="848"/>
<source>The version info you specified is invalid. The game will therefore consider this Pokémon invalid.</source>
<translation>Les informations sur la version du jeu que vous avez entrées sont invalides. Le jeu considérera de ce fait ce Pokémon invalide.</translation>
</message>
@ -928,158 +930,158 @@
<name>MainWindow</name>
<message>
<location filename="../src/MainWindow.cpp" line="82"/>
<location filename="../src/MainWindow.cpp" line="198"/>
<location filename="../src/MainWindow.cpp" line="205"/>
<source>&amp;File</source>
<translation>&amp;Fichier</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="99"/>
<location filename="../src/MainWindow.cpp" line="205"/>
<location filename="../src/MainWindow.cpp" line="212"/>
<source>&amp;Options</source>
<translation>&amp;Options</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="100"/>
<location filename="../src/MainWindow.cpp" line="206"/>
<location filename="../src/MainWindow.cpp" line="213"/>
<source>&amp;Interface language</source>
<translation>Langue de l&apos;&amp;interface</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="101"/>
<location filename="../src/MainWindow.cpp" line="207"/>
<location filename="../src/MainWindow.cpp" line="214"/>
<source>&amp;Dumped names language</source>
<translation>Langue des noms &amp;extraits</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="105"/>
<location filename="../src/MainWindow.cpp" line="220"/>
<location filename="../src/MainWindow.cpp" line="227"/>
<source>&amp;Bug fixes</source>
<translation>&amp;Correctifs de bugs</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="200"/>
<location filename="../src/MainWindow.cpp" line="207"/>
<source>&amp;Open...</source>
<translation>&amp;Ouvrir...</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="201"/>
<location filename="../src/MainWindow.cpp" line="208"/>
<source>&amp;Save</source>
<translation>&amp;Enregistrer</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="202"/>
<location filename="../src/MainWindow.cpp" line="209"/>
<source>Save &amp;as...</source>
<translation>Enregistrer &amp;sous...</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="203"/>
<location filename="../src/MainWindow.cpp" line="210"/>
<source>&amp;Exit</source>
<translation>&amp;Quitter</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="211"/>
<location filename="../src/MainWindow.cpp" line="212"/>
<location filename="../src/MainWindow.cpp" line="218"/>
<location filename="../src/MainWindow.cpp" line="219"/>
<source>Select &amp;automatically</source>
<translation>Sélectionner &amp;automatiquement</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="221"/>
<location filename="../src/MainWindow.cpp" line="228"/>
<source>Bugs affecting &amp;Pokémon (Colosseum, PkmGCSaveEditor 1.1.0)</source>
<translation>Bugs affectant les &amp;Pokémon (Colosseum, PkmGCSaveEditor 1.1.0)</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="222"/>
<location filename="../src/MainWindow.cpp" line="229"/>
<source>&amp;Ignore data corruption</source>
<translation>&amp;Ignorer la corruption des données</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="306"/>
<location filename="../src/MainWindow.cpp" line="332"/>
<location filename="../src/MainWindow.cpp" line="451"/>
<location filename="../src/MainWindow.cpp" line="313"/>
<location filename="../src/MainWindow.cpp" line="339"/>
<location filename="../src/MainWindow.cpp" line="458"/>
<source>GCI save files (*.gci)</source>
<translation>Fichiers de sauvegarde GCI (*.gci)</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="307"/>
<location filename="../src/MainWindow.cpp" line="333"/>
<location filename="../src/MainWindow.cpp" line="452"/>
<location filename="../src/MainWindow.cpp" line="314"/>
<location filename="../src/MainWindow.cpp" line="340"/>
<location filename="../src/MainWindow.cpp" line="459"/>
<source>Raw save files (*.bin)</source>
<translation>Fichiers de sauvegarde bruts (*.bin)</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="309"/>
<location filename="../src/MainWindow.cpp" line="316"/>
<source>The save file has been modified.</source>
<translation>Le fichier de sauvegarde a é modifié.</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="310"/>
<location filename="../src/MainWindow.cpp" line="317"/>
<source>Do you want to save your changes?</source>
<translation>Voulez-vous enregistrer vos modifications ?</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="335"/>
<location filename="../src/MainWindow.cpp" line="342"/>
<source>Could not open file.</source>
<translation>Impossible d&apos;ouvrir le fichier.</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="336"/>
<location filename="../src/MainWindow.cpp" line="343"/>
<source>An error occured while reading the specified save file.</source>
<translation>Une erreur s&apos;est produite durant la lecture du fichier de sauvegarde.</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="339"/>
<location filename="../src/MainWindow.cpp" line="346"/>
<source>Open save file</source>
<translation>Ouvrir fichier de sauvegarde</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="339"/>
<location filename="../src/MainWindow.cpp" line="346"/>
<source>All Files (*)</source>
<translation>Tous les fichiers (*)</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="355"/>
<location filename="../src/MainWindow.cpp" line="361"/>
<location filename="../src/MainWindow.cpp" line="366"/>
<location filename="../src/MainWindow.cpp" line="390"/>
<location filename="../src/MainWindow.cpp" line="431"/>
<location filename="../src/MainWindow.cpp" line="442"/>
<location filename="../src/MainWindow.cpp" line="362"/>
<location filename="../src/MainWindow.cpp" line="368"/>
<location filename="../src/MainWindow.cpp" line="373"/>
<location filename="../src/MainWindow.cpp" line="397"/>
<location filename="../src/MainWindow.cpp" line="438"/>
<location filename="../src/MainWindow.cpp" line="449"/>
<source>Error</source>
<translation>Erreur</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="355"/>
<location filename="../src/MainWindow.cpp" line="362"/>
<source>Invalid file size.</source>
<translation>Taille de fichier invalide</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="385"/>
<location filename="../src/MainWindow.cpp" line="387"/>
<location filename="../src/MainWindow.cpp" line="481"/>
<location filename="../src/MainWindow.cpp" line="133"/>
<location filename="../src/MainWindow.cpp" line="392"/>
<location filename="../src/MainWindow.cpp" line="394"/>
<source>Warning</source>
<translation>Avertissement</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="385"/>
<location filename="../src/MainWindow.cpp" line="392"/>
<source>The backup save slot was loaded because the most recent save slot is corrupt.</source>
<translation>L&apos;emplacement de sauvegarde de secours a é chargé car l&apos;emplacement le plus récent est corrompu</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="387"/>
<location filename="../src/MainWindow.cpp" line="394"/>
<source>The second backup save slot was loaded because the other ones are corrupt.</source>
<translation>Le deuxième emplacement de sauvegarde de secours a é chargé car l&apos;emplacement le plus récent est corrompu</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="390"/>
<location filename="../src/MainWindow.cpp" line="397"/>
<source>All save slots are corrupt.</source>
<translation>Tous les emplacements de sauvegarde sont corrompus.</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="414"/>
<location filename="../src/MainWindow.cpp" line="421"/>
<source>No save file loaded</source>
<translation>Aucune sauvegarde chargée</translation>
</message>
<message numerus="yes">
<location filename="../src/MainWindow.cpp" line="417"/>
<location filename="../src/MainWindow.cpp" line="424"/>
<source>%1, %n save(s)</source>
<translation>
<numerusform>%1, %n sauvegarde</numerusform>
@ -1087,37 +1089,37 @@
</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="418"/>
<location filename="../src/MainWindow.cpp" line="425"/>
<source>Colosseum</source>
<translation>Colosseum</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="418"/>
<location filename="../src/MainWindow.cpp" line="425"/>
<source>XD</source>
<translation>XD</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="423"/>
<location filename="../src/MainWindow.cpp" line="430"/>
<source>Could not write to file.</source>
<translation>Impossible d&apos;écrire dans le fichier.</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="424"/>
<location filename="../src/MainWindow.cpp" line="431"/>
<source>An error occured while writing to the specified save file.</source>
<translation>Une erreur s&apos;est produite pendant l&apos;écriture des données sur le fichier de sauvegarde.</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="455"/>
<location filename="../src/MainWindow.cpp" line="462"/>
<source>All files (*)</source>
<translation>Tous les fichiers (*)</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="456"/>
<location filename="../src/MainWindow.cpp" line="463"/>
<source>Save save file</source>
<translation>Sauvegarder fichier de sauvegarde</translation>
</message>
<message>
<location filename="../src/MainWindow.cpp" line="481"/>
<location filename="../src/MainWindow.cpp" line="133"/>
<source>You have used a version of PkmGCSaveEditor older than 1.1.1.&lt;br/&gt;Please consider the following points:&lt;ul&gt;&lt;li&gt;If and &lt;b&gt;only&lt;/b&gt; if you have modified a &lt;b&gt;Colosseum&lt;/b&gt; save file with that previous version, please load this save file again, and click &quot;Bugs affecting Pokémon...&quot;(in &quot;Options&quot;, &quot;Bug fixes&quot;). &lt;b&gt;Do it only once and only once&lt;/b&gt; (for each concerned save file).&lt;/li&gt;&lt;li&gt;If you have imported or exported a Pokémon in the GBA format, please check its status alteration, its EVs, and its game of origin.&lt;/li&gt;&lt;/ul&gt;</source>
<translation>Vous avez utilisé une version de PkmGCSaveEditor plus vielle que la version 1.1.1.&lt;br/&gt;Veuillez considérer les points suivants : &lt;ul&gt;&lt;li&gt;Si et &lt;b&gt;seulement&lt;/b&gt; si vous avez modifié une sauvegarde de &lt;b&gt;Colosseum&lt;/b&gt; avec cette version-là, veuillez charger cette sauvegarde à nouveau, et cliquer sur &quot;Bug affectant les Pokémon ...&quot; (dans &quot;Options&quot;, &quot;Correctifs de bugs&quot;). &lt;b&gt;Ne le faites qu&apos;une et une seule fois&lt;/b&gt; (pour chaque sauvegarde concernée).&lt;&lt;/li&gt;&lt;li&gt;Si vous avez importé ou exporté un Pokémon au format GBA, veulliez vérifier son altération de statut, ses EVs et son jeu d&apos;origine.&lt;/li&gt;&lt;/ul&gt;</translation>
</message>