diff --git a/bsnes/sfc/ppu-fast/line.cpp b/bsnes/sfc/ppu-fast/line.cpp index 309d742e..7fa41de0 100644 --- a/bsnes/sfc/ppu-fast/line.cpp +++ b/bsnes/sfc/ppu-fast/line.cpp @@ -107,7 +107,7 @@ auto PPU::Line::render(bool fieldID) -> void { } } -auto PPU::Line::pixel(uint x, Pixel above, Pixel below) const -> uint16_t { +auto PPU::Line::pixel(uint x, Pixel above, Pixel below) const -> uint16 { if(!windowAbove[x]) above.color = 0x0000; if(!windowBelow[x]) return above.color; if(!io.col.enable[above.source]) return above.color; @@ -115,7 +115,7 @@ auto PPU::Line::pixel(uint x, Pixel above, Pixel below) const -> uint16_t { return blend(above.color, below.color, io.col.halve && windowAbove[x] && below.source != Source::COL); } -auto PPU::Line::blend(uint x, uint y, bool halve) const -> uint16_t { +auto PPU::Line::blend(uint x, uint y, bool halve) const -> uint16 { if(!io.col.mathMode) { //add if(!halve) { uint sum = x + y; @@ -135,7 +135,7 @@ auto PPU::Line::blend(uint x, uint y, bool halve) const -> uint16_t { } } -auto PPU::Line::directColor(uint paletteIndex, uint paletteColor) const -> uint16_t { +auto PPU::Line::directColor(uint paletteIndex, uint paletteColor) const -> uint16 { //paletteIndex = bgr //paletteColor = BBGGGRRR //output = 0 BBb00 GGGg0 RRRr0 diff --git a/bsnes/sfc/ppu/background.cpp b/bsnes/sfc/ppu/background.cpp index b686b5db..e215fb79 100644 --- a/bsnes/sfc/ppu/background.cpp +++ b/bsnes/sfc/ppu/background.cpp @@ -40,6 +40,7 @@ auto PPU::Background::begin() -> void { latch.hoffset = io.hoffset; latch.voffset = io.voffset; } + latch.screenAddress = io.screenAddress; mosaic.hcounter = mosaic.size + 1; mosaic.hoffset = 0; @@ -114,7 +115,7 @@ auto PPU::Background::getTile() -> void { if(tileX & 0x20) offset += screenX; if(tileY & 0x20) offset += screenY; - uint16 address = io.screenAddress + offset; + uint16 address = latch.screenAddress + offset; tile = ppu.vram[address]; bool mirrorY = tile & 0x8000; bool mirrorX = tile & 0x4000; @@ -187,6 +188,20 @@ auto PPU::Background::run(bool screen) -> void { if(!hires() || screen == Screen::Below) if(io.belowEnable) output.below = pixel; } +auto PPU::Background::getTile(uint x, uint y) -> uint16 { + uint tileHeight = 3 + io.tileSize; + uint tileWidth = !hires() ? tileHeight : 4; + uint screenX = io.screenSize.bit(0) ? 32 << 5 : 0; + uint screenY = io.screenSize.bit(1) ? 32 << 5 + io.screenSize.bit(0) : 0; + uint tileX = x >> tileWidth; + uint tileY = y >> tileHeight; + uint16 offset = (tileY & 0x1f) << 5 | (tileX & 0x1f); + if(tileX & 0x20) offset += screenX; + if(tileY & 0x20) offset += screenY; + uint16 address = latch.screenAddress + offset; + return ppu.vram[address]; +} + auto PPU::Background::getTileColor() -> uint { uint color = 0; @@ -239,17 +254,3 @@ auto PPU::Background::power() -> void { paletteIndex = 0; for(auto& word : data) word = 0; } - -auto PPU::Background::getTile(uint x, uint y) -> uint16 { - uint tileHeight = 3 + io.tileSize; - uint tileWidth = !hires() ? tileHeight : 4; - uint screenX = io.screenSize.bit(0) ? 32 << 5 : 0; - uint screenY = io.screenSize.bit(1) ? 32 << 5 + io.screenSize.bit(0) : 0; - uint tileX = x >> tileWidth; - uint tileY = y >> tileHeight; - uint16 offset = (tileY & 0x1f) << 5 | (tileX & 0x1f); - if(tileX & 0x20) offset += screenX; - if(tileY & 0x20) offset += screenY; - uint16 address = io.screenAddress + offset; - return ppu.vram[address]; -} diff --git a/bsnes/sfc/ppu/background.hpp b/bsnes/sfc/ppu/background.hpp index a6e59f58..efda7d4b 100644 --- a/bsnes/sfc/ppu/background.hpp +++ b/bsnes/sfc/ppu/background.hpp @@ -12,8 +12,8 @@ struct Background { auto power() -> void; auto getTile() -> void; - auto getTileColor() -> uint; auto getTile(uint x, uint y) -> uint16; + auto getTileColor() -> uint; alwaysinline auto clip(int n) -> int; auto beginMode7() -> void; auto runMode7() -> void; @@ -47,6 +47,7 @@ struct Background { struct Latch { uint16 hoffset; uint16 voffset; + uint16 screenAddress; } latch; struct Pixel { diff --git a/bsnes/sfc/ppu/serialization.cpp b/bsnes/sfc/ppu/serialization.cpp index c986b2ef..2f2fced3 100644 --- a/bsnes/sfc/ppu/serialization.cpp +++ b/bsnes/sfc/ppu/serialization.cpp @@ -96,6 +96,7 @@ auto PPU::Background::serialize(serializer& s) -> void { s.integer(latch.hoffset); s.integer(latch.voffset); + s.integer(latch.screenAddress); s.integer(output.above.priority); s.integer(output.above.palette); diff --git a/bsnes/target-bsnes/program/hacks.cpp b/bsnes/target-bsnes/program/hacks.cpp index d99e50fa..5defba93 100644 --- a/bsnes/target-bsnes/program/hacks.cpp +++ b/bsnes/target-bsnes/program/hacks.cpp @@ -11,6 +11,9 @@ auto Program::hackCompatibility() -> void { //relies on mid-scanline rendering techniques if(title == "AIR STRIKE PATROL" || title == "DESERT FIGHTER") fastPPU = false; + //stage 2 uses pseudo-hires in a way that's not compatible with the scanline-based renderer + if(title == "SFC クレヨンシンチャン") fastPPU = false; + //relies on cycle-accurate writes to the echo buffer if(title == "KOUSHIEN_2") fastDSP = false;