aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMiquel Sabaté Solà <mssola@mssola.com>2026-03-20 21:52:36 +0100
committerMiquel Sabaté Solà <mssola@mssola.com>2026-03-22 15:17:24 +0100
commitfb23cf51040f06bfcfbaf318d7b452d76ffbedfb (patch)
treec65bd96d3789cb8dd60e1f6baf7942a68528a84a /src
parentb7ec9a63ebf0895f9c1940772a5735f905cccfb8 (diff)
downloadjetpac.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>
Diffstat (limited to 'src')
-rw-r--r--src/enemies.s2
-rw-r--r--src/jetpac.s1
-rw-r--r--src/prng.s35
3 files changed, 37 insertions, 1 deletions
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
diff --git a/src/prng.s b/src/prng.s
index c5ec474..7aa313a 100644
--- a/src/prng.s
+++ b/src/prng.s
@@ -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