Added experimental timing code to the X11 and SDL versions. Now its possible

to use the emulator without hogging the CPU.  Usage on most machines I've
tested is around 1% - 2%, versus the 100% that was used before.

SDL version seems to like this new code better.  I think that usleep is
causing some problems in the X11 version.  I'd appreciate some feedback
on this.  Maybe I'll change to select or something.

There is a slight skip in framerate that can't be avoided unfortunately.
You may not even notice it.  Sound may be slightly different as well.  In
my opinion, this is a good tradeoff for basically reducing CPU usage to nil.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@50 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2002-03-20 00:03:24 +00:00
parent 47f740acdd
commit a6b74d92f0
3 changed files with 134 additions and 36 deletions

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: makefile,v 1.11 2002-03-17 19:37:00 stephena Exp $ ## $Id: makefile,v 1.12 2002-03-20 00:03:24 stephena Exp $
##============================================================================ ##============================================================================
##============================================================================ ##============================================================================
@ -57,6 +57,11 @@ OPTIMIZATIONS =
### Only X11 and SDL ports supported for now ### Only X11 and SDL ports supported for now
# SNAPSHOT_SUPPORT = 1 # SNAPSHOT_SUPPORT = 1
### to enable EXPERIMENTAL TIMING code
### Enables emulator to not use 100% CPU
### Only X11 and SDL ports supported for now
# EXPERIMENTAL_TIMING = 1
##============================================================================ ##============================================================================
## All done, type make to get a list of frontends ## All done, type make to get a list of frontends
## No configurable options below this line ... ## No configurable options below this line ...
@ -90,36 +95,41 @@ CXXFLAGS = $(OPTIMIZATIONS) $(INCLUDES) $(SYS_INCLUDES)
## set the user-defined options ## set the user-defined options
ifdef BSPF_BOOL ifdef BSPF_BOOL
OPTS.X11 += -DBSPF_BOOL OPTS.X11 += -DBSPF_BOOL=1
OPTS.DOS += -DBSPF_BOOL OPTS.DOS += -DBSPF_BOOL=1
endif endif
ifdef SHOW_TIMING ifdef SHOW_TIMING
OPTS.X11 += -DSHOW_TIMING OPTS.X11 += -DSHOW_TIMING=1
OPTS.SDL += -DSHOW_TIMING OPTS.SDL += -DSHOW_TIMING=1
OPTS.DOS += -DSHOW_TIMING OPTS.DOS += -DSHOW_TIMING=1
endif endif
ifdef DEBUG ifdef DEBUG
OPTS.X11 += -DDEBUG OPTS.X11 += -DDEBUG=1
OPTS.SDL += -DDEBUG OPTS.SDL += -DDEBUG=1
OPTS.DOS += -DDEBUG OPTS.DOS += -DDEBUG=1
endif endif
ifdef LINUX_JOYSTICK ifdef LINUX_JOYSTICK
OPTS.X11 += -DLINUX_JOYSTICK OPTS.X11 += -DLINUX_JOYSTICK=1
endif endif
ifdef SNAPSHOT_SUPPORT ifdef SNAPSHOT_SUPPORT
OBJS.X11 += Snapshot.o OBJS.X11 += Snapshot.o
OPTS.X11 += -DHAVE_PNG -I$(UI)/common OPTS.X11 += -DHAVE_PNG=1 -I$(UI)/common
LIBS.X11 += -lpng LIBS.X11 += -lpng
OBJS.SDL += Snapshot.o OBJS.SDL += Snapshot.o
OPTS.SDL += -DHAVE_PNG -I$(UI)/common OPTS.SDL += -DHAVE_PNG=1 -I$(UI)/common
LIBS.SDL += -lpng LIBS.SDL += -lpng
endif endif
ifdef EXPERIMENTAL_TIMING
OPTS.X11 += -DEXPERIMENTAL_TIMING=1
OPTS.SDL += -DEXPERIMENTAL_TIMING=1
endif
default: default:
@echo "" @echo ""
@echo "To build Stella type: 'make <version>'" @echo "To build Stella type: 'make <version>'"
@ -142,7 +152,7 @@ dos:
LD="gxx" \ LD="gxx" \
CXX="gcc" \ CXX="gcc" \
INCLUDES="$(INCLUDES) -I$(UI)/dos -I$(UI)/sound" \ INCLUDES="$(INCLUDES) -I$(UI)/dos -I$(UI)/sound" \
OPTIONS="-DBSPF_DOS" \ OPTIONS="-DBSPF_DOS=1" \
OPTIONS+="$(OPTS.DOS)" \ OPTIONS+="$(OPTS.DOS)" \
LDFLAGS="" \ LDFLAGS="" \
LDLIBS="" \ LDLIBS="" \
@ -152,7 +162,7 @@ unix-x:
make stella.x11 \ make stella.x11 \
INCLUDES="$(INCLUDES) -I$(UI)/x11 -I$(UI)/sound" \ INCLUDES="$(INCLUDES) -I$(UI)/x11 -I$(UI)/sound" \
SYS_INCLUDES="" \ SYS_INCLUDES="" \
OPTIONS="-DBSPF_UNIX" \ OPTIONS="-DBSPF_UNIX=1" \
OPTIONS+="$(OPTS.X11)" \ OPTIONS+="$(OPTS.X11)" \
LDFLAGS="-L/usr/X11R6/lib" \ LDFLAGS="-L/usr/X11R6/lib" \
LDFLAGS+="$(CFLAGS.X11)" \ LDFLAGS+="$(CFLAGS.X11)" \
@ -164,7 +174,7 @@ linux-x:
make stella.x11 \ make stella.x11 \
INCLUDES="$(INCLUDES) -I$(UI)/x11 -I$(UI)/sound" \ INCLUDES="$(INCLUDES) -I$(UI)/x11 -I$(UI)/sound" \
SYS_INCLUDES="" \ SYS_INCLUDES="" \
OPTIONS="-DBSPF_UNIX" \ OPTIONS="-DBSPF_UNIX=1" \
OPTIONS+="$(OPTS.X11)" \ OPTIONS+="$(OPTS.X11)" \
LDFLAGS="-L/usr/X11R6/lib" \ LDFLAGS="-L/usr/X11R6/lib" \
LDFLAGS+="$(CFLAGS.X11)" \ LDFLAGS+="$(CFLAGS.X11)" \
@ -177,7 +187,7 @@ linux-sdl:
make stella.sdl \ make stella.sdl \
INCLUDES="$(INCLUDES) -I$(UI)/sdl -I$(UI)/sound" \ INCLUDES="$(INCLUDES) -I$(UI)/sdl -I$(UI)/sound" \
SYS_INCLUDES="" \ SYS_INCLUDES="" \
OPTIONS="-DBSPF_UNIX" \ OPTIONS="-DBSPF_UNIX=1" \
OPTIONS+="$(OPTS.SDL)" \ OPTIONS+="$(OPTS.SDL)" \
LDFLAGS="-L/usr/X11R6/lib" \ LDFLAGS="-L/usr/X11R6/lib" \
LDFLAGS+="$(CFLAGS.SDL)" \ LDFLAGS+="$(CFLAGS.SDL)" \
@ -189,7 +199,7 @@ bsdi-x:
make stella.x11 \ make stella.x11 \
INCLUDES="$(INCLUDES) -I$(UI)/x11 -I$(UI)/sound" \ INCLUDES="$(INCLUDES) -I$(UI)/x11 -I$(UI)/sound" \
SYS_INCLUDES="-I/usr/X11R6/include" \ SYS_INCLUDES="-I/usr/X11R6/include" \
OPTIONS="-DBSPF_UNIX" \ OPTIONS="-DBSPF_UNIX=1" \
OPTIONS+="$(OPTS.X11)" \ OPTIONS+="$(OPTS.X11)" \
LDFLAGS="-L/usr/X11R6/lib" \ LDFLAGS="-L/usr/X11R6/lib" \
LDFLAGS+="$(CFLAGS.X11)" \ LDFLAGS+="$(CFLAGS.X11)" \
@ -201,7 +211,7 @@ solaris-x:
make stella.x11 \ make stella.x11 \
INCLUDES="$(INCLUDES) -I$(UI)/x11 -I$(UI)/sound" \ INCLUDES="$(INCLUDES) -I$(UI)/x11 -I$(UI)/sound" \
SYS_INCLUDES="-I/usr/openwin/include" \ SYS_INCLUDES="-I/usr/openwin/include" \
OPTIONS="-DBSPF_UNIX" \ OPTIONS="-DBSPF_UNIX=1" \
OPTIONS+="$(OPTS.X11)" \ OPTIONS+="$(OPTS.X11)" \
LDFLAGS="-L/usr/openwin/lib" \ LDFLAGS="-L/usr/openwin/lib" \
LDFLAGS+="$(CFLAGS.X11)" \ LDFLAGS+="$(CFLAGS.X11)" \

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: mainSDL.cxx,v 1.13 2002-03-17 19:37:00 stephena Exp $ // $Id: mainSDL.cxx,v 1.14 2002-03-20 00:03:24 stephena Exp $
//============================================================================ //============================================================================
#include <fstream> #include <fstream>
@ -1674,10 +1674,54 @@ int main(int argc, char* argv[])
cleanup(); cleanup();
} }
#ifdef EXPERIMENTAL_TIMING
// Set up timing stuff // Set up timing stuff
Uint32 before, delta, frameTime = 0, eventTime = 0; uInt32 startTime, frameTime, virtualTime, currentTime;
Uint32 timePerFrame = 1000000 / theDesiredFrameRate; uInt32 numberOfFrames = 0;
Uint32 numberOfFrames = 0; uInt32 timePerFrame = (uInt32) (1000000.0 / (double) theDesiredFrameRate);
// Set the base for the timers
virtualTime = getTicks();
frameTime = 0;
// Main game loop
for(;;)
{
// Exit if the user wants to quit
if(theQuitIndicator)
{
break;
}
startTime = getTicks();
if(!thePauseIndicator)
{
theConsole->mediaSource().update();
}
updateDisplay(theConsole->mediaSource());
handleEvents();
currentTime = getTicks();
virtualTime += timePerFrame;
if(currentTime < virtualTime)
{
SDL_Delay((virtualTime - currentTime)/1000);
}
currentTime = getTicks() - startTime;
frameTime += currentTime;
++numberOfFrames;
// cerr << "FPS = " << (double) numberOfFrames / ((double) frameTime / 1000000.0) << endl;
}
#else
// Set up timing stuff
uInt32 startTime, frameTime, delta;
uInt32 numberOfFrames = 0;
uInt32 timePerFrame = (uInt32) (1000000.0 / (double) theDesiredFrameRate);
// Set the base for the timers
frameTime = 0;
// Main game loop // Main game loop
for(;;) for(;;)
@ -1697,7 +1741,7 @@ int main(int argc, char* argv[])
continue; continue;
} }
before = getTicks(); startTime = getTicks();
theConsole->mediaSource().update(); theConsole->mediaSource().update();
updateDisplay(theConsole->mediaSource()); updateDisplay(theConsole->mediaSource());
handleEvents(); handleEvents();
@ -1705,15 +1749,16 @@ int main(int argc, char* argv[])
// Now, waste time if we need to so that we are at the desired frame rate // Now, waste time if we need to so that we are at the desired frame rate
for(;;) for(;;)
{ {
delta = getTicks() - before; delta = getTicks() - startTime;
if(delta >= timePerFrame) if(delta >= timePerFrame)
break; break;
} }
frameTime += (getTicks() - before); frameTime += getTicks() - startTime;
++numberOfFrames; ++numberOfFrames;
} }
#endif
if(theShowInfoFlag) if(theShowInfoFlag)
{ {
@ -1745,13 +1790,11 @@ inline uInt32 getTicks()
timeval now; timeval now;
gettimeofday(&now, 0); gettimeofday(&now, 0);
uInt32 ticks = now.tv_sec * 1000000 + now.tv_usec; return (uInt32) (now.tv_sec * 1000000 + now.tv_usec);
return ticks;
} }
#else #else
inline uInt32 getTicks() inline uInt32 getTicks()
{ {
return SDL_GetTicks() * 1000; return (uInt32) SDL_GetTicks() * 1000;
} }
#endif #endif

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: mainX11.cxx,v 1.14 2002-03-17 19:37:00 stephena Exp $ // $Id: mainX11.cxx,v 1.15 2002-03-20 00:03:24 stephena Exp $
//============================================================================ //============================================================================
#include <fstream> #include <fstream>
@ -1576,10 +1576,54 @@ int main(int argc, char* argv[])
cleanup(); cleanup();
} }
#ifdef EXPERIMENTAL_TIMING
// Set up timing stuff // Set up timing stuff
uInt32 before, delta, frameTime = 0, eventTime = 0; uInt32 startTime, frameTime, virtualTime, currentTime;
uInt32 timePerFrame = 1000000 / theDesiredFrameRate;
uInt32 numberOfFrames = 0; uInt32 numberOfFrames = 0;
uInt32 timePerFrame = (uInt32) (1000000.0 / (double) theDesiredFrameRate);
// Set the base for the timers
virtualTime = getTicks();
frameTime = 0;
// Main game loop
for(;;)
{
// Exit if the user wants to quit
if(theQuitIndicator)
{
break;
}
startTime = getTicks();
if(!thePauseIndicator)
{
theConsole->mediaSource().update();
}
updateDisplay(theConsole->mediaSource());
handleEvents();
currentTime = getTicks();
virtualTime += timePerFrame;
if(currentTime < virtualTime)
{
usleep(virtualTime - currentTime);
}
currentTime = getTicks() - startTime;
frameTime += currentTime;
++numberOfFrames;
// cerr << "FPS = " << (double) numberOfFrames / ((double) frameTime / 1000000.0) << endl;
}
#else
// Set up timing stuff
uInt32 startTime, frameTime, delta;
uInt32 numberOfFrames = 0;
uInt32 timePerFrame = (uInt32) (1000000.0 / (double) theDesiredFrameRate);
// Set the base for the timers
frameTime = 0;
// Main game loop // Main game loop
for(;;) for(;;)
@ -1599,7 +1643,7 @@ int main(int argc, char* argv[])
continue; continue;
} }
before = getTicks(); startTime = getTicks();
theConsole->mediaSource().update(); theConsole->mediaSource().update();
updateDisplay(theConsole->mediaSource()); updateDisplay(theConsole->mediaSource());
handleEvents(); handleEvents();
@ -1607,15 +1651,16 @@ int main(int argc, char* argv[])
// Now, waste time if we need to so that we are at the desired frame rate // Now, waste time if we need to so that we are at the desired frame rate
for(;;) for(;;)
{ {
delta = getTicks() - before; delta = getTicks() - startTime;
if(delta > timePerFrame) if(delta >= timePerFrame)
break; break;
} }
frameTime += (getTicks() - before); frameTime += getTicks() - startTime;
++numberOfFrames; ++numberOfFrames;
} }
#endif
if(theShowInfoFlag) if(theShowInfoFlag)
{ {