Random Monitors - RetroKoH/S1Fixed GitHub Wiki

(Original guide by RetroKoH and Devon)
Source: Commits
Commit: 905faf0
This mod can be toggled in S1Fixed by setting RandomMonitors to 0 or 1.

In Sonic 2's 2 Player mode, monitors are randomized, with no hint of what you may receive until you break it open, due to the icon being replaced with a red question mark. Wouldn't it be fun to include that in Sonic 1 as an option? Of course it would! Let's give it a go!

First, go to _incObj/2E Monitor Content Power-Up.asm. We only need to add an include to a randomizer routine, and the call to said routine. At the very top of the file, above everything else, place this:

include		"_inc/Monitor Randomizer.asm"

Now, in Pow_Main, add a branch to this new routine we're about to add:

Pow_Main:	; Routine 0
	addq.b	#2,obRoutine(a0)
	move.w	#make_art_tile(ArtTile_Monitor,0,0),obGfx(a0)
	move.b	#$24,obRender(a0)
	move.b	#3,obPriority(a0)	; RetroKoH/Devon S3K+ Priority Manager
	move.b	#8,obActWid(a0)
	move.w	#-$300,obVelY(a0)
	moveq	#0,d0
-	move.b	obAnim(a0),d0		; get subtype

+	bsr.w	MonitorRandomizer	; give 'random' item

	addq.b	#2,d0
	move.b	d0,obFrame(a0)		; use correct frame
	movea.l	#Map_Monitor,a1

Now for the new routine. It should be noted that this randomizer is extremely basic, only making use of the built-in PRNG function. It isn't very good, and won't do much to vary results between playthroughs. A new randomizer is in the works. Anyway, here it is.

MonitorRandomizer:

	jsr	(RandomNumber).w	; call for random number

	; randomize monitor icon
	andi.l	#$FFFF,d0		; Make sure division will always work
	divu.w	#6,d0			; Divide by adjusted maximum number > #(MAX_NUM-MIN_NUM)+1,d0 MAX = 6; MIN = 1.
	swap	d0			; Get remainder of division
	addi.w	#1,d0			; Add minimum number

	move.b	d0,obAnim(a0)		; get subtype
	rts

If you've added S3K Shields, you'll want to tweak this slightly. Here's what I did to get random elemental shields included.

MonitorRandomizer:

	jsr	(RandomNumber).w	; call for random number

+	; Get random factor for elemental shield (1, 2, 3)
+	move.l	d0,d1
+	swap	d1
+	andi.l	#$FFFF,d1		; Make sure division will always work
+	divu.w	#3,d1			; Divide by adjusted maximum number > #(MAX_NUM-MIN_NUM)+1,d0 MAX = 3; MIN = 1.
+	swap	d1
+	; This time we won't add 1, giving us a range of 0-2

	; randomize monitor icon
	andi.l	#$FFFF,d0		; Make sure division will always work
	divu.w	#6,d0			; Divide by adjusted maximum number > #(MAX_NUM-MIN_NUM)+1,d0 MAX = 6; MIN = 1.
	swap	d0			; Get remainder of division
	addi.w	#1,d0			; Add minimum number

+	cmpi.b	#4,d0			; is this a shield?
+	bne.s	.skipcheck		; if not, skip and exit
		
	; Only include these lines for "stacking shields"
!	btst	#sta2ndShield,(v_player+obStatus2nd).w	; does Sonic already have a shield?
!	beq.s	.skipcheck				; if no, don't change it.
	
	; Set to elemental shield
+	move.b	#7,d0			; set to flame shield
+	add.b	d1,d0			; randomize elemental shields

+.skipcheck:
	move.b	d0,obAnim(a0)		; get subtype
	rts

More to come w/ art modifications soon.