Sonic 1-3 Collision in Sonic 1

Discussion in 'Discussion and Q&A Archive' started by ProjectFM, Apr 22, 2015.

  1. ProjectFM

    ProjectFM Optimistic and self-dependent Member

    Joined:
    Oct 4, 2014
    Messages:
    912
    Location:
    Orono, Maine
    This topic is for the 128 version of the Hivebrain 2005 disassembly.

    I thought this topic was too important and may require a few posts to be answered so I thought it deserved a topic.

    In my Sonic hack, I have a few levels ported from Sonic 2 and 3 and want the correct collision files (CollArray1, CollArray2, AngleMap) to be loaded once the level it is needed in starts. I have tried using branches but that was incredible ineffecient and I have tried using a table which somehow messed up some of the collision. These are the pieces of code I want to replace:


    lea (CollArray1).l,a2

    lea (CollArray2).l,a2

    lea (AngleMap).l,a2

    Secondary question: This is somewhat related to the topic.

    Sometimes when standing on a platform, Sonic will act as if he is in the air leading to him acting odd and only using one animation frame.
     
  2. MarkeyJester

    MarkeyJester ♡ ! Member

    Joined:
    Jun 27, 2009
    Messages:
    2,867
    At the start of loading the level, try:

    Code:
    		move.l	#CollArray1,($FFFF8000).w
    Then when you need to load the address of the collision array/angle map:
    Code:
    		movea.l	($FFFF8000).w,a2
    a2 will contain the address that you forced into RAM 8000. (This is just an example, RAM 8000 may not be available to you)
     
  3. ProjectFM

    ProjectFM Optimistic and self-dependent Member

    Joined:
    Oct 4, 2014
    Messages:
    912
    Location:
    Orono, Maine
    Are there any places where a different piece of code is loaded depending on the zone?
     
  4. Pacca

    Pacca Having an online identity crisis since 2019 Member

    Joined:
    Jul 5, 2014
    Messages:
    1,175
    Location:
    Limbo
    It might make a little more sense to put the collision loading routine right under each levels Level Events labels. It's messy, I know, but it guarantees that the collision is level specific, and it runs right when the level starts.You might want to avoid having the player start on slopes if you do this method though, as it will likely take significantly longer to load the new collision set; also, it will run always throughout the level... The only other option I can think of is a huge list of cmpi/beq instructions, though, and you said you didn't want that.
     
  5. AURORA☆FIELDS

    AURORA☆FIELDS so uh yes Exiled

    Joined:
    Oct 7, 2011
    Messages:
    759
    As Markey suggested here, I used the same way with Sonic Green Snake back in the day to achieve a HPZ port (in unreleased version). If you have 12 bytes of RAM free you can store all necessary pointers in RAM.

    You would load the pointers in RAM somewhere before Level_TtlCard. You would have 3 entries per zone, one for each type of collision index (CollArray1, CollArray2, AngleMap), and load them to RAM you allocated for the pointers. Now you can simply do as Markey instructed to load the correct pointer

    Pacguy Actually, simply loading pointers to RAM is very quick so there will be no issues with slopes, and neither it could even if you copied the collision from ROM to RAM, since M68K needs to wait throughout the copy loop. There is no threading in MegaDrive afterall!
     
  6. ProjectFM

    ProjectFM Optimistic and self-dependent Member

    Joined:
    Oct 4, 2014
    Messages:
    912
    Location:
    Orono, Maine
    The problem with that is that it uses up RAM which is something I like to ration. When I get around to it, I'll try Pacguys's idea.

    Edit: Nevermind. The collision loading routine is way too long.
     
    Last edited by a moderator: Apr 22, 2015
  7. AURORA☆FIELDS

    AURORA☆FIELDS so uh yes Exiled

    Joined:
    Oct 7, 2011
    Messages:
    759
    You need the RAM anyway, no matter what you do unless you do simple compare statements which is sluggish. and Sonic 1 has plenty of free RAM you can spend on this for sure. I have still hundreds of bytes of free RAM even after having large arrays in RAM. I am sure by rearranging RAM you can free up way more than 12 bytes, and its really worth the spend.

    It's just my opinions of course, your are free to do whatever you wish. Also for the record, you can use this page to find free RAM easily.
     
    Last edited by a moderator: Apr 22, 2015
  8. ProjectFM

    ProjectFM Optimistic and self-dependent Member

    Joined:
    Oct 4, 2014
    Messages:
    912
    Location:
    Orono, Maine
    I want to try your way but I'm having a hard time understanding what you mean. How do you store pointers into RAM? Why do I need 12 bytes of RAM if I'm storing three versions of three things?
     
  9. Clownacy

    Clownacy Retired Staff lolololo Member

    Joined:
    Aug 15, 2014
    Messages:
    1,020
    3 longword pointers (1 version of 3 things) = 12 bytes


    Look at MJ's post for an example of storing and using a pointer in RAM.
     
    Last edited by a moderator: Apr 22, 2015
  10. ProjectFM

    ProjectFM Optimistic and self-dependent Member

    Joined:
    Oct 4, 2014
    Messages:
    912
    Location:
    Orono, Maine
    I understand that I need to move the collision into the RAM and have it get loaded in a different piece of code but that brings me make to the first problem of how I'm going to make the right collision load depending on the level. Maybe loading the collision into RAM will help prevent problems and reduce the amount of code I need to add so I'm going to try loading the collision from a table and moving it into RAM to be used when needed.
     
  11. ProjectFM

    ProjectFM Optimistic and self-dependent Member

    Joined:
    Oct 4, 2014
    Messages:
    912
    Location:
    Orono, Maine
    Sorry to double post

    I tried using a table to load the collision arrays and angle maps to RAM addresses and loading the RAM addresses when it needed but I got an illegal addressing mode error for this:


    Level_LoadCol:
    moveq #0,d0
    move.b ($FFFFFE10).w,d0
    add.b d0,d0 ; multiply d3 by x2
    add.b d0,d0 ; multiply d3 by x2 again (x4)
    movea.l CollArray1Table(pc,d0.w),($FFFFF784).w
    movea.l CollArray2Table(pc,d0.w),($FFFFF788).w
    movea.l AngleMapTable(pc,d0.w),($FFFFF78C).w

    I thought it might have been because I was loading an array directly to a RAM address so I tried moving it to d1 and moving d1 to the RAM addresses but I got the same error.

    Edit: Also, should it be add.w or add.b because Markey told me add.w but add.b makes more sense.
     
    Last edited by a moderator: Apr 22, 2015
  12. AURORA☆FIELDS

    AURORA☆FIELDS so uh yes Exiled

    Joined:
    Oct 7, 2011
    Messages:
    759
    Movea loads address from RAM or immediate value, but Array such as your example is not a "static" address but rather a look-up table, which is why you need to use Move instead. Don't worry if it sounds confusing, later when you learn of these concepts more you will understand why this is. Also it is safe to use add.w instead of add.b, because if you had more than $40 levels, it would amount to greater than $FF, meaning with byte additions it would overflow and give wrong values. For example $41 * 4 = $104   & $FF = 4. Furthermore values $80 to $FF will be considered negative, and will now read from above the Array declaration (or the label). Using add.w would have no negative consequences, but will circumvent these issue.
     
  13. Clownacy

    Clownacy Retired Staff lolololo Member

    Joined:
    Aug 15, 2014
    Messages:
    1,020
    movea.l should only be used when the destination is an address register.

    add.w is recommended because it allows for some room to grow. If d0 contains $40, two 'add.b d0,d0's would set d0 to $0000 instead of $0100, because the data outside of the lowest byte would be lost.

    Edit: Yeah, well, I thought my explanation was better.
     
    Last edited by a moderator: Apr 23, 2015
  14. ProjectFM

    ProjectFM Optimistic and self-dependent Member

    Joined:
    Oct 4, 2014
    Messages:
    912
    Location:
    Orono, Maine
    ^Ninja'd

    Thanks everyone. This worked great!

    Now onto the secondary problem: