Added 'WINDOWED_SUPPORT' compile-time argument, which can be used for

those systems which don't actually have a windowing environment.  When
this is set, toggling from fullscreen will not be possible, and certain
window-related UI functions will not be accessible.

Completely revamped video subsystem.  Windowed and fullscreen modes are
now dealt with separately.  Windows can be zoomed using the 'zoom_ui'
and 'zoom_tia' arguments.  Fullscreen modes are now set by resolution,
not zoom, so you can specify to always use a certain fullscreen
resolution, and the images will be scaled appropriately.  This also
fixes the fullscreen issues on widescreen monitors; just select a
widescreen video mode, and the aspect ratio will always be correct.

Removed dirty-rect support for software rendering of the TIA image,
as it ended up being slower than just updating the entire image.
For those resolutions where it will start to slow down (1024x768 or
higher), one should be using OpenGL.

Fixed issue in Windows when returning from fullscreen mode made the
window constantly 'shrink' in size.  It was related to auto-detecting
the desktop resolution, which is really the job of SDL.  As such, all
further releases of Stella will require SDL 1.2.10, which includes
this auto-detection code internally.

Made ROM launcher resizable, configurable in sizes from 320x240
to 800x600.  Updated the UIDialog to change these quantities from the
UI (Stella will need to be restarted for it to take effect).

Removed aspect ratio support, since it was causing problems, and the
new fullscreen mode work has made it obsolete.  i *may* consider it
again in the future, if there's sufficient demand.

Added 'fullres' commandline argument, used to set the fullscreen
resolution.

Added 'launcherres' commandline argument, used to set the ROM
launcher resolution.  This replaces 'launchersize' argument, which
has been removed.

Changed 'scale_ui' and 'scale_tia' to 'zoom_ui' and 'zoom_tia',
respectively.  Their function remains the same.

Changed meaning of 'gl_fsmax' argument to specify what modes to use
fullscreen OpenGL scaling (previously, this was a boolean, and
didn't consider different modes).


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1323 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2007-06-20 16:33:23 +00:00
parent 317648f37d
commit 6abcac4597
39 changed files with 1047 additions and 2131 deletions

18
stella/configure vendored
View File

@ -19,6 +19,7 @@ _zlib=auto
# default option behaviour yes/no # default option behaviour yes/no
_build_gl=yes _build_gl=yes
_build_windowed=yes
_build_sound=yes _build_sound=yes
_build_debugger=yes _build_debugger=yes
_build_snapshot=yes _build_snapshot=yes
@ -255,6 +256,8 @@ Installation directories:
Optional Features: Optional Features:
--enable-gl enable/disable OpenGL rendering support [enabled] --enable-gl enable/disable OpenGL rendering support [enabled]
--disable-gl --disable-gl
--enable-windowed enable/disable windowed rendering modes [enabled]
--disable-windowed
--enable-sound enable/disable sound support [enabled] --enable-sound enable/disable sound support [enabled]
--disable-sound --disable-sound
--enable-debugger enable/disable all debugger options [enabled] --enable-debugger enable/disable all debugger options [enabled]
@ -298,6 +301,8 @@ for ac_option in $@; do
case "$ac_option" in case "$ac_option" in
--enable-gl) _build_gl=yes ;; --enable-gl) _build_gl=yes ;;
--disable-gl) _build_gl=no ;; --disable-gl) _build_gl=no ;;
--enable-windowed) _build_windowed=yes ;;
--disable-windowed) _build_windowed=no ;;
--enable-sound) _build_sound=yes ;; --enable-sound) _build_sound=yes ;;
--disable-sound) _build_sound=no ;; --disable-sound) _build_sound=no ;;
--enable-debugger) _build_debugger=yes ;; --enable-debugger) _build_debugger=yes ;;
@ -538,6 +543,7 @@ if test -n "$_host"; then
echo "Cross-compiling to $_host, forcing static build, and disabling OpenGL." echo "Cross-compiling to $_host, forcing static build, and disabling OpenGL."
_build_static=yes _build_static=yes
_build_gl=no _build_gl=no
_build_windowed=no
;; ;;
*) *)
echo "Cross-compiling to unknown target, please add your target to configure." echo "Cross-compiling to unknown target, please add your target to configure."
@ -689,6 +695,14 @@ else
echo echo
fi fi
if test "$_build_windowed" = "yes" ; then
echo_n " Windowed rendering modes enabled"
echo
else
echo_n " Windowed rendering modes disabled"
echo
fi
if test "$_build_sound" = "yes" ; then if test "$_build_sound" = "yes" ; then
echo_n " Sound support enabled" echo_n " Sound support enabled"
echo echo
@ -852,6 +866,10 @@ if test "$_build_gl" = yes ; then
DEFINES="$DEFINES -DDISPLAY_OPENGL" DEFINES="$DEFINES -DDISPLAY_OPENGL"
fi fi
if test "$_build_windowed" = yes ; then
DEFINES="$DEFINES -DWINDOWED_SUPPORT"
fi
if test "$_build_sound" = yes ; then if test "$_build_sound" = yes ; then
DEFINES="$DEFINES -DSOUND_SUPPORT" DEFINES="$DEFINES -DSOUND_SUPPORT"
fi fi

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: FrameBufferGL.cxx,v 1.86 2007-01-15 00:07:51 stephena Exp $ // $Id: FrameBufferGL.cxx,v 1.87 2007-06-20 16:33:22 stephena Exp $
//============================================================================ //============================================================================
#ifdef DISPLAY_OPENGL #ifdef DISPLAY_OPENGL
@ -88,11 +88,8 @@ FrameBufferGL::FrameBufferGL(OSystem* osystem)
: FrameBuffer(osystem), : FrameBuffer(osystem),
myTexture(NULL), myTexture(NULL),
myHaveTexRectEXT(false), myHaveTexRectEXT(false),
myScreenmode(0),
myScreenmodeCount(0),
myFilterParamName("GL_NEAREST"), myFilterParamName("GL_NEAREST"),
myZoomLevel(1), myScaleFactor(1.0),
myFSScaleFactor(1.0),
myDirtyFlag(true) myDirtyFlag(true)
{ {
} }
@ -186,7 +183,7 @@ bool FrameBufferGL::loadFuncs(const string& library)
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool FrameBufferGL::initSubsystem() bool FrameBufferGL::initSubsystem(VideoMode mode)
{ {
mySDLFlags |= SDL_OPENGL; mySDLFlags |= SDL_OPENGL;
@ -207,15 +204,8 @@ bool FrameBufferGL::initSubsystem()
break; break;
} }
// Get the valid OpenGL screenmodes
myScreenmodeCount = 0;
myScreenmode = SDL_ListModes(NULL, SDL_FULLSCREEN|SDL_OPENGL);
if((myScreenmode != (SDL_Rect**) -1) && (myScreenmode != (SDL_Rect**) 0))
for(uInt32 i = 0; myScreenmode[i]; ++i)
myScreenmodeCount++;
// Create the screen // Create the screen
if(!createScreen()) if(!setVidMode(mode))
return false; return false;
// Now check to see what color components were actually created // Now check to see what color components were actually created
@ -248,22 +238,55 @@ string FrameBufferGL::about()
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferGL::setAspectRatio() bool FrameBufferGL::setVidMode(VideoMode mode)
{ {
theAspectRatio = myOSystem->settings().getFloat("gl_aspect") / 2; myScreenDim.x = myScreenDim.y = 0;
if(theAspectRatio <= 0.0) myScreenDim.w = mode.screen_w;
theAspectRatio = 1.0; myScreenDim.h = mode.screen_h;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - myImageDim.x = mode.image_x;
void FrameBufferGL::setScaler(Scaler scaler) myImageDim.y = mode.image_y;
{ myImageDim.w = mode.image_w;
myZoomLevel = scaler.zoom; myImageDim.h = mode.image_h;
}
// Activate stretching if its been requested and it makes sense to do so
myScaleFactor = 1.0;
if(fullScreen() && (mode.image_w < mode.screen_w) &&
(mode.image_h < mode.screen_h))
{
const string& gl_fsmax = myOSystem->settings().getString("gl_fsmax");
bool inUIMode =
myOSystem->eventHandler().state() == EventHandler::S_LAUNCHER ||
myOSystem->eventHandler().state() == EventHandler::S_DEBUGGER;
// Only stretch in certain modes
if((gl_fsmax == "always") ||
(inUIMode && gl_fsmax == "ui") ||
(!inUIMode && gl_fsmax == "tia"))
{
float scaleX = float(myImageDim.w) / myScreenDim.w;
float scaleY = float(myImageDim.h) / myScreenDim.h;
if(scaleX > scaleY)
myScaleFactor = float(myScreenDim.w) / myImageDim.w;
else
myScaleFactor = float(myScreenDim.h) / myImageDim.h;
myImageDim.w = (Uint16) (myScaleFactor * myImageDim.w);
myImageDim.h = (Uint16) (myScaleFactor * myImageDim.h);
myImageDim.x = (myScreenDim.w - myImageDim.w) / 2;
myImageDim.y = (myScreenDim.h - myImageDim.h) / 2;
}
}
// Combine the zoom level and scaler into one quantity
myScaleFactor *= (float) mode.zoom;
GLdouble orthoWidth = (GLdouble)
(myImageDim.w / myScaleFactor);
GLdouble orthoHeight = (GLdouble)
(myImageDim.h / myScaleFactor);
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool FrameBufferGL::createScreen()
{
SDL_GL_SetAttribute( SDL_GL_RED_SIZE, myRGB[0] ); SDL_GL_SetAttribute( SDL_GL_RED_SIZE, myRGB[0] );
SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, myRGB[1] ); SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, myRGB[1] );
SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, myRGB[2] ); SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, myRGB[2] );
@ -276,11 +299,6 @@ bool FrameBufferGL::createScreen()
int vsync = myOSystem->settings().getBool("gl_vsync") ? 1 : 0; int vsync = myOSystem->settings().getBool("gl_vsync") ? 1 : 0;
SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL, vsync ); SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL, vsync );
// Set the screen coordinates
GLdouble orthoWidth = 0.0;
GLdouble orthoHeight = 0.0;
setDimensions(&orthoWidth, &orthoHeight);
// Create screen containing GL context // Create screen containing GL context
myScreen = SDL_SetVideoMode(myScreenDim.w, myScreenDim.h, 0, mySDLFlags); myScreen = SDL_SetVideoMode(myScreenDim.w, myScreenDim.h, 0, mySDLFlags);
if(myScreen == NULL) if(myScreen == NULL)
@ -291,7 +309,7 @@ bool FrameBufferGL::createScreen()
// Check for some extensions that can potentially speed up operation // Check for some extensions that can potentially speed up operation
const char* extensions = (const char *) p_glGetString(GL_EXTENSIONS); const char* extensions = (const char *) p_glGetString(GL_EXTENSIONS);
myHaveTexRectEXT = strstr(extensions, "ARB_texture_rectangle") != NULL; myHaveTexRectEXT = strstr(extensions, "ARB_texture_rectangle") != NULL;
// Initialize GL display // Initialize GL display
p_glViewport(myImageDim.x, myImageDim.y, myImageDim.w, myImageDim.h); p_glViewport(myImageDim.x, myImageDim.y, myImageDim.w, myImageDim.h);
@ -544,11 +562,11 @@ void FrameBufferGL::drawBitmap(uInt32* bitmap, Int32 tx, Int32 ty,
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferGL::translateCoords(Int32* x, Int32* y) void FrameBufferGL::translateCoords(Int32& x, Int32& y)
{ {
// Wow, what a mess :) // Wow, what a mess :)
*x = (Int32) (((*x - myImageDim.x) / (myZoomLevel * myFSScaleFactor * theAspectRatio))); x = (Int32) ((x - myImageDim.x) / myScaleFactor);
*y = (Int32) (((*y - myImageDim.y) / (myZoomLevel * myFSScaleFactor))); y = (Int32) ((y - myImageDim.y) / myScaleFactor);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -666,112 +684,6 @@ bool FrameBufferGL::createTextures()
return true; return true;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferGL::setDimensions(GLdouble* orthoWidth, GLdouble* orthoHeight)
{
// We always know the initial image width and height
// We have to determine final image dimensions as well as screen dimensions
myImageDim.x = 0;
myImageDim.y = 0;
myImageDim.w = (Uint16) (myBaseDim.w * myZoomLevel * theAspectRatio);
myImageDim.h = (Uint16) (myBaseDim.h * myZoomLevel);
myScreenDim = myImageDim;
myFSScaleFactor = 1.0f;
// Determine if we're in fullscreen or windowed mode
// In fullscreen mode, we clip the SDL screen to known resolutions
// In windowed mode, we use the actual image resolution for the SDL screen
if(mySDLFlags & SDL_FULLSCREEN)
{
float scaleX = 0.0f;
float scaleY = 0.0f;
// When in a fullscreen, most text mode, attempt to do 'nice' scaling
// This means scaling will only use integral values (1, 2, 3, ...)
bool gl_fsmax = myOSystem->settings().getBool("gl_fsmax");
bool nicescale = myOSystem->eventHandler().state() == EventHandler::S_LAUNCHER ||
myOSystem->eventHandler().state() == EventHandler::S_DEBUGGER;
if(gl_fsmax && myDesktopDim.w != 0 && myDesktopDim.h != 0)
{
// Use the largest available screen size
myScreenDim.w = myDesktopDim.w;
myScreenDim.h = myDesktopDim.h;
scaleX = float(myImageDim.w) / myScreenDim.w;
scaleY = float(myImageDim.h) / myScreenDim.h;
if(scaleX > scaleY)
myFSScaleFactor = float(myScreenDim.w) / myImageDim.w;
else
myFSScaleFactor = float(myScreenDim.h) / myImageDim.h;
if(nicescale)
myFSScaleFactor = (int)myFSScaleFactor;
myImageDim.w = (Uint16) (myFSScaleFactor * myImageDim.w);
myImageDim.h = (Uint16) (myFSScaleFactor * myImageDim.h);
}
else if(gl_fsmax && myScreenmode != (SDL_Rect**) -1)
{
// Use the largest available screen size
myScreenDim.w = myScreenmode[0]->w;
myScreenDim.h = myScreenmode[0]->h;
scaleX = float(myImageDim.w) / myScreenDim.w;
scaleY = float(myImageDim.h) / myScreenDim.h;
if(scaleX > scaleY)
myFSScaleFactor = float(myScreenDim.w) / myImageDim.w;
else
myFSScaleFactor = float(myScreenDim.h) / myImageDim.h;
if(nicescale)
myFSScaleFactor = (int)myFSScaleFactor;
myImageDim.w = (Uint16) (myFSScaleFactor * myImageDim.w);
myImageDim.h = (Uint16) (myFSScaleFactor * myImageDim.h);
}
else if(myScreenmode == (SDL_Rect**) -1)
{
// All modes are available, so use the exact image resolution
myScreenDim.w = myImageDim.w;
myScreenDim.h = myImageDim.h;
}
else // otherwise, search for a valid screenmode
{
for(uInt32 i = myScreenmodeCount-1; i >= 0; i--)
{
if(myImageDim.w <= myScreenmode[i]->w && myImageDim.h <= myScreenmode[i]->h)
{
myScreenDim.w = myScreenmode[i]->w;
myScreenDim.h = myScreenmode[i]->h;
break;
}
}
}
// Now calculate the OpenGL coordinates
myImageDim.x = (myScreenDim.w - myImageDim.w) / 2;
myImageDim.y = (myScreenDim.h - myImageDim.h) / 2;
*orthoWidth = (GLdouble) (myImageDim.w / (myZoomLevel * theAspectRatio * myFSScaleFactor));
*orthoHeight = (GLdouble) (myImageDim.h / (myZoomLevel * myFSScaleFactor));
}
else
{
*orthoWidth = (GLdouble) (myImageDim.w / (myZoomLevel * theAspectRatio));
*orthoHeight = (GLdouble) (myImageDim.h / myZoomLevel);
}
/*
cerr << "myImageDim.x = " << myImageDim.x << ", myImageDim.y = " << myImageDim.y << endl;
cerr << "myImageDim.w = " << myImageDim.w << ", myImageDim.h = " << myImageDim.h << endl;
cerr << "myScreenDim.w = " << myScreenDim.w << ", myScreenDim.h = " << myScreenDim.h << endl;
cerr << endl;
*/
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool FrameBufferGL::myFuncsLoaded = false; bool FrameBufferGL::myFuncsLoaded = false;

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: FrameBufferGL.hxx,v 1.43 2007-01-12 16:03:10 stephena Exp $ // $Id: FrameBufferGL.hxx,v 1.44 2007-06-20 16:33:22 stephena Exp $
//============================================================================ //============================================================================
#ifndef FRAMEBUFFER_GL_HXX #ifndef FRAMEBUFFER_GL_HXX
@ -36,7 +36,7 @@ class GUI::Font;
This class implements an SDL OpenGL framebuffer. This class implements an SDL OpenGL framebuffer.
@author Stephen Anthony @author Stephen Anthony
@version $Id: FrameBufferGL.hxx,v 1.43 2007-01-12 16:03:10 stephena Exp $ @version $Id: FrameBufferGL.hxx,v 1.44 2007-06-20 16:33:22 stephena Exp $
*/ */
class FrameBufferGL : public FrameBuffer class FrameBufferGL : public FrameBuffer
{ {
@ -67,7 +67,7 @@ class FrameBufferGL : public FrameBuffer
This method is called to initialize OpenGL video mode. This method is called to initialize OpenGL video mode.
Return false if any operation fails, otherwise return true. Return false if any operation fails, otherwise return true.
*/ */
virtual bool initSubsystem(); virtual bool initSubsystem(VideoMode mode);
/** /**
This method is called to query the type of the FrameBuffer. This method is called to query the type of the FrameBuffer.
@ -80,22 +80,11 @@ class FrameBufferGL : public FrameBuffer
virtual string about(); virtual string about();
/** /**
This method is called to set the aspect ratio of the screen. This method is called to change to the given video mode.
*/
virtual void setAspectRatio();
/** @param mode The mode to use for rendering the mediasource
This method is called to change to the given scaler type.
@param scaler The scaler to use for rendering the mediasource
*/ */
virtual void setScaler(Scaler scaler); virtual bool setVidMode(VideoMode mode);
/**
This method is called whenever the screen needs to be recreated.
It updates the global screen variable.
*/
virtual bool createScreen();
/** /**
Switches between the two filtering options in OpenGL. Switches between the two filtering options in OpenGL.
@ -200,7 +189,7 @@ class FrameBufferGL : public FrameBuffer
@param x X coordinate to translate @param x X coordinate to translate
@param y Y coordinate to translate @param y Y coordinate to translate
*/ */
inline virtual void translateCoords(Int32* x, Int32* y); inline virtual void translateCoords(Int32& x, Int32& y);
/** /**
This method adds a dirty rectangle This method adds a dirty rectangle
@ -221,8 +210,6 @@ class FrameBufferGL : public FrameBuffer
private: private:
bool createTextures(); bool createTextures();
void setDimensions(GLdouble* orthoWidth, GLdouble* orthoHeight);
inline uInt32 power_of_two(uInt32 input) inline uInt32 power_of_two(uInt32 input)
{ {
uInt32 value = 1; uInt32 value = 1;
@ -257,12 +244,6 @@ class FrameBufferGL : public FrameBuffer
// Optional GL extensions that may increase performance // Optional GL extensions that may increase performance
bool myHaveTexRectEXT; bool myHaveTexRectEXT;
// The possible OpenGL screenmodes to use
SDL_Rect** myScreenmode;
// The number of usable OpenGL screenmodes
uInt32 myScreenmodeCount;
// The depth of the texture buffer // The depth of the texture buffer
uInt32 myDepth; uInt32 myDepth;
@ -272,12 +253,8 @@ class FrameBufferGL : public FrameBuffer
// The name of the texture filtering to use // The name of the texture filtering to use
string myFilterParamName; string myFilterParamName;
// Used for zooming/scaling // The amount by which to scale the imagein fullscreen mode
uInt32 myZoomLevel; float myScaleFactor;
// The scaling to use in fullscreen mode
// This is separate from both zoomlevel and aspect ratio
float myFSScaleFactor;
// TODO - will be removed when textured dirty rect support is added // TODO - will be removed when textured dirty rect support is added
bool myDirtyFlag; bool myDirtyFlag;

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: FrameBufferSoft.cxx,v 1.70 2007-01-30 17:13:07 stephena Exp $ // $Id: FrameBufferSoft.cxx,v 1.71 2007-06-20 16:33:22 stephena Exp $
//============================================================================ //============================================================================
#include <sstream> #include <sstream>
@ -32,10 +32,10 @@
FrameBufferSoft::FrameBufferSoft(OSystem* osystem) FrameBufferSoft::FrameBufferSoft(OSystem* osystem)
: FrameBuffer(osystem), : FrameBuffer(osystem),
myZoomLevel(1), myZoomLevel(1),
myRenderType(kDirtyRect), myRenderType(kSoftZoom_16),
myUseDirtyRects(true), myDirtyFlag(false),
myRectList(NULL), myInUIMode(false),
myOverlayRectList(NULL) myRectList(NULL)
{ {
} }
@ -43,26 +43,23 @@ FrameBufferSoft::FrameBufferSoft(OSystem* osystem)
FrameBufferSoft::~FrameBufferSoft() FrameBufferSoft::~FrameBufferSoft()
{ {
delete myRectList; delete myRectList;
delete myOverlayRectList;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool FrameBufferSoft::initSubsystem() bool FrameBufferSoft::initSubsystem(VideoMode mode)
{ {
// Set up the rectangle list to be used in the dirty update // Set up the rectangle list to be used in the dirty update
delete myRectList; delete myRectList;
myRectList = new RectList(); myRectList = new RectList();
delete myOverlayRectList;
myOverlayRectList = new RectList();
if(!myRectList || !myOverlayRectList) if(!myRectList)
{ {
cerr << "ERROR: Unable to get memory for SDL rects" << endl; cerr << "ERROR: Unable to get memory for SDL rects" << endl;
return false; return false;
} }
// Create the screen // Create the screen
return createScreen(); return setVidMode(mode);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -86,43 +83,25 @@ string FrameBufferSoft::about()
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferSoft::setAspectRatio() bool FrameBufferSoft::setVidMode(VideoMode mode)
{
// Aspect ratio correction not yet available in software mode
theAspectRatio = 1.0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferSoft::setScaler(Scaler scaler)
{
switch(scaler.type)
{
case kZOOM1X:
case kZOOM2X:
case kZOOM3X:
case kZOOM4X:
case kZOOM5X:
case kZOOM6X:
// Software framebuffer doesn't handle the fancy scaling modes
myZoomLevel = scaler.zoom;
break;
default: // should never get here
myZoomLevel = 1;
break;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool FrameBufferSoft::createScreen()
{ {
myScreenDim.x = myScreenDim.y = 0; myScreenDim.x = myScreenDim.y = 0;
myScreenDim.w = mode.screen_w;
myScreenDim.h = mode.screen_h;
myScreenDim.w = myBaseDim.w * myZoomLevel; myImageDim.x = mode.image_x;
myScreenDim.h = myBaseDim.h * myZoomLevel; myImageDim.y = mode.image_y;
myImageDim.w = mode.image_w;
myImageDim.h = mode.image_h;
// In software mode, the image and screen dimensions are always the same myZoomLevel = mode.zoom;
myImageDim = myScreenDim;
// Make sure to clear the screen
if(myScreen)
{
SDL_FillRect(myScreen, NULL, 0);
SDL_UpdateRect(myScreen, 0, 0, 0, 0);
}
myScreen = SDL_SetVideoMode(myScreenDim.w, myScreenDim.h, 0, mySDLFlags); myScreen = SDL_SetVideoMode(myScreenDim.w, myScreenDim.h, 0, mySDLFlags);
if(myScreen == NULL) if(myScreen == NULL)
{ {
@ -134,11 +113,11 @@ bool FrameBufferSoft::createScreen()
// Make sure drawMediaSource() knows which renderer to use // Make sure drawMediaSource() knows which renderer to use
stateChanged(myOSystem->eventHandler().state()); stateChanged(myOSystem->eventHandler().state());
myBaseOffset = myImageDim.y * myPitch + myImageDim.x;
// Erase old rects, since they've probably been scaled for // Erase old rects, since they've probably been scaled for
// a different sized screen // a different sized screen
myRectList->start(); myRectList->start();
myOverlayRectList->start();
return true; return true;
} }
@ -150,164 +129,16 @@ void FrameBufferSoft::drawMediaSource()
uInt8* currentFrame = mediasrc.currentFrameBuffer(); uInt8* currentFrame = mediasrc.currentFrameBuffer();
uInt8* previousFrame = mediasrc.previousFrameBuffer(); uInt8* previousFrame = mediasrc.previousFrameBuffer();
uInt16 screenMultiple = (uInt16) myZoomLevel;
uInt32 width = mediasrc.width(); uInt32 width = mediasrc.width();
uInt32 height = mediasrc.height(); uInt32 height = mediasrc.height();
switch(myRenderType) // use switch/case, since we'll eventually have filters switch(myRenderType)
{ {
case kDirtyRect:
{
struct Rectangle
{
uInt8 color;
uInt16 x, y, width, height;
} rectangles[2][160];
// This array represents the rectangles that need displaying
// on the current scanline we're processing
Rectangle* currentRectangles = rectangles[0];
// This array represents the rectangles that are still active
// from the previous scanlines we have processed
Rectangle* activeRectangles = rectangles[1];
// Indicates the number of active rectangles
uInt16 activeCount = 0;
// This update procedure requires theWidth to be a multiple of four.
// This is validated when the properties are loaded.
for(uInt16 y = 0; y < height; ++y)
{
// Indicates the number of current rectangles
uInt16 currentCount = 0;
// Look at four pixels at a time to see if anything has changed
uInt32* current = (uInt32*)(currentFrame);
uInt32* previous = (uInt32*)(previousFrame);
for(uInt16 x = 0; x < width; x += 4, ++current, ++previous)
{
// Has something changed in this set of four pixels?
if((*current != *previous) || theRedrawTIAIndicator)
{
uInt8* c = (uInt8*)current;
uInt8* p = (uInt8*)previous;
// Look at each of the bytes that make up the uInt32
for(uInt16 i = 0; i < 4; ++i, ++c, ++p)
{
// See if this pixel has changed
if((*c != *p) || theRedrawTIAIndicator)
{
// Can we extend a rectangle or do we have to create a new one?
if((currentCount != 0) &&
(currentRectangles[currentCount - 1].color == *c) &&
((currentRectangles[currentCount - 1].x +
currentRectangles[currentCount - 1].width) == (x + i)))
{
currentRectangles[currentCount - 1].width += 1;
}
else
{
currentRectangles[currentCount].x = x + i;
currentRectangles[currentCount].y = y;
currentRectangles[currentCount].width = 1;
currentRectangles[currentCount].height = 1;
currentRectangles[currentCount].color = *c;
currentCount++;
}
}
}
}
}
// Merge the active and current rectangles flushing any that are of no use
uInt16 activeIndex = 0;
for(uInt16 t = 0; (t < currentCount) && (activeIndex < activeCount); ++t)
{
Rectangle& current = currentRectangles[t];
Rectangle& active = activeRectangles[activeIndex];
// Can we merge the current rectangle with an active one?
if((current.x == active.x) && (current.width == active.width) &&
(current.color == active.color))
{
current.y = active.y;
current.height = active.height + 1;
++activeIndex;
}
// Is it impossible for this active rectangle to be merged?
else if(current.x >= active.x)
{
// Flush the active rectangle
SDL_Rect temp;
temp.x = active.x * screenMultiple << 1;
temp.y = active.y * screenMultiple;
temp.w = active.width * screenMultiple << 1;
temp.h = active.height * screenMultiple;
myRectList->add(&temp);
SDL_FillRect(myScreen, &temp, myDefPalette[active.color]);
++activeIndex;
}
}
// Flush any remaining active rectangles
for(uInt16 s = activeIndex; s < activeCount; ++s)
{
Rectangle& active = activeRectangles[s];
SDL_Rect temp;
temp.x = active.x * screenMultiple << 1;
temp.y = active.y * screenMultiple;
temp.w = active.width * screenMultiple << 1;
temp.h = active.height * screenMultiple;
myRectList->add(&temp);
SDL_FillRect(myScreen, &temp, myDefPalette[active.color]);
}
// We can now make the current rectangles into the active rectangles
Rectangle* tmp = currentRectangles;
currentRectangles = activeRectangles;
activeRectangles = tmp;
activeCount = currentCount;
currentFrame += width;
previousFrame += width;
}
// Flush any rectangles that are still active
for(uInt16 t = 0; t < activeCount; ++t)
{
Rectangle& active = activeRectangles[t];
SDL_Rect temp;
temp.x = active.x * screenMultiple << 1;
temp.y = active.y * screenMultiple;
temp.w = active.width * screenMultiple << 1;
temp.h = active.height * screenMultiple;
myRectList->add(&temp);
SDL_FillRect(myScreen, &temp, myDefPalette[active.color]);
}
break; // kDirtyRect
}
case kSoftZoom_16: case kSoftZoom_16:
{ {
SDL_Rect temp;
temp.x = temp.y = temp.w = temp.h = 0;
myRectList->add(&temp);
SDL_LockSurface(myScreen); SDL_LockSurface(myScreen);
uInt16* buffer = (uInt16*)myScreen->pixels; uInt16* buffer = (uInt16*)myScreen->pixels + myBaseOffset;
uInt32 bufofsY = 0; uInt32 bufofsY = 0;
uInt32 screenofsY = 0; uInt32 screenofsY = 0;
for(uInt32 y = 0; y < height; ++y) for(uInt32 y = 0; y < height; ++y)
@ -331,6 +162,7 @@ void FrameBufferSoft::drawMediaSource()
buffer[pos++] = (uInt16) myDefPalette[v]; buffer[pos++] = (uInt16) myDefPalette[v];
buffer[pos++] = (uInt16) myDefPalette[v]; buffer[pos++] = (uInt16) myDefPalette[v];
} }
myDirtyFlag = true;
} }
else else
pos += xstride + xstride; pos += xstride + xstride;
@ -345,12 +177,8 @@ void FrameBufferSoft::drawMediaSource()
case kSoftZoom_24: case kSoftZoom_24:
{ {
SDL_Rect temp;
temp.x = temp.y = temp.w = temp.h = 0;
myRectList->add(&temp);
SDL_LockSurface(myScreen); SDL_LockSurface(myScreen);
uInt8* buffer = (uInt8*)myScreen->pixels; uInt8* buffer = (uInt8*)myScreen->pixels + myBaseOffset;
uInt32 bufofsY = 0; uInt32 bufofsY = 0;
uInt32 screenofsY = 0; uInt32 screenofsY = 0;
for(uInt32 y = 0; y < height; ++y) for(uInt32 y = 0; y < height; ++y)
@ -379,6 +207,7 @@ void FrameBufferSoft::drawMediaSource()
buffer[pos++] = r; buffer[pos++] = g; buffer[pos++] = b; buffer[pos++] = r; buffer[pos++] = g; buffer[pos++] = b;
buffer[pos++] = r; buffer[pos++] = g; buffer[pos++] = b; buffer[pos++] = r; buffer[pos++] = g; buffer[pos++] = b;
} }
myDirtyFlag = true;
} }
else // try to eliminate multply whereever possible else // try to eliminate multply whereever possible
pos += xstride + xstride + xstride + xstride + xstride + xstride; pos += xstride + xstride + xstride + xstride + xstride + xstride;
@ -393,12 +222,8 @@ void FrameBufferSoft::drawMediaSource()
case kSoftZoom_32: case kSoftZoom_32:
{ {
SDL_Rect temp;
temp.x = temp.y = temp.w = temp.h = 0;
myRectList->add(&temp);
SDL_LockSurface(myScreen); SDL_LockSurface(myScreen);
uInt32* buffer = (uInt32*)myScreen->pixels; uInt32* buffer = (uInt32*)myScreen->pixels + myBaseOffset;
uInt32 bufofsY = 0; uInt32 bufofsY = 0;
uInt32 screenofsY = 0; uInt32 screenofsY = 0;
for(uInt32 y = 0; y < height; ++y) for(uInt32 y = 0; y < height; ++y)
@ -422,6 +247,7 @@ void FrameBufferSoft::drawMediaSource()
buffer[pos++] = (uInt32) myDefPalette[v]; buffer[pos++] = (uInt32) myDefPalette[v];
buffer[pos++] = (uInt32) myDefPalette[v]; buffer[pos++] = (uInt32) myDefPalette[v];
} }
myDirtyFlag = true;
} }
else else
pos += xstride + xstride; pos += xstride + xstride;
@ -436,12 +262,8 @@ void FrameBufferSoft::drawMediaSource()
case kPhosphor_16: case kPhosphor_16:
{ {
SDL_Rect temp;
temp.x = temp.y = temp.w = temp.h = 0;
myRectList->add(&temp);
SDL_LockSurface(myScreen); SDL_LockSurface(myScreen);
uInt16* buffer = (uInt16*)myScreen->pixels; uInt16* buffer = (uInt16*)myScreen->pixels + myBaseOffset;
uInt32 bufofsY = 0; uInt32 bufofsY = 0;
uInt32 screenofsY = 0; uInt32 screenofsY = 0;
for(uInt32 y = 0; y < height; ++y) for(uInt32 y = 0; y < height; ++y)
@ -469,17 +291,14 @@ void FrameBufferSoft::drawMediaSource()
bufofsY += width; bufofsY += width;
} }
SDL_UnlockSurface(myScreen); SDL_UnlockSurface(myScreen);
myDirtyFlag = true;
break; // kPhosphor_16 break; // kPhosphor_16
} }
case kPhosphor_24: case kPhosphor_24:
{ {
SDL_Rect temp;
temp.x = temp.y = temp.w = temp.h = 0;
myRectList->add(&temp);
SDL_LockSurface(myScreen); SDL_LockSurface(myScreen);
uInt8* buffer = (uInt8*)myScreen->pixels; uInt8* buffer = (uInt8*)myScreen->pixels + myBaseOffset;
uInt32 bufofsY = 0; uInt32 bufofsY = 0;
uInt32 screenofsY = 0; uInt32 screenofsY = 0;
for(uInt32 y = 0; y < height; ++y) for(uInt32 y = 0; y < height; ++y)
@ -511,17 +330,14 @@ void FrameBufferSoft::drawMediaSource()
bufofsY += width; bufofsY += width;
} }
SDL_UnlockSurface(myScreen); SDL_UnlockSurface(myScreen);
myDirtyFlag = true;
break; // kPhosphor_24 break; // kPhosphor_24
} }
case kPhosphor_32: case kPhosphor_32:
{ {
SDL_Rect temp;
temp.x = temp.y = temp.w = temp.h = 0;
myRectList->add(&temp);
SDL_LockSurface(myScreen); SDL_LockSurface(myScreen);
uInt32* buffer = (uInt32*)myScreen->pixels; uInt32* buffer = (uInt32*)myScreen->pixels + myBaseOffset;
uInt32 bufofsY = 0; uInt32 bufofsY = 0;
uInt32 screenofsY = 0; uInt32 screenofsY = 0;
for(uInt32 y = 0; y < height; ++y) for(uInt32 y = 0; y < height; ++y)
@ -549,6 +365,7 @@ void FrameBufferSoft::drawMediaSource()
bufofsY += width; bufofsY += width;
} }
SDL_UnlockSurface(myScreen); SDL_UnlockSurface(myScreen);
myDirtyFlag = true;
break; // kPhosphor_32 break; // kPhosphor_32
} }
} }
@ -557,26 +374,28 @@ void FrameBufferSoft::drawMediaSource()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferSoft::preFrameUpdate() void FrameBufferSoft::preFrameUpdate()
{ {
// Start a new rectlist on each display update
myRectList->start();
// Add all previous overlay rects, then erase
SDL_Rect* dirtyOverlayRects = myOverlayRectList->rects();
for(unsigned int i = 0; i < myOverlayRectList->numRects(); ++i)
myRectList->add(&dirtyOverlayRects[i]);
myOverlayRectList->start();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferSoft::postFrameUpdate() void FrameBufferSoft::postFrameUpdate()
{ {
if(myUseDirtyRects) /*
cerr << "FrameBufferSoft::postFrameUpdate()" << endl
<< " myInUIMode: " << myInUIMode << endl
<< " myRectList->numRects(): " << myRectList->numRects() << endl
<< " myDirtyFlag: " << myDirtyFlag << endl
<< endl;
*/
if(myInUIMode && myRectList->numRects() > 0)
{
SDL_UpdateRects(myScreen, myRectList->numRects(), myRectList->rects()); SDL_UpdateRects(myScreen, myRectList->numRects(), myRectList->rects());
else if(myRectList->numRects() > 0) }
else if(myDirtyFlag || myRectList->numRects() > 0)
{ {
SDL_Flip(myScreen); SDL_Flip(myScreen);
myRectList->start(); myDirtyFlag = false;
} }
myRectList->start();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -588,11 +407,13 @@ void FrameBufferSoft::scanline(uInt32 row, uInt8* data)
uInt32 pixel = 0; uInt32 pixel = 0;
uInt8 *p, r, g, b; uInt8 *p, r, g, b;
for(Int32 x = 0; x < myScreen->w; x++) // Row will be offset by the amount the actual image is shifted down
row += myImageDim.y;
for(Int32 x = 0; x < myScreen->w; ++x)
{ {
p = (Uint8*) ((uInt8*)myScreen->pixels + // Start at top of RAM p = (Uint8*) ((uInt8*)myScreen->pixels + // Start at top of RAM
(row * myScreen->pitch) + // Go down 'row' lines (row * myScreen->pitch) + // Go down 'row' lines
(x * myBytesPerPixel)); // Go in 'x' pixels ((x + myImageDim.x) * myBytesPerPixel)); // Go in 'x' pixels
switch(myBytesPerPixel) switch(myBytesPerPixel)
{ {
@ -638,8 +459,8 @@ void FrameBufferSoft::hLine(uInt32 x, uInt32 y, uInt32 x2, int color)
SDL_Rect tmp; SDL_Rect tmp;
// Horizontal line // Horizontal line
tmp.x = x * myZoomLevel; tmp.x = myImageDim.x + x * myZoomLevel;
tmp.y = y * myZoomLevel; tmp.y = myImageDim.y + y * myZoomLevel;
tmp.w = (x2 - x + 1) * myZoomLevel; tmp.w = (x2 - x + 1) * myZoomLevel;
tmp.h = myZoomLevel; tmp.h = myZoomLevel;
SDL_FillRect(myScreen, &tmp, myDefPalette[color]); SDL_FillRect(myScreen, &tmp, myDefPalette[color]);
@ -651,8 +472,8 @@ void FrameBufferSoft::vLine(uInt32 x, uInt32 y, uInt32 y2, int color)
SDL_Rect tmp; SDL_Rect tmp;
// Vertical line // Vertical line
tmp.x = x * myZoomLevel; tmp.x = myImageDim.x + x * myZoomLevel;
tmp.y = y * myZoomLevel; tmp.y = myImageDim.y + y * myZoomLevel;
tmp.w = myZoomLevel; tmp.w = myZoomLevel;
tmp.h = (y2 - y + 1) * myZoomLevel; tmp.h = (y2 - y + 1) * myZoomLevel;
SDL_FillRect(myScreen, &tmp, myDefPalette[color]); SDL_FillRect(myScreen, &tmp, myDefPalette[color]);
@ -665,8 +486,8 @@ void FrameBufferSoft::fillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
SDL_Rect tmp; SDL_Rect tmp;
// Fill the rectangle // Fill the rectangle
tmp.x = x * myZoomLevel; tmp.x = myImageDim.x + x * myZoomLevel;
tmp.y = y * myZoomLevel; tmp.y = myImageDim.y + y * myZoomLevel;
tmp.w = w * myZoomLevel; tmp.w = w * myZoomLevel;
tmp.h = h * myZoomLevel; tmp.h = h * myZoomLevel;
SDL_FillRect(myScreen, &tmp, myDefPalette[color]); SDL_FillRect(myScreen, &tmp, myDefPalette[color]);
@ -702,7 +523,7 @@ void FrameBufferSoft::drawChar(const GUI::Font* font, uInt8 chr,
case 2: case 2:
{ {
// Get buffer position where upper-left pixel of the character will be drawn // Get buffer position where upper-left pixel of the character will be drawn
uInt16* buffer = (uInt16*) myScreen->pixels + yorig * myPitch + xorig; uInt16* buffer = (uInt16*) myScreen->pixels + myBaseOffset + yorig * myPitch + xorig;
for(int y = h; y; --y) for(int y = h; y; --y)
{ {
const uInt16 fontbuf = *tmp++; const uInt16 fontbuf = *tmp++;
@ -728,7 +549,7 @@ void FrameBufferSoft::drawChar(const GUI::Font* font, uInt8 chr,
case 3: case 3:
{ {
// Get buffer position where upper-left pixel of the character will be drawn // Get buffer position where upper-left pixel of the character will be drawn
uInt8* buffer = (uInt8*) myScreen->pixels + yorig * myPitch + xorig; uInt8* buffer = (uInt8*) myScreen->pixels + myBaseOffset + yorig * myPitch + xorig;
uInt32 pixel = myDefPalette[color]; uInt32 pixel = myDefPalette[color];
uInt8 r = (pixel & myFormat->Rmask) >> myFormat->Rshift; uInt8 r = (pixel & myFormat->Rmask) >> myFormat->Rshift;
uInt8 g = (pixel & myFormat->Gmask) >> myFormat->Gshift; uInt8 g = (pixel & myFormat->Gmask) >> myFormat->Gshift;
@ -763,7 +584,7 @@ void FrameBufferSoft::drawChar(const GUI::Font* font, uInt8 chr,
case 4: case 4:
{ {
// Get buffer position where upper-left pixel of the character will be drawn // Get buffer position where upper-left pixel of the character will be drawn
uInt32* buffer = (uInt32*) myScreen->pixels + yorig * myPitch + xorig; uInt32* buffer = (uInt32*) myScreen->pixels + myBaseOffset + yorig * myPitch + xorig;
for(int y = h; y; --y) for(int y = h; y; --y)
{ {
const uInt16 fontbuf = *tmp++; const uInt16 fontbuf = *tmp++;
@ -805,8 +626,8 @@ void FrameBufferSoft::drawBitmap(uInt32* bitmap, Int32 xorig, Int32 yorig,
{ {
if(bitmap[y] & mask) if(bitmap[y] & mask)
{ {
rect.x = (x + xorig) * myZoomLevel; rect.x = myImageDim.x + (x + xorig) * myZoomLevel;
rect.y = (y + yorig) * myZoomLevel; rect.y = myImageDim.y + (y + yorig) * myZoomLevel;
rect.w = rect.h = myZoomLevel; rect.w = rect.h = myZoomLevel;
SDL_FillRect(myScreen, &rect, myDefPalette[color]); SDL_FillRect(myScreen, &rect, myDefPalette[color]);
} }
@ -815,27 +636,24 @@ void FrameBufferSoft::drawBitmap(uInt32* bitmap, Int32 xorig, Int32 yorig,
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferSoft::translateCoords(Int32* x, Int32* y) void FrameBufferSoft::translateCoords(Int32& x, Int32& y)
{ {
// We don't bother checking offsets or aspect ratios, since x = (x - myImageDim.x) / myZoomLevel;
// they're not yet supported in software mode. y = (y - myImageDim.y) / myZoomLevel;
*x /= myZoomLevel;
*y /= myZoomLevel;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferSoft::addDirtyRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h) void FrameBufferSoft::addDirtyRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h)
{ {
// Add a dirty rect to the overlay rectangle list // Add a dirty rect to the UI rectangle list
// They will actually be added to the main rectlist in preFrameUpdate()
// TODO - intelligent merging of rectangles, to avoid overlap // TODO - intelligent merging of rectangles, to avoid overlap
SDL_Rect temp; SDL_Rect temp;
temp.x = x * myZoomLevel; temp.x = myImageDim.x + x * myZoomLevel;
temp.y = y * myZoomLevel; temp.y = myImageDim.y + y * myZoomLevel;
temp.w = w * myZoomLevel; temp.w = w * myZoomLevel;
temp.h = h * myZoomLevel; temp.h = h * myZoomLevel;
myOverlayRectList->add(&temp); myRectList->add(&temp);
// cerr << "addDirtyRect(): " // cerr << "addDirtyRect(): "
// << "x=" << temp.x << ", y=" << temp.y << ", w=" << temp.w << ", h=" << temp.h << endl; // << "x=" << temp.x << ", y=" << temp.y << ", w=" << temp.w << ", h=" << temp.h << endl;
@ -856,60 +674,38 @@ void FrameBufferSoft::stateChanged(EventHandler::State state)
if(!myScreen) if(!myScreen)
return; return;
// When in a UI mode, always use dirty rects myInUIMode = (state == EventHandler::S_LAUNCHER ||
// Otherwise, check the 'dirtyrects' setting state == EventHandler::S_DEBUGGER);
// Phosphor mode implies a full update, so turn off dirty rects
bool emulation = (state == EventHandler::S_EMULATE ||
state == EventHandler::S_PAUSE);
if(emulation)
{
if(myUsePhosphor)
myUseDirtyRects = false;
else
myUseDirtyRects = myOSystem->settings().getBool("dirtyrects");
}
else
myUseDirtyRects = true;
// Make sure drawMediaSource() knows which renderer to use // Make sure drawMediaSource() knows which renderer to use
// Testing for dirty rects takes priority over phosphor mode,
// since phosphor mode only exists while emulating a ROM
switch(myBytesPerPixel) switch(myBytesPerPixel)
{ {
case 2: // 16-bit case 2: // 16-bit
myPitch = myScreen->pitch/2; myPitch = myScreen->pitch/2;
if(myUsePhosphor && emulation) if(myUsePhosphor)
myRenderType = kPhosphor_16; myRenderType = kPhosphor_16;
else if(myUseDirtyRects)
myRenderType = kDirtyRect;
else else
myRenderType = kSoftZoom_16; myRenderType = kSoftZoom_16;
break; break;
case 3: // 24-bit case 3: // 24-bit
myPitch = myScreen->pitch; myPitch = myScreen->pitch;
if(myUsePhosphor && emulation) if(myUsePhosphor)
myRenderType = kPhosphor_24; myRenderType = kPhosphor_24;
else if(myUseDirtyRects)
myRenderType = kDirtyRect;
else else
myRenderType = kSoftZoom_24; myRenderType = kSoftZoom_24;
break; break;
case 4: // 32-bit case 4: // 32-bit
myPitch = myScreen->pitch/4; myPitch = myScreen->pitch/4;
if(myUsePhosphor && emulation) if(myUsePhosphor)
myRenderType = kPhosphor_32; myRenderType = kPhosphor_32;
else if(myUseDirtyRects)
myRenderType = kDirtyRect;
else else
myRenderType = kSoftZoom_32; myRenderType = kSoftZoom_32;
break; break;
default: default:
myRenderType = kDirtyRect; // What else should we do here? myRenderType = kSoftZoom_16; // What else should we do here?
break; break;
} }
// Have the changes take effect // Have the changes take effect
myOSystem->eventHandler().refreshDisplay(); myOSystem->eventHandler().refreshDisplay();
//cerr << "Render type = " << myRenderType << ", dirty rects = " << myUseDirtyRects << endl;
} }

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: FrameBufferSoft.hxx,v 1.45 2007-01-15 00:07:51 stephena Exp $ // $Id: FrameBufferSoft.hxx,v 1.46 2007-06-20 16:33:22 stephena Exp $
//============================================================================ //============================================================================
#ifndef FRAMEBUFFER_SOFT_HXX #ifndef FRAMEBUFFER_SOFT_HXX
@ -33,7 +33,7 @@ class RectList;
This class implements an SDL software framebuffer. This class implements an SDL software framebuffer.
@author Stephen Anthony @author Stephen Anthony
@version $Id: FrameBufferSoft.hxx,v 1.45 2007-01-15 00:07:51 stephena Exp $ @version $Id: FrameBufferSoft.hxx,v 1.46 2007-06-20 16:33:22 stephena Exp $
*/ */
class FrameBufferSoft : public FrameBuffer class FrameBufferSoft : public FrameBuffer
{ {
@ -55,7 +55,7 @@ class FrameBufferSoft : public FrameBuffer
This method is called to initialize software video mode. This method is called to initialize software video mode.
Return false if any operation fails, otherwise return true. Return false if any operation fails, otherwise return true.
*/ */
virtual bool initSubsystem(); virtual bool initSubsystem(VideoMode mode);
/** /**
This method is called to query the type of the FrameBuffer. This method is called to query the type of the FrameBuffer.
@ -68,22 +68,11 @@ class FrameBufferSoft : public FrameBuffer
virtual string about(); virtual string about();
/** /**
This method is called to set the aspect ratio of the screen. This method is called to change to the given videomode type.
*/
virtual void setAspectRatio();
/** @param mode The video mode to use for rendering the mediasource
This method is called to change to the given scaler type.
@param scaler The scaler to use for rendering the mediasource
*/ */
virtual void setScaler(Scaler scaler); virtual bool setVidMode(VideoMode mode);
/**
This method is called whenever the screen needs to be recreated.
It updates the global screen variable.
*/
virtual bool createScreen();
/** /**
Switches between the filtering options in software mode. Switches between the filtering options in software mode.
@ -188,7 +177,7 @@ class FrameBufferSoft : public FrameBuffer
@param x X coordinate to translate @param x X coordinate to translate
@param y Y coordinate to translate @param y Y coordinate to translate
*/ */
virtual void translateCoords(Int32* x, Int32* y); virtual void translateCoords(Int32& x, Int32& y);
/** /**
This method adds a dirty rectangle This method adds a dirty rectangle
@ -215,10 +204,10 @@ class FrameBufferSoft : public FrameBuffer
int myZoomLevel; int myZoomLevel;
int myBytesPerPixel; int myBytesPerPixel;
int myPitch; int myPitch;
int myBaseOffset;
SDL_PixelFormat* myFormat; SDL_PixelFormat* myFormat;
enum RenderType { enum RenderType {
kDirtyRect,
kSoftZoom_16, kSoftZoom_16,
kSoftZoom_24, kSoftZoom_24,
kSoftZoom_32, kSoftZoom_32,
@ -228,14 +217,14 @@ class FrameBufferSoft : public FrameBuffer
}; };
RenderType myRenderType; RenderType myRenderType;
// Use dirty updates (SDL_UpdateRects instead of SDL_UpdateRect) // Indicates if the TIA image has been modified
bool myUseDirtyRects; bool myDirtyFlag;
// Used in the dirty update of the SDL surface // Indicates if we're in a purely UI mode
bool myInUIMode;
// Used in the dirty update of rectangles in non-TIA modes
RectList* myRectList; RectList* myRectList;
// Used in the dirty update of the overlay surface
RectList* myOverlayRectList;
}; };
#endif #endif

View File

@ -0,0 +1,114 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2007 by Bradford W. Mott and the Stella team
//
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: VideoModeList.hxx,v 1.1 2007-06-20 16:33:22 stephena Exp $
//============================================================================
#ifndef VIDMODE_LIST_HXX
#define VIDMODE_LIST_HXX
#include "Array.hxx"
#include "bspf.hxx"
struct VideoMode {
uInt32 image_x, image_y, image_w, image_h;
uInt32 screen_w, screen_h;
uInt32 zoom;
string name;
};
/**
This class implements an iterator around an array of VideoMode objects.
@author Stephen Anthony
@version $Id: VideoModeList.hxx,v 1.1 2007-06-20 16:33:22 stephena Exp $
*/
class VideoModeList
{
public:
VideoModeList() : myIdx(-1) { }
void add(VideoMode mode) { myModeList.push_back(mode); }
void clear() { myModeList.clear(); }
bool isEmpty() const { return myModeList.isEmpty(); }
uInt32 size() const { return myModeList.size(); }
const VideoMode& previous()
{
--myIdx;
if(myIdx < 0) myIdx = myModeList.size() - 1;
return current();
}
const VideoMode& current() const
{
return myModeList[myIdx];
}
const VideoMode& next()
{
myIdx = (myIdx + 1) % myModeList.size();
return current();
}
void setByResolution(uInt32 width, uInt32 height)
{
// Find the largest resolution within the given bounds
myIdx = 0;
for(unsigned int i = myModeList.size() - 1; i; --i)
{
if(myModeList[i].screen_w <= width && myModeList[i].screen_h <= height)
{
myIdx = i;
break;
}
}
}
void setByZoom(uInt32 zoom)
{
// Find the largest zoom within the given bounds
myIdx = 0;
for(unsigned int i = myModeList.size() - 1; i; --i)
{
if(myModeList[i].zoom <= zoom)
{
myIdx = i;
break;
}
}
}
static bool modesAreEqual(const VideoMode& m1, const VideoMode& m2)
{
return (m1.image_x == m2.image_x) &&
(m1.image_y == m2.image_y) &&
(m1.image_w == m2.image_w) &&
(m1.image_h == m2.image_h) &&
(m1.screen_w == m2.screen_w) &&
(m1.screen_h == m2.screen_h) &&
(m1.zoom == m2.zoom) &&
(m1.name == m2.name);
}
private:
Common::Array<VideoMode> myModeList;
int myIdx;
};
#endif

View File

@ -14,7 +14,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: EventHandler.cxx,v 1.202 2007-02-22 02:15:46 stephena Exp $ // $Id: EventHandler.cxx,v 1.203 2007-06-20 16:33:22 stephena Exp $
//============================================================================ //============================================================================
#include <sstream> #include <sstream>
@ -388,11 +388,11 @@ void EventHandler::poll(uInt32 time)
{ {
#ifndef MAC_OSX #ifndef MAC_OSX
case SDLK_EQUALS: case SDLK_EQUALS:
myOSystem->frameBuffer().scale(+1); myOSystem->frameBuffer().changeVidMode(+1);
break; break;
case SDLK_MINUS: case SDLK_MINUS:
myOSystem->frameBuffer().scale(-1); myOSystem->frameBuffer().changeVidMode(-1);
break; break;
case SDLK_RETURN: case SDLK_RETURN:
@ -510,11 +510,11 @@ void EventHandler::poll(uInt32 time)
break; break;
case SDLK_EQUALS: case SDLK_EQUALS:
myOSystem->frameBuffer().scale(+1); myOSystem->frameBuffer().changeVidMode(+1);
break; break;
case SDLK_MINUS: case SDLK_MINUS:
myOSystem->frameBuffer().scale(-1); myOSystem->frameBuffer().changeVidMode(-1);
break; break;
case SDLK_RETURN: case SDLK_RETURN:
@ -850,12 +850,13 @@ void EventHandler::handleMouseMotionEvent(SDL_Event& event)
{ {
// Take window zooming into account // Take window zooming into account
int x = event.motion.x, y = event.motion.y; int x = event.motion.x, y = event.motion.y;
myOSystem->frameBuffer().translateCoords(&x, &y); myOSystem->frameBuffer().translateCoords(x, y);
// Determine which mode we're in, then send the event to the appropriate place // Determine which mode we're in, then send the event to the appropriate place
if(myState == S_EMULATE) if(myState == S_EMULATE)
{ {
int w = myOSystem->frameBuffer().baseWidth(); int w = myOSystem->frameBuffer().baseWidth();
if(x < 0 || x > w) return;
// Grabmouse introduces some lag into the mouse movement, // Grabmouse introduces some lag into the mouse movement,
// so we need to fudge the numbers a bit // so we need to fudge the numbers a bit
@ -882,7 +883,7 @@ void EventHandler::handleMouseButtonEvent(SDL_Event& event, int state)
// Take window zooming into account // Take window zooming into account
Int32 x = event.button.x, y = event.button.y; Int32 x = event.button.x, y = event.button.y;
//if (state) cerr << "B: x = " << x << ", y = " << y << endl; //if (state) cerr << "B: x = " << x << ", y = " << y << endl;
myOSystem->frameBuffer().translateCoords(&x, &y); myOSystem->frameBuffer().translateCoords(x, y);
//if (state) cerr << "A: x = " << x << ", y = " << y << endl << endl; //if (state) cerr << "A: x = " << x << ", y = " << y << endl << endl;
MouseButton button; MouseButton button;

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: FrameBuffer.cxx,v 1.117 2007-01-30 17:13:10 stephena Exp $ // $Id: FrameBuffer.cxx,v 1.118 2007-06-20 16:33:22 stephena Exp $
//============================================================================ //============================================================================
#include <sstream> #include <sstream>
@ -40,7 +40,6 @@
FrameBuffer::FrameBuffer(OSystem* osystem) FrameBuffer::FrameBuffer(OSystem* osystem)
: myOSystem(osystem), : myOSystem(osystem),
myScreen(0), myScreen(0),
theAspectRatio(1.0),
theRedrawTIAIndicator(true), theRedrawTIAIndicator(true),
myUsePhosphor(false), myUsePhosphor(false),
myPhosphorBlend(77), myPhosphorBlend(77),
@ -55,48 +54,33 @@ FrameBuffer::~FrameBuffer(void)
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::initialize(const string& title, uInt32 width, uInt32 height, void FrameBuffer::initialize(const string& title, uInt32 width, uInt32 height)
bool useAspect)
{ {
bool isAlreadyInitialized = (SDL_WasInit(SDL_INIT_VIDEO) & SDL_INIT_VIDEO) > 0; // Now (re)initialize the SDL video system
// These things only have to be done one per FrameBuffer creation
if(SDL_WasInit(SDL_INIT_VIDEO) == 0)
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0)
return;
myInitializedCount++;
myBaseDim.x = myBaseDim.y = 0; myBaseDim.x = myBaseDim.y = 0;
myBaseDim.w = (uInt16) width; myBaseDim.w = (uInt16) width;
myBaseDim.h = (uInt16) height; myBaseDim.h = (uInt16) height;
// Now (re)initialize the SDL video system
// These things only have to be done one per FrameBuffer creation
if(!isAlreadyInitialized)
{
Uint32 initflags = SDL_INIT_VIDEO | SDL_INIT_TIMER;
if(SDL_Init(initflags) < 0)
return;
}
myInitializedCount++;
// Query the desktop size
// This is really the job of SDL
int dwidth = 0, dheight = 0;
myOSystem->getScreenDimensions(dwidth, dheight);
myDesktopDim.w = dwidth; myDesktopDim.h = dheight;
// Get the aspect ratio for the display if it's been enabled
theAspectRatio = 1.0;
if(useAspect) setAspectRatio();
// Set fullscreen flag // Set fullscreen flag
#ifdef WINDOWED_SUPPORT
mySDLFlags = myOSystem->settings().getBool("fullscreen") ? SDL_FULLSCREEN : 0; mySDLFlags = myOSystem->settings().getBool("fullscreen") ? SDL_FULLSCREEN : 0;
#else
mySDLFlags = 0;
#endif
// Set the available scalers for this framebuffer, based on current eventhandler // Set the available video modes for this framebuffer
// state and the maximum size of a window for the current desktop setAvailableVidModes();
setAvailableScalers();
// Initialize video subsystem // Initialize video subsystem
Scaler scaler; VideoMode mode = getSavedVidMode();
getScaler(scaler, 0, currentScalerName()); initSubsystem(mode);
setScaler(scaler);
initSubsystem();
// Set window title and icon // Set window title and icon
setWindowTitle(title); setWindowTitle(title);
@ -371,50 +355,73 @@ void FrameBuffer::toggleFullscreen()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::setFullscreen(bool enable) void FrameBuffer::setFullscreen(bool enable)
{ {
#ifdef WINDOWED_SUPPORT
// Update the settings // Update the settings
myOSystem->settings().setBool("fullscreen", enable); myOSystem->settings().setBool("fullscreen", enable);
if(enable) if(enable)
mySDLFlags |= SDL_FULLSCREEN; mySDLFlags |= SDL_FULLSCREEN;
else else
mySDLFlags &= ~SDL_FULLSCREEN; mySDLFlags &= ~SDL_FULLSCREEN;
if(!createScreen()) // Do a dummy call to getSavedVidMode to set up the modelists
return; // and have it point to the correct 'current' mode
getSavedVidMode();
myOSystem->eventHandler().refreshDisplay(); // Do a mode change to the 'current' mode by not passing a '+1' or '-1'
setCursorState(); // to changeVidMode()
changeVidMode(0);
#endif
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool FrameBuffer::scale(int direction, const string& type) bool FrameBuffer::changeVidMode(int direction)
{ {
Scaler newScaler; VideoMode oldmode = myCurrentModeList->current();
const string& currentScaler = (direction == 0 ? type : currentScalerName()); if(direction == +1)
getScaler(newScaler, direction, currentScaler); myCurrentModeList->next();
else if(direction == -1)
myCurrentModeList->previous();
// Only update the scaler if it's changed from the old one VideoMode newmode = myCurrentModeList->current();
if(currentScaler != string(newScaler.comparitor)) if(!setVidMode(newmode))
return false;
myOSystem->eventHandler().refreshDisplay();
setCursorState();
showMessage(newmode.name);
// Determine which mode we're in, and save to the appropriate setting
if(fullScreen())
{
myOSystem->settings().setSize("fullres", newmode.screen_w, newmode.screen_h);
}
else
{ {
setScaler(newScaler);
if(!createScreen())
return false;
EventHandler::State state = myOSystem->eventHandler().state(); EventHandler::State state = myOSystem->eventHandler().state();
bool inTIAMode = (state == EventHandler::S_EMULATE || bool inTIAMode = (state == EventHandler::S_EMULATE ||
state == EventHandler::S_PAUSE || state == EventHandler::S_PAUSE ||
state == EventHandler::S_MENU || state == EventHandler::S_MENU ||
state == EventHandler::S_CMDMENU); state == EventHandler::S_CMDMENU);
myOSystem->eventHandler().refreshDisplay();
showMessage(newScaler.name);
if(inTIAMode) if(inTIAMode)
myOSystem->settings().setString("scale_tia", newScaler.comparitor); myOSystem->settings().setInt("zoom_tia", newmode.zoom);
else else
myOSystem->settings().setString("scale_ui", newScaler.comparitor); myOSystem->settings().setInt("zoom_ui", newmode.zoom);
} }
return true; return true;
/*
cerr << "New mode:" << endl
<< " screen w = " << newmode.screen_w << endl
<< " screen h = " << newmode.screen_h << endl
<< " image x = " << newmode.image_x << endl
<< " image y = " << newmode.image_y << endl
<< " image w = " << newmode.image_w << endl
<< " image h = " << newmode.image_h << endl
<< " zoom = " << newmode.zoom << endl
<< " name = " << newmode.name << endl
<< endl;
*/
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -459,7 +466,11 @@ void FrameBuffer::grabMouse(bool grab)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool FrameBuffer::fullScreen() bool FrameBuffer::fullScreen()
{ {
return myOSystem->settings().getBool("fullscreen"); #ifdef WINDOWED_SUPPORT
return myOSystem->settings().getBool("fullscreen");
#else
return true;
#endif
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -666,108 +677,116 @@ uInt8 FrameBuffer::getPhosphor(uInt8 c1, uInt8 c2)
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int FrameBuffer::maxWindowSizeForScreen() uInt32 FrameBuffer::maxWindowSizeForScreen(uInt32 screenWidth, uInt32 screenHeight)
{ {
uInt32 sWidth = myDesktopDim.w; uInt32 multiplier = 1;
uInt32 sHeight = myDesktopDim.h; for(;;)
uInt32 multiplier = 10;
// If screenwidth or height could not be found, use default zoom value
if(sWidth == 0 || sHeight == 0)
return 4;
bool found = false;
while(!found && (multiplier > 0))
{ {
// Figure out the desired size of the window // Figure out the zoomed size of the window
uInt32 width = (uInt32) (myBaseDim.w * multiplier * theAspectRatio); uInt32 width = myBaseDim.w * multiplier;
uInt32 height = myBaseDim.h * multiplier; uInt32 height = myBaseDim.h * multiplier;
if((width < sWidth) && (height < sHeight)) if((width > screenWidth) || (height > screenHeight))
found = true;
else
multiplier--;
}
if(found)
return multiplier;
else
return 1;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::setAvailableScalers()
{
/** Different emulation modes support different scalers, and the size
of the current desktop also determines how much a window can be
zoomed. */
int maxsize = maxWindowSizeForScreen();
myScalerList.clear();
for(int i = 0; i < kScalerListSize; ++i)
if(ourScalers[i].zoom <= maxsize)
myScalerList.push_back(&ourScalers[i]);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::getScaler(Scaler& scaler, int direction, const string& name)
{
// First search for the scaler specified by name
int pos = -1;
for(unsigned int i = 0; i < myScalerList.size(); ++i)
{
if(BSPF_strcasecmp(myScalerList[i]->name, name.c_str()) == 0)
{
pos = i;
break; break;
}
++multiplier;
}
return multiplier > 1 ? multiplier - 1 : 1;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::setAvailableVidModes()
{
// First we look at windowed modes
// These can be sized exactly as required, since there's normally no
// restriction on window size (up the maximum size)
myWindowedModeList.clear();
int max_zoom = maxWindowSizeForScreen(myOSystem->desktopWidth(),
myOSystem->desktopHeight());
for(int i = 1; i <= max_zoom; ++i)
{
VideoMode m;
m.image_x = m.image_y = 0;
m.image_w = m.screen_w = myBaseDim.w * i;
m.image_h = m.screen_h = myBaseDim.h * i;
m.zoom = i;
ostringstream buf;
buf << "Zoom " << i << "x";
m.name = buf.str();
myWindowedModeList.add(m);
} }
// If we found a scaler, look at direction // Now consider the fullscreen modes
if(pos >= 0) // There are often stricter requirements on these, and they're normally
// different depending on the OSystem in use
// As well, we usually can't get fullscreen modes in the exact size
// we want, so we need to calculate image offsets
myFullscreenModeList.clear();
const ResolutionList& res = myOSystem->supportedResolutions();
for(unsigned int i = 0; i < res.size(); ++i)
{ {
switch(direction) VideoMode m;
m.screen_w = res[i].width;
m.screen_h = res[i].height;
m.zoom = maxWindowSizeForScreen(m.screen_w, m.screen_h);
m.name = res[i].name;
// Auto-calculate 'smart' centering; platform-specific framebuffers are
// free to ignore or augment it
m.image_w = myBaseDim.w * m.zoom;
m.image_h = myBaseDim.h * m.zoom;
m.image_x = (m.screen_w - m.image_w) / 2;
m.image_y = (m.screen_h - m.image_h) / 2;
/*
cerr << "Fullscreen modes:" << endl
<< " Mode " << i << endl
<< " screen w = " << m.screen_w << endl
<< " screen h = " << m.screen_h << endl
<< " image x = " << m.image_x << endl
<< " image y = " << m.image_y << endl
<< " image w = " << m.image_w << endl
<< " image h = " << m.image_h << endl
<< " zoom = " << m.zoom << endl
<< endl;
*/
myFullscreenModeList.add(m);
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
VideoMode FrameBuffer::getSavedVidMode()
{
if(myOSystem->settings().getBool("fullscreen"))
{
// Point the modelist to fullscreen modes, and set the iterator to
// the mode closest to the given resolution
int w = -1, h = -1;
myOSystem->settings().getSize("fullres", w, h);
if(w < 0 || h < 0)
{ {
case 0: // actual scaler specified in 'name' w = myOSystem->desktopWidth();
// pos is already set from above h = myOSystem->desktopHeight();
break;
case -1: // previous scaler from one specified in 'name'
pos--;
if(pos < 0) pos = myScalerList.size() - 1;
break;
case +1: // next scaler from one specified in 'name'
pos = (pos + 1) % myScalerList.size();
break;
} }
scaler = *(myScalerList[pos]); myCurrentModeList = &myFullscreenModeList;
myCurrentModeList->setByResolution(w, h);
} }
else else
{ {
// Otherwise, get the largest scaler that's available // Point the modelist to windowed modes, and set the iterator to
scaler = *(myScalerList[myScalerList.size()-1]); // the mode closest to the given zoom level
EventHandler::State state = myOSystem->eventHandler().state();
bool inTIAMode = (state == EventHandler::S_EMULATE ||
state == EventHandler::S_PAUSE ||
state == EventHandler::S_MENU ||
state == EventHandler::S_CMDMENU);
int zoom = (inTIAMode ? myOSystem->settings().getInt("zoom_tia") :
myOSystem->settings().getInt("zoom_ui") );
myCurrentModeList = &myWindowedModeList;
myCurrentModeList->setByZoom(zoom);
} }
return myCurrentModeList->current();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const string& FrameBuffer::currentScalerName()
{
EventHandler::State state = myOSystem->eventHandler().state();
bool inTIAMode = (state == EventHandler::S_EMULATE ||
state == EventHandler::S_PAUSE ||
state == EventHandler::S_MENU ||
state == EventHandler::S_CMDMENU);
return (inTIAMode ?
myOSystem->settings().getString("scale_tia") :
myOSystem->settings().getString("scale_ui") );
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Scaler FrameBuffer::ourScalers[kScalerListSize] = {
{ kZOOM1X, "Zoom1x", "zoom1x", 1 },
{ kZOOM2X, "Zoom2x", "zoom2x", 2 },
{ kZOOM3X, "Zoom3x", "zoom3x", 3 },
{ kZOOM4X, "Zoom4x", "zoom4x", 4 },
{ kZOOM5X, "Zoom5x", "zoom5x", 5 },
{ kZOOM6X, "Zoom6x", "zoom6x", 6 }
};

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: FrameBuffer.hxx,v 1.86 2007-01-30 17:13:10 stephena Exp $ // $Id: FrameBuffer.hxx,v 1.87 2007-06-20 16:33:22 stephena Exp $
//============================================================================ //============================================================================
#ifndef FRAMEBUFFER_HXX #ifndef FRAMEBUFFER_HXX
@ -28,6 +28,7 @@
#include "MediaSrc.hxx" #include "MediaSrc.hxx"
#include "Font.hxx" #include "Font.hxx"
#include "GuiUtils.hxx" #include "GuiUtils.hxx"
#include "VideoModeList.hxx"
class OSystem; class OSystem;
class Console; class Console;
@ -76,14 +77,6 @@ enum {
kNumColors kNumColors
}; };
// Different types of scalers available
enum ScalerType { kZOOM1X, kZOOM2X, kZOOM3X, kZOOM4X, kZOOM5X, kZOOM6X };
struct Scaler {
ScalerType type;
const char* name;
const char* comparitor;
int zoom;
};
/** /**
This class encapsulates the MediaSource and is the basis for the video This class encapsulates the MediaSource and is the basis for the video
@ -93,10 +86,12 @@ struct Scaler {
All GUI elements (ala ScummVM) are drawn here as well. All GUI elements (ala ScummVM) are drawn here as well.
@author Stephen Anthony @author Stephen Anthony
@version $Id: FrameBuffer.hxx,v 1.86 2007-01-30 17:13:10 stephena Exp $ @version $Id: FrameBuffer.hxx,v 1.87 2007-06-20 16:33:22 stephena Exp $
*/ */
class FrameBuffer class FrameBuffer
{ {
friend class TiaOutputWidget;
public: public:
/** /**
Creates a new Frame Buffer Creates a new Frame Buffer
@ -115,10 +110,8 @@ class FrameBuffer
@param title The title of the window @param title The title of the window
@param width The width of the framebuffer @param width The width of the framebuffer
@param height The height of the framebuffer @param height The height of the framebuffer
@param aspect Whether to use the aspect ratio setting
*/ */
void initialize(const string& title, uInt32 width, uInt32 height, void initialize(const string& title, uInt32 width, uInt32 height);
bool aspect = true);
/** /**
Updates the display, which depending on the current mode could mean Updates the display, which depending on the current mode could mean
@ -193,16 +186,14 @@ class FrameBuffer
void setFullscreen(bool enable); void setFullscreen(bool enable);
/** /**
This method is called when the user wants to scale the window, in effect This method is called when the user wants to switch to the next available
changing to another scaler. video mode (functionality depends on fullscreen or windowed mode).
direction = -1 means window should go to the next lower scaler direction = -1 means go to the next lower video mode
direction = 0 means window should be created with the given scaler direction = +1 means go to the next higher video mode
direction = +1 means window should go to the next higher scaler
@param direction Described above @param direction Described above
@param type The scaler to use if direction is set to 0
*/ */
bool scale(int direction, const string& type = "zoom1x"); bool changeVidMode(int direction);
/** /**
Sets the state of the cursor (hidden or grabbed) based on the Sets the state of the cursor (hidden or grabbed) based on the
@ -287,73 +278,18 @@ class FrameBuffer
*/ */
void drawString(const GUI::Font* font, const string& str, int x, int y, int w, void drawString(const GUI::Font* font, const string& str, int x, int y, int w,
int color, TextAlignment align = kTextAlignLeft, int color, TextAlignment align = kTextAlignLeft,
int deltax = 0, bool useEllipsis = true); int deltax = 0, bool useEllipsis = true);
/** /**
Informs the Framebuffer of a change in EventHandler state. Informs the Framebuffer of a change in EventHandler state.
*/ */
virtual void stateChanged(EventHandler::State state) { } virtual void stateChanged(EventHandler::State state) { }
//////////////////////////////////////////////////////////////////////
// The following methods are system-specific and must be implemented
// in derived classes.
//////////////////////////////////////////////////////////////////////
public: public:
//////////////////////////////////////////////////////////////////////
// The following methods are system-specific and must be implemented
// in derived classes.
//////////////////////////////////////////////////////////////////////
/**
This method is called to initialize the subsystem-specific video mode
with the given scaler.
*/
virtual bool initSubsystem() = 0;
/**
This method is called to query the type of the FrameBuffer.
*/
virtual BufferType type() = 0;
/**
This method is called to provide information about the FrameBuffer.
*/
virtual string about() = 0;
/**
This method is called to set the aspect ratio of the screen.
*/
virtual void setAspectRatio() = 0;
/**
This method is called to change to the given scaler type.
@param scaler The scaler to use for rendering the mediasource
*/
virtual void setScaler(Scaler scaler) = 0;
/**
This method is called whenever the screen needs to be recreated.
It updates the global screen variable.
*/
virtual bool createScreen() = 0;
/**
Switches between the filtering options in the video subsystem.
*/
virtual void toggleFilter() = 0;
/**
This method should be called anytime the MediaSource needs to be redrawn
to the screen.
*/
virtual void drawMediaSource() = 0;
/**
This method is called before any drawing is done (per-frame).
*/
virtual void preFrameUpdate() = 0;
/**
This method is called after any drawing is done (per-frame).
*/
virtual void postFrameUpdate() = 0;
/** /**
This method is called to get the specified scanline data. This method is called to get the specified scanline data.
@ -362,15 +298,6 @@ class FrameBuffer
*/ */
virtual void scanline(uInt32 row, uInt8* data) = 0; virtual void scanline(uInt32 row, uInt8* data) = 0;
/**
This method is called to map a given r,g,b triple to the screen palette.
@param r The red component of the color.
@param g The green component of the color.
@param b The blue component of the color.
*/
virtual Uint32 mapRGB(Uint8 r, Uint8 g, Uint8 b) = 0;
/** /**
This method should be called to draw a horizontal line. This method should be called to draw a horizontal line.
@ -434,7 +361,7 @@ class FrameBuffer
@param x X coordinate to translate @param x X coordinate to translate
@param y Y coordinate to translate @param y Y coordinate to translate
*/ */
virtual void translateCoords(Int32* x, Int32* y) = 0; virtual void translateCoords(Int32& x, Int32& y) = 0;
/** /**
This method should be called to add a dirty rectangle This method should be called to add a dirty rectangle
@ -452,6 +379,62 @@ class FrameBuffer
*/ */
virtual void enablePhosphor(bool enable, int blend) = 0; virtual void enablePhosphor(bool enable, int blend) = 0;
/**
This method is called to query the type of the FrameBuffer.
*/
virtual BufferType type() = 0;
protected:
/**
This method is called to initialize the video subsystem
with the given video mode. Normally, it will also call setVidMode().
*/
virtual bool initSubsystem(VideoMode mode) = 0;
/**
This method is called to change to the given video mode.
@param mode The video mode to use for rendering the mediasource
*/
virtual bool setVidMode(VideoMode mode) = 0;
/**
Switches between the filtering options in the video subsystem.
*/
virtual void toggleFilter() = 0;
/**
This method should be called anytime the MediaSource needs to be redrawn
to the screen.
*/
virtual void drawMediaSource() = 0;
/**
This method is called before any drawing is done (per-frame).
*/
virtual void preFrameUpdate() = 0;
/**
This method is called after any drawing is done (per-frame).
*/
virtual void postFrameUpdate() = 0;
/**
This method is called to map a given r,g,b triple to the screen palette.
@param r The red component of the color.
@param g The green component of the color.
@param b The blue component of the color.
*/
virtual Uint32 mapRGB(Uint8 r, Uint8 g, Uint8 b) = 0;
/**
This method is called to provide information about the FrameBuffer.
*/
virtual string about() = 0;
protected: protected:
// The parent system for the framebuffer // The parent system for the framebuffer
OSystem* myOSystem; OSystem* myOSystem;
@ -468,9 +451,6 @@ class FrameBuffer
// Dimensions of the SDL window (not always the same as the image) // Dimensions of the SDL window (not always the same as the image)
SDL_Rect myScreenDim; SDL_Rect myScreenDim;
// Dimensions of the desktop area
SDL_Rect myDesktopDim;
// The SDL video buffer // The SDL video buffer
SDL_Surface* myScreen; SDL_Surface* myScreen;
@ -481,9 +461,6 @@ class FrameBuffer
Uint32 myDefPalette[256+kNumColors]; Uint32 myDefPalette[256+kNumColors];
Uint32 myAvgPalette[256][256]; Uint32 myAvgPalette[256][256];
// The aspect ratio of the window
float theAspectRatio;
// Indicates if the TIA area should be redrawn // Indicates if the TIA area should be redrawn
bool theRedrawTIAIndicator; bool theRedrawTIAIndicator;
@ -515,34 +492,24 @@ class FrameBuffer
uInt8 getPhosphor(uInt8 c1, uInt8 c2); uInt8 getPhosphor(uInt8 c1, uInt8 c2);
/** /**
Calculate the maximum window size that the current screen can hold. Calculate the maximum level by which the base window can be zoomed and
If not supported by platform, always return 4. still fit in the given screen dimensions.
*/ */
int maxWindowSizeForScreen(); uInt32 maxWindowSizeForScreen(uInt32 screenWidth, uInt32 screenHeight);
/** /**
Set the scalers available for this framebuffer based on current emulation Set all possible video modes (both windowed and fullscreen) available for
state and maximum window size. this framebuffer based on current emulation state and maximum window size.
*/ */
void setAvailableScalers(); void setAvailableVidModes();
/** /**
Returns a scaler based on the current eventhandler mode and the value of direction. Returns an appropriate video mode based on the current eventhandler
If there's any error, default to 'zoom1x'. state, taking into account the maximum size of the window.
direction = -1 means previous scaler based on value in 'name'
direction = 0 means actual scaler based on value in 'name'
direction = +1 means next scaler based on value in 'name'
@param scaler The reference to store the scaler we're looking for @return A valid VideoMode for this framebuffer
@param direction Described above
@param name The name of the scaler
*/ */
void getScaler(Scaler& scaler, int direction, const string& name); VideoMode getSavedVidMode();
/**
Get the current scaler based on the eventhandler mode.
*/
const string& currentScalerName();
private: private:
// Indicates the number of times the framebuffer was initialized // Indicates the number of times the framebuffer was initialized
@ -560,14 +527,10 @@ class FrameBuffer
}; };
Message myMessage; Message myMessage;
// The various scalers available in TIA vs. non-TIA mode // The list of all available video modes for this framebuffer
// For the foreseeable future, the UI scalers will be restricted VideoModeList myWindowedModeList;
// from using the more advanced scalers VideoModeList myFullscreenModeList;
enum { kScalerListSize = 6 }; VideoModeList* myCurrentModeList;
static Scaler ourScalers[kScalerListSize];
// The list of scalers available in the current mode
Common::Array<Scaler*> myScalerList;
}; };
#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: OSystem.cxx,v 1.96 2007-02-06 23:34:33 stephena Exp $ // $Id: OSystem.cxx,v 1.97 2007-06-20 16:33:22 stephena Exp $
//============================================================================ //============================================================================
#include <cassert> #include <cassert>
@ -65,6 +65,22 @@ OSystem::OSystem()
myFont(NULL), myFont(NULL),
myConsoleFont(NULL) myConsoleFont(NULL)
{ {
#ifdef DISPLAY_OPENGL
myFeatures += "OpenGL ";
#endif
#ifdef SOUND_SUPPORT
myFeatures += "Sound ";
#endif
#ifdef JOYSTICK_SUPPORT
myFeatures += "Joystick ";
#endif
#ifdef DEBUGGER_SUPPORT
myFeatures += "Debugger ";
#endif
#ifdef CHEATCODE_SUPPORT
myFeatures += "Cheats";
#endif
#if 0 #if 0
// Debugging info for the GUI widgets // Debugging info for the GUI widgets
cerr << " kStaticTextWidget = " << kStaticTextWidget << endl; cerr << " kStaticTextWidget = " << kStaticTextWidget << endl;
@ -131,6 +147,11 @@ OSystem::~OSystem()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool OSystem::create() bool OSystem::create()
{ {
// Get relevant information about the video hardware
// This must be done before any graphics context is created, since
// it may be needed to initialize the size of graphical objects
queryVideoHardware();
// Create fonts to draw text // Create fonts to draw text
myFont = new GUI::Font(GUI::stellaDesc); myFont = new GUI::Font(GUI::stellaDesc);
myLauncherFont = new GUI::Font(GUI::stellaDesc); // FIXME myLauncherFont = new GUI::Font(GUI::stellaDesc); // FIXME
@ -161,23 +182,6 @@ bool OSystem::create()
// that only have a single sound device (no hardware mixing) // that only have a single sound device (no hardware mixing)
createSound(); createSound();
// Determine which features were conditionally compiled into Stella
#ifdef DISPLAY_OPENGL
myFeatures += "OpenGL ";
#endif
#ifdef SOUND_SUPPORT
myFeatures += "Sound ";
#endif
#ifdef JOYSTICK_SUPPORT
myFeatures += "Joystick ";
#endif
#ifdef DEBUGGER_SUPPORT
myFeatures += "Debugger ";
#endif
#ifdef CHEATCODE_SUPPORT
myFeatures += "Cheats";
#endif
return true; return true;
} }
@ -498,9 +502,11 @@ bool OSystem::openROM(const string& rom, string& md5, uInt8** image, int* size)
if(!in) if(!in)
return false; return false;
*image = new uInt8[512 * 1024]; in.seekg(0, ios::end);
in.read((char*)(*image), 512 * 1024); *size = (int)in.tellg();
*size = in.gcount(); in.seekg(0, ios::beg);
*image = new uInt8[*size];
in.read((char*)(*image), *size);
in.close(); in.close();
} }
@ -702,6 +708,45 @@ void OSystem::mainLoop()
} }
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void OSystem::queryVideoHardware()
{
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0)
return;
// First get the maximum windowed desktop resolution
const SDL_VideoInfo* info = SDL_GetVideoInfo();
myDesktopWidth = info->current_w;
myDesktopHeight = info->current_h;
// Then get the valid fullscreen modes
// If there are any errors, just use the desktop resolution
ostringstream buf;
SDL_Rect** modes = SDL_ListModes(NULL, SDL_FULLSCREEN);
if((modes == (SDL_Rect**)0) || (modes == (SDL_Rect**)-1))
{
Resolution r;
r.width = myDesktopWidth;
r.height = myDesktopHeight;
buf << r.width << "x" << r.height;
r.name = buf.str();
myResolutions.push_back(r);
}
else
{
for(uInt32 i = 0; modes[i]; ++i)
{
Resolution r;
r.width = modes[i]->w;
r.height = modes[i]->h;
buf.str("");
buf << r.width << "x" << r.height;
r.name = buf.str();
myResolutions.insert_at(0, r); // insert in opposite (of descending) order
}
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/* /*
Palette is defined as follows: Palette is defined as follows:

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.hxx,v 1.51 2007-01-01 18:04:49 stephena Exp $ // $Id: OSystem.hxx,v 1.52 2007-06-20 16:33:22 stephena Exp $
//============================================================================ //============================================================================
#ifndef OSYSTEM_HXX #ifndef OSYSTEM_HXX
@ -28,16 +28,22 @@ class Debugger;
class CheatManager; class CheatManager;
class VideoDialog; class VideoDialog;
#include "Array.hxx"
#include "EventHandler.hxx" #include "EventHandler.hxx"
#include "FrameBuffer.hxx" #include "FrameBuffer.hxx"
#include "Sound.hxx" #include "Sound.hxx"
#include "Settings.hxx" #include "Settings.hxx"
#include "Console.hxx" #include "Console.hxx"
#include "StringList.hxx"
#include "Font.hxx" #include "Font.hxx"
#include "bspf.hxx" #include "bspf.hxx"
struct Resolution {
uInt32 width;
uInt32 height;
string name;
};
typedef Common::Array<Resolution> ResolutionList;
/** /**
This class provides an interface for accessing operating system specific This class provides an interface for accessing operating system specific
@ -45,7 +51,7 @@ class VideoDialog;
other objects belong. other objects belong.
@author Stephen Anthony @author Stephen Anthony
@version $Id: OSystem.hxx,v 1.51 2007-01-01 18:04:49 stephena Exp $ @version $Id: OSystem.hxx,v 1.52 2007-06-20 16:33:22 stephena Exp $
*/ */
class OSystem class OSystem
{ {
@ -193,6 +199,19 @@ class OSystem
*/ */
inline uInt32 frameRate() const { return myDisplayFrameRate; } inline uInt32 frameRate() const { return myDisplayFrameRate; }
/**
Get the maximum dimensions of a window for the video hardware.
*/
const uInt32 desktopWidth() const { return myDesktopWidth; }
const uInt32 desktopHeight() const { return myDesktopHeight; }
/**
Get the supported fullscreen resolutions for the video hardware.
@return An array of supported resolutions
*/
const ResolutionList& supportedResolutions() const { return myResolutions; }
/** /**
Return the default directory for storing data. Return the default directory for storing data.
*/ */
@ -303,11 +322,6 @@ class OSystem
*/ */
virtual uInt32 getTicks() = 0; virtual uInt32 getTicks() = 0;
/**
This method queries the dimensions of the screen for the given device.
*/
virtual void getScreenDimensions(int& width, int& height) = 0;
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// The following methods are system-specific and can be overrided in // The following methods are system-specific and can be overrided in
// derived classes. Otherwise, the base methods will be used. // derived classes. Otherwise, the base methods will be used.
@ -355,6 +369,12 @@ class OSystem
*/ */
virtual void stateChanged(EventHandler::State state); virtual void stateChanged(EventHandler::State state);
protected:
/**
Query the OSystem video hardware for resolution information.
*/
virtual void queryVideoHardware();
protected: protected:
/** /**
Set the base directory for all Stella files Set the base directory for all Stella files
@ -415,6 +435,12 @@ class OSystem
// Pointer to the CheatManager object // Pointer to the CheatManager object
CheatManager* myCheatManager; CheatManager* myCheatManager;
// Maximum dimensions of the desktop area
uInt32 myDesktopWidth, myDesktopHeight;
// Supported fullscreen resolutions
ResolutionList myResolutions;
// Number of times per second to iterate through the main loop // Number of times per second to iterate through the main loop
uInt32 myDisplayFrameRate; uInt32 myDisplayFrameRate;
@ -456,6 +482,9 @@ class OSystem
}; };
TimingInfo myTimingInfo; TimingInfo myTimingInfo;
// Capabilities for this OSystem
uInt32 myCapabilities;
// Table of RGB values for GUI elements // Table of RGB values for GUI elements
static uInt32 ourGUIColors[kNumUIPalettes][kNumColors-256]; static uInt32 ourGUIColors[kNumUIPalettes][kNumColors-256];

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.116 2007-02-06 23:34:33 stephena Exp $ // $Id: Settings.cxx,v 1.117 2007-06-20 16:33:22 stephena Exp $
//============================================================================ //============================================================================
#include <cassert> #include <cassert>
@ -34,17 +34,16 @@ Settings::Settings(OSystem* osystem)
// Add options that are common to all versions of Stella // Add options that are common to all versions of Stella
setInternal("video", "soft"); setInternal("video", "soft");
setInternal("dirtyrects", "false"); // This only becomes useful at high resolutions
setInternal("gl_filter", "nearest"); setInternal("gl_filter", "nearest");
setInternal("gl_aspect", "2.0"); setInternal("gl_fsmax", "never");
setInternal("gl_fsmax", "true");
setInternal("gl_lib", "libGL.so"); setInternal("gl_lib", "libGL.so");
setInternal("gl_vsync", "false"); setInternal("gl_vsync", "false");
setInternal("scale_ui", "zoom2x"); setInternal("zoom_ui", "2");
setInternal("scale_tia", "zoom2x"); setInternal("zoom_tia", "2");
setInternal("fullscreen", "false"); setInternal("fullscreen", "false");
setInternal("fullres", "");
setInternal("center", "true"); setInternal("center", "true");
setInternal("grabmouse", "false"); setInternal("grabmouse", "false");
setInternal("palette", "standard"); setInternal("palette", "standard");
@ -80,7 +79,7 @@ Settings::Settings(OSystem* osystem)
setInternal("lastrom", ""); setInternal("lastrom", "");
setInternal("modtime", ""); setInternal("modtime", "");
setInternal("debugheight", "0"); setInternal("debugheight", "0");
setInternal("launchersize", "2"); setInternal("launcherres", "320x240");
setInternal("uipalette", "0"); setInternal("uipalette", "0");
setInternal("autoslot", "false"); setInternal("autoslot", "false");
} }
@ -220,9 +219,9 @@ void Settings::validate()
if(s != "linear" && s != "nearest") if(s != "linear" && s != "nearest")
setInternal("gl_filter", "nearest"); setInternal("gl_filter", "nearest");
float f = getFloat("gl_aspect"); s = getString("gl_fsmax");
if(f < 1.1 || f > 2.0) if(s != "never" && s != "ui" && s != "tia" && s != "always")
setInternal("gl_aspect", "2.0"); setInternal("gl_fsmax", "never");
#endif #endif
#ifdef SOUND_SUPPORT #ifdef SOUND_SUPPORT
@ -237,15 +236,13 @@ void Settings::validate()
setInternal("tiafreq", "31400"); setInternal("tiafreq", "31400");
#endif #endif
s = getString("scale_ui"); i = getInt("zoom_ui");
if(s != "zoom1x" && s != "zoom2x" && s != "zoom3x" && if(i < 1 || i > 10)
s != "zoom4x" && s != "zoom5x" && s != "zoom6x") setInternal("zoom_ui", "2");
setInternal("scale_ui", "zoom1x");
s = getString("scale_tia"); i = getInt("zoom_tia");
if(s != "zoom1x" && s != "zoom2x" && s != "zoom3x" && if(i < 1 || i > 10)
s != "zoom4x" && s != "zoom5x" && s != "zoom6x") setInternal("zoom_tia", "2");
setInternal("scale_tia", "zoom1x");
i = getInt("paddle"); i = getInt("paddle");
if(i < 0 || i > 3) if(i < 0 || i > 3)
@ -283,14 +280,15 @@ void Settings::usage()
<< " -gl_filter <type> Type is one of the following:\n" << " -gl_filter <type> Type is one of the following:\n"
<< " nearest Normal scaling (GL_NEAREST)\n" << " nearest Normal scaling (GL_NEAREST)\n"
<< " linear Blurred scaling (GL_LINEAR)\n" << " linear Blurred scaling (GL_LINEAR)\n"
<< " -gl_aspect <number> Scale the width by the given amount\n" << " -gl_fsmax <never|always| Stretch GL image in fullscreen mode\n"
<< " -gl_fsmax <1|0> Use the largest available screenmode in fullscreen OpenGL\n" << " ui|tia\n"
<< " -gl_vsync <1|0> Enable synchronize to vertical blank interrupt\n" << " -gl_vsync <1|0> Enable synchronize to vertical blank interrupt\n"
<< endl << endl
#endif #endif
<< " -scale_tia <scaler> Use the specified scaler in emulation mode\n" << " -zoom_tia <zoom> Use the specified zoom level in emulation mode\n"
<< " -scale_ui <scaler> Use the specified scaler in non-emulation mode (ROM browser/debugger)\n" << " -zoom_ui <zoom> Use the specified zoom level in non-emulation mode (ROM browser/debugger)\n"
<< " -fullscreen <1|0> Play the game in fullscreen mode\n" << " -fullscreen <1|0> Play the game in fullscreen mode\n"
<< " -fullres <res> The resolution to use in fullscreen mode\n"
<< " -center <1|0> Centers game window (if possible)\n" << " -center <1|0> Centers game window (if possible)\n"
<< " -grabmouse <1|0> Keeps the mouse in the game window\n" << " -grabmouse <1|0> Keeps the mouse in the game window\n"
<< " -palette <original| Use the specified color palette\n" << " -palette <original| Use the specified color palette\n"
@ -329,7 +327,7 @@ void Settings::usage()
<< endl << endl
<< " -listrominfo Display contents of stella.pro, one line per ROM entry\n" << " -listrominfo Display contents of stella.pro, one line per ROM entry\n"
<< " -rominfo <rom> Display detailed information for the given ROM\n" << " -rominfo <rom> Display detailed information for the given ROM\n"
<< " -launchersize <1|2|3> Set the size of the ROM launcher\n" << " -launcherres <res> The resolution to use in ROM launcher mode\n"
<< " -uipalette <1|2> Used the specified palette for UI elements\n" << " -uipalette <1|2> Used the specified palette for UI elements\n"
<< " -help Show the text you're now reading\n" << " -help Show the text you're now reading\n"
#ifdef DEBUGGER_SUPPORT #ifdef DEBUGGER_SUPPORT
@ -460,6 +458,16 @@ void Settings::setString(const string& key, const string& value)
setExternal(key, value); setExternal(key, value);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Settings::getSize(const string& key, int& x, int& y) const
{
string size = getString(key);
replace(size.begin(), size.end(), 'x', ' ');
istringstream buf(size);
buf >> x;
buf >> y;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int Settings::getInt(const string& key) const int Settings::getInt(const string& key) const
{ {
@ -528,6 +536,14 @@ const string& Settings::getString(const string& key) const
return EmptyString; return EmptyString;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Settings::setSize(const string& key, const int value1, const int value2)
{
ostringstream buf;
buf << value1 << "x" << value2;
setString(key, buf.str());
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int Settings::getInternalPos(const string& key) const int Settings::getInternalPos(const string& key) const
{ {

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.hxx,v 1.31 2007-01-01 18:04:49 stephena Exp $ // $Id: Settings.hxx,v 1.32 2007-06-20 16:33:22 stephena Exp $
//============================================================================ //============================================================================
#ifndef SETTINGS_HXX #ifndef SETTINGS_HXX
@ -28,7 +28,7 @@ class OSystem;
This class provides an interface for accessing frontend specific settings. This class provides an interface for accessing frontend specific settings.
@author Stephen Anthony @author Stephen Anthony
@version $Id: Settings.hxx,v 1.31 2007-01-01 18:04:49 stephena Exp $ @version $Id: Settings.hxx,v 1.32 2007-06-20 16:33:22 stephena Exp $
*/ */
class Settings class Settings
{ {
@ -74,7 +74,7 @@ class Settings
/** /**
Get the value assigned to the specified key. If the key does Get the value assigned to the specified key. If the key does
not exist then 0 is returned. not exist then -1 is returned.
@param key The key of the setting to lookup @param key The key of the setting to lookup
@return The integer value of the setting @return The integer value of the setting
@ -108,6 +108,15 @@ class Settings
*/ */
const string& getString(const string& key) const; const string& getString(const string& key) const;
/**
Get the x*y size assigned to the specified key. If the key does
not exist (or is invalid) then results are -1 for each item.
@param key The key of the setting to lookup
@return The x and y values encoded in the key
*/
void getSize(const string& key, int& x, int& y) const;
/** /**
Set the value associated with key to the given value. Set the value associated with key to the given value.
@ -140,6 +149,14 @@ class Settings
*/ */
void setString(const string& key, const string& value); void setString(const string& key, const string& value);
/**
Set the value associated with key to the given value.
@param key The key of the setting
@param value The value to assign to the setting
*/
void setSize(const string& key, const int value1, const int value2);
private: private:
// Copy constructor isn't supported by this class so make it private // Copy constructor isn't supported by this class so make it private
Settings(const Settings&); Settings(const Settings&);

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: FrameBufferGP2X.cxx,v 1.21 2007-01-07 17:59:52 stephena Exp $ // $Id: FrameBufferGP2X.cxx,v 1.22 2007-06-20 16:33:22 stephena Exp $
//============================================================================ //============================================================================
#include <SDL.h> #include <SDL.h>
@ -40,10 +40,10 @@ FrameBufferGP2X::~FrameBufferGP2X()
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool FrameBufferGP2X::initSubsystem() bool FrameBufferGP2X::initSubsystem(VideoMode mode)
{ {
// Create the screen // Create the screen
return createScreen(); return setVidMode(mode);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -54,20 +54,7 @@ string FrameBufferGP2X::about()
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferGP2X::setAspectRatio() bool FrameBufferGP2X::setVidMode(VideoMode mode)
{
// Aspect ratio correction not yet available in software mode
theAspectRatio = 1.0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferGP2X::setScaler(Scaler scaler)
{
// Not supported, we always use 1x zoom
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool FrameBufferGP2X::createScreen()
{ {
// Make sure to clear the screen, since we're using different resolutions, // Make sure to clear the screen, since we're using different resolutions,
// and there tends to be lingering artifacts in hardware mode // and there tends to be lingering artifacts in hardware mode

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: OSystemGP2X.cxx,v 1.26 2007-01-24 21:36:38 stephena Exp $ // $Id: OSystemGP2X.cxx,v 1.27 2007-06-20 16:33:22 stephena Exp $
// Modified on 2006/01/06 by Alex Zaballa for use on GP2X // Modified on 2006/01/06 by Alex Zaballa for use on GP2X
//============================================================================ //============================================================================
@ -67,6 +67,9 @@ OSystemGP2X::OSystemGP2X(const string& path) : OSystem()
// Set event arrays to a known state // Set event arrays to a known state
myPreviousEvents = new uInt8[8]; memset(myPreviousEvents, 0, 8); myPreviousEvents = new uInt8[8]; memset(myPreviousEvents, 0, 8);
myCurrentEvents = new uInt8[8]; memset(myCurrentEvents, 0, 8); myCurrentEvents = new uInt8[8]; memset(myCurrentEvents, 0, 8);
// GP2X doesn't have windowed mode; it's always in fullscreen
clearCapability(CAP_WINDOWED);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -13,9 +13,11 @@
// 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: Launcher.cxx,v 1.14 2007-01-19 21:53:27 stephena Exp $ // $Id: Launcher.cxx,v 1.15 2007-06-20 16:33:23 stephena Exp $
//============================================================================ //============================================================================
#include <sstream>
#include "LauncherDialog.hxx" #include "LauncherDialog.hxx"
#include "Version.hxx" #include "Version.hxx"
#include "OSystem.hxx" #include "OSystem.hxx"
@ -30,28 +32,16 @@ Launcher::Launcher(OSystem* osystem)
myWidth(320), myWidth(320),
myHeight(240) myHeight(240)
{ {
int size = myOSystem->settings().getInt("launchersize"); int w, h;
switch(size) myOSystem->settings().getSize("launcherres", w, h);
{ myWidth = w >= 0 ? w : 0;
case 1: myHeight = h >= 0 ? h : 0;
myWidth = 320;
myHeight = 240;
break;
case 2:
myWidth = 400;
myHeight = 300;
break;
case 3:
myWidth = 512;
myHeight = 384;
break;
}
// Error check the resolution // Error check the resolution
int w, h; if(myWidth < 320) myWidth = 320;
osystem->getScreenDimensions(w, h); if(myWidth > osystem->desktopWidth()) myWidth = osystem->desktopWidth();
if(myWidth > w) myWidth = w; if(myHeight < 240) myHeight = 240;
if(myHeight > h) myHeight = h; if(myHeight > osystem->desktopHeight()) myHeight = osystem->desktopHeight();
myBaseDialog = new LauncherDialog(myOSystem, this, 0, 0, myWidth, myHeight); myBaseDialog = new LauncherDialog(myOSystem, this, 0, 0, myWidth, myHeight);
} }
@ -65,5 +55,5 @@ Launcher::~Launcher()
void Launcher::initializeVideo() void Launcher::initializeVideo()
{ {
string title = string("Stella ") + STELLA_VERSION; string title = string("Stella ") + STELLA_VERSION;
myOSystem->frameBuffer().initialize(title, myWidth, myHeight, false); myOSystem->frameBuffer().initialize(title, myWidth, myHeight);
} }

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: Launcher.hxx,v 1.9 2007-01-01 18:04:53 stephena Exp $ // $Id: Launcher.hxx,v 1.10 2007-06-20 16:33:23 stephena Exp $
//============================================================================ //============================================================================
#ifndef LAUNCHER_HXX #ifndef LAUNCHER_HXX
@ -27,7 +27,7 @@ class OSystem;
The base dialog for the ROM launcher in Stella. The base dialog for the ROM launcher in Stella.
@author Stephen Anthony @author Stephen Anthony
@version $Id: Launcher.hxx,v 1.9 2007-01-01 18:04:53 stephena Exp $ @version $Id: Launcher.hxx,v 1.10 2007-06-20 16:33:23 stephena Exp $
*/ */
class Launcher : public DialogContainer class Launcher : public DialogContainer
{ {
@ -50,8 +50,8 @@ class Launcher : public DialogContainer
private: private:
// The width and height of this dialog // The width and height of this dialog
// These can only be changed by exiting and restarting Stella // These can only be changed by exiting and restarting Stella
int myWidth; uInt32 myWidth;
int myHeight; uInt32 myHeight;
}; };
#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: OptionsDialog.cxx,v 1.51 2007-01-23 09:37:38 knakos Exp $ // $Id: OptionsDialog.cxx,v 1.52 2007-06-20 16:33:23 stephena Exp $
// //
// Based on code from ScummVM - Scumm Interpreter // Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project // Copyright (C) 2002-2004 The ScummVM project
@ -107,19 +107,14 @@ OptionsDialog::OptionsDialog(OSystem* osystem, DialogContainer* parent,
int x = 0, y = 0, w, h; int x = 0, y = 0, w, h;
// Now create all the dialogs attached to each menu button // Now create all the dialogs attached to each menu button
w = 230; h = 135; w = 230; h = 150;
myVideoDialog = new VideoDialog(myOSystem, parent, font, x, y, w, h); myVideoDialog = new VideoDialog(myOSystem, parent, font, x, y, w, h);
w = 200; h = 140; w = 200; h = 140;
myAudioDialog = new AudioDialog(myOSystem, parent, font, x, y, w, h); myAudioDialog = new AudioDialog(myOSystem, parent, font, x, y, w, h);
// knakos: I think this is wrong: (instantiating twice)
//w = 230; h = 185;
//myInputDialog = new InputDialog(myOSystem, parent, font, x, y, w, h);
#ifdef _WIN32_WCE #ifdef _WIN32_WCE
int sx, sy; int sx = myOSystem->desktopWidth();
myOSystem->getScreenDimensions(sx, sy);
// we scale the input dialog down a bit in low res devices. // we scale the input dialog down a bit in low res devices.
// looks only a little ugly, but the functionality is very welcome // looks only a little ugly, but the functionality is very welcome
if(sx < 320) { w = 220; h = 176; } if(sx < 320) { w = 220; h = 176; }
@ -129,7 +124,7 @@ OptionsDialog::OptionsDialog(OSystem* osystem, DialogContainer* parent,
#endif #endif
myInputDialog = new InputDialog(myOSystem, parent, font, x, y, w, h); myInputDialog = new InputDialog(myOSystem, parent, font, x, y, w, h);
w = 200; h = 90; w = 200; h = 105;
myUIDialog = new UIDialog(myOSystem, parent, font, x, y, w, h); myUIDialog = new UIDialog(myOSystem, parent, font, x, y, w, h);
w = 280; h = 120; w = 280; h = 120;

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: UIDialog.cxx,v 1.3 2007-01-23 09:37:39 knakos Exp $ // $Id: UIDialog.cxx,v 1.4 2007-06-20 16:33:23 stephena Exp $
// //
// Based on code from ScummVM - Scumm Interpreter // Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project // Copyright (C) 2002-2004 The ScummVM project
@ -45,13 +45,33 @@ UIDialog::UIDialog(OSystem* osystem, DialogContainer* parent,
xpos = 10; ypos = 10; xpos = 10; ypos = 10;
// Launcher size // Launcher width and height
myLauncherPopup = new PopUpWidget(this, font, xpos, ypos, pwidth, lineHeight, myLauncherWidthSlider = new SliderWidget(this, font, xpos, ypos, pwidth,
"Rom launcher size: ", lwidth); lineHeight, "Launcher Width: ",
myLauncherPopup->appendEntry("320x240", 1); lwidth, kLWidthChanged);
myLauncherPopup->appendEntry("400x300", 2); myLauncherWidthSlider->setMinValue(320);
myLauncherPopup->appendEntry("512x384", 3); myLauncherWidthSlider->setMaxValue(800);
wid.push_back(myLauncherPopup); myLauncherWidthSlider->setStepValue(10);
wid.push_back(myLauncherWidthSlider);
myLauncherWidthLabel =
new StaticTextWidget(this, font,
xpos + myLauncherWidthSlider->getWidth() + 4,
ypos + 1, 15, fontHeight, "", kTextAlignLeft);
myLauncherWidthLabel->setFlags(WIDGET_CLEARBG);
ypos += lineHeight + 4;
myLauncherHeightSlider = new SliderWidget(this, font, xpos, ypos, pwidth,
lineHeight, "Launcher Height: ",
lwidth, kLHeightChanged);
myLauncherHeightSlider->setMinValue(240);
myLauncherHeightSlider->setMaxValue(600);
myLauncherHeightSlider->setStepValue(10);
wid.push_back(myLauncherHeightSlider);
myLauncherHeightLabel =
new StaticTextWidget(this, font,
xpos + myLauncherHeightSlider->getWidth() + 4,
ypos + 1, 15, fontHeight, "", kTextAlignLeft);
myLauncherHeightLabel->setFlags(WIDGET_CLEARBG);
ypos += lineHeight + 4; ypos += lineHeight + 4;
// UI Palette // UI Palette
@ -103,16 +123,21 @@ UIDialog::~UIDialog()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void UIDialog::loadConfig() void UIDialog::loadConfig()
{ {
int i;
// Launcher size // Launcher size
i = instance()->settings().getInt("launchersize"); int w, h;
if(i < 1 || i > 3) instance()->settings().getSize("launcherres", w, h);
i = 1; if(w < 320) w = 320;
myLauncherPopup->setSelectedTag(i); if(w > 800) w = 800;
if(h < 240) h = 240;
if(h > 600) h = 600;
myLauncherWidthSlider->setValue(w);
myLauncherWidthLabel->setValue(w);
myLauncherHeightSlider->setValue(h);
myLauncherHeightLabel->setValue(h);
// UI palette // UI palette
i = instance()->settings().getInt("uipalette"); int i = instance()->settings().getInt("uipalette");
if(i < 1 || i > 2) if(i < 1 || i > 2)
i = 1; i = 1;
myPalettePopup->setSelectedTag(i); myPalettePopup->setSelectedTag(i);
@ -121,26 +146,28 @@ void UIDialog::loadConfig()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void UIDialog::saveConfig() void UIDialog::saveConfig()
{ {
Settings& settings = instance()->settings();
int i;
// Launcher size // Launcher size
i = myLauncherPopup->getSelectedTag(); instance()->settings().setSize("launcherres",
settings.setInt("launchersize", i); myLauncherWidthSlider->getValue(), myLauncherHeightSlider->getValue());
// UI palette // UI palette
i = myPalettePopup->getSelectedTag(); instance()->settings().setInt("uipalette",
settings.setInt("uipalette", i); myPalettePopup->getSelectedTag());
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void UIDialog::setDefaults() void UIDialog::setDefaults()
{ {
int w = MIN(instance()->desktopWidth(), (const uInt32) 400);
int h = MIN(instance()->desktopHeight(), (const uInt32) 300);
myLauncherWidthSlider->setValue(w);
myLauncherWidthLabel->setValue(w);
myLauncherHeightSlider->setValue(h);
myLauncherHeightLabel->setValue(h);
#if !defined (GP2X) #if !defined (GP2X)
myLauncherPopup->setSelectedTag(2);
myPalettePopup->setSelectedTag(1); myPalettePopup->setSelectedTag(1);
#else #else
myLauncherPopup->setSelectedTag(1);
myPalettePopup->setSelectedTag(2); myPalettePopup->setSelectedTag(2);
#endif #endif
@ -152,6 +179,14 @@ void UIDialog::handleCommand(CommandSender* sender, int cmd, int data, int id)
{ {
switch(cmd) switch(cmd)
{ {
case kLWidthChanged:
myLauncherWidthLabel->setValue(myLauncherWidthSlider->getValue());
break;
case kLHeightChanged:
myLauncherHeightLabel->setValue(myLauncherHeightSlider->getValue());
break;
case kOKCmd: case kOKCmd:
saveConfig(); saveConfig();
close(); close();

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: UIDialog.hxx,v 1.2 2007-01-01 18:04:54 stephena Exp $ // $Id: UIDialog.hxx,v 1.3 2007-06-20 16:33:23 stephena Exp $
// //
// Based on code from ScummVM - Scumm Interpreter // Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project // Copyright (C) 2002-2004 The ScummVM project
@ -26,6 +26,8 @@ class CommandSender;
class Dialog; class Dialog;
class DialogContainer; class DialogContainer;
class PopUpWidget; class PopUpWidget;
class SliderWidget;
class StaticTextWidget;
#include "OSystem.hxx" #include "OSystem.hxx"
#include "bspf.hxx" #include "bspf.hxx"
@ -38,7 +40,11 @@ class UIDialog : public Dialog
~UIDialog(); ~UIDialog();
protected: protected:
PopUpWidget* myLauncherPopup; SliderWidget* myLauncherWidthSlider;
StaticTextWidget* myLauncherWidthLabel;
SliderWidget* myLauncherHeightSlider;
StaticTextWidget* myLauncherHeightLabel;
PopUpWidget* myPalettePopup; PopUpWidget* myPalettePopup;
private: private:
@ -47,6 +53,11 @@ class UIDialog : public Dialog
void setDefaults(); void setDefaults();
virtual void handleCommand(CommandSender* sender, int cmd, int data, int id); virtual void handleCommand(CommandSender* sender, int cmd, int data, int id);
enum {
kLWidthChanged = 'UIlw',
kLHeightChanged = 'UIlh',
};
}; };
#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: VideoDialog.cxx,v 1.42 2007-01-23 09:37:39 knakos Exp $ // $Id: VideoDialog.cxx,v 1.43 2007-06-20 16:33:23 stephena Exp $
// //
// Based on code from ScummVM - Scumm Interpreter // Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project // Copyright (C) 2002-2004 The ScummVM project
@ -66,16 +66,14 @@ VideoDialog::VideoDialog(OSystem* osystem, DialogContainer* parent,
wid.push_back(myFilterPopup); wid.push_back(myFilterPopup);
ypos += lineHeight + 4; ypos += lineHeight + 4;
// Aspect ratio // GL FS stretch
myAspectRatioSlider = new SliderWidget(this, font, xpos, ypos, pwidth, lineHeight, myFSStretchPopup = new PopUpWidget(this, font, xpos, ypos,
"GL Aspect: ", lwidth, kAspectRatioChanged); pwidth, lineHeight, "GL Stretch: ", lwidth);
myAspectRatioSlider->setMinValue(1); myAspectRatioSlider->setMaxValue(100); myFSStretchPopup->appendEntry("Never", 1);
wid.push_back(myAspectRatioSlider); myFSStretchPopup->appendEntry("UI mode", 2);
myAspectRatioLabel = new StaticTextWidget(this, font, myFSStretchPopup->appendEntry("TIA mode", 3);
xpos + myAspectRatioSlider->getWidth() + 4, myFSStretchPopup->appendEntry("Always", 4);
ypos + 1, wid.push_back(myFSStretchPopup);
15, fontHeight, "", kTextAlignLeft);
myAspectRatioLabel->setFlags(WIDGET_CLEARBG);
ypos += lineHeight + 4; ypos += lineHeight + 4;
// Palette // Palette
@ -88,27 +86,28 @@ VideoDialog::VideoDialog(OSystem* osystem, DialogContainer* parent,
wid.push_back(myPalettePopup); wid.push_back(myPalettePopup);
ypos += lineHeight + 4; ypos += lineHeight + 4;
// Available TIA scalers // Available UI zoom levels
myTIAScalerPopup = new PopUpWidget(this, font, xpos, ypos, pwidth, myUIZoomSlider = new SliderWidget(this, font, xpos, ypos, pwidth, lineHeight,
lineHeight, "TIA Scaler: ", lwidth); "UI Zoom: ", lwidth, kUIZoomChanged);
myTIAScalerPopup->appendEntry("Zoom1x", 1); myUIZoomSlider->setMinValue(1); myUIZoomSlider->setMaxValue(10);
myTIAScalerPopup->appendEntry("Zoom2x", 2); wid.push_back(myUIZoomSlider);
myTIAScalerPopup->appendEntry("Zoom3x", 3); myUIZoomLabel = new StaticTextWidget(this, font,
myTIAScalerPopup->appendEntry("Zoom4x", 4); xpos + myUIZoomSlider->getWidth() + 4,
myTIAScalerPopup->appendEntry("Zoom5x", 5); ypos + 1,
myTIAScalerPopup->appendEntry("Zoom6x", 6); 15, fontHeight, "", kTextAlignLeft);
wid.push_back(myTIAScalerPopup); myUIZoomLabel->setFlags(WIDGET_CLEARBG);
ypos += lineHeight + 4; ypos += lineHeight + 4;
myUIScalerPopup = new PopUpWidget(this, font, xpos, ypos, pwidth,
lineHeight, "UI Scaler: ", lwidth); // Available TIA zoom levels
myUIScalerPopup->appendEntry("Zoom1x", 1); myTIAZoomSlider = new SliderWidget(this, font, xpos, ypos, pwidth, lineHeight,
myUIScalerPopup->appendEntry("Zoom2x", 2); "TIA Zoom: ", lwidth, kTIAZoomChanged);
myUIScalerPopup->appendEntry("Zoom3x", 3); myTIAZoomSlider->setMinValue(1); myTIAZoomSlider->setMaxValue(10);
myUIScalerPopup->appendEntry("Zoom4x", 4); wid.push_back(myTIAZoomSlider);
myUIScalerPopup->appendEntry("Zoom5x", 5); myTIAZoomLabel = new StaticTextWidget(this, font,
myUIScalerPopup->appendEntry("Zoom6x", 6); xpos + myTIAZoomSlider->getWidth() + 4,
wid.push_back(myUIScalerPopup); ypos + 1,
15, fontHeight, "", kTextAlignLeft);
myTIAZoomLabel->setFlags(WIDGET_CLEARBG);
// Move over to the next column // Move over to the next column
xpos += 115; ypos = 10; xpos += 115; ypos = 10;
@ -127,7 +126,7 @@ VideoDialog::VideoDialog(OSystem* osystem, DialogContainer* parent,
// Fullscreen // Fullscreen
myFullscreenCheckbox = new CheckboxWidget(this, font, xpos + 5, ypos, myFullscreenCheckbox = new CheckboxWidget(this, font, xpos + 5, ypos,
"Fullscreen mode"); "Fullscreen mode", kFullScrChanged);
wid.push_back(myFullscreenCheckbox); wid.push_back(myFullscreenCheckbox);
ypos += lineHeight + 4; ypos += lineHeight + 4;
@ -137,23 +136,23 @@ VideoDialog::VideoDialog(OSystem* osystem, DialogContainer* parent,
wid.push_back(myColorLossCheckbox); wid.push_back(myColorLossCheckbox);
ypos += lineHeight + 4; ypos += lineHeight + 4;
// Use dirty rectangle merging
myDirtyRectCheckbox = new CheckboxWidget(this, font, xpos + 5, ypos,
"Dirty-rect merging");
wid.push_back(myDirtyRectCheckbox);
ypos += lineHeight + 4;
// Use desktop res in OpenGL
myUseDeskResCheckbox = new CheckboxWidget(this, font, xpos + 5, ypos,
"Desktop Res in FS");
wid.push_back(myUseDeskResCheckbox);
ypos += lineHeight + 4;
// Use sync to vblank in OpenGL // Use sync to vblank in OpenGL
myUseVSyncCheckbox = new CheckboxWidget(this, font, xpos + 5, ypos, myUseVSyncCheckbox = new CheckboxWidget(this, font, xpos + 5, ypos,
"GL VSync"); "GL VSync");
wid.push_back(myUseVSyncCheckbox); wid.push_back(myUseVSyncCheckbox);
ypos += lineHeight + 20; ypos += lineHeight + 4;
// Center window (in windowed mode)
myCenterCheckbox = new CheckboxWidget(this, font, xpos + 5, ypos,
"Center window (*)");
wid.push_back(myCenterCheckbox);
ypos += lineHeight + 4;
// Add message concerning usage
lwidth = font.getStringWidth("(*) Requires application restart");
new StaticTextWidget(this, font, 10, _h - 38, lwidth, fontHeight,
"(*) Requires application restart",
kTextAlignLeft);
// Add Defaults, OK and Cancel buttons // Add Defaults, OK and Cancel buttons
ButtonWidget* b; ButtonWidget* b;
@ -177,11 +176,19 @@ VideoDialog::VideoDialog(OSystem* osystem, DialogContainer* parent,
addToFocusList(wid); addToFocusList(wid);
#ifdef _WIN32_WCE // Disable certain functions when we know they aren't present
myTIAScalerPopup->clearFlags(WIDGET_ENABLED); #ifndef DISPLAY_GL
myUIScalerPopup->clearFlags(WIDGET_ENABLED); myFilterPopup->clearFlags(WIDGET_ENABLED);
myFSStretchPopup->clearFlags(WIDGET_ENABLED);
myUseVSyncCheckbox->clearFlags(WIDGET_ENABLED);
#endif
#ifndef WINDOWED_SUPPORT
myUIZoomSlider->clearFlags(WIDGET_ENABLED);
myUIZoomLabel->clearFlags(WIDGET_ENABLED);
myTIAZoomSlider->clearFlags(WIDGET_ENABLED);
myTIAZoomLabel->clearFlags(WIDGET_ENABLED);
myFullscreenCheckbox->clearFlags(WIDGET_ENABLED); myFullscreenCheckbox->clearFlags(WIDGET_ENABLED);
myDirtyRectCheckbox->clearFlags(WIDGET_ENABLED); myCenterCheckbox->clearFlags(WIDGET_ENABLED);
#endif #endif
} }
@ -196,7 +203,6 @@ void VideoDialog::loadConfig()
string s; string s;
bool b; bool b;
int i; int i;
double f;
// Renderer setting // Renderer setting
s = instance()->settings().getString("video"); s = instance()->settings().getString("video");
@ -208,14 +214,13 @@ void VideoDialog::loadConfig()
if(s == "linear") myFilterPopup->setSelectedTag(1); if(s == "linear") myFilterPopup->setSelectedTag(1);
else if(s == "nearest") myFilterPopup->setSelectedTag(2); else if(s == "nearest") myFilterPopup->setSelectedTag(2);
// Aspect ratio - another huge hack // GL stretch setting
s = instance()->settings().getString("gl_aspect"); s = instance()->settings().getString("gl_fsmax");
f = instance()->settings().getFloat("gl_aspect"); if(s == "never") myFSStretchPopup->setSelectedTag(1);
if(f < 1.1) { f = 1.1; s = "1.1"; } else if(s == "ui") myFSStretchPopup->setSelectedTag(2);
else if(f > 2.0) { f = 2.0; s = "2.0"; } else if(s == "tia") myFSStretchPopup->setSelectedTag(3);
i = (int)((f * 10) - 10) * 10; else if(s == "always") myFSStretchPopup->setSelectedTag(4);
myAspectRatioSlider->setValue(i); else myFSStretchPopup->setSelectedTag(1);
myAspectRatioLabel->setLabel(s);
// Palette // Palette
s = instance()->settings().getString("palette"); s = instance()->settings().getString("palette");
@ -224,25 +229,17 @@ void VideoDialog::loadConfig()
else if(s == "z26") myPalettePopup->setSelectedTag(3); else if(s == "z26") myPalettePopup->setSelectedTag(3);
else if(s == "user") myPalettePopup->setSelectedTag(4); else if(s == "user") myPalettePopup->setSelectedTag(4);
// TIA Scaler // UI zoom level
s = instance()->settings().getString("scale_tia"); s = instance()->settings().getString("zoom_ui");
if(s == "zoom1x") myTIAScalerPopup->setSelectedTag(1); i = instance()->settings().getInt("zoom_ui");
else if(s == "zoom2x") myTIAScalerPopup->setSelectedTag(2); myUIZoomSlider->setValue(i);
else if(s == "zoom3x") myTIAScalerPopup->setSelectedTag(3); myUIZoomLabel->setLabel(s);
else if(s == "zoom4x") myTIAScalerPopup->setSelectedTag(4);
else if(s == "zoom5x") myTIAScalerPopup->setSelectedTag(5);
else if(s == "zoom6x") myTIAScalerPopup->setSelectedTag(6);
else myTIAScalerPopup->setSelectedTag(0);
// UI Scaler // TIA zoom level
s = instance()->settings().getString("scale_ui"); s = instance()->settings().getString("zoom_tia");
if(s == "zoom1x") myUIScalerPopup->setSelectedTag(1); i = instance()->settings().getInt("zoom_tia");
else if(s == "zoom2x") myUIScalerPopup->setSelectedTag(2); myTIAZoomSlider->setValue(i);
else if(s == "zoom3x") myUIScalerPopup->setSelectedTag(3); myTIAZoomLabel->setLabel(s);
else if(s == "zoom4x") myUIScalerPopup->setSelectedTag(4);
else if(s == "zoom5x") myUIScalerPopup->setSelectedTag(5);
else if(s == "zoom6x") myUIScalerPopup->setSelectedTag(6);
else myUIScalerPopup->setSelectedTag(0);
// FIXME - what to do with this?? // FIXME - what to do with this??
myFrameRateSlider->setEnabled(false); myFrameRateSlider->setEnabled(false);
@ -250,23 +247,20 @@ void VideoDialog::loadConfig()
// Fullscreen // Fullscreen
b = instance()->settings().getBool("fullscreen"); b = instance()->settings().getBool("fullscreen");
myFullscreenCheckbox->setState(b); myFullscreenCheckbox->setState(b);
handleFullscreenChange(b);
// PAL color-loss effect // PAL color-loss effect
b = instance()->settings().getBool("colorloss"); b = instance()->settings().getBool("colorloss");
myColorLossCheckbox->setState(b); myColorLossCheckbox->setState(b);
// Dirty-rect merging (software mode only)
b = instance()->settings().getBool("dirtyrects");
myDirtyRectCheckbox->setState(b);
// Use desktop resolution in fullscreen mode (GL mode only)
b = instance()->settings().getBool("gl_fsmax");
myUseDeskResCheckbox->setState(b);
// Use sync to vertical blank (GL mode only) // Use sync to vertical blank (GL mode only)
b = instance()->settings().getBool("gl_vsync"); b = instance()->settings().getBool("gl_vsync");
myUseVSyncCheckbox->setState(b); myUseVSyncCheckbox->setState(b);
// Center window
b = instance()->settings().getBool("center");
myCenterCheckbox->setState(b);
// Make sure that mutually-exclusive items are not enabled at the same time // Make sure that mutually-exclusive items are not enabled at the same time
i = myRendererPopup->getSelectedTag(); i = myRendererPopup->getSelectedTag();
handleRendererChange(i); handleRendererChange(i);
@ -291,9 +285,19 @@ void VideoDialog::saveConfig()
else if(i == 2) s = "nearest"; else if(i == 2) s = "nearest";
instance()->settings().setString("gl_filter", s); instance()->settings().setString("gl_filter", s);
// GL stretch setting
i = myFSStretchPopup->getSelectedTag();
if(i == 1) s = "never";
else if(i == 2) s = "ui";
else if(i == 3) s = "tia";
else if(i == 4) s = "always";
instance()->settings().setString("gl_fsmax", s);
/*
// Aspect ratio // Aspect ratio
s = myAspectRatioLabel->getLabel(); s = myAspectRatioLabel->getLabel();
instance()->settings().setString("gl_aspect", s); instance()->settings().setString("gl_aspect", s);
*/
// Palette // Palette
i = myPalettePopup->getSelectedTag(); i = myPalettePopup->getSelectedTag();
@ -303,25 +307,13 @@ void VideoDialog::saveConfig()
else if(i == 4) s = "user"; else if(i == 4) s = "user";
instance()->settings().setString("palette", s); instance()->settings().setString("palette", s);
// TIA Scaler
i = myTIAScalerPopup->getSelectedTag();
if(i == 1) s = "zoom1x";
else if(i == 2) s = "zoom2x";
else if(i == 3) s = "zoom3x";
else if(i == 4) s = "zoom4x";
else if(i == 5) s = "zoom5x";
else if(i == 6) s = "zoom6x";
instance()->settings().setString("scale_tia", s);
// UI Scaler // UI Scaler
i = myUIScalerPopup->getSelectedTag(); s = myUIZoomLabel->getLabel();
if(i == 1) s = "zoom1x"; instance()->settings().setString("zoom_ui", s);
else if(i == 2) s = "zoom2x";
else if(i == 3) s = "zoom3x"; // TIA Scaler
else if(i == 4) s = "zoom4x"; s = myTIAZoomLabel->getLabel();
else if(i == 5) s = "zoom5x"; instance()->settings().setString("zoom_tia", s);
else if(i == 6) s = "zoom6x";
instance()->settings().setString("scale_ui", s);
// Framerate FIXME - I haven't figured out what to do with this yet // Framerate FIXME - I haven't figured out what to do with this yet
/* /*
@ -338,18 +330,14 @@ void VideoDialog::saveConfig()
b = myColorLossCheckbox->getState(); b = myColorLossCheckbox->getState();
instance()->settings().setBool("colorloss", b); instance()->settings().setBool("colorloss", b);
// Dirty rectangle merging (software mode only)
b = myDirtyRectCheckbox->getState();
instance()->settings().setBool("dirtyrects", b);
// Use desktop resolution in fullscreen mode (GL mode only)
b = myUseDeskResCheckbox->getState();
instance()->settings().setBool("gl_fsmax", b);
// Use sync to vertical blank (GL mode only) // Use sync to vertical blank (GL mode only)
b = myUseVSyncCheckbox->getState(); b = myUseVSyncCheckbox->getState();
instance()->settings().setBool("gl_vsync", b); instance()->settings().setBool("gl_vsync", b);
// Center window
b = myCenterCheckbox->getState();
instance()->settings().setBool("center", b);
// Finally, issue a complete framebuffer re-initialization // Finally, issue a complete framebuffer re-initialization
instance()->createFrameBuffer(false); instance()->createFrameBuffer(false);
} }
@ -359,43 +347,52 @@ void VideoDialog::setDefaults()
{ {
myRendererPopup->setSelectedTag(1); myRendererPopup->setSelectedTag(1);
myFilterPopup->setSelectedTag(1); myFilterPopup->setSelectedTag(1);
myFSStretchPopup->setSelectedTag(1);
myPalettePopup->setSelectedTag(1); myPalettePopup->setSelectedTag(1);
myTIAScalerPopup->setSelectedTag(2); myUIZoomSlider->setValue(2);
myUIScalerPopup->setSelectedTag(2); myUIZoomLabel->setLabel("2");
myTIAZoomSlider->setValue(2);
myTIAZoomLabel->setLabel("2");
// myFrameRateSlider->setValue(0); // myFrameRateSlider->setValue(0);
// myFrameRateLabel->setLabel("0"); // myFrameRateLabel->setLabel("0");
// For some unknown reason (ie, a bug), slider widgets can only
// take certain ranges of numbers. So we have to fudge things ...
myAspectRatioSlider->setValue(100);
myAspectRatioLabel->setLabel("2.0");
myFullscreenCheckbox->setState(false); myFullscreenCheckbox->setState(false);
myColorLossCheckbox->setState(false); myColorLossCheckbox->setState(false);
myDirtyRectCheckbox->setState(false);
myUseDeskResCheckbox->setState(true);
myUseVSyncCheckbox->setState(true); myUseVSyncCheckbox->setState(true);
myCenterCheckbox->setState(true);
// Make sure that mutually-exclusive items are not enabled at the same time // Make sure that mutually-exclusive items are not enabled at the same time
handleRendererChange(1); // 1 indicates software mode handleRendererChange(1); // 1 indicates software mode
handleFullscreenChange(false); // indicates fullscreen deactivated
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void VideoDialog::handleRendererChange(int item) void VideoDialog::handleRendererChange(int item)
{ {
#ifdef DISPLAY_OPENGL
// When we're in software mode, certain OpenGL-related options are disabled // When we're in software mode, certain OpenGL-related options are disabled
bool gl = (item > 1) ? true : false; bool gl = (item > 1) ? true : false;
myFilterPopup->setEnabled(gl); myFilterPopup->setEnabled(gl);
myAspectRatioSlider->setEnabled(gl); myFSStretchPopup->setEnabled(gl);
myAspectRatioLabel->setEnabled(gl); myFSStretchPopup->setEnabled(gl);
myUseDeskResCheckbox->setEnabled(gl);
myUseVSyncCheckbox->setEnabled(gl); myUseVSyncCheckbox->setEnabled(gl);
// Also, in OpenGL mode, certain software related items are disabled _dirty = true;
myDirtyRectCheckbox->setEnabled(!gl); #endif
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void VideoDialog::handleFullscreenChange(bool enable)
{
#ifdef WINDOWED_SUPPORT
myUIZoomSlider->setEnabled(!enable);
myUIZoomLabel->setEnabled(!enable);
myTIAZoomSlider->setEnabled(!enable);
myTIAZoomLabel->setEnabled(!enable);
_dirty = true; _dirty = true;
#endif
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -417,23 +414,22 @@ void VideoDialog::handleCommand(CommandSender* sender, int cmd,
handleRendererChange(data); handleRendererChange(data);
break; break;
case kAspectRatioChanged: case kUIZoomChanged:
{ myUIZoomLabel->setValue(myUIZoomSlider->getValue());
// This is terribly dirty, but what can we do? break;
float ratio = (((myAspectRatioSlider->getValue() + 9) / 10) / 10.0) + 1.0;
ostringstream r; case kTIAZoomChanged:
if(ratio == 2.0) myTIAZoomLabel->setValue(myTIAZoomSlider->getValue());
r << ratio << ".0";
else
r << ratio;
myAspectRatioLabel->setLabel(r.str());
break; break;
}
case kFrameRateChanged: case kFrameRateChanged:
myFrameRateLabel->setValue(myFrameRateSlider->getValue()); myFrameRateLabel->setValue(myFrameRateSlider->getValue());
break; break;
case kFullScrChanged:
handleFullscreenChange(myFullscreenCheckbox->getState());
break;
default: default:
Dialog::handleCommand(sender, cmd, data, 0); Dialog::handleCommand(sender, cmd, data, 0);
break; break;

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: VideoDialog.hxx,v 1.19 2007-01-01 18:04:55 stephena Exp $ // $Id: VideoDialog.hxx,v 1.20 2007-06-20 16:33:23 stephena Exp $
// //
// Based on code from ScummVM - Scumm Interpreter // Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project // Copyright (C) 2002-2004 The ScummVM project
@ -46,29 +46,32 @@ class VideoDialog : public Dialog
void setDefaults(); void setDefaults();
void handleRendererChange(int item); void handleRendererChange(int item);
void handleFullscreenChange(bool enable);
virtual void handleCommand(CommandSender* sender, int cmd, int data, int id); virtual void handleCommand(CommandSender* sender, int cmd, int data, int id);
private: private:
PopUpWidget* myRendererPopup; PopUpWidget* myRendererPopup;
PopUpWidget* myFilterPopup; PopUpWidget* myFilterPopup;
SliderWidget* myAspectRatioSlider; PopUpWidget* myFSStretchPopup;
StaticTextWidget* myAspectRatioLabel;
PopUpWidget* myPalettePopup; PopUpWidget* myPalettePopup;
PopUpWidget* myTIAScalerPopup; SliderWidget* myUIZoomSlider;
PopUpWidget* myUIScalerPopup; StaticTextWidget* myUIZoomLabel;
SliderWidget* myTIAZoomSlider;
StaticTextWidget* myTIAZoomLabel;
SliderWidget* myFrameRateSlider; SliderWidget* myFrameRateSlider;
StaticTextWidget* myFrameRateLabel; StaticTextWidget* myFrameRateLabel;
CheckboxWidget* myFullscreenCheckbox; CheckboxWidget* myFullscreenCheckbox;
CheckboxWidget* myColorLossCheckbox; CheckboxWidget* myColorLossCheckbox;
CheckboxWidget* myDirtyRectCheckbox;
CheckboxWidget* myUseDeskResCheckbox;
CheckboxWidget* myUseVSyncCheckbox; CheckboxWidget* myUseVSyncCheckbox;
CheckboxWidget* myCenterCheckbox;
enum { enum {
kRendererChanged = 'VDrd', kRendererChanged = 'VDrd',
kAspectRatioChanged = 'VDar', kUIZoomChanged = 'VDui',
kFrameRateChanged = 'VDfr' kTIAZoomChanged = 'VDti',
kFrameRateChanged = 'VDfr',
kFullScrChanged = 'VDfs'
}; };
}; };

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: Widget.cxx,v 1.48 2007-01-15 13:51:55 stephena Exp $ // $Id: Widget.cxx,v 1.49 2007-06-20 16:33:23 stephena Exp $
// //
// Based on code from ScummVM - Scumm Interpreter // Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project // Copyright (C) 2002-2004 The ScummVM project
@ -525,10 +525,8 @@ void SliderWidget::setValue(int value)
<< ", max = " << _valueMax << ", max = " << _valueMax
<< ", min = " << _valueMin << ", min = " << _valueMin
<< endl;*/ << endl;*/
if(value < _valueMin) if(value < _valueMin) value = _valueMin;
value = _valueMin; else if(value > _valueMax) value = _valueMax;
else if(value > _valueMax)
value = _valueMax;
if(value != _value) if(value != _value)
{ {
@ -542,14 +540,18 @@ void SliderWidget::setValue(int value)
void SliderWidget::setMinValue(int value) void SliderWidget::setMinValue(int value)
{ {
_valueMin = value; _valueMin = value;
// _stepValue = (int) ((_valueMax - _valueMin) * 0.05); // Step at 5% intervals
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void SliderWidget::setMaxValue(int value) void SliderWidget::setMaxValue(int value)
{ {
_valueMax = value; _valueMax = value;
// _stepValue = (int) ((_valueMax - _valueMin) * 0.05); // Step at 5% intervals }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void SliderWidget::setStepValue(int value)
{
_stepValue = value;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -637,11 +639,17 @@ void SliderWidget::drawWidget(bool hilite)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int SliderWidget::valueToPos(int value) int SliderWidget::valueToPos(int value)
{ {
if(value < _valueMin) value = _valueMin;
else if(value > _valueMax) value = _valueMax;
return ((_w - _labelWidth - 4) * (value - _valueMin) / (_valueMax - _valueMin)); return ((_w - _labelWidth - 4) * (value - _valueMin) / (_valueMax - _valueMin));
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int SliderWidget::posToValue(int pos) int SliderWidget::posToValue(int pos)
{ {
return (pos) * (_valueMax - _valueMin) / (_w - _labelWidth - 4) + _valueMin; int value = (pos) * (_valueMax - _valueMin) / (_w - _labelWidth - 4) + _valueMin;
// Scale the position to the correct interval (according to step value)
return value - (value % _stepValue);
} }

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: Widget.hxx,v 1.53 2007-01-01 18:04:55 stephena Exp $ // $Id: Widget.hxx,v 1.54 2007-06-20 16:33:23 stephena Exp $
// //
// Based on code from ScummVM - Scumm Interpreter // Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project // Copyright (C) 2002-2004 The ScummVM project
@ -88,7 +88,7 @@ enum {
This is the base class for all widgets. This is the base class for all widgets.
@author Stephen Anthony @author Stephen Anthony
@version $Id: Widget.hxx,v 1.53 2007-01-01 18:04:55 stephena Exp $ @version $Id: Widget.hxx,v 1.54 2007-06-20 16:33:23 stephena Exp $
*/ */
class Widget : public GuiObject class Widget : public GuiObject
{ {
@ -289,6 +289,8 @@ class SliderWidget : public ButtonWidget
int getMinValue() const { return _valueMin; } int getMinValue() const { return _valueMin; }
void setMaxValue(int value); void setMaxValue(int value);
int getMaxValue() const { return _valueMax; } int getMaxValue() const { return _valueMax; }
void setStepValue(int value);
int getStepValue() const { return _stepValue; }
virtual void handleMouseMoved(int x, int y, int button); virtual void handleMouseMoved(int x, int y, int button);
virtual void handleMouseDown(int x, int y, int button, int clickCount); virtual void handleMouseDown(int x, int y, int button, int clickCount);

View File

@ -1,285 +0,0 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2007 by Bradford W. Mott and the Stella team
//
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: FSNodePSP.cxx,v 1.3 2007-01-01 18:04:55 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
//============================================================================
#include "FSNode.hxx"
#include <pspdebug.h>
#include <pspiofilemgr.h>
#include <stdlib.h>
#include <string.h>
#include <sstream>
/*
* Implementation of the Stella file system API based on POSIX for PSP
*/
class PSPFilesystemNode : public AbstractFilesystemNode
{
public:
PSPFilesystemNode();
PSPFilesystemNode(const string& path);
PSPFilesystemNode(const PSPFilesystemNode* node);
virtual string displayName() const { return _displayName; }
virtual bool isValid() const { return _isValid; }
virtual bool isDirectory() const { return _isDirectory; }
virtual string path() const { return _path; }
virtual FSList listDir(ListMode mode = kListDirectoriesOnly) const;
virtual AbstractFilesystemNode* parent() const;
static void stripTailingSlashes(char * buf);
protected:
string _displayName;
bool _isDirectory;
bool _isValid;
string _path;
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
static const char* lastPathComponent(const string& str)
{
const char *start = str.c_str();
const char *cur = start + str.size() - 2;
while (cur > start && *cur != '/')
--cur;
return cur+1;
}
static void stripTailingSlashes(char * buf)
{
char * ptr;
ptr = buf + strlen(buf)-1;
while(*(ptr)=='/') *(ptr--)='\0';
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
static string validatePath(const string& p)
{
string path = p;
if(p.size() <= 0 || p[0] == '/')
path = "ms0:/";
return path;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
AbstractFilesystemNode* FilesystemNode::getRoot()
{
return new PSPFilesystemNode();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
AbstractFilesystemNode* FilesystemNode::getNodeForPath(const string& path)
{
return new PSPFilesystemNode(validatePath(path));
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PSPFilesystemNode::PSPFilesystemNode()
{
const char buf[] = "ms0:/stella/";
_path = buf;
_displayName = string("stella");
_isValid = true;
_isDirectory = true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PSPFilesystemNode::PSPFilesystemNode(const string& p)
{
string path = validatePath(p);
Int32 len = 0, offset = path.size();
SceIoStat st;
_path = path;
// Extract last component from path
const char *str = path.c_str();
while (offset > 0 && str[offset-1] == '/')
offset--;
while (offset > 0 && str[offset-1] != '/')
{
len++;
offset--;
}
_displayName = string(str + offset, len);
// Check whether it is a directory, and whether the file actually exists
//_isValid = (0 == stat(_path.c_str(), &st));
//_isDirectory = S_ISDIR(st.st_mode);
_isValid = (0 == sceIoGetstat(_path.c_str(), &st));
_isDirectory = FIO_S_ISDIR(st.st_mode);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PSPFilesystemNode::PSPFilesystemNode(const PSPFilesystemNode* node)
{
_displayName = node->_displayName;
_isValid = node->_isValid;
_isDirectory = node->_isDirectory;
_path = node->_path;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FSList PSPFilesystemNode::listDir(ListMode mode) const
{
// assert(_isDirectory);
FSList myList;
SceUID dfd = sceIoDopen (_path.c_str());
SceIoDirent *dp;
dp = (SceIoDirent*)malloc(sizeof(SceIoDirent));
#ifdef PSP_DEBUG
fprintf(stdout,"PSPFilesystemNode::listDir: dir='%s'\n",_path.c_str());
#endif
if (!dfd){
#ifdef PSP_DEBUG
fprintf(stdout,"PSPFilesystemNode::listDir: no dir handle\n");
#endif
return myList;
}
while (sceIoDread(dfd,dp) > 0){
if (dp->d_name[0]=='.')
continue;
PSPFilesystemNode entry;
entry._displayName = dp->d_name;
entry._path = _path;
if (entry._path.length() > 0 && entry._path[entry._path.length()-1] != '/')
entry._path += "/";
entry._path += dp->d_name;
entry._isDirectory = dp->d_stat.st_attr & FIO_SO_IFDIR;
// Honor the chosen mode
if ((mode == kListFilesOnly && entry._isDirectory) ||
(mode == kListDirectoriesOnly && !entry._isDirectory))
continue;
if (entry._isDirectory)
entry._path += "/";
myList.push_back(wrap(new PSPFilesystemNode(&entry)));
}
sceIoDclose(dfd);
free(dp);
return myList;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
AbstractFilesystemNode *PSPFilesystemNode::parent() const
{
if (_path == "/")
return 0;
PSPFilesystemNode* p = new PSPFilesystemNode();
const char *start = _path.c_str();
const char *end = lastPathComponent(_path);
p->_path = string(start, end - start);
p->_displayName = lastPathComponent(p->_path);
p->_isValid = true;
p->_isDirectory = true;
return p;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool AbstractFilesystemNode::fileExists(const string& path)
{
SceIoStat st;
#ifdef PSP_DEBUG
fprintf(stdout,"AbstractFilesystemNode::fileExists '%s'\n",path.c_str());
#endif
if(sceIoGetstat(path.c_str(), &st) != 0){
#ifdef PSP_DEBUG
fprintf(stdout,"AbstractFilesystemNode::fileExists error \n");
#endif
return false;
}
#ifdef PSP_DEBUG
fprintf(stdout,"AbstractFilesystemNode::fileExists return '%i'\n", !FIO_SO_ISREG(st.st_mode));
#endif
return !FIO_SO_ISREG(st.st_mode);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool AbstractFilesystemNode::dirExists(const string& in)
{
char tmp_buf[1024];
strncpy(tmp_buf,in.c_str(),1023);
stripTailingSlashes(tmp_buf);
string path = (char*)tmp_buf;
#ifdef PSP_DEBUG
fprintf(stdout,"AbstractFilesystemNode::dirExists '%s'\n", path.c_str());
#endif
SceIoStat st;
if(sceIoGetstat(path.c_str(), &st) != 0)
return false;
#ifdef PSP_DEBUG
fprintf(stdout,"AbstractFilesystemNode::dirExists return '%i'\n", !FIO_SO_ISDIR(st.st_mode));
#endif
return !FIO_SO_ISDIR(st.st_mode);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool AbstractFilesystemNode::makeDir(const string& path)
{
return sceIoMkdir(path.c_str(), 0777) == 0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string AbstractFilesystemNode::modTime(const string& in)
{
char tmp_buf[1024];
strncpy(tmp_buf,in.c_str(),1023);
stripTailingSlashes(tmp_buf);
string path = (char*)tmp_buf;
SceIoStat st;
#ifdef PSP_DEBUG
fprintf(stdout,"AbstractFilesystemNode::modTime '%s'\n",path.c_str());
#endif
if(sceIoGetstat(path.c_str(), &st) < 0){
#ifdef PSP_DEBUG
fprintf(stdout,"AbstractFilesystemNode::modTime returns error\n");
#endif
return "";
}
ostringstream buf;
buf << (unsigned short)st.st_mtime.year
<< (unsigned short)st.st_mtime.month
<< (unsigned short)st.st_mtime.day
<< (unsigned short)st.st_mtime.hour
<< (unsigned short)st.st_mtime.minute
<< (unsigned short)st.st_mtime.second;
#ifdef PSP_DEBUG
fprintf(stdout,"AbstractFilesystemNode::modTime returns '%s'\n",buf.str().c_str());
#endif
return buf.str();
}

View File

@ -1,119 +0,0 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2007 by Bradford W. Mott and the Stella team
//
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: FrameBufferPSP.cxx,v 1.3 2007-01-01 18:04:55 stephena Exp $
//============================================================================
#include <SDL.h>
#include <SDL_syswm.h>
#include <sstream>
#include "Console.hxx"
#include "FrameBufferPSP.hxx"
#include "MediaSrc.hxx"
#include "Settings.hxx"
#include "OSystem.hxx"
#include "Font.hxx"
#include "GuiUtils.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FrameBufferPSP::FrameBufferPSP(OSystem* osystem)
: FrameBufferSoft(osystem)
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FrameBufferPSP::~FrameBufferPSP()
{
delete myRectList;
delete myOverlayRectList;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool FrameBufferPSP::initSubsystem()
{
// Set up the rectangle list to be used in the dirty update
delete myRectList;
myRectList = new RectList();
delete myOverlayRectList;
myOverlayRectList = new RectList();
#ifdef PSP_DEBUG
fprintf(stdout, "FrameBufferPSP::initSubsystem\n");
#endif
if(!myRectList || !myOverlayRectList)
{
cerr << "ERROR: Unable to get memory for SDL rects" << endl;
return false;
}
// Create the screen
if(!createScreen())
return false;
// Show some info
if(myOSystem->settings().getBool("showinfo"))
cout << "Video rendering: Software mode" << endl << endl;
// Precompute the GUI palette
// We abuse the concept of 'enum' by referring directly to the integer values
for(uInt8 i = 0; i < kNumColors-256; i++)
myPalette[i+256] = mapRGB(ourGUIColors[i][0], ourGUIColors[i][1], ourGUIColors[i][2]);
return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool FrameBufferPSP::createScreen()
{
myScreenDim.x = myScreenDim.y = 0;
myScreenDim.w = myBaseDim.w;
myScreenDim.h = myBaseDim.h;
// In software mode, the image and screen dimensions are always the same
myImageDim = myScreenDim;
if (mySDLFlags & SDL_HWSURFACE )
{
/* double buff is broken */
mySDLFlags = SDL_HWSURFACE;
myScreenDim.w = myDesktopDim.w;
myScreenDim.h = myDesktopDim.w;
#ifdef PSP_DEBUG
fprintf(stdout, "FrameBufferPSP::createScreen Hardware Mode "
"myScreenDim.w='%i' myScreenDim.h='%i'\n",
myScreenDim.w,myScreenDim.h);
#endif
}
else
{
#ifdef PSP_DEBUG
fprintf(stdout, "FrameBufferPSP::createScreen Software Mode "
"myScreenDim.w='%i' myScreenDim.h='%i'\n",
myScreenDim.w,myScreenDim.h);
#endif
}
myScreen = SDL_SetVideoMode(myScreenDim.w, myScreenDim.h, 0, mySDLFlags);
if(myScreen == NULL)
{
fprintf(stdout,"ERROR: Unable to open SDL window: %s\n",SDL_GetError());
return false;
}
myOSystem->eventHandler().refreshDisplay();
return true;
}

View File

@ -1,73 +0,0 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2007 by Bradford W. Mott and the Stella team
//
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: FrameBufferPSP.hxx,v 1.4 2007-01-01 18:04:55 stephena Exp $
//============================================================================
#ifndef FRAMEBUFFER_PSP_HXX
#define FRAMEBUFFER_PSP_HXX
#include "Font.hxx"
#include "bspf.hxx"
#include "GuiUtils.hxx"
#include "FrameBufferSoft.hxx"
/**
This class implements an SDL software framebuffer.
@author Stephen Anthony
@version $Id: FrameBufferPSP.hxx,v 1.4 2007-01-01 18:04:55 stephena Exp $
*/
class FrameBufferPSP : public FrameBufferSoft
{
public:
/**
Creates a new software framebuffer
*/
FrameBufferPSP(OSystem* osystem);
/**
Destructor
*/
virtual ~FrameBufferPSP();
//////////////////////////////////////////////////////////////////////
// The following methods are derived from FrameBuffer.hxx
//////////////////////////////////////////////////////////////////////
/**
This method is called to initialize software video mode.
Return false if any operation fails, otherwise return true.
*/
virtual bool initSubsystem();
/**
This method is called to query the type of the FrameBuffer.
*/
virtual BufferType type() { return kSoftBuffer; }
/**
This method is called whenever the screen needs to be recreated.
It updates the global screen variable.
*/
virtual bool createScreen();
};
#endif

View File

@ -1,172 +0,0 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2007 by Bradford W. Mott and the Stella team
//
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: OSystemPSP.cxx,v 1.8 2007-01-01 18:04:55 stephena Exp $
//============================================================================
#include <cstdlib>
#include <sstream>
#include <fstream>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <pspkernel.h>
#include <psppower.h>
#include "bspf.hxx"
#include "OSystem.hxx"
#include "OSystemPSP.hxx"
#ifdef HAVE_GETTIMEOFDAY
#include <time.h>
#include <sys/time.h>
#endif
/**
Each derived class is responsible for calling the following methods
in its constructor:
setBaseDir()
setStateDir()
setPropertiesFiles()
setConfigFiles()
setCacheFile()
And for initializing the following variables:
myDriverList (a StringList)
See OSystem.hxx for a further explanation
*/
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OSystemPSP::OSystemPSP(const string& path) : OSystem()
{
// First set variables that the OSystem needs
string basedir = string("ms0:/stella");
setBaseDir(basedir);
string statedir = basedir + "/state";
setStateDir(statedir);
string userPropertiesFile = basedir + "/stella.pro";
string systemPropertiesFile = "/etc/stella.pro";
setConfigFiles(userPropertiesFile, systemPropertiesFile);
string userConfigFile = basedir + "/stellarc";
string systemConfigFile = "/etc/stellarc";
setConfigFiles(userConfigFile, systemConfigFile);
string cacheFile = basedir + "/stella.cache";
setCacheFile(cacheFile);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OSystemPSP::~OSystemPSP()
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void OSystemPSP::mainLoop()
{
// These variables are common to both timing options
// and are needed to calculate the overall frames per second.
uInt32 frameTime = 0, numberOfFrames = 0;
// Set up less accurate timing stuff
uInt32 startTime, virtualTime, currentTime;
// Set the base for the timers
virtualTime = getTicks();
frameTime = 0;
// Overclock CPU to 333MHz
if (settings().getBool("pspoverclock"))
{
scePowerSetClockFrequency(333,333,166);
fprintf(stderr,"OSystemPSP::mainLoop overclock to 333\n");
}
else
{
fprintf(stderr,"OSystemPSP::mainLoop NOT overclock\n");
}
// Main game loop
for(;;)
{
// Exit if the user wants to quit
if(myEventHandler->doQuit())
break;
startTime = getTicks();
myEventHandler->poll(startTime);
myFrameBuffer->update();
currentTime = getTicks();
virtualTime += myTimePerFrame;
if(currentTime < virtualTime)
SDL_Delay((virtualTime - currentTime)/1000);
currentTime = getTicks() - startTime;
frameTime += currentTime;
++numberOfFrames;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 OSystemPSP::getTicks()
{
#if defined(HAVE_GETTIMEOFDAY)
timeval now;
gettimeofday(&now, 0);
return (uInt32) (now.tv_sec * 1000000 + now.tv_usec);
#else
return (uInt32) SDL_GetTicks() * 1000;
#endif
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void OSystemPSP::getScreenDimensions(int& width, int& height)
{
width = 480;
height = 272;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void OSystemPSP::setDefaultJoymap()
{
myEventHandler->setDefaultJoyMapping(Event::TakeSnapshot, 0, 0); // Triangle
myEventHandler->setDefaultJoyMapping(Event::LoadState, 0, 1); // Circle
myEventHandler->setDefaultJoyMapping(Event::JoystickZeroFire, 0, 2); // Cross
myEventHandler->setDefaultJoyMapping(Event::SaveState, 0, 3); // Square
myEventHandler->setDefaultJoyMapping(Event::MenuMode, 0, 4); // Left trigger
myEventHandler->setDefaultJoyMapping(Event::CmdMenuMode, 0, 5); // Right trigger
myEventHandler->setDefaultJoyMapping(Event::JoystickZeroDown, 0, 6); // Down
myEventHandler->setDefaultJoyMapping(Event::JoystickZeroLeft, 0, 7); // Left
myEventHandler->setDefaultJoyMapping(Event::JoystickZeroUp, 0, 8); // Up
myEventHandler->setDefaultJoyMapping(Event::JoystickZeroRight, 0, 9); // Right
myEventHandler->setDefaultJoyMapping(Event::ConsoleSelect, 0, 10); // Select
myEventHandler->setDefaultJoyMapping(Event::ConsoleReset, 0, 11); // Start
myEventHandler->setDefaultJoyMapping(Event::NoType, 0, 12); // Home
myEventHandler->setDefaultJoyMapping(Event::NoType, 0, 13); // Hold
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void OSystemPSP::setDefaultJoyAxisMap()
{
}

View File

@ -1,86 +0,0 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2007 by Bradford W. Mott and the Stella team
//
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: OSystemPSP.hxx,v 1.7 2007-01-01 18:04:55 stephena Exp $
//============================================================================
#ifndef OSYSTEM_PSP_HXX
#define OSYSTEM_PSP_HXX
#include "bspf.hxx"
/**
This class defines PSP-specific settings.
@author Stephen Anthony
@version $Id: OSystemPSP.hxx,v 1.7 2007-01-01 18:04:55 stephena Exp $
*/
class OSystemPSP : public OSystem
{
public:
/**
Create a new PSP-specific operating system object
*/
OSystemPSP(const string& path);
/**
Destructor
*/
virtual ~OSystemPSP();
public:
/**
This method runs the main loop. Since different platforms
may use different timing methods and/or algorithms, this method has
been abstracted to each platform.
*/
void mainLoop();
/**
This method returns number of ticks in microseconds.
@return Current time in microseconds.
*/
uInt32 getTicks();
/**
This method determines the default mapping of joystick buttons to
Stella events for the PSP device.
*/
void setDefaultJoymap();
/**
This method determines the default mapping of joystick axis to
Stella events for for the PSP device.
*/
void setDefaultJoyAxisMap();
/**
This method queries the dimensions of the screen for this hardware.
*/
virtual void getScreenDimensions(int& width, int& height);
};
// FIXME - this doesn't even compile any more ...
/*
kJDirUp = 8, kJDirUpLeft = -1,
kJDirLeft = 7, kJDirDownLeft = -2,
kJDirDown = 6, kJDirDownRight = -3,
kJDirRight = 9, kJDirUpRight = -4
*/
#endif

View File

@ -1,39 +0,0 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2007 by Bradford W. Mott and the Stella team
//
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: SettingsPSP.cxx,v 1.6 2007-01-01 18:04:55 stephena Exp $
//============================================================================
#include "bspf.hxx"
#include "Settings.hxx"
#include "SettingsPSP.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SettingsPSP::SettingsPSP(OSystem* osystem)
: Settings(osystem)
{
set("accurate", "false");
set("zoom", "1");
set("romdir", "ms0:/stella/roms/");
set("ssdir", "ms0:/stella/snapshots/");
set("sound", "true");
set("pspoverclock", "false");
set("joymouse", "true");
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SettingsPSP::~SettingsPSP()
{
}

View File

@ -1,46 +0,0 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2007 by Bradford W. Mott and the Stella team
//
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: SettingsPSP.hxx,v 1.3 2007-01-01 18:04:55 stephena Exp $
//============================================================================
#ifndef SETTINGS_PSP_HXX
#define SETTINGS_PSP_HXX
class OSystem;
#include "bspf.hxx"
/**
This class defines PSP-like OS's (Linux) system specific settings.
@author Stephen Anthony
@version $Id: SettingsPSP.hxx,v 1.3 2007-01-01 18:04:55 stephena Exp $
*/
class SettingsPSP : public Settings
{
public:
/**
Create a new PSP settings object
*/
SettingsPSP(OSystem* osystem);
/**
Destructor
*/
virtual ~SettingsPSP();
};
#endif

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 153 KiB

View File

@ -1,41 +0,0 @@
; Stella configuration file
;
; Lines starting with ';' are comments and are ignored.
; Spaces and tabs are ignored.
;
; Format MUST be as follows:
; command = value
;
; Commmands are the same as those specified on the commandline,
; without the '-' character.
;
; Values are the same as those allowed on the commandline.
; Boolean values are specified as 1 (or true) and 0 (or false)
;
video = soft
video_driver =
gl_filter = nearest
gl_aspect = 2.0
gl_fsmax = false
zoom = 1
fullscreen = false
grabmouse = 1
center = true
palette = standard
debugheight = 20
sound = 1
fragsize = 1024
volume = 100
keymap =
joymap =
paddle = 0
showinfo = false
ssdir = ms0:/stella/snapshots/
ssname = romname
sssingle = false
romdir = ms0:/stella/roms/
lastrom =
modtime =
accurate = false
break =
pspoverclock = false

View File

@ -1,12 +0,0 @@
MODULE := src/psp
MODULE_OBJS := \
src/psp/FSNodePSP.o \
src/psp/OSystemPSP.o \
src/psp/SettingsPSP.o \
src/psp/FrameBufferPSP.o
MODULE_DIRS += \
src/psp
# Include common rules
include $(srcdir)/common.rules

View File

@ -1,175 +0,0 @@
/* SCE CONFIDENTIAL
PSP(TM) Programmer Tool Runtime Library Release 1.5.0
*
* Copyright (C) 2005 Sony Computer Entertainment Inc.
* All Rights Reserved.
*
*/
/*
*
* PSP(TM) integer types
*
* pspstdint.h
*
* Version Date Design Log
* --------------------------------------------------------------------
* 0.00 2005-01-19 kono the first version
*/
#ifndef _SCE_PSPSTDINT_H
#define _SCE_PSPSTDINT_H
/* Exact-width integer types */
#ifndef _SCE_PSPSTDINT_int8_t_DEFINED
#define _SCE_PSPSTDINT_int8_t_DEFINED
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef short int16_t;
typedef unsigned short uint16_t;
typedef int int32_t;
typedef unsigned int uint32_t;
#if defined(__GNUC__)
__extension__ typedef long long int64_t __attribute__((mode(DI)));
__extension__ typedef unsigned long long uint64_t __attribute__((mode(DI)));
#else /* defined(__GNUC__) */
typedef long long int64_t;
typedef unsigned long long uint64_t;
#endif /* defined(__GNUC__) */
#endif /* _SCE_PSPSTDINT_int8_t_DEFINED */
/* Minimum-width integer types */
#ifndef _SCE_PSPSTDINT_int_least8_t_DEFINED
#define _SCE_PSPSTDINT_int_least8_t_DEFINED
typedef signed char int_least8_t;
typedef unsigned char uint_least8_t;
typedef short int_least16_t;
typedef unsigned short uint_least16_t;
typedef int int_least32_t;
typedef unsigned int uint_least32_t;
#if defined(__GNUC__)
__extension__ typedef long long int_least64_t __attribute__((mode(DI)));
__extension__ typedef unsigned long long uint_least64_t __attribute__((mode(DI)));
#else /* defined(__GNUC__) */
typedef long long int_least64_t;
typedef unsigned long long uint_least64_t;
#endif /* defined(__GNUC__) */
#endif /* _SCE_PSPSTDINT_int_least8_t_DEFINED */
/* Fastest minimum-width integer types */
#ifndef _SCE_PSPSTDINT_int_fast8_t_DEFINED
#define _SCE_PSPSTDINT_int_fast8_t_DEFINED
typedef char int_fast8_t;
typedef unsigned char uint_fast8_t;
typedef int int_fast16_t;
typedef unsigned int uint_fast16_t;
typedef int int_fast32_t;
typedef unsigned int uint_fast32_t;
#if defined(__GNUC__)
__extension__ typedef long long int_fast64_t __attribute__((mode(DI)));
__extension__ typedef unsigned long long uint_fast64_t __attribute__((mode(DI)));
#else /* defined(__GNUC__) */
typedef long long int_fast64_t;
typedef unsigned long long uint_fast64_t;
#endif /* defined(__GNUC__) */
#endif /* _SCE_PSPSTDINT_int_fast8_t_DEFINED */
/* Integer types capable of holding object pointers */
#ifndef _SCE_PSPSTDINT_intptr_t_DEFINED
#define _SCE_PSPSTDINT_intptr_t_DEFINED
typedef int intptr_t;
typedef unsigned int uintptr_t;
#endif /* _SCE_PSPSTDINT_intptr_t_DEFINED */
/* Gereat-width integer types */
#ifndef _SCE_PSPSTDINT_intmax_t_DEFINED
#define _SCE_PSPSTDINT_intmax_t_DEFINED
#if defined(__GNUC__)
typedef long long intmax_t __attribute__((mode(DI)));
typedef unsigned long long uintmax_t __attribute__((mode(DI)));
#else /* defined(__GNUC__) */
typedef long long intmax_t;
typedef unsigned long long uintmax_t;
#endif /* defined(__GNUC__) */
#endif /* _SCE_PSPSTDINT_intmax_t_DEFINED */
/* Limits of specified-width intger types */
#if (!(defined(_LANGUAGE_C_PLUS_PLUS)||defined(__cplusplus)||defined(c_plusplus)))||defined(__STDC_CONSTANT_MACROS)
/* Limits of exact-width integer types */
#define INT8_MIN (-128)
#define INT16_MIN (-32767-1)
#define INT32_MIN (-2147483647-1)
#define INT64_MIN (-9223372036854775807LL-1)
#define INT8_MAX (127)
#define INT16_MAX (32767)
#define INT32_MAX (2147483647)
#define INT64_MAX (9223372036854775807LL)
#define UINT8_MAX (255)
#define UINT16_MAX (65535)
#define UINT32_MAX (4294967295U)
#define UINT64_MAX (18446744073709551615ULL)
/* Limits of minimum-width integer types */
#define INT_LEAST8_MIN (-128)
#define INT_LEAST16_MIN (-32767-1)
#define INT_LEAST32_MIN (-2147483647-1)
#define INT_LEAST64_MIN (-9223372036854775807LL-1)
#define INT_LEAST8_MAX (127)
#define INT_LEAST16_MAX (32767)
#define INT_LEAST32_MAX (2147483647)
#define INT_LEAST64_MAX (9223372036854775807LL)
#define UINT_LEAST8_MAX (255)
#define UINT_LEAST16_MAX (65535)
#define UINT_LEAST32_MAX (4294967295U)
#define UINT_LEAST64_MAX (18446744073709551615ULL)
/* Limits of fastest minimum-width integer types */
#define INT_FAST8_MIN (-128)
#define INT_FAST16_MIN (-2147483647-1)
#define INT_FAST32_MIN (-2147483647-1)
#define INT_FAST64_MIN (-9223372036854775807LL-1)
#define INT_FAST8_MAX (127)
#define INT_FAST16_MAX (2147483647)
#define INT_FAST32_MAX (2147483647)
#define INT_FAST64_MAX (9223372036854775807LL)
#define UINT_FAST8_MAX (255)
#define UINT_FAST16_MAX (4294967295U)
#define UINT_FAST32_MAX (4294967295U)
#define UINT_FAST64_MAX (18446744073709551615ULL)
/* Limits of integer types capable of holding object pointers */
#define INTPTR_MIN (-2147483647-1)
#define INTPTR_MAX (2147483647)
#define UINTPTR_MAX (4294967295U)
/* Limits of greates-width intger types */
#define INTMAX_MIN (-9223372036854775807LL-1)
#define INTMAX_MAX (9223372036854775807LL)
#define UINTMAX_MAX (18446744073709551615ULL)
/* Macros for minimum-width integer constants */
#define INT8_C(c) c
#define INT16_C(c) c
#define INT32_C(c) c
#define INT64_C(c) c ## LL
#define UINT8_C(c) c ## U
#define UINT16_C(c) c ## U
#define UINT32_C(c) c ## U
#define UINT64_C(c) c ## ULL
/* Macros for greatest-width integer constants */
#define INTMAX_C(c) c ## LL
#define UINTMAX_C(c) c ## ULL
#endif /* (!(defined(_LANGUAGE_C_PLUS_PLUS)||defined(__cplusplus)||defined(c_plusplus)))||defined(__STDC_CONSTANT_MACROS) */
#endif /* _SCE_PSPSTDINT_H */

View File

@ -0,0 +1,72 @@
#include <iostream>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <cstring>
using namespace std;
typedef unsigned char uInt8;
typedef unsigned int uInt32;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int searchForBytes(const uInt8* image, uInt32 imagesize,
const uInt8* signature, uInt32 sigsize)
{
uInt32 count = 0;
for(uInt32 i = 0; i < imagesize - sigsize; ++i)
{
uInt32 matches = 0;
for(uInt32 j = 0; j < sigsize; ++j)
{
if(image[i+j] == signature[j])
++matches;
else
break;
}
if(matches == sigsize)
++count;
}
return count;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int main(int ac, char* av[])
{
if(ac != 3)
{
cout << "usage: " << av[0] << " <filename> <hex pattern>\n";
exit(0);
}
ifstream in(av[1], ios_base::binary);
in.seekg(0, ios::end);
int i_size = (int) in.tellg();
in.seekg(0, ios::beg);
uInt8* image = new uInt8[i_size];
in.read((char*)(image), i_size);
in.close();
int s_size = 0;
uInt8* sig = new uInt8[strlen(av[2])/2];
istringstream buf(av[2]);
uInt32 c;
while(buf >> hex >> c)
{
sig[s_size++] = (uInt8)c;
// cerr << "character = " << hex << (int)sig[s_size-1] << endl;
}
// cerr << "sig size = " << hex << s_size << endl;
int result = searchForBytes(image, i_size, sig, s_size);
if(result > 0)
cout << setw(3) << result << " hits: \'" << av[2] << "\' - \"" << av[1] << "\"" << endl;
delete[] image;
delete[] sig;
return 0;
}

View File

@ -13,11 +13,10 @@
// 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: OSystemUNIX.cxx,v 1.25 2007-01-01 18:04:55 stephena Exp $ // $Id: OSystemUNIX.cxx,v 1.26 2007-06-20 16:33:23 stephena Exp $
//============================================================================ //============================================================================
#include <SDL.h> #include <SDL.h>
#include <SDL_syswm.h>
#include <cstdlib> #include <cstdlib>
#include <sstream> #include <sstream>
@ -81,28 +80,3 @@ uInt32 OSystemUNIX::getTicks()
return (uInt32) SDL_GetTicks() * 1000; return (uInt32) SDL_GetTicks() * 1000;
#endif #endif
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void OSystemUNIX::getScreenDimensions(int& width, int& height)
{
// We might need to temporarily enable VIDEO support to check
// screen dimensions
bool isAlreadyInitialized = (SDL_WasInit(SDL_INIT_VIDEO) & SDL_INIT_VIDEO) > 0;
if(!isAlreadyInitialized)
SDL_Init(SDL_INIT_VIDEO);
SDL_SysWMinfo myWMInfo;
SDL_VERSION(&myWMInfo.version);
if(SDL_GetWMInfo(&myWMInfo) > 0 && myWMInfo.subsystem == SDL_SYSWM_X11)
{
myWMInfo.info.x11.lock_func();
width = DisplayWidth(myWMInfo.info.x11.display,
DefaultScreen(myWMInfo.info.x11.display));
height = DisplayHeight(myWMInfo.info.x11.display,
DefaultScreen(myWMInfo.info.x11.display));
myWMInfo.info.x11.unlock_func();
}
if(!isAlreadyInitialized)
SDL_QuitSubSystem(SDL_INIT_VIDEO);
}

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: OSystemUNIX.hxx,v 1.14 2007-01-01 18:04:55 stephena Exp $ // $Id: OSystemUNIX.hxx,v 1.15 2007-06-20 16:33:23 stephena Exp $
//============================================================================ //============================================================================
#ifndef OSYSTEM_UNIX_HXX #ifndef OSYSTEM_UNIX_HXX
@ -21,12 +21,11 @@
#include "bspf.hxx" #include "bspf.hxx"
/** /**
This class defines UNIX-like OS's (Linux) system specific settings. This class defines UNIX-like OS's (Linux) system specific settings.
@author Stephen Anthony @author Stephen Anthony
@version $Id: OSystemUNIX.hxx,v 1.14 2007-01-01 18:04:55 stephena Exp $ @version $Id: OSystemUNIX.hxx,v 1.15 2007-06-20 16:33:23 stephena Exp $
*/ */
class OSystemUNIX : public OSystem class OSystemUNIX : public OSystem
{ {
@ -41,19 +40,12 @@ class OSystemUNIX : public OSystem
*/ */
virtual ~OSystemUNIX(); virtual ~OSystemUNIX();
public:
/** /**
This method returns number of ticks in microseconds. This method returns number of ticks in microseconds.
@return Current time in microseconds. @return Current time in microseconds.
*/ */
uInt32 getTicks(); uInt32 getTicks();
/**
This method queries the dimensions of the screen for this hardware.
It is assumed that a UNIX SDL framebuffer is using X11.
*/
void getScreenDimensions(int& width, int& height);
}; };
#endif #endif