don't click here

Basic Questions & Answers thread

Discussion in 'Engineering & Reverse Engineering' started by Tweaker, May 29, 2008.

  1. Aerosol

    Aerosol

    Not here. Moderator
    11,164
    573
    93
    Not where I want to be.
    Sonic (?): Coming summer of 2055...?
    That's actually more or less what I have now. The flag is being set, but Sonic isn't doing any homing. And the flag is being set before I even press jump a second time.
     
  2. flamewing

    flamewing

    Emerald Hunter Tech Member
    1,161
    67
    28
    France
    Sonic Classic Heroes; Sonic 2 Special Stage Editor; Sonic 3&K Heroes (on hold)
    There was another error on the code regarding the button pressed -- you were checking the held state ($FFFFF604), not the newly pressed state ($FFFFF605). Another fix would be to use
    Code (ASM):
    1.     move.w ($FFFFF604).w, d0; HOMING
    2.     and.w #$70, d0; did you just press a button?
    instead of shifting to $FFFFF605.

    Edit: in fact, you may want to consider using $FFFFF602 and $FFFFF603 instead of $FFFFF604 and $FFFFF605 as these respect the control locked flag.
     
  3. Aerosol

    Aerosol

    Not here. Moderator
    11,164
    573
    93
    Not where I want to be.
    Sonic (?): Coming summer of 2055...?
    I started over with a clean asm.

    Code (ASM):
    1.     cmp.w   y_vel(a0),d1    ; is Sonic going up faster than d1?
    2.     ble.s   +       ; if not, branch
    3.     move.b  (Ctrl_1_Held_Logical).w,d0
    4.     andi.b  #button_B_mask|button_C_mask|button_A_mask,d0 ; is a jump button pressed?
    5.     bne.s   +       ; if yes, branch
    6.     move.w  d1,y_vel(a0)    ; immediately reduce Sonic's upward speed to d1
    7. +
    8.     move.b  ($FFFFF604).w,d0
    9.     andi.b  #$70,d0 ; is a jump button pressed newly this frame?
    10.     ;tst.b  y_vel(a0)       ; is Sonic exactly at the height of his jump?
    11.     beq.s   Sonic_SetHomeFlag   ; if yes, set the homing flag.
    12.     rts
    then

    Code (ASM):
    1. Sonic_SetHomeFlag:
    2.     move.b #1,($FFFFF100).w
    same behaviour. $F100 is being set to 1 before I even press jump a second time. Where am I going wrong here?
     
  4. flamewing

    flamewing

    Emerald Hunter Tech Member
    1,161
    67
    28
    France
    Sonic Classic Heroes; Sonic 2 Special Stage Editor; Sonic 3&K Heroes (on hold)
    This:
    Code (ASM):
    1.  
    2.     move.b  ($FFFFF604).w,d0
    3.     andi.b  #$70,d0 ; is a jump button pressed newly this frame?
    4.     ;tst.b  y_vel(a0)       ; is Sonic exactly at the height of his jump?
    5.     beq.s   Sonic_SetHomeFlag   ; if yes, set the homing flag.
    Try this instead:
    Code (ASM):
    1.  
    2.     move.b  (Ctrl_1_Press_Logical).w,d0
    3.     andi.b  #button_B_mask|button_C_mask|button_A_mask,d0 ; is a jump button pressed newly this frame?
    4.     ;tst.b  y_vel(a0)       ; is Sonic exactly at the height of his jump?
    5.     bne.s   Sonic_SetHomeFlag   ; if yes, set the homing flag.
     
  5. Aerosol

    Aerosol

    Not here. Moderator
    11,164
    573
    93
    Not where I want to be.
    Sonic (?): Coming summer of 2055...?
    Faaaantastic.

    Mind explaining why that worked so that I may be able to solve similar problems on my own in the future?
     
  6. flamewing

    flamewing

    Emerald Hunter Tech Member
    1,161
    67
    28
    France
    Sonic Classic Heroes; Sonic 2 Special Stage Editor; Sonic 3&K Heroes (on hold)
    This:
    Specifically: the bytes at $FFFFF602 and $FFFFF604 contain all buttons being pressed in this frame and all buttons being held from a previous frame; the bytes at $FFFFF603 and $FFFFF605 contain only the buttons being pressed in the current frame (I.e., new button presses). If you access the words at $FFFFF602 and $FFFFF604, you can access all of them together. Since the 68k is big-endian, the low byte is the newly pressed buttons while the high byte is the newly pressed + held buttons.

    That and the inverted condition.
     
  7. Aerosol

    Aerosol

    Not here. Moderator
    11,164
    573
    93
    Not where I want to be.
    Sonic (?): Coming summer of 2055...?
    Alrighty. Thanks alot.
     
  8. GT Koopa

    GT Koopa

    Member
    2,023
    18
    18
    Elgin, IL
    Flicky Turncoat DX, T.L.W.S. Vs M.G.W.
    While my previous question remains here, I have a new one as well.

    So Sonic 2 bosses. I want to an action to happen when it is hit, but how do I go about doing that? I mean I know where I am going to put it when I find it, however I can't find where the "hit" code is. Is it out of the bosses normal asm and is a subroutine somewhere? I'll keep checking, but if anyone knows, tell me.
     
  9. FraGag

    FraGag

    Tech Member
    Simply remove all operations done on bit 0 of render_flags (btst, bchg, bset, bclr) and the logic around them (be especially careful about the btsts, because the following branch instruction depends on it!).

    The normal collision code also handles collision with the bosses. Bosses are much like normal enemies, except for the hit counter: if it's not zero, it's decremented and the object's collision is removed. Each boss is programmed to flash when hit, so if you want something to happen when it's hit, just add code where the flashing is done. If you're starting from scratch, just test collision_flags(a0) and do something when it's 0. The original bosses start a timer and alternate a palette color between black and white, then when the timer has run out, restore the collision.

    If you want to learn how to program bosses, you might find the Sonic 1 bosses easier to learn from, because they're simpler, so there's less code to go through. There aren't many differences between both games; one that particularly stands out is that most bosses use objoff_A(a0) instead of routine(a0) for the main routine counter. I don't really know why; maybe $24(a0) is used for something else, but I didn't investigate this. Other people here might be able to answer this. There's also some setup with global variables and boss IDs, but I don't know how it works or how it's used.
     
  10. GT Koopa

    GT Koopa

    Member
    2,023
    18
    18
    Elgin, IL
    Flicky Turncoat DX, T.L.W.S. Vs M.G.W.
    Oh I know. I am trying to learn how to make bosses/minibosses from scratch in Sonic 1. There is also my boss at the end of Pocky Fields, which in the end is still based on the original code. In Sonic 2 I am just tweaking/learning how the code works. In the end I will have all the bosses in Sonic 2 tweaked in time for the release.

    Thank you in advance. Now lets see if I can try to understand how everything works now.
     
  11. Aerosol

    Aerosol

    Not here. Moderator
    11,164
    573
    93
    Not where I want to be.
    Sonic (?): Coming summer of 2055...?
    I've finally got homing attack activating and behaving properly. Well...about that behaving properly part...

    Right now, Sonic is targeting whatever at $FFFFB400 in memory. Obviously, this isn't right. I've looked at the object pointer list, and the only thing I can think to do is write a check for each and every type of badnik, but that just seems bloated. Anyone can think of a better way to do this?
     
  12. FraGag

    FraGag

    Tech Member
    Check the collision property of an object. If it's between 0 and $3F (that is, less than $40), it's an object with "enemy" collision, so it's a good target. You will probably also want to target monitors; check for the monitor's ID ($26) or collision property = $46.
     
  13. Aerosol

    Aerosol

    Not here. Moderator
    11,164
    573
    93
    Not where I want to be.
    Sonic (?): Coming summer of 2055...?
    Oh I forgot to mention, this is Sonic 2.
     
  14. GT Koopa

    GT Koopa

    Member
    2,023
    18
    18
    Elgin, IL
    Flicky Turncoat DX, T.L.W.S. Vs M.G.W.
    More on the Sonic 2 "hit and boss will do stuff" code.

    Code (ASM):
    1. loc_31D24:
    2.     lea (Normal_palette_line2+2).w,a1
    3.    
    4.    
    5.     cmpi.w #0,render_flags(a0)
    6.     beq.s Smokey
    7.    
    8.     move.w  #-360,($FFFFF758).w ;Go right
    9.     bra.w Smokey2
    10.    
    11. Smokey:
    12.     move.w  #360,($FFFFF758).w ;Go left
    13.    
    14. Smokey2:       
    15.     moveq   #0,d0
    16.     tst.w   (a1)
    17.     bne.s   loc_31D32
    18.     move.w  #$EEE,d0
    Here is the code I am using. For some reason the boss will always go to the left when hit.
     
  15. MainMemory

    MainMemory

    Kate the Wolf Tech Member
    4,759
    341
    63
    SonLVL
    I need to get Sonic to jump backwards in addition to upwards, add an extra animation that displays frame D6, and make a homing attack. And I'm pretty sure I can't do any of those on my own.

    Edit: Sonic 2 2005 disasm
     
  16. FraGag

    FraGag

    Tech Member
    Same difference. The collision property is collision_flags(aX).

    Why are you checking render_flags? You should be checking collision_flags.
     
  17. GT Koopa

    GT Koopa

    Member
    2,023
    18
    18
    Elgin, IL
    Flicky Turncoat DX, T.L.W.S. Vs M.G.W.
    Ugh. I starting to think that this just won't work.

    Not only does cmpi.w #$0,collision_flags(a0) or tst.b collision_flags(a0) not work right (maybe a branching issue?), but -everytime- the boss is hit in mid move he moves farther.

    All I want to do is have the casino night zone boss stop at the ends (which I have done already) AND move again in the correct direction when hit, and then stop again at the other side.

    I mean if I can figure out how the boss does the bypass code regularly I guess I could fix that.
     
  18. FraGag

    FraGag

    Tech Member
    Is it a word or a byte? Make up your mind! (It's a byte.)
     
  19. Aerosol

    Aerosol

    Not here. Moderator
    11,164
    573
    93
    Not where I want to be.
    Sonic (?): Coming summer of 2055...?
    Here I am again!

    So I did some research and, while this is probably obvious to everyone else, I have discovered that badniks are not always loaded at $B400. At some point, that becomes a bridge stake in EHZ. I can very well program the game to ignore targets that aren't badniks at $B400, but I need a way to be able to detect any object when it's loaded into memory, so that I can test it.

    Is there an example of the game doing something like this (in the Sonic 2 SVN disasm) so I can learn from it? If not...well what's the best way to detect which objects the game has loaded into memory?
     
  20. Xenowhirl

    Xenowhirl

    Tech Member
    175
    0
    0
    A good example is the routine called "RunObjects" which loops through all the objects and does something to each one. Copying that method and doing a bunch of branch checks on the ID and routine of each object (or checking the collision properties makes sense) is probably the easiest way, but I wouldn't say it's the best way. An alternative is to set a global flag for the frame and make each individual object's code check the flag and call some routine of yours if it's set, which makes it easier to get specific about which objects should be affected, but could make some of the other code harder to write. Another method is to maintain a list of loaded badniks that you update whenever a badnik gets created or deleted, and loop through only that list.