News:

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

Main Menu

asm - air fool xray's block collision code

Started by softglow, December 24, 2013, 09:27:39 PM

Previous topic - Next topic

softglow

Can someone check my work and tell me if I went off the rails somewhere?

I'm chasing a random idea where I want to write a patch that makes "blocks passable when <some item> is equipped"--they should be air when the condition is met, solid otherwise.

I started in Kejardon's BlockCollisReact.txt which, first of all, points me into bank $94 for everything.  Then the "XRay Air" type (2) has horizontal collision handling code at $9018 and vertical at $901A.  At $9018 are just two opcodes, CLC and RTS, simple enough.  Always air, just like $8F47 (for the air tile types).

I pulled up squishy's ASMInstructionList.rtf and ASMMnemonics.rtf and proceeded to disassemble the code at $94:901A.  This is what I came up with (pardon if I mix up some # signs, this is my first ASM in years):


LDX $0DC4     ; load block index from RAM 7E:0DC4
LDA $7F6402,X ; copy BTS into A
AND #$00FF    ; drop high byte of BTS value, A=00..FF
ASL           ; convert ordinal/index to offset into pointer table
TAX           ; transfer (copy?) A into X
JSR ($8FF6,X) ; subroutine's address is the value stored in 8FF6+X
CLC           ; always air
RTS           ; finished


At $94:8FF6 seems to be 22 bytes / 11 pointers, which are all $8E81, which disassembles as another (redundant) CLC/RTS pair.  After that, the "table" overlaps the $9018/$901A opcodes, implying that BTS values between at least $0C..15 aren't trivially usable.

It seems to me, then, that the effect of colliding vertically with Air Fool XRay tiles is to run a useless, redundant BTS routine, then unconditionally treat the tile as air.  Which, okay, it's supposed to be air, but... why the BTS check if it's not going to actually do anything?

I'd suspect the "Fool XRay" nature is involved in the answer, but if I understand XRayBlocks.txt, all that lives in separate tables over in bank $91.

So that's the question.  Did I get all of that right?  Is the BTS check+table actually useless, or does it have some hidden function I missed?

edit: noticed I had the wrong LDA addressing mode, meaning the LDX is actually useful.  Updated disassembly.

Crashtour99

I think the main error is that you're using the wrong tile type.  An air tile is coded in a way that it really doesn't have collision checking (as you've observed), it just has a "touch" routine, or rather a pointer to code that it runs based on BTS while Samus is inside the block, which usually doesn't even do anything.
If what you've got there is correct, then you can change one of those pointers in the table to run some custom code like checking if a certain item is equipped, and then treat that as solid or air depending, at least for vertical stuffs.

A better approach might be to use a tile type that already has collision checking built in for both directions, so something like a spike or crumble BTS.  I myself made some Phase Blocks very much like what you seem to be wanting to do using iirc spike BTS and unused item bits.  It's really just putting a pointer in a table and running some custom code, though for something like a crumble BTS it would spawn a PLM (which could come in handy if you want the tile to change gfx when you contact it).

softglow

Quote from: Crashtour99 on December 25, 2013, 01:02:09 AM
A better approach might be to use a tile type that already has collision checking built in for both directions, so something like a spike or crumble BTS.  I myself made some Phase Blocks very much like what you seem to be wanting to do using iirc spike BTS and unused item bits.  It's really just putting a pointer in a table and running some custom code, though for something like a crumble BTS it would spawn a PLM (which could come in handy if you want the tile to change gfx when you contact it).

Interesting thought.  Having them crumble would make it a bit more obvious when you hit them with the right equipment.

I think I'm looking at a call chain like: Generic block code JSRs to block type code, which JSRs to code from table according to BTS.  The block type and BTS code I can readily patch, but the default BTS code seems completely useless.  It's a lot of bytes to spend for one byte of actual effect (the CLC instruction to signal "act as air"), which is what makes me wonder if I'm missing something... or is the whole ROM coding kind of sloppy like that?

Crashtour99

It's a combination of sloppy and unused versatility.  On one hand having tables like that allows for adding in all sorts of nifty special blocks, but then again it's not actually USED so it's just wasting space.  Good for us really, since it makes it easier to add new stuff in.

There are a number of places in the ROM that are coded pretty poorly though.  As an example, I once rewrote a routine/jump table in $91 saving something like 120 bytes or so.  However the game was written by a bunch of different people that definitely didn't have the same skill level when it came to coding, because there are other sections that are coded quite brilliantly.