Quick Theoretical

Discussion in 'Discussion and Q&A Archive' started by Psi, Jan 5, 2015.

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

    Psi Well-Known Member Member

    Joined:
    Dec 20, 2014
    Messages:
    102
    This is just a couple of theoretical questions I thought I'd ask to see if a future project I have in mind is worth looking into.

    How complex would it be to code Sonic 1 to:

    1. Connect an object to the player so that it moves and functions without going out of sync with them, ie. essentially being attached to them (eg. similar to shields I suppose, or the ring hands in Chaotix)?

    2. Have an object's animation go backwards? i.e. let's the say the animation had six frames but underwent a certain function while at frame 4 or another before the last. It would then go back from the frame it was on to the frame 0 and then delete.
     
    Last edited by a moderator: Jan 5, 2015
  2. MarkeyJester

    MarkeyJester ♡ ! Member

    Joined:
    Jun 27, 2009
    Messages:
    2,867
    1. Provided the object is at the end of the SST, and it processed last, then it'll remain in positional sync with the player (it's stuff such as platform objects that reposition the player afterwards. If the object is after the player but before the other objects (like the shield), then it'll remain in sync until other objects move the player around, only then will there be a frame's worth of delay.

    The problem is, if a platform object gets the last slot before your object, you're screwed. I'd say, have the object near the beginning like the shield's etc. But after the objects have all processed, manually reposition the object through a separate code/routine:

    Code:
    		move.l	(Player+$08).w,(Object+$08).w
    		move.l	(Player+$0C).w,(Object+$0C).w
    2. There are a variety of ways this can be done. Though, my personal preference would be manually (as it'll be much easier):
    Code:
    List:		dc.w	Routine04
    		dc.w	Routine06
    
    Routine04:
    		lea	Animation(pc),a1		; load animation script
    		jsr	AnimateSprite			; process animation
    		cmpi.b	#$04,$1A(a0)			; is the frame at 04?
    		bne.s	R04_Display			; if not, branch
    		addq.b	#$02,$24(a0)			; increase routine counter
    
    R04_Display:
    		bra.w	DisplaySprite			; save object for display
    
    Routine06:
    		tst.b	$1E(a0)				; has the frame duration reached 0?
    		bne.s	R06_Animate			; if not, branch
    		subq.b	#$02,$1B(a0)			; move back two spaces (AnimateSprite will move forwards once)
    		beq.s	R06_Delete			; if it has moved back to 00, this is the speed, so branch
    
    R06_Animate:
    		lea	Animation(pc),a1		; load animation script
    		jsr	AnimateSprite			; process animation
    		bra.w	DisplaySprite			; save object for display
    
    R06_Delete:
    		bra.w	DeleteObject			; delete the object
     
  3. Psi

    Psi Well-Known Member Member

    Joined:
    Dec 20, 2014
    Messages:
    102
    I think I've figured out how to do step one.

    As soon as I have enough work, I'll try out step two (I think if this project ever comes into fruition I'll have to credit you significantly, that's practically the whole code right there :p). I don't think there's any script titled 'animation' in S1's ASM though.
     
    Last edited by a moderator: Jan 7, 2015
  4. Clownacy

    Clownacy Retired Staff lolololo Member

    Joined:
    Aug 15, 2014
    Messages:
    1,020
    It's a placeholder. Replace it with the name of the animation script you want to run in reverse.
     
  5. Psi

    Psi Well-Known Member Member

    Joined:
    Dec 20, 2014
    Messages:
    102
    Ah I see. Well I've tested the coding out, and to give you a clue into what I'm trying for, here's a screenie:

    [​IMG]

    Basically the arm just extends and retracts. Made through an animation, simple enough.

    So far I've encountered one problem, the animation runs okay with the coding, however the object seems to disconnect from the player when it reverses the frames, suggesting it's altering the coding above connecting it in someway (I use the Hivebrain variant).

    move.w ($FFFFD008).w,8(a0)
    move.w ($FFFFD00C).w,$C(a0)
    move.b ($FFFFD022).w,$22(a0)

     

    As far as I know the coding above is still connecting a0 to the object so shouldn't overwrite it that way.

    Also in a less on topic note, it doesn't seem to hit anything, though the programming to destroy enemies and boxes is there. I'm guessing I may have to edit it's Touchresponse to extend to each sprite or something?
     
    Last edited by a moderator: Jan 9, 2015
  6. MarkeyJester

    MarkeyJester ♡ ! Member

    Joined:
    Jun 27, 2009
    Messages:
    2,867
    If you used my code above to do it, then chances are, you've got your code in one of the routines, but not the other. Like, you have it in "Routine04" but you need to have it in "Routine06" as well. (Just making an assumption here).
     
  7. Psi

    Psi Well-Known Member Member

    Joined:
    Dec 20, 2014
    Messages:
    102
    Ah that seems to have done it. Thanx. :D

    I've fiddled with the collision check and it seems yes, there is collision there, but it doesn't expand with the sprite and since it's connected directly to the player now it can only reach an object when they're refreshing or invincible. Is there any strategy to expand or move the touch radius according to the animation?
     
  8. Psi

    Psi Well-Known Member Member

    Joined:
    Dec 20, 2014
    Messages:
    102
    Okay, that problem is fixed with some branching and position tweaks.

    Found two new problems however:

    * For some reason when the player is in the air, the object's sprite is flipped vertically. Does anyone know what might be causing this?

    * I want to add in a second version of this routine for another animation. I'm guessing it will have to be tweaked according to the different frames however (when I try it, it starts with the new animation, but instead of backtracking, it runs the first animation instead). Would this be to do with the Routine6 coding? ('tst.b   $1E(a0)' looks like it is searching for the animation reaching the first frame of the object which the second animation wouldn't use).
     
    Last edited by a moderator: Jan 20, 2015
  9. TheInvisibleSun

    TheInvisibleSun Visible Member

    Joined:
    Jul 2, 2013
    Messages:
    425
    Location:
    Western New York, USA
    I believe the first issue has to with this line, or the like:


    move.b (v_player+obStatus).w,obStatus(a0)


    A shield in my hack features upward pointing arrows, but they awkwardly pointed down anytime Sonic was mid-air. In code, I fixed this by commenting out the above line.

    EDIT: Someone correct me if I'm wrong I believe it has to do with the object essentially copying Sonic's physical orientation (established somewhere in Object 01's "In Air" Routine)
     
    Last edited by a moderator: Jan 20, 2015
  10. Psi

    Psi Well-Known Member Member

    Joined:
    Dec 20, 2014
    Messages:
    102
    The problem with commenting out that code is that I still need the object to flip horizontally when the player turns around.
     
  11. Clownacy

    Clownacy Retired Staff lolololo Member

    Joined:
    Aug 15, 2014
    Messages:
    1,020
    Then and out the vertical flip bit. That's your problem.

    Look (taken from SCHG):

    Regular Status bitfield

    Bit  Hex  Description
    0  $01  X Orientation. Clear is left and set is right.
    1  $02  Y Orientation. Clear is right-side up, and set is upside-down
    2  $04  Unknown or unused
    3  $08  Set if Sonic is standing on this object.
    4  $10  Unknown or unused
    5  $20  Set if Sonic is pushing on this object.
    6  $40  Unknown or unused
    7  $80  Unknown or unused

    Sonic's Status bitfield

    Bit  Hex  Description
    0  $01  Orientation. Clear is left and set is right.
    1  $02  Set if Sonic is in the air (jump counts).
    2  $04  Set if jumping or rolling.
    3  $08  Set if Sonic isn't on the ground but shouldn't fall. (Usually when he is on a object that should stop him falling, like a platform or a bridge.)
    4  $10  Set if jumping after rolling.
    5  $20  Set if pushing something.
    6  $40  Set if underwater.
    7  $80  Unused.

    Notice something? Sonic's 'in air' bit is the same as the object's 'Y orientation' bit. So, when in the air, the object appears upside-down, having inherited the 'in air' bit.

    S3K's shields would combat this by using 'andi.b #1,obStatus(a0)' to limit Status inheritance to the 'X orientation' bit.
     
    Last edited by a moderator: Jan 21, 2015
  12. Psi

    Psi Well-Known Member Member

    Joined:
    Dec 20, 2014
    Messages:
    102
    Ah. That fixed it. Thanx very much. :D
     
Thread Status:
Not open for further replies.