From e3b36b202c0c36c9a5a42f725cb424766eee1aaa Mon Sep 17 00:00:00 2001 From: stephena Date: Mon, 16 Oct 2006 01:09:00 +0000 Subject: [PATCH] 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 --- stella/src/common/FrameBufferGL.cxx | 342 ++++++++++++++++---------- stella/src/common/FrameBufferGL.hxx | 21 +- stella/src/common/FrameBufferSoft.cxx | 19 +- stella/src/emucore/Console.cxx | 109 ++++---- stella/src/emucore/Console.hxx | 21 +- stella/src/emucore/FrameBuffer.cxx | 38 +-- stella/src/emucore/FrameBuffer.hxx | 10 +- stella/src/emucore/OSystem.cxx | 5 +- stella/src/gui/OptionsDialog.cxx | 14 +- 9 files changed, 350 insertions(+), 229 deletions(-) diff --git a/stella/src/common/FrameBufferGL.cxx b/stella/src/common/FrameBufferGL.cxx index b273282e2..366121b36 100644 --- a/stella/src/common/FrameBufferGL.cxx +++ b/stella/src/common/FrameBufferGL.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: 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; diff --git a/stella/src/common/FrameBufferGL.hxx b/stella/src/common/FrameBufferGL.hxx index e990bc59c..77e8e5f46 100644 --- a/stella/src/common/FrameBufferGL.hxx +++ b/stella/src/common/FrameBufferGL.hxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: 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 diff --git a/stella/src/common/FrameBufferSoft.cxx b/stella/src/common/FrameBufferSoft.cxx index e558947d0..0a5151262 100644 --- a/stella/src/common/FrameBufferSoft.cxx +++ b/stella/src/common/FrameBufferSoft.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: 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 @@ -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 + } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/stella/src/emucore/Console.cxx b/stella/src/emucore/Console.cxx index 08cbe27c8..15f3f4116 100644 --- a/stella/src/emucore/Console.cxx +++ b/stella/src/emucore/Console.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: 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 @@ -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, diff --git a/stella/src/emucore/Console.hxx b/stella/src/emucore/Console.hxx index 724ed2bcc..5d1a9723a 100644 --- a/stella/src/emucore/Console.hxx +++ b/stella/src/emucore/Console.hxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: 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 diff --git a/stella/src/emucore/FrameBuffer.cxx b/stella/src/emucore/FrameBuffer.cxx index 0619a0cf7..d9f56a9b4 100644 --- a/stella/src/emucore/FrameBuffer.cxx +++ b/stella/src/emucore/FrameBuffer.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: 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 @@ -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 } }; diff --git a/stella/src/emucore/FrameBuffer.hxx b/stella/src/emucore/FrameBuffer.hxx index 5b75cf2fe..c4a7cb115 100644 --- a/stella/src/emucore/FrameBuffer.hxx +++ b/stella/src/emucore/FrameBuffer.hxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: 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 { diff --git a/stella/src/emucore/OSystem.cxx b/stella/src/emucore/OSystem.cxx index dd652911a..623ecb490 100644 --- a/stella/src/emucore/OSystem.cxx +++ b/stella/src/emucore/OSystem.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: 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 @@ -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 diff --git a/stella/src/gui/OptionsDialog.cxx b/stella/src/gui/OptionsDialog.cxx index 221b1d5c1..a82a2068c 100644 --- a/stella/src/gui/OptionsDialog.cxx +++ b/stella/src/gui/OptionsDialog.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: 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