I'm trying to create a generic 2x2 meta sprite rendering system and I'm having an issue with it where if I store the hardware sprites anywhere but the beginning of my oam buffer I get a bunch of garbage sprites all over the screen. I'm using a data format like this:
I've got some constants that I'm using to select between 16 byte sections of my oam buffer
And here is my meta sprite drawing routine:
and I'm calling my meta sprite drawing routine like this:
This works fine if in my meta sprite calling code I set my sprite_id to #$00, but if I set it to any of the other available ids I get a bunch of garbage all over the screen that moves with my sprite and gets horizontally flipped along with my sprite. Is there a reason I can't have gaps in my oam buffer or is there something really wrong with my code?
Code:
player_frame_1:
; byte 0 - meta sprite y offset, byte 1 - tile, byte 3 - attributes, byte 4 - meta sprite x offset
.byte $00,$32,%00000000,$00
.byte $00,$33,%00000000,$08
.byte $08,$34,%00000000,$00
.byte $08,$35,%00000000,$08
; byte 0 - meta sprite y offset, byte 1 - tile, byte 3 - attributes, byte 4 - meta sprite x offset
.byte $00,$32,%00000000,$00
.byte $00,$33,%00000000,$08
.byte $08,$34,%00000000,$00
.byte $08,$35,%00000000,$08
I've got some constants that I'm using to select between 16 byte sections of my oam buffer
Code:
sprite_id_constants:
.byte $00, $10, $20, $30, $40, $50, $60, $70
.byte $00, $10, $20, $30, $40, $50, $60, $70
And here is my meta sprite drawing routine:
Code:
LEFT = 1
RIGHT = 0
.proc draw_metasprite
; set up oam offset based on sprite id
ldx sprite_id
ldy sprite_id_constants, x
:
; deal with byte 0 - y pos
lda (sprite_addr), y
clc
adc sprite_y
sta oam, y
; deal with byte 1 - tile
iny
lda (sprite_addr), y
sta oam, y
; deal with byte 2 - attributes
iny
lda sprite_direction
cmp #LEFT
beq set_flipped_horizontal
lda #%00000000
sta oam, y
jmp done_flipping_sprite
set_flipped_horizontal:
lda #%01000000
sta oam, y
done_flipping_sprite:
; deal with byte 3 - x pos
iny
; if player is facing left subtract offset if not, add it
lda sprite_direction
cmp #LEFT
bne add_offset
subtract_offset:
; put offset into tmp
lda sprite_x ; (player_curr_sprite), y
sec
sbc (sprite_addr), y
sta oam, y
jmp :+
add_offset:
lda (sprite_addr), y
clc
adc sprite_x
sta oam, y
:
; increase y by for to start at the next row
iny
cpy #$10 ; loop four times, once per row
bne :--
rts
.endproc
RIGHT = 0
.proc draw_metasprite
; set up oam offset based on sprite id
ldx sprite_id
ldy sprite_id_constants, x
:
; deal with byte 0 - y pos
lda (sprite_addr), y
clc
adc sprite_y
sta oam, y
; deal with byte 1 - tile
iny
lda (sprite_addr), y
sta oam, y
; deal with byte 2 - attributes
iny
lda sprite_direction
cmp #LEFT
beq set_flipped_horizontal
lda #%00000000
sta oam, y
jmp done_flipping_sprite
set_flipped_horizontal:
lda #%01000000
sta oam, y
done_flipping_sprite:
; deal with byte 3 - x pos
iny
; if player is facing left subtract offset if not, add it
lda sprite_direction
cmp #LEFT
bne add_offset
subtract_offset:
; put offset into tmp
lda sprite_x ; (player_curr_sprite), y
sec
sbc (sprite_addr), y
sta oam, y
jmp :+
add_offset:
lda (sprite_addr), y
clc
adc sprite_x
sta oam, y
:
; increase y by for to start at the next row
iny
cpy #$10 ; loop four times, once per row
bne :--
rts
.endproc
and I'm calling my meta sprite drawing routine like this:
Code:
.proc draw_player
; this macro just sets a pointer to point to
; whichever animation frame I'd like to draw
load_pointer sprite_addr, player_map
; set up x and y values
lda player_x
sta sprite_x
lda player_y
sta sprite_y
; flag that indicates whether or not to flip horizontal
lda player_direction
sta sprite_direction
; sprite_id tells the meta sprite drawing routine which section of the oam buffer to
; copy the meta sprite to
lda #$01
sta sprite_id
; build the buffer
jsr draw_metasprite
rts
.endproc
; this macro just sets a pointer to point to
; whichever animation frame I'd like to draw
load_pointer sprite_addr, player_map
; set up x and y values
lda player_x
sta sprite_x
lda player_y
sta sprite_y
; flag that indicates whether or not to flip horizontal
lda player_direction
sta sprite_direction
; sprite_id tells the meta sprite drawing routine which section of the oam buffer to
; copy the meta sprite to
lda #$01
sta sprite_id
; build the buffer
jsr draw_metasprite
rts
.endproc
This works fine if in my meta sprite calling code I set my sprite_id to #$00, but if I set it to any of the other available ids I get a bunch of garbage all over the screen that moves with my sprite and gets horizontally flipped along with my sprite. Is there a reason I can't have gaps in my oam buffer or is there something really wrong with my code?