Actions

SCHG How-to

Difference between revisions of "Set up the Goggle Monitor to work with it"

From Sonic Retro

m (Text replacement - "</asm>" to "</syntaxhighlight>")
m (Text replacement - "<asm>" to "<syntaxhighlight lang="asm">")
Line 5: Line 5:
  
 
Search for ''Obj2E_ChkS:'' and replace everything from there with this:
 
Search for ''Obj2E_ChkS:'' and replace everything from there with this:
<asm>Obj2E_ChkS:
+
<syntaxhighlight lang="asm">Obj2E_ChkS:
 
cmpi.b #7,d0 ; does monitor contain 'S'
 
cmpi.b #7,d0 ; does monitor contain 'S'
 
bne Obj2E_ChkGoggles ; if not, branch to Goggle code
 
bne Obj2E_ChkGoggles ; if not, branch to Goggle code
Line 20: Line 20:
  
 
First off, open ''sonic1.asm'' and go to the Routine for the monitor contents (Obj2E). Scroll down until you see this:
 
First off, open ''sonic1.asm'' and go to the Routine for the monitor contents (Obj2E). Scroll down until you see this:
<asm> ...
+
<syntaxhighlight lang="asm"> ...
 
Obj2E_RingSound:
 
Obj2E_RingSound:
 
move.w #$B5,d0
 
move.w #$B5,d0
Line 43: Line 43:
  
 
Before Obj2E_ChkEnd add a new label. The most fitting one is ''Obj2E_ChkGoggles:'' in my opinion:
 
Before Obj2E_ChkEnd add a new label. The most fitting one is ''Obj2E_ChkGoggles:'' in my opinion:
<asm>Obj2E_ChkS:
+
<syntaxhighlight lang="asm">Obj2E_ChkS:
 
cmpi.b #7,d0 ; does monitor contain 'S'
 
cmpi.b #7,d0 ; does monitor contain 'S'
 
bne Obj2E_ChkEnd
 
bne Obj2E_ChkEnd
Line 54: Line 54:
  
 
In ChkS is a code to branch to ChkEnd. Scroll up and you will see, there is in every monitor a code like this, but instead of branching to ChkEnd, they are branching to the next monitor code. So do the same with the S code. Change ''bne Obj2E_ChkEnd'' to ''bne Obj2E_ChkGoggles'':
 
In ChkS is a code to branch to ChkEnd. Scroll up and you will see, there is in every monitor a code like this, but instead of branching to ChkEnd, they are branching to the next monitor code. So do the same with the S code. Change ''bne Obj2E_ChkEnd'' to ''bne Obj2E_ChkGoggles'':
<asm>Obj2E_ChkS:
+
<syntaxhighlight lang="asm">Obj2E_ChkS:
 
cmpi.b #7,d0 ; does monitor contain 'S'
 
cmpi.b #7,d0 ; does monitor contain 'S'
 
bne Obj2E_ChkGoggles ; if not, branch to Goggle code
 
bne Obj2E_ChkGoggles ; if not, branch to Goggle code
Line 65: Line 65:
  
 
Okay, we've set a few things up, but we are not done yet. Maybe you've noticed with the last step, those 2 lines in each monitor at the beginning (a 'cmpi.b' code and a 'bne' code). They are there to check if that monitor was destroyed and if so, do the code under it, otherwise check for the next monitor. We need that for the goggle monitor as well, so copy any of these 2 lines to your ''Obj2E_ChkGoggles:'' label. I'm using the lines of ChkS:
 
Okay, we've set a few things up, but we are not done yet. Maybe you've noticed with the last step, those 2 lines in each monitor at the beginning (a 'cmpi.b' code and a 'bne' code). They are there to check if that monitor was destroyed and if so, do the code under it, otherwise check for the next monitor. We need that for the goggle monitor as well, so copy any of these 2 lines to your ''Obj2E_ChkGoggles:'' label. I'm using the lines of ChkS:
<asm>Obj2E_ChkS:
+
<syntaxhighlight lang="asm">Obj2E_ChkS:
 
cmpi.b #7,d0 ; does monitor contain 'S'
 
cmpi.b #7,d0 ; does monitor contain 'S'
 
bne Obj2E_ChkGoggles ; if not, branch to Goggle code
 
bne Obj2E_ChkGoggles ; if not, branch to Goggle code
Line 78: Line 78:
  
 
As you can see, this can't work, because they are checking for the same things! Look up again. Every monitor has a higher number in the cmpi.b command. The number in S was 7. So what is the next number? 8 of course! So change the 7 to 8 in your Goggle code:
 
As you can see, this can't work, because they are checking for the same things! Look up again. Every monitor has a higher number in the cmpi.b command. The number in S was 7. So what is the next number? 8 of course! So change the 7 to 8 in your Goggle code:
<asm>Obj2E_ChkS:
+
<syntaxhighlight lang="asm">Obj2E_ChkS:
 
cmpi.b #7,d0 ; does monitor contain 'S'
 
cmpi.b #7,d0 ; does monitor contain 'S'
 
bne Obj2E_ChkGoggles ; if not, branch to Goggle code
 
bne Obj2E_ChkGoggles ; if not, branch to Goggle code
Line 91: Line 91:
  
 
7: We are nearly done. The last thing we have to do is to change the bne command in your Goggle code to ChkEnd. Like this:
 
7: We are nearly done. The last thing we have to do is to change the bne command in your Goggle code to ChkEnd. Like this:
<asm>Obj2E_ChkS:
+
<syntaxhighlight lang="asm">Obj2E_ChkS:
 
cmpi.b #7,d0 ; does monitor contain 'S'
 
cmpi.b #7,d0 ; does monitor contain 'S'
 
bne Obj2E_ChkGoggles ; if not, branch to Goggle code
 
bne Obj2E_ChkGoggles ; if not, branch to Goggle code
Line 104: Line 104:
  
 
Now we're done, and you can insert code to run when you destroy a Goggle monitor. But if you don't wanna add code for now, you have to add a ''nop'' under the bne command, otherwise you will get an '''Illegal zero length branch''' error when building. Also, you should change the comments, because they are really misleading. Here is my finished code:
 
Now we're done, and you can insert code to run when you destroy a Goggle monitor. But if you don't wanna add code for now, you have to add a ''nop'' under the bne command, otherwise you will get an '''Illegal zero length branch''' error when building. Also, you should change the comments, because they are really misleading. Here is my finished code:
<asm>Obj2E_ChkS:
+
<syntaxhighlight lang="asm">Obj2E_ChkS:
 
cmpi.b #7,d0 ; does monitor contain 'S'
 
cmpi.b #7,d0 ; does monitor contain 'S'
 
bne Obj2E_ChkGoggles ; if not, branch to Goggle code
 
bne Obj2E_ChkGoggles ; if not, branch to Goggle code
Line 121: Line 121:
  
 
Go to the Goggle code and add a line, which is moving $1 to an unused RAM adress:
 
Go to the Goggle code and add a line, which is moving $1 to an unused RAM adress:
<asm> move.b #1,($FFFFFFA0).w ; move 1 to the goggle check</syntaxhighlight>
+
<syntaxhighlight lang="asm"> move.b #1,($FFFFFFA0).w ; move 1 to the goggle check</syntaxhighlight>
  
 
It should look like this:
 
It should look like this:
<asm> ...
+
<syntaxhighlight lang="asm"> ...
 
nop
 
nop
  
Line 136: Line 136:
  
 
Next go to to ''Obj0A_ReduceAir:'' and add these 2 lines right after the label:
 
Next go to to ''Obj0A_ReduceAir:'' and add these 2 lines right after the label:
<asm> tst.b ($FFFFFFFB).w ; was a goggle monitor broken?
+
<syntaxhighlight lang="asm"> tst.b ($FFFFFFFB).w ; was a goggle monitor broken?
 
bne Obj0A_GoMakeItem ; if yes, branch</syntaxhighlight>
 
bne Obj0A_GoMakeItem ; if yes, branch</syntaxhighlight>
  
 
It should look like this:
 
It should look like this:
<asm>Obj0A_ReduceAir:
+
<syntaxhighlight lang="asm">Obj0A_ReduceAir:
 
tst.b ($FFFFFFFB).w ; was a goggle monitor broken?
 
tst.b ($FFFFFFFB).w ; was a goggle monitor broken?
 
bne Obj0A_GoMakeItem ; if yes, branch
 
bne Obj0A_GoMakeItem ; if yes, branch

Revision as of 21:46, 20 December 2015

Did you know that there are 2 unused monitors in Sonic 1? The 'S' and 'Goggle' monitors. You can place and also destroy them, but nothing will happen. In the split is under "Obj2E_ChkS:" the code for the S monitor, but there is no code for the Goggle monitor! If you want to have that monitor to do something, you need to set it up first. It's not too hard, so I will explain it you step-by-step.

Quick guide

I know there are many people who just want to rip off the code without learning because they think they have better things to do. For those people I took the time to make a simple copy/paste guide:

Search for Obj2E_ChkS: and replace everything from there with this:

Obj2E_ChkS:
		cmpi.b	#7,d0		; does monitor contain 'S'
		bne	Obj2E_ChkGoggles		; if not, branch to Goggle code
		nop

Obj2E_ChkGoggles:	
		cmpi.b	#8,d0		; does monitor contain Goggles?
		bne	Obj2E_ChkEnd		; if not, branch to ChkEnd
		nop

That was everything. If you are too dumb to add/understand this, then you weren't reading the real guide.

Full guide

This version tells you how to do this in detail, and very well explained. It's not more than what you can see in the quick version, but with comments and explanations you can learn something, so this one is recommended.

First off, open sonic1.asm and go to the Routine for the monitor contents (Obj2E). Scroll down until you see this:

	...
Obj2E_RingSound:
		move.w	#$B5,d0
		jmp	(PlaySound).l	; play ring sound
; ===========================================================================

Obj2E_ChkS:
		cmpi.b	#7,d0		; does monitor contain 'S'
		bne	Obj2E_ChkEnd
		nop	

Obj2E_ChkEnd:
		rts			; 'S' and Goggles monitors do nothing
; ===========================================================================

Obj2E_Delete:				; XREF: Obj2E_Index
		subq.w	#1,$1E(a0)
		bmi.w	DeleteObject
		rts

As you can see, there is no Goggle Code. But there is code that checks if the monitor contains 'S'. However, you can open SonED2 and add a new monitor using the object editor. Scroll through the different monitors, and you will see, in Obj2E are the monitors in the same order as in SonED2. The Goggle monitor is the last monitor in this list. This means that you will have to add your new code under the code for the S.

Before Obj2E_ChkEnd add a new label. The most fitting one is Obj2E_ChkGoggles: in my opinion:

Obj2E_ChkS:
		cmpi.b	#7,d0		; does monitor contain 'S'
		bne	Obj2E_ChkEnd
		nop

Obj2E_ChkGoggles:	

Obj2E_ChkEnd:
		rts			; 'S' and Goggles monitors do nothing

In ChkS is a code to branch to ChkEnd. Scroll up and you will see, there is in every monitor a code like this, but instead of branching to ChkEnd, they are branching to the next monitor code. So do the same with the S code. Change bne Obj2E_ChkEnd to bne Obj2E_ChkGoggles:

Obj2E_ChkS:
		cmpi.b	#7,d0		; does monitor contain 'S'
		bne	Obj2E_ChkGoggles		; if not, branch to Goggle code
		nop

Obj2E_ChkGoggles:	

Obj2E_ChkEnd:
		rts			; 'S' and Goggles monitors do nothing

Okay, we've set a few things up, but we are not done yet. Maybe you've noticed with the last step, those 2 lines in each monitor at the beginning (a 'cmpi.b' code and a 'bne' code). They are there to check if that monitor was destroyed and if so, do the code under it, otherwise check for the next monitor. We need that for the goggle monitor as well, so copy any of these 2 lines to your Obj2E_ChkGoggles: label. I'm using the lines of ChkS:

Obj2E_ChkS:
		cmpi.b	#7,d0		; does monitor contain 'S'
		bne	Obj2E_ChkGoggles		; if not, branch to Goggle code
		nop

Obj2E_ChkGoggles:	
		cmpi.b	#7,d0		; does monitor contain 'S'
		bne	Obj2E_ChkGoggles		; if not, branch to Goggle code

Obj2E_ChkEnd:
		rts			; 'S' and Goggles monitors do nothing

As you can see, this can't work, because they are checking for the same things! Look up again. Every monitor has a higher number in the cmpi.b command. The number in S was 7. So what is the next number? 8 of course! So change the 7 to 8 in your Goggle code:

Obj2E_ChkS:
		cmpi.b	#7,d0		; does monitor contain 'S'
		bne	Obj2E_ChkGoggles		; if not, branch to Goggle code
		nop

Obj2E_ChkGoggles:	
		cmpi.b	#8,d0		; does monitor contain 'S'
		bne	Obj2E_ChkGoggles		; if not, branch to Goggle code

Obj2E_ChkEnd:
		rts			; 'S' and Goggles monitors do nothing

7: We are nearly done. The last thing we have to do is to change the bne command in your Goggle code to ChkEnd. Like this:

Obj2E_ChkS:
		cmpi.b	#7,d0		; does monitor contain 'S'
		bne	Obj2E_ChkGoggles		; if not, branch to Goggle code
		nop

Obj2E_ChkGoggles:	
		cmpi.b	#8,d0		; does monitor contain 'S'
		bne	Obj2E_ChkEnd		; if not, branch to Goggle code

Obj2E_ChkEnd:
		rts			; 'S' and Goggles monitors do nothing

Now we're done, and you can insert code to run when you destroy a Goggle monitor. But if you don't wanna add code for now, you have to add a nop under the bne command, otherwise you will get an Illegal zero length branch error when building. Also, you should change the comments, because they are really misleading. Here is my finished code:

Obj2E_ChkS:
		cmpi.b	#7,d0		; does monitor contain 'S'
		bne	Obj2E_ChkGoggles		; if not, branch to Goggle code
		nop

Obj2E_ChkGoggles:	
		cmpi.b	#8,d0		; does monitor contain Goggles?
		bne	Obj2E_ChkEnd		; if not, branch to ChkEnd
		nop

Obj2E_ChkEnd:
		rts

Example Code

Although that code is perfect now, it still does nothing. Unless you already have plans to do something with it, you can use this very simple code, that gives infinite air in LZ.

Go to the Goggle code and add a line, which is moving $1 to an unused RAM adress:

		move.b	#1,($FFFFFFA0).w ; move 1 to the goggle check

It should look like this:

		...
		nop

Obj2E_ChkGoggles:	
		cmpi.b	#8,d0		; does monitor contain Goggles?
		bne	Obj2E_ChkEnd		; if not, branch to ChkEnd
		move.b	#1,($FFFFFFFB).w ; move 1 to the goggle check

Obj2E_ChkEnd:
		...

Next go to to Obj0A_ReduceAir: and add these 2 lines right after the label:

		tst.b	($FFFFFFFB).w	; was a goggle monitor broken?
		bne	Obj0A_GoMakeItem	; if yes, branch

It should look like this:

Obj0A_ReduceAir:
		tst.b	($FFFFFFFB).w	; was a goggle monitor broken?
		bne	Obj0A_GoMakeItem	; if yes, branch
		...

This is not a perfect code, because you will ALWAYS have infinite time underwater once you destroy the monitor, but it works.

SCHG How-To Guide: Sonic the Hedgehog (16-bit)
Fixing Bugs
Fix Demo Playback | Fix a Race Condition with Pattern Load Cues | Fix the SEGA Sound | Display the Press Start Button Text | Fix the Level Select Menu | Fix the Hidden Points Bug | Fix Accidental Deletion of Scattered Rings | Fix Ring Timers | Fix the Walk-Jump Bug | Correct Drowning Bugs | Fix the Death Boundary Bug | Fix the Camera Follow Bug | Fix Song Restoration Bugs | Fix the HUD Blinking | Fix the Level Select Graphics Bug | Fix a remember sprite related bug
Changing Design Choices
Change Spike Behavior | Collide with Water After Being Hurt | Fix Special Stage Jumping Physics | Improve the Fade In\Fade Out Progression Routines | Fix Scattered Rings' Underwater Physics | Remove the Speed Cap | Port the REV01 Background Effects | Port Sonic 2's Level Art Loader | Retain Rings Between Acts | Add Sonic 2 (Simon Wai Prototype) Level Select | Improve ObjectMove Subroutines | Port Sonic 2 Level Select
Adding Features
Add Spin Dash ( Part 1 / Part 2 / Part 3 / Part 4 ) | Add Eggman Monitor | Add Super Sonic | Add the Air Roll
Sound Features
Expand the Sound Index | Play Different Songs Per Act | Port Sonic 2 Final Sound Driver | Port Sonic 3's Sound Driver | Port Flamewing's Sonic 3 & Knuckles Sound Driver | Change The SEGA Sound
Extending the Game
Load Chunks From ROM | Add Extra Characters | Make an Alternative Title Screen | Use Dynamic Tilesets | Make GHZ Load Alternate Art | Make Ending Load Alternate Art | Add a New Zone | Set Up the Goggle Monitor | Add New Moves | Add a Dynamic Collision System | Dynamic Special Stage Walls System | Extend Sprite Mappings and Art Limit | Enigma Credits | Use Dynamic Palettes
Miscellaneous
Convert the Hivebrain 2005 Disassembly to ASM68K
Split Disassembly Guides
Set Up a Split Disassembly | Basic Level Editing | Basic Art Editing | Basic ASM Editing (Spin Dash)