diff --git a/asm/code_8094D28.s b/asm/code_8094D28.s deleted file mode 100644 index cfb921663..000000000 --- a/asm/code_8094D28.s +++ /dev/null @@ -1,275 +0,0 @@ - #include "asm/constants/gba_constants.inc" - #include "asm/macros.inc" - - .syntax unified - - .text - - thumb_func_start sub_8094D74 -sub_8094D74: - push {r4-r7,lr} - mov r7, r9 - mov r6, r8 - push {r6,r7} - mov r8, r0 - adds r7, r1, 0 - ldr r0, _08094E34 - bl sub_8094D28 - movs r4, 0x1 - movs r5, 0 - adds r3, r7, 0 - movs r0, 0x9C - lsls r0, 2 - cmp r3, r0 - bge _08094D96 - adds r3, r0, 0 -_08094D96: - ldr r6, _08094E38 - cmp r3, 0 - beq _08094DE2 - mov r9, r6 - ldr r0, _08094E3C - adds r0, r6 - mov r12, r0 - adds r2, r6, 0 -_08094DA6: - ldr r1, [r2] - lsrs r0, r1, 30 - eors r1, r0 - ldr r0, _08094E40 - muls r0, r1 - ldr r1, [r2, 0x4] - eors r1, r0 - lsls r0, r5, 2 - add r0, r8 - ldr r0, [r0] - adds r1, r0 - adds r1, r5 - str r1, [r2, 0x4] - adds r2, 0x4 - adds r4, 0x1 - adds r5, 0x1 - ldr r0, _08094E44 - cmp r4, r0 - ble _08094DD6 - mov r1, r12 - ldr r0, [r1] - str r0, [r6] - mov r2, r9 - movs r4, 0x1 -_08094DD6: - cmp r5, r7 - blt _08094DDC - movs r5, 0 -_08094DDC: - subs r3, 0x1 - cmp r3, 0 - bne _08094DA6 -_08094DE2: - ldr r3, _08094E44 - ldr r5, _08094E38 - ldr r0, _08094E3C - adds r0, r5 - mov r8, r0 - lsls r0, r4, 2 - subs r0, 0x4 - adds r2, r0, r5 - ldr r1, _08094E48 - mov r12, r1 - adds r7, r3, 0 -_08094DF8: - ldr r0, [r2] - lsrs r1, r0, 30 - eors r0, r1 - mov r1, r12 - muls r1, r0 - ldr r0, [r2, 0x4] - eors r0, r1 - subs r0, r4 - str r0, [r2, 0x4] - adds r2, 0x4 - adds r4, 0x1 - cmp r4, r7 - ble _08094E1C - mov r1, r8 - ldr r0, [r1] - str r0, [r6] - adds r2, r5, 0 - movs r4, 0x1 -_08094E1C: - subs r3, 0x1 - cmp r3, 0 - bne _08094DF8 - movs r0, 0x80 - lsls r0, 24 - str r0, [r6] - pop {r3,r4} - mov r8, r3 - mov r9, r4 - pop {r4-r7} - pop {r0} - bx r0 - .align 2, 0 -_08094E34: .4byte 0x012bd6aa -_08094E38: .4byte gUnknown_3001198 -_08094E3C: .4byte 0x000009bc -_08094E40: .4byte 0x0019660d -_08094E44: .4byte 0x0000026f -_08094E48: .4byte 0x5d588b65 - thumb_func_end sub_8094D74 - - thumb_func_start sub_8094E4C -sub_8094E4C: - push {r4-r7,lr} - mov r7, r9 - mov r6, r8 - push {r6,r7} - ldr r0, _08094F54 - ldr r2, [r0] - ldr r1, _08094F58 - mov r8, r0 - cmp r2, r1 - ble _08094F1C - ldr r0, _08094F5C - cmp r2, r0 - bne _08094E6C - ldr r0, _08094F60 - bl sub_8094D28 -_08094E6C: - movs r3, 0 - ldr r0, _08094F64 - mov r9, r0 - ldr r7, _08094F68 - mov r12, r9 - adds r5, r7, 0 -_08094E78: - ldr r4, [r5] - movs r6, 0x80 - lsls r6, 24 - ands r4, r6 - ldr r0, [r5, 0x4] - ldr r1, _08094F6C - ands r0, r1 - orrs r4, r0 - ldr r1, _08094F70 - adds r0, r3, r1 - lsls r0, 2 - adds r0, r7 - lsrs r2, r4, 1 - ldr r1, [r0] - eors r1, r2 - movs r0, 0x1 - ands r4, r0 - lsls r0, r4, 2 - add r0, r12 - ldr r0, [r0] - eors r1, r0 - stm r5!, {r1} - adds r3, 0x1 - cmp r3, 0xE2 - ble _08094E78 - ldr r5, _08094F74 - cmp r3, r5 - bgt _08094EE6 - ldr r1, _08094F68 - ldr r4, _08094F64 - mov r12, r4 - lsls r0, r3, 2 - adds r2, r0, r1 - ldr r4, _08094F78 - adds r0, r4 - adds r7, r0, r1 -_08094EC0: - ldr r4, [r2] - ands r4, r6 - ldr r0, [r2, 0x4] - ldr r1, _08094F6C - ands r0, r1 - orrs r4, r0 - lsrs r0, r4, 1 - ldm r7!, {r1} - eors r1, r0 - movs r0, 0x1 - ands r4, r0 - lsls r0, r4, 2 - add r0, r12 - ldr r0, [r0] - eors r1, r0 - stm r2!, {r1} - adds r3, 0x1 - cmp r3, r5 - ble _08094EC0 -_08094EE6: - ldr r2, _08094F68 - ldr r0, _08094F7C - adds r3, r2, r0 - ldr r4, [r3] - movs r0, 0x80 - lsls r0, 24 - ands r4, r0 - ldr r0, [r2] - ldr r1, _08094F6C - ands r0, r1 - orrs r4, r0 - movs r1, 0xC6 - lsls r1, 3 - adds r2, r1 - lsrs r0, r4, 1 - ldr r1, [r2] - eors r1, r0 - movs r0, 0x1 - ands r4, r0 - lsls r0, r4, 2 - add r0, r9 - ldr r0, [r0] - eors r1, r0 - str r1, [r3] - movs r0, 0 - mov r4, r8 - str r0, [r4] -_08094F1C: - ldr r2, _08094F68 - mov r0, r8 - ldr r1, [r0] - lsls r0, r1, 2 - adds r0, r2 - ldr r4, [r0] - adds r1, 0x1 - mov r0, r8 - str r1, [r0] - lsrs r0, r4, 11 - eors r4, r0 - lsls r0, r4, 7 - ldr r1, _08094F80 - ands r0, r1 - eors r4, r0 - lsls r0, r4, 15 - ldr r1, _08094F84 - ands r0, r1 - eors r4, r0 - lsrs r0, r4, 18 - eors r4, r0 - adds r0, r4, 0 - pop {r3,r4} - mov r8, r3 - mov r9, r4 - pop {r4-r7} - pop {r1} - bx r1 - .align 2, 0 -_08094F54: .4byte gUnknown_203B470 -_08094F58: .4byte 0x0000026f -_08094F5C: .4byte 0x00000271 -_08094F60: .4byte 0x00001571 -_08094F64: .4byte gUnknown_203B474 -_08094F68: .4byte gUnknown_3001198 -_08094F6C: .4byte 0x7fffffff -_08094F70: .4byte 0x0000018d -_08094F74: .4byte 0x0000026e -_08094F78: .4byte 0xfffffc74 -_08094F7C: .4byte 0x000009bc -_08094F80: .4byte 0x9d2c5680 -_08094F84: .4byte 0xefc60000 - thumb_func_end sub_8094E4C - - .align 2,0 diff --git a/include/code_8094D28.h b/include/code_8094D28.h deleted file mode 100644 index e166da1d7..000000000 --- a/include/code_8094D28.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef GUARD_CODE_8094D28_H -#define GUARD_CODE_8094D28_H - -// code_8094D28.s -void sub_8094D28(s32 r0); -extern s32 sub_8094E4C(void); - -#endif // GUARD_CODE_8094D28_H diff --git a/include/random_mersenne_twister.h b/include/random_mersenne_twister.h new file mode 100644 index 000000000..3b711694c --- /dev/null +++ b/include/random_mersenne_twister.h @@ -0,0 +1,7 @@ +#ifndef GUARD_RANDOM_MERSENNE_TWISTER_H +#define GUARD_RANDOM_MERSENNE_TWISTER_H + +void MersenneTwister_InitializeState(u32 seed); +s32 Random32MersenneTwister(void); + +#endif // GUARD_RANDOM_MERSENNE_TWISTER_H diff --git a/ld_script.txt b/ld_script.txt index 84fa9304f..9b4e2cc5a 100755 --- a/ld_script.txt +++ b/ld_script.txt @@ -290,8 +290,7 @@ SECTIONS { src/code_809447C.o(.text); src/code_8092334.o(.text); src/game_options.o(.text); - src/code_8094D28.o(.text); - asm/code_8094D28.o(.text); + src/random_mersenne_twister.o(.text); src/play_time.o(.text); src/code_8094F88.o(.text); src/code_80958E8.o(.text); @@ -566,7 +565,7 @@ SECTIONS { src/pokemon.o(.rodata); data/data_81076E4.o(.rodata); src/game_options.o(.rodata); - src/code_8094D28.o(.rodata); + src/random_mersenne_twister.o(.rodata); src/play_time.o(.rodata); src/code_8094F88.o(.rodata); src/code_80958E8.o(.rodata); diff --git a/src/code_8094D28.c b/src/code_8094D28.c deleted file mode 100644 index 5e330ed55..000000000 --- a/src/code_8094D28.c +++ /dev/null @@ -1,20 +0,0 @@ -#include "global.h" -#include "globaldata.h" - -IWRAM_DATA u32 gUnknown_3001198[0x270] = {0}; -EWRAM_INIT s32 gUnknown_203B470 = 0x271; -EWRAM_INIT s32 gUnknown_203B474 = 0; -UNUSED static EWRAM_INIT s32 sUnusedEwramVar = 0x9908b0df; // Hm... - -void sub_8094D28(s32 r0) { - - gUnknown_3001198[0] = r0; - gUnknown_203B470 = 1; - - for(; gUnknown_203B470 < 0x270; gUnknown_203B470++) - { - gUnknown_3001198[gUnknown_203B470] = - (gUnknown_3001198[gUnknown_203B470 - 1] ^ - (gUnknown_3001198[gUnknown_203B470 - 1] >> 0x1e)) * 0x6c078965 + gUnknown_203B470; - } -} diff --git a/src/code_8094F88.c b/src/code_8094F88.c index c36a9c924..829c140e8 100644 --- a/src/code_8094F88.c +++ b/src/code_8094F88.c @@ -1,6 +1,6 @@ #include "global.h" #include "globaldata.h" -#include "code_8094D28.h" +#include "random_mersenne_twister.h" #include "code_8094F88.h" #include "constants/wonder_mail.h" #include "dungeon.h" @@ -277,8 +277,8 @@ void sub_809542C(WonderMailSub *param_1) gUnknown_203B480->mailType = 1; gUnknown_203B480->unk4 = *param_1; - sub_8094D28(Rand32Bit()); - gUnknown_203B480->unk10.unk10 = sub_8094E4C(); + MersenneTwister_InitializeState(Rand32Bit()); + gUnknown_203B480->unk10.unk10 = Random32MersenneTwister(); gUnknown_203B480->clientSpecies = GetPlayerPokemonStruct()->speciesNum; PrintPokeNameToBuffer(buffer, GetPlayerPokemonStruct()); CopyStringtoBuffer(gUnknown_203B480->playerName, buffer); diff --git a/src/personality_test1.c b/src/personality_test1.c index c53b502a1..31fbd467f 100644 --- a/src/personality_test1.c +++ b/src/personality_test1.c @@ -3,7 +3,7 @@ #include "bg_palette_buffer.h" #include "string_format.h" #include "code_801602C.h" -#include "code_8094D28.h" +#include "random_mersenne_twister.h" #include "code_8099360.h" #include "constants/emotions.h" #include "game_options.h" @@ -148,14 +148,14 @@ u32 HandleTestTrackerState(void) break; case PERSONALITY_TEST_END: iVar1 = Rand32Bit() * sPersonalityTestTracker->FrameCounter; - sub_8094D28(Rand32Bit()); + MersenneTwister_InitializeState(Rand32Bit()); for (counter = 0; counter < NUM_PERSONALITIES; counter++) iVar1 *= sPersonalityTestTracker->NatureTotals[counter] + counter + 3; - iVar1 += sub_8094E4C(); + iVar1 += Random32MersenneTwister(); while (iVar1 == -1) - iVar1 += sub_8094E4C(); + iVar1 += Random32MersenneTwister(); sub_8011C40(iVar1); return 3; diff --git a/src/random_mersenne_twister.c b/src/random_mersenne_twister.c new file mode 100644 index 000000000..e74628cae --- /dev/null +++ b/src/random_mersenne_twister.c @@ -0,0 +1,116 @@ +#include "global.h" +#include "globaldata.h" +#include "random_mersenne_twister.h" + +// Implementation and names based on https://en.wikipedia.org/wiki/Mersenne_Twister + +#define n (624) // degree of recurrence +#define m (397) // middle word, an offset used in the recurrence relation defining the series x, 1 <= m < n +#define w (32) // word size (in number of bits) +#define r (31) // separation point of one word, or the number of bits of the lower bitmask, 0 <= r <= w − 1 +#define UMASK (0xffffffffU << r) +#define LMASK (0xffffffffU >> (w-r)) +#define a (0x9908b0dfU) // coefficients of the rational normal form twist matrix +// additional Mersenne Twister tempering bit shifts/masks +#define u (11) +#define s (7) +#define t (15) +#define l (18) +// tempering bitmasks +#define b (0x9d2c5680U) +#define c (0xefc60000U) +#define f (1812433253U) +#define INITIAL_SEED (19650218U) // // suggested initial seed + +static IWRAM_DATA u32 sStateArray[n] = {0}; // the array for the state vector +static EWRAM_INIT s32 sStateIndex = n + 1; // index into state vector array, 0 <= state_index <= n-1 +// Only read from. For what it's worth, it could be const. +static EWRAM_INIT u32 sTwistMatrix[2] = {0, a}; + +void MersenneTwister_InitializeState(u32 seed) +{ + sStateArray[0] = seed; + + for (sStateIndex = 1; sStateIndex < n; sStateIndex++) { + sStateArray[sStateIndex] = + (sStateArray[sStateIndex - 1] ^ + (sStateArray[sStateIndex - 1] >> (w - 2))) * f + sStateIndex; + } +} + +// Apparently this could improve entropy of the randomness...Though it remained unused. +UNUSED static void MersenneTwister_MixSeeds(u32 *seeds, s32 count) +{ + s32 i; + s32 id; + s32 seedId; + + MersenneTwister_InitializeState(INITIAL_SEED); + id = 1; + seedId = 0; + + for (i = max(count, n); i != 0; i--) { + u32 bits = sStateArray[id - 1] ^ (sStateArray[id - 1] >> (w - 2)); + sStateArray[id] = (sStateArray[id] ^ (bits * 0x19660d)) + seeds[seedId] + seedId; + + id++; + seedId++; + if (id >= n) { + sStateArray[0] = sStateArray[n - 1]; + id = 1; + } + if (seedId >= count) { + seedId = 0; + } + } + + for (i = n - 1; i != 0; i--) { + u32 bits = sStateArray[id - 1] ^ (sStateArray[id - 1] >> (w - 2)); + sStateArray[id] = (sStateArray[id] ^ (bits * 0x5d588b65)) - id; + + id++; + if (id >= n) { + sStateArray[0] = sStateArray[n - 1]; + id = 1; + } + } + + sStateArray[0] = UMASK; +} + +s32 Random32MersenneTwister(void) +{ + u32 bits1, bits2; + s32 i; + + if (sStateIndex >= n) { + // Re-initialize state if all numbers were used + if (sStateIndex == n + 1) { + MersenneTwister_InitializeState(0x1571); + } + + for (i = 0; i < 227; i++) { + bits1 = (sStateArray[i] & UMASK) | (sStateArray[i + 1] & LMASK); + bits2 = sStateArray[i + m] ^ (bits1 >> 1); + sStateArray[i] = bits2 ^ sTwistMatrix[bits1 & 1]; + } + for (; i < n - 1; i++) { + bits1 = (sStateArray[i] & UMASK) | (sStateArray[i + 1] & LMASK); + bits2 = sStateArray[i - 227] ^ (bits1 >> 1); + sStateArray[i] = bits2 ^ sTwistMatrix[bits1 & 1]; + } + + bits1 = (sStateArray[n - 1] & UMASK) | (sStateArray[0] & LMASK); + bits2 = sStateArray[m - 1] ^ (bits1 >> 1); + sStateArray[n - 1] = bits2 ^ sTwistMatrix[bits1 & 1]; + sStateIndex = 0; + } + + // tempering + bits1 = sStateArray[sStateIndex++]; + bits1 ^= (bits1 >> u); + bits1 ^= (bits1 << s) & b; + bits1 ^= (bits1 << t) & c; + bits1 ^= (bits1 >> l); + return bits1; +} diff --git a/sym_ewram_init.txt b/sym_ewram_init.txt index 5b7925143..0dadb0bd7 100644 --- a/sym_ewram_init.txt +++ b/sym_ewram_init.txt @@ -127,7 +127,7 @@ .include "src/rescue_team_info.o" .include "src/friend_area.o" .include "src/game_options.o" -.include "src/code_8094D28.o" +.include "src/random_mersenne_twister.o" .include "src/play_time.o" .include "src/code_8094F88.o" .include "src/code_80958E8.o" diff --git a/sym_iwram.txt b/sym_iwram.txt index 908f47ef4..8ef6e8574 100644 --- a/sym_iwram.txt +++ b/sym_iwram.txt @@ -9,4 +9,4 @@ gUnknown_3000C00: /* 3000C00 */ .include "src/text.o" .include "src/music.o" .include "src/code_803E724.o" -.include "src/code_8094D28.o" +.include "src/random_mersenne_twister.o"