Sonic and Sega Retro Message Board: Some changes/fixes for Sonic 1 - Sonic and Sega Retro Message Board

Jump to content

Hey there, Guest!  (Log In · Register) Help
  • 7 Pages +
  • 1
  • 2
  • 3
  • Last ►
    Locked
    Locked Forum

Some changes/fixes for Sonic 1

#1 User is offline KingofHarts 

Posted 04 September 2012 - 09:38 AM

  • Posts: 1609
  • Joined: 07-August 10
  • Gender:Male
  • Project:Project Sonic 8x16
  • Wiki edits:1
EDIT: I have added to this, below. We are now covering many previously unseen changes/fixes, and edits to currently known fixes/changes.
I've created a mod to prevent score padding via dying... you know, rack up a nice score, and kill yourself to continue from before and snag more points.
I'm sure it's not something everyone does... and probably sounds like a silly thing to consider, but I have, and have prevented such a thing from happening.

Basically I added a variable that stores the score at the start of the game and after a level/Special Stage and when you die, at a check point or not, it will reset to this value. Newer Sonic games do this (except they only store individual level values so it works slightly differently, but same principle that I'm working under). It works to punish players for failing.

My question is would this be a mod anyone would like to see? If so I will share it.

ALSO I'm looking into modding Monitor behavior to prevent dying and padding the lives counter much the same way (die and go back to get the life monitor(s)) by changing their subtype to a ring monitor.

Would anything like this be appealing or interesting at all to anyone?
This post has been edited by KingofHarts: 20 November 2013 - 08:46 AM

#2 User is offline Ravenfreak 

Posted 04 September 2012 - 10:46 AM

  • Posts: 2654
  • Joined: 24-November 08
  • Gender:Male
  • Location:O'Fallon Mo
  • Project:Hacking some 8-bit Sonic game
  • Wiki edits:112
I personally think the second one it's a cool concept, but not really the concept you've already coded in. :\ I'm just not too keen on punishing the player for dying, but then again it's the classic games and I'm sure most of us on here don't die that often while playing the games if not at all. Also wouldn't this be better in the E/RE forum? Since after all, you're hacking a rom. xP

#3 User is offline Endri 

Posted 04 September 2012 - 11:25 AM

  • Officer I don't have my drivers license with me. Can I give you something else?
  • Posts: 1871
  • Joined: 18-November 08
  • Gender:Male
  • Location:São Paulo, Brazil
  • Wiki edits:7

View PostRavenfreak, on 04 September 2012 - 10:46 AM, said:

Also wouldn't this be better in the E/RE forum? Since after all, you're hacking a rom. xP
Precisely.

Actually, I apply both of these concepts in my fangame. In fact, there's only one 1up Monitor in each act, and the object is pretty much hidden. I would also recommend to, instead of changing the subtype of the Monitor to a Super Rings Monitor after restarting the level (if said monitor was already broken by the player), simply set the object status to "broken" upon initialization.

Another thing I do is to prevent, using your terms, "Time Padding." For example, if the player hit the furthest Star Post in the level, and, intentionally, perform a Time Over to make the Time reset to 0:00, so them can finish the level with the most absurd low times possible. Quite simple to solve, also: during the score tally, check if the Time Over flag is set, and, if it is, set the Time Bonus to 0.

#4 User is offline KingofHarts 

Posted 04 September 2012 - 07:09 PM

  • Posts: 1609
  • Joined: 07-August 10
  • Gender:Male
  • Project:Project Sonic 8x16
  • Wiki edits:1

View PostEndri, on 04 September 2012 - 11:25 AM, said:

View PostRavenfreak, on 04 September 2012 - 10:46 AM, said:

Also wouldn't this be better in the E/RE forum? Since after all, you're hacking a rom. xP
Precisely.

Actually, I apply both of these concepts in my fangame. In fact, there's only one 1up Monitor in each act, and the object is pretty much hidden. I would also recommend to, instead of changing the subtype of the Monitor to a Super Rings Monitor after restarting the level (if said monitor was already broken by the player), simply set the object status to "broken" upon initialization.

Another thing I do is to prevent, using your terms, "Time Padding." For example, if the player hit the furthest Star Post in the level, and, intentionally, perform a Time Over to make the Time reset to 0:00, so them can finish the level with the most absurd low times possible. Quite simple to solve, also: during the score tally, check if the Time Over flag is set, and, if it is, set the Time Bonus to 0.


I didn't think of that at all... and now plan on implementing this. Awesome stuff.

#5 User is offline KingofHarts 

Posted 04 September 2012 - 07:44 PM

  • Posts: 1609
  • Joined: 07-August 10
  • Gender:Male
  • Project:Project Sonic 8x16
  • Wiki edits:1

View PostRavenfreak, on 04 September 2012 - 10:46 AM, said:

I personally think the second one it's a cool concept, but not really the concept you've already coded in. :\ I'm just not too keen on punishing the player for dying, but then again it's the classic games and I'm sure most of us on here don't die that often while playing the games if not at all. Also wouldn't this be better in the E/RE forum? Since after all, you're hacking a rom. xP


I guess that is a difference of preference :)

And I didn't post in ERE with this because I haven't really posted anything of merit... YET. Only a concept. I'll put some code up when all is finished then maybe it can be moved later.

#6 User is offline Endri 

Posted 04 September 2012 - 10:44 PM

  • Officer I don't have my drivers license with me. Can I give you something else?
  • Posts: 1871
  • Joined: 18-November 08
  • Gender:Male
  • Location:São Paulo, Brazil
  • Wiki edits:7

View PostKingofHarts, on 04 September 2012 - 07:44 PM, said:

I guess that is a difference of preference :)

And I didn't post in ERE with this because I haven't really posted anything of merit... YET. Only a concept. I'll put some code up when all is finished then maybe it can be moved later.
In the end of the day, these are not really fixes; they are more design decisions. Because: 1)a unexperienced player wouldn't risk attemping any of these "exploits" in the first place; 2)only a experienced player would figure out that these exploits are possible, and would be able to successfully put them into practice; 3)it all boils down to if you want to remove the exploits and punish the unexperienced players, or, if you want to just leave the exploits there and reward the experienced players.

That being said, that is why I recommeded you to not transform the already-used 1up Monitors into Super Ring Monitors, because you would eventually end up making room for more exploits (say that you designed a level that has just 190 rings exactly... if the player grabs the 1up Monitor and die purposefully, now he has the chance to get 200 rings instead, and earn an extra life for these 200 rings).

Oh, which just reminded me, you probably don't want the 100 and 200 rings extra lives flags to be reseted when the player dies, otherwise, the player would still be able to "pad" the number of life: grab 200 rings, earn 2 extra lives, die, grab 200 rings, earn 2 extra lives, die, rinse and repeat. You could clear the rings lives flags only in the part of the level initiation code that is run only when the level is not started from a Star Post. This would solve the problem.

#7 User is offline KingofHarts 

Posted 05 September 2012 - 01:41 AM

  • Posts: 1609
  • Joined: 07-August 10
  • Gender:Male
  • Project:Project Sonic 8x16
  • Wiki edits:1

View PostEndri, on 04 September 2012 - 10:44 PM, said:

View PostKingofHarts, on 04 September 2012 - 07:44 PM, said:

I guess that is a difference of preference :)

And I didn't post in ERE with this because I haven't really posted anything of merit... YET. Only a concept. I'll put some code up when all is finished then maybe it can be moved later.
In the end of the day, these are not really fixes; they are more design decisions. Because: 1)a unexperienced player wouldn't risk attemping any of these "exploits" in the first place; 2)only a experienced player would figure out that these exploits are possible, and would be able to successfully put them into practice; 3)it all boils down to if you want to remove the exploits and punish the unexperienced players, or, if you want to just leave the exploits there and reward the experienced players.

That being said, that is why I recommeded you to not transform the already-used 1up Monitors into Super Ring Monitors, because you would eventually end up making room for more exploits (say that you designed a level that has just 190 rings exactly... if the player grabs the 1up Monitor and die purposefully, now he has the chance to get 200 rings instead, and earn an extra life for these 200 rings).

Oh, which just reminded me, you probably don't want the 100 and 200 rings extra lives flags to be reseted when the player dies, otherwise, the player would still be able to "pad" the number of life: grab 200 rings, earn 2 extra lives, die, grab 200 rings, earn 2 extra lives, die, rinse and repeat. You could clear the rings lives flags only in the part of the level initiation code that is run only when the level is not started from a Star Post. This would solve the problem.


Damn... First off, you're right. the term fix was wrong in this case.
Second, another idea I didn't think of with the 100/200 rings thing. I'm loving it.
Third... I'll do you one better. Broken monitors are a tad inconsistent given that nothing is broken when returning... how about instead of those, OR rings, they are empty static monitors.

:)

#8 User is offline Aesculapius Piranha 

Posted 05 September 2012 - 05:05 AM

  • つづく
  • Posts: 4053
  • Joined: 14-March 08
  • Gender:Male
  • Location:Unknown
  • Project:Diva
  • Wiki edits:6
Really I think the monitor thing isn't an issue for the experienced, because what player is going to rack up lives like that if they are experienced enough not to need them? That is a change to prevent n00bs from building cushion.

The first isn't an issue for the experienced either per say. It's more an issue for the niche that goes for score attacks versus everyone else.
This post has been edited by Aesculapius Piranha: 05 September 2012 - 05:08 AM

#9 User is offline KingofHarts 

Posted 05 September 2012 - 05:08 AM

  • Posts: 1609
  • Joined: 07-August 10
  • Gender:Male
  • Project:Project Sonic 8x16
  • Wiki edits:1
I'm just looking for something to do. In the right type of hack, this would be a good thing to implement. In a standard Sonic 1, it's not that big of a deal. But I'm looking at practicing and learning more about how to hack, so I'm trying my hand at implementing different things just for the hell of it, and for experience. And since I didn't recall seeing these implemented, I thought... why not share my thoughts.


SPEAKING OF WHICH... I have bumped into a coding problem, and perhaps we have started to reach the point where this COULD be moved to ERE, but I'm posting the question here as it is in direct relation to the current topic.

I have attempted to edit the Level Select selection code, to make it reset these certain variables when selecting from level select...
If one plays through a game, and either finishes or get Game Over, and then comes back via Level Select, Not everything is cleared correctly. I have added the move codes necessary... take a look

LevSel_Level_SS:			; XREF: LevelSelect
		add.w	d0,d0
		move.w	LevSel_Ptrs(pc,d0.w),d0 ; load level number ; ERROR VALUE <--------------------------------
		bmi.w	LevelSelect
		cmpi.w	#id_SS*$100,d0	; check	if level is 0700 (Special Stage)
		bne.s	LevSel_Level	; if not, branch
		move.b	#id_Special,(v_gamemode).w ; set screen mode to $10 (Special Stage)
		clr.w	(v_zone).w	; clear	level
		move.b	#3,(v_lives).w	; set lives to 3
		moveq	#0,d0
		move.w	d0,(v_rings).w	; clear rings
		move.l	d0,(v_time).w	; clear time
		move.l	d0,(v_score).w	; clear score
		; KingofHarts Level Select Mod
		;move.l  d0,(v_startscore).w ; clear start score
		;move.b	d0,(v_lastspecial).w ; clear special stage number
		;move.b	d0,(v_emeralds).w ; clear emeralds
		;move.l	d0,(v_emldlist).w ; clear emeralds
		;move.l	d0,(v_emldlist+4).w ; clear emeralds
		;move.b	d0,(v_continues).w ; clear continues
		; end of mod
		move.l	#5000,(v_scorelife).w ; extra life is awarded at 50000 points
  		rts



and for the other part, selecting a normal level, it has more of the clears...
LevSel_Level:				; XREF: LevSel_Level_SS
		andi.w	#$3FFF,d0
		move.w	d0,(v_zone).w	; set level number

PlayLevel:
		move.b	#id_Level,(v_gamemode).w ; set screen mode to $0C (level)
		move.b	#3,(v_lives).w	; set lives to 3
		moveq	#0,d0
		move.w	d0,(v_rings).w	; clear rings
		move.l	d0,(v_time).w	; clear time
		move.l	d0,(v_score).w	; clear score
		; KingofHarts Level Select Mod
		;move.l  d0,(v_startscore).w ; clear start score
		move.b	d0,(v_lastspecial).w ; clear special stage number
		move.b	d0,(v_emeralds).w ; clear emeralds
		move.l	d0,(v_emldlist).w ; clear emeralds
		move.l	d0,(v_emldlist+4).w ; clear emeralds
		move.b	d0,(v_continues).w ; clear continues
		move.l	#5000,(v_scorelife).w ; extra life is awarded at 50000 points
		move.b	#$E0,d0
		bsr.w	PlaySound_Special ; fade out music
		rts




I have commented out my Level Select mods for a reason. Implementing them in the code causes a build error, stating "Illegal Value"
Now with all of these implemented, that value comes out to 152. Using less lines of mine, results in a smaller value, the smallest being 128.

The line in question is the one I marked ERROR VALUE.

Any reason why this could be?
EDIT: Disregard this, I simply moved the level select table closer to the instruction calling it. I think it did the trick.
This post has been edited by KingofHarts: 05 September 2012 - 06:45 PM

#10 User is offline Endri 

Posted 06 September 2012 - 02:05 PM

  • Officer I don't have my drivers license with me. Can I give you something else?
  • Posts: 1871
  • Joined: 18-November 08
  • Gender:Male
  • Location:São Paulo, Brazil
  • Wiki edits:7

View PostKingofHarts, on 05 September 2012 - 05:08 AM, said:

EDIT: Disregard this, I simply moved the level select table closer to the instruction calling it. I think it did the trick.
Ah, okay then, because the code itself you posted is fine. If you use too great jump distances, misname the calling of a routine label or put data tables too far from where you call them, while building you will pretty much receive errors coming out of everywhere inside the code.

The only thing I'm missing in your code is the:
		move.w	(Level_select_zone).w,d0

right before:
		add.w	d0,d0

on the LevSel_Level_SS routine (the address costant is called Level_select_zone in the Mercurial disassembly; I don't remember the name of the equivalent constant in your disassembly).

By the way, I highly recommend the use of the Mercurial disasm (the subroutines and macros are way more commented and explained, and everything is far more organized). So organized, in fact, that you can move things around and still make a perfectly working build. It probably should give less readaches.

#11 User is offline KingofHarts 

Posted 06 September 2012 - 07:01 PM

  • Posts: 1609
  • Joined: 07-August 10
  • Gender:Male
  • Project:Project Sonic 8x16
  • Wiki edits:1

View PostEndri, on 06 September 2012 - 02:05 PM, said:

View PostKingofHarts, on 05 September 2012 - 05:08 AM, said:

EDIT: Disregard this, I simply moved the level select table closer to the instruction calling it. I think it did the trick.
Ah, okay then, because the code itself you posted is fine. If you use too great jump distances, misname the calling of a routine label or put data tables too far from where you call them, while building you will pretty much receive errors coming out of everywhere inside the code.

The only thing I'm missing in your code is the:
		move.w	(Level_select_zone).w,d0

right before:
		add.w	d0,d0

on the LevSel_Level_SS routine (the address costant is called Level_select_zone in the Mercurial disassembly; I don't remember the name of the equivalent constant in your disassembly).

By the way, I highly recommend the use of the Mercurial disasm (the subroutines and macros are way more commented and explained, and everything is far more organized). So organized, in fact, that you can move things around and still make a perfectly working build. It probably should give less readaches.

I do have the Mercurial. Unless I had inadvertently changed a name somewhere, I think mine should be the same, if not... at least similar.
BTW I don't have that code in either my code or the Mercurial disasm. And... while I've messed with my disassembly, I know for a fact I have changed ZERO with the Mercurial.




View PostEndri, on 04 September 2012 - 11:25 AM, said:

Another thing I do is to prevent, using your terms, "Time Padding." For example, if the player hit the furthest Star Post in the level, and, intentionally, perform a Time Over to make the Time reset to 0:00, so them can finish the level with the most absurd low times possible. Quite simple to solve, also: during the score tally, check if the Time Over flag is set, and, if it is, set the Time Bonus to 0.



Also I wanted to ask about this. Is there another Time Over flag... or something you are referring to? f_timeover returns to 0 after the zone restarts from a Time Over. I've thought about stopping it from doing that, to implement this change, but woldn't that mess stuff up?

#12 User is offline Endri 

Posted 07 September 2012 - 10:18 PM

  • Officer I don't have my drivers license with me. Can I give you something else?
  • Posts: 1871
  • Joined: 18-November 08
  • Gender:Male
  • Location:São Paulo, Brazil
  • Wiki edits:7
Oh, I just noticed that you were actually working with the Sonic 1 disasm. For some reason, I assumed you were working with Sonic 2! That's why the routines and constants have different names. :specialed:

View PostKingofHarts, on 06 September 2012 - 07:01 PM, said:

Also I wanted to ask about this. Is there another Time Over flag... or something you are referring to? f_timeover returns to 0 after the zone restarts from a Time Over. I've thought about stopping it from doing that, to implement this change, but woldn't that mess stuff up?
If you do that, what will happen is that, everytime you die, the Time Over object is gonna be called! :v:

You can do the following: when the level restarts from a Time Over, instead of setting the flag to 0, set it to $FF. Now, any function that tst.b (f_timeover).w branches with either a beq.s or bne.s. Change these bne.s to bpl.s (so the functions will only branch if the Time Over flag is 1 or higher). In your code to clear the time bonus if the character had a Time Over, you'll branch with a bmi.s (branch if the Time Over flag is -1 or lower, in this case, $FF).

That's about it.

#13 User is offline KingofHarts 

Posted 08 September 2012 - 05:26 AM

  • Posts: 1609
  • Joined: 07-August 10
  • Gender:Male
  • Project:Project Sonic 8x16
  • Wiki edits:1

View PostEndri, on 07 September 2012 - 10:18 PM, said:

Oh, I just noticed that you were actually working with the Sonic 1 disasm. For some reason, I assumed you were working with Sonic 2! That's why the routines and constants have different names. :specialed:

View PostKingofHarts, on 06 September 2012 - 07:01 PM, said:

Also I wanted to ask about this. Is there another Time Over flag... or something you are referring to? f_timeover returns to 0 after the zone restarts from a Time Over. I've thought about stopping it from doing that, to implement this change, but woldn't that mess stuff up?
If you do that, what will happen is that, everytime you die, the Time Over object is gonna be called! :v:

You can do the following: when the level restarts from a Time Over, instead of setting the flag to 0, set it to $FF. Now, any function that tst.b (f_timeover).w branches with either a beq.s or bne.s. Change these bne.s to bpl.s (so the functions will only branch if the Time Over flag is 1 or higher). In your code to clear the time bonus if the character had a Time Over, you'll branch with a bmi.s (branch if the Time Over flag is -1 or lower, in this case, $FF).

That's about it.

That's quite alright Endri. I am also working with Sonic 2 (and 3, actually) as well, just not at this particular moment, though I plan on making the SAME additions to Sonic 2 REV C in the future, so I will bear this in mind... and I will try the thing with the Time Over.
Also that means I will need to add an extra instruction(s) to reset f_timeover from FF to 0 as well in other areas, correct?
This post has been edited by KingofHarts: 08 September 2012 - 05:28 AM

#14 User is offline Endri 

Posted 08 September 2012 - 06:30 PM

  • Officer I don't have my drivers license with me. Can I give you something else?
  • Posts: 1871
  • Joined: 18-November 08
  • Gender:Male
  • Location:São Paulo, Brazil
  • Wiki edits:7

View PostKingofHarts, on 08 September 2012 - 05:26 AM, said:

Also that means I will need to add an extra instruction(s) to reset f_timeover from FF to 0 as well in other areas, correct?
Not necessary, because any object which tries to reset f_timeover will do so with either a move.b #0,(f_timeover).w, clr.b (f_timeover).w, or moveq #0,d0 > move.b d0,(f_timeover).w. In other words, they all set the time over flag to 0 no matter what was the previous value of f_timeover. What you have to do, however, is to make sure to only set f_timeover to 0 if the value is positive when restarting from a checkpoint, otherwise it will wipe out your $FF.
For example:
	Level_SkipClr:
		tst.b	(f_timeover).w	; <<<<<<<<<<<<<<<<<<<<<<<<< test the time over flag
		bmi.s	@skiptimeclear		; <<<<<<<<<<<<<<<<<<<<<<<<< if negative, branch
		move.b	d0,(f_timeover).w
	@skiptimeclear:
		move.b	d0,(v_shield).w	; clear shield
		move.b	d0,(v_invinc).w	; clear invincibility
		move.b	d0,(v_shoes).w	; clear speed shoes
		move.b	d0,($FFFFFE2F).w
	...


and, in Sonic (part 2).asm:
GameOver:
	...
	loc_138D4:
		move.w	#60,$3A(a0)	; set time delay to 1 second
		tst.b	(f_timeover).w	; is TIME OVER tag set?
		beq.s	locret_13900	; if not, branch
		bmi.s	locret_13900	; <<<<<<<<<<<<<<<<<<<<<<<<<< if negative, also branch
		move.b	#$FF,(f_timeover).w ; <<<<<<<<<<<<<<<<<<<<<< set the flag to -1
		move.w	#0,$3A(a0)
		move.b	#$39,(v_objspace+$80).w ; load TIME object
		move.b	#$39,(v_objspace+$C0).w ; load OVER object
		move.b	#2,(v_objspace+$80+obFrame).w
		move.b	#3,(v_objspace+$C0+obFrame).w
		bra.s	loc_138C2
	...


and, in Object 0D Signpost:
GotThroughAct:
	...
	@hastimebonus:
		add.w	d0,d0
		move.w	TimeBonuses(pc,d0.w),(v_timebonus).w ; set time bonus
		tst.b	(f_timeover).w	; <<<<<<<<<<<<<<<<<<<<<<<< is the TIME OVER flag set?
		beq.s	@skiptimebonusclear		; <<<<<<<<<<<<<<<<<<<<<<<< if not, branch
		clr.w	(v_timebonus).w ; <<<<<<<<<<<<<<< set Time Bonus to 0
		clr.b	(f_timeover).w ; <<<<<<<<<<<<<<< reset TIME OVER flag back to 0
	@skiptimebonusclear:
		move.w	(v_rings).w,d0	; load number of rings
		mulu.w	#10,d0		; multiply by 10
	...


This is the general idea. Though, since you are working with Sonic 1, you could create a new variable for doing that, since there are more free RAM areas in Sonic 1 than there are for the other games. I suggested the approach of using the same variable for this purpose because I had Sonic 2 in mind at the time.

By the way, I just remembered that Rev 00 of Sonic 1 doesn't reset the time when you die from a Time Over anyways.
This post has been edited by Endri: 08 September 2012 - 10:15 PM

#15 User is offline KingofHarts 

Posted 08 September 2012 - 10:43 PM

  • Posts: 1609
  • Joined: 07-August 10
  • Gender:Male
  • Project:Project Sonic 8x16
  • Wiki edits:1

View PostEndri, on 08 September 2012 - 06:30 PM, said:

View PostKingofHarts, on 08 September 2012 - 05:26 AM, said:

Also that means I will need to add an extra instruction(s) to reset f_timeover from FF to 0 as well in other areas, correct?
Not necessary, because any object which tries to reset f_timeover will do so with either a move.b #0,(f_timeover).w, clr.b (f_timeover).w, or moveq #0,d0 > move.b d0,(f_timeover).w. In other words, they all set the time over flag to 0 no matter what was the previous value of f_timeover. What you have to do, however, is to make sure to only set f_timeover to 0 if the value is positive when restarting from a checkpoint, otherwise it will wipe out your $FF.
For example:
	Level_SkipClr:
		tst.b	(f_timeover).w	; <<<<<<<<<<<<<<<<<<<<<<<<< test the time over flag
		bmi.s	@skiptimeclear		; <<<<<<<<<<<<<<<<<<<<<<<<< if negative, branch
		move.b	d0,(f_timeover).w
	@skiptimeclear:
		move.b	d0,(v_shield).w	; clear shield
		move.b	d0,(v_invinc).w	; clear invincibility
		move.b	d0,(v_shoes).w	; clear speed shoes
		move.b	d0,($FFFFFE2F).w
	...


and, in Sonic (part 2).asm:
GameOver:
	...
	loc_138D4:
		move.w	#60,$3A(a0)	; set time delay to 1 second
		tst.b	(f_timeover).w	; is TIME OVER tag set?
		beq.s	locret_13900	; if not, branch
		bmi.s	locret_13900	; <<<<<<<<<<<<<<<<<<<<<<<<<< if negative, also branch
		move.b	#$FF,(f_timeover).w ; <<<<<<<<<<<<<<<<<<<<<< set the flag to -1
		move.w	#0,$3A(a0)
		move.b	#$39,(v_objspace+$80).w ; load TIME object
		move.b	#$39,(v_objspace+$C0).w ; load OVER object
		move.b	#2,(v_objspace+$80+obFrame).w
		move.b	#3,(v_objspace+$C0+obFrame).w
		bra.s	loc_138C2
	...


and, in Object 0D Signpost:
GotThroughAct:
	...
	@hastimebonus:
		add.w	d0,d0
		move.w	TimeBonuses(pc,d0.w),(v_timebonus).w ; set time bonus
		tst.b	(f_timeover).w	; <<<<<<<<<<<<<<<<<<<<<<<< is the TIME OVER flag set?
		beq.s	@skiptimebonusclear		; <<<<<<<<<<<<<<<<<<<<<<<< if not, branch
		clr.w	(v_timebonus).w ; <<<<<<<<<<<<<<< set Time Bonus to 0
		clr.b	(f_timeover).w ; <<<<<<<<<<<<<<< reset TIME OVER flag back to 0
	@skiptimebonusclear:
		move.w	(v_rings).w,d0	; load number of rings
		mulu.w	#10,d0		; multiply by 10
	...


This is the general idea. Though, since you are working with Sonic 1, you could create a new variable for doing that, since there are more free RAM areas in Sonic 1 than there are for the other games. I suggested the approach of using the same variable for this purpose because I had Sonic 2 in mind at the time.

By the way, I just remembered that Rev 00 of Sonic 1 doesn't reset the time when you die from a Time Over anyways.


Couple notes:
1. You actually gave me an easier process than the one I had put together... which had worked somewhat... but was a mess... So I'm using yours. Much thanks!
2. I'm glad to not have to use another RAM address after all, as I want to save as many as I can for something else...
3. I took out all of the Revision 00 stuff anyways.

Oh, and on a side note...


View PostEndri, on 04 September 2012 - 10:44 PM, said:

You probably don't want the 100 and 200 rings extra lives flags to be reseted when the player dies, otherwise, the player would still be able to "pad" the number of life: grab 200 rings, earn 2 extra lives, die, grab 200 rings, earn 2 extra lives, die, rinse and repeat. You could clear the rings lives flags only in the part of the level initiation code that is run only when the level is not started from a Star Post. This would solve the problem.


That is actually what the Sonic 1 ROM already does. I am opting to instead remove this instruction from level init, and instead clear the ring lives flag at signpost, much like the time over flag instead.

:) Much thanks Endri!
This post has been edited by KingofHarts: 08 September 2012 - 11:14 PM

  • 7 Pages +
  • 1
  • 2
  • 3
  • Last ►
    Locked
    Locked Forum

2 User(s) are reading this topic
0 members, 2 guests, 0 anonymous users