summaryrefslogtreecommitdiff
path: root/src/com/sneed/pkrandom/romhandlers
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 /src/com/sneed/pkrandom/romhandlers
parentf5880a1039828686ff0d7d0bf8fac304044f9b62 (diff)
Gen 5: Fix Shedinja evo crashing on Bizhawk/real hardware
Diffstat (limited to 'src/com/sneed/pkrandom/romhandlers')
-rwxr-xr-xsrc/com/sneed/pkrandom/romhandlers/Gen4RomHandler.java13
-rwxr-xr-xsrc/com/sneed/pkrandom/romhandlers/Gen5RomHandler.java69
2 files changed, 31 insertions, 51 deletions
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);
}
}