diff options
-rw-r--r-- | engine/battle/core.asm | 69 | ||||
-rw-r--r-- | shim.sym | 1 | ||||
-rw-r--r-- | wram.asm | 7 |
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 @@ -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 @@ -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] |