Question about resolution and sprite placement?

Discussion of hardware and software development for Super NES and Super Famicom. See the SNESdev wiki for more information.

Moderator: Moderators

Forum rules
  • For making cartridges of your Super NES games, see Reproduction.
Post Reply
Esns68
Posts: 31
Joined: Tue Jan 07, 2020 2:03 pm

Question about resolution and sprite placement?

Post by Esns68 »

Hi, I'm just starting SNES Assembly and am starting to learn how everything works.

I'm messing with the source code included in the famous SNES starter-kit, specifically Walker.asm and loadgraphics.asm,
cause right now I'm trying to learn how resolution and sprites work.

I mostly was wondering about the placing the sprite on the screen part:

[
;setup our walking sprite
;put him in the center of the screen
lda #($80-16)
sta SpriteBuf1+sx
lda #(224/2-16)
sta SpriteBuf1+sy
]

Just wondered how it works when you want to put them on a specific spot on the resolution,
assuming it is the usual 256×224.

I'm guessing for the x and y instructions, you start from 0 in hexadecimal, then go further up, equal to the desired pixel location on the resolution.
So for example, lets say I want to place the sprite at 142x182, I would enter $8E and $B6.
Is this correct?

While I'm asking this, I was also just wondering:
What were the 16's for in the parenthesis?
What is a sprite buffer?
And, how do you set the resolution to begin with?

Thank you so much for your time! I'm excited to be learning this.
DashEightMate
Posts: 17
Joined: Wed Aug 05, 2020 12:22 pm

Re: Question about resolution and sprite placement?

Post by DashEightMate »

I can answer some of these questions.

On the snes, data about a sprite is stored in Object Attribute Memory. There are two "sections", each of which store different data. Fullsnes.txt can explain the layout better than I can:

Code: Select all

Contains data for 128 OBJs. OAM Size is 512+32 Bytes. The first part (512
bytes) contains 128 4-byte entries for each OBJ:
  Byte 0 - X-Coordinate (lower 8bit) (upper 1bit at end of OAM)
  Byte 1 - Y-Coordinate (all 8bits)
  Byte 2 - Tile Number  (lower 8bit) (upper 1bit within Attributes)
  Byte 3 - Attributes
Attributes:
  Bit7    Y-Flip (0=Normal, 1=Mirror Vertically)
  Bit6    X-Flip (0=Normal, 1=Mirror Horizontally)
  Bit5-4  Priority relative to BG (0=Low..3=High)
  Bit3-1  Palette Number (0-7) (OBJ Palette 4-7 can use Color Math via CGADSUB)
  Bit0    Tile Number (upper 1bit)
After above 512 bytes, additional 32 bytes follow, containing 2-bits per OBJ:
  Bit7    OBJ 3 OBJ Size     (0=Small, 1=Large)
  Bit6    OBJ 3 X-Coordinate (upper 1bit)
  Bit5    OBJ 2 OBJ Size     (0=Small, 1=Large)
  Bit4    OBJ 2 X-Coordinate (upper 1bit)
  Bit3    OBJ 1 OBJ Size     (0=Small, 1=Large)
  Bit2    OBJ 1 X-Coordinate (upper 1bit)
  Bit1    OBJ 0 OBJ Size     (0=Small, 1=Large)
  Bit0    OBJ 0 X-Coordinate (upper 1bit)
I'm assuming the "sprite buffer" is how the program builds the OAM entry for that sprite. Does it get transferred into VRAM once it's done building the buffer?

Positioning the sprite has a few quirks on the snes as well. Like you said, you put in the hex value for the location of the sprite from the top left. However, although a byte is large enough to cover all 256 pixels, it's not large enough to allow a sprite to go offscreen. In the high portion of OAM, there's a 9th x coordinate bit so that sprites can go offscreen to the right and left.

As for "setting the resolution", for the most part you're going to have to work with the default. However, there are a couple modes where you can enable a sort of interlacing. I'm not too well versed in these but I do know that they were almost never used during the commercial lifespan of the snes. Unless you absolutely need the extra resolution they are too much hassle for what they're worth.

I'm not entirely sure about the "-16"s in the code.
Myself086
Posts: 158
Joined: Sat Nov 10, 2018 2:49 pm

Re: Question about resolution and sprite placement?

Post by Myself086 »

Esns68 wrote: Wed Jan 27, 2021 6:57 pm I'm guessing for the x and y instructions, you start from 0 in hexadecimal, then go further up, equal to the desired pixel location on the resolution.
So for example, lets say I want to place the sprite at 142x182, I would enter $8E and $B6.
Is this correct?
You don't need to write number in hexadecimal, you can use decimal, binary, octal or hexadecimal based on the situation. If your decision is based on decimal, keep your number in decimal. The origin (0, 0) is top left and the coordinates are a 1:1 to pixel count. Placing a sprite at 142,182 would place the top left corner of the sprite at 142,182.
Esns68 wrote: Wed Jan 27, 2021 6:57 pm What were the 16's for in the parenthesis?
I'm assuming the sprites are 32x32 in size so placing a sprite at $80-16 (or 128-16) would place it perfectly centered.
You can also think of it this way: (resolution_width - sprite_width) / 2 = (256 - 32) / 2 = $80-16
Esns68 wrote: Wed Jan 27, 2021 6:57 pm What is a sprite buffer?
It contains all of your sprites before being transferred to the OAM. 128 sprites in total.
Esns68 wrote: Wed Jan 27, 2021 6:57 pm And, how do you set the resolution to begin with?
There are only 3 options to change resolution:
- 15 extra scan lines
- Interlace, effectively doubles vertical resolution.
- Hire mode, effectively doubles horizontal resolution.
Each one comes at a cost elsewhere, usually it's best to stay with the standard 256x224 resolution.
Esns68
Posts: 31
Joined: Tue Jan 07, 2020 2:03 pm

Re: Question about resolution and sprite placement?

Post by Esns68 »

Thank you so much for the replies, they were very helpful.

@myself - Oh, so is it automatically set to 256x244? Without needing to write it or anything?
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Question about resolution and sprite placement?

Post by tepples »

The init code sets the resolution. The init code in my lorom-template, for example, set it to 256x224.
Pokun
Posts: 2681
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: Question about resolution and sprite placement?

Post by Pokun »

Almost nothing is automatically set to anything, so you have to initialize everything before doing anything else. You are probably using the init code that most guides provide though, so the resolution is probably already set. The devdocs has a page on what values you can use for all CPU and PPU registers as a beginner to make sure everything has a good default value.
That way the screen settings will be: mode 0, 256x224 dot resolution, H-pseudo 512 mode is off and interlace is off. These settings are set at register $2133 (except screen mode which is set at $2105). You might want to change to mode 1 for the game though as mode 0 has restricted number of colours for the background. That's what most games uses most of the time. Mode 0 is mainly useful for menus and stuff, or if you really need all 4 background layers.

To make it clear, the OAM buffer is a place in RAM that you use as a shadow of the real OAM. You write to it to update your sprites (e.g. when moving them) and in vblank you have a routine that copies (using general-purpose DMA) the buffer content to the real OAM so that the updates actually show up on screen. This buffering technique allows you to have your sprite manipulation outside of the expensive vblank time, since RAM can be written to at any time unlike OAM. Since OAM is 544 byte (512+32 for low+high OAM tables), your OAM buffer also needs to be 544 byte. The guide you are using is probably doing all this.
Post Reply