News:

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

Main Menu

[SM] [ASM] Making water lower once charge beam collected (SOLVED)

Started by Mon732, November 06, 2011, 03:58:08 PM

Previous topic - Next topic

Mon732

I've got a room that's full of water and has the charge beam in. What's supposed to happen is that once the charge beam has been collected the water level would fall.
I collect the charge beam but nothing happens.

The FX2 pointer for that room is set to 8FEB40.
The start of the code is at 8FEB40.

Part of this code was taken from one of Black Falcons' ASM files.
lorom
org $8FEB40
LDA $09A9 ;Load value for Charge Beam Collected
CMP #$0000 ;Check if Charge beam has not been collected
BEQ END ;branch to the end if Charge beam is has not been collected
FALL:
LDA #$001F
STA $197C
LDA $1978
CLC
ADC #$0200
STA $197A
END:
RTS


What am I doing wrong?

herald83

#1
What you want to do is use the event system, not the FX2 pointer.  Give JAM's uber-doc on this a read through.  If that's too confusing just ask more questions and we'll get it sorted out.

What room are you using for this?  Hopefully it's already got a state you can just modify, but otherwise you'll have to add one.  Also, did you repoint the level data already?

As for using the charge beam as a trigger, it's doable, but you'll have to do some tweaking since the vanilla game doesn't have any events related to that item.  The easiest way would be to change the Speed Booster test state.  Do you want any other rooms with item-based state changes?


Then I re-read your post and realized you wanted it to fall while you're still in the room after grabbing the item.  Good question, but I can't help you there.

Crashtour99

It would probably be best/easiest to do it with a PLM instead of FX2 coding.  There's a special PLM used in the rooms you get speedbooster in.  I'd suggest doing a disassembly of that to see just how it works, and create a new one (or modify it if you aren't going to use it) as needed to get the effect you're looking for.

Smiley

Not sure if this will work, but try this:

lorom
org $8FEB40
LDA $09A9 ;Load value for Charge Beam Collected
CMP #$0000 ;Check if Charge beam has not been collected
BEQ END ;branch to the end if Charge beam is has not been collected
FALL:
LDA $1978 ;loads FX3 height...
        CLC
        ADC #$001F ;...adds 1F to it...
        STA $1978   ;...and stores it back.
END:
RTS

I really don't know whether that works or not, but it should.

Mon732

I'm not sure where the coding is actually stored.
I know that PLMs are in bank 84 however when looking at the Lava Rising PLM (B8AC) in SMILE I'm not sure which address to go to.
[spoiler][/spoiler]
Is it the Red, Dark Red or Purple address?
Which bank does the Purple address point to?

Also, I tried your code SMILEuser96 however that also didn't work. Thanks anyways though.

Crashtour99

#5
All the addresses are in $84.
The one in purple (PLM ID in SMILE) is the location of the PLM header.  If you go to that address you will see 2 pointers.
The first is B89C (the SNES address of the red circle).  This is the PLM's initiation code location.
The second pointer is B88A (the SNES address of the dark red circle).  This is the PLM's running code location.

So in essence:
2389C (84:B89C) is the routine that sets up the PLM in the room (run during room loading).
2388A (84:B88A) has the code that is run every frame while in the room. (unlike the initiation routine, this is a series of 2 byte pointers to other routines in $84, so it's a bit more complex).

You probably won't have to mess with the initiation code, but it wouldn't hurt to look it over just in case.

Just to get you started (copy/paste from ROM)

Initiation routine (it's pretty darn short):
A9 15 00 22 33 82 80 90 06 A9 00 00 99 37 1C 60
LDA #$0015
JSL $808233  ;calls 80:818E and tests against 7E:D820,X. CLC if 0, SEC if 1.
BCC +06
LDA #$0000
STA $1C37,Y  ;PLM header table (deletes PLM)
RTS
It's basically testing the event bit array to see if event $15 (outran speedbooster lava quake) has been set, if so delete PLM (and use original FX2 data).

Running routine (those 2 byte pointers I mentioned earlier, remember the bytes are reversed in the ROM):
C1 86 EF B7 B4 86 C1 86 2A B8 B4 86 C1 86 46 B8 B4 86

And the more I do this, the more inclined I am to dive further into it.   :lol:
[spoiler]
The running routine, with bytes flipped so pointers are easier to understand, and comments from http://jathys.zophar.net/supermetroid/kejardon/PLM_Details.txt

86C1  Stores the argument to 7E:1CD7,X, which will be executed every frame before the PLM instruction(s) until something overwrites it.
B7EF 
86B4  Do nothing. Absolutely, positively, nothing. The PLM will sit on this instruction until something else (often pre-PLM instruction) tells it to change.
86C1  Stores the argument to 7E:1CD7,X, which will be executed every frame before the PLM instruction(s) until something overwrites it.
B82A 
86B4  Do nothing. Absolutely, positively, nothing. The PLM will sit on this instruction until something else (often pre-PLM instruction) tells it to change.
86C1  Stores the argument to 7E:1CD7,X, which will be executed every frame before the PLM instruction(s) until something overwrites it.
B846 
86B4  Do nothing. Absolutely, positively, nothing. The PLM will sit on this instruction until something else (often pre-PLM instruction) tells it to change.


So it looks like all the relevant parts you need to look into are in $84 @ B7EF, B82A, and B846.
[/spoiler]

Edit:  You might also need to look into the Speed Booster PLM to find out how it activates the quake and rising lava in it's room.  It will be a very similar process to this one (just with some added graphical instructions since it's an item). 

P.JBoy

...

Mon732

#7
Ok, I think I've done a complete disassembly of PLM B8AC (minus a few values just beyond the ASM).

http://dl.dropbox.com/u/44022905/PLM%20B8AC%20Disassembly.txt

Disassembly:
$84/B7EF AD A4 09    LDA $09A4  [$00:09A4]   ;Load Collected Items
$84/B7F2 29 00 20    AND #$2000              ;Check for SpeedBooster
$84/B7F5 D0 13       BNE $13    [$B80A]      ;Branch to B80A if no SpeedBooster
$84/B7F7 A9 FF FF    LDA #$FFFF              ;Load 0xFFFF
$84/B7FA 8D 7A 19    STA $197A  [$00:197A]   ;Set FX3 destination height to 0xFFFF
$84/B7FD 9C 7C 19    STZ $197C  [$00:197C]   ;Set FX3 speed to 0x00
$84/B800 9C 80 19    STZ $1980  [$00:1980]   ;Set delay to 0x00
$84/B803 9C 40 18    STZ $1840  [$00:1840]   ;Set screen shake duration to 0x00
$84/B806 9E 37 1C    STZ $1C37,x[$00:1C37]   ;delete PLM (is this why it doesn't activate when speedbooster is collected in same room)
$84/B809 60          RTS                     ;Return from Subroutine (looks more like return to sender to me :P)

Disassembly:
$84/B80A AD 7A 19    LDA $197A  [$00:197A]   ;Load FX3 destination height
$84/B80D 30 17       BMI $17    [$B826]      ;Branch to B826 if height is negative
$84/B80F A9 80 FF    LDA #$FF80              ;Load 0xFF80
$84/B812 8D 7C 19    STA $197C  [$00:197C]   ;Set FX3 speed to 0xFF80
$84/B815 A9 01 00    LDA #$0001              ;Load 0x01
$84/B818 9F 1C DE 7E STA $7EDE1C,x[$7E:DE1C] ;Set PLM frame delay to 0x01
$84/B81C FE 27 1D    INC $1D27,x[$00:1D27]   ;Increment PLM instruction
$84/B81F FE 27 1D    INC $1D27,x[$00:1D27]   ;    " " "
$84/B822 9E 77 1D    STZ $1D77,x[$00:1D77]   ;Set PLM variable to 0x00
$84/B825 60          RTS                     ;Return from Subroutine

Disassembly:
$84/B826 9E 37 1C    STZ $1C37,x[$00:1C37]   ;delete PLM
$84/B829 60          RTS                     ;Return from Subroutine

Disassembly:
$84/B82A A9 E0 0A    LDA #$0AE0              ;Load 0x0AE0
$84/B82D CD F6 0A    CMP $0AF6  [$00:0AF6]   ;Compare A with Samus's X position.
$84/B830 90 13       BCC $13    [$B845]      ;Branch to B845 if Carry flag is cleared (not set)
$84/B832 A9 01 00    LDA #$0001              ;Load 0x01
$84/B835 8D 80 19    STA $1980  [$00:1980]   ;Set delay to 0x01
$84/B838 9F 1C DE 7E STA $7EDE1C,x[$7E:DE1C] ;Set PLM frame delay to 0x01
$84/B83C FE 27 1D    INC $1D27,x[$00:1D27]   ;Increment PLM instruction
$84/B83F FE 27 1D    INC $1D27,x[$00:1D27]   ;    " " "
$84/B842 9E 77 1D    STZ $1D77,x[$00:1D77]   ;Set PLM variable to 0x00
$84/B845 60          RTS                     ;Return from Subroutine

Disassembly:
$84/B846 BD 77 1D    LDA $1D77,x[$00:1D77]   ;Load PLM variable
$84/B849 A8          TAY                     ;Transfer A to Y
$84/B84A B9 76 B8    LDA $B876,y[$00:B876]   ;Load the value at B876+y
$84/B84D 30 1F       BMI $1F    [$B86E]      ;Branch to B86E if A is negative
$84/B84F CD F6 0A    CMP $0AF6  [$00:0AF6]   ;Compare A with Samus's X position.
$84/B852 90 19       BCC $19    [$B86D]      ;Branch to B86D if Carry flag is cleared
$84/B854 B9 78 B8    LDA $B878,y[$00:B878]   ;Load the value at B878+y
$84/B857 CD 78 19    CMP $1978  [$00:1978]   ;Compare FX3 height with A
$84/B85A B0 03       BCS $03    [$B85F]      ;Branch to B85F is Carry flag is set
$84/B85C 8D 78 19    STA $1978  [$00:1978]   ;Set FX3 height to A
$84/B85F B9 7A B8    LDA $B87A,y[$00:B87A]   ;Load the value at B87A+y
$84/B862 8D 7C 19    STA $197C  [$00:197C]   ;Set FX3 speed to A
$84/B865 98          TYA                     ;Transfer Y to A
$84/B866 18          CLC                     ;Clear Carry flag
$84/B867 69 06 00    ADC #$0006              ;Add 0x0006 to A
$84/B86A 9D 77 1D    STA $1D77,x[$00:1D77]   ;Set PLM variable to A
$84/B86D 60          RTS                     ;Return from Subroutine

Disassembly:
$84/B86E A9 15 00    LDA #$0015              ;Load 0x0015 into A (0x15 is the event bit for escaping speedbooster lava quake)
$84/B871 22 FA 81 80 JSL $8081FA[$80:81FA]   ;Jump to 8081FA (Stating an event has happened)
$84/B875 60          RTS                     ;Return from Subroutine


It seems that B7EF is the routine to check if Samus has the speedbooster (need to change it to check for charge beam) and is also what stops it from activating when the item is collected in the same room (something I need to circumvent to let the water drop while in the room).

I believe that B82A is what stops the lava from rising until Samus has gone past a certain point.

B846 is what actually changes the lava height.

I'll probs have a crack at it tomorrow as it's 10:38 PM here in England :yay:

P.JBoy, I know which Gold Chozo you mean. That is also another possibility and/or disassembly project.  :^_^:
G'night all!


EDIT: I've made the following changes to PLM B8AC.

    ADDRESS         |   HEX CHANGES
  PC    |   LoROM  |  BEFORE    | NOW
237F0  |  84B7F0  |  A4 09      | A8 09
237F3  |  84B7F3  |  00 20      | 00 10
23854  |  84B854  |  B9 78 B8  | A9 00 00
2385F  |  84B85F  |  B9 7A B8  | A9 00 01

What it now does:
-Reacts to having Charge Beam instead of Speedbooster
-lowers the water slowly (sort of, read below)

This is what is left to do:
PLM still doesn't activate when Charge Beam has been collected in same room.
When the room is exited and reentered the water blinks once then lowers at the correct speed to the correct level but then it jumps back up to full.

JAM

Wow! A lot of codes there are... But actually, there is a simple solution (even 2 of them, but first is better) without using PLMs, events and such things (but FX2 will be used in both cases).

Solution 1.
Set surfance start and surfance end values as you wish, surfance speed to 0000 and delay to 01.

FX2 should be a pointer to a free space in bank $8F (F000 leads to $7F000).
Code at there should be:
[AD A8 09] [89 00 10] [D0 09] [A9 XX XX] [8D 7C 19] [9C DF 07] [60]
XX XX -- lowering speed




Solution 2.
Set surfance start, surfance end and surfance speed values as you wish, and delay to 00.

FX2 should be a pointer to a free space in bank $8F (F000 leads to $7F000).
Code at there should be:
[AD A8 09] [89 00 10] [D0 09] [A9 01 00] [8D 80 19] [9C DF 07] [60]

Note that liquid in this solution will start lowering even without collecting Charge Beam after about 18 minutes of waiting (that's why solution 1 is better).

Mon732

Thanks JAM, however I had to make a slight change.
The water lowered when I did not have the charge beam and did not lower when I did have it.

Code (OLD) Select
AD A8 09 LDA $09A8
89 00 10 BIT #$1000
D0 09 BNE END ;from this
A9 01 00 LDA #$0001
8D 7C 19 STA 197C
9C DF 07 STZ 07DF
END:
60 RTS


Code (NEW) Select
AD A8 09 LDA $09A8
89 00 10 BIT #$1000
D0 09 BEQ END ;to this
A9 01 00 LDA #$0001
8D 7C 19 STA 197C
9C DF 07 STZ 07DF
END:
60 RTS


The change I made works but it doesn't make sense!


Oh, and if anyone wants to use the disassembly of PLM B8AC then feel free.

P.JBoy

It's because BEQ actually means to branch if the last operation set the Zero flag; in this case, the operation is a BIT (and AND that doesn't keep the result), so if you have #$1000 in your equipment, then [$09A8] AND #$1000 = #$1000, otherwise if you didn't have it, it would equal zero.  So for BIT, BNE means branch if not zero, which means branch if equal!  (well, not equal, rather, one has the other)
...

Mon732

Ah that makes sense P.JBoy. Thanks for clearing things up!

JAM

P.JBoy
Thanks for correcting. I'm making mistakes with BIT from time to time...

Mon732
I have to note that this way of lowering liquid works right only for water. If you want to do something like this with acid or lava, you'll have to write extra code, because screen will shaking even if liquid speed is zero or if delay is zero.

Mon732

Quote from: JAMscreen will shaking even if liquid speed is zero or if delay is zero.
Ah, like in the room before the speed booster? I presume the code would possibly involve changing something at 7E:183E - 7E:1841?

JAM

#14
Mon732
Yes, exactly. To find what values to store to these addresses, simply search for cheates in Zsnes in the room where are lava/acid is lowering/rising and see what is stored at 7E:183E and 7E:1840