tokumaru wrote:
unregistered wrote:
Code:
;= ... (Y / 16) * (2 * 16) + (X / 16)
;= ... ((Y / 16) * 16) * 2 + (X / 16)
Is that correct?
Looks correct to me. Take care with that optimization you did though: you might look at (Y / 16) * 16 and feel tempted to skip all the shifting, but then you'll be keeping the lower 4 bits of Y, which will screw up the result when you add (X / 16) later. The correct way to optimize this formula is (Y AND $F0) * 2 + (X / 16). Multiplications and divisions are obviously done by shifting bits.
Also, since you have only 2 screens worth of collision data, you should ignore the higher bits (you only need bits 0 through 8) of the X coordinate, otherwise you might end up with a pointer to a memory location past the area you have defined for collision data.
unregistered wrote:
My collision data is kept in a 15 rows by 32 columns table in 0600-07DF.
If you add $600 to the result from the formula above, you'll end up with a 16-bit pointer you can use to read from this table. You could even skip adding (X / 16) to the pointer and put that into the Y registers instead. The complete code might look like this:
Code:
lda PixelY ;8-bit Y coordinate
and #$0f ;same as shifting right 4 times and then left 4 times
asl ;shift one more time to complete the multiplication by 32
sta Pointer+0 ;the low byte of the pointer is ready
lda #$06 ;prepare to add the high byte of the base address
adc #$00 ;add to the highest bit (carry) of PixelY * 32
sta Pointer+1 ;the high byte of the pointer is ready
lda PixelX+1 ;high byte of 16-bit X coordinate
lsr ;get the only bit we need from it
lda PixelX+0 ;low byte of the 16-bit X coordinate
ror ;put the high bit in
lsr ;shift 3 times to complete the division by 16
lsr
lsr
tay ;put the row offset in the index register
lda (Pointer), y ;get the collision data
This is just one way to do it. Another approach would be to store the collision data a bit differently, as 2 16x15 blocks, instead of a single 32x15 one. That way you could use only the lower bytes of the coordinates to form an 8-bit index and check the 9th bit of the X coordinate to decide between reading from the first or the second collision table. The options are endless, so pick what works best for you. =)
Thank you * 1,000,000 tokumaru!!!

Being able to see just how it should work meant volumes for me because... I have received help from other threads... I think that's where I got the function
linear_position from... and I also had another function called
use_colTables that I got from Kasumi... and somehow I mixed them both together so our girl would fall and reach the ground and stop!!

And then after fixing some things she began to fall through the ground... and I messed up and couldn't remember how the two functions worked together... until just a little while ago I read your code there and I went and changed
use_colTables and
linear_position16bit a little and IT WORKS!!!!!!!!!!!!!!!!!!!!!!!!!!!! I'M SO HAPPY THANK YOU SO MUCH TOKUMARU!!

It was so nice to finally get some code that encompassed the entire method for linear position! WOOOOOHOOOOOO!!

edit:
tokumaru wrote:
tepples wrote:
This is what Super Mario Bros. does: a 32x13-metatile sliding window stored as two 16x13 halves.
This might be a good approach because it better matches the name table layout, in addition to the possibility of accessing any part of each table with an 8-bit index.
this is part of my edit... wow, it would be fun to try this Mario's way (thank U tepples

)... but it works so far with the 32x15 way that my code does... and I do think that it would be nice to access with an 8 bit index AND also it would be easier to read the two 16x15 halves ( 16x15 instead of 16x13 because my game doesn't use a status bar unlike Mario who does) instead of the 32x15 thing that I have because the hex editor in FCEUX lists everything in 16 sections... the extra lines will be confusing... but I'm going to create a Monitor covering
that so I'll be able to move
it to see the different sections... that will be fun to make I think...
final edit.