diff --git a/stella/src/gp2x/FrameBufferGP2X.cxx b/stella/src/gp2x/FrameBufferGP2X.cxx index 076598836..9c14bf297 100644 --- a/stella/src/gp2x/FrameBufferGP2X.cxx +++ b/stella/src/gp2x/FrameBufferGP2X.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: FrameBufferGP2X.cxx,v 1.7 2006-12-05 14:53:26 stephena Exp $ +// $Id: FrameBufferGP2X.cxx,v 1.8 2006-12-05 21:55:15 stephena Exp $ //============================================================================ #include @@ -23,44 +23,24 @@ #include "OSystem.hxx" #include "Font.hxx" #include "GuiUtils.hxx" -#include "RectList.hxx" #include "FrameBufferGP2X.hxx" -// Comment out entire line to test new rendering code -#define DIRTY_RECTS 1 - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - FrameBufferGP2X::FrameBufferGP2X(OSystem* osystem) : FrameBuffer(osystem), - myDirtyFlag(true), - myRectList(NULL), - myOverlayRectList(NULL) + myDirtyFlag(true) { } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - FrameBufferGP2X::~FrameBufferGP2X() { - delete myRectList; - delete myOverlayRectList; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool FrameBufferGP2X::initSubsystem() { - // Set up the rectangle list to be used in the dirty update - delete myRectList; - myRectList = new RectList(); - delete myOverlayRectList; - myOverlayRectList = new RectList(); - - if(!myRectList || !myOverlayRectList) - { - cerr << "ERROR: Unable to get memory for SDL rects" << endl; - return false; - } - // Create the screen return createScreen(); } @@ -89,6 +69,7 @@ bool FrameBufferGP2X::createScreen() // In software mode, the image and screen dimensions are always the same myImageDim = myScreenDim; + // The GP2X always uses a 16-bit hardware buffer myScreen = SDL_SetVideoMode(myScreenDim.w, myScreenDim.h, 16, mySDLFlags); if(myScreen == NULL) { @@ -96,13 +77,8 @@ bool FrameBufferGP2X::createScreen() return false; } myPitch = myScreen->pitch/2; - - // Erase old rects, since they've probably been scaled for - // a different sized screen - myRectList->start(); - myOverlayRectList->start(); - myDirtyFlag = true; + return true; } @@ -122,143 +98,6 @@ void FrameBufferGP2X::drawMediaSource() if(!myUsePhosphor) { -#ifdef DIRTY_RECTS - 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 are still active - // from the previous scanlines we have processed - Rectangle* activeRectangles = rectangles[1]; - - // 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) - { - 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) - { - // 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 << 1; - temp.y = active.y; - temp.w = active.width << 1; - temp.h = active.height; - - myRectList->add(&temp); - SDL_FillRect(myScreen, &temp, myDefPalette[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 << 1; - temp.y = active.y; - temp.w = active.width << 1; - temp.h = active.height; - - myRectList->add(&temp); - SDL_FillRect(myScreen, &temp, myDefPalette[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 << 1; - temp.y = active.y; - temp.w = active.width << 1; - temp.h = active.height; - - myRectList->add(&temp); - SDL_FillRect(myScreen, &temp, myDefPalette[active.color]); - } -#else for(uInt32 y = 0; y < height; ++y ) { uInt32 pos = screenofsY; @@ -281,7 +120,6 @@ void FrameBufferGP2X::drawMediaSource() bufofsY += width; screenofsY += myPitch; } -#endif } else { @@ -310,14 +148,6 @@ void FrameBufferGP2X::drawMediaSource() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void FrameBufferGP2X::preFrameUpdate() { - // Start a new rectlist on each display update - myRectList->start(); - - // Add all previous overlay rects, then erase - SDL_Rect* dirtyOverlayRects = myOverlayRectList->rects(); - for(unsigned int i = 0; i < myOverlayRectList->numRects(); ++i) - myRectList->add(&dirtyOverlayRects[i]); - myOverlayRectList->start(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -326,7 +156,6 @@ void FrameBufferGP2X::postFrameUpdate() if(myDirtyFlag) { SDL_Flip(myScreen); - myRectList->start(); myDirtyFlag = false; } } @@ -476,20 +305,8 @@ void FrameBufferGP2X::translateCoords(Int32* x, Int32* y) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void FrameBufferGP2X::addDirtyRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h) { - // We may entirely remove the RectList, since it might be faster to just - // flip the screen (since it's a hardware buffer) + // We're using a hardware buffer; just indicate that the buffer is dirty myDirtyFlag = true; - - // Add a dirty rect to the overlay rectangle list - // They will actually be added to the main rectlist in preFrameUpdate() - // TODO - intelligent merging of rectangles, to avoid overlap - SDL_Rect temp; - temp.x = x; - temp.y = y; - temp.w = w; - temp.h = h; - - myOverlayRectList->add(&temp); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/stella/src/gp2x/FrameBufferGP2X.hxx b/stella/src/gp2x/FrameBufferGP2X.hxx index f17d1eed7..bb1ee57fd 100644 --- a/stella/src/gp2x/FrameBufferGP2X.hxx +++ b/stella/src/gp2x/FrameBufferGP2X.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: FrameBufferGP2X.hxx,v 1.4 2006-12-04 19:43:26 stephena Exp $ +// $Id: FrameBufferGP2X.hxx,v 1.5 2006-12-05 21:55:15 stephena Exp $ //============================================================================ #ifndef FRAMEBUFFER_GP2X_HXX @@ -23,7 +23,6 @@ class OSystem; class GUI::Font; -class RectList; #include "bspf.hxx" #include "FrameBuffer.hxx" @@ -33,7 +32,7 @@ class RectList; This class implements an SDL hardware framebuffer for the GP2X device. @author Stephen Anthony - @version $Id: FrameBufferGP2X.hxx,v 1.4 2006-12-04 19:43:26 stephena Exp $ + @version $Id: FrameBufferGP2X.hxx,v 1.5 2006-12-05 21:55:15 stephena Exp $ */ class FrameBufferGP2X : public FrameBuffer { @@ -212,14 +211,11 @@ class FrameBufferGP2X : public FrameBuffer virtual void showCursor(bool show); private: + // Indicates that the buffer is dirty, and should be redrawn/flipped bool myDirtyFlag; + + // Pitch (in bytes) of the current screen int myPitch; - - // Used in the dirty update of the SDL surface - RectList* myRectList; - - // Used in the dirty update of the overlay surface - RectList* myOverlayRectList; }; #endif