diff --git a/Makefile b/Makefile index 1c7ae02e3..e1b7210c6 100644 --- a/Makefile +++ b/Makefile @@ -318,6 +318,7 @@ ifeq ($(COMPILER), ido) src/lib/ultra/io/pfsinitpak2.c MIPS3_C_FILES := \ + src/lib/rng.c \ src/lib/ultra/libc/ll.c \ src/lib/ultra/libc/llcvt.c @@ -750,6 +751,11 @@ $(B_DIR)/rsp/%.o: $(B_DIR)/rsp/%.bin TOOLCHAIN=$(TOOLCHAIN) ROMID=$(ROMID) tools/mkrawobject $< $@ ifeq ($(COMPILER), ido) +$(B_DIR)/lib/rng.o: src/lib/rng.c $(ASSETMGR_O_FILES) $(RECOMP_FILES) + @mkdir -p $(dir $@) + $(CC) -c $(CFLAGS) $(OPT_LVL) -o $@ $< + tools/patchmips3 $@ || rm $@ + $(B_DIR)/lib/ultra/libc/llcvt.o: src/lib/ultra/libc/llcvt.c $(ASSETMGR_O_FILES) $(RECOMP_FILES) @mkdir -p $(dir $@) $(CC) -c $(CFLAGS) $(OPT_LVL) -o $@ $< diff --git a/ld/libfiles.jpn-final.inc b/ld/libfiles.jpn-final.inc index 2a3b003fd..cfdceda97 100644 --- a/ld/libfiles.jpn-final.inc +++ b/ld/libfiles.jpn-final.inc @@ -40,7 +40,7 @@ build/ROMID/lib/music.o (section); \ build/ROMID/lib/memp.o (section); \ build/ROMID/lib/mema.o (section); \ - build/ROMID/lib/rng.o (section); \ + build/ROMID/lib/rngasm.o (section); \ build/ROMID/lib/args.o (section); \ build/ROMID/lib/str.o (section); \ build/ROMID/lib/ultra/libc/sprintf.o (section); \ diff --git a/ld/libfiles.ntsc-beta.inc b/ld/libfiles.ntsc-beta.inc index a33cfbd31..9cb456e32 100644 --- a/ld/libfiles.ntsc-beta.inc +++ b/ld/libfiles.ntsc-beta.inc @@ -42,7 +42,7 @@ build/ROMID/lib/music.o (section); \ build/ROMID/lib/memp.o (section); \ build/ROMID/lib/mema.o (section); \ - build/ROMID/lib/rng.o (section); \ + build/ROMID/lib/rngasm.o (section); \ build/ROMID/lib/args.o (section); \ build/ROMID/lib/str.o (section); \ build/ROMID/lib/ultra/libc/sprintf.o (section); \ diff --git a/ld/libfiles.ntsc-final.inc b/ld/libfiles.ntsc-final.inc index 0d14cee3a..5d2863913 100644 --- a/ld/libfiles.ntsc-final.inc +++ b/ld/libfiles.ntsc-final.inc @@ -40,7 +40,7 @@ build/ROMID/lib/music.o (section); \ build/ROMID/lib/memp.o (section); \ build/ROMID/lib/mema.o (section); \ - build/ROMID/lib/rng.o (section); \ + build/ROMID/lib/rngasm.o (section); \ build/ROMID/lib/args.o (section); \ build/ROMID/lib/str.o (section); \ build/ROMID/lib/ultra/libc/sprintf.o (section); \ diff --git a/ld/libfiles.pal-beta.inc b/ld/libfiles.pal-beta.inc index 2a3b003fd..cfdceda97 100644 --- a/ld/libfiles.pal-beta.inc +++ b/ld/libfiles.pal-beta.inc @@ -40,7 +40,7 @@ build/ROMID/lib/music.o (section); \ build/ROMID/lib/memp.o (section); \ build/ROMID/lib/mema.o (section); \ - build/ROMID/lib/rng.o (section); \ + build/ROMID/lib/rngasm.o (section); \ build/ROMID/lib/args.o (section); \ build/ROMID/lib/str.o (section); \ build/ROMID/lib/ultra/libc/sprintf.o (section); \ diff --git a/ld/libfiles.pal-final.inc b/ld/libfiles.pal-final.inc index 2a3b003fd..cfdceda97 100644 --- a/ld/libfiles.pal-final.inc +++ b/ld/libfiles.pal-final.inc @@ -40,7 +40,7 @@ build/ROMID/lib/music.o (section); \ build/ROMID/lib/memp.o (section); \ build/ROMID/lib/mema.o (section); \ - build/ROMID/lib/rng.o (section); \ + build/ROMID/lib/rngasm.o (section); \ build/ROMID/lib/args.o (section); \ build/ROMID/lib/str.o (section); \ build/ROMID/lib/ultra/libc/sprintf.o (section); \ diff --git a/src/include/lib/rng.h b/src/include/lib/rng.h index d5231d39d..32741640f 100644 --- a/src/include/lib/rng.h +++ b/src/include/lib/rng.h @@ -5,7 +5,6 @@ #include "types.h" u32 random(void); -void rngSetSeed(u32 seed); u32 rngRotateSeed(u64 *value); #endif diff --git a/src/lib/main.c b/src/lib/main.c index ba388a23d..43fca9c04 100644 --- a/src/lib/main.c +++ b/src/lib/main.c @@ -70,6 +70,10 @@ #include "data.h" #include "types.h" +// mainLoop calls rngSetSeed with a u32 argument, +// but the function takes a u64 so an incorrect declaration is needed. +void rngSetSeed(u32 seed); + bool var8005d9b0 = false; s32 g_StageNum = STAGE_TITLE; u32 g_MainMemaHeapSize = 1024 * 300; diff --git a/src/lib/rng.c b/src/lib/rng.c new file mode 100644 index 000000000..6bee7e7f3 --- /dev/null +++ b/src/lib/rng.c @@ -0,0 +1,41 @@ +#include +#include "constants.h" +#include "bss.h" +#include "lib/rng.h" +#include "data.h" +#include "types.h" + +u64 g_RngSeed = 0xab8d9f7781280783; + +/** + * Generate a random number between 0 and 4294967295. + */ +u32 random(void) +{ + g_RngSeed = ((g_RngSeed << 63) >> 31 | (g_RngSeed << 31) >> 32) ^ (g_RngSeed << 44) >> 32; + g_RngSeed = ((g_RngSeed >> 20) & 0xfff) ^ g_RngSeed; + + return g_RngSeed; +} + +/** + * Set the given seed as the RNG seed. Add 1 to make sure it isn't 0. + */ +void rngSetSeed(u64 seed) +{ + g_RngSeed = seed + 1; +} + +/** + * Rotate the given seed using the same algorithm as random(). + * + * Store the new 64-bit seed at the pointed address and return the same seed + * cast as a u32. + */ +u32 rngRotateSeed(u64 *seed) +{ + *seed = ((*seed << 63) >> 31 | (*seed << 31) >> 32) ^ (*seed << 44) >> 32; + *seed = ((*seed >> 20) & 0xfff) ^ *seed; + + return *seed; +} diff --git a/src/lib/rng.s b/src/lib/rngasm.s similarity index 98% rename from src/lib/rng.s rename to src/lib/rngasm.s index c94a82a22..30f97bed0 100644 --- a/src/lib/rng.s +++ b/src/lib/rngasm.s @@ -36,7 +36,7 @@ glabel random dsra32 $v0, $v0, 0 /** - * void rngSetSeed(u32 seed) + * void rngSetSeed(u64 seed) * * Set the given seed as the RNG seed. Add 1 to make sure it isn't 0. */