First pass at tying the NTSC filtering code into the OpenGL TIA

rendering code.  This is just infrastructure for now.  Pressing
Alt-f will toggle the filtering, but there's no output yet.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2430 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2012-03-25 17:51:13 +00:00
parent db6e1c7c81
commit 303fb5bdbc
12 changed files with 143 additions and 43 deletions

View File

@ -1488,6 +1488,12 @@
<td>Control + f</td>
</tr>
<tr>
<td>Toggle Blargg NTSC filtering</td>
<td>Alt + f</td>
<td>Cmd + f</td>
</tr>
<tr>
<td>Save current properties to a new properties file</td>
<td>Control + s</td>
@ -1766,6 +1772,11 @@
period. This can result in smoother updates, and eliminate tearing.</td>
</tr>
<tr>
<td><pre>-ntsc_filter &lt;1|0&gt;</pre></td>
<td>OpenGL mode only. Enables Blargg NTSC filtering.</td>
</tr>
<!-- FIXME
<tr>
<td><pre>-tv_tex &lt;off|normal|stag&gt;</pre></td>

View File

@ -22,6 +22,7 @@
#include "Font.hxx"
#include "FrameBufferGL.hxx"
#include "TIA.hxx"
#include "NTSCFilter.hxx"
#include "FBSurfaceTIA.hxx"
@ -97,35 +98,46 @@ void FBSurfaceTIA::update()
uInt32 height = myTIA->height();
uInt16* buffer = (uInt16*) myTexture->pixels;
if(!myFB.myUsePhosphor)
switch(myFB.myFilterType)
{
uInt32 bufofsY = 0;
uInt32 screenofsY = 0;
for(uInt32 y = 0; y < height; ++y )
case FrameBufferGL::kNone:
{
uInt32 pos = screenofsY;
for(uInt32 x = 0; x < width; ++x )
buffer[pos++] = (uInt16) myFB.myDefPalette[currentFrame[bufofsY + x]];
bufofsY += width;
screenofsY += myPitch;
}
}
else
{
uInt32 bufofsY = 0;
uInt32 screenofsY = 0;
for(uInt32 y = 0; y < height; ++y )
{
uInt32 pos = screenofsY;
for(uInt32 x = 0; x < width; ++x )
uInt32 bufofsY = 0;
uInt32 screenofsY = 0;
for(uInt32 y = 0; y < height; ++y)
{
const uInt32 bufofs = bufofsY + x;
buffer[pos++] = (uInt16)
myFB.myAvgPalette[currentFrame[bufofs]][previousFrame[bufofs]];
uInt32 pos = screenofsY;
for(uInt32 x = 0; x < width; ++x)
buffer[pos++] = (uInt16) myFB.myDefPalette[currentFrame[bufofsY + x]];
bufofsY += width;
screenofsY += myPitch;
}
bufofsY += width;
screenofsY += myPitch;
break;
}
case FrameBufferGL::kPhosphor:
{
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;
buffer[pos++] = (uInt16)
myFB.myAvgPalette[currentFrame[bufofs]][previousFrame[bufofs]];
}
bufofsY += width;
screenofsY += myPitch;
}
break;
}
case FrameBufferGL::kBlarggNTSC:
{
break;
}
}
@ -345,4 +357,10 @@ void FBSurfaceTIA::updateCoords()
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurfaceTIA::setTIAPalette(const uInt32* palette)
{
myNTSCFilter.setTIAPalette(palette);
}
#endif

View File

@ -25,6 +25,7 @@
#include "bspf.hxx"
#include "FrameBuffer.hxx"
#include "FrameBufferGL.hxx"
#include "NTSCFilter.hxx"
/**
A surface suitable for OpenGL rendering mode, but specifically for
@ -56,6 +57,7 @@ class FBSurfaceTIA : public FBSurface
private:
void setTIA(const TIA& tia) { myTIA = &tia; }
void setTIAPalette(const uInt32* palette);
void setFilter(const string& name);
void updateCoords();
@ -64,6 +66,7 @@ class FBSurfaceTIA : public FBSurface
const FrameBufferGL::GLpointers& myGL;
const TIA* myTIA;
SDL_Surface* myTexture;
NTSCFilter myNTSCFilter;
uInt32 myPitch;
GLuint myTexID[2], myVBOID;

View File

@ -40,6 +40,7 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FrameBufferGL::FrameBufferGL(OSystem* osystem)
: FrameBuffer(osystem),
myFilterType(kNone),
myTiaSurface(NULL),
myFilterParamName("GL_NEAREST"),
myDirtyFlag(true)
@ -131,10 +132,6 @@ bool FrameBufferGL::loadFuncs(GLFunctionality functionality)
OGL_INIT(BufferData,void,glBufferData,(GLenum,GLsizei,const void*,GLenum));
OGL_INIT(DeleteBuffers,void,glDeleteBuffers,(GLsizei, const GLuint*));
break; // kGL_VBO
case kGL_FBO:
return false; // TODO - implement this
break; // kGL_FBO
}
}
else
@ -196,7 +193,6 @@ string FrameBufferGL::about() const
<< " Filter: " << myFilterParamName << endl
<< " Extensions: ";
if(myVBOAvailable) out << "VBO ";
if(myFBOAvailable) out << "FBO ";
out << endl;
return out.str();
}
@ -280,7 +276,6 @@ bool FrameBufferGL::setVidMode(VideoMode& mode)
myGLVersion = atof(version.substr(0, 3).c_str());
myVBOAvailable = myOSystem->settings().getBool("gl_vbo") && loadFuncs(kGL_VBO);
myFBOAvailable = false;
}
else
return false;
@ -389,10 +384,29 @@ void FrameBufferGL::enablePhosphor(bool enable, int blend)
{
myUsePhosphor = enable;
myPhosphorBlend = blend;
myFilterType = enable ? kPhosphor : kNone;
myRedrawEntireFrame = true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferGL::enableNTSC(bool enable)
{
if(enable)
myFilterType = kBlarggNTSC;
else
myFilterType = myUsePhosphor ? kPhosphor : kNone;
myRedrawEntireFrame = true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferGL::setTIAPalette(const uInt32* palette)
{
myTiaSurface->setTIAPalette(palette);
FrameBuffer::setTIAPalette(palette);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FBSurface* FrameBufferGL::createSurface(int w, int h, bool isBase) const
{
@ -423,7 +437,4 @@ float FrameBufferGL::myGLVersion = 0.0;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool FrameBufferGL::myVBOAvailable = false;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool FrameBufferGL::myFBOAvailable = false;
#endif // DISPLAY_OPENGL

View File

@ -79,11 +79,6 @@ class FrameBufferGL : public FrameBuffer
*/
static float glVersion() { return myGLVersion; }
/**
Indicates whether GL FBO functionality was detected and enabled.
*/
static bool isFBOAvailable() { return myFBOAvailable; }
//////////////////////////////////////////////////////////////////////
// The following are derived from public methods in FrameBuffer.hxx
//////////////////////////////////////////////////////////////////////
@ -92,6 +87,18 @@ class FrameBufferGL : public FrameBuffer
*/
void enablePhosphor(bool enable, int blend);
/**
Enable/disable NTSC filtering effects.
*/
void enableNTSC(bool enable);
/**
Set up the TIA/emulation palette for a screen of any depth > 8.
@param palette The array of colors
*/
void setTIAPalette(const uInt32* palette);
/**
This method is called to retrieve the R/G/B data from the given pixel.
@ -185,10 +192,17 @@ class FrameBufferGL : public FrameBuffer
private:
enum GLFunctionality {
kGL_BASIC, kGL_VBO, kGL_FBO
kGL_BASIC, kGL_VBO
};
bool loadFuncs(GLFunctionality functionality);
enum FilterType {
kNone,
kPhosphor,
kBlarggNTSC
};
FilterType myFilterType;
static uInt32 power_of_two(uInt32 input)
{
uInt32 value = 1;
@ -223,8 +237,8 @@ class FrameBufferGL : public FrameBuffer
// Indicates the OpenGL version found (0 indicates none)
static float myGLVersion;
// Indicates whether Vertex/Frame Buffer Object functions were properly loaded
static bool myVBOAvailable, myFBOAvailable;
// Indicates whether Vertex Buffer Objects (VBO) are available
static bool myVBOAvailable;
// Structure containing dynamically-loaded OpenGL function pointers
#define OGL_DECLARE(NAME,RET,FUNC,PARAMS) RET (APIENTRY* NAME) PARAMS

View File

@ -58,6 +58,11 @@ class FrameBufferSoft : public FrameBuffer
*/
void enablePhosphor(bool enable, int blend);
/**
Enable/disable NTSC filtering effects (not supported in software mode).
*/
void enableNTSC(bool enable) { }
/**
This method is called to retrieve the R/G/B data from the given pixel.

View File

@ -86,7 +86,7 @@ extern atari_ntsc_setup_t const atari_ntsc_svideo; /* color bleeding only */
extern atari_ntsc_setup_t const atari_ntsc_rgb; /* crisp image */
extern atari_ntsc_setup_t const atari_ntsc_monochrome;/* desaturated + artifacts */
enum { atari_ntsc_palette_size = 256 };
enum { atari_ntsc_palette_size = 128 };
/* Initializes and adjusts parameters. Can be called multiple times on the same
atari_ntsc_t object. Can pass NULL for either parameter. */

View File

@ -441,6 +441,24 @@ void Console::togglePhosphor()
myOSystem->frameBuffer().enablePhosphor(enable, blend);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Console::toggleNTSC()
{
ostringstream buf;
if(myOSystem->frameBuffer().type() == kDoubleBuffer)
{
bool state = !myOSystem->settings().getBool("ntsc_filter");
myOSystem->frameBuffer().enableNTSC(state);
myOSystem->settings().setBool("ntsc_filter", state);
buf << "NTSC filtering " << (state ? "enabled" : "disabled");
myOSystem->frameBuffer().showMessage(buf.str());
}
else
buf << "NTSC filtering not available";
myOSystem->frameBuffer().showMessage(buf.str());
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Console::setProperties(const Properties& props)
{
@ -468,6 +486,7 @@ FBInitStatus Console::initializeVideo(bool full)
bool enable = myProperties.get(Display_Phosphor) == "YES";
int blend = atoi(myProperties.get(Display_PPBlend).c_str());
myOSystem->frameBuffer().enablePhosphor(enable, blend);
myOSystem->frameBuffer().enableNTSC(myOSystem->settings().getBool("ntsc_filter"));
setPalette(myOSystem->settings().getString("palette"));
// Set the correct framerate based on the format of the ROM

View File

@ -201,6 +201,11 @@ class Console : public Serializable
*/
void togglePhosphor();
/**
Toggles NTSC filtering effects.
*/
void toggleNTSC();
/**
Toggles the PAL color-loss effect.
*/

View File

@ -375,6 +375,10 @@ void EventHandler::poll(uInt64 time)
myOSystem->console().changeYStart(-1);
break;
case KBDK_f: // Alt-f toggles NTSC filtering
myOSystem->console().toggleNTSC();
break;
case KBDK_z:
if(mod & KMOD_SHIFT)
myOSystem->console().toggleP0Collision();

View File

@ -299,6 +299,11 @@ class FrameBuffer
*/
virtual void enablePhosphor(bool enable, int blend) = 0;
/**
Enable/disable NTSC filtering effects.
*/
virtual void enableNTSC(bool enable) = 0;
/**
This method is called to retrieve the R/G/B data from the given pixel.

View File

@ -59,6 +59,9 @@ Settings::Settings(OSystem* osystem)
setInternal("timing", "sleep");
setInternal("uimessages", "true");
// NTSC filtering options
setInternal("ntsc_filter", "false");
// Sound options
setInternal("sound", "true");
setInternal("fragsize", "512");
@ -340,6 +343,8 @@ void Settings::usage()
<< " -gl_vsync <1|0> Enable 'synchronize to vertical blank interrupt'\n"
<< " -gl_vbo <1|0> Enable 'vertex buffer objects'\n"
<< endl
<< " -ntsc_filter <1|0> Enable Blargg NTSC filtering effects\n"
<< endl
#endif
<< " -tia_filter <filter> Use the specified filter in emulation mode\n"
<< " -fullscreen <1|0|-1> Use fullscreen mode (1 or 0), or disable switching to fullscreen entirely\n"