diff --git a/bsnes/emulator/emulator.hpp b/bsnes/emulator/emulator.hpp index 63faea03..967d7cb0 100644 --- a/bsnes/emulator/emulator.hpp +++ b/bsnes/emulator/emulator.hpp @@ -29,13 +29,13 @@ using namespace nall; namespace Emulator { static const string Name = "bsnes"; - static const string Version = "114.1"; + static const string Version = "114.2"; static const string Author = "byuu"; static const string License = "GPLv3"; static const string Website = "https://byuu.org"; //incremented only when serialization format changes - static const string SerializerVersion = "114.1"; + static const string SerializerVersion = "114.2"; namespace Constants { namespace Colorburst { diff --git a/bsnes/sfc/coprocessor/sdd1/serialization.cpp b/bsnes/sfc/coprocessor/sdd1/serialization.cpp index be381b9b..b4b57a83 100644 --- a/bsnes/sfc/coprocessor/sdd1/serialization.cpp +++ b/bsnes/sfc/coprocessor/sdd1/serialization.cpp @@ -6,9 +6,9 @@ auto SDD1::serialize(serializer& s) -> void { s.integer(r4806); s.integer(r4807); - for(auto n : range(8)) { - s.integer(dma[n].addr); - s.integer(dma[n].size); + for(auto& channel : dma) { + s.integer(channel.addr); + s.integer(channel.size); } s.integer(dmaReady); @@ -26,6 +26,7 @@ auto SDD1::Decompressor::serialize(serializer& s) -> void { bg5.serialize(s); bg6.serialize(s); bg7.serialize(s); + pem.serialize(s); cm.serialize(s); ol.serialize(s); } diff --git a/bsnes/sfc/ppu/background.cpp b/bsnes/sfc/ppu/background.cpp index 09db47e3..1e236c48 100644 --- a/bsnes/sfc/ppu/background.cpp +++ b/bsnes/sfc/ppu/background.cpp @@ -13,13 +13,6 @@ auto PPU::Background::scanline() -> void { mosaic.hcounter = ppu.mosaic.size; mosaic.hoffset = 0; - if(io.mode == Mode::Mode7) return beginMode7(); - - latch.hoffset = io.hoffset; - latch.voffset = io.voffset; - - nameTableIndex = 0; - characterIndex = 0; renderingIndex = 0; opt.hoffset = 0; @@ -36,11 +29,13 @@ auto PPU::Background::begin() -> void { auto PPU::Background::fetchNameTable() -> void { if(ppu.vcounter() == 0) return; + uint nameTableIndex = ppu.hcounter() >> 5 << hires(); int x = (ppu.hcounter() & ~31) >> 2; + uint hpixel = x << hires(); uint vpixel = ppu.vcounter(); - uint hscroll = latch.hoffset; - uint vscroll = latch.voffset; + uint hscroll = io.hoffset; + uint vscroll = io.voffset; if(mosaic.enable) vpixel -= ppu.mosaic.voffset(); if(hires()) { @@ -131,6 +126,7 @@ auto PPU::Background::fetchNameTable() -> void { auto PPU::Background::fetchOffset(uint y) -> void { if(ppu.vcounter() == 0) return; + uint characterIndex = ppu.hcounter() >> 5 << hires(); uint x = characterIndex << 3; uint hoffset = x + (io.hoffset & ~7); @@ -152,13 +148,13 @@ auto PPU::Background::fetchOffset(uint y) -> void { uint16 address = io.screenAddress + offset; if(y == 0) opt.hoffset = ppu.vram[address]; if(y == 8) opt.voffset = ppu.vram[address]; - - if(y == 0) characterIndex++; } -auto PPU::Background::fetchCharacter(uint index) -> void { +auto PPU::Background::fetchCharacter(uint index, bool half) -> void { if(ppu.vcounter() == 0) return; + uint characterIndex = (ppu.hcounter() >> 5 << hires()) + half; + auto& tile = tiles[characterIndex]; uint16 data = ppu.vram[tile.address + (index << 3)]; @@ -174,8 +170,6 @@ auto PPU::Background::fetchCharacter(uint index) -> void { ((uint8(data >> 0) * 0x0101010101010101ull & 0x8040201008040201ull) * 0x0102040810204081ull >> 49) & 0x5555 | ((uint8(data >> 8) * 0x0101010101010101ull & 0x8040201008040201ull) * 0x0102040810204081ull >> 48) & 0xaaaa ); - - if(index == 0) characterIndex++; } auto PPU::Background::run(bool screen) -> void { @@ -230,8 +224,6 @@ auto PPU::Background::power() -> void { io.hoffset = random(); io.voffset = random(); - latch = {}; - output.above = {}; output.below = {}; diff --git a/bsnes/sfc/ppu/background.hpp b/bsnes/sfc/ppu/background.hpp index 4b752774..eb44d25c 100644 --- a/bsnes/sfc/ppu/background.hpp +++ b/bsnes/sfc/ppu/background.hpp @@ -9,13 +9,12 @@ struct Background { auto begin() -> void; auto fetchNameTable() -> void; auto fetchOffset(uint y) -> void; - auto fetchCharacter(uint index) -> void; + auto fetchCharacter(uint index, bool half = 0) -> void; auto run(bool screen) -> void; auto power() -> void; //mode7.cpp alwaysinline auto clip(int n) -> int; - auto beginMode7() -> void; auto runMode7() -> void; auto serialize(serializer&) -> void; @@ -44,11 +43,6 @@ struct Background { uint16 voffset; } io; - struct Latch { - uint16 hoffset; - uint16 voffset; - } latch; - struct Pixel { uint8 priority; //0 = none (transparent) uint8 palette; @@ -84,8 +78,8 @@ struct Background { uint16 data[4]; } tiles[66]; - uint7 nameTableIndex; - uint7 characterIndex; +uint7 nameTableIndex2; +uint7 characterIndex2; uint7 renderingIndex; uint3 pixelCounter; diff --git a/bsnes/sfc/ppu/main.cpp b/bsnes/sfc/ppu/main.cpp index 07cbc54d..68f994ca 100644 --- a/bsnes/sfc/ppu/main.cpp +++ b/bsnes/sfc/ppu/main.cpp @@ -95,60 +95,60 @@ auto PPU::cycleBackgroundFetch() -> void { if constexpr(Cycle == 1) bg2.fetchNameTable(); if constexpr(Cycle == 2) bg1.fetchNameTable(); if constexpr(Cycle == 3) bg3.fetchCharacter(0); - if constexpr(Cycle == 4) bg2.fetchCharacter(1); - if constexpr(Cycle == 5) bg2.fetchCharacter(0); - if constexpr(Cycle == 6) bg1.fetchCharacter(1); - if constexpr(Cycle == 7) bg1.fetchCharacter(0); + if constexpr(Cycle == 4) bg2.fetchCharacter(0); + if constexpr(Cycle == 5) bg2.fetchCharacter(1); + if constexpr(Cycle == 6) bg1.fetchCharacter(0); + if constexpr(Cycle == 7) bg1.fetchCharacter(1); break; case 2: if constexpr(Cycle == 0) bg2.fetchNameTable(); if constexpr(Cycle == 1) bg1.fetchNameTable(); - if constexpr(Cycle == 2) bg3.fetchOffset(8); - if constexpr(Cycle == 3) bg3.fetchOffset(0); - if constexpr(Cycle == 4) bg2.fetchCharacter(1); - if constexpr(Cycle == 5) bg2.fetchCharacter(0); - if constexpr(Cycle == 6) bg1.fetchCharacter(1); - if constexpr(Cycle == 7) bg1.fetchCharacter(0); + if constexpr(Cycle == 2) bg3.fetchOffset(0); + if constexpr(Cycle == 3) bg3.fetchOffset(8); + if constexpr(Cycle == 4) bg2.fetchCharacter(0); + if constexpr(Cycle == 5) bg2.fetchCharacter(1); + if constexpr(Cycle == 6) bg1.fetchCharacter(0); + if constexpr(Cycle == 7) bg1.fetchCharacter(1); break; case 3: if constexpr(Cycle == 0) bg2.fetchNameTable(); if constexpr(Cycle == 1) bg1.fetchNameTable(); - if constexpr(Cycle == 2) bg2.fetchCharacter(1); - if constexpr(Cycle == 3) bg2.fetchCharacter(0); - if constexpr(Cycle == 4) bg1.fetchCharacter(3); - if constexpr(Cycle == 5) bg1.fetchCharacter(2); - if constexpr(Cycle == 6) bg1.fetchCharacter(1); - if constexpr(Cycle == 7) bg1.fetchCharacter(0); + if constexpr(Cycle == 2) bg2.fetchCharacter(0); + if constexpr(Cycle == 3) bg2.fetchCharacter(1); + if constexpr(Cycle == 4) bg1.fetchCharacter(0); + if constexpr(Cycle == 5) bg1.fetchCharacter(1); + if constexpr(Cycle == 6) bg1.fetchCharacter(2); + if constexpr(Cycle == 7) bg1.fetchCharacter(3); break; case 4: if constexpr(Cycle == 0) bg2.fetchNameTable(); if constexpr(Cycle == 1) bg1.fetchNameTable(); if constexpr(Cycle == 2) bg3.fetchOffset(0); if constexpr(Cycle == 3) bg2.fetchCharacter(0); - if constexpr(Cycle == 4) bg1.fetchCharacter(3); - if constexpr(Cycle == 5) bg1.fetchCharacter(2); - if constexpr(Cycle == 6) bg1.fetchCharacter(1); - if constexpr(Cycle == 7) bg1.fetchCharacter(0); + if constexpr(Cycle == 4) bg1.fetchCharacter(0); + if constexpr(Cycle == 5) bg1.fetchCharacter(1); + if constexpr(Cycle == 6) bg1.fetchCharacter(2); + if constexpr(Cycle == 7) bg1.fetchCharacter(3); break; case 5: if constexpr(Cycle == 0) bg2.fetchNameTable(); if constexpr(Cycle == 1) bg1.fetchNameTable(); - if constexpr(Cycle == 2) bg2.fetchCharacter(0); - if constexpr(Cycle == 3) bg2.fetchCharacter(0); - if constexpr(Cycle == 4) bg1.fetchCharacter(1); - if constexpr(Cycle == 5) bg1.fetchCharacter(0); - if constexpr(Cycle == 6) bg1.fetchCharacter(1); - if constexpr(Cycle == 7) bg1.fetchCharacter(0); + if constexpr(Cycle == 2) bg2.fetchCharacter(0, 0); + if constexpr(Cycle == 3) bg2.fetchCharacter(0, 1); + if constexpr(Cycle == 4) bg1.fetchCharacter(0, 0); + if constexpr(Cycle == 5) bg1.fetchCharacter(1, 0); + if constexpr(Cycle == 6) bg1.fetchCharacter(0, 1); + if constexpr(Cycle == 7) bg1.fetchCharacter(1, 1); break; case 6: if constexpr(Cycle == 0) bg2.fetchNameTable(); if constexpr(Cycle == 1) bg1.fetchNameTable(); - if constexpr(Cycle == 2) bg3.fetchOffset(8); - if constexpr(Cycle == 3) bg3.fetchOffset(0); - if constexpr(Cycle == 4) bg1.fetchCharacter(1); - if constexpr(Cycle == 5) bg1.fetchCharacter(0); - if constexpr(Cycle == 6) bg1.fetchCharacter(1); - if constexpr(Cycle == 7) bg1.fetchCharacter(0); + if constexpr(Cycle == 2) bg3.fetchOffset(0); + if constexpr(Cycle == 3) bg3.fetchOffset(8); + if constexpr(Cycle == 4) bg1.fetchCharacter(0, 0); + if constexpr(Cycle == 5) bg1.fetchCharacter(1, 0); + if constexpr(Cycle == 6) bg1.fetchCharacter(0, 1); + if constexpr(Cycle == 7) bg1.fetchCharacter(1, 1); break; case 7: //handled separately by mode7.cpp diff --git a/bsnes/sfc/ppu/mode7.cpp b/bsnes/sfc/ppu/mode7.cpp index af246453..4b4413b9 100644 --- a/bsnes/sfc/ppu/mode7.cpp +++ b/bsnes/sfc/ppu/mode7.cpp @@ -3,12 +3,6 @@ auto PPU::Background::clip(int n) -> int { return n & 0x2000 ? (n | ~1023) : (n & 1023); } -//H = 0 -auto PPU::Background::beginMode7() -> void { - latch.hoffset = ppu.io.hoffsetMode7; - latch.voffset = ppu.io.voffsetMode7; -} - auto PPU::Background::runMode7() -> void { int a = (int16)ppu.io.m7a; int b = (int16)ppu.io.m7b; @@ -17,14 +11,16 @@ auto PPU::Background::runMode7() -> void { int hcenter = (int13)ppu.io.m7x; int vcenter = (int13)ppu.io.m7y; - int hoffset = (int13)latch.hoffset; - int voffset = (int13)latch.voffset; + int hoffset = (int13)ppu.io.hoffsetMode7; + int voffset = (int13)ppu.io.voffsetMode7; uint x = mosaic.hoffset; uint y = ppu.vcounter(); if(ppu.bg1.mosaic.enable) y -= ppu.mosaic.voffset(); //BG2 vertical mosaic uses BG1 mosaic enable - if(--mosaic.hcounter == 0) { + if(!mosaic.enable) { + mosaic.hoffset += 1; + } else if(--mosaic.hcounter == 0) { mosaic.hcounter = ppu.mosaic.size; mosaic.hoffset += ppu.mosaic.size; } diff --git a/bsnes/sfc/ppu/serialization.cpp b/bsnes/sfc/ppu/serialization.cpp index 30723a8a..9a022211 100644 --- a/bsnes/sfc/ppu/serialization.cpp +++ b/bsnes/sfc/ppu/serialization.cpp @@ -100,9 +100,6 @@ auto PPU::Background::serialize(serializer& s) -> void { s.integer(io.hoffset); s.integer(io.voffset); - s.integer(latch.hoffset); - s.integer(latch.voffset); - s.integer(output.above.priority); s.integer(output.above.palette); s.integer(output.above.paletteGroup); @@ -133,8 +130,6 @@ auto PPU::Background::serialize(serializer& s) -> void { s.array(tile.data); } - s.integer(nameTableIndex); - s.integer(characterIndex); s.integer(renderingIndex); s.integer(pixelCounter); }