I'm confused by what you mean by 'the stack', do you mean put that line in loc_1978E? If so where (if not where either)? And hi again Felicia Val. Why did you delete your account in DA by the way?
Oh hi again Psi. Ah...well, long story. I deleted it about 2 months ago or so. PM me if you're interested on knowing
I want to import a PCX into SonEd2, but it does not use existing pallets. How would I go about extracting it from the PCX (prepared to use 16 8-bit colors) and adding it into the Zone's pallet? Else, SonEd2 doesn't want to import it correctly.
In this post I explained what the stack is. The link to the second pic is dead, so here it is another one:
Is the Tower of Hanoi really what's commonly used as an analogy? I've read everything from cards to pizza boxes being used, but never the Tower of Hanoi.
Sorry, but I tried not to go into too much detail on what the stack actually is, because you don't really need to know in order to fix the problem you're having. All you have to do is make sure that the line immediately after the "loc_189A8:" label gets executed every time. To do that, just make the the two changes that I suggested. However, if you're interested (and why wouldn't you be? ) here's the full explanation. The stack is just an area of memory, the same as the memory where you've been storing Sonic's lives and rings. It starts at RAM location $FFFFFE00 and has the label "System_Stack" in the disassembly I'm using. It extends upwards from this address, and although it looks like it has $80 bytes assigned to it, there's nothing to stop it carrying on past that (stack overflow). Unlike other areas of memory, though, rather than access any part of it at any time, you only access what's on the "top" of the stack, which will be the most recent thing put on it. As nineko said, think of it like that wooden Tower of Hanoi game. You can't get at anything in the stack until you've taken off everything above it. The stack is used automatically by your program when it's running. If you branch to a subroutine by using bsr or jsr, the address you just came from will be "pushed" on to the stack (put on the top). At the end of the subroutine, when the program encounters an rts, this address is "popped" from (taken off) the stack, and execution continues from that address. Think for a moment about subroutines inside subroutines inside more subroutines, and you'll see why a stack is the best way of keeping track of things. The stack isn't just for use by the system, though - we can use it as well. By using sp (stack pointer), we know where the top of the stack is. You'll see Sonic Team has used the stack on various occasions to store variables temporarily. It happens a lot in Sonic 1, but less so in Sonic 2. I personally don't recommend using the stack at all, as getting it even slightly wrong causes huge problems. In your case, E-122-Psi, as soon as the program hit an rts it would crash, because it was expecting to find the address that it came from in order to get to that subroutine, but instead found a bunch of random data that you (or rather, Sonic Team!) put there. Summary: if your game is crashing, check for lines with "sp" in your code and make sure they're being executed in the order they were intended to.
Got it working. Thanx. :D Say, is it possible to place this coding in other objects such as Obj32 (breakable hill top/chemical plant objects) so they will activate in a similar method?
I don't see why not - it only looks at the X and Y locations of the object so it should work with pretty much anything. I assume the code activates the spring (or other object) when Amy hits it with her hammer? That would be pretty cool for breakable blocks. However, I can see one minor issue: it will still activate even if Amy is facing away from the object. Not sure if that's a problem for you or not.
Correct, just like Advance 1. Well beggers can't be choosers, if I limit the radius it works it would be hard to create such a situation anyway. Any idea where to place the code though? The routine for the object's radius and recognition with the character seems rather different from the springs.
I've just had a quick look at Obj32. I'd suggest putting the code in Obj32_Main, just after the solidity check (bsr.w JmpTo3_SolidObject). If Amy is using the hammer, it looks like Obj32_Destroy is the place to branch to. If she's not, then carry on with the normal code. I haven't tested this, though, so no guarantees that it'll work! One issue you'l have to look out for is if Tails is standing on the block when you destroy it with the hammer. Just look at what the regular code does it that situation and try to use that if possible.
It does use the correct palette—just not the proper IDs. Unfortunately the only good PCX editor is Paint Shop Pro, that keeps IDs. anything else, even photoshop, does not, resulting in broken imports.
Success. I got it working, plus there doesn't seem to be any problems with Tails, if you hammer it with him on he just falls onto the ground. You sound like you have a much more clearly labelled ASM than me though, there is no Obj32_Destroy on mine so I had to improvise.
Cool, nice one. I thought Tails might be an issue because the original code seemed to have a lot of routines for dealing with him. And yes, I'm using the SVN version of the disassembly, which does have better labels and variable names.
So the earlier version of the dissassembly is better labelled? Well if I ask some rather obvious questions you may know why. Another problem. I have entered a branch in a routine that is meant to lock the controls. I've got it to work however entering the branch to clear it not only deactivates it after the move as intended but all other sequences involving control lock (eg. the ending in Sonic 1, the WFZ cutscene in Sonic 2). clr.w ($FFFFF7CC).w ; unlock controls For Sonic 2 it is basically the same thing except with it's respective labelled flag (control_lock). Any solutions?
IIRC, the control lock is stored as a byte, rather than a word. So you would have to change it to clr.b($FFFFF7CC).w; unlock controls.
It's difficult to tell without seeing the code, but is there a chance that the "unlock" line above is being called repeatedly? In other words, every frame the code says "Is Amy doing this attack? No? Then clear the control lock flag." If so, you'll want to change it to only clear the lock once, when the attack has just finished. I'm afraid that's my only guess!
If it helps here is the routine: Code (ASM): ; --------------------------------------------------------------------------- ; Subroutine allowing Sonic to attack ; --------------------------------------------------------------------------- ; ||||||||||||||| S U B R O U T I N E ||||||||||||||||||||||||||||||||||||||| Sonic_Hammer: cmp.b #$1F,$1C(a0) bne.s lol7 move.b #$01,($FFFFF7CC).w ; lock controls move.w $14(a0),d0 move.w d0,d1 asr.w #3,d1 sub.w d1,d0 move.w d0,$14(a0) rts lol7: btst #1,($FFFFF602).w ; is Down button pressed? bne.s JmpTo_SonicHammerreturn ; if yes, return btst #6,($FFFFF603).w ; is A button pressed? beq lol ; if not branch tst.b ($FFFFFFA4).w ; was jumpdash flag set? bne.w JmpTo_SonicHammerreturn ; if yes, branch move.b #1,($FFFFFFA4).w ; if not, set jumpdash flag move.b #$1F,$1C(a0) ; show hammer animation jmp Hammer_Cont JmpTo_SonicHammerreturn: jmp Sonic_Hammer_return Hammer_Cont: move.b #$01,($FFFFF7CC).w ; lock controls move.w $14(a0),d0 btst #0,$22(a0) beq lol8 neg.w d0 lol8: cmp.w #$400,d0 bgt lol move.w #$400,d0 btst #0,$22(a0) beq lol9 neg.w d0 lol9: move.w d0,$14(a0) lol: move.w $10(a0),d0 tst.w d0 bpl label neg.w d0 label: cmpi.w #$600,d0 bgt Sonic_Hammer_Return clr.b ($FFFFF7CC).w ; unlock controls btst #6,($FFFFF603).w ; is A button pressed? beq.b Sonic_Hammer_return ; if not, return move.b #$1F,$1C(a0) ; show animation $20 move.w #$BD,d0 jsr (PlaySound_Special).l Sonic_Hammer_return: rts ; End of function Sonic_Hammer