mirror of https://github.com/stella-emu/stella.git
And so it begins. This is only symbolic ATM, but I've now killed
software rendering support. I've been wanting to do this for years, and finally the time has come. So for now, you need OpenGL for Stella to build and run. Expect major breakage over the next few months, as I port to SDL2. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2829 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
cda1e301e2
commit
a911a5b368
|
@ -1,860 +0,0 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2013 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id$
|
||||
//============================================================================
|
||||
|
||||
#include <sstream>
|
||||
#include <SDL.h>
|
||||
|
||||
#include "bspf.hxx"
|
||||
|
||||
#include "Console.hxx"
|
||||
#include "Font.hxx"
|
||||
#include "OSystem.hxx"
|
||||
#include "RectList.hxx"
|
||||
#include "Settings.hxx"
|
||||
#include "TIA.hxx"
|
||||
|
||||
#include "FrameBufferSoft.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
FrameBufferSoft::FrameBufferSoft(OSystem* osystem)
|
||||
: FrameBuffer(osystem),
|
||||
myZoomLevel(2),
|
||||
myRenderType(kSoftZoom_16),
|
||||
myTiaDirty(false),
|
||||
myInUIMode(false),
|
||||
myRectList(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
FrameBufferSoft::~FrameBufferSoft()
|
||||
{
|
||||
delete myRectList;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool FrameBufferSoft::initSubsystem(VideoMode& mode)
|
||||
{
|
||||
// Set up the rectangle list to be used in the dirty update
|
||||
delete myRectList;
|
||||
myRectList = new RectList();
|
||||
|
||||
if(!myRectList)
|
||||
{
|
||||
myOSystem->logMessage("ERROR: Unable to get memory for SDL rects", 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create the screen
|
||||
return setVidMode(mode);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string FrameBufferSoft::about() const
|
||||
{
|
||||
ostringstream buf;
|
||||
|
||||
buf << "Video rendering: Software mode" << endl << setfill('0')
|
||||
<< " Color: " << (int)myFormat->BitsPerPixel << " bit" << endl
|
||||
<< " Rmask = " << hex << setw(8) << (int)myFormat->Rmask
|
||||
<< ", Rshift = "<< dec << setw(2) << (int)myFormat->Rshift
|
||||
<< ", Rloss = " << dec << setw(2) << (int)myFormat->Rloss << endl
|
||||
<< " Gmask = " << hex << setw(8) << (int)myFormat->Gmask
|
||||
<< ", Gshift = "<< dec << setw(2) << (int)myFormat->Gshift
|
||||
<< ", Gloss = " << dec << setw(2) << (int)myFormat->Gloss << endl
|
||||
<< " Bmask = " << hex << setw(8) << (int)myFormat->Bmask
|
||||
<< ", Bshift = "<< dec << setw(2) << (int)myFormat->Bshift
|
||||
<< ", Bloss = " << dec << setw(2) << (int)myFormat->Bloss << endl;
|
||||
|
||||
return buf.str();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool FrameBufferSoft::setVidMode(VideoMode& mode)
|
||||
{
|
||||
// Make sure to clear the screen
|
||||
if(myScreen)
|
||||
{
|
||||
SDL_FillRect(myScreen, NULL, 0);
|
||||
SDL_UpdateRect(myScreen, 0, 0, 0, 0);
|
||||
}
|
||||
myScreen = SDL_SetVideoMode(mode.screen_w, mode.screen_h, 0, mySDLFlags);
|
||||
if(myScreen == NULL)
|
||||
{
|
||||
ostringstream buf;
|
||||
buf << "ERROR: Unable to open SDL window: " << SDL_GetError() << endl;
|
||||
myOSystem->logMessage(buf.str(), 0);
|
||||
return false;
|
||||
}
|
||||
myFormat = myScreen->format;
|
||||
myBytesPerPixel = myFormat->BytesPerPixel;
|
||||
|
||||
// Make sure the flags represent the current screen state
|
||||
mySDLFlags = myScreen->flags;
|
||||
|
||||
// Make sure drawTIA() knows which renderer to use
|
||||
switch(myBytesPerPixel)
|
||||
{
|
||||
case 2: // 16-bit
|
||||
myPitch = myScreen->pitch >> 1;
|
||||
myRenderType = myUsePhosphor ? kPhosphor_16 : kSoftZoom_16;
|
||||
break;
|
||||
case 3: // 24-bit
|
||||
myPitch = myScreen->pitch;
|
||||
myRenderType = myUsePhosphor ? kPhosphor_24 : kSoftZoom_24;
|
||||
break;
|
||||
case 4: // 32-bit
|
||||
myPitch = myScreen->pitch >> 2;
|
||||
myRenderType = myUsePhosphor ? kPhosphor_32 : kSoftZoom_32;
|
||||
break;
|
||||
}
|
||||
myBaseOffset = mode.image_y * myPitch + mode.image_x;
|
||||
|
||||
// If software mode can open the given screen, it will always be in the
|
||||
// requested format, or not at all; we only update mode when the screen
|
||||
// is successfully created
|
||||
mode.screen_w = myScreen->w;
|
||||
mode.screen_h = myScreen->h;
|
||||
myZoomLevel = mode.gfxmode.zoom;
|
||||
|
||||
// Erase old rects, since they've probably been scaled for
|
||||
// a different sized screen
|
||||
myRectList->start();
|
||||
|
||||
// Any previously allocated surfaces have probably changed as well,
|
||||
// so we should refresh them
|
||||
resetSurfaces();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferSoft::invalidate()
|
||||
{
|
||||
if(myScreen)
|
||||
SDL_FillRect(myScreen, NULL, 0);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferSoft::drawTIA(bool fullRedraw)
|
||||
{
|
||||
const TIA& tia = myOSystem->console().tia();
|
||||
|
||||
uInt8* currentFrame = tia.currentFrameBuffer();
|
||||
uInt8* previousFrame = tia.previousFrameBuffer();
|
||||
|
||||
uInt32 width = tia.width();
|
||||
uInt32 height = tia.height();
|
||||
|
||||
switch(myRenderType)
|
||||
{
|
||||
case kSoftZoom_16:
|
||||
{
|
||||
SDL_LockSurface(myScreen);
|
||||
uInt16* buffer = (uInt16*)myScreen->pixels + myBaseOffset;
|
||||
uInt32 bufofsY = 0;
|
||||
uInt32 screenofsY = 0;
|
||||
for(uInt32 y = 0; y < height; ++y)
|
||||
{
|
||||
uInt32 ystride = myZoomLevel;
|
||||
while(ystride--)
|
||||
{
|
||||
uInt32 pos = screenofsY;
|
||||
for(uInt32 x = 0; x < width; ++x)
|
||||
{
|
||||
const uInt32 bufofs = bufofsY + x;
|
||||
uInt32 xstride = myZoomLevel;
|
||||
|
||||
uInt8 v = currentFrame[bufofs];
|
||||
uInt8 w = previousFrame[bufofs];
|
||||
|
||||
if(v != w || fullRedraw)
|
||||
{
|
||||
while(xstride--)
|
||||
{
|
||||
buffer[pos++] = (uInt16) myDefPalette[v];
|
||||
buffer[pos++] = (uInt16) myDefPalette[v];
|
||||
}
|
||||
myTiaDirty = true;
|
||||
}
|
||||
else
|
||||
pos += xstride + xstride;
|
||||
}
|
||||
screenofsY += myPitch;
|
||||
}
|
||||
bufofsY += width;
|
||||
}
|
||||
SDL_UnlockSurface(myScreen);
|
||||
break; // kSoftZoom_16
|
||||
}
|
||||
|
||||
case kSoftZoom_24:
|
||||
{
|
||||
SDL_LockSurface(myScreen);
|
||||
uInt8* buffer = (uInt8*)myScreen->pixels + myBaseOffset;
|
||||
uInt32 bufofsY = 0;
|
||||
uInt32 screenofsY = 0;
|
||||
for(uInt32 y = 0; y < height; ++y)
|
||||
{
|
||||
uInt32 ystride = myZoomLevel;
|
||||
while(ystride--)
|
||||
{
|
||||
uInt32 pos = screenofsY;
|
||||
for(uInt32 x = 0; x < width; ++x)
|
||||
{
|
||||
const uInt32 bufofs = bufofsY + x;
|
||||
uInt32 xstride = myZoomLevel;
|
||||
|
||||
uInt8 v = currentFrame[bufofs];
|
||||
uInt8 w = previousFrame[bufofs];
|
||||
|
||||
if(v != w || fullRedraw)
|
||||
{
|
||||
uInt8 a = myDefPalette24[v][0],
|
||||
b = myDefPalette24[v][1],
|
||||
c = myDefPalette24[v][2];
|
||||
|
||||
while(xstride--)
|
||||
{
|
||||
buffer[pos++] = a; buffer[pos++] = b; buffer[pos++] = c;
|
||||
buffer[pos++] = a; buffer[pos++] = b; buffer[pos++] = c;
|
||||
}
|
||||
myTiaDirty = true;
|
||||
}
|
||||
else // try to eliminate multiply whereever possible
|
||||
pos += xstride + xstride + xstride + xstride + xstride + xstride;
|
||||
}
|
||||
screenofsY += myPitch;
|
||||
}
|
||||
bufofsY += width;
|
||||
}
|
||||
SDL_UnlockSurface(myScreen);
|
||||
break; // kSoftZoom_24
|
||||
}
|
||||
|
||||
case kSoftZoom_32:
|
||||
{
|
||||
SDL_LockSurface(myScreen);
|
||||
uInt32* buffer = (uInt32*)myScreen->pixels + myBaseOffset;
|
||||
uInt32 bufofsY = 0;
|
||||
uInt32 screenofsY = 0;
|
||||
for(uInt32 y = 0; y < height; ++y)
|
||||
{
|
||||
uInt32 ystride = myZoomLevel;
|
||||
while(ystride--)
|
||||
{
|
||||
uInt32 pos = screenofsY;
|
||||
for(uInt32 x = 0; x < width; ++x)
|
||||
{
|
||||
const uInt32 bufofs = bufofsY + x;
|
||||
uInt32 xstride = myZoomLevel;
|
||||
|
||||
uInt8 v = currentFrame[bufofs];
|
||||
uInt8 w = previousFrame[bufofs];
|
||||
|
||||
if(v != w || fullRedraw)
|
||||
{
|
||||
while(xstride--)
|
||||
{
|
||||
buffer[pos++] = (uInt32) myDefPalette[v];
|
||||
buffer[pos++] = (uInt32) myDefPalette[v];
|
||||
}
|
||||
myTiaDirty = true;
|
||||
}
|
||||
else
|
||||
pos += xstride + xstride;
|
||||
}
|
||||
screenofsY += myPitch;
|
||||
}
|
||||
bufofsY += width;
|
||||
}
|
||||
SDL_UnlockSurface(myScreen);
|
||||
break; // kSoftZoom_32
|
||||
}
|
||||
|
||||
case kPhosphor_16:
|
||||
{
|
||||
SDL_LockSurface(myScreen);
|
||||
uInt16* buffer = (uInt16*)myScreen->pixels + myBaseOffset;
|
||||
uInt32 bufofsY = 0;
|
||||
uInt32 screenofsY = 0;
|
||||
for(uInt32 y = 0; y < height; ++y)
|
||||
{
|
||||
uInt32 ystride = myZoomLevel;
|
||||
while(ystride--)
|
||||
{
|
||||
uInt32 pos = screenofsY;
|
||||
for(uInt32 x = 0; x < width; ++x)
|
||||
{
|
||||
const uInt32 bufofs = bufofsY + x;
|
||||
uInt32 xstride = myZoomLevel;
|
||||
|
||||
uInt8 v = currentFrame[bufofs];
|
||||
uInt8 w = previousFrame[bufofs];
|
||||
|
||||
while(xstride--)
|
||||
{
|
||||
buffer[pos++] = (uInt16) myAvgPalette[v][w];
|
||||
buffer[pos++] = (uInt16) myAvgPalette[v][w];
|
||||
}
|
||||
}
|
||||
screenofsY += myPitch;
|
||||
}
|
||||
bufofsY += width;
|
||||
}
|
||||
SDL_UnlockSurface(myScreen);
|
||||
myTiaDirty = true;
|
||||
break; // kPhosphor_16
|
||||
}
|
||||
|
||||
case kPhosphor_24:
|
||||
{
|
||||
SDL_LockSurface(myScreen);
|
||||
uInt8* buffer = (uInt8*)myScreen->pixels + myBaseOffset;
|
||||
uInt32 bufofsY = 0;
|
||||
uInt32 screenofsY = 0;
|
||||
for(uInt32 y = 0; y < height; ++y)
|
||||
{
|
||||
uInt32 ystride = myZoomLevel;
|
||||
while(ystride--)
|
||||
{
|
||||
uInt32 pos = screenofsY;
|
||||
for(uInt32 x = 0; x < width; ++x)
|
||||
{
|
||||
const uInt32 bufofs = bufofsY + x;
|
||||
uInt32 xstride = myZoomLevel;
|
||||
|
||||
uInt8 v = currentFrame[bufofs];
|
||||
uInt8 w = previousFrame[bufofs];
|
||||
uInt8 a, b, c;
|
||||
uInt32 pixel = myAvgPalette[v][w];
|
||||
if(SDL_BYTEORDER == SDL_LIL_ENDIAN)
|
||||
{
|
||||
a = (pixel & myFormat->Bmask) >> myFormat->Bshift;
|
||||
b = (pixel & myFormat->Gmask) >> myFormat->Gshift;
|
||||
c = (pixel & myFormat->Rmask) >> myFormat->Rshift;
|
||||
}
|
||||
else
|
||||
{
|
||||
a = (pixel & myFormat->Rmask) >> myFormat->Rshift;
|
||||
b = (pixel & myFormat->Gmask) >> myFormat->Gshift;
|
||||
c = (pixel & myFormat->Bmask) >> myFormat->Bshift;
|
||||
}
|
||||
|
||||
while(xstride--)
|
||||
{
|
||||
buffer[pos++] = a; buffer[pos++] = b; buffer[pos++] = c;
|
||||
buffer[pos++] = a; buffer[pos++] = b; buffer[pos++] = c;
|
||||
}
|
||||
}
|
||||
screenofsY += myPitch;
|
||||
}
|
||||
bufofsY += width;
|
||||
}
|
||||
SDL_UnlockSurface(myScreen);
|
||||
myTiaDirty = true;
|
||||
break; // kPhosphor_24
|
||||
}
|
||||
|
||||
case kPhosphor_32:
|
||||
{
|
||||
SDL_LockSurface(myScreen);
|
||||
uInt32* buffer = (uInt32*)myScreen->pixels + myBaseOffset;
|
||||
uInt32 bufofsY = 0;
|
||||
uInt32 screenofsY = 0;
|
||||
for(uInt32 y = 0; y < height; ++y)
|
||||
{
|
||||
uInt32 ystride = myZoomLevel;
|
||||
while(ystride--)
|
||||
{
|
||||
uInt32 pos = screenofsY;
|
||||
for(uInt32 x = 0; x < width; ++x)
|
||||
{
|
||||
const uInt32 bufofs = bufofsY + x;
|
||||
uInt32 xstride = myZoomLevel;
|
||||
|
||||
uInt8 v = currentFrame[bufofs];
|
||||
uInt8 w = previousFrame[bufofs];
|
||||
|
||||
while(xstride--)
|
||||
{
|
||||
buffer[pos++] = (uInt32) myAvgPalette[v][w];
|
||||
buffer[pos++] = (uInt32) myAvgPalette[v][w];
|
||||
}
|
||||
}
|
||||
screenofsY += myPitch;
|
||||
}
|
||||
bufofsY += width;
|
||||
}
|
||||
SDL_UnlockSurface(myScreen);
|
||||
myTiaDirty = true;
|
||||
break; // kPhosphor_32
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferSoft::postFrameUpdate()
|
||||
{
|
||||
if(myTiaDirty && !myInUIMode)
|
||||
{
|
||||
SDL_UpdateRect(myScreen, 0, 0, 0, 0);
|
||||
myTiaDirty = false;
|
||||
}
|
||||
else if(myRectList->numRects() > 0)
|
||||
{
|
||||
//myRectList->print(myScreen->w, myScreen->h);
|
||||
SDL_UpdateRects(myScreen, myRectList->numRects(), myRectList->rects());
|
||||
}
|
||||
myRectList->start();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferSoft::enablePhosphor(bool enable, int blend)
|
||||
{
|
||||
myUsePhosphor = enable;
|
||||
myPhosphorBlend = blend;
|
||||
|
||||
// Make sure drawMediaSource() knows which renderer to use
|
||||
switch(myBytesPerPixel)
|
||||
{
|
||||
case 2: // 16-bit
|
||||
myRenderType = myUsePhosphor ? kPhosphor_16 : kSoftZoom_16;
|
||||
break;
|
||||
case 3: // 24-bit
|
||||
myRenderType = myUsePhosphor ? kPhosphor_24 : kSoftZoom_24;
|
||||
break;
|
||||
case 4: // 32-bit
|
||||
myRenderType = myUsePhosphor ? kPhosphor_32 : kSoftZoom_32;
|
||||
break;
|
||||
}
|
||||
myRedrawEntireFrame = true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
FBSurface* FrameBufferSoft::createSurface(int w, int h, bool isBase) const
|
||||
{
|
||||
// For some unknown reason, OSX in software fullscreen mode doesn't like
|
||||
// to use the underlying surface directly
|
||||
// I suspect it's an SDL compatibility thing, since I get errors
|
||||
// referencing Quartz vs. QuickDraw, and then a program crash
|
||||
// For now, we'll just always use entire surfaces for OSX
|
||||
// I don't think this will have much effect, since OpenGL mode is the
|
||||
// preferred method in OSX (basically, all OSX installations have OpenGL
|
||||
// support)
|
||||
#ifdef MAC_OSX
|
||||
isBase = false;
|
||||
#endif
|
||||
|
||||
SDL_Surface* surface = isBase ? myScreen :
|
||||
SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, myFormat->BitsPerPixel,
|
||||
myFormat->Rmask, myFormat->Gmask, myFormat->Bmask,
|
||||
myFormat->Amask);
|
||||
|
||||
return new FBSurfaceSoft(*this, surface, w, h, isBase);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferSoft::scanline(uInt32 row, uInt8* data) const
|
||||
{
|
||||
// Make sure no pixels are being modified
|
||||
SDL_LockSurface(myScreen);
|
||||
|
||||
uInt32 pixel = 0;
|
||||
uInt8 *p, r, g, b;
|
||||
|
||||
// Row will be offset by the amount the actual image is shifted down
|
||||
const GUI::Rect& image = imageRect();
|
||||
row += image.y();
|
||||
for(Int32 x = 0; x < myScreen->w; ++x)
|
||||
{
|
||||
p = (Uint8*) ((uInt8*)myScreen->pixels + // Start at top of RAM
|
||||
(row * myScreen->pitch) + // Go down 'row' lines
|
||||
((x + image.x()) * myBytesPerPixel)); // Go in 'x' pixels
|
||||
|
||||
switch(myBytesPerPixel)
|
||||
{
|
||||
case 1:
|
||||
pixel = *p;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
pixel = *(Uint16*) p;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
|
||||
pixel = p[0] << 16 | p[1] << 8 | p[2];
|
||||
else
|
||||
pixel = p[0] | p[1] << 8 | p[2] << 16;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
pixel = *(Uint32*) p;
|
||||
break;
|
||||
}
|
||||
|
||||
SDL_GetRGB(pixel, myScreen->format, &r, &g, &b);
|
||||
|
||||
data[x * 3 + 0] = r;
|
||||
data[x * 3 + 1] = g;
|
||||
data[x * 3 + 2] = b;
|
||||
}
|
||||
|
||||
SDL_UnlockSurface(myScreen);
|
||||
}
|
||||
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// FBSurfaceSoft implementation follows ...
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
FBSurfaceSoft::FBSurfaceSoft(const FrameBufferSoft& buffer, SDL_Surface* surface,
|
||||
uInt32 w, uInt32 h, bool isBase)
|
||||
: myFB(buffer),
|
||||
mySurface(surface),
|
||||
myWidth(w),
|
||||
myHeight(h),
|
||||
myIsBaseSurface(isBase),
|
||||
mySurfaceIsDirty(false),
|
||||
myPitch(0),
|
||||
myXOrig(0),
|
||||
myYOrig(0),
|
||||
myXOffset(0),
|
||||
myYOffset(0)
|
||||
{
|
||||
reload();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
FBSurfaceSoft::~FBSurfaceSoft()
|
||||
{
|
||||
if(!myIsBaseSurface)
|
||||
SDL_FreeSurface(mySurface);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceSoft::hLine(uInt32 x, uInt32 y, uInt32 x2, uInt32 color)
|
||||
{
|
||||
// Horizontal line
|
||||
SDL_Rect tmp;
|
||||
tmp.x = x + myXOffset;
|
||||
tmp.y = y + myYOffset;
|
||||
tmp.w = x2 - x + 1;
|
||||
tmp.h = 1;
|
||||
SDL_FillRect(mySurface, &tmp, myFB.myDefPalette[color]);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceSoft::vLine(uInt32 x, uInt32 y, uInt32 y2, uInt32 color)
|
||||
{
|
||||
// Vertical line
|
||||
SDL_Rect tmp;
|
||||
tmp.x = x + myXOffset;
|
||||
tmp.y = y + myYOffset;
|
||||
tmp.w = 1;
|
||||
tmp.h = y2 - y + 1;
|
||||
SDL_FillRect(mySurface, &tmp, myFB.myDefPalette[color]);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceSoft::fillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h, uInt32 color)
|
||||
{
|
||||
// Fill the rectangle
|
||||
SDL_Rect tmp;
|
||||
tmp.x = x + myXOffset;
|
||||
tmp.y = y + myYOffset;
|
||||
tmp.w = w;
|
||||
tmp.h = h;
|
||||
SDL_FillRect(mySurface, &tmp, myFB.myDefPalette[color]);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceSoft::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));
|
||||
switch(myFB.myBytesPerPixel)
|
||||
{
|
||||
case 2:
|
||||
{
|
||||
// Get buffer position where upper-left pixel of the character will be drawn
|
||||
uInt16* buffer = (uInt16*)getBasePtr(tx + bbx, ty + desc.ascent - bby - bbh);
|
||||
|
||||
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] = (uInt16) myFB.myDefPalette[color];
|
||||
|
||||
buffer += myPitch;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
// Get buffer position where upper-left pixel of the character will be drawn
|
||||
uInt8* buffer = (uInt8*)getBasePtr(tx + bbx, ty + desc.ascent - bby - bbh);
|
||||
|
||||
uInt8 a = myFB.myDefPalette24[color][0],
|
||||
b = myFB.myDefPalette24[color][1],
|
||||
c = myFB.myDefPalette24[color][2];
|
||||
|
||||
for(int y = 0; y < bbh; y++, buffer += myPitch)
|
||||
{
|
||||
const uInt16 ptr = *tmp++;
|
||||
uInt16 mask = 0x8000;
|
||||
|
||||
uInt8* buf_ptr = buffer;
|
||||
for(int x = 0; x < bbw; x++, mask >>= 1)
|
||||
{
|
||||
if(ptr & mask)
|
||||
{
|
||||
*buf_ptr++ = a; *buf_ptr++ = b; *buf_ptr++ = c;
|
||||
}
|
||||
else
|
||||
buf_ptr += 3;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
// Get buffer position where upper-left pixel of the character will be drawn
|
||||
uInt32* buffer = (uInt32*)getBasePtr(tx + bbx, ty + desc.ascent - bby - bbh);
|
||||
for(int y = 0; y < bbh; y++, buffer += myPitch)
|
||||
{
|
||||
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];
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceSoft::drawBitmap(uInt32* bitmap, uInt32 tx, uInt32 ty,
|
||||
uInt32 color, uInt32 h)
|
||||
{
|
||||
SDL_Rect rect;
|
||||
rect.y = ty + myYOffset;
|
||||
rect.w = rect.h = 1;
|
||||
for(uInt32 y = 0; y < h; y++)
|
||||
{
|
||||
rect.x = tx + myXOffset;
|
||||
uInt32 mask = 0xF0000000;
|
||||
for(uInt32 x = 0; x < 8; x++, mask >>= 4)
|
||||
{
|
||||
if(bitmap[y] & mask)
|
||||
SDL_FillRect(mySurface, &rect, myFB.myDefPalette[color]);
|
||||
|
||||
rect.x++;
|
||||
}
|
||||
rect.y++;
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceSoft::drawPixels(uInt32* data, uInt32 tx, uInt32 ty,
|
||||
uInt32 numpixels)
|
||||
{
|
||||
SDL_Rect rect;
|
||||
rect.x = tx + myXOffset;
|
||||
rect.y = ty + myYOffset;
|
||||
rect.w = rect.h = 1;
|
||||
for(uInt32 x = 0; x < numpixels; ++x)
|
||||
{
|
||||
SDL_FillRect(mySurface, &rect, data[x]);
|
||||
rect.x++;
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceSoft::drawSurface(const FBSurface* surface, uInt32 tx, uInt32 ty)
|
||||
{
|
||||
const FBSurfaceSoft* s = (const FBSurfaceSoft*) surface;
|
||||
|
||||
SDL_Rect dstrect;
|
||||
dstrect.x = tx + myXOffset;
|
||||
dstrect.y = ty + myYOffset;
|
||||
SDL_Rect srcrect;
|
||||
srcrect.x = 0;
|
||||
srcrect.y = 0;
|
||||
srcrect.w = s->myWidth;
|
||||
srcrect.h = s->myHeight;
|
||||
|
||||
SDL_BlitSurface(s->mySurface, &srcrect, mySurface, &dstrect);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceSoft::addDirtyRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h)
|
||||
{
|
||||
//cerr << " -> addDirtyRect: x = " << x << ", y = " << y << ", w = " << w << ", h = " << h << endl;
|
||||
|
||||
// Base surfaces use dirty-rectangle updates, since they can be quite
|
||||
// large, and updating the entire surface each frame would be too slow
|
||||
// Non-base surfaces are usually smaller, and can be updated entirely
|
||||
if(myIsBaseSurface)
|
||||
{
|
||||
// Add a dirty rect to the UI rectangle list
|
||||
SDL_Rect temp;
|
||||
temp.x = x + myXOrig; temp.y = y + myYOrig; temp.w = w; temp.h = h;
|
||||
myFB.myRectList->add(&temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_Rect temp;
|
||||
temp.x = myXOrig; temp.y = myYOrig; temp.w = myWidth; temp.h = myHeight;
|
||||
myFB.myRectList->add(&temp);
|
||||
|
||||
// Indicate that at least one dirty rect has been added
|
||||
// This is an optimization for the update() method
|
||||
mySurfaceIsDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceSoft::getPos(uInt32& x, uInt32& y) const
|
||||
{
|
||||
// Return the origin of the 'usable' area of a surface
|
||||
if(myIsBaseSurface)
|
||||
{
|
||||
x = myXOffset;
|
||||
y = myYOffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = myXOrig;
|
||||
y = myYOrig;
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceSoft::setPos(uInt32 x, uInt32 y)
|
||||
{
|
||||
myXOrig = x;
|
||||
myYOrig = y;
|
||||
|
||||
if(myIsBaseSurface)
|
||||
{
|
||||
myXOffset = myFB.imageRect().x();
|
||||
myYOffset = myFB.imageRect().y();
|
||||
}
|
||||
else
|
||||
{
|
||||
myXOffset = myYOffset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceSoft::setWidth(uInt32 w)
|
||||
{
|
||||
myWidth = BSPF_min(w, (uInt32)mySurface->w);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceSoft::setHeight(uInt32 h)
|
||||
{
|
||||
myHeight = BSPF_min(h, (uInt32)mySurface->h);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceSoft::translateCoords(Int32& x, Int32& y) const
|
||||
{
|
||||
x -= myXOrig;
|
||||
y -= myYOrig;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceSoft::update()
|
||||
{
|
||||
// Since this method is called each frame, we only blit the surfaces when
|
||||
// absolutely necessary
|
||||
if(mySurfaceIsDirty /* && !myIsBaseSurface */)
|
||||
{
|
||||
SDL_Rect srcrect;
|
||||
srcrect.x = 0;
|
||||
srcrect.y = 0;
|
||||
srcrect.w = myWidth;
|
||||
srcrect.h = myHeight;
|
||||
|
||||
SDL_Rect dstrect;
|
||||
dstrect.x = myXOrig;
|
||||
dstrect.y = myYOrig;
|
||||
dstrect.w = myWidth;
|
||||
dstrect.h = myHeight;
|
||||
|
||||
SDL_BlitSurface(mySurface, &srcrect, myFB.myScreen, &dstrect);
|
||||
mySurfaceIsDirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceSoft::reload()
|
||||
{
|
||||
switch(mySurface->format->BytesPerPixel)
|
||||
{
|
||||
case 2: // 16-bit
|
||||
myPitch = mySurface->pitch >> 1;
|
||||
break;
|
||||
case 3: // 24-bit
|
||||
myPitch = mySurface->pitch;
|
||||
break;
|
||||
case 4: // 32-bit
|
||||
myPitch = mySurface->pitch >> 2;
|
||||
break;
|
||||
}
|
||||
}
|
|
@ -1,230 +0,0 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2013 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id$
|
||||
//============================================================================
|
||||
|
||||
#ifndef FRAMEBUFFER_SOFT_HXX
|
||||
#define FRAMEBUFFER_SOFT_HXX
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
class OSystem;
|
||||
class RectList;
|
||||
|
||||
#include "bspf.hxx"
|
||||
#include "FrameBuffer.hxx"
|
||||
|
||||
|
||||
/**
|
||||
This class implements an SDL software framebuffer.
|
||||
|
||||
@author Stephen Anthony
|
||||
@version $Id$
|
||||
*/
|
||||
class FrameBufferSoft : public FrameBuffer
|
||||
{
|
||||
friend class FBSurfaceSoft;
|
||||
|
||||
public:
|
||||
/**
|
||||
Creates a new software framebuffer
|
||||
*/
|
||||
FrameBufferSoft(OSystem* osystem);
|
||||
|
||||
/**
|
||||
Destructor
|
||||
*/
|
||||
virtual ~FrameBufferSoft();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// The following are derived from public methods in FrameBuffer.hxx
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
Enable/disable phosphor effect.
|
||||
*/
|
||||
void enablePhosphor(bool enable, int blend);
|
||||
|
||||
/**
|
||||
This method is called to retrieve the R/G/B data from the given pixel.
|
||||
|
||||
@param pixel The pixel containing R/G/B data
|
||||
@param r The red component of the color
|
||||
@param g The green component of the color
|
||||
@param b The blue component of the color
|
||||
*/
|
||||
void getRGB(Uint32 pixel, Uint8* r, Uint8* g, Uint8* b) const
|
||||
{ SDL_GetRGB(pixel, myScreen->format, r, g, b); }
|
||||
|
||||
/**
|
||||
This method is called to map a given R/G/B triple to the screen palette.
|
||||
|
||||
@param r The red component of the color.
|
||||
@param g The green component of the color.
|
||||
@param b The blue component of the color.
|
||||
*/
|
||||
Uint32 mapRGB(Uint8 r, Uint8 g, Uint8 b) const
|
||||
{ return SDL_MapRGB(myScreen->format, r, g, b); }
|
||||
|
||||
/**
|
||||
This method is called to query the type of the FrameBuffer.
|
||||
*/
|
||||
BufferType type() const { return kSoftBuffer; }
|
||||
|
||||
/**
|
||||
This method is called to get the specified scanline data.
|
||||
|
||||
@param row The row we are looking for
|
||||
@param data The actual pixel data (in bytes)
|
||||
*/
|
||||
void scanline(uInt32 row, uInt8* data) const;
|
||||
|
||||
protected:
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// The following are derived from protected methods in FrameBuffer.hxx
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
This method is called to initialize the video subsystem
|
||||
with the given video mode. Normally, it will also call setVidMode().
|
||||
|
||||
@param mode The video mode to use
|
||||
|
||||
@return False on any errors, else true
|
||||
*/
|
||||
bool initSubsystem(VideoMode& mode);
|
||||
|
||||
/**
|
||||
This method is called to change to the given video mode. If the mode
|
||||
is successfully changed, 'mode' holds the actual dimensions used.
|
||||
|
||||
@param mode The video mode to use
|
||||
|
||||
@return False on any errors (in which case 'mode' is invalid), else true
|
||||
*/
|
||||
bool setVidMode(VideoMode& mode);
|
||||
|
||||
/**
|
||||
This method is called to invalidate the contents of the entire
|
||||
framebuffer (ie, mark the current content as invalid, and erase it on
|
||||
the next drawing pass).
|
||||
*/
|
||||
void invalidate();
|
||||
|
||||
/**
|
||||
This method is called to create a surface compatible with the one
|
||||
currently in use, but having the given dimensions.
|
||||
|
||||
@param w The requested width of the new surface.
|
||||
@param h The requested height of the new surface.
|
||||
@param useBase Use the base surface instead of creating a new one
|
||||
*/
|
||||
FBSurface* createSurface(int w, int h, bool useBase = false) const;
|
||||
|
||||
/**
|
||||
This method should be called anytime the TIA needs to be redrawn
|
||||
to the screen (full indicating that a full redraw is required).
|
||||
*/
|
||||
void drawTIA(bool full);
|
||||
|
||||
/**
|
||||
This method is called after any drawing is done (per-frame).
|
||||
*/
|
||||
void postFrameUpdate();
|
||||
|
||||
/**
|
||||
This method is called to provide information about the FrameBuffer.
|
||||
*/
|
||||
string about() const;
|
||||
|
||||
private:
|
||||
int myZoomLevel;
|
||||
int myBytesPerPixel;
|
||||
int myBaseOffset;
|
||||
int myPitch;
|
||||
SDL_PixelFormat* myFormat;
|
||||
|
||||
enum RenderType {
|
||||
kSoftZoom_16,
|
||||
kSoftZoom_24,
|
||||
kSoftZoom_32,
|
||||
kPhosphor_16,
|
||||
kPhosphor_24,
|
||||
kPhosphor_32
|
||||
};
|
||||
RenderType myRenderType;
|
||||
|
||||
// Indicates if the TIA image has been modified
|
||||
bool myTiaDirty;
|
||||
|
||||
// Indicates if we're in a purely UI mode
|
||||
bool myInUIMode;
|
||||
|
||||
// Used in the dirty update of rectangles in non-TIA modes
|
||||
RectList* myRectList;
|
||||
};
|
||||
|
||||
/**
|
||||
A surface suitable for software rendering mode.
|
||||
|
||||
@author Stephen Anthony
|
||||
@version $Id$
|
||||
*/
|
||||
class FBSurfaceSoft : public FBSurface
|
||||
{
|
||||
public:
|
||||
FBSurfaceSoft(const FrameBufferSoft& buffer, SDL_Surface* surface,
|
||||
uInt32 w, uInt32 h, bool isBase);
|
||||
virtual ~FBSurfaceSoft();
|
||||
|
||||
void hLine(uInt32 x, uInt32 y, uInt32 x2, uInt32 color);
|
||||
void vLine(uInt32 x, uInt32 y, uInt32 y2, uInt32 color);
|
||||
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;
|
||||
void setPos(uInt32 x, uInt32 y);
|
||||
uInt32 getWidth() const { return myWidth; }
|
||||
uInt32 getHeight() const { return myHeight; }
|
||||
void setWidth(uInt32 w);
|
||||
void setHeight(uInt32 h);
|
||||
void translateCoords(Int32& x, Int32& y) const;
|
||||
void update();
|
||||
void free() { } // Not required for software mode
|
||||
void reload();
|
||||
|
||||
private:
|
||||
void* getBasePtr(uInt32 x, uInt32 y) {
|
||||
return static_cast<void *>(static_cast<uInt8*>(mySurface->pixels) +
|
||||
(myYOffset + y) * mySurface->pitch + (myXOffset + x) *
|
||||
mySurface->format->BytesPerPixel);
|
||||
}
|
||||
|
||||
private:
|
||||
const FrameBufferSoft& myFB;
|
||||
SDL_Surface* mySurface;
|
||||
uInt32 myWidth, myHeight;
|
||||
bool myIsBaseSurface;
|
||||
bool mySurfaceIsDirty;
|
||||
int myPitch;
|
||||
|
||||
uInt32 myXOrig, myYOrig;
|
||||
uInt32 myXOffset, myYOffset;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,96 +0,0 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2013 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id$
|
||||
//============================================================================
|
||||
|
||||
#include <SDL.h>
|
||||
#include "bspf.hxx"
|
||||
#include "RectList.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
RectList::RectList(Uint32 size)
|
||||
{
|
||||
currentSize = size;
|
||||
currentRect = 0;
|
||||
|
||||
rectArray = new SDL_Rect[currentSize];
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
RectList::~RectList()
|
||||
{
|
||||
delete[] rectArray;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void RectList::add(SDL_Rect* newRect)
|
||||
{
|
||||
if(currentRect >= currentSize)
|
||||
{
|
||||
currentSize = currentSize * 2;
|
||||
SDL_Rect *temp = new SDL_Rect[currentSize];
|
||||
|
||||
for(Uint32 i = 0; i < currentRect; ++i)
|
||||
temp[i] = rectArray[i];
|
||||
|
||||
delete[] rectArray;
|
||||
rectArray = temp;
|
||||
}
|
||||
|
||||
rectArray[currentRect].x = newRect->x;
|
||||
rectArray[currentRect].y = newRect->y;
|
||||
rectArray[currentRect].w = newRect->w;
|
||||
rectArray[currentRect].h = newRect->h;
|
||||
|
||||
++currentRect;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
SDL_Rect* RectList::rects()
|
||||
{
|
||||
return rectArray;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Uint32 RectList::numRects()
|
||||
{
|
||||
return currentRect;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void RectList::start()
|
||||
{
|
||||
currentRect = 0;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void RectList::print(int boundWidth, int boundHeight)
|
||||
{
|
||||
cerr << "RectList: rects = " << numRects() << endl;
|
||||
for(Uint32 i = 0; i < currentRect; ++i)
|
||||
{
|
||||
cerr << "Rect " << i << endl
|
||||
<< " x = " << rectArray[i].x << endl
|
||||
<< " y = " << rectArray[i].y << endl
|
||||
<< " w = " << rectArray[i].w << endl
|
||||
<< " h = " << rectArray[i].h << endl;
|
||||
if((rectArray[i].x + rectArray[i].w) > boundWidth ||
|
||||
(rectArray[i].y + rectArray[i].h) > boundHeight)
|
||||
cerr << " TOO LARGE" << endl;
|
||||
cerr << endl;
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2013 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id$
|
||||
//============================================================================
|
||||
|
||||
#ifndef RECTLIST_HXX
|
||||
#define RECTLIST_HXX
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
class RectList
|
||||
{
|
||||
public:
|
||||
RectList(Uint32 size = 256);
|
||||
~RectList();
|
||||
|
||||
void add(SDL_Rect* rect);
|
||||
|
||||
SDL_Rect* rects();
|
||||
Uint32 numRects();
|
||||
void start();
|
||||
void print(int boundWidth, int boundHeight);
|
||||
|
||||
private:
|
||||
Uint32 currentSize, currentRect;
|
||||
|
||||
SDL_Rect* rectArray;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
#include <cstdlib>
|
||||
|
||||
#define STELLA_VERSION "3.9.3_svn"
|
||||
#define STELLA_VERSION "3.9.100_svn"
|
||||
#define STELLA_BUILD atoi("$Rev$" + 6)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4,14 +4,12 @@ MODULE_OBJS := \
|
|||
src/common/mainSDL.o \
|
||||
src/common/Base.o \
|
||||
src/common/SoundSDL.o \
|
||||
src/common/FrameBufferSoft.o \
|
||||
src/common/FrameBufferGL.o \
|
||||
src/common/FBSurfaceGL.o \
|
||||
src/common/FBSurfaceTIA.o \
|
||||
src/common/FSNodeZIP.o \
|
||||
src/common/PNGLibrary.o \
|
||||
src/common/MouseControl.o \
|
||||
src/common/RectList.o \
|
||||
src/common/ZipHandler.o
|
||||
|
||||
MODULE_DIRS += \
|
||||
|
|
|
@ -128,8 +128,12 @@ void TiaOutputWidget::handleCommand(CommandSender* sender, int cmd, int data, in
|
|||
void TiaOutputWidget::drawWidget(bool hilite)
|
||||
{
|
||||
//cerr << "TiaOutputWidget::drawWidget\n";
|
||||
FBSurface& s = dialog().surface();
|
||||
renderToSurface(dialog().surface());
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void TiaOutputWidget::renderToSurface(FBSurface& s)
|
||||
{
|
||||
const uInt32 width = instance().console().tia().width(),
|
||||
height = instance().console().tia().height();
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
class GuiObject;
|
||||
class ContextMenu;
|
||||
class FBSurface;
|
||||
class TiaZoomWidget;
|
||||
|
||||
#include "Widget.hxx"
|
||||
|
@ -38,6 +39,8 @@ class TiaOutputWidget : public Widget, public CommandSender
|
|||
void loadConfig();
|
||||
void setZoomWidget(TiaZoomWidget* w) { myZoom = w; }
|
||||
|
||||
void saveSnapshot();
|
||||
|
||||
// Eventually, these methods will enable access to the onscreen TIA image
|
||||
// For example, clicking an area may cause an action
|
||||
// (fill to this scanline, etc).
|
||||
|
@ -55,6 +58,9 @@ class TiaOutputWidget : public Widget, public CommandSender
|
|||
void drawWidget(bool hilite);
|
||||
bool wantsFocus() { return false; }
|
||||
|
||||
private:
|
||||
void renderToSurface(FBSurface& s);
|
||||
|
||||
private:
|
||||
ContextMenu* myMenu;
|
||||
TiaZoomWidget* myZoom;
|
||||
|
@ -64,6 +70,9 @@ class TiaOutputWidget : public Widget, public CommandSender
|
|||
// Create this buffer once, instead of allocating it each time the
|
||||
// TIA image is redrawn
|
||||
uInt32 myLineBuffer[320];
|
||||
|
||||
// Surface to use when taking snapshots
|
||||
FBSurface* mySnapSurface;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include "Settings.hxx"
|
||||
|
||||
#include "FrameBuffer.hxx"
|
||||
#include "FrameBufferSoft.hxx"
|
||||
#ifdef DISPLAY_OPENGL
|
||||
#include "FrameBufferGL.hxx"
|
||||
#endif
|
||||
|
@ -63,11 +62,6 @@ class MediaFactory
|
|||
}
|
||||
#endif
|
||||
|
||||
// If OpenGL failed, or if it wasn't requested, create the appropriate
|
||||
// software framebuffer
|
||||
if(!fb)
|
||||
fb = new FrameBufferSoft(osystem);
|
||||
|
||||
// This should never happen
|
||||
assert(fb != NULL);
|
||||
|
||||
|
|
|
@ -24,10 +24,13 @@
|
|||
|
||||
#include "bspf.hxx"
|
||||
|
||||
#include "DebuggerDialog.hxx"
|
||||
#include "OSystem.hxx"
|
||||
#include "Version.hxx"
|
||||
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
#include "DebuggerDialog.hxx"
|
||||
#endif
|
||||
|
||||
#include "Settings.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -120,8 +123,11 @@ Settings::Settings(OSystem* osystem)
|
|||
setInternal("lastrom", "");
|
||||
|
||||
// UI-related options
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
setInternal("dbg.res",
|
||||
GUI::Size(DebuggerDialog::kMediumFontMinW, DebuggerDialog::kMediumFontMinH));
|
||||
GUI::Size(DebuggerDialog::kMediumFontMinW,
|
||||
DebuggerDialog::kMediumFontMinH));
|
||||
#endif
|
||||
setInternal("uipalette", "0");
|
||||
setInternal("listdelay", "300");
|
||||
setInternal("mwheel", "4");
|
||||
|
@ -139,6 +145,7 @@ Settings::Settings(OSystem* osystem)
|
|||
setExternal("romloadcount", "0");
|
||||
setExternal("maxres", "");
|
||||
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
// Debugger/disassembly options
|
||||
setInternal("dbg.fontstyle", "0");
|
||||
setInternal("dbg.uhex", "true");
|
||||
|
@ -146,9 +153,12 @@ Settings::Settings(OSystem* osystem)
|
|||
setInternal("dis.gfxformat", "2");
|
||||
setInternal("dis.showaddr", "true");
|
||||
setInternal("dis.relocate", "false");
|
||||
#endif
|
||||
|
||||
#ifdef DTHUMB_SUPPORT
|
||||
// Thumb ARM emulation options
|
||||
setInternal("thumb.trapfatal", "true");
|
||||
#endif
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#include "bspf.hxx"
|
||||
|
||||
#include "Dialog.hxx"
|
||||
#include "DebuggerDialog.hxx"
|
||||
#include "OSystem.hxx"
|
||||
#include "ListWidget.hxx"
|
||||
#include "PopUpWidget.hxx"
|
||||
|
@ -31,6 +30,9 @@
|
|||
#include "StringList.hxx"
|
||||
#include "TabWidget.hxx"
|
||||
#include "Widget.hxx"
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
#include "DebuggerDialog.hxx"
|
||||
#endif
|
||||
|
||||
#include "UIDialog.hxx"
|
||||
|
||||
|
@ -160,6 +162,7 @@ UIDialog::UIDialog(OSystem* osystem, DialogContainer* parent,
|
|||
// 2) Debugger options
|
||||
wid.clear();
|
||||
tabID = myTab->addTab(" Debugger ");
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
lwidth = font.getStringWidth("Debugger Height: ");
|
||||
xpos = ypos = vBorder;
|
||||
|
||||
|
@ -239,6 +242,10 @@ UIDialog::UIDialog(OSystem* osystem, DialogContainer* parent,
|
|||
|
||||
// Add items for tab 1
|
||||
addToFocusList(wid, myTab, tabID);
|
||||
#else
|
||||
new StaticTextWidget(myTab, font, 0, 20, _w-20, fontHeight,
|
||||
"Debugger support not included", kTextAlignCenter);
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
// 3) Misc. options
|
||||
|
@ -438,6 +445,7 @@ void UIDialog::setDefaults()
|
|||
|
||||
case 1: // Debugger options
|
||||
{
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
int w = BSPF_min(instance().desktopWidth(), (uInt32)DebuggerDialog::kMediumFontMinW);
|
||||
int h = BSPF_min(instance().desktopHeight(), (uInt32)DebuggerDialog::kMediumFontMinH);
|
||||
myDebuggerWidthSlider->setValue(w);
|
||||
|
@ -445,6 +453,7 @@ void UIDialog::setDefaults()
|
|||
myDebuggerHeightSlider->setValue(h);
|
||||
myDebuggerHeightLabel->setValue(h);
|
||||
myDebuggerFontStyle->setSelected("0");
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -474,6 +483,7 @@ void UIDialog::handleCommand(CommandSender* sender, int cmd, int data, int id)
|
|||
myLauncherHeightLabel->setValue(myLauncherHeightSlider->getValue());
|
||||
break;
|
||||
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
case kDWidthChanged:
|
||||
myDebuggerWidthLabel->setValue(myDebuggerWidthSlider->getValue());
|
||||
break;
|
||||
|
@ -502,6 +512,7 @@ void UIDialog::handleCommand(CommandSender* sender, int cmd, int data, int id)
|
|||
myDebuggerHeightSlider->setValue(DebuggerDialog::kLargeFontMinH);
|
||||
myDebuggerHeightLabel->setValue(DebuggerDialog::kLargeFontMinH);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case kOKCmd:
|
||||
saveConfig();
|
||||
|
|
Loading…
Reference in New Issue