Skip to content

Commit e908705

Browse files
committed
Add in better NES RNG [work-in-progress]
The vanilla game's RNG, in many cases, outputs poorly randomized values that form too much of a pattern. I've inserted a better NES RNG to see if that makes things more fun. This can pretty much replace the need for "Reduce Dripper Variance". In theory it should also reduce the need for the 50/50 Alternating Jar, but that feature seems well-liked so probably can't remove that. This assumes $F9-$FB in zero page memory is unused - which seems to be true so far in my testing. Things I specifically don't think should be changed to use this as players are used to how they work: - Overworld enemy random movement - Bot/Bit/Myu random movement Other enemies RNG behavior is a maybe for now. Potential future things to do: - Rework Standardize Drops to use a separate seed in SRAM (that will start the same for all players) and is used for drops only, removing the predictability of the current Standardize Drops solution.
1 parent ea265e3 commit e908705

4 files changed

Lines changed: 139 additions & 3 deletions

File tree

RandomizerCore/Asm/MMC5.s

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -603,14 +603,32 @@ ClearPartialDevRAM:
603603

604604

605605
.org $a69c
606-
jsr SetSoftEnableNmiWithSta
606+
jmp SetSoftEnableNmiWithSta
607+
FREE_UNTIL $a6a0
608+
609+
.reloc
610+
SetSoftEnableNmiWithSta: ; ends with RTI
611+
sta PPUCTRL
612+
lda #0
613+
sta SoftDisableNmi
614+
rti
615+
607616
.org $a6d5
608-
jsr SetSoftEnableNmiWithSta
617+
jmp ResetMemoryEntryPoint
618+
FREE_UNTIL $a6d9
619+
609620
.reloc
610-
SetSoftEnableNmiWithSta:
621+
; extending this as a point where we hook into "on reset memory"
622+
ResetMemoryEntryPoint: ; ends with RTS
611623
sta PPUCTRL
612624
lda #0
613625
sta SoftDisableNmi
626+
627+
lda #.lobyte(RngSeed)
628+
sta ZpRng
629+
lda #.hibyte(RngSeed)
630+
sta ZpRng+1
631+
614632
rts
615633

616634
.segment "PRG5","PRG7"

RandomizerCore/Asm/z2r.inc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,11 @@ ENABLE_SCANLINE_IRQ = $80
104104
MulLoReg = $5205
105105
MulHiReg = $5206
106106

107+
; F0-F4, F9-FB seems unused
108+
ZpTmp = $F9 ; nice to have a known disposable byte in zero page
109+
; New RNG zero page seed (2 bytes)
110+
ZpRng = $FA ; and $FB
111+
107112
;; Common locations used in the code
108113
PpuCtrlShadow = $ff
109114
ScrollPosShadow = $fd

RandomizerCore/Hyrule.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3588,6 +3588,7 @@ private void ChangeMapperToMMC5(Assembler asm, bool preventFlash, bool enableZ2F
35883588
a.Assign("PREVENT_HUD_FLASH_ON_LAG", preventFlash ? 1 : 0);
35893589
a.Assign("ENABLE_Z2FT", enableZ2Ft ? 1 : 0);
35903590
AssignRealPalaceLocations(a);
3591+
a.Set("RngSeed", 18724); // new in-game ASM rng seed (just picked a number for now)
35913592
a.Code(Util.ReadResource("Z2Randomizer.RandomizerCore.Asm.MMC5.s"), "mmc5_conversion.s");
35923593
}
35933594

@@ -3695,6 +3696,7 @@ private void ApplyAsmPatches(RandomizerProperties props, Assembler engine, Rando
36953696
FixSoftLock(engine);
36963697

36973698
RandomizeStartingValues(props, engine, r, rom);
3699+
rom.BetterAsmRng(engine);
36983700
rom.FixStaleSaveSlotData(engine);
36993701
rom.UseExtendedBanksForPalaceRooms(engine);
37003702
rom.ExtendMapSize(engine);

RandomizerCore/ROM.cs

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -838,6 +838,117 @@ public void DisableMusic()
838838
Put(0x1a975, 0);
839839
}
840840

841+
public void BetterAsmRng(Assembler asm)
842+
{
843+
var a = asm.Module();
844+
a.Code("""
845+
.include "z2r.inc"
846+
847+
.segment "PRG7"
848+
.reloc
849+
; From https://github.com/bbbradsmith/prng_6502
850+
; Returns a random 8-bit number in A (0-255), clobbers Y
851+
GetBetterRngByteDiscardY:
852+
lda ZpRng+1
853+
tay ; store copy of high byte
854+
; compute ZpRng+1 ($39>>1 = %11100)
855+
lsr ; shift to consume zeroes on left...
856+
lsr
857+
lsr
858+
sta ZpRng+1 ; now recreate the remaining bits in reverse order... %111
859+
lsr
860+
eor ZpRng+1
861+
lsr
862+
eor ZpRng+1
863+
eor ZpRng+0 ; recombine with original low byte
864+
sta ZpRng+1
865+
; compute ZpRng+0 ($39 = %111001)
866+
tya ; original high byte
867+
sta ZpRng+0
868+
asl
869+
eor ZpRng+0
870+
asl
871+
eor ZpRng+0
872+
asl
873+
asl
874+
asl
875+
eor ZpRng+0
876+
sta ZpRng+0
877+
rts
878+
879+
.reloc
880+
; Returns a random 8-bit number in A (0-255)
881+
GetBetterRngByte:
882+
sty ZpTmp
883+
jsr GetBetterRngByteDiscardY
884+
ldy ZpTmp
885+
rts
886+
887+
.segment "PRG1"
888+
; Megmat
889+
.org $989E
890+
jsr GetBetterRngByteDiscardY
891+
892+
; Goriya
893+
.org $99AB
894+
jsr GetBetterRngByte ; (X would be discardable here, but not Y)
895+
896+
; Daira
897+
.org $9A76
898+
jsr GetBetterRngByte
899+
.org $9A92
900+
jsr GetBetterRngByte
901+
902+
; Moby and Moblin generator (which direction to spawn from)
903+
.org $9B58
904+
jsr GetBetterRngByteDiscardY
905+
906+
.segment "PRG4"
907+
; Stalfos
908+
.org $970E
909+
jsr GetBetterRngByteDiscardY
910+
911+
; Iron Knuckle
912+
.org $9D2E
913+
jsr GetBetterRngByteDiscardY
914+
.org $9D58
915+
jsr GetBetterRngByteDiscardY
916+
ldy $df
917+
.org $9DC7
918+
jsr GetBetterRngByteDiscardY
919+
.org $9DD2
920+
jsr GetBetterRngByteDiscardY
921+
ldy #$01
922+
923+
; Falling Block Generator
924+
.org $ABB0
925+
jsr GetBetterRngByteDiscardY
926+
927+
; Dripping Column
928+
.org $B9EB
929+
jsr GetBetterRngByte
930+
931+
.segment "PRG7"
932+
; Bot -- Disabled - don't want to change how the Bot (& similar) enemies act
933+
;.org $DA15
934+
; jsr GetBetterRngByteDiscardY
935+
; Bot, Bit, Myu
936+
;.org $DAB0
937+
; jsr GetBetterRngByte
938+
939+
; Moa
940+
.org $DB0D
941+
jsr GetBetterRngByteDiscardY
942+
943+
; Raising Bubbles
944+
.org $DC27
945+
jsr GetBetterRngByte ; (X would be discardable here, but not Y)
946+
adc $072c ; add scrolling offset low byte
947+
and #$fc ; allow slightly finer x positioning (snap to every 4th pixel instead of every 16th pixel)
948+
949+
""");
950+
}
951+
841952
/// The vanilla game sets up all 3 save slots from PRG in the
842953
/// title screen. If there is already valid data in a save slot,
843954
/// it will keep it. Note: this includes keeping save slots

0 commit comments

Comments
 (0)