- For making cartridges of your Super NES games, see Reproduction.
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
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.
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)
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.
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.
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
It contains all of your sprites before being transferred to the OAM. 128 sprites in total.
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.
@myself - Oh, so is it automatically set to 256x244? Without needing to write it or anything?
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.