Few questions about Offset-per-tile mode
Moderator: Moderators
Forum rules
- For making cartridges of your Super NES games, see Reproduction.
Few questions about Offset-per-tile mode
Now I add Offset-per-tile mode in my FPGA SNES, for now I did Offset-per-tile only for BG1 in BGMODE 2 (it works in Tetris Attack, Battletoads in battlemaniacs and SNES burn-in test rom), and I have a few questions.
As I understand, scrolling values in BG3 common to BG1 and BG2, but read 2 times: one for BG1 with BG1HOFS, and one for BG2 with BG2HOFS. Also, I think that in hardware reading scrolling values from BG3 occurs after reading tiles of BG1 and BG2 (in the place where the reading occurs tiles of BG3 and BG4 in BGMODE 0), therefore this scrolling values apply to next tile in row. I'm right or not?
And the second question, what games or test roms using Offset-per-tile in BGMODE 4 and 6?
As I understand, scrolling values in BG3 common to BG1 and BG2, but read 2 times: one for BG1 with BG1HOFS, and one for BG2 with BG2HOFS. Also, I think that in hardware reading scrolling values from BG3 occurs after reading tiles of BG1 and BG2 (in the place where the reading occurs tiles of BG3 and BG4 in BGMODE 0), therefore this scrolling values apply to next tile in row. I'm right or not?
And the second question, what games or test roms using Offset-per-tile in BGMODE 4 and 6?
Re: Few questions about Offset-per-tile mode
lidnariq posted a test ROM here which uses modes 0-6.
viewtopic.php?f=12&t=14945
And I think Yoshi's Island uses an offset per tile mode on the "Touch Fuzzy Get Dizzy" level.
viewtopic.php?f=12&t=14945
And I think Yoshi's Island uses an offset per tile mode on the "Touch Fuzzy Get Dizzy" level.
nesdoug.com -- blog/tutorial on programming for the NES
-
- Posts: 611
- Joined: Mon Jan 23, 2006 7:47 am
- Location: Germany
- Contact:
Re: Few questions about Offset-per-tile mode
Also in the levels that use lava or stone blocks that move up/down, iirc.
My current setup:
Super Famicom ("2/1/3" SNS-CPU-GPM-02) → SCART → OSSC → StarTech USB3HDCAP → AmaRecTV 3.10
Super Famicom ("2/1/3" SNS-CPU-GPM-02) → SCART → OSSC → StarTech USB3HDCAP → AmaRecTV 3.10
Re: Few questions about Offset-per-tile mode
Thanks, lidnariq's test rom very helped me.
Re: Few questions about Offset-per-tile mode
If Mode 2 fetches only two words of offset-per-tile data for BG1 and BG2, then how calculate HOFS and VOFS for BG3?AWJ wrote:Mode 2 fetches the nametables, then two words of offset-per-tile data (again, we would need the lower address lines to distinguish them), then the patterns. Since the offset-per-tile is fetched after the nametables, each offset-per-tile fetch must apply to the next set of nametable fetches. This explains why offset-per-tile never applies to the first visible tile in a scanline.Code: Select all
0.000004208333333, 0, 0, 1, 0, 1, 0, 0, 1 ; BG2 nametable .1666 us 0.000004375000000, 0, 0, 0, 0, 0, 0, 0, 1 ; BG1 nametable .1666 us 0.000004541666667, 0, 1, 0, 1, 0, 0, 0, 1 ; BG3 OPT .3750 us 0.000004916666667, 1, 0, 0, 0, 0, 0, 0, 1 ; BG2 4bpp .3750 us 0.000005291666667, 1, 0, 1, 0, 1, 0, 0, 1 ; BG1 4bpp .3750 us 0.000005666666667, 0, 0, 1, 0, 1, 0, 0, 1 ; BG2 nametable .2083 us 0.000005875000000, 0, 0, 0, 0, 0, 0, 0, 1 ; BG1 nametable .1666 us 0.000006041666667, 0, 1, 0, 1, 0, 0, 0, 1 ; BG3 OPT .3750 us 0.000006416666667, 1, 0, 0, 0, 0, 0, 0, 1 ; BG2 4bpp .3750 us 0.000006791666667, 1, 0, 1, 0, 1, 0, 0, 1 ; BG1 4bpp .3750 us 0.000007166666667, 0, 0, 1, 0, 1, 0, 0, 1 ; BG2 nametable
-
- Posts: 3140
- Joined: Wed May 19, 2010 6:12 pm
Re: Few questions about Offset-per-tile mode
It doesn't. Mode 2 only has 2 layers.srg320 wrote:If Mode 2 fetches only two words of offset-per-tile data for BG1 and BG2, then how calculate HOFS and VOFS for BG3?AWJ wrote:Mode 2 fetches the nametables, then two words of offset-per-tile data (again, we would need the lower address lines to distinguish them), then the patterns. Since the offset-per-tile is fetched after the nametables, each offset-per-tile fetch must apply to the next set of nametable fetches. This explains why offset-per-tile never applies to the first visible tile in a scanline.Code: Select all
0.000004208333333, 0, 0, 1, 0, 1, 0, 0, 1 ; BG2 nametable .1666 us 0.000004375000000, 0, 0, 0, 0, 0, 0, 0, 1 ; BG1 nametable .1666 us 0.000004541666667, 0, 1, 0, 1, 0, 0, 0, 1 ; BG3 OPT .3750 us 0.000004916666667, 1, 0, 0, 0, 0, 0, 0, 1 ; BG2 4bpp .3750 us 0.000005291666667, 1, 0, 1, 0, 1, 0, 0, 1 ; BG1 4bpp .3750 us 0.000005666666667, 0, 0, 1, 0, 1, 0, 0, 1 ; BG2 nametable .2083 us 0.000005875000000, 0, 0, 0, 0, 0, 0, 0, 1 ; BG1 nametable .1666 us 0.000006041666667, 0, 1, 0, 1, 0, 0, 0, 1 ; BG3 OPT .3750 us 0.000006416666667, 1, 0, 0, 0, 0, 0, 0, 1 ; BG2 4bpp .3750 us 0.000006791666667, 1, 0, 1, 0, 1, 0, 0, 1 ; BG1 4bpp .3750 us 0.000007166666667, 0, 0, 1, 0, 1, 0, 0, 1 ; BG2 nametable
Re: Few questions about Offset-per-tile mode
Code: Select all
HOFS = X + BGnHOFS
VOFS = Y + BGnVOFS
ValidBit = 0x2000 for BG1, or 0x4000 for BG2
if (!IsFirst8x8Tile(BGn, HOFS)) {
/* Hopefully these calculations are right... */
Hval = GetTile(BG3, (HOFS&7)|(((X-8)&~7)+(BG3HOFS&~7)), BG3VOFS)
Vval = GetTile(BG3, (HOFS&7)|(((X-8)&~7)+(BG3HOFS&~7)), BG3VOFS + 8)
if (Hval&ValidBit) HOFS = (HOFS&7) | ((X&~7) + (Hval&~7))
if (Vval&ValidBit) VOFS = Y + Vval
}
Pixel[X,Y] = GetPixel(Get8x8Tile(BGn, HOFS, VOFS), HOFS, VOFS)
In BSNES source BG3's offsets calculate separately for BG1 and BG2, that is 4 words of offset-per-tile data reads from BG3 tilemap.
Code: Select all
if(self.regs.bgmode == 2 || self.regs.bgmode == 4 || self.regs.bgmode == 6) {
uint16 offset_x = (x + (hscroll & 7));
if(offset_x >= 8) {
unsigned hval = self.bg3.get_tile((offset_x - 8) + (self.bg3.regs.hoffset & ~7), self.bg3.regs.voffset + 0);
unsigned vval = self.bg3.get_tile((offset_x - 8) + (self.bg3.regs.hoffset & ~7), self.bg3.regs.voffset + 8);
unsigned valid_mask = (id == ID::BG1 ? 0x2000 : 0x4000);
if(self.regs.bgmode == 4) {
if(hval & valid_mask) {
if((hval & 0x8000) == 0) {
hoffset = offset_x + (hval & ~7);
} else {
voffset = y + hval;
}
}
} else {
if(hval & valid_mask) hoffset = offset_x + (hval & ~7);
if(vval & valid_mask) voffset = y + vval;
}
}
}
Re: Few questions about Offset-per-tile mode
In the offset-per-tile modes, BG3 doesn't contain a nametable. Instead it literally contains the horizontal and vertical offsets for the lower-numbered backgrounds.srg320 wrote:If Mode 2 fetches only two words of offset-per-tile data for BG1 and BG2, then how calculate HOFS and VOFS for BG3?
Re: Few questions about Offset-per-tile mode
Maybe I'm stupid, maybe my bad English is the problem. I formulate a question on another.
For example, in Mode 2 enabled BG1 and BG2 with different scroll values and size 64x32. How to calculate the position in BG3 Map memory region to get the horizontal and vertical offsets for BG1 and BG2?
For example, in Mode 2 enabled BG1 and BG2 with different scroll values and size 64x32. How to calculate the position in BG3 Map memory region to get the horizontal and vertical offsets for BG1 and BG2?
Re: Few questions about Offset-per-tile mode
So, I asked and I answer. OPT data read from BG3 Map Table, 3 (4 if tile size 16x16) lower bits of scrolling offset not use in this case. Therefore no need in addition lower bits BG1(2)HOFS to BG3 horizontal scrolling offset. I think the formula should be that:
With this variant, need to read only 2 words of OPT data like in real hardware.
I applied this formula to my FPGA project and it works.
Code: Select all
HOFS = X + BGnHOFS
VOFS = Y + BGnVOFS
ValidBit = 0x2000 for BG1, or 0x4000 for BG2
if (!IsFirst8x8Tile(BGn, HOFS)) {
/* Hopefully these calculations are right... */
Hval = GetTile(BG3, ((X-8)&~7)+BG3HOFS, BG3VOFS)
Vval = GetTile(BG3, ((X-8)&~7)+BG3HOFS, BG3VOFS + 8)
if (Hval&ValidBit) HOFS = (HOFS&7) | ((X&~7) + (Hval&~7))
if (Vval&ValidBit) VOFS = Y + Vval
}
Pixel[X,Y] = GetPixel(Get8x8Tile(BGn, HOFS, VOFS), HOFS, VOFS)
I applied this formula to my FPGA project and it works.