Added more sophisticated framerate calculation based on the number of

scanlines.  Previously, this was only done for the first few frames.
However, that approach won't work for ROMs that change the number of
scanlines later in their run.  Now, the framerate is automatically
re-calculated at regular intervals within the TIA.

Reworked 'framerate' argument to override auto-frame calculation when
it contains a non-zero value, and use the given framerate instead.
Setting it to zero resumes auto-frame calculation.

Re-activated framerate option in the UI.  This can be changed while
the ROM is running, updates will be almost immediate.

Upped the release date, since more testing is required.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1524 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2008-05-21 14:01:31 +00:00
parent 23d8618db7
commit bd90840ded
14 changed files with 126 additions and 60 deletions

View File

@ -12,18 +12,24 @@
Release History
===============================================================================
2.6 to 2.6.1: (May 21, 2008)
2.6 to 2.6.1: (May 23, 2008)
* Introduced more accurate timing for NTSC vs. PAL modes, where the
framerate is based on the number of scanlines per frame. This should
eliminate 'clicking' sounds when emulating ROMs that don't follow
the exact NTSC or PAL specs.
the exact NTSC or PAL scanline specs.
* Added ability to see the current number of scanlines and corresponding
framerate to the TIA emulation. This can be set with the '-stats'
commandline argument, or dynamically turned on and off with the
'Alt-l' key combo.
* Modified '-framerate' commandline argument, where a non-zero value
overrides the automatic framerate calculation (based on number of
scanlines). Setting 'framerate' to zero re-enables auto-frame
calculation. Also, re-enabled changing the framerate from within the
UI.
* Fixed issue with debugger disassembly and mirrored $40 TIA write
addresses. They were actually defined at $30, and generating incorrect
labels.
@ -39,7 +45,7 @@
* Fixed issue with M6532/RIOT timer initialization; it was causing some
ROMs to hang (most notably Summer Games). Related to this, reworked
the built-in random number generator to generate 'more random' numbers.
the built-in random number generator to generate 'more' random numbers.
* Fixed bug in CommandMenu where console buttons (Select, Reset, etc)
weren't doing anything.

View File

@ -9,4 +9,4 @@ the Stella Website at:
Enjoy,
The Stella Team
May 21, 2008
May 23, 2008

View File

@ -227,13 +227,19 @@
<li>Introduced more accurate timing for NTSC vs. PAL modes, where the
framerate is based on the number of scanlines per frame. This should
eliminate 'clicking' sounds when emulating ROMs that don't follow
the exact NTSC or PAL specs.</li>
the exact NTSC or PAL scanline specs.</li>
<li>Added ability to see the current number of scanlines and corresponding
framerate to the TIA emulation. This can be set with the '-stats'
commandline argument, or dynamically turned on and off with the
'Alt-l' key combo.</li>
<li>Modified '-framerate' commandline argument, where a non-zero value
overrides the automatic framerate calculation (based on number of
scanlines). Setting 'framerate' to zero re-enables auto-frame
calculation. Also, re-enabled changing the framerate from within the
UI.</li>
<li>Fixed issue with debugger disassembly and mirrored $40 TIA write
addresses. They were actually defined at $30, and generating incorrect
labels.</li>
@ -654,7 +660,9 @@
<tr>
<td><pre>-framerate &lt;number&gt;</pre></td>
<td>Display the given number of frames per second. Normally, Stella
will determine framerate based on ROM format.</td>
will determine framerate based on number of scanlines.
Setting this to 0 automatically enables auto-frame
calculation (ie, framerate based on scanlines).</td>
</tr>
<tr>

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: SoundSDL.cxx,v 1.43 2008-05-19 21:16:58 stephena Exp $
// $Id: SoundSDL.cxx,v 1.44 2008-05-21 14:01:29 stephena Exp $
//============================================================================
#ifdef SOUND_SUPPORT
@ -285,7 +285,6 @@ void SoundSDL::setFrameRate(float framerate)
{
// FIXME, we should clear out the queue or adjust the values in it
myDisplayFrameRate = framerate;
myLastRegisterSetCycle = 0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -302,7 +301,8 @@ void SoundSDL::set(uInt16 addr, uInt8 value, Int32 cycle)
// the sound to "scale" correctly, we have to know the games real frame
// rate (e.g., 50 or 60) and the currently emulated frame rate. We use these
// values to "scale" the time before the register change occurs.
delta = delta * (myDisplayFrameRate / (double)myOSystem->frameRate());
// FIXME - this always results in 1.0, so we don't really need it
// delta = delta * (myDisplayFrameRate / myOSystem->frameRate());
RegWrite info;
info.addr = addr;
info.value = value;

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: Console.cxx,v 1.144 2008-05-19 21:16:58 stephena Exp $
// $Id: Console.cxx,v 1.145 2008-05-21 14:01:29 stephena Exp $
//============================================================================
#include <cassert>
@ -458,7 +458,16 @@ void Console::initializeVideo(bool full)
setColorLossPalette(myOSystem->settings().getBool("colorloss"));
setPalette(myOSystem->settings().getString("palette"));
myOSystem->setFramerate(getFramerate());
// Set the correct framerate based on the format of the ROM
// This can be overridden by changing the framerate in the
// VideoDialog box or on the commandline, but it can't be saved
// (ie, framerate is now determined based on number of scanlines).
int framerate = myOSystem->settings().getInt("framerate");
if(framerate > 0) myFramerate = framerate;
myOSystem->setFramerate(myFramerate);
// Make sure auto-frame calculation is only enabled when necessary
myMediaSource->enableAutoFrame(framerate <= 0);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -467,13 +476,18 @@ void Console::initializeAudio()
// Initialize the sound interface.
// The # of channels can be overridden in the AudioDialog box or on
// the commandline, but it can't be saved.
int framerate = myOSystem->settings().getInt("framerate");
if(framerate > 0) myFramerate = framerate;
const string& sound = myProperties.get(Cartridge_Sound);
uInt32 channels = (sound == "STEREO" ? 2 : 1);
myOSystem->sound().close();
myOSystem->sound().setChannels(channels);
myOSystem->sound().setFrameRate(getFramerate());
myOSystem->sound().setFrameRate(myFramerate);
myOSystem->sound().initialize();
// Make sure auto-frame calculation is only enabled when necessary
myMediaSource->enableAutoFrame(framerate <= 0);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -810,14 +824,11 @@ void Console::setColorLossPalette(bool loss)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
float Console::getFramerate() const
void Console::setFramerate(float framerate)
{
// Set the correct framerate based on the format of the ROM
// This can be overridden by changing the framerate in the
// VideoDialog box or on the commandline, but it can't be saved
// (ie, framerate is now solely determined based on ROM format).
int framerate = myOSystem->settings().getInt("framerate");
return (float) framerate == -1 ? myFramerate : framerate;
myFramerate = framerate;
myOSystem->setFramerate(framerate);
myOSystem->sound().setFrameRate(framerate);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: Console.hxx,v 1.67 2008-05-19 21:16:58 stephena Exp $
// $Id: Console.hxx,v 1.68 2008-05-21 14:01:29 stephena Exp $
//============================================================================
#ifndef CONSOLE_HXX
@ -39,7 +39,7 @@ class System;
This class represents the entire game console.
@author Bradford W. Mott
@version $Id: Console.hxx,v 1.67 2008-05-19 21:16:58 stephena Exp $
@version $Id: Console.hxx,v 1.68 2008-05-21 14:01:29 stephena Exp $
*/
class Console : public Serializable
{
@ -225,11 +225,17 @@ class Console : public Serializable
*/
void changeHeight(int direction);
/**
Sets the framerate of the console, which in turn communicates
this to all applicable subsystems.
*/
void setFramerate(float framerate);
/**
Returns the framerate based on a number of factors
(whether 'framerate' is set, what display format is in use, etc)
*/
float getFramerate() const;
float getFramerate() const { return myFramerate; }
/**
Toggles the TIA bit specified in the method name.

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: FrameBuffer.cxx,v 1.129 2008-05-20 13:42:50 stephena Exp $
// $Id: FrameBuffer.cxx,v 1.130 2008-05-21 14:01:29 stephena Exp $
//============================================================================
#include <sstream>
@ -129,10 +129,10 @@ void FrameBuffer::update()
if(myFrameStatsEnabled)
{
// FIXME - sizes hardcoded for now; fix during UI refactoring
uInt32 scanlines = myOSystem->console().mediaSource().scanlines();
float fps = (scanlines <= 285 ? 15720.0 : 15600.0) / scanlines;
char msg[30];
sprintf(msg, "%u LINES %2.2f FPS", scanlines, fps);
sprintf(msg, "%u LINES %2.2f FPS",
myOSystem->console().mediaSource().scanlines(),
myOSystem->console().getFramerate());
fillRect(3, 3, 95, 9, kBGColor);
drawString(&myOSystem->font(), msg, 3, 3, 95, kBtnTextColor, kTextAlignCenter);
}

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: MediaSrc.hxx,v 1.18 2008-02-06 13:45:22 stephena Exp $
// $Id: MediaSrc.hxx,v 1.19 2008-05-21 14:01:30 stephena Exp $
//============================================================================
#ifndef MEDIASOURCE_HXX
@ -30,7 +30,7 @@ class Sound;
This class provides an interface for accessing graphics and audio data.
@author Bradford W. Mott
@version $Id: MediaSrc.hxx,v 1.18 2008-02-06 13:45:22 stephena Exp $
@version $Id: MediaSrc.hxx,v 1.19 2008-05-21 14:01:30 stephena Exp $
*/
class MediaSource
{
@ -107,6 +107,14 @@ class MediaSource
virtual uInt32 width() const = 0;
public:
/**
Enables/disables auto-frame calculation. If enabled, the
MediaSource should re-adjust the framerate at regular intervals.
@param mode Whether to enable or disable all auto-frame calculation
*/
virtual void enableAutoFrame(bool mode) = 0;
/**
Answers the total number of scanlines the media source generated
in producing the current frame buffer.

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: Settings.cxx,v 1.145 2008-05-20 13:42:50 stephena Exp $
// $Id: Settings.cxx,v 1.146 2008-05-21 14:01:30 stephena Exp $
//============================================================================
#include <cassert>
@ -307,7 +307,7 @@ void Settings::usage()
<< " z26|\n"
<< " user>\n"
<< " -colorloss <1|0> Enable PAL color-loss effect\n"
<< " -framerate <number> Display the given number of frames per second\n"
<< " -framerate <number> Display the given number of frames per second (0 to auto-calculate)\n"
<< endl
#ifdef SOUND_SUPPORT
<< " -sound <1|0> Enable sound generation\n"

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: TIA.cxx,v 1.92 2008-05-19 21:16:58 stephena Exp $
// $Id: TIA.cxx,v 1.93 2008-05-21 14:01:30 stephena Exp $
//============================================================================
//#define DEBUG_HMOVE
@ -38,7 +38,7 @@
#define HBLANK 68
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TIA::TIA(const Console& console, Settings& settings)
TIA::TIA(Console& console, Settings& settings)
: myConsole(console),
mySettings(settings),
mySound(NULL),
@ -56,6 +56,7 @@ TIA::TIA(const Console& console, Settings& settings)
myPreviousFrameBuffer = new uInt8[160 * 300];
myFrameGreyed = false;
myAutoFrameEnabled = false;
for(i = 0; i < 6; ++i)
myBitEnabled[i] = true;
@ -195,6 +196,8 @@ void TIA::reset()
myFloatTIAOutputPins = mySettings.getBool("tiafloat");
myAutoFrameEnabled = (mySettings.getInt("framerate") <= 0);
if(myConsole.getFramerate() > 55.0) // NTSC
{
myColorLossEnabled = false;
@ -593,6 +596,15 @@ inline void TIA::endFrame()
// Stats counters
myFrameCounter++;
// Recalculate framerate. attempting to auto-correct for scanline 'jumps'
if(myFrameCounter % 64 == 0 && myAutoFrameEnabled)
{
float framerate =
(myScanlineCountForLastFrame > 285 ? 15600.0 : 15720.0) /
myScanlineCountForLastFrame;
myConsole.setFramerate(framerate);
}
myFrameGreyed = false;
}

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: TIA.hxx,v 1.46 2008-03-03 17:51:55 estolberg Exp $
// $Id: TIA.hxx,v 1.47 2008-05-21 14:01:31 stephena Exp $
//============================================================================
#ifndef TIA_HXX
@ -40,7 +40,7 @@ class Settings;
be displayed on screen.
@author Bradford W. Mott
@version $Id: TIA.hxx,v 1.46 2008-03-03 17:51:55 estolberg Exp $
@version $Id: TIA.hxx,v 1.47 2008-05-21 14:01:31 stephena Exp $
*/
class TIA : public Device , public MediaSource
{
@ -53,7 +53,7 @@ class TIA : public Device , public MediaSource
@param console The console the TIA is associated with
@param settings The settings object for this TIA device
*/
TIA(const Console& console, Settings& settings);
TIA(Console& console, Settings& settings);
/**
Destructor
@ -171,6 +171,14 @@ class TIA : public Device , public MediaSource
*/
uInt32 width() const;
/**
Enables/disables auto-frame calculation. If enabled, the TIA
re-adjusts the framerate at regular intervals.
@param mode Whether to enable or disable all auto-frame calculation
*/
void enableAutoFrame(bool mode) { myAutoFrameEnabled = mode; }
/**
Answers the total number of scanlines the media source generated
in producing the current frame buffer. For partial frames, this
@ -180,6 +188,11 @@ class TIA : public Device , public MediaSource
*/
uInt32 scanlines() const;
/**
Sets the sound device for the TIA.
*/
void setSound(Sound& sound);
/**
Answers the current color clock we've gotten to on this scanline.
@ -187,11 +200,6 @@ class TIA : public Device , public MediaSource
*/
uInt32 clocksThisLine() const;
/**
Sets the sound device for the TIA.
*/
void setSound(Sound& sound);
enum TIABit {
P0, // Descriptor for Player 0 Bit
P1, // Descriptor for Player 1 Bit
@ -288,10 +296,10 @@ class TIA : public Device , public MediaSource
private:
// Console the TIA is associated with
const Console& myConsole;
Console& myConsole;
// Settings object the TIA is associated with
const Settings& mySettings;
Settings& mySettings;
// Sound object the TIA is associated with
Sound* mySound;
@ -518,8 +526,11 @@ class TIA : public Device , public MediaSource
// Answers whether specified bits (from TIABit) are enabled or disabled
bool myBitEnabled[6];
// Has current frame been "greyed out" (has updateScanline() been run?)
bool myFrameGreyed;
// Has current frame been "greyed out" (has updateScanline() been run?)
bool myFrameGreyed;
// Automatic framerate correction based on number of scanlines
bool myAutoFrameEnabled;
private:
// Ball mask table (entries are true or false)

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: DialogContainer.cxx,v 1.43 2008-05-20 13:42:50 stephena Exp $
// $Id: DialogContainer.cxx,v 1.44 2008-05-21 14:01:31 stephena Exp $
//============================================================================
#include "OSystem.hxx"
@ -136,9 +136,6 @@ void DialogContainer::reStack()
myDialogStack.pop();
addDialog(myBaseDialog);
// Erase any previous messages
myOSystem->frameBuffer().enableMessages(false);
// Reset all continuous events
reset();
}

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: VideoDialog.cxx,v 1.49 2008-03-23 16:22:46 stephena Exp $
// $Id: VideoDialog.cxx,v 1.50 2008-05-21 14:01:31 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -28,6 +28,7 @@
#include "Menu.hxx"
#include "OSystem.hxx"
#include "PopUpWidget.hxx"
#include "Console.hxx"
#include "Settings.hxx"
#include "Widget.hxx"
@ -140,7 +141,7 @@ VideoDialog::VideoDialog(OSystem* osystem, DialogContainer* parent,
// Framerate
myFrameRateSlider = new SliderWidget(this, font, xpos, ypos, 30, lineHeight,
"Framerate: ", lwidth, kFrameRateChanged);
myFrameRateSlider->setMinValue(1); myFrameRateSlider->setMaxValue(300);
myFrameRateSlider->setMinValue(0); myFrameRateSlider->setMaxValue(300);
wid.push_back(myFrameRateSlider);
myFrameRateLabel = new StaticTextWidget(this, font,
xpos + myFrameRateSlider->getWidth() + 4,
@ -266,8 +267,11 @@ void VideoDialog::loadConfig()
myAspectRatioSlider->setValue(i);
myAspectRatioLabel->setLabel(s);
// FIXME - what to do with this??
myFrameRateSlider->setEnabled(false);
// Framerate (0 or -1 means disabled)
s = instance()->settings().getString("framerate");
i = instance()->settings().getInt("framerate");
myFrameRateSlider->setValue(i < 0 ? 0 : i);
myFrameRateLabel->setLabel(i < 0 ? "0" : s);
// Fullscreen
b = instance()->settings().getBool("fullscreen");
@ -341,12 +345,15 @@ void VideoDialog::saveConfig()
s = myAspectRatioLabel->getLabel();
instance()->settings().setString("gl_aspect", s);
// Framerate FIXME - I haven't figured out what to do with this yet
/*
// Framerate
i = myFrameRateSlider->getValue();
if(i > 0)
instance()->setFramerate(i);
*/
instance()->settings().setInt("framerate", i);
if(&instance()->console())
{
// Make sure auto-frame calculation is only enabled when necessary
instance()->console().mediaSource().enableAutoFrame(i <= 0);
instance()->console().setFramerate(i);
}
// Fullscreen
b = myFullscreenCheckbox->getState();
@ -382,8 +389,8 @@ void VideoDialog::setDefaults()
myTIAZoomLabel->setLabel("2");
myAspectRatioSlider->setValue(100);
myAspectRatioLabel->setLabel("100");
// myFrameRateSlider->setValue(0);
// myFrameRateLabel->setLabel("0");
myFrameRateSlider->setValue(0);
myFrameRateLabel->setLabel("0");
myFullscreenCheckbox->setState(false);
myColorLossCheckbox->setState(false);

View File

@ -107,7 +107,7 @@ rm -rf $RPM_BUILD_DIR/%{name}-%{version}
%_datadir/icons/large/%{name}.png
%changelog
* Fri May 21 2008 Stephen Anthony <stephena@users.sf.net> 2.6.1-1
* Fri May 23 2008 Stephen Anthony <stephena@users.sf.net> 2.6.1-1
- Version 2.6.1 release
* Fri May 16 2008 Stephen Anthony <stephena@users.sf.net> 2.6-1