diff --git a/bsnes/emulator/emulator.hpp b/bsnes/emulator/emulator.hpp index eed7c283..ff6f3734 100644 --- a/bsnes/emulator/emulator.hpp +++ b/bsnes/emulator/emulator.hpp @@ -29,7 +29,7 @@ using namespace nall; namespace Emulator { static const string Name = "bsnes"; - static const string Version = "108.13"; + static const string Version = "108.14"; static const string Author = "byuu"; static const string License = "GPLv3"; static const string Website = "https://byuu.org"; diff --git a/bsnes/sfc/ppu-fast/background.cpp b/bsnes/sfc/ppu-fast/background.cpp index 7b4c7acd..5051151d 100644 --- a/bsnes/sfc/ppu-fast/background.cpp +++ b/bsnes/sfc/ppu-fast/background.cpp @@ -1,3 +1,15 @@ +//single-threaded +auto PPU::Line::cacheBackground(PPU::IO::Background& bg) -> void { + if(y == 1) { + bg.mosaicCounter = ppu.io.mosaicSize + 1; + bg.mosaicOffset = 1; + } else if(--bg.mosaicCounter == 0) { + bg.mosaicCounter = ppu.io.mosaicSize + 1; + bg.mosaicOffset += ppu.io.mosaicSize + 1; + } +} + +//parallelized auto PPU::Line::renderBackground(PPU::IO::Background& self, uint source) -> void { if(!self.aboveEnable && !self.belowEnable) return; if(self.tileMode == TileMode::Mode7) return renderMode7(self, source); @@ -26,7 +38,7 @@ auto PPU::Line::renderBackground(PPU::IO::Background& self, uint source) -> void uint hmask = (width << self.tileSize << !!(self.screenSize & 1)) - 1; uint vmask = (width << self.tileSize << !!(self.screenSize & 2)) - 1; - uint y = this->y - (self.mosaicEnable ? this->y % (1 + io.mosaicSize) : 0); + uint y = self.mosaicEnable ? self.mosaicOffset : this->y; if(hires) { hscroll <<= 1; if(io.interlace) y = y << 1 | field(); diff --git a/bsnes/sfc/ppu-fast/line.cpp b/bsnes/sfc/ppu-fast/line.cpp index 6e060ec7..309d742e 100644 --- a/bsnes/sfc/ppu-fast/line.cpp +++ b/bsnes/sfc/ppu-fast/line.cpp @@ -24,6 +24,23 @@ auto PPU::Line::flush() -> void { } } +auto PPU::Line::cache() -> void { + cacheBackground(ppu.io.bg1); + cacheBackground(ppu.io.bg2); + cacheBackground(ppu.io.bg3); + cacheBackground(ppu.io.bg4); + + uint y = ppu.vcounter(); + if(ppu.io.displayDisable || y >= ppu.vdisp()) { + io.displayDisable = true; + } else { + memcpy(&io, &ppu.io, sizeof(io)); + memcpy(&cgram, &ppu.cgram, sizeof(cgram)); + } + if(!Line::count) Line::start = y; + Line::count++; +} + auto PPU::Line::render(bool fieldID) -> void { this->fieldID = fieldID; uint y = this->y + (!ppu.latch.overscan ? 7 : 0); diff --git a/bsnes/sfc/ppu-fast/mode7.cpp b/bsnes/sfc/ppu-fast/mode7.cpp index 08a33429..45f53cde 100644 --- a/bsnes/sfc/ppu-fast/mode7.cpp +++ b/bsnes/sfc/ppu-fast/mode7.cpp @@ -4,7 +4,7 @@ auto PPU::Line::renderMode7(PPU::IO::Background& self, uint source) -> void { if(ppu.hdScale() > 1) return renderMode7HD(self, source); } - int Y = this->y - (self.mosaicEnable ? this->y % (1 + io.mosaicSize) : 0); + int Y = self.mosaicEnable ? self.mosaicOffset : this->y; int y = !io.mode7.vflip ? Y : 255 - Y; int a = (int16)io.mode7.a; diff --git a/bsnes/sfc/ppu-fast/ppu.cpp b/bsnes/sfc/ppu-fast/ppu.cpp index 3775ab99..65b2ba7e 100644 --- a/bsnes/sfc/ppu-fast/ppu.cpp +++ b/bsnes/sfc/ppu-fast/ppu.cpp @@ -89,16 +89,9 @@ auto PPU::main() -> void { if(system.frameCounter == 0) { uint y = vcounter(); - step(renderCycle()); if(y >= 1 && y <= 239) { - if(io.displayDisable || y >= vdisp()) { - lines[y].io.displayDisable = true; - } else { - memcpy(&lines[y].io, &io, sizeof(io)); - memcpy(&lines[y].cgram, &cgram, sizeof(cgram)); - } - if(!Line::count) Line::start = y; - Line::count++; + step(renderCycle()); + lines[y].cache(); } } diff --git a/bsnes/sfc/ppu-fast/ppu.hpp b/bsnes/sfc/ppu-fast/ppu.hpp index 60949ee9..15555ff3 100644 --- a/bsnes/sfc/ppu-fast/ppu.hpp +++ b/bsnes/sfc/ppu-fast/ppu.hpp @@ -160,6 +160,8 @@ public: bool aboveEnable = 0; bool belowEnable = 0; bool mosaicEnable = 0; + uint16 mosaicCounter = 0; + uint16 mosaicOffset = 0; uint16 tiledataAddress = 0; uint16 screenAddress = 0; uint8 screenSize = 0; @@ -282,6 +284,7 @@ public: //line.cpp inline auto field() const -> bool { return fieldID; } static auto flush() -> void; + auto cache() -> void; auto render(bool field) -> void; auto pixel(uint x, Pixel above, Pixel below) const -> uint16; auto blend(uint x, uint y, bool halve) const -> uint16; @@ -291,6 +294,7 @@ public: alwaysinline auto plotHD(Pixel*, uint x, uint source, uint priority, uint color, bool hires, bool subpixel) -> void; //background.cpp + auto cacheBackground(PPU::IO::Background&) -> void; auto renderBackground(PPU::IO::Background&, uint source) -> void; auto getTile(PPU::IO::Background&, uint hoffset, uint voffset) -> uint; diff --git a/bsnes/sfc/ppu-fast/serialization.cpp b/bsnes/sfc/ppu-fast/serialization.cpp index b7525dd8..38ac36ef 100644 --- a/bsnes/sfc/ppu-fast/serialization.cpp +++ b/bsnes/sfc/ppu-fast/serialization.cpp @@ -115,6 +115,8 @@ auto PPU::IO::Background::serialize(serializer& s) -> void { s.integer(aboveEnable); s.integer(belowEnable); s.integer(mosaicEnable); + s.integer(mosaicCounter); + s.integer(mosaicOffset); s.integer(tiledataAddress); s.integer(screenAddress); s.integer(screenSize);