diff --git a/stella/src/build/makefile b/stella/src/build/makefile index 45f2d5ed9..ea856dd07 100644 --- a/stella/src/build/makefile +++ b/stella/src/build/makefile @@ -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: makefile,v 1.10 2002-03-10 01:29:54 stephena Exp $ +## $Id: makefile,v 1.11 2002-03-17 19:37:00 stephena Exp $ ##============================================================================ ##============================================================================ @@ -34,7 +34,7 @@ OPTIMIZATIONS = # -funroll-loops -fstrength-reduce -fomit-frame-pointer -ffast-math \ # -malign-functions=2 -malign-jumps=2 -malign-loops=2 ### to get full optimization under gcc/x Athlon based OS's.. -# OPTIMIZATIONS = -O3 -march=athlon -Wall -Wno-unused \ +# OPTIMIZATIONS = -O3 -mcpu=athlon -march=athlon -Wall -Wno-unused \ # -funroll-loops -fstrength-reduce -fomit-frame-pointer -ffast-math \ # -malign-functions=2 -malign-jumps=2 -malign-loops=2 diff --git a/stella/src/emucore/MediaSrc.hxx b/stella/src/emucore/MediaSrc.hxx index 660970bf1..0ce28a583 100644 --- a/stella/src/emucore/MediaSrc.hxx +++ b/stella/src/emucore/MediaSrc.hxx @@ -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.1.1.1 2001-12-27 19:54:22 bwmott Exp $ +// $Id: MediaSrc.hxx,v 1.2 2002-03-17 19:37:00 stephena Exp $ //============================================================================ #ifndef MEDIASOURCE_HXX @@ -27,7 +27,7 @@ class MediaSource; This class provides an interface for accessing graphics data. @author Bradford W. Mott - @version $Id: MediaSrc.hxx,v 1.1.1.1 2001-12-27 19:54:22 bwmott Exp $ + @version $Id: MediaSrc.hxx,v 1.2 2002-03-17 19:37:00 stephena Exp $ */ class MediaSource { @@ -49,6 +49,15 @@ class MediaSource */ virtual void update() = 0; + /** + This method should be called to cause further calls to 'update' + to be ignored until an unpause is given. Will also send a mute to + the Sound device. + + @return Status of the pause, success (true) or failure (false) + */ + virtual bool pause(bool state) = 0; + /** Answers the current frame buffer @@ -102,4 +111,3 @@ class MediaSource MediaSource& operator = (const MediaSource&); }; #endif - diff --git a/stella/src/emucore/TIA.cxx b/stella/src/emucore/TIA.cxx index 1661ca105..426c2c636 100644 --- a/stella/src/emucore/TIA.cxx +++ b/stella/src/emucore/TIA.cxx @@ -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.6 2002-01-27 02:10:04 stephena Exp $ +// $Id: TIA.cxx,v 1.7 2002-03-17 19:37:00 stephena Exp $ //============================================================================ #include @@ -262,6 +262,10 @@ void TIA::install(System& system) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void TIA::update() { + // Don't do an update if the emulator is paused + if(pauseState) + return; + uInt8* tmp = myCurrentFrameBuffer; myCurrentFrameBuffer = myPreviousFrameBuffer; myPreviousFrameBuffer = tmp; @@ -295,6 +299,21 @@ void TIA::update() myScanlineCountForFrame = totalClocks / 228; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool TIA::pause(bool state) +{ + // Ignore multiple calls to do the same thing + if(pauseState == state) + return false; + + pauseState = state; + + // Now pause the Sound device + mySound.mute(pauseState); + + return true; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - const uInt32* TIA::palette() const { diff --git a/stella/src/emucore/TIA.hxx b/stella/src/emucore/TIA.hxx index f1b06f4ce..8f05e528a 100644 --- a/stella/src/emucore/TIA.hxx +++ b/stella/src/emucore/TIA.hxx @@ -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.1.1.1 2001-12-27 19:54:25 bwmott Exp $ +// $Id: TIA.hxx,v 1.2 2002-03-17 19:37:00 stephena Exp $ //============================================================================ #ifndef TIA_HXX @@ -38,7 +38,7 @@ class System; be displayed on screen. @author Bradford W. Mott - @version $Id: TIA.hxx,v 1.1.1.1 2001-12-27 19:54:25 bwmott Exp $ + @version $Id: TIA.hxx,v 1.2 2002-03-17 19:37:00 stephena Exp $ */ class TIA : public Device , public MediaSource { @@ -106,6 +106,15 @@ class TIA : public Device , public MediaSource */ virtual void update(); + /** + This method should be called to cause further calls to 'update' + to be ignored until an unpause is given. Will also send a mute to + the Sound device. + + @return Status of the pause, success (true) or failure (false) + */ + virtual bool pause(bool state); + /** Answers the current frame buffer @@ -417,6 +426,8 @@ class TIA : public Device , public MediaSource // Assignment operator isn't supported by this class so make it private TIA& operator = (const TIA&); + + // Indicates whether the current emulation cycle should is paused + bool pauseState; }; #endif - diff --git a/stella/src/ui/sdl/mainSDL.cxx b/stella/src/ui/sdl/mainSDL.cxx index e13513a2e..eb87615c7 100644 --- a/stella/src/ui/sdl/mainSDL.cxx +++ b/stella/src/ui/sdl/mainSDL.cxx @@ -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: mainSDL.cxx,v 1.12 2002-03-10 01:29:55 stephena Exp $ +// $Id: mainSDL.cxx,v 1.13 2002-03-17 19:37:00 stephena Exp $ //============================================================================ #include @@ -49,6 +49,7 @@ #define SDL_DISABLE 0 #endif +#define HAVE_GETTIMEOFDAY SDL_Joystick* theLeftJoystick; SDL_Joystick* theRightJoystick; @@ -73,6 +74,7 @@ void toggleFullscreen(); void takeSnapshot(); void togglePause(); uInt32 maxWindowSizeForScreen(); +uInt32 getTicks(); bool setupProperties(PropertiesSet& set); void handleCommandLineArguments(int ac, char* av[]); @@ -608,8 +610,6 @@ void toggleFullscreen() */ void togglePause() { -// todo: implement pause functionality - if(thePauseIndicator) // emulator is already paused so continue { thePauseIndicator = false; @@ -618,6 +618,8 @@ void togglePause() { thePauseIndicator = true; } + + theConsole->mediaSource().pause(thePauseIndicator); } @@ -961,8 +963,7 @@ void handleEvents() { if(!thePauseIndicator) { - // togglePause(); - cerr << "todo: Pause on minimize.\n"; + togglePause(); } } } @@ -1673,13 +1674,13 @@ int main(int argc, char* argv[]) cleanup(); } - // Get the starting time in case we need to print statistics - timeval startingTime; - gettimeofday(&startingTime, 0); + // Set up timing stuff + Uint32 before, delta, frameTime = 0, eventTime = 0; + Uint32 timePerFrame = 1000000 / theDesiredFrameRate; + Uint32 numberOfFrames = 0; - uInt32 numberOfFrames = 0; - uInt32 frameTime = 1000000 / theDesiredFrameRate; - for( ; ; ++numberOfFrames) + // Main game loop + for(;;) { // Exit if the user wants to quit if(theQuitIndicator) @@ -1687,36 +1688,37 @@ int main(int argc, char* argv[]) break; } - // Remember the current time before we start drawing the frame - timeval before; - gettimeofday(&before, 0); + // Call handleEvents here to see if user pressed pause + handleEvents(); + if(thePauseIndicator) + { + updateDisplay(theConsole->mediaSource()); + SDL_Delay(10); + continue; + } + before = getTicks(); theConsole->mediaSource().update(); updateDisplay(theConsole->mediaSource()); handleEvents(); // Now, waste time if we need to so that we are at the desired frame rate - timeval after; for(;;) { - gettimeofday(&after, 0); + delta = getTicks() - before; - uInt32 delta = (uInt32)((after.tv_sec - before.tv_sec) * 1000000 + - (after.tv_usec - before.tv_usec)); - - if(delta > frameTime) + if(delta >= timePerFrame) break; -//else SDL_Delay(1); } + + frameTime += (getTicks() - before); + ++numberOfFrames; } if(theShowInfoFlag) { - timeval endingTime; - gettimeofday(&endingTime, 0); - double executionTime = (endingTime.tv_sec - startingTime.tv_sec) + - ((endingTime.tv_usec - startingTime.tv_usec) / 1000000.0); - double framesPerSecond = numberOfFrames / executionTime; + double executionTime = (double) frameTime / 1000000.0; + double framesPerSecond = (double) numberOfFrames / executionTime; cout << endl; cout << numberOfFrames << " total frames drawn\n"; @@ -1732,3 +1734,24 @@ int main(int argc, char* argv[]) // Cleanup time ... cleanup(); } + + +/** + Returns number of ticks in microseconds +*/ +#ifdef HAVE_GETTIMEOFDAY +inline uInt32 getTicks() +{ + timeval now; + gettimeofday(&now, 0); + + uInt32 ticks = now.tv_sec * 1000000 + now.tv_usec; + + return ticks; +} +#else +inline uInt32 getTicks() +{ + return SDL_GetTicks() * 1000; +} +#endif diff --git a/stella/src/ui/x11/mainX11.cxx b/stella/src/ui/x11/mainX11.cxx index 9a2171c34..fa2a27edc 100644 --- a/stella/src/ui/x11/mainX11.cxx +++ b/stella/src/ui/x11/mainX11.cxx @@ -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: mainX11.cxx,v 1.13 2002-03-12 19:27:11 stephena Exp $ +// $Id: mainX11.cxx,v 1.14 2002-03-17 19:37:00 stephena Exp $ //============================================================================ #include @@ -66,6 +66,8 @@ int theRightJoystickFd; #endif +#define HAVE_GETTIMEOFDAY + // Globals for X windows stuff Display* theDisplay; string theDisplayName = ""; @@ -99,6 +101,7 @@ void toggleFullscreen(); void takeSnapshot(); void togglePause(); uInt32 maxWindowSizeForScreen(); +uInt32 getTicks(); bool setupProperties(PropertiesSet& set); void handleCommandLineArguments(int argc, char* argv[]); @@ -686,8 +689,7 @@ void handleEvents() { if(!thePauseIndicator) { - // togglePause(); - cerr << "todo: Pause on minimize.\n"; + togglePause(); } } } @@ -922,8 +924,6 @@ void toggleFullscreen() */ void togglePause() { -// todo: implement pause functionality - if(thePauseIndicator) // emulator is already paused so continue { thePauseIndicator = false; @@ -932,6 +932,8 @@ void togglePause() { thePauseIndicator = true; } + + theConsole->mediaSource().pause(thePauseIndicator); } /** @@ -1574,13 +1576,13 @@ int main(int argc, char* argv[]) cleanup(); } - // Get the starting time in case we need to print statistics - timeval startingTime; - gettimeofday(&startingTime, 0); - + // Set up timing stuff + uInt32 before, delta, frameTime = 0, eventTime = 0; + uInt32 timePerFrame = 1000000 / theDesiredFrameRate; uInt32 numberOfFrames = 0; - uInt32 frameTime = 1000000 / theDesiredFrameRate; - for( ; ; ++numberOfFrames) + + // Main game loop + for(;;) { // Exit if the user wants to quit if(theQuitIndicator) @@ -1588,35 +1590,37 @@ int main(int argc, char* argv[]) break; } - // Remember the current time before we start drawing the frame - timeval before; - gettimeofday(&before, 0); + // Call handleEvents here to see if user pressed pause + handleEvents(); + if(thePauseIndicator) + { + updateDisplay(theConsole->mediaSource()); + usleep(10000); + continue; + } + before = getTicks(); theConsole->mediaSource().update(); updateDisplay(theConsole->mediaSource()); handleEvents(); // Now, waste time if we need to so that we are at the desired frame rate - timeval after; for(;;) { - gettimeofday(&after, 0); + delta = getTicks() - before; - uInt32 delta = (uInt32)((after.tv_sec - before.tv_sec) * 1000000 + - (after.tv_usec - before.tv_usec)); - - if(delta > frameTime) + if(delta > timePerFrame) break; } + + frameTime += (getTicks() - before); + ++numberOfFrames; } if(theShowInfoFlag) { - timeval endingTime; - gettimeofday(&endingTime, 0); - double executionTime = (endingTime.tv_sec - startingTime.tv_sec) + - ((endingTime.tv_usec - startingTime.tv_usec) / 1000000.0); - double framesPerSecond = numberOfFrames / executionTime; + double executionTime = (double) frameTime / 1000000.0; + double framesPerSecond = (double) numberOfFrames / executionTime; cout << endl; cout << numberOfFrames << " total frames drawn\n"; @@ -1633,3 +1637,20 @@ int main(int argc, char* argv[]) cleanup(); return 0; } + +/** + Returns number of ticks in microseconds +*/ +#ifdef HAVE_GETTIMEOFDAY +inline uInt32 getTicks() +{ + timeval now; + gettimeofday(&now, 0); + + uInt32 ticks = now.tv_sec * 1000000 + now.tv_usec; + + return ticks; +} +#else +#error "We need gettimeofday for the X11 version" +#endif