mirror of https://github.com/stella-emu/stella.git
First pass at fixing the 'white texture' issue with OpenGL mode in OSX.
Basically, all textures/surfaces need to be reloaded each time the GL context changes (which seems to be more often under OSX than on other systems). This new code takes care of that. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1560 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
f599e1611d
commit
203cdaf323
|
@ -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.112 2008-12-10 18:11:21 stephena Exp $
|
// $Id: FrameBufferGL.cxx,v 1.113 2008-12-12 15:51:06 stephena Exp $
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#ifdef DISPLAY_OPENGL
|
#ifdef DISPLAY_OPENGL
|
||||||
|
@ -356,6 +356,10 @@ cerr << "dimensions: " << endl
|
||||||
myBaseSurface = new FBSurfaceGL(*this, baseWidth, baseHeight,
|
myBaseSurface = new FBSurfaceGL(*this, baseWidth, baseHeight,
|
||||||
mode.image_w, mode.image_h);
|
mode.image_w, mode.image_h);
|
||||||
|
|
||||||
|
// Old textures currently in use by various UI items need to be
|
||||||
|
// refreshed as well (only seems to be required for OSX)
|
||||||
|
reloadSurfaces();
|
||||||
|
|
||||||
// Make sure any old parts of the screen are erased
|
// Make sure any old parts of the screen are erased
|
||||||
p_glClear(GL_COLOR_BUFFER_BIT);
|
p_glClear(GL_COLOR_BUFFER_BIT);
|
||||||
SDL_GL_SwapBuffers();
|
SDL_GL_SwapBuffers();
|
||||||
|
@ -528,6 +532,8 @@ FBSurfaceGL::FBSurfaceGL(FrameBufferGL& buffer,
|
||||||
uInt32 baseWidth, uInt32 baseHeight,
|
uInt32 baseWidth, uInt32 baseHeight,
|
||||||
uInt32 scaleWidth, uInt32 scaleHeight)
|
uInt32 scaleWidth, uInt32 scaleHeight)
|
||||||
: myFB(buffer),
|
: myFB(buffer),
|
||||||
|
myTexture(NULL),
|
||||||
|
myTexID(0),
|
||||||
myXOrig(0),
|
myXOrig(0),
|
||||||
myYOrig(0),
|
myYOrig(0),
|
||||||
myWidth(scaleWidth),
|
myWidth(scaleWidth),
|
||||||
|
@ -558,9 +564,6 @@ cerr << " FBSurfaceGL::FBSurfaceGL: w = " << baseWidth << ", h = " << baseHeigh
|
||||||
|
|
||||||
// Based on experimentation, the following is the fastest 16-bit
|
// Based on experimentation, the following is the fastest 16-bit
|
||||||
// format for OpenGL (on all platforms)
|
// format for OpenGL (on all platforms)
|
||||||
// TODO - make sure this is endian-clean
|
|
||||||
GLenum tex_intformat;
|
|
||||||
tex_intformat = GL_RGB5;
|
|
||||||
myTexFormat = GL_BGRA;
|
myTexFormat = GL_BGRA;
|
||||||
myTexType = GL_UNSIGNED_SHORT_1_5_5_5_REV;
|
myTexType = GL_UNSIGNED_SHORT_1_5_5_5_REV;
|
||||||
myTexture = SDL_CreateRGBSurface(SDL_SWSURFACE,
|
myTexture = SDL_CreateRGBSurface(SDL_SWSURFACE,
|
||||||
|
@ -582,41 +585,15 @@ cerr << " FBSurfaceGL::FBSurfaceGL: w = " << baseWidth << ", h = " << baseHeigh
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Associate the SDL surface with a GL texture object
|
||||||
// Create an OpenGL texture from the SDL texture
|
reload();
|
||||||
const string& filter = myOSystem->settings().getString("gl_filter");
|
|
||||||
if(filter == "linear")
|
|
||||||
{
|
|
||||||
myBuffer.filter = GL_LINEAR;
|
|
||||||
myFilterParamName = "GL_LINEAR";
|
|
||||||
}
|
|
||||||
else if(filter == "nearest")
|
|
||||||
{
|
|
||||||
myBuffer.filter = GL_NEAREST;
|
|
||||||
myFilterParamName = "GL_NEAREST";
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
p_glGenTextures(1, &myTexID);
|
|
||||||
p_glBindTexture(myTexTarget, myTexID);
|
|
||||||
p_glTexParameteri(myTexTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
||||||
p_glTexParameteri(myTexTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
||||||
// p_glTexParameteri(myTexTarget, GL_TEXTURE_MIN_FILTER, myBuffer.filter);
|
|
||||||
// p_glTexParameteri(myTexTarget, GL_TEXTURE_MAG_FILTER, myBuffer.filter);
|
|
||||||
p_glTexParameteri(myTexTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
||||||
p_glTexParameteri(myTexTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
||||||
|
|
||||||
// Finally, create the texture in the most optimal format
|
|
||||||
p_glTexImage2D(myTexTarget, 0, tex_intformat,
|
|
||||||
myTexWidth, myTexHeight, 0,
|
|
||||||
myTexFormat, myTexType, myTexture->pixels);
|
|
||||||
|
|
||||||
p_glEnable(myTexTarget);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
FBSurfaceGL::~FBSurfaceGL()
|
FBSurfaceGL::~FBSurfaceGL()
|
||||||
{
|
{
|
||||||
|
cerr << " FBSurfaceGL::~FBSurfaceGL(): " << this << endl;
|
||||||
|
|
||||||
if(myTexture)
|
if(myTexture)
|
||||||
SDL_FreeSurface(myTexture);
|
SDL_FreeSurface(myTexture);
|
||||||
|
|
||||||
|
@ -816,6 +793,53 @@ void FBSurfaceGL::update()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void FBSurfaceGL::reload()
|
||||||
|
{
|
||||||
|
// This does a 'soft' reset of the surface
|
||||||
|
// It seems that on some system (notably, OSX), creating a new SDL window
|
||||||
|
// destroys the GL context, requiring a reload of all textures
|
||||||
|
// However, destroying the entire FBSurfaceGL object is wasteful, since
|
||||||
|
// it will also regenerate SDL software surfaces (which are not required
|
||||||
|
// to be regenerated)
|
||||||
|
// Basically, all that needs to be done is to re-call glTexImage2D with a
|
||||||
|
// new texture ID, so that's what we do here
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Create an OpenGL texture from the SDL texture
|
||||||
|
const string& filter = myOSystem->settings().getString("gl_filter");
|
||||||
|
if(filter == "linear")
|
||||||
|
{
|
||||||
|
myBuffer.filter = GL_LINEAR;
|
||||||
|
myFilterParamName = "GL_LINEAR";
|
||||||
|
}
|
||||||
|
else if(filter == "nearest")
|
||||||
|
{
|
||||||
|
myBuffer.filter = GL_NEAREST;
|
||||||
|
myFilterParamName = "GL_NEAREST";
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
p_glDeleteTextures(1, &myTexID);
|
||||||
|
p_glGenTextures(1, &myTexID);
|
||||||
|
p_glBindTexture(myTexTarget, myTexID);
|
||||||
|
p_glTexParameteri(myTexTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
|
p_glTexParameteri(myTexTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
// p_glTexParameteri(myTexTarget, GL_TEXTURE_MIN_FILTER, myBuffer.filter);
|
||||||
|
// p_glTexParameteri(myTexTarget, GL_TEXTURE_MAG_FILTER, myBuffer.filter);
|
||||||
|
p_glTexParameteri(myTexTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
p_glTexParameteri(myTexTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
|
||||||
|
// Finally, create the texture in the most optimal format
|
||||||
|
p_glTexImage2D(myTexTarget, 0, GL_RGB5,
|
||||||
|
myTexWidth, myTexHeight, 0,
|
||||||
|
myTexFormat, myTexType, myTexture->pixels);
|
||||||
|
|
||||||
|
p_glEnable(myTexTarget);
|
||||||
|
|
||||||
|
cerr << " ==> FBSurfaceGL::reload(): myTexID = " << myTexID << endl;
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
GUI::Surface* FrameBufferGL::createSurface(int width, int height) const
|
GUI::Surface* FrameBufferGL::createSurface(int width, int height) const
|
||||||
|
|
|
@ -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.60 2008-12-10 18:11:21 stephena Exp $
|
// $Id: FrameBufferGL.hxx,v 1.61 2008-12-12 15:51:06 stephena Exp $
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#ifndef FRAMEBUFFER_GL_HXX
|
#ifndef FRAMEBUFFER_GL_HXX
|
||||||
|
@ -35,7 +35,7 @@ class FBSurfaceGL;
|
||||||
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.60 2008-12-10 18:11:21 stephena Exp $
|
@version $Id: FrameBufferGL.hxx,v 1.61 2008-12-12 15:51:06 stephena Exp $
|
||||||
*/
|
*/
|
||||||
class FrameBufferGL : public FrameBuffer
|
class FrameBufferGL : public FrameBuffer
|
||||||
{
|
{
|
||||||
|
@ -83,16 +83,6 @@ class FrameBufferGL : public FrameBuffer
|
||||||
*/
|
*/
|
||||||
BufferType type() const { return kGLBuffer; }
|
BufferType type() const { return kGLBuffer; }
|
||||||
|
|
||||||
/**
|
|
||||||
This method is called to create a surface compatible with the one
|
|
||||||
currently in use, but having the given dimensions.
|
|
||||||
|
|
||||||
@param w The requested width of the new surface.
|
|
||||||
@param h The requested height of the new surface.
|
|
||||||
@param useBase Use the base surface instead of creating a new one
|
|
||||||
*/
|
|
||||||
FBSurface* createSurface(int w, int h, bool useBase = false) const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This method is called to get the specified scanline data.
|
This method is called to get the specified scanline data.
|
||||||
|
|
||||||
|
@ -125,6 +115,16 @@ class FrameBufferGL : public FrameBuffer
|
||||||
*/
|
*/
|
||||||
bool setVidMode(VideoMode& mode);
|
bool setVidMode(VideoMode& mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
This method is called to create a surface compatible with the one
|
||||||
|
currently in use, but having the given dimensions.
|
||||||
|
|
||||||
|
@param w The requested width of the new surface.
|
||||||
|
@param h The requested height of the new surface.
|
||||||
|
@param useBase Use the base surface instead of creating a new one
|
||||||
|
*/
|
||||||
|
FBSurface* createSurface(int w, int h, bool useBase = false) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Switches between the two filtering options in OpenGL.
|
Switches between the two filtering options in OpenGL.
|
||||||
Currently, these are GL_NEAREST and GL_LINEAR.
|
Currently, these are GL_NEAREST and GL_LINEAR.
|
||||||
|
@ -201,7 +201,7 @@ class FrameBufferGL : public FrameBuffer
|
||||||
A surface suitable for OpenGL rendering mode.
|
A surface suitable for OpenGL rendering mode.
|
||||||
|
|
||||||
@author Stephen Anthony
|
@author Stephen Anthony
|
||||||
@version $Id: FrameBufferGL.hxx,v 1.60 2008-12-10 18:11:21 stephena Exp $
|
@version $Id: FrameBufferGL.hxx,v 1.61 2008-12-12 15:51:06 stephena Exp $
|
||||||
*/
|
*/
|
||||||
class FBSurfaceGL : public FBSurface
|
class FBSurfaceGL : public FBSurface
|
||||||
{
|
{
|
||||||
|
@ -227,6 +227,7 @@ class FBSurfaceGL : public FBSurface
|
||||||
void setHeight(uInt32 h);
|
void setHeight(uInt32 h);
|
||||||
void translateCoords(Int32& x, Int32& y) const;
|
void translateCoords(Int32& x, Int32& y) const;
|
||||||
void update();
|
void update();
|
||||||
|
void reload();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
inline void* pixels() const { return myTexture->pixels; }
|
inline void* pixels() const { return myTexture->pixels; }
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// See the file "license" for information on usage and redistribution of
|
// See the file "license" for information on usage and redistribution of
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
//
|
//
|
||||||
// $Id: FrameBufferSoft.hxx,v 1.55 2008-11-02 16:46:05 stephena Exp $
|
// $Id: FrameBufferSoft.hxx,v 1.56 2008-12-12 15:51:06 stephena Exp $
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#ifndef FRAMEBUFFER_SOFT_HXX
|
#ifndef FRAMEBUFFER_SOFT_HXX
|
||||||
|
@ -32,7 +32,7 @@ class RectList;
|
||||||
This class implements an SDL software framebuffer.
|
This class implements an SDL software framebuffer.
|
||||||
|
|
||||||
@author Stephen Anthony
|
@author Stephen Anthony
|
||||||
@version $Id: FrameBufferSoft.hxx,v 1.55 2008-11-02 16:46:05 stephena Exp $
|
@version $Id: FrameBufferSoft.hxx,v 1.56 2008-12-12 15:51:06 stephena Exp $
|
||||||
*/
|
*/
|
||||||
class FrameBufferSoft : public FrameBuffer
|
class FrameBufferSoft : public FrameBuffer
|
||||||
{
|
{
|
||||||
|
@ -72,16 +72,6 @@ class FrameBufferSoft : public FrameBuffer
|
||||||
*/
|
*/
|
||||||
BufferType type() const { return kSoftBuffer; }
|
BufferType type() const { return kSoftBuffer; }
|
||||||
|
|
||||||
/**
|
|
||||||
This method is called to create a surface compatible with the one
|
|
||||||
currently in use, but having the given dimensions.
|
|
||||||
|
|
||||||
@param w The requested width of the new surface.
|
|
||||||
@param h The requested height of the new surface.
|
|
||||||
@param useBase Use the base surface instead of creating a new one
|
|
||||||
*/
|
|
||||||
FBSurface* createSurface(int w, int h, bool useBase = false) const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This method is called to get the specified scanline data.
|
This method is called to get the specified scanline data.
|
||||||
|
|
||||||
|
@ -114,6 +104,16 @@ class FrameBufferSoft : public FrameBuffer
|
||||||
*/
|
*/
|
||||||
bool setVidMode(VideoMode& mode);
|
bool setVidMode(VideoMode& mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
This method is called to create a surface compatible with the one
|
||||||
|
currently in use, but having the given dimensions.
|
||||||
|
|
||||||
|
@param w The requested width of the new surface.
|
||||||
|
@param h The requested height of the new surface.
|
||||||
|
@param useBase Use the base surface instead of creating a new one
|
||||||
|
*/
|
||||||
|
FBSurface* createSurface(int w, int h, bool useBase = false) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Switches between the filtering options in software mode.
|
Switches between the filtering options in software mode.
|
||||||
Currently, none exist.
|
Currently, none exist.
|
||||||
|
@ -172,7 +172,7 @@ class FrameBufferSoft : public FrameBuffer
|
||||||
A surface suitable for software rendering mode.
|
A surface suitable for software rendering mode.
|
||||||
|
|
||||||
@author Stephen Anthony
|
@author Stephen Anthony
|
||||||
@version $Id: FrameBufferSoft.hxx,v 1.55 2008-11-02 16:46:05 stephena Exp $
|
@version $Id: FrameBufferSoft.hxx,v 1.56 2008-12-12 15:51:06 stephena Exp $
|
||||||
*/
|
*/
|
||||||
class FBSurfaceSoft : public FBSurface
|
class FBSurfaceSoft : public FBSurface
|
||||||
{
|
{
|
||||||
|
@ -195,6 +195,7 @@ class FBSurfaceSoft : public FBSurface
|
||||||
void setHeight(uInt32 h);
|
void setHeight(uInt32 h);
|
||||||
void translateCoords(Int32& x, Int32& y) const;
|
void translateCoords(Int32& x, Int32& y) const;
|
||||||
void update();
|
void update();
|
||||||
|
void reload() { } // Not required for software mode
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void recalc();
|
void recalc();
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// See the file "license" for information on usage and redistribution of
|
// See the file "license" for information on usage and redistribution of
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
//
|
//
|
||||||
// $Id: FrameBuffer.cxx,v 1.142 2008-12-08 18:56:54 stephena Exp $
|
// $Id: FrameBuffer.cxx,v 1.143 2008-12-12 15:51:07 stephena Exp $
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
@ -46,17 +46,19 @@ FrameBuffer::FrameBuffer(OSystem* osystem)
|
||||||
myUsePhosphor(false),
|
myUsePhosphor(false),
|
||||||
myPhosphorBlend(77),
|
myPhosphorBlend(77),
|
||||||
myInitializedCount(0),
|
myInitializedCount(0),
|
||||||
myPausedCount(0)
|
myPausedCount(0),
|
||||||
|
mySurfaceCount(0)
|
||||||
{
|
{
|
||||||
myMsg.surface = myStatsMsg.surface = 0;
|
myMsg.surface = myStatsMsg.surface = 0;
|
||||||
myMsg.enabled = myStatsMsg.enabled = false;
|
myMsg.surfaceID = myStatsMsg.surfaceID = -1;
|
||||||
|
myMsg.enabled = myStatsMsg.enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
FrameBuffer::~FrameBuffer(void)
|
FrameBuffer::~FrameBuffer(void)
|
||||||
{
|
{
|
||||||
delete myMsg.surface;
|
freeSurface(myMsg.surfaceID);
|
||||||
delete myStatsMsg.surface;
|
freeSurface(myStatsMsg.surfaceID);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -126,10 +128,16 @@ cerr << " <== FrameBuffer::initialize: w = " << width << ", h = " << height << e
|
||||||
myStatsMsg.color = kBtnTextColor;
|
myStatsMsg.color = kBtnTextColor;
|
||||||
myStatsMsg.w = myOSystem->consoleFont().getStringWidth("000 LINES %00.00 FPS");
|
myStatsMsg.w = myOSystem->consoleFont().getStringWidth("000 LINES %00.00 FPS");
|
||||||
myStatsMsg.h = myOSystem->consoleFont().getFontHeight();
|
myStatsMsg.h = myOSystem->consoleFont().getFontHeight();
|
||||||
if(!myStatsMsg.surface)
|
if(myStatsMsg.surfaceID < 0)
|
||||||
myStatsMsg.surface = createSurface(myStatsMsg.w, myStatsMsg.h);
|
{
|
||||||
|
myStatsMsg.surfaceID = allocateSurface(myStatsMsg.w, myStatsMsg.h);
|
||||||
|
myStatsMsg.surface = surface(myStatsMsg.surfaceID);
|
||||||
|
}
|
||||||
if(!myMsg.surface) // TODO - change this to the font we'll really use
|
if(!myMsg.surface) // TODO - change this to the font we'll really use
|
||||||
myMsg.surface = createSurface(320, myOSystem->consoleFont().getFontHeight()+10);
|
{
|
||||||
|
myMsg.surfaceID = allocateSurface(320, myOSystem->consoleFont().getFontHeight()+10);
|
||||||
|
myMsg.surface = surface(myMsg.surfaceID);
|
||||||
|
}
|
||||||
|
|
||||||
// Finally, show some information about the framebuffer,
|
// Finally, show some information about the framebuffer,
|
||||||
// but only on the first initialization
|
// but only on the first initialization
|
||||||
|
@ -373,6 +381,51 @@ void FrameBuffer::refresh()
|
||||||
myRedrawEntireFrame = true;
|
myRedrawEntireFrame = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
int FrameBuffer::allocateSurface(int w, int h, bool useBase)
|
||||||
|
{
|
||||||
|
// Create a new surface
|
||||||
|
FBSurface* surface = createSurface(w, h, useBase);
|
||||||
|
|
||||||
|
// Add it to the list
|
||||||
|
mySurfaceList.insert(make_pair(mySurfaceCount, surface));
|
||||||
|
mySurfaceCount++;
|
||||||
|
|
||||||
|
// Return a reference to it
|
||||||
|
return mySurfaceCount - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
int FrameBuffer::freeSurface(int id)
|
||||||
|
{
|
||||||
|
// Really delete the surface this time
|
||||||
|
// That means actually deleting the FBSurface object, and removing it
|
||||||
|
// from the list
|
||||||
|
map<int,FBSurface*>::iterator iter = mySurfaceList.find(id);
|
||||||
|
if(iter != mySurfaceList.end())
|
||||||
|
{
|
||||||
|
cerr << " delete id = " << iter->first << ", " << iter->second << endl;
|
||||||
|
delete iter->second;
|
||||||
|
mySurfaceList.erase(iter);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
FBSurface* FrameBuffer::surface(int id) const
|
||||||
|
{
|
||||||
|
map<int,FBSurface*>::const_iterator iter = mySurfaceList.find(id);
|
||||||
|
return iter != mySurfaceList.end() ? iter->second : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void FrameBuffer::reloadSurfaces()
|
||||||
|
{
|
||||||
|
map<int,FBSurface*>::iterator iter;
|
||||||
|
for(iter = mySurfaceList.begin(); iter != mySurfaceList.end(); ++iter)
|
||||||
|
iter->second->reload();
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void FrameBuffer::setTIAPalette(const uInt32* palette)
|
void FrameBuffer::setTIAPalette(const uInt32* palette)
|
||||||
{
|
{
|
||||||
|
|
|
@ -13,12 +13,13 @@
|
||||||
// See the file "license" for information on usage and redistribution of
|
// See the file "license" for information on usage and redistribution of
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
//
|
//
|
||||||
// $Id: FrameBuffer.hxx,v 1.104 2008-08-04 11:56:12 stephena Exp $
|
// $Id: FrameBuffer.hxx,v 1.105 2008-12-12 15:51:07 stephena Exp $
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#ifndef FRAMEBUFFER_HXX
|
#ifndef FRAMEBUFFER_HXX
|
||||||
#define FRAMEBUFFER_HXX
|
#define FRAMEBUFFER_HXX
|
||||||
|
|
||||||
|
#include <map>
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
|
|
||||||
class FBSurface;
|
class FBSurface;
|
||||||
|
@ -90,7 +91,7 @@ enum {
|
||||||
turn drawn here as well.
|
turn drawn here as well.
|
||||||
|
|
||||||
@author Stephen Anthony
|
@author Stephen Anthony
|
||||||
@version $Id: FrameBuffer.hxx,v 1.104 2008-08-04 11:56:12 stephena Exp $
|
@version $Id: FrameBuffer.hxx,v 1.105 2008-12-12 15:51:07 stephena Exp $
|
||||||
*/
|
*/
|
||||||
class FrameBuffer
|
class FrameBuffer
|
||||||
{
|
{
|
||||||
|
@ -150,6 +151,35 @@ class FrameBuffer
|
||||||
*/
|
*/
|
||||||
void enableMessages(bool enable);
|
void enableMessages(bool enable);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Allocate a new surface with a unique ID.
|
||||||
|
|
||||||
|
@param w The requested width of the new surface.
|
||||||
|
@param h The requested height of the new surface.
|
||||||
|
@param useBase Use the base surface instead of creating a new one
|
||||||
|
|
||||||
|
@return A unique ID used to identify this surface
|
||||||
|
*/
|
||||||
|
int allocateSurface(int w, int h, bool useBase = false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
De-allocate a previously allocated surface. Other classes should
|
||||||
|
call this method when a surface is no longer needed; it shouldn't
|
||||||
|
try to manually delete the surface object.
|
||||||
|
|
||||||
|
@param id The ID for the surface to de-allocate.
|
||||||
|
@return The ID indicating a non-existent surface (-1).
|
||||||
|
*/
|
||||||
|
int freeSurface(int id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Retrieve the surface associated with the given ID.
|
||||||
|
|
||||||
|
@param id The ID for the surface to retrieve.
|
||||||
|
@return A pointer to a valid surface object, or NULL.
|
||||||
|
*/
|
||||||
|
FBSurface* surface(int id) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns the current dimensions of the framebuffer image.
|
Returns the current dimensions of the framebuffer image.
|
||||||
Note that this will take into account the current scaling (if any)
|
Note that this will take into account the current scaling (if any)
|
||||||
|
@ -268,16 +298,6 @@ class FrameBuffer
|
||||||
*/
|
*/
|
||||||
virtual BufferType type() const = 0;
|
virtual BufferType type() const = 0;
|
||||||
|
|
||||||
/**
|
|
||||||
This method is called to create a surface compatible with the one
|
|
||||||
currently in use, but having the given dimensions.
|
|
||||||
|
|
||||||
@param w The requested width of the new surface.
|
|
||||||
@param h The requested height of the new surface.
|
|
||||||
@param useBase Use the base surface instead of creating a new one
|
|
||||||
*/
|
|
||||||
virtual FBSurface* createSurface(int w, int h, bool useBase = false) const = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This method is called to get the specified scanline data.
|
This method is called to get the specified scanline data.
|
||||||
|
|
||||||
|
@ -343,6 +363,16 @@ class FrameBuffer
|
||||||
*/
|
*/
|
||||||
virtual bool setVidMode(VideoMode& mode) = 0;
|
virtual bool setVidMode(VideoMode& mode) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
This method is called to create a surface compatible with the one
|
||||||
|
currently in use, but having the given dimensions.
|
||||||
|
|
||||||
|
@param w The requested width of the new surface.
|
||||||
|
@param h The requested height of the new surface.
|
||||||
|
@param useBase Use the base surface instead of creating a new one
|
||||||
|
*/
|
||||||
|
virtual FBSurface* createSurface(int w, int h, bool useBase = false) const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Switches between the filtering options in the video subsystem.
|
Switches between the filtering options in the video subsystem.
|
||||||
*/
|
*/
|
||||||
|
@ -364,6 +394,12 @@ class FrameBuffer
|
||||||
*/
|
*/
|
||||||
virtual string about() const = 0;
|
virtual string about() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Issues the 'reload' instruction to all surfaces that the
|
||||||
|
framebuffer knows about.
|
||||||
|
*/
|
||||||
|
void reloadSurfaces();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// The parent system for the framebuffer
|
// The parent system for the framebuffer
|
||||||
OSystem* myOSystem;
|
OSystem* myOSystem;
|
||||||
|
@ -492,6 +528,7 @@ class FrameBuffer
|
||||||
int x, y, w, h;
|
int x, y, w, h;
|
||||||
uInt32 color;
|
uInt32 color;
|
||||||
FBSurface* surface;
|
FBSurface* surface;
|
||||||
|
int surfaceID;
|
||||||
bool enabled;
|
bool enabled;
|
||||||
};
|
};
|
||||||
Message myMsg;
|
Message myMsg;
|
||||||
|
@ -502,6 +539,10 @@ class FrameBuffer
|
||||||
VideoModeList myFullscreenModeList;
|
VideoModeList myFullscreenModeList;
|
||||||
VideoModeList* myCurrentModeList;
|
VideoModeList* myCurrentModeList;
|
||||||
|
|
||||||
|
// Holds a reference to all the surfaces that have been created
|
||||||
|
map<int,FBSurface*> mySurfaceList;
|
||||||
|
int mySurfaceCount;
|
||||||
|
|
||||||
// Holds static strings for the remap menu (emulation and menu events)
|
// Holds static strings for the remap menu (emulation and menu events)
|
||||||
static GraphicsMode ourGraphicsModes[GFX_NumModes];
|
static GraphicsMode ourGraphicsModes[GFX_NumModes];
|
||||||
};
|
};
|
||||||
|
@ -516,7 +557,7 @@ class FrameBuffer
|
||||||
FrameBuffer type.
|
FrameBuffer type.
|
||||||
|
|
||||||
@author Stephen Anthony
|
@author Stephen Anthony
|
||||||
@version $Id: FrameBuffer.hxx,v 1.104 2008-08-04 11:56:12 stephena Exp $
|
@version $Id: FrameBuffer.hxx,v 1.105 2008-12-12 15:51:07 stephena Exp $
|
||||||
*/
|
*/
|
||||||
// Text alignment modes for drawString()
|
// Text alignment modes for drawString()
|
||||||
enum TextAlignment {
|
enum TextAlignment {
|
||||||
|
@ -650,6 +691,11 @@ class FBSurface
|
||||||
*/
|
*/
|
||||||
virtual void update() = 0;
|
virtual void update() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
This method should be called to reload the surface data/state.
|
||||||
|
*/
|
||||||
|
virtual void reload() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This method should be called to draw a rectangular box with sides
|
This method should be called to draw a rectangular box with sides
|
||||||
at the specified coordinates.
|
at the specified coordinates.
|
||||||
|
|
|
@ -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: Dialog.cxx,v 1.64 2008-08-01 12:16:00 stephena Exp $
|
// $Id: Dialog.cxx,v 1.65 2008-12-12 15:51:07 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
|
||||||
|
@ -47,7 +47,8 @@ Dialog::Dialog(OSystem* instance, DialogContainer* parent,
|
||||||
_isBase(isBase),
|
_isBase(isBase),
|
||||||
_ourTab(NULL),
|
_ourTab(NULL),
|
||||||
_surface(NULL),
|
_surface(NULL),
|
||||||
_focusID(0)
|
_focusID(0),
|
||||||
|
_surfaceID(-1)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +63,8 @@ Dialog::~Dialog()
|
||||||
|
|
||||||
_ourButtonGroup.clear();
|
_ourButtonGroup.clear();
|
||||||
|
|
||||||
delete _surface;
|
_surfaceID = instance().frameBuffer().freeSurface(_surfaceID);
|
||||||
|
_surface = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -77,6 +79,28 @@ void Dialog::open()
|
||||||
// Base surfaces are typically large, and will probably cause slow
|
// Base surfaces are typically large, and will probably cause slow
|
||||||
// performance if we update the whole area each frame
|
// performance if we update the whole area each frame
|
||||||
// Instead, dirty rectangle updates should be performed
|
// Instead, dirty rectangle updates should be performed
|
||||||
|
// However, this policy is left entirely to the framebuffer
|
||||||
|
// We suggest the hint here, but specific framebuffers are free to
|
||||||
|
// ignore it
|
||||||
|
if(_surfaceID < 0 || _surface == NULL)
|
||||||
|
{
|
||||||
|
_surfaceID = instance().frameBuffer().allocateSurface(_w, _h, _isBase);
|
||||||
|
_surface = instance().frameBuffer().surface(_surfaceID);
|
||||||
|
}
|
||||||
|
else if((uInt32)_w > _surface->getWidth() || (uInt32)_h > _surface->getHeight())
|
||||||
|
{
|
||||||
|
_surfaceID = instance().frameBuffer().freeSurface(_surfaceID);
|
||||||
|
_surfaceID = instance().frameBuffer().allocateSurface(_w, _h, _isBase);
|
||||||
|
_surface = instance().frameBuffer().surface(_surfaceID);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_surface->setWidth(_w);
|
||||||
|
_surface->setHeight(_h);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
if(_surface == NULL)
|
if(_surface == NULL)
|
||||||
_surface = instance().frameBuffer().createSurface(_w, _h, _isBase);
|
_surface = instance().frameBuffer().createSurface(_w, _h, _isBase);
|
||||||
else if((uInt32)_w > _surface->getWidth() || (uInt32)_h > _surface->getHeight())
|
else if((uInt32)_w > _surface->getWidth() || (uInt32)_h > _surface->getHeight())
|
||||||
|
@ -89,6 +113,8 @@ void Dialog::open()
|
||||||
_surface->setWidth(_w);
|
_surface->setWidth(_w);
|
||||||
_surface->setHeight(_h);
|
_surface->setHeight(_h);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
center();
|
center();
|
||||||
|
|
||||||
|
|
|
@ -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: Dialog.hxx,v 1.39 2008-06-19 19:15:44 stephena Exp $
|
// $Id: Dialog.hxx,v 1.40 2008-12-12 15:51:07 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
|
||||||
|
@ -47,7 +47,7 @@ class TabWidget;
|
||||||
This is the base class for all dialog boxes.
|
This is the base class for all dialog boxes.
|
||||||
|
|
||||||
@author Stephen Anthony
|
@author Stephen Anthony
|
||||||
@version $Id: Dialog.hxx,v 1.39 2008-06-19 19:15:44 stephena Exp $
|
@version $Id: Dialog.hxx,v 1.40 2008-12-12 15:51:07 stephena Exp $
|
||||||
*/
|
*/
|
||||||
class Dialog : public GuiObject
|
class Dialog : public GuiObject
|
||||||
{
|
{
|
||||||
|
@ -135,6 +135,7 @@ class Dialog : public GuiObject
|
||||||
|
|
||||||
int _result;
|
int _result;
|
||||||
int _focusID;
|
int _focusID;
|
||||||
|
int _surfaceID;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue