It is currently Mon Feb 19, 2018 9:22 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 5 posts ] 
Author Message
 Post subject: corrupted sprites
PostPosted: Thu Feb 08, 2018 9:32 pm 
Offline

Joined: Sat Sep 27, 2014 10:10 pm
Posts: 20
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:

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


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


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


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 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?


Top
 Profile  
 
 Post subject: Re: corrupted sprites
PostPosted: Thu Feb 08, 2018 9:45 pm 
Offline
User avatar

Joined: Wed Apr 02, 2008 2:09 pm
Posts: 1088
Because you're using y for both an offset in your OAM and an offset in your data.

Let's assume Y is 0.
Code:
      lda (sprite_addr), y
      clc
      adc sprite_y
      sta oam, y

You load byte 0 of your sprite data, you store it to byte 0 of OAM. Awesome!
Let's assume Y is 64.
Code:
      lda (sprite_addr), y
      clc
      adc sprite_y
      sta oam, y

You load entirely past your intended data because (sprite_addr), y is loading player_frame_1+64.
But it is stored in the right place in OAM.
The simple fix? Use both X and Y.
Code:
    ldy sprite_id
    lda sprite_id_constants, y
    tax
   :
      ; deal with byte 0 - y pos
      ldy #0;Start at the beginning of the data in the pointer
      lda (sprite_addr), y
      clc
      adc sprite_y
      sta oam, x

      ; deal with byte 1 - tile
      iny
      inx
      lda (sprite_addr), y
      sta oam, x
;etc
;You now need iny and inx
;you lda (sprite_addr), y
;and you sta oam, x
;in the other places in the code


I... also have to mention this:
Quote:
; byte 0 - meta sprite y offset, byte 1 - tile, byte 3 - attributes, byte 4 - meta sprite x offset

0, 1, 3, 4. Please change that to either 0, 1, 2, 3 or 1, 2, 3, 4

Edit: An explanation without code: You always want to copy FROM the same bytes (relative to the pointer), but you want to change where you're copying TO (relative to OAM). If you use Y for both, you can't change where you copy TO without also changing where you copy FROM. That's why X is needed.

_________________
https://kasumi.itch.io/indivisible


Last edited by Kasumi on Thu Feb 08, 2018 10:06 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: corrupted sprites
PostPosted: Thu Feb 08, 2018 10:05 pm 
Offline

Joined: Sat Sep 27, 2014 10:10 pm
Posts: 20
Edit: I noticed I had an extra inx at the end. Now that I've removed that I've only got 1/4 of my meta sprite. I'm looking into this now

Edit2: as for your second comment... :oops: yeah I wrote that comment quickly for the post. I didn't have a comment there in my code, but I see what you're saying

That makes sense. I tried altering my meta sprite drawing code and I've got a similar problem but now it seems to be messing with the tile and palette and moving diagonally. Here is the updated code:

Code:
LEFT = 1
RIGHT = 0

.proc draw_metasprite
    ; set up oam offset based on sprite id
    ldy sprite_id ; sprite id 0
    lda sprite_id_constants, y ; low byte for oam offset
    tax
   :
        ldy #$00
      ; deal with byte 0 - y pos
      lda (sprite_addr), y
      clc
      adc sprite_y
      sta oam, x

      ; deal with byte 1 - tile
      iny
        inx
      lda (sprite_addr), y
      sta oam, x

      ; deal with byte 2 - attributes
      iny
        inx
      lda sprite_direction
      cmp #LEFT
      beq set_flipped_horizontal
      ; if we don't need to flip, just set whats defaulted
      lda #%00000000 ; (player_curr_sprite), y
      sta oam, x
      jmp done_flipping_sprite
set_flipped_horizontal:
      lda #%01000000
      sta oam, x
done_flipping_sprite:

      ; deal with byte 3 - x pos
      iny
        inx
      ; 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, x
      jmp :+
add_offset:
      lda (sprite_addr), y
      clc
      adc sprite_x
      sta oam, x
        :
      ; increase y by for to start at the next row   
      iny
        inx
        ; increase x for oam
        inx
      cpy #$10 ; loop four times, once per row
   bne :--
   rts
.endproc


Top
 Profile  
 
 Post subject: Re: corrupted sprites
PostPosted: Thu Feb 08, 2018 10:24 pm 
Offline
User avatar

Joined: Wed Apr 02, 2008 2:09 pm
Posts: 1088
Yeah, the double inx was one thing.

Another thing I see is totally my fault. This:
Code:
cpy #$10 ; loop four times, once per row
   bne :--
   rts

branches to here:
Code:
:
        ldy #$00

So your loop keeps reloading Y with 0 and it never stops branching. That's my bad, I don't use nameless labels. They look like comments. So:
Code:
        ldy #$00
:

Would probably do it.

_________________
https://kasumi.itch.io/indivisible


Top
 Profile  
 
 Post subject: Re: corrupted sprites
PostPosted: Thu Feb 08, 2018 10:29 pm 
Offline

Joined: Sat Sep 27, 2014 10:10 pm
Posts: 20
Kasumi wrote:
Code:
        ldy #$00
:

Would probably do it.


Sweet thanks a lot man. That did it. I'm now reconsidering my use of anonymous labels. They're kind of confusing me too when I read my own code.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 6 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group