summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortom-overton <tom.overton@outlook.com>2022-12-22 22:37:02 -0800
committerRafael Marçalo <raroma09@gmail.com>2023-01-03 14:41:30 +0000
commit175ec21f7b5983a3bb472953c2119af9e3b69f39 (patch)
tree9feb7e4b044446ae855642762ced02dae234a4d9
parentf5880a1039828686ff0d7d0bf8fac304044f9b62 (diff)
Gen 5: Fix Shedinja evo crashing on Bizhawk/real hardware
-rw-r--r--asm/shedinja/black2_shedinja.asm58
-rw-r--r--asm/shedinja/black_shedinja.asm58
-rw-r--r--asm/shedinja/white2_shedinja.asm58
-rw-r--r--asm/shedinja/white_shedinja.asm58
-rw-r--r--src/com/dabomstew/pkrandom/patches/shedinja/black2_ovl284_shedinja.ipsbin0 -> 31 bytes
-rw-r--r--src/com/dabomstew/pkrandom/patches/shedinja/black2_shedinja.ipsbin0 -> 69 bytes
-rw-r--r--src/com/dabomstew/pkrandom/patches/shedinja/black_ovl195_shedinja.ipsbin0 -> 31 bytes
-rw-r--r--src/com/dabomstew/pkrandom/patches/shedinja/black_shedinja.ipsbin0 -> 61 bytes
-rw-r--r--src/com/dabomstew/pkrandom/patches/shedinja/white2_ovl284_shedinja.ipsbin0 -> 31 bytes
-rw-r--r--src/com/dabomstew/pkrandom/patches/shedinja/white2_shedinja.ipsbin0 -> 69 bytes
-rw-r--r--src/com/dabomstew/pkrandom/patches/shedinja/white_ovl195_shedinja.ipsbin0 -> 31 bytes
-rw-r--r--src/com/dabomstew/pkrandom/patches/shedinja/white_shedinja.ipsbin0 -> 61 bytes
-rwxr-xr-xsrc/com/sneed/pkrandom/config/gen4_offsets.ini8
-rwxr-xr-xsrc/com/sneed/pkrandom/config/gen5_offsets.ini18
-rw-r--r--src/com/sneed/pkrandom/constants/Gen5Constants.java11
-rwxr-xr-xsrc/com/sneed/pkrandom/romhandlers/Gen4RomHandler.java13
-rwxr-xr-xsrc/com/sneed/pkrandom/romhandlers/Gen5RomHandler.java69
17 files changed, 282 insertions, 69 deletions
diff --git a/asm/shedinja/black2_shedinja.asm b/asm/shedinja/black2_shedinja.asm
new file mode 100644
index 0000000..6a63d68
--- /dev/null
+++ b/asm/shedinja/black2_shedinja.asm
@@ -0,0 +1,58 @@
+ .nds
+ .thumb
+ .open "pkmnblack2_ovl284", "pkmnblack2_ovl284_shedinja", 0x021E30E0
+
+ NEW_INDEX_TO_SHEDINJA_SUBR_HOOK equ 0x021E488E
+ OLD_INDEX_TO_SHEDINJA_SUBR_CONTINUED equ 0x021E48B6
+
+ SET_POKEMON_SPECIES equ 0x0201C7B4
+ SET_POKEMON_ATTRIBUTE equ 0x0201CD1C
+
+ ITCM_SRC_START equ 0x0209D740
+ ITCM_DEST_START equ 0x01FF8000
+ ITCM_OLD_SIZE equ 0x1560 ; Originally 0x13A0, but this occurs after the 0x1C0 sized music patch
+
+ NEW_INDEX_TO_SHEDINJA_SUBR equ ITCM_SRC_START + ITCM_OLD_SIZE
+ NEW_INDEX_TO_SHEDINJA_SUBR_ITCM equ ITCM_DEST_START + ITCM_OLD_SIZE
+ BL_OFFSET equ (NEW_INDEX_TO_SHEDINJA_SUBR) - (NEW_INDEX_TO_SHEDINJA_SUBR_ITCM)
+
+ ; Hook that jumps to our new subroutine
+ .org NEW_INDEX_TO_SHEDINJA_SUBR_HOOK
+ mov r0, r4
+ bl org() + 6
+ b OLD_INDEX_TO_SHEDINJA_SUBR_CONTINUED
+ ldr r2,=#(NEW_INDEX_TO_SHEDINJA_SUBR_ITCM + 1)
+ bx r2
+ .pool
+
+ .close
+
+ .open "pkmnblack2.bin", "pkmnblack2_shedinja.bin", 0x02004000
+ ; New subroutine. This is passed a pointer to the Pokemon data struct in r0; it is responsible
+ ; for setting the species and first few attributes of the newly-generated Shedinja. Most of this
+ ; code is copied from the original game, but it has been modified for easier modification of the
+ ; species ID (it was generated via some silly left shift in the original code).
+ .org NEW_INDEX_TO_SHEDINJA_SUBR
+ .area 48
+
+ push { r4, lr }
+ mov r4, r0 ; Save pointer to Pokemon data to r4 so it can be used again after calling functions
+ ldr r1,=#0x124 ; Shedinja
+ bl BL_OFFSET + SET_POKEMON_SPECIES
+ mov r0, r4
+ mov r1, #0x98 ; Attribute key for which ball the Pokemon is caught in
+ mov r2, #0x4 ; Poke Ball
+ bl BL_OFFSET + SET_POKEMON_ATTRIBUTE
+ mov r0, r4
+ mov r1, #0x6 ; Attribute key for the Pokemon's held item
+ mov r2, #0x0 ; No item
+ bl BL_OFFSET + SET_POKEMON_ATTRIBUTE
+ mov r0, r4
+ mov r1, #0xB ; Attribute key for the Pokemon's mark
+ mov r2, #0x0 ; No mark
+ bl BL_OFFSET + SET_POKEMON_ATTRIBUTE
+ pop { r4, pc }
+ .pool
+ .endarea
+
+ .close \ No newline at end of file
diff --git a/asm/shedinja/black_shedinja.asm b/asm/shedinja/black_shedinja.asm
new file mode 100644
index 0000000..818e2ad
--- /dev/null
+++ b/asm/shedinja/black_shedinja.asm
@@ -0,0 +1,58 @@
+ .nds
+ .thumb
+ .open "pkmnblack_ovl195", "pkmnblack_ovl195_shedinja", 0x02203FA0
+
+ NEW_INDEX_TO_SHEDINJA_SUBR_HOOK equ 0x0220573E
+ OLD_INDEX_TO_SHEDINJA_SUBR_CONTINUED equ 0x02205766
+
+ SET_POKEMON_SPECIES equ 0x020178D8
+ SET_POKEMON_ATTRIBUTE equ 0x02017E40
+
+ ITCM_SRC_START equ 0x020A9E80
+ ITCM_DEST_START equ 0x01FF8000
+ ITCM_OLD_SIZE equ 0x91C ; Originally 0x820, but this occurs after the 0xFC sized music patch
+
+ NEW_INDEX_TO_SHEDINJA_SUBR equ ITCM_SRC_START + ITCM_OLD_SIZE
+ NEW_INDEX_TO_SHEDINJA_SUBR_ITCM equ ITCM_DEST_START + ITCM_OLD_SIZE
+ BL_OFFSET equ (NEW_INDEX_TO_SHEDINJA_SUBR) - (NEW_INDEX_TO_SHEDINJA_SUBR_ITCM)
+
+ ; Hook that jumps to our new subroutine
+ .org NEW_INDEX_TO_SHEDINJA_SUBR_HOOK
+ mov r0, r4
+ bl org() + 6
+ b OLD_INDEX_TO_SHEDINJA_SUBR_CONTINUED
+ ldr r2,=#(NEW_INDEX_TO_SHEDINJA_SUBR_ITCM + 1)
+ bx r2
+ .pool
+
+ .close
+
+ .open "pkmnblack.bin", "pkmnblack_shedinja.bin", 0x02004000
+ ; New subroutine. This is passed a pointer to the Pokemon data struct in r0; it is responsible
+ ; for setting the species and first few attributes of the newly-generated Shedinja. Most of this
+ ; code is copied from the original game, but it has been modified for easier modification of the
+ ; species ID (it was generated via some silly left shift in the original code).
+ .org NEW_INDEX_TO_SHEDINJA_SUBR
+ .area 48
+
+ push { r4, lr }
+ mov r4, r0 ; Save pointer to Pokemon data to r4 so it can be used again after calling functions
+ ldr r1,=#0x124 ; Shedinja
+ bl BL_OFFSET + SET_POKEMON_SPECIES
+ mov r0, r4
+ mov r1, #0x98 ; Attribute key for which ball the Pokemon is caught in
+ mov r2, #0x4 ; Poke Ball
+ bl BL_OFFSET + SET_POKEMON_ATTRIBUTE
+ mov r0, r4
+ mov r1, #0x6 ; Attribute key for the Pokemon's held item
+ mov r2, #0x0 ; No item
+ bl BL_OFFSET + SET_POKEMON_ATTRIBUTE
+ mov r0, r4
+ mov r1, #0xB ; Attribute key for the Pokemon's mark
+ mov r2, #0x0 ; No mark
+ bl BL_OFFSET + SET_POKEMON_ATTRIBUTE
+ pop { r4, pc }
+ .pool
+ .endarea
+
+ .close \ No newline at end of file
diff --git a/asm/shedinja/white2_shedinja.asm b/asm/shedinja/white2_shedinja.asm
new file mode 100644
index 0000000..3f937ce
--- /dev/null
+++ b/asm/shedinja/white2_shedinja.asm
@@ -0,0 +1,58 @@
+ .nds
+ .thumb
+ .open "pkmnwhite2_ovl284", "pkmnwhite2_ovl284_shedinja", 0x021E3120
+
+ NEW_INDEX_TO_SHEDINJA_SUBR_HOOK equ 0x021E48CE
+ OLD_INDEX_TO_SHEDINJA_SUBR_CONTINUED equ 0x021E48F6
+
+ SET_POKEMON_SPECIES equ 0x0201C7E0
+ SET_POKEMON_ATTRIBUTE equ 0x0201CD48
+
+ ITCM_SRC_START equ 0x0209D780
+ ITCM_DEST_START equ 0x01FF8000
+ ITCM_OLD_SIZE equ 0x1560 ; Originally 0x13A0, but this occurs after the 0x1C0 sized music patch
+
+ NEW_INDEX_TO_SHEDINJA_SUBR equ ITCM_SRC_START + ITCM_OLD_SIZE
+ NEW_INDEX_TO_SHEDINJA_SUBR_ITCM equ ITCM_DEST_START + ITCM_OLD_SIZE
+ BL_OFFSET equ (NEW_INDEX_TO_SHEDINJA_SUBR) - (NEW_INDEX_TO_SHEDINJA_SUBR_ITCM)
+
+ ; Hook that jumps to our new subroutine
+ .org NEW_INDEX_TO_SHEDINJA_SUBR_HOOK
+ mov r0, r4
+ bl org() + 6
+ b OLD_INDEX_TO_SHEDINJA_SUBR_CONTINUED
+ ldr r2,=#(NEW_INDEX_TO_SHEDINJA_SUBR_ITCM + 1)
+ bx r2
+ .pool
+
+ .close
+
+ .open "pkmnwhite2.bin", "pkmnwhite2_shedinja.bin", 0x02004000
+ ; New subroutine. This is passed a pointer to the Pokemon data struct in r0; it is responsible
+ ; for setting the species and first few attributes of the newly-generated Shedinja. Most of this
+ ; code is copied from the original game, but it has been modified for easier modification of the
+ ; species ID (it was generated via some silly left shift in the original code).
+ .org NEW_INDEX_TO_SHEDINJA_SUBR
+ .area 48
+
+ push { r4, lr }
+ mov r4, r0 ; Save pointer to Pokemon data to r4 so it can be used again after calling functions
+ ldr r1,=#0x124 ; Shedinja
+ bl BL_OFFSET + SET_POKEMON_SPECIES
+ mov r0, r4
+ mov r1, #0x98 ; Attribute key for which ball the Pokemon is caught in
+ mov r2, #0x4 ; Poke Ball
+ bl BL_OFFSET + SET_POKEMON_ATTRIBUTE
+ mov r0, r4
+ mov r1, #0x6 ; Attribute key for the Pokemon's held item
+ mov r2, #0x0 ; No item
+ bl BL_OFFSET + SET_POKEMON_ATTRIBUTE
+ mov r0, r4
+ mov r1, #0xB ; Attribute key for the Pokemon's mark
+ mov r2, #0x0 ; No mark
+ bl BL_OFFSET + SET_POKEMON_ATTRIBUTE
+ pop { r4, pc }
+ .pool
+ .endarea
+
+ .close \ No newline at end of file
diff --git a/asm/shedinja/white_shedinja.asm b/asm/shedinja/white_shedinja.asm
new file mode 100644
index 0000000..336cabe
--- /dev/null
+++ b/asm/shedinja/white_shedinja.asm
@@ -0,0 +1,58 @@
+ .nds
+ .thumb
+ .open "pkmnwhite_ovl195", "pkmnwhite_ovl195_shedinja", 0x02203FC0
+
+ NEW_INDEX_TO_SHEDINJA_SUBR_HOOK equ 0x0220575E
+ OLD_INDEX_TO_SHEDINJA_SUBR_CONTINUED equ 0x02205786
+
+ SET_POKEMON_SPECIES equ 0x020178F4
+ SET_POKEMON_ATTRIBUTE equ 0x02017E5C
+
+ ITCM_SRC_START equ 0x020A9EA0
+ ITCM_DEST_START equ 0x01FF8000
+ ITCM_OLD_SIZE equ 0x91C ; Originally 0x820, but this occurs after the 0xFC sized music patch
+
+ NEW_INDEX_TO_SHEDINJA_SUBR equ ITCM_SRC_START + ITCM_OLD_SIZE
+ NEW_INDEX_TO_SHEDINJA_SUBR_ITCM equ ITCM_DEST_START + ITCM_OLD_SIZE
+ BL_OFFSET equ (NEW_INDEX_TO_SHEDINJA_SUBR) - (NEW_INDEX_TO_SHEDINJA_SUBR_ITCM)
+
+ ; Hook that jumps to our new subroutine
+ .org NEW_INDEX_TO_SHEDINJA_SUBR_HOOK
+ mov r0, r4
+ bl org() + 6
+ b OLD_INDEX_TO_SHEDINJA_SUBR_CONTINUED
+ ldr r2,=#(NEW_INDEX_TO_SHEDINJA_SUBR_ITCM + 1)
+ bx r2
+ .pool
+
+ .close
+
+ .open "pkmnwhite.bin", "pkmnwhite_shedinja.bin", 0x02004000
+ ; New subroutine. This is passed a pointer to the Pokemon data struct in r0; it is responsible
+ ; for setting the species and first few attributes of the newly-generated Shedinja. Most of this
+ ; code is copied from the original game, but it has been modified for easier modification of the
+ ; species ID (it was generated via some silly left shift in the original code).
+ .org NEW_INDEX_TO_SHEDINJA_SUBR
+ .area 48
+
+ push { r4, lr }
+ mov r4, r0 ; Save pointer to Pokemon data to r4 so it can be used again after calling functions
+ ldr r1,=#0x124 ; Shedinja
+ bl BL_OFFSET + SET_POKEMON_SPECIES
+ mov r0, r4
+ mov r1, #0x98 ; Attribute key for which ball the Pokemon is caught in
+ mov r2, #0x4 ; Poke Ball
+ bl BL_OFFSET + SET_POKEMON_ATTRIBUTE
+ mov r0, r4
+ mov r1, #0x6 ; Attribute key for the Pokemon's held item
+ mov r2, #0x0 ; No item
+ bl BL_OFFSET + SET_POKEMON_ATTRIBUTE
+ mov r0, r4
+ mov r1, #0xB ; Attribute key for the Pokemon's mark
+ mov r2, #0x0 ; No mark
+ bl BL_OFFSET + SET_POKEMON_ATTRIBUTE
+ pop { r4, pc }
+ .pool
+ .endarea
+
+ .close \ No newline at end of file
diff --git a/src/com/dabomstew/pkrandom/patches/shedinja/black2_ovl284_shedinja.ips b/src/com/dabomstew/pkrandom/patches/shedinja/black2_ovl284_shedinja.ips
new file mode 100644
index 0000000..3da8290
--- /dev/null
+++ b/src/com/dabomstew/pkrandom/patches/shedinja/black2_ovl284_shedinja.ips
Binary files differ
diff --git a/src/com/dabomstew/pkrandom/patches/shedinja/black2_shedinja.ips b/src/com/dabomstew/pkrandom/patches/shedinja/black2_shedinja.ips
new file mode 100644
index 0000000..c6eb474
--- /dev/null
+++ b/src/com/dabomstew/pkrandom/patches/shedinja/black2_shedinja.ips
Binary files differ
diff --git a/src/com/dabomstew/pkrandom/patches/shedinja/black_ovl195_shedinja.ips b/src/com/dabomstew/pkrandom/patches/shedinja/black_ovl195_shedinja.ips
new file mode 100644
index 0000000..b6fd282
--- /dev/null
+++ b/src/com/dabomstew/pkrandom/patches/shedinja/black_ovl195_shedinja.ips
Binary files differ
diff --git a/src/com/dabomstew/pkrandom/patches/shedinja/black_shedinja.ips b/src/com/dabomstew/pkrandom/patches/shedinja/black_shedinja.ips
new file mode 100644
index 0000000..08acd5e
--- /dev/null
+++ b/src/com/dabomstew/pkrandom/patches/shedinja/black_shedinja.ips
Binary files differ
diff --git a/src/com/dabomstew/pkrandom/patches/shedinja/white2_ovl284_shedinja.ips b/src/com/dabomstew/pkrandom/patches/shedinja/white2_ovl284_shedinja.ips
new file mode 100644
index 0000000..3da8290
--- /dev/null
+++ b/src/com/dabomstew/pkrandom/patches/shedinja/white2_ovl284_shedinja.ips
Binary files differ
diff --git a/src/com/dabomstew/pkrandom/patches/shedinja/white2_shedinja.ips b/src/com/dabomstew/pkrandom/patches/shedinja/white2_shedinja.ips
new file mode 100644
index 0000000..2901b63
--- /dev/null
+++ b/src/com/dabomstew/pkrandom/patches/shedinja/white2_shedinja.ips
Binary files differ
diff --git a/src/com/dabomstew/pkrandom/patches/shedinja/white_ovl195_shedinja.ips b/src/com/dabomstew/pkrandom/patches/shedinja/white_ovl195_shedinja.ips
new file mode 100644
index 0000000..b6fd282
--- /dev/null
+++ b/src/com/dabomstew/pkrandom/patches/shedinja/white_ovl195_shedinja.ips
Binary files differ
diff --git a/src/com/dabomstew/pkrandom/patches/shedinja/white_shedinja.ips b/src/com/dabomstew/pkrandom/patches/shedinja/white_shedinja.ips
new file mode 100644
index 0000000..a00135b
--- /dev/null
+++ b/src/com/dabomstew/pkrandom/patches/shedinja/white_shedinja.ips
Binary files differ
diff --git a/src/com/sneed/pkrandom/config/gen4_offsets.ini b/src/com/sneed/pkrandom/config/gen4_offsets.ini
index 9aab5dd..8cfc7d1 100755
--- a/src/com/sneed/pkrandom/config/gen4_offsets.ini
+++ b/src/com/sneed/pkrandom/config/gen4_offsets.ini
@@ -400,7 +400,7 @@ 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
+Arm9CRC32=99A30D93
OverlayCRC32<1>=21F7A855
OverlayCRC32<12>=90D2AF3E
OverlayCRC32<21>=A6363D04
@@ -422,7 +422,7 @@ NationalDexAtStartTweak=national_dex/hgss_national_dex
NewCatchingTutorialSubroutineTweak=hgss_catching_tutorialfix
NewRoamerSubroutineTweak=hardcoded_statics/roamers/hgss_roamers
MainGameLegendaries=[249]
-Arm9CRC32=C243A15F
+Arm9CRC32=8711C90D
OverlayCRC32<1>=172E4E62
OverlayCRC32<12>=7AFCE42A
OverlayCRC32<21>=A6363D04
@@ -518,7 +518,7 @@ NewRoamerSubroutineTweak=hardcoded_statics/roamers/hgss_roamers
NewCatchingTutorialSubroutineTweak=hgss_catching_tutorialfix
FastestTextTweak=instant_text/hgss_instant_text
NationalDexAtStartTweak=national_dex/hgss_national_dex
-Arm9CRC32=ED466320
+Arm9CRC32=99A30D93
OverlayCRC32<1>=21F7A855
OverlayCRC32<12>=90D2AF3E
OverlayCRC32<21>=A6363D04
@@ -536,7 +536,7 @@ FastestTextTweak=instant_text/hgss_instant_text
NationalDexAtStartTweak=national_dex/hgss_national_dex
NewCatchingTutorialSubroutineTweak=hgss_catching_tutorialfix
NewRoamerSubroutineTweak=hardcoded_statics/roamers/hgss_roamers
-Arm9CRC32=C243A15F
+Arm9CRC32=8711C90D
OverlayCRC32<1>=172E4E62
OverlayCRC32<12>=7AFCE42A
OverlayCRC32<21>=A6363D04
diff --git a/src/com/sneed/pkrandom/config/gen5_offsets.ini b/src/com/sneed/pkrandom/config/gen5_offsets.ini
index 11684f0..b92c16f 100755
--- a/src/com/sneed/pkrandom/config/gen5_offsets.ini
+++ b/src/com/sneed/pkrandom/config/gen5_offsets.ini
@@ -35,6 +35,8 @@ StarterCryOvlNumber=223
FastestTextTweak=instant_text/b1_instant_text
NewIndexToMusicTweak=musicfix/black_musicfix
NewIndexToMusicOvlTweak=musicfix/black_ovl21_musicfix
+ShedinjaEvolutionTweak=shedinja/black_shedinja
+ShedinjaEvolutionOvlTweak=shedinja/black_ovl195_shedinja
NationalDexAtStartTweak=national_dex/bw1_national_dex
TradesUnused=[1,3,7,8,9,10,11,12]
StarterOffsets1=[782:639, 782:644, 782:0x361, 782:0x5FD, 304:0xF9, 304:0x19C]
@@ -59,7 +61,6 @@ LuckyEggScriptOffset=390
ItemBallsScriptOffset=864
HiddenItemsScriptOffset=865
MapNamesTextOffset=89
-ShedinjaCodePatchOffsets=[0x40, 0x56, 0x154]
ShopItemOffsets=[0x51538,0x5153C,0x51546,0x5154C,0x51564,0x51590,0x515E4,0x515F2,0x51600,0x51610,0x51620,0x51630,0x51640,0x51650,0x51662,0x51674,0x51686,0x5169C,0x516B2,0x516C8,0x516F8,0x51714,0x51734,0x51774,0x51796,0x517BA]
ShopItemSizes=[2,2,3,4,4,6,7,7,8,8,8,8,8,9,9,9,11,11,11,11,14,16,16,17,18,19]
ShopCount=26
@@ -114,10 +115,11 @@ TradeScript[]=[830:0xB3:0xAE, 830:0xEA:0xE5, 830:0x114:0x10F] // Cinccino/Munchl
TradeScript[]=[764:0x43:0x3E] // Ditto/Rotom
StaticEggPokemonOffsets=[5]
MainGameLegendaries=[643,644]
+Arm9ExtensionSize=300 // 252 for music, 48 for Shedinja
TCMCopyingPrefix=1030A0E3013053E2FDFFFF1AF8FFFFEA
NewIndexToMusicPrefix=208020202860FFE7012002BC08470000
-NewIndexToMusicSize=252
SpecialMusicStatics=[494,571,637,638,639,640,641,643,645,646]
+ShedinjaSpeciesOffset=0xA67C8
TrainerOverworldTextBoxPrefix=0004000C03D10320
DoubleBattleLimitPrefix=321C26E0012E17D1
DoubleBattleGetPointerPrefix=0A9906980904090C
@@ -147,6 +149,8 @@ File<PokedexAreaData>=<a/1/7/8, ED259CD8>
FastestTextTweak=instant_text/w1_instant_text
NewIndexToMusicTweak=musicfix/white_musicfix
NewIndexToMusicOvlTweak=musicfix/white_ovl21_musicfix
+ShedinjaEvolutionTweak=shedinja/white_shedinja
+ShedinjaEvolutionOvlTweak=shedinja/white_ovl195_shedinja
NationalDexAtStartTweak=national_dex/bw1_national_dex
TradesUnused=[0,2,7,8,9,10,11,12]
ShopItemOffsets=[0x51530,0x51534,0x5153E,0x51544,0x5155C,0x51588,0x515DC,0x515EA,0x515F8,0x51608,0x51618,0x51628,0x51638,0x51648,0x5165A,0x5166C,0x5167E,0x51694,0x516AA,0x516C0,0x516F0,0x5170C,0x5172C,0x5176C,0x5178E,0x517B2]
@@ -154,6 +158,7 @@ BoxLegendaryOffset=16
EliteFourIndices=[228, 229, 230, 231, 232, 586]
IsBlack=0
SpecialMusicStatics=[494,571,637,638,639,640,642,644,645,646]
+ShedinjaSpeciesOffset=0xA67E8
Arm9CRC32=A6BA89D8
OverlayCRC32<10>=40E9CEEE
OverlayCRC32<21>=EAC5BFE0
@@ -205,6 +210,8 @@ StarterCryOvlNumber=316
FastestTextTweak=instant_text/b2_instant_text
NewIndexToMusicTweak=musicfix/black2_musicfix
NewIndexToMusicOvlTweak=musicfix/black2_ovl36_musicfix
+ShedinjaEvolutionTweak=shedinja/black2_shedinja
+ShedinjaEvolutionOvlTweak=shedinja/black2_ovl284_shedinja
NationalDexAtStartTweak=national_dex/bw2_national_dex
HiddenHollowIndex=1
ShopCount=32
@@ -236,7 +243,6 @@ LuckyEggScriptOffset=676
ItemBallsScriptOffset=1240
HiddenItemsScriptOffset=1241
MapNamesTextOffset=109
-ShedinjaCodePatchOffsets=[0x40, 0x56, 0x160]
ItemBallsSkip=[]
HiddenItemsSkip=[]
NationalDexScriptOffset=854
@@ -287,10 +293,11 @@ StaticPokemonFakeBall{}={Species=[1273:0xC7], Level=[534:0x2F2, 534:0x316, 562:0
IngameTradePersonTextOffsets=[529, 555, 193, 594, 628, 628]
StaticEggPokemonOffsets=[29]
MainGameLegendaries=[638,639,640]
+Arm9ExtensionSize=496 // 448 for music, 48 for Shedinja
TCMCopyingPrefix=1030A0E3013053E2FDFFFF1AF8FFFFEA
NewIndexToMusicPrefix=2648288021203060FFE7012002BC0847
-NewIndexToMusicSize=448
SpecialMusicStatics=[377,378,379,381,480,481,482,485,486,488,494,571,612,637,638,639,640,644,646,669]
+ShedinjaSpeciesOffset=0x9ACCC
TrainerOverworldTextBoxPrefix=0004000C03D10320
DoubleBattleLimitPrefix=0224E3E7012817D1
DoubleBattleGetPointerPrefix=0A9906980904090C
@@ -318,12 +325,15 @@ File<HabitatList>=<a/2/9/6, E578C751>
FastestTextTweak=instant_text/w2_instant_text
NewIndexToMusicTweak=musicfix/white2_musicfix
NewIndexToMusicOvlTweak=musicfix/white2_ovl36_musicfix
+ShedinjaEvolutionTweak=shedinja/white2_shedinja
+ShedinjaEvolutionOvlTweak=shedinja/white2_ovl284_shedinja
NationalDexAtStartTweak=national_dex/bw2_national_dex
HiddenHollowIndex=0
MoveTutorDataOffset=0x5152C
TradesUnused=[24]
IngameTradePersonTextOffsets=[537, 555, 193, 594, 628, 628]
SpecialMusicStatics=[377,378,379,380,480,481,482,485,486,488,494,571,612,637,638,639,640,643,646,668]
+ShedinjaSpeciesOffset=0x9AD0C
Arm9CRC32=DB3843F0
OverlayCRC32<36>=E3CF3D36
OverlayCRC32<162>=CCA4CB78
diff --git a/src/com/sneed/pkrandom/constants/Gen5Constants.java b/src/com/sneed/pkrandom/constants/Gen5Constants.java
index 169ecba..ef03ca1 100644
--- a/src/com/sneed/pkrandom/constants/Gen5Constants.java
+++ b/src/com/sneed/pkrandom/constants/Gen5Constants.java
@@ -359,9 +359,8 @@ public class Gen5Constants {
Moves.cut, Moves.fly, Moves.surf, Moves.strength, Moves.flash, Moves.dig, Moves.teleport,
Moves.waterfall, Moves.sweetScent, Moves.dive);
- public static final String shedinjaFunctionLocator = "F8B582B0061C30680F1C";
+ public static final String shedinjaSpeciesLocator = "24010000";
- private static final int bw1FieldOverlayNumber = 21, bw2FieldOverlayNumber = 36;
public static final String runningShoesPrefix = "01D0012008BD002008BD63";
public static final String introGraphicPrefix = "5A0000010000001700000001000000", bw1IntroCryPrefix = "0021009101910291", bw2IntroCryLocator = "3D020000F8B51C1C";
@@ -822,14 +821,6 @@ public class Gen5Constants {
return m;
}
- public static int getFieldOverlayNumber(int romType) {
- if (romType == Gen5Constants.Type_BW) {
- return Gen5Constants.bw1FieldOverlayNumber;
- } else {
- return Gen5Constants.bw2FieldOverlayNumber;
- }
- }
-
public static ItemList allowedItems, nonBadItemsBW1, nonBadItemsBW2;
public static List<Integer> regularShopItems, opShopItems;
diff --git a/src/com/sneed/pkrandom/romhandlers/Gen4RomHandler.java b/src/com/sneed/pkrandom/romhandlers/Gen4RomHandler.java
index 56b0147..8a936ec 100755
--- a/src/com/sneed/pkrandom/romhandlers/Gen4RomHandler.java
+++ b/src/com/sneed/pkrandom/romhandlers/Gen4RomHandler.java
@@ -539,6 +539,12 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
(romEntry.romType == Gen4Constants.Type_Plat && romEntry.tweakFiles.containsKey("NewRoamerSubroutineTweak")) ||
(romEntry.romType == Gen4Constants.Type_HGSS && romEntry.tweakFiles.containsKey("NewRoamerSubroutineTweak"));
+ try {
+ computeCRC32sForRom();
+ } catch (IOException e) {
+ throw new RandomizerIOException(e);
+ }
+
// We want to guarantee that the catching tutorial in HGSS has Ethan/Lyra's new Pokemon. We also
// want to allow the option of randomizing the enemy Pokemon too. Unfortunately, the latter can
// occur *before* the former, but there's no guarantee that it will even happen. Since we *know*
@@ -548,12 +554,6 @@ 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() {
@@ -5660,6 +5660,7 @@ public class Gen4RomHandler extends AbstractDSRomHandler {
@Override
public boolean isRomValid() {
if (romEntry.arm9ExpectedCRC32 != actualArm9CRC32) {
+ System.out.println(actualArm9CRC32);
return false;
}
diff --git a/src/com/sneed/pkrandom/romhandlers/Gen5RomHandler.java b/src/com/sneed/pkrandom/romhandlers/Gen5RomHandler.java
index 58fe224..242b2ca 100755
--- a/src/com/sneed/pkrandom/romhandlers/Gen5RomHandler.java
+++ b/src/com/sneed/pkrandom/romhandlers/Gen5RomHandler.java
@@ -478,6 +478,13 @@ public class Gen5RomHandler extends AbstractDSRomHandler {
} catch (IOException e) {
throw new RandomizerIOException(e);
}
+
+ // If there are tweaks for expanding the ARM9, do it here to keep it simple.
+ boolean shouldExtendARM9 = romEntry.tweakFiles.containsKey("ShedinjaEvolutionTweak") || romEntry.tweakFiles.containsKey("NewIndexToMusicTweak");
+ if (shouldExtendARM9) {
+ int extendBy = romEntry.getInt("Arm9ExtensionSize");
+ arm9 = extendARM9(arm9, extendBy, romEntry.getString("TCMCopyingPrefix"), Gen5Constants.arm9Offset);
+ }
}
private void loadPokemonStats() {
@@ -1977,8 +1984,7 @@ public class Gen5RomHandler extends AbstractDSRomHandler {
e.printStackTrace();
}
- int extendBy = romEntry.getInt("NewIndexToMusicSize");
- arm9 = extendARM9(arm9, extendBy, romEntry.getString("TCMCopyingPrefix"), Gen5Constants.arm9Offset);
+ // Relies on arm9 already being extended, which it *should* have been in loadedROM
genericIPSPatch(arm9, "NewIndexToMusicTweak");
String newIndexToMusicPrefix = romEntry.getString("NewIndexToMusicPrefix");
@@ -2510,13 +2516,12 @@ public class Gen5RomHandler extends AbstractDSRomHandler {
// set on the save file. If it isn't, the code branches to a separate code path
// where the function returns 0. The below code simply nops this branch so that
// this function always returns 1, regardless of the status of flag 2403.
- int fieldOverlayNumber = Gen5Constants.getFieldOverlayNumber(romEntry.romType);
- byte[] fieldOverlay = readOverlay(fieldOverlayNumber);
+ byte[] fieldOverlay = readOverlay(romEntry.getInt("FieldOvlNumber"));
String prefix = Gen5Constants.runningShoesPrefix;
int offset = find(fieldOverlay, prefix);
if (offset != 0) {
writeWord(fieldOverlay, offset, 0);
- writeOverlay(fieldOverlayNumber, fieldOverlay);
+ writeOverlay(romEntry.getInt("FieldOvlNumber"), fieldOverlay);
}
} catch (IOException e) {
throw new RandomizerIOException(e);
@@ -3051,7 +3056,7 @@ public class Gen5RomHandler extends AbstractDSRomHandler {
for (int i = 1; i <= Gen5Constants.pokemonCount; i++) {
byte[] evoEntry = evoNARC.files.get(i);
Pokemon pk = pokes[i];
- if (pk.number == Species.nincada) {
+ if (pk.number == Species.nincada && romEntry.tweakFiles.containsKey("ShedinjaEvolutionTweak")) {
writeShedinjaEvolution();
}
int evosWritten = 0;
@@ -3087,48 +3092,22 @@ public class Gen5RomHandler extends AbstractDSRomHandler {
if (nincada.evolutionsFrom.size() < 2) {
return;
}
+
Pokemon extraEvolution = nincada.evolutionsFrom.get(1).to;
- // In all the Gen 5 games, the evolution overlay is hardcoded to generate
- // a Shedinja by loading its species ID using the following instructions:
- // mov r1, #0x49
- // lsl r1, r1, #2
- // Since Gen 5 has more than 510 species, we cannot use 8-bit addition to
- // load any Pokemon; instead, we nop out a useless load of a string, then
- // use the space that used to store the address of that string to instead
- // store Nincada's new extra evolution's species ID.
+ // Update the evolution overlay to point towards our custom code in the expanded arm9.
byte[] evolutionOverlay = readOverlay(romEntry.getInt("EvolutionOvlNumber"));
- int functionOffset = find(evolutionOverlay, Gen5Constants.shedinjaFunctionLocator);
- if (functionOffset > 0) {
- int[] patchOffsets = romEntry.arrayEntries.get("ShedinjaCodePatchOffsets");
-
- // First, nop the instruction that loads a pointer to the string
- // "shinka_demo.c" into a register; this has seemingly no effect on
- // the game and was probably used strictly for debugging.
- evolutionOverlay[functionOffset + patchOffsets[0]] = 0x00;
- evolutionOverlay[functionOffset + patchOffsets[0] + 1] = 0x00;
-
- // In the space that used to hold the address of the "shinka_demo.c" string,
- // we're going to instead store a species ID. We need to write a pc-relative
- // load to that space. However, the original Shedinja instructions are
- // misaligned to do a load; there's an "add r0, r4, #0x0" between the move
- // and the shift that is correctly-aligned. So we first move this add up one
- // instruction, then we write out the load ("ldr r1, [pc #pcRelativeOffset]")
- // in the correctly-aligned space, then we nop out the shift.
- int pcRelativeOffset = patchOffsets[2] - patchOffsets[1] - 6;
- evolutionOverlay[functionOffset + patchOffsets[1]] = 0x20;
- evolutionOverlay[functionOffset + patchOffsets[1] + 1] = 0x1c;
- evolutionOverlay[functionOffset + patchOffsets[1] + 2] = (byte) (pcRelativeOffset / 4);
- evolutionOverlay[functionOffset + patchOffsets[1] + 3] = 0x49;
- evolutionOverlay[functionOffset + patchOffsets[1] + 4] = 0x00;
- evolutionOverlay[functionOffset + patchOffsets[1] + 5] = 0x00;
-
- // Finally, we replace what used to store the address of "shinka_demo.c"
- // with the species ID of Nincada's new extra evolution.
- int newSpeciesIDOffset = functionOffset + patchOffsets[2];
- FileFunctions.writeFullInt(evolutionOverlay, newSpeciesIDOffset, extraEvolution.number);
-
- writeOverlay(romEntry.getInt("EvolutionOvlNumber"), evolutionOverlay);
+ genericIPSPatch(evolutionOverlay, "ShedinjaEvolutionOvlTweak");
+ writeOverlay(romEntry.getInt("EvolutionOvlNumber"), evolutionOverlay);
+
+ // Relies on arm9 already being extended, which it *should* have been in loadedROM
+ genericIPSPatch(arm9, "ShedinjaEvolutionTweak");
+
+ // After applying the tweak, Shedinja's ID is simply pc-relative loaded, so just
+ // update the constant
+ int offset = romEntry.getInt("ShedinjaSpeciesOffset");
+ if (offset > 0) {
+ FileFunctions.writeFullInt(arm9, offset, extraEvolution.number);
}
}