Update to bsnes v107r3 beta release.

byuu says:

Changes: HD mode 7 supersampling support, HD mode 7 mosaic disable option,
various HD mode 7 bugfixes, default waveOut audio latency to 128 instead of 512,
removed 512x240 hires mode 7 mode.

There's also a small experiment, making this release a beta release as well:
for a large speedup, when in EXTBG mode, I'm bypassing rendering BG1 for a
performance boost. EXTBG is only used as a priority layer, and is overwritten by
BG2 except in one extremely pathological case.
This commit is contained in:
Tim Allen 2019-04-19 18:02:31 +10:00
parent 7a548482ed
commit becbca47d4
16 changed files with 113 additions and 139 deletions

View File

@ -31,13 +31,13 @@ using namespace nall;
namespace Emulator {
static const string Name = "bsnes";
static const string Version = "107.2";
static const string Version = "107.3";
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 = "107";
static const string SerializerVersion = "107.3";
namespace Constants {
namespace Colorburst {

View File

@ -1490,6 +1490,7 @@ const int16 Dsp1::SinTable[256] = {
// As a curiosity, in the positions 0x21c-0x31c it's contained a
// 257-points arccos table that, apparently, have been not used anywhere
// (maybe for the MaxAZS_Exp table?).
// byuu note: the error at DataRom[0x3c] has been corrected from 0x0001 to 0x0010
const uint16 Dsp1::DataRom[1024] = {
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
@ -1498,7 +1499,7 @@ const int16 Dsp1::SinTable[256] = {
0x0000, 0x0000, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020,
0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000,
0x4000, 0x7fff, 0x4000, 0x2000, 0x1000, 0x0800, 0x0400, 0x0200,
0x0100, 0x0080, 0x0040, 0x0020, 0x0001, 0x0008, 0x0004, 0x0002,
0x0100, 0x0080, 0x0040, 0x0020, 0x0010, 0x0008, 0x0004, 0x0002,
0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,

View File

@ -18,9 +18,10 @@ auto Configuration::process(Markup::Node document, bool load) -> void {
bind(boolean, "Hacks/PPU/Fast", hacks.ppu.fast);
bind(boolean, "Hacks/PPU/NoSpriteLimit", hacks.ppu.noSpriteLimit);
bind(boolean, "Hacks/PPU/Mode7/Hires", hacks.ppu.mode7.hires);
bind(natural, "Hacks/PPU/Mode7/Scale", hacks.ppu.mode7.scale);
bind(boolean, "Hacks/PPU/Mode7/Perspective", hacks.ppu.mode7.perspective);
bind(boolean, "Hacks/PPU/Mode7/Supersample", hacks.ppu.mode7.supersample);
bind(boolean, "Hacks/PPU/Mode7/Mosaic", hacks.ppu.mode7.mosaic);
bind(boolean, "Hacks/DSP/Fast", hacks.dsp.fast);
bind(boolean, "Hacks/DSP/Cubic", hacks.dsp.cubic);
bind(boolean, "Hacks/Coprocessors/HLE", hacks.coprocessors.hle);

View File

@ -29,9 +29,10 @@ struct Configuration {
bool fast = true;
bool noSpriteLimit = false;
struct Mode7 {
bool hires = false;
uint scale = 1;
bool perspective = true;
bool supersample = false;
bool mosaic = true;
} mode7;
} ppu;
struct DSP {

View File

@ -14,6 +14,7 @@ auto PPUfast::Line::flush() -> void {
auto PPUfast::Line::render() -> void {
auto hd = ppufast.hd();
auto ss = ppufast.ss();
auto scale = ppufast.hdScale();
auto output = ppufast.output + (!hd
? (y * 1024 + (ppufast.interlace() && ppufast.field() ? 512 : 0))
@ -29,11 +30,10 @@ auto PPUfast::Line::render() -> void {
}
bool hires = io.pseudoHires || io.bgMode == 5 || io.bgMode == 6;
bool hiresMode7 = io.bgMode == 7 && configuration.hacks.ppu.mode7.hires;
auto aboveColor = cgram[0];
auto belowColor = hires ? cgram[0] : io.col.fixedColor;
uint xa = hd && ppufast.interlace() && ppufast.field() ? 256 * scale * scale / 2 : 0;
uint xb = !hd ? 256 << hiresMode7 : ppufast.interlace() && !ppufast.field() ? 256 * scale * scale / 2 : 256 * scale * scale;
uint xa = (hd || ss) && ppufast.interlace() && ppufast.field() ? 256 * scale * scale / 2 : 0;
uint xb = !(hd || ss) ? 256 : ppufast.interlace() && !ppufast.field() ? 256 * scale * scale / 2 : 256 * scale * scale;
for(uint x = xa; x < xb; x++) {
above[x] = {Source::COL, 0, aboveColor};
below[x] = {Source::COL, 0, belowColor};
@ -50,10 +50,6 @@ auto PPUfast::Line::render() -> void {
auto luma = io.displayBrightness << 15;
if(hd) for(uint x : range(256 * scale * scale)) {
*output++ = luma | pixel(x / scale & 255, above[x], below[x]);
} else if(hiresMode7) for(uint x : range(512)) {
auto Above = above[x >> 1].source >= Source::OBJ1 ? above[x >> 1] : above[x >> 1 | (x & 1 ? 256 : 0)];
auto Below = below[x >> 1].source >= Source::OBJ1 ? below[x >> 1] : below[x >> 1 | (x & 1 ? 256 : 0)];
*output++ = luma | pixel(x >> 1, Above, Below);
} else if(width == 256) for(uint x : range(256)) {
*output++ = luma | pixel(x, above[x], below[x]);
} else if(!hires) for(uint x : range(256)) {

View File

@ -1,6 +1,12 @@
auto PPUfast::Line::renderMode7(PPUfast::IO::Background& self, uint source) -> void {
//EXTBG is only really used by games to give the mode 7 layer two priority levels
//especially with HD mode 7, it's just wasteful to render BG1 just to be overwritten by BG2
if(io.extbg && source == Source::BG1) return;
//HD mode 7 support
if(!ppufast.hdMosaic() || !self.mosaicEnable || !io.mosaicSize) {
if(ppufast.hdScale() > 1) return renderMode7HD(self, source);
if(configuration.hacks.ppu.mode7.hires) return renderMode7Hires(self, source);
}
int Y = this->y - (self.mosaicEnable ? this->y % (1 + io.mosaicSize) : 0);
int y = !io.mode7.vflip ? Y : 255 - Y;

View File

@ -21,9 +21,6 @@ auto PPUfast::Line::renderMode7HD(PPUfast::IO::Background& self, uint source) ->
}
#undef isLineMode7
int Y = y - (self.mosaicEnable ? y % (1 + io.mosaicSize) : 0);
float yt = !io.mode7.vflip ? Y : 255 - Y;
Line line_a = ppufast.lines[y_a];
float a_a = (int16)line_a.io.mode7.a;
float b_a = (int16)line_a.io.mode7.b;
@ -41,6 +38,11 @@ auto PPUfast::Line::renderMode7HD(PPUfast::IO::Background& self, uint source) ->
int hoffset = (int13)io.mode7.hoffset;
int voffset = (int13)io.mode7.voffset;
if(io.mode7.vflip) {
y_a = 255 - y_a;
y_b = 255 - y_b;
}
array<bool[256]> windowAbove;
array<bool[256]> windowBelow;
renderWindow(self.window, self.window.aboveEnable, windowAbove);
@ -48,72 +50,90 @@ auto PPUfast::Line::renderMode7HD(PPUfast::IO::Background& self, uint source) ->
int pixelYp = INT_MIN;
for(int ys : range(scale)) {
float y = yt + ys * 1.0 / scale - 0.5;
float a = 1.0 / lerp(y_a, 1.0 / a_a, y_b, 1.0 / a_b, y);
float b = 1.0 / lerp(y_a, 1.0 / b_a, y_b, 1.0 / b_b, y);
float c = 1.0 / lerp(y_a, 1.0 / c_a, y_b, 1.0 / c_b, y);
float d = 1.0 / lerp(y_a, 1.0 / d_a, y_b, 1.0 / d_b, y);
float yf = y + ys * 1.0 / scale - 0.5;
if(io.mode7.vflip) yf = 255 - yf;
float a = 1.0 / lerp(y_a, 1.0 / a_a, y_b, 1.0 / a_b, yf);
float b = 1.0 / lerp(y_a, 1.0 / b_a, y_b, 1.0 / b_b, yf);
float c = 1.0 / lerp(y_a, 1.0 / c_a, y_b, 1.0 / c_b, yf);
float d = 1.0 / lerp(y_a, 1.0 / d_a, y_b, 1.0 / d_b, yf);
int ht = (hoffset - hcenter) % 1024;
float vty = ((voffset - vcenter) % 1024) + y;
float vty = ((voffset - vcenter) % 1024) + yf;
float originX = (a * ht) + (b * vty) + (hcenter << 8);
float originY = (c * ht) + (d * vty) + (vcenter << 8);
uint tile, palette, priority;
//some games enable mosaic with a mosaic size of 0 (1x1)
bool mosaicEnable = self.mosaicEnable && io.mosaicSize;
uint mosaicCounter = 1;
uint mosaicPalette = 0;
uint mosaicPriority = 0;
uint mosaicColor = 0;
Pixel mosaicPixel;
int pixelXp = INT_MIN;
for(int X : range(256)) {
float xt = !io.mode7.hflip ? X : 255 - X;
bool doAbove = self.aboveEnable && !windowAbove[X];
bool doBelow = self.belowEnable && !windowBelow[X];
for(int x : range(256)) {
bool doAbove = self.aboveEnable && !windowAbove[x];
bool doBelow = self.belowEnable && !windowBelow[x];
for(int xs : range(scale)) {
float x = xt + xs * 1.0 / scale - 0.5;
int pixelX = (originX + a * x) / 256;
int pixelY = (originY + c * x) / 256;
float xf = x + xs * 1.0 / scale - 0.5;
if(io.mode7.hflip) xf = 255 - xf;
int pixelX = (originX + a * xf) / 256;
int pixelY = (originY + c * xf) / 256;
above++;
below++;
//only compute color again when coordinates have changed
if(pixelX != pixelXp || pixelY != pixelYp) {
pixelXp = pixelX;
pixelYp = pixelY;
tile = io.mode7.repeat == 3 && ((pixelX | pixelY) & ~1023) ? 0 : ppufast.vram[(pixelY >> 3 & 127) * 128 + (pixelX >> 3 & 127)].byte(0);
palette = io.mode7.repeat == 2 && ((pixelX | pixelY) & ~1023) ? 0 : ppufast.vram[(((pixelY & 7) << 3) + (pixelX & 7)) + (tile << 6)].byte(1);
uint tile = io.mode7.repeat == 3 && ((pixelX | pixelY) & ~1023) ? 0 : ppufast.vram[(pixelY >> 3 & 127) * 128 + (pixelX >> 3 & 127)].byte(0);
uint palette = io.mode7.repeat == 2 && ((pixelX | pixelY) & ~1023) ? 0 : ppufast.vram[(((pixelY & 7) << 3) + (pixelX & 7)) + (tile << 6)].byte(1);
uint priority;
if(!extbg) {
priority = self.priority[0];
} else {
priority = self.priority[palette >> 7];
palette &= 0x7f;
}
}
if(!palette) continue;
if(!mosaicEnable || --mosaicCounter == 0) {
mosaicCounter = (1 + io.mosaicSize) * scale;
mosaicPalette = palette;
mosaicPriority = priority;
uint color;
if(io.col.directColor && !extbg) {
mosaicColor = directColor(0, palette);
color = directColor(0, palette);
} else {
mosaicColor = cgram[palette];
color = cgram[palette];
}
pixel = {source, mosaicPriority, mosaicColor};
}
if(!mosaicPalette) continue;
if(doAbove && (!extbg || mosaicPriority > above->priority)) *above = pixel;
if(doBelow && (!extbg || mosaicPriority > below->priority)) *below = pixel;
pixel = {source, priority, color};
pixelXp = pixelX;
pixelYp = pixelY;
}
if(doAbove && (!extbg || pixel.priority > above->priority)) *above = pixel;
if(doBelow && (!extbg || pixel.priority > below->priority)) *below = pixel;
}
}
}
if(ppufast.ss()) {
uint divisor = scale * scale;
for(uint p : range(256)) {
uint ab = 0, bb = 0;
uint ag = 0, bg = 0;
uint ar = 0, br = 0;
for(uint y : range(scale)) {
auto above = &this->above[p * scale];
auto below = &this->below[p * scale];
for(uint x : range(scale)) {
uint a = above[x].color;
uint b = below[x].color;
ab += a >> 0 & 31;
ag += a >> 5 & 31;
ar += a >> 10 & 31;
bb += b >> 0 & 31;
bg += b >> 5 & 31;
br += b >> 10 & 31;
}
}
uint aboveColor = ab / divisor << 0 | ag / divisor << 5 | ar / divisor << 10;
uint belowColor = bb / divisor << 0 | bg / divisor << 5 | br / divisor << 10;
this->above[p] = {source, this->above[p * scale].priority, aboveColor};
this->below[p] = {source, this->below[p * scale].priority, belowColor};
}
}
}

View File

@ -1,63 +0,0 @@
auto PPUfast::Line::renderMode7Hires(PPUfast::IO::Background& self, uint source) -> void {
int Y = this->y - (self.mosaicEnable ? this->y % (1 + io.mosaicSize) : 0);
int y = !io.mode7.vflip ? Y : 255 - Y;
int a = (int16)io.mode7.a;
int b = (int16)io.mode7.b;
int c = (int16)io.mode7.c;
int d = (int16)io.mode7.d;
int hcenter = (int13)io.mode7.x;
int vcenter = (int13)io.mode7.y;
int hoffset = (int13)io.mode7.hoffset;
int voffset = (int13)io.mode7.voffset;
uint mosaicCounter = 1;
uint mosaicPalette = 0;
uint mosaicPriority = 0;
uint mosaicColor = 0;
auto clip = [](int n) -> int { return n & 0x2000 ? (n | ~1023) : (n & 1023); };
int originX = (a * clip(hoffset - hcenter) & ~63) + (b * clip(voffset - vcenter) & ~63) + (b * y & ~63) + (hcenter << 8);
int originY = (c * clip(hoffset - hcenter) & ~63) + (d * clip(voffset - vcenter) & ~63) + (d * y & ~63) + (vcenter << 8);
array<bool[256]> windowAbove;
array<bool[256]> windowBelow;
renderWindow(self.window, self.window.aboveEnable, windowAbove);
renderWindow(self.window, self.window.belowEnable, windowBelow);
for(int X : range(512)) {
int x = !io.mode7.hflip ? X : 511 - X;
int pixelX = 2 * originX + a * x >> 9;
int pixelY = 2 * originY + c * x >> 9;
int tileX = pixelX >> 3 & 127;
int tileY = pixelY >> 3 & 127;
bool outOfBounds = (pixelX | pixelY) & ~1023;
uint15 tileAddress = tileY * 128 + tileX;
uint15 paletteAddress = ((pixelY & 7) << 3) + (pixelX & 7);
uint8 tile = io.mode7.repeat == 3 && outOfBounds ? 0 : ppufast.vram[tileAddress].byte(0);
uint8 palette = io.mode7.repeat == 2 && outOfBounds ? 0 : ppufast.vram[paletteAddress + (tile << 6)].byte(1);
uint priority;
if(source == Source::BG1) {
priority = self.priority[0];
} else if(source == Source::BG2) {
priority = self.priority[palette >> 7];
palette &= 0x7f;
}
if(!self.mosaicEnable || !io.mosaicSize || --mosaicCounter == 0) {
mosaicCounter = (1 + io.mosaicSize) << 1;
mosaicPalette = palette;
mosaicPriority = priority;
if(io.col.directColor && source == Source::BG1) {
mosaicColor = directColor(0, palette);
} else {
mosaicColor = cgram[palette];
}
}
if(!mosaicPalette) continue;
if(self.aboveEnable && !windowAbove[X >> 1]) plotAbove(X >> 1 | (X & 1 ? 256 : 0), source, mosaicPriority, mosaicColor);
if(self.belowEnable && !windowBelow[X >> 1]) plotBelow(X >> 1 | (X & 1 ? 256 : 0), source, mosaicPriority, mosaicColor);
}
}

View File

@ -9,7 +9,6 @@ PPUfast ppufast;
#include "line.cpp"
#include "background.cpp"
#include "mode7.cpp"
#include "mode7hires.cpp"
#include "mode7hd.cpp"
#include "object.cpp"
#include "window.cpp"
@ -20,8 +19,11 @@ auto PPUfast::overscan() const -> bool { return ppubase.display.overscan; }
auto PPUfast::vdisp() const -> uint { return ppubase.display.vdisp; }
auto PPUfast::hires() const -> bool { return latch.hires; }
auto PPUfast::hd() const -> bool { return latch.hd; }
auto PPUfast::ss() const -> bool { return latch.ss; }
auto PPUfast::hdScale() const -> uint { return configuration.hacks.ppu.mode7.scale; }
auto PPUfast::hdPerspective() const -> bool { return configuration.hacks.ppu.mode7.perspective; }
auto PPUfast::hdSupersample() const -> bool { return configuration.hacks.ppu.mode7.supersample; }
auto PPUfast::hdMosaic() const -> bool { return configuration.hacks.ppu.mode7.mosaic; }
PPUfast::PPUfast() {
output = new uint32[2304 * 2304] + 72 * 2304; //overscan offset
@ -78,14 +80,15 @@ auto PPUfast::scanline() -> void {
ppubase.display.overscan = io.overscan;
latch.hires = false;
latch.hd = false;
latch.ss = false;
io.obj.timeOver = false;
io.obj.rangeOver = false;
}
if(vcounter() > 0 && vcounter() < vdisp()) {
latch.hires |= io.pseudoHires || io.bgMode == 5 || io.bgMode == 6;
latch.hires |= io.bgMode == 7 && configuration.hacks.ppu.mode7.hires;
latch.hd |= io.bgMode == 7 && hdScale() > 1;
latch.hd |= io.bgMode == 7 && hdScale() > 1 && hdSupersample() == 0;
latch.ss |= io.bgMode == 7 && hdScale() > 1 && hdSupersample() == 1;
}
if(vcounter() == vdisp() && !io.displayDisable) {

View File

@ -11,8 +11,11 @@ struct PPUfast : Thread, PPUcounter {
alwaysinline auto vdisp() const -> uint;
alwaysinline auto hires() const -> bool;
alwaysinline auto hd() const -> bool;
alwaysinline auto ss() const -> bool;
alwaysinline auto hdScale() const -> uint;
alwaysinline auto hdPerspective() const -> bool;
alwaysinline auto hdSupersample() const -> bool;
alwaysinline auto hdMosaic() const -> bool;
//ppu.cpp
PPUfast();
@ -42,6 +45,7 @@ public:
uint1 overscan;
uint1 hires;
uint1 hd;
uint1 ss;
uint16 vram;
uint8 oam;
@ -281,9 +285,6 @@ public:
//mode7.cpp
auto renderMode7(PPUfast::IO::Background&, uint source) -> void;
//mode7hires.cpp
auto renderMode7Hires(PPUfast::IO::Background&, uint source) -> void;
//mode7hd.cpp
auto renderMode7HD(PPUfast::IO::Background&, uint source) -> void;
alwaysinline auto lerp(float pa, float va, float pb, float vb, float pr) -> float;

View File

@ -18,6 +18,7 @@ auto PPUfast::Latch::serialize(serializer& s) -> void {
s.integer(overscan);
s.integer(hires);
s.integer(hd);
s.integer(ss);
s.integer(vram);
s.integer(oam);
s.integer(cgram);

View File

@ -1,7 +1,6 @@
auto Program::hackCompatibility() -> void {
bool fastPPU = emulatorSettings.fastPPU.checked();
bool fastPPUNoSpriteLimit = emulatorSettings.noSpriteLimit.checked();
bool fastPPUHiresMode7 = emulatorSettings.hiresMode7.checked();
bool fastDSP = emulatorSettings.fastDSP.checked();
bool coprocessorsDelayedSync = emulatorSettings.coprocessorsDelayedSyncOption.checked();
@ -12,9 +11,10 @@ auto Program::hackCompatibility() -> void {
emulator->configure("Hacks/PPU/Fast", fastPPU);
emulator->configure("Hacks/PPU/NoSpriteLimit", fastPPUNoSpriteLimit);
emulator->configure("Hacks/PPU/Mode7/Hires", fastPPUHiresMode7);
emulator->configure("Hacks/PPU/Mode7/Scale", settings.emulator.hack.ppu.mode7.scale);
emulator->configure("Hacks/PPU/Mode7/Perspective", settings.emulator.hack.ppu.mode7.perspective);
emulator->configure("Hacks/PPU/Mode7/Supersample", settings.emulator.hack.ppu.mode7.supersample);
emulator->configure("Hacks/PPU/Mode7/Mosaic", settings.emulator.hack.ppu.mode7.mosaic);
emulator->configure("Hacks/DSP/Fast", fastDSP);
emulator->configure("Hacks/DSP/Cubic", settings.emulator.hack.dsp.cubic);
emulator->configure("Hacks/Coprocessors/DelayedSync", coprocessorsDelayedSync);

View File

@ -13,7 +13,7 @@ auto DriverSettings::create() -> void {
videoDriverUpdate.setText("Change").onActivate([&] { videoDriverChange(); });
videoFormatLabel.setText("Format:");
videoFormatOption.onChange([&] { videoFormatChange(); });
videoExclusiveToggle.setText("Exclusive").setToolTip(
videoExclusiveToggle.setText("Exclusive fullscreen mode").setToolTip(
"(Direct3D driver only)\n\n"
"Acquires exclusive access to the display in fullscreen mode.\n"
"Eliminates compositing issues such as video stuttering."
@ -57,7 +57,7 @@ auto DriverSettings::create() -> void {
audioFrequencyOption.onChange([&] { audioFrequencyChange(); });
audioLatencyLabel.setText("Latency:");
audioLatencyOption.onChange([&] { audioLatencyChange(); });
audioExclusiveToggle.setText("Exclusive").setToolTip(
audioExclusiveToggle.setText("Exclusive mode").setToolTip(
"(ASIO, WASAPI drivers only)\n\n"
"Acquires exclusive control of the sound card device.\n"
"This can significantly reduce audio latency.\n"

View File

@ -42,19 +42,13 @@ auto EmulatorSettings::create() -> void {
settings.emulator.hack.ppu.fast = fastPPU.checked();
if(!fastPPU.checked()) {
noSpriteLimit.setEnabled(false).setChecked(false).doToggle();
hiresMode7.setEnabled(false).setChecked(false).doToggle();
} else {
noSpriteLimit.setEnabled(true);
hiresMode7.setEnabled(true);
}
}).doToggle();
noSpriteLimit.setText("No sprite limit").setChecked(settings.emulator.hack.ppu.noSpriteLimit).onToggle([&] {
settings.emulator.hack.ppu.noSpriteLimit = noSpriteLimit.checked();
});
hiresMode7.setText("Hires mode 7").setChecked(settings.emulator.hack.ppu.mode7.hires).setVisible(false).onToggle([&] {
settings.emulator.hack.ppu.mode7.hires = hiresMode7.checked();
emulator->configure("Hacks/PPU/Mode7/Hires", settings.emulator.hack.ppu.mode7.hires);
});
mode7Label.setText("HD Mode 7 (fast PPU only)").setFont(Font().setBold());
mode7ScaleLabel.setText("Scale:");
mode7Scale.append(ComboButtonItem().setText( "240p").setProperty("multiplier", 1));
@ -77,6 +71,14 @@ auto EmulatorSettings::create() -> void {
settings.emulator.hack.ppu.mode7.perspective = mode7Perspective.checked();
emulator->configure("Hacks/PPU/Mode7/Perspective", settings.emulator.hack.ppu.mode7.perspective);
});
mode7Supersample.setText("Supersample").setChecked(settings.emulator.hack.ppu.mode7.supersample).onToggle([&] {
settings.emulator.hack.ppu.mode7.supersample = mode7Supersample.checked();
emulator->configure("Hacks/PPU/Mode7/Supersample", settings.emulator.hack.ppu.mode7.supersample);
});
mode7Mosaic.setText("HD->SD Mosaic").setChecked(settings.emulator.hack.ppu.mode7.mosaic).onToggle([&] {
settings.emulator.hack.ppu.mode7.mosaic = mode7Mosaic.checked();
emulator->configure("Hacks/PPU/Mode7/Mosaic", settings.emulator.hack.ppu.mode7.mosaic);
});
dspLabel.setText("DSP (audio)").setFont(Font().setBold());
fastDSP.setText("Fast mode").setChecked(settings.emulator.hack.dsp.fast).onToggle([&] {
settings.emulator.hack.dsp.fast = fastDSP.checked();
@ -105,8 +107,10 @@ auto EmulatorSettings::create() -> void {
auto EmulatorSettings::updateConfiguration() -> void {
emulator->configure("Hacks/PPU/Fast", fastPPU.checked());
emulator->configure("Hacks/PPU/NoSpriteLimit", noSpriteLimit.checked());
emulator->configure("Hacks/PPU/Mode7/Hires", hiresMode7.checked());
emulator->configure("Hacks/PPU/Mode7/Scale", mode7Scale.selected().property("multiplier").natural());
emulator->configure("Hacks/PPU/Mode7/Perspective", mode7Perspective.checked());
emulator->configure("Hacks/PPU/Mode7/Supersample", mode7Supersample.checked());
emulator->configure("Hacks/PPU/Mode7/Mosaic", mode7Mosaic.checked());
emulator->configure("Hacks/DSP/Fast", fastDSP.checked());
emulator->configure("Hacks/DSP/Cubic", cubicInterpolation.checked());
emulator->configure("Hacks/Coprocessor/DelayedSync", coprocessorsDelayedSyncOption.checked());

View File

@ -97,9 +97,10 @@ auto Settings::process(bool load) -> void {
bind(boolean, "Emulator/AutoLoadStateOnLoad", emulator.autoLoadStateOnLoad);
bind(boolean, "Emulator/Hack/PPU/Fast", emulator.hack.ppu.fast);
bind(boolean, "Emulator/Hack/PPU/NoSpriteLimit", emulator.hack.ppu.noSpriteLimit);
bind(boolean, "Emulator/Hack/PPU/Mode7/Hires", emulator.hack.ppu.mode7.hires);
bind(natural, "Emulator/Hack/PPU/Mode7/Scale", emulator.hack.ppu.mode7.scale);
bind(boolean, "Emulator/Hack/PPU/Mode7/Perspective", emulator.hack.ppu.mode7.perspective);
bind(boolean, "Emulator/Hack/PPU/Mode7/Supersample", emulator.hack.ppu.mode7.supersample);
bind(boolean, "Emulator/Hack/PPU/Mode7/Mosaic", emulator.hack.ppu.mode7.mosaic);
bind(boolean, "Emulator/Hack/DSP/Fast", emulator.hack.dsp.fast);
bind(boolean, "Emulator/Hack/DSP/Cubic", emulator.hack.dsp.cubic);
bind(boolean, "Emulator/Hack/Coprocessors/DelayedSync", emulator.hack.coprocessors.delayedSync);

View File

@ -79,9 +79,10 @@ struct Settings : Markup::Node {
bool fast = true;
bool noSpriteLimit = false;
struct Mode7 {
bool hires = false;
uint scale = 1;
bool perspective = true;
bool supersample = false;
bool mosaic = true;
} mode7;
} ppu;
struct DSP {
@ -265,12 +266,13 @@ public:
HorizontalLayout ppuLayout{&layout, Size{~0, 0}};
CheckLabel fastPPU{&ppuLayout, Size{0, 0}};
CheckLabel noSpriteLimit{&ppuLayout, Size{0, 0}};
CheckLabel hiresMode7{&ppuLayout, Size{0, 0}};
Label mode7Label{&layout, Size{~0, 0}, 2};
HorizontalLayout mode7Layout{&layout, Size{~0, 0}};
Label mode7ScaleLabel{&mode7Layout, Size{0, 0}};
ComboButton mode7Scale{&mode7Layout, Size{0, 0}};
CheckLabel mode7Perspective{&mode7Layout, Size{0, 0}};
CheckLabel mode7Supersample{&mode7Layout, Size{0, 0}};
CheckLabel mode7Mosaic{&mode7Layout, Size{0, 0}};
Label dspLabel{&layout, Size{~0, 0}, 2};
HorizontalLayout dspLayout{&layout, Size{~0, 0}};
CheckLabel fastDSP{&dspLayout, Size{0, 0}};