diff --git a/stella/src/common/FrameBufferGL.cxx b/stella/src/common/FrameBufferGL.cxx index 46de9ea86..d65aba534 100644 --- a/stella/src/common/FrameBufferGL.cxx +++ b/stella/src/common/FrameBufferGL.cxx @@ -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 diff --git a/stella/src/common/FrameBufferSoft.cxx b/stella/src/common/FrameBufferSoft.cxx index 27d8a2580..bf9852da9 100644 --- a/stella/src/common/FrameBufferSoft.cxx +++ b/stella/src/common/FrameBufferSoft.cxx @@ -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 @@ -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; } diff --git a/stella/src/common/FrameBufferSoft.hxx b/stella/src/common/FrameBufferSoft.hxx index 8cf083033..5c0a6a20b 100644 --- a/stella/src/common/FrameBufferSoft.hxx +++ b/stella/src/common/FrameBufferSoft.hxx @@ -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 diff --git a/stella/src/emucore/FrameBuffer.cxx b/stella/src/emucore/FrameBuffer.cxx index 64cd5a4fe..9929ba451 100644 --- a/stella/src/emucore/FrameBuffer.cxx +++ b/stella/src/emucore/FrameBuffer.cxx @@ -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 @@ -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)