More work on the new scaler infrastructure, and a fix for incorrectly

positioned GUI elements in emulation mode (I was a little too eager with
code pruning).


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1135 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2006-10-16 01:09:00 +00:00
parent 8925bf8b36
commit e3b36b202c
9 changed files with 350 additions and 229 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.63 2006-10-14 20:08:29 stephena Exp $
// $Id: FrameBufferGL.cxx,v 1.64 2006-10-16 01:08:59 stephena Exp $
//============================================================================
#ifdef DISPLAY_OPENGL
@ -69,13 +69,16 @@ static void (APIENTRY* p_glTexParameteri)( GLenum, GLenum, GLint );
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FrameBufferGL::FrameBufferGL(OSystem* osystem)
: FrameBuffer(osystem),
myTexture(NULL),
myBaseTexture(NULL),
myScaledTexture(NULL),
myCurrentTexture(NULL),
myScreenmode(0),
myScreenmodeCount(0),
myTextureID(0),
myFilterParam(GL_NEAREST),
myFilterParamName("GL_NEAREST"),
myZoomLevel(1), // FIXME
myZoomLevel(1),
myScaleLevel(1),
myFSScaleFactor(1.0),
myDirtyFlag(true)
{
@ -84,8 +87,10 @@ FrameBufferGL::FrameBufferGL(OSystem* osystem)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FrameBufferGL::~FrameBufferGL()
{
if(myTexture)
SDL_FreeSurface(myTexture);
if(myBaseTexture)
SDL_FreeSurface(myBaseTexture);
if(myScaledTexture)
SDL_FreeSurface(myScaledTexture);
p_glDeleteTextures(1, &myTextureID);
}
@ -172,40 +177,20 @@ bool FrameBufferGL::initSubsystem()
switch(myDepth)
{
case 8:
myRGB[0] = 3;
myRGB[1] = 3;
myRGB[2] = 2;
myRGB[3] = 0;
myRGB[0] = 3; myRGB[1] = 3; myRGB[2] = 2; myRGB[3] = 0;
break;
case 15:
myRGB[0] = 5;
myRGB[1] = 5;
myRGB[2] = 5;
myRGB[3] = 0;
myRGB[0] = 5; myRGB[1] = 5; myRGB[2] = 5; myRGB[3] = 0;
break;
case 16:
myRGB[0] = 5;
myRGB[1] = 6;
myRGB[2] = 5;
myRGB[3] = 0;
myRGB[0] = 5; myRGB[1] = 6; myRGB[2] = 5; myRGB[3] = 0;
break;
case 24:
myRGB[0] = 8;
myRGB[1] = 8;
myRGB[2] = 8;
myRGB[3] = 0;
myRGB[0] = 8; myRGB[1] = 8; myRGB[2] = 8; myRGB[3] = 0;
break;
case 32:
myRGB[0] = 8;
myRGB[1] = 8;
myRGB[2] = 8;
myRGB[3] = 8;
myRGB[0] = 8; myRGB[1] = 8; myRGB[2] = 8; myRGB[3] = 8;
break;
default: // This should never happen
break;
}
@ -227,11 +212,6 @@ bool FrameBufferGL::initSubsystem()
SDL_GL_GetAttribute( SDL_GL_BLUE_SIZE, (int*)&myRGB[2] );
SDL_GL_GetAttribute( SDL_GL_ALPHA_SIZE, (int*)&myRGB[3] );
#ifndef TEXTURES_ARE_LOST
// Create the texture surface
createTextures();
#endif
// Show some OpenGL info
if(myOSystem->settings().getBool("showinfo"))
{
@ -263,9 +243,54 @@ void FrameBufferGL::setAspectRatio()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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;
myScalerType = scaler.type;
myZoomLevel = scaler.zoom;
myScaleLevel = scaler.scale;
switch(scaler.type)
{
case kZOOM1X:
case kZOOM2X:
case kZOOM3X:
case kZOOM4X:
case kZOOM5X:
case kZOOM6X:
myQuadRect.w = myBaseDim.w;
myQuadRect.h = myBaseDim.h;
break;
case kSCALE2X:
myQuadRect.w = myBaseDim.w * 2;
myQuadRect.h = myBaseDim.h * 2;
cerr << "scaler: " << scaler.name << endl;
break;
case kSCALE3X:
myQuadRect.w = myBaseDim.w * 3;
myQuadRect.h = myBaseDim.h * 3;
cerr << "scaler: " << scaler.name << endl;
break;
case kSCALE4X:
myQuadRect.w = myBaseDim.w * 4;
myQuadRect.h = myBaseDim.h * 4;
cerr << "scaler: " << scaler.name << endl;
break;
case kHQ2X:
myQuadRect.w = myBaseDim.w * 2;
myQuadRect.h = myBaseDim.h * 2;
cerr << "scaler: " << scaler.name << endl;
break;
case kHQ3X:
myQuadRect.w = myBaseDim.w * 3;
myQuadRect.h = myBaseDim.h * 3;
cerr << "scaler: " << scaler.name << endl;
break;
case kHQ4X:
myQuadRect.w = myBaseDim.w * 4;
myQuadRect.h = myBaseDim.h * 4;
cerr << "scaler: " << scaler.name << endl;
break;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -306,9 +331,7 @@ bool FrameBufferGL::createScreen()
p_glPushMatrix();
p_glLoadIdentity();
#ifdef TEXTURES_ARE_LOST
createTextures();
#endif
// Make sure any old parts of the screen are erased
// Do it for both buffers!
@ -329,67 +352,71 @@ void FrameBufferGL::drawMediaSource()
uInt8* previousFrame = mediasrc.previousFrameBuffer();
uInt32 width = mediasrc.width();
uInt32 height = mediasrc.height();
uInt16* buffer = (uInt16*) myTexture->pixels;
uInt16* buffer = (uInt16*) myBaseTexture->pixels;
// TODO - is this fast enough?
switch((int)myUsePhosphor) // use switch/case, since we'll eventually have filters
if(!myUsePhosphor)
{
case 0:
uInt32 bufofsY = 0;
uInt32 screenofsY = 0;
for(uInt32 y = 0; y < height; ++y )
{
uInt32 bufofsY = 0;
uInt32 screenofsY = 0;
for(uInt32 y = 0; y < height; ++y )
uInt32 pos = screenofsY;
for(uInt32 x = 0; x < width; ++x )
{
uInt32 pos = screenofsY;
for(uInt32 x = 0; x < width; ++x )
const uInt32 bufofs = bufofsY + x;
uInt8 v = currentFrame[bufofs];
uInt8 w = previousFrame[bufofs];
if(v != w || theRedrawTIAIndicator)
{
const uInt32 bufofs = bufofsY + x;
uInt8 v = currentFrame[bufofs];
uInt8 w = previousFrame[bufofs];
// If we ever get to this point, we know the current and previous
// buffers differ. In that case, make sure the changes are
// are drawn in postFrameUpdate()
myDirtyFlag = true;
if(v != w || theRedrawTIAIndicator)
{
// If we ever get to this point, we know the current and previous
// buffers differ. In that case, make sure the changes are
// are drawn in postFrameUpdate()
myDirtyFlag = true;
buffer[pos] = buffer[pos+1] = (uInt16) myDefPalette[v];
}
pos += 2;
buffer[pos] = buffer[pos+1] = (uInt16) myDefPalette[v];
}
bufofsY += width;
screenofsY += myTexture->w;
pos += 2;
}
break;
}
case 1:
{
// Phosphor mode always implies a dirty update,
// so we don't care about theRedrawTIAIndicator
myDirtyFlag = true;
uInt32 bufofsY = 0;
uInt32 screenofsY = 0;
for(uInt32 y = 0; y < height; ++y )
{
uInt32 pos = screenofsY;
for(uInt32 x = 0; x < width; ++x )
{
const uInt32 bufofs = bufofsY + x;
uInt8 v = currentFrame[bufofs];
uInt8 w = previousFrame[bufofs];
buffer[pos++] = (uInt16) myAvgPalette[v][w];
buffer[pos++] = (uInt16) myAvgPalette[v][w];
}
bufofsY += width;
screenofsY += myTexture->w;
}
break;
bufofsY += width;
screenofsY += myBaseTexture->w;
}
}
else
{
// Phosphor mode always implies a dirty update,
// so we don't care about theRedrawTIAIndicator
myDirtyFlag = true;
uInt32 bufofsY = 0;
uInt32 screenofsY = 0;
for(uInt32 y = 0; y < height; ++y )
{
uInt32 pos = screenofsY;
for(uInt32 x = 0; x < width; ++x )
{
const uInt32 bufofs = bufofsY + x;
uInt8 v = currentFrame[bufofs];
uInt8 w = previousFrame[bufofs];
buffer[pos++] = (uInt16) myAvgPalette[v][w];
buffer[pos++] = (uInt16) myAvgPalette[v][w];
}
bufofsY += width;
screenofsY += myBaseTexture->w;
}
}
// At this point, myBaseTexture will be filled with a valid TIA image
// Now we check if post-processing scalers should be applied
// In any event, myCurrentTexture will point to the valid data to be
// rendered to the screen
/*
switch(myScalerType)
{
case
*/
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -404,11 +431,12 @@ void FrameBufferGL::postFrameUpdate()
{
// Texturemap complete texture to surface so we have free scaling
// and antialiasing
uInt32 w = myBaseDim.w, h = myBaseDim.h;
uInt32 w = myQuadRect.w, h = myQuadRect.h;
p_glBindTexture(GL_TEXTURE_2D, myTextureID);
p_glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, myTexture->w, myTexture->h,
GL_RGB, GL_UNSIGNED_SHORT_5_6_5, myTexture->pixels);
p_glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
myCurrentTexture->w, myCurrentTexture->h,
GL_RGB, GL_UNSIGNED_SHORT_5_6_5, myCurrentTexture->pixels);
p_glBegin(GL_QUADS);
/* Upside down !
p_glTexCoord2f(myTexCoord[2], myTexCoord[3]); p_glVertex2i(0, 0);
@ -469,20 +497,41 @@ void FrameBufferGL::toggleFilter()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferGL::hLine(uInt32 x, uInt32 y, uInt32 x2, int color)
{
uInt16* buffer = (uInt16*) myTexture->pixels + y * myTexture->w + x;
/*
uInt16* buffer = (uInt16*) myCurrentTexture->pixels + y * myCurrentTexture->w + x;
while(x++ <= x2)
*buffer++ = (uInt16) myDefPalette[color];
*/
SDL_Rect tmp;
// Horizontal line
tmp.x = x * myScaleLevel;
tmp.y = y * myScaleLevel;
tmp.w = (x2 - x + 1) * myScaleLevel;
tmp.h = myScaleLevel;
SDL_FillRect(myCurrentTexture, &tmp, myDefPalette[color]);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferGL::vLine(uInt32 x, uInt32 y, uInt32 y2, int color)
{
uInt16* buffer = (uInt16*) myTexture->pixels + y * myTexture->w + x;
/*
uInt16* buffer = (uInt16*) myCurrentTexture->pixels + y * myCurrentTexture->w + x;
while(y++ <= y2)
{
*buffer = (uInt16) myDefPalette[color];
buffer += myTexture->w;
buffer += myCurrentTexture->w;
}
*/
SDL_Rect tmp;
// Vertical line
tmp.x = x * myScaleLevel;
tmp.y = y * myScaleLevel;
tmp.w = myScaleLevel;
tmp.h = (y2 - y + 1) * myScaleLevel;
SDL_FillRect(myCurrentTexture, &tmp, myDefPalette[color]);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -492,11 +541,19 @@ void FrameBufferGL::fillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
SDL_Rect tmp;
// Fill the rectangle
tmp.x = x;
tmp.y = y;
tmp.w = w;
tmp.h = h;
SDL_FillRect(myTexture, &tmp, myDefPalette[color]);
tmp.x = x * myScaleLevel;
tmp.y = y * myScaleLevel;
tmp.w = w * myScaleLevel;
tmp.h = h * myScaleLevel;
SDL_FillRect(myCurrentTexture, &tmp, myDefPalette[color]);
/*
cerr << "FrameBufferGL::fillRect:" << endl
<< "x = " << tmp.x << endl
<< "y = " << tmp.y << endl
<< "w = " << tmp.w << endl
<< "h = " << tmp.h << endl
<< endl;
*/
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -520,7 +577,7 @@ void FrameBufferGL::drawChar(const GUI::Font* FONT, uInt8 chr,
const uInt16* tmp = font->desc().bits + (font->desc().offset ?
font->desc().offset[chr] : (chr * h));
uInt16* buffer = (uInt16*) myTexture->pixels + ty * myTexture->w + tx;
uInt16* buffer = (uInt16*) myCurrentTexture->pixels + ty * myCurrentTexture->w + tx;
for(int y = 0; y < h; ++y)
{
const uInt16 ptr = *tmp++;
@ -531,7 +588,7 @@ void FrameBufferGL::drawChar(const GUI::Font* FONT, uInt8 chr,
if(ptr & mask)
buffer[x] = (uInt16) myDefPalette[color];
}
buffer += myTexture->w;
buffer += myCurrentTexture->w;
}
}
@ -539,7 +596,7 @@ void FrameBufferGL::drawChar(const GUI::Font* FONT, uInt8 chr,
void FrameBufferGL::drawBitmap(uInt32* bitmap, Int32 tx, Int32 ty,
int color, Int32 h)
{
uInt16* buffer = (uInt16*) myTexture->pixels + ty * myTexture->w + tx;
uInt16* buffer = (uInt16*) myCurrentTexture->pixels + ty * myCurrentTexture->w + tx;
for(int y = 0; y < h; ++y)
{
@ -549,7 +606,7 @@ void FrameBufferGL::drawBitmap(uInt32* bitmap, Int32 tx, Int32 ty,
if(bitmap[y] & mask)
buffer[x] = (uInt16) myDefPalette[color];
}
buffer += myTexture->w;
buffer += myCurrentTexture->w;
}
}
@ -557,17 +614,13 @@ 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) / (myZoomLevel * myFSScaleFactor * theAspectRatio)));
*y = (Int32) (((*y - myImageDim.y) / (myZoomLevel * myFSScaleFactor)));
*x = (Int32) (((*x - myImageDim.x) / (myZoomLevel * myScaleLevel * myFSScaleFactor * theAspectRatio)));
*y = (Int32) (((*y - myImageDim.y) / (myZoomLevel * myScaleLevel * myFSScaleFactor)));
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferGL::addDirtyRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h)
{
// TODO
// Add logic to create one large dirty-rect that encompasses all
// smaller dirty rects. Then in postFrameUpdate(), change the
// coordinates to only update that portion of the texture.
myDirtyFlag = true;
}
@ -594,28 +647,63 @@ void FrameBufferGL::cls()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool FrameBufferGL::createTextures()
{
if(myTexture)
cerr << "FrameBufferGL::createTextures()\n";
if(myBaseTexture)
{
SDL_FreeSurface(myTexture);
myTexture = NULL;
SDL_FreeSurface(myBaseTexture);
myBaseTexture = NULL;
}
if(myScaledTexture)
{
SDL_FreeSurface(myScaledTexture);
myScaledTexture = NULL;
}
myCurrentTexture = NULL;
p_glDeleteTextures(1, &myTextureID);
uInt32 w = power_of_two(myBaseDim.w);
uInt32 h = power_of_two(myBaseDim.h);
cerr << "texture dimensions (before power of 2 scaling):" << endl
<< "myBaseTexture->w = " << myBaseDim.w << endl
<< "myBaseTexture->h = " << myBaseDim.h << endl
<< "myScaledTexture->w = " << myQuadRect.w << endl
<< "myScaledTexture->h = " << myQuadRect.h << endl
<< endl;
uInt32 w1 = power_of_two(myBaseDim.w);
uInt32 h1 = power_of_two(myBaseDim.h);
uInt32 w2 = power_of_two(myQuadRect.w);
uInt32 h2 = power_of_two(myQuadRect.h);
myTexCoord[0] = 0.0f;
myTexCoord[1] = 0.0f;
myTexCoord[2] = (GLfloat) myBaseDim.w / w;
myTexCoord[3] = (GLfloat) myBaseDim.h / h;
myTexCoord[2] = (GLfloat) myQuadRect.w / w1;
myTexCoord[3] = (GLfloat) myQuadRect.h / h1;
myTexture = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 16,
myBaseTexture = SDL_CreateRGBSurface(SDL_SWSURFACE, w1, h1, 16,
0x0000F800, 0x000007E0, 0x0000001F, 0x00000000);
if(myTexture == NULL)
if(myBaseTexture == NULL)
return false;
myScaledTexture = SDL_CreateRGBSurface(SDL_SWSURFACE, w2, h2, 16,
0x0000F800, 0x000007E0, 0x0000001F, 0x00000000);
if(myScaledTexture == NULL)
return false;
// Set current texture pointer
switch(myScalerType)
{
case kZOOM1X:
case kZOOM2X:
case kZOOM3X:
case kZOOM4X:
case kZOOM5X:
case kZOOM6X:
myCurrentTexture = myBaseTexture;
break;
default:
myCurrentTexture = myScaledTexture;
break;
}
// Create an OpenGL texture from the SDL texture
string filter = myOSystem->settings().getString("gl_filter");
if(filter == "linear")
@ -635,8 +723,9 @@ bool FrameBufferGL::createTextures()
p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
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);
p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
myCurrentTexture->w, myCurrentTexture->h, 0,
GL_RGB, GL_UNSIGNED_SHORT_5_6_5, NULL);
p_glDisable(GL_DEPTH_TEST);
p_glDisable(GL_CULL_FACE);
@ -651,12 +740,13 @@ bool FrameBufferGL::createTextures()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferGL::setDimensions(GLdouble* orthoWidth, GLdouble* orthoHeight)
{
cerr << "FrameBufferGL::setDimensions()\n";
// 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);
myImageDim.w = (Uint16) (myBaseDim.w * myZoomLevel * myScaleLevel * theAspectRatio);
myImageDim.h = (Uint16) (myBaseDim.h * myZoomLevel * myScaleLevel);
myScreenDim = myImageDim;
myFSScaleFactor = 1.0f;

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.32 2006-10-14 20:08:29 stephena Exp $
// $Id: FrameBufferGL.hxx,v 1.33 2006-10-16 01:08:59 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.32 2006-10-14 20:08:29 stephena Exp $
@version $Id: FrameBufferGL.hxx,v 1.33 2006-10-16 01:08:59 stephena Exp $
*/
class FrameBufferGL : public FrameBuffer
{
@ -131,7 +131,7 @@ class FrameBufferGL : public FrameBuffer
@param b The blue component of the color.
*/
virtual Uint32 mapRGB(Uint8 r, Uint8 g, Uint8 b)
{ return SDL_MapRGB(myTexture->format, r, g, b); }
{ return SDL_MapRGB(myBaseTexture->format, r, g, b); }
/**
This method is called to draw a horizontal line.
@ -233,12 +233,21 @@ class FrameBufferGL : public FrameBuffer
}
private:
// The main texture buffer
SDL_Surface* myTexture;
// The base and scaled texture buffers
SDL_Surface* myBaseTexture;
SDL_Surface* myScaledTexture;
// Points to the current texture data, which is one of myBaseTexture or myScaledTexture
SDL_Surface* myCurrentTexture;
SDL_Rect myQuadRect;
// The possible OpenGL screenmodes to use
SDL_Rect** myScreenmode;
// Scaler currently in use
ScalerType myScalerType;
// The number of usable OpenGL screenmodes
uInt32 myScreenmodeCount;
@ -261,7 +270,7 @@ class FrameBufferGL : public FrameBuffer
string myFilterParamName;
// FIXME - used for zooming, still work todo here
uInt32 myZoomLevel;
uInt32 myZoomLevel, myScaleLevel;
// The scaling to use in fullscreen mode
// This is separate from both zoomlevel and aspect ratio

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.54 2006-10-14 22:17:26 stephena Exp $
// $Id: FrameBufferSoft.cxx,v 1.55 2006-10-16 01:08:59 stephena Exp $
//============================================================================
#include <SDL.h>
@ -82,8 +82,21 @@ void FrameBufferSoft::setAspectRatio()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferSoft::setScaler(Scaler scaler)
{
// Software framebuffer doesn't handle the fancy scaling modes
myZoomLevel = scaler.zoom;
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:
break; // should never get here
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

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.94 2006-10-14 20:08:29 stephena Exp $
// $Id: Console.cxx,v 1.95 2006-10-16 01:08:59 stephena Exp $
//============================================================================
#include <assert.h>
@ -64,8 +64,7 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Console::Console(const uInt8* image, uInt32 size, const string& md5,
OSystem* osystem)
: myOSystem(osystem),
myIsInitializedFlag(false)
: myOSystem(osystem)
{
myControllers[0] = 0;
myControllers[1] = 0;
@ -223,56 +222,6 @@ Console::Console(const uInt8* image, uInt32 size, const string& md5,
// Reset, the system to its power-on state
mySystem->reset();
// Set the correct framerate based on the format of the ROM
// This can be overridden by changing the framerate in the
// VideoDialog box or on the commandline, but it can't be saved
// (ie, framerate is now solely determined based on ROM format).
uInt32 framerate = myOSystem->settings().getInt("framerate");
if(framerate == 0)
{
const string& s = myProperties.get(Display_Format);
if(s == "NTSC")
framerate = 60;
else if(s == "PAL")
framerate = 50;
else
framerate = 60;
}
myOSystem->setFramerate(framerate);
// Initialize the sound interface.
// The # of channels can be overridden in the AudioDialog box or on
// the commandline, but it can't be saved.
uInt32 channels;
const string& s = myProperties.get(Cartridge_Sound);
if(s == "STEREO")
channels = 2;
else if(s == "MONO")
channels = 1;
else
channels = 1;
myOSystem->sound().close();
myOSystem->sound().setChannels(channels);
myOSystem->sound().setFrameRate(framerate);
myOSystem->sound().initialize();
// Initialize the options menu system with updated values from the framebuffer
myOSystem->menu().initialize();
myOSystem->menu().setGameProfile(myProperties);
// Initialize the command menu system with updated values from the framebuffer
myOSystem->commandMenu().initialize();
#ifdef DEVELOPER_SUPPORT
// Finally, initialize the debugging system, since it depends on the current ROM
myOSystem->debugger().setConsole(this);
myOSystem->debugger().initialize();
#endif
// If we get this far, the console must be valid
myIsInitializedFlag = true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -436,9 +385,63 @@ void Console::saveProperties(string filename, bool merge)
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Console::initialize()
{
// Set the correct framerate based on the format of the ROM
// This can be overridden by changing the framerate in the
// VideoDialog box or on the commandline, but it can't be saved
// (ie, framerate is now solely determined based on ROM format).
uInt32 framerate = myOSystem->settings().getInt("framerate");
if(framerate == 0)
{
const string& s = myProperties.get(Display_Format);
if(s == "NTSC")
framerate = 60;
else if(s == "PAL")
framerate = 50;
else
framerate = 60;
}
myOSystem->setFramerate(framerate);
// Initialize the sound interface.
// The # of channels can be overridden in the AudioDialog box or on
// the commandline, but it can't be saved.
uInt32 channels;
const string& s = myProperties.get(Cartridge_Sound);
if(s == "STEREO")
channels = 2;
else if(s == "MONO")
channels = 1;
else
channels = 1;
myOSystem->sound().close();
myOSystem->sound().setChannels(channels);
myOSystem->sound().setFrameRate(framerate);
myOSystem->sound().initialize();
// Initialize the options menu system with updated values from the framebuffer
myOSystem->menu().initialize();
myOSystem->menu().setGameProfile(myProperties);
// Initialize the command menu system with updated values from the framebuffer
myOSystem->commandMenu().initialize();
#ifdef DEVELOPER_SUPPORT
// Finally, initialize the debugging system, since it depends on the current ROM
myOSystem->debugger().setConsole(this);
myOSystem->debugger().initialize();
#endif
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Console::initializeVideo()
{
cerr << " ==> Console::initializeVideo(): w = " << (myMediaSource->width() << 1)
<< ", h = " << myMediaSource->height() << endl;
string title = string("Stella ") + STELLA_VERSION +
": \"" + myProperties.get(Cartridge_Name) + "\"";
myOSystem->frameBuffer().initialize(title,

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.hxx,v 1.45 2006-08-09 02:38:03 bwmott Exp $
// $Id: Console.hxx,v 1.46 2006-10-16 01:08:59 stephena Exp $
//============================================================================
#ifndef CONSOLE_HXX
@ -38,7 +38,7 @@ class System;
This class represents the entire game console.
@author Bradford W. Mott
@version $Id: Console.hxx,v 1.45 2006-08-09 02:38:03 bwmott Exp $
@version $Id: Console.hxx,v 1.46 2006-10-16 01:08:59 stephena Exp $
*/
class Console
{
@ -120,11 +120,6 @@ class Console
*/
M6532& riot() const { return *myRiot; }
/**
Determine whether the console was successfully created
*/
bool isInitialized() { return myIsInitializedFlag; }
public:
/**
Overloaded assignment operator
@ -165,6 +160,14 @@ class Console
*/
void saveProperties(string filename, bool merge = false);
/**
Initialize the basic properties of the console.
TODO - This is a workaround for a bug in the TIA rendering, whereby
XStart/YStart values cause incorrect coordinates to be passed to the
in-game GUI rendering.
*/
void initialize();
/**
Initialize the video subsystem wrt this class.
*/
@ -276,10 +279,6 @@ class Console
#ifdef ATARIVOX_SUPPORT
AtariVox *vox;
#endif
// Indicates whether the console was correctly initialized
// We don't really care why it wasn't initialized ...
bool myIsInitializedFlag;
};
#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: FrameBuffer.cxx,v 1.92 2006-10-14 22:17:27 stephena Exp $
// $Id: FrameBuffer.cxx,v 1.93 2006-10-16 01:08:59 stephena Exp $
//============================================================================
#include <sstream>
@ -905,28 +905,28 @@ const uInt8 FrameBuffer::ourGUIColors[kNumColors-256][3] = {
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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 }
{ kZOOM1X, "Zoom1x", 1, 1, false },
{ kZOOM2X, "Zoom2x", 2, 1, false },
{ kZOOM3X, "Zoom3x", 3, 1, false },
{ kZOOM4X, "Zoom4x", 4, 1, false },
{ kZOOM5X, "Zoom5x", 5, 1, false },
{ kZOOM6X, "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 },
{ kZOOM1X, "Zoom1x", 1, 1, false },
{ kZOOM2X, "Zoom2x", 2, 1, false },
{ kZOOM3X, "Zoom3x", 3, 1, false },
{ kZOOM4X, "Zoom4x", 4, 1, false },
{ kZOOM5X, "Zoom5x", 5, 1, false },
{ kZOOM6X, "Zoom6x", 6, 1, false },
{ "Scale2x", 1, 2, false },
{ "Scale3x", 1, 3, false },
{ "Scale4x", 1, 4, false },
{ kSCALE2X, "Scale2x", 1, 2, false },
{ kSCALE3X, "Scale3x", 1, 3, false },
{ kSCALE4X, "Scale4x", 1, 4, false },
{ "HQ2x", 1, 2, false },
{ "HQ3x", 1, 3, false },
{ "HQ4x", 1, 4, false }
{ kHQ2X, "HQ2x", 1, 2, false },
{ kHQ3X, "HQ3x", 1, 3, false },
{ kHQ4X, "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.71 2006-10-14 20:08:29 stephena Exp $
// $Id: FrameBuffer.hxx,v 1.72 2006-10-16 01:08:59 stephena Exp $
//============================================================================
#ifndef FRAMEBUFFER_HXX
@ -75,7 +75,13 @@ enum {
};
// Different types of scalers available
enum ScalerType {
kZOOM1X, kZOOM2X, kZOOM3X, kZOOM4X, kZOOM5X, kZOOM6X,
kSCALE2X, kSCALE3X, kSCALE4X,
kHQ2X, kHQ3X, kHQ4X
};
struct Scaler {
ScalerType type;
string name;
int zoom;
int scale;
@ -90,7 +96,7 @@ struct Scaler {
All GUI elements (ala ScummVM) are drawn here as well.
@author Stephen Anthony
@version $Id: FrameBuffer.hxx,v 1.71 2006-10-14 20:08:29 stephena Exp $
@version $Id: FrameBuffer.hxx,v 1.72 2006-10-16 01:08:59 stephena Exp $
*/
class FrameBuffer
{

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.71 2006-10-14 20:08:29 stephena Exp $
// $Id: OSystem.cxx,v 1.72 2006-10-16 01:09:00 stephena Exp $
//============================================================================
#include <cassert>
@ -301,7 +301,7 @@ bool OSystem::createConsole(const string& romfile)
// Create an instance of the 2600 game console
// The Console c'tor takes care of updating the eventhandler state
myConsole = new Console(image, size, md5, this);
if(myConsole->isInitialized())
if(myConsole)
{
#ifdef CHEATCODE_SUPPORT
myCheatManager->loadCheats(md5);
@ -314,6 +314,7 @@ bool OSystem::createConsole(const string& romfile)
myEventHandler->reset(EventHandler::S_EMULATE);
createFrameBuffer(false);
myFrameBuffer->setCursorState();
myConsole->initialize(); // Must be done *after* the framebuffer is created
retval = true;
}
else

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: OptionsDialog.cxx,v 1.39 2006-05-04 17:45:25 stephena Exp $
// $Id: OptionsDialog.cxx,v 1.40 2006-10-16 01:09:00 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -70,16 +70,18 @@ OptionsDialog::OptionsDialog(OSystem* osystem, DialogContainer* parent)
myHelpDialog(NULL),
myAboutDialog(NULL)
{
// Set actual dialog dimensions
_x = (osystem->frameBuffer().baseWidth() - kMainMenuWidth) / 2;
_y = (osystem->frameBuffer().baseHeight() - kMainMenuHeight) / 2;
int yoffset = 7;
const int xoffset = (_w - kBigButtonWidth) / 2;
const int fbWidth = osystem->frameBuffer().baseWidth(),
fbHeight = osystem->frameBuffer().baseHeight();
const GUI::Font& font = instance()->font(); // FIXME - change reference to optionsFont()
WidgetArray wid;
ButtonWidget* b = NULL;
// Set actual dialog dimensions
_x = (fbWidth - kMainMenuWidth) / 2;
_y = (fbHeight - kMainMenuHeight) / 2;
b = addBigButton("Video Settings", kVidCmd);
wid.push_back(b);
@ -111,8 +113,6 @@ OptionsDialog::OptionsDialog(OSystem* osystem, DialogContainer* parent)
wid.push_back(b);
// Set some sane values for the dialog boxes
int fbWidth = osystem->frameBuffer().baseWidth();
int fbHeight = osystem->frameBuffer().baseHeight();
int x, y, w, h;
// Now create all the dialogs attached to each menu button