Yet more upheaval of the FrameBuffer/surface code. Moved most of the

functionality of FBSurfaceUI into FBSurface directly, since there was
absolutely no need of the SDL-specific code to know about underlying
FrameBuffer-specific stuff.  This makes a clear separation between
SDL and the core code, making porting easier in the future.  As a
result, renamed FBSurfaceUI as FBSurfaceSDL2.

Eventually, FBSurfaceTIA will disappear completely, being integrated
into FBSurface and FBSurfaceSDL2.  Again, the logic for drawing the
TIA and using Blargg, etc has absolutely no place in SDL-specific
areas of the code.

When this conversion is complete, I see FrameBufferSDL2 and FBSurfaceSDL2
as being thin wrappers around SDL-specific functions that simply push
pixel data to the video system.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2880 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2014-05-02 13:17:24 +00:00
parent 4654975341
commit 3914b15e9b
10 changed files with 155 additions and 145 deletions

View File

@ -18,11 +18,12 @@
//============================================================================
#include "Font.hxx"
#include "FBSurfaceUI.hxx"
#include "FBSurfaceSDL2.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FBSurfaceUI::FBSurfaceUI(FrameBufferSDL2& buffer, uInt32 width, uInt32 height)
: myFB(buffer),
FBSurfaceSDL2::FBSurfaceSDL2(FrameBufferSDL2& buffer, uInt32 width, uInt32 height)
: FBSurface(buffer.myDefPalette),
myFB(buffer),
mySurface(NULL),
myTexture(NULL),
mySurfaceIsDirty(true)
@ -37,6 +38,7 @@ FBSurfaceUI::FBSurfaceUI(FrameBufferSDL2& buffer, uInt32 width, uInt32 height)
mySrc.w = myDst.w = width;
mySrc.h = myDst.h = height;
myPixels = (uInt32*) mySurface->pixels;
myPitch = mySurface->pitch / pf->BytesPerPixel;
// To generate texture
@ -44,7 +46,7 @@ FBSurfaceUI::FBSurfaceUI(FrameBufferSDL2& buffer, uInt32 width, uInt32 height)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FBSurfaceUI::~FBSurfaceUI()
FBSurfaceSDL2::~FBSurfaceSDL2()
{
if(mySurface)
SDL_FreeSurface(mySurface);
@ -53,26 +55,7 @@ FBSurfaceUI::~FBSurfaceUI()
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurfaceUI::hLine(uInt32 x, uInt32 y, uInt32 x2, uInt32 color)
{
uInt32* buffer = (uInt32*) mySurface->pixels + y * myPitch + x;
while(x++ <= x2)
*buffer++ = (uInt32) myFB.myDefPalette[color];
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurfaceUI::vLine(uInt32 x, uInt32 y, uInt32 y2, uInt32 color)
{
uInt32* buffer = (uInt32*) mySurface->pixels + y * myPitch + x;
while(y++ <= y2)
{
*buffer = (uInt32) myFB.myDefPalette[color];
buffer += myPitch;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurfaceUI::fillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h, uInt32 color)
void FBSurfaceSDL2::fillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h, uInt32 color)
{
// Fill the rectangle
SDL_Rect tmp;
@ -84,84 +67,9 @@ void FBSurfaceUI::fillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h, uInt32 color)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurfaceUI::drawChar(const GUI::Font& font, uInt8 chr,
uInt32 tx, uInt32 ty, uInt32 color)
void FBSurfaceSDL2::drawSurface(const FBSurface* surface, uInt32 tx, uInt32 ty)
{
const FontDesc& desc = font.desc();
// If this character is not included in the font, use the default char.
if(chr < desc.firstchar || chr >= desc.firstchar + desc.size)
{
if (chr == ' ') return;
chr = desc.defaultchar;
}
chr -= desc.firstchar;
// Get the bounding box of the character
int bbw, bbh, bbx, bby;
if(!desc.bbx)
{
bbw = desc.fbbw;
bbh = desc.fbbh;
bbx = desc.fbbx;
bby = desc.fbby;
}
else
{
bbw = desc.bbx[chr].w;
bbh = desc.bbx[chr].h;
bbx = desc.bbx[chr].x;
bby = desc.bbx[chr].y;
}
const uInt16* tmp = desc.bits + (desc.offset ? desc.offset[chr] : (chr * desc.fbbh));
uInt32* buffer = (uInt32*) mySurface->pixels +
(ty + desc.ascent - bby - bbh) * myPitch +
tx + bbx;
for(int y = 0; y < bbh; y++)
{
const uInt16 ptr = *tmp++;
uInt16 mask = 0x8000;
for(int x = 0; x < bbw; x++, mask >>= 1)
if(ptr & mask)
buffer[x] = (uInt32) myFB.myDefPalette[color];
buffer += myPitch;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurfaceUI::drawBitmap(uInt32* bitmap, uInt32 tx, uInt32 ty,
uInt32 color, uInt32 h)
{
uInt32* buffer = (uInt32*) mySurface->pixels + ty * myPitch + tx;
for(uInt32 y = 0; y < h; ++y)
{
uInt32 mask = 0xF0000000;
for(uInt32 x = 0; x < 8; ++x, mask >>= 4)
if(bitmap[y] & mask)
buffer[x] = (uInt32) myFB.myDefPalette[color];
buffer += myPitch;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurfaceUI::drawPixels(uInt32* data, uInt32 tx, uInt32 ty, uInt32 numpixels)
{
uInt32* buffer = (uInt32*) mySurface->pixels + ty * myPitch + tx;
for(uInt32 i = 0; i < numpixels; ++i)
*buffer++ = (uInt32) data[i];
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurfaceUI::drawSurface(const FBSurface* surface, uInt32 tx, uInt32 ty)
{
const FBSurfaceUI* s = (const FBSurfaceUI*) surface;
const FBSurfaceSDL2* s = (const FBSurfaceSDL2*) surface;
SDL_Rect dst;
dst.x = tx;
@ -173,28 +81,28 @@ void FBSurfaceUI::drawSurface(const FBSurface* surface, uInt32 tx, uInt32 ty)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurfaceUI::addDirtyRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h)
void FBSurfaceSDL2::addDirtyRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h)
{
// It's faster to just update the entire (hardware) surface
mySurfaceIsDirty = true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurfaceUI::getPos(uInt32& x, uInt32& y) const
void FBSurfaceSDL2::getPos(uInt32& x, uInt32& y) const
{
x = myDst.x;
y = myDst.y;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurfaceUI::setPos(uInt32 x, uInt32 y)
void FBSurfaceSDL2::setPos(uInt32 x, uInt32 y)
{
myDst.x = x;
myDst.y = y;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurfaceUI::setWidth(uInt32 w)
void FBSurfaceSDL2::setWidth(uInt32 w)
{
// This method can't be used with 'scaled' surface (aka TIA surfaces)
// That shouldn't really matter, though, as all the UI stuff isn't scaled,
@ -204,7 +112,7 @@ void FBSurfaceUI::setWidth(uInt32 w)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurfaceUI::setHeight(uInt32 h)
void FBSurfaceSDL2::setHeight(uInt32 h)
{
// This method can't be used with 'scaled' surface (aka TIA surfaces)
// That shouldn't really matter, though, as all the UI stuff isn't scaled,
@ -214,14 +122,14 @@ void FBSurfaceUI::setHeight(uInt32 h)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurfaceUI::translateCoords(Int32& x, Int32& y) const
void FBSurfaceSDL2::translateCoords(Int32& x, Int32& y) const
{
x -= myDst.x;
y -= myDst.y;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurfaceUI::update()
void FBSurfaceSDL2::update()
{
if(mySurfaceIsDirty)
{
@ -239,13 +147,13 @@ void FBSurfaceUI::update()
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurfaceUI::invalidate()
void FBSurfaceSDL2::invalidate()
{
SDL_FillRect(mySurface, NULL, 0);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurfaceUI::free()
void FBSurfaceSDL2::free()
{
if(myTexture)
{
@ -255,7 +163,7 @@ void FBSurfaceUI::free()
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurfaceUI::reload()
void FBSurfaceSDL2::reload()
{
// Re-create texture; the underlying SDL_Surface is fine as-is
myTexture = SDL_CreateTexture(myFB.myRenderer,

View File

@ -17,8 +17,8 @@
// $Id$
//============================================================================
#ifndef FB_SURFACE_UI_HXX
#define FB_SURFACE_UI_HXX
#ifndef FBSURFACE_SDL2_HXX
#define FBSURFACE_SDL2_HXX
#include "bspf.hxx"
#include "FrameBufferSDL2.hxx"
@ -29,21 +29,19 @@
@author Stephen Anthony
*/
class FBSurfaceUI : public FBSurface
class FBSurfaceSDL2 : public FBSurface
{
friend class FrameBufferSDL2;
public:
FBSurfaceUI(FrameBufferSDL2& buffer, uInt32 width, uInt32 height);
virtual ~FBSurfaceUI();
FBSurfaceSDL2(FrameBufferSDL2& buffer, uInt32 width, uInt32 height);
virtual ~FBSurfaceSDL2();
// Normal surfaces need all drawing primitives
void hLine(uInt32 x, uInt32 y, uInt32 x2, uInt32 color);
void vLine(uInt32 x, uInt32 y, uInt32 y2, uInt32 color);
// Only some of them use SDL-specific code; the rest are defined
// in the parent FBSurface class
//
void fillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h, uInt32 color);
void drawChar(const GUI::Font& font, uInt8 c, uInt32 x, uInt32 y, uInt32 color);
void drawBitmap(uInt32* bitmap, uInt32 x, uInt32 y, uInt32 color, uInt32 h = 8);
void drawPixels(uInt32* data, uInt32 x, uInt32 y, uInt32 numpixels);
void drawSurface(const FBSurface* surface, uInt32 x, uInt32 y);
void addDirtyRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h);
void getPos(uInt32& x, uInt32& y) const;
@ -66,7 +64,6 @@ class FBSurfaceUI : public FBSurface
SDL_Rect mySrc, myDst;
bool mySurfaceIsDirty;
uInt32 myPitch;
};
#endif

View File

@ -26,7 +26,8 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FBSurfaceTIA::FBSurfaceTIA(FrameBufferSDL2& buffer)
: myFB(buffer),
: FBSurface(buffer.myDefPalette),
myFB(buffer),
mySurface(NULL),
myTexture(NULL),
myScanlines(NULL),

View File

@ -30,7 +30,7 @@
#include "Settings.hxx"
#include "TIA.hxx"
#include "FBSurfaceUI.hxx"
#include "FBSurfaceSDL2.hxx"
#include "FBSurfaceTIA.hxx"
#include "FrameBufferSDL2.hxx"
@ -55,7 +55,7 @@ FrameBufferSDL2::FrameBufferSDL2(OSystem* osystem)
}
// We need a pixel format for palette value calculations
// It's done this way (vs directly accessing a FBSurfaceUI object)
// It's done this way (vs directly accessing a FBSurfaceSDL2 object)
// since the structure may be needed before any FBSurface's have
// been created
myPixelFormat = SDL_AllocFormat(SDL_PIXELFORMAT_ARGB8888);
@ -338,7 +338,7 @@ void FrameBufferSDL2::setTIAPalette(const uInt32* palette)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FBSurface* FrameBufferSDL2::createSurface(int w, int h) const
{
return new FBSurfaceUI((FrameBufferSDL2&)*this, w, h);
return new FBSurfaceSDL2((FrameBufferSDL2&)*this, w, h);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -24,7 +24,7 @@
#include <SDL_opengl.h>
class OSystem;
class FBSurfaceUI;
class FBSurfaceSDL2;
class FBSurfaceTIA;
class TIA;
@ -40,7 +40,7 @@ class TIA;
*/
class FrameBufferSDL2 : public FrameBuffer
{
friend class FBSurfaceUI;
friend class FBSurfaceSDL2;
friend class FBSurfaceTIA;
public:

View File

@ -5,7 +5,7 @@ MODULE_OBJS := \
src/common/Base.o \
src/common/EventHandlerSDL2.o \
src/common/FrameBufferSDL2.o \
src/common/FBSurfaceUI.o \
src/common/FBSurfaceSDL2.o \
src/common/FBSurfaceTIA.o \
src/common/SoundSDL2.o \
src/common/FSNodeZIP.o \

View File

@ -17,8 +17,109 @@
// $Id$
//============================================================================
#include "FrameBuffer.hxx"
#include "FBSurface.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FBSurface::FBSurface(const uInt32* palette)
: myPixels(NULL),
myPitch(0),
myPalette(palette)
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurface::hLine(uInt32 x, uInt32 y, uInt32 x2, uInt32 color)
{
uInt32* buffer = myPixels + y * myPitch + x;
while(x++ <= x2)
*buffer++ = (uInt32) myPalette[color];
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurface::vLine(uInt32 x, uInt32 y, uInt32 y2, uInt32 color)
{
uInt32* buffer = (uInt32*) myPixels + y * myPitch + x;
while(y++ <= y2)
{
*buffer = (uInt32) myPalette[color];
buffer += myPitch;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurface::drawChar(const GUI::Font& font, uInt8 chr,
uInt32 tx, uInt32 ty, uInt32 color)
{
const FontDesc& desc = font.desc();
// If this character is not included in the font, use the default char.
if(chr < desc.firstchar || chr >= desc.firstchar + desc.size)
{
if (chr == ' ') return;
chr = desc.defaultchar;
}
chr -= desc.firstchar;
// Get the bounding box of the character
int bbw, bbh, bbx, bby;
if(!desc.bbx)
{
bbw = desc.fbbw;
bbh = desc.fbbh;
bbx = desc.fbbx;
bby = desc.fbby;
}
else
{
bbw = desc.bbx[chr].w;
bbh = desc.bbx[chr].h;
bbx = desc.bbx[chr].x;
bby = desc.bbx[chr].y;
}
const uInt16* tmp = desc.bits + (desc.offset ? desc.offset[chr] : (chr * desc.fbbh));
uInt32* buffer = myPixels + (ty + desc.ascent - bby - bbh) * myPitch + tx + bbx;
for(int y = 0; y < bbh; y++)
{
const uInt16 ptr = *tmp++;
uInt16 mask = 0x8000;
for(int x = 0; x < bbw; x++, mask >>= 1)
if(ptr & mask)
buffer[x] = (uInt32) myPalette[color];
buffer += myPitch;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurface::drawBitmap(uInt32* bitmap, uInt32 tx, uInt32 ty,
uInt32 color, uInt32 h)
{
uInt32* buffer = myPixels + ty * myPitch + tx;
for(uInt32 y = 0; y < h; ++y)
{
uInt32 mask = 0xF0000000;
for(uInt32 x = 0; x < 8; ++x, mask >>= 4)
if(bitmap[y] & mask)
buffer[x] = (uInt32) myPalette[color];
buffer += myPitch;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurface::drawPixels(uInt32* data, uInt32 tx, uInt32 ty, uInt32 numpixels)
{
uInt32* buffer = myPixels + ty * myPitch + tx;
for(uInt32 i = 0; i < numpixels; ++i)
*buffer++ = (uInt32) data[i];
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurface::box(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
uInt32 colorA, uInt32 colorB)

View File

@ -20,6 +20,8 @@
#ifndef FBSURFACE_HXX
#define FBSURFACE_HXX
class FrameBuffer;
#include "bspf.hxx"
#include "Font.hxx"
@ -52,7 +54,7 @@ class FBSurface
/**
Creates a new FBSurface object
*/
FBSurface() { }
FBSurface(const uInt32* palette);
/**
Destructor
@ -67,7 +69,7 @@ class FBSurface
@param x2 The second x coordinate
@param color The color of the line
*/
virtual void hLine(uInt32 x, uInt32 y, uInt32 x2, uInt32 color) { }
virtual void hLine(uInt32 x, uInt32 y, uInt32 x2, uInt32 color);
/**
This method should be called to draw a vertical line.
@ -77,7 +79,7 @@ class FBSurface
@param y2 The second y coordinate
@param color The color of the line
*/
virtual void vLine(uInt32 x, uInt32 y, uInt32 y2, uInt32 color) { }
virtual void vLine(uInt32 x, uInt32 y, uInt32 y2, uInt32 color);
/**
This method should be called to draw a filled rectangle.
@ -101,7 +103,7 @@ class FBSurface
@param color The color of the character
*/
virtual void drawChar(const GUI::Font& font, uInt8 c, uInt32 x, uInt32 y,
uInt32 color) { }
uInt32 color);
/**
This method should be called to draw the bitmap image.
@ -113,7 +115,7 @@ class FBSurface
@param h The height of the data image
*/
virtual void drawBitmap(uInt32* bitmap, uInt32 x, uInt32 y, uInt32 color,
uInt32 h = 8) { }
uInt32 h = 8);
/**
This method should be called to convert and copy a given row of pixel
@ -124,7 +126,7 @@ class FBSurface
@param row The row of the surface the data should be placed in
@param rowbytes The number of bytes in row of 'data'
*/
virtual void drawPixels(uInt32* data, uInt32 x, uInt32 y, uInt32 numpixels) { }
virtual void drawPixels(uInt32* data, uInt32 x, uInt32 y, uInt32 numpixels);
/**
This method should be called copy the contents of the given
@ -252,11 +254,12 @@ class FBSurface
int deltax = 0, bool useEllipsis = true);
protected:
/**
This method answers the current position of the surface.
*/
// virtual void getBufferPtr(uInt32& x, uInt32& y) const = 0;
// These are also used by any derived FBSurface classes
uInt32* myPixels;
uInt32 myPitch;
private:
const uInt32* myPalette;
};
#endif

View File

@ -221,7 +221,7 @@
<ItemGroup>
<ClCompile Include="..\common\Base.cxx" />
<ClCompile Include="..\common\EventHandlerSDL2.cxx" />
<ClCompile Include="..\common\FBSurfaceUI.cxx" />
<ClCompile Include="..\common\FBSurfaceSDL2.cxx" />
<ClCompile Include="..\common\FBSurfaceTIA.cxx" />
<ClCompile Include="..\common\FrameBufferSDL2.cxx" />
<ClCompile Include="..\common\FSNodeZIP.cxx" />
@ -464,7 +464,7 @@
<ClInclude Include="..\common\Base.hxx" />
<ClInclude Include="..\common\bspf.hxx" />
<ClInclude Include="..\common\EventHandlerSDL2.hxx" />
<ClInclude Include="..\common\FBSurfaceUI.hxx" />
<ClInclude Include="..\common\FBSurfaceSDL2.hxx" />
<ClInclude Include="..\common\FBSurfaceTIA.hxx" />
<ClInclude Include="..\common\FrameBufferSDL2.hxx" />
<ClInclude Include="..\common\FSNodeFactory.hxx" />
@ -726,4 +726,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>

View File

@ -564,7 +564,7 @@
<ClCompile Include="..\gui\LoggerDialog.cxx">
<Filter>Source Files\gui</Filter>
</ClCompile>
<ClCompile Include="..\common\FBSurfaceUI.cxx">
<ClCompile Include="..\common\FBSurfaceSDL2.cxx">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\common\FBSurfaceTIA.cxx">
@ -1298,7 +1298,7 @@
<ClInclude Include="..\gui\LoggerDialog.hxx">
<Filter>Header Files\gui</Filter>
</ClInclude>
<ClInclude Include="..\common\FBSurfaceUI.hxx">
<ClInclude Include="..\common\FBSurfaceSDL2.hxx">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\common\FBSurfaceTIA.hxx">
@ -1537,4 +1537,4 @@
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>
</Project>