Added preliminary framework for using advanced scalers. Right now,

functionality is exactly the same as before; Alt-Equals goes to the
next valid scaler, and Alt-Minus goes to the previous one.

What were previously zoomed modes are now treated as scalers, named
'Zoom1x', 'Zoom2x', etc.  Various scalexx and hqxx modes will also be made
available.

For now, and probably forever, these advanced scaling modes will only
be available for OpenGL, since if you don't have a card that can handle
GL well, the scalers will probably be too much anyway.  Also, the advanced
scaling will not be available in UI mode, only OpenGL emulation mode.

The UI (Launcher, Debugger) and emulation modes are now scaled separately,
specified with the new settings 'scale_ui' and 'scale_tia'.  The 'zoom'
setting has been removed.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1133 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2006-10-14 20:08:29 +00:00
parent bffb697b34
commit db3ed5372d
11 changed files with 457 additions and 180 deletions

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: FrameBufferGL.cxx,v 1.62 2006-09-08 14:35:20 stephena Exp $
// $Id: FrameBufferGL.cxx,v 1.63 2006-10-14 20:08:29 stephena Exp $
//============================================================================
#ifdef DISPLAY_OPENGL
@ -75,6 +75,7 @@ FrameBufferGL::FrameBufferGL(OSystem* osystem)
myTextureID(0),
myFilterParam(GL_NEAREST),
myFilterParamName("GL_NEAREST"),
myZoomLevel(1), // FIXME
myFSScaleFactor(1.0),
myDirtyFlag(true)
{
@ -259,6 +260,14 @@ void FrameBufferGL::setAspectRatio()
theAspectRatio = 1.0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferGL::setScaler(Scaler scaler)
{
// TODO - have this inspect 'scaler' and set the appropriate state
cerr << "FrameBufferGL::setScaler: zoom = " << scaler.zoom << endl;
myZoomLevel = scaler.zoom;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool FrameBufferGL::createScreen()
{
@ -548,8 +557,8 @@ void FrameBufferGL::drawBitmap(uInt32* bitmap, Int32 tx, Int32 ty,
void FrameBufferGL::translateCoords(Int32* x, Int32* y)
{
// Wow, what a mess :)
*x = (Int32) (((*x - myImageDim.x) / (theZoomLevel * myFSScaleFactor * theAspectRatio)));
*y = (Int32) (((*y - myImageDim.y) / (theZoomLevel * myFSScaleFactor)));
*x = (Int32) (((*x - myImageDim.x) / (myZoomLevel * myFSScaleFactor * theAspectRatio)));
*y = (Int32) (((*y - myImageDim.y) / (myZoomLevel * myFSScaleFactor)));
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -627,7 +636,7 @@ bool FrameBufferGL::createTextures()
p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, myFilterParam);
p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, myFilterParam);
p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
myTexture->pixels);
myTexture->pixels);
p_glDisable(GL_DEPTH_TEST);
p_glDisable(GL_CULL_FACE);
@ -646,8 +655,8 @@ void FrameBufferGL::setDimensions(GLdouble* orthoWidth, GLdouble* orthoHeight)
// We have to determine final image dimensions as well as screen dimensions
myImageDim.x = 0;
myImageDim.y = 0;
myImageDim.w = (Uint16) (myBaseDim.w * theZoomLevel * theAspectRatio);
myImageDim.h = (Uint16) (myBaseDim.h * theZoomLevel);
myImageDim.w = (Uint16) (myBaseDim.w * myZoomLevel * theAspectRatio);
myImageDim.h = (Uint16) (myBaseDim.h * myZoomLevel);
myScreenDim = myImageDim;
myFSScaleFactor = 1.0f;
@ -719,13 +728,13 @@ void FrameBufferGL::setDimensions(GLdouble* orthoWidth, GLdouble* orthoHeight)
myImageDim.x = (myScreenDim.w - myImageDim.w) / 2;
myImageDim.y = (myScreenDim.h - myImageDim.h) / 2;
*orthoWidth = (GLdouble) (myImageDim.w / (theZoomLevel * theAspectRatio * myFSScaleFactor));
*orthoHeight = (GLdouble) (myImageDim.h / (theZoomLevel * myFSScaleFactor));
*orthoWidth = (GLdouble) (myImageDim.w / (myZoomLevel * theAspectRatio * myFSScaleFactor));
*orthoHeight = (GLdouble) (myImageDim.h / (myZoomLevel * myFSScaleFactor));
}
else
{
*orthoWidth = (GLdouble) (myImageDim.w / (theZoomLevel * theAspectRatio));
*orthoHeight = (GLdouble) (myImageDim.h / theZoomLevel);
*orthoWidth = (GLdouble) (myImageDim.w / (myZoomLevel * theAspectRatio));
*orthoHeight = (GLdouble) (myImageDim.h / myZoomLevel);
}
/*
cerr << "myImageDim.x = " << myImageDim.x << ", myImageDim.y = " << myImageDim.y << endl;

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: FrameBufferGL.hxx,v 1.31 2006-03-25 00:34:17 stephena Exp $
// $Id: FrameBufferGL.hxx,v 1.32 2006-10-14 20:08:29 stephena Exp $
//============================================================================
#ifndef FRAMEBUFFER_GL_HXX
@ -37,7 +37,7 @@ class GUI::Font;
This class implements an SDL OpenGL framebuffer.
@author Stephen Anthony
@version $Id: FrameBufferGL.hxx,v 1.31 2006-03-25 00:34:17 stephena Exp $
@version $Id: FrameBufferGL.hxx,v 1.32 2006-10-14 20:08:29 stephena Exp $
*/
class FrameBufferGL : public FrameBuffer
{
@ -80,6 +80,13 @@ class FrameBufferGL : public FrameBuffer
*/
virtual void setAspectRatio();
/**
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);
/**
This method is called whenever the screen needs to be recreated.
It updates the global screen variable.
@ -253,6 +260,9 @@ class FrameBufferGL : public FrameBuffer
// The name of the texture filtering to use
string myFilterParamName;
// FIXME - used for zooming, still work todo here
uInt32 myZoomLevel;
// The scaling to use in fullscreen mode
// This is separate from both zoomlevel and aspect ratio
float myFSScaleFactor;

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: FrameBufferSoft.cxx,v 1.52 2006-03-25 00:34:17 stephena Exp $
// $Id: FrameBufferSoft.cxx,v 1.53 2006-10-14 20:08:29 stephena Exp $
//============================================================================
#include <SDL.h>
@ -32,6 +32,7 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FrameBufferSoft::FrameBufferSoft(OSystem* osystem)
: FrameBuffer(osystem),
myZoomLevel(1),
myRectList(NULL),
myOverlayRectList(NULL),
myRenderType(kSoftZoom)
@ -78,13 +79,20 @@ void FrameBufferSoft::setAspectRatio()
theAspectRatio = 1.0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferSoft::setScaler(Scaler scaler)
{
// Software framebuffer doesn't handle the fancy scaling modes
myZoomLevel = scaler.zoom;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool FrameBufferSoft::createScreen()
{
myScreenDim.x = myScreenDim.y = 0;
myScreenDim.w = myBaseDim.w * theZoomLevel;
myScreenDim.h = myBaseDim.h * theZoomLevel;
myScreenDim.w = myBaseDim.w * myZoomLevel;
myScreenDim.h = myBaseDim.h * myZoomLevel;
// In software mode, the image and screen dimensions are always the same
myImageDim = myScreenDim;
@ -118,7 +126,7 @@ void FrameBufferSoft::drawMediaSource()
uInt8* currentFrame = mediasrc.currentFrameBuffer();
uInt8* previousFrame = mediasrc.previousFrameBuffer();
uInt16 screenMultiple = (uInt16) theZoomLevel;
uInt16 screenMultiple = (uInt16) myZoomLevel;
uInt32 width = mediasrc.width();
uInt32 height = mediasrc.height();
@ -282,14 +290,14 @@ void FrameBufferSoft::drawMediaSource()
uInt32 screenofsY = 0;
for(uInt32 y = 0; y < height; ++y )
{
uInt32 ystride = theZoomLevel;
uInt32 ystride = myZoomLevel;
while(ystride--)
{
uInt32 pos = screenofsY;
for(uInt32 x = 0; x < width; ++x )
{
const uInt32 bufofs = bufofsY + x;
uInt32 xstride = theZoomLevel;
uInt32 xstride = myZoomLevel;
uInt8 v = currentFrame[bufofs];
uInt8 w = previousFrame[bufofs];
@ -321,14 +329,14 @@ void FrameBufferSoft::drawMediaSource()
uInt32 screenofsY = 0;
for(uInt32 y = 0; y < height; ++y )
{
uInt32 ystride = theZoomLevel;
uInt32 ystride = myZoomLevel;
while(ystride--)
{
uInt32 pos = screenofsY;
for(uInt32 x = 0; x < width; ++x )
{
const uInt32 bufofs = bufofsY + x;
uInt32 xstride = theZoomLevel;
uInt32 xstride = myZoomLevel;
uInt8 v = currentFrame[bufofs];
uInt8 w = previousFrame[bufofs];
@ -375,14 +383,14 @@ void FrameBufferSoft::drawMediaSource()
uInt32 screenofsY = 0;
for(uInt32 y = 0; y < height; ++y )
{
uInt32 ystride = theZoomLevel;
uInt32 ystride = myZoomLevel;
while(ystride--)
{
uInt32 pos = screenofsY;
for(uInt32 x = 0; x < width; ++x )
{
const uInt32 bufofs = bufofsY + x;
uInt32 xstride = theZoomLevel;
uInt32 xstride = myZoomLevel;
uInt8 v = currentFrame[bufofs];
uInt8 w = previousFrame[bufofs];
@ -492,10 +500,10 @@ void FrameBufferSoft::hLine(uInt32 x, uInt32 y, uInt32 x2, int color)
SDL_Rect tmp;
// Horizontal line
tmp.x = x * theZoomLevel;
tmp.y = y * theZoomLevel;
tmp.w = (x2 - x + 1) * theZoomLevel;
tmp.h = theZoomLevel;
tmp.x = x * myZoomLevel;
tmp.y = y * myZoomLevel;
tmp.w = (x2 - x + 1) * myZoomLevel;
tmp.h = myZoomLevel;
SDL_FillRect(myScreen, &tmp, myDefPalette[color]);
}
@ -505,10 +513,10 @@ void FrameBufferSoft::vLine(uInt32 x, uInt32 y, uInt32 y2, int color)
SDL_Rect tmp;
// Vertical line
tmp.x = x * theZoomLevel;
tmp.y = y * theZoomLevel;
tmp.w = theZoomLevel;
tmp.h = (y2 - y + 1) * theZoomLevel;
tmp.x = x * myZoomLevel;
tmp.y = y * myZoomLevel;
tmp.w = myZoomLevel;
tmp.h = (y2 - y + 1) * myZoomLevel;
SDL_FillRect(myScreen, &tmp, myDefPalette[color]);
}
@ -519,10 +527,10 @@ void FrameBufferSoft::fillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
SDL_Rect tmp;
// Fill the rectangle
tmp.x = x * theZoomLevel;
tmp.y = y * theZoomLevel;
tmp.w = w * theZoomLevel;
tmp.h = h * theZoomLevel;
tmp.x = x * myZoomLevel;
tmp.y = y * myZoomLevel;
tmp.w = w * myZoomLevel;
tmp.h = h * myZoomLevel;
SDL_FillRect(myScreen, &tmp, myDefPalette[color]);
}
@ -556,9 +564,9 @@ void FrameBufferSoft::drawChar(const GUI::Font* FONT, uInt8 chr,
{
if ((buffer & mask) != 0)
{
rect.x = (x + xorig) * theZoomLevel;
rect.y = (y + yorig) * theZoomLevel;
rect.w = rect.h = theZoomLevel;
rect.x = (x + xorig) * myZoomLevel;
rect.y = (y + yorig) * myZoomLevel;
rect.w = rect.h = myZoomLevel;
SDL_FillRect(myScreen, &rect, myDefPalette[color]);
}
}
@ -578,9 +586,9 @@ void FrameBufferSoft::drawBitmap(uInt32* bitmap, Int32 xorig, Int32 yorig,
{
if(bitmap[y] & mask)
{
rect.x = (x + xorig) * theZoomLevel;
rect.y = (y + yorig) * theZoomLevel;
rect.w = rect.h = theZoomLevel;
rect.x = (x + xorig) * myZoomLevel;
rect.y = (y + yorig) * myZoomLevel;
rect.w = rect.h = myZoomLevel;
SDL_FillRect(myScreen, &rect, myDefPalette[color]);
}
}
@ -592,17 +600,17 @@ void FrameBufferSoft::translateCoords(Int32* x, Int32* y)
{
// We don't bother checking offsets or aspect ratios, since
// they're not yet supported in software mode.
*x /= theZoomLevel;
*y /= theZoomLevel;
*x /= myZoomLevel;
*y /= myZoomLevel;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferSoft::addDirtyRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h)
{
x *= theZoomLevel;
y *= theZoomLevel;
w *= theZoomLevel;
h *= theZoomLevel;
x *= myZoomLevel;
y *= myZoomLevel;
w *= myZoomLevel;
h *= myZoomLevel;
// Check if rect is in screen area
// This is probably a bug, since the GUI code shouldn't be setting

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: FrameBufferSoft.hxx,v 1.34 2006-03-25 00:34:17 stephena Exp $
// $Id: FrameBufferSoft.hxx,v 1.35 2006-10-14 20:08:29 stephena Exp $
//============================================================================
#ifndef FRAMEBUFFER_SOFT_HXX
@ -35,7 +35,7 @@ class RectList;
This class implements an SDL software framebuffer.
@author Stephen Anthony
@version $Id: FrameBufferSoft.hxx,v 1.34 2006-03-25 00:34:17 stephena Exp $
@version $Id: FrameBufferSoft.hxx,v 1.35 2006-10-14 20:08:29 stephena Exp $
*/
class FrameBufferSoft : public FrameBuffer
{
@ -69,6 +69,13 @@ class FrameBufferSoft : public FrameBuffer
*/
virtual void setAspectRatio();
/**
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);
/**
This method is called whenever the screen needs to be recreated.
It updates the global screen variable.
@ -201,14 +208,8 @@ class FrameBufferSoft : public FrameBuffer
*/
virtual void cls();
protected:
// Used in the dirty update of the SDL surface
RectList* myRectList;
// Used in the dirty update of the overlay surface
RectList* myOverlayRectList;
private:
int myZoomLevel;
int myPitch;
enum RenderType {
@ -218,6 +219,12 @@ class FrameBufferSoft : public FrameBuffer
kPhosphor_32
};
RenderType myRenderType;
// Used in the dirty update of the SDL surface
RectList* myRectList;
// Used in the dirty update of the overlay surface
RectList* myOverlayRectList;
};
class RectList

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: Console.cxx,v 1.93 2006-08-09 02:38:03 bwmott Exp $
// $Id: Console.cxx,v 1.94 2006-10-14 20:08:29 stephena Exp $
//============================================================================
#include <assert.h>
@ -241,10 +241,6 @@ Console::Console(const uInt8* image, uInt32 size, const string& md5,
}
myOSystem->setFramerate(framerate);
// Initialize the framebuffer interface.
// This must be done *after* a reset, since it needs updated values.
initializeVideo();
// Initialize the sound interface.
// The # of channels can be overridden in the AudioDialog box or on
// the commandline, but it can't be saved.

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: EventHandler.cxx,v 1.164 2006-05-24 17:37:33 stephena Exp $
// $Id: EventHandler.cxx,v 1.165 2006-10-14 20:08:29 stephena Exp $
//============================================================================
#include <sstream>
@ -394,11 +394,11 @@ void EventHandler::poll(uInt32 time)
{
#ifndef MAC_OSX
case SDLK_EQUALS:
myOSystem->frameBuffer().resize(+1);
myOSystem->frameBuffer().scale(+1);
break;
case SDLK_MINUS:
myOSystem->frameBuffer().resize(-1);
myOSystem->frameBuffer().scale(-1);
break;
case SDLK_RETURN:
@ -528,11 +528,11 @@ void EventHandler::poll(uInt32 time)
break;
case SDLK_EQUALS:
myOSystem->frameBuffer().resize(+1);
myOSystem->frameBuffer().scale(+1);
break;
case SDLK_MINUS:
myOSystem->frameBuffer().resize(-1);
myOSystem->frameBuffer().scale(-1);
break;
case SDLK_RETURN:

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: FrameBuffer.cxx,v 1.90 2006-08-11 12:50:22 stephena Exp $
// $Id: FrameBuffer.cxx,v 1.91 2006-10-14 20:08:29 stephena Exp $
//============================================================================
#include <sstream>
@ -40,8 +40,6 @@
FrameBuffer::FrameBuffer(OSystem* osystem)
: myOSystem(osystem),
myScreen(0),
theZoomLevel(2),
theMaxZoomLevel(2),
theAspectRatio(1.0),
theRedrawTIAIndicator(true),
myUsePhosphor(false),
@ -95,16 +93,14 @@ void FrameBuffer::initialize(const string& title, uInt32 width, uInt32 height,
if(useAspect)
setAspectRatio();
// Get the maximum size of a window for the current desktop
theMaxZoomLevel = maxWindowSizeForScreen();
// Check to see if window size will fit in the screen
if((uInt32)myOSystem->settings().getInt("zoom") > theMaxZoomLevel)
theZoomLevel = theMaxZoomLevel;
else
theZoomLevel = myOSystem->settings().getInt("zoom");
// Set the available scalers for this framebuffer, based on current eventhandler
// state and the maximum size of a window for the current desktop
setAvailableScalers();
// Initialize video subsystem
Scaler scaler;
getScaler(scaler, 0, currentScalerName());
setScaler(scaler);
initSubsystem();
// And refresh the display
@ -389,51 +385,37 @@ void FrameBuffer::setFullscreen(bool enable)
return;
myOSystem->eventHandler().refreshDisplay();
setCursorState();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::resize(int size, Int8 zoom)
bool FrameBuffer::scale(int direction, const string& type)
{
switch(size)
Scaler newScaler;
const string& currentScaler = (direction == 0 ? type : currentScalerName());
getScaler(newScaler, direction, currentScaler);
// Only update the scaler if it's changed from the old one
if(currentScaler != newScaler.name)
{
case -1: // decrease size
if(myOSystem->settings().getBool("fullscreen"))
return;
if(theZoomLevel == 1)
theZoomLevel = theMaxZoomLevel;
else
theZoomLevel--;
break;
setScaler(newScaler);
if(!createScreen())
return false;
case +1: // increase size
if(myOSystem->settings().getBool("fullscreen"))
return;
if(theZoomLevel == theMaxZoomLevel)
theZoomLevel = 1;
else
theZoomLevel++;
break;
myOSystem->eventHandler().refreshDisplay();
showMessage(newScaler.name);
case 0: // use 'zoom' quantity
if(zoom < 1)
theZoomLevel = 1;
else if((uInt32)zoom > theMaxZoomLevel)
theZoomLevel = theMaxZoomLevel;
else
theZoomLevel = zoom;
break;
EventHandler::State state = myOSystem->eventHandler().state();
bool inTIAMode = (state == EventHandler::S_EMULATE ||
state == EventHandler::S_MENU ||
state == EventHandler::S_CMDMENU);
default: // should never happen
return;
break;
if(inTIAMode)
myOSystem->settings().setString("scale_tia", newScaler.name);
else
myOSystem->settings().setString("scale_ui", newScaler.name);
}
if(!createScreen())
return;
myOSystem->eventHandler().refreshDisplay();
return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -481,36 +463,6 @@ bool FrameBuffer::fullScreen()
return myOSystem->settings().getBool("fullscreen");
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 FrameBuffer::maxWindowSizeForScreen()
{
uInt32 sWidth = myDesktopDim.w;
uInt32 sHeight = myDesktopDim.h;
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
uInt32 width = (uInt32) (myBaseDim.w * multiplier * theAspectRatio);
uInt32 height = myBaseDim.h * multiplier;
if((width < sWidth) && (height < sHeight))
found = true;
else
multiplier--;
}
if(found)
return multiplier;
else
return 1;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::setWindowTitle(const string& title)
{
@ -714,6 +666,224 @@ uInt8 FrameBuffer::getPhosphor(uInt8 c1, uInt8 c2)
return ((c1 - c2) * myPhosphorBlend)/100 + c2;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int FrameBuffer::maxWindowSizeForScreen()
{
uInt32 sWidth = myDesktopDim.w;
uInt32 sHeight = myDesktopDim.h;
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
uInt32 width = (uInt32) (myBaseDim.w * multiplier * theAspectRatio);
uInt32 height = myBaseDim.h * multiplier;
if((width < sWidth) && (height < sHeight))
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. For now, there are two separate scaler lists; one for
normal emulation mode (and modes that have the TIA in the background),
and one for standard GUI modes (modes that bypass drawMediaSource).
For reasons of efficiency, only zooming is supported in GUI mode. Also,
it doesn't really make sense to use high quality scalers on text-only
windows. */
EventHandler::State state = myOSystem->eventHandler().state();
int maxsize = maxWindowSizeForScreen();
// First we disable all scalers
for(int i = 0; i < kUIScalerListSize; ++i)
ourUIScalers[i].available = false;
for(int i = 0; i < kTIAScalerListSize; ++i)
ourTIAScalers[i].available = false;
bool inTIAMode = (state == EventHandler::S_EMULATE ||
state == EventHandler::S_MENU ||
state == EventHandler::S_CMDMENU);
/*
cerr << "TIA mode: " << (inTIAMode ? "yes" : "no") << ", state: " << state << endl
<< "maxsize: " << maxsize << endl
<< "type: " << (type() == kSoftBuffer ? "soft buffer" : "GL buffer") << endl
<< endl;
*/
// Next, determine which mode we're in and update the appropriate scaler list
if(type() == kSoftBuffer)
{
if(inTIAMode)
{
for(int i = 0; i < kTIAScalerListSize; ++i)
if(ourTIAScalers[i].scale == 1 && ourTIAScalers[i].zoom <= maxsize)
ourTIAScalers[i].available = true;
}
else // UI mode
{
for(int i = 0; i < kUIScalerListSize; ++i)
if(ourUIScalers[i].scale == 1 && ourUIScalers[i].zoom <= maxsize)
ourUIScalers[i].available = true;
}
}
else if(type() == kGLBuffer)
{
if(inTIAMode)
{
for(int i = 0; i < kTIAScalerListSize; ++i)
if(ourTIAScalers[i].scale <= maxsize && ourTIAScalers[i].zoom <= maxsize)
ourTIAScalers[i].available = true;
}
else // UI mode
{
for(int i = 0; i < kUIScalerListSize; ++i)
if(ourUIScalers[i].scale == 1 && ourUIScalers[i].zoom <= maxsize)
ourUIScalers[i].available = true;
}
}
/*
cerr << "UI Scalers available:\n";
for(int i = 0; i < 6; ++i)
if(ourUIScalers[i].available)
cerr << ourUIScalers[i].name << endl;
for(int i = 0; i < kNumScalers; ++i)
if(ourTIAScalers[i].available)
cerr << ourTIAScalers[i].name << endl;
cerr << endl << endl;
*/
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::getScaler(Scaler& scaler, int direction, const string& name)
{
EventHandler::State state = myOSystem->eventHandler().state();
bool inTIAMode = (state == EventHandler::S_EMULATE ||
state == EventHandler::S_MENU ||
state == EventHandler::S_CMDMENU);
Scaler* list = (inTIAMode ? ourTIAScalers : ourUIScalers);
int size = (inTIAMode ? kTIAScalerListSize : kUIScalerListSize);
bool found = false;
switch(direction)
{
case 0: // search for the actual scaler specified in 'name'
for(int i = 0; i < size; ++i)
{
if(list[i].name == name)
{
scaler = list[i];
found = true;
break;
}
}
break;
case -1: // search for the previous scaler from one specified in 'name'
{
int i, pos = -1;
// First find the current scaler
for(i = 0; i < size; ++i)
{
if(list[i].name == name)
{
pos = i;
break;
}
}
// If we found it, then search for the previous one
if(pos != -1)
{
i = size;
while(i > 0 && !found)
{
pos--;
if(pos < 0) pos = size - 1;
if(list[pos].available)
{
scaler = list[pos];
found = true;
break;
}
--i;
}
}
break;
}
case +1: // search for the next scaler from one specified in 'name'
{
int i, pos = -1;
// First find the current scaler
for(i = 0; i < size; ++i)
{
if(list[i].name == name)
{
pos = i;
break;
}
}
// If we found it, then search for the next one
if(pos != -1)
{
i = size;
while(i > 0 && !found)
{
pos++;
if(pos >= size) pos = 0;
if(list[pos].available)
{
scaler = list[pos];
found = true;
break;
}
--i;
}
}
break;
}
}
// Default to 'Zoom1x' if we didn't find a valid scaler
if(!found)
scaler = list[0];
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const string& FrameBuffer::currentScalerName()
{
EventHandler::State state = myOSystem->eventHandler().state();
bool inTIAMode = (state == EventHandler::S_EMULATE ||
state == EventHandler::S_MENU ||
state == EventHandler::S_CMDMENU);
return (inTIAMode ?
myOSystem->settings().getString("scale_tia") :
myOSystem->settings().getString("scale_ui") );
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const uInt8 FrameBuffer::ourGUIColors[kNumColors-256][3] = {
{ 104, 104, 104 }, // kColor
@ -728,3 +898,31 @@ const uInt8 FrameBuffer::ourGUIColors[kNumColors-256][3] = {
#endif
{ 200, 0, 0 } // kTextColorEm
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Scaler FrameBuffer::ourUIScalers[kUIScalerListSize] = {
{ "Zoom1x", 1, 1, false },
{ "Zoom2x", 2, 1, false },
{ "Zoom3x", 3, 1, false },
{ "Zoom4x", 4, 1, false },
{ "Zoom5x", 5, 1, false },
{ "Zoom6x", 6, 1, false }
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Scaler FrameBuffer::ourTIAScalers[kTIAScalerListSize] = {
{ "Zoom1x", 1, 1, false },
{ "Zoom2x", 2, 1, false },
{ "Zoom3x", 3, 1, false },
{ "Zoom4x", 4, 1, false },
{ "Zoom5x", 5, 1, false },
{ "Zoom6x", 6, 1, false },
{ "Scale2x", 1, 2, false },
{ "Scale3x", 1, 3, false },
{ "Scale4x", 1, 4, false },
{ "HQ2x", 1, 2, false },
{ "HQ3x", 1, 3, false },
{ "HQ4x", 1, 4, false }
};

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: FrameBuffer.hxx,v 1.70 2006-05-15 12:24:09 stephena Exp $
// $Id: FrameBuffer.hxx,v 1.71 2006-10-14 20:08:29 stephena Exp $
//============================================================================
#ifndef FRAMEBUFFER_HXX
@ -74,6 +74,14 @@ enum {
kNumColors
};
// Different types of scalers available
struct Scaler {
string name;
int zoom;
int scale;
bool available;
};
/**
This class encapsulates the MediaSource and is the basis for the video
display in Stella. All graphics ports should derive from this class for
@ -82,7 +90,7 @@ enum {
All GUI elements (ala ScummVM) are drawn here as well.
@author Stephen Anthony
@version $Id: FrameBuffer.hxx,v 1.70 2006-05-15 12:24:09 stephena Exp $
@version $Id: FrameBuffer.hxx,v 1.71 2006-10-14 20:08:29 stephena Exp $
*/
class FrameBuffer
{
@ -189,15 +197,16 @@ class FrameBuffer
void setFullscreen(bool enable);
/**
This method is called when the user wants to resize the window.
Size = -1 means window should decrease in size
Size = 0 means window should be resized to quantity given in 'zoom'
Size = +1 means window should increase in size
This method is called when the user wants to scale the window, in effect
changing to another scaler.
direction = -1 means window should go to the next lower scaler
direction = 0 means window should be created with the given scaler
direction = +1 means window should go to the next higher scaler
@param size Described above
@param zoom The zoom level to use if size is set to 'sGiven'
@param direction Described above
@param type The scaler to use if direction is set to 0
*/
void resize(int size, Int8 zoom = 0);
bool scale(int direction, const string& type = "Zoom1x");
/**
Sets the state of the cursor (hidden or grabbed) based on the
@ -220,17 +229,6 @@ class FrameBuffer
*/
bool fullScreen();
/**
Calculate the maximum window size that the current screen can hold.
If not supported by platform, always return 4.
*/
virtual uInt32 maxWindowSizeForScreen();
/**
Returns current zoomlevel of the framebuffer.
*/
uInt32 zoomLevel() { return theZoomLevel; }
/**
Set the title for the main SDL window.
*/
@ -288,14 +286,14 @@ class FrameBuffer
int color, TextAlignment align = kTextAlignLeft,
int deltax = 0, bool useEllipsis = true);
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.
This method is called to initialize the subsystem-specific video mode
with the given scaler.
*/
virtual bool initSubsystem() = 0;
@ -309,6 +307,13 @@ class FrameBuffer
*/
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.
@ -443,7 +448,7 @@ class FrameBuffer
// The parent system for the framebuffer
OSystem* myOSystem;
// Dimensions of the base image, before zooming.
// Dimensions of the base image, before scaling.
// All external GUI items should refer to these dimensions,
// since this is the *real* size of the image.
// The other sizes are simply scaled versions of these dimensions.
@ -468,12 +473,6 @@ class FrameBuffer
Uint32 myDefPalette[256+kNumColors];
Uint32 myAvgPalette[256][256];
// Indicates the current zoom level of the SDL screen
uInt32 theZoomLevel;
// Indicates the maximum zoom of the SDL screen
uInt32 theMaxZoomLevel;
// The aspect ratio of the window
float theAspectRatio;
@ -513,6 +512,36 @@ class FrameBuffer
*/
uInt8 getPhosphor(uInt8 c1, uInt8 c2);
/**
Calculate the maximum window size that the current screen can hold.
If not supported by platform, always return 4.
*/
int maxWindowSizeForScreen();
/**
Set the scalers available for this framebuffer based on current emulation
state and maximum window size.
*/
void setAvailableScalers();
/**
Returns a scaler based on the current eventhandler mode and the value of direction.
If there's any error, default to 'Zoom1x'.
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
@param direction Described above
@param name The name of the scaler
*/
void getScaler(Scaler& scaler, int direction, const string& name);
/**
Get the current scaler based on the eventhandler mode.
*/
const string& currentScalerName();
private:
// Indicates the current framerate of the system
uInt32 myFrameRate;
@ -525,6 +554,16 @@ class FrameBuffer
uInt32 color;
};
Message myMessage;
// The various scalers available in TIA vs. non-TIA mode
// For the foreseeable future, the UI scalers will be restricted
// from using the more advanced scalers
enum {
kUIScalerListSize = 6,
kTIAScalerListSize = 12
};
static Scaler ourUIScalers[kUIScalerListSize];
static Scaler ourTIAScalers[kTIAScalerListSize];
};
#endif

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: OSystem.cxx,v 1.70 2006-06-10 13:27:23 stephena Exp $
// $Id: OSystem.cxx,v 1.71 2006-10-14 20:08:29 stephena Exp $
//============================================================================
#include <cassert>
@ -312,6 +312,7 @@ bool OSystem::createConsole(const string& romfile)
cout << "Game console created: " << myRomFile << endl;
myEventHandler->reset(EventHandler::S_EMULATE);
createFrameBuffer(false);
myFrameBuffer->setCursorState();
retval = true;
}
@ -340,9 +341,7 @@ void OSystem::createLauncher()
mySound->close();
setFramerate(60);
myEventHandler->reset(EventHandler::S_LAUNCHER);
// Create the window
myLauncher->initializeVideo();
createFrameBuffer(false);
// And start the base dialog
myLauncher->initialize();

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: Settings.cxx,v 1.85 2006-04-05 12:28:37 stephena Exp $
// $Id: Settings.cxx,v 1.86 2006-10-14 20:08:29 stephena Exp $
//============================================================================
#include <cassert>
@ -42,7 +42,8 @@ Settings::Settings(OSystem* osystem)
setInternal("gl_fsmax", "false");
setInternal("gl_lib", "");
setInternal("zoom", "2");
setInternal("scale_ui", "Zoom1x");
setInternal("scale_tia", "Zoom1x");
setInternal("fullscreen", "false");
setInternal("center", "true");
setInternal("grabmouse", "false");
@ -239,9 +240,17 @@ void Settings::validate()
setInternal("tiafreq", "31400");
#endif
i = getInt("zoom");
if(i < 1 || i > 6)
setInternal("zoom", "2");
s = getString("scale_ui");
if(s != "Zoom1x" && s != "Zoom2x" && s != "Zoom3x" &&
s != "Zoom4x" && s != "Zoom5x" && s != "Zoom6x")
setInternal("scale_ui", "Zoom1x");
s = getString("scale_tia");
if(s != "Zoom1x" && s != "Zoom2x" && s != "Zoom3x" &&
s != "Zoom4x" && s != "Zoom5x" && s != "Zoom6x" &&
s != "Scale2x" && s != "Scale3x" && s != "Scale4x" &&
s != "HQ2x" && s != "HQ3x" && s != "HQ4x")
setInternal("scale_tia", "Zoom1x");
i = getInt("paddle");
if(i < 0 || i > 3)

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: VideoDialog.cxx,v 1.30 2006-05-04 17:45:25 stephena Exp $
// $Id: VideoDialog.cxx,v 1.31 2006-10-14 20:08:29 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -309,10 +309,12 @@ void VideoDialog::saveConfig()
if(i > 0)
instance()->setFramerate(i);
/* FIXME - this has to be changed to scaler - zoom will disappear
// Zoom
i = (myZoomSlider->getValue() / 10) + 1;
instance()->settings().setInt("zoom", i);
instance()->frameBuffer().resize(0, i);
*/
// Fullscreen (the setFullscreen method takes care of updating settings)
b = myFullscreenCheckbox->getState();