summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engine/battle/core.asm69
-rw-r--r--shim.sym1
-rw-r--r--wram.asm7
3 files changed, 76 insertions, 1 deletions
diff --git a/engine/battle/core.asm b/engine/battle/core.asm
new file mode 100644
index 0000000..c79fb22
--- /dev/null
+++ b/engine/battle/core.asm
@@ -0,0 +1,69 @@
+include "constants.asm"
+
+SECTION "Battle Random", ROMX [$63DA], BANK [$0F]
+_BattleRandom: ; 3e3da (f:63da)
+; If the normal RNG is used in a link battle it'll desync.
+; To circumvent this a shared PRNG is used instead.
+
+; But if we're in a non-link battle we're safe to use it
+ ld a, [wLinkMode]
+ and a
+ jp z, Random
+
+; The PRNG operates in streams of 10 values.
+
+; Which value are we trying to pull?
+ push hl
+ push bc
+ ld a, [wLinkBattleRNCount]
+ ld c, a
+ ld b, $0
+ ld hl, wLinkBattleRNs
+ add hl, bc
+ inc a
+ ld [wLinkBattleRNCount], a
+
+; If we haven't hit the end yet, we're good
+ cp 9 ; number of seeds, including the last one. see comment in pokecrystal
+ ld a, [hl]
+ pop bc
+ pop hl
+ ret c
+
+; If we have, we have to generate new pseudorandom data
+; Instead of having multiple PRNGs, ten seeds are used
+ push hl
+ push bc
+ push af
+
+; Reset count to 0
+ xor a
+ ld [wLinkBattleRNCount], a
+ ld hl, wLinkBattleRNs
+ ld b, 9 ; number of seeds; in release, this was increased to 10
+
+; Generate next number in the sequence for each seed
+; a[n+1] = (a[n] * 5 + 1) % 256
+.loop
+ ; get last #
+ ld a, [hl]
+
+ ; a * 5 + 1
+ ld c, a
+ add a
+ add a
+ add c
+ inc a
+
+ ; update #
+ ld [hli], a
+ dec b
+ jr nz, .loop
+
+; This has the side effect of pulling the last value first,
+; then wrapping around. As a result
+
+ pop af
+ pop bc
+ pop hl
+ ret
diff --git a/shim.sym b/shim.sym
index 9c0c63e..ac185f2 100644
--- a/shim.sym
+++ b/shim.sym
@@ -133,7 +133,6 @@
0F:55CE Function_3d5ce
0F:567C Function_3d67c
0F:61A4 Function_3e1a4
-0F:63DA _BattleRandom
0F:6874 Function_3e874
0F:691E Function_3e91e
0F:6963 Function_3e963
diff --git a/wram.asm b/wram.asm
index a6ed29e..8042d4d 100644
--- a/wram.asm
+++ b/wram.asm
@@ -182,6 +182,9 @@ wEnemySubStatus3:: db ; ca42
ds $14
wTrainerClass:: ; ca57
db
+; ca58
+ ds $6b
+wLinkBattleRNCount:: db ; cac3
ENDU
@@ -370,6 +373,10 @@ wLinkMode:: db ; cdbd
wTargetMapUnk:: db ; cdbe ; TODO: Probably warp ID, check
wTargetMapGroup:: db ; cdbf
wTargetMapId:: db ; cdc0
+; cdc1
+ ds $c
+wLinkBattleRNs:: ds 10 ; cdcd
+; cddd
SECTION "CE00", WRAM0[$CE00]