summaryrefslogtreecommitdiff
path: root/src/com/dabomstew
diff options
context:
space:
mode:
authortom-overton <tom.overton@outlook.com>2021-12-14 00:58:03 -0800
committertom-overton <tom.overton@outlook.com>2021-12-14 00:58:07 -0800
commit2cd725f57b180d45e1edbde7eac513e8f72ddf3d (patch)
treeee3dff2ff2ed59e1d12c244c172af363df18490f /src/com/dabomstew
parent36f157b1e232d3d65fe50bf0e686c91930f97125 (diff)
Gen 4: Check that ROMs are clean and official
Also fix a shop item thing I broke in Gen 3/4 lol
Diffstat (limited to 'src/com/dabomstew')
-rwxr-xr-xsrc/com/dabomstew/pkrandom/config/gen4_offsets.ini646
-rwxr-xr-xsrc/com/dabomstew/pkrandom/newnds/NDSRom.java8
-rwxr-xr-xsrc/com/dabomstew/pkrandom/romhandlers/AbstractDSRomHandler.java20
-rwxr-xr-xsrc/com/dabomstew/pkrandom/romhandlers/Gen3RomHandler.java6
-rwxr-xr-xsrc/com/dabomstew/pkrandom/romhandlers/Gen4RomHandler.java196
-rwxr-xr-xsrc/com/dabomstew/pkrandom/romhandlers/Gen5RomHandler.java4
6 files changed, 717 insertions, 163 deletions
diff --git a/src/com/dabomstew/pkrandom/config/gen4_offsets.ini b/src/com/dabomstew/pkrandom/config/gen4_offsets.ini
index 70c4f01..e76af40 100755
--- a/src/com/dabomstew/pkrandom/config/gen4_offsets.ini
+++ b/src/com/dabomstew/pkrandom/config/gen4_offsets.ini
@@ -1,24 +1,25 @@
[Diamond (U)]
Game=ADAE
Type=DP
-PokedexAreaData=application/zukanlist/zkn_data/zukan_enc_diamond.narc
-ExtraEncounters=arc/encdata_ex.narc
-BattleSkillSubSeq=battle/skill/sub_seq.narc
-WildPokemon=fielddata/encountdata/d_enc_data.narc
-Events=fielddata/eventdata/zone_event_release.narc
-MapTableFile=fielddata/maptable/mapname.bin
-InGameTrades=fielddata/pokemon_trade/fld_trade.narc
-Scripts=fielddata/script/scr_seq_release.narc
-ItemData=itemtool/itemdata/item_data.narc
-Text=msgdata/msg.narc
-PokemonEvolutions=poketool/personal/evo.narc
-PokemonStats=poketool/personal/personal.narc
-BabyPokemon=poketool/personal/pms.narc
-PokemonMovesets=poketool/personal/wotbl.narc
-PokemonGraphics=poketool/pokegra/pokegra.narc
-TrainerData=poketool/trainer/trdata.narc
-TrainerPokemon=poketool/trainer/trpoke.narc
-MoveData=poketool/waza/waza_tbl.narc
+Version=5
+File<PokedexAreaData>=<application/zukanlist/zkn_data/zukan_enc_diamond.narc, 96EF04FA>
+File<ExtraEncounters>=<arc/encdata_ex.narc, C64C7415>
+File<BattleSkillSubSeq>=<battle/skill/sub_seq.narc, E03D048D>
+File<WildPokemon>=<fielddata/encountdata/d_enc_data.narc, E58BE3CA>
+File<Events>=<fielddata/eventdata/zone_event_release.narc, B15ED699>
+File<MapTableFile>=<fielddata/maptable/mapname.bin, D80BFD77>
+File<InGameTrades>=<fielddata/pokemon_trade/fld_trade.narc, 08464A7E>
+File<Scripts>=<fielddata/script/scr_seq_release.narc, 5FDE722D>
+File<ItemData>=<itemtool/itemdata/item_data.narc, 1E4BDEA1>
+File<Text>=<msgdata/msg.narc, CC7250FE>
+File<PokemonEvolutions>=<poketool/personal/evo.narc, 0F425176>
+File<PokemonStats>=<poketool/personal/personal.narc, F963E181>
+File<BabyPokemon>=<poketool/personal/pms.narc, 6531B9B2>
+File<PokemonMovesets>=<poketool/personal/wotbl.narc, 2AC7EF62>
+File<PokemonGraphics>=<poketool/pokegra/pokegra.narc, 953F8198>
+File<TrainerData>=<poketool/trainer/trdata.narc, 4A3C0C89>
+File<TrainerPokemon>=<poketool/trainer/trpoke.narc, C4AA9026>
+File<MoveData>=<poketool/waza/waza_tbl.narc, 1D89A95D>
EncounterOvlNumber=6
BattleOvlNumber=11
IntroOvlNumber=59
@@ -101,37 +102,57 @@ DoubleBattleTextBoxPrefix=F7F71AFEF7F734FE
TrainerEndFileNumber=4
TrainerEndTextBoxOffset=0xD8
TMText{}={42=[538:1], 48=[54:2], 56=[466:1, 466:2], 63=[135:35], 66=[453:1], 67=[90:0], 76=[60:4], 77=[437:2], 78=[419:2], 88=[518:2], 92=[449:1]}
+Arm9CRC32=08E0337C
+OverlayCRC32<6>=0AE6A693
+OverlayCRC32<11>=3DCCA476
+OverlayCRC32<59>=8CEA8C3C
+OverlayCRC32<64>=727963E2
[Pearl (U)]
Game=APAE
Type=DP
+Version=5
CopyText=1
CopyStaticPokemon=1
CopyRoamingPokemon=1
-CopyFrom=ADAE
-PokedexAreaData=application/zukanlist/zkn_data/zukan_enc_pearl.narc
-WildPokemon=fielddata/encountdata/p_enc_data.narc
-PokemonStats=poketool/personal_pearl/personal.narc
+CopyFrom=Diamond (U)
+File<PokedexAreaData>=<application/zukanlist/zkn_data/zukan_enc_pearl.narc, 14FDDFE6>
+File<WildPokemon>=<fielddata/encountdata/p_enc_data.narc, 5AB5DD4F>
+File<PokemonStats>=<poketool/personal_pearl/personal.narc, 075AD59A>
FastestTextTweak=instant_text/dp_instant_text
NewIndexToMusicTweak=musicfix/diamond_musicfix
NationalDexAtStartTweak=national_dex/dp_national_dex
HoneyTreeOffsets=[5, 6, 7]
MainGameLegendaries=[484]
+Arm9CRC32=D80458A5
+OverlayCRC32<6>=F7C193D2
+OverlayCRC32<11>=0DD7691D
+OverlayCRC32<59>=8CEA8C3C
+OverlayCRC32<64>=525F49E6
[Platinum (U)]
Game=CPUE
Type=Plat
-CopyFrom=ADAE
-PokedexAreaData=application/zukanlist/zkn_data/zukan_enc_platinum.narc
-ExtraEncounters=arc/encdata_ex.narc
-WildPokemon=fielddata/encountdata/pl_enc_data.narc
-Events=fielddata/eventdata/zone_event.narc
-Scripts=fielddata/script/scr_seq.narc
-ItemData=itemtool/itemdata/pl_item_data.narc
-Text=msgdata/pl_msg.narc
-PokemonStats=poketool/personal/pl_personal.narc
-PokemonGraphics=poketool/pokegra/pl_pokegra.narc
-MoveData=poketool/waza/pl_waza_tbl.narc
+Version=0
+CopyFrom=Diamond (U)
+File<PokedexAreaData>=<application/zukanlist/zkn_data/zukan_enc_platinum.narc, 2F58506E>
+File<ExtraEncounters>=<arc/encdata_ex.narc, 03FB3F28>
+File<BattleSkillSubSeq>=<battle/skill/sub_seq.narc, B02FF213>
+File<WildPokemon>=<fielddata/encountdata/pl_enc_data.narc, 188084F5>
+File<Events>=<fielddata/eventdata/zone_event.narc, D8BB2D84>
+File<MapTableFile>=<fielddata/maptable/mapname.bin, 530174B6>
+File<InGameTrades>=<fielddata/pokemon_trade/fld_trade.narc, B98CC1AF>
+File<Scripts>=<fielddata/script/scr_seq.narc, 6D482515>
+File<ItemData>=<itemtool/itemdata/pl_item_data.narc, AAE44533>
+File<Text>=<msgdata/pl_msg.narc, 5666AAEC>
+File<PokemonEvolutions>=<poketool/personal/evo.narc, 6711E4B4>
+File<PokemonStats>=<poketool/personal/pl_personal.narc, B16A8A01>
+File<BabyPokemon>=<poketool/personal/pms.narc, C457991B>
+File<PokemonMovesets>=<poketool/personal/wotbl.narc, 977997B9>
+File<PokemonGraphics>=<poketool/pokegra/pl_pokegra.narc, 03BBC013>
+File<TrainerData>=<poketool/trainer/trdata.narc, 2EE9B886>
+File<TrainerPokemon>=<poketool/trainer/trpoke.narc, 739A02EE>
+File<MoveData>=<poketool/waza/pl_waza_tbl.narc, B2D18230>
FieldOvlNumber=5
MoveTutorCompatOvlNumber=5
BattleOvlNumber=16
@@ -216,30 +237,37 @@ DoubleBattleWalkingPrefix1=16B00020F8BD1498
DoubleBattleWalkingPrefix2=C4FE16B00120F8BD
DoubleBattleTextBoxPrefix=F6F792FCF6F7ACFC
TMText{}={27=[561:10], 42=[594:1], 48=[61:1], 56=[517:0, 517:1], 63=[143:51], 66=[504:1, 504:2], 67=[98:0], 76=[67:4], 77=[488:2], 78=[470:2], 88=[574:2], 92=[500:1]}
+Arm9CRC32=4D104949
+OverlayCRC32<5>=3E286491
+OverlayCRC32<6>=E6C5F31B
+OverlayCRC32<16>=25EBE8C1
+OverlayCRC32<73>=C003DED1
+OverlayCRC32<78>=091E8E97
[HeartGold (U)]
Game=IPKE
Type=HGSS
-BattleSkillSubSeq=a/0/0/1
-PokemonStats=a/0/0/2
-PokemonGraphics=a/0/0/4
-MoveData=a/0/1/1
-Scripts=a/0/1/2
-ItemData=a/0/1/7
-Text=a/0/2/7
-Events=a/0/3/2
-PokemonMovesets=a/0/3/3
-PokemonEvolutions=a/0/3/4
-WildPokemon=a/0/3/7
-TrainerData=a/0/5/5
-TrainerPokemon=a/0/5/6
-InGameTrades=a/1/1/2
-PokedexAreaData=a/1/3/3
-HeadbuttPokemon=a/2/5/2
-BCCWilds=data/mushi/mushi_encount.bin
-MapTableFile=fielddata/maptable/mapname.bin
-MoveTutorCompat=fielddata/wazaoshie/waza_oshie.bin
-BabyPokemon=poketool/personal/pms.narc
+Version=0
+File<BattleSkillSubSeq>=<a/0/0/1, 6644F919>
+File<PokemonStats>=<a/0/0/2, DE8C5CAF>
+File<PokemonGraphics>=<a/0/0/4, 373BBE93>
+File<MoveData>=<a/0/1/1, 284AEE7A>
+File<Scripts>=<a/0/1/2, A7E3F740>
+File<ItemData>=<a/0/1/7, 40823EDE>
+File<Text>=<a/0/2/7, 123DEB0B>
+File<Events>=<a/0/3/2, 3AC93851>
+File<PokemonMovesets>=<a/0/3/3, F0F9B169>
+File<PokemonEvolutions>=<a/0/3/4, 6711E4B4>
+File<WildPokemon>=<a/0/3/7, 9B861BD5>
+File<TrainerData>=<a/0/5/5, 8B9BD9CE>
+File<TrainerPokemon>=<a/0/5/6, E30BC8BE>
+File<InGameTrades>=<a/1/1/2, 24561BD6>
+File<PokedexAreaData>=<a/1/3/3, 4B9696A6>
+File<HeadbuttPokemon>=<a/2/5/2, 82A55C45>
+File<BCCWilds>=<data/mushi/mushi_encount.bin, 17CA15C5>
+File<MapTableFile>=<fielddata/maptable/mapname.bin, 5547F5BE>
+File<MoveTutorCompat>=<fielddata/wazaoshie/waza_oshie.bin, 1DFC77A1>
+File<BabyPokemon>=<poketool/personal/pms.narc, C457991B>
FieldOvlNumber=1
BattleOvlNumber=12
FossilTableOvlNumber=21
@@ -364,28 +392,156 @@ FrontierScriptNumber=76
FrontierScriptTMOffsets{}={40=0xC5C, 31=0xC7A, 89=0xC98, 81=0xCB6, 71=0xCD4, 26=0xCF2, 30=0xD88, 53=0xDA6, 36=0xDC4, 59=0xDE2, 06=0xEA2, 73=0xEC0, 61=0xEDE, 45=0xEFC, 08=0xF1A, 04=0xF38}
MiscUITextOffset=191
FrontierTMText{}={40=380, 31=381, 89=382, 81=383, 71=384, 26=385, 30=386, 53=387, 36=388, 59=389, 06=390, 73=391, 61=392, 45=393, 08=394, 04=395}
+Arm9CRC32=ED466320
+OverlayCRC32<1>=21F7A855
+OverlayCRC32<12>=90D2AF3E
+OverlayCRC32<21>=A6363D04
+OverlayCRC32<61>=EE849CB4
[SoulSilver (U)]
Game=IPGE
Type=HGSS
+Version=0
CopyText=1
CopyStaticPokemon=1
CopyRoamingPokemon=1
-CopyFrom=IPKE
-WildPokemon=a/1/3/6
+CopyFrom=HeartGold (U)
+File<PokedexAreaData>=<a/1/3/3, D6CA84B4>
+File<WildPokemon>=<a/1/3/6, BB578A64>
+File<HeadbuttPokemon>=<a/2/5/2, 58826D1E>
FastestTextTweak=instant_text/hgss_instant_text
NationalDexAtStartTweak=national_dex/hgss_national_dex
NewCatchingTutorialSubroutineTweak=hgss_catching_tutorialfix
NewRoamerSubroutineTweak=hardcoded_statics/roamers/hgss_roamers
MainGameLegendaries=[249]
+Arm9CRC32=C243A15F
+OverlayCRC32<1>=172E4E62
+OverlayCRC32<12>=7AFCE42A
+OverlayCRC32<21>=A6363D04
+OverlayCRC32<61>=EE849CB4
+
+[Diamond (E)]
+Game=ADAE
+Type=DP
+Version=13
+CopyText=1
+CopyStaticPokemon=1
+CopyRoamingPokemon=1
+CopyFrom=Diamond (U)
+File<Text>=<msgdata/msg.narc, 35C0495C>
+FastestTextTweak=instant_text/dp_instant_text
+NewIndexToMusicTweak=musicfix/diamond_musicfix
+NationalDexAtStartTweak=national_dex/dp_national_dex
+Arm9CRC32=08E0337C
+OverlayCRC32<6>=0AE6A693
+OverlayCRC32<11>=3DCCA476
+OverlayCRC32<59>=8CEA8C3C
+OverlayCRC32<64>=727963E2
+
+[Pearl (E)]
+Game=APAE
+Type=DP
+Version=13
+CopyText=1
+CopyStaticPokemon=1
+CopyRoamingPokemon=1
+CopyFrom=Pearl (U)
+File<Text>=<msgdata/msg.narc, 35C0495C>
+FastestTextTweak=instant_text/dp_instant_text
+NewIndexToMusicTweak=musicfix/diamond_musicfix
+NationalDexAtStartTweak=national_dex/dp_national_dex
+Arm9CRC32=D80458A5
+OverlayCRC32<6>=F7C193D2
+OverlayCRC32<11>=0DD7691D
+OverlayCRC32<59>=8CEA8C3C
+OverlayCRC32<64>=525F49E6
+
+[Platinum (U Rev 1)]
+Game=CPUE
+Type=Plat
+Version=1
+CopyText=1
+CopyStaticPokemon=1
+CopyRoamingPokemon=1
+CopyFrom=Platinum (U)
+NewRoamerSubroutineTweak=hardcoded_statics/roamers/plat_roamers
+FastestTextTweak=instant_text/plat_instant_text
+NewIndexToMusicTweak=musicfix/plat_musicfix
+NationalDexAtStartTweak=national_dex/plat_national_dex
+Arm9CRC32=4D104949
+OverlayCRC32<5>=3E286491
+OverlayCRC32<6>=E6C5F31B
+OverlayCRC32<16>=25EBE8C1
+OverlayCRC32<73>=C003DED1
+OverlayCRC32<78>=091E8E97
+
+[Platinum (E)]
+Game=CPUE
+Type=Plat
+Version=10
+CopyText=1
+CopyStaticPokemon=1
+CopyRoamingPokemon=1
+CopyFrom=Platinum (U)
+File<Scripts>=<fielddata/script/scr_seq.narc, FFAB46E4>
+File<Text>=<msgdata/pl_msg.narc, B2ECC558>
+NewRoamerSubroutineTweak=hardcoded_statics/roamers/plat_roamers
+FastestTextTweak=instant_text/plat_instant_text
+NewIndexToMusicTweak=musicfix/plat_musicfix
+NationalDexAtStartTweak=national_dex/plat_national_dex
+Arm9CRC32=4D104949
+OverlayCRC32<5>=3E286491
+OverlayCRC32<6>=E6C5F31B
+OverlayCRC32<16>=25EBE8C1
+OverlayCRC32<73>=C003DED1
+OverlayCRC32<78>=091E8E97
+
+[HeartGold (E)]
+Game=IPKE
+Type=HGSS
+Version=10
+CopyText=1
+CopyStaticPokemon=1
+CopyRoamingPokemon=1
+CopyFrom=HeartGold (U)
+NewRoamerSubroutineTweak=hardcoded_statics/roamers/hgss_roamers
+NewCatchingTutorialSubroutineTweak=hgss_catching_tutorialfix
+FastestTextTweak=instant_text/hgss_instant_text
+NationalDexAtStartTweak=national_dex/hgss_national_dex
+Arm9CRC32=ED466320
+OverlayCRC32<1>=21F7A855
+OverlayCRC32<12>=90D2AF3E
+OverlayCRC32<21>=A6363D04
+OverlayCRC32<61>=EE849CB4
+
+[SoulSilver (E)]
+Game=IPGE
+Type=HGSS
+Version=10
+CopyText=1
+CopyStaticPokemon=1
+CopyRoamingPokemon=1
+CopyFrom=SoulSilver (U)
+FastestTextTweak=instant_text/hgss_instant_text
+NationalDexAtStartTweak=national_dex/hgss_national_dex
+NewCatchingTutorialSubroutineTweak=hgss_catching_tutorialfix
+NewRoamerSubroutineTweak=hardcoded_statics/roamers/hgss_roamers
+Arm9CRC32=C243A15F
+OverlayCRC32<1>=172E4E62
+OverlayCRC32<12>=7AFCE42A
+OverlayCRC32<21>=A6363D04
+OverlayCRC32<61>=EE849CB4
[Pearl (J)]
Game=APAJ
Type=DP
+Version=0
CopyStaticPokemon=1
-CopyFrom=APAE
-Events=fielddata/eventdata/zone_event.narc
-Scripts=fielddata/script/scr_seq.narc
+CopyFrom=Pearl (U)
+File<BattleSkillSubSeq>=<battle/skill/sub_seq.narc, E4519D76>
+File<Events>=<fielddata/eventdata/zone_event.narc, D7363FA7>
+File<Scripts>=<fielddata/script/scr_seq.narc, E814B448>
+File<Text>=<msgdata/msg.narc, F39D072F>
StarterPokemonOffset=0x30
HiddenItemTableOffset=0xF4C14
HasExtraPokemonNames=No
@@ -407,14 +563,22 @@ MapNamesTextOffset=374
CatchingTutorialOpponentMonOffset=0x4AB34
FossilTableOffset=0xF6334
ShopDataPrefix=F11A040249BD030219BD0302FDBC0302
+Arm9CRC32=B1A9B403
+OverlayCRC32<6>=AD2BA4AF
+OverlayCRC32<11>=4F5D2535
+OverlayCRC32<59>=52AAB459
+OverlayCRC32<64>=6CC01D0F
[Diamond (J)]
Game=ADAJ
Type=DP
+Version=0
CopyStaticPokemon=1
-CopyFrom=ADAE
-Events=fielddata/eventdata/zone_event.narc
-Scripts=fielddata/script/scr_seq.narc
+CopyFrom=Diamond (U)
+File<BattleSkillSubSeq>=<battle/skill/sub_seq.narc, E4519D76>
+File<Events>=<fielddata/eventdata/zone_event.narc, D7363FA7>
+File<Scripts>=<fielddata/script/scr_seq.narc, E814B448>
+File<Text>=<msgdata/msg.narc, F39D072F>
StarterPokemonOffset=0x30
HiddenItemTableOffset=0xF4C10
HasExtraPokemonNames=No
@@ -436,13 +600,36 @@ MapNamesTextOffset=374
CatchingTutorialOpponentMonOffset=0x4AB34
FossilTableOffset=0xF6330
ShopDataPrefix=F11A040249BD030219BD0302FDBC0302
+Arm9CRC32=2624AED0
+OverlayCRC32<6>=90564DAF
+OverlayCRC32<11>=87D3D888
+OverlayCRC32<59>=189D13CA
+OverlayCRC32<64>=6F2480C9
+
+[Pearl (J Rev 5)]
+Game=APAJ
+Type=DP
+Version=5
+CopyText=1
+CopyStaticPokemon=1
+CopyFrom=Pearl (J)
+Arm9CRC32=B1A9B403
+OverlayCRC32<6>=AD2BA4AF
+OverlayCRC32<11>=4F5D2535
+OverlayCRC32<59>=52AAB459
+OverlayCRC32<64>=6CC01D0F
[Pearl (G)]
Game=APAD
Type=DP
+Version=5
CopyStaticPokemon=1
-CopyFrom=APAE
-InGameTrades=resource/ger/pokemon_trade/fld_trade.narc
+CopyFrom=Pearl (U)
+File<BattleSkillSubSeq>=<battle/skill/sub_seq.narc, A2B73706>
+File<Scripts>=<fielddata/script/scr_seq_release.narc, 81E4C75B>
+File<Text>=<msgdata/msg.narc, 4A2EDAAE>
+File<PokemonGraphics>=<poketool/pokegra/pokegra.narc, 99FC6C2E>
+File<InGameTrades>=<resource/ger/pokemon_trade/fld_trade.narc, EA64A7F9>
NationalDexAtStartTweak=national_dex/dp_national_dex
HiddenItemTableOffset=0xF2DC4
MapTableARM9Offset=0xEEDCC
@@ -452,13 +639,23 @@ DoubleBattleFlagReturnPrefix=08B5092131F02AFB
DoubleBattleWalkingPrefix2=22FB16B00120F8BD
DoubleBattleTextBoxPrefix=F7F706FEF7F720FE
ShopDataPrefix=BD110402CDAF0302EDAF0302DD110402
+Arm9CRC32=672E6E4B
+OverlayCRC32<6>=6E45EC08
+OverlayCRC32<11>=A1F171CB
+OverlayCRC32<59>=96DC349C
+OverlayCRC32<64>=CD34E846
[Diamond (G)]
Game=ADAD
Type=DP
+Version=5
CopyStaticPokemon=1
-CopyFrom=ADAE
-InGameTrades=resource/ger/pokemon_trade/fld_trade.narc
+CopyFrom=Diamond (U)
+File<BattleSkillSubSeq>=<battle/skill/sub_seq.narc, A2B73706>
+File<Scripts>=<fielddata/script/scr_seq_release.narc, 81E4C75B>
+File<Text>=<msgdata/msg.narc, 4A2EDAAE>
+File<PokemonGraphics>=<poketool/pokegra/pokegra.narc, 99FC6C2E>
+File<InGameTrades>=<resource/ger/pokemon_trade/fld_trade.narc, EA64A7F9>
NationalDexAtStartTweak=national_dex/dp_national_dex
HiddenItemTableOffset=0xF2DC4
MapTableARM9Offset=0xEEDCC
@@ -468,13 +665,23 @@ DoubleBattleFlagReturnPrefix=08B5092131F02AFB
DoubleBattleWalkingPrefix2=22FB16B00120F8BD
DoubleBattleTextBoxPrefix=F7F706FEF7F720FE
ShopDataPrefix=BD110402CDAF0302EDAF0302DD110402
+Arm9CRC32=6534A1F1
+OverlayCRC32<6>=93FB792F
+OverlayCRC32<11>=0C8681F0
+OverlayCRC32<59>=96DC349C
+OverlayCRC32<64>=65244084
[Pearl (S)]
Game=APAS
Type=DP
+Version=5
CopyStaticPokemon=1
-CopyFrom=APAE
-InGameTrades=resource/spa/pokemon_trade/fld_trade.narc
+CopyFrom=Pearl (U)
+File<BattleSkillSubSeq>=<battle/skill/sub_seq.narc, A2B73706>
+File<Scripts>=<fielddata/script/scr_seq_release.narc, 8FADF14D>
+File<Text>=<msgdata/msg.narc, 011962EF>
+File<PokemonGraphics>=<poketool/pokegra/pokegra.narc, 99FC6C2E>
+File<InGameTrades>=<resource/spa/pokemon_trade/fld_trade.narc, B0A25B9D>
NationalDexAtStartTweak=national_dex/dp_national_dex
HiddenItemTableOffset=0xF2E00
MapTableARM9Offset=0xEEE08
@@ -484,13 +691,23 @@ DoubleBattleFlagReturnPrefix=08B5092131F02AFB
DoubleBattleWalkingPrefix2=22FB16B00120F8BD
DoubleBattleTextBoxPrefix=F7F706FEF7F720FE
ShopDataPrefix=BD110402CDAF0302EDAF0302DD110402
+Arm9CRC32=F84C375A
+OverlayCRC32<6>=E2BF78A0
+OverlayCRC32<11>=22C6C9CA
+OverlayCRC32<59>=B77DAB96
+OverlayCRC32<64>=A92907D8
[Diamond (S)]
Game=ADAS
Type=DP
+Version=5
CopyStaticPokemon=1
-CopyFrom=ADAE
-InGameTrades=resource/spa/pokemon_trade/fld_trade.narc
+CopyFrom=Diamond (U)
+File<BattleSkillSubSeq>=<battle/skill/sub_seq.narc, A2B73706>
+File<Scripts>=<fielddata/script/scr_seq_release.narc, 8FADF14D>
+File<Text>=<msgdata/msg.narc, 011962EF>
+File<PokemonGraphics>=<poketool/pokegra/pokegra.narc, 99FC6C2E>
+File<InGameTrades>=<resource/spa/pokemon_trade/fld_trade.narc, B0A25B9D>
NationalDexAtStartTweak=national_dex/dp_national_dex
HiddenItemTableOffset=0xF2E00
MapTableARM9Offset=0xEEE08
@@ -500,13 +717,23 @@ DoubleBattleFlagReturnPrefix=08B5092131F02AFB
DoubleBattleWalkingPrefix2=22FB16B00120F8BD
DoubleBattleTextBoxPrefix=F7F706FEF7F720FE
ShopDataPrefix=BD110402CDAF0302EDAF0302DD110402
+Arm9CRC32=6A024910
+OverlayCRC32<6>=34FF651E
+OverlayCRC32<11>=17D68A91
+OverlayCRC32<59>=B77DAB96
+OverlayCRC32<64>=5CE1EE3C
[Pearl (I)]
Game=APAI
Type=DP
+Version=5
CopyStaticPokemon=1
-CopyFrom=APAE
-InGameTrades=resource/ita/pokemon_trade/fld_trade.narc
+CopyFrom=Pearl (U)
+File<BattleSkillSubSeq>=<battle/skill/sub_seq.narc, A2B73706>
+File<Scripts>=<fielddata/script/scr_seq_release.narc, 3596DF31>
+File<Text>=<msgdata/msg.narc, 9809787C>
+File<PokemonGraphics>=<poketool/pokegra/pokegra.narc, 99FC6C2E>
+File<InGameTrades>=<resource/ita/pokemon_trade/fld_trade.narc, 0168D04C>
NationalDexAtStartTweak=national_dex/dp_national_dex
HiddenItemTableOffset=0xF2D68
MapTableARM9Offset=0xEED70
@@ -516,14 +743,24 @@ DoubleBattleFlagReturnPrefix=08B5092131F01AFB
DoubleBattleWalkingPrefix2=22FB16B00120F8BD
DoubleBattleTextBoxPrefix=F7F706FEF7F720FE
ShopDataPrefix=BD110402CDAF0302EDAF0302DD110402
+Arm9CRC32=6C854C5F
+OverlayCRC32<6>=45958341
+OverlayCRC32<11>=2E88B408
+OverlayCRC32<59>=65BC0057
+OverlayCRC32<64>=AEC1D5A4
[Diamond (I)]
Game=ADAI
Type=DP
+Version=5
CopyStaticPokemon=1
-CopyFrom=ADAE
+CopyFrom=Diamond (U)
HiddenItemTableOffset=0xF2D68
-InGameTrades=resource/ita/pokemon_trade/fld_trade.narc
+File<BattleSkillSubSeq>=<battle/skill/sub_seq.narc, A2B73706>
+File<Scripts>=<fielddata/script/scr_seq_release.narc, 3596DF31>
+File<Text>=<msgdata/msg.narc, 9809787C>
+File<PokemonGraphics>=<poketool/pokegra/pokegra.narc, 99FC6C2E>
+File<InGameTrades>=<resource/ita/pokemon_trade/fld_trade.narc, 0168D04C>
NationalDexAtStartTweak=national_dex/dp_national_dex
MapTableARM9Offset=0xEED70
CatchingTutorialOpponentMonOffset=0x479D0
@@ -532,13 +769,23 @@ DoubleBattleFlagReturnPrefix=08B5092131F01AFB
DoubleBattleWalkingPrefix2=22FB16B00120F8BD
DoubleBattleTextBoxPrefix=F7F706FEF7F720FE
ShopDataPrefix=BD110402CDAF0302EDAF0302DD110402
+Arm9CRC32=569504C4
+OverlayCRC32<6>=DEAC5AEB
+OverlayCRC32<11>=8C0E7676
+OverlayCRC32<59>=65BC0057
+OverlayCRC32<64>=5B093C40
[Pearl (F)]
Game=APAF
Type=DP
+Version=5
CopyStaticPokemon=1
-CopyFrom=APAE
-InGameTrades=resource/fra/pokemon_trade/fld_trade.narc
+CopyFrom=Pearl (U)
+File<BattleSkillSubSeq>=<battle/skill/sub_seq.narc, A2B73706>
+File<Scripts>=<fielddata/script/scr_seq_release.narc, 8FADF14D>
+File<Text>=<msgdata/msg.narc, 2A61CC12>
+File<PokemonGraphics>=<poketool/pokegra/pokegra.narc, 99FC6C2E>
+File<InGameTrades>=<resource/fra/pokemon_trade/fld_trade.narc, D6CAB8E0>
NationalDexAtStartTweak=national_dex/dp_national_dex
HiddenItemTableOffset=0xF2DF4
MapTableARM9Offset=0xEEDFC
@@ -548,13 +795,23 @@ DoubleBattleFlagReturnPrefix=08B5092131F02AFB
DoubleBattleWalkingPrefix2=22FB16B00120F8BD
DoubleBattleTextBoxPrefix=F7F706FEF7F720FE
ShopDataPrefix=BD110402CDAF0302EDAF0302DD110402
+Arm9CRC32=AD992311
+OverlayCRC32<6>=8934EF2F
+OverlayCRC32<11>=53F5A4B0
+OverlayCRC32<59>=95817DEA
+OverlayCRC32<64>=143FB16B
[Diamond (F)]
Game=ADAF
Type=DP
+Version=5
CopyStaticPokemon=1
-CopyFrom=ADAE
-InGameTrades=resource/fra/pokemon_trade/fld_trade.narc
+CopyFrom=Diamond (U)
+File<BattleSkillSubSeq>=<battle/skill/sub_seq.narc, A2B73706>
+File<Scripts>=<fielddata/script/scr_seq_release.narc, 8FADF14D>
+File<Text>=<msgdata/msg.narc, 2A61CC12>
+File<PokemonGraphics>=<poketool/pokegra/pokegra.narc, 99FC6C2E>
+File<InGameTrades>=<resource/fra/pokemon_trade/fld_trade.narc, D6CAB8E0>
NationalDexAtStartTweak=national_dex/dp_national_dex
HiddenItemTableOffset=0xF2DF4
MapTableARM9Offset=0xEEDFC
@@ -564,13 +821,23 @@ DoubleBattleFlagReturnPrefix=08B5092131F02AFB
DoubleBattleWalkingPrefix2=22FB16B00120F8BD
DoubleBattleTextBoxPrefix=F7F706FEF7F720FE
ShopDataPrefix=BD110402CDAF0302EDAF0302DD110402
+Arm9CRC32=B8EE141C
+OverlayCRC32<6>=A5AD136A
+OverlayCRC32<11>=A0CA9F36
+OverlayCRC32<59>=95817DEA
+OverlayCRC32<64>=34199B6F
[Pearl (K)]
Game=APAK
Type=DP
+Version=0
CopyStaticPokemon=1
-CopyFrom=APAE
-InGameTrades=resource/kor/pokemon_trade/fld_trade.narc
+CopyFrom=Pearl (U)
+File<BattleSkillSubSeq>=<battle/skill/sub_seq.narc, FE6A1BDA>
+File<Scripts>=<fielddata/script/scr_seq_release.narc, C39FCE21>
+File<Text>=<msgdata/msg.narc, 1C515BDD>
+File<PokemonGraphics>=<poketool/pokegra/pokegra.narc, 99FC6C2E>
+File<InGameTrades>=<resource/kor/pokemon_trade/fld_trade.narc, ABD1F5CB>
NationalDexAtStartTweak=national_dex/dp_national_dex
HiddenItemTableOffset=0xEE400
HasExtraPokemonNames=No
@@ -595,13 +862,23 @@ DoubleBattleFlagReturnPrefix=08B5092131F04AFB
DoubleBattleWalkingPrefix2=02FB16B00120F8BD
DoubleBattleTextBoxPrefix=F7F708FEF7F722FE
ShopDataPrefix=E1150402F1B3030211B4030201160402
+Arm9CRC32=E317C09B
+OverlayCRC32<6>=37ECE0C0
+OverlayCRC32<11>=A41BD6FC
+OverlayCRC32<59>=E3B4A7FF
+OverlayCRC32<64>=4431AA3B
[Diamond (K)]
Game=ADAK
Type=DP
+Version=0
CopyStaticPokemon=1
-CopyFrom=ADAE
-InGameTrades=resource/kor/pokemon_trade/fld_trade.narc
+CopyFrom=Diamond (U)
+File<BattleSkillSubSeq>=<battle/skill/sub_seq.narc, FE6A1BDA>
+File<Scripts>=<fielddata/script/scr_seq_release.narc, C39FCE21>
+File<Text>=<msgdata/msg.narc, 1C515BDD>
+File<PokemonGraphics>=<poketool/pokegra/pokegra.narc, 99FC6C2E>
+File<InGameTrades>=<resource/kor/pokemon_trade/fld_trade.narc, ABD1F5CB>
NationalDexAtStartTweak=national_dex/dp_national_dex
HiddenItemTableOffset=0xEE400
HasExtraPokemonNames=No
@@ -626,12 +903,22 @@ DoubleBattleFlagReturnPrefix=08B5092131F04AFB
DoubleBattleWalkingPrefix2=02FB16B00120F8BD
DoubleBattleTextBoxPrefix=F7F708FEF7F722FE
ShopDataPrefix=E1150402F1B3030211B4030201160402
+Arm9CRC32=E50BF4B5
+OverlayCRC32<6>=4681ECC3
+OverlayCRC32<11>=3D2D9752
+OverlayCRC32<59>=E3B4A7FF
+OverlayCRC32<64>=6417803F
[Platinum (J)]
Game=CPUJ
Type=Plat
+Version=0
CopyStaticPokemon=1
-CopyFrom=CPUE
+CopyFrom=Platinum (U)
+File<InGameTrades>=<fielddata/pokemon_trade/fld_trade.narc, 08464A7E>
+File<Scripts>=<fielddata/script/scr_seq.narc, F121799E>
+File<Text>=<msgdata/pl_msg.narc, A131FC08>
+File<PokemonGraphics>=<poketool/pokegra/pl_pokegra.narc, 6C318437>
HiddenItemTableOffset=0xE9A4C
MoveTutorMovesOffset=0x2FD54
MoveTutorCompatOffset=0x2FF1C
@@ -658,13 +945,22 @@ DoubleBattleFlagReturnPrefix=08B5092139F054FE
DoubleBattleWalkingPrefix2=3CF816B00120F8BD
DoubleBattleTextBoxPrefix=F6F7FEFDF6F718FE
ShopDataPrefix=E5691F0271450402A5450402A1200402
+Arm9CRC32=9370B1BD
+OverlayCRC32<5>=D045CE6A
+OverlayCRC32<6>=D5C60661
+OverlayCRC32<16>=13CDEC92
+OverlayCRC32<73>=8FB18796
+OverlayCRC32<78>=ABCE5F9F
[Platinum (G)]
Game=CPUD
Type=Plat
+Version=0
CopyStaticPokemon=1
-CopyFrom=CPUE
-InGameTrades=resource/ger/pokemon_trade/fld_trade.narc
+CopyFrom=Platinum (U)
+File<Scripts>=<fielddata/script/scr_seq.narc, 01DF1412>
+File<Text>=<msgdata/pl_msg.narc, 96C8829B>
+File<InGameTrades>=<resource/ger/pokemon_trade/fld_trade.narc, EA64A7F9>
NationalDexAtStartTweak=national_dex/plat_national_dex
HiddenItemTableOffset=0xEA3D0
MoveTutorMovesOffset=0x2FF80
@@ -674,13 +970,22 @@ CatchingTutorialOpponentMonOffset=0x52144
FossilTableOffset=0xEC054
DoubleBattleFlagReturnPrefix=08B5092139F0C4FF
ShopDataPrefix=91800402C98004020581040225810402
+Arm9CRC32=14AC281F
+OverlayCRC32<5>=9ABB1B3D
+OverlayCRC32<6>=531E0103
+OverlayCRC32<16>=81FBB5A9
+OverlayCRC32<73>=78321B58
+OverlayCRC32<78>=BB90F646
[Platinum (F)]
Game=CPUF
Type=Plat
+Version=0
CopyStaticPokemon=1
-CopyFrom=CPUE
-InGameTrades=resource/fra/pokemon_trade/fld_trade.narc
+CopyFrom=Platinum (U)
+File<Scripts>=<fielddata/script/scr_seq.narc, D81D0712>
+File<Text>=<msgdata/pl_msg.narc, 541B73AE>
+File<InGameTrades>=<resource/fra/pokemon_trade/fld_trade.narc, D6CAB8E0>
NationalDexAtStartTweak=national_dex/plat_national_dex
HiddenItemTableOffset=0xEA400
MoveTutorMovesOffset=0x2FF6C
@@ -690,13 +995,22 @@ CatchingTutorialOpponentMonOffset=0x52144
FossilTableOffset=0xEC084
DoubleBattleFlagReturnPrefix=08B5092139F0C4FF
ShopDataPrefix=91800402C98004020581040225810402
+Arm9CRC32=C0B29D1E
+OverlayCRC32<5>=7157FFE7
+OverlayCRC32<6>=0FCDB778
+OverlayCRC32<16>=495B8746
+OverlayCRC32<73>=CD2E3918
+OverlayCRC32<78>=5181F86B
[Platinum (S)]
Game=CPUS
Type=Plat
+Version=0
CopyStaticPokemon=1
-CopyFrom=CPUE
-InGameTrades=resource/spa/pokemon_trade/fld_trade.narc
+CopyFrom=Platinum (U)
+File<Scripts>=<fielddata/script/scr_seq.narc, D81D0712>
+File<Text>=<msgdata/pl_msg.narc, 8DE5119D>
+File<InGameTrades>=<resource/spa/pokemon_trade/fld_trade.narc, B0A25B9D>
NationalDexAtStartTweak=national_dex/plat_national_dex
HiddenItemTableOffset=0xEA40C
MoveTutorMovesOffset=0x2FF6C
@@ -706,13 +1020,22 @@ CatchingTutorialOpponentMonOffset=0x52144
FossilTableOffset=0xEC090
DoubleBattleFlagReturnPrefix=08B5092139F0C4FF
ShopDataPrefix=91800402C98004020581040225810402
+Arm9CRC32=D3F8273F
+OverlayCRC32<5>=C4A31B48
+OverlayCRC32<6>=0E93E266
+OverlayCRC32<16>=1BBB41F1
+OverlayCRC32<73>=0F84AAEE
+OverlayCRC32<78>=07F2C593
[Platinum (I)]
Game=CPUI
Type=Plat
+Version=0
CopyStaticPokemon=1
-CopyFrom=CPUE
-InGameTrades=resource/ita/pokemon_trade/fld_trade.narc
+CopyFrom=Platinum (U)
+File<Scripts>=<fielddata/script/scr_seq.narc, D12BBD3C>
+File<Text>=<msgdata/pl_msg.narc, 641AA93B>
+File<InGameTrades>=<resource/ita/pokemon_trade/fld_trade.narc, 0168D04C>
NationalDexAtStartTweak=national_dex/plat_national_dex
HiddenItemTableOffset=0xEA394
MoveTutorMovesOffset=0x2FF74
@@ -722,13 +1045,22 @@ CatchingTutorialOpponentMonOffset=0x52144
FossilTableOffset=0xEC018
DoubleBattleFlagReturnPrefix=08B5092139F0C4FF
ShopDataPrefix=91800402C98004020581040225810402
+Arm9CRC32=EDD15660
+OverlayCRC32<5>=DAD8DD1C
+OverlayCRC32<6>=5664CD24
+OverlayCRC32<16>=3528E1D6
+OverlayCRC32<73>=03562E3A
+OverlayCRC32<78>=A99B6322
[Platinum (K)]
Game=CPUK
Type=Plat
+Version=0
CopyStaticPokemon=1
-CopyFrom=CPUE
-InGameTrades=resource/kor/pokemon_trade/fld_trade.narc
+CopyFrom=Platinum (U)
+File<Scripts>=<fielddata/script/scr_seq.narc, CC45B7B9>
+File<Text>=<msgdata/pl_msg.narc, 158E7FDB>
+File<InGameTrades>=<resource/kor/pokemon_trade/fld_trade.narc, ABD1F5CB>
NationalDexAtStartTweak=national_dex/plat_national_dex
HiddenItemTableOffset=0xEAE00
MoveTutorMovesOffset=0x2FF5C
@@ -755,11 +1087,22 @@ DoubleBattleFlagReturnPrefix=08B5092139F0C4FF
DoubleBattleWalkingPrefix2=C0FE16B00120F8BD
DoubleBattleTextBoxPrefix=F6F790FCF6F7AAFC
ShopDataPrefix=E1840402198504025585040275850402
+Arm9CRC32=BAE2AD4B
+OverlayCRC32<5>=CADD3A64
+OverlayCRC32<6>=CFF5136D
+OverlayCRC32<16>=14CC7DEA
+OverlayCRC32<73>=D891EA37
+OverlayCRC32<78>=923ACAED
[HeartGold (J)]
Game=IPKJ
Type=HGSS
-CopyFrom=IPKE
+Version=0
+CopyFrom=HeartGold (U)
+File<Scripts>=<a/0/1/2, 98F75402>
+File<Text>=<a/0/2/7, 7026E193>
+File<Events>=<a/0/3/2, BB5D8229>
+File<InGameTrades>=<a/1/1/2, 76DCB3F5>
NationalDexAtStartTweak=national_dex/hgss_national_dex
HiddenItemTableOffset=0xF9D08
MoveTutorMovesOffset=0x23954
@@ -841,21 +1184,37 @@ DoubleBattleTextBoxPrefix=F6F7F0FFF7F70AF8
ShopDataPrefix=E57C040235770402CD1C200251320402
TMTextGameCorner{}={90=[591:39], 75=[591:40], 44=[591:41], 35=[591:42], 13=[591:43], 24=[591:44]} // Goldenrod
TMTextGameCorner{}={58=[502:23], 32=[502:24], 10=[502:25], 29=[502:26], 74=[502:27], 68=[502:28]} // Celadon
+Arm9CRC32=BA386530
+OverlayCRC32<1>=513BF822
+OverlayCRC32<12>=C95025DF
+OverlayCRC32<21>=7874DA2E
+OverlayCRC32<61>=F45FB204
[SoulSilver (J)]
Game=IPGJ
Type=HGSS
+Version=0
CopyStaticPokemon=1
-CopyFrom=IPKJ
-WildPokemon=a/1/3/6
+CopyFrom=HeartGold (J)
+File<PokedexAreaData>=<a/1/3/3, D6CA84B4>
+File<WildPokemon>=<a/1/3/6, BB578A64>
+File<HeadbuttPokemon>=<a/2/5/2, 58826D1E>
NationalDexAtStartTweak=national_dex/hgss_national_dex
+Arm9CRC32=C537A4E3
+OverlayCRC32<1>=00255396
+OverlayCRC32<12>=AA71062F
+OverlayCRC32<21>=7874DA2E
+OverlayCRC32<61>=F45FB204
[HeartGold (K)]
Game=IPKK
Type=HGSS
+Version=0
IgnoreGameCornerStatics=1
CopyStaticPokemon=1
-CopyFrom=IPKE
+CopyFrom=HeartGold (U)
+File<Text>=<a/0/2/7, 6C096A9F>
+File<InGameTrades>=<a/1/1/2, 649D61C3>
NationalDexAtStartTweak=national_dex/hgss_national_dex
HasExtraPokemonNames=No
HiddenItemTableOffset=0xFAC04
@@ -880,13 +1239,21 @@ DoubleBattleFlagReturnPrefix=08B5092132F0E6FE
DoubleBattleWalkingPrefix2=6AFF16B00120F8BD
DoubleBattleTextBoxPrefix=F6F762FFF6F77CFF
ShopDataPrefix=858F04028D8F0402958F0402B58F0402
+Arm9CRC32=DD15025F
+OverlayCRC32<1>=485A49F3
+OverlayCRC32<12>=926F3029
+OverlayCRC32<21>=A2FA11EE
+OverlayCRC32<61>=53119D58
[SoulSilver (K)]
Game=IPGK
Type=HGSS
+Version=0
IgnoreGameCornerStatics=1
CopyStaticPokemon=1
-CopyFrom=IPGE
+CopyFrom=SoulSilver (U)
+File<Text>=<a/0/2/7, 6C096A9F>
+File<InGameTrades>=<a/1/1/2, 649D61C3>
NationalDexAtStartTweak=national_dex/hgss_national_dex
HasExtraPokemonNames=No
HiddenItemTableOffset=0xFABFC
@@ -911,13 +1278,21 @@ DoubleBattleFlagReturnPrefix=08B5092132F0E6FE
DoubleBattleWalkingPrefix2=6AFF16B00120F8BD
DoubleBattleTextBoxPrefix=F6F762FFF6F77CFF
ShopDataPrefix=7D8F0402858F04028D8F0402AD8F0402
+Arm9CRC32=F1C4716F
+OverlayCRC32<1>=AAC2EFA7
+OverlayCRC32<12>=EE7F9555
+OverlayCRC32<21>=D2DAA298
+OverlayCRC32<61>=F1C15D1F
[HeartGold (F)]
Game=IPKF
Type=HGSS
+Version=0
CopyText=1
CopyStaticPokemon=1
-CopyFrom=IPKE
+CopyFrom=HeartGold (U)
+File<Text>=<a/0/2/7, F8323397>
+File<InGameTrades>=<a/1/1/2, 37DEEDE2>
NationalDexAtStartTweak=national_dex/hgss_national_dex
HiddenItemTableOffset=0xFA53C
MapTableARM9Offset=0xF6BC4
@@ -925,13 +1300,21 @@ CatchingTutorialPlayerMonOffset=0x51B78
CatchingTutorialPlayerLevelOffset=0x51B7A
CatchingTutorialOpponentMonOffset=0x51B9A
ShopDataPrefix=298E0402618E0402998E0402B98E0402
+Arm9CRC32=590080BF
+OverlayCRC32<1>=6DD56808
+OverlayCRC32<12>=43574EA6
+OverlayCRC32<21>=5045E946
+OverlayCRC32<61>=62BC379B
[SoulSilver (F)]
Game=IPGF
Type=HGSS
+Version=0
CopyText=1
CopyStaticPokemon=1
-CopyFrom=IPGE
+CopyFrom=SoulSilver (U)
+File<Text>=<a/0/2/7, F8323397>
+File<InGameTrades>=<a/1/1/2, 37DEEDE2>
NationalDexAtStartTweak=national_dex/hgss_national_dex
HiddenItemTableOffset=0xFA53C
MapTableARM9Offset=0xF6BC4
@@ -939,13 +1322,21 @@ CatchingTutorialPlayerMonOffset=0x51B78
CatchingTutorialPlayerLevelOffset=0x51B7A
CatchingTutorialOpponentMonOffset=0x51B9A
ShopDataPrefix=298E0402618E0402998E0402B98E0402
+Arm9CRC32=A55C566F
+OverlayCRC32<1>=5B0C8E3F
+OverlayCRC32<12>=BDF17AFF
+OverlayCRC32<21>=5045E946
+OverlayCRC32<61>=62BC379B
[HeartGold (G)]
Game=IPKD
Type=HGSS
+Version=0
CopyText=1
CopyStaticPokemon=1
-CopyFrom=IPKE
+CopyFrom=HeartGold (U)
+File<Text>=<a/0/2/7, 5325ECF3>
+File<InGameTrades>=<a/1/1/2, F4D80FDB>
NationalDexAtStartTweak=national_dex/hgss_national_dex
HiddenItemTableOffset=0xFA50C
MapTableARM9Offset=0xF6B94
@@ -953,13 +1344,21 @@ CatchingTutorialPlayerMonOffset=0x51B78
CatchingTutorialPlayerLevelOffset=0x51B7A
CatchingTutorialOpponentMonOffset=0x51B9A
ShopDataPrefix=298E0402618E0402998E0402B98E0402
+Arm9CRC32=010DE166
+OverlayCRC32<1>=03A114D2
+OverlayCRC32<12>=8F59BA1A
+OverlayCRC32<21>=8B953722
+OverlayCRC32<61>=09E99828
[SoulSilver (G)]
Game=IPGD
Type=HGSS
+Version=0
CopyText=1
CopyStaticPokemon=1
-CopyFrom=IPGE
+CopyFrom=SoulSilver (U)
+File<Text>=<a/0/2/7, 5325ECF3>
+File<InGameTrades>=<a/1/1/2, F4D80FDB>
NationalDexAtStartTweak=national_dex/hgss_national_dex
HiddenItemTableOffset=0xFA50C
MapTableARM9Offset=0xF6B94
@@ -967,13 +1366,21 @@ CatchingTutorialPlayerMonOffset=0x51B78
CatchingTutorialPlayerLevelOffset=0x51B7A
CatchingTutorialOpponentMonOffset=0x51B9A
ShopDataPrefix=298E0402618E0402998E0402B98E0402
+Arm9CRC32=7133E536
+OverlayCRC32<1>=3578F2E5
+OverlayCRC32<12>=71FF8E43
+OverlayCRC32<21>=8B953722
+OverlayCRC32<61>=09E99828
[HeartGold (S)]
Game=IPKS
Type=HGSS
+Version=0
CopyText=1
CopyStaticPokemon=1
-CopyFrom=IPKE
+CopyFrom=HeartGold (U)
+File<Text>=<a/0/2/7, BFAE82BF>
+File<InGameTrades>=<a/1/1/2, B5DA51CC>
NationalDexAtStartTweak=national_dex/hgss_national_dex
HiddenItemTableOffset=0xFA540
MapTableARM9Offset=0xF6BC8
@@ -981,13 +1388,21 @@ CatchingTutorialPlayerMonOffset=0x51B70
CatchingTutorialPlayerLevelOffset=0x51B72
CatchingTutorialOpponentMonOffset=0x51B92
ShopDataPrefix=218E0402598E0402918E0402B18E0402
+Arm9CRC32=E44F2901
+OverlayCRC32<1>=76637802
+OverlayCRC32<12>=1BE62592
+OverlayCRC32<21>=0788415E
+OverlayCRC32<61>=27EDB088
[SoulSilver (S)]
Game=IPGS
Type=HGSS
+Version=0
CopyText=1
CopyStaticPokemon=1
-CopyFrom=IPGE
+CopyFrom=SoulSilver (U)
+File<Text>=<a/0/2/7, BFAE82BF>
+File<InGameTrades>=<a/1/1/2, B5DA51CC>
NationalDexAtStartTweak=national_dex/hgss_national_dex
HiddenItemTableOffset=0xFA548
MapTableARM9Offset=0xF6BD0
@@ -995,13 +1410,21 @@ CatchingTutorialPlayerMonOffset=0x51B78
CatchingTutorialPlayerLevelOffset=0x51B7A
CatchingTutorialOpponentMonOffset=0x51B9A
ShopDataPrefix=298E0402618E0402998E0402B98E0402
+Arm9CRC32=E705FE48
+OverlayCRC32<1>=05057EF4
+OverlayCRC32<12>=DD0D85AD
+OverlayCRC32<21>=7FD40F84
+OverlayCRC32<61>=88DA5446
[HeartGold (I)]
Game=IPKI
Type=HGSS
+Version=0
CopyText=1
CopyStaticPokemon=1
-CopyFrom=IPKE
+CopyFrom=HeartGold (U)
+File<Text>=<a/0/2/7, 5FD94A88>
+File<InGameTrades>=<a/1/1/2, 39E1A3F0>
NationalDexAtStartTweak=national_dex/hgss_national_dex
HiddenItemTableOffset=0xFA4D0
MapTableARM9Offset=0xF6B58
@@ -1009,13 +1432,21 @@ CatchingTutorialPlayerMonOffset=0x51B78
CatchingTutorialPlayerLevelOffset=0x51B7A
CatchingTutorialOpponentMonOffset=0x51B9A
ShopDataPrefix=298E0402618E0402998E0402B98E0402
+Arm9CRC32=A200E7D3
+OverlayCRC32<1>=51DB5337
+OverlayCRC32<12>=B91C4DD4
+OverlayCRC32<21>=F71A0EFA
+OverlayCRC32<61>=C4A4AED5
[SoulSilver (I)]
Game=IPGI
Type=HGSS
+Version=0
CopyText=1
CopyStaticPokemon=1
-CopyFrom=IPGE
+CopyFrom=SoulSilver (U)
+File<Text>=<a/0/2/7, 5FD94A88>
+File<InGameTrades>=<a/1/1/2, 39E1A3F0>
NationalDexAtStartTweak=national_dex/hgss_national_dex
HiddenItemTableOffset=0xFA4D0
MapTableARM9Offset=0xF6B58
@@ -1023,3 +1454,8 @@ CatchingTutorialPlayerMonOffset=0x51B78
CatchingTutorialPlayerLevelOffset=0x51B7A
CatchingTutorialOpponentMonOffset=0x51B9A
ShopDataPrefix=298E0402618E0402998E0402B98E0402
+Arm9CRC32=9A50D8E0
+OverlayCRC32<1>=6702B500
+OverlayCRC32<12>=47BA798D
+OverlayCRC32<21>=F71A0EFA
+OverlayCRC32<61>=C4A4AED5
diff --git a/src/com/dabomstew/pkrandom/newnds/NDSRom.java b/src/com/dabomstew/pkrandom/newnds/NDSRom.java
index be00c32..163d509 100755
--- a/src/com/dabomstew/pkrandom/newnds/NDSRom.java
+++ b/src/com/dabomstew/pkrandom/newnds/NDSRom.java
@@ -34,6 +34,7 @@ import cuecompressors.BLZCoder;
public class NDSRom {
private String romCode;
+ private byte version;
private String romFilename;
private RandomAccessFile baseRom;
private boolean romOpen;
@@ -103,6 +104,9 @@ public class NDSRom {
baseRom.readFully(sig);
this.romCode = new String(sig, "US-ASCII");
+ baseRom.seek(0x1E);
+ this.version = baseRom.readByte();
+
baseRom.seek(0x28);
this.arm9_ramoffset = readFromFile(baseRom, 4);
@@ -443,6 +447,10 @@ public class NDSRom {
return this.romCode;
}
+ public byte getVersion() {
+ return this.version;
+ }
+
// returns null if file doesn't exist
public byte[] getFile(String filename) throws IOException {
if (files.containsKey(filename)) {
diff --git a/src/com/dabomstew/pkrandom/romhandlers/AbstractDSRomHandler.java b/src/com/dabomstew/pkrandom/romhandlers/AbstractDSRomHandler.java
index bac90cf..4eeeff9 100755
--- a/src/com/dabomstew/pkrandom/romhandlers/AbstractDSRomHandler.java
+++ b/src/com/dabomstew/pkrandom/romhandlers/AbstractDSRomHandler.java
@@ -49,11 +49,11 @@ public abstract class AbstractDSRomHandler extends AbstractRomHandler {
super(random, logStream);
}
- protected abstract boolean detectNDSRom(String ndsCode);
+ protected abstract boolean detectNDSRom(String ndsCode, byte version);
@Override
public boolean loadRom(String filename) {
- if (!this.detectNDSRom(getROMCodeFromFile(filename))) {
+ if (!this.detectNDSRom(getROMCodeFromFile(filename), getVersionFromFile(filename))) {
return false;
}
// Load inner rom
@@ -63,7 +63,7 @@ public abstract class AbstractDSRomHandler extends AbstractRomHandler {
throw new RandomizerIOException(e);
}
loadedFN = filename;
- loadedROM(baseRom.getCode());
+ loadedROM(baseRom.getCode(), baseRom.getVersion());
return true;
}
@@ -80,7 +80,7 @@ public abstract class AbstractDSRomHandler extends AbstractRomHandler {
return ret;
}
- protected abstract void loadedROM(String romCode);
+ protected abstract void loadedROM(String romCode, byte version);
protected abstract void savingROM();
@@ -171,6 +171,18 @@ public abstract class AbstractDSRomHandler extends AbstractRomHandler {
}
}
+ protected static byte getVersionFromFile(String filename) {
+ try {
+ FileInputStream fis = new FileInputStream(filename);
+ fis.skip(0x1E);
+ byte[] version = FileFunctions.readFullyIntoBuffer(fis, 1);
+ fis.close();
+ return version[0];
+ } catch (IOException e) {
+ throw new RandomizerIOException(e);
+ }
+ }
+
protected int readByte(byte[] data, int offset) { return data[offset] & 0xFF; }
protected int readWord(byte[] data, int offset) {
diff --git a/src/com/dabomstew/pkrandom/romhandlers/Gen3RomHandler.java b/src/com/dabomstew/pkrandom/romhandlers/Gen3RomHandler.java
index b314aa2..0412c0d 100755
--- a/src/com/dabomstew/pkrandom/romhandlers/Gen3RomHandler.java
+++ b/src/com/dabomstew/pkrandom/romhandlers/Gen3RomHandler.java
@@ -2800,10 +2800,10 @@ public class Gen3RomHandler extends AbstractGBRomHandler {
public void setShopItems(Map<Integer, Shop> shopItems) {
int[] shopItemOffsets = romEntry.arrayEntries.get("ShopItemOffsets");
for (int i = 0; i < shopItemOffsets.length; i++) {
- List<Integer> thisShopItems = shopItems.get(i).items;
- if (thisShopItems != null) {
+ Shop thisShop = shopItems.get(i);
+ if (thisShop != null && thisShop.items != null) {
int offset = shopItemOffsets[i];
- Iterator<Integer> iterItems = thisShopItems.iterator();
+ Iterator<Integer> iterItems = thisShop.items.iterator();
while (iterItems.hasNext()) {
FileFunctions.write2ByteInt(rom, offset, iterItems.next());
offset += 2;
diff --git a/src/com/dabomstew/pkrandom/romhandlers/Gen4RomHandler.java b/src/com/dabomstew/pkrandom/romhandlers/Gen4RomHandler.java
index 876d67e..4b0f69e 100755
--- a/src/com/dabomstew/pkrandom/romhandlers/Gen4RomHandler.java
+++ b/src/com/dabomstew/pkrandom/romhandlers/Gen4RomHandler.java
@@ -53,7 +53,7 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
}
public boolean isLoadable(String filename) {
- return detectNDSRomInner(getROMCodeFromFile(filename));
+ return detectNDSRomInner(getROMCodeFromFile(filename), getVersionFromFile(filename));
}
}
@@ -65,16 +65,25 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
super(random, logStream);
}
+ private static class FileEntry {
+ public String path;
+ public long expectedCRC32;
+ }
+
private static class RomEntry {
private String name;
private String romCode;
+ private byte version;
private int romType;
+ private long arm9ExpectedCRC32;
private boolean staticPokemonSupport = false, copyStaticPokemon = false,copyRoamingPokemon = false,
ignoreGameCornerStatics = false, copyText = false;
private Map<String, String> strings = new HashMap<>();
private Map<String, String> tweakFiles = new HashMap<>();
private Map<String, Integer> numbers = new HashMap<>();
private Map<String, int[]> arrayEntries = new HashMap<>();
+ private Map<String, FileEntry> files = new HashMap<>();
+ private Map<Integer, Long> overlayExpectedCRC32s = new HashMap<>();
private List<StaticPokemon> staticPokemon = new ArrayList<>();
private List<RoamingPokemon> roamingPokemon = new ArrayList<>();
private List<ScriptEntry> marillCryScriptEntries = new ArrayList<>();
@@ -96,6 +105,13 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
}
return strings.get(key);
}
+
+ private String getFile(String key) {
+ if (!files.containsKey(key)) {
+ files.put(key, new FileEntry());
+ }
+ return files.get(key).path;
+ }
}
private static List<RomEntry> roms;
@@ -133,6 +149,8 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
r[1] = r[1].trim();
if (r[0].equals("Game")) {
current.romCode = r[1];
+ } else if (r[0].equals("Version")) {
+ current.version = Byte.parseByte(r[1]);
} else if (r[0].equals("Type")) {
if (r[1].equalsIgnoreCase("DP")) {
current.romType = Gen4Constants.Type_DP;
@@ -145,11 +163,12 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
}
} else if (r[0].equals("CopyFrom")) {
for (RomEntry otherEntry : roms) {
- if (r[1].equalsIgnoreCase(otherEntry.romCode)) {
+ if (r[1].equalsIgnoreCase(otherEntry.name)) {
// copy from here
current.arrayEntries.putAll(otherEntry.arrayEntries);
current.numbers.putAll(otherEntry.numbers);
current.strings.putAll(otherEntry.strings);
+ current.files.putAll(otherEntry.files);
if (current.copyStaticPokemon) {
current.staticPokemon.addAll(otherEntry.staticPokemon);
if (current.ignoreGameCornerStatics) {
@@ -171,6 +190,20 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
current.marillCryScriptEntries.addAll(otherEntry.marillCryScriptEntries);
}
}
+ } else if (r[0].startsWith("File<")) {
+ String key = r[0].split("<")[1].split(">")[0];
+ String[] values = r[1].substring(1, r[1].length() - 1).split(",");
+ FileEntry entry = new FileEntry();
+ entry.path = values[0].trim();
+ entry.expectedCRC32 = parseRIILong("0x" + values[1].trim());
+ current.files.put(key, entry);
+ } else if (r[0].equals("Arm9CRC32")) {
+ current.arm9ExpectedCRC32 = parseRIILong("0x" + r[1]);
+ } else if (r[0].startsWith("OverlayCRC32<")) {
+ String keyString = r[0].split("<")[1].split(">")[0];
+ int key = parseRIInt(keyString);
+ long value = parseRIILong("0x" + r[1]);
+ current.overlayExpectedCRC32s.put(key, value);
} else if (r[0].equals("StaticPokemon{}")) {
current.staticPokemon.add(parseStaticPokemon(r[1]));
} else if (r[0].equals("RoamingPokemon{}")) {
@@ -270,6 +303,21 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
}
}
+ private static long parseRIILong(String off) {
+ int radix = 10;
+ off = off.trim().toLowerCase();
+ if (off.startsWith("0x") || off.startsWith("&h")) {
+ radix = 16;
+ off = off.substring(2);
+ }
+ try {
+ return Long.parseLong(off, radix);
+ } catch (NumberFormatException ex) {
+ System.err.println("invalid base " + radix + "number " + off);
+ return 0;
+ }
+ }
+
private static StaticPokemon parseStaticPokemon(String staticPokemonString) {
StaticPokemon sp = new StaticPokemon();
String pattern = "[A-z]+=\\[([0-9]+:0x[0-9a-fA-F]+,?\\s?)+]";
@@ -428,21 +476,24 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
private boolean roamerRandomizationEnabled;
private boolean effectivenessUpdated;
private int pickupItemsTableOffset, rarePickupItemsTableOffset;
+ private long actualArm9CRC32;
+ private Map<Integer, Long> actualOverlayCRC32s;
+ private Map<String, Long> actualFileCRC32s;
private RomEntry romEntry;
@Override
- protected boolean detectNDSRom(String ndsCode) {
- return detectNDSRomInner(ndsCode);
+ protected boolean detectNDSRom(String ndsCode, byte version) {
+ return detectNDSRomInner(ndsCode, version);
}
- private static boolean detectNDSRomInner(String ndsCode) {
- return entryFor(ndsCode) != null;
+ private static boolean detectNDSRomInner(String ndsCode, byte version) {
+ return entryFor(ndsCode, version) != null;
}
- private static RomEntry entryFor(String ndsCode) {
+ private static RomEntry entryFor(String ndsCode, byte version) {
for (RomEntry re : roms) {
- if (ndsCode.equals(re.romCode)) {
+ if (ndsCode.equals(re.romCode) && version == re.version) {
return re;
}
}
@@ -450,25 +501,25 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
}
@Override
- protected void loadedROM(String romCode) {
- this.romEntry = entryFor(romCode);
+ protected void loadedROM(String romCode, byte version) {
+ this.romEntry = entryFor(romCode, version);
try {
arm9 = readARM9();
} catch (IOException e) {
throw new RandomizerIOException(e);
}
try {
- msgNarc = readNARC(romEntry.getString("Text"));
+ msgNarc = readNARC(romEntry.getFile("Text"));
} catch (IOException e) {
throw new RandomizerIOException(e);
}
try {
- scriptNarc = readNARC(romEntry.getString("Scripts"));
+ scriptNarc = readNARC(romEntry.getFile("Scripts"));
} catch (IOException e) {
throw new RandomizerIOException(e);
}
try {
- eventNarc = readNARC(romEntry.getString("Events"));
+ eventNarc = readNARC(romEntry.getFile("Events"));
} catch (IOException e) {
throw new RandomizerIOException(e);
}
@@ -497,11 +548,17 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
arm9 = extendARM9(arm9, extendBy, romEntry.getString("TCMCopyingPrefix"), Gen4Constants.arm9Offset);
genericIPSPatch(arm9, "NewCatchingTutorialSubroutineTweak");
}
+
+ try {
+ computeCRC32sForRom();
+ } catch (IOException e) {
+ throw new RandomizerIOException(e);
+ }
}
private void loadMoves() {
try {
- moveNarc = this.readNARC(romEntry.getString("MoveData"));
+ moveNarc = this.readNARC(romEntry.getFile("MoveData"));
moves = new Move[Gen4Constants.moveCount + 1];
List<String> moveNames = getStrings(romEntry.getInt("MoveNamesTextOffset"));
for (int i = 1; i <= Gen4Constants.moveCount; i++) {
@@ -538,7 +595,7 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
private void loadPokemonStats() {
try {
- String pstatsnarc = romEntry.getString("PokemonStats");
+ String pstatsnarc = romEntry.getFile("PokemonStats");
pokeNarc = this.readNARC(pstatsnarc);
String[] pokeNames = readPokemonNames();
int formeCount = Gen4Constants.getFormeCount(romEntry.romType);
@@ -1142,7 +1199,7 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
private List<EncounterSet> getEncountersDPPt(boolean useTimeOfDay) throws IOException {
// Determine file to use
- String encountersFile = romEntry.getString("WildPokemon");
+ String encountersFile = romEntry.getFile("WildPokemon");
NARCArchive encounterData = readNARC(encountersFile);
List<EncounterSet> encounters = new ArrayList<>();
@@ -1227,7 +1284,7 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
}
// Now do the extra encounters (Feebas tiles, honey trees, Great Marsh rotating Pokemon, etc.)
- String extraEncountersFile = romEntry.getString("ExtraEncounters");
+ String extraEncountersFile = romEntry.getFile("ExtraEncounters");
NARCArchive extraEncounterData = readNARC(extraEncountersFile);
// Feebas tiles
@@ -1374,7 +1431,7 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
}
private List<EncounterSet> getEncountersHGSS(boolean useTimeOfDay) throws IOException {
- String encountersFile = romEntry.getString("WildPokemon");
+ String encountersFile = romEntry.getFile("WildPokemon");
NARCArchive encounterData = readNARC(encountersFile);
List<EncounterSet> encounters = new ArrayList<>();
// Credit for
@@ -1470,7 +1527,7 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
}
// Headbutt Encounters
- String headbuttEncountersFile = romEntry.getString("HeadbuttPokemon");
+ String headbuttEncountersFile = romEntry.getFile("HeadbuttPokemon");
NARCArchive headbuttEncounterData = readNARC(headbuttEncountersFile);
c = -1;
for (byte[] b : headbuttEncounterData.files) {
@@ -1497,7 +1554,7 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
}
// Bug Catching Contest Encounters
- String bccEncountersFile = romEntry.getString("BCCWilds");
+ String bccEncountersFile = romEntry.getFile("BCCWilds");
byte[] bccEncountersData = readFile(bccEncountersFile);
EncounterSet bccEncountersPreNationalDex = readBCCEncountersHGSS(bccEncountersData, 0, 10);
bccEncountersPreNationalDex.displayName = "Bug Catching Contest (Pre-National Dex)";
@@ -1632,7 +1689,7 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
private void setEncountersDPPt(boolean useTimeOfDay, List<EncounterSet> encounterList) throws IOException {
// Determine file to use
- String encountersFile = romEntry.getString("WildPokemon");
+ String encountersFile = romEntry.getFile("WildPokemon");
NARCArchive encounterData = readNARC(encountersFile);
Iterator<EncounterSet> encounters = encounterList.iterator();
// Credit for
@@ -1706,7 +1763,7 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
writeNARC(encountersFile, encounterData);
// Now do the extra encounters (Feebas tiles, honey trees, Great Marsh rotating Pokemon, etc.)
- String extraEncountersFile = romEntry.getString("ExtraEncounters");
+ String extraEncountersFile = romEntry.getFile("ExtraEncounters");
NARCArchive extraEncounterData = readNARC(extraEncountersFile);
// Feebas tiles
@@ -1816,7 +1873,7 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
}
private void setEncountersHGSS(boolean useTimeOfDay, List<EncounterSet> encounterList) throws IOException {
- String encountersFile = romEntry.getString("WildPokemon");
+ String encountersFile = romEntry.getFile("WildPokemon");
NARCArchive encounterData = readNARC(encountersFile);
Iterator<EncounterSet> encounters = encounterList.iterator();
// Credit for
@@ -1879,7 +1936,7 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
writeNARC(encountersFile, encounterData);
// Write Headbutt encounters
- String headbuttEncountersFile = romEntry.getString("HeadbuttPokemon");
+ String headbuttEncountersFile = romEntry.getFile("HeadbuttPokemon");
NARCArchive headbuttEncounterData = readNARC(headbuttEncountersFile);
int c = -1;
for (byte[] b : headbuttEncounterData.files) {
@@ -1900,7 +1957,7 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
writeNARC(headbuttEncountersFile, headbuttEncounterData);
// Write Bug Catching Contest encounters
- String bccEncountersFile = romEntry.getString("BCCWilds");
+ String bccEncountersFile = romEntry.getFile("BCCWilds");
byte[] bccEncountersData = readFile(bccEncountersFile);
EncounterSet bccEncountersPreNationalDex = encounters.next();
writeBCCEncountersHGSS(bccEncountersData, 0, bccEncountersPreNationalDex.encounters);
@@ -1993,7 +2050,7 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
try {
wildMapNames = new HashMap<>();
headbuttMapNames = new HashMap<>();
- byte[] internalNames = this.readFile(romEntry.getString("MapTableFile"));
+ byte[] internalNames = this.readFile(romEntry.getFile("MapTableFile"));
int numMapHeaders = internalNames.length / 16;
int baseMHOffset = romEntry.getInt("MapTableARM9Offset");
List<String> allMapNames = getStrings(romEntry.getInt("MapNamesTextOffset"));
@@ -2024,7 +2081,7 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
}
private void updatePokedexAreaDataDPPt(List<EncounterSet> encounters) throws IOException {
- String encountersFile = romEntry.getString("WildPokemon");
+ String encountersFile = romEntry.getFile("WildPokemon");
NARCArchive encounterData = readNARC(encountersFile);
// Initialize empty area data
@@ -2150,7 +2207,7 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
// Write new area data to its file
// Area data format credit to Ganix
- String pokedexAreaDataFile = romEntry.getString("PokedexAreaData");
+ String pokedexAreaDataFile = romEntry.getFile("PokedexAreaData");
NARCArchive pokedexAreaData = readNARC(pokedexAreaDataFile);
int dungeonDataIndex = romEntry.getInt("PokedexAreaDataDungeonIndex");
int dungeonSpecialPreNationalDataIndex = romEntry.getInt("PokedexAreaDataDungeonSpecialPreNationalIndex");
@@ -2178,7 +2235,7 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
}
private void updatePokedexAreaDataHGSS(List<EncounterSet> encounters) throws IOException {
- String encountersFile = romEntry.getString("WildPokemon");
+ String encountersFile = romEntry.getFile("WildPokemon");
NARCArchive encounterData = readNARC(encountersFile);
// Initialize empty area data
@@ -2297,7 +2354,7 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
// Write new area data to its file
// Area data format credit to Ganix
- String pokedexAreaDataFile = romEntry.getString("PokedexAreaData");
+ String pokedexAreaDataFile = romEntry.getFile("PokedexAreaData");
NARCArchive pokedexAreaData = readNARC(pokedexAreaDataFile);
int dungeonDataIndex = romEntry.getInt("PokedexAreaDataDungeonIndex");
int overworldDataIndex = romEntry.getInt("PokedexAreaDataOverworldIndex");
@@ -2331,8 +2388,8 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
public List<Trainer> getTrainers() {
List<Trainer> allTrainers = new ArrayList<>();
try {
- NARCArchive trainers = this.readNARC(romEntry.getString("TrainerData"));
- NARCArchive trpokes = this.readNARC(romEntry.getString("TrainerPokemon"));
+ NARCArchive trainers = this.readNARC(romEntry.getFile("TrainerData"));
+ NARCArchive trpokes = this.readNARC(romEntry.getFile("TrainerPokemon"));
List<String> tclasses = this.getTrainerClassNames();
List<String> tnames = this.getTrainerNames();
int trainernum = trainers.files.size();
@@ -2443,7 +2500,7 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
}
Iterator<Trainer> allTrainers = trainerData.iterator();
try {
- NARCArchive trainers = this.readNARC(romEntry.getString("TrainerData"));
+ NARCArchive trainers = this.readNARC(romEntry.getFile("TrainerData"));
NARCArchive trpokes = new NARCArchive();
// Get current movesets in case we need to reset them for certain
@@ -2597,7 +2654,7 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
// Changing this byte from 4 -> 0 makes it check if the "double battle" flag is exactly 2 instead of
// checking "flag & 2", which makes the single trainer double battles use the single battle
// handling (since we set their flag to 3 instead of 2)
- NARCArchive battleSkillSubSeq = readNARC(romEntry.getString("BattleSkillSubSeq"));
+ NARCArchive battleSkillSubSeq = readNARC(romEntry.getFile("BattleSkillSubSeq"));
byte[] trainerEndFile = battleSkillSubSeq.files.get(romEntry.getInt("TrainerEndFileNumber"));
trainerEndFile[romEntry.getInt("TrainerEndTextBoxOffset")] = 0;
writeNARC(romEntry.getString("BattleSkillSubSeq"), battleSkillSubSeq);
@@ -2650,7 +2707,7 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
public Map<Integer, List<MoveLearnt>> getMovesLearnt() {
Map<Integer, List<MoveLearnt>> movesets = new TreeMap<>();
try {
- NARCArchive movesLearnt = this.readNARC(romEntry.getString("PokemonMovesets"));
+ NARCArchive movesLearnt = this.readNARC(romEntry.getFile("PokemonMovesets"));
int formeCount = Gen4Constants.getFormeCount(romEntry.romType);
for (int i = 1; i <= Gen4Constants.pokemonCount + formeCount; i++) {
Pokemon pkmn = pokes[i];
@@ -2912,7 +2969,7 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
sp.add(se);
}
if (romEntry.arrayEntries.containsKey("StaticPokemonTrades")) {
- NARCArchive tradeNARC = this.readNARC(romEntry.getString("InGameTrades"));
+ NARCArchive tradeNARC = this.readNARC(romEntry.getFile("InGameTrades"));
int[] trades = romEntry.arrayEntries.get("StaticPokemonTrades");
int[] scripts = romEntry.arrayEntries.get("StaticPokemonTradeScripts");
int[] scriptOffsets = romEntry.arrayEntries.get("StaticPokemonTradeLevelOffsets");
@@ -2983,7 +3040,7 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
}
}
if (romEntry.arrayEntries.containsKey("StaticPokemonTrades")) {
- NARCArchive tradeNARC = this.readNARC(romEntry.getString("InGameTrades"));
+ NARCArchive tradeNARC = this.readNARC(romEntry.getFile("InGameTrades"));
int[] trades = romEntry.arrayEntries.get("StaticPokemonTrades");
int[] scripts = romEntry.arrayEntries.get("StaticPokemonTradeScripts");
int[] scriptOffsets = romEntry.arrayEntries.get("StaticPokemonTradeLevelOffsets");
@@ -3411,7 +3468,7 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
try {
byte[] mtcFile;
if (romEntry.romType == Gen4Constants.Type_HGSS) {
- mtcFile = readFile(romEntry.getString("MoveTutorCompat"));
+ mtcFile = readFile(romEntry.getFile("MoveTutorCompat"));
} else {
mtcFile = readOverlay(romEntry.getInt("MoveTutorCompatOvlNumber"));
}
@@ -3445,7 +3502,7 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
try {
byte[] mtcFile;
if (romEntry.romType == Gen4Constants.Type_HGSS) {
- mtcFile = readFile(romEntry.getString("MoveTutorCompat"));
+ mtcFile = readFile(romEntry.getFile("MoveTutorCompat"));
} else {
mtcFile = readOverlay(romEntry.getInt("MoveTutorCompatOvlNumber"));
}
@@ -3605,7 +3662,7 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
// Read NARC
try {
- NARCArchive evoNARC = readNARC(romEntry.getString("PokemonEvolutions"));
+ NARCArchive evoNARC = readNARC(romEntry.getFile("PokemonEvolutions"));
for (int i = 1; i <= Gen4Constants.pokemonCount; i++) {
Pokemon pk = pokes[i];
byte[] evoEntry = evoNARC.files.get(i);
@@ -3639,7 +3696,7 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
private void writeEvolutions() {
try {
- NARCArchive evoNARC = readNARC(romEntry.getString("PokemonEvolutions"));
+ NARCArchive evoNARC = readNARC(romEntry.getFile("PokemonEvolutions"));
for (int i = 1; i <= Gen4Constants.pokemonCount; i++) {
byte[] evoEntry = evoNARC.files.get(i);
Pokemon pk = pokes[i];
@@ -3947,15 +4004,15 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
offset += shopDataPrefix.length() / 2;
for (int i = 0; i < shopCount; i++) {
- List<Integer> thisShopItems = shopItems.get(i).items;
- if (thisShopItems == null) {
+ Shop thisShop = shopItems.get(i);
+ if (thisShop == null || thisShop.items == null) {
while ((FileFunctions.read2ByteInt(arm9, offset) & 0xFFFF) != 0xFFFF) {
offset += 2;
}
offset += 2;
continue;
}
- Iterator<Integer> iterItems = thisShopItems.iterator();
+ Iterator<Integer> iterItems = thisShop.items.iterator();
int val = (FileFunctions.read2ByteInt(arm9, offset));
while ((val & 0xFFFF) != 0xFFFF) {
if (val != 0) {
@@ -3974,7 +4031,7 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
// In Diamond and Pearl, item IDs 112 through 134 are unused. In Platinum and HGSS, item ID 112 is used for
// the Griseous Orb. So we need to skip through the unused IDs at different points depending on the game.
int startOfUnusedIDs = romEntry.romType == Gen4Constants.Type_DP ? 112 : 113;
- NARCArchive itemPriceNarc = this.readNARC(romEntry.getString("ItemData"));
+ NARCArchive itemPriceNarc = this.readNARC(romEntry.getFile("ItemData"));
int itemID = 1;
for (int i = 1; i < itemPriceNarc.files.size(); i++) {
writeWord(itemPriceNarc.files.get(i),0,Gen4Constants.balancedItemPrices.get(itemID) * 10);
@@ -4467,7 +4524,7 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
public List<IngameTrade> getIngameTrades() {
List<IngameTrade> trades = new ArrayList<>();
try {
- NARCArchive tradeNARC = this.readNARC(romEntry.getString("InGameTrades"));
+ NARCArchive tradeNARC = this.readNARC(romEntry.getFile("InGameTrades"));
int[] spTrades = new int[0];
if (romEntry.arrayEntries.containsKey("StaticPokemonTrades")) {
spTrades = romEntry.arrayEntries.get("StaticPokemonTrades");
@@ -4510,7 +4567,7 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
int tradeOffset = 0;
List<IngameTrade> oldTrades = this.getIngameTrades();
try {
- NARCArchive tradeNARC = this.readNARC(romEntry.getString("InGameTrades"));
+ NARCArchive tradeNARC = this.readNARC(romEntry.getFile("InGameTrades"));
int[] spTrades = new int[0];
if (romEntry.arrayEntries.containsKey("StaticPokemonTrades")) {
spTrades = romEntry.arrayEntries.get("StaticPokemonTrades");
@@ -4629,7 +4686,7 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
}
try {
- byte[] babyPokes = readFile(romEntry.getString("BabyPokemon"));
+ byte[] babyPokes = readFile(romEntry.getFile("BabyPokemon"));
// baby pokemon
for (int i = 1; i <= Gen4Constants.pokemonCount; i++) {
Pokemon baby = pokes[i];
@@ -5009,11 +5066,52 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
}
}
+ private void computeCRC32sForRom() throws IOException {
+ this.actualOverlayCRC32s = new HashMap<>();
+ this.actualFileCRC32s = new HashMap<>();
+ this.actualArm9CRC32 = FileFunctions.getCRC32(arm9);
+ for (int overlayNumber : romEntry.overlayExpectedCRC32s.keySet()) {
+ byte[] overlay = readOverlay(overlayNumber);
+ long crc32 = FileFunctions.getCRC32(overlay);
+ this.actualOverlayCRC32s.put(overlayNumber, crc32);
+ }
+ for (String fileKey : romEntry.files.keySet()) {
+ byte[] file = readFile(romEntry.getFile(fileKey));
+ long crc32 = FileFunctions.getCRC32(file);
+ this.actualFileCRC32s.put(fileKey, crc32);
+ }
+ }
+
+ @Override
+ public boolean isRomValid() {
+ if (romEntry.arm9ExpectedCRC32 != actualArm9CRC32) {
+ return false;
+ }
+
+ for (int overlayNumber : romEntry.overlayExpectedCRC32s.keySet()) {
+ long expectedCRC32 = romEntry.overlayExpectedCRC32s.get(overlayNumber);
+ long actualCRC32 = actualOverlayCRC32s.get(overlayNumber);
+ if (expectedCRC32 != actualCRC32) {
+ return false;
+ }
+ }
+
+ for (String fileKey : romEntry.files.keySet()) {
+ long expectedCRC32 = romEntry.files.get(fileKey).expectedCRC32;
+ long actualCRC32 = actualFileCRC32s.get(fileKey);
+ if (expectedCRC32 != actualCRC32) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
@Override
public BufferedImage getMascotImage() {
try {
Pokemon pk = randomPokemon();
- NARCArchive pokespritesNARC = this.readNARC(romEntry.getString("PokemonGraphics"));
+ NARCArchive pokespritesNARC = this.readNARC(romEntry.getFile("PokemonGraphics"));
int spriteIndex = pk.number * 6 + 2 + random.nextInt(2);
int palIndex = pk.number * 6 + 4;
if (random.nextInt(10) == 0) {
diff --git a/src/com/dabomstew/pkrandom/romhandlers/Gen5RomHandler.java b/src/com/dabomstew/pkrandom/romhandlers/Gen5RomHandler.java
index 7e35a3b..fadc3dc 100755
--- a/src/com/dabomstew/pkrandom/romhandlers/Gen5RomHandler.java
+++ b/src/com/dabomstew/pkrandom/romhandlers/Gen5RomHandler.java
@@ -379,7 +379,7 @@ public class Gen5RomHandler extends AbstractDSRomHandler {
private NARCArchive pokeNarc, moveNarc, stringsNarc, storyTextNarc, scriptNarc, shopNarc;
@Override
- protected boolean detectNDSRom(String ndsCode) {
+ protected boolean detectNDSRom(String ndsCode, byte version) {
return detectNDSRomInner(ndsCode);
}
@@ -401,7 +401,7 @@ public class Gen5RomHandler extends AbstractDSRomHandler {
}
@Override
- protected void loadedROM(String romCode) {
+ protected void loadedROM(String romCode, byte version) {
this.romEntry = entryFor(romCode);
try {
arm9 = readARM9();