mirror of https://github.com/stella-emu/stella.git
Phosphor effect now working for software render in 16/32 bit color modes;
still TODO for 24 bit mode. I've benchmarked the CPU usage in Linux under 16/32 bit modes, and they're within 1% of those for z26. Not bad for C++ vs. assembly code :) I still need to test in Windows, which (ironically enough) tends to be slower than Linux in graphics performance. Note that CPU usage ranges from 6% (Linux/1x/software/phosphor/16bit) to 85% (Linux/3x/software/phosphor/32bit). Using OpenGL, the usage is always 12%, whatever the zoom/color depth/phosphor. I just love OpenGL ... git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@955 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
b4525b5ff7
commit
53d70797d8
|
@ -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.47 2006-01-11 20:28:06 stephena Exp $
|
// $Id: FrameBufferGL.cxx,v 1.48 2006-01-12 16:23:36 stephena Exp $
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#ifdef DISPLAY_OPENGL
|
#ifdef DISPLAY_OPENGL
|
||||||
|
@ -221,16 +221,16 @@ void FrameBufferGL::drawMediaSource()
|
||||||
uInt16* buffer = (uInt16*) myTexture->pixels;
|
uInt16* buffer = (uInt16*) myTexture->pixels;
|
||||||
|
|
||||||
// TODO - is this fast enough?
|
// TODO - is this fast enough?
|
||||||
register uInt32 x, y;
|
|
||||||
switch((int)myUsePhosphor) // use switch/case, since we'll eventually have filters
|
switch((int)myUsePhosphor) // use switch/case, since we'll eventually have filters
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
for(y = 0; y < height; ++y )
|
|
||||||
{
|
{
|
||||||
const uInt32 bufofsY = y * width;
|
uInt32 bufofsY = 0;
|
||||||
const uInt32 screenofsY = y * myTexture->w;
|
uInt32 screenofsY = 0;
|
||||||
|
for(uInt32 y = 0; y < height; ++y )
|
||||||
for(x = 0; x < width; ++x )
|
{
|
||||||
|
uInt32 pos = screenofsY;
|
||||||
|
for(uInt32 x = 0; x < width; ++x )
|
||||||
{
|
{
|
||||||
const uInt32 bufofs = bufofsY + x;
|
const uInt32 bufofs = bufofsY + x;
|
||||||
uInt8 v = currentFrame[bufofs];
|
uInt8 v = currentFrame[bufofs];
|
||||||
|
@ -243,63 +243,42 @@ void FrameBufferGL::drawMediaSource()
|
||||||
// are drawn in postFrameUpdate()
|
// are drawn in postFrameUpdate()
|
||||||
myDirtyFlag = true;
|
myDirtyFlag = true;
|
||||||
|
|
||||||
// x << 1 is times 2 ( doubling width )
|
|
||||||
const uInt32 pos = screenofsY + (x << 1);
|
|
||||||
buffer[pos] = buffer[pos+1] = (uInt16) myPalette[v];
|
buffer[pos] = buffer[pos+1] = (uInt16) myPalette[v];
|
||||||
}
|
}
|
||||||
|
pos += 2;
|
||||||
}
|
}
|
||||||
|
bufofsY += width;
|
||||||
|
screenofsY += myTexture->w;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
for(y = 0; y < height; ++y )
|
|
||||||
{
|
|
||||||
const uInt32 bufofsY = y * width;
|
|
||||||
const uInt32 screenofsY = y * myTexture->w;
|
|
||||||
|
|
||||||
for(x = 0; x < width; ++x )
|
|
||||||
{
|
|
||||||
const uInt32 bufofs = bufofsY + x;
|
|
||||||
uInt8 v = currentFrame[bufofs];
|
|
||||||
uInt8 w = previousFrame[bufofs];
|
|
||||||
|
|
||||||
if(v != w || theRedrawTIAIndicator)
|
|
||||||
{
|
|
||||||
// If we ever get to this point, we know the current and previous
|
|
||||||
// buffers differ. In that case, make sure the changes are
|
|
||||||
// are drawn in postFrameUpdate()
|
|
||||||
myDirtyFlag = true;
|
|
||||||
|
|
||||||
// x << 1 is times 2 ( doubling width )
|
|
||||||
const uInt32 pos = screenofsY + (x << 1);
|
|
||||||
buffer[pos] = buffer[pos+1] = (uInt16) myPalette[v];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
|
{
|
||||||
// Phosphor mode always implies a dirty update,
|
// Phosphor mode always implies a dirty update,
|
||||||
// so we don't care about theRedrawTIAIndicator
|
// so we don't care about theRedrawTIAIndicator
|
||||||
myDirtyFlag = true;
|
myDirtyFlag = true;
|
||||||
for(y = 0; y < height; ++y )
|
|
||||||
{
|
|
||||||
const uInt32 bufofsY = y * width;
|
|
||||||
const uInt32 screenofsY = y * myTexture->w;
|
|
||||||
|
|
||||||
for(x = 0; x < width; ++x )
|
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;
|
const uInt32 bufofs = bufofsY + x;
|
||||||
uInt8 v = currentFrame[bufofs];
|
uInt8 v = currentFrame[bufofs];
|
||||||
uInt8 w = previousFrame[bufofs];
|
uInt8 w = previousFrame[bufofs];
|
||||||
|
|
||||||
// x << 1 is times 2 ( doubling width )
|
buffer[pos++] = (uInt16) myAvgPalette[v][w];
|
||||||
const uInt32 pos = screenofsY + (x << 1);
|
buffer[pos++] = (uInt16) myAvgPalette[v][w];
|
||||||
buffer[pos] = buffer[pos+1] = (uInt16) myAvgPalette[v][w];
|
|
||||||
}
|
}
|
||||||
|
bufofsY += width;
|
||||||
|
screenofsY += myTexture->w;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -495,11 +474,6 @@ void FrameBufferGL::enablePhosphor(bool enable)
|
||||||
{
|
{
|
||||||
myUsePhosphor = enable;
|
myUsePhosphor = enable;
|
||||||
myPhosphorBlend = myOSystem->settings().getInt("ppblend");
|
myPhosphorBlend = myOSystem->settings().getInt("ppblend");
|
||||||
|
|
||||||
cerr << "phosphor effect: " << (myUsePhosphor ? "yes" : "no") << endl
|
|
||||||
<< "phosphor amount: " << myPhosphorBlend << endl << endl;
|
|
||||||
|
|
||||||
// FIXME - change rendering method
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
|
@ -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.cxx,v 1.41 2006-01-11 20:28:06 stephena Exp $
|
// $Id: FrameBufferSoft.cxx,v 1.42 2006-01-12 16:23:36 stephena Exp $
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
|
@ -117,7 +117,7 @@ void FrameBufferSoft::drawMediaSource()
|
||||||
uInt32 width = mediasrc.width();
|
uInt32 width = mediasrc.width();
|
||||||
uInt32 height = mediasrc.height();
|
uInt32 height = mediasrc.height();
|
||||||
|
|
||||||
switch(myRenderType) // use switch/case, since we'll eventually have filters
|
switch((int)myRenderType) // use switch/case, since we'll eventually have filters
|
||||||
{
|
{
|
||||||
case kSoftZoom:
|
case kSoftZoom:
|
||||||
{
|
{
|
||||||
|
@ -259,11 +259,10 @@ void FrameBufferSoft::drawMediaSource()
|
||||||
myRectList->add(&temp);
|
myRectList->add(&temp);
|
||||||
SDL_FillRect(myScreen, &temp, myPalette[active.color]);
|
SDL_FillRect(myScreen, &temp, myPalette[active.color]);
|
||||||
}
|
}
|
||||||
|
|
||||||
break; // case 0
|
break; // case 0
|
||||||
}
|
}
|
||||||
|
|
||||||
case kPhosphor2x_16:
|
case kPhosphor_16:
|
||||||
{
|
{
|
||||||
// Since phosphor mode updates the whole screen,
|
// Since phosphor mode updates the whole screen,
|
||||||
// we might as well use SDL_Flip (see postFrameUpdate)
|
// we might as well use SDL_Flip (see postFrameUpdate)
|
||||||
|
@ -273,53 +272,114 @@ void FrameBufferSoft::drawMediaSource()
|
||||||
myRectList->add(&temp);
|
myRectList->add(&temp);
|
||||||
|
|
||||||
uInt16* buffer = (uInt16*)myScreen->pixels;
|
uInt16* buffer = (uInt16*)myScreen->pixels;
|
||||||
int pixel;
|
uInt32 bufofsY = 0;
|
||||||
|
uInt32 screenofsY = 0;
|
||||||
for(uInt32 y = 0; y < height; ++y)
|
|
||||||
{
|
|
||||||
for(int i = 0; i < width>>2; ++i)
|
|
||||||
{
|
|
||||||
pixel = myAvgPalette[*currentFrame++][*previousFrame++];
|
|
||||||
*buffer++ = pixel; *buffer++ = pixel;
|
|
||||||
*buffer++ = pixel; *buffer++ = pixel;
|
|
||||||
|
|
||||||
pixel = myAvgPalette[*currentFrame++][*previousFrame++];
|
|
||||||
*buffer++ = pixel; *buffer++ = pixel;
|
|
||||||
*buffer++ = pixel; *buffer++ = pixel;
|
|
||||||
|
|
||||||
pixel = myAvgPalette[*currentFrame++][*previousFrame++];
|
|
||||||
*buffer++ = pixel; *buffer++ = pixel;
|
|
||||||
*buffer++ = pixel; *buffer++ = pixel;
|
|
||||||
|
|
||||||
pixel = myAvgPalette[*currentFrame++][*previousFrame++];
|
|
||||||
*buffer++ = pixel; *buffer++ = pixel;
|
|
||||||
*buffer++ = pixel; *buffer++ = pixel;
|
|
||||||
}
|
|
||||||
buffer+=myScreen->pitch/2;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
uInt32 bufofsY = 0;//y * width;
|
|
||||||
uInt32 screenofsY = 0;//y * myScreen->pitch/2;
|
|
||||||
for(uInt32 y = 0; y < height; ++y )
|
for(uInt32 y = 0; y < height; ++y )
|
||||||
{
|
{
|
||||||
for(uInt32 x = 0; x < width; ++x)
|
uInt32 ystride = theZoomLevel;
|
||||||
|
while(ystride--)
|
||||||
|
{
|
||||||
|
uInt32 pos = screenofsY;
|
||||||
|
for(uInt32 x = 0; x < width; ++x )
|
||||||
{
|
{
|
||||||
const uInt32 bufofs = bufofsY + x;
|
const uInt32 bufofs = bufofsY + x;
|
||||||
|
uInt32 xstride = theZoomLevel;
|
||||||
|
|
||||||
uInt8 v = currentFrame[bufofs];
|
uInt8 v = currentFrame[bufofs];
|
||||||
uInt8 w = previousFrame[bufofs];
|
uInt8 w = previousFrame[bufofs];
|
||||||
|
|
||||||
// x << 1 is times 2 ( doubling width )
|
while(xstride--)
|
||||||
int pos = screenofsY + (x << 2);
|
{
|
||||||
buffer[pos++] = (uInt16) myAvgPalette[v][w];
|
|
||||||
buffer[pos++] = (uInt16) myAvgPalette[v][w];
|
|
||||||
buffer[pos++] = (uInt16) myAvgPalette[v][w];
|
buffer[pos++] = (uInt16) myAvgPalette[v][w];
|
||||||
buffer[pos++] = (uInt16) myAvgPalette[v][w];
|
buffer[pos++] = (uInt16) myAvgPalette[v][w];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
screenofsY += myScreen->w;
|
||||||
|
}
|
||||||
bufofsY += width;
|
bufofsY += width;
|
||||||
screenofsY += myScreen->pitch/2;
|
|
||||||
}
|
}
|
||||||
*/
|
break; // kPhosphor_16
|
||||||
break;
|
}
|
||||||
|
|
||||||
|
case kPhosphor_24:
|
||||||
|
{
|
||||||
|
// FIXME - implement 24 bit mode
|
||||||
|
#if 0
|
||||||
|
// Since phosphor mode updates the whole screen,
|
||||||
|
// we might as well use SDL_Flip (see postFrameUpdate)
|
||||||
|
myUseDirtyRects = false;
|
||||||
|
SDL_Rect temp;
|
||||||
|
temp.x = temp.y = temp.w = temp.h = 0;
|
||||||
|
myRectList->add(&temp);
|
||||||
|
|
||||||
|
uInt16* buffer = (uInt16*)myScreen->pixels;
|
||||||
|
uInt32 bufofsY = 0;
|
||||||
|
uInt32 screenofsY = 0;
|
||||||
|
for(uInt32 y = 0; y < height; ++y )
|
||||||
|
{
|
||||||
|
uInt32 ystride = theZoomLevel;
|
||||||
|
while(ystride--)
|
||||||
|
{
|
||||||
|
uInt32 pos = screenofsY;
|
||||||
|
for(uInt32 x = 0; x < width; ++x )
|
||||||
|
{
|
||||||
|
const uInt32 bufofs = bufofsY + x;
|
||||||
|
uInt32 xstride = theZoomLevel;
|
||||||
|
|
||||||
|
uInt8 v = currentFrame[bufofs];
|
||||||
|
uInt8 w = previousFrame[bufofs];
|
||||||
|
|
||||||
|
while(xstride--)
|
||||||
|
{
|
||||||
|
buffer[pos++] = (uInt16) myAvgPalette[v][w];
|
||||||
|
buffer[pos++] = (uInt16) myAvgPalette[v][w];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
screenofsY += myScreen->w;
|
||||||
|
}
|
||||||
|
bufofsY += width;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
break; // kPhosphor_24
|
||||||
|
}
|
||||||
|
|
||||||
|
case kPhosphor_32:
|
||||||
|
{
|
||||||
|
// Since phosphor mode updates the whole screen,
|
||||||
|
// we might as well use SDL_Flip (see postFrameUpdate)
|
||||||
|
myUseDirtyRects = false;
|
||||||
|
SDL_Rect temp;
|
||||||
|
temp.x = temp.y = temp.w = temp.h = 0;
|
||||||
|
myRectList->add(&temp);
|
||||||
|
|
||||||
|
uInt32* buffer = (uInt32*)myScreen->pixels;
|
||||||
|
uInt32 bufofsY = 0;
|
||||||
|
uInt32 screenofsY = 0;
|
||||||
|
for(uInt32 y = 0; y < height; ++y )
|
||||||
|
{
|
||||||
|
uInt32 ystride = theZoomLevel;
|
||||||
|
while(ystride--)
|
||||||
|
{
|
||||||
|
uInt32 pos = screenofsY;
|
||||||
|
for(uInt32 x = 0; x < width; ++x )
|
||||||
|
{
|
||||||
|
const uInt32 bufofs = bufofsY + x;
|
||||||
|
uInt32 xstride = theZoomLevel;
|
||||||
|
|
||||||
|
uInt8 v = currentFrame[bufofs];
|
||||||
|
uInt8 w = previousFrame[bufofs];
|
||||||
|
|
||||||
|
while(xstride--)
|
||||||
|
{
|
||||||
|
buffer[pos++] = (uInt32) myAvgPalette[v][w];
|
||||||
|
buffer[pos++] = (uInt32) myAvgPalette[v][w];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
screenofsY += myScreen->w;
|
||||||
|
}
|
||||||
|
bufofsY += width;
|
||||||
|
}
|
||||||
|
break; // kPhosphor_32
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -557,12 +617,25 @@ void FrameBufferSoft::enablePhosphor(bool enable)
|
||||||
myPhosphorBlend = myOSystem->settings().getInt("ppblend");
|
myPhosphorBlend = myOSystem->settings().getInt("ppblend");
|
||||||
|
|
||||||
if(myUsePhosphor)
|
if(myUsePhosphor)
|
||||||
myRenderType = kPhosphor2x_16;
|
{
|
||||||
|
switch(myScreen->format->BitsPerPixel)
|
||||||
|
{
|
||||||
|
case 16:
|
||||||
|
myRenderType = kPhosphor_16;
|
||||||
|
break;
|
||||||
|
case 24:
|
||||||
|
myRenderType = kPhosphor_24;
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
myRenderType = kPhosphor_32;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
myRenderType = kSoftZoom; // What else should we do here?
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
myRenderType = kSoftZoom;
|
myRenderType = kSoftZoom;
|
||||||
|
|
||||||
cerr << "phosphor effect: " << (myUsePhosphor ? "yes" : "no") << endl
|
|
||||||
<< "phosphor amount: " << myPhosphorBlend << endl << endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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.27 2006-01-11 20:28:06 stephena Exp $
|
// $Id: FrameBufferSoft.hxx,v 1.28 2006-01-12 16:23:36 stephena Exp $
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#ifndef FRAMEBUFFER_SOFT_HXX
|
#ifndef FRAMEBUFFER_SOFT_HXX
|
||||||
|
@ -35,7 +35,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.27 2006-01-11 20:28:06 stephena Exp $
|
@version $Id: FrameBufferSoft.hxx,v 1.28 2006-01-12 16:23:36 stephena Exp $
|
||||||
*/
|
*/
|
||||||
class FrameBufferSoft : public FrameBuffer
|
class FrameBufferSoft : public FrameBuffer
|
||||||
{
|
{
|
||||||
|
@ -201,18 +201,9 @@ class FrameBufferSoft : public FrameBuffer
|
||||||
private:
|
private:
|
||||||
enum RenderType {
|
enum RenderType {
|
||||||
kSoftZoom,
|
kSoftZoom,
|
||||||
kPhosphor1x_16,
|
kPhosphor_16,
|
||||||
kPhosphor2x_16,
|
kPhosphor_24,
|
||||||
kPhosphor3x_16,
|
kPhosphor_32
|
||||||
kPhosphor4x_16,
|
|
||||||
kPhosphor1x_24,
|
|
||||||
kPhosphor2x_24,
|
|
||||||
kPhosphor3x_24,
|
|
||||||
kPhosphor4x_24,
|
|
||||||
kPhosphor1x_32,
|
|
||||||
kPhosphor2x_32,
|
|
||||||
kPhosphor3x_32,
|
|
||||||
kPhosphor4x_32,
|
|
||||||
};
|
};
|
||||||
RenderType myRenderType;
|
RenderType myRenderType;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue