Sally In Sonic 2

Discussion in 'Engineering & Reverse Engineering' started by E-122-Psi, Jun 22, 2013.

  1. E-122-Psi

    E-122-Psi

    Member
    2,130
    327
    63
    Revision 1.2 uploaded:

    http://www.sendspace.com/file/vcl56c

    * SEGA animation fixed (thanx MainMemory).
    * Remaining sprites added (including tornado sprites for Tails' mode).
    * Added a duck laser attack for when crouching.
    * Couple of sprite fixes that didn't quite look right.
    * Handful of other bug fixes I didn't keep track of.

    Okay if I wiki this by the way?
     
  2. E-122-Psi

    E-122-Psi

    Member
    2,130
    327
    63
    And in a year+ absence, another update:

    [​IMG]

    Sally's projectile is now REAL and long distance! A very special thanks to Snkenjoi for coding this.

    Admittedly there are parts where a projectile in a Sonic game seemed better on paper, Sally frequently outruns her laser attack and some elements are extremely difficult to aim onto (see SCZ and OOZ boss) but owning parts such as the last boss are a lot of fun and at least now Sally isn't an Amy-lite. I'm wondering whether to keep her hitbox when she fires so she isn't completely vulnerable, since it's now extremely easy for her to get hit.

    Bugs:

    * The slide and close range fire is still needed for some objects such as the CPZ and HTZ bricks until I figure out how to code the projectile object to work with them.

    Go to the wiki entry for the new revision.
     
  3. Strife

    Strife

    Member
    1,982
    101
    43
    United States
    Freedom Planet 2
    If you're worried about Sally outrunning her projectile, would it be possible to add Sally's current speed to the projectile's base speed when it's fired?
     
  4. MathUser

    MathUser

    3rd top wiki contributor Researcher
    2,101
    2
    18
    New hack eh? Looking pretty good. Glad you made her explosion thing a real projectile instead.
     
  5. E-122-Psi

    E-122-Psi

    Member
    2,130
    327
    63
    Would it be easy enough to have Sally switch art files when she turns super? (I know S3+K does, even if the dissassembly screws it up). If so I could at least make a more impressive super form for her by switching some colors around, even if her transformation sequence would likely look fucked up.

    [​IMG]

    This is my mock up. While the colors are still underplayed, I thought it made a funny nod to her old blonde color scheme.

    The next revision fixes this by clearing Sally's x velocity. While this means slowing her down whenever she has to attack, it gets rid of the issue and makes it easier to aim too. She also has a downward fire move too, which makes some parts a whole lot easier.
     
  6. Covarr

    Covarr

    Sentient Cash Register Member
    4,233
    3
    18
    Trapped in my own thoughts.
    Two stageplays, a screenplay, and an album
    With the right sound effect and a recoil animation, you could easily make this feel as deliberate as it is.
     
  7. Hitaxas

    Hitaxas

    Retro 80's themed Twich streamer Member
    Doing so would be easy enough just set the art, mappings and dplc files to load when turning super and set the normal ones when reverting from super to normal. Then you will also have to most likely make the super form animation lists from scratch, since I'd assume you would be replacing every sprite with a super form version?
     
  8. E-122-Psi

    E-122-Psi

    Member
    2,130
    327
    63
    Another new revision!

    * Sally has a new downward laser ability, fire while airbourne holding downward, Sally also gets a vertical boost.
    * Super Sal has been tweaked up a bit, better color scheme and her laser is boosted.
    * Sally's laser can now shoot through most breakable objects (except the wing fortress entrance capsule, which still needs a close up attack to break).

    Bugs:

    * An odd bug sometimes occurs where Sal can just smash through some objects just by rushing through them a certain way.
    * While Sally herself is fixed, some sprites still aren't refined to the super pallette.
     
  9. E-122-Psi

    E-122-Psi

    Member
    2,130
    327
    63
    Okay I've been attempting to convert the projectile code into the Sonic 1 hack. So far I've gotten the basic physics to work (eg. it shoots from Sally and hits things) but the art itself refuses to load no matter what I do. If anyone can see any flaws I've made in the conversion please say so. This has been driving me crazy for a while now:

    Code (ASM):
    1. ObjDE:
    2.     moveq   #0,d0
    3.     move.b  $24(a0),d0
    4.     move.w  Obj_Blob_Index(pc,d0),d0
    5.     jmp Obj_Blob_Index(pc,d0)
    6.  
    7. Obj_Blob_Index:
    8.     dc.w    Obj_Blob_Init-Obj_Blob_Index
    9.     dc.w    Obj_Blob_Move-Obj_Blob_Index
    10.     dc.w    Obj_Blob_Destroy-Obj_Blob_Index
    11.  
    12. Obj_Blob_Init:
    13.     move.l  #SME_0iwB5,mappings(a0) ; ($C)
    14.     move.w  #$79C,art_tile(a0)
    15.     move.w  #$2,priority(a0)
    16.     move.b  #$8,width_pixels(a0)
    17.     move.b  #$4,render_flags(a0)
    18.     move.b  #$4,y_radius(a0) ; $A
    19.     move.b  #$18,$30(a0)                ; distance laser will travel
    20.     move.w    #$C4,d0                       ; play sound
    21.     jsr    (PlaySound).l
    22.     cmpi.b  #$29,(MainCharacter+anim).w
    23.     beq.s   ObjDE_DownwardNICOLE        ; if not, branch
    24.     move.w  #$660,x_vel(a0)             ; speed of laser
    25.     jmp ObjDE_ContNICOLE
    26. ObjDE_DownwardNICOLE:
    27.     move.w  #$660,y_vel(a0)             ; speed of laser
    28. ObjDE_ContNICOLE:
    29.     add.w   #$10,x_pos(a0)
    30.     btst    #0,($FFFFB001).w
    31.     beq.s +
    32.     neg.w   x_vel(a0)
    33.     sub.w   #$20,x_pos(a0)
    34. +
    35.     lea (ArtSNK_Laser0).l,a1
    36.     move.w #$79C*$20,d2
    37.     jsr (SNKDec).l
    38.     addq.b  #2,$24(a0) ;
    39.  
    40. Obj_Blob_Move:
    41.     cmp.b   #$0,$30(a0)
    42.     beq.w   Obj_Blob_Destroy
    43.     sub.b   #$1,$30(a0)
    44.     bsr.w   ObjectMove
    45.     move.b  $40,$20(a0) ; lol
    46.    
    47.     clr.w d0
    48.     move.b $1A(a0),d0
    49.     asl.w #$1,d0    ; *2 for correct offset
    50.     lea (LaserArtPointers).l,a1
    51.     adda.w (a1,d0.w),a1
    52.     move.w #$79C*$20,d2
    53.     jsr     (SNKDec).l
    54.    
    55.     lea (Ani_Laser).l,a1
    56.     jsr AnimateSprite
    57.     jsr (TouchResponse).l ;Touch_KillEnemy, Touch_Monitor
    58.     jmp DisplaySprite
    59.  
    60. Obj_Blob_Destroy:
    61.     clr.b   ($FFFFFFA4).w   ; clear NICOLE flag
    62.     jmp DeleteObject
    63.    
    64. Ani_Laser:
    65.     dc.w laser0-Ani_Laser
    66. laser0: dc.b 3,0,1,1,2,2,3,3,$FD,0
    67.     even
    68.  
    69. SME_0iwB5: 
    70.         dc.w SME_0iwB5_8-SME_0iwB5, SME_0iwB5_12-SME_0iwB5 
    71.         dc.w SME_0iwB5_1C-SME_0iwB5, SME_0iwB5_26-SME_0iwB5
    72. SME_0iwB5_8:    dc.b 0, 1  
    73.         dc.b $F8, 5, 0, 0, 0, 0, $FF, $F8  
    74. SME_0iwB5_12:   dc.b 0, 1  
    75.         dc.b $F8, 5, 0, 0, 0, 0, $FF, $F8  
    76. SME_0iwB5_1C:   dc.b 0, 1  
    77.         dc.b $F8, 5, 0, 0, 0, 0, $FF, $F8  
    78. SME_0iwB5_26:   dc.b 0, 1  
    79.         dc.b $F8, 5, 0, 0, 0, 0, $FF, $F8  
    80.         even
    Sonic 1 attempt:

    Code (ASM):
    1. Obj10:
    2.     moveq   #0,d0
    3.     move.b  $24(a0),d0
    4.     move.w  Obj_Blob_Index(pc,d0),d0
    5.     jmp Obj_Blob_Index(pc,d0)
    6.  
    7. Obj_Blob_Index:
    8.     dc.w    Obj_Blob_Init-Obj_Blob_Index
    9.     dc.w    Obj_Blob_Move-Obj_Blob_Index
    10.     dc.w    Obj_Blob_Destroy-Obj_Blob_Index
    11.  
    12. Obj_Blob_Init:
    13.     lea ($FFFFD000).w,a1
    14.     move.l  #SME_0iwB5,4(a0) ; ($C)
    15.     move.w  #$7A0,2(a0)
    16.     move.w  #$2,$18(a0)
    17.     move.b  #$8,$19(a0)
    18.     move.b  #$4,1(a0)
    19.     move.b  #$4,$16(a0) ; $A
    20.     move.b  #$18,$30(a0)                ; distance laser will travel
    21.     cmpi.b  #$25,$1C(a1)    ; is NICOLE attack being performed?
    22.     beq.w   Obj10_DownwardNICOLE        ; if not, branch
    23.     move.w  #$660,$10(a0)               ; speed of laser
    24.     jmp Obj10_ForwardNICOLE
    25. Obj10_DownwardNICOLE:
    26.     move.w  #$660,$12(a0)               ; speed of laser
    27. Obj10_ForwardNICOLE:
    28.     add.w   #$10,8(a0)
    29.     btst    #0,$22(a1)
    30.     beq.s Obj10_Cont
    31.     neg.w   $10(a0)
    32.     sub.w   #$20,8(a0)
    33.  
    34. Obj10_Cont:
    35.     lea (ArtSNK_Laser0).l,a1
    36.     move.w #$7A0*$20,d2
    37.     jsr (SNKDec).l
    38.     addq.b  #2,$24(a0) ;
    39.  
    40. Obj_Blob_Move:
    41.     cmp.b   #$0,$30(a0)
    42.     beq.w   Obj_Blob_Destroy
    43.     sub.b   #$1,$30(a0)
    44.     jsr SpeedToPos2
    45.     move.b  $40,$20(a0) ; lol
    46.    
    47.     clr.w d0
    48.     move.b $1A(a0),d0
    49.     asl.w #$1,d0    ; *2 for correct offset
    50.     lea (LaserArtPointers).l,a1
    51.     adda.w (a1,d0.w),a1
    52.     move.w #$7A0*$20,d2
    53.     jsr     (SNKDec).l
    54.    
    55.     lea (Ani_Laser).l,a1
    56.     jsr AnimateSprite
    57.     jsr (TouchResponse).l ;Touch_KillEnemy, Touch_Monitor  
    58.     jmp DisplaySprite
    59.  
    60. Obj_Blob_Destroy:
    61.     clr.b   ($FFFFFFA4).w   ; clear NICOLE flag
    62.     jmp DeleteObject
    63.    
    64. Ani_Laser:
    65.     dc.w laser0-Ani_Laser
    66. laser0: dc.b 3,0,1,1,1,2,2,2,3,3,3,$FD,0
    67.     even
    68.  
    69. SME_0iwB5: 
    70.         dc.w SME_0iwB5_8-SME_0iwB5, SME_0iwB5_12-SME_0iwB5 
    71.         dc.w SME_0iwB5_1C-SME_0iwB5, SME_0iwB5_26-SME_0iwB5
    72. SME_0iwB5_8:    dc.b 0, 1  
    73.         dc.b $F8, 5, 0, 0, 0, 0, $FF, $F8  
    74. SME_0iwB5_12:   dc.b 0, 1  
    75.         dc.b $F8, 5, 0, 0, 0, 0, $FF, $F8  
    76. SME_0iwB5_1C:   dc.b 0, 1  
    77.         dc.b $F8, 5, 0, 0, 0, 0, $FF, $F8  
    78. SME_0iwB5_26:   dc.b 0, 1  
    79.         dc.b $F8, 5, 0, 0, 0, 0, $FF, $F8  
    80.         even
    Also, more a question for the long run, is it possible to put new gameplay objects into the S3+K disassembly (I don't think I've seen any projects that do so, unless Tiddle's extras in Complete apply). If it is, you know what must happen...
     
  10. MainMemory

    MainMemory

    Kate the Wolf Tech Member
    4,551
    145
    43
    SonLVL
    I can't imagine there being any disassembly that wouldn't allow you to add new objects.
     
  11. Tiddles

    Tiddles

    Diamond Dust Tech Member
    471
    0
    0
    Leicester, England
    Get in an accident and wake up in 1973
    What's a Tiddle? (Canned laughter)

    I create all sorts of objects for S3C, though they're mostly of the helper object kind. There's no special trick to it compared to any of the other games, as far as I know, but there are a few things to remember:

    • Instead of a single byte object ID at the start of the object's memory, there is a four byte pointer directly to the location of the object's code. This is really handy because you can have objects that you just spawn on demand that don't need to waste space in any of the level object lists (e.g. none of the player objects have IDs, because you'd never place them in a level layout), and you can also avoid the boring routine counter and jump table by just pushing a new code address to (a0) when you want the object to run different code next frame. Objects in S3&K use both this technique and the old routine technique, which obviously still works fine.
    • If you do need the object to appear in a level, you need to add it to as slot under either Sprite_Listing3 or Sprite_ListingK (or both) depending on which levels you want to be able to use it in. Sprite_ListingK covers the levels that only appear in S&K excluding Flying Battery and the bonus stages, and Sprite_Listing3 covers everything else. The files for these are "Levels/Misc/Object list - Sonic 3.asm" and "Levels/Misc/Object list - Sonic & Knuckles.asm".
    • I understand there are various differences in areas such as priority definition, but I don't really work with the other games so I can't tell you a lot about that. As usual, all the necessary helper routines probably have different names from any of the other disassemblies.
    So basically, write some object-style code, add a pointer to the start of it into one of the object lists if you want it in a level, ??? and profit.
     
  12. E-122-Psi

    E-122-Psi

    Member
    2,130
    327
    63
    Whoops, I always make that typo. Yeah, I know you added a huge load of stuff to Sonic 3, I just wasn't sure if it was along the lines of full new objects rather than, like you said, 'helper objects' or additions to existing routines.

    By location do you mean like the line in the ASM?

    Depending on if it translates any easier than Sonic 1, I may have something for next year's hacking contest. :D
     
  13. Tiddles

    Tiddles

    Diamond Dust Tech Member
    471
    0
    0
    Leicester, England
    Get in an accident and wake up in 1973
    For code writing purposes, I mean its starting label. So you'd define a simple object like:

    Code (Text):
    1.  
    2. Obj_TitleANDKnuckles:
    3.         move.l  #Map_TitleANDKnuckles,mappings(a0)
    4.         move.w  #$E4C0,art_tile(a0)
    5.         move.w  #$120,x_pos(a0)
    6.         move.w  #$108,y_pos(a0)
    7.         move.w  #$80,priority(a0)
    8.         move.b  #$54,width_pixels(a0)
    9.         move.b  #$C,height_pixels(a0)
    10.         move.l  #Obj_TitleANDKnuckles_Display,(a0)
    11.  
    12. Obj_TitleANDKnuckles_Display:
    13.         move.w  (Player_1+y_pos).w,d0
    14.         addi.w  #$5C,d0
    15.         move.w  d0,y_pos(a0)
    16.         jmp (Draw_Sprite).l
    17.  
    This is the big &KNUCKLES on the title screen that I don't use. Note how it skips its initialisation routine once run by changing its own code pointer to Obj_TitleANDKnuckles_Display, so Process_Sprites will come straight back to that point in future, rather than using a routine counter and jump table.

    If you're creating it procedurally, you'd do something like:

    Code (Text):
    1.  
    2.         jsr (Create_New_Sprite).l
    3.         bne.s   +
    4.         move.l  #Obj_TitleANDKnuckles,(a1)
    5. +
    6.  
    As usual you can set anything else like x_pos(a1) and y_pos(a1) before the + if you want to, but there's no point with this object since it writes its own in anyway.

    If you have it in a level layout, you still give it an object ID by placing it in one of the lists I mentioned (add dc.l #Obj_TitleANDKnuckles like the other entries in those lists) and use that ID in the level layout. That much still works like it used to. But if you go and snoop in object RAM, you'll see its first four bytes are something like 00 00 49 6A, which is the ROM location of where the object code ended up. (Having your assembly generate a listing file as the Git disassemblies now do is really helpful for tracking this back to the actual code that object is running).
     
  14. MathUser

    MathUser

    3rd top wiki contributor Researcher
    2,101
    2
    18
    I enjoy these character in Sonic game hacks. Keep up the good work.
     
  15. E-122-Psi

    E-122-Psi

    Member
    2,130
    327
    63
    Thanx. I'll try. :P

    Concerning the Sonic 3 translation, I gave it a quick shot. I put it in the listings of both the 3 and Knuckles files too. So far it seems to be recognizing the object at least, but all it does is crash the game. I'm not fluent in Sonic 3 commands, is there anything in this that looks off here?:

    Code (ASM):
    1. Obj_Laser:
    2.     moveq   #0,d0
    3.     move.b  $24(a0),d0
    4.     move.w  Obj_Blob_Index(pc,d0.w),d0
    5.     jmp Obj_Blob_Index(pc,d0.w)
    6.  
    7. Obj_Blob_Index:
    8.     dc.w    Obj_Blob_Init-Obj_Blob_Index
    9.     dc.w    Obj_Blob_Move-Obj_Blob_Index
    10.     dc.w    Obj_Blob_Destroy-Obj_Blob_Index
    11.  
    12. Obj_Blob_Init:
    13.         move.l  #SME_0iwB5,mappings(a0) ; ($C)
    14.         move.w  #$79C,art_tile(a0)
    15.         move.w  #$2,priority(a0)
    16.         move.b  #$8,width_pixels(a0)
    17.         move.b  #$4,render_flags(a0)
    18.         move.b  #$4,y_radius(a0) ; $A  
    19.     move.l  Obj_Laser_Display,(a0)
    20.  
    21. Obj_Laser_Display:
    22.     lea (Player_1).w,a1
    23.     move.b  #$18,$30(a0)                ; distance laser will travel
    24.     move.w    #$C4,d0                       ; play sound
    25.     jsr    (Play_Sound).l
    26.     cmpi.b  #$29,$20(a1)
    27.     beq.s   Obj_Laser_DownwardNICOLE        ; if not, branch
    28.     move.w  #$660,$18(a0)               ; speed of laser
    29.     jmp Obj_Laser_ContNICOLE
    30. Obj_Laser_DownwardNICOLE:
    31.     move.w  #$660,$1A(a0)               ; speed of laser
    32. Obj_Laser_ContNICOLE:
    33.     add.w   #$10,x_pos(a0)
    34.     btst    #0,(Player_1).w
    35.     beq.s +
    36.     neg.w   $10(a0)
    37.     sub.w   #$20,x_pos(a0)
    38. +
    39.     lea (ArtSNK_Laser0).l,a1
    40.     move.w #$79C*$20,d2
    41.     jsr (SNKDec).l
    42.     addq.b  #2,$24(a0) ;
    43.  
    44. Obj_Blob_Move:
    45.     cmp.b   #$0,$30(a0)
    46.     beq.w   Obj_Blob_Destroy
    47.     sub.b   #$1,$30(a0)
    48.     jsr (loc_358A8).l
    49.     move.b  $40,$20(a0) ; lol
    50.    
    51.     clr.w d0
    52.     move.b mapping_frame(a0),d0
    53.     asl.w #$1,d0    ; *2 for correct offset
    54.     lea (LaserArtPointers).l,a1
    55.     adda.w (a1,d0.w),a1
    56.     move.w #$79C*$20,d2
    57.     jsr     (SNKDec).l
    58.    
    59.     lea (Ani_Laser).l,a1
    60.     jsr (Animate_Sprite).l
    61.     jsr (sub_FE6E).l ;enemy and monitor data
    62.     jmp (Draw_Sprite).l
    63.  
    64. Obj_Blob_Destroy:
    65.     clr.b   ($FFFFFFA4).w   ; clear NICOLE flag
    66.     jmp Delete_Current_Sprite
    67.    
    68. Ani_Laser:
    69.     dc.w laser0-Ani_Laser
    70. laser0: dc.b 3,0,1,1,2,2,3,3,$FD,0
    71.     even
    72.  
    73. SME_0iwB5: 
    74.         dc.w SME_0iwB5_8-SME_0iwB5, SME_0iwB5_12-SME_0iwB5 
    75.         dc.w SME_0iwB5_1C-SME_0iwB5, SME_0iwB5_26-SME_0iwB5
    76. SME_0iwB5_8:    dc.b 0, 1  
    77.         dc.b $F8, 5, 0, 0, 0, 0, $FF, $F8  
    78. SME_0iwB5_12:   dc.b 0, 1  
    79.         dc.b $F8, 5, 0, 0, 0, 0, $FF, $F8  
    80. SME_0iwB5_1C:   dc.b 0, 1  
    81.         dc.b $F8, 5, 0, 0, 0, 0, $FF, $F8  
    82. SME_0iwB5_26:   dc.b 0, 1  
    83.         dc.b $F8, 5, 0, 0, 0, 0, $FF, $F8  
    84.         even
    I can get most of the other coding needed from my Amy hack, so if I get this bit working, I could probably get a basic build of S3 Sally done fairly quick.
     
  16. Lilly

    Lilly

    Member
    2,305
    110
    43
    United States
    Shang Mu Architect
    Seriously enjoying this hack, E-122. Sally is doing a lot of things here to stand out from Amy in play style, and I'm liking the changes. (The disabled air cap leaves a lot of room for insane moves too, because after I fell in Chemical Plant Zone 2, I spindashed and jumped off a ramp to fly back above the water.)

    Although I think I'm going a little nuts with being able to shoot at things here. :specialed: I was camping at the rightmost totem-pole in Aquatic Ruin's boss while shooting at Eggman, and Sally's physics were pretty much disabled when the totems collapsed. I could walk around in mid-air, and it didn't stop until she jumped.

    I'm trying to remember if this is an issue in the vanilla game too, but here's a screenshot from playing on my DS with jEnesis.

    [​IMG]
     
  17. E-122-Psi

    E-122-Psi

    Member
    2,130
    327
    63
    It's likely to do with this bug here:

    http://info.sonicretro.org/SCHG_How-to:Fix_ARZ_Boss_Walking_on_Air_Glitch

    I'll try fixing it for a later update.
     
  18. E-122-Psi

    E-122-Psi

    Member
    2,130
    327
    63
    New revision uploaded:

    * Scan mode added. Like with S1, not a lot of objects to try it on, but effective enough when found.
    * Laser compatibility with WFZ entrance capsule added.
    * Some odd effects caused by laser reacting with objects fixed.
    * Odd cosmetic fixes.
    * Glitch that causes Sally to sometimes break objects by charging into them fixed.
    * Glitch that causes the projectile to collect rings fixed.
    * ARZ boss glitch which breaks Sally's gravity fixed.

    Remaining bugs:

    * Laser art is garbled in splitscreen.
    * Some art still doesn't transition properly with super mode.
    * Title screen glitches a little when skipped with Start button.
     
  19. Hayate

    Hayate

    Tech Member
    Don't know if you're still struggling with this, but there are a couple things I noticed:

    1. SST offsets have changed in S3&K, for example, routine should be 5(a0) not $24(a0). Have a look at this wiki page for more info (I refer to it so often it's the top result if I type 'I' in my address bar :v: )
    2. I'm a bit concerned about this:

    Code (Text):
    1.  
    2.         lea (ArtSNK_Laser0).l,a1
    3.         move.w #$79C*$20,d2
    4.         jsr (SNKDec).l
    5.         addq.b  #2,$24(a0) ;
    6.  
    I'm not familiar with the labels you're using, and SNKDec doesn't exist in the disasm I have, but many of the data loading routines do not work while in a level (for example, they can only be used on a menu screen, or when loading a level, but cannot be called by objects).

    I'm guessing you're trying to use DPLCs? In which case look at Sonic_Load_PLC, and the generic version Perform_DPLC for examples on how the game does it already. If you don't have those labels, loc_12CD6 and loc_8504A should go into the middle of them respectively. Hope this helps a bit!
     
  20. E-122-Psi

    E-122-Psi

    Member
    2,130
    327
    63
    Contest build added to the wiki. Not much new except a little bonus cheat:

    Play 03, 03, 03, 0B, 10, 10, 10 and 04 on the level select sound test for a hidden bonus.

    Sally in Sonic 1 is also updated, but since it has little but some rather minor bug and palette fixes, I'm not sure if it's worth noting.