aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.nasm/memory.txt3
-rw-r--r--.nasm/segments.txt2
-rw-r--r--src/enemies.s2
-rw-r--r--src/jetpac.s1
-rw-r--r--src/prng.s35
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
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