don't click here

Update: How to port S3K Priority Manager into S2

Discussion in 'Engineering & Reverse Engineering' started by redhotsonic, Jun 24, 2012.

  1. redhotsonic

    redhotsonic

    Also known as RHS Tech Member
    1,587
    10
    18
    United Kingdom
    YouTuber


    I might be wrong here, but the break-down to S2, doesn't the cycles actually read 44, not 68 (making Esrael's version 2 cycles faster and not 26)? Or am I missing the point?







    Tets, have you followed Module's advice? If so, this is the problem. You need to do it my way (like I showed in the guide). I realised this when I implemented it to the Egg Prison. When I tried Module's code on the Egg Prison, all the priorities went wrong. I then tried it to "LoadSubObject_Part3:" then I got the same problem you are experiencing in DEZ. Changing it to the way I originally showed fixes this.


    Although, why it does this, I actually do not know.
     
  2. flamewing

    flamewing

    Emerald Hunter Tech Member
    1,161
    65
    28
    France
    Sonic Classic Heroes; Sonic 2 Special Stage Editor; Sonic 3&K Heroes (on hold)
    Derp, you are right; where did I come up with the 68 cycles from? Anyway, I fixed the other post.
     
  3. redhotsonic

    redhotsonic

    Also known as RHS Tech Member
    1,587
    10
    18
    United Kingdom
    YouTuber

    That means for the sake of adding a table using more space, Esrael's version only makes it faster by 2 cycles. But then again, like said before, it's a matter of choice on speed vs size.
     
  4. flamewing

    flamewing

    Emerald Hunter Tech Member
    1,161
    65
    28
    France
    Sonic Classic Heroes; Sonic 2 Special Stage Editor; Sonic 3&K Heroes (on hold)
    Technically, with the improvement I suggested, it improves by 10 cycles -- priority is never more than 7 anyway, so multiplying by 4 is no biggie. But pre-multiplying by 4 takes quite more work than Esrael's original version, so yeah.
     
  5. BlueAuraEX

    BlueAuraEX

    The Blue Aura
    20
    0
    0
    ????
    Nothing..."Yet"
    Whoa! I'm loving that large increase in lag speed! This could most definitely help out Sonic 2 hacks in a massive way. Sure, it's a small, aesthetic change, but man does it make a big difference. Hoping to see this tool used in future Sonic 2 hacks! (especially a few that I'm waiting for personally, winkwink, nudgenudge)
     
  6. redhotsonic

    redhotsonic

    Also known as RHS Tech Member
    1,587
    10
    18
    United Kingdom
    YouTuber
    Hello, all! There is an update to the priority guide. 2 extra steps! These steps are actually bug fixes caused by the new priority manager, and you may want to implement these if you've followed my guide.


    Thanks to flamewing for the help and advice on these fixes.




    Step 10 update - Fix the priority for when the main character is dead


    In my priority guide, for step 10, I explained that when you're dead, all the objects stop moving. And they all jump to "DisplaySprite:" via "RunObjectDisplayOnly:". Because of this, some objects that use priority for different reason will cause the game to crash. The way I showed you was that we had to make all objects use the same priority, so that it wouldn't freeze. Most of the time, this isn't a problem, but then, you'll may notice things like this:


    [​IMG]

    [​IMG]


    This is because, when you die, all objects jump to the "RunObjectDisplayOnly:". As they're all using the same priority, a newer one will overlap. Take the EHZ boss. His drill gets displayed first, then his wheels (so they overlap), then the cockpit (so they overlap the rest), then finally Eggman (which overlaps all). See what I mean?


    To fix this, it's simple, and I should have thought of it before (Sonic 2 Recreation has different coding and doesn't suffer this). Anyway, go to "RunObjectDisplayOnly:", and change from this:

    Code (ASM):
    1. RunObjectDisplayOnly:
    2.     moveq   #0,d0
    3.     move.b  (a0),d0 ; get the object's ID
    4.     beq.s   +   ; if it's obj00, skip it
    5.     tst.b   render_flags(a0)    ; should we render it?
    6.     bpl.s   +           ; if not, skip it
    7.     move.w  #$200,d0
    8.     bsr.w   DisplaySprite3
    9. +
    10.     lea next_object(a0),a0 ; load 0bj address
    11.     dbf d7,RunObjectDisplayOnly
    12.     rts
    13. ; End of function RunObjectDisplayOnly

    to this:

    Code (ASM):
    1. RunObjectDisplayOnly:
    2.     moveq   #0,d0           ; Clear d0 quickly
    3.     move.b  (a0),d0         ; get the object's ID
    4.     beq.s   ++          ; if it's obj00, skip it
    5.     tst.b   render_flags(a0)    ; should we render it?
    6.     bpl.s   ++          ; if not, skip it
    7.     move.w  priority(a0),d0     ; move object's priority to d0
    8.     btst    #6,render_flags(a0) ; is the compound sprites flag set?
    9.     beq.s   +           ; if not, branch
    10.     move.w  #$200,d0        ; move $200 to d0
    11. +
    12.     bsr.w   DisplaySprite3      ; Display the object with whatever is set at d0
    13. +
    14.     lea next_object(a0),a0  ; load 0bj address
    15.     dbf d7,RunObjectDisplayOnly
    16.     rts
    17. ; End of function RunObjectDisplayOnly

    So now, when all objects jump here, it will ask first, does it have the compound sprite flag set? If not, branch and continue, and use the object's original priority. If it IS set, it means that the current object's status table also contains information about other child sprites which need to be drawn using the current object's mappings. In other words, for our sake, it's using priority for something different. Therefore, it will NOT branch and it will move $200 to d0 instead.



    That's it. Done, you'll now get stuff like this:

    [​IMG]

    [​IMG]


    It was that simple.






    Step 13 - Fix the priority for Tails' tails


    This bug I only noticed the other day (was also present in S2R). The fix was a bit more involved than I thought.

    The problem is, Tails' tail's priority has been affected. Even though Tails' priority is $100, and his tails' priority is $100. Here is an example:

    [​IMG]


    It seems that his tails are not as much as a priority anymore. Anyway, flamewing had a solution, which he uses for his hack; Sonic 2 Heroes.



    Anyway, the fix:


    First, you're going to have to use some RAM. Only a word. So, go to your list of equates. I used $FFFFF5C0 (it's free whether you use the S1 sound driver or not). Call the RAM "Tails_Tails_ptr"

    Code (ASM):
    1. Tails_Tails_ptr =       ramaddr( $FFFFF5C0 )

    Our new RAM is ready for use. First, go to "InitPlayers:" and under the line:

    Code (ASM):
    1.     move.b  #2,(Sidekick).w ; load Obj02 Tails object at $FFFFB040

    SVN users, yours will say:

    Code (ASM):
    1.     move.b  #ObjID_Tails,(Sidekick+id).w ; load Obj02 Tails object at $FFFFB040

    Insert this:

    Code (ASM):
    1.     move.w  #Tails_Tails,(Tails_Tails_ptr).w

    So you have something like this (SVN users, reference only):

    Code (ASM):
    1.     move.b  #2,(Sidekick).w ; load Obj02 Tails object at $FFFFB040
    2.     move.w  #Tails_Tails,(Tails_Tails_ptr).w
    3.     move.w  (MainCharacter+x_pos).w,(Sidekick+x_pos).w
    4.     move.w  (MainCharacter+y_pos).w,(Sidekick+y_pos).w
    5.     subi.w  #$20,(Sidekick+x_pos).w
    6.     addi.w  #4,(Sidekick+y_pos).w
    7.     move.b  #8,(Tails_Dust).w ; load Obj08 Tails' spindash dust/splash object at $FFFFD140


    Do the same at label "InitPlayers_TailsAlone:", so you have something like this (SVN users, reference only):

    Code (ASM):
    1. InitPlayers_TailsAlone:
    2.     move.b  #2,(MainCharacter).w ; load Obj02 Tails object at $FFFFB000
    3.     move.w  #Tails_Tails,(Tails_Tails_ptr).w
    4.     move.b  #8,(Tails_Dust).w ; load Obj08 Tails' spindash dust/splash object at $FFFFD100
    5.     addi.w  #4,(MainCharacter+y_pos).w
    6.     rts
    7. ; End of function InitPlayers



    Next, go to "loc_A2F2:". This is for when you're at the cutscene at the end of the game.


    XenoWhirl users. Change this:

    Code (ASM):
    1. loc_A2F2:
    2.     moveq   #$E,d0
    3.     move.b  #2,(a1) ; load Tails object
    4.     move.b  #$81,$2A(a1)
    5.     move.b  #5,(Object_RAM+$80).w ; load Obj05 (Tails' tails) at $FFFFB080
    6.     move.w  a1,(Object_RAM+$80+parent).w
    7.     rts

    to this:

    Code (ASM):
    1. loc_A2F2:
    2.     moveq   #$E,d0
    3.     move.b  #2,(a1) ; load Tails object
    4.     move.b  #$81,$2A(a1)
    5.     move.w  #Object_RAM+$80,(Tails_Tails_ptr).w
    6.     rts




    SVN users, change this:

    Code (ASM):
    1. loc_A2F2:
    2.     moveq   #$E,d0
    3.     move.b  #ObjID_Tails,id(a1) ; load Tails object
    4.     move.b  #$81,obj_control(a1)
    5.     move.b  #ObjID_TailsTails,(Tails_Tails_Cutscene+id).w ; load Obj05 (Tails' tails) at $FFFFB080
    6.     move.w  a1,(Tails_Tails_Cutscene+parent).w
    7.     rts

    to this:

    Code (ASM):
    1. loc_A2F2:
    2.     moveq   #$E,d0
    3.     move.b  #ObjID_Tails,id(a1) ; load Tails object
    4.     move.b  #$81,obj_control(a1)
    5.     move.w  #Tails_Tails_Cutscene,(Tails_Tails_ptr).w ; Tails' tails at $FFFFB080
    6.     rts





    Next, go to "Obj02_Init_Continued:", and change the last few lines. Change this:

    Code (ASM):
    1.     move.b  #5,(Tails_Tails).w ; load Obj05 (Tails' Tails) at $FFFFD000
    2.     move.w  a0,(Tails_Tails+parent).w ; set its parent object to this

    SVN users, yours will say:

    Code (ASM):
    1.     move.b  #ObjID_TailsTails,(Tails_Tails+id).w ; load Obj05 (Tails' Tails) at $FFFFD000
    2.     move.w  a0,(Tails_Tails+parent).w ; set its parent object to this

    And change it to this:

    Code (ASM):
    1.     movea.w (Tails_Tails_ptr).w,a1
    2.     move.b  #5,0(a1) ; load Obj05 (Tails' Tails) at $FFFFD000
    3.     move.w  a0,parent(a1) ; set its parent object to this

    And change it to this:

    Code (ASM):
    1.     movea.w  (Tails_Tails_ptr).w,a1
    2.     move.b  #ObjID_TailsTails,id(a1) ; load Obj05 (Tails' Tails)
    3.     move.w  a0,parent(a1) ; set its parent object to this



    One more step! Go to "Obj02:" See the command jmp Obj02_States(pc,d1.w) (jmp Obj02_Index(pc,d1.w))? Change the "jmp" to a "jsr".


    And directly underneath it, add this:

    Code (ASM):
    1.     movea.w (Tails_Tails_ptr).w,a1
    2.     tst.b   routine(a1)
    3.     beq.s   +
    4.     jmp (DisplaySprite2).l
    5. +
    6.     rts

    So you have something like this (SVN users, reference only):

    Code (ASM):
    1. Obj02:
    2.     ; a0=character
    3.     cmpi.w  #2,(Player_mode).w
    4.     bne.s   +
    5.     move.w  (Camera_Min_X_pos).w,(Tails_Min_X_pos).w
    6.     move.w  (Camera_Max_X_pos).w,(Tails_Max_X_pos).w
    7.     move.w  (Camera_Max_Y_pos_now).w,(Tails_Max_Y_pos).w
    8. +
    9.     moveq   #0,d0
    10.     move.b  routine(a0),d0
    11.     move.w  Obj02_States(pc,d0.w),d1
    12.     jsr Obj02_States(pc,d1.w)
    13.     movea.w (Tails_Tails_ptr).w,a1
    14.     tst.b   routine(a1)
    15.     beq.s   +
    16.     jmp (DisplaySprite2).l
    17. +
    18.     rts



    Done! Tails' tails should now work with the right priority! Tails will now queue his tails for drawing right after himself. Without this, the tails will be queued for drawing after all objects between Tails and the tails that have the same priority. And that's why before, Tails' tails had less priority.



    [​IMG]




    I'll update my first post containing the guide with this information. Any bugs/troubles, reply here. If anyone wants to add this extra bit to the SCHG, feel free.



    Cheers,
    redhotsonic
     
  7. RetroKoH

    RetroKoH

    Member
    1,662
    22
    18
    Project Sonic 8x16
    You finally gave me something to do! Gives me an excuse to take a break from Triad (though not before I fixed the palette editor's greyscale & inversion effects)

    EDIT: DONE! And I only put in one image... I don't know how to put the image in without uploading the damn thing.... and I don't want to upload 500 images (That is unless it's ok to upload the necessary imagery for these pages I've posted)

    I put up the pic for the Tails error. Could someone with authority fill me in? Is it ok for me to upload any and all necessary images for these pages?
     
  8. redhotsonic

    redhotsonic

    Also known as RHS Tech Member
    1,587
    10
    18
    United Kingdom
    YouTuber
    Thanks, mate. That great.

    Yeah, it would be useful for more pictures, but until someone is able to help you out, it doesn't matter too much (for this priority guide anyway).
     
  9. redhotsonic

    redhotsonic

    Also known as RHS Tech Member
    1,587
    10
    18
    United Kingdom
    YouTuber
    Hey, guys!


    There seems to be a bug with following this guide with the SVN disassembly. If you're a XenoWhirl's user, you're safe and can ignore this post and go on with your day. SVN user? Read on.


    Seems that if you follow this guide as an SVN user, there may be a glitch with the Special Stages. Sonic and Tails act like they're being hit by the bombs object over and over, making it impossible to get any emeralds in the special stages. The reason? inertia is being used for something else in the special stages. This doesn't seem to be the case in Xenowhirl's dis.


    So, in your SST table, you're better off switching inertia with something else. invulnerable_time seems to be the best to swap it with. So change them so you end up with this:


    Code (ASM):
    1. invulnerable_time = $20 ; and $21 ; time remaining until you stop blinking
    Code (ASM):
    1. inertia =       $30 ; and $31 ; directionless representation of speed... not updated in the air


    Any more problems, with either disassembly, give me a shout.



    My SST guide has been updated as well to provide this bit of information
     
  10. RetroKoH

    RetroKoH

    Member
    1,662
    22
    18
    Project Sonic 8x16
    This step has been added to the wiki. Step 11.b

    Any errors or omissions lemme know.
     
  11. ShadowsofYesterday

    ShadowsofYesterday

    I have no idea what's going on. Member
    169
    0
    0
    Fort Wayne, IN
    Sonic and the Magic Hat
    Sorry to bump this topic after two years, but hey, hacking information is always worth a bump, right?

    I was puzzling for a bit over why this would create a problem on the newer disassembly, but not the old Xenowhirl one. After all, everything's equated, so changing the SSTs shouldn't do anything, right? Well, it's actually a problem with the disassembly, rather than the SST. $20 is a perfectly acceptable spot for inertia. Here's what's wrong: In the old Xenowhirl disassembly, at several points in the special stage's code, objoff_14 is used, whereas in the newer disassembly, this was changed to inertia for some reason. As far as I can tell, this change was completely needless. objoff_14 is still a valid equate.

    So basically, if you want an alternative (and in my opinion, preferable) fix to changing the SST, fix what the SVN disassembly changed for no apparent reason instead. To do this, go to the following labels, and everywhere you see "inertia", change it back to "objoff_14".

    Code (ASM):
    1. SSPlayer_DoLevelCollision: (toward the end of the label)
    2. SSPlayer_Collision:
    3. SSPlayer_Move:
    4. SSPlayer_MoveLeft: (a few lines above this label)
    5. SSPlayer_MoveRight: (after the plus)
    6. SSPlayer_Traction: (one before the plus, and another after it)
    7. SSObjectMove:
    Technically in the vanilla game, they both use $14, which is why inertia didn't create any problems before you changed its value to $20. But the code is looking specifically for $14, not necessarily for inertia. So changing the SST to $20 made it go haywire, because it was messing with something else that was probably using $20. Really, either fix works just as well. Yours works because it sets inertia to a value that's never called in the special stage's code, so it doesn't interfere with anything else. Mine works because it fixes a misused equate so that it's using the offset it should have been using all along. It's a matter of preference. Yours is simpler, but I personally wouldn't feel comfortable with it.

    EDIT: Also, I'd like to point out that you never updated the first post of this thread when you came up with that fix, just your SST thread.
     
  12. flamewing

    flamewing

    Emerald Hunter Tech Member
    1,161
    65
    28
    France
    Sonic Classic Heroes; Sonic 2 Special Stage Editor; Sonic 3&K Heroes (on hold)
    Lets see your argument:
    Premise 1: 2007 disasm used objoff_14 for Special Stage.
    Premise 2: SVN diasm uses inertia for Special Stage.
    Premise 3: The guide fails on SVN because of this difference.
    Conclusion: The SVN disassembly is "wrong" somehow.

    Huh? I am sorry to burst your bubble, but fact of the matter is that all this does is make the guide incomplete or incorrect, since both disassemblies build bit-perfect ROMs. Moreover, one can make the argument that is is actually the 2007 disassembly that is wrong here: objoff_14 is used by the players in special stage as a measure of speed; hence inertia. See?
     
  13. ShadowsofYesterday

    ShadowsofYesterday

    I have no idea what's going on. Member
    169
    0
    0
    Fort Wayne, IN
    Sonic and the Magic Hat
    You're right, both disassemblies do build bit-perfect ROMs. I just had this conversation with someone else last night. I suppose "wrong" is the wrong way of wording it, more like needless relabeling. Anyone who follows this guide – which in all honesty is a very helpful guide that should be followed by pretty much everyone – is going to be tripped up because a change was made that didn't need to be made. You could argue that the fault is in the guide for not initially taking this into account, but the fact of the matter is, there was nothing wrong with objoff_14 there.

    Also, you don't have to be rude about it.
     
  14. redhotsonic

    redhotsonic

    Also known as RHS Tech Member
    1,587
    10
    18
    United Kingdom
    YouTuber
    Whoops. Added to the guide. Also, linked to your post too in case they want your alternative fix. Thanks!


    Plus, the guide was actually made with Xeno's dis' in mind. It was out of the kindness of my heart that decided to help SVN users. As I never use SVN and will always prefer to use Xeno's, there was bound to be bits and bobs that I would miss for SVN users. But, it works for both now anyway. As for flamewing's (somewhat sarcastic?) conclusion, this would have been the case if I had made this guide before SVN came out, but it didn't, so it was the guide at fault, but again, it's fixed now, all good. Thanks for the alternative fix though :)

    As for the "which disassembly is better/right/wrong", let's not get into that. flamewing and I still continue to argue to this day which is better, and neither of us ever back down =P
     
  15. ShadowsofYesterday

    ShadowsofYesterday

    I have no idea what's going on. Member
    169
    0
    0
    Fort Wayne, IN
    Sonic and the Magic Hat
    Yeah, I'm sorry to everyone if I came across as abrasive, that was not my intention. I did feel offended by the condescending tone of Flamewing's post, but I suppose he was just defending something that technically wasn't wrong.

    Either way, either method stands as a valid fix, so it's just a matter of which way people prefer to do it.
     
  16. RetroKoH

    RetroKoH

    Member
    1,662
    22
    18
    Project Sonic 8x16
    I didn't see what flamewing said as abrasive. Matter of interpretation, sure... such is the nature of the beast with regards to the internet, and seeing typed responses. I think he just typed it out the way he did to illustrate why it appeared you had misunderstood a certain point. I'm sure he certainly didn't intend for you to take it in that manner.

    Now, same goes the other way too. I wouldn't interpret you as "abrasive". I'd certainly degree that an overall higher level of detail to all forms of disassemblies of each game is imperative for this site's guides. That said, do understand, as RHS pointed out... that for some people this can spark some unnecessary banter over preferences.
     
  17. Clownacy

    Clownacy

    Tech Member
    1,061
    607
    93
    You're offended by someone correcting you? You're offended by someone bursting your bubble of delusion? You're offended by someone trying to make you see something their way?

    How is it "needless relabelling" to label inertia as 'inertia'? There is everything wrong with using objoff_14 there: It's vague, it doesn't align itself with the other matching-group SSTs, etc...

    The problem here is collision_property ($21), which is overwritten by the relocated inertia ($20 & $21). The thing is, the Special Stage objects use both conventions specific to sonic/tails (inertia) and conventions followed by many objects but NOT sonic/tails (collision_property). What to do about this, I have no idea.
     
  18. RetroKoH

    RetroKoH

    Member
    1,662
    22
    18
    Project Sonic 8x16
    Dunno if that one was necessary...

    Anyway as for the last one... and correct me if I'm wrong, as I'm not so familiar with the S2 Special Stage... but it's different objects that use these conventions, right? I.e. Players use inertia, while others use collision property.

    If I'm mistaken... then objects that conflict could perhaps use scratch RAM?


     
  19. Clownacy

    Clownacy

    Tech Member
    1,061
    607
    93
    Well, what bubble do you think Flamewing was talking about? He thought the Git disasm is wrong, when he was wrong. To do that is to be deluded. My point was that if "Sorry to burst your bubble" is the condescending phrase that ticked him off, then it isn't something that exists just to be insulting; it explains the purpose of his post.
     
  20. RetroKoH

    RetroKoH

    Member
    1,662
    22
    18
    Project Sonic 8x16
    Yea... Trying to defuse this situation instead of watching it turn into a potential explosive back and forth... Not saying you or flamewing are wrong, mind you.