News:

Don't forget to visit the main site! There's lots of helpful docs, patches, and more!

Main Menu

[SM] [ASM] Assistance with Item ASM

Started by shadedmagus, May 30, 2013, 07:14:04 PM

Previous topic - Next topic

shadedmagus

I'm requesting some assistance with ASM regarding changing the functionality of the Spring Ball item.

Background: I made a topic about a year and a half ago (wow, it's been that long?) to get some assistance in adding the properties of the Spring Ball item into the Hi-Jump Boots item, and about adding new properties to the Spring Ball item. Scyzer graciously helped me with the Hi-Jump Boots, and Black Falcon gave me some pointers regarding how to write the ASM for pointing the routines for the shinespark energy drain to a check to determine if the Spring Ball item is equipped, and to stop the energy drain from happening if the item is equipped.

However, the code is not working as intended, and I'm not sure why. Instead of keeping shinesparks from draining energy, as soon as I have the Spring Ball item and try to shinespark, at the first animation frame, the shinespark freezes and energy drops very rapidly to zero.

Here is what I have:


lorom

; This is the Super Spark patch. It takes the Springball item, which is made defunct by merging
; its functionality with the Hi-Jump Boots, and gives it the ability to keep the Speed Booster
; shinespark (super jump) from draining energy.

org $90D0CE
JSR $F659 ; Hijack the DEC for vertical spineshark

org $90D0FD
JSR $F659 ; Hijack the DEC for diagonal spineshark

org $90D129
JSR $F659 ; Hijack the DEC for horizontal spineshark

org $90F659
LDA $09A2 ; Load address for equipped items
BIT #$0002 ; Check to see if Springball is equipped
BNE ifEquipped ; If it is, RTS
DEC $09C2 ; Otherwise, DEC energy when shinesparking
ifEquipped:
RTS


Can someone shed any light on where this has gone wrong? Is this only a syntax issue (I'm not terribly familiar with xkas), or have I gone completely off-track?

Quote58

#1
from a quick look I'd say it looks pretty good. The first thing I would suggest is to check to make sure you're overwriting the write bytes by looking through the bank log courtesy of pjboy.
The second thing would be to put a PHA and PLA to ensure you aren't making the game lose an important value.

P.JBoy

That code looks absolutely fine... I'll take a look at it later
...

Scyzer

There is nothing wrong with the code you have so far, but you did forget something crucial.
After the DEC $09C2 in the original locations (the hijacks), there is a BPL which simply reduces Samus' energy to zero should it happen to be less than zero. This can't happen normally in the game anyway, since Shinesparks don't work at all with less than 30 energy.
Your problem is that with the new code you've put in, if it doesn't DEC the energy, then the last value loaded is Samus' equipment, which may or may not trigger the BPL after it returns, which can kill Samus. You just need to remove the BPL $03 from after the checks. You can just put an RTS after each JSR at the hijack points.

shadedmagus

Well, it's good to know that I was able to follow Black Falcon well enough to set the ASM right.  :yay:

Quote from: Scyzer on May 31, 2013, 06:16:56 AM
There is nothing wrong with the code you have so far, but you did forget something crucial.
After the DEC $09C2 in the original locations (the hijacks), there is a BPL which simply reduces Samus' energy to zero should it happen to be less than zero. This can't happen normally in the game anyway, since Shinesparks don't work at all with less than 30 energy.
Your problem is that with the new code you've put in, if it doesn't DEC the energy, then the last value loaded is Samus' equipment, which may or may not trigger the BPL after it returns, which can kill Samus. You just need to remove the BPL $03 from after the checks. You can just put an RTS after each JSR at the hijack points.

It looks like that BPL is being triggered, since I tried inserting the ASM into several different copies of the ROM and got the same behavior each time.

I'll make that change and see if it works. It might be a few days before I can test it, but I'll let you know. Thanks!

P.JBoy

#5
That's pretty much it. The LDA $09A2 is affecting the negative flag, so if you have X-Ray, the negative flag is set and the BPL isn't taken, killing Samus (possibly activating her reserves first). Possible solutions: NOP the STZ's, surround you code with PHP and PLP, change the BPL into a BRA, append some operation that clears the N flag (e.g. TDC), or use JMP instead of JSR (my recommended solution)
...

shadedmagus

#6
Quote from: P.JBoy on May 31, 2013, 02:15:42 PM
That's pretty much it. The LDA $09A2 is affecting the negative flag, so if you have X-Ray, the negative flag is set and the BPL isn't taken, killing Samus (possibly activating her reserves first). Possible solutions: NOP the STZ's, surround you code with PHP and PLP, change the BPL into a BRA, append some operation that clears the N flag (e.g. TDC), or use JMP instead of JSR (my recommended solution)

So if I replace the JSR lines with JMP, the routine would not carry the N flag back on RTS? Would that mean that I could keep the BPL $03 lines intact, so that without the item shinesparks would still decrement energy and the check for less-than-zero would work normally?

P.JBoy

If you replace the JSR with JMP, then when the game executes the RTS in your code, it returns from the routine that jumped to your code. So the BPL and the STZ never get executed at all; don't worry about keeping them, they never get executed in the original ROM either.
...

shadedmagus

Thanks, PJBoy! The change from JSR to JMP did the trick, with no need to change anything else. That was my last major hurdle in terms of game behaviors that I wanted to change.

I appreciate all the help!