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:
Tim Allen 2010-09-09 16:34:54 +10:00
parent 4147dc42d0
commit 92ab697f8c
48 changed files with 101 additions and 33 deletions

View File

@ -1,6 +1,6 @@
include nall/Makefile
snes := snes
profile := compatibility
profile := performance
ui := qt
# compiler

View File

@ -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)

View File

@ -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();
}

View File

@ -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/*

View File

@ -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() {

View File

@ -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();

View File

@ -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() {

View File

@ -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();

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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>

View File

@ -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>

View File

@ -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;
}
}