News:

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

Main Menu

[SM] Shot blocks

Started by Crashtour99, August 15, 2010, 01:07:10 AM

Previous topic - Next topic

Crashtour99

I have some ideas I'd like to try for making new shot blocks but for some reason I can't figure out how to find the BTS pointer array. 

:just for clarification:
Like Air Fool x-ray bts 07 is @ $9498BA (2 byte pointer)
Air Fool x-ray bts 08 is @ $9498BC (2 byte pointer)

I just need the ROM location for the start of the BTS pointers for shot blocks (and now that I think about it, solid blocks as well).  If all goes well, I should have something interesting to add to the collaboration thread soon.


DSO

9E73 : Check BTS. If positive, create PLM from main table (94:9EA6 + BTS*2, 'max' BTS of 50). If negative, create region-indexed PLM (94:9F46 + 10*region + BTS*2, 'max' BTS of 10). Either way, clear V, SEC, RTS.
That's the beam collision reaction for shotblocks, the full list is at http://jathys.zophar.net/supermetroid/kejardon/BlockShotReact.txt

Crashtour99

I've actually decompiled and chased that code, and several others, but I just can't seem to locate the pointer array in the ROM.  I need to find those pointer arrays so that I can make my own BTS's.  Though I will probably end up rewriting that particular code a bit.

begrimed

Not sure how helpful this will be. I grabbed it from my PM logs, but I think it addresses what you're looking for:

<LusterVanguard> but, for the hijack points for when samus touches a BTS, you can have up to 0F for fool x-ray, and $7F for treadmill
<LusterVanguard> so you can have 137 different ASM codes
<LusterVanguard> Fool-XRay Air - $A18AC (up to $0F)
<LusterVanguard> Treadmill - $A1966 (up to $7F) =D
<LusterVanguard> it's indexed by 2 for each BTS
<LusterVanguard> so at those locations is BTS $00
<LusterVanguard> adding 2 to it is BTS $01
<LusterVanguard> etc

Crashtour99

Hmmm, not too helpful, but at least on the right track.
I just need that for shot blocks and solid blocks instead of Treadmills and AirFoolX-ray.

JAM

#5
Here you go:
Shotblocks array starts at $A1EA6.

Every word -- pointer to PLM header in bank $84.


Don't sure about this, but:
Solid block array starts at $A14D5 and ends at $A1515. Possibly can be relocated and expanded. Pointers leads to the same bank

Crashtour99

 :cheers:  Thank you JAM!  I swear, your knowledge on the areas of this game that most people don't look into is extraordinary.

I doubt I'd need to relocate/expand the solid block array, cause my new shot blocks will basically work like this:
equipment check, if true act like normal shotblock, if not, act like solid block (so they only break while a certain item/s are equipped).

Now I can do some code chasing and see if I can get this to work right.   :wink:

Scyzer

This site has a ton of documents, including where all the shot blocks are, and all other types in detail, as well as some dissasemblies, etc, other random stuff.
http://jathys.zophar.net/supermetroid/kejardon/index.html

Crashtour99

I actually have that site bookmarked and routinely visit it when looking for information.  I swear I didn't see the info there that JAM provided.  Perhaps I wasn't looking in the right document?  (though I swear I scoured every single one in the "blocks and PLMs" section and couldn't find it)

DSO

Quote from: Crashtour99 on August 16, 2010, 10:08:19 AM
I actually have that site bookmarked and routinely visit it when looking for information.  I swear I didn't see the info there that JAM provided.  Perhaps I wasn't looking in the right document?  (though I swear I scoured every single one in the "blocks and PLMs" section and couldn't find it)

It was there in the shot react doc which I posted for shotblocks, though I didn't explain it in easier to understand terms... I figured if you understood the air/fool xray blocks, you'd understand that these are saying the same thing.

Quote from: DSO(94:9EA6 + BTS*2, 'max' BTS of 50)

Quote from: JAMShotblocks array starts at $A1EA6.

Crashtour99

*slaps forehead*
TBH DSO I don't know how I didn't see that before...   Looking at it from the wrong frame of reference I suppose. 

Crashtour99

So it turns out that it's not as simple as I had thought it would be.  For some reason when the beam hits my BTS the game freezes.  I think I'm on the right track, but I can't for the life of me figure out where I'm going wrong on this.

[spoiler]
lorom

org $949EC8    ;shotblock bts 11
dw $B1A0       ;pointer to freespace (was 64 D0 in ROM)

org $94B1A0    ;freespace
LDA $09A6      ;currently equiped beams
CMP #$0001     ;value for wave beam
BPL NoWave     ;branch if not equal
LDA $D064      ;pointer for 1x1 shotblock
RTS

NoWave:
LDA $B62F      ;pointer for solid block (filler pointer but acts as solid block)
RTS
[/spoiler]

Any ideas?

Scyzer

Well for one, don't use CMP #$0001, otherwise it will only branch when they is ONLY wave equipped, not wave and anything else.
Second, just LDA'ing those pointers won't do anything at all, because the routine you've written there is the same routine generation as what tells blocks what to do (if that makes sense). There's the routine that gets the table location, then the actual routine that sets up the blocks. You're tyring to put in a routine between them, when the fact is, the main routine won't do anything with those pointers in A. You can JSR to them, which might work (not sure, but it should), but if not you'll need to put the entire routine in there for shotblocks or solid blocks. IIRC it's just a CLC or SEC, but that's for making blocks passable or solid, and may not be the case with shot reactions.

Crashtour99

The idea is that there would be a different bts shotblock for each beam, with no beam mixing (using Black Falcon's HUD hack for ease of switching between beams).

I was really hoping it would be as simple as inserting a routine to check for the equipped beam as a BTS.  I actually tried it as a JSR instead of LDA and it did the same freezing thing. 

Within the main shot reaction routine there's an LDA $9EA6,x (shotblock pointer table, increased by x/BTS to locate the pointer) so it loads the pointer to A, then JSL's to $84 (to execute it and create the PLM I assume).  I'm wondering if I can hijack the code at that LDA to run the BTS routine based off of it's value ($10 and under are for powerbomb, super missile, and regular shot blocks, above that are free), so for BTS less than 10 just LDA $9EA6,x and 11 or above execute the routine at the BTS (which would include an LDA of the proper pointer).  I'm confident I can write the code for the BTS's, but the other part might be a bit beyond me at the moment.

JAM

#14
Quote from: Crashtour99 on August 16, 2010, 10:08:19 AM
I actually have that site bookmarked and routinely visit it when looking for information.  I swear I didn't see the info there that JAM provided.  Perhaps I wasn't looking in the right document?
To clarify the situation... There aren't any doc related to BTS (except X-Ray Blocks), but there is PLM_Details where you can see info of PLMs. Shotblocks, crumble blocks etc. are written there.

How have I located a start of shotblock array?

Look at this:
Quote1x1 Respawning shot block reaction (D064 --> CE6B, CADF)

Then I jumped to $A0000 (bank where all BTS stored) and searched for "64 D0" and got $A1EA6.
1x1 respawning shot block is a block with type "shot" and BTS value 00, so this is the start of this array.

And I still don't sure about solid block array.


Quote from: Crashtour99 on August 19, 2010, 12:44:44 AM
Any ideas?
Almost everything is wrong... When something hits shot blocks it "activate" and load PLM, not the code in bank $94.



As for the code...


org $949EC8    ;shotblock bts 11

Don't sure will this work or no. Try to use BTS from $0C up to $0F.


CMP #$0001     ;value for wave beam

Should be BIT #$0001. When you have equipped charge beam, the value of Charged Wave will be $1001. And even then if you shoot with wave and change the beam type while shot is flying, this block willn't be broken.





Look how Super Missile block is working. Respawning is BTS $0A; shot type.
Non-respawning is BTS $0B; shot type.

In shotblock array BTS $0A loads PLM D08C

Jump to $2508C
There are 2 words: 67 CF and 71 CB
First one is checking for damage with Super Missile. Second one is drawing "removing block sequence".

Jump to $24F67 ($84:CF67)


[spoiler=Super Missile Block code]
[AE DE 0D] [BD 18 0C] [29 00 0F] [C9 00 05] [F0 24] [C9 00 02] [F0 07] [A9 00 00] [99 37 1C] [60]

AEDE0D      LDX 0DDE      Load BB:0DDE to X
BD180C      LDA 0C18,X      Load BB:0C18+X to A
29000F      AND #0F00      AND A by #0F00      ;A=0*00
C90005      CMP #0500      Compare #0500 to A
F024      BEQ 24         Branch to PC+±#24 if equal
   (BRANCH_ALPHA)               ;bombed?
C90002      CMP #0200      Compare #0200 to A
F007      BEQ 07         Branch to PC+±#07 if equal
   (BRANCH_BETA)            ;shot by super missile?
A90000      LDA #0000      Load #0000 to A   ;don't touch the block
99371C      STA 1C37,Y      Store A to BB:1C37+Y
60      RTS         Return from subroutine

;7E:1C37,X has the pointer to the PLM header.

BRANCH_BETA:
[BE 87 1C] [BF 02 00 7F] [29 00 F0] [09 9F 00] [99 17 1E] [29 FF 8F] [9F 02 00 7F] [60]

BE871C      LDX 1C87,Y      Load BB:1C87+Y to X
BF02007F   LDA 7F0002,X      Load 7F:0002+X to A
2900F0      AND #F000      AND A by #F000      ;A=*000
099F00      ORA #009F      OR #009F to A      ;A=*09F (9F -- tile number when respawn)
99171E      STA 1E17,Y      Store A to BB:1E17+Y   ;remember it
29FF8F      AND #8FFF      AND A by #8FFF      ;A=809F/009F
9F02007F   STA 7F0002,X      Store A to 7F:0002+X
60      RTS         Return from subroutine


;7E:1C87,X is the table for PLM's location in the room (7E:0002 array)
;7E:1E17,X has an unknown use (initialized to 0000 by the scroll PLM's startup code) (Changes PLM to this kind of block?)(Or use as a pointer to something)(Ok, this seems to have a lot of uses. Variable.)

BRANCH_ALPHA:
[A9 22 C9] [99 27 1D] [60]

A922C9      LDA #C922      Load #C922 to A      ;reveal the tile if hit by bomb
99271D      STA 1D27,Y      Store A to BB:1D27+Y

;7E:1D27,X is a pointer to current instruction to be run.
[/spoiler]

Then jump to $24B71 ($84:CB71)


[spoiler=Second instruction (drawing)]
10 8C 0A 04 00 45 A3 04 00 AB A3 04 00 51 A3 80 01 57 A3 04 00 51 A3 04 00 4B A3 04 00 45 A3 17 8B BC 86
[/spoiler]




EDIT: To get shotblock checking for beams you'll need to create new PLM (2 words) and write it's address to somewhere in shotblock array in bank $94.

If new PLM will be at $84:F000, write 00 F0 to the array.

At $84:F000 will be 2 words: 04 F0 and DF CA (second instruction from regular shotblock).
At $84:F004 place the code of Super Missile block (posted above) with several changes:
after checking for bombs, LDA 0C18,X again and AND it by #000F. Compare with #0001 (instead of #0200) and the check is done. The rest code will be the same except ORA operator. OR A with value of tile number of your wave block (000..0FF for CRE, 100..3FF for SCENERY).

Crashtour99

 :holyf: Wow, was I ever way the hell off on this one.  LOL
Thanks a TON JAM!  The way you describe it here, it's actually pretty easy to make new shot PLMs.  This has been a valuable learning experience.

*goes off to make a bunch of new shot PLMs with JAM's wisdom*

Crashtour99

#16
Well, it works perfectly with one exception.
When bombs reveal the tile, it still shows the super missile block tile.
However once the block is destroyed it loads the correct tile for respawning.

BRANCH_ALPHA:
[A9 22 C9] [99 27 1D] [60]
A922C9      LDA #C922      Load #C922 to A      ;reveal the tile if hit by bomb
99271D      STA 1D27,Y      Store A to BB:1D27+Y
60             RTS

I know it has something to do with that LDA value.
Supermissiles is C922
Powerbombs is C91C
I just don't know how that value determines the tile displayed.  
If they are pointers for $84 then they read out like this:
84C91C
01 00 E7 A4 BC 86
84C922
01 00 ED A4 BC 86

But I have no idea what this information means.  The 01 00 seems like it's for a frame count.

Ok, I played "follow the leader" with this assuming the 2nd word was a pointer and got.
84A4E7
01 00 57 C0 00 00
84A4ED
01 00 9F C0 00 00
I'm pretty sure that the 2nd word in this string is for locating the tile that's shown.

So it seems like I'll have to give a new value for that LDA, then come up with a few more pointers and such to get the bomb reveal to work properly.

Scyzer

Quote from: Crashtour99 on August 19, 2010, 09:40:31 PM

Ok, I played "follow the leader" with this assuming the 2nd word was a pointer and got.
84A4E7
01 00 57 C0 00 00
84A4ED
01 00 9F C0 00 00
I'm pretty sure that the 2nd word in this string is for locating the tile that's shown.

Correct. The C057 refers to the PB block, the C09F is the SM block. You can check the value needed for any graphic by placing the tile into a room in SMILE 2.5, and pressing A over the tile. This will tell you the tile's number in the tilemap (which tile in the room), the tile data (this is what you want. It refers to the corresponding tile's position in the tiletable), and the BTS value of that specific tile.

Crashtour99

So I was testing these new blocks out and they work perfectly shotwise and such (everything breaks how it's supposed to) but I ran into a few snags.

The first one I know what's wrong.  My blocks aren't showing up using the x-ray scope.  I looked through Kej's docs and found that the x-ray reaction table only goes up to BTS 0F.  My BTS PLMs go from 11 to 18 (respawning and non-respawning for each beam).  Since this table is located in $91 where space is at a premium, just expanding it there is out of the question.  Is it possible to relocate this table out of $91?  Perhaps put it at the end of $84?  In the coding for the x-ray reactions there is an "LDA $D2D6, X   ;Check D2D6,X for matching block type" ($91D2D6 is the start of the reaction table).  I was thinking about possibly replacing this with a JSR to freespace, then JSL to a different bank where the table would be relocated, run the LDA of the table, then return.
If this isn't possible (or would be extremely difficult) then I'd probably just go the easier way of nuking the respawning ones along with the respawning supermissile block (because I made a regular missile block as well).  Which might not be a bad idea anyway because Samus has a nasty habit of getting horribly permastuck when they respawn on top of her.

The second one I'm not so sure about though.  It turns out that if you pause (map/status screen) when you return to the game the blocks I made get blacked out.  If you don't pause, they display perfectly.  Could it be because I located them in the bottom row of the CRE tiletable?  (blocks F8 to FC)

JAM

Quote from: Crashtour99 on August 19, 2010, 02:39:29 PM
This has been a valuable learning experience.
No problems, I learned from the best and almost done a patch for new blocks :wink:

Quote from: Crashtour99 on August 21, 2010, 05:56:34 AM
The first one I know what's wrong.  My blocks aren't showing up using the x-ray scope.  I looked through Kej's docs and found that the x-ray reaction table only goes up to BTS 0F.

Quote from: Crashtour99 on August 21, 2010, 05:56:34 AM
Since this table is located in $91 where space is at a premium, just expanding it there is out of the question.  Is it possible to relocate this table out of $91?  Perhaps put it at the end of $84?  In the coding for the x-ray reactions there is an "LDA $D2D6, X   ;Check D2D6,X for matching block type" ($91D2D6 is the start of the reaction table).
From what I've seen in bank $91, there is also another way. You can compress existing data. Shotblock array can be expanded without a problem because respawning and non-respawning block are using the same graphics when scanned, but it placed twice: for respawning and for non-respawning.

Look at this.
Shotblock array ($8D3CC):
00 00 0E D4
01 00 12 D4
02 00 18 D4
03 00 1E D4
04 00 28 D4
05 00 2C D4
06 00 32 D4
07 00 38 D4
...

respawning 1*1 block (BTS Shot; 00)
$8D40E:
52 00 4E CF

non-respawning 1*1 block (BTS Shot; 04)
$8D428:
52 00 4E CF

See the difference? I can't see it too.
Remaining blocks of the same size is also matches.


In the array use pointers to non-respawning blocks.

[spoiler=hint]
Change
00 00 0E D4
to
00 00 28 D4
and can overwrite the data at $8D40E.

Repeat the process for BTS 01..03
[/spoiler]

You can overwrite the data between $8D40E and $8D427. [$1A bytes]

After this, just expand this array and overwrite data for respawning blocks.


But that's not all...

Shotblock array (continue):
08 00 42 D4
09 00 46 D4
0A 00 4A D4
0B 00 4E D4
0C 00 52 D4
0D 00 56 D4
0E 00 5A D4
0F 00 5E D4

If you will not use BTS $0C..0F, you can completly exclude it. If even if you'll use them...

$8D442:
36 CF 57 00

$8D446:
36 CF 57 00

Again, respawning and non-respawing power bomb blocks (BTS 08 and 09).


$8D44A:
36 CF 9F 00

$8D44E:
36 CF 9F 00

Same for super missile blocks, as you see (BTS 0A and 0B).

And data for BTS 0C..0F is just a copy of super missile blocks. Overwrite them and don't worry.

For BTS 08..0F [$18 bytes can be used, should be enough for missile block, 4 beam blocks and one more block]

As far as I see, if you will use every BTS from 00 to 18, the data between $8D40E and $8D427 will be not enough to expand array. So, expand it from other side too.

There are another array, starting from 8D31E. I think, it's a crumble block array. Do the same, compress the code there. Still a lot of matching data.

Quote from: Crashtour99 on August 21, 2010, 05:56:34 AM
The second one I'm not so sure about though.  It turns out that if you pause (map/status screen) when you return to the game the blocks I made get blacked out.  If you don't pause, they display perfectly.  Could it be because I located them in the bottom row of the CRE tiletable?  (blocks F8 to FC)
Yeah, you can't use 8*8 tiles from $E0 to $FF because you'll get this effect, but you can use 8*8 SCENERY tiles for that or replace some tiles.

Default CRE 8*8 tiles that can be replaced:
4 tiles for block "placed under the item". Block under power bombs is a little bit brighter, but almost the same.
2 tiles for Power Bombs (upper right tile in Power Bomb blocks can be replaced with flipped left tile. They are completly matching).

Don't sure where to get 2 more tiles. That's all I've found. Try to search for something very familar in 8*8 tiles that can be replaced with different flipped tile or use 8*8 tiles from SCENERY (must be the same tile number in any graphic set).

Crashtour99

Heh, I didn't even think about compressing it.  Great idea!

Now I just need to figure out which direction I want to go with these blocks.  (keep respawning ones or not, figuring out where to place them in the CRE, etc.)

Thanks a million JAM. :cool:

Mettyk25jigsaw

#21
I am wondering if anyone out there can help me to find where abouts in the rom one would go to alter the time for respawning shot blocks to reshow themselves again?. I figure it may only be a single byte change by any luck.

P.JBoy

Not a single byte change, but a word change :>

024AEE ; For 1x1 shotblocks
024B11 ; 2x1
024B36 ; 1x2
024B5B ; 2x2

By default they're 0180h (384 frames, about 6.4 seconds)
...

Mettyk25jigsaw

Thanks pjboy, it worked a treat...