Okay this is a more complex one that is sort of an theory throughout all 3 games, but I wanna know if it's possible to turn off the animation reset when landing on the ground or on an object. Like when you land on something it reverts to standing or running, and even on something you bounce off it just converts your animation (eg. when you bounce off a breakable rock, it doesn't continue the rolling animation, it just commands it again so it looks like the loop is continuing, turn that off as it defaults to walking animation). I wanna know if there's something that can turn that off and let an in-air animation continue until it's finished even when you land.
You'd have to change how it handles setting the animation and resetting it in (Player)_Move, (Player)_Move(Direction), ResetOnFloor, and AnglePos. Just check for a flag or specific animation and skip over setting/resetting the animation in those routines, and I think you should be good to go.
A'ight this is a question intended for Selbi to answer - in Sonic Erazor (one of my favourite games, even if it is a romhack) the giant rings in Uberhub Place take you to different levels. I'd like to know how you did that, along with the haptic effects when you hit a monitor or Badnik. Also, how did you add textboxes? I'd like to actually incorporate a story into my game by interacting with NPCs (i.e objects) to show textboxes.
@AppleSauce Selbi hasn't even been online for over a year, what makes you think that he's gonna turn up now to answer your question? I'm gonna give you the best, last advice you'll ever get from me: TRY to learn to program, instead of asking everyone else to tell you how to implement cool ideas. Start small, follow some bugfix guides, learn the engine. Don't just follow the guides by rote, actually try to understand the changes you're making. If you don't understand a line, look it up in the instruction set. Make mistakes, learn from them, try to improve yourself. And next time you come to ask a question, don't aim it specifically at a stranger just because you don't like the advice that you've already been offered.
Echoing the above: this is the BASIC questions and answers thread. Asking how to implement entire features is outside it's scope. That being said, for text boxes, you could probably start here: https://blog.bigevilcorporation.co.uk/2012/04/09/sega-megadrive-5-fonts-and-text/ If that's over your head, you need to start smaller. EDIT: I do have a problem of my own though. My object won't persist. I'm trying to change it a bit so that rather than moving Sonic into position, he just snaps there. That works, but after using the object it disappears. There's a second problem with it as well, probably due to how I'm snapping Sonic into position. When he lands, he lands a few pixels below the ground. He seems to interact with it fine though, and it fixes itself if I jump. Here's the code: https://pastebin.com/X1e4sVks
A characters animation is reset to 0 upon landing on the floor. Take a look at X_resetonfloor (x being the character name, in most cases), perhaps you could make a check for the specific animation you want, and if it is positive, branch over the line that sets the animation to 0. Perhaps, set a flag when Sonic is bounced off the object. Check in the resetonfloor subroutine for the flag, and if so, subtract his y_pos by a few pixels.
That's an option! Djohe taught me a few things and it turns out the idle code I have is better served in Sonic 2 via the MarkObjGone subroutine. My object persists properly now, so that's a plus.
Thanks! My level is very, very newbie. I've never edited Mster system games before and have not much technical knowledge haha. Thanks for the info! Ive been replacing the text, keeping the same number of characters and changing when any word has less characters than the ones that were before into EB (blank space). But it still wont work. I'l try with a better emulator then and see what can I do. Thanks!
@ashthedragon Cool. I just had a crack at this myself based on the information on the wiki and I got positive results after a couple of attempts, no need to change the checksum, at least on Emulicious and Kega. I did trip up over the control codes a bit, so just be wary of those. But no matter what I did to the data, it didn't stop the ROM from loading in Emulicious or Kega, so I'm not sure what's causing your issues.
Can someone tell me if this code is correct? Code (Text): Chase_Object: ; a0 = MainCharacter a2 = object move.w d0,d2 ; d0 = Maximum speed neg.w d2 ; reverse max speed? move.w d1,d3 ; d1 = acceleration move.w x_pos(a0),d4 ; move x_pos of a0 to d4 cmp.w x_pos(a2),d4 ; compare the x_pos of a2 to a0's seq d5 ; set if equal beq.s loc_8545E ; branch if equal as well bcs.s loc_8544C ; branch if carry set neg.w d1 ; reverse acceleration loc_8544C: move.w x_vel(a0),d4 ; move x_vel of a0 to d4 now add.w d1,d4 ; add acceleration of d1 to d4 cmp.w d2,d4 ; compare reversed max speed blt.s loc_8545E ; if it's lower than max, branch cmp.w d0,d4 ; compare max speed bgt.s loc_8545E ; if it is higher than max, branch move.w d4,x_vel(a0) ; otherwise move max speed to x_vel loc_8545E: move.w y_pos(a0),d4 ; move y_pos of a0 to d4 now cmp.w y_pos(a2),d4 ; compare with y_pos of a2 to a0's beq.s loc_85480 ; if equal, branch bcs.s loc_8546C ; if carry clear, branch neg.w d3 ; otherwise, reverse max speed loc_8546C: move.w y_vel(a0),d4 ; move y_vel of a0 to d4 now add.w d3,d4 ; add acceleration of d3 to d4 cmp.w d2,d4 ; compare with y_vel of a2 blt.s locret_8547E ; if less than, branch cmp.w d0,d4 ; compare max speed with acceleration bgt.s locret_8547E ; branch if greater than move.w d4,y_vel(a0) ; move acceleration of d4 to y_vel locret_8547E: rts ; --------------------------------------------------------------------------- loc_85480: tst.b d5 ; test for d5 beq.s locret_8547E ; if yes, branch clr.w x_vel(a0) ; clear x_vel of a0 clr.w y_vel(a0) ; clear y_vel of a0 rts ; End of function Chase_Object My thought is, player is in a0, object being chased is in a2. If conditions are met, it ends, otherwise continues.
You are more or less on the right track, except you have them swapped, and a few of the terminology is somewhat wrong (or vague/incomplete). Code (Text): Chase_Object: move.w d0,d2 ; copy and create a negative version of the maximum speed neg.w d2 ; '' move.w d1,d3 ; store current speed in d3 (for Y later) ; --- Checking X position --- move.w x_pos(a0),d4 ; load object's X position cmp.w x_pos(a2),d4 ; check against character's X position (subtraction) seq d5 ; if they are in exactly the same spot on X, set d5 as a reminder for later beq.s CO_FinishX ; if they are in exactly the same spot on X, branch bcs.s CO_MoveRight ; if carry set, then character is to the right of the object, so branch neg.w d1 ; convert speed to negative (go left instead of right) CO_MoveRight: ; --- Handling X speed --- move.w x_vel(a0),d4 ; load object's X speed add.w d1,d4 ; add current speed cmp.w d2,d4 ; is the speed passed its maximum in negative (left)? blt.s CO_FinishX ; if so, branch (don't change the speed) cmp.w d0,d4 ; is the speed passed its maximum in positive (right)? bgt.s CO_FinishX ; if so, branch (don't change the speed) move.w d4,x_vel(a0) ; update object's new X speed CO_FinishX: ; --- Checking Y position --- move.w y_pos(a0),d4 ; load object's Y position cmp.w y_pos(a2),d4 ; check against character's Y position (subtraction) beq.s CO_FinishY ; if they are in exactly the same spot on Y, branch bcs.s CO_MoveDown ; if carry set, then character is below the object, so branch neg.w d3 ; convert speed to negative (go up instead of down) CO_MoveDown: ; --- Handling Y speed --- move.w y_vel(a0),d4 ; load object's Y speed add.w d3,d4 ; add current speed cmp.w d2,d4 ; is the speed passed its maximum in negative (up)? blt.s CO_Return ; if so, branch (don't change the speed) cmp.w d0,d4 ; is the speed passed its maximum in positive (down)? bgt.s CO_Return ; if so, branch (don't change the speed) move.w d4,y_vel(a0) ; update object's new Y speed CO_Return: rts ; return ; --- Destination reached check --- CO_FinishY: tst.b d5 ; has the object reached the character exactly on X (and Y)? beq.s CO_Return ; if not, branch/return clr.w x_vel(a0) ; stop object from moving on X clr.w y_vel(a0) ; stop object from moving on Y rts ; return
Wouldn't this do the opposite of what I was looking for, in a sense? If I am reading it correctly, this is check to see if the object (a0) is reaching the player's (a2) position. I am looking for if the player (a0) reached the object's (a2) position. Hit me up in DMs on discord maybe. Edit: What I am looking for, is what I call persistent tracking. I want the player to continuously move towards the object's location until it is reached. It seems, what this routine does, at least in my testing, is controls the player's max speed depending on distance from the target object.
This subroutine is designed to move an object in a0 towards an object in a2 in a gravity like way, at the acceleration speed of d1, and a maximum speed of d0. This is likely the subroutine responsible for moving the rings towards the main character when they have an electric shield on. It sounds to me like you're looking for something more along the lines of a homing attack?
Actually its current setup might be useful to me. I want to make a routine for a projectile so it homes back to the player when it's finished it's thrust forward routine. Would the above code be advisable for such behaviour? (And if so, would you be against me stealing it? :P)
You are more than welcome to use it how you see fit. All you have to do is reverse the registers in order to make the object come to the player.
Thanx. I'm not sure I need to though, because I placed it in the object's routine where the main character is already a2 (and switching them around only tries to forcibly move the main character instead). Here's what I have so far, but it doesn't seem to do the job, the object just seems to delete when the counter is done: Code (Text): move.w #$740,x_vel(a0) ; speed of laser move.w #-$490,y_vel(a0) ; speed of laser move.b #$38,$30(a0) ; distance laser will travel Obj4D_Cont: btst #0,($FFFFB001).w beq.s + neg.w x_vel(a0) add.w #$40,x_pos(a0) bset #0,$22(a0) ; Flip to the left bra.w ++ + sub.w #$40,x_pos(a0) + move.w #$9E00,d2 addq.b #2,$24(a0) ; Obj_Blob_Move: cmp.b #0,$30(a0) bne.w ContCounter Reel_Homing: move.b #1,anim(a0) Chase_Object: lea (MainCharacter).w,a2 move.w d0,d2 ; copy and create a negative version of the maximum speed neg.w d2 ; '' move.w d1,d3 ; store current speed in d3 (for Y later) ; --- Checking X position --- move.w x_pos(a0),d4 ; load object's X position cmp.w x_pos(a2),d4 ; check against character's X position (subtraction) seq d5 ; if they are in exactly the same spot on X, set d5 as a reminder for later beq.s CO_FinishX ; if they are in exactly the same spot on X, branch bcs.s CO_MoveRight ; if carry set, then character is to the right of the object, so branch neg.w d1 ; convert speed to negative (go left instead of right) CO_MoveRight: ; --- Handling X speed --- move.w x_vel(a0),d4 ; load object's X speed add.w d1,d4 ; add current speed cmp.w d2,d4 ; is the speed passed its maximum in negative (left)? blt.s CO_FinishX ; if so, branch (don't change the speed) cmp.w d0,d4 ; is the speed passed its maximum in positive (right)? bgt.s CO_FinishX ; if so, branch (don't change the speed) move.w d4,x_vel(a0) ; update object's new X speed CO_FinishX: ; --- Checking Y position --- move.w y_pos(a0),d4 ; load object's Y position cmp.w y_pos(a2),d4 ; check against character's Y position (subtraction) beq.s CO_FinishY ; if they are in exactly the same spot on Y, branch bcs.s CO_MoveDown ; if carry set, then character is below the object, so branch neg.w d3 ; convert speed to negative (go up instead of down) CO_MoveDown: ; --- Handling Y speed --- move.w y_vel(a0),d4 ; load object's Y speed add.w d3,d4 ; add current speed cmp.w d2,d4 ; is the speed passed its maximum in negative (up)? blt.s CO_Return ; if so, branch (don't change the speed) cmp.w d0,d4 ; is the speed passed its maximum in positive (down)? bgt.s CO_Return ; if so, branch (don't change the speed) move.w d4,y_vel(a0) ; update object's new Y speed CO_Return: rts ; return ; --- Destination reached check --- CO_FinishY: tst.b d5 ; has the object reached the character exactly on X (and Y)? beq.s CO_Return ; if not, branch/return clr.w x_vel(a0) ; stop object from moving on X clr.w y_vel(a0) ; stop object from moving on Y bra.w Obj_Blob_Destroy rts ContCounter: sub.b #$1,$30(a0) bsr.w ObjectMoveAndFall move.b $40,$20(a0) ; lol clr.w d0 move.b $1A(a0),d0 asl.w #$1,d0 ; *2 for correct offset lea (ArtUnc_Lure).l,a1 adda.w (a1,d0.w),a1 move.w #$9E00,d2 lea (Ani_Laser).l,a1 jsr AnimateSprite bsr.w LoadLureDynPLC jsr (TouchResponse).l ;Touch_KillEnemy, Touch_Monitor jmp DisplaySprite Obj_Blob_Destroy: lea (MainCharacter).w,a2 btst #1,status(a2) bne.s Obj_Blob_Destroy_2 move.w #0,(Chain_Bonus_counter).w Obj_Blob_Destroy_2: jmp DeleteObject I'm guessing I've made a blatant error here. Any idea? EDIT: Okay I've partially solved this by moving the animation/PLC branches up since the new routine skipped over them, however the object still doesn't move a muscle after it's run it's distance. What did you use to program max speed into d0 by any chance. Was it x_vel?
I've actually worked out how to do exactly what you are looking for. Hit me up on Discord later, and I will walk you through it.
Hey y'all. In Sonic 1, I'm trying to create a new jump mechanic. My original plan was to have it curl midair and stay in a ball until they reach the ground, like Pantufa: Extended Edition with the player being vulnerable if they are not in a ball. I couldn't figure out how to repeat only a segment of the animation, so instead, it also curls out of the ball midair. I think I got the animation going good, but in SAnim_RollJump, I'm having trouble keeping the animation speed consistent regardless of speed, and for some reason, no matter what I do, when I go to GHZ Act 2 and jump, the character jumps reeeeaaally quickly like he's high on caffeine. Could anyone provide me with help? I'm using the Hivebrain 2005 disassembly.
Yes, at the very start of both roll anims. Edit: I clicked on the orange text in your reply, and I didn't know I was supposed to set the FE flag to step back a few sprites. I thought it handled speed, because if I don't have the FE flag at the start of the anims, it is really slow, like a snail carrying heavy shopping. So what's up with that?