Added 'GL_TEXTURE_RECTANGLE_ARB' texturing to FrameBufferGL, since it's

apparently faster on hardware that supports it.  Added GL optimizations
for Apple/OSX OpenGL, which is supposed to be much faster on lower-end
hardware.

In the process of completely removing advanced scaler support from the
OpenGL rendering modes.  I could never get the code to work anyway, and
there's much more important stuff to do in the core.

Fixed bug in properties saving where all ROM properties were being saved,
not just the ones edited from GameInfoDialog.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1209 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2006-12-13 17:09:11 +00:00
parent 534ef05cc0
commit ab51324f50
9 changed files with 271 additions and 341 deletions

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: FrameBufferGL.cxx,v 1.73 2006-12-11 00:15:33 stephena Exp $ // $Id: FrameBufferGL.cxx,v 1.74 2006-12-13 17:09:09 stephena Exp $
//============================================================================ //============================================================================
#ifdef DISPLAY_OPENGL #ifdef DISPLAY_OPENGL
@ -31,10 +31,6 @@
#include "Font.hxx" #include "Font.hxx"
#include "GuiUtils.hxx" #include "GuiUtils.hxx"
#ifdef SCALER_SUPPORT
#include "scaler.hxx"
#endif
// There's probably a cleaner way of doing this // There's probably a cleaner way of doing this
// These values come from SDL_video.c // These values come from SDL_video.c
// If they change, this code will break horribly // If they change, this code will break horribly
@ -45,6 +41,15 @@
#define SDL_GL_SWAP_CONTROL SDL_GLattr(16) #define SDL_GL_SWAP_CONTROL SDL_GLattr(16)
#endif #endif
// These are not defined in the current version of SDL_opengl.h
// Hopefully speed up OpenGL rendering in OSX
#ifndef GL_TEXTURE_STORAGE_HINT_APPLE
#define GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC
#endif
#ifndef GL_STORAGE_SHARED_APPLE
#define GL_STORAGE_SHARED_APPLE 0x85BF
#endif
// Maybe this code could be cleaner ... // Maybe this code could be cleaner ...
static void (APIENTRY* p_glClear)( GLbitfield ); static void (APIENTRY* p_glClear)( GLbitfield );
static void (APIENTRY* p_glEnable)( GLenum ); static void (APIENTRY* p_glEnable)( GLenum );
@ -52,6 +57,7 @@ static void (APIENTRY* p_glDisable)( GLenum );
static void (APIENTRY* p_glPushAttrib)( GLbitfield ); static void (APIENTRY* p_glPushAttrib)( GLbitfield );
static const GLubyte* (APIENTRY* p_glGetString)( GLenum ); static const GLubyte* (APIENTRY* p_glGetString)( GLenum );
static void (APIENTRY* p_glHint)( GLenum, GLenum ); static void (APIENTRY* p_glHint)( GLenum, GLenum );
static void (APIENTRY* p_glShadeModel)( GLenum );
// Matrix // Matrix
static void (APIENTRY* p_glMatrixMode)( GLenum ); static void (APIENTRY* p_glMatrixMode)( GLenum );
@ -83,38 +89,26 @@ static void (APIENTRY* p_glTexParameteri)( GLenum, GLenum, GLint );
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FrameBufferGL::FrameBufferGL(OSystem* osystem) FrameBufferGL::FrameBufferGL(OSystem* osystem)
: FrameBuffer(osystem), : FrameBuffer(osystem),
myBaseTexture(NULL), myTexture(NULL),
myScaledTexture(NULL),
myCurrentTexture(NULL),
myScreenmode(0), myScreenmode(0),
myScreenmodeCount(0), myScreenmodeCount(0),
myTextureID(0),
myFilterParam(GL_NEAREST),
myFilterParamName("GL_NEAREST"), myFilterParamName("GL_NEAREST"),
myZoomLevel(1), myZoomLevel(1),
myScaleLevel(1),
myFSScaleFactor(1.0), myFSScaleFactor(1.0),
myDirtyFlag(true) myDirtyFlag(true),
myHaveTexRectEXT(false),
myHaveAppleCStorageEXT(false),
myHaveAppleTexRangeEXT(false)
{ {
#ifdef SCALER_SUPPORT
myScalerProc = 0;
InitScalers();
#endif
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FrameBufferGL::~FrameBufferGL() FrameBufferGL::~FrameBufferGL()
{ {
if(myBaseTexture) if(myTexture)
SDL_FreeSurface(myBaseTexture); SDL_FreeSurface(myTexture);
if(myScaledTexture)
SDL_FreeSurface(myScaledTexture);
p_glDeleteTextures(1, &myTextureID); p_glDeleteTextures(1, &myBuffer.texture);
#ifdef SCALER_SUPPORT
FreeScalers();
#endif
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -146,6 +140,8 @@ bool FrameBufferGL::loadFuncs(const string& library)
SDL_GL_GetProcAddress("glGetString"); if(!p_glGetString) return false; SDL_GL_GetProcAddress("glGetString"); if(!p_glGetString) return false;
p_glHint = (void(APIENTRY*)(GLenum, GLenum)) p_glHint = (void(APIENTRY*)(GLenum, GLenum))
SDL_GL_GetProcAddress("glHint"); if(!p_glHint) return false; SDL_GL_GetProcAddress("glHint"); if(!p_glHint) return false;
p_glShadeModel = (void(APIENTRY*)(GLenum))
SDL_GL_GetProcAddress("glShadeModel"); if(!p_glShadeModel) return false;
p_glMatrixMode = (void(APIENTRY*)(GLenum)) p_glMatrixMode = (void(APIENTRY*)(GLenum))
SDL_GL_GetProcAddress("glMatrixMode"); if(!p_glMatrixMode) return false; SDL_GL_GetProcAddress("glMatrixMode"); if(!p_glMatrixMode) return false;
@ -199,22 +195,16 @@ bool FrameBufferGL::initSubsystem()
myDepth = SDL_GetVideoInfo()->vfmt->BitsPerPixel; myDepth = SDL_GetVideoInfo()->vfmt->BitsPerPixel;
switch(myDepth) switch(myDepth)
{ {
case 8:
myRGB[0] = 3; myRGB[1] = 3; myRGB[2] = 2; myRGB[3] = 0;
break;
case 15: case 15:
case 16:
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; break;
case 16:
myRGB[0] = 5; myRGB[1] = 6; myRGB[2] = 5; myRGB[3] = 0;
break;
case 24: case 24:
case 32:
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; break;
case 32:
myRGB[0] = 8; myRGB[1] = 8; myRGB[2] = 8; myRGB[3] = 8;
break;
default: // This should never happen default: // This should never happen
return false;
break; break;
} }
@ -241,15 +231,21 @@ bool FrameBufferGL::initSubsystem()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string FrameBufferGL::about() string FrameBufferGL::about()
{ {
ostringstream out; string extensions;
if(myHaveTexRectEXT) extensions += "GL_TEXTURE_RECTANGLE_ARB ";
if(myHaveAppleCStorageEXT) extensions += "GL_TEXTURE_STORAGE_HINT_APPLE ";
if(myHaveAppleTexRangeEXT) extensions += "GL_TEXTURE_STORAGE_HINT_APPLE ";
if(extensions == "") extensions = "None";
ostringstream out;
out << "Video rendering: OpenGL mode" << endl out << "Video rendering: OpenGL mode" << endl
<< " Vendor : " << p_glGetString(GL_VENDOR) << endl << " Vendor: " << p_glGetString(GL_VENDOR) << endl
<< " Renderer: " << p_glGetString(GL_RENDERER) << endl << " Renderer: " << p_glGetString(GL_RENDERER) << endl
<< " Version : " << p_glGetString(GL_VERSION) << endl << " Version: " << p_glGetString(GL_VERSION) << endl
<< " Color : " << myDepth << " bit, " << myRGB[0] << "-" << " Color: " << myDepth << " bit, " << myRGB[0] << "-"
<< myRGB[1] << "-" << myRGB[2] << "-" << myRGB[3] << endl << myRGB[1] << "-" << myRGB[2] << "-" << myRGB[3] << endl
<< " Filter : " << myFilterParamName << endl; << " Filter: " << myFilterParamName << endl
<< " Extensions: " << extensions << endl;
return out.str(); return out.str();
} }
@ -265,61 +261,7 @@ void FrameBufferGL::setAspectRatio()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferGL::setScaler(Scaler scaler) void FrameBufferGL::setScaler(Scaler scaler)
{ {
myScalerType = scaler.type; myZoomLevel = scaler.zoom;
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;
#ifdef SCALER_SUPPORT
case kSCALE2X:
myQuadRect.w = myBaseDim.w * 2;
myQuadRect.h = myBaseDim.h * 2;
cerr << "scaler: " << scaler.name << endl;
myScalerProc = AdvMame2x;
break;
case kSCALE3X:
myQuadRect.w = myBaseDim.w * 3;
myQuadRect.h = myBaseDim.h * 3;
cerr << "scaler: " << scaler.name << endl;
myScalerProc = AdvMame3x;
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;
myScalerProc = HQ2x;
break;
case kHQ3X:
myQuadRect.w = myBaseDim.w * 3;
myQuadRect.h = myBaseDim.h * 3;
cerr << "scaler: " << scaler.name << endl;
myScalerProc = HQ3x;
break;
case kHQ4X:
myQuadRect.w = myBaseDim.w * 4;
myQuadRect.h = myBaseDim.h * 4;
cerr << "scaler: " << scaler.name << endl;
break;
#endif
default:
break;
}
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -342,35 +284,46 @@ bool FrameBufferGL::createScreen()
GLdouble orthoHeight = 0.0; GLdouble orthoHeight = 0.0;
setDimensions(&orthoWidth, &orthoHeight); setDimensions(&orthoWidth, &orthoHeight);
// Create screen containing GL context
myScreen = SDL_SetVideoMode(myScreenDim.w, myScreenDim.h, 0, mySDLFlags); myScreen = SDL_SetVideoMode(myScreenDim.w, myScreenDim.h, 0, mySDLFlags);
if(myScreen == NULL) if(myScreen == NULL)
{ {
cerr << "ERROR: Unable to open SDL window: " << SDL_GetError() << endl; cerr << "ERROR: Unable to open SDL window: " << SDL_GetError() << endl;
return false; return false;
} }
myUse16Bit = (myDepth == 15 || myDepth == 16);
p_glPushAttrib(GL_ENABLE_BIT); // Check for some extensions that can potentially speed up operation
const char* extensions = (const char *) p_glGetString(GL_EXTENSIONS);
myHaveTexRectEXT = strstr(extensions, "ARB_texture_rectangle") != NULL;
myHaveAppleCStorageEXT = strstr(extensions, "APPLE_client_storage") != NULL;
myHaveAppleTexRangeEXT = strstr(extensions, "APPLE_texture_range") != NULL;
// Center the image horizontally and vertically // Initialize GL display
p_glViewport(myImageDim.x, myImageDim.y, myImageDim.w, myImageDim.h); p_glViewport(myImageDim.x, myImageDim.y, myImageDim.w, myImageDim.h);
p_glShadeModel(GL_FLAT);
p_glDisable(GL_CULL_FACE);
p_glDisable(GL_DEPTH_TEST);
p_glDisable(GL_ALPHA_TEST);
p_glDisable(GL_LIGHTING);
p_glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
if(myHaveTexRectEXT)
p_glEnable(GL_TEXTURE_RECTANGLE_ARB);
else
p_glEnable(GL_TEXTURE_2D);
p_glMatrixMode(GL_PROJECTION); p_glMatrixMode(GL_PROJECTION);
p_glPushMatrix();
p_glLoadIdentity(); p_glLoadIdentity();
p_glOrtho(0.0, orthoWidth, orthoHeight, 0, -1.0, 1.0);
p_glOrtho(0.0, orthoWidth, orthoHeight, 0.0, 0.0, 1.0);
p_glMatrixMode(GL_MODELVIEW); p_glMatrixMode(GL_MODELVIEW);
p_glPushMatrix();
p_glLoadIdentity(); p_glLoadIdentity();
// Allocate GL textures
createTextures(); createTextures();
// Make sure any old parts of the screen are erased // Make sure any old parts of the screen are erased
// Do it for both buffers! cls();
p_glClear(GL_COLOR_BUFFER_BIT);
SDL_GL_SwapBuffers();
p_glClear(GL_COLOR_BUFFER_BIT);
return true; return true;
} }
@ -385,7 +338,7 @@ void FrameBufferGL::drawMediaSource()
uInt8* previousFrame = mediasrc.previousFrameBuffer(); uInt8* previousFrame = mediasrc.previousFrameBuffer();
uInt32 width = mediasrc.width(); uInt32 width = mediasrc.width();
uInt32 height = mediasrc.height(); uInt32 height = mediasrc.height();
uInt16* buffer = (uInt16*) myBaseTexture->pixels; uInt16* buffer = (uInt16*) myTexture->pixels;
// TODO - is this fast enough? // TODO - is this fast enough?
if(!myUsePhosphor) if(!myUsePhosphor)
@ -413,7 +366,7 @@ void FrameBufferGL::drawMediaSource()
pos += 2; pos += 2;
} }
bufofsY += width; bufofsY += width;
screenofsY += myBaseTexture->w; screenofsY += myTexture->w;
} }
} }
else else
@ -437,22 +390,9 @@ void FrameBufferGL::drawMediaSource()
buffer[pos++] = (uInt16) myAvgPalette[v][w]; buffer[pos++] = (uInt16) myAvgPalette[v][w];
} }
bufofsY += width; bufofsY += width;
screenofsY += myBaseTexture->w; screenofsY += myTexture->w;
} }
} }
#ifdef SCALER_SUPPORT
// 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
if(myDirtyFlag && myScalerProc)
{
myScalerProc((uInt8*) myBaseTexture->pixels, myBaseTexture->pitch,
(uInt8*) myScaledTexture->pixels, myScaledTexture->pitch,
myBaseTexture->w, myBaseTexture->h);
}
#endif
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -467,23 +407,16 @@ void FrameBufferGL::postFrameUpdate()
{ {
// Texturemap complete texture to surface so we have free scaling // Texturemap complete texture to surface so we have free scaling
// and antialiasing // and antialiasing
uInt32 w = myQuadRect.w, h = myQuadRect.h; uInt32 w = myBuffer.width, h = myBuffer.height;
p_glBindTexture(GL_TEXTURE_2D, myTextureID); p_glTexSubImage2D(myBuffer.target, 0, 0, 0,
p_glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, myBuffer.texture_width, myBuffer.texture_height,
myCurrentTexture->w, myCurrentTexture->h, myBuffer.format, myBuffer.type, myBuffer.pixels);
GL_RGB, GL_UNSIGNED_SHORT_5_6_5, myCurrentTexture->pixels);
p_glBegin(GL_QUADS); p_glBegin(GL_QUADS);
/* Upside down ! p_glTexCoord2f(myBuffer.tex_coord[0], myBuffer.tex_coord[1]); p_glVertex2i(0, 0);
p_glTexCoord2f(myTexCoord[2], myTexCoord[3]); p_glVertex2i(0, 0); p_glTexCoord2f(myBuffer.tex_coord[2], myBuffer.tex_coord[1]); p_glVertex2i(w, 0);
p_glTexCoord2f(myTexCoord[0], myTexCoord[3]); p_glVertex2i(w, 0); p_glTexCoord2f(myBuffer.tex_coord[2], myBuffer.tex_coord[3]); p_glVertex2i(w, h);
p_glTexCoord2f(myTexCoord[0], myTexCoord[1]); p_glVertex2i(w, h); p_glTexCoord2f(myBuffer.tex_coord[0], myBuffer.tex_coord[3]); p_glVertex2i(0, h);
p_glTexCoord2f(myTexCoord[2], myTexCoord[1]); p_glVertex2i(0, h);
*/
p_glTexCoord2f(myTexCoord[0], myTexCoord[1]); p_glVertex2i(0, 0);
p_glTexCoord2f(myTexCoord[2], myTexCoord[1]); p_glVertex2i(w, 0);
p_glTexCoord2f(myTexCoord[2], myTexCoord[3]); p_glVertex2i(w, h);
p_glTexCoord2f(myTexCoord[0], myTexCoord[3]); p_glVertex2i(0, h);
p_glEnd(); p_glEnd();
// Now show all changes made to the texture // Now show all changes made to the texture
@ -507,24 +440,24 @@ void FrameBufferGL::scanline(uInt32 row, uInt8* data)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferGL::toggleFilter() void FrameBufferGL::toggleFilter()
{ {
if(myFilterParam == GL_NEAREST) if(myBuffer.filter == GL_NEAREST)
{ {
myFilterParam = GL_LINEAR; myBuffer.filter = GL_LINEAR;
myOSystem->settings().setString("gl_filter", "linear"); myOSystem->settings().setString("gl_filter", "linear");
showMessage("Filtering: GL_LINEAR"); showMessage("Filtering: GL_LINEAR");
} }
else else
{ {
myFilterParam = GL_NEAREST; myBuffer.filter = GL_NEAREST;
myOSystem->settings().setString("gl_filter", "nearest"); myOSystem->settings().setString("gl_filter", "nearest");
showMessage("Filtering: GL_NEAREST"); showMessage("Filtering: GL_NEAREST");
} }
p_glBindTexture(GL_TEXTURE_2D, myTextureID); p_glBindTexture(myBuffer.target, myBuffer.texture);
p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); p_glTexParameteri(myBuffer.target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); p_glTexParameteri(myBuffer.target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, myFilterParam); p_glTexParameteri(myBuffer.target, GL_TEXTURE_MAG_FILTER, myBuffer.filter);
p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, myFilterParam); p_glTexParameteri(myBuffer.target, GL_TEXTURE_MIN_FILTER, myBuffer.filter);
// The filtering has changed, so redraw the entire screen // The filtering has changed, so redraw the entire screen
theRedrawTIAIndicator = true; theRedrawTIAIndicator = true;
@ -533,56 +466,38 @@ void FrameBufferGL::toggleFilter()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferGL::hLine(uInt32 x, uInt32 y, uInt32 x2, int color) void FrameBufferGL::hLine(uInt32 x, uInt32 y, uInt32 x2, int color)
{ {
#ifndef SCALER_SUPPORT
uInt16* buffer = (uInt16*) myCurrentTexture->pixels + y * myCurrentTexture->w + x;
while(x++ <= x2)
*buffer++ = (uInt16) myDefPalette[color];
#else
SDL_Rect tmp;
// Horizontal line // Horizontal line
tmp.x = x * myScaleLevel; SDL_Rect tmp;
tmp.y = y * myScaleLevel; tmp.x = x;
tmp.w = (x2 - x + 1) * myScaleLevel; tmp.y = y;
tmp.h = myScaleLevel; tmp.w = x2 - x + 1;
SDL_FillRect(myCurrentTexture, &tmp, myDefPalette[color]); tmp.h = 1;
#endif SDL_FillRect(myTexture, &tmp, myDefPalette[color]);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferGL::vLine(uInt32 x, uInt32 y, uInt32 y2, int color) void FrameBufferGL::vLine(uInt32 x, uInt32 y, uInt32 y2, int color)
{ {
#ifndef SCALER_SUPPORT
uInt16* buffer = (uInt16*) myCurrentTexture->pixels + y * myCurrentTexture->w + x;
while(y++ <= y2)
{
*buffer = (uInt16) myDefPalette[color];
buffer += myCurrentTexture->w;
}
#else
SDL_Rect tmp;
// Vertical line // Vertical line
tmp.x = x * myScaleLevel; SDL_Rect tmp;
tmp.y = y * myScaleLevel; tmp.x = x;
tmp.w = myScaleLevel; tmp.y = y;
tmp.h = (y2 - y + 1) * myScaleLevel; tmp.w = 1;
SDL_FillRect(myCurrentTexture, &tmp, myDefPalette[color]); tmp.h = y2 - y + 1;
#endif SDL_FillRect(myTexture, &tmp, myDefPalette[color]);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferGL::fillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h, void FrameBufferGL::fillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
int color) int color)
{ {
SDL_Rect tmp;
// Fill the rectangle // Fill the rectangle
tmp.x = x * myScaleLevel; SDL_Rect tmp;
tmp.y = y * myScaleLevel; tmp.x = x;
tmp.w = w * myScaleLevel; tmp.y = y;
tmp.h = h * myScaleLevel; tmp.w = w;
SDL_FillRect(myCurrentTexture, &tmp, myDefPalette[color]); tmp.h = h;
SDL_FillRect(myTexture, &tmp, myDefPalette[color]);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -604,7 +519,7 @@ void FrameBufferGL::drawChar(const GUI::Font* font, uInt8 chr,
const uInt16* tmp = font->desc().bits + (font->desc().offset ? const uInt16* tmp = font->desc().bits + (font->desc().offset ?
font->desc().offset[chr] : (chr * h)); font->desc().offset[chr] : (chr * h));
uInt16* buffer = (uInt16*) myCurrentTexture->pixels + ty * myCurrentTexture->w + tx; uInt16* buffer = (uInt16*) myTexture->pixels + ty * myTexture->w + tx;
for(int y = 0; y < h; ++y) for(int y = 0; y < h; ++y)
{ {
const uInt16 ptr = *tmp++; const uInt16 ptr = *tmp++;
@ -615,7 +530,7 @@ void FrameBufferGL::drawChar(const GUI::Font* font, uInt8 chr,
if(ptr & mask) if(ptr & mask)
buffer[x] = (uInt16) myDefPalette[color]; buffer[x] = (uInt16) myDefPalette[color];
} }
buffer += myCurrentTexture->w; buffer += myTexture->w;
} }
} }
@ -623,7 +538,7 @@ void FrameBufferGL::drawChar(const GUI::Font* font, uInt8 chr,
void FrameBufferGL::drawBitmap(uInt32* bitmap, Int32 tx, Int32 ty, void FrameBufferGL::drawBitmap(uInt32* bitmap, Int32 tx, Int32 ty,
int color, Int32 h) int color, Int32 h)
{ {
uInt16* buffer = (uInt16*) myCurrentTexture->pixels + ty * myCurrentTexture->w + tx; uInt16* buffer = (uInt16*) myTexture->pixels + ty * myTexture->w + tx;
for(int y = 0; y < h; ++y) for(int y = 0; y < h; ++y)
{ {
@ -633,7 +548,7 @@ void FrameBufferGL::drawBitmap(uInt32* bitmap, Int32 tx, Int32 ty,
if(bitmap[y] & mask) if(bitmap[y] & mask)
buffer[x] = (uInt16) myDefPalette[color]; buffer[x] = (uInt16) myDefPalette[color];
} }
buffer += myCurrentTexture->w; buffer += myTexture->w;
} }
} }
@ -641,8 +556,8 @@ void FrameBufferGL::drawBitmap(uInt32* bitmap, Int32 tx, Int32 ty,
void FrameBufferGL::translateCoords(Int32* x, Int32* y) void FrameBufferGL::translateCoords(Int32* x, Int32* y)
{ {
// Wow, what a mess :) // Wow, what a mess :)
*x = (Int32) (((*x - myImageDim.x) / (myZoomLevel * myScaleLevel * myFSScaleFactor * theAspectRatio))); *x = (Int32) (((*x - myImageDim.x) / (myZoomLevel * myFSScaleFactor * theAspectRatio)));
*y = (Int32) (((*y - myImageDim.y) / (myZoomLevel * myScaleLevel * myFSScaleFactor))); *y = (Int32) (((*y - myImageDim.y) / (myZoomLevel * myFSScaleFactor)));
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -661,7 +576,7 @@ void FrameBufferGL::enablePhosphor(bool enable, int blend)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferGL::cls() void FrameBufferGL::cls()
{ {
if(myFuncsLoaded && myCurrentTexture) if(myFuncsLoaded && myTexture)
{ {
p_glClear(GL_COLOR_BUFFER_BIT); p_glClear(GL_COLOR_BUFFER_BIT);
SDL_GL_SwapBuffers(); SDL_GL_SwapBuffers();
@ -672,93 +587,112 @@ void FrameBufferGL::cls()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool FrameBufferGL::createTextures() bool FrameBufferGL::createTextures()
{ {
if(myBaseTexture) if(myTexture) SDL_FreeSurface(myTexture);
{ if(myBuffer.texture) p_glDeleteTextures(1, &myBuffer.texture);
SDL_FreeSurface(myBaseTexture); memset(&myBuffer, 0, sizeof(glBufferType));
myBaseTexture = NULL; myBuffer.filter = GL_NEAREST;
}
if(myScaledTexture)
{
SDL_FreeSurface(myScaledTexture);
myScaledTexture = NULL;
}
myCurrentTexture = NULL;
p_glDeleteTextures(1, &myTextureID);
// Fill buffer struct with valid data
// This changes depending on the texturing used
myBuffer.width = myBaseDim.w;
myBuffer.height = myBaseDim.h;
myBuffer.tex_coord[0] = 0.0f;
myBuffer.tex_coord[1] = 0.0f;
if(myHaveTexRectEXT)
{
myBuffer.texture_width = myBuffer.width;
myBuffer.texture_height = myBuffer.height;
myBuffer.target = GL_TEXTURE_RECTANGLE_ARB;
myBuffer.tex_coord[2] = (GLfloat) myBuffer.texture_width;
myBuffer.tex_coord[3] = (GLfloat) myBuffer.texture_height;
}
else
{
myBuffer.texture_width = power_of_two(myBuffer.width);
myBuffer.texture_height = power_of_two(myBuffer.height);
myBuffer.target = GL_TEXTURE_2D;
myBuffer.tex_coord[2] = (GLfloat) myBuffer.width / myBuffer.texture_width;
myBuffer.tex_coord[3] = (GLfloat) myBuffer.height / myBuffer.texture_height;
}
// Create a texture that best suits the current display depth and system
// This code needs to be Apple-specific, otherwise performance is
// terrible on a Mac Mini
// if(myUse16Bit)
{
#if defined(MAC_OSX)
myTexture = SDL_CreateRGBSurface(SDL_SWSURFACE,
myBuffer.texture_width, myBuffer.texture_height, 16,
0x00007c00, 0x000003e0, 0x0000001f, 0x00000000);
#else
myTexture = SDL_CreateRGBSurface(SDL_SWSURFACE,
myBuffer.texture_width, myBuffer.texture_height, 16,
0x0000f800, 0x000007e0, 0x0000001f, 0x00000000);
#endif
}
/* /*
cerr << "texture dimensions (before power of 2 scaling):" << endl else
<< "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) myQuadRect.w / w1;
myTexCoord[3] = (GLfloat) myQuadRect.h / h1;
myBaseTexture = SDL_CreateRGBSurface(SDL_SWSURFACE, w1, h1, 16,
0x0000F800, 0x000007E0, 0x0000001F, 0x00000000);
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: myTexture = SDL_CreateRGBSurface(SDL_SWSURFACE,
case kZOOM2X: myBuffer.texture_width, myBuffer.texture_height, 32,
case kZOOM3X: 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000);
case kZOOM4X:
case kZOOM5X:
case kZOOM6X:
myCurrentTexture = myBaseTexture;
break;
default:
myCurrentTexture = myScaledTexture;
break;
} }
*/
if(myTexture == NULL)
return false;
myBuffer.pixels = myTexture->pixels;
myBuffer.pitch = myTexture->pitch;
// Create an OpenGL texture from the SDL texture // Create an OpenGL texture from the SDL texture
string filter = myOSystem->settings().getString("gl_filter"); const string& filter = myOSystem->settings().getString("gl_filter");
if(filter == "linear") if(filter == "linear")
{ {
myFilterParam = GL_LINEAR; myBuffer.filter = GL_LINEAR;
myFilterParamName = "GL_LINEAR"; myFilterParamName = "GL_LINEAR";
} }
else if(filter == "nearest") else if(filter == "nearest")
{ {
myFilterParam = GL_NEAREST; myBuffer.filter = GL_NEAREST;
myFilterParamName = "GL_NEAREST"; myFilterParamName = "GL_NEAREST";
} }
p_glGenTextures(1, &myTextureID); p_glGenTextures(1, &myBuffer.texture);
p_glBindTexture(GL_TEXTURE_2D, myTextureID); p_glBindTexture(myBuffer.target, myBuffer.texture);
p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); if(myHaveAppleCStorageEXT)
p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, myFilterParam); if(myHaveAppleTexRangeEXT)
p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, myFilterParam); p_glTexParameteri(myBuffer.target, GL_TEXTURE_STORAGE_HINT_APPLE, GL_STORAGE_SHARED_APPLE);
p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, p_glTexParameteri(myBuffer.target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
myCurrentTexture->w, myCurrentTexture->h, 0, p_glTexParameteri(myBuffer.target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
GL_RGB, GL_UNSIGNED_SHORT_5_6_5, NULL); p_glTexParameteri(myBuffer.target, GL_TEXTURE_MIN_FILTER, myBuffer.filter);
p_glTexParameteri(myBuffer.target, GL_TEXTURE_MAG_FILTER, myBuffer.filter);
p_glDisable(GL_DEPTH_TEST); // Finally, create the texture in the most optimal format
p_glDisable(GL_CULL_FACE); GLenum tex_intformat;
p_glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); // if(myUse16Bit)
p_glEnable(GL_TEXTURE_2D); {
#if defined (MAC_OSX)
p_glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); tex_intformat = GL_RGB5;
myBuffer.format = GL_BGRA;
myBuffer.type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
#else
tex_intformat = GL_RGB;
myBuffer.format = GL_RGB;
myBuffer.type = GL_UNSIGNED_SHORT_5_6_5;
#endif
}
/*
else
{
tex_intformat = GL_RGBA8;
myBuffer.format = GL_BGRA;
myBuffer.type = GL_UNSIGNED_INT_8_8_8_8_REV;
}
*/
p_glTexImage2D(myBuffer.target, 0, tex_intformat,
myBuffer.texture_width, myBuffer.texture_height, 0,
myBuffer.format, myBuffer.type, myBuffer.pixels);
return true; return true;
} }
@ -770,8 +704,8 @@ void FrameBufferGL::setDimensions(GLdouble* orthoWidth, GLdouble* orthoHeight)
// We have to determine final image dimensions as well as screen dimensions // We have to determine final image dimensions as well as screen dimensions
myImageDim.x = 0; myImageDim.x = 0;
myImageDim.y = 0; myImageDim.y = 0;
myImageDim.w = (Uint16) (myBaseDim.w * myZoomLevel * myScaleLevel * theAspectRatio); myImageDim.w = (Uint16) (myBaseDim.w * myZoomLevel * theAspectRatio);
myImageDim.h = (Uint16) (myBaseDim.h * myZoomLevel * myScaleLevel); myImageDim.h = (Uint16) (myBaseDim.h * myZoomLevel);
myScreenDim = myImageDim; myScreenDim = myImageDim;
myFSScaleFactor = 1.0f; myFSScaleFactor = 1.0f;

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: FrameBufferGL.hxx,v 1.38 2006-12-11 00:15:33 stephena Exp $ // $Id: FrameBufferGL.hxx,v 1.39 2006-12-13 17:09:09 stephena Exp $
//============================================================================ //============================================================================
#ifndef FRAMEBUFFER_GL_HXX #ifndef FRAMEBUFFER_GL_HXX
@ -32,15 +32,11 @@ class GUI::Font;
#include "GuiUtils.hxx" #include "GuiUtils.hxx"
#include "FrameBuffer.hxx" #include "FrameBuffer.hxx"
#ifdef SCALER_SUPPORT
#include "scaler.hxx"
#endif
/** /**
This class implements an SDL OpenGL framebuffer. This class implements an SDL OpenGL framebuffer.
@author Stephen Anthony @author Stephen Anthony
@version $Id: FrameBufferGL.hxx,v 1.38 2006-12-11 00:15:33 stephena Exp $ @version $Id: FrameBufferGL.hxx,v 1.39 2006-12-13 17:09:09 stephena Exp $
*/ */
class FrameBufferGL : public FrameBuffer class FrameBufferGL : public FrameBuffer
{ {
@ -139,7 +135,7 @@ class FrameBufferGL : public FrameBuffer
@param b The blue component of the color. @param b The blue component of the color.
*/ */
virtual Uint32 mapRGB(Uint8 r, Uint8 g, Uint8 b) virtual Uint32 mapRGB(Uint8 r, Uint8 g, Uint8 b)
{ return SDL_MapRGB(myBaseTexture->format, r, g, b); } { return SDL_MapRGB(myTexture->format, r, g, b); }
/** /**
This method is called to draw a horizontal line. This method is called to draw a horizontal line.
@ -241,22 +237,32 @@ class FrameBufferGL : public FrameBuffer
} }
private: private:
// The base and scaled texture buffers // Points to the current texture data
SDL_Surface* myBaseTexture; SDL_Surface* myTexture;
SDL_Surface* myScaledTexture;
// Points to the current texture data, which is one of struct glBufferType
// myBaseTexture or myScaledTexture {
SDL_Surface* myCurrentTexture; GLuint texture;
GLsizei texture_width;
GLsizei texture_height;
GLfloat tex_coord[4];
SDL_Rect myQuadRect; GLenum target;
GLenum format;
GLenum type;
GLint filter; // The texture filtering to use
void* pixels;
int width, height;
int pitch;
};
glBufferType myBuffer;
bool myUse16Bit;
// The possible OpenGL screenmodes to use // The possible OpenGL screenmodes to use
SDL_Rect** myScreenmode; SDL_Rect** myScreenmode;
// Scaler currently in use
ScalerType myScalerType;
// The number of usable OpenGL screenmodes // The number of usable OpenGL screenmodes
uInt32 myScreenmodeCount; uInt32 myScreenmodeCount;
@ -266,20 +272,11 @@ class FrameBufferGL : public FrameBuffer
// The size of color components for OpenGL // The size of color components for OpenGL
uInt32 myRGB[4]; uInt32 myRGB[4];
// The OpenGL main texture handle
GLuint myTextureID;
// OpenGL texture coordinates for the main surface
GLfloat myTexCoord[4];
// The texture filtering to use
GLint myFilterParam;
// The name of the texture filtering to use // The name of the texture filtering to use
string myFilterParamName; string myFilterParamName;
// FIXME - used for zooming, still work todo here // Used for zooming/scaling
uInt32 myZoomLevel, myScaleLevel; uInt32 myZoomLevel;
// The scaling to use in fullscreen mode // The scaling to use in fullscreen mode
// This is separate from both zoomlevel and aspect ratio // This is separate from both zoomlevel and aspect ratio
@ -288,12 +285,11 @@ class FrameBufferGL : public FrameBuffer
// TODO - will be removed when textured dirty rect support is added // TODO - will be removed when textured dirty rect support is added
bool myDirtyFlag; bool myDirtyFlag;
// Optional extensions that may increase performance
bool myHaveTexRectEXT, myHaveAppleCStorageEXT, myHaveAppleTexRangeEXT;
// Indicates if the OpenGL functions have been properly loaded // Indicates if the OpenGL functions have been properly loaded
static bool myFuncsLoaded; static bool myFuncsLoaded;
#ifdef SCALER_SUPPORT
ScalerProc *myScalerProc;
#endif
}; };
#endif // DISPLAY_OPENGL #endif // DISPLAY_OPENGL

View File

@ -598,7 +598,7 @@ static const char* DefProps[][23] = {
{ "2517827950fee41a3b9de60275c8aa6a", "Activision", "", "Fishing Derby (1980) (Activision) [p1]", "", "", "", "", "", "", "", "", "", "", "", "PAL", "8", "144", "64", "188", "", "", "" }, { "2517827950fee41a3b9de60275c8aa6a", "Activision", "", "Fishing Derby (1980) (Activision) [p1]", "", "", "", "", "", "", "", "", "", "", "", "PAL", "8", "144", "64", "188", "", "", "" },
{ "25a943e9d5e312b516660b0627352448", "", "", "Image - Baboon (Interlaced Demo 1) (15-02-2003) (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, { "25a943e9d5e312b516660b0627352448", "", "", "Image - Baboon (Interlaced Demo 1) (15-02-2003) (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
{ "25e73efb9a6edf119114718bd2f646ba", "", "", "Miss Piggy's Wedding (Prototype) [!]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "28", "195", "", "", "" }, { "25e73efb9a6edf119114718bd2f646ba", "", "", "Miss Piggy's Wedding (Prototype) [!]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "28", "195", "", "", "" },
{ "2683d29a282dd059535ac3bb250f540d", "", "", "Space Treat (12-01-2003) (Fabrizio Zavagli)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, { "265a85f66544eaf95fda06c3d9e48abf", "", "", "Tunnel Demo (Cycling Colours) (29-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
{ "270229c6d5578446e6a588492e4e5910", "", "", "Space Invaders 2 (Space Invaders Hack)", "Hack of Space Invaders (Atari)", "", "", "4K", "", "", "", "", "", "", "", "", "", "", "42", "200", "", "", "" }, { "270229c6d5578446e6a588492e4e5910", "", "", "Space Invaders 2 (Space Invaders Hack)", "Hack of Space Invaders (Atari)", "", "", "4K", "", "", "", "", "", "", "", "", "", "", "42", "200", "", "", "" },
{ "277cca62014fceebb46c549bac25a2e3", "Activision", "AG-002", "Boxing (1981) (Activision) [o1]", "", "Uncommon", "", "", "", "", "", "", "", "", "", "", "8", "140", "", "", "", "", "" }, { "277cca62014fceebb46c549bac25a2e3", "Activision", "AG-002", "Boxing (1981) (Activision) [o1]", "", "Uncommon", "", "", "", "", "", "", "", "", "", "", "8", "140", "", "", "", "", "" },
{ "27a3c5216b6c6e96e321634973b73784", "", "", "Greeting Cart Atari Coin (V1) (SnailSoft)(PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, { "27a3c5216b6c6e96e321634973b73784", "", "", "Greeting Cart Atari Coin (V1) (SnailSoft)(PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
@ -616,7 +616,7 @@ static const char* DefProps[][23] = {
{ "2d76c5d1aad506442b9e9fb67765e051", "Apollo", "", "Lost Luggage (1981) (Apollo) (NTSC) [!]", "", "", "", "", "", "", "", "", "", "", "", "", "8", "152", "38", "196", "", "", "" }, { "2d76c5d1aad506442b9e9fb67765e051", "Apollo", "", "Lost Luggage (1981) (Apollo) (NTSC) [!]", "", "", "", "", "", "", "", "", "", "", "", "", "8", "152", "38", "196", "", "", "" },
{ "2e0aed5bb619edcefa3fafb4fbe7c551", "", "", "Qb (2.06) (Retroactive) (NTSC)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "Yes", "", "" }, { "2e0aed5bb619edcefa3fafb4fbe7c551", "", "", "Qb (2.06) (Retroactive) (NTSC)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "Yes", "", "" },
{ "2e663eaa0d6b723b645e643750b942fd", "Atari", "CX2634 / 75121", "Golf (1978) (Atari) [!]", "", "Common", "", "", "", "", "", "", "", "", "", "", "8", "152", "36", "191", "", "", "" }, { "2e663eaa0d6b723b645e643750b942fd", "Atari", "CX2634 / 75121", "Golf (1978) (Atari) [!]", "", "Common", "", "", "", "", "", "", "", "", "", "", "8", "152", "36", "191", "", "", "" },
{ "2eda6a49a49fcb2b674ea9e160b6a617", "Kyle Pittman", "", "Rambo in Afghanistan by Kyle Pittman (Riddle of the Sphinx Hack)", "Hack of Riddle of the Sphinx (Imagic)", "New Release (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "39", "186", "", "", "" }, { "2ec6b045cfd7bc52d9cdfd1b1447d1e5", "Activision", "AG-009", "Freeway (1981) (Activision) (PAL) [!]", "", "Uncommon", "", "2K", "", "", "", "", "", "", "", "PAL", "8", "144", "61", "201", "", "", "" },
{ "2f273c423471d125d32d1d54d58f063a", "Parker Bros", "PB5080", "Gyruss (1984) (Parker Bros) [b1]", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "47", "180", "Yes", "", "" }, { "2f273c423471d125d32d1d54d58f063a", "Parker Bros", "PB5080", "Gyruss (1984) (Parker Bros) [b1]", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "47", "180", "Yes", "", "" },
{ "3025bdc30b5aec9fb40668787f67d24c", "", "", "Demo Image Series #14 - Two Marios (4K Interleaved Chronocolour Vertical Movement) (05-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, { "3025bdc30b5aec9fb40668787f67d24c", "", "", "Demo Image Series #14 - Two Marios (4K Interleaved Chronocolour Vertical Movement) (05-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
{ "3051b6071cb26377cd428af155e1bfc4", "", "CX2607 / 6699828 / 4975115", "Canyon Bomber (1978) (Atari) [o1]", "Uses the Paddle Controllers", "Uncommon", "", "", "", "", "", "", "Paddles", "Paddles", "Yes", "", "", "", "47", "195", "", "", "" }, { "3051b6071cb26377cd428af155e1bfc4", "", "CX2607 / 6699828 / 4975115", "Canyon Bomber (1978) (Atari) [o1]", "Uses the Paddle Controllers", "Uncommon", "", "", "", "", "", "", "Paddles", "Paddles", "Yes", "", "", "", "47", "195", "", "", "" },
@ -1190,7 +1190,7 @@ static const char* DefProps[][23] = {
{ "25d4be3309b89583c6b39d9f93bf654f", "Activision", "AX-015", "Chopper Command (1982) (Activision) [o1]", "", "Uncommon", "", "4K", "", "", "", "", "", "", "", "", "8", "152", "49", "183", "", "", "" }, { "25d4be3309b89583c6b39d9f93bf654f", "Activision", "AX-015", "Chopper Command (1982) (Activision) [o1]", "", "Uncommon", "", "4K", "", "", "", "", "", "", "", "", "8", "152", "49", "183", "", "", "" },
{ "25f2e760cd7f56b88aac88d63757d41b", "Activision", "AG-002", "Boxing (1981) (Activision) (PAL) [!]", "", "Uncommon", "", "", "", "", "", "", "", "", "", "PAL", "8", "140", "64", "201", "", "", "" }, { "25f2e760cd7f56b88aac88d63757d41b", "Activision", "AG-002", "Boxing (1981) (Activision) (PAL) [!]", "", "Uncommon", "", "", "", "", "", "", "", "", "", "PAL", "8", "140", "64", "201", "", "", "" },
{ "262ccb882ff617d9b4b51f24aee02cbe", "Atari", "CX26154", "Super Football (1988) (Atari) (PAL) [!]", "", "Uncommon", "", "F6SC", "", "", "", "", "", "", "", "PAL", "4", "152", "64", "189", "", "", "" }, { "262ccb882ff617d9b4b51f24aee02cbe", "Atari", "CX26154", "Super Football (1988) (Atari) (PAL) [!]", "", "Uncommon", "", "F6SC", "", "", "", "", "", "", "", "PAL", "4", "152", "64", "189", "", "", "" },
{ "268f46038e29301568fa9e443e16e960", "", "", "Pitfall Unlimited (Atarius Maximus)", "", "", "", "", "", "", "", "", "", "", "", "", "8", "152", "40", "195", "", "", "" }, { "2683d29a282dd059535ac3bb250f540d", "", "", "Space Treat (12-01-2003) (Fabrizio Zavagli)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
{ "26f4f8b098609164effef7809e0121e1", "", "", "Oystron (V2.7) (Piero Cavina) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "35", "195", "", "", "" }, { "26f4f8b098609164effef7809e0121e1", "", "", "Oystron (V2.7) (Piero Cavina) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "35", "195", "", "", "" },
{ "2723e442d55d741a8e2d9293108cd5ed", "Tigervision", "7-011", "Miner 2049er Volume II (1983) (Tigervision) [b1]", "", "Extremely Rare", "", "3F", "", "", "", "", "", "", "", "", "8", "144", "60", "212", "Yes", "", "" }, { "2723e442d55d741a8e2d9293108cd5ed", "Tigervision", "7-011", "Miner 2049er Volume II (1983) (Tigervision) [b1]", "", "Extremely Rare", "", "3F", "", "", "", "", "", "", "", "", "8", "144", "60", "212", "Yes", "", "" },
{ "277c7281ac945b8331e2e6fcad560c11", "Starpath", "AR-4401", "Survival Island (2 of 3) (1983) (Starpath) (PAL)", "", "Rare", "", "AR", "", "", "", "", "", "", "", "PAL", "", "", "38", "200", "", "", "No" }, { "277c7281ac945b8331e2e6fcad560c11", "Starpath", "AR-4401", "Survival Island (2 of 3) (1983) (Starpath) (PAL)", "", "Rare", "", "AR", "", "", "", "", "", "", "", "PAL", "", "", "38", "200", "", "", "No" },
@ -1225,8 +1225,8 @@ static const char* DefProps[][23] = {
{ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, { "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
{ "2e3728f3086dc3e71047ffd6b2d9f015", "Atari", "", "Outlaw (32-in-1) (Atari) (PAL) [!]", "", "", "", "", "", "", "", "", "", "", "", "PAL", "", "", "58", "230", "", "", "" }, { "2e3728f3086dc3e71047ffd6b2d9f015", "Atari", "", "Outlaw (32-in-1) (Atari) (PAL) [!]", "", "", "", "", "", "", "", "", "", "", "", "PAL", "", "", "58", "230", "", "", "" },
{ "2e82a1628ef6c735c0ab8fa92927e9b0", "Atari", "CX26109", "Sorcerer's Apprentice (1983) (Atari) (PAL) [!]", "", "Rare", "", "", "", "", "", "", "", "", "", "PAL", "8", "152", "46", "227", "", "", "" }, { "2e82a1628ef6c735c0ab8fa92927e9b0", "Atari", "CX26109", "Sorcerer's Apprentice (1983) (Atari) (PAL) [!]", "", "Rare", "", "", "", "", "", "", "", "", "", "PAL", "8", "152", "46", "227", "", "", "" },
{ "2ec6b045cfd7bc52d9cdfd1b1447d1e5", "Activision", "AG-009", "Freeway (1981) (Activision) (PAL) [!]", "", "Uncommon", "", "2K", "", "", "", "", "", "", "", "PAL", "8", "144", "61", "201", "", "", "" }, { "2eb1277d623b303062ec5654eeaa3c73", "Spiceware", "SW-01", "Medieval Mayhem (NTSC)", "", "Homebrew", "STEREO", "", "", "", "", "", "PADDLES", "PADDLES", "", "", "", "", "", "", "", "", "" },
{ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, { "2eda6a49a49fcb2b674ea9e160b6a617", "Kyle Pittman", "", "Rambo in Afghanistan by Kyle Pittman (Riddle of the Sphinx Hack)", "Hack of Riddle of the Sphinx (Imagic)", "New Release (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "39", "186", "", "", "" },
{ "2f11ba54609777e2c6a5da9b302c98e8", "Atari", "", "Centipede (1982) (Atari) (Prototype) (PAL) [!]", "", "Prototype", "", "", "", "", "", "", "", "", "", "PAL", "8", "144", "64", "197", "", "", "" }, { "2f11ba54609777e2c6a5da9b302c98e8", "Atari", "", "Centipede (1982) (Atari) (Prototype) (PAL) [!]", "", "Prototype", "", "", "", "", "", "", "", "", "", "PAL", "8", "144", "64", "197", "", "", "" },
{ "2f66ebf037321ed0442ac4b89ce22633", "Baroque Gaming (Brian Eno)", "", "Warring Worms (Beta 2) (2002) (Baroque Gaming)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "37", "200", "", "", "" }, { "2f66ebf037321ed0442ac4b89ce22633", "Baroque Gaming (Brian Eno)", "", "Warring Worms (Beta 2) (2002) (Baroque Gaming)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "37", "200", "", "", "" },
{ "2facd460a6828e0e476d3ac4b8c5f4f7", "", "", "Sancho - Words (198x) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "PAL", "", "", "", "235", "", "", "" }, { "2facd460a6828e0e476d3ac4b8c5f4f7", "", "", "Sancho - Words (198x) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "PAL", "", "", "", "235", "", "", "" },
@ -2372,9 +2372,9 @@ static const char* DefProps[][23] = {
{ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, { "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
{ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, { "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
{ "260c787e8925bf3649c8aeae5b97dcc0", "ITT Family Games / Thomas Jentzsch", "", "Hell Driver (ITT Family Games) (NTSC by Thomas Jentzsch)", "", "New Release (Video Format Conversion)", "", "", "", "", "", "", "", "", "", "", "", "", "37", "209", "", "", "" }, { "260c787e8925bf3649c8aeae5b97dcc0", "ITT Family Games / Thomas Jentzsch", "", "Hell Driver (ITT Family Games) (NTSC by Thomas Jentzsch)", "", "New Release (Video Format Conversion)", "", "", "", "", "", "", "", "", "", "", "", "", "37", "209", "", "", "" },
{ "265a85f66544eaf95fda06c3d9e48abf", "", "", "Tunnel Demo (Cycling Colours) (29-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, { "264e205ff090ddfdd16d507127f79090", "Spiceware", "SW-01", "Medieval Mayhem (PAL)", "", "Homebrew", "STEREO", "", "", "", "", "", "PADDLES", "PADDLES", "", "PAL", "", "", "", "250", "", "", "" },
{ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
{ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, { "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
{ "268f46038e29301568fa9e443e16e960", "", "", "Pitfall Unlimited (Atarius Maximus)", "", "", "", "", "", "", "", "", "", "", "", "", "8", "152", "40", "195", "", "", "" },
{ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, { "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
{ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, { "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
{ "271bfd5dc2673d382019f1fb6cab9332", "Starpath", "AR-4200", "Escape from the Mindmaster Preview (1982) (Starpath) (PAL)", "", "Extremely Rare", "", "AR", "", "", "", "", "", "", "", "PAL", "8", "144", "56", "192", "", "", "" }, { "271bfd5dc2673d382019f1fb6cab9332", "Starpath", "AR-4200", "Escape from the Mindmaster Preview (1982) (Starpath) (PAL)", "", "Extremely Rare", "", "AR", "", "", "", "", "", "", "", "PAL", "8", "144", "56", "192", "", "", "" },

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: OSystem.cxx,v 1.78 2006-12-08 16:49:27 stephena Exp $ // $Id: OSystem.cxx,v 1.79 2006-12-13 17:09:10 stephena Exp $
//============================================================================ //============================================================================
#include <cassert> #include <cassert>
@ -517,7 +517,7 @@ bool OSystem::openROM(const string& rom, string& md5, uInt8** image, int* size)
name = rom.substr(pos+1); name = rom.substr(pos+1);
props.set(Cartridge_MD5, md5); props.set(Cartridge_MD5, md5);
props.set(Cartridge_Name, name); props.set(Cartridge_Name, name);
myPropSet->insert(props); myPropSet->insert(props, false);
} }
} }

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: PropsSet.cxx,v 1.26 2006-12-13 00:32:17 stephena Exp $ // $Id: PropsSet.cxx,v 1.27 2006-12-13 17:09:10 stephena Exp $
//============================================================================ //============================================================================
#include <sstream> #include <sstream>
@ -77,12 +77,10 @@ void PropertiesSet::getMD5(const string& md5, Properties& properties,
const string& currentMd5 = current->props->get(Cartridge_MD5); const string& currentMd5 = current->props->get(Cartridge_MD5);
if(currentMd5 == md5) if(currentMd5 == md5)
{ {
// We only report a node as found if it's to be saved. // We only report a node as found if it's been marked as valid.
// Nodes in the BST that are marked as 'do not save' are // Invalid nodes are those that should be removed, and are
// essentially treated as if they're not present. // essentially treated as if they're not present.
// What really should happen is the node should be removed, found = current->valid;
// and the tree rebalanced ...
found = current->save;
break; break;
} }
else if(md5 < currentMd5) else if(md5 < currentMd5)
@ -122,8 +120,8 @@ void PropertiesSet::getMD5(const string& md5, Properties& properties,
if(myOSystem->settings().getBool("tiadefaults")) if(myOSystem->settings().getBool("tiadefaults"))
{ {
// properties.set(Display_XStart, Properties::ourDefaultProperties[Display_XStart]); // properties.set(Display_XStart, Properties::ourDefaultProperties[Display_XStart]);
properties.set(Display_Width, Properties::ourDefaultProperties[Display_Width]);
// properties.set(Display_YStart, Properties::ourDefaultProperties[Display_YStart]); // properties.set(Display_YStart, Properties::ourDefaultProperties[Display_YStart]);
properties.set(Display_Width, Properties::ourDefaultProperties[Display_Width]);
properties.set(Display_Height, Properties::ourDefaultProperties[Display_Height]); properties.set(Display_Height, Properties::ourDefaultProperties[Display_Height]);
} }
} }
@ -146,7 +144,7 @@ void PropertiesSet::removeMD5(const string& md5)
const string& currentMd5 = current->props->get(Cartridge_MD5); const string& currentMd5 = current->props->get(Cartridge_MD5);
if(currentMd5 == md5) if(currentMd5 == md5)
{ {
current->save = false; // make sure this node isn't saved current->valid = false; // Essentially, this node doesn't exist
break; break;
} }
else if(md5 < currentMd5) else if(md5 < currentMd5)
@ -175,6 +173,7 @@ void PropertiesSet::insertNode(TreeNode* &t, const Properties& properties,
delete t->props; delete t->props;
t->props = new Properties(properties); t->props = new Properties(properties);
t->save = save; t->save = save;
t->valid = true;
} }
} }
else else
@ -184,6 +183,7 @@ void PropertiesSet::insertNode(TreeNode* &t, const Properties& properties,
t->left = 0; t->left = 0;
t->right = 0; t->right = 0;
t->save = save; t->save = save;
t->valid = true;
++mySize; ++mySize;
} }
@ -249,7 +249,7 @@ void PropertiesSet::saveNode(ostream& out, TreeNode *node) const
{ {
if(node) if(node)
{ {
if(node->save) if(node->valid && node->save)
node->props->save(out); node->props->save(out);
saveNode(out, node->left); saveNode(out, node->left);
saveNode(out, node->right); saveNode(out, node->right);
@ -261,7 +261,7 @@ void PropertiesSet::printNode(TreeNode *node) const
{ {
if(node) if(node)
{ {
if(node->save) if(node->valid && node->save)
node->props->print(); node->props->print();
printNode(node->left); printNode(node->left);
printNode(node->right); printNode(node->right);

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: PropsSet.hxx,v 1.16 2006-12-08 16:49:27 stephena Exp $ // $Id: PropsSet.hxx,v 1.17 2006-12-13 17:09:10 stephena Exp $
//============================================================================ //============================================================================
#ifndef PROPERTIES_SET_HXX #ifndef PROPERTIES_SET_HXX
@ -90,7 +90,7 @@ class PropertiesSet
@param save Indicates whether to set the 'save' tag for @param save Indicates whether to set the 'save' tag for
this property this property
*/ */
void insert(const Properties& properties, bool save = true); void insert(const Properties& properties, bool save);
/** /**
Marks the property with the given MD5 as being removed. Marks the property with the given MD5 as being removed.
@ -117,6 +117,7 @@ class PropertiesSet
TreeNode* left; TreeNode* left;
TreeNode* right; TreeNode* right;
bool save; bool save;
bool valid;
}; };
/** /**

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: Settings.cxx,v 1.98 2006-12-13 00:05:46 stephena Exp $ // $Id: Settings.cxx,v 1.99 2006-12-13 17:09:10 stephena Exp $
//============================================================================ //============================================================================
#include <cassert> #include <cassert>
@ -247,12 +247,7 @@ void Settings::validate()
s = getString("scale_tia"); s = getString("scale_tia");
if(s != "zoom1x" && s != "zoom2x" && s != "zoom3x" && if(s != "zoom1x" && s != "zoom2x" && s != "zoom3x" &&
s != "zoom4x" && s != "zoom5x" && s != "zoom6x" s != "zoom4x" && s != "zoom5x" && s != "zoom6x")
#ifdef SCALER_SUPPORT
&& s != "scale2x" && s != "scale3x" && s != "scale4x" &&
s != "hq2x" && s != "hq3x" && s != "hq4x"
#endif
)
setInternal("scale_tia", "zoom1x"); setInternal("scale_tia", "zoom1x");
i = getInt("paddle"); i = getInt("paddle");

View File

@ -20965,3 +20965,25 @@
"Cartridge.Name" "Conquest Of Mars" "Cartridge.Name" "Conquest Of Mars"
"Cartridge.Rarity" "Homebrew" "Cartridge.Rarity" "Homebrew"
"" ""
"Cartridge.MD5" "264e205ff090ddfdd16d507127f79090"
"Cartridge.Manufacturer" "Spiceware"
"Cartridge.ModelNo" "SW-01"
"Cartridge.Name" "Medieval Mayhem (PAL)"
"Cartridge.Rarity" "Homebrew"
"Cartridge.Sound" "STEREO"
"Controller.Left" "PADDLES"
"Controller.Right" "PADDLES"
"Display.Format" "PAL"
"Display.Height" "250"
""
"Cartridge.MD5" "2eb1277d623b303062ec5654eeaa3c73"
"Cartridge.Manufacturer" "Spiceware"
"Cartridge.ModelNo" "SW-01"
"Cartridge.Name" "Medieval Mayhem (NTSC)"
"Cartridge.Rarity" "Homebrew"
"Cartridge.Sound" "STEREO"
"Controller.Left" "PADDLES"
"Controller.Right" "PADDLES"
""

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: VideoDialog.cxx,v 1.37 2006-12-13 00:05:46 stephena Exp $ // $Id: VideoDialog.cxx,v 1.38 2006-12-13 17:09:11 stephena Exp $
// //
// Based on code from ScummVM - Scumm Interpreter // Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project // Copyright (C) 2002-2004 The ScummVM project
@ -107,12 +107,6 @@ VideoDialog::VideoDialog(OSystem* osystem, DialogContainer* parent,
myScalerPopup->appendEntry("Zoom4x", 4); myScalerPopup->appendEntry("Zoom4x", 4);
myScalerPopup->appendEntry("Zoom5x", 5); myScalerPopup->appendEntry("Zoom5x", 5);
myScalerPopup->appendEntry("Zoom6x", 6); myScalerPopup->appendEntry("Zoom6x", 6);
#ifdef SCALER_SUPPORT
myScalerPopup->appendEntry("Scale2x", 7);
myScalerPopup->appendEntry("Scale3x", 8);
myScalerPopup->appendEntry("HQ2x", 9);
myScalerPopup->appendEntry("HQ3x", 10);
#endif
wid.push_back(myScalerPopup); wid.push_back(myScalerPopup);
// Move over to the next column // Move over to the next column
@ -239,12 +233,6 @@ void VideoDialog::loadConfig()
else if(s == "zoom4x") myScalerPopup->setSelectedTag(4); else if(s == "zoom4x") myScalerPopup->setSelectedTag(4);
else if(s == "zoom5x") myScalerPopup->setSelectedTag(5); else if(s == "zoom5x") myScalerPopup->setSelectedTag(5);
else if(s == "zoom6x") myScalerPopup->setSelectedTag(6); else if(s == "zoom6x") myScalerPopup->setSelectedTag(6);
#ifdef SCALER_SUPPORT
else if(s == "scale2x") myScalerPopup->setSelectedTag(7);
else if(s == "scale3x") myScalerPopup->setSelectedTag(8);
else if(s == "hq2x") myScalerPopup->setSelectedTag(9);
else if(s == "hq3x") myScalerPopup->setSelectedTag(10);
#endif
else myScalerPopup->setSelectedTag(0); else myScalerPopup->setSelectedTag(0);
// Fullscreen // Fullscreen
@ -330,12 +318,6 @@ void VideoDialog::saveConfig()
else if(i == 4) s = "zoom4x"; else if(i == 4) s = "zoom4x";
else if(i == 5) s = "zoom5x"; else if(i == 5) s = "zoom5x";
else if(i == 6) s = "zoom6x"; else if(i == 6) s = "zoom6x";
#ifdef SCALER_SUPPORT
else if(i == 7) s = "scale2x";
else if(i == 8) s = "scale3x";
else if(i == 9) s = "hq2x";
else if(i == 10) s = "hq3x";
#endif
if(s != instance()->settings().getString("scale_tia")) if(s != instance()->settings().getString("scale_tia"))
{ {
instance()->settings().setString("scale_tia", s); instance()->settings().setString("scale_tia", s);