mirror of https://github.com/stella-emu/stella.git
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:
parent
db6e1c7c81
commit
303fb5bdbc
|
@ -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 <1|0></pre></td>
|
||||
<td>OpenGL mode only. Enables Blargg NTSC filtering.</td>
|
||||
</tr>
|
||||
|
||||
<!-- FIXME
|
||||
<tr>
|
||||
<td><pre>-tv_tex <off|normal|stag></pre></td>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -201,6 +201,11 @@ class Console : public Serializable
|
|||
*/
|
||||
void togglePhosphor();
|
||||
|
||||
/**
|
||||
Toggles NTSC filtering effects.
|
||||
*/
|
||||
void toggleNTSC();
|
||||
|
||||
/**
|
||||
Toggles the PAL color-loss effect.
|
||||
*/
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue