mirror of https://github.com/bsnes-emu/bsnes.git
Update to v068r17 release.
byuu says: This hopefully fixes vertical and horizontal mosaic with the accurate S-PPU core. It also adds frame-skipping support to the compatibility and performance S-PPU cores. This is not visible to the user interface, because I feel that virtually nobody is going to play with frame-skipping on when they could use a faster emulation with it off. However, I did use it to enhance the 'Fast Forward' key. When you press it, it will now turn off video and audio sync, and set a frameskip of 9. This allows you to speed things up an additional ~60% over your max theoretical speed without frameskipping. ~35% with the compatible core, because the PPU is less of a bottleneck for it. Slowdown was improved, it will turn on audio sync if it is off until you release the key to ensure you actually get 30fps. Eventually it'd probably be wise to set a cap on the fast forward speed, but I hardly think it's an issue on today's computers.
This commit is contained in:
parent
4147dc42d0
commit
92ab697f8c
|
@ -1,6 +1,6 @@
|
|||
include nall/Makefile
|
||||
snes := snes
|
||||
profile := compatibility
|
||||
profile := performance
|
||||
ui := qt
|
||||
|
||||
# compiler
|
||||
|
|
|
@ -178,6 +178,9 @@ MainWindow::MainWindow() {
|
|||
tools_stateManager = tools->addAction("&State Manager ...");
|
||||
|
||||
tools_effectToggle = tools->addAction("Effect &Toggle ...");
|
||||
#if !defined(PROFILE_COMPATIBILITY) && !defined(PROFILE_PERFORMANCE)
|
||||
tools_effectToggle->setVisible(false);
|
||||
#endif
|
||||
|
||||
tools_debugger = tools->addAction("&Debugger ...");
|
||||
#if !defined(DEBUGGER)
|
||||
|
|
|
@ -8,15 +8,21 @@ namespace UserInterfaceEmulationSpeed {
|
|||
|
||||
struct Slowdown : HotkeyInput {
|
||||
bool syncVideo;
|
||||
bool syncAudio;
|
||||
|
||||
void pressed() {
|
||||
config().system.speed = 0;
|
||||
utility.updateEmulationSpeed();
|
||||
syncVideo = config().video.synchronize;
|
||||
syncAudio = config().audio.synchronize;
|
||||
if(syncVideo) {
|
||||
config().video.synchronize = false;
|
||||
utility.updateAvSync();
|
||||
}
|
||||
if(!syncAudio) {
|
||||
config().audio.synchronize = true;
|
||||
utility.updateAvSync();
|
||||
}
|
||||
mainWindow->syncUi();
|
||||
}
|
||||
|
||||
|
@ -27,35 +33,56 @@ struct Slowdown : HotkeyInput {
|
|||
config().video.synchronize = true;
|
||||
utility.updateAvSync();
|
||||
}
|
||||
if(!syncAudio) {
|
||||
config().audio.synchronize = false;
|
||||
utility.updateAvSync();
|
||||
}
|
||||
mainWindow->syncUi();
|
||||
}
|
||||
|
||||
Slowdown() : HotkeyInput("Slowdown", "input.userInterface.emulationSpeed.slowdown") {
|
||||
name = "Shift+KB0::Tilde";
|
||||
userInterfaceEmulationSpeed.attach(this);
|
||||
}
|
||||
} slowdown;
|
||||
|
||||
struct Speedup : HotkeyInput {
|
||||
bool syncVideo;
|
||||
bool syncAudio;
|
||||
|
||||
void pressed() {
|
||||
#if defined(PROFILE_COMPATIBILITY) || defined(PROFILE_PERFORMANCE)
|
||||
SNES::ppu.set_frameskip(9);
|
||||
#endif
|
||||
config().system.speed = 4;
|
||||
utility.updateEmulationSpeed();
|
||||
syncVideo = config().video.synchronize;
|
||||
syncAudio = config().audio.synchronize;
|
||||
if(syncVideo) {
|
||||
config().video.synchronize = false;
|
||||
utility.updateAvSync();
|
||||
}
|
||||
if(syncAudio) {
|
||||
config().audio.synchronize = false;
|
||||
utility.updateAvSync();
|
||||
}
|
||||
mainWindow->syncUi();
|
||||
}
|
||||
|
||||
void released() {
|
||||
#if defined(PROFILE_COMPATIBILITY) || defined(PROFILE_PERFORMANCE)
|
||||
SNES::ppu.set_frameskip(0);
|
||||
#endif
|
||||
config().system.speed = 2;
|
||||
utility.updateEmulationSpeed();
|
||||
if(syncVideo) {
|
||||
config().video.synchronize = true;
|
||||
utility.updateAvSync();
|
||||
}
|
||||
if(syncAudio) {
|
||||
config().audio.synchronize = true;
|
||||
utility.updateAvSync();
|
||||
}
|
||||
mainWindow->syncUi();
|
||||
}
|
||||
|
||||
|
|
|
@ -21,13 +21,13 @@ else ifeq ($(profile),compatibility)
|
|||
snescpu := $(snes)/cpu
|
||||
snessmp := $(snes)/smp
|
||||
snesdsp := $(snes)/alt/dsp
|
||||
snesppu := $(snes)/alt/ppu
|
||||
snesppu := $(snes)/alt/ppu-compatibility
|
||||
else ifeq ($(profile),performance)
|
||||
flags += -DPROFILE_PERFORMANCE
|
||||
snescpu := $(snes)/alt/cpu
|
||||
snessmp := $(snes)/smp
|
||||
snesdsp := $(snes)/alt/dsp
|
||||
snesppu := $(snes)/alt/ppu-new
|
||||
snesppu := $(snes)/alt/ppu-performance
|
||||
endif
|
||||
|
||||
obj/libco.o : libco/libco.c libco/*
|
||||
|
|
|
@ -105,6 +105,7 @@ void PPU::scanline() {
|
|||
|
||||
void PPU::render_scanline() {
|
||||
if(line >= 1 && line < (!overscan() ? 225 : 240)) {
|
||||
if(framecounter) return;
|
||||
render_line_oam_rto();
|
||||
render_line();
|
||||
}
|
||||
|
@ -117,6 +118,8 @@ void PPU::frame() {
|
|||
display.interlace = regs.interlace;
|
||||
regs.scanlines = (regs.overscan == false) ? 224 : 239;
|
||||
}
|
||||
|
||||
framecounter = (frameskip == 0 ? 0 : (framecounter + 1) % frameskip);
|
||||
}
|
||||
|
||||
void PPU::power() {
|
||||
|
@ -382,6 +385,11 @@ void PPU::layer_enable(unsigned layer, unsigned priority, bool enable) {
|
|||
}
|
||||
}
|
||||
|
||||
void PPU::set_frameskip(unsigned frameskip_) {
|
||||
frameskip = frameskip_;
|
||||
framecounter = 0;
|
||||
}
|
||||
|
||||
PPU::PPU() {
|
||||
surface = new uint16[512 * 512];
|
||||
output = surface + 16 * 512;
|
||||
|
@ -420,6 +428,8 @@ PPU::PPU() {
|
|||
layer_enabled[OAM][1] = true;
|
||||
layer_enabled[OAM][2] = true;
|
||||
layer_enabled[OAM][3] = true;
|
||||
frameskip = 0;
|
||||
framecounter = 0;
|
||||
}
|
||||
|
||||
PPU::~PPU() {
|
|
@ -61,6 +61,9 @@ public:
|
|||
|
||||
bool layer_enabled[5][4];
|
||||
void layer_enable(unsigned layer, unsigned priority, bool enable);
|
||||
unsigned frameskip;
|
||||
unsigned framecounter;
|
||||
void set_frameskip(unsigned frameskip);
|
||||
|
||||
void serialize(serializer&);
|
||||
PPU();
|
|
@ -56,6 +56,7 @@ void PPU::add_clocks(unsigned clocks) {
|
|||
}
|
||||
|
||||
void PPU::render_scanline() {
|
||||
if(display.framecounter) return; //skip this frame?
|
||||
bg1.scanline();
|
||||
bg2.scanline();
|
||||
bg3.scanline();
|
||||
|
@ -80,6 +81,7 @@ void PPU::scanline() {
|
|||
void PPU::frame() {
|
||||
oam.frame();
|
||||
system.frame();
|
||||
display.framecounter = display.frameskip == 0 ? 0 : (display.framecounter + 1) % display.frameskip;
|
||||
}
|
||||
|
||||
void PPU::power() {
|
||||
|
@ -113,6 +115,11 @@ void PPU::layer_enable(unsigned layer, unsigned priority, bool enable) {
|
|||
}
|
||||
}
|
||||
|
||||
void PPU::set_frameskip(unsigned frameskip) {
|
||||
display.frameskip = frameskip;
|
||||
display.framecounter = 0;
|
||||
}
|
||||
|
||||
PPU::PPU() :
|
||||
cache(*this),
|
||||
bg1(*this, Background::ID::BG1),
|
||||
|
@ -123,6 +130,10 @@ oam(*this),
|
|||
screen(*this) {
|
||||
surface = new uint16[512 * 512];
|
||||
output = surface + 16 * 512;
|
||||
display.width = 256;
|
||||
display.height = 224;
|
||||
display.frameskip = 0;
|
||||
display.framecounter = 0;
|
||||
}
|
||||
|
||||
PPU::~PPU() {
|
|
@ -16,6 +16,7 @@ public:
|
|||
void frame();
|
||||
|
||||
void layer_enable(unsigned layer, unsigned priority, bool enable);
|
||||
void set_frameskip(unsigned frameskip);
|
||||
|
||||
void serialize(serializer&);
|
||||
PPU();
|
||||
|
@ -43,6 +44,8 @@ private:
|
|||
struct Display {
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
unsigned frameskip;
|
||||
unsigned framecounter;
|
||||
} display;
|
||||
|
||||
static void Enter();
|
|
@ -20,7 +20,7 @@ void PPU::Background::scanline() {
|
|||
mosaic_voffset += regs.mosaic + 1;
|
||||
}
|
||||
|
||||
mosaic_hcounter = 0;
|
||||
mosaic_hcounter = regs.mosaic + 1;
|
||||
mosaic_hoffset = 0;
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ void PPU::Background::get_tile() {
|
|||
mask_y--;
|
||||
|
||||
unsigned px = x << hires;
|
||||
unsigned py = mosaic_voffset;
|
||||
unsigned py = (regs.mosaic == 0 ? y : mosaic_voffset);
|
||||
|
||||
unsigned hscroll = regs.hoffset;
|
||||
unsigned vscroll = regs.voffset;
|
||||
|
@ -152,38 +152,41 @@ void PPU::Background::run(bool screen) {
|
|||
tile_counter = 7;
|
||||
get_tile();
|
||||
}
|
||||
if(screen == Screen::Main) x++;
|
||||
|
||||
uint8 palette = get_tile_color();
|
||||
if(x >= 0 && mosaic_hcounter++ >= regs.mosaic) {
|
||||
mosaic_hcounter = 0;
|
||||
mosaic_palette = palette;
|
||||
if(x == 0) mosaic_hcounter = 1;
|
||||
if(x >= 0 && --mosaic_hcounter == 0) {
|
||||
mosaic_hcounter = regs.mosaic + 1;
|
||||
mosaic_priority = priority;
|
||||
mosaic_palette = palette ? palette_index + palette : 0;
|
||||
mosaic_tile = tile;
|
||||
}
|
||||
if(screen == Screen::Main) x++;
|
||||
if(mosaic_palette == 0) return;
|
||||
|
||||
if(hires == false) {
|
||||
if(regs.main_enable) {
|
||||
output.main.priority = priority;
|
||||
output.main.palette = palette_index + mosaic_palette;
|
||||
output.main.tile = tile;
|
||||
output.main.priority = mosaic_priority;
|
||||
output.main.palette = mosaic_palette;
|
||||
output.main.tile = mosaic_tile;
|
||||
}
|
||||
|
||||
if(regs.sub_enable) {
|
||||
output.sub.priority = priority;
|
||||
output.sub.palette = palette_index + mosaic_palette;
|
||||
output.sub.tile = tile;
|
||||
output.sub.priority = mosaic_priority;
|
||||
output.sub.palette = mosaic_palette;
|
||||
output.sub.tile = mosaic_tile;
|
||||
}
|
||||
} else if(screen == Screen::Main) {
|
||||
if(regs.main_enable) {
|
||||
output.main.priority = priority;
|
||||
output.main.palette = palette_index + mosaic_palette;
|
||||
output.main.tile = tile;
|
||||
output.main.priority = mosaic_priority;
|
||||
output.main.palette = mosaic_palette;
|
||||
output.main.tile = mosaic_tile;
|
||||
}
|
||||
} else if(screen == Screen::Sub) {
|
||||
if(regs.sub_enable) {
|
||||
output.sub.priority = priority;
|
||||
output.sub.palette = palette_index + mosaic_palette;
|
||||
output.sub.tile = tile;
|
||||
output.sub.priority = mosaic_priority;
|
||||
output.sub.palette = mosaic_palette;
|
||||
output.sub.tile = mosaic_tile;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -233,7 +236,10 @@ void PPU::Background::reset() {
|
|||
mosaic_voffset = 0;
|
||||
mosaic_hcounter = 0;
|
||||
mosaic_hoffset = 0;
|
||||
|
||||
mosaic_priority = 0;
|
||||
mosaic_palette = 0;
|
||||
mosaic_tile = 0;
|
||||
|
||||
tile_counter = 0;
|
||||
tile = 0;
|
||||
|
|
|
@ -41,7 +41,10 @@ class Background {
|
|||
unsigned mosaic_voffset;
|
||||
unsigned mosaic_hcounter;
|
||||
unsigned mosaic_hoffset;
|
||||
unsigned mosaic_palette;
|
||||
|
||||
unsigned mosaic_priority;
|
||||
uint8 mosaic_palette;
|
||||
uint16 mosaic_tile;
|
||||
|
||||
unsigned tile_counter;
|
||||
unsigned tile;
|
||||
|
|
|
@ -20,8 +20,8 @@ void PPU::Background::run_mode7() {
|
|||
unsigned x = mosaic_hoffset;
|
||||
unsigned y = self.bg1.mosaic_voffset; //BG2 vertical mosaic uses BG1 mosaic size
|
||||
|
||||
if(mosaic_hcounter++ == regs.mosaic) {
|
||||
mosaic_hcounter = 0;
|
||||
if(--mosaic_hcounter == 0) {
|
||||
mosaic_hcounter = regs.mosaic + 1;
|
||||
mosaic_hoffset += regs.mosaic + 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,11 +38,10 @@ void PPU::enter() {
|
|||
}
|
||||
|
||||
scanline();
|
||||
add_clocks(56);
|
||||
add_clocks(60);
|
||||
|
||||
if(vcounter() <= (!regs.overscan ? 224 : 239)) {
|
||||
add_clocks(4);
|
||||
for(unsigned pixel = 1; pixel < 8 + 256; pixel++) {
|
||||
for(signed pixel = -7; pixel <= 255; pixel++) {
|
||||
bg1.run(1);
|
||||
bg2.run(1);
|
||||
bg3.run(1);
|
||||
|
@ -53,7 +52,7 @@ void PPU::enter() {
|
|||
bg2.run(0);
|
||||
bg3.run(0);
|
||||
bg4.run(0);
|
||||
if(pixel >= 8) {
|
||||
if(pixel >= 0) {
|
||||
oam.run();
|
||||
window.run();
|
||||
screen.run();
|
||||
|
@ -64,10 +63,10 @@ void PPU::enter() {
|
|||
add_clocks(22);
|
||||
oam.tilefetch();
|
||||
} else {
|
||||
add_clocks(1056 + 22 + 136);
|
||||
add_clocks(1052 + 22 + 136);
|
||||
}
|
||||
|
||||
add_clocks(lineclocks() - 56 - 1056 - 22 - 136);
|
||||
add_clocks(lineclocks() - 60 - 1052 - 22 - 136);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -120,7 +120,10 @@ void PPU::Background::serialize(serializer &s) {
|
|||
s.integer(mosaic_voffset);
|
||||
s.integer(mosaic_hcounter);
|
||||
s.integer(mosaic_hoffset);
|
||||
|
||||
s.integer(mosaic_priority);
|
||||
s.integer(mosaic_palette);
|
||||
s.integer(mosaic_tile);
|
||||
|
||||
s.integer(tile_counter);
|
||||
s.integer(tile);
|
||||
|
|
|
@ -5,4 +5,4 @@ namespace Info {
|
|||
#include <cpu/cpu.hpp>
|
||||
#include <smp/smp.hpp>
|
||||
#include <alt/dsp/dsp.hpp>
|
||||
#include <alt/ppu/ppu.hpp>
|
||||
#include <alt/ppu-compatibility/ppu.hpp>
|
||||
|
|
|
@ -5,4 +5,4 @@ namespace Info {
|
|||
#include <alt/cpu/cpu.hpp>
|
||||
#include <smp/smp.hpp>
|
||||
#include <alt/dsp/dsp.hpp>
|
||||
#include <alt/ppu-new/ppu.hpp>
|
||||
#include <alt/ppu-performance/ppu.hpp>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
namespace SNES {
|
||||
namespace Info {
|
||||
static const char Name[] = "bsnes";
|
||||
static const char Version[] = "068.16";
|
||||
static const char Version[] = "068.17";
|
||||
static const unsigned SerializerVersion = 13;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue