Reimplementing Unused Monitors - RetroKoH/S1Fixed GitHub Wiki

(Original guides, sources, and commits noted in each section)

There are three monitor types that go unused throughout the entirety of Sonic 1 (4 if you count the static monitor). They are the Eggman, 'S', and Goggles monitors. The exact intended use of these monitors at the time of development is unknown, but based on later entries in the series, we can come to some conclusion as to how they may have been used, as well as how to best use them if reimplemented into Sonic 1.

Eggman Monitor

Commit: eb67773
You might take one look at this monitor and assume that it would harm you if broken, serving as an opposite of sorts to the Sonic monitor. According to one of the original game's developers, Dean Sutton, it waa never meant to have an actual function, instead only serving as a breakable warning sign. Seeing as how this monitor DOES damage Sonic in the Taxman remakes, as well as in the original Sonic 2's 2P Mode, and throughout Sonic 3K, it makes sense to implement that functionality here too. Here is what the code for the Eggman monitor looks like in stock Sonic 1:

Pow_Checks:
	addq.b	#2,obRoutine(a0)
	move.w	#29,obTimeFrame(a0) ; display icon for half a second

Pow_ChkEggman:
	move.b	obAnim(a0),d0
	cmpi.b	#1,d0	; does monitor contain Eggman?
	bne.s	Pow_ChkSonic
	rts	; does nothing

As you can see, if the monitor sports an Eggman monitor, we get stopped by an rts instruction, which exits the code and renders the monitor icon useless. Obviously we will replace it with code that will hurt Sonic. We have two options.

Option 1: Call HurtSonic Check

(Nineko)
The first is to call the standard HurtSonic routine. To do that, we must reassign the first two address registers and call a check to see if Sonic should be hurt.

Pow_Checks:
	addq.b	#2,obRoutine(a0)
	move.w	#29,obTimeFrame(a0) ; display icon for half a second

Pow_ChkEggman:
	move.b	obAnim(a0),d0
	cmpi.b	#1,d0	; does monitor contain Eggman?
	bne.s	Pow_ChkSonic
+	move.l	a0,a1	; move a0 to a1, because Touch_ChkHurt wants the damaging object to be in a1
+	move.l	a0,-(sp) ; push a0 on the stack, and decrement stack pointer
+	lea	(v_player).w,a0		; put Sonic's ram address in a0, because Touch_ChkHurt wants the damaged object to be in a0
+	jsr	(React_ChkHurt).l	; run the Touch_ChkHurt routine
+	move.l	(sp)+,a0	; pop the previous value of a0 from the stack, and increment stack pointer
	rts

Option 2: Call Spike Hurt Check

(AlexShx)
This is a simpler check that accomplishes the same thing (though I want to test this at some point). All we do is change the last line, that old rts:

Pow_Checks:
	addq.b	#2,obRoutine(a0)
	move.w	#29,obTimeFrame(a0) ; display icon for half a second

Pow_ChkEggman:
	move.b	obAnim(a0),d0
	cmpi.b	#1,d0	; does monitor contain Eggman?
	bne.s	Pow_ChkSonic
!	bra.w	Spik_Hurt  ; Eggman monitor hurts Sonic

S Monitor

(RetroKoH)
Once again, we have a monitor type that saw use in later games, albeit exclusively in each game's Debug Mode. Like the Eggman monitor, its effect was also applied to Sonic 1 in the remake. So let's d- ... wait, what was its effect again? Oh, Super Sonic. Well then, it seems you'll need to apply one of the Elective Mods for this to work. But fear not, this guide will also provide an alternative, should you decide not to implement Super Sonic.

Pseudo-Super Sonic

This code gives us a temporary "pseudo" Super Sonic, by granting invincibility stars AND Speed Shoes simultaneously. This effect is actually what the S monitor did in the Sonic CD 510 Prototype, so there is precedence for this. I also added the same check to grant an extra life with enough rings, AND cap rings at 999, like before.

	addi.w	#50,(v_rings).w
	bsr.w	Pow_Invinc
	bsr.w	Pow_Shoes

	ori.b	#1,(f_ringcount).w	; update the ring counter
	cmpi.w	#100,(v_rings).w	; check if you have 100 rings
	blo.s	Pow_RingSound
	bset	#1,(v_lifecount).w
	beq.w	ExtraLife
	cmpi.w	#200,(v_rings).w	; check if you have 200 rings
	blo.s	Pow_RingSound
	bset	#2,(v_lifecount).w
	beq.w	ExtraLife

You'll notice I called two other Powerups as subroutines. The ability to do this will require a rework to the Monitor Icon object that I will provide a guide for later.

Proper Super Sonic

This code is inspired by the sequel games' code for this monitor, but I once again added a check to grant an extra life with enough rings, AND cap rings at 999, so as to avoid breaking the HUD.

Pow_S:
	addi.w	#50,(v_rings).w
	movem.l a0-a2,-(sp)		; Move a0, a1 and a2 onto stack
	lea     (v_player).w,a0		; Load Sonic to a0
	jsr	Sonic_TurnSuper		; turn super
	movem.l (sp)+,a0-a2		; Move a0, a1 and a2 from stack

	ori.b	#1,(f_ringcount).w	; update the ring counter
	cmpi.w	#100,(v_rings).w	; check if you have 100 rings
	blo.s	Pow_RingSound
	bset	#1,(v_lifecount).w
	beq.w	ExtraLife
	cmpi.w	#200,(v_rings).w	; check if you have 200 rings
	blo.s	Pow_RingSound
	bset	#2,(v_lifecount).w
	beq.w	ExtraLife

Goggles Monitor

(RetroKoH)
The final monitor we will implement is one seen in the Taxman remakes only in Labyrinth Zone's Debug Mode Object listings, so it is indeed a rare sight to behold. In that game, breaking the monitor would grant Sonic a pair of goggles adorned over his face, which also functioned as a Shield. The aforementioned Dean Sitton explained that, similar to the Eggman monitor, the Goggles were purely cosmetic, and the monitor was only meant to warn players of upcoming underwater sections. For simplicity's sake, that's all we'll be doing here.

Here is the code to create a Goggles object upon breaking the monitor:

	; (Optional) Set a flag to give Sonic goggles here
	move.b	#id_GogglesItem,(v_gogglesobj).w	; load goggles object
	move.w	#sfx_A2,d0
	jmp	(PlaySound).w				; play sound

We will need to add the Goggles Object, get the art loaded into VRAM, and create mappings (possibly DPLCs) for them as well. I'll continue this guide later. SFX $A2 is an unused sound I put in as a placeholder. Feel free to change it to whatever you'd like.