mirror of https://github.com/bsnes-emu/bsnes.git
Update to v078r07 release.
byuu says: Would appreciate testing on any games with mosaic, especially Mode7 mosaic.I have tested Super Turrican 2, Sim Earth, Contra III and SNES Test Program. This only applies to BG modes 0-6, and technically should not affect Mode7 at all. I am not sure if Mode7 needs the same change made or not, but given the way it fetches that could prove quite challenging. I also simplified the background renderer a good bit. See eg the pixel copy stuff in Background::run(). I've only fixed this in the accuracy renderer. I'm sorry, but the compatibility renderer is a fucking mess. I haven't really touched it in four or five years now. Will probably just revert to the accuracy/SMP in the performance profile for the next release since it's not being used otherwise. People can toggle it on if they want to try it out.
This commit is contained in:
parent
bc0b86891a
commit
d129b72ced
|
@ -1,7 +1,7 @@
|
||||||
include nall/Makefile
|
include nall/Makefile
|
||||||
snes := snes
|
snes := snes
|
||||||
gameboy := gameboy
|
gameboy := gameboy
|
||||||
profile := compatibility
|
profile := accuracy
|
||||||
ui := ui
|
ui := ui
|
||||||
|
|
||||||
# debugger
|
# debugger
|
||||||
|
|
|
@ -9,26 +9,31 @@ void PPU::Background::scanline() {
|
||||||
bool hires = (self.regs.bgmode == 5 || self.regs.bgmode == 6);
|
bool hires = (self.regs.bgmode == 5 || self.regs.bgmode == 6);
|
||||||
x = -7;
|
x = -7;
|
||||||
y = self.vcounter();
|
y = self.vcounter();
|
||||||
tile_counter = (7 - (regs.hoffset & 7)) << hires;
|
|
||||||
for(unsigned n = 0; n < 8; n++) data[n] = 0;
|
|
||||||
|
|
||||||
if(self.vcounter() == 1) {
|
if(y == 1) {
|
||||||
mosaic_vcounter = regs.mosaic + 1;
|
mosaic.vcounter = regs.mosaic + 1;
|
||||||
mosaic_voffset = 1;
|
mosaic.voffset = 1;
|
||||||
} else if(--mosaic_vcounter == 0) {
|
mosaic.vscroll = regs.voffset;
|
||||||
mosaic_vcounter = regs.mosaic + 1;
|
mosaic.hscroll = regs.hoffset;
|
||||||
mosaic_voffset += regs.mosaic + 1;
|
} else if(--mosaic.vcounter == 0) {
|
||||||
|
mosaic.vcounter = regs.mosaic + 1;
|
||||||
|
mosaic.voffset += regs.mosaic + 1;
|
||||||
|
mosaic.vscroll = regs.voffset;
|
||||||
|
mosaic.hscroll = regs.hoffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
mosaic_hcounter = regs.mosaic + 1;
|
tile_counter = (7 - (mosaic.hscroll & 7)) << hires;
|
||||||
mosaic_hoffset = 0;
|
for(unsigned n = 0; n < 8; n++) data[n] = 0;
|
||||||
|
|
||||||
|
mosaic.hcounter = regs.mosaic + 1;
|
||||||
|
mosaic.hoffset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPU::Background::get_tile() {
|
void PPU::Background::get_tile() {
|
||||||
bool hires = (self.regs.bgmode == 5 || self.regs.bgmode == 6);
|
bool hires = (self.regs.bgmode == 5 || self.regs.bgmode == 6);
|
||||||
|
|
||||||
unsigned color_depth = (regs.mode == Mode::BPP2 ? 0 : regs.mode == Mode::BPP4 ? 1 : 2);
|
unsigned color_depth = (regs.mode == Mode::BPP2 ? 0 : regs.mode == Mode::BPP4 ? 1 : 2);
|
||||||
unsigned palette_offset = (self.regs.bgmode == 0 ? (id << 5) : 0);
|
unsigned palette_offset = (self.regs.bgmode == 0 ? id << 5 : 0);
|
||||||
unsigned palette_size = 2 << color_depth;
|
unsigned palette_size = 2 << color_depth;
|
||||||
unsigned tile_mask = 0x0fff >> color_depth;
|
unsigned tile_mask = 0x0fff >> color_depth;
|
||||||
unsigned tiledata_index = regs.tiledata_addr >> (4 + color_depth);
|
unsigned tiledata_index = regs.tiledata_addr >> (4 + color_depth);
|
||||||
|
@ -38,18 +43,18 @@ void PPU::Background::get_tile() {
|
||||||
|
|
||||||
unsigned width = 256 << hires;
|
unsigned width = 256 << hires;
|
||||||
|
|
||||||
unsigned mask_x = (tile_height == 3 ? width : (width << 1));
|
unsigned hmask = (tile_height == 3 ? width : width << 1);
|
||||||
unsigned mask_y = mask_x;
|
unsigned vmask = hmask;
|
||||||
if(regs.screen_size & 1) mask_x <<= 1;
|
if(regs.screen_size & 1) hmask <<= 1;
|
||||||
if(regs.screen_size & 2) mask_y <<= 1;
|
if(regs.screen_size & 2) vmask <<= 1;
|
||||||
mask_x--;
|
hmask--;
|
||||||
mask_y--;
|
vmask--;
|
||||||
|
|
||||||
unsigned px = x << hires;
|
unsigned px = x << hires;
|
||||||
unsigned py = (regs.mosaic == 0 ? y : mosaic_voffset);
|
unsigned py = (regs.mosaic == 0 ? y : mosaic.voffset);
|
||||||
|
|
||||||
unsigned hscroll = regs.hoffset;
|
unsigned hscroll = mosaic.hscroll;
|
||||||
unsigned vscroll = regs.voffset;
|
unsigned vscroll = mosaic.vscroll;
|
||||||
if(hires) {
|
if(hires) {
|
||||||
hscroll <<= 1;
|
hscroll <<= 1;
|
||||||
if(self.regs.interlace) py = (py << 1) + self.field();
|
if(self.regs.interlace) py = (py << 1) + self.field();
|
||||||
|
@ -81,8 +86,8 @@ void PPU::Background::get_tile() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hoffset &= mask_x;
|
hoffset &= hmask;
|
||||||
voffset &= mask_y;
|
voffset &= vmask;
|
||||||
|
|
||||||
unsigned screen_x = (regs.screen_size & 1 ? 32 << 5 : 0);
|
unsigned screen_x = (regs.screen_size & 1 ? 32 << 5 : 0);
|
||||||
unsigned screen_y = (regs.screen_size & 2 ? 32 << 5 : 0);
|
unsigned screen_y = (regs.screen_size & 2 ? 32 << 5 : 0);
|
||||||
|
@ -143,9 +148,8 @@ void PPU::Background::run(bool screen) {
|
||||||
if(hires == false) return;
|
if(hires == false) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(regs.mode == Mode::Inactive) return;
|
|
||||||
if(regs.main_enable == false && regs.sub_enable == false) return;
|
if(regs.main_enable == false && regs.sub_enable == false) return;
|
||||||
|
if(regs.mode == Mode::Inactive) return;
|
||||||
if(regs.mode == Mode::Mode7) return run_mode7();
|
if(regs.mode == Mode::Mode7) return run_mode7();
|
||||||
|
|
||||||
if(tile_counter-- == 0) {
|
if(tile_counter-- == 0) {
|
||||||
|
@ -154,41 +158,18 @@ void PPU::Background::run(bool screen) {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 palette = get_tile_color();
|
uint8 palette = get_tile_color();
|
||||||
if(x == 0) mosaic_hcounter = 1;
|
if(x == 0) mosaic.hcounter = 1;
|
||||||
if(x >= 0 && --mosaic_hcounter == 0) {
|
if(x >= 0 && --mosaic.hcounter == 0) {
|
||||||
mosaic_hcounter = regs.mosaic + 1;
|
mosaic.hcounter = regs.mosaic + 1;
|
||||||
mosaic_priority = priority;
|
mosaic.priority = priority;
|
||||||
mosaic_palette = palette ? palette_index + palette : 0;
|
mosaic.palette = palette ? palette_index + palette : 0;
|
||||||
mosaic_tile = tile;
|
mosaic.tile = tile;
|
||||||
}
|
}
|
||||||
if(screen == Screen::Main) x++;
|
if(screen == Screen::Main) x++;
|
||||||
if(mosaic_palette == 0) return;
|
if(mosaic.palette == 0) return;
|
||||||
|
|
||||||
if(hires == false) {
|
if(hires == false || screen == Screen::Main) if(regs.main_enable) output.main = mosaic;
|
||||||
if(regs.main_enable) {
|
if(hires == false || screen == Screen::Sub ) if(regs.sub_enable ) output.sub = mosaic;
|
||||||
output.main.priority = mosaic_priority;
|
|
||||||
output.main.palette = mosaic_palette;
|
|
||||||
output.main.tile = mosaic_tile;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(regs.sub_enable) {
|
|
||||||
output.sub.priority = mosaic_priority;
|
|
||||||
output.sub.palette = mosaic_palette;
|
|
||||||
output.sub.tile = mosaic_tile;
|
|
||||||
}
|
|
||||||
} else if(screen == Screen::Main) {
|
|
||||||
if(regs.main_enable) {
|
|
||||||
output.main.priority = mosaic_priority;
|
|
||||||
output.main.palette = mosaic_palette;
|
|
||||||
output.main.tile = mosaic_tile;
|
|
||||||
}
|
|
||||||
} else if(screen == Screen::Sub) {
|
|
||||||
if(regs.sub_enable) {
|
|
||||||
output.sub.priority = mosaic_priority;
|
|
||||||
output.sub.palette = mosaic_palette;
|
|
||||||
output.sub.tile = mosaic_tile;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned PPU::Background::get_tile_color() {
|
unsigned PPU::Background::get_tile_color() {
|
||||||
|
@ -229,18 +210,20 @@ void PPU::Background::reset() {
|
||||||
output.sub.palette = 0;
|
output.sub.palette = 0;
|
||||||
output.sub.priority = 0;
|
output.sub.priority = 0;
|
||||||
|
|
||||||
|
mosaic.priority = 0;
|
||||||
|
mosaic.palette = 0;
|
||||||
|
mosaic.tile = 0;
|
||||||
|
|
||||||
|
mosaic.vcounter = 0;
|
||||||
|
mosaic.voffset = 0;
|
||||||
|
mosaic.vscroll = 0;
|
||||||
|
mosaic.hcounter = 0;
|
||||||
|
mosaic.hoffset = 0;
|
||||||
|
mosaic.hscroll = 0;
|
||||||
|
|
||||||
x = 0;
|
x = 0;
|
||||||
y = 0;
|
y = 0;
|
||||||
|
|
||||||
mosaic_vcounter = 0;
|
|
||||||
mosaic_voffset = 0;
|
|
||||||
mosaic_hcounter = 0;
|
|
||||||
mosaic_hoffset = 0;
|
|
||||||
|
|
||||||
mosaic_priority = 0;
|
|
||||||
mosaic_palette = 0;
|
|
||||||
mosaic_tile = 0;
|
|
||||||
|
|
||||||
tile_counter = 0;
|
tile_counter = 0;
|
||||||
tile = 0;
|
tile = 0;
|
||||||
priority = 0;
|
priority = 0;
|
||||||
|
@ -254,15 +237,15 @@ unsigned PPU::Background::get_tile(unsigned x, unsigned y) {
|
||||||
unsigned tile_height = (regs.tile_size == TileSize::Size8x8 ? 3 : 4);
|
unsigned tile_height = (regs.tile_size == TileSize::Size8x8 ? 3 : 4);
|
||||||
unsigned tile_width = (!hires ? tile_height : 4);
|
unsigned tile_width = (!hires ? tile_height : 4);
|
||||||
unsigned width = (!hires ? 256 : 512);
|
unsigned width = (!hires ? 256 : 512);
|
||||||
unsigned mask_x = (tile_height == 3 ? width : (width << 1));
|
unsigned mask_x = (tile_height == 3 ? width : width << 1);
|
||||||
unsigned mask_y = mask_x;
|
unsigned mask_y = mask_x;
|
||||||
if(regs.screen_size & 1) mask_x <<= 1;
|
if(regs.screen_size & 1) mask_x <<= 1;
|
||||||
if(regs.screen_size & 2) mask_y <<= 1;
|
if(regs.screen_size & 2) mask_y <<= 1;
|
||||||
mask_x--;
|
mask_x--;
|
||||||
mask_y--;
|
mask_y--;
|
||||||
|
|
||||||
unsigned screen_x = (regs.screen_size & 1 ? (32 << 5) : 0);
|
unsigned screen_x = (regs.screen_size & 1 ? 32 << 5 : 0);
|
||||||
unsigned screen_y = (regs.screen_size & 2 ? (32 << 5) : 0);
|
unsigned screen_y = (regs.screen_size & 2 ? 32 << 5 : 0);
|
||||||
if(regs.screen_size == 3) screen_y <<= 1;
|
if(regs.screen_size == 3) screen_y <<= 1;
|
||||||
|
|
||||||
x = (x & mask_x) >> tile_width;
|
x = (x & mask_x) >> tile_width;
|
||||||
|
|
|
@ -33,19 +33,19 @@ class Background {
|
||||||
} main, sub;
|
} main, sub;
|
||||||
} output;
|
} output;
|
||||||
|
|
||||||
|
struct Mosaic : Output::Pixel {
|
||||||
|
unsigned vcounter;
|
||||||
|
unsigned voffset;
|
||||||
|
unsigned vscroll;
|
||||||
|
unsigned hcounter;
|
||||||
|
unsigned hoffset;
|
||||||
|
unsigned hscroll;
|
||||||
|
} mosaic;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
signed x;
|
signed x;
|
||||||
signed y;
|
signed y;
|
||||||
|
|
||||||
unsigned mosaic_vcounter;
|
|
||||||
unsigned mosaic_voffset;
|
|
||||||
unsigned mosaic_hcounter;
|
|
||||||
unsigned mosaic_hoffset;
|
|
||||||
|
|
||||||
unsigned mosaic_priority;
|
|
||||||
uint8 mosaic_palette;
|
|
||||||
uint16 mosaic_tile;
|
|
||||||
|
|
||||||
unsigned tile_counter;
|
unsigned tile_counter;
|
||||||
unsigned tile;
|
unsigned tile;
|
||||||
unsigned priority;
|
unsigned priority;
|
||||||
|
|
|
@ -17,12 +17,12 @@ void PPU::Background::run_mode7() {
|
||||||
signed voffset = sclip<13>(self.regs.mode7_voffset);
|
signed voffset = sclip<13>(self.regs.mode7_voffset);
|
||||||
|
|
||||||
if(Background::x++ & ~255) return;
|
if(Background::x++ & ~255) return;
|
||||||
unsigned x = mosaic_hoffset;
|
unsigned x = mosaic.hoffset;
|
||||||
unsigned y = self.bg1.mosaic_voffset; //BG2 vertical mosaic uses BG1 mosaic size
|
unsigned y = self.bg1.mosaic.voffset; //BG2 vertical mosaic uses BG1 mosaic size
|
||||||
|
|
||||||
if(--mosaic_hcounter == 0) {
|
if(--mosaic.hcounter == 0) {
|
||||||
mosaic_hcounter = regs.mosaic + 1;
|
mosaic.hcounter = regs.mosaic + 1;
|
||||||
mosaic_hoffset += regs.mosaic + 1;
|
mosaic.hoffset += regs.mosaic + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(self.regs.mode7_hflip) x = 255 - x;
|
if(self.regs.mode7_hflip) x = 255 - x;
|
||||||
|
|
|
@ -120,14 +120,16 @@ void PPU::Background::serialize(serializer &s) {
|
||||||
s.integer(x);
|
s.integer(x);
|
||||||
s.integer(y);
|
s.integer(y);
|
||||||
|
|
||||||
s.integer(mosaic_vcounter);
|
s.integer(mosaic.priority);
|
||||||
s.integer(mosaic_voffset);
|
s.integer(mosaic.palette);
|
||||||
s.integer(mosaic_hcounter);
|
s.integer(mosaic.tile);
|
||||||
s.integer(mosaic_hoffset);
|
|
||||||
|
|
||||||
s.integer(mosaic_priority);
|
s.integer(mosaic.vcounter);
|
||||||
s.integer(mosaic_palette);
|
s.integer(mosaic.voffset);
|
||||||
s.integer(mosaic_tile);
|
s.integer(mosaic.vscroll);
|
||||||
|
s.integer(mosaic.hcounter);
|
||||||
|
s.integer(mosaic.hoffset);
|
||||||
|
s.integer(mosaic.hscroll);
|
||||||
|
|
||||||
s.integer(tile_counter);
|
s.integer(tile_counter);
|
||||||
s.integer(tile);
|
s.integer(tile);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
namespace SNES {
|
namespace SNES {
|
||||||
namespace Info {
|
namespace Info {
|
||||||
static const char Name[] = "bsnes";
|
static const char Name[] = "bsnes";
|
||||||
static const char Version[] = "078.06";
|
static const char Version[] = "078.07";
|
||||||
static const unsigned SerializerVersion = 20;
|
static const unsigned SerializerVersion = 20;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue