mirror of https://github.com/stella-emu/stella.git
Added scanline interpolation option (blended scanlines) with the
'tv_scaninter' option. Added Alt-8 keypress to toggle this; still TODO is add a UI item for it. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2462 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
7d3ea13a01
commit
f59f5ab5e8
|
@ -230,8 +230,8 @@ void FBSurfaceTIA::reload()
|
|||
|
||||
// Base texture (@ index 0)
|
||||
myGL.BindTexture(GL_TEXTURE_2D, myTexID[0]);
|
||||
myGL.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
myGL.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
myGL.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, myTexFilter[0]);
|
||||
myGL.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, myTexFilter[0]);
|
||||
myGL.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
myGL.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
|
@ -247,10 +247,11 @@ void FBSurfaceTIA::reload()
|
|||
|
||||
// Scanline texture (@ index 1)
|
||||
myGL.BindTexture(GL_TEXTURE_2D, myTexID[1]);
|
||||
myGL.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
myGL.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
myGL.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, myTexFilter[1]);
|
||||
myGL.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, myTexFilter[1]);
|
||||
myGL.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
myGL.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
|
||||
#ifdef HAVE_GL_BGRA
|
||||
static uInt16 const scanline[4] = { 0x0000, 0x0000, 0x8000, 0x0000 };
|
||||
myGL.TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 2, 0,
|
||||
|
@ -273,18 +274,34 @@ void FBSurfaceTIA::reload()
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceTIA::setFilter(const string& name)
|
||||
void FBSurfaceTIA::setScanIntensity(uInt32 intensity)
|
||||
{
|
||||
// We only do GL_NEAREST or GL_LINEAR for now
|
||||
GLint filter = name == "linear" ? GL_LINEAR : GL_NEAREST;
|
||||
myScanlineIntensityI = (GLuint)intensity;
|
||||
myScanlineIntensityF = (GLfloat)intensity / 100;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceTIA::setTexInterpolation(bool enable)
|
||||
{
|
||||
myTexFilter[0] = enable ? GL_LINEAR : GL_NEAREST;
|
||||
myGL.BindTexture(GL_TEXTURE_2D, myTexID[0]);
|
||||
myGL.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
|
||||
myGL.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
|
||||
myGL.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, myTexFilter[0]);
|
||||
myGL.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, myTexFilter[0]);
|
||||
myGL.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
myGL.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceTIA::setScanInterpolation(bool enable)
|
||||
{
|
||||
myTexFilter[1] = enable ? GL_LINEAR : GL_NEAREST;
|
||||
myGL.BindTexture(GL_TEXTURE_2D, myTexID[1]);
|
||||
myGL.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, myTexFilter[1]);
|
||||
myGL.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, myTexFilter[1]);
|
||||
myGL.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
myGL.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceTIA::updateCoords(uInt32 baseH,
|
||||
uInt32 imgX, uInt32 imgY, uInt32 imgW, uInt32 imgH)
|
||||
|
|
|
@ -56,8 +56,10 @@ class FBSurfaceTIA : public FBSurface
|
|||
private:
|
||||
void setTIA(const TIA& tia) { myTIA = &tia; }
|
||||
void setTIAPalette(const uInt32* palette);
|
||||
void setFilter(const string& name);
|
||||
void enableScanlines(bool enable) { myScanlinesEnabled = enable; }
|
||||
void setScanIntensity(uInt32 intensity);
|
||||
void setTexInterpolation(bool enable);
|
||||
void setScanInterpolation(bool enable);
|
||||
void updateCoords(uInt32 baseH, uInt32 imgX, uInt32 imgY, uInt32 imgW, uInt32 imgH);
|
||||
void updateCoords();
|
||||
|
||||
|
@ -75,6 +77,7 @@ class FBSurfaceTIA : public FBSurface
|
|||
GLuint myImageX, myImageY, myImageW, myImageH;
|
||||
GLfloat myTexCoordW, myTexCoordH;
|
||||
GLfloat myCoord[32];
|
||||
GLint myTexFilter[2];
|
||||
|
||||
bool myScanlinesEnabled;
|
||||
GLuint myScanlineIntensityI;
|
||||
|
|
|
@ -311,10 +311,7 @@ bool FrameBufferGL::setVidMode(VideoMode& mode)
|
|||
p_gl.MatrixMode(GL_MODELVIEW);
|
||||
p_gl.LoadIdentity();
|
||||
|
||||
#if 0
|
||||
cerr << "dimensions: " << (fullScreen() ? "(full)" : "") << endl
|
||||
<< mode << endl;
|
||||
#endif
|
||||
//cerr << "dimensions: " << (fullScreen() ? "(full)" : "") << endl << mode << endl;
|
||||
|
||||
// The framebuffer only takes responsibility for TIA surfaces
|
||||
// Other surfaces (such as the ones used for dialogs) are allocated
|
||||
|
@ -330,8 +327,10 @@ cerr << "dimensions: " << (fullScreen() ? "(full)" : "") << endl
|
|||
myTiaSurface->updateCoords(baseHeight, mode.image_x, mode.image_y,
|
||||
mode.image_w, mode.image_h);
|
||||
|
||||
myTiaSurface->setFilter(myOSystem->settings().getString("gl_filter"));
|
||||
myTiaSurface->enableScanlines(myFilterType == kBlarggNTSC);
|
||||
myTiaSurface->setScanIntensity(myOSystem->settings().getInt("tv_scanlines"));
|
||||
myTiaSurface->setTexInterpolation(myOSystem->settings().getBool("gl_inter"));
|
||||
myTiaSurface->setScanInterpolation(myOSystem->settings().getBool("tv_scaninter"));
|
||||
myTiaSurface->setTIA(myOSystem->console().tia());
|
||||
}
|
||||
|
||||
|
@ -385,7 +384,12 @@ void FrameBufferGL::enableNTSC(bool enable)
|
|||
{
|
||||
myFilterType = enable ? kBlarggNTSC : myUsePhosphor ? kPhosphor : kNone;
|
||||
myTiaSurface->updateCoords();
|
||||
|
||||
myTiaSurface->enableScanlines(myFilterType == kBlarggNTSC);
|
||||
myTiaSurface->setScanIntensity(myOSystem->settings().getInt("tv_scanlines"));
|
||||
myTiaSurface->setTexInterpolation(myOSystem->settings().getBool("gl_inter"));
|
||||
myTiaSurface->setScanInterpolation(myOSystem->settings().getBool("tv_scaninter"));
|
||||
|
||||
myRedrawEntireFrame = true;
|
||||
}
|
||||
}
|
||||
|
@ -401,14 +405,22 @@ uInt32 FrameBufferGL::changeScanlines(int relative, int absolute)
|
|||
intensity = BSPF_max(0, intensity);
|
||||
intensity = BSPF_min(100, intensity);
|
||||
|
||||
myTiaSurface->myScanlineIntensityI = (GLuint)intensity;
|
||||
myTiaSurface->myScanlineIntensityF = (GLfloat)intensity / 100;
|
||||
|
||||
myTiaSurface->setScanIntensity(intensity);
|
||||
myRedrawEntireFrame = true;
|
||||
}
|
||||
return intensity;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferGL::enableScanlineInterpolation(bool enable)
|
||||
{
|
||||
if(myTiaSurface)
|
||||
{
|
||||
myTiaSurface->setScanInterpolation(enable);
|
||||
myRedrawEntireFrame = true;
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferGL::setTIAPalette(const uInt32* palette)
|
||||
{
|
||||
|
|
|
@ -94,7 +94,7 @@ class FrameBufferGL : public FrameBuffer
|
|||
bool ntscEnabled() const { return myFilterType == kBlarggNTSC; }
|
||||
|
||||
/**
|
||||
Change scanline intensity.
|
||||
Change scanline intensity and interpolation.
|
||||
relative = -1 means decrease current intensity by 'directin
|
||||
direction = 0 means to reload the current video mode
|
||||
direction = +1 means go to the next higher video mode
|
||||
|
@ -105,6 +105,7 @@ class FrameBufferGL : public FrameBuffer
|
|||
@return New current intensity
|
||||
*/
|
||||
uInt32 changeScanlines(int relative, int absolute = 50);
|
||||
void enableScanlineInterpolation(bool enable);
|
||||
|
||||
/**
|
||||
Set up the TIA/emulation palette for a screen of any depth > 8.
|
||||
|
|
|
@ -490,6 +490,28 @@ void Console::changeScanlines(int amount, bool show)
|
|||
if(show) myOSystem->frameBuffer().showMessage(buf.str());
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Console::toggleScanlineInterpolation()
|
||||
{
|
||||
ostringstream buf;
|
||||
if(myOSystem->frameBuffer().type() == kDoubleBuffer)
|
||||
{
|
||||
if(myOSystem->frameBuffer().ntscEnabled())
|
||||
{
|
||||
bool enable = !myOSystem->settings().getBool("tv_scaninter");
|
||||
myOSystem->frameBuffer().enableScanlineInterpolation(enable);
|
||||
buf << "Scanline interpolation " << (enable ? "enabled" : "disabled");
|
||||
myOSystem->settings().setBool("tv_scaninter", enable);
|
||||
}
|
||||
else
|
||||
buf << "Scanlines only available in TV filtering mode";
|
||||
}
|
||||
else
|
||||
buf << "Scanlines not available in software mode";
|
||||
|
||||
myOSystem->frameBuffer().showMessage(buf.str());
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Console::setProperties(const Properties& props)
|
||||
{
|
||||
|
@ -517,7 +539,6 @@ 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().changeScanlines(0, myOSystem->settings().getInt("tv_scanlines"));
|
||||
toggleNTSC((NTSCFilter::Preset)myOSystem->settings().getInt("tv_filter"));
|
||||
setPalette(myOSystem->settings().getString("palette"));
|
||||
|
||||
|
|
|
@ -212,6 +212,11 @@ class Console : public Serializable
|
|||
*/
|
||||
void changeScanlines(int amount, bool show = false);
|
||||
|
||||
/**
|
||||
Toggles interpolation/smoothing of scanlines in TV modes.
|
||||
*/
|
||||
void toggleScanlineInterpolation();
|
||||
|
||||
/**
|
||||
Toggles the PAL color-loss effect.
|
||||
*/
|
||||
|
|
|
@ -409,6 +409,10 @@ void EventHandler::poll(uInt64 time)
|
|||
myOSystem->console().changeScanlines(+5, true);
|
||||
break;
|
||||
|
||||
case KBDK_8: // Alt-8 turns toggles scanline interpolation
|
||||
myOSystem->console().toggleScanlineInterpolation();
|
||||
break;
|
||||
|
||||
case KBDK_z:
|
||||
if(mod & KMOD_SHIFT)
|
||||
myOSystem->console().toggleP0Collision();
|
||||
|
|
|
@ -303,7 +303,7 @@ class FrameBuffer
|
|||
virtual bool ntscEnabled() const { return false; }
|
||||
|
||||
/**
|
||||
Change scanline intensity.
|
||||
Change scanline intensity and interpolation.
|
||||
relative = -1 means decrease current intensity by 'directin
|
||||
direction = 0 means to reload the current video mode
|
||||
direction = +1 means go to the next higher video mode
|
||||
|
@ -314,6 +314,7 @@ class FrameBuffer
|
|||
@return New current intensity
|
||||
*/
|
||||
virtual uInt32 changeScanlines(int relative, int absolute = 50) { return absolute; }
|
||||
virtual void enableScanlineInterpolation(bool enable) { }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// The following methods are system-specific and *must* be implemented
|
||||
|
|
|
@ -40,7 +40,7 @@ Settings::Settings(OSystem* osystem)
|
|||
setInternal("video", "soft");
|
||||
|
||||
// OpenGL specific options
|
||||
setInternal("gl_filter", "nearest");
|
||||
setInternal("gl_inter", "false");
|
||||
setInternal("gl_aspectn", "90");
|
||||
setInternal("gl_aspectp", "100");
|
||||
setInternal("gl_fsscale", "false");
|
||||
|
@ -62,6 +62,7 @@ Settings::Settings(OSystem* osystem)
|
|||
// TV filtering options
|
||||
setInternal("tv_filter", "0");
|
||||
setInternal("tv_scanlines", "50");
|
||||
setInternal("tv_scaninter", "true");
|
||||
|
||||
// Sound options
|
||||
setInternal("sound", "true");
|
||||
|
@ -259,9 +260,6 @@ void Settings::validate()
|
|||
if(s != "sleep" && s != "busy") setInternal("timing", "sleep");
|
||||
|
||||
#ifdef DISPLAY_OPENGL
|
||||
s = getString("gl_filter");
|
||||
if(s != "linear" && s != "nearest") setInternal("gl_filter", "nearest");
|
||||
|
||||
i = getInt("gl_aspectn");
|
||||
if(i < 80 || i > 120) setInternal("gl_aspectn", "100");
|
||||
i = getInt("gl_aspectp");
|
||||
|
@ -335,9 +333,7 @@ void Settings::usage()
|
|||
<< " gl SDL OpenGL mode\n"
|
||||
<< endl
|
||||
<< " -gl_lib <name> Specify the OpenGL library\n"
|
||||
<< " -gl_filter <type> Type is one of the following:\n"
|
||||
<< " nearest Normal scaling (GL_NEAREST)\n"
|
||||
<< " linear Blurred scaling (GL_LINEAR)\n"
|
||||
<< " -gl_inter <1|0> Enable interpolated (smooth) scaling\n"
|
||||
<< " -gl_aspectn <number> Scale the TIA width by the given percentage in NTSC mode\n"
|
||||
<< " -gl_aspectp <number> Scale the TIA width by the given percentage in PAL mode\n"
|
||||
<< " -gl_fsscale <1|0> Stretch GL image in fullscreen emulation mode to max/integer scale\n"
|
||||
|
@ -346,6 +342,7 @@ void Settings::usage()
|
|||
<< endl
|
||||
<< " -tv_filter <0-5> Set TV effects off (0) or to specified mode (1-5)\n"
|
||||
<< " -tv_scanlines <0-100> Set scanline intensity to percentage (0 disables completely)\n"
|
||||
<< " -tv_scaninter <1|0> Enable interpolated (smooth) scanlines\n"
|
||||
<< endl
|
||||
#endif
|
||||
<< " -tia_filter <filter> Use the specified filter in emulation mode\n"
|
||||
|
|
|
@ -317,6 +317,7 @@ void VideoDialog::loadConfig()
|
|||
instance().settings().getString("timing"), "sleep");
|
||||
|
||||
// GL Filter setting
|
||||
// FIXME
|
||||
myGLFilterPopup->setSelected(
|
||||
instance().settings().getString("gl_filter"), "nearest");
|
||||
myGLFilterPopup->setEnabled(gl);
|
||||
|
|
Loading…
Reference in New Issue