Added '-timing' commandline argument, which determines the type of waiting

to do between processing frames, and can be set to 'sleep' or 'busy'.
Sleep emulates previous Stella behaviour, releasing the CPU whenever
possible (at the expense of graphical tearing on some systems, unless
gl_vsync is enabled).  Busy emulates the busy-wait behaviour of z26,
using all available CPU time but sometimes eliminating (or at least
reducing) graphical tearing.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1526 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2008-05-21 16:49:07 +00:00
parent 20dd5c98e9
commit 9fc6eff352
4 changed files with 63 additions and 13 deletions

View File

@ -30,6 +30,12 @@
calculation. Also, re-enabled changing the framerate from within the calculation. Also, re-enabled changing the framerate from within the
UI. UI.
* Added '-timing' commandline argument, which sets the type of waiting
between processing frames. Setting it to 'sleep' emulates the
previous behaviour in Stella; setting it to 'busy' emulates z26,
and can in some cases eliminate screen tearing (at the expense of
using all available CPU time).
* Fixed issue with debugger disassembly and mirrored $40 TIA write * Fixed issue with debugger disassembly and mirrored $40 TIA write
addresses. They were actually defined at $30, and generating incorrect addresses. They were actually defined at $30, and generating incorrect
labels. labels.

View File

@ -240,6 +240,12 @@
calculation. Also, re-enabled changing the framerate from within the calculation. Also, re-enabled changing the framerate from within the
UI.</li> UI.</li>
<li>Added '-timing' commandline argument, which sets the type of waiting
between processing frames. Setting it to 'sleep' emulates the
previous behaviour in Stella; setting it to 'busy' emulates z26,
and can in some cases eliminate screen tearing (at the expense of
using all available CPU time).</li>
<li>Fixed issue with debugger disassembly and mirrored $40 TIA write <li>Fixed issue with debugger disassembly and mirrored $40 TIA write
addresses. They were actually defined at $30, and generating incorrect addresses. They were actually defined at $30, and generating incorrect
labels.</li> labels.</li>
@ -657,6 +663,16 @@
<td>Enable/disable the PAL color-loss effect.</td> <td>Enable/disable the PAL color-loss effect.</td>
</tr> </tr>
<tr>
<td><pre>-timing &lt;sleep|busy&gt;</pre></td>
<td>Determines type of wait to perform between processing frames.
Sleep will release the CPU as much as possible, and is the
preferred method on laptops (and other low-powered devices)
and when using GL VSync. Busy will emulate z26 busy-wait
behaviour, and use all possible CPU time, but may eliminate
graphical 'tearing'.</td>
</tr>
<tr> <tr>
<td><pre>-framerate &lt;number&gt;</pre></td> <td><pre>-framerate &lt;number&gt;</pre></td>
<td>Display the given number of frames per second. Normally, Stella <td>Display the given number of frames per second. Normally, Stella

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: OSystem.cxx,v 1.128 2008-05-21 14:50:41 stephena Exp $ // $Id: OSystem.cxx,v 1.129 2008-05-21 16:49:07 stephena Exp $
//============================================================================ //============================================================================
#include <cassert> #include <cassert>
@ -797,20 +797,42 @@ void OSystem::stateChanged(EventHandler::State state)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void OSystem::mainLoop() void OSystem::mainLoop()
{ {
for(;;) if(mySettings->getString("timing") == "sleep")
{ {
myTimingInfo.start = getTicks(); // Sleep-based wait: good for CPU, bad for graphical sync
myEventHandler->poll(myTimingInfo.start); for(;;)
if(myQuitLoop) break; // Exit if the user wants to quit {
myFrameBuffer->update(); myTimingInfo.start = getTicks();
myTimingInfo.current = getTicks(); myEventHandler->poll(myTimingInfo.start);
myTimingInfo.virt += myTimePerFrame; if(myQuitLoop) break; // Exit if the user wants to quit
myFrameBuffer->update();
myTimingInfo.current = getTicks();
myTimingInfo.virt += myTimePerFrame;
if(myTimingInfo.current < myTimingInfo.virt) if(myTimingInfo.current < myTimingInfo.virt)
SDL_Delay((myTimingInfo.virt - myTimingInfo.current) / 1000); SDL_Delay((myTimingInfo.virt - myTimingInfo.current) / 1000);
myTimingInfo.totalTime += (getTicks() - myTimingInfo.start); myTimingInfo.totalTime += (getTicks() - myTimingInfo.start);
myTimingInfo.totalFrames++; myTimingInfo.totalFrames++;
}
}
else
{
// Busy-wait: bad for CPU, good for graphical sync
for(;;)
{
myTimingInfo.start = getTicks();
myEventHandler->poll(myTimingInfo.start);
if(myQuitLoop) break; // Exit if the user wants to quit
myFrameBuffer->update();
myTimingInfo.virt += myTimePerFrame;
while(getTicks() < myTimingInfo.virt)
; // busy-wait
myTimingInfo.totalTime += (getTicks() - myTimingInfo.start);
myTimingInfo.totalFrames++;
}
} }
} }

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: Settings.cxx,v 1.146 2008-05-21 14:01:30 stephena Exp $ // $Id: Settings.cxx,v 1.147 2008-05-21 16:49:07 stephena Exp $
//============================================================================ //============================================================================
#include <cassert> #include <cassert>
@ -55,6 +55,7 @@ Settings::Settings(OSystem* osystem)
setInternal("grabmouse", "false"); setInternal("grabmouse", "false");
setInternal("palette", "standard"); setInternal("palette", "standard");
setInternal("colorloss", "false"); setInternal("colorloss", "false");
setInternal("timing", "sleep");
// Sound options // Sound options
setInternal("sound", "true"); setInternal("sound", "true");
@ -214,6 +215,10 @@ void Settings::validate()
if(s != "soft" && s != "gl") if(s != "soft" && s != "gl")
setInternal("video", "soft"); setInternal("video", "soft");
s = getString("timing");
if(s != "sleep" && s != "busy")
setInternal("timing", "sleep");
#ifdef DISPLAY_OPENGL #ifdef DISPLAY_OPENGL
s = getString("gl_filter"); s = getString("gl_filter");
if(s != "linear" && s != "nearest") if(s != "linear" && s != "nearest")
@ -308,6 +313,7 @@ void Settings::usage()
<< " user>\n" << " user>\n"
<< " -colorloss <1|0> Enable PAL color-loss effect\n" << " -colorloss <1|0> Enable PAL color-loss effect\n"
<< " -framerate <number> Display the given number of frames per second (0 to auto-calculate)\n" << " -framerate <number> Display the given number of frames per second (0 to auto-calculate)\n"
<< " -timing <sleep|busy> Use the given type of wait between frames\n"
<< endl << endl
#ifdef SOUND_SUPPORT #ifdef SOUND_SUPPORT
<< " -sound <1|0> Enable sound generation\n" << " -sound <1|0> Enable sound generation\n"