diff --git a/stella/src/common/FrameBufferGL.cxx b/stella/src/common/FrameBufferGL.cxx index d65aba534..9abe0697e 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.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 @@ -221,16 +221,16 @@ void FrameBufferGL::drawMediaSource() uInt16* buffer = (uInt16*) myTexture->pixels; // TODO - is this fast enough? - register uInt32 x, y; switch((int)myUsePhosphor) // use switch/case, since we'll eventually have filters { case 0: - for(y = 0; y < height; ++y ) + { + uInt32 bufofsY = 0; + uInt32 screenofsY = 0; + for(uInt32 y = 0; y < height; ++y ) { - const uInt32 bufofsY = y * width; - const uInt32 screenofsY = y * myTexture->w; - - for(x = 0; x < width; ++x ) + uInt32 pos = screenofsY; + for(uInt32 x = 0; x < width; ++x ) { const uInt32 bufofs = bufofsY + x; uInt8 v = currentFrame[bufofs]; @@ -243,62 +243,41 @@ void FrameBufferGL::drawMediaSource() // 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]; } + 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; + } 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 ) + 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; uInt8 v = currentFrame[bufofs]; uInt8 w = previousFrame[bufofs]; - // x << 1 is times 2 ( doubling width ) - const uInt32 pos = screenofsY + (x << 1); - buffer[pos] = buffer[pos+1] = (uInt16) myAvgPalette[v][w]; + buffer[pos++] = (uInt16) myAvgPalette[v][w]; + buffer[pos++] = (uInt16) myAvgPalette[v][w]; } + bufofsY += width; + screenofsY += myTexture->w; } break; + } } } @@ -495,11 +474,6 @@ void FrameBufferGL::enablePhosphor(bool enable) { myUsePhosphor = enable; myPhosphorBlend = myOSystem->settings().getInt("ppblend"); - -cerr << "phosphor effect: " << (myUsePhosphor ? "yes" : "no") << endl - << "phosphor amount: " << myPhosphorBlend << endl << endl; - - // FIXME - change rendering method } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/stella/src/common/FrameBufferSoft.cxx b/stella/src/common/FrameBufferSoft.cxx index bf9852da9..88064d2c1 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.41 2006-01-11 20:28:06 stephena Exp $ +// $Id: FrameBufferSoft.cxx,v 1.42 2006-01-12 16:23:36 stephena Exp $ //============================================================================ #include @@ -117,7 +117,7 @@ void FrameBufferSoft::drawMediaSource() uInt32 width = mediasrc.width(); 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: { @@ -138,76 +138,119 @@ void FrameBufferSoft::drawMediaSource() // 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. - for(uInt16 y = 0; y < height; ++y) - { - // Indicates the number of current rectangles - uInt16 currentCount = 0; - - // Look at four pixels at a time to see if anything has changed - uInt32* current = (uInt32*)(currentFrame); - uInt32* previous = (uInt32*)(previousFrame); - - for(uInt16 x = 0; x < width; x += 4, ++current, ++previous) - { - // Has something changed in this set of four pixels? - if((*current != *previous) || theRedrawTIAIndicator) + // This update procedure requires theWidth to be a multiple of four. + // This is validated when the properties are loaded. + for(uInt16 y = 0; y < height; ++y) { - uInt8* c = (uInt8*)current; - uInt8* p = (uInt8*)previous; + // Indicates the number of current rectangles + uInt16 currentCount = 0; - // Look at each of the bytes that make up the uInt32 - for(uInt16 i = 0; i < 4; ++i, ++c, ++p) + // Look at four pixels at a time to see if anything has changed + uInt32* current = (uInt32*)(currentFrame); + uInt32* previous = (uInt32*)(previousFrame); + + for(uInt16 x = 0; x < width; x += 4, ++current, ++previous) { - // See if this pixel has changed - if((*c != *p) || theRedrawTIAIndicator) + // Has something changed in this set of four pixels? + if((*current != *previous) || theRedrawTIAIndicator) { - // Can we extend a rectangle or do we have to create a new one? - if((currentCount != 0) && - (currentRectangles[currentCount - 1].color == *c) && - ((currentRectangles[currentCount - 1].x + - currentRectangles[currentCount - 1].width) == (x + i))) + uInt8* c = (uInt8*)current; + uInt8* p = (uInt8*)previous; + + // Look at each of the bytes that make up the uInt32 + for(uInt16 i = 0; i < 4; ++i, ++c, ++p) { - currentRectangles[currentCount - 1].width += 1; - } - else - { - currentRectangles[currentCount].x = x + i; - currentRectangles[currentCount].y = y; - currentRectangles[currentCount].width = 1; - currentRectangles[currentCount].height = 1; - currentRectangles[currentCount].color = *c; - currentCount++; + // See if this pixel has changed + if((*c != *p) || theRedrawTIAIndicator) + { + // Can we extend a rectangle or do we have to create a new one? + if((currentCount != 0) && + (currentRectangles[currentCount - 1].color == *c) && + ((currentRectangles[currentCount - 1].x + + currentRectangles[currentCount - 1].width) == (x + i))) + { + currentRectangles[currentCount - 1].width += 1; + } + else + { + currentRectangles[currentCount].x = x + i; + currentRectangles[currentCount].y = y; + currentRectangles[currentCount].width = 1; + currentRectangles[currentCount].height = 1; + currentRectangles[currentCount].color = *c; + currentCount++; + } + } } } } + + // Merge the active and current rectangles flushing any that are of no use + uInt16 activeIndex = 0; + + for(uInt16 t = 0; (t < currentCount) && (activeIndex < activeCount); ++t) + { + Rectangle& current = currentRectangles[t]; + Rectangle& active = activeRectangles[activeIndex]; + + // Can we merge the current rectangle with an active one? + if((current.x == active.x) && (current.width == active.width) && + (current.color == active.color)) + { + current.y = active.y; + current.height = active.height + 1; + + ++activeIndex; + } + // Is it impossible for this active rectangle to be merged? + else if(current.x >= active.x) + { + // Flush the active rectangle + SDL_Rect temp; + + temp.x = active.x * screenMultiple << 1; + temp.y = active.y * screenMultiple; + temp.w = active.width * screenMultiple << 1; + temp.h = active.height * screenMultiple; + + myRectList->add(&temp); + SDL_FillRect(myScreen, &temp, myPalette[active.color]); + + ++activeIndex; + } + } + + // Flush any remaining active rectangles + for(uInt16 s = activeIndex; s < activeCount; ++s) + { + Rectangle& active = activeRectangles[s]; + + SDL_Rect temp; + temp.x = active.x * screenMultiple << 1; + temp.y = active.y * screenMultiple; + temp.w = active.width * screenMultiple << 1; + temp.h = active.height * screenMultiple; + + myRectList->add(&temp); + SDL_FillRect(myScreen, &temp, myPalette[active.color]); + } + + // We can now make the current rectangles into the active rectangles + Rectangle* tmp = currentRectangles; + currentRectangles = activeRectangles; + activeRectangles = tmp; + activeCount = currentCount; + + currentFrame += width; + previousFrame += width; } - } - // Merge the active and current rectangles flushing any that are of no use - uInt16 activeIndex = 0; - - for(uInt16 t = 0; (t < currentCount) && (activeIndex < activeCount); ++t) - { - Rectangle& current = currentRectangles[t]; - Rectangle& active = activeRectangles[activeIndex]; - - // Can we merge the current rectangle with an active one? - if((current.x == active.x) && (current.width == active.width) && - (current.color == active.color)) + // Flush any rectangles that are still active + for(uInt16 t = 0; t < activeCount; ++t) { - current.y = active.y; - current.height = active.height + 1; + Rectangle& active = activeRectangles[t]; - ++activeIndex; - } - // Is it impossible for this active rectangle to be merged? - else if(current.x >= active.x) - { - // Flush the active rectangle SDL_Rect temp; - temp.x = active.x * screenMultiple << 1; temp.y = active.y * screenMultiple; temp.w = active.width * screenMultiple << 1; @@ -215,55 +258,11 @@ void FrameBufferSoft::drawMediaSource() myRectList->add(&temp); SDL_FillRect(myScreen, &temp, myPalette[active.color]); - - ++activeIndex; } - } - - // Flush any remaining active rectangles - for(uInt16 s = activeIndex; s < activeCount; ++s) - { - Rectangle& active = activeRectangles[s]; - - SDL_Rect temp; - temp.x = active.x * screenMultiple << 1; - temp.y = active.y * screenMultiple; - temp.w = active.width * screenMultiple << 1; - temp.h = active.height * screenMultiple; - - myRectList->add(&temp); - SDL_FillRect(myScreen, &temp, myPalette[active.color]); - } - - // We can now make the current rectangles into the active rectangles - Rectangle* tmp = currentRectangles; - currentRectangles = activeRectangles; - activeRectangles = tmp; - activeCount = currentCount; - - currentFrame += width; - previousFrame += width; - } - - // Flush any rectangles that are still active - for(uInt16 t = 0; t < activeCount; ++t) - { - Rectangle& active = activeRectangles[t]; - - SDL_Rect temp; - temp.x = active.x * screenMultiple << 1; - temp.y = active.y * screenMultiple; - temp.w = active.width * screenMultiple << 1; - temp.h = active.height * screenMultiple; - - myRectList->add(&temp); - SDL_FillRect(myScreen, &temp, myPalette[active.color]); - } - break; // case 0 } - case kPhosphor2x_16: + case kPhosphor_16: { // Since phosphor mode updates the whole screen, // we might as well use SDL_Flip (see postFrameUpdate) @@ -273,53 +272,114 @@ void FrameBufferSoft::drawMediaSource() 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; + uInt32 bufofsY = 0; + uInt32 screenofsY = 0; for(uInt32 y = 0; y < height; ++y ) { - for(uInt32 x = 0; x < width; ++x) + uInt32 ystride = theZoomLevel; + while(ystride--) { - const uInt32 bufofs = bufofsY + x; - uInt8 v = currentFrame[bufofs]; - uInt8 w = previousFrame[bufofs]; + uInt32 pos = screenofsY; + for(uInt32 x = 0; x < width; ++x ) + { + const uInt32 bufofs = bufofsY + x; + uInt32 xstride = theZoomLevel; - // 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]; + 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; - screenofsY += myScreen->pitch/2; } -*/ - break; + break; // kPhosphor_16 + } + + 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"); 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 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 5c0a6a20b..032ab285e 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.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 @@ -35,7 +35,7 @@ class RectList; This class implements an SDL software framebuffer. @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 { @@ -201,18 +201,9 @@ class FrameBufferSoft : public FrameBuffer 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, + kPhosphor_16, + kPhosphor_24, + kPhosphor_32 }; RenderType myRenderType; };