Reversed a number of the UI/TIA palette changes I made yesterday, as it's

a can of worms I don't want to open (and besides, the current
implementation works well enough).

Added '-ss1x' commandline argument (and associated UI element) to
generate TIA snapshots in 1x mode (ie, without any scaling included).
Useful for those who would like to generate many small snapshots, but
don't want to run the emulation in 1x mode (which is no longer possible
anyway).


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1595 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2009-01-03 22:57:12 +00:00
parent e3b07007d4
commit 6a4945528f
31 changed files with 391 additions and 342 deletions

View File

@ -767,12 +767,19 @@
<tr>
<td><pre>-sssingle &lt;0|1&gt;</pre></td>
<td>Generate single snapshot instead of many.</td>
<td>Generate single snapshot instead of many, overwriting
any previous snapshots.</td>
</tr>
<tr>
<td><pre>-ss1x &lt;0|1&gt;</pre></td>
<td>Ignore any scaling applied to the TIA image, and save
snapshot in unscaled mode.</td>
</tr>
<tr>
<td><pre>-stats &lt;0|1&gt;</pre></td>
<td>Show scanline and framerate info during emulation.</td>
<td>Overlay console info on the TIA image during emulation.</td>
</tr>
<tr>

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: FrameBufferGL.cxx,v 1.131 2009-01-03 15:44:12 stephena Exp $
// $Id: FrameBufferGL.cxx,v 1.132 2009-01-03 22:57:12 stephena Exp $
//============================================================================
#ifdef DISPLAY_OPENGL
@ -569,26 +569,26 @@ FBSurfaceGL::~FBSurfaceGL()
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurfaceGL::hLine(uInt32 x, uInt32 y, uInt32 x2, UIColor color)
void FBSurfaceGL::hLine(uInt32 x, uInt32 y, uInt32 x2, uInt32 color)
{
uInt16* buffer = (uInt16*) myTexture->pixels + y * myPitch + x;
while(x++ <= x2)
*buffer++ = (uInt16) myFB.myUIPalette[color];
*buffer++ = (uInt16) myFB.myDefPalette[color];
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurfaceGL::vLine(uInt32 x, uInt32 y, uInt32 y2, UIColor color)
void FBSurfaceGL::vLine(uInt32 x, uInt32 y, uInt32 y2, uInt32 color)
{
uInt16* buffer = (uInt16*) myTexture->pixels + y * myPitch + x;
while(y++ <= y2)
{
*buffer = (uInt16) myFB.myUIPalette[color];
*buffer = (uInt16) myFB.myDefPalette[color];
buffer += myPitch;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurfaceGL::fillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h, UIColor color)
void FBSurfaceGL::fillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h, uInt32 color)
{
// Fill the rectangle
SDL_Rect tmp;
@ -596,26 +596,12 @@ void FBSurfaceGL::fillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h, UIColor color
tmp.y = y;
tmp.w = w;
tmp.h = h;
SDL_FillRect(myTexture, &tmp, myFB.myUIPalette[color]);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurfaceGL::fillTIARect(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
int c1, int c2)
{
// Fill the rectangle
SDL_Rect tmp;
tmp.x = x;
tmp.y = y;
tmp.w = w;
tmp.h = h;
SDL_FillRect(myTexture, &tmp,
(c2 == -1 ? myFB.myDefPalette[c1] : myFB.myAvgPalette[c1][c2]));
SDL_FillRect(myTexture, &tmp, myFB.myDefPalette[color]);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurfaceGL::drawChar(const GUI::Font* font, uInt8 chr,
uInt32 tx, uInt32 ty, UIColor color)
uInt32 tx, uInt32 ty, uInt32 color)
{
const FontDesc& desc = font->desc();
@ -656,7 +642,7 @@ void FBSurfaceGL::drawChar(const GUI::Font* font, uInt8 chr,
for(int x = 0; x < bbw; x++, mask >>= 1)
if(ptr & mask)
buffer[x] = (uInt16) myFB.myUIPalette[color];
buffer[x] = (uInt16) myFB.myDefPalette[color];
buffer += myPitch;
}
@ -664,7 +650,7 @@ void FBSurfaceGL::drawChar(const GUI::Font* font, uInt8 chr,
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurfaceGL::drawBitmap(uInt32* bitmap, uInt32 tx, uInt32 ty,
UIColor color, uInt32 h)
uInt32 color, uInt32 h)
{
uInt16* buffer = (uInt16*) myTexture->pixels + ty * myPitch + tx;
@ -673,19 +659,19 @@ void FBSurfaceGL::drawBitmap(uInt32* bitmap, uInt32 tx, uInt32 ty,
uInt32 mask = 0xF0000000;
for(uInt32 x = 0; x < 8; ++x, mask >>= 4)
if(bitmap[y] & mask)
buffer[x] = (uInt16) myFB.myUIPalette[color];
buffer[x] = (uInt16) myFB.myDefPalette[color];
buffer += myPitch;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurfaceGL::drawBytes(uInt8* data, uInt32 tx, uInt32 ty, uInt32 rowbytes)
void FBSurfaceGL::drawPixels(uInt32* data, uInt32 tx, uInt32 ty, uInt32 numpixels)
{
uInt16* buffer = (uInt16*) myTexture->pixels + ty * myPitch + tx;
for(uInt32 c = 0; c < rowbytes; c += 3)
*buffer++ = SDL_MapRGB(&myFB.myPixelFormat, data[c], data[c+1], data[c+2]);
for(uInt32 i = 0; i < numpixels; ++i)
*buffer++ = (uInt16) data[i];
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: FrameBufferGL.hxx,v 1.69 2009-01-03 15:44:12 stephena Exp $
// $Id: FrameBufferGL.hxx,v 1.70 2009-01-03 22:57:12 stephena Exp $
//============================================================================
#ifndef FRAMEBUFFER_GL_HXX
@ -35,7 +35,7 @@ class FBSurfaceGL;
This class implements an SDL OpenGL framebuffer.
@author Stephen Anthony
@version $Id: FrameBufferGL.hxx,v 1.69 2009-01-03 15:44:12 stephena Exp $
@version $Id: FrameBufferGL.hxx,v 1.70 2009-01-03 22:57:12 stephena Exp $
*/
class FrameBufferGL : public FrameBuffer
{
@ -70,7 +70,18 @@ class FrameBufferGL : public FrameBuffer
void enablePhosphor(bool enable, int blend);
/**
This method is called to map a given r,g,b triple to the screen palette.
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, (SDL_PixelFormat*)&myPixelFormat, 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.
@ -176,7 +187,7 @@ class FrameBufferGL : public FrameBuffer
A surface suitable for OpenGL rendering mode.
@author Stephen Anthony
@version $Id: FrameBufferGL.hxx,v 1.69 2009-01-03 15:44:12 stephena Exp $
@version $Id: FrameBufferGL.hxx,v 1.70 2009-01-03 22:57:12 stephena Exp $
*/
class FBSurfaceGL : public FBSurface
{
@ -188,13 +199,12 @@ class FBSurfaceGL : public FBSurface
uInt32 scaleWidth, uInt32 scaleHeight);
virtual ~FBSurfaceGL();
void hLine(uInt32 x, uInt32 y, uInt32 x2, UIColor color);
void vLine(uInt32 x, uInt32 y, uInt32 y2, UIColor color);
void fillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h, UIColor color);
void fillTIARect(uInt32 x, uInt32 y, uInt32 w, uInt32 h, int c1, int c2);
void drawChar(const GUI::Font* font, uInt8 c, uInt32 x, uInt32 y, UIColor color);
void drawBitmap(uInt32* bitmap, uInt32 x, uInt32 y, UIColor color, uInt32 h = 8);
void drawBytes(uInt8* data, uInt32 x, uInt32 y, uInt32 rowbytes);
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;

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: FrameBufferSoft.cxx,v 1.90 2009-01-03 15:44:12 stephena Exp $
// $Id: FrameBufferSoft.cxx,v 1.91 2009-01-03 22:57:12 stephena Exp $
//============================================================================
#include <sstream>
@ -533,7 +533,7 @@ FBSurfaceSoft::~FBSurfaceSoft()
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurfaceSoft::hLine(uInt32 x, uInt32 y, uInt32 x2, UIColor color)
void FBSurfaceSoft::hLine(uInt32 x, uInt32 y, uInt32 x2, uInt32 color)
{
// Horizontal line
SDL_Rect tmp;
@ -541,11 +541,11 @@ void FBSurfaceSoft::hLine(uInt32 x, uInt32 y, uInt32 x2, UIColor color)
tmp.y = y + myYOffset;
tmp.w = x2 - x + 1;
tmp.h = 1;
SDL_FillRect(mySurface, &tmp, myFB.myUIPalette[color]);
SDL_FillRect(mySurface, &tmp, myFB.myDefPalette[color]);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurfaceSoft::vLine(uInt32 x, uInt32 y, uInt32 y2, UIColor color)
void FBSurfaceSoft::vLine(uInt32 x, uInt32 y, uInt32 y2, uInt32 color)
{
// Vertical line
SDL_Rect tmp;
@ -553,11 +553,11 @@ void FBSurfaceSoft::vLine(uInt32 x, uInt32 y, uInt32 y2, UIColor color)
tmp.y = y + myYOffset;
tmp.w = 1;
tmp.h = y2 - y + 1;
SDL_FillRect(mySurface, &tmp, myFB.myUIPalette[color]);
SDL_FillRect(mySurface, &tmp, myFB.myDefPalette[color]);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurfaceSoft::fillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h, UIColor color)
void FBSurfaceSoft::fillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h, uInt32 color)
{
// Fill the rectangle
SDL_Rect tmp;
@ -565,26 +565,12 @@ void FBSurfaceSoft::fillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h, UIColor col
tmp.y = y + myYOffset;
tmp.w = w;
tmp.h = h;
SDL_FillRect(mySurface, &tmp, myFB.myUIPalette[color]);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurfaceSoft::fillTIARect(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
int c1, int c2)
{
// Fill the rectangle
SDL_Rect tmp;
tmp.x = x + myXOffset;
tmp.y = y + myYOffset;
tmp.w = w;
tmp.h = h;
SDL_FillRect(mySurface, &tmp,
(c2 == -1 ? myFB.myDefPalette[c1] : myFB.myAvgPalette[c1][c2]));
SDL_FillRect(mySurface, &tmp, myFB.myDefPalette[color]);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurfaceSoft::drawChar(const GUI::Font* font, uInt8 chr,
uInt32 tx, uInt32 ty, UIColor color)
uInt32 tx, uInt32 ty, uInt32 color)
{
// TODO - test this in 16-bit, and re-write 24-bit
const FontDesc& desc = font->desc();
@ -631,7 +617,7 @@ void FBSurfaceSoft::drawChar(const GUI::Font* font, uInt8 chr,
for(int x = 0; x < bbw; x++, mask >>= 1)
if(ptr & mask)
buffer[x] = (uInt16) myFB.myUIPalette[color];
buffer[x] = (uInt16) myFB.myDefPalette[color];
buffer += myPitch;
}
@ -691,7 +677,7 @@ void FBSurfaceSoft::drawChar(const GUI::Font* font, uInt8 chr,
for(int x = 0; x < bbw; x++, mask >>= 1)
if(ptr & mask)
buffer[x] = (uInt32) myFB.myUIPalette[color];
buffer[x] = (uInt32) myFB.myDefPalette[color];
buffer += myPitch;
}
@ -704,7 +690,7 @@ void FBSurfaceSoft::drawChar(const GUI::Font* font, uInt8 chr,
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurfaceSoft::drawBitmap(uInt32* bitmap, uInt32 tx, uInt32 ty,
UIColor color, uInt32 h)
uInt32 color, uInt32 h)
{
SDL_Rect rect;
rect.y = ty + myYOffset;
@ -716,7 +702,7 @@ void FBSurfaceSoft::drawBitmap(uInt32* bitmap, uInt32 tx, uInt32 ty,
for(uInt32 x = 0; x < 8; x++, mask >>= 4)
{
if(bitmap[y] & mask)
SDL_FillRect(mySurface, &rect, myFB.myUIPalette[color]);
SDL_FillRect(mySurface, &rect, myFB.myDefPalette[color]);
rect.x++;
}
@ -725,17 +711,16 @@ void FBSurfaceSoft::drawBitmap(uInt32* bitmap, uInt32 tx, uInt32 ty,
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurfaceSoft::drawBytes(uInt8* data, uInt32 tx, uInt32 ty, uInt32 rowbytes)
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 < rowbytes; x += 3)
for(uInt32 x = 0; x < numpixels; ++x)
{
SDL_FillRect(mySurface, &rect,
SDL_MapRGB(myFB.myFormat, data[x], data[x+1], data[x+2]));
SDL_FillRect(mySurface, &rect, data[x]);
rect.x++;
}
}

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: FrameBufferSoft.hxx,v 1.62 2009-01-03 15:44:13 stephena Exp $
// $Id: FrameBufferSoft.hxx,v 1.63 2009-01-03 22:57:12 stephena Exp $
//============================================================================
#ifndef FRAMEBUFFER_SOFT_HXX
@ -32,7 +32,7 @@ class RectList;
This class implements an SDL software framebuffer.
@author Stephen Anthony
@version $Id: FrameBufferSoft.hxx,v 1.62 2009-01-03 15:44:13 stephena Exp $
@version $Id: FrameBufferSoft.hxx,v 1.63 2009-01-03 22:57:12 stephena Exp $
*/
class FrameBufferSoft : public FrameBuffer
{
@ -58,7 +58,18 @@ class FrameBufferSoft : public FrameBuffer
void enablePhosphor(bool enable, int blend);
/**
This method is called to map a given r,g,b triple to the screen palette.
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.
@ -166,7 +177,7 @@ class FrameBufferSoft : public FrameBuffer
A surface suitable for software rendering mode.
@author Stephen Anthony
@version $Id: FrameBufferSoft.hxx,v 1.62 2009-01-03 15:44:13 stephena Exp $
@version $Id: FrameBufferSoft.hxx,v 1.63 2009-01-03 22:57:12 stephena Exp $
*/
class FBSurfaceSoft : public FBSurface
{
@ -175,13 +186,12 @@ class FBSurfaceSoft : public FBSurface
uInt32 w, uInt32 h, bool isBase);
virtual ~FBSurfaceSoft();
void hLine(uInt32 x, uInt32 y, uInt32 x2, UIColor color);
void vLine(uInt32 x, uInt32 y, uInt32 y2, UIColor color);
void fillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h, UIColor color);
void fillTIARect(uInt32 x, uInt32 y, uInt32 w, uInt32 h, int c1, int c2);
void drawChar(const GUI::Font* font, uInt8 c, uInt32 x, uInt32 y, UIColor color);
void drawBitmap(uInt32* bitmap, uInt32 x, uInt32 y, UIColor color, uInt32 h = 8);
void drawBytes(uInt8* data, uInt32 x, uInt32 y, uInt32 rowbytes);
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;

View File

@ -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: Snapshot.cxx,v 1.24 2009-01-01 18:13:35 stephena Exp $
// $Id: Snapshot.cxx,v 1.25 2009-01-03 22:57:12 stephena Exp $
//============================================================================
#include <zlib.h>
@ -23,32 +23,81 @@
#include "bspf.hxx"
#include "FrameBuffer.hxx"
#include "MediaSrc.hxx"
#include "Props.hxx"
#include "Version.hxx"
#include "Snapshot.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Snapshot::savePNG(FrameBuffer& framebuffer, const Properties& props,
const string& filename)
string Snapshot::savePNG(const FrameBuffer& framebuffer, const Properties& props,
const string& filename)
{
ofstream out(filename.c_str(), ios_base::binary);
if(!out.is_open())
return "ERROR: Couldn't create snapshot file";
// Get actual image dimensions. which are not always the same
// as the framebuffer dimensions
const GUI::Rect& image = framebuffer.imageRect();
uInt32 width = image.width(), height = image.height(),
pitch = width * 3;
uInt8* buffer = new uInt8[(pitch + 1) * height];
// Fill the buffer with scanline data
uInt8* buf_ptr = buffer;
for(uInt32 row = 0; row < height; row++)
{
*buf_ptr++ = 0; // first byte of row is filter type
framebuffer.scanline(row, buf_ptr); // get another scanline
buf_ptr += pitch; // add pitch
}
return saveBufferToPNG(out, buffer, width, height, props);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string Snapshot::savePNG(const FrameBuffer& framebuffer,
const MediaSource& mediasrc, const Properties& props,
const string& filename)
{
ofstream out(filename.c_str(), ios_base::binary);
if(!out.is_open())
return "ERROR: Couldn't create snapshot file";
uInt32 width = mediasrc.width(), height = mediasrc.height();
uInt8* buffer = new uInt8[(width*3*2 + 1) * height];
// Fill the buffer with pixels from the mediasrc
uInt8 r, g, b;
uInt8* buf_ptr = buffer;
for(uInt32 y = 0; y < height; ++y)
{
*buf_ptr++ = 0; // first byte of row is filter type
for(uInt32 x = 0; x < width; ++x)
{
uInt32 pixel = framebuffer.tiaPixel(y*width+x);
framebuffer.getRGB(pixel, &r, &g, &b);
*buf_ptr++ = r;
*buf_ptr++ = g;
*buf_ptr++ = b;
*buf_ptr++ = r;
*buf_ptr++ = g;
*buf_ptr++ = b;
}
}
return saveBufferToPNG(out, buffer, width<<1, height, props);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string Snapshot::saveBufferToPNG(ofstream& out, uInt8* buffer,
uInt32 width, uInt32 height,
const Properties& props)
{
uInt8* buffer = (uInt8*) NULL;
uInt8* compmem = (uInt8*) NULL;
ofstream out;
try
{
// Make sure we have a 'clean' image, with no onscreen messages
framebuffer.enableMessages(false);
// Get actual image dimensions. which are not always the same
// as the framebuffer dimensions
const GUI::Rect& image = framebuffer.imageRect();
int width = image.width(), height = image.height();
out.open(filename.c_str(), ios_base::binary);
if(!out.is_open())
throw "ERROR: Couldn't create snapshot file";
// PNG file header
uInt8 header[8] = { 137, 80, 78, 71, 13, 10, 26, 10 };
out.write((const char*)header, 8);
@ -70,17 +119,6 @@ void Snapshot::savePNG(FrameBuffer& framebuffer, const Properties& props,
ihdr[12] = 0; // PNG_INTERLACE_NONE
writePNGChunk(out, "IHDR", ihdr, 13);
// Fill the buffer with scanline data
int rowbytes = width * 3;
buffer = new uInt8[(rowbytes + 1) * height];
uInt8* buf_ptr = buffer;
for(int row = 0; row < height; row++)
{
*buf_ptr++ = 0; // first byte of row is filter type
framebuffer.scanline(row, buf_ptr); // get another scanline
buf_ptr += rowbytes; // add pitch
}
// Compress the data with zlib
uLongf compmemsize = (uLongf)((height * (width + 1) * 3 * 1.001 + 1) + 12);
compmem = new uInt8[compmemsize];
@ -105,16 +143,14 @@ void Snapshot::savePNG(FrameBuffer& framebuffer, const Properties& props,
if(compmem) delete[] compmem;
out.close();
// Re-enable old messages
framebuffer.enableMessages(true);
framebuffer.showMessage("Snapshot saved");
return "Snapshot saved";
}
catch(const char *msg)
{
if(buffer) delete[] buffer;
if(compmem) delete[] compmem;
out.close();
framebuffer.showMessage(msg);
return msg;
}
}
@ -156,12 +192,10 @@ void Snapshot::writePNGChunk(ofstream& out, const char* type,
void Snapshot::writePNGText(ofstream& out, const string& key, const string& text)
{
int length = key.length() + 1 + text.length() + 1;
uInt8* data = new uInt8[length];
uInt8 data[length];
strcpy((char*)data, key.c_str());
strcpy((char*)data + key.length() + 1, text.c_str());
writePNGChunk(out, "tEXt", data, length-1);
delete[] data;
}

View File

@ -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: Snapshot.hxx,v 1.14 2009-01-01 18:13:35 stephena Exp $
// $Id: Snapshot.hxx,v 1.15 2009-01-03 22:57:12 stephena Exp $
//============================================================================
#ifndef SNAPSHOT_HXX
@ -21,6 +21,7 @@
class Properties;
class FrameBuffer;
class MediaSource;
#include <fstream>
#include "bspf.hxx"
@ -29,16 +30,33 @@ class Snapshot
{
public:
/**
Save the current frame buffer to a PNG file.
Save the current TIA image to a PNG file using data from the Framebuffer.
Any postprocessing/filtering will be included.
@param framebuffer The framebuffer containing the image data
@param props The properties object containing info about the ROM
@param filename The filename of the PNG file
*/
static void savePNG(FrameBuffer& framebuffer, const Properties& props,
const string& filename);
static string savePNG(const FrameBuffer& framebuffer, const Properties& props,
const string& filename);
/**
Save the current TIA image to a PNG file using data directly from
the MediaSource/TIA. No filtering or scaling will be included.
@param framebuffer The framebuffer containing the image data
@param mediasrc Source of the raw TIA data
@param props The properties object containing info about the ROM
@param filename The filename of the PNG file
*/
static string savePNG(const FrameBuffer& framebuffer,
const MediaSource& mediasrc, const Properties& props,
const string& filename);
private:
static string saveBufferToPNG(ofstream& out, uInt8* buffer,
uInt32 width, uInt32 height,
const Properties& props);
static void writePNGChunk(ofstream& out, const char* type, uInt8* data, int size);
static void writePNGText(ofstream& out, const string& key, const string& text);
};

View File

@ -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: mainSDL.cxx,v 1.83 2009-01-01 18:13:35 stephena Exp $
// $Id: mainSDL.cxx,v 1.84 2009-01-03 22:57:12 stephena Exp $
//============================================================================
#include <SDL.h>
@ -166,7 +166,6 @@ int main(int argc, char* argv[])
if(theOSystem->settings().getBool("takesnapshot"))
{
for(int i = 0; i < 60; ++i) theOSystem->frameBuffer().update();
theOSystem->console().system().reset();
theOSystem->eventHandler().takeSnapshot();
Cleanup();
return 0;

View File

@ -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: TIADebug.cxx,v 1.28 2009-01-01 18:13:35 stephena Exp $
// $Id: TIADebug.cxx,v 1.29 2009-01-03 22:57:12 stephena Exp $
//============================================================================
#include "System.hxx"
@ -157,25 +157,25 @@ void TIADebug::saveOldState()
}
/* the set methods now use mySystem.poke(). This will save us the
trouble of masking the values here, since TIA::poke() will do it
for us.
trouble of masking the values here, since TIA::poke() will do it
for us.
This means that the GUI should *never* just display the value the
user entered: it should always read the return value of the set
method and display that.
This means that the GUI should *never* just display the value the
user entered: it should always read the return value of the set
method and display that.
An Example:
An Example:
User enters "ff" in the AUDV0 field. GUI calls value = tiaDebug->audV0(0xff).
The AUDV0 register is only 4 bits wide, so "value" is 0x0f. That's what
should be displayed.
User enters "ff" in the AUDV0 field. GUI calls value = tiaDebug->audV0(0xff).
The AUDV0 register is only 4 bits wide, so "value" is 0x0f. That's what
should be displayed.
In a perfect world, the GUI would only allow one hex digit to be entered...
but we allow decimal or binary input in the GUI (with # or \ prefix). The
only way to make that work would be to validate the data entry after every
keystroke... which would be a pain for both us and the user. Using poke()
here is a compromise that allows the TIA to do the range-checking for us,
so the GUI and/or TIADebug don't have to duplicate logic from TIA::poke().
In a perfect world, the GUI would only allow one hex digit to be entered...
but we allow decimal or binary input in the GUI (with # or \ prefix). The
only way to make that work would be to validate the data entry after every
keystroke... which would be a pain for both us and the user. Using poke()
here is a compromise that allows the TIA to do the range-checking for us,
so the GUI and/or TIADebug don't have to duplicate logic from TIA::poke().
*/
// bool vdelP0(int newVal = -1);

View File

@ -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: ColorWidget.cxx,v 1.11 2009-01-03 15:44:13 stephena Exp $
// $Id: ColorWidget.cxx,v 1.12 2009-01-03 22:57:12 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -73,5 +73,5 @@ void ColorWidget::drawWidget(bool hilite)
s.vLine(_x + _w - 1, _y, _y +_h - 1, kShadowColor);
// Show the currently selected color
s.fillTIARect(_x+1, _y+1, _w-2, _h-1, _color);
s.fillRect(_x+1, _y+1, _w-2, _h-1, _color);
}

View File

@ -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: DataGridWidget.cxx,v 1.16 2009-01-03 15:44:13 stephena Exp $
// $Id: DataGridWidget.cxx,v 1.17 2009-01-03 22:57:12 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -521,7 +521,7 @@ void DataGridWidget::drawWidget(bool hilite)
buffer = _valueStringList[pos];
deltax = 0;
UIColor color = kTextColor;
uInt32 color = kTextColor;
if(_changedList[pos])
{
s.fillRect(x - 3, y - 1, _colWidth-1, _rowHeight-1, kDbgChangedColor);

View File

@ -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: PromptWidget.cxx,v 1.27 2009-01-03 15:44:13 stephena Exp $
// $Id: PromptWidget.cxx,v 1.28 2009-01-03 22:57:12 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -101,7 +101,7 @@ PromptWidget::~PromptWidget()
void PromptWidget::drawWidget(bool hilite)
{
//cerr << "PromptWidget::drawWidget\n";
UIColor fgcolor, bgcolor;
uInt32 fgcolor, bgcolor;
FBSurface& s = _boss->dialog().surface();
@ -117,10 +117,10 @@ void PromptWidget::drawWidget(bool hilite)
if(c & (1 << 17)) { // inverse video flag
fgcolor = _bgcolor;
//FIXME bgcolor = (c & 0x1ffff) >> 8;
bgcolor = (c & 0x1ffff) >> 8;
s.fillRect(x, y, _kConsoleCharWidth, _kConsoleCharHeight, bgcolor);
} else {
//FIXME fgcolor = c >> 8;
fgcolor = c >> 8;
}
s.drawChar(&instance().consoleFont(), c & 0x7f, x, y, fgcolor);
x += _kConsoleCharWidth;
@ -804,10 +804,10 @@ void PromptWidget::putcharIntern(int c)
// don't print or advance cursor
// there are only 128 TIA colors, but
// OverlayColor contains 256 of them
//FIXME _textcolor = 0;//FIXME(c & 0x7f) << 1;
_textcolor = (c & 0x7f) << 1;
}
else if(c < ' ') { // More colors (the regular GUI ones)
//FIXME _textcolor = c + 0x100;
_textcolor = c + 0x100;
}
else if(c == 0x7f) { // toggle inverse video (DEL char)
_inverse = !_inverse;

View File

@ -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: PromptWidget.hxx,v 1.14 2009-01-01 18:13:35 stephena Exp $
// $Id: PromptWidget.hxx,v 1.15 2009-01-03 22:57:12 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -112,6 +112,8 @@ class PromptWidget : public Widget, public CommandSender
bool _firstTime;
bool _exitedEarly;
int _textcolorInt;
int compareHistory(const char *histLine);
};

View File

@ -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: TiaOutputWidget.cxx,v 1.23 2009-01-03 15:44:13 stephena Exp $
// $Id: TiaOutputWidget.cxx,v 1.24 2009-01-03 22:57:12 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -139,7 +139,22 @@ void TiaOutputWidget::handleCommand(CommandSender* sender, int cmd, int data, in
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TiaOutputWidget::drawWidget(bool hilite)
{
//cerr << "TiaOutputWidget::drawWidget\n";
// FIXME - maybe 'greyed out mode' should be done here, not in the TIA class
const FBSurface* tia = instance().frameBuffer().smallTIASurface();
dialog().surface().drawSurface(tia, 0, 0);
FBSurface& s = dialog().surface();
const uInt32 width = instance().console().mediaSource().width(),
height = instance().console().mediaSource().height();
uInt32 line[width << 1];
for(uInt32 y = 0; y < height; ++y)
{
uInt32* line_ptr = line;
for(uInt32 x = 0; x < width; ++x)
{
uInt32 pixel = instance().frameBuffer().tiaPixel(y*width+x);
*line_ptr++ = pixel;
*line_ptr++ = pixel;
}
s.drawPixels(line, _x, _y+y, width << 1);
}
}

View File

@ -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: TiaZoomWidget.cxx,v 1.21 2009-01-03 15:44:13 stephena Exp $
// $Id: TiaZoomWidget.cxx,v 1.22 2009-01-03 22:57:12 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -230,8 +230,8 @@ void TiaZoomWidget::drawWidget(bool hilite)
{
for(x = myXoff, col = 0; x < myNumCols+myXoff; ++x, col += width)
{
s.fillTIARect(_x + col + 2, _y + row + 2, width, height,
currentFrame[y*pitch + x]);
s.fillRect(_x + col + 2, _y + row + 2, width, height,
currentFrame[y*pitch + x]);
}
}
}

View File

@ -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: TogglePixelWidget.cxx,v 1.10 2009-01-03 15:44:13 stephena Exp $
// $Id: TogglePixelWidget.cxx,v 1.11 2009-01-03 22:57:12 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -140,10 +140,8 @@ void TogglePixelWidget::drawWidget(bool hilite)
s.fillRect(x - 4, y - 2, _colWidth+1, _rowHeight+1, kTextColorHi);
// Either draw the pixel in given color, or erase (show background)
if(_stateList[pos])
s.fillTIARect(x - 3, y - 1, _colWidth-1, _rowHeight-1, _pixelColor);
else
s.fillRect(x - 3, y - 1, _colWidth-1, _rowHeight-1, kBGColor);
s.fillRect(x - 3, y - 1, _colWidth-1, _rowHeight-1,
_stateList[pos] ? _pixelColor : kBGColor);
}
}
}

View File

@ -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: EventHandler.cxx,v 1.234 2009-01-01 18:13:35 stephena Exp $
// $Id: EventHandler.cxx,v 1.235 2009-01-03 22:57:12 stephena Exp $
//============================================================================
#include <sstream>
@ -1789,8 +1789,25 @@ void EventHandler::takeSnapshot()
filename = sspath + ".png";
// Now create a PNG snapshot
Snapshot::savePNG(myOSystem->frameBuffer(),
myOSystem->console().properties(), filename);
if(myOSystem->settings().getBool("ss1x"))
{
string msg = Snapshot::savePNG(myOSystem->frameBuffer(),
myOSystem->console().mediaSource(),
myOSystem->console().properties(), filename);
myOSystem->frameBuffer().showMessage(msg);
}
else
{
// Make sure we have a 'clean' image, with no onscreen messages
myOSystem->frameBuffer().enableMessages(false);
string msg = Snapshot::savePNG(myOSystem->frameBuffer(),
myOSystem->console().properties(), filename);
// Re-enable old messages
myOSystem->frameBuffer().enableMessages(true);
myOSystem->frameBuffer().showMessage(msg);
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -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: FrameBuffer.cxx,v 1.153 2009-01-03 15:44:13 stephena Exp $
// $Id: FrameBuffer.cxx,v 1.154 2009-01-03 22:57:12 stephena Exp $
//============================================================================
#include <algorithm>
@ -47,8 +47,7 @@ FrameBuffer::FrameBuffer(OSystem* osystem)
myPhosphorBlend(77),
myInitializedCount(0),
myPausedCount(0),
mySurfaceCount(0),
mySmallTiaSurface(NULL)
mySurfaceCount(0)
{
myMsg.surface = myStatsMsg.surface = NULL;
myMsg.surfaceID = myStatsMsg.surfaceID = -1;
@ -136,14 +135,10 @@ bool FrameBuffer::initialize(const string& title, uInt32 width, uInt32 height)
}
if(myMsg.surface == NULL)
{
myMsg.surfaceID = allocateSurface(320, myOSystem->font().getFontHeight()+10);
myMsg.surfaceID = allocateSurface(500, myOSystem->font().getFontHeight()+10);
myMsg.surface = surface(myMsg.surfaceID);
}
// Create surface for 1x TIA mode
if(mySmallTiaSurface == NULL)
mySmallTiaSurface = surface(allocateSurface(320, 260));
// Finally, show some information about the framebuffer,
// but only on the first initialization
if(myInitializedCount == 1 && myOSystem->settings().getBool("showinfo"))
@ -252,7 +247,7 @@ void FrameBuffer::update()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::showMessage(const string& message, MessagePosition position,
UIColor color)
uInt32 color)
{
// Erase old messages on the screen
if(myMsg.counter > 0)
@ -483,34 +478,15 @@ void FrameBuffer::resetSurfaces()
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const FBSurface* FrameBuffer::smallTIASurface()
uInt32 FrameBuffer::tiaPixel(uInt32 idx) const
{
// This method isn't terribly fast, as it does a complete draw each time
// it's called and doesn't use direct pixel access
// Do not use it in time-sensitive situations
if(&myOSystem->console())
{
const MediaSource& src = myOSystem->console().mediaSource();
uInt8 c = *(myOSystem->console().mediaSource().currentFrameBuffer() + idx);
uInt8 p = *(myOSystem->console().mediaSource().previousFrameBuffer() + idx);
mySmallTiaSurface->setWidth(src.width() << 1); // should always be 320
mySmallTiaSurface->setHeight(src.height()); // can be up to 260
uInt8* currentFrame = src.currentFrameBuffer();
uInt8* previousFrame = src.previousFrameBuffer();
for(uInt32 y = 0; y < src.height(); ++y)
{
for(uInt32 x = 0; x < src.width(); ++x)
{
mySmallTiaSurface->fillTIARect(x + x, y, 2, 1,
currentFrame[y*160+x],
myUsePhosphor ? previousFrame[y*160+x] : -1);
}
}
}
return mySmallTiaSurface;
return (!myUsePhosphor ? myDefPalette[c] : myAvgPalette[c][p]);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::setTIAPalette(const uInt32* palette)
{
@ -553,12 +529,12 @@ void FrameBuffer::setTIAPalette(const uInt32* palette)
void FrameBuffer::setUIPalette(const uInt32* palette)
{
// Set palette for GUI
for(int i = 0; i < kNumUIColors; ++i)
for(int i = 0; i < kNumColors-256; ++i)
{
Uint8 r = (palette[i] >> 16) & 0xff;
Uint8 g = (palette[i] >> 8) & 0xff;
Uint8 b = palette[i] & 0xff;
myUIPalette[i] = mapRGB(r, g, b);
myDefPalette[i+256] = mapRGB(r, g, b);
}
}
@ -1093,7 +1069,7 @@ void FrameBuffer::VideoModeList::print()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurface::box(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
UIColor colorA, UIColor colorB)
uInt32 colorA, uInt32 colorB)
{
hLine(x + 1, y, x + w - 2, colorA);
hLine(x, y + 1, x + w - 1, colorA);
@ -1108,7 +1084,7 @@ void FBSurface::box(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurface::frameRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
UIColor color, FrameStyle style)
uInt32 color, FrameStyle style)
{
switch(style)
{
@ -1145,7 +1121,7 @@ void FBSurface::frameRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurface::drawString(const GUI::Font* font, const string& s,
int x, int y, int w,
UIColor color, TextAlignment align,
uInt32 color, TextAlignment align,
int deltax, bool useEllipsis)
{
const int leftX = x, rightX = x + w;

View File

@ -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: FrameBuffer.hxx,v 1.112 2009-01-03 15:44:13 stephena Exp $
// $Id: FrameBuffer.hxx,v 1.113 2009-01-03 22:57:12 stephena Exp $
//============================================================================
#ifndef FRAMEBUFFER_HXX
@ -56,8 +56,8 @@ enum MessagePosition {
};
// Colors indices to use for the various GUI elements
enum UIColor {
kColor,
enum {
kColor = 256,
kBGColor,
kShadowColor,
kTextColor,
@ -78,7 +78,7 @@ enum UIColor {
kDbgChangedColor,
kDbgChangedTextColor,
kDbgColorHi,
kNumUIColors
kNumColors
};
@ -91,12 +91,10 @@ enum UIColor {
turn drawn here as well.
@author Stephen Anthony
@version $Id: FrameBuffer.hxx,v 1.112 2009-01-03 15:44:13 stephena Exp $
@version $Id: FrameBuffer.hxx,v 1.113 2009-01-03 22:57:12 stephena Exp $
*/
class FrameBuffer
{
friend class TiaOutputWidget;
public:
/**
Creates a new Frame Buffer
@ -133,7 +131,7 @@ class FrameBuffer
*/
void showMessage(const string& message,
MessagePosition position = kBottomCenter,
UIColor color = kTextColorHi);
uInt32 color = kTextColorHi);
/**
Toggles showing or hiding framerate statistics.
@ -172,19 +170,6 @@ class FrameBuffer
*/
FBSurface* surface(int id) const;
/**
Returns a surface representing the TIA image in 1x mode without
any postprocessing (aka, no filtering, scanlines, etc) sized at
maximum 320 x 260 pixels. The phosphor effect *is* applied when
necessary, though. This is useful for those parts of the codebase
that need an unfiltered TIA image (snapshots in 1x mode, debugger,
etc). Note that if a console hasn't been created when this
method is called, a blank surface is returned.
@return A pointer to a valid TIA surface.
*/
const FBSurface* smallTIASurface();
/**
Returns the current dimensions of the framebuffer image.
Note that this will take into account the current scaling (if any)
@ -223,6 +208,7 @@ class FrameBuffer
This method is called when the user wants to switch to the next available
video mode (functionality depends on fullscreen or windowed mode).
direction = -1 means go to the next lower video mode
direction = 0 means to reload the current video mode
direction = +1 means go to the next higher video mode
@param direction Described above
@ -260,6 +246,11 @@ class FrameBuffer
*/
const StringMap& supportedTIAFilters(const string& type);
/**
Get the TIA pixel associated with the given MediaSrc index.
*/
uInt32 tiaPixel(uInt32 idx) const;
/**
Set up the TIA/emulation palette for a screen of any depth > 8.
@ -290,7 +281,17 @@ class FrameBuffer
virtual void enablePhosphor(bool enable, int blend) = 0;
/**
This method is called to map a given r,g,b triple to the screen palette.
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
*/
virtual void getRGB(Uint32 pixel, Uint8* r, Uint8* g, Uint8* b) const = 0;
/**
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.
@ -422,11 +423,9 @@ class FrameBuffer
// Amount to blend when using phosphor effect
int myPhosphorBlend;
// UI palette
Uint32 myUIPalette[kNumUIColors];
// TIA palettes for normal and phosphor modes
Uint32 myDefPalette[256];
// 'myDefPalette' also contains the UI palette
Uint32 myDefPalette[256+kNumColors];
Uint32 myAvgPalette[256][256];
// Names of the TIA filters that can be used for this framebuffer
@ -532,7 +531,7 @@ class FrameBuffer
string text;
int counter;
int x, y, w, h;
UIColor color;
uInt32 color;
FBSurface* surface;
int surfaceID;
bool enabled;
@ -549,11 +548,6 @@ class FrameBuffer
map<int,FBSurface*> mySurfaceList;
int mySurfaceCount;
// A surface representing TIA emulation in 1x mode
// The parent FrameBuffer class (ie, this class) is responsible for
// initializing and deleting this surface
FBSurface* mySmallTiaSurface;
// Holds static strings for the remap menu (emulation and menu events)
static GraphicsMode ourGraphicsModes[GFX_NumModes];
};
@ -568,7 +562,7 @@ class FrameBuffer
FrameBuffer type.
@author Stephen Anthony
@version $Id: FrameBuffer.hxx,v 1.112 2009-01-03 15:44:13 stephena Exp $
@version $Id: FrameBuffer.hxx,v 1.113 2009-01-03 22:57:12 stephena Exp $
*/
// Text alignment modes for drawString()
enum TextAlignment {
@ -603,7 +597,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, UIColor color) = 0;
virtual void hLine(uInt32 x, uInt32 y, uInt32 x2, uInt32 color) = 0;
/**
This method should be called to draw a vertical line.
@ -613,11 +607,10 @@ class FBSurface
@param y2 The second y coordinate
@param color The color of the line
*/
virtual void vLine(uInt32 x, uInt32 y, uInt32 y2, UIColor color) = 0;
virtual void vLine(uInt32 x, uInt32 y, uInt32 y2, uInt32 color) = 0;
/**
This method should be called to draw a filled rectangle using the
UI palette.
This method should be called to draw a filled rectangle.
@param x The x coordinate
@param y The y coordinate
@ -626,21 +619,7 @@ class FBSurface
@param color
*/
virtual void fillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
UIColor color) = 0;
/**
This method should be called to draw a filled rectangle using the
TIA palette(s).
@param x The x coordinate
@param y The y coordinate
@param w The width of the area
@param h The height of the area
@param c1 Indices into the relevant TIA palettes
@param c2 Indices into the relevant TIA palettes
*/
virtual void fillTIARect(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
int c1, int c2 = -1) = 0;
uInt32 color) = 0;
/**
This method should be called to draw the specified character.
@ -652,7 +631,7 @@ class FBSurface
@param color The color of the character
*/
virtual void drawChar(const GUI::Font* font, uInt8 c, uInt32 x, uInt32 y,
UIColor color) = 0;
uInt32 color) = 0;
/**
This method should be called to draw the bitmap image.
@ -663,18 +642,19 @@ class FBSurface
@param color The color of the character
@param h The height of the data image
*/
virtual void drawBitmap(uInt32* bitmap, uInt32 x, uInt32 y, UIColor color,
virtual void drawBitmap(uInt32* bitmap, uInt32 x, uInt32 y, uInt32 color,
uInt32 h = 8) = 0;
/**
This method should be called to convert and copy a given row of RGB
data into a FrameBuffer surface.
This method should be called to convert and copy a given row of pixel
data into a FrameBuffer surface. The pixels must already be in the
format used by the surface.
@param data The data in uInt8 R/G/B format
@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 drawBytes(uInt8* data, uInt32 x, uInt32 y, uInt32 rowbytes) = 0;
virtual void drawPixels(uInt32* data, uInt32 x, uInt32 y, uInt32 numpixels) = 0;
/**
This method should be called copy the contents of the given
@ -761,7 +741,7 @@ class FBSurface
@param colorB Darker color for inside line.
*/
void box(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
UIColor colorA, UIColor colorB);
uInt32 colorA, uInt32 colorB);
/**
This method should be called to draw a framed rectangle.
@ -774,7 +754,7 @@ class FBSurface
@param color The color of the surrounding frame
*/
void frameRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
UIColor color, FrameStyle style = kSolidLine);
uInt32 color, FrameStyle style = kSolidLine);
/**
This method should be called to draw the specified string.
@ -791,7 +771,7 @@ class FBSurface
@param useEllipsis Whether to use '...' when the string is too long
*/
void drawString(const GUI::Font* font, const string& str, int x, int y, int w,
UIColor color, TextAlignment align = kTextAlignLeft,
uInt32 color, TextAlignment align = kTextAlignLeft,
int deltax = 0, bool useEllipsis = true);
};

View File

@ -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: OSystem.cxx,v 1.140 2009-01-03 15:44:13 stephena Exp $
// $Id: OSystem.cxx,v 1.141 2009-01-03 22:57:12 stephena Exp $
//============================================================================
#include <cassert>
@ -871,7 +871,7 @@ void OSystem::queryVideoHardware()
kDbgChangedTextColor Text color for changed cells
kDbgColorHi Highlighted color in debugger data cells
*/
uInt32 OSystem::ourGUIColors[kNumUIPalettes][kNumUIColors] = {
uInt32 OSystem::ourGUIColors[kNumUIPalettes][kNumColors-256] = {
// Standard
{ 0x686868, 0x000000, 0x404040, 0x000000, 0x62a108, 0x9f0000,
0xc9af7c, 0xf0f0cf, 0xc80000,

View File

@ -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: OSystem.hxx,v 1.71 2009-01-03 15:44:13 stephena Exp $
// $Id: OSystem.hxx,v 1.72 2009-01-03 22:57:12 stephena Exp $
//============================================================================
#ifndef OSYSTEM_HXX
@ -56,7 +56,7 @@ typedef Common::Array<Resolution> ResolutionList;
other objects belong.
@author Stephen Anthony
@version $Id: OSystem.hxx,v 1.71 2009-01-03 15:44:13 stephena Exp $
@version $Id: OSystem.hxx,v 1.72 2009-01-03 22:57:12 stephena Exp $
*/
class OSystem
{
@ -521,7 +521,7 @@ class OSystem
TimingInfo myTimingInfo;
// Table of RGB values for GUI elements
static uInt32 ourGUIColors[kNumUIPalettes][kNumUIColors];
static uInt32 ourGUIColors[kNumUIPalettes][kNumColors-256];
private:
/**

View File

@ -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: Settings.cxx,v 1.152 2009-01-01 18:13:37 stephena Exp $
// $Id: Settings.cxx,v 1.153 2009-01-03 22:57:12 stephena Exp $
//============================================================================
#include <cassert>
@ -77,6 +77,7 @@ Settings::Settings(OSystem* osystem)
// Snapshot options
setInternal("ssdir", "");
setInternal("sssingle", "false");
setInternal("ss1x", "false");
// Config files and paths
setInternal("romdir", "");
@ -325,7 +326,8 @@ void Settings::usage()
<< " -autoslot <1|0> Automatically switch to next save slot when state saving\n"
<< " -ssdir <path> The directory to save snapshot files to\n"
<< " -sssingle <1|0> Generate single snapshot instead of many\n"
<< " -stats <1|0> Show scanline and framerate info during emulation\n"
<< " -ss1x <1|0> Generate TIA snapshot in 1x mode (ignore scaling)\n"
<< " -stats <1|0> Overlay console info during emulation\n"
<< endl
<< " -listrominfo Display contents of stella.pro, one line per ROM entry\n"
<< " -rominfo <rom> Display detailed information for the given ROM\n"

View File

@ -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: AboutDialog.cxx,v 1.28 2009-01-03 15:44:13 stephena Exp $
// $Id: AboutDialog.cxx,v 1.29 2009-01-03 22:57:12 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -195,7 +195,7 @@ void AboutDialog::displayInfo()
{
const char *str = dscStr[i].c_str();
TextAlignment align = kTextAlignCenter;
UIColor color = kTextColor;
uInt32 color = kTextColor;
while (str[0] == '\\')
{

View File

@ -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: FileSnapDialog.cxx,v 1.23 2009-01-01 22:44:14 stephena Exp $
// $Id: FileSnapDialog.cxx,v 1.24 2009-01-03 22:57:12 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -116,9 +116,15 @@ FileSnapDialog::FileSnapDialog(
// Snapshot single or multiple saves
xpos = 30; ypos += b->getHeight() + 5;
mySnapSingleCheckbox = new CheckboxWidget(this, font, xpos, ypos,
"Multiple snapshots");
wid.push_back(mySnapSingleCheckbox);
mySnapSingle = new CheckboxWidget(this, font, xpos, ypos,
"Multiple snapshots");
wid.push_back(mySnapSingle);
// Snapshot in 1x mode (ignore scaling)
xpos += mySnapSingle->getWidth() + 20;
mySnap1x = new CheckboxWidget(this, font, xpos, ypos,
"Snapshot in 1x mode");
wid.push_back(mySnap1x);
// Add Defaults, OK and Cancel buttons
b = new ButtonWidget(this, font, 10, _h - buttonHeight - 10,
@ -155,7 +161,8 @@ void FileSnapDialog::loadConfig()
myPaletteFile->setEditString(instance().paletteFile());
myPropsFile->setEditString(instance().propertiesFile());
mySnapPath->setEditString(instance().settings().getString("ssdir"));
mySnapSingleCheckbox->setState(!instance().settings().getBool("sssingle"));
mySnapSingle->setState(!instance().settings().getBool("sssingle"));
mySnap1x->setState(instance().settings().getBool("ss1x"));
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -167,7 +174,8 @@ void FileSnapDialog::saveConfig()
instance().settings().setString("palettefile", myPaletteFile->getEditString());
instance().settings().setString("propsfile", myPropsFile->getEditString());
instance().settings().setString("ssdir", mySnapPath->getEditString());
instance().settings().setBool("sssingle", !mySnapSingleCheckbox->getState());
instance().settings().setBool("sssingle", !mySnapSingle->getState());
instance().settings().setBool("ss1x", mySnap1x->getState());
// Flush changes to disk and inform the OSystem
instance().settings().saveConfig();
@ -192,7 +200,8 @@ void FileSnapDialog::setDefaults()
myPropsFile->setEditString(propsfile);
mySnapPath->setEditString(ssdir);
mySnapSingleCheckbox->setState(true);
mySnapSingle->setState(true);
mySnap1x->setState(false);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -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: FileSnapDialog.hxx,v 1.11 2009-01-01 18:13:38 stephena Exp $
// $Id: FileSnapDialog.hxx,v 1.12 2009-01-03 22:57:12 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -75,7 +75,8 @@ class FileSnapDialog : public Dialog, public CommandSender
EditTextWidget* myPaletteFile;
EditTextWidget* myPropsFile;
EditTextWidget* mySnapPath;
CheckboxWidget* mySnapSingleCheckbox;
CheckboxWidget* mySnapSingle;
CheckboxWidget* mySnap1x;
// Indicates if this dialog is used for global (vs. in-game) settings
bool myIsGlobal;

View File

@ -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: RomInfoWidget.cxx,v 1.13 2009-01-01 18:13:39 stephena Exp $
// $Id: RomInfoWidget.cxx,v 1.14 2009-01-03 22:57:12 stephena Exp $
//============================================================================
#include <cstring>
@ -289,7 +289,7 @@ bool RomInfoWidget::parseIDATChunk(FBSurface* surface, int width, int height,
spitch = sw * 3; // bytes per line of the surface/line
uLongf bufsize = ipitch * height;
uInt8* buffer = new uInt8[bufsize];
uInt8* line = new uInt8[spitch + myZoomLevel*3]; // few extra bytes for rounding issues
uInt32* line = new uInt32[spitch + 3]; // few extra bytes for rounding issues
if(uncompress(buffer, &bufsize, data, size) == Z_OK)
{
@ -297,6 +297,42 @@ bool RomInfoWidget::parseIDATChunk(FBSurface* surface, int width, int height,
uInt32 buf_offset = ipitch * izoom;
uInt32 i_offset = 3 * izoom;
uInt32 srow = 0;
// Grab each non-duplicate row of data from the image
for(int irow = 0; irow < height; irow += izoom, buf_ptr += buf_offset)
{
// Scale the image data into the temporary line buffer
uInt8* i_ptr = buf_ptr;
uInt32* l_ptr = line;
for(int icol = 0; icol < width; icol += izoom, i_ptr += i_offset)
{
uInt32 pixel =
instance().frameBuffer().mapRGB(*i_ptr, *(i_ptr+1), *(i_ptr+2));
uInt32 xstride = myZoomLevel;
while(xstride--)
*l_ptr++ = pixel;
}
// Then fill the surface with those bytes
uInt32 ystride = myZoomLevel;
while(ystride--)
surface->drawPixels(line, 0, srow++, spitch);
}
delete[] buffer;
delete[] line;
return true;
}
delete[] buffer;
delete[] line;
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string RomInfoWidget::parseTextChunk(uInt8* data, int size)
{
return "";
}
/*
cerr << "surface:" << endl
<< " w = " << sw << endl
@ -315,39 +351,3 @@ cerr << "image:" << endl
<< " i_offset = " << i_offset << endl
<< endl;
*/
// Grab each non-duplicate row of data from the image
for(int irow = 0; irow < height; irow += izoom, buf_ptr += buf_offset)
{
// Scale the image data into the temporary line buffer
uInt8* i_ptr = buf_ptr;
uInt8* l_ptr = line;
for(int icol = 0; icol < width; icol += izoom, i_ptr += i_offset)
{
uInt32 xstride = myZoomLevel;
while(xstride--)
{
*l_ptr++ = *i_ptr;
*l_ptr++ = *(i_ptr+1);
*l_ptr++ = *(i_ptr+2);
}
}
// Then fill the surface with those bytes
uInt32 ystride = myZoomLevel;
while(ystride--)
surface->drawBytes(line, 0, srow++, spitch);
}
delete[] buffer;
delete[] line;
return true;
}
delete[] buffer;
delete[] line;
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string RomInfoWidget::parseTextChunk(uInt8* data, int size)
{
return "";
}

View File

@ -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: StringListWidget.cxx,v 1.13 2009-01-03 15:44:13 stephena Exp $
// $Id: StringListWidget.cxx,v 1.14 2009-01-03 22:57:12 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -61,8 +61,8 @@ void StringListWidget::drawWidget(bool hilite)
// Draw the list items
for (i = 0, pos = _currentPos; i < _rows && pos < len; i++, pos++)
{
const UIColor textColor = (_selectedItem == pos && _editMode)
? kColor : kTextColor;
const uInt32 textColor = (_selectedItem == pos && _editMode)
? kColor : kTextColor;
const int y = _y + 2 + _fontHeight * i;
// Draw the selected item inverted, on a highlighted background.

View File

@ -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: TabWidget.cxx,v 1.34 2009-01-03 15:44:13 stephena Exp $
// $Id: TabWidget.cxx,v 1.35 2009-01-03 22:57:12 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -252,7 +252,7 @@ void TabWidget::loadConfig()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TabWidget::box(int x, int y, int width, int height,
UIColor colorA, UIColor colorB, bool omitBottom)
uInt32 colorA, uInt32 colorB, bool omitBottom)
{
//cerr << "TabWidget::box\n";
FBSurface& s = _boss->dialog().surface();
@ -294,8 +294,8 @@ void TabWidget::drawWidget(bool hilite)
int i, x = _x + kTabLeftOffset;
for (i = 0; i < (int)_tabs.size(); ++i)
{
UIColor fontcolor = _tabs[i].enabled ? kTextColor : kColor;
UIColor boxcolor = (i == _activeTab) ? kColor : kShadowColor;
uInt32 fontcolor = _tabs[i].enabled ? kTextColor : kColor;
uInt32 boxcolor = (i == _activeTab) ? kColor : kShadowColor;
int yOffset = (i == _activeTab) ? 0 : 2;
box(x, _y + yOffset, _tabWidth, _tabHeight - yOffset, boxcolor, boxcolor, (i == _activeTab));
s.drawString(_font, _tabs[i].title, x + kTabPadding,

View File

@ -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: TabWidget.hxx,v 1.22 2009-01-03 15:44:13 stephena Exp $
// $Id: TabWidget.hxx,v 1.23 2009-01-03 22:57:12 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -91,7 +91,7 @@ class TabWidget : public Widget, public CommandSender
private:
void box(int x, int y, int width, int height,
UIColor colorA, UIColor colorB, bool omitBottom);
uInt32 colorA, uInt32 colorB, bool omitBottom);
void updateActiveTab();
};

View File

@ -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: Widget.cxx,v 1.60 2009-01-03 15:44:13 stephena Exp $
// $Id: Widget.cxx,v 1.61 2009-01-03 22:57:12 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -516,8 +516,8 @@ void CheckboxWidget::drawWidget(bool hilite)
{
if(_state)
{
unsigned int* img = _fillRect ? checked_img_o : checked_img_x;
UIColor color = _fillRect ? kWidFrameColor : kCheckColor;
uInt32* img = _fillRect ? checked_img_o : checked_img_x;
uInt32 color = _fillRect ? kWidFrameColor : kCheckColor;
s.drawBitmap(img, _x + 3, _y + _boxY + 3, color);
}
}

View File

@ -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: Widget.hxx,v 1.65 2009-01-03 15:44:13 stephena Exp $
// $Id: Widget.hxx,v 1.66 2009-01-03 22:57:12 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -83,7 +83,7 @@ enum {
This is the base class for all widgets.
@author Stephen Anthony
@version $Id: Widget.hxx,v 1.65 2009-01-03 15:44:13 stephena Exp $
@version $Id: Widget.hxx,v 1.66 2009-01-03 22:57:12 stephena Exp $
*/
class Widget : public GuiObject
{
@ -135,10 +135,10 @@ class Widget : public GuiObject
virtual const GUI::Font* font() { return _font; }
void setTextColor(UIColor color) { _textcolor = color; }
void setTextColorHi(UIColor color) { _textcolorhi = color; }
void setBGColor(UIColor color) { _bgcolor = color; }
void setBGColorHi(UIColor color) { _bgcolorhi = color; }
void setTextColor(uInt32 color) { _textcolor = color; }
void setTextColorHi(uInt32 color) { _textcolorhi = color; }
void setBGColor(uInt32 color) { _bgcolor = color; }
void setBGColorHi(uInt32 color) { _bgcolorhi = color; }
virtual void loadConfig() {}
@ -166,10 +166,10 @@ class Widget : public GuiObject
bool _hasFocus;
int _fontWidth;
int _fontHeight;
UIColor _bgcolor;
UIColor _bgcolorhi;
UIColor _textcolor;
UIColor _textcolorhi;
uInt32 _bgcolor;
uInt32 _bgcolorhi;
uInt32 _textcolor;
uInt32 _textcolorhi;
public:
static Widget* findWidgetInChain(Widget* start, int x, int y);
@ -266,7 +266,7 @@ class CheckboxWidget : public ButtonWidget
bool _fillRect;
bool _drawBox;
UIColor _fillColor;
uInt32 _fillColor;
private:
int _boxY;