diff options
| author | Miquel Sabaté Solà <mssola@mssola.com> | 2026-03-20 21:52:36 +0100 |
|---|---|---|
| committer | Miquel Sabaté Solà <mssola@mssola.com> | 2026-03-22 15:17:24 +0100 |
| commit | fb23cf51040f06bfcfbaf318d7b452d76ffbedfb (patch) | |
| tree | c65bd96d3789cb8dd60e1f6baf7942a68528a84a | |
| parent | b7ec9a63ebf0895f9c1940772a5735f905cccfb8 (diff) | |
| download | jetpac.nes-fb23cf51040f06bfcfbaf318d7b452d76ffbedfb.tar.gz jetpac.nes-fb23cf51040f06bfcfbaf318d7b452d76ffbedfb.zip | |
Try to initialize enemies on unique Y coordinates
That is, our PRNG algorithm is so stupid that sometimes it cycles into
the same value multiple times. While play testing, sometimes we were so
unlucky that we got all enemies on the same Y screen coordinate.
As funny as these situations can be, this shouldn't happen, so I have
introduced an (awesomely named) function that makes a harder effort at
finding a unique random number.
Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
| -rw-r--r-- | .nasm/memory.txt | 3 | ||||
| -rw-r--r-- | .nasm/segments.txt | 2 | ||||
| -rw-r--r-- | src/enemies.s | 2 | ||||
| -rw-r--r-- | src/jetpac.s | 1 | ||||
| -rw-r--r-- | src/prng.s | 35 |
5 files changed, 40 insertions, 3 deletions
diff --git a/.nasm/memory.txt b/.nasm/memory.txt index 3603fc9..397a90b 100644 --- a/.nasm/memory.txt +++ b/.nasm/memory.txt @@ -16,6 +16,7 @@ $0E: zp_player_tile_waist $0F: zp_player_tile_bottom $10: zp_displayed $11: zp_timer +$12: zp_last_rand $20: zp_flags $21: zp_prev $22: zp_buttons @@ -80,4 +81,4 @@ $4016: m_joypad $4017: m_frame_counter --- Summary (in bytes) --- -- Internal RAM: 418/2048 (20.41%) +- Internal RAM: 419/2048 (20.46%) diff --git a/.nasm/segments.txt b/.nasm/segments.txt index 2c4877f..85c337d 100644 --- a/.nasm/segments.txt +++ b/.nasm/segments.txt @@ -1,4 +1,4 @@ - HEADER: 16/16 (100%) -- ROM0: 8253/32762 (25.19%) +- ROM0: 8276/32762 (25.26%) - ROMV: 6/6 (100%) - ROM2: 8192/8192 (100%) diff --git a/src/enemies.s b/src/enemies.s index 6201416..2208758 100644 --- a/src/enemies.s +++ b/src/enemies.s @@ -244,7 +244,7 @@ ;; The Y coordinate is also set at random within the bounds of the ;; playable screen. - jsr Prng::random_valid_y_coordinate + jsr Prng::random_non_repeated_valid_y_coordinate ldx Globals::zp_tmp0 inx sta Enemies::zp_pool_base, x diff --git a/src/jetpac.s b/src/jetpac.s index f99c8b0..3cf8f0a 100644 --- a/src/jetpac.s +++ b/src/jetpac.s @@ -130,6 +130,7 @@ sta Joypad::zp_prev sta Player::zp_state sta Items::zp_state + sta Prng::zp_last_rand ;; Initialize the level. We allow the build system to pass its own value for ;; this in `LEVEL`, just in case we want to debug the enemy of a specific @@ -9,6 +9,14 @@ ;; Current random value. Initialized on the title to game transition. zp_rand = $0A + ;; Last random value as stored by + ;; Prng::random_non_repeated_valid_y_coordinate(). + zp_last_rand = $12 + + ;; How many attempts should Prng::random_non_repeated_valid_y_coordinate() + ;; take to find a unique value. + RAND_ATTEMPTS = 3 + ;; Updates the 'a' register with the next random number set after the ;; current value of `zp_rand`, while also making sure that it is a valid ;; screen Y coordinate. @@ -21,6 +29,33 @@ sta zp_rand rts .endproc + + ;; Calls Prng::random_valid_y_coordinate() multiple times until we get a + ;; different value than what we got the last time we called this + ;; function. Realistically this should just take 1 attempt for most cases, + ;; and in the worst case just 2. Nevertheless, we have set a generous value + ;; to 'RAND_ATTEMPTS' just in case. + ;; + ;; NOTE: the 'y' register is preserved. + .proc random_non_repeated_valid_y_coordinate + tya + pha + ldy #RAND_ATTEMPTS + + @again: + jsr Prng::random_valid_y_coordinate + cmp Prng::zp_last_rand + bne @end + dey + bne @again + + @end: + sta Prng::zp_last_rand + pla + tay + lda Prng::zp_last_rand + rts + .endproc .endscope |
