16x32 sprites in interlaced mode?

Discussion of hardware and software development for Super NES and Super Famicom.

Moderator: Moderators

Forum rules
  • For making cartridges of your Super NES games, see Reproduction.
Post Reply
marshoepial
Posts: 16
Joined: Wed Aug 05, 2020 3:36 pm

16x32 sprites in interlaced mode?

Post by marshoepial » Fri Dec 04, 2020 7:49 pm

Right now, my program has an HDMA partway down the screen which turns both interlace mode and 16x32 sprite size on. I understand that this is an undocumented size but I thought it would help cut down on sprite count while still maintaining a good aspect ratio for the metasprite I need to display. In Mesen-S it displays like I'd expect, square but with half pixels vertically. But in bsnes it only displays the top half of the sprite. I also asked someone to try it on their flashcart and it behaved the same way as bsnes. Disabling interlaced mode displays the sprites in 16x32 like you'd expect (this isn't tested on the flashcart though.) Here is the code for the HDMA, ran in vblank:

Code: Select all

        HDMA_set_absolute 0, 0, SETINI, hdma_hires
        HDMA_set_absolute 1, 0, OBJSEL, hdma_sprite_comp
        lda #%00000011
        sta $420C

        rtl

; =======

.segment "RODATA"

hdma_hires:
        .byte $7F, $00, $05, $00, $60, $03, $00
hdma_sprite_comp:
        .byte $7F, $00, $05, $00, $60, $C7, $00
Is this documented? Am I missing something, or is this just one of the quirks of the unofficial sprite sizes?

Kingizor
Posts: 21
Joined: Sat Jun 18, 2011 10:50 am

Re: 16x32 sprites in interlaced mode?

Post by Kingizor » Sat Dec 05, 2020 3:43 am

The only mention of it as far as I know is here (edit: and here).

I've tested it (on hardware) and it seems to happen with both 16x32 configurations. It does not happen with 32x64 sprites, and that makes it rather puzzling.

Just to clarify what's happening:

---
Enabling $2133.1 squashes sprites by drawing every other line of a sprite each frame instead of every line.

Say if you had a 8x8 sprite at Y=120. On even (?) frames you would get lines 0,2,4,6 of the sprite on 120-123, whereas on odd (?) frames you would get lines 1,3,5,7 instead. When the resulting picture is deinterlaced we get the whole sprite back, but packed into an area of half the height. The effect ends up being that a 8x8 sprite gets squashed into a 8x4 space, 16x16 gets squashed into 16x8 and so on.

The sole exception occurs with 16x32 sprites. Although we would expect the whole 16x32 sprite to be squashed into a 16x16 space, instead what seems to happen is that only the top half of the sprite (16x16) is considered before rendered and squashed into a 16x8 space.

i.e. crop 16x32 to 16x16 and then squash to 16x8.
---

Does this sound right?

The other better-known and easier explained edge case is the one with vertical flipping; that if rectangular sprites are flipped vertically, they get flipped as stacked squares with height = width (or at least that's the most convenient explanation). The flipping one applies to both 16x32 and 32x64 sprites, but this one only applies to the former and that makes things complicated. With only the dimensions, sprite mode indexes and OAM size bit at hand, I can't see any obvious solution that would explain why it happens. As to whether those quirks are related, who knows?

Your setup looks fine, but writing to anything related to OAM during the active frame is discouraged and that particular register is probably being used regularly if not constantly (don't complain if it works though!). Setting the low bit of $2133 isn't required and probably won't have any effect here as far as I'm aware.
Last edited by Kingizor on Sun Dec 20, 2020 6:40 pm, edited 1 time in total.

psycopathicteen
Posts: 2980
Joined: Wed May 19, 2010 6:12 pm

Re: 16x32 sprites in interlaced mode?

Post by psycopathicteen » Sat Dec 12, 2020 9:45 am

I've always what kind of internal logic ends up with 16x32 and 32x64 sprites in the first place.

Post Reply