I'm not sure I understand the purpose of the new code. t0 and t1 have the address we want to load the data from. Y keeps track of how far into the data we are.
Code: Select all
TYA;We're pushing the value in Y
PHA;To the stack
lda (t0+0), y ;We're loading from the data. So shouldn't this mean the value we've meant to load is now in A?
TAY;But then we move it into Y
LDA $0000, y;And load a zero page variable?
STA t2+1
PLA ;<-------------
TAY
This code suggests your table whose address is stored at t0 contains a zero page index that contains the actual value you want. This is not necessarily bad, but why the extra step? Why not just store the actual value you want rather than a reference to a variable that contains that value?
My sister helped me to learn that it was starting with #$03 because oX is at address $0003
I'm not sure I understand. Where the variable is on the zero page should have no bearing on what its initial/current value would ever be.
If your table was set up like this:
Code: Select all
sprite_layout_one:
.db $00;Y offset for sprite 0
.db $00;Tile for sprite 0
.db %00000000;Attributes for sprite 0
.db $00;X offset for sprite 0
.db $00;Y offset for sprite 1
.db $01;Tile for sprite 1
.db %00000000;Attributes for sprite 1
.db $08;X offset for sprite 1
.db $08;Y offset for sprite 2
.db $02;Tile for sprite 2
.db %00000000;Attributes for sprite 2
.db $00;X offset for sprite 2
.db $08;Y offset for sprite 3
.db $03;Tile for sprite 3
.db %00000000;Attributes for sprite 3
.db $08;X offset for sprite 3
;Sprite 0 is drawn using tile index #$00 directly at the X and Y position.
;Sprite 1 is drawn using tile index #$01 eight pixels to the right of the X position, and directly at the Y position
;Sprite 2 is drawn using tile index #$02 directly at the X position, and eight pixels below the Y position
;Sprite 3 is drawn using tile index #$03 eight pixels to the right of the X position, and eight pixels below the Y position
You'd already have all the info you need by accessing sprite_layout_one. Like so:
Code: Select all
@loop:
lda sprite_layout_one,y;This is how far the sprite is OFFSET from our Y position
clc;So we add it to the Y position
adc oY
sta sprite,x
iny
inx
lda sprite_layout_one,y;Tile index
sta sprite,x
iny
inx
lda sprite_layout_one,y;Sprite attributes
sta sprite,x
iny
inx
lda sprite_layout_one,y;This is how far the sprite is OFFSET from our X position
clc;So we add it to the x position
adc oX
sta sprite,x
iny
inx
dec t2
bne @loop
stx oamIndex
rts
The only thing missing in the above is the indirect part.
Code: Select all
;If the low and high bytes of sprite_layout_one were in t0 and t1, the following two lines of code would access the same value. (And put it into A)
lda sprite_layout_one,y
lda (t0),y
So a full version might look like...
Code: Select all
; t0-t2 are temporary zero page locations holding
; the address of a particular sprite layout and the
; number of sprites left to draw
draw_sprite:
lda sprite_layouts_lo, x
sta t0
lda sprite_layouts_hi, x ;<-- ABSOLUTE INDEXED ADDRESSING
sta t0+1
lda sprite_layouts_count, x ;<-- ABSOLUTE INDEXED ADDRESSING
sta t2
ldy #0
ldx oamIndex; oamIndex is a variable tracking how far you've written
; into shadow OAM (customarily at $0200-$02FF)
@loop:
lda (t0),y;This is how far the sprite is OFFSET from our Y position
clc;So we add it to the Y position
adc oY
sta sprite,x
iny
inx
lda (t0),y;Tile index
sta sprite,x
iny
inx
lda (t0),y;Sprite attributes
sta sprite,x
iny
inx
lda (t0),y;This is how far the sprite is OFFSET from our X position
clc;So we add it to the x position
adc oX
sta sprite,x
iny
inx
dec t2
bne @loop:
stx oamIndex
rts
sprite_layout_one:
.db $00;Y offset for sprite 0
.db $00;Tile for sprite 0
.db %00000000;Attributes for sprite 0
.db $00;X offset for sprite 0
.db $00;Y offset for sprite 1
.db $01;Tile for sprite 1
.db %00000000;Attributes for sprite 1
.db $08;X offset for sprite 1
.db $08;Y offset for sprite 2
.db $02;Tile for sprite 2
.db %00000000;Attributes for sprite 2
.db $00;X offset for sprite 2
.db $08;Y offset for sprite 3
.db $03;Tile for sprite 3
.db %00000000;Attributes for sprite 3
.db $08;X offset for sprite 3
;Sprite 0 is drawn using tile index #$00 directly at the X and Y position.
;Sprite 1 is drawn using tile index #$01 eight pixels to the right of the X position, and directly at the Y position
;Sprite 2 is drawn using tile index #$02 directly at the X position, and eight pixels below the Y position
;Sprite 3 is drawn using tile index #$03 eight pixels to the right of the X position, and eight pixels below the Y position
sprite_layouts_lo:
.db <sprite_layout_one
sprite_layouts_hi:
.db >sprite_layout_one
sprite_layouts_count:
.db 4;There are four sprites in sprite_layout_one
So if you did
You'd get a 16x16 metasprite composed of tile $00 for top left corner, tile $01 for the top right corner, tile $02 for the bottom left corner, tile $03 for the bottom right corner. All with no flipping, and palette 0.
I have zero idea what your tables look like or how your data is stored. So here's a way store the data and access it that might be different from what you're doing.
I did test the above, but full disclosure: I tested it very briefly and I had to convert its syntax to NESASM, so something small done in that process may have fixed a potential issue. But I can fix this if it's broken. I cannot help fix what you have without... the rest of what you have.
edit: I made a test rom, because lately I've been making a lot of mistakes by trying to help without testing my code. And since the test rom exists, may as well attach it. It is the definition of quick and dirty, you've got to edit RAM manually to see the sprite move. ($03 and $04 are its X and Y positions respectively.) After initialization it literally does nothing but run this routine in the main loop every frame. The NMI updates palettes so the sprite is visible, and of course does the sprite DMA. Nothing else. (Also, adc oY and adc oX end up assembled as absolute not zero page, because I didn't bother doing zero page the nesasm way when converting.)