mirror of https://github.com/bsnes-emu/bsnes.git
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:
parent
7a548482ed
commit
becbca47d4
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
auto PPUfast::Line::renderMode7(PPUfast::IO::Background& self, uint source) -> void {
|
||||
if(ppufast.hdScale() > 1) return renderMode7HD(self, source);
|
||||
if(configuration.hacks.ppu.mode7.hires) return renderMode7Hires(self, source);
|
||||
//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);
|
||||
}
|
||||
|
||||
int Y = this->y - (self.mosaicEnable ? this->y % (1 + io.mosaicSize) : 0);
|
||||
int y = !io.mode7.vflip ? Y : 255 - Y;
|
||||
|
|
|
@ -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,74 +50,92 @@ 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};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//interpolation and extrapolation
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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}};
|
||||
|
|
Loading…
Reference in New Issue