mirror of https://github.com/stella-emu/stella.git
The ROM launcher now uses a separate FBSurface for snapshots, so that
any-sized PNG can be loaded and then scaled to the available space. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2979 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
8da55d8eac
commit
f6dd1ba27b
|
@ -21,6 +21,10 @@
|
|||
* Added 'MDM' (Menu Driven Megacart) bankswitch scheme as described on
|
||||
AtariAge and originally developed by Edwin Blink.
|
||||
|
||||
* Improved snapshot viewing in the ROM launcher; snapshots are now
|
||||
scaled to the available space, and can better accommodate sizes
|
||||
other than those generated by Stella itself.
|
||||
|
||||
* Removed the 'bank' command from the debugger prompt, as it only worked
|
||||
with certain bankswitch types. The bankswitch UI should now be used
|
||||
to query/set bank state.
|
||||
|
|
|
@ -33,36 +33,7 @@ FBSurfaceSDL2::FBSurfaceSDL2(FrameBufferSDL2& buffer,
|
|||
myBlendAlpha(255),
|
||||
myStaticData(NULL)
|
||||
{
|
||||
// Create a surface in the same format as the parent GL class
|
||||
const SDL_PixelFormat* pf = myFB.myPixelFormat;
|
||||
|
||||
mySurface = SDL_CreateRGBSurface(0, width, height,
|
||||
pf->BitsPerPixel, pf->Rmask, pf->Gmask, pf->Bmask, pf->Amask);
|
||||
|
||||
// We start out with the src and dst rectangles containing the same
|
||||
// dimensions, indicating no scaling or re-positioning
|
||||
mySrcR.x = mySrcR.y = myDstR.x = myDstR.y = 0;
|
||||
mySrcR.w = myDstR.w = width;
|
||||
mySrcR.h = myDstR.h = height;
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
// These *must* be set for the parent class
|
||||
myPixels = (uInt32*) mySurface->pixels;
|
||||
myPitch = mySurface->pitch / pf->BytesPerPixel;
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
if(data)
|
||||
{
|
||||
myTexAccess = SDL_TEXTUREACCESS_STATIC;
|
||||
myStaticPitch = mySurface->w * 4; // we need pitch in 'bytes'
|
||||
myStaticData = new uInt32[mySurface->w * mySurface->h];
|
||||
SDL_memcpy(myStaticData, data, mySurface->w * mySurface->h * 4);
|
||||
}
|
||||
|
||||
applyAttributes(false);
|
||||
|
||||
// To generate texture
|
||||
reload();
|
||||
createSurface(width, height, data);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -92,14 +63,6 @@ void FBSurfaceSDL2::fillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h, uInt32 colo
|
|||
SDL_FillRect(mySurface, &tmp, myPalette[color]);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceSDL2::drawSurface(const FBSurface* surface)
|
||||
{
|
||||
const FBSurfaceSDL2* s = (const FBSurfaceSDL2*) surface;
|
||||
SDL_Rect dst = s->myDstR;
|
||||
SDL_BlitSurface(s->mySurface, &(s->mySrcR), mySurface, &dst);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt32 FBSurfaceSDL2::width() const
|
||||
{
|
||||
|
@ -113,16 +76,14 @@ uInt32 FBSurfaceSDL2::height() const
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
const GUI::Rect& FBSurfaceSDL2::srcRect()
|
||||
const GUI::Rect& FBSurfaceSDL2::srcRect() const
|
||||
{
|
||||
mySrcGUIR.setBounds(mySrcR.x, mySrcR.y, mySrcR.x+mySrcR.w, mySrcR.y+mySrcR.h);
|
||||
return mySrcGUIR;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
const GUI::Rect& FBSurfaceSDL2::dstRect()
|
||||
const GUI::Rect& FBSurfaceSDL2::dstRect() const
|
||||
{
|
||||
myDstGUIR.setBounds(myDstR.x, myDstR.y, myDstR.x+myDstR.w, myDstR.y+myDstR.h);
|
||||
return myDstGUIR;
|
||||
}
|
||||
|
||||
|
@ -130,24 +91,28 @@ const GUI::Rect& FBSurfaceSDL2::dstRect()
|
|||
void FBSurfaceSDL2::setSrcPos(uInt32 x, uInt32 y)
|
||||
{
|
||||
mySrcR.x = x; mySrcR.y = y;
|
||||
mySrcGUIR.moveTo(x, y);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceSDL2::setSrcSize(uInt32 w, uInt32 h)
|
||||
{
|
||||
mySrcR.w = w; mySrcR.h = h;
|
||||
mySrcGUIR.setWidth(w); mySrcGUIR.setHeight(h);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceSDL2::setDstPos(uInt32 x, uInt32 y)
|
||||
{
|
||||
myDstR.x = x; myDstR.y = y;
|
||||
myDstGUIR.moveTo(x, y);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceSDL2::setDstSize(uInt32 w, uInt32 h)
|
||||
{
|
||||
myDstR.w = w; myDstR.h = h;
|
||||
myDstGUIR.setWidth(w); myDstGUIR.setHeight(h);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -220,6 +185,57 @@ void FBSurfaceSDL2::reload()
|
|||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceSDL2::resize(uInt32 width, uInt32 height)
|
||||
{
|
||||
// We will only resize when necessary, and not using static textures
|
||||
if((myTexAccess == SDL_TEXTUREACCESS_STATIC) ||
|
||||
(width <= mySurface->w && height <= mySurface->h))
|
||||
return; // don't need to resize at all
|
||||
|
||||
if(mySurface)
|
||||
SDL_FreeSurface(mySurface);
|
||||
free();
|
||||
|
||||
createSurface(width, height, NULL);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceSDL2::createSurface(uInt32 width, uInt32 height,
|
||||
const uInt32* data)
|
||||
{
|
||||
// Create a surface in the same format as the parent GL class
|
||||
const SDL_PixelFormat* pf = myFB.myPixelFormat;
|
||||
|
||||
mySurface = SDL_CreateRGBSurface(0, width, height,
|
||||
pf->BitsPerPixel, pf->Rmask, pf->Gmask, pf->Bmask, pf->Amask);
|
||||
|
||||
// We start out with the src and dst rectangles containing the same
|
||||
// dimensions, indicating no scaling or re-positioning
|
||||
mySrcR.x = mySrcR.y = myDstR.x = myDstR.y = 0;
|
||||
mySrcR.w = myDstR.w = width;
|
||||
mySrcR.h = myDstR.h = height;
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
// These *must* be set for the parent class
|
||||
myPixels = (uInt32*) mySurface->pixels;
|
||||
myPitch = mySurface->pitch / pf->BytesPerPixel;
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
if(data)
|
||||
{
|
||||
myTexAccess = SDL_TEXTUREACCESS_STATIC;
|
||||
myStaticPitch = mySurface->w * 4; // we need pitch in 'bytes'
|
||||
myStaticData = new uInt32[mySurface->w * mySurface->h];
|
||||
SDL_memcpy(myStaticData, data, mySurface->w * mySurface->h * 4);
|
||||
}
|
||||
|
||||
applyAttributes(false);
|
||||
|
||||
// To generate texture
|
||||
reload();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceSDL2::applyAttributes(bool immediate)
|
||||
{
|
||||
|
|
|
@ -40,15 +40,14 @@ class FBSurfaceSDL2 : public FBSurface
|
|||
// the ones implemented here use SDL-specific code for extra performance
|
||||
//
|
||||
void fillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h, uInt32 color);
|
||||
void drawSurface(const FBSurface* surface);
|
||||
// With hardware surfaces, it's faster to just update the entire surface
|
||||
void setDirty() { mySurfaceIsDirty = true; }
|
||||
|
||||
uInt32 width() const;
|
||||
uInt32 height() const;
|
||||
|
||||
const GUI::Rect& srcRect();
|
||||
const GUI::Rect& dstRect();
|
||||
const GUI::Rect& srcRect() const;
|
||||
const GUI::Rect& dstRect() const;
|
||||
void setSrcPos(uInt32 x, uInt32 y);
|
||||
void setSrcSize(uInt32 w, uInt32 h);
|
||||
void setDstPos(uInt32 x, uInt32 y);
|
||||
|
@ -60,10 +59,14 @@ class FBSurfaceSDL2 : public FBSurface
|
|||
void invalidate();
|
||||
void free();
|
||||
void reload();
|
||||
void resize(uInt32 width, uInt32 height);
|
||||
|
||||
protected:
|
||||
void applyAttributes(bool immediate);
|
||||
|
||||
private:
|
||||
void createSurface(uInt32 width, uInt32 height, const uInt32* data);
|
||||
|
||||
private:
|
||||
FrameBufferSDL2& myFB;
|
||||
|
||||
|
|
|
@ -38,7 +38,6 @@ PNGLibrary::PNGLibrary(const FrameBuffer& fb)
|
|||
PNGLibrary::~PNGLibrary()
|
||||
{
|
||||
delete[] ReadInfo.buffer;
|
||||
delete[] ReadInfo.line;
|
||||
delete[] ReadInfo.row_pointers;
|
||||
}
|
||||
|
||||
|
@ -115,8 +114,8 @@ void PNGLibrary::loadImage(const string& filename, FBSurface& surface)
|
|||
// We're finished reading
|
||||
png_read_end(png_ptr, info_ptr);
|
||||
|
||||
// Scale image to surface dimensions
|
||||
scaleImagetoSurface(surface);
|
||||
// Load image into the surface, setting the correct dimensions
|
||||
loadImagetoSurface(surface);
|
||||
|
||||
// Cleanup
|
||||
done:
|
||||
|
@ -258,16 +257,6 @@ bool PNGLibrary::allocateStorage(png_uint_32 w, png_uint_32 h)
|
|||
|
||||
ReadInfo.buffer_size = req_buffer_size;
|
||||
}
|
||||
uInt32 req_line_size = w * 3;
|
||||
if(req_line_size > ReadInfo.line_size)
|
||||
{
|
||||
delete[] ReadInfo.line;
|
||||
ReadInfo.line = new uInt32[req_line_size];
|
||||
if(ReadInfo.line == NULL)
|
||||
return false;
|
||||
|
||||
ReadInfo.line_size = req_line_size;
|
||||
}
|
||||
uInt32 req_row_size = h;
|
||||
if(req_row_size > ReadInfo.row_size)
|
||||
{
|
||||
|
@ -287,53 +276,30 @@ bool PNGLibrary::allocateStorage(png_uint_32 w, png_uint_32 h)
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void PNGLibrary::scaleImagetoSurface(FBSurface& surface)
|
||||
void PNGLibrary::loadImagetoSurface(FBSurface& surface)
|
||||
{
|
||||
// Figure out the original zoom level of the snapshot
|
||||
// All snapshots generated by Stella are at most some multiple of 320
|
||||
// pixels wide
|
||||
// The only complication is when the aspect ratio is changed, the width
|
||||
// can range from 256 (80%) to 320 (100%)
|
||||
// The following calculation will work up to approx. 16x zoom level,
|
||||
// but since Stella only generates snapshots at up to 10x, we should
|
||||
// be fine for a while ...
|
||||
uInt32 izoom = uInt32(ceil(ReadInfo.width/320.0)),
|
||||
szoom = surface.width()/320;
|
||||
// First determine if we need to resize the surface
|
||||
uInt32 iw = ReadInfo.width, ih = ReadInfo.height;
|
||||
if(iw > surface.width() || ih > surface.height())
|
||||
surface.resize(iw, ih);
|
||||
|
||||
uInt32 sw = ReadInfo.width / izoom * szoom,
|
||||
sh = ReadInfo.height / izoom * szoom;
|
||||
sw = BSPF_min(sw, surface.width());
|
||||
sh = BSPF_min(sh, surface.height());
|
||||
surface.setSrcSize(sw, sh);
|
||||
surface.setDstSize(sw, sh);
|
||||
// The source dimensions are set here; the destination dimensions are
|
||||
// set by whoever owns the surface
|
||||
surface.setSrcPos(0, 0);
|
||||
surface.setSrcSize(iw, ih);
|
||||
|
||||
// Decompress the image, and scale it correctly
|
||||
uInt32 buf_offset = ReadInfo.pitch * izoom;
|
||||
uInt32 i_offset = 3 * izoom;
|
||||
// Convert RGB triples into pixels and store in the surface
|
||||
uInt32 *s_buf, s_pitch;
|
||||
surface.basePtr(s_buf, s_pitch);
|
||||
uInt8* i_buf = ReadInfo.buffer;
|
||||
uInt32 i_pitch = ReadInfo.pitch;
|
||||
|
||||
// We can only scan at most the height of the image to the constraints of
|
||||
// the surface height (some multiple of 256)
|
||||
uInt32 iheight = BSPF_min((uInt32)ReadInfo.height, izoom * 256);
|
||||
|
||||
// Grab each non-duplicate row of data from the image
|
||||
uInt8* buffer = ReadInfo.buffer;
|
||||
for(uInt32 irow = 0, srow = 0; irow < iheight; irow += izoom, buffer += buf_offset)
|
||||
for(uInt32 irow = 0; irow < ih; ++irow, i_buf += i_pitch, s_buf += s_pitch)
|
||||
{
|
||||
// Scale the image data into the temporary line buffer
|
||||
uInt8* i_ptr = buffer;
|
||||
uInt32* l_ptr = ReadInfo.line;
|
||||
for(uInt32 icol = 0; icol < ReadInfo.width; icol += izoom, i_ptr += i_offset)
|
||||
{
|
||||
uInt32 pixel = myFB.mapRGB(*i_ptr, *(i_ptr+1), *(i_ptr+2));
|
||||
uInt32 xstride = szoom;
|
||||
while(xstride--)
|
||||
*l_ptr++ = pixel;
|
||||
}
|
||||
|
||||
// Then fill the surface with those bytes
|
||||
uInt32 ystride = szoom;
|
||||
while(ystride--)
|
||||
surface.drawPixels(ReadInfo.line, 0, srow++, sw);
|
||||
uInt8* i_ptr = i_buf;
|
||||
uInt32* s_ptr = s_buf;
|
||||
for(uInt32 icol = 0; icol < ReadInfo.width; ++icol, i_ptr += 3)
|
||||
*s_ptr++ = myFB.mapRGB(*i_ptr, *(i_ptr+1), *(i_ptr+2));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -394,5 +360,5 @@ void PNGLibrary::png_user_error(png_structp ctx, png_const_charp str)
|
|||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
PNGLibrary::ReadInfoType PNGLibrary::ReadInfo = {
|
||||
NULL, NULL, 0, 0, 0, NULL, 0, 0, 0
|
||||
NULL, NULL, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
|
|
@ -95,8 +95,7 @@ class PNGLibrary
|
|||
uInt8* buffer;
|
||||
png_bytep* row_pointers;
|
||||
png_uint_32 width, height, pitch;
|
||||
uInt32* line;
|
||||
uInt32 buffer_size, line_size, row_size;
|
||||
uInt32 buffer_size, row_size;
|
||||
} ReadInfoType;
|
||||
static ReadInfoType ReadInfo;
|
||||
|
||||
|
@ -128,12 +127,12 @@ class PNGLibrary
|
|||
const VariantList& comments);
|
||||
|
||||
/**
|
||||
Scale the PNG data from 'ReadInfo' into the FBSurface. For now, scaling
|
||||
is done on integer boundaries only (ie, 1x, 2x, etc up or down).
|
||||
Load the PNG data from 'ReadInfo' into the FBSurface. The surface
|
||||
is resized as necessary to accommodate the data.
|
||||
|
||||
@param surface The FBSurface into which to place the PNG data
|
||||
*/
|
||||
void scaleImagetoSurface(FBSurface& surface);
|
||||
void loadImagetoSurface(FBSurface& surface);
|
||||
|
||||
/**
|
||||
Write PNG tEXt chunks to the image.
|
||||
|
|
|
@ -283,23 +283,5 @@ void FBSurface::drawString(const GUI::Font& font, const string& s,
|
|||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurface::drawSurface(const FBSurface* surface)
|
||||
{
|
||||
const GUI::Rect& srcR = ((FBSurface*)surface)->srcRect();
|
||||
const GUI::Rect& dstR = ((FBSurface*)surface)->dstRect();
|
||||
|
||||
const uInt32* src = surface->myPixels + srcR.y() * surface->myPitch + srcR.x();
|
||||
uInt32* dst = myPixels + dstR.y() * myPitch + dstR.x();
|
||||
|
||||
uInt32 h = srcR.height(), w = srcR.width() * 4;
|
||||
while(h--)
|
||||
{
|
||||
memcpy(dst, src, w);
|
||||
src += surface->myPitch;
|
||||
dst += myPitch;
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
const uInt32* FBSurface::myPalette = 0;
|
||||
|
|
|
@ -52,7 +52,7 @@ enum FrameStyle {
|
|||
|
||||
class FBSurface
|
||||
{
|
||||
friend class TIASurface;
|
||||
// friend class TIASurface;
|
||||
|
||||
public:
|
||||
/**
|
||||
|
@ -208,16 +208,6 @@ class FBSurface
|
|||
uInt32 color, TextAlignment align = kTextAlignLeft,
|
||||
int deltax = 0, bool useEllipsis = true);
|
||||
|
||||
/**
|
||||
This method should be called copy the contents of the given
|
||||
surface into the FrameBuffer surface. No scaling is done; that is,
|
||||
a straight-forward copy of the surface pixels is done at the specified
|
||||
destination.
|
||||
|
||||
@param surface The data to draw
|
||||
*/
|
||||
virtual void drawSurface(const FBSurface* surface);
|
||||
|
||||
/**
|
||||
This method should be called to indicate that the surface has been
|
||||
modified, and should be redrawn at the next interval.
|
||||
|
@ -243,8 +233,8 @@ class FBSurface
|
|||
These methods answer the current *rendering* dimensions of the
|
||||
specified surface.
|
||||
*/
|
||||
virtual const GUI::Rect& srcRect() = 0;
|
||||
virtual const GUI::Rect& dstRect() = 0;
|
||||
virtual const GUI::Rect& srcRect() const = 0;
|
||||
virtual const GUI::Rect& dstRect() const = 0;
|
||||
|
||||
/**
|
||||
These methods set the origin point and width/height for the
|
||||
|
@ -295,9 +285,13 @@ class FBSurface
|
|||
*/
|
||||
virtual void reload() = 0;
|
||||
|
||||
static void setPalette(const uInt32* palette) { myPalette = palette; }
|
||||
/**
|
||||
This method should be called to resize the surface to the
|
||||
given dimensions and reload data/state. The surface is not
|
||||
modified if it is larger than the given dimensions.
|
||||
*/
|
||||
virtual void resize(uInt32 width, uInt32 height) = 0;
|
||||
|
||||
protected:
|
||||
/**
|
||||
The rendering attributes that can be modified for this texture.
|
||||
These probably can only be implemented in child FBSurfaces where
|
||||
|
@ -308,6 +302,12 @@ class FBSurface
|
|||
bool blending; // Blending is enabled
|
||||
uInt32 blendalpha; // Alpha to use in blending mode (0-100%)
|
||||
};
|
||||
|
||||
/**
|
||||
Get the currently applied attributes.
|
||||
*/
|
||||
Attributes& attributes() { return myAttributes; }
|
||||
|
||||
/**
|
||||
The child class chooses which (if any) of the actual attributes
|
||||
can be applied.
|
||||
|
@ -318,6 +318,8 @@ class FBSurface
|
|||
*/
|
||||
virtual void applyAttributes(bool immediate = true) = 0;
|
||||
|
||||
static void setPalette(const uInt32* palette) { myPalette = palette; }
|
||||
|
||||
protected:
|
||||
static const uInt32* myPalette;
|
||||
uInt32* myPixels;
|
||||
|
|
|
@ -137,9 +137,8 @@ const FBSurface& TIASurface::baseSurface(GUI::Rect& rect)
|
|||
rect.setBounds(0, 0, width, height);
|
||||
|
||||
// Fill the surface with pixels from the TIA, scaled 2x horizontally
|
||||
uInt32 *buffer, pitch;
|
||||
myBaseTiaSurface->basePtr(buffer, pitch);
|
||||
uInt32* buf_ptr = buffer;
|
||||
uInt32 *buf_ptr, pitch;
|
||||
myBaseTiaSurface->basePtr(buf_ptr, pitch);
|
||||
|
||||
for(uInt32 y = 0; y < height; ++y)
|
||||
{
|
||||
|
@ -219,22 +218,23 @@ void TIASurface::toggleScanlineInterpolation()
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt32 TIASurface::enableScanlines(int relative, int absolute)
|
||||
{
|
||||
uInt32& intensity = mySLineSurface->myAttributes.blendalpha;
|
||||
if(relative == 0) intensity = absolute;
|
||||
else intensity += relative;
|
||||
intensity = BSPF_max(0u, intensity);
|
||||
intensity = BSPF_min(100u, intensity);
|
||||
FBSurface::Attributes& attr = mySLineSurface->attributes();
|
||||
if(relative == 0) attr.blendalpha = absolute;
|
||||
else attr.blendalpha += relative;
|
||||
attr.blendalpha = BSPF_max(0u, attr.blendalpha);
|
||||
attr.blendalpha = BSPF_min(100u, attr.blendalpha);
|
||||
|
||||
mySLineSurface->applyAttributes();
|
||||
mySLineSurface->setDirty();
|
||||
|
||||
return intensity;
|
||||
return attr.blendalpha;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void TIASurface::enableScanlineInterpolation(bool enable)
|
||||
{
|
||||
mySLineSurface->myAttributes.smoothing = enable;
|
||||
FBSurface::Attributes& attr = mySLineSurface->attributes();
|
||||
attr.smoothing = enable;
|
||||
mySLineSurface->applyAttributes();
|
||||
mySLineSurface->setDirty();
|
||||
}
|
||||
|
@ -266,16 +266,15 @@ void TIASurface::enableNTSC(bool enable)
|
|||
// Normal vs NTSC mode uses different source widths
|
||||
myTiaSurface->setSrcSize(enable ? ATARI_NTSC_OUT_WIDTH(160) : 160, myTIA->height());
|
||||
|
||||
myTiaSurface->myAttributes.smoothing =
|
||||
myOSystem.settings().getBool("tia.inter");
|
||||
FBSurface::Attributes& tia_attr = myTiaSurface->attributes();
|
||||
tia_attr.smoothing = myOSystem.settings().getBool("tia.inter");
|
||||
myTiaSurface->applyAttributes();
|
||||
|
||||
myScanlinesEnabled = enable;
|
||||
mySLineSurface->myAttributes.smoothing =
|
||||
myOSystem.settings().getBool("tv.scaninter");
|
||||
mySLineSurface->myAttributes.blending = myScanlinesEnabled;
|
||||
mySLineSurface->myAttributes.blendalpha =
|
||||
myOSystem.settings().getInt("tv.scanlines");
|
||||
FBSurface::Attributes& sl_attr = mySLineSurface->attributes();
|
||||
sl_attr.smoothing = myOSystem.settings().getBool("tv.scaninter");
|
||||
sl_attr.blending = myScanlinesEnabled;
|
||||
sl_attr.blendalpha = myOSystem.settings().getInt("tv.scanlines");
|
||||
mySLineSurface->applyAttributes();
|
||||
|
||||
myTiaSurface->setDirty();
|
||||
|
@ -285,6 +284,8 @@ void TIASurface::enableNTSC(bool enable)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string TIASurface::effectsInfo() const
|
||||
{
|
||||
const FBSurface::Attributes& attr = mySLineSurface->attributes();
|
||||
|
||||
ostringstream buf;
|
||||
switch(myFilterType)
|
||||
{
|
||||
|
@ -295,14 +296,12 @@ string TIASurface::effectsInfo() const
|
|||
buf << "Disabled, phosphor mode";
|
||||
break;
|
||||
case kBlarggNormal:
|
||||
buf << myNTSCFilter.getPreset() << ", scanlines="
|
||||
<< mySLineSurface->myAttributes.blendalpha << "/"
|
||||
<< (mySLineSurface->myAttributes.smoothing ? "inter" : "nointer");
|
||||
buf << myNTSCFilter.getPreset() << ", scanlines=" << attr.blendalpha << "/"
|
||||
<< (attr.smoothing ? "inter" : "nointer");
|
||||
break;
|
||||
case kBlarggPhosphor:
|
||||
buf << myNTSCFilter.getPreset() << ", phosphor, scanlines="
|
||||
<< mySLineSurface->myAttributes.blendalpha << "/"
|
||||
<< (mySLineSurface->myAttributes.smoothing ? "inter" : "nointer");
|
||||
<< attr.blendalpha << "/" << (attr.smoothing ? "inter" : "nointer");
|
||||
break;
|
||||
}
|
||||
return buf.str();
|
||||
|
|
|
@ -42,8 +42,6 @@ class VideoMode;
|
|||
|
||||
class TIASurface
|
||||
{
|
||||
friend class FrameBuffer;
|
||||
|
||||
public:
|
||||
/**
|
||||
Creates a new TIASurface object
|
||||
|
|
|
@ -92,9 +92,11 @@ void RomInfoWidget::parseProperties()
|
|||
// only draw certain parts of it
|
||||
if(mySurface == NULL)
|
||||
{
|
||||
uInt32 ID = instance().frameBuffer().allocateSurface(
|
||||
320*myZoomLevel, 256*myZoomLevel);
|
||||
uInt32 ID = instance().frameBuffer().allocateSurface(320*2, 256*2);
|
||||
mySurface = instance().frameBuffer().surface(ID);
|
||||
mySurface->attributes().smoothing = true;
|
||||
mySurface->applyAttributes();
|
||||
|
||||
dialog().addSurface(mySurface);
|
||||
}
|
||||
|
||||
|
@ -111,6 +113,12 @@ void RomInfoWidget::parseProperties()
|
|||
try
|
||||
{
|
||||
instance().png().loadImage(filename, *mySurface);
|
||||
|
||||
// Scale surface to available image area
|
||||
const GUI::Rect& src = mySurface->srcRect();
|
||||
uInt32 avail_w = 320 * myZoomLevel, avail_h = 256 * myZoomLevel;
|
||||
float scale = BSPF_min(float(avail_w) / src.width(), float(avail_h) / src.height());
|
||||
mySurface->setDstSize(src.width() * scale, src.height() * scale);
|
||||
}
|
||||
catch(const char* msg)
|
||||
{
|
||||
|
@ -145,9 +153,9 @@ void RomInfoWidget::drawWidget(bool hilite)
|
|||
|
||||
if(mySurfaceIsValid)
|
||||
{
|
||||
const GUI::Rect& src = mySurface->srcRect();
|
||||
uInt32 x = _x + ((_w - src.width()) >> 1);
|
||||
uInt32 y = _y + ((yoff - src.height()) >> 1);
|
||||
const GUI::Rect& dst = mySurface->dstRect();
|
||||
uInt32 x = _x + ((_w - dst.width()) >> 1);
|
||||
uInt32 y = _y + ((yoff - dst.height()) >> 1);
|
||||
|
||||
// Make sure when positioning the snapshot surface that we take
|
||||
// the dialog surface position into account
|
||||
|
|
Loading…
Reference in New Issue