Perfect Bonus & Life every 50000 points.

Discussion in 'Discussion and Q&A Archive' started by Jimmy, Apr 20, 2008.

Thread Status:
Not open for further replies.
  1. Jimmy

    Jimmy "GIVE HIM BREAD FIST!" Member

    Joined:
    Apr 2, 2008
    Messages:
    41
    Location:
    Slough. England
    The things mentioned in the topic title, Perfect Bonus & a "life get" every 50000 points, are in Sonic 2.


    How would I make this happen in Sonic 1?
     
  2. amphobius

    amphobius spreader of the pink text Member

    Joined:
    Feb 24, 2008
    Messages:
    970
    Location:
    United Kingdom
    Go to the point routine in your dissasembly, and add a check for 50000 points to give a life.


    I don't think it's possible for the perfect bonus, as I haven't seen it happen in the professional hacks.
     
  3. shobiz

    shobiz Well-Known Member Member

    Joined:
    Aug 11, 2007
    Messages:
    198
    Location:
    Karachi, Pakistan
    The extra life per 50000 points is handled by Sonic 2's AddPoints routine. Basically, there's a RAM variable (Next_Extra_life_score) which is initially set to 5000. Each time the specified number of points are added, the subroutine compares the current score with this value to see if the score exceeds it. If it does, a life is added, appropriate flags set and the sound played, and 5000 is added to Next_Extra_life_score, otherwise nothing happens. If you're wondering why it's 5000 and not 50000, that's because the game internally stores the score divided by 10. By looking at AddPoints in Sonic 2 and then comparing it with Sonic 1's version you should be able to figure it out.


    Perfect Bonus is handled by Sonic 2's ring manager, which calculates the number of rings in each level and stores them in a RAM variable (the perfect counter). Each time a ring is collected the perfect counter is decremented, and at the end of the act, if this variable is zero (i.e. all rings have been collected) the perfect bonus is granted. Although Sonic 1 doesn't have a separate rings manager and just uses normal object handling routines for rings, it doesn't seem too hard to write a routine to go through the object placement list and calculate the number of ring objects and store it in some unused RAM variable, and then subtract from this RAM variable every time a ring is collected and do the appropriate check at the end of level score tally. To find the code which does all the handling, just do a search for Perfect_rings_left in the Sonic 2 disassembly. It's quite easy to see how it works.
     
  4. Jimmy

    Jimmy "GIVE HIM BREAD FIST!" Member

    Joined:
    Apr 2, 2008
    Messages:
    41
    Location:
    Slough. England
    Cool, thanks shobiz. Hopefully I can figure them out & put them in the hack im working on.
     
  5. OrdosAlpha

    OrdosAlpha RIGHT! Naebody move! Root Admin

    Joined:
    Aug 5, 2007
    Messages:
    1,793
    Location:
    Glasgow, Scotland
    I thought that was self explanatory.
     
  6. Jimmy

    Jimmy "GIVE HIM BREAD FIST!" Member

    Joined:
    Apr 2, 2008
    Messages:
    41
    Location:
    Slough. England
    After putting the code for the life every 50000 points thing from Sonic 2 to Sonic 1, and making slight changes to the code, I got 2 errors when trying to build.


    "s1comb.asm<14128> : Error 06060 : Branch offset 0 is not allowed"


    and


    "s1comb.asm<42539> : Error 15019 : FREF symbol 'Next_Extra_life_score' <s1comb.asm[42539]> not defined"


    How would I fix these? (Sorry if I sound like a complete n00b =/)


    Here's the edited AddPoints routine:



    Code:
    
    AddPoints:
    
    		move.b	#1,($FFFFFE1F).w ; set score counter to	update
    
    		lea	($FFFFFFC0).w,a2
    
    		lea	($FFFFFE26).w,a3
    
    		add.l	d0,(a3)		; add d0*10 to the score
    
    		move.l	#999999,d1
    
    		cmp.l	(a3),d1		; is #999999 higher than the score?
    
    		bhi.w	loc_1C6AC	; if yes, branch
    		move.l	d1,(a3)		; reset	score to #999999
    
    loc_1C6AC
    	        move.l	(a3),d0
    	        cmp.l	(Next_Extra_life_score).w,d0
    	        bcs.s	locret_1C6B6
    	        addi.l	#5000,(Next_Extra_life_score).w
    		addq.b	#1,($FFFFFE12).w  ; add 1 to the number of lives you have
    		addq.b	#1,($FFFFFE1C).w  ; add 1 to the lives counter
    		move.w	#$88,d0
    		jmp	(PlaySound).l	; play extra life music
    
    locret_1C6B6:
    		rts	
    ; End of function AddPoints
    
     
  7. shobiz

    shobiz Well-Known Member Member

    Joined:
    Aug 11, 2007
    Messages:
    198
    Location:
    Karachi, Pakistan
    Well, Next_Extra_life_score is actually an equate. To the assembler, it has no meaning unless you associate a RAM address with it. In the Sonic 2 disassembly, there's a large equates section at the top which tells the assembler which name refers to which address. There's nothing similar in the Sonic 1 disassembly, but as far as I can see, $FFFFFFC0 appears to be unused besides this one write, so you can use that as your next extra life score counter. You'll just have to initialize it to 5000 in the parts which do level initialization - to find out where the initialization takes place, do a search for Next_Extra_life_score in the Sonic 2 disassembly, see all the parts where it's set to 5000, and do the same thing in the corresponding parts of the Sonic 1 disassembly.
     
    Last edited by a moderator: Apr 21, 2008
  8. Jimmy

    Jimmy "GIVE HIM BREAD FIST!" Member

    Joined:
    Apr 2, 2008
    Messages:
    41
    Location:
    Slough. England
    Where in the disassembly would I associate the RAM address with it?
     
  9. redhotsonic

    redhotsonic Also known as RHS Member

    Joined:
    Aug 10, 2007
    Messages:
    2,969
    Location:
    England
    Next_Extra_life_score doesn't exist. Are you using nemesis disassembly because it looks like you are.
     
  10. shobiz

    shobiz Well-Known Member Member

    Joined:
    Aug 11, 2007
    Messages:
    198
    Location:
    Karachi, Pakistan
    I think you misunderstood what I meant. What I was actually trying to say was that instead of Next_extra_life_score, use $FFFFFFC0.
     
  11. Sephiroth

    Sephiroth WHY SO CURIOUS?!? Member

    Joined:
    Aug 11, 2007
    Messages:
    507
    Location:
    Qatar, M.E.
    The Branch Offset 0 error is because you are basically doing a piece of code that looks like this:



    Code:
    Bob&#58; &#59;Then some code or something
    
    
    
    more code
    
    more code
    
    
    
    
    
    bra.s Steve
    
    
    
    Steve&#58;


    Basically, it's trying to branch off to something that is in the next line anyway.
     
  12. redhotsonic

    redhotsonic Also known as RHS Member

    Joined:
    Aug 10, 2007
    Messages:
    2,969
    Location:
    England
    Who's Bob and Steve?
     
  13. Sephiroth

    Sephiroth WHY SO CURIOUS?!? Member

    Joined:
    Aug 11, 2007
    Messages:
    507
    Location:
    Qatar, M.E.
    I just used the first things that popped into my head.


    They happened to be Bob and Steve.


    Should I have been eating, they could have been called Cheese and Burger. However, its the concept. You should look for that branch that goes straight to the next line, and remove it.
     
  14. Jimmy

    Jimmy "GIVE HIM BREAD FIST!" Member

    Joined:
    Apr 2, 2008
    Messages:
    41
    Location:
    Slough. England
    Thanks, the Next_extra_life_score part worked, but even though I removed the line "bhi.w loc_1C6AC ; if yes, branch" it still comes up with the branch offset 0 error =/


    EDIT: Typos =P
     
    Last edited by a moderator: Apr 21, 2008
  15. shobiz

    shobiz Well-Known Member Member

    Joined:
    Aug 11, 2007
    Messages:
    198
    Location:
    Karachi, Pakistan
    That line has nothing to do with the branch offset error as far as I can tell. The error message the assembler gives contains a line number. For example, in s1comb.asm<14128>, 14128 is the line number. Open up s1comb.asm, go to whichever line is giving the error, find the corresponding line in sonic1.asm and comment it out. That should fix it.
     
  16. Jimmy

    Jimmy "GIVE HIM BREAD FIST!" Member

    Joined:
    Apr 2, 2008
    Messages:
    41
    Location:
    Slough. England
    Huh, I somehow accidently removed a bit of the code from the Life Monitor check. After fixing it & trying to build the rom it worked! Thanks for all the help guys =D


    EDIT: When I tested it I killed the first motobug & it gave me a life, even though I only had 100 score. But after that it works fine. (The same wierd effect happens after you die & hit something) How come?
     
    Last edited by a moderator: Apr 21, 2008
  17. redhotsonic

    redhotsonic Also known as RHS Member

    Joined:
    Aug 10, 2007
    Messages:
    2,969
    Location:
    England
    The score is more than likely checking it for 100 and not 50000. Just a guess.
     
  18. Jimmy

    Jimmy "GIVE HIM BREAD FIST!" Member

    Joined:
    Apr 2, 2008
    Messages:
    41
    Location:
    Slough. England
    But after that first time it does it every 50000 like it's supposed to.
     
  19. shobiz

    shobiz Well-Known Member Member

    Joined:
    Aug 11, 2007
    Messages:
    198
    Location:
    Karachi, Pakistan
    Did you initialize $FFFFFFC0 to 5000 somewhere in the level variables initialization code? If you didn't, that'll happen. In the Sonic 2 disassembly, do a search for all instances of "#5000,(Next_Extra_life_score).w" (without the quotes). If the full instruction is a move.l #5000,(Next_Extra_life_score).w, it's one of the code parts where this variable is initialized. You'll have to find the corresponding routines in Sonic 1 (if any) and over there set $FFFFFFC0 to 5000 so that the first life is given for 50000 points and not 0.
     
  20. Jimmy

    Jimmy "GIVE HIM BREAD FIST!" Member

    Joined:
    Apr 2, 2008
    Messages:
    41
    Location:
    Slough. England
    I've found parts in S2 disassembly with it in, but I don't know where in the S1 disassembly they correspond with.
     
Thread Status:
Not open for further replies.