Starting to convert software mode to use the phosphor effect; it's almost

completely broken right now.  I *really* hate software buffers.  Why
can't everyone have hardware support for zoom and color depth (aka OpenGL)?


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@954 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2006-01-11 20:28:07 +00:00
parent 63275fc581
commit b4525b5ff7
4 changed files with 153 additions and 31 deletions

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: FrameBufferGL.cxx,v 1.46 2006-01-10 20:37:00 stephena Exp $
// $Id: FrameBufferGL.cxx,v 1.47 2006-01-11 20:28:06 stephena Exp $
//============================================================================
#ifdef DISPLAY_OPENGL
@ -241,7 +241,7 @@ void FrameBufferGL::drawMediaSource()
// 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()
theRedrawTIAIndicator = true;
myDirtyFlag = true;
// x << 1 is times 2 ( doubling width )
const uInt32 pos = screenofsY + (x << 1);
@ -249,9 +249,8 @@ void FrameBufferGL::drawMediaSource()
}
}
}
break;
case 1: // TODO - profile this, maybe we can get rid of mult's?
/*
for(y = 0; y < height; ++y )
{
const uInt32 bufofsY = y * width;
@ -263,10 +262,36 @@ void FrameBufferGL::drawMediaSource()
uInt8 v = currentFrame[bufofs];
uInt8 w = previousFrame[bufofs];
// 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()
theRedrawTIAIndicator = true;
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;
case 1:
// Phosphor mode always implies a dirty update,
// so we don't care about theRedrawTIAIndicator
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 )
{
const uInt32 bufofs = bufofsY + x;
uInt8 v = currentFrame[bufofs];
uInt8 w = previousFrame[bufofs];
// x << 1 is times 2 ( doubling width )
const uInt32 pos = screenofsY + (x << 1);
@ -285,7 +310,7 @@ void FrameBufferGL::preFrameUpdate()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferGL::postFrameUpdate()
{
if(theRedrawTIAIndicator || myDirtyFlag)
if(myDirtyFlag)
{
// Texturemap complete texture to surface so we have free scaling
// and antialiasing

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: FrameBufferSoft.cxx,v 1.40 2006-01-10 20:37:00 stephena Exp $
// $Id: FrameBufferSoft.cxx,v 1.41 2006-01-11 20:28:06 stephena Exp $
//============================================================================
#include <SDL.h>
@ -33,7 +33,8 @@
FrameBufferSoft::FrameBufferSoft(OSystem* osystem)
: FrameBuffer(osystem),
myRectList(NULL),
myOverlayRectList(NULL)
myOverlayRectList(NULL),
myRenderType(kSoftZoom)
{
}
@ -116,22 +117,26 @@ void FrameBufferSoft::drawMediaSource()
uInt32 width = mediasrc.width();
uInt32 height = mediasrc.height();
struct Rectangle
switch(myRenderType) // use switch/case, since we'll eventually have filters
{
uInt8 color;
uInt16 x, y, width, height;
} rectangles[2][160];
case kSoftZoom:
{
struct Rectangle
{
uInt8 color;
uInt16 x, y, width, height;
} rectangles[2][160];
// This array represents the rectangles that need displaying
// on the current scanline we're processing
Rectangle* currentRectangles = rectangles[0];
// This array represents the rectangles that need displaying
// on the current scanline we're processing
Rectangle* currentRectangles = rectangles[0];
// This array represents the rectangles that are still active
// from the previous scanlines we have processed
Rectangle* activeRectangles = rectangles[1];
// This array represents the rectangles that are still active
// from the previous scanlines we have processed
Rectangle* activeRectangles = rectangles[1];
// Indicates the number of active rectangles
uInt16 activeCount = 0;
// Indicates the number of active rectangles
uInt16 activeCount = 0;
// This update procedure requires theWidth to be a multiple of four.
// This is validated when the properties are loaded.
@ -253,6 +258,69 @@ void FrameBufferSoft::drawMediaSource()
myRectList->add(&temp);
SDL_FillRect(myScreen, &temp, myPalette[active.color]);
}
break; // case 0
}
case kPhosphor2x_16:
{
// 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;
int pixel;
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 x = 0; x < width; ++x)
{
const uInt32 bufofs = bufofsY + x;
uInt8 v = currentFrame[bufofs];
uInt8 w = previousFrame[bufofs];
// x << 1 is times 2 ( doubling width )
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];
}
bufofsY += width;
screenofsY += myScreen->pitch/2;
}
*/
break;
}
}
}
@ -485,9 +553,16 @@ void FrameBufferSoft::addDirtyRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferSoft::enablePhosphor(bool enable)
{
// FIXME - implement for software mode
// myUsePhosphor = enable;
// myPhosphorBlend = blend;
myUsePhosphor = enable;
myPhosphorBlend = myOSystem->settings().getInt("ppblend");
if(myUsePhosphor)
myRenderType = kPhosphor2x_16;
else
myRenderType = kSoftZoom;
cerr << "phosphor effect: " << (myUsePhosphor ? "yes" : "no") << endl
<< "phosphor amount: " << myPhosphorBlend << endl << endl;
}

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: FrameBufferSoft.hxx,v 1.26 2006-01-10 20:37:00 stephena Exp $
// $Id: FrameBufferSoft.hxx,v 1.27 2006-01-11 20:28:06 stephena Exp $
//============================================================================
#ifndef FRAMEBUFFER_SOFT_HXX
@ -35,7 +35,7 @@ class RectList;
This class implements an SDL software framebuffer.
@author Stephen Anthony
@version $Id: FrameBufferSoft.hxx,v 1.26 2006-01-10 20:37:00 stephena Exp $
@version $Id: FrameBufferSoft.hxx,v 1.27 2006-01-11 20:28:06 stephena Exp $
*/
class FrameBufferSoft : public FrameBuffer
{
@ -197,6 +197,24 @@ class FrameBufferSoft : public FrameBuffer
// Used in the dirty update of the overlay surface
RectList* myOverlayRectList;
private:
enum RenderType {
kSoftZoom,
kPhosphor1x_16,
kPhosphor2x_16,
kPhosphor3x_16,
kPhosphor4x_16,
kPhosphor1x_24,
kPhosphor2x_24,
kPhosphor3x_24,
kPhosphor4x_24,
kPhosphor1x_32,
kPhosphor2x_32,
kPhosphor3x_32,
kPhosphor4x_32,
};
RenderType myRenderType;
};
class RectList

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: FrameBuffer.cxx,v 1.72 2006-01-11 13:25:20 stephena Exp $
// $Id: FrameBuffer.cxx,v 1.73 2006-01-11 20:28:07 stephena Exp $
//============================================================================
#include <sstream>
@ -159,16 +159,20 @@ void FrameBuffer::update()
{
case EventHandler::S_EMULATE:
{
bool mediaSourceChanged = false;
// Draw changes to the mediasource
if(!myPauseStatus)
{
myOSystem->console().mediaSource().update();
if(myOSystem->eventHandler().frying())
myOSystem->console().fry();
mediaSourceChanged = true; // mediasource changed, so force an update
}
// We always draw the screen, even if the core is paused
drawMediaSource();
// Only update the screen if it's been invalidated
if(mediaSourceChanged || theRedrawTIAIndicator)
drawMediaSource();
// Draw any pending messages
if(myMessageTime > 0 && !myPauseStatus)