Help on respawning objects

Discussion in 'Discussion and Q&A Archive' started by redhotsonic, Dec 11, 2011.

Thread Status:
Not open for further replies.
  1. redhotsonic

    redhotsonic Also known as RHS Member

    Joined:
    Aug 10, 2007
    Messages:
    2,969
    Location:
    England
    Hello, all. As some of you may know, in my hack, when the character dies, the level zooms back to the beginning rather than restarting itself (similar to how 2player mode works). To do this a lot needed changing.


    I thought of everything and made it clear your ring count, and load the saved time, save position, music (so if you died when invincible, the music goes back to the lvel music), etc etc.


    The only problem is that I can't seem to make all the rings/object respawn. I've tried making the restart routine jump (to subroutine) to:

    • (RunObjects).l
    • (BuildSprites).l
    • (loc_17AA4).l [object placement engine]


    I've even tried taking snippets from these subroutines. Whatever I try, either nothing happens, or the game locks up.


    Look at this



    (only first 25 seconds needs to be seen for this help). Sonic dies and he respawns perfectly, and so does the running object, but notice the rings haven't. The only reason why the running object has come back is because Sonic is so far away, so it naturally comes back. Rings naturally don't.


    Now, look at this video. Sonic falls down and jumps on the moving platform, but immediately jumps off and dies. He gets respawned to the last checkpoint, and jumps down again, but the platform hasn't respawned because Sonic is too close. Notice again, the rings haven't spawned either.


    If it helps, here is my level restart routine that gets called when you die.


    Any help or advice would be greatly appreciated. Cheers!
     
  2. SpirituInsanum

    SpirituInsanum Well-Known Member Member

    Joined:
    Feb 11, 2010
    Messages:
    642
    Do you clear the destroyable object state table?
     
  3. redhotsonic

    redhotsonic Also known as RHS Member

    Joined:
    Aug 10, 2007
    Messages:
    2,969
    Location:
    England
    If you mean if I've tried messing round with (Object_Respawn_Table).w, everytime I tried with that, the game locked up.
     
  4. SpirituInsanum

    SpirituInsanum Well-Known Member Member

    Joined:
    Feb 11, 2010
    Messages:
    642
    So, that's the problem, now finding a solution is another problem xD


    The game seems to do it like this in s1:



    lea (Object_Respawn_Table).w,a2
    move.w #$101,(a2)+


    move.w #$5E,d0


    OPL_ClrList:


    clr.l (a2)+


    dbf d0,OPL_ClrList ; clear pre-destroyed object list



    Is it what you tried?
     
  5. redhotsonic

    redhotsonic Also known as RHS Member

    Joined:
    Aug 10, 2007
    Messages:
    2,969
    Location:
    England
    Not quite, I tried something similar.


    Your bit there you just posted kinda works. The objects all respawn when you die, unless you died near it and got respawned by it (for example, that platform still doesn't respawn in this video if you died next to it and respawned by it). I'm guessing because the platform hasn't actually been destroyed. If you died far away and get respawned, it is back.


    None of things respawn still, so your bit hs helped a little bit.
     
    Last edited by a moderator: Dec 11, 2011
  6. SpirituInsanum

    SpirituInsanum Well-Known Member Member

    Joined:
    Feb 11, 2010
    Messages:
    642
    That was expected, at least it won't crash.


    So now, you need not only that, but also to force the game to reset all the objects in memory and reload the ones that were skipped because they were destroyed.


    By the way, when you tried with the object placement routine, did you reset it? In the disassembly I have it has a routine counter ( addq.b #2,(Obj_placement_routine).w ).
     
  7. redhotsonic

    redhotsonic Also known as RHS Member

    Joined:
    Aug 10, 2007
    Messages:
    2,969
    Location:
    England
    I swear I tried that before:



    clr.b (Obj_placement_routine).w



    It's now working, maybe it's because of your new addition before.


    Everything is now getting respawned by the looks of it, no errors yet. It's just the rings now, they still do not respawn. Maybe I should of mentioned I ported the S3K ring manager into my hack =P


    EDIT: Spellings.
     
    Last edited by a moderator: Dec 11, 2011
  8. SpirituInsanum

    SpirituInsanum Well-Known Member Member

    Joined:
    Feb 11, 2010
    Messages:
    642
    Remove it and you'll know... ^^'


    Great to see you got it working anyway.


    I don't know much about S3K's ring manager, but it has its own status table, so it's probably a similar solution.
     
  9. redhotsonic

    redhotsonic Also known as RHS Member

    Joined:
    Aug 10, 2007
    Messages:
    2,969
    Location:
    England
    Ok, having more time to test it properly, both of these help, but not correctly.

    This makes all objects respawn, unless you're respawned near it. Like that platform for example. Another example is on one of my levels, their is a monitor near a checkpoint. I destroyed that monitor. When I died and respawned by the checkpoint, the monitor didn't get respawned because Sonic is too close.

    This makes all objects respawn regardless, so if I died close to that platform or that monitor, it WILL respawn. Which is good, but anything you havn't destroyed yet, there will be double of (because it respawned again). So elsewhere, when hitting a 10ring monitor, there will be another right behind it, or two badniks in the same place, etc.


    EDIT: I tried



    clr.b (Ring_Positions).w



    for the rings (also tried clr.w and clr.l). No effect whatsoever.
     
    Last edited by a moderator: Dec 12, 2011
  10. SpirituInsanum

    SpirituInsanum Well-Known Member Member

    Joined:
    Feb 11, 2010
    Messages:
    642
    You have to destroy all the existing objects (clear memory from $FFFFB400 to $FFFFD5FF in S2, but I don't know the name of the equates), which will reset their position unfortunately.


    There may be a way to avoid this problem but it's a little complicated. You'd have to check if the object has been destroyed, and if it hasn't, don't reload it. But in order to do that you need to know how the entry number in the destroyable object table is given. If I understood correctly it's related to their order in the object position array, if you have an S1 disassembly find OPL_MakeItem, and see the d2 moved in $23(a1), that d2 is the variable you need (I think it's always the same for a particular object, but you may need to check this in the RAM for an object before and after respawning). The equivalent routine in S2 should be at the bottom of the object placement engine. Problem: if I'm wrong about that number being always the same for one particular object, it probably won't work.


    So the idea is to read the number from the objects that are still in memory (an object that has been destroyed shouldn't be in memory anymore, I can't think of any case of a child object, like an explosion, keeping the id of its parent). Then, once you have that number, put it in a temporary array, and on the reloading object routine, skip every entry from the level's object position array that is in the temporary array.


    It should work...


    I have to admit I have no idea of how slow it would be. There may be other solutions though.


    I didn't look further into this part yet, so I can't help much.
     
    Last edited by a moderator: Dec 12, 2011
  11. redhotsonic

    redhotsonic Also known as RHS Member

    Joined:
    Aug 10, 2007
    Messages:
    2,969
    Location:
    England
    Yes, I was thinking of comparing if a certain object had been destroyed and if so, respawn it.


    What I have noticed is that the command:



    clr.b (Obj_placement_routine).w




    Objects that are far away from you do not double up, only the ones that are close to you. So it seems like a certain radius.


    EDIT: Progress! I managed to make the rings respawn! And they do not have the same problem as the objects do! Just the objects that need sorting now. The only solution I've got for the objects is to move them away from the starting/check point. But only temporarily.


    Another solution is just before the command to respawn all objects regardlessly, is to delete ALL objects. So, it deletes all objects, respawns them all, respawns the rings, then Sonic reappears then play-on. That way, nothing will duplicate and their positions will not be removed either. I just need a bit of help on how to delete all objects.
     
    Last edited by a moderator: Dec 12, 2011
  12. SpirituInsanum

    SpirituInsanum Well-Known Member Member

    Joined:
    Feb 11, 2010
    Messages:
    642
    If you want to delete all the objects, clear data from FFB400 to FFD5FF. That's 21FF bytes in hex, 880 long words, so the result should be something like this:




    lea ($FFFFB400).w,a1


    moveq #0,d0


    move.w #$87F,d1


    @loop:


    move.l d0,(a1)+


    dbf d1,@loop ; clear object RAM



    Again, I don't know the name of the equates, you may want to replace the address.
     
  13. redhotsonic

    redhotsonic Also known as RHS Member

    Joined:
    Aug 10, 2007
    Messages:
    2,969
    Location:
    England
    That ALMOST worked, but it just needs a little tweaking, which I should be able to do. I tried:



    lea ($FFFFB400).w,a1
    moveq #0,d0


    move.w #$87F,d1


    @loop:


    move.l d0,(a1)+


    dbf d1,@loop ; clear object RAM



    Followed by:



    clr.b (Obj_placement_routine).w



    And within a flash, everything deleted itself and reappeared again. No duplications, no failed respawning. The only problem is, Tails' Tails does not respawn. So half the time, he has no tails =P


    So basically, I need to up the $FFFFB400, so going to tweak it now and get back to you. Cheers.
     
  14. SpirituInsanum

    SpirituInsanum Well-Known Member Member

    Joined:
    Feb 11, 2010
    Messages:
    642
    Maybe Tails's tails don't have a static address in memory, I don't know how S2 deals with it (neither did I ever tried to know how it works xD ).


    You should check that first.
     
  15. redhotsonic

    redhotsonic Also known as RHS Member

    Joined:
    Aug 10, 2007
    Messages:
    2,969
    Location:
    England
    I've also noticed that the dust from Sonic's/Tails' spindash and stopping animation has gone too! But I have fixed that. I've also come close to making Tails' Tails reappear, but not quite right as you can see in this picture:


    [​IMG]


    =P
     
  16. SpirituInsanum

    SpirituInsanum Well-Known Member Member

    Joined:
    Feb 11, 2010
    Messages:
    642
    Paint them blue, nobody will notice ;)


    So, it's about the object not being given the right parent when created. I don't know how/when it's being created though, but the most logical would be to create it when Tails is being created (during its routine 0). In which case, rather than creating the tails object, you could instead reset Tails' routine counter.


    But, as MainMemory kindly pointed out, the tails object is always in D000, which is a surprising choice in my opinion. But anyway, you could update the object clearing code so it clears everything from B400 to D000, and then D040 to D5FF. You should also check to position of the spindash dust objects (should be D100 in single player and D140 in two players mode).


    But at this point, I really think it would be easier and cleaner to move all those objects in B400 and the next slots, and update the object placement/creation routines so it begins a few object slots later (like B500 for example). There may be more to tweak, but probably not much, especially since your disassembly is probably using only equates.
     
  17. redhotsonic

    redhotsonic Also known as RHS Member

    Joined:
    Aug 10, 2007
    Messages:
    2,969
    Location:
    England
    Yeah, that was the problem, fixed it last night, it was the wrong parent, and then, had to "lea" the sidekick to a1 first. So now, Tails has his tails back. BUT, when Sonic and Knuckles, Knuckles grew some tails XD


    That was a simple fix though.



    ; =======================
    ; Reset objects and rings for Sonic


    ; =======================


    clr.b ($FFFFF710).w ; clear rings, so they can respawn again


    ; Start of deletion of all objects except Sonic/Knux and Tails/Knux


    lea ($FFFFB400).w,a1


    moveq #0,d0


    move.w #$87F,d1


    -


    move.l d0,(a1)+


    dbf d1,- ; clear object RAM


    ; End of deletion of all objects except Sonic/Knux and Tails/Knux


    clr.b (Obj_placement_routine).w ; Clear object placement routine, so it automatically starts again, spawning most objects


    move.b #5,(Tails_Tails).w ; load Obj05 (Tails' Tails) at $FFFFD000


    lea (Sidekick).w,a1 ; a1=character


    move.w a1,(Tails_Tails+parent).w ; makes Tails magically grow his tails again


    move.b #8,(Sonic_Dust).w ; load Obj08 Sonic's spindash dust/splash object at $FFFFD100


    move.b #8,(Tails_Dust).w ; load Obj08 Tails' spindash dust/splash object at $FFFFD140



    I've applied this to Tails and Knuckles objects; modifying bits and bobs to make it work with them. So far so good, will report back tomorrow if it's definitley working or if somethings not quite right.


    Thanks for all your help, SpirituInsanum. Greatly appreciated.
     
  18. Dark Lips

    Dark Lips Well-Known Member Member

    Joined:
    Nov 14, 2008
    Messages:
    293
    Location:
    Wolverhampton UK
    I have been following this thread with some intrest and was wondering if you have had any problem with knuckles dust when he slides from a glide to the ground>? as I am unable to get it to spawn/load.
     
  19. Crash

    Crash Well-Known Member Member

    Joined:
    Jul 15, 2010
    Messages:
    302
    Location:
    Australia
    You should just be able to copy the code that creates the skidding dust, and just change the part that checks for the skid animation to the knuckles sliding animation.
     
    Last edited by a moderator: Dec 16, 2011
  20. MainMemory

    MainMemory Well-Known Member Member

    Joined:
    Mar 29, 2011
    Messages:
    922
    You have to add a check for Knuckles' sliding state in the dust object. I used the Knuckles in Sonic 2 disassembly as a reference, and changed Obj08_CheckSkid:



    Obj08_CheckSkid:
    movea.w parent(a0),a2 ; a2=character


    moveq #$10,d1 ; move y offset to d1


    cmpi.b #$D,anim(a2) ; SonAni_Stop


    beq.s Obj08_SkidDust


    moveq #6,d1 ; move different y offset to d1


    cmpi.b #$4D,0(a2) ; playing as Knuckles (Obj4D)?


    bne.s +


    cmpi.b #3,$21(a2) ; check for sliding


    beq.s Obj08_SkidDust


    + move.b #2,routine(a0)


    move.b #0,objoff_32(a0)


    rts



    Then, in Obj08_SkidDust, I changed the lines below "move.w y_pos(a2),y_pos(a1)" to:



    tst.b objoff_34(a0)
    beq.s +


    subi.w #4,d1


    + add.w d1,y_pos(a1)



    This is to make the dust appear in the correct spot for Knuckles sliding.
     
Thread Status:
Not open for further replies.