don't click here

Personal help thread

Discussion in 'Engineering & Reverse Engineering' started by Blastfrog, Nov 19, 2011.

  1. Blastfrog

    Blastfrog

    See ya starside. Member
    EDIT: decided to turn this thread into a personal version of the basic answers and questions thread. The reason for this is because I have many questions, and don't want to flood the existing thread, as I want them to have their questions answered as well.



    Not sure if it's a good idea to make this it's own thread, but as it's own thread, it's more likely to get noticed than in the general hacking help thread. Sorry if this is kind of annoying being in the hacking forum, but I figured it would be more appropriate here than in the member's lounge

    I'm still a total novice at ASM, and while I have a basic understanding of ASM, I'm not at all familiar with the internal workings of the Sonic engine. I am fully capable of editing art and levels, and even music to some extent, but the code is what really gets me. Basically, I was wondering if there's any guru out there that would be willing to help a novice out a bit. (not hold my hand, I don't want that. I just need a little help getting off the ground, and having interactive examples and lessons to teach me how to get around in the Sonic engine)

    I know there's tutorials on the wiki, but I've used them and don't feel that I learned very much, besides just ASM, not actually explaining what the Sonic engine does and how. What I mean is that it doesn't really explain things on a larger scale (the whole picture), it only provides steps with how to do a specific task. Having an interactive teacher that explains why and how things work the way they do, rather than just show me steps to a solution, would work much better.

    Anyway, is there anyone out there willing to help? I'm not looking for someone to do the work for me, just kind of a hacking "mentor". I am willing to compensate you monetarily for your efforts (as long as it's low enough, I don't exactly have very much cash), if you feel it necessary. Again, I emphasize that I don't want to have my hand held, only a guide.

    I'd also like to point out that I prefer real time conversation (text or voice), as it allows me to ask questions and get answers more quickly and efficiently than PM or email.
     
  2. MarkeyJester

    MarkeyJester

    Original, No substitute Resident Jester
    2,192
    404
    63
    Japan
    I always find that the individuals who you're most likely looking for as a mentor, are those whom of which are too busy to help, of course, have you considered popping onto badnik.net on irc and asking in some of the public channels? A few people pop into #ssrg on a basis and ask a few questions there, and there are plenty of people around who usually break things down and explain them, I'm not sure about #retro (that's usually quite crowded and often you can't get a word in), but there are bound to be a whole load of public channels in general, where people will be more than friendly enough to help answer any questions you might have about the game engines as a whole.
     
  3. Blastfrog

    Blastfrog

    See ya starside. Member
    I'll consider popping into some of those channels, thanks for recommending them.

    Anyway, I've decided to turn this into a personal version of the basic answers and questions thread, as I have many questions and do not want to flood the existing thread, so that others have a chance of getting their questions answered.


    I'm creating a hack in Sonic 2 using the Xenowhirl disassembly. My questions are ordered from most to least priority.

    How would I go about recreating the Sonic Triple Trouble HUD in Sonic 2? I want to remove score entirely, and I want to add trailing 0's to the rings and lives counter. I want the rings counter to be fixed at 3 digits, and I want the lives counter to be fixed at 2 digits. I also only want the icon to remain of the lives counter, and not have the "x" or name in it. I'd also like to have it use the large 8x16 font instead of the small 8x8 font that it already uses. Also, how would I be able to have a spinning ring in the hud? And lastly, be able to just outright remove the Score Time Rings part of the HUD.

    Another question, how can I set Sonic Alone as the default player in Sonic 2?

    And lastly, how could I make the ring animation 8 frames instead, and change the animation speed to accommodate this?
     
  4. E-122-Psi

    E-122-Psi

    Member
    2,470
    612
    93
    The Life Icon can be editted easily in SonMapEd (the number tiles for the lives will be harder to edit however). HUD data I'm less knowledgeable about.

    As for ring animations, I'm not positive but there could be an animation script in the ASM that you can edit, make more sprites in SonMapEd and then add them onto the animation loop data. A speed level should be on there too, usually the first number after dc.b, make it smaller and it will take less frames to run.
     
  5. Blastfrog

    Blastfrog

    See ya starside. Member
    I'm having a difficult time finding the ring animation script using the search function. Oh well. Anyone know how to edit the HUD though? Or the default player? I want all games to be started with Sonic Alone by default, not Sonic and Tails.
     
  6. FraGag

    FraGag

    Tech Member
    Editing the HUD
    Editing the HUD is somewhat difficult. You can edit the mappings in SonMapEd, but there's no art file you can load because the art is dynamically refreshed on each frame. You can, however, take a savestate, extract the VRAM starting at $D940 (where the HUD patterns start in VRAM) from the savestate, and load that as the art file.

    Forcing leading zeroes on the HUD is done in the code. The HudUpdate subroutine updates the patterns in VRAM that are used the HUD sprite mappings. Just remove these lines to get leading zeroes for the score and rings (you probably don't care about the score since you want to remove it):
    Code (ASM):
    1.     tst.w   d2
    2.     beq.s   loc_4116A
    3.     move.w  #1,d4
    4.  
    5. loc_4116A:
    6.     tst.w   d4
    7.     beq.s   loc_41198
    8.  
    Here, d2 is the value of the current digit. When it encounters a digit that is not zero, it sets d4 to 1. Zeroes that come before d4 is set to 1 are left blank, and zeroes that come after d4 is set are drawn as "0". By removing these lines, we always draw all zeroes as "0". Since the rings counter is already programmed for 3 digits, you don't have anything else to do for the rings counter!

    For the lives counter, it's the same pattern, but elsewhere. Remove these lines:
    Code (ASM):
    1.     tst.w   d2
    2.     beq.s   loc_41314
    3.     move.w  #1,d4
    4.  
    5. loc_41314:
    6.     tst.w   d4
    7.     beq.s   Hud_ClrLives
    8.  
    To get an animated ring in the HUD, I'd create a new object type (or add a routine to an existing object, like Obj25) that uses the same art_tile, mappings and animation code as the debug ring object type (Obj25) or scattering ring object type (Obj37), but without collision and with screen-space coordinates.

    Default player configuration
    There are 2 variables controlling the player configuration: Player_option and Player_mode. The value of Player_option is the value selected on the options screen. Player_mode is the value actually used during a level. When a level is started, if the game is playing a demo or in 2P versus mode, Player_mode is forced to 0 (Sonic and Tails); otherwise, the value of Player_option is used.

    The value of Player_option is never explicitly set; it is set to 0 when the game clears most of the RAM on startup. I think the best place to set it is just before the MainGameLoop label:
    Code (ASM):
    1.     move.b  #GameModeID_SegaScreen,(Game_Mode).w    ; => SegaScreen
    2.     move.w  #1,(Player_option).w    ; +++
    3. ; loc_394:
    4. MainGameLoop:
    5.     move.b  (Game_Mode).w,d0
    This way, it's set to Sonic alone on reset, but it won't override the choice the player made on the options screen.

    Ring animation
    The ring animation is controlled globally; all rings display the same frame at the same time. The Rings_anim_frame variable specifies what's the current frame. The ChangeRingFrame subroutine controls that variable, and uses Rings_anim_counter to control the animation speed. This is the original code:
    Code (ASM):
    1.     subq.b  #1,(Rings_anim_counter).w
    2.     bpl.s   +
    3.     move.b  #7,(Rings_anim_counter).w
    4.     addq.b  #1,(Rings_anim_frame).w ; animate rings in the level (obj25)
    5.     andi.b  #3,(Rings_anim_frame).w
    6. +
    7.  
    When Rings_anim_counter becomes negative, its value is reset to 7 and the current frame is incremented by 1. The ANDI instruction then restricts the value to the 0-3 range. If you want to double the number of frames while keeping the same duration for an animation cycle, you'll need to reset Rings_anim_counter to 3 and use andi.b #7,(Rings_anim_frame).w. Then, you'll have to add frames between the existing frames in the mappings (obj37_a.bin). Note that this will move the sparkle frames, so you'll have to fix the animation script for it (Ani_Ring). Change dc.b 5,4,5,6,7,$FC to dc.b 5,8,9,$A,$B,$FC in Ani_Ring to reference the new frame numbers of the sparkle frames.

    Spilled rings use a separate counter: Ring_spill_anim_counter. The algorithm to control it is a bit more complicated:
    Code (ASM):
    1.     tst.b   (Ring_spill_anim_counter).w
    2.     beq.s   +   ; rts
    3.     moveq   #0,d0
    4.     move.b  (Ring_spill_anim_counter).w,d0
    5.     add.w   (Ring_spill_anim_accum).w,d0
    6.     move.w  d0,(Ring_spill_anim_accum).w
    7.     rol.w   #7,d0
    8.     andi.w  #3,d0
    9.     move.b  d0,(Ring_spill_anim_frame).w ; animate scattered rings (obj37)
    10.     subq.b  #1,(Ring_spill_anim_counter).w
    11. +
    12.  
    Change rol.w #7,d0 to rol.w #6,d0 and change andi.w #3,d0 to andi.w #7,d0. The first change should preserve the animation speed and the second change will use all 8 frames.
     
  7. Blastfrog

    Blastfrog

    See ya starside. Member
    Thank you, this worked out perfectly. I cannot find Ani_Ring in the disassembly. I downloaded it off of the disassembly page on the wiki, so it may be out of date and have a different label, perhaps?

    Also, how do I expand the art tiles for the rings? I don't know how to increase the file size of the art to add new tiles, and I'm worried about how it's going to fit into VRAM. The only amount of space that I need is 8 new 8x8 tiles (as in 2 16x16 tiles, I'm trying to port Chaotix's enhanced ring animation).

    My disassembly also lacks obj25.bin and obj37.bin in the sprite mappings folder, yet rings still appear in the rom. What could the mappings file be named?
     
  8. FraGag

    FraGag

    Tech Member
    Ani_Ring might be named byte_1237A in your disassembly. As for increasing the file size, it depends on the program you use to edit the art. If you're afraid the art might not fit in VRAM, maybe you could use DPLCs to reload only the visible frame (separately for each counter), while keeping the sparkle frames as they are currently. The mappings should be named obj37_a.bin in mappings/sprite; I don't think the file names changed since the 2007 disassembly.
     
  9. Blastfrog

    Blastfrog

    See ya starside. Member
    It's almost perfect, but still a few kinks. The ring animation now works perfectly, but only on rings that have been spilled. The regular rings still have the old mappings, it doesn't appear to use obj37_a.bin, only the spilled rings appear to.

    Also, it's still displaying frames 5-8 instead of 9-12 when I pick up a spilled ring, but it does display frames 9-12 on a regular ring when I pick it up (actually, come to think of it, it's probably still 5-8, since it's using the old mappings). Here's the code I have so far:

    ; ===========================================================================
    byte_1237A:
    dc.b 0

    dc.b 2 ; 1
    dc.b 5 ; 2
    dc.b 8 ; 3
    dc.b 9 ; 4
    dc.b $A ; 5
    dc.b $B ; 6
    dc.b $FC ; 7
    ; -------------------------------------------------------------------------------


    Lastly, it does cut into other tiles in the VRAM, but it conveniently only cuts into the SCORE TIME RINGS text, which I planned on removing anyway. I'll worry about the HUD later, I want to get these rings fixed first.

    Also, thanks for taking the time to help an ASM-illiterate moron such as myself. :P
     
  10. FraGag

    FraGag

    Tech Member
    The rings in Sonic 2 aren't objects like in Sonic 1. Instead, they're handled by the "rings manager". The rings laid out in the ring layout use the mappings in mappings/sprite/Rings.bin (which are not exactly sprite mappings, annoyingly; the number of sprites is missing (a single sprite is assumed)); you'll have to edit those to add your new frames (you can copy the mappings from your edited obj37_a.bin).

    If the svn disassembly isn't lying, this line sets the frame and destruction timer when a ring is collected:
    Code (ASM):
    1. loc_17148:
    2.     move.w  #$604,(a1)
    Change $604 to $608 to use the sparkle frames in their new location.
     
  11. Blastfrog

    Blastfrog

    See ya starside. Member
    Two problems. One, Rings.bin doesn't exist in /mappings/sprite/ in my copy, nor anything similarly named. Second, when I made that code modification ($604 to $608), the most bizarre and unexpected thing happened: whenever you pick up a ring, it simply disappears without the sparkles, and then random garbled crap just flashes all over the screen until you walk off screen from where you picked the ring up.

    When I reverted it back to $604, the problem went away.

    [​IMG]


    Ignore the HUD garbling, I don't really care that it's that messed up, it's going to be revamped and replaced anyway.

    Speaking of the HUD, how can I change the position of the HUD elements? I want to be able to move the score number completely offscreen, or simply outright remove it if possible. I then want to adjust the X and Y positions of the lives, rings, and time numbers on screen. Lastly, I need to have the lives number use the big font instead of the small font.

    Note that I don't want to change the position of the SCORE TIME RINGS object, but rather just have it be completely static (no animations, just one, consistent state).
     
  12. FraGag

    FraGag

    Tech Member
    That's because you need to change the mappings before using them! :specialed:

    The mappings are at off_1736A in the 2007 disassembly. The first four entries are the ring frames, and the next four entries are the sparkle frames.

    The whole HUD is one big mapping (hud_a.bin). These mappings have 4 frames: the 2nd, 3rd and 4th frame have the time and/or rings counter in red. Just remove the "pieces" you don't want from each frame and move the other pieces where you want them to appear.

    To get larger numbers for the lives counter, replace $5FA00003 in the Hud_Lives2 routine with $5F800003, and replace the Hud_Lives routine (up to the ; End of function Hud_Lives line) with this:
    Code (ASM):
    1. Hud_Lives:
    2.     move.l  #$7B800003,d0
    3.     moveq   #0,d1
    4.     move.b  (Life_count).w,d1
    5.  
    6. loc_412EE:
    7.     lea Hud_10(pc),a2
    8.     moveq   #1,d6
    9.     moveq   #0,d4
    10.     lea Art_Hud(pc),a1
    11.     move.l  d0,4(a6)
    12. ; loc_412FA:
    13. Hud_LivesLoop:
    14.     moveq   #0,d2
    15.     move.l  (a2)+,d3
    16. -   sub.l   d3,d1
    17.     bcs.s   loc_4130A
    18.     addq.w  #1,d2
    19.     bra.s   -
    20. ; ===========================================================================
    21.  
    22. loc_4130A:
    23.     add.l   d3,d1
    24.     tst.w   d2
    25.     beq.s   loc_41314
    26.     move.w  #1,d4
    27.  
    28. loc_41314:
    29.     tst.w   d4
    30.     beq.s   Hud_ClrLives
    31.  
    32. loc_41318:
    33.     lsl.w   #6,d2
    34.     lea (a1,d2.w),a3
    35.     rept 16
    36.     move.l  (a3)+,(a6)
    37.     endm
    38.  
    39. loc_4132E:
    40.     dbf d6,Hud_LivesLoop ; repeat 1 more time
    41.     rts
    42. ; ===========================================================================
    43. ; loc_4133A:
    44. Hud_ClrLives:
    45.     tst.w   d6
    46.     beq.s   loc_41318
    47.     moveq   #$F,d5
    48. ; loc_41340:
    49. Hud_ClrLivesLoop:
    50.     move.l  #0,(a6)
    51.     dbf d5,Hud_ClrLivesLoop
    52.     bra.s   loc_4132E
    53. ; End of function Hud_Lives
    If you don't need the HUD mapping frames with the TIME and/or RINGS in red, you can remove those frames altogether (Edit > Sprite > Delete Sprite in SonMapEd). However, if you do that, the game must not try to use them anymore; to do that, remove these lines under loc_40804:
    Code (ASM):
    1.     btst    #3,($FFFFFE05).w
    2.     bne.s   BranchTo_loc_40836
    3.     cmpi.b  #9,(Timer_minute).w
    4.     bne.s   BranchTo_loc_40836
    5.     addq.w  #2,d1
    6.  
    7. BranchTo_loc_40836
    8.     bra.s   loc_40836
    9. ; ===========================================================================
    10.  
    11. loc_40820:
    12.     moveq   #0,d1
    13.     btst    #3,($FFFFFE05).w
    14.     bne.s   loc_40836
    15.     addq.w  #1,d1
    16.     cmpi.b  #9,(Timer_minute).w
    17.     bne.s   loc_40836
    18.     addq.w  #2,d1
    19.  
    20. loc_40836:
     
  13. Blastfrog

    Blastfrog

    See ya starside. Member
    When I remove those lines of code to make the STR object not animate, it doesn't build, complaining that loc_40820 cannot be found (because it was removed and is still being referenced a few lines back). I reverted it so that it could build again, and found a cheap-ass solution of just duplicating the frames, which is, well, hacky. :P Despite the cheapness of the solution, I don't mind using it, but it's probably still a good idea to have things done "cleanly".

    Also, while that code that's supposed to make the lives counter use the large numbers instead does work, it's back to not having leading zeroes.

    The HUD otherwise works perfectly. (I decided against having the ring in the HUD animate)

    [​IMG]


    Anyway, I got the rings to function perfectly now, except one thing. While all animations on both kinds of rings are functioning perfectly (including the sparkles), garbled shit still moves across the screen when I pick up a normal ring when that one variable is set to $608.
     
  14. FraGag

    FraGag

    Tech Member
    Oops, take this Hud_Lives instead:
    Code (ASM):
    1. Hud_Lives:
    2.     move.l  #$7B800003,d0
    3.     moveq   #0,d1
    4.     move.b  (Life_count).w,d1
    5.  
    6. loc_412EE:
    7.     lea Hud_10(pc),a2
    8.     moveq   #1,d6
    9.     moveq   #0,d4
    10.     lea Art_Hud(pc),a1
    11.     move.l  d0,4(a6)
    12. ; loc_412FA:
    13. Hud_LivesLoop:
    14.     moveq   #0,d2
    15.     move.l  (a2)+,d3
    16. -   sub.l   d3,d1
    17.     bcs.s   loc_4130A
    18.     addq.w  #1,d2
    19.     bra.s   -
    20. ; ===========================================================================
    21.  
    22. loc_4130A:
    23.     add.l   d3,d1
    24.     lsl.w   #6,d2
    25.     lea (a1,d2.w),a3
    26.     rept 16
    27.     move.l  (a3)+,(a6)
    28.     endm
    29.  
    30. loc_4132E:
    31.     dbf d6,Hud_LivesLoop ; repeat 1 more time
    32.     rts
    33. ; End of function Hud_Lives
    I knew I forgot something (except for the lives counter, I didn't test any of these things :P). There's one more line to change under loc_16FE8:
    Code (ASM):
    1.     cmpi.b  #8,1(a1)
    Change the 8 to $C. $C is one more than the last frame ID to use in the sparkling animation.
     
  15. Blastfrog

    Blastfrog

    See ya starside. Member
    Thanks, that did the trick.

    Where are the settings for how many frames Sonic's walking animation are, and their duration? I want to set the number of frames for walking to 6, and the duration to whatever it was for walking in Sonic 1. I remember doing this about a year ago on my own, but I can't remember where those settings are now. I don't mind having the last 2 frames of each angle of the walking animation going unused, I don't really want to bother with shifting the frames of all the animations at the moment just because I made a tweak somewhere, since it's much more complex than a small number of frames like the rings.


    Also, there appears to be a small bug caused by some of the recent changes. Whenever I land a hit on the boss, the black index on the palette remains white instead of reverting to black again after the black and white flashing is done.
     
  16. Blastfrog

    Blastfrog

    See ya starside. Member
    Dunno if double posting is any more tolerated nowadays than it was in the Simon days, but the reason I'm double posting is because this is a rather separate issue, and most people have probably already read my previous post, so editing it wouldn't help much.

    SonMapEd won't import sprites correctly. It still imports them, but despite the fact that my images that I'm importing match the palette precisely, it keeps assigning my transparent color to some solid color. (I'm using a color close to cyan as transparency, and no colors are even remotely similar) How do I go about making the damn thing cooperate?

    [​IMG]

    [​IMG]

    [​IMG]
     
  17. 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)
    Go to 'Settings' -> 'Image Importing' and make sure 'Assume Corner is Background' is unchecked, and that 'Direct/Nearest Match to Current Palette' is checked.
     
  18. Blastfrog

    Blastfrog

    See ya starside. Member
    It unfortunately is still turning to grey. It did work when I checked "Assume Corner is Background" and I changed the corner to cyan. Oh well, I guess that will have to do.

    EDIT: Anyway, back to the subject of ASM. Some more features that I want to add to this hack, in order of most to least priority:

    1. How do I implement that feature seen in other hacks where if you press the jump button in midair, Sonic will start spinning?

    2. Also, how do I add Sonic CD style camera effects when the player is going very fast?

    3. How can I rip Sonic CD FM sound effects and convert them to a format that can be used by Sonic 2's sound driver?

    4. How do I add some elements of Sonic CD style physics? What I'm looking to do is make it so Sonic can control his horizontal trajectory in the air like in Sonic CD, move in the same way while under water (kinda like how when you spring out of the water, you go much faster once you are in air than in water), and cap Sonic's gravity to 16 pixels per frame?
     
  19. Blastfrog

    Blastfrog

    See ya starside. Member
    The above post isn't as important as getting Sonic's walking animation changed. How can I make Sonic only use the first 6 frames of animation when walking, and go at the same speed as Sonic 1's walking animation speed? I also want to fix that bug where the first frame of animation in the walking animation only lasts one screen frame when it initializes.