Some pretty huge changes right across the board.

Changed pointers to references in c'tor calls, making things a little safer.

Removed FBSurfaceTIA, since it was tied too closely to SDL itself.  Added a
class called TIASurface that is functionally very similar, but is more generic
and accessible by the FrameBuffer directly.  Eventually, this class will take
responsibility for all things related to rendering the TIA image (Blargg TV
effects, phosphor mode, etc).

TIA rendering is currently borked; fixes will follow ...


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2889 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2014-05-12 23:34:25 +00:00
parent d57184a4fc
commit c8b27ec114
39 changed files with 1095 additions and 1217 deletions

View File

@ -21,7 +21,7 @@
#include "EventHandlerSDL2.hxx" #include "EventHandlerSDL2.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
EventHandlerSDL2::EventHandlerSDL2(OSystem* osystem) EventHandlerSDL2::EventHandlerSDL2(OSystem& osystem)
: EventHandler(osystem) : EventHandler(osystem)
{ {
} }

View File

@ -37,7 +37,7 @@ class EventHandlerSDL2 : public EventHandler
/** /**
Create a new SDL2 event handler object Create a new SDL2 event handler object
*/ */
EventHandlerSDL2(OSystem* osystem); EventHandlerSDL2(OSystem& osystem);
/** /**
Destructor Destructor

View File

@ -21,8 +21,7 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FBSurfaceSDL2::FBSurfaceSDL2(FrameBufferSDL2& buffer, uInt32 width, uInt32 height) FBSurfaceSDL2::FBSurfaceSDL2(FrameBufferSDL2& buffer, uInt32 width, uInt32 height)
: FBSurface(buffer.myDefPalette), : myFB(buffer),
myFB(buffer),
mySurface(NULL), mySurface(NULL),
myTexture(NULL), myTexture(NULL),
mySurfaceIsDirty(true), mySurfaceIsDirty(true),
@ -111,19 +110,6 @@ void FBSurfaceSDL2::setStaticContents(const uInt32* pixels, uInt32 pitch)
reload(); reload();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurfaceSDL2::setInterpolationAndBlending(
bool smoothScale, bool useBlend, uInt32 blendAlpha)
{
myInterpolate = smoothScale;
myBlendEnabled = useBlend;
myBlendAlpha = uInt8(blendAlpha * 2.55);
// Re-create the texture with the new settings
free();
reload();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 FBSurfaceSDL2::width() const uInt32 FBSurfaceSDL2::width() const
{ {
@ -236,3 +222,18 @@ void FBSurfaceSDL2::reload()
SDL_SetTextureAlphaMod(myTexture, myBlendAlpha); SDL_SetTextureAlphaMod(myTexture, myBlendAlpha);
} }
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurfaceSDL2::applyAttributes(bool immediate)
{
myInterpolate = myAttributes.smoothing;
myBlendEnabled = myAttributes.blending;
myBlendAlpha = uInt8(myAttributes.blendalpha * 2.55);
if(immediate)
{
// Re-create the texture with the new settings
free();
reload();
}
}

View File

@ -33,7 +33,6 @@ class FBSurfaceSDL2 : public FBSurface
{ {
public: public:
FBSurfaceSDL2(FrameBufferSDL2& buffer, uInt32 width, uInt32 height); FBSurfaceSDL2(FrameBufferSDL2& buffer, uInt32 width, uInt32 height);
virtual ~FBSurfaceSDL2(); virtual ~FBSurfaceSDL2();
// Most of the surface drawing primitives are implemented in FBSurface; // Most of the surface drawing primitives are implemented in FBSurface;
@ -44,8 +43,6 @@ class FBSurfaceSDL2 : public FBSurface
void addDirtyRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h); void addDirtyRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h);
void setStaticContents(const uInt32* pixels, uInt32 pitch); void setStaticContents(const uInt32* pixels, uInt32 pitch);
void setInterpolationAndBlending(bool smoothScale, bool useBlend,
uInt32 blendAlpha);
uInt32 width() const; uInt32 width() const;
uInt32 height() const; uInt32 height() const;
@ -63,6 +60,9 @@ class FBSurfaceSDL2 : public FBSurface
void free(); void free();
void reload(); void reload();
protected:
void applyAttributes(bool immediate);
private: private:
FrameBufferSDL2& myFB; FrameBufferSDL2& myFB;

View File

@ -1,237 +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-2014 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 <cmath>
#include "NTSCFilter.hxx"
#include "TIA.hxx"
#include "FBSurfaceTIA.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FBSurfaceTIA::FBSurfaceTIA(FrameBufferSDL2& buffer)
: FBSurface(buffer.myDefPalette),
myFB(buffer),
mySurface(NULL),
myTexture(NULL),
myScanlines(NULL),
myScanlinesEnabled(false),
myScanlineIntensity(50)
{
// Texture width is set to contain all possible sizes for a TIA image,
// including Blargg filtering
int width = ATARI_NTSC_OUT_WIDTH(160);
int height = 320;
// Create a surface in the same format as the parent GL class
const SDL_PixelFormat* pf = myFB.myPixelFormat;
mySurface = SDL_CreateRGBSurface(0, width, height*2,
pf->BitsPerPixel, pf->Rmask, pf->Gmask, pf->Bmask, pf->Amask);
mySrcR.x = mySrcR.y = myDstR.x = myDstR.y = myScanR.x = myScanR.y = 0;
mySrcR.w = myDstR.w = width;
mySrcR.h = myDstR.h = height;
myScanR.w = 1; myScanR.h = 0;
myPitch = mySurface->pitch / pf->BytesPerPixel;
// Generate scanline data
myScanData = new uInt32[mySurface->h];
for(int i = 0; i < mySurface->h; i+=2)
{
myScanData[i] = 0x00000000;
myScanData[i+1] = 0xff000000;
}
// To generate textures
reload();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FBSurfaceTIA::~FBSurfaceTIA()
{
if(mySurface)
SDL_FreeSurface(mySurface);
free();
delete[] myScanData;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurfaceTIA::getPos(uInt32& x, uInt32& y) const
{
x = mySrcR.x;
y = mySrcR.y;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurfaceTIA::translateCoords(Int32& x, Int32& y) const
{
x = mySrcR.x;
y = mySrcR.y;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurfaceTIA::render()
{
// Copy the mediasource framebuffer to the RGB texture
// In hardware rendering mode, it's faster to just assume that the screen
// is dirty and always do an update
uInt8* currentFrame = myTIA->currentFrameBuffer();
uInt8* previousFrame = myTIA->previousFrameBuffer();
uInt32 width = myTIA->width();
uInt32 height = myTIA->height();
uInt32* buffer = (uInt32*) mySurface->pixels;
// TODO - Eventually 'phosphor' won't be a separate mode, and will become
// a post-processing filter by blending several frames.
switch(myFB.myFilterType)
{
case FrameBufferSDL2::kNormal:
{
uInt32 bufofsY = 0;
uInt32 screenofsY = 0;
for(uInt32 y = 0; y < height; ++y)
{
uInt32 pos = screenofsY;
for(uInt32 x = 0; x < width; ++x)
buffer[pos++] = (uInt32) myFB.myDefPalette[currentFrame[bufofsY + x]];
bufofsY += width;
screenofsY += myPitch;
}
break;
}
case FrameBufferSDL2::kPhosphor:
{
uInt32 bufofsY = 0;
uInt32 screenofsY = 0;
for(uInt32 y = 0; y < height; ++y)
{
uInt32 pos = screenofsY;
for(uInt32 x = 0; x < width; ++x)
{
const uInt32 bufofs = bufofsY + x;
buffer[pos++] = (uInt32)
myFB.myAvgPalette[currentFrame[bufofs]][previousFrame[bufofs]];
}
bufofsY += width;
screenofsY += myPitch;
}
break;
}
case FrameBufferSDL2::kBlarggNormal:
{
myFB.myNTSCFilter.blit_single(currentFrame, width, height,
buffer, mySurface->pitch);
break;
}
case FrameBufferSDL2::kBlarggPhosphor:
{
myFB.myNTSCFilter.blit_double(currentFrame, previousFrame, width, height,
buffer, mySurface->pitch);
break;
}
}
// Draw TIA image
SDL_UpdateTexture(myTexture, &mySrcR, mySurface->pixels, mySurface->pitch);
SDL_RenderCopy(myFB.myRenderer, myTexture, &mySrcR, &myDstR);
// Draw overlaying scanlines
if(myScanlinesEnabled)
SDL_RenderCopy(myFB.myRenderer, myScanlines, &myScanR, &myDstR);
// Let postFrameUpdate() know that a change has been made
myFB.myDirtyFlag = true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurfaceTIA::invalidate()
{
SDL_FillRect(mySurface, NULL, 0);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurfaceTIA::free()
{
if(myTexture)
{
SDL_DestroyTexture(myTexture);
myTexture = NULL;
}
if(myScanlines)
{
SDL_DestroyTexture(myScanlines);
myScanlines = NULL;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurfaceTIA::reload()
{
// Re-create texture; the underlying SDL_Surface is fine as-is
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, myTexFilter[0] ? "1" : "0");
myTexture = SDL_CreateTexture(myFB.myRenderer,
myFB.myPixelFormat->format, SDL_TEXTUREACCESS_STREAMING,
mySurface->w, mySurface->h);
// Re-create scanline texture (contents don't change)
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, myTexFilter[1] ? "1" : "0");
myScanlines = SDL_CreateTexture(myFB.myRenderer,
myFB.myPixelFormat->format, SDL_TEXTUREACCESS_STATIC,
1, mySurface->h);
SDL_SetTextureBlendMode(myScanlines, SDL_BLENDMODE_BLEND);
SDL_SetTextureAlphaMod(myScanlines, Uint8(myScanlineIntensity*2.55));
SDL_UpdateTexture(myScanlines, &myScanR, myScanData, 4);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurfaceTIA::updateCoords(uInt32 baseH,
uInt32 imgX, uInt32 imgY, uInt32 imgW, uInt32 imgH)
{
mySrcR.h = baseH;
myDstR.w = imgW;
myDstR.h = imgH;
// Scanline repeating is sensitive to non-integral vertical resolution,
// so rounding is performed to eliminate it
// This won't be 100% accurate, but non-integral scaling isn't 100%
// accurate anyway
myScanR.w = 1;
myScanR.h = int(2 * float(imgH) / floor(((float)imgH / baseH) + 0.5));
updateCoords();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurfaceTIA::updateCoords()
{
// Normal TIA rendering and TV effects use different widths
// We use the same buffer, and only pick the width we need
mySrcR.w = myFB.ntscEnabled() ? ATARI_NTSC_OUT_WIDTH(160) : 160;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurfaceTIA::setTIAPalette(const uInt32* palette)
{
myFB.myNTSCFilter.setTIAPalette(myFB, palette);
}

View File

@ -1,104 +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-2014 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 FB_SURFACE_TIA_HXX
#define FB_SURFACE_TIA_HXX
#include "bspf.hxx"
#include "FrameBuffer.hxx"
#include "FrameBufferSDL2.hxx"
/**
A surface suitable for SDL Render2D API and rendering from a TIA source.
It doesn't implement most of the drawing primitives, since it's concerned
with TIA images only. This class extends FrameBuffer::FBSurface.
@author Stephen Anthony
*/
class FBSurfaceTIA : public FBSurface
{
friend class FrameBufferSDL2;
public:
FBSurfaceTIA(FrameBufferSDL2& buffer);
virtual ~FBSurfaceTIA();
// TIA surfaces don't implement most of the drawing primitives,
// only the methods absolutely necessary for dealing with drawing
// a TIA image
void translateCoords(Int32& x, Int32& y) const;
void render();
void invalidate();
void free();
void reload();
void setStaticContents(const uInt32* pixels, uInt32 pitch) { }
void setInterpolationAndBlending(bool smoothScale, bool useBlend,
uInt32 blendAlpha) { }
uInt32 width() const { return 0; }
uInt32 height() const { return 0; }
const GUI::Rect& srcRect() { return GUI::Rect(); }
const GUI::Rect& dstRect() { return GUI::Rect(); }
///////////////////////////////////////////////////////
void getPos(uInt32& x, uInt32& y) const;
uInt32 getWidth() const { return myDstR.w; }
uInt32 getHeight() const { return myDstR.h; }
///////////////////////////////////////////////////////
void setSrcPos(uInt32 x, uInt32 y) { }
void setSrcSize(uInt32 w, uInt32 h) { }
void setDstPos(uInt32 x, uInt32 y) { }
void setDstSize(uInt32 w, uInt32 h) { }
///////////////////////////////////////////////////////
void setPos(uInt32 x, uInt32 y) { }
void setWidth(uInt32 w) { }
void setHeight(uInt32 h) { }
///////////////////////////////////////////////////////
private:
void setTIA(const TIA& tia) { myTIA = &tia; }
void setTIAPalette(const uInt32* palette);
void enableScanlines(bool enable) { myScanlinesEnabled = enable; }
void setScanIntensity(uInt32 intensity) { myScanlineIntensity = intensity; }
void setTexInterpolation(bool enable) { myTexFilter[0] = enable; }
void setScanInterpolation(bool enable) { myTexFilter[1] = enable; }
void updateCoords(uInt32 baseH, uInt32 imgX, uInt32 imgY, uInt32 imgW, uInt32 imgH);
void updateCoords();
private:
FrameBufferSDL2& myFB;
const TIA* myTIA;
SDL_Surface* mySurface;
SDL_Texture* myTexture;
SDL_Texture* myScanlines;
SDL_Rect mySrcR, myDstR, myScanR;
uInt32 myPitch;
bool myScanlinesEnabled;
uInt32* myScanData;
uInt32 myScanlineIntensity;
bool myTexFilter[2];
};
#endif

View File

@ -31,17 +31,14 @@
#include "TIA.hxx" #include "TIA.hxx"
#include "FBSurfaceSDL2.hxx" #include "FBSurfaceSDL2.hxx"
#include "FBSurfaceTIA.hxx"
#include "FrameBufferSDL2.hxx" #include "FrameBufferSDL2.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FrameBufferSDL2::FrameBufferSDL2(OSystem* osystem) FrameBufferSDL2::FrameBufferSDL2(OSystem& osystem)
: FrameBuffer(osystem), : FrameBuffer(osystem),
myFilterType(kNormal),
myWindow(NULL), myWindow(NULL),
myRenderer(NULL), myRenderer(NULL),
myWindowFlags(0), myWindowFlags(0),
myTiaSurface(NULL),
myDirtyFlag(true), myDirtyFlag(true),
myDblBufferedFlag(true) myDblBufferedFlag(true)
{ {
@ -50,7 +47,7 @@ FrameBufferSDL2::FrameBufferSDL2(OSystem* osystem)
{ {
ostringstream buf; ostringstream buf;
buf << "ERROR: Couldn't initialize SDL: " << SDL_GetError() << endl; buf << "ERROR: Couldn't initialize SDL: " << SDL_GetError() << endl;
myOSystem->logMessage(buf.str(), 0); myOSystem.logMessage(buf.str(), 0);
return; return;
} }
@ -76,9 +73,6 @@ FrameBufferSDL2::~FrameBufferSDL2()
SDL_DestroyWindow(myWindow); SDL_DestroyWindow(myWindow);
myWindow = NULL; myWindow = NULL;
} }
// We're taking responsibility for this surface
delete myTiaSurface;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -102,21 +96,12 @@ void FrameBufferSDL2::queryHardware(uInt32& w, uInt32& h, VariantList& renderers
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode, bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode)
bool full)
{ {
// If not initialized by this point, then immediately fail // If not initialized by this point, then immediately fail
if(SDL_WasInit(SDL_INIT_VIDEO) == 0) if(SDL_WasInit(SDL_INIT_VIDEO) == 0)
return false; return false;
bool inTIAMode =
myOSystem->eventHandler().state() != EventHandler::S_LAUNCHER &&
myOSystem->eventHandler().state() != EventHandler::S_DEBUGGER;
// Grab the initial height before it's updated below
// We need it for the creating the TIA surface
uInt32 baseHeight = mode.image.height() / mode.zoom;
// (Re)create window and renderer // (Re)create window and renderer
if(myRenderer) if(myRenderer)
{ {
@ -130,7 +115,7 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode,
} }
// Window centering option // Window centering option
int pos = myOSystem->settings().getBool("center") int pos = myOSystem.settings().getBool("center")
? SDL_WINDOWPOS_CENTERED : SDL_WINDOWPOS_UNDEFINED; ? SDL_WINDOWPOS_CENTERED : SDL_WINDOWPOS_UNDEFINED;
myWindow = SDL_CreateWindow(title.c_str(), myWindow = SDL_CreateWindow(title.c_str(),
pos, pos, mode.image.width(), mode.image.height(), pos, pos, mode.image.width(), mode.image.height(),
@ -138,60 +123,34 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode,
if(myWindow == NULL) if(myWindow == NULL)
{ {
string msg = "ERROR: Unable to open SDL window: " + string(SDL_GetError()); string msg = "ERROR: Unable to open SDL window: " + string(SDL_GetError());
myOSystem->logMessage(msg, 0); myOSystem.logMessage(msg, 0);
return false; return false;
} }
// V'synced blits option // V'synced blits option
Uint32 renderFlags = SDL_RENDERER_ACCELERATED; Uint32 renderFlags = SDL_RENDERER_ACCELERATED;
if(myOSystem->settings().getBool("vsync")) if(myOSystem.settings().getBool("vsync"))
renderFlags |= SDL_RENDERER_PRESENTVSYNC; renderFlags |= SDL_RENDERER_PRESENTVSYNC;
// Render hint // Render hint
const string& video = myOSystem->settings().getString("video"); const string& video = myOSystem.settings().getString("video");
if(video != "") if(video != "")
SDL_SetHint(SDL_HINT_RENDER_DRIVER, video.c_str()); SDL_SetHint(SDL_HINT_RENDER_DRIVER, video.c_str());
myRenderer = SDL_CreateRenderer(myWindow, -1, renderFlags); myRenderer = SDL_CreateRenderer(myWindow, -1, renderFlags);
if(myWindow == NULL) if(myWindow == NULL)
{ {
string msg = "ERROR: Unable to create SDL renderer: " + string(SDL_GetError()); string msg = "ERROR: Unable to create SDL renderer: " + string(SDL_GetError());
myOSystem->logMessage(msg, 0); myOSystem.logMessage(msg, 0);
return false; return false;
} }
SDL_RendererInfo renderinfo; SDL_RendererInfo renderinfo;
if(SDL_GetRendererInfo(myRenderer, &renderinfo) >= 0) if(SDL_GetRendererInfo(myRenderer, &renderinfo) >= 0)
{ {
myOSystem->settings().setValue("video", renderinfo.name); myOSystem.settings().setValue("video", renderinfo.name);
// For now, accelerated renderers imply double buffering // For now, accelerated renderers imply double buffering
// Eventually, SDL may be updated to query this from the render backend // Eventually, SDL may be updated to query this from the render backend
myDblBufferedFlag = renderinfo.flags & SDL_RENDERER_ACCELERATED; myDblBufferedFlag = renderinfo.flags & SDL_RENDERER_ACCELERATED;
} }
// The framebuffer only takes responsibility for TIA surfaces
// Other surfaces (such as the ones used for dialogs) are allocated
// in the Dialog class
if(inTIAMode)
{
// Since we have free hardware stretching, the base TIA surface is created
// only once, and its texture coordinates changed when we want to draw a
// smaller or larger image
if(!myTiaSurface)
myTiaSurface = new FBSurfaceTIA(*this);
myTiaSurface->updateCoords(baseHeight, mode.image.x(), mode.image.y(),
mode.image.width(), mode.image.height());
myTiaSurface->enableScanlines(ntscEnabled());
myTiaSurface->setTexInterpolation(myOSystem->settings().getBool("tia.inter"));
myTiaSurface->setScanIntensity(myOSystem->settings().getInt("tv.scanlines"));
myTiaSurface->setScanInterpolation(myOSystem->settings().getBool("tv.scaninter"));
myTiaSurface->setTIA(myOSystem->console().tia());
}
// Any previously allocated textures currently in use by various UI items
// need to be refreshed as well
// This *must* come after the TIA settings have been updated
resetSurfaces(myTiaSurface);
return true; return true;
} }
@ -218,9 +177,8 @@ string FrameBufferSDL2::about() const
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferSDL2::invalidate() void FrameBufferSDL2::invalidate()
{ {
SDL_RenderClear(myRenderer); myDirtyFlag = true;
if(myTiaSurface) // SDL_RenderClear(myRenderer);
myTiaSurface->invalidate();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -240,7 +198,7 @@ void FrameBufferSDL2::enableFullscreen(bool enable)
{ {
uInt32 flags = enable ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0; uInt32 flags = enable ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0;
if(SDL_SetWindowFullscreen(myWindow, flags)) if(SDL_SetWindowFullscreen(myWindow, flags))
myOSystem->settings().setValue("fullscreen", enable); myOSystem.settings().setValue("fullscreen", enable);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -253,13 +211,6 @@ bool FrameBufferSDL2::fullScreen() const
#endif #endif
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferSDL2::drawTIA(bool fullRedraw)
{
// The TIA surface takes all responsibility for drawing
myTiaSurface->render();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferSDL2::postFrameUpdate() void FrameBufferSDL2::postFrameUpdate()
{ {
@ -271,70 +222,6 @@ void FrameBufferSDL2::postFrameUpdate()
} }
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferSDL2::enablePhosphor(bool enable, int blend)
{
if(myTiaSurface)
{
myUsePhosphor = enable;
myPhosphorBlend = blend;
myFilterType = FilterType(enable ? myFilterType | 0x01 : myFilterType & 0x10);
myRedrawEntireFrame = true;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferSDL2::enableNTSC(bool enable)
{
if(myTiaSurface)
{
myFilterType = FilterType(enable ? myFilterType | 0x10 : myFilterType & 0x01);
myTiaSurface->updateCoords();
myTiaSurface->enableScanlines(ntscEnabled());
myTiaSurface->setScanIntensity(myOSystem->settings().getInt("tv.scanlines"));
myTiaSurface->setTexInterpolation(myOSystem->settings().getBool("tia.inter"));
myTiaSurface->setScanInterpolation(myOSystem->settings().getBool("tv.scaninter"));
myRedrawEntireFrame = true;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 FrameBufferSDL2::enableScanlines(int relative, int absolute)
{
if(myTiaSurface)
{
int intensity = myTiaSurface->myScanlineIntensity;
if(relative == 0) intensity = absolute;
else intensity += relative;
intensity = BSPF_max(0, intensity);
intensity = BSPF_min(100, intensity);
myTiaSurface->setScanIntensity(intensity);
myRedrawEntireFrame = true;
return intensity;
}
return 0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferSDL2::enableScanlineInterpolation(bool enable)
{
if(myTiaSurface)
{
myTiaSurface->setScanInterpolation(enable);
myRedrawEntireFrame = true;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferSDL2::setTIAPalette(const uInt32* palette)
{
FrameBuffer::setTIAPalette(palette);
myTiaSurface->setTIAPalette(palette);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FBSurface* FrameBufferSDL2::createSurface(uInt32 w, uInt32 h) const FBSurface* FrameBufferSDL2::createSurface(uInt32 w, uInt32 h) const
{ {
@ -354,29 +241,3 @@ void FrameBufferSDL2::scanline(uInt32 row, uInt8* data) const
p_gl.ReadPixels(image.x(), row, image.width(), 1, GL_RGB, GL_UNSIGNED_BYTE, data); p_gl.ReadPixels(image.x(), row, image.width(), 1, GL_RGB, GL_UNSIGNED_BYTE, data);
#endif #endif
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string FrameBufferSDL2::effectsInfo() const
{
ostringstream buf;
switch(myFilterType)
{
case kNormal:
buf << "Disabled, normal mode";
break;
case kPhosphor:
buf << "Disabled, phosphor mode";
break;
case kBlarggNormal:
buf << myNTSCFilter.getPreset() << ", scanlines="
<< myTiaSurface->myScanlineIntensity << "/"
<< (myTiaSurface->myTexFilter[1] ? "inter" : "nointer");
break;
case kBlarggPhosphor:
buf << myNTSCFilter.getPreset() << ", phosphor, scanlines="
<< myTiaSurface->myScanlineIntensity << "/"
<< (myTiaSurface->myTexFilter[1] ? "inter" : "nointer");
break;
}
return buf.str();
}

View File

@ -24,8 +24,6 @@
class OSystem; class OSystem;
class FBSurfaceSDL2; class FBSurfaceSDL2;
class FBSurfaceTIA;
class TIA;
#include "bspf.hxx" #include "bspf.hxx"
#include "FrameBuffer.hxx" #include "FrameBuffer.hxx"
@ -40,13 +38,12 @@ class TIA;
class FrameBufferSDL2 : public FrameBuffer class FrameBufferSDL2 : public FrameBuffer
{ {
friend class FBSurfaceSDL2; friend class FBSurfaceSDL2;
friend class FBSurfaceTIA;
public: public:
/** /**
Creates a new SDL2 framebuffer Creates a new SDL2 framebuffer
*/ */
FrameBufferSDL2(OSystem* osystem); FrameBufferSDL2(OSystem& osystem);
/** /**
Destructor Destructor
@ -72,24 +69,6 @@ class FrameBufferSDL2 : public FrameBuffer
*/ */
bool fullScreen() const; bool fullScreen() const;
/**
Enable/disable phosphor effect.
*/
void enablePhosphor(bool enable, int blend);
/**
Enable/disable NTSC filtering effects.
*/
void enableNTSC(bool enable);
bool ntscEnabled() const { return myFilterType & 0x10; }
/**
Set up the TIA/emulation palette for a screen of any depth > 8.
@param palette The array of colors
*/
void setTIAPalette(const uInt32* palette);
/** /**
This method is called to retrieve the R/G/B data from the given pixel. This method is called to retrieve the R/G/B data from the given pixel.
@ -116,11 +95,6 @@ class FrameBufferSDL2 : public FrameBuffer
*/ */
bool isDoubleBuffered() const { return myDblBufferedFlag; } bool isDoubleBuffered() const { return myDblBufferedFlag; }
/**
This method is called to query the TV effects in use by the FrameBuffer.
*/
string effectsInfo() const;
/** /**
This method is called to get the specified scanline data. This method is called to get the specified scanline data.
@ -140,16 +114,14 @@ class FrameBufferSDL2 : public FrameBuffer
void queryHardware(uInt32& w, uInt32& h, VariantList& renderers); void queryHardware(uInt32& w, uInt32& h, VariantList& renderers);
/** /**
This method is called to change to the given video mode. If the mode This method is called to change to the given video mode.
is successfully changed, 'mode' holds the actual dimensions used.
@param title The title for the created window @param title The title for the created window
@param mode The video mode to use @param mode The video mode to use
@param full Whether this is a fullscreen or windowed mode
@return False on any errors, else true @return False on any errors, else true
*/ */
bool setVideoMode(const string& title, const VideoMode& mode, bool full); bool setVideoMode(const string& title, const VideoMode& mode);
/** /**
Enables/disables fullscreen mode. Enables/disables fullscreen mode.
@ -181,12 +153,6 @@ class FrameBufferSDL2 : public FrameBuffer
*/ */
void setWindowIcon() { } // Not currently needed on any supported systems void setWindowIcon() { } // Not currently needed on any supported systems
/**
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 to provide information about the FrameBuffer. This method is called to provide information about the FrameBuffer.
*/ */
@ -197,27 +163,6 @@ class FrameBufferSDL2 : public FrameBuffer
*/ */
void postFrameUpdate(); void postFrameUpdate();
/**
Change scanline intensity and interpolation.
@param relative If non-zero, change current intensity by
'relative' amount, otherwise set to 'absolute'
@return New current intensity
*/
uInt32 enableScanlines(int relative, int absolute = 50);
void enableScanlineInterpolation(bool enable);
private:
// Enumeration created such that phosphor off/on is in LSB,
// and Blargg off/on is in MSB
enum FilterType {
kNormal = 0x00,
kPhosphor = 0x01,
kBlarggNormal = 0x10,
kBlarggPhosphor = 0x11
};
FilterType myFilterType;
private: private:
// The SDL video buffer // The SDL video buffer
SDL_Window* myWindow; SDL_Window* myWindow;
@ -229,10 +174,6 @@ class FrameBufferSDL2 : public FrameBuffer
// it to point to the actual flags used by the SDL_Surface // it to point to the actual flags used by the SDL_Surface
uInt32 myWindowFlags; uInt32 myWindowFlags;
// The lower-most base surface (will always be a TIA surface,
// since Dialog surfaces are allocated by the Dialog class directly).
FBSurfaceTIA* myTiaSurface;
// Used by mapRGB (when palettes are created) // Used by mapRGB (when palettes are created)
SDL_PixelFormat* myPixelFormat; SDL_PixelFormat* myPixelFormat;

View File

@ -156,8 +156,8 @@ string PNGLibrary::saveImage(const string& filename,
buf_ptr += pitch; // add pitch buf_ptr += pitch; // add pitch
} }
return saveBufferToPNG(out, buffer, width, height, return saveBufferToPNG(out, buffer, width, height, props,
props, framebuffer.effectsInfo()); framebuffer.tiaSurface().effectsInfo());
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -180,7 +180,7 @@ string PNGLibrary::saveImage(const string& filename,
*buf_ptr++ = 0; // first byte of row is filter type *buf_ptr++ = 0; // first byte of row is filter type
for(uInt32 x = 0; x < width; ++x) for(uInt32 x = 0; x < width; ++x)
{ {
uInt32 pixel = framebuffer.tiaPixel(y*width+x); uInt32 pixel = framebuffer.tiaSurface().pixel(y*width+x);
framebuffer.getRGB(pixel, &r, &g, &b); framebuffer.getRGB(pixel, &r, &g, &b);
*buf_ptr++ = r; *buf_ptr++ = r;
*buf_ptr++ = g; *buf_ptr++ = g;
@ -191,8 +191,8 @@ string PNGLibrary::saveImage(const string& filename,
} }
} }
return saveBufferToPNG(out, buffer, width << 1, height, return saveBufferToPNG(out, buffer, width << 1, height, props,
props, framebuffer.effectsInfo()); framebuffer.tiaSurface().effectsInfo());
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -40,7 +40,7 @@ class SoundNull : public Sound
Create a new sound object. The init method must be invoked before Create a new sound object. The init method must be invoked before
using the object. using the object.
*/ */
SoundNull(OSystem* osystem) : Sound(osystem) SoundNull(OSystem& osystem) : Sound(osystem)
{ {
myOSystem->logMessage("Sound disabled.\n", 1); myOSystem->logMessage("Sound disabled.\n", 1);
} }

View File

@ -33,7 +33,7 @@
#include "SoundSDL2.hxx" #include "SoundSDL2.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SoundSDL2::SoundSDL2(OSystem* osystem) SoundSDL2::SoundSDL2(OSystem& osystem)
: Sound(osystem), : Sound(osystem),
myIsEnabled(false), myIsEnabled(false),
myIsInitializedFlag(false), myIsInitializedFlag(false),
@ -43,17 +43,17 @@ SoundSDL2::SoundSDL2(OSystem* osystem)
myIsMuted(true), myIsMuted(true),
myVolume(100) myVolume(100)
{ {
myOSystem->logMessage("SoundSDL2::SoundSDL2 started ...", 2); myOSystem.logMessage("SoundSDL2::SoundSDL2 started ...", 2);
// The sound system is opened only once per program run, to eliminate // The sound system is opened only once per program run, to eliminate
// issues with opening and closing it multiple times // issues with opening and closing it multiple times
// This fixes a bug most prevalent with ATI video cards in Windows, // This fixes a bug most prevalent with ATI video cards in Windows,
// whereby sound stopped working after the first video change // whereby sound stopped working after the first video change
SDL_AudioSpec desired; SDL_AudioSpec desired;
desired.freq = myOSystem->settings().getInt("freq"); desired.freq = myOSystem.settings().getInt("freq");
desired.format = AUDIO_S16SYS; desired.format = AUDIO_S16SYS;
desired.channels = 2; desired.channels = 2;
desired.samples = myOSystem->settings().getInt("fragsize"); desired.samples = myOSystem.settings().getInt("fragsize");
desired.callback = callback; desired.callback = callback;
desired.userdata = (void*)this; desired.userdata = (void*)this;
@ -62,7 +62,7 @@ SoundSDL2::SoundSDL2(OSystem* osystem)
{ {
buf << "WARNING: Couldn't open SDL audio system! " << endl buf << "WARNING: Couldn't open SDL audio system! " << endl
<< " " << SDL_GetError() << endl; << " " << SDL_GetError() << endl;
myOSystem->logMessage(buf.str(), 0); myOSystem.logMessage(buf.str(), 0);
return; return;
} }
@ -73,7 +73,7 @@ SoundSDL2::SoundSDL2(OSystem* osystem)
buf << "WARNING: Sound device doesn't support realtime audio! Make " buf << "WARNING: Sound device doesn't support realtime audio! Make "
<< "sure a sound" << endl << "sure a sound" << endl
<< " server isn't running. Audio is disabled." << endl; << " server isn't running. Audio is disabled." << endl;
myOSystem->logMessage(buf.str(), 0); myOSystem.logMessage(buf.str(), 0);
SDL_CloseAudio(); SDL_CloseAudio();
return; return;
@ -87,7 +87,7 @@ SoundSDL2::SoundSDL2(OSystem* osystem)
myIsInitializedFlag = true; myIsInitializedFlag = true;
SDL_PauseAudio(1); SDL_PauseAudio(1);
myOSystem->logMessage("SoundSDL2::SoundSDL2 initialized", 2); myOSystem.logMessage("SoundSDL2::SoundSDL2 initialized", 2);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -100,27 +100,27 @@ SoundSDL2::~SoundSDL2()
myIsEnabled = myIsInitializedFlag = false; myIsEnabled = myIsInitializedFlag = false;
} }
myOSystem->logMessage("SoundSDL2 destroyed", 2); myOSystem.logMessage("SoundSDL2 destroyed", 2);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void SoundSDL2::setEnabled(bool state) void SoundSDL2::setEnabled(bool state)
{ {
myOSystem->settings().setValue("sound", state); myOSystem.settings().setValue("sound", state);
myOSystem->logMessage(state ? "SoundSDL2::setEnabled(true)" : myOSystem.logMessage(state ? "SoundSDL2::setEnabled(true)" :
"SoundSDL2::setEnabled(false)", 2); "SoundSDL2::setEnabled(false)", 2);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void SoundSDL2::open() void SoundSDL2::open()
{ {
myOSystem->logMessage("SoundSDL2::open started ...", 2); myOSystem.logMessage("SoundSDL2::open started ...", 2);
myIsEnabled = false; myIsEnabled = false;
mute(true); mute(true);
if(!myIsInitializedFlag || !myOSystem->settings().getBool("sound")) if(!myIsInitializedFlag || !myOSystem.settings().getBool("sound"))
{ {
myOSystem->logMessage("Sound disabled\n", 1); myOSystem.logMessage("Sound disabled\n", 1);
return; return;
} }
@ -130,7 +130,7 @@ void SoundSDL2::open()
myTIASound.channels(myHardwareSpec.channels, myNumChannels == 2); myTIASound.channels(myHardwareSpec.channels, myNumChannels == 2);
// Adjust volume to that defined in settings // Adjust volume to that defined in settings
myVolume = myOSystem->settings().getInt("volume"); myVolume = myOSystem.settings().getInt("volume");
setVolume(myVolume); setVolume(myVolume);
// Show some info // Show some info
@ -142,13 +142,13 @@ void SoundSDL2::open()
<< " Channels: " << (int)myHardwareSpec.channels << " Channels: " << (int)myHardwareSpec.channels
<< " (" << chanResult << ")" << endl << " (" << chanResult << ")" << endl
<< endl; << endl;
myOSystem->logMessage(buf.str(), 1); myOSystem.logMessage(buf.str(), 1);
// And start the SDL sound subsystem ... // And start the SDL sound subsystem ...
myIsEnabled = true; myIsEnabled = true;
mute(false); mute(false);
myOSystem->logMessage("SoundSDL2::open finished", 2); myOSystem.logMessage("SoundSDL2::open finished", 2);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -161,7 +161,7 @@ void SoundSDL2::close()
myLastRegisterSetCycle = 0; myLastRegisterSetCycle = 0;
myTIASound.reset(); myTIASound.reset();
myRegWriteQueue.clear(); myRegWriteQueue.clear();
myOSystem->logMessage("SoundSDL2::close", 2); myOSystem.logMessage("SoundSDL2::close", 2);
} }
} }
@ -193,7 +193,7 @@ void SoundSDL2::setVolume(Int32 percent)
{ {
if(myIsInitializedFlag && (percent >= 0) && (percent <= 100)) if(myIsInitializedFlag && (percent >= 0) && (percent <= 100))
{ {
myOSystem->settings().setValue("volume", percent); myOSystem.settings().setValue("volume", percent);
SDL_LockAudio(); SDL_LockAudio();
myVolume = percent; myVolume = percent;
myTIASound.volume(percent); myTIASound.volume(percent);
@ -224,7 +224,7 @@ void SoundSDL2::adjustVolume(Int8 direction)
message = "Volume set to "; message = "Volume set to ";
message += strval.str(); message += strval.str();
myOSystem->frameBuffer().showMessage(message); myOSystem.frameBuffer().showMessage(message);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -400,7 +400,7 @@ bool SoundSDL2::save(Serializer& out) const
} }
catch(...) catch(...)
{ {
myOSystem->logMessage("ERROR: SoundSDL2::save", 0); myOSystem.logMessage("ERROR: SoundSDL2::save", 0);
return false; return false;
} }
@ -441,7 +441,7 @@ bool SoundSDL2::load(Serializer& in)
} }
catch(...) catch(...)
{ {
myOSystem->logMessage("ERROR: SoundSDL2::load", 0); myOSystem.logMessage("ERROR: SoundSDL2::load", 0);
return false; return false;
} }

View File

@ -43,7 +43,7 @@ class SoundSDL2 : public Sound
Create a new sound object. The init method must be invoked before Create a new sound object. The init method must be invoked before
using the object. using the object.
*/ */
SoundSDL2(OSystem* osystem); SoundSDL2(OSystem& osystem);
/** /**
Destructor Destructor

View File

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

View File

@ -17,7 +17,7 @@
// $Id$ // $Id$
//============================================================================ //============================================================================
#include "FrameBuffer.hxx" #include "TIASurface.hxx"
#include "Settings.hxx" #include "Settings.hxx"
#include "NTSCFilter.hxx" #include "NTSCFilter.hxx"
@ -36,7 +36,7 @@ NTSCFilter::~NTSCFilter()
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void NTSCFilter::setTIAPalette(const FrameBuffer& fb, const uInt32* palette) void NTSCFilter::setTIAPalette(const TIASurface& tiaSurface, const uInt32* palette)
{ {
// Normal TIA palette contains 256 colours, where every odd indexed colour // Normal TIA palette contains 256 colours, where every odd indexed colour
// is used for PAL colour-loss effect // is used for PAL colour-loss effect
@ -58,9 +58,9 @@ void NTSCFilter::setTIAPalette(const FrameBuffer& fb, const uInt32* palette)
uInt8 gj = (palette[j] >> 8) & 0xff; uInt8 gj = (palette[j] >> 8) & 0xff;
uInt8 bj = palette[j] & 0xff; uInt8 bj = palette[j] & 0xff;
*ptr++ = fb.getPhosphor(ri, rj); *ptr++ = tiaSurface.getPhosphor(ri, rj);
*ptr++ = fb.getPhosphor(gi, gj); *ptr++ = tiaSurface.getPhosphor(gi, gj);
*ptr++ = fb.getPhosphor(bi, bj); *ptr++ = tiaSurface.getPhosphor(bi, bj);
} }
} }
// Set palette for normal fill // Set palette for normal fill

View File

@ -20,7 +20,7 @@
#ifndef NTSC_FILTER_HXX #ifndef NTSC_FILTER_HXX
#define NTSC_FILTER_HXX #define NTSC_FILTER_HXX
class FrameBuffer; class TIASurface;
class Settings; class Settings;
#include "bspf.hxx" #include "bspf.hxx"
@ -67,7 +67,7 @@ class NTSCFilter
uses this as a baseline for calculating its own internal palette uses this as a baseline for calculating its own internal palette
in YIQ format. in YIQ format.
*/ */
void setTIAPalette(const FrameBuffer& fb, const uInt32* palette); void setTIAPalette(const TIASurface& tiaSurface, const uInt32* palette);
// The following are meant to be used strictly for toggling from the GUI // The following are meant to be used strictly for toggling from the GUI
string setPreset(Preset preset); string setPreset(Preset preset);

View File

@ -28,6 +28,7 @@
#include "Debugger.hxx" #include "Debugger.hxx"
#include "DebuggerParser.hxx" #include "DebuggerParser.hxx"
#include "TIADebug.hxx" #include "TIADebug.hxx"
#include "TIASurface.hxx"
#include "TIA.hxx" #include "TIA.hxx"
#include "TiaOutputWidget.hxx" #include "TiaOutputWidget.hxx"
@ -150,7 +151,7 @@ void TiaOutputWidget::renderToSurface(FBSurface& s)
for(uInt32 x = 0; x < width; ++x, ++i) for(uInt32 x = 0; x < width; ++x, ++i)
{ {
uInt8 shift = i > scanoffset ? 1 : 0; uInt8 shift = i > scanoffset ? 1 : 0;
uInt32 pixel = instance().frameBuffer().tiaPixel(i, shift); uInt32 pixel = instance().frameBuffer().tiaSurface().pixel(i, shift);
*line_ptr++ = pixel; *line_ptr++ = pixel;
*line_ptr++ = pixel; *line_ptr++ = pixel;
} }

View File

@ -66,14 +66,14 @@
#include "Console.hxx" #include "Console.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Console::Console(OSystem* osystem, Cartridge* cart, const Properties& props) Console::Console(OSystem& osystem, Cartridge& cart, const Properties& props)
: myOSystem(osystem), : myOSystem(osystem),
myEvent(osystem->eventHandler().event()), myCart(cart),
myEvent(osystem.eventHandler().event()),
myProperties(props), myProperties(props),
myTIA(0), myTIA(0),
mySwitches(0), mySwitches(0),
mySystem(0), mySystem(0),
myCart(cart),
myCMHandler(0), myCMHandler(0),
myDisplayFormat(""), // Unknown TV format @ start myDisplayFormat(""), // Unknown TV format @ start
myFramerate(0.0), // Unknown framerate @ start myFramerate(0.0), // Unknown framerate @ start
@ -99,27 +99,27 @@ Console::Console(OSystem* osystem, Cartridge* cart, const Properties& props)
myControllers[0] = new Joystick(Controller::Left, myEvent, *mySystem); myControllers[0] = new Joystick(Controller::Left, myEvent, *mySystem);
myControllers[1] = new Joystick(Controller::Right, myEvent, *mySystem); myControllers[1] = new Joystick(Controller::Right, myEvent, *mySystem);
M6502* m6502 = new M6502(1, myOSystem->settings()); M6502* m6502 = new M6502(1, myOSystem.settings());
myRiot = new M6532(*this, myOSystem->settings()); myRiot = new M6532(*this, myOSystem.settings());
myTIA = new TIA(*this, myOSystem->sound(), myOSystem->settings()); myTIA = new TIA(*this, myOSystem.sound(), myOSystem.settings());
mySystem->attach(m6502); mySystem->attach(m6502);
mySystem->attach(myRiot); mySystem->attach(myRiot);
mySystem->attach(myTIA); mySystem->attach(myTIA);
mySystem->attach(myCart); mySystem->attach(&myCart);
// Auto-detect NTSC/PAL mode if it's requested // Auto-detect NTSC/PAL mode if it's requested
string autodetected = ""; string autodetected = "";
myDisplayFormat = myProperties.get(Display_Format); myDisplayFormat = myProperties.get(Display_Format);
if(myDisplayFormat == "AUTO" || myOSystem->settings().getBool("rominfo")) if(myDisplayFormat == "AUTO" || myOSystem.settings().getBool("rominfo"))
{ {
// Run the TIA, looking for PAL scanline patterns // Run the TIA, looking for PAL scanline patterns
// We turn off the SuperCharger progress bars, otherwise the SC BIOS // We turn off the SuperCharger progress bars, otherwise the SC BIOS
// will take over 250 frames! // will take over 250 frames!
// The 'fastscbios' option must be changed before the system is reset // The 'fastscbios' option must be changed before the system is reset
bool fastscbios = myOSystem->settings().getBool("fastscbios"); bool fastscbios = myOSystem.settings().getBool("fastscbios");
myOSystem->settings().setValue("fastscbios", true); myOSystem.settings().setValue("fastscbios", true);
mySystem->reset(true); // autodetect in reset enabled mySystem->reset(true); // autodetect in reset enabled
for(int i = 0; i < 60; ++i) for(int i = 0; i < 60; ++i)
myTIA->update(); myTIA->update();
@ -131,7 +131,7 @@ Console::Console(OSystem* osystem, Cartridge* cart, const Properties& props)
} }
// Don't forget to reset the SC progress bars again // Don't forget to reset the SC progress bars again
myOSystem->settings().setValue("fastscbios", fastscbios); myOSystem.settings().setValue("fastscbios", fastscbios);
} }
myConsoleInfo.DisplayFormat = myDisplayFormat + autodetected; myConsoleInfo.DisplayFormat = myDisplayFormat + autodetected;
@ -157,8 +157,8 @@ Console::Console(OSystem* osystem, Cartridge* cart, const Properties& props)
// Other ROMs can use it if the setting is enabled // Other ROMs can use it if the setting is enabled
bool joyallow4 = md5 == "aa1c41f86ec44c0a44eb64c332ce08af" || bool joyallow4 = md5 == "aa1c41f86ec44c0a44eb64c332ce08af" ||
md5 == "1bf503c724001b09be79c515ecfcbd03" || md5 == "1bf503c724001b09be79c515ecfcbd03" ||
myOSystem->settings().getBool("joyallow4"); myOSystem.settings().getBool("joyallow4");
myOSystem->eventHandler().allowAllDirections(joyallow4); myOSystem.eventHandler().allowAllDirections(joyallow4);
// Reset the system to its power-on state // Reset the system to its power-on state
mySystem->reset(); mySystem->reset();
@ -168,9 +168,9 @@ Console::Console(OSystem* osystem, Cartridge* cart, const Properties& props)
myConsoleInfo.CartMD5 = myProperties.get(Cartridge_MD5); myConsoleInfo.CartMD5 = myProperties.get(Cartridge_MD5);
myConsoleInfo.Control0 = myControllers[0]->about(); myConsoleInfo.Control0 = myControllers[0]->about();
myConsoleInfo.Control1 = myControllers[1]->about(); myConsoleInfo.Control1 = myControllers[1]->about();
myConsoleInfo.BankSwitch = cart->about(); myConsoleInfo.BankSwitch = myCart.about();
myCart->setRomName(myConsoleInfo.CartName); myCart.setRomName(myConsoleInfo.CartName);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -274,24 +274,24 @@ void Console::toggleFormat(int direction)
} }
myProperties.set(Display_Format, saveformat); myProperties.set(Display_Format, saveformat);
setPalette(myOSystem->settings().getString("palette")); setPalette(myOSystem.settings().getString("palette"));
setTIAProperties(); setTIAProperties();
myTIA->frameReset(); myTIA->frameReset();
initializeVideo(); // takes care of refreshing the screen initializeVideo(); // takes care of refreshing the screen
myOSystem->frameBuffer().showMessage(message); myOSystem.frameBuffer().showMessage(message);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Console::toggleColorLoss() void Console::toggleColorLoss()
{ {
bool colorloss = !myOSystem->settings().getBool("colorloss"); bool colorloss = !myOSystem.settings().getBool("colorloss");
myOSystem->settings().setValue("colorloss", colorloss); myOSystem.settings().setValue("colorloss", colorloss);
myTIA->enableColorLoss(colorloss); myTIA->enableColorLoss(colorloss);
string message = string("PAL color-loss ") + string message = string("PAL color-loss ") +
(colorloss ? "enabled" : "disabled"); (colorloss ? "enabled" : "disabled");
myOSystem->frameBuffer().showMessage(message); myOSystem.frameBuffer().showMessage(message);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -304,7 +304,7 @@ void Console::toggleColorLoss(bool state)
void Console::togglePalette() void Console::togglePalette()
{ {
string palette, message; string palette, message;
palette = myOSystem->settings().getString("palette"); palette = myOSystem.settings().getString("palette");
if(palette == "standard") // switch to z26 if(palette == "standard") // switch to z26
{ {
@ -337,8 +337,8 @@ void Console::togglePalette()
message = "Standard Stella palette"; message = "Standard Stella palette";
} }
myOSystem->settings().setValue("palette", palette); myOSystem.settings().setValue("palette", palette);
myOSystem->frameBuffer().showMessage(message); myOSystem.frameBuffer().showMessage(message);
setPalette(palette); setPalette(palette);
} }
@ -369,7 +369,7 @@ void Console::setPalette(const string& type)
(myDisplayFormat.compare(0, 5, "SECAM") == 0) ? palettes[paletteNum][2] : (myDisplayFormat.compare(0, 5, "SECAM") == 0) ? palettes[paletteNum][2] :
palettes[paletteNum][0]; palettes[paletteNum][0];
myOSystem->frameBuffer().setTIAPalette(palette); myOSystem.frameBuffer().setPalette(palette);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -382,16 +382,16 @@ void Console::togglePhosphor()
{ {
myProperties.set(Display_Phosphor, "No"); myProperties.set(Display_Phosphor, "No");
enable = false; enable = false;
myOSystem->frameBuffer().showMessage("Phosphor effect disabled"); myOSystem.frameBuffer().showMessage("Phosphor effect disabled");
} }
else else
{ {
myProperties.set(Display_Phosphor, "Yes"); myProperties.set(Display_Phosphor, "Yes");
enable = true; enable = true;
myOSystem->frameBuffer().showMessage("Phosphor effect enabled"); myOSystem.frameBuffer().showMessage("Phosphor effect enabled");
} }
myOSystem->frameBuffer().enablePhosphor(enable, blend); myOSystem.frameBuffer().tiaSurface().enablePhosphor(enable, blend);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -403,35 +403,30 @@ void Console::setProperties(const Properties& props)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FBInitStatus Console::initializeVideo(bool full) FBInitStatus Console::initializeVideo(bool full)
{ {
setPalette(myOSystem.settings().getString("palette"));
FBInitStatus fbstatus = kSuccess; FBInitStatus fbstatus = kSuccess;
if(full) if(full)
{ {
const string& title = string("Stella ") + STELLA_VERSION + const string& title = string("Stella ") + STELLA_VERSION +
": \"" + myProperties.get(Cartridge_Name) + "\""; ": \"" + myProperties.get(Cartridge_Name) + "\"";
fbstatus = myOSystem->frameBuffer().createDisplay(title, fbstatus = myOSystem.frameBuffer().createDisplay(title,
myTIA->width() << 1, myTIA->height()); myTIA->width() << 1, myTIA->height());
if(fbstatus != kSuccess) if(fbstatus != kSuccess)
return fbstatus; return fbstatus;
myOSystem->frameBuffer().showFrameStats(myOSystem->settings().getBool("stats")); myOSystem.frameBuffer().showFrameStats(myOSystem.settings().getBool("stats"));
setColorLossPalette(); generateColorLossPalette();
} }
bool enable = myProperties.get(Display_Phosphor) == "YES";
int blend = atoi(myProperties.get(Display_PPBlend).c_str());
myOSystem->frameBuffer().enablePhosphor(enable, blend);
myOSystem->frameBuffer().setNTSC(
(NTSCFilter::Preset)myOSystem->settings().getInt("tv.filter"), false);
setPalette(myOSystem->settings().getString("palette"));
// Set the correct framerate based on the format of the ROM // Set the correct framerate based on the format of the ROM
// This can be overridden by changing the framerate in the // This can be overridden by changing the framerate in the
// VideoDialog box or on the commandline, but it can't be saved // VideoDialog box or on the commandline, but it can't be saved
// (ie, framerate is now determined based on number of scanlines). // (ie, framerate is now determined based on number of scanlines).
int framerate = myOSystem->settings().getInt("framerate"); int framerate = myOSystem.settings().getInt("framerate");
if(framerate > 0) myFramerate = float(framerate); if(framerate > 0) myFramerate = float(framerate);
myOSystem->setFramerate(myFramerate); myOSystem.setFramerate(myFramerate);
// Make sure auto-frame calculation is only enabled when necessary // Make sure auto-frame calculation is only enabled when necessary
myTIA->enableAutoFrame(framerate <= 0); myTIA->enableAutoFrame(framerate <= 0);
@ -445,20 +440,19 @@ void Console::initializeAudio()
// Initialize the sound interface. // Initialize the sound interface.
// The # of channels can be overridden in the AudioDialog box or on // The # of channels can be overridden in the AudioDialog box or on
// the commandline, but it can't be saved. // the commandline, but it can't be saved.
int framerate = myOSystem->settings().getInt("framerate"); int framerate = myOSystem.settings().getInt("framerate");
if(framerate > 0) myFramerate = float(framerate); if(framerate > 0) myFramerate = float(framerate);
const string& sound = myProperties.get(Cartridge_Sound); const string& sound = myProperties.get(Cartridge_Sound);
myOSystem->sound().close(); myOSystem.sound().close();
myOSystem->sound().setChannels(sound == "STEREO" ? 2 : 1); myOSystem.sound().setChannels(sound == "STEREO" ? 2 : 1);
myOSystem->sound().setFrameRate(myFramerate); myOSystem.sound().setFrameRate(myFramerate);
myOSystem->sound().open(); myOSystem.sound().open();
// Make sure auto-frame calculation is only enabled when necessary // Make sure auto-frame calculation is only enabled when necessary
myTIA->enableAutoFrame(framerate <= 0); myTIA->enableAutoFrame(framerate <= 0);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/* Original frying research and code by Fred Quimby. /* Original frying research and code by Fred Quimby.
I've tried the following variations on this code: I've tried the following variations on this code:
- Both OR and Exclusive OR instead of AND. This generally crashes the game - Both OR and Exclusive OR instead of AND. This generally crashes the game
@ -478,6 +472,7 @@ void Console::initializeAudio()
Until someone comes up with a more accurate way to emulate frying, I'm Until someone comes up with a more accurate way to emulate frying, I'm
leaving this as Fred posted it. -- B. leaving this as Fred posted it. -- B.
*/ */
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Console::fry() const void Console::fry() const
{ {
for (int ZPmem=0; ZPmem<0x100; ZPmem += rand() % 4) for (int ZPmem=0; ZPmem<0x100; ZPmem += rand() % 4)
@ -493,7 +488,7 @@ void Console::changeYStart(int direction)
{ {
if(ystart >= 64) if(ystart >= 64)
{ {
myOSystem->frameBuffer().showMessage("YStart at maximum"); myOSystem.frameBuffer().showMessage("YStart at maximum");
return; return;
} }
ystart++; ystart++;
@ -502,7 +497,7 @@ void Console::changeYStart(int direction)
{ {
if(ystart == 0) if(ystart == 0)
{ {
myOSystem->frameBuffer().showMessage("YStart at minimum"); myOSystem.frameBuffer().showMessage("YStart at minimum");
return; return;
} }
ystart--; ystart--;
@ -512,11 +507,11 @@ void Console::changeYStart(int direction)
myTIA->setYStart(ystart); myTIA->setYStart(ystart);
myTIA->frameReset(); myTIA->frameReset();
myOSystem->frameBuffer().refresh(); myOSystem.frameBuffer().refresh();
ostringstream val; ostringstream val;
val << ystart; val << ystart;
myOSystem->frameBuffer().showMessage("YStart " + val.str()); myOSystem.frameBuffer().showMessage("YStart " + val.str());
myProperties.set(Display_YStart, val.str()); myProperties.set(Display_YStart, val.str());
} }
@ -524,14 +519,14 @@ void Console::changeYStart(int direction)
void Console::changeHeight(int direction) void Console::changeHeight(int direction)
{ {
uInt32 height = myTIA->height(); uInt32 height = myTIA->height();
uInt32 dheight = myOSystem->frameBuffer().desktopSize().h; uInt32 dheight = myOSystem.frameBuffer().desktopSize().h;
if(direction == +1) // increase Height if(direction == +1) // increase Height
{ {
height++; height++;
if(height > 256 || height > dheight) if(height > 256 || height > dheight)
{ {
myOSystem->frameBuffer().showMessage("Height at maximum"); myOSystem.frameBuffer().showMessage("Height at maximum");
return; return;
} }
} }
@ -540,7 +535,7 @@ void Console::changeHeight(int direction)
height--; height--;
if(height < 210) if(height < 210)
{ {
myOSystem->frameBuffer().showMessage("Height at minimum"); myOSystem.frameBuffer().showMessage("Height at minimum");
return; return;
} }
} }
@ -553,7 +548,7 @@ void Console::changeHeight(int direction)
ostringstream val; ostringstream val;
val << height; val << height;
myOSystem->frameBuffer().showMessage("Height " + val.str()); myOSystem.frameBuffer().showMessage("Height " + val.str());
myProperties.set(Display_Height, val.str()); myProperties.set(Display_Height, val.str());
} }
@ -586,7 +581,7 @@ void Console::setTIAProperties()
// Make sure these values fit within the bounds of the desktop // Make sure these values fit within the bounds of the desktop
// If not, attempt to center vertically // If not, attempt to center vertically
uInt32 dheight = myOSystem->frameBuffer().desktopSize().h; uInt32 dheight = myOSystem.frameBuffer().desktopSize().h;
if(height > dheight) if(height > dheight)
{ {
ystart += height - dheight; ystart += height - dheight;
@ -612,7 +607,7 @@ void Console::setControllers(const string& rommd5)
if(left == "COMPUMATE" || right == "COMPUMATE") if(left == "COMPUMATE" || right == "COMPUMATE")
{ {
delete myCMHandler; delete myCMHandler;
myCMHandler = new CompuMate(*((CartridgeCM*)myCart), myEvent, *mySystem); myCMHandler = new CompuMate(*((CartridgeCM*)&myCart), myEvent, *mySystem);
myControllers[0] = myCMHandler->leftController(); myControllers[0] = myCMHandler->leftController();
myControllers[1] = myCMHandler->rightController(); myControllers[1] = myCMHandler->rightController();
return; return;
@ -729,14 +724,14 @@ void Console::setControllers(const string& rommd5)
} }
else if(right == "ATARIVOX") else if(right == "ATARIVOX")
{ {
const string& nvramfile = myOSystem->nvramDir() + "atarivox_eeprom.dat"; const string& nvramfile = myOSystem.nvramDir() + "atarivox_eeprom.dat";
myControllers[rightPort] = new AtariVox(Controller::Right, myEvent, myControllers[rightPort] = new AtariVox(Controller::Right, myEvent,
*mySystem, myOSystem->serialPort(), *mySystem, myOSystem.serialPort(),
myOSystem->settings().getString("avoxport"), nvramfile); myOSystem.settings().getString("avoxport"), nvramfile);
} }
else if(right == "SAVEKEY") else if(right == "SAVEKEY")
{ {
const string& nvramfile = myOSystem->nvramDir() + "savekey_eeprom.dat"; const string& nvramfile = myOSystem.nvramDir() + "savekey_eeprom.dat";
myControllers[rightPort] = new SaveKey(Controller::Right, myEvent, *mySystem, myControllers[rightPort] = new SaveKey(Controller::Right, myEvent, *mySystem,
nvramfile); nvramfile);
} }
@ -761,7 +756,7 @@ void Console::setControllers(const string& rommd5)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Console::loadUserPalette() void Console::loadUserPalette()
{ {
const string& palette = myOSystem->paletteFile(); const string& palette = myOSystem.paletteFile();
ifstream in(palette.c_str(), ios::binary); ifstream in(palette.c_str(), ios::binary);
if(!in) if(!in)
return; return;
@ -816,7 +811,7 @@ void Console::loadUserPalette()
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Console::setColorLossPalette() void Console::generateColorLossPalette()
{ {
// Look at all the palettes, since we don't know which one is // Look at all the palettes, since we don't know which one is
// currently active // currently active
@ -857,8 +852,8 @@ void Console::setColorLossPalette()
void Console::setFramerate(float framerate) void Console::setFramerate(float framerate)
{ {
myFramerate = framerate; myFramerate = framerate;
myOSystem->setFramerate(framerate); myOSystem.setFramerate(framerate);
myOSystem->sound().setFrameRate(framerate); myOSystem.sound().setFrameRate(framerate);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -866,7 +861,7 @@ void Console::toggleTIABit(TIABit bit, const string& bitname, bool show) const
{ {
bool result = myTIA->toggleBit(bit); bool result = myTIA->toggleBit(bit);
string message = bitname + (result ? " enabled" : " disabled"); string message = bitname + (result ? " enabled" : " disabled");
myOSystem->frameBuffer().showMessage(message); myOSystem.frameBuffer().showMessage(message);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -874,7 +869,7 @@ void Console::toggleBits() const
{ {
bool enabled = myTIA->toggleBits(); bool enabled = myTIA->toggleBits();
string message = string("TIA bits") + (enabled ? " enabled" : " disabled"); string message = string("TIA bits") + (enabled ? " enabled" : " disabled");
myOSystem->frameBuffer().showMessage(message); myOSystem.frameBuffer().showMessage(message);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -882,7 +877,7 @@ void Console::toggleTIACollision(TIABit bit, const string& bitname, bool show) c
{ {
bool result = myTIA->toggleCollision(bit); bool result = myTIA->toggleCollision(bit);
string message = bitname + (result ? " collision enabled" : " collision disabled"); string message = bitname + (result ? " collision enabled" : " collision disabled");
myOSystem->frameBuffer().showMessage(message); myOSystem.frameBuffer().showMessage(message);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -890,33 +885,33 @@ void Console::toggleCollisions() const
{ {
bool enabled = myTIA->toggleCollisions(); bool enabled = myTIA->toggleCollisions();
string message = string("TIA collisions") + (enabled ? " enabled" : " disabled"); string message = string("TIA collisions") + (enabled ? " enabled" : " disabled");
myOSystem->frameBuffer().showMessage(message); myOSystem.frameBuffer().showMessage(message);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Console::toggleHMOVE() const void Console::toggleHMOVE() const
{ {
if(myTIA->toggleHMOVEBlank()) if(myTIA->toggleHMOVEBlank())
myOSystem->frameBuffer().showMessage("HMOVE blanking enabled"); myOSystem.frameBuffer().showMessage("HMOVE blanking enabled");
else else
myOSystem->frameBuffer().showMessage("HMOVE blanking disabled"); myOSystem.frameBuffer().showMessage("HMOVE blanking disabled");
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Console::toggleFixedColors() const void Console::toggleFixedColors() const
{ {
if(myTIA->toggleFixedColors()) if(myTIA->toggleFixedColors())
myOSystem->frameBuffer().showMessage("Fixed debug colors enabled"); myOSystem.frameBuffer().showMessage("Fixed debug colors enabled");
else else
myOSystem->frameBuffer().showMessage("Fixed debug colors disabled"); myOSystem.frameBuffer().showMessage("Fixed debug colors disabled");
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Console::addDebugger() void Console::addDebugger()
{ {
#ifdef DEBUGGER_SUPPORT #ifdef DEBUGGER_SUPPORT
myOSystem->createDebugger(*this); myOSystem.createDebugger(*this);
mySystem->m6502().attach(myOSystem->debugger()); mySystem->m6502().attach(myOSystem.debugger());
#endif #endif
} }
@ -1156,6 +1151,7 @@ uInt32 Console::ourUserSECAMPalette[256] = { 0 }; // filled from external file
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Console::Console(const Console& console) Console::Console(const Console& console)
: myOSystem(console.myOSystem), : myOSystem(console.myOSystem),
myCart(console.myCart),
myEvent(console.myEvent) myEvent(console.myEvent)
{ {
assert(false); assert(false);

View File

@ -68,7 +68,7 @@ class Console : public Serializable
@param cart The cartridge to use with this console @param cart The cartridge to use with this console
@param props The properties for the cartridge @param props The properties for the cartridge
*/ */
Console(OSystem* osystem, Cartridge* cart, const Properties& props); Console(OSystem& osystem, Cartridge& cart, const Properties& props);
/** /**
Create a new console object by copying another one Create a new console object by copying another one
@ -126,7 +126,7 @@ class Console : public Serializable
@return The cartridge for this console @return The cartridge for this console
*/ */
Cartridge& cartridge() const { return *myCart; } Cartridge& cartridge() const { return myCart; }
/** /**
Get the 6532 used by the console Get the 6532 used by the console
@ -327,7 +327,7 @@ class Console : public Serializable
normally can't have it enabled (NTSC), since it's also used for normally can't have it enabled (NTSC), since it's also used for
'greying out' the frame in the debugger. 'greying out' the frame in the debugger.
*/ */
void setColorLossPalette(); void generateColorLossPalette();
/** /**
Returns a pointer to the palette data for the palette currently defined Returns a pointer to the palette data for the palette currently defined
@ -339,8 +339,11 @@ class Console : public Serializable
void toggleTIACollision(TIABit bit, const string& bitname, bool show = true) const; void toggleTIACollision(TIABit bit, const string& bitname, bool show = true) const;
private: private:
// Pointer to the osystem object // Reference to the osystem object
OSystem* myOSystem; OSystem& myOSystem;
// Pointer to the Cartridge (the debugger needs it)
Cartridge& myCart;
// Reference to the event object to use // Reference to the event object to use
Event& myEvent; Event& myEvent;
@ -360,9 +363,6 @@ class Console : public Serializable
// Pointer to the 6502 based system being emulated // Pointer to the 6502 based system being emulated
System* mySystem; System* mySystem;
// Pointer to the Cartridge (the debugger needs it)
Cartridge* myCart;
// Pointer to the 6532 (aka RIOT) (the debugger needs it) // Pointer to the 6532 (aka RIOT) (the debugger needs it)
// A RIOT of my own! (...with apologies to The Clash...) // A RIOT of my own! (...with apologies to The Clash...)
M6532* myRiot; M6532* myRiot;

View File

@ -55,7 +55,7 @@
#endif #endif
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
EventHandler::EventHandler(OSystem* osystem) EventHandler::EventHandler(OSystem& osystem)
: myOSystem(osystem), : myOSystem(osystem),
myOverlay(NULL), myOverlay(NULL),
myMouseControl(NULL), myMouseControl(NULL),
@ -102,27 +102,27 @@ void EventHandler::initialize()
setActionMappings(kEmulationMode); setActionMappings(kEmulationMode);
setActionMappings(kMenuMode); setActionMappings(kMenuMode);
myUseCtrlKeyFlag = myOSystem->settings().getBool("ctrlcombo"); myUseCtrlKeyFlag = myOSystem.settings().getBool("ctrlcombo");
Joystick::setDeadZone(myOSystem->settings().getInt("joydeadzone")); Joystick::setDeadZone(myOSystem.settings().getInt("joydeadzone"));
Paddles::setDigitalSensitivity(myOSystem->settings().getInt("dsense")); Paddles::setDigitalSensitivity(myOSystem.settings().getInt("dsense"));
Paddles::setMouseSensitivity(myOSystem->settings().getInt("msense")); Paddles::setMouseSensitivity(myOSystem.settings().getInt("msense"));
// Set quick select delay when typing characters in listwidgets // Set quick select delay when typing characters in listwidgets
ListWidget::setQuickSelectDelay(myOSystem->settings().getInt("listdelay")); ListWidget::setQuickSelectDelay(myOSystem.settings().getInt("listdelay"));
// Set number of lines a mousewheel will scroll // Set number of lines a mousewheel will scroll
ScrollBarWidget::setWheelLines(myOSystem->settings().getInt("mwheel")); ScrollBarWidget::setWheelLines(myOSystem.settings().getInt("mwheel"));
// Integer to string conversions (for HEX) use upper or lower-case // Integer to string conversions (for HEX) use upper or lower-case
Common::Base::setHexUppercase(myOSystem->settings().getBool("dbg.uhex")); Common::Base::setHexUppercase(myOSystem.settings().getBool("dbg.uhex"));
// Joystick stuff // Joystick stuff
#ifdef JOYSTICK_SUPPORT #ifdef JOYSTICK_SUPPORT
initializeJoysticks(); initializeJoysticks();
// Map the stelladaptors we've found according to the specified ports // Map the stelladaptors we've found according to the specified ports
mapStelladaptors(myOSystem->settings().getString("saport")); mapStelladaptors(myOSystem.settings().getString("saport"));
setJoymap(); setJoymap();
setActionMappings(kEmulationMode); setActionMappings(kEmulationMode);
@ -137,9 +137,9 @@ void EventHandler::initialize()
for(uInt32 i = 0; i < myJoysticks.size(); ++i) for(uInt32 i = 0; i < myJoysticks.size(); ++i)
buf << " " << i << ": " << myJoysticks[i]->about() << endl; buf << " " << i << ": " << myJoysticks[i]->about() << endl;
} }
myOSystem->logMessage(buf.str(), 1); myOSystem.logMessage(buf.str(), 1);
#else #else
myOSystem->logMessage("Joystick support disabled.", 1); myOSystem.logMessage("Joystick support disabled.", 1);
#endif #endif
} }
@ -147,7 +147,7 @@ void EventHandler::initialize()
void EventHandler::reset(State state) void EventHandler::reset(State state)
{ {
setEventState(state); setEventState(state);
myOSystem->state().reset(); myOSystem.state().reset();
setContinuousSnapshots(0); setContinuousSnapshots(0);
@ -256,7 +256,7 @@ void EventHandler::mapStelladaptors(const string& saport)
} }
} }
} }
myOSystem->settings().setValue("saport", saport); myOSystem.settings().setValue("saport", saport);
// We're potentially swapping out an input device behind the back of // We're potentially swapping out an input device behind the back of
// the Event system, so we make sure all Stelladaptor-generated events // the Event system, so we make sure all Stelladaptor-generated events
@ -276,16 +276,16 @@ void EventHandler::mapStelladaptors(const string& saport)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void EventHandler::toggleSAPortOrder() void EventHandler::toggleSAPortOrder()
{ {
const string& saport = myOSystem->settings().getString("saport"); const string& saport = myOSystem.settings().getString("saport");
if(saport == "lr") if(saport == "lr")
{ {
mapStelladaptors("rl"); mapStelladaptors("rl");
myOSystem->frameBuffer().showMessage("Stelladaptor ports right/left"); myOSystem.frameBuffer().showMessage("Stelladaptor ports right/left");
} }
else else
{ {
mapStelladaptors("lr"); mapStelladaptors("lr");
myOSystem->frameBuffer().showMessage("Stelladaptor ports left/right"); myOSystem.frameBuffer().showMessage("Stelladaptor ports left/right");
} }
} }
@ -299,21 +299,21 @@ void EventHandler::poll(uInt64 time)
// related to emulation // related to emulation
if(myState == S_EMULATE) if(myState == S_EMULATE)
{ {
myOSystem->console().riot().update(); myOSystem.console().riot().update();
#if 0 #if 0
// Now check if the StateManager should be saving or loading state // Now check if the StateManager should be saving or loading state
// Per-frame cheats are disabled if the StateManager is active, since // Per-frame cheats are disabled if the StateManager is active, since
// it would interfere with proper playback // it would interfere with proper playback
if(myOSystem->state().isActive()) if(myOSystem.state().isActive())
{ {
myOSystem->state().update(); myOSystem.state().update();
} }
else else
#endif #endif
{ {
#ifdef CHEATCODE_SUPPORT #ifdef CHEATCODE_SUPPORT
const CheatList& cheats = myOSystem->cheat().perFrame(); const CheatList& cheats = myOSystem.cheat().perFrame();
for(uInt32 i = 0; i < cheats.size(); i++) for(uInt32 i = 0; i < cheats.size(); i++)
cheats[i]->evaluate(); cheats[i]->evaluate();
#endif #endif
@ -359,7 +359,7 @@ void EventHandler::handleKeyEvent(StellaKey key, StellaMod mod, char ascii, bool
#endif #endif
if(key == KBDK_RETURN) if(key == KBDK_RETURN)
{ {
myOSystem->frameBuffer().toggleFullscreen(); myOSystem.frameBuffer().toggleFullscreen();
} }
// These only work when in emulation mode // These only work when in emulation mode
else if(myState == S_EMULATE) else if(myState == S_EMULATE)
@ -367,160 +367,160 @@ void EventHandler::handleKeyEvent(StellaKey key, StellaMod mod, char ascii, bool
switch(key) switch(key)
{ {
case KBDK_EQUALS: case KBDK_EQUALS:
myOSystem->frameBuffer().changeWindowedVidMode(+1); myOSystem.frameBuffer().changeWindowedVidMode(+1);
break; break;
case KBDK_MINUS: case KBDK_MINUS:
myOSystem->frameBuffer().changeWindowedVidMode(-1); myOSystem.frameBuffer().changeWindowedVidMode(-1);
break; break;
case KBDK_LEFTBRACKET: case KBDK_LEFTBRACKET:
myOSystem->sound().adjustVolume(-1); myOSystem.sound().adjustVolume(-1);
break; break;
case KBDK_RIGHTBRACKET: case KBDK_RIGHTBRACKET:
myOSystem->sound().adjustVolume(+1); myOSystem.sound().adjustVolume(+1);
break; break;
case KBDK_PAGEUP: // Alt-PageUp increases YStart case KBDK_PAGEUP: // Alt-PageUp increases YStart
myOSystem->console().changeYStart(+1); myOSystem.console().changeYStart(+1);
break; break;
case KBDK_PAGEDOWN: // Alt-PageDown decreases YStart case KBDK_PAGEDOWN: // Alt-PageDown decreases YStart
myOSystem->console().changeYStart(-1); myOSystem.console().changeYStart(-1);
break; break;
case KBDK_1: // Alt-1 turns off NTSC filtering case KBDK_1: // Alt-1 turns off NTSC filtering
myOSystem->frameBuffer().setNTSC(NTSCFilter::PRESET_OFF); myOSystem.frameBuffer().tiaSurface().setNTSC(NTSCFilter::PRESET_OFF);
break; break;
case KBDK_2: // Alt-2 turns on 'composite' NTSC filtering case KBDK_2: // Alt-2 turns on 'composite' NTSC filtering
myOSystem->frameBuffer().setNTSC(NTSCFilter::PRESET_COMPOSITE); myOSystem.frameBuffer().tiaSurface().setNTSC(NTSCFilter::PRESET_COMPOSITE);
break; break;
case KBDK_3: // Alt-3 turns on 'svideo' NTSC filtering case KBDK_3: // Alt-3 turns on 'svideo' NTSC filtering
myOSystem->frameBuffer().setNTSC(NTSCFilter::PRESET_SVIDEO); myOSystem.frameBuffer().tiaSurface().setNTSC(NTSCFilter::PRESET_SVIDEO);
break; break;
case KBDK_4: // Alt-4 turns on 'rgb' NTSC filtering case KBDK_4: // Alt-4 turns on 'rgb' NTSC filtering
myOSystem->frameBuffer().setNTSC(NTSCFilter::PRESET_RGB); myOSystem.frameBuffer().tiaSurface().setNTSC(NTSCFilter::PRESET_RGB);
break; break;
case KBDK_5: // Alt-5 turns on 'bad' NTSC filtering case KBDK_5: // Alt-5 turns on 'bad' NTSC filtering
myOSystem->frameBuffer().setNTSC(NTSCFilter::PRESET_BAD); myOSystem.frameBuffer().tiaSurface().setNTSC(NTSCFilter::PRESET_BAD);
break; break;
case KBDK_6: // Alt-6 turns on 'custom' NTSC filtering case KBDK_6: // Alt-6 turns on 'custom' NTSC filtering
myOSystem->frameBuffer().setNTSC(NTSCFilter::PRESET_CUSTOM); myOSystem.frameBuffer().tiaSurface().setNTSC(NTSCFilter::PRESET_CUSTOM);
break; break;
case KBDK_7: // Alt-7 changes scanline intensity for NTSC filtering case KBDK_7: // Alt-7 changes scanline intensity for NTSC filtering
if(mod & KMOD_SHIFT) if(mod & KMOD_SHIFT)
myOSystem->frameBuffer().setScanlineIntensity(-5); myOSystem.frameBuffer().tiaSurface().setScanlineIntensity(-5);
else else
myOSystem->frameBuffer().setScanlineIntensity(+5); myOSystem.frameBuffer().tiaSurface().setScanlineIntensity(+5);
break; break;
case KBDK_8: // Alt-8 turns toggles scanline interpolation case KBDK_8: // Alt-8 turns toggles scanline interpolation
myOSystem->frameBuffer().toggleScanlineInterpolation(); myOSystem.frameBuffer().tiaSurface().toggleScanlineInterpolation();
break; break;
case KBDK_9: // Alt-9 selects various custom adjustables for NTSC filtering case KBDK_9: // Alt-9 selects various custom adjustables for NTSC filtering
if(myOSystem->frameBuffer().ntscEnabled()) if(myOSystem.frameBuffer().tiaSurface().ntscEnabled())
{ {
if(mod & KMOD_SHIFT) if(mod & KMOD_SHIFT)
myOSystem->frameBuffer().showMessage( myOSystem.frameBuffer().showMessage(
myOSystem->frameBuffer().ntsc().setPreviousAdjustable()); myOSystem.frameBuffer().tiaSurface().ntsc().setPreviousAdjustable());
else else
myOSystem->frameBuffer().showMessage( myOSystem.frameBuffer().showMessage(
myOSystem->frameBuffer().ntsc().setNextAdjustable()); myOSystem.frameBuffer().tiaSurface().ntsc().setNextAdjustable());
} }
break; break;
case KBDK_0: // Alt-0 changes custom adjustables for NTSC filtering case KBDK_0: // Alt-0 changes custom adjustables for NTSC filtering
if(myOSystem->frameBuffer().ntscEnabled()) if(myOSystem.frameBuffer().tiaSurface().ntscEnabled())
{ {
if(mod & KMOD_SHIFT) if(mod & KMOD_SHIFT)
myOSystem->frameBuffer().showMessage( myOSystem.frameBuffer().showMessage(
myOSystem->frameBuffer().ntsc().decreaseAdjustable()); myOSystem.frameBuffer().tiaSurface().ntsc().decreaseAdjustable());
else else
myOSystem->frameBuffer().showMessage( myOSystem.frameBuffer().showMessage(
myOSystem->frameBuffer().ntsc().increaseAdjustable()); myOSystem.frameBuffer().tiaSurface().ntsc().increaseAdjustable());
} }
break; break;
case KBDK_Z: case KBDK_Z:
if(mod & KMOD_SHIFT) if(mod & KMOD_SHIFT)
myOSystem->console().toggleP0Collision(); myOSystem.console().toggleP0Collision();
else else
myOSystem->console().toggleP0Bit(); myOSystem.console().toggleP0Bit();
break; break;
case KBDK_X: case KBDK_X:
if(mod & KMOD_SHIFT) if(mod & KMOD_SHIFT)
myOSystem->console().toggleP1Collision(); myOSystem.console().toggleP1Collision();
else else
myOSystem->console().toggleP1Bit(); myOSystem.console().toggleP1Bit();
break; break;
case KBDK_C: case KBDK_C:
if(mod & KMOD_SHIFT) if(mod & KMOD_SHIFT)
myOSystem->console().toggleM0Collision(); myOSystem.console().toggleM0Collision();
else else
myOSystem->console().toggleM0Bit(); myOSystem.console().toggleM0Bit();
break; break;
case KBDK_V: case KBDK_V:
if(mod & KMOD_SHIFT) if(mod & KMOD_SHIFT)
myOSystem->console().toggleM1Collision(); myOSystem.console().toggleM1Collision();
else else
myOSystem->console().toggleM1Bit(); myOSystem.console().toggleM1Bit();
break; break;
case KBDK_B: case KBDK_B:
if(mod & KMOD_SHIFT) if(mod & KMOD_SHIFT)
myOSystem->console().toggleBLCollision(); myOSystem.console().toggleBLCollision();
else else
myOSystem->console().toggleBLBit(); myOSystem.console().toggleBLBit();
break; break;
case KBDK_N: case KBDK_N:
if(mod & KMOD_SHIFT) if(mod & KMOD_SHIFT)
myOSystem->console().togglePFCollision(); myOSystem.console().togglePFCollision();
else else
myOSystem->console().togglePFBit(); myOSystem.console().togglePFBit();
break; break;
case KBDK_M: case KBDK_M:
myOSystem->console().toggleHMOVE(); myOSystem.console().toggleHMOVE();
break; break;
case KBDK_COMMA: case KBDK_COMMA:
myOSystem->console().toggleFixedColors(); myOSystem.console().toggleFixedColors();
break; break;
case KBDK_PERIOD: case KBDK_PERIOD:
if(mod & KMOD_SHIFT) if(mod & KMOD_SHIFT)
myOSystem->console().toggleCollisions(); myOSystem.console().toggleCollisions();
else else
myOSystem->console().toggleBits(); myOSystem.console().toggleBits();
break; break;
case KBDK_P: // Alt-p toggles phosphor effect case KBDK_P: // Alt-p toggles phosphor effect
myOSystem->console().togglePhosphor(); myOSystem.console().togglePhosphor();
break; break;
case KBDK_L: case KBDK_L:
myOSystem->frameBuffer().toggleFrameStats(); myOSystem.frameBuffer().toggleFrameStats();
break; break;
case KBDK_S: case KBDK_S:
if(myContSnapshotInterval == 0) if(myContSnapshotInterval == 0)
{ {
ostringstream buf; ostringstream buf;
uInt32 interval = myOSystem->settings().getInt("ssinterval"); uInt32 interval = myOSystem.settings().getInt("ssinterval");
buf << "Enabling shotshots in " << interval << " second intervals"; buf << "Enabling shotshots in " << interval << " second intervals";
myOSystem->frameBuffer().showMessage(buf.str()); myOSystem.frameBuffer().showMessage(buf.str());
setContinuousSnapshots(interval); setContinuousSnapshots(interval);
} }
else else
@ -529,7 +529,7 @@ void EventHandler::handleKeyEvent(StellaKey key, StellaMod mod, char ascii, bool
buf << "Disabling snapshots, generated " buf << "Disabling snapshots, generated "
<< (myContSnapshotCounter / myContSnapshotInterval) << (myContSnapshotCounter / myContSnapshotInterval)
<< " files"; << " files";
myOSystem->frameBuffer().showMessage(buf.str()); myOSystem.frameBuffer().showMessage(buf.str());
setContinuousSnapshots(0); setContinuousSnapshots(0);
} }
break; break;
@ -556,7 +556,7 @@ void EventHandler::handleKeyEvent(StellaKey key, StellaMod mod, char ascii, bool
{ {
case KBDK_0: // Ctrl-0 switches between mouse control modes case KBDK_0: // Ctrl-0 switches between mouse control modes
if(myMouseControl) if(myMouseControl)
myOSystem->frameBuffer().showMessage(myMouseControl->next()); myOSystem.frameBuffer().showMessage(myMouseControl->next());
break; break;
case KBDK_1: // Ctrl-1 swaps Stelladaptor/2600-daptor ports case KBDK_1: // Ctrl-1 swaps Stelladaptor/2600-daptor ports
@ -564,47 +564,47 @@ void EventHandler::handleKeyEvent(StellaKey key, StellaMod mod, char ascii, bool
break; break;
case KBDK_F: // (Shift) Ctrl-f toggles NTSC/PAL/SECAM mode case KBDK_F: // (Shift) Ctrl-f toggles NTSC/PAL/SECAM mode
myOSystem->console().toggleFormat(mod & KMOD_SHIFT ? -1 : 1); myOSystem.console().toggleFormat(mod & KMOD_SHIFT ? -1 : 1);
break; break;
case KBDK_G: // Ctrl-g (un)grabs mouse case KBDK_G: // Ctrl-g (un)grabs mouse
if(!myOSystem->frameBuffer().fullScreen()) if(!myOSystem.frameBuffer().fullScreen())
myOSystem->frameBuffer().toggleGrabMouse(); myOSystem.frameBuffer().toggleGrabMouse();
break; break;
case KBDK_L: // Ctrl-l toggles PAL color-loss effect case KBDK_L: // Ctrl-l toggles PAL color-loss effect
myOSystem->console().toggleColorLoss(); myOSystem.console().toggleColorLoss();
break; break;
case KBDK_P: // Ctrl-p toggles different palettes case KBDK_P: // Ctrl-p toggles different palettes
myOSystem->console().togglePalette(); myOSystem.console().togglePalette();
break; break;
case KBDK_R: // Ctrl-r reloads the currently loaded ROM case KBDK_R: // Ctrl-r reloads the currently loaded ROM
myOSystem->reloadConsole(); myOSystem.reloadConsole();
break; break;
case KBDK_PAGEUP: // Ctrl-PageUp increases Height case KBDK_PAGEUP: // Ctrl-PageUp increases Height
myOSystem->console().changeHeight(+1); myOSystem.console().changeHeight(+1);
break; break;
case KBDK_PAGEDOWN: // Ctrl-PageDown decreases Height case KBDK_PAGEDOWN: // Ctrl-PageDown decreases Height
myOSystem->console().changeHeight(-1); myOSystem.console().changeHeight(-1);
break; break;
case KBDK_S: // Ctrl-s saves properties to a file case KBDK_S: // Ctrl-s saves properties to a file
{ {
string filename = myOSystem->baseDir() + string filename = myOSystem.baseDir() +
myOSystem->console().properties().get(Cartridge_Name) + ".pro"; myOSystem.console().properties().get(Cartridge_Name) + ".pro";
ofstream out(filename.c_str(), ios::out); ofstream out(filename.c_str(), ios::out);
if(out) if(out)
{ {
myOSystem->console().properties().save(out); myOSystem.console().properties().save(out);
out.close(); out.close();
myOSystem->frameBuffer().showMessage("Properties saved"); myOSystem.frameBuffer().showMessage("Properties saved");
} }
else else
myOSystem->frameBuffer().showMessage("Error saving properties"); myOSystem.frameBuffer().showMessage("Error saving properties");
break; break;
} }
@ -718,7 +718,7 @@ void EventHandler::handleJoyEvent(int stick, int button, uInt8 state)
// enum; subtracting four gives us Controller 0 and 1 // enum; subtracting four gives us Controller 0 and 1
if(myState == S_EMULATE) if(myState == S_EMULATE)
{ {
switch(myOSystem->console().controller(Controller::Left).type()) switch(myOSystem.console().controller(Controller::Left).type())
{ {
case Controller::Keyboard: case Controller::Keyboard:
if(button < 12) myEvent.set(SA_Key[joy.type-4][button], state); if(button < 12) myEvent.set(SA_Key[joy.type-4][button], state);
@ -726,7 +726,7 @@ void EventHandler::handleJoyEvent(int stick, int button, uInt8 state)
default: default:
if(button < 4) myEvent.set(SA_Button[joy.type-4][button], state); if(button < 4) myEvent.set(SA_Button[joy.type-4][button], state);
} }
switch(myOSystem->console().controller(Controller::Right).type()) switch(myOSystem.console().controller(Controller::Right).type())
{ {
case Controller::Keyboard: case Controller::Keyboard:
if(button < 12) myEvent.set(SA_Key[joy.type-4][button], state); if(button < 12) myEvent.set(SA_Key[joy.type-4][button], state);
@ -895,7 +895,7 @@ void EventHandler::handleSystemEvent(SystemEvent e, int data1, int data2)
switch(e) switch(e)
{ {
case EVENT_WINDOW_EXPOSED: case EVENT_WINDOW_EXPOSED:
myOSystem->frameBuffer().refresh(); myOSystem.frameBuffer().refresh();
break; break;
default: // handle other events as testing requires default: // handle other events as testing requires
// cerr << "handleSystemEvent: " << e << endl; // cerr << "handleSystemEvent: " << e << endl;
@ -964,23 +964,23 @@ void EventHandler::handleEvent(Event::Type event, int state)
return; return;
case Event::VolumeDecrease: case Event::VolumeDecrease:
if(state) myOSystem->sound().adjustVolume(-1); if(state) myOSystem.sound().adjustVolume(-1);
return; return;
case Event::VolumeIncrease: case Event::VolumeIncrease:
if(state) myOSystem->sound().adjustVolume(+1); if(state) myOSystem.sound().adjustVolume(+1);
return; return;
case Event::SaveState: case Event::SaveState:
if(state) myOSystem->state().saveState(); if(state) myOSystem.state().saveState();
return; return;
case Event::ChangeState: case Event::ChangeState:
if(state) myOSystem->state().changeState(); if(state) myOSystem.state().changeState();
return; return;
case Event::LoadState: case Event::LoadState:
if(state) myOSystem->state().loadState(); if(state) myOSystem.state().loadState();
return; return;
case Event::TakeSnapshot: case Event::TakeSnapshot:
@ -992,11 +992,11 @@ void EventHandler::handleEvent(Event::Type event, int state)
myState == S_DEBUGGER) && state) myState == S_DEBUGGER) && state)
{ {
// Go back to the launcher, or immediately quit // Go back to the launcher, or immediately quit
if(myOSystem->settings().getBool("exitlauncher") || if(myOSystem.settings().getBool("exitlauncher") ||
myOSystem->launcherUsed()) myOSystem.launcherUsed())
{ {
myOSystem->deleteConsole(); myOSystem.deleteConsole();
myOSystem->createLauncher(); myOSystem.createLauncher();
} }
else else
handleEvent(Event::Quit, 1); handleEvent(Event::Quit, 1);
@ -1008,7 +1008,7 @@ void EventHandler::handleEvent(Event::Type event, int state)
{ {
saveKeyMapping(); saveKeyMapping();
saveJoyMapping(); saveJoyMapping();
myOSystem->quit(); myOSystem.quit();
} }
return; return;
@ -1039,22 +1039,22 @@ void EventHandler::handleEvent(Event::Type event, int state)
// Events which generate messages // Events which generate messages
case Event::ConsoleColor: case Event::ConsoleColor:
if(state) myOSystem->frameBuffer().showMessage("Color Mode"); if(state) myOSystem.frameBuffer().showMessage("Color Mode");
break; break;
case Event::ConsoleBlackWhite: case Event::ConsoleBlackWhite:
if(state) myOSystem->frameBuffer().showMessage("BW Mode"); if(state) myOSystem.frameBuffer().showMessage("BW Mode");
break; break;
case Event::ConsoleLeftDiffA: case Event::ConsoleLeftDiffA:
if(state) myOSystem->frameBuffer().showMessage("Left Difficulty A"); if(state) myOSystem.frameBuffer().showMessage("Left Difficulty A");
break; break;
case Event::ConsoleLeftDiffB: case Event::ConsoleLeftDiffB:
if(state) myOSystem->frameBuffer().showMessage("Left Difficulty B"); if(state) myOSystem.frameBuffer().showMessage("Left Difficulty B");
break; break;
case Event::ConsoleRightDiffA: case Event::ConsoleRightDiffA:
if(state) myOSystem->frameBuffer().showMessage("Right Difficulty A"); if(state) myOSystem.frameBuffer().showMessage("Right Difficulty A");
break; break;
case Event::ConsoleRightDiffB: case Event::ConsoleRightDiffB:
if(state) myOSystem->frameBuffer().showMessage("Right Difficulty B"); if(state) myOSystem.frameBuffer().showMessage("Right Difficulty B");
break; break;
case Event::NoType: // Ignore unmapped events case Event::NoType: // Ignore unmapped events
@ -1261,7 +1261,7 @@ void EventHandler::setKeymap()
{ {
// Since istringstream swallows whitespace, we have to make the // Since istringstream swallows whitespace, we have to make the
// delimiters be spaces // delimiters be spaces
string list = myOSystem->settings().getString("keymap"); string list = myOSystem.settings().getString("keymap");
replace(list.begin(), list.end(), ':', ' '); replace(list.begin(), list.end(), ':', ' ');
istringstream buf(list); istringstream buf(list);
@ -1300,7 +1300,7 @@ void EventHandler::setJoymap()
setDefaultJoymap(Event::NoType, kMenuMode); setDefaultJoymap(Event::NoType, kMenuMode);
// Get all mappings from the settings // Get all mappings from the settings
istringstream buf(myOSystem->settings().getString("joymap")); istringstream buf(myOSystem.settings().getString("joymap"));
string joymap; string joymap;
// First check the event type, and disregard the entire mapping if it's invalid // First check the event type, and disregard the entire mapping if it's invalid
@ -1339,7 +1339,7 @@ void EventHandler::setComboMap()
{ {
// Since istringstream swallows whitespace, we have to make the // Since istringstream swallows whitespace, we have to make the
// delimiters be spaces // delimiters be spaces
string list = myOSystem->settings().getString("combomap"); string list = myOSystem.settings().getString("combomap");
replace(list.begin(), list.end(), ':', ' '); replace(list.begin(), list.end(), ':', ' ');
istringstream buf(list); istringstream buf(list);
@ -1623,7 +1623,7 @@ void EventHandler::setDefaultJoymap(Event::Type event, EventMode mode)
else else
myJoysticks[i]->eraseEvent(event, mode); // only reset the specific event myJoysticks[i]->eraseEvent(event, mode); // only reset the specific event
} }
myOSystem->setDefaultJoymap(event, mode); myOSystem.setDefaultJoymap(event, mode);
setActionMappings(mode); setActionMappings(mode);
#endif #endif
} }
@ -1639,7 +1639,7 @@ void EventHandler::saveKeyMapping()
for(int i = 0; i < KBDK_LAST; ++i) for(int i = 0; i < KBDK_LAST; ++i)
keybuf << ":" << myKeyTable[i][mode]; keybuf << ":" << myKeyTable[i][mode];
myOSystem->settings().setValue("keymap", keybuf.str()); myOSystem.settings().setValue("keymap", keybuf.str());
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -1674,7 +1674,7 @@ void EventHandler::saveJoyMapping()
for(iter = myJoystickMap.begin(); iter != myJoystickMap.end(); ++iter) for(iter = myJoystickMap.begin(); iter != myJoystickMap.end(); ++iter)
joybuf << "^" << iter->second; joybuf << "^" << iter->second;
myOSystem->settings().setValue("joymap", joybuf.str()); myOSystem.settings().setValue("joymap", joybuf.str());
#endif #endif
} }
@ -1692,7 +1692,7 @@ void EventHandler::saveComboMapping()
for(int j = 1; j < kEventsPerCombo; ++j) for(int j = 1; j < kEventsPerCombo; ++j)
buf << "," << myComboTable[i][j]; buf << "," << myComboTable[i][j];
} }
myOSystem->settings().setValue("combomap", buf.str()); myOSystem.settings().setValue("combomap", buf.str());
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -1866,10 +1866,10 @@ void EventHandler::takeSnapshot(uInt32 number)
// Figure out the correct snapshot name // Figure out the correct snapshot name
string filename; string filename;
bool showmessage = number == 0; bool showmessage = number == 0;
string sspath = myOSystem->snapshotSaveDir() + string sspath = myOSystem.snapshotSaveDir() +
(myOSystem->settings().getString("snapname") != "int" ? (myOSystem.settings().getString("snapname") != "int" ?
myOSystem->romFile().getNameWithExt("") myOSystem.romFile().getNameWithExt("")
: myOSystem->console().properties().get(Cartridge_Name)); : myOSystem.console().properties().get(Cartridge_Name));
// Check whether we want multiple snapshots created // Check whether we want multiple snapshots created
if(number > 0) if(number > 0)
@ -1878,7 +1878,7 @@ void EventHandler::takeSnapshot(uInt32 number)
buf << sspath << "_" << hex << setw(8) << setfill('0') << number << ".png"; buf << sspath << "_" << hex << setw(8) << setfill('0') << number << ".png";
filename = buf.str(); filename = buf.str();
} }
else if(!myOSystem->settings().getBool("sssingle")) else if(!myOSystem.settings().getBool("sssingle"))
{ {
// Determine if the file already exists, checking each successive filename // Determine if the file already exists, checking each successive filename
// until one doesn't exist // until one doesn't exist
@ -1902,35 +1902,35 @@ void EventHandler::takeSnapshot(uInt32 number)
filename = sspath + ".png"; filename = sspath + ".png";
// Now create a PNG snapshot // Now create a PNG snapshot
if(myOSystem->settings().getBool("ss1x")) if(myOSystem.settings().getBool("ss1x"))
{ {
string msg = string msg =
myOSystem->png().saveImage(filename, myOSystem->frameBuffer(), myOSystem.png().saveImage(filename, myOSystem.frameBuffer(),
myOSystem->console().tia(), myOSystem.console().tia(),
myOSystem->console().properties()); myOSystem.console().properties());
if(showmessage) if(showmessage)
myOSystem->frameBuffer().showMessage(msg); myOSystem.frameBuffer().showMessage(msg);
} }
else else
{ {
// Make sure we have a 'clean' image, with no onscreen messages // Make sure we have a 'clean' image, with no onscreen messages
myOSystem->frameBuffer().enableMessages(false); myOSystem.frameBuffer().enableMessages(false);
string msg = string msg =
myOSystem->png().saveImage(filename, myOSystem->frameBuffer(), myOSystem.png().saveImage(filename, myOSystem.frameBuffer(),
myOSystem->console().properties()); myOSystem.console().properties());
// Re-enable old messages // Re-enable old messages
myOSystem->frameBuffer().enableMessages(true); myOSystem.frameBuffer().enableMessages(true);
if(showmessage) if(showmessage)
myOSystem->frameBuffer().showMessage(msg); myOSystem.frameBuffer().showMessage(msg);
} }
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void EventHandler::setMouseControllerMode(const string& enable) void EventHandler::setMouseControllerMode(const string& enable)
{ {
if(&myOSystem->console()) if(&myOSystem.console())
{ {
delete myMouseControl; myMouseControl = NULL; delete myMouseControl; myMouseControl = NULL;
@ -1941,7 +1941,7 @@ void EventHandler::setMouseControllerMode(const string& enable)
usemouse = false; usemouse = false;
else // 'analog' else // 'analog'
{ {
switch(myOSystem->console().controller(Controller::Left).type()) switch(myOSystem.console().controller(Controller::Left).type())
{ {
case Controller::Paddles: case Controller::Paddles:
case Controller::Driving: case Controller::Driving:
@ -1954,7 +1954,7 @@ void EventHandler::setMouseControllerMode(const string& enable)
default: default:
break; break;
} }
switch(myOSystem->console().controller(Controller::Right).type()) switch(myOSystem.console().controller(Controller::Right).type())
{ {
case Controller::Paddles: case Controller::Paddles:
case Controller::Driving: case Controller::Driving:
@ -1970,9 +1970,9 @@ void EventHandler::setMouseControllerMode(const string& enable)
} }
const string& control = usemouse ? const string& control = usemouse ?
myOSystem->console().properties().get(Controller_MouseAxis) : "none"; myOSystem.console().properties().get(Controller_MouseAxis) : "none";
myMouseControl = new MouseControl(myOSystem->console(), control); myMouseControl = new MouseControl(myOSystem.console(), control);
myMouseControl->next(); // set first available mode myMouseControl->next(); // set first available mode
} }
} }
@ -1980,7 +1980,7 @@ void EventHandler::setMouseControllerMode(const string& enable)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void EventHandler::setContinuousSnapshots(uInt32 interval) void EventHandler::setContinuousSnapshots(uInt32 interval)
{ {
myContSnapshotInterval = (uInt32) myOSystem->frameRate() * interval; myContSnapshotInterval = (uInt32) myOSystem.frameRate() * interval;
myContSnapshotCounter = 0; myContSnapshotCounter = 0;
} }
@ -1989,44 +1989,44 @@ void EventHandler::enterMenuMode(State state)
{ {
setEventState(state); setEventState(state);
myOverlay->reStack(); myOverlay->reStack();
myOSystem->sound().mute(true); myOSystem.sound().mute(true);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void EventHandler::leaveMenuMode() void EventHandler::leaveMenuMode()
{ {
setEventState(S_EMULATE); setEventState(S_EMULATE);
myOSystem->sound().mute(false); myOSystem.sound().mute(false);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool EventHandler::enterDebugMode() bool EventHandler::enterDebugMode()
{ {
#ifdef DEBUGGER_SUPPORT #ifdef DEBUGGER_SUPPORT
if(myState == S_DEBUGGER || !(&myOSystem->console())) if(myState == S_DEBUGGER || !(&myOSystem.console()))
return false; return false;
// Make sure debugger starts in a consistent state // Make sure debugger starts in a consistent state
// This absolutely *has* to come before we actually change to debugger // This absolutely *has* to come before we actually change to debugger
// mode, since it takes care of locking the debugger state, which will // mode, since it takes care of locking the debugger state, which will
// probably be modified below // probably be modified below
myOSystem->debugger().setStartState(); myOSystem.debugger().setStartState();
setEventState(S_DEBUGGER); setEventState(S_DEBUGGER);
FBInitStatus fbstatus = myOSystem->createFrameBuffer(); FBInitStatus fbstatus = myOSystem.createFrameBuffer();
if(fbstatus != kSuccess) if(fbstatus != kSuccess)
{ {
myOSystem->debugger().setQuitState(); myOSystem.debugger().setQuitState();
setEventState(S_EMULATE); setEventState(S_EMULATE);
if(fbstatus == kFailTooLarge) if(fbstatus == kFailTooLarge)
myOSystem->frameBuffer().showMessage("Debugger window too large for screen", myOSystem.frameBuffer().showMessage("Debugger window too large for screen",
kBottomCenter, true); kBottomCenter, true);
return false; return false;
} }
myOverlay->reStack(); myOverlay->reStack();
myOSystem->sound().mute(true); myOSystem.sound().mute(true);
#else #else
myOSystem->frameBuffer().showMessage("Debugger support not included", myOSystem.frameBuffer().showMessage("Debugger support not included",
kBottomCenter, true); kBottomCenter, true);
#endif #endif
@ -2042,11 +2042,11 @@ void EventHandler::leaveDebugMode()
return; return;
// Make sure debugger quits in a consistent state // Make sure debugger quits in a consistent state
myOSystem->debugger().setQuitState(); myOSystem.debugger().setQuitState();
setEventState(S_EMULATE); setEventState(S_EMULATE);
myOSystem->createFrameBuffer(); myOSystem.createFrameBuffer();
myOSystem->sound().mute(false); myOSystem.sound().mute(false);
#endif #endif
} }
@ -2057,7 +2057,7 @@ void EventHandler::setEventState(State state)
// Normally, the usage of Control key is determined by 'ctrlcombo' // Normally, the usage of Control key is determined by 'ctrlcombo'
// For certain ROMs it may be forced off, whatever the setting // For certain ROMs it may be forced off, whatever the setting
myUseCtrlKeyFlag = myOSystem->settings().getBool("ctrlcombo"); myUseCtrlKeyFlag = myOSystem.settings().getBool("ctrlcombo");
// Only enable Unicode in GUI modes, since there we need it for ascii data // Only enable Unicode in GUI modes, since there we need it for ascii data
// Otherwise, it causes a performance hit, so leave it off // Otherwise, it causes a performance hit, so leave it off
@ -2065,37 +2065,37 @@ void EventHandler::setEventState(State state)
{ {
case S_EMULATE: case S_EMULATE:
myOverlay = NULL; myOverlay = NULL;
myOSystem->sound().mute(false); myOSystem.sound().mute(false);
//FIXME SDL_EnableUNICODE(0); //FIXME SDL_EnableUNICODE(0);
if(myOSystem->console().controller(Controller::Left).type() == if(myOSystem.console().controller(Controller::Left).type() ==
Controller::CompuMate) Controller::CompuMate)
myUseCtrlKeyFlag = false; myUseCtrlKeyFlag = false;
break; break;
case S_PAUSE: case S_PAUSE:
myOverlay = NULL; myOverlay = NULL;
myOSystem->sound().mute(true); myOSystem.sound().mute(true);
//FIXME SDL_EnableUNICODE(0); //FIXME SDL_EnableUNICODE(0);
break; break;
case S_MENU: case S_MENU:
myOverlay = &myOSystem->menu(); myOverlay = &myOSystem.menu();
//FIXME SDL_EnableUNICODE(1); //FIXME SDL_EnableUNICODE(1);
break; break;
case S_CMDMENU: case S_CMDMENU:
myOverlay = &myOSystem->commandMenu(); myOverlay = &myOSystem.commandMenu();
//FIXME SDL_EnableUNICODE(1); //FIXME SDL_EnableUNICODE(1);
break; break;
case S_LAUNCHER: case S_LAUNCHER:
myOverlay = &myOSystem->launcher(); myOverlay = &myOSystem.launcher();
//FIXME SDL_EnableUNICODE(1); //FIXME SDL_EnableUNICODE(1);
break; break;
#ifdef DEBUGGER_SUPPORT #ifdef DEBUGGER_SUPPORT
case S_DEBUGGER: case S_DEBUGGER:
myOverlay = &myOSystem->debugger(); myOverlay = &myOSystem.debugger();
//FIXME SDL_EnableUNICODE(1); //FIXME SDL_EnableUNICODE(1);
break; break;
#endif #endif
@ -2106,15 +2106,15 @@ void EventHandler::setEventState(State state)
} }
// Inform various subsystems about the new state // Inform various subsystems about the new state
myOSystem->stateChanged(myState); myOSystem.stateChanged(myState);
if(&myOSystem->frameBuffer()) if(&myOSystem.frameBuffer())
{ {
myOSystem->frameBuffer().stateChanged(myState); myOSystem.frameBuffer().stateChanged(myState);
myOSystem->frameBuffer().setCursorState(); myOSystem.frameBuffer().setCursorState();
} }
if(&myOSystem->console()) if(&myOSystem.console())
{ {
myOSystem->console().stateChanged(myState); myOSystem.console().stateChanged(myState);
} }
// Always clear any pending events when changing states // Always clear any pending events when changing states

View File

@ -86,7 +86,7 @@ class EventHandler
/** /**
Create a new event handler object Create a new event handler object
*/ */
EventHandler(OSystem* osystem); EventHandler(OSystem& osystem);
/** /**
Destructor Destructor
@ -319,7 +319,7 @@ class EventHandler
protected: protected:
// Global OSystem object // Global OSystem object
OSystem* myOSystem; OSystem& myOSystem;
/** /**
Methods which are called by derived classes to handle specific types Methods which are called by derived classes to handle specific types

View File

@ -21,9 +21,8 @@
#include "FBSurface.hxx" #include "FBSurface.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FBSurface::FBSurface(const uInt32* palette) FBSurface::FBSurface()
: myPalette(palette), : myPixels(NULL),
myPixels(NULL),
myPitch(0) myPitch(0)
{ {
// NOTE: myPixels and myPitch MUST be set in child classes that inherit // NOTE: myPixels and myPitch MUST be set in child classes that inherit
@ -278,3 +277,6 @@ void FBSurface::drawSurface(const FBSurface* surface)
dst += myPitch; dst += myPitch;
} }
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const uInt32* FBSurface::myPalette = 0;

View File

@ -21,6 +21,7 @@
#define FBSURFACE_HXX #define FBSURFACE_HXX
class FrameBuffer; class FrameBuffer;
class TIASurface;
#include "bspf.hxx" #include "bspf.hxx"
#include "Font.hxx" #include "Font.hxx"
@ -51,11 +52,13 @@ enum FrameStyle {
class FBSurface class FBSurface
{ {
friend class TIASurface;
public: public:
/** /**
Creates a new FBSurface object Creates a new FBSurface object
*/ */
FBSurface(const uInt32* palette); FBSurface();
/** /**
Destructor Destructor
@ -259,17 +262,6 @@ class FBSurface
*/ */
virtual void setStaticContents(const uInt32* pixels, uInt32 pitch) = 0; virtual void setStaticContents(const uInt32* pixels, uInt32 pitch) = 0;
/**
This method should be called to modify the interpolation and
blending effects to be applied to this surface.
@param smoothScale Whether to use interpolation during scaling
@param useBlend Whether the surface should use alpha blending
@param blendAlpha The alpha to use during blending (if used)
*/
virtual void setInterpolationAndBlending(bool smoothScale,
bool useBlend, uInt32 blendAlpha) = 0;
/** /**
This method should be called to translate the given coordinates This method should be called to translate the given coordinates
to the (destination) surface coordinates. to the (destination) surface coordinates.
@ -302,10 +294,35 @@ class FBSurface
*/ */
virtual void reload() = 0; virtual void reload() = 0;
static void setPalette(const uInt32* palette) { myPalette = palette; }
protected: protected:
const uInt32* myPalette; /**
The rendering attributes that can be modified for this texture.
These probably can only be implemented in child FBSurfaces where
the specific functionality actually exists.
*/
struct Attributes {
bool smoothing; // Scaling is smoothed or blocky
bool blending; // Blending is enabled
uInt32 blendalpha; // Alpha to use in blending mode (0-100%)
};
/**
The child class chooses which (if any) of the actual attributes
can be applied.
@param immediate Whether to re-initialize the surface immediately
with the new attributes, or wait until manually
reloaded
*/
virtual void applyAttributes(bool immediate = true) = 0;
protected:
static const uInt32* myPalette;
uInt32* myPixels; uInt32* myPixels;
uInt32 myPitch; uInt32 myPitch;
Attributes myAttributes;
}; };
#endif #endif

View File

@ -38,6 +38,7 @@
#include "TIA.hxx" #include "TIA.hxx"
#include "FBSurface.hxx" #include "FBSurface.hxx"
#include "TIASurface.hxx"
#include "FrameBuffer.hxx" #include "FrameBuffer.hxx"
#ifdef DEBUGGER_SUPPORT #ifdef DEBUGGER_SUPPORT
@ -45,19 +46,15 @@
#endif #endif
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FrameBuffer::FrameBuffer(OSystem* osystem) FrameBuffer::FrameBuffer(OSystem& osystem)
: myOSystem(osystem), : myOSystem(osystem),
myRedrawEntireFrame(true), myRedrawEntireFrame(true),
myUsePhosphor(false),
myPhosphorBlend(77),
myInitializedCount(0), myInitializedCount(0),
myPausedCount(0) myPausedCount(0),
myTIASurface(NULL)
{ {
myMsg.surface = myStatsMsg.surface = NULL; myMsg.surface = myStatsMsg.surface = NULL;
myMsg.enabled = myStatsMsg.enabled = false; myMsg.enabled = myStatsMsg.enabled = false;
// Load NTSC filter settings
myNTSCFilter.loadConfig(myOSystem->settings());
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -67,6 +64,7 @@ FrameBuffer::~FrameBuffer(void)
delete myInfoFont; delete myInfoFont;
delete mySmallFont; delete mySmallFont;
delete myLauncherFont; delete myLauncherFont;
delete myTIASurface;
// Free all allocated surfaces // Free all allocated surfaces
while(!mySurfaceList.empty()) while(!mySurfaceList.empty())
@ -85,7 +83,7 @@ bool FrameBuffer::initialize()
// Check the 'maxres' setting, which is an undocumented developer feature // Check the 'maxres' setting, which is an undocumented developer feature
// that specifies the desktop size (not normally set) // that specifies the desktop size (not normally set)
const GUI::Size& s = myOSystem->settings().getSize("maxres"); const GUI::Size& s = myOSystem.settings().getSize("maxres");
if(s.w > 0 && s.h > 0) if(s.w > 0 && s.h > 0)
{ {
query_w = s.w; query_w = s.w;
@ -126,7 +124,7 @@ bool FrameBuffer::initialize()
// very small screens // very small screens
if(!smallScreen) if(!smallScreen)
{ {
const string& lf = myOSystem->settings().getString("launcherfont"); const string& lf = myOSystem.settings().getString("launcherfont");
if(lf == "small") if(lf == "small")
myLauncherFont = new GUI::Font(GUI::consoleDesc); myLauncherFont = new GUI::Font(GUI::consoleDesc);
else if(lf == "medium") else if(lf == "medium")
@ -150,6 +148,20 @@ bool FrameBuffer::initialize()
myTIAZoomLevels.push_back(desc.str(), zoom); myTIAZoomLevels.push_back(desc.str(), zoom);
} }
// Set palette for GUI (upper area of array, doesn't change during execution)
for(int i = 0, j = 256; i < kNumColors-256; ++i, ++j)
{
Uint8 r = (ourGUIColors[i] >> 16) & 0xff;
Uint8 g = (ourGUIColors[i] >> 8) & 0xff;
Uint8 b = ourGUIColors[i] & 0xff;
myPalette[j] = mapRGB(r, g, b);
}
FBSurface::setPalette(myPalette);
// Create a TIA surface; we need it for rendering TIA images
myTIASurface = new TIASurface(*this, myOSystem);
return true; return true;
} }
@ -181,7 +193,7 @@ FBInitStatus FrameBuffer::createDisplay(const string& title,
return kFailTooLarge; return kFailTooLarge;
// FIXSDL - remove size limitations here? // FIXSDL - remove size limitations here?
if(myOSystem->settings().getString("fullscreen") == "1") if(myOSystem.settings().getString("fullscreen") == "1")
{ {
if(myDesktopSize.w < width || myDesktopSize.h < height) if(myDesktopSize.w < width || myDesktopSize.h < height)
return kFailTooLarge; return kFailTooLarge;
@ -208,15 +220,21 @@ FBInitStatus FrameBuffer::createDisplay(const string& title,
myScreenSize = mode.screen; myScreenSize = mode.screen;
if(width <= (uInt32)myScreenSize.w && height <= (uInt32)myScreenSize.h) if(width <= (uInt32)myScreenSize.w && height <= (uInt32)myScreenSize.h)
{ {
if(setVideoMode(myScreenTitle, mode, useFullscreen)) if(setVideoMode(myScreenTitle, mode))
{ {
// Inform TIA surface about new mode
if(myOSystem.eventHandler().state() != EventHandler::S_LAUNCHER &&
myOSystem.eventHandler().state() != EventHandler::S_DEBUGGER)
myTIASurface->initialize(myOSystem.console(), mode);
// Did we get the requested fullscreen state? // Did we get the requested fullscreen state?
myOSystem->settings().setValue("fullscreen", fullScreen()); myOSystem.settings().setValue("fullscreen", fullScreen());
resetSurfaces();
setCursorState(); setCursorState();
} }
else else
{ {
myOSystem->logMessage("ERROR: Couldn't initialize video subsystem", 0); myOSystem.logMessage("ERROR: Couldn't initialize video subsystem", 0);
return kFailNotSupported; return kFailNotSupported;
} }
} }
@ -245,15 +263,14 @@ FBInitStatus FrameBuffer::createDisplay(const string& title,
// Take care of some items that are only done once per framebuffer creation. // Take care of some items that are only done once per framebuffer creation.
if(myInitializedCount == 1) if(myInitializedCount == 1)
{ {
myOSystem->logMessage(about(), 1); myOSystem.logMessage(about(), 1);
setUIPalette();
setWindowIcon(); setWindowIcon();
} }
else else
{ {
string post_about = about(); string post_about = about();
if(post_about != pre_about) if(post_about != pre_about)
myOSystem->logMessage(post_about, 1); myOSystem.logMessage(post_about, 1);
} }
return kSuccess; return kSuccess;
@ -265,31 +282,31 @@ void FrameBuffer::update()
// Determine which mode we are in (from the EventHandler) // Determine which mode we are in (from the EventHandler)
// Take care of S_EMULATE mode here, otherwise let the GUI // Take care of S_EMULATE mode here, otherwise let the GUI
// figure out what to draw // figure out what to draw
switch(myOSystem->eventHandler().state()) switch(myOSystem.eventHandler().state())
{ {
case EventHandler::S_EMULATE: case EventHandler::S_EMULATE:
{ {
// Run the console for one frame // Run the console for one frame
// Note that the debugger can cause a breakpoint to occur, which changes // Note that the debugger can cause a breakpoint to occur, which changes
// the EventHandler state 'behind our back' - we need to check for that // the EventHandler state 'behind our back' - we need to check for that
myOSystem->console().tia().update(); myOSystem.console().tia().update();
#ifdef DEBUGGER_SUPPORT #ifdef DEBUGGER_SUPPORT
if(myOSystem->eventHandler().state() != EventHandler::S_EMULATE) break; if(myOSystem.eventHandler().state() != EventHandler::S_EMULATE) break;
#endif #endif
if(myOSystem->eventHandler().frying()) if(myOSystem.eventHandler().frying())
myOSystem->console().fry(); myOSystem.console().fry();
// And update the screen // And update the screen
drawTIA(myRedrawEntireFrame); drawTIA();
// Show frame statistics // Show frame statistics
if(myStatsMsg.enabled) if(myStatsMsg.enabled)
{ {
const ConsoleInfo& info = myOSystem->console().about(); const ConsoleInfo& info = myOSystem.console().about();
char msg[30]; char msg[30];
BSPF_snprintf(msg, 30, "%3u @ %3.2ffps => %s", BSPF_snprintf(msg, 30, "%3u @ %3.2ffps => %s",
myOSystem->console().tia().scanlines(), myOSystem.console().tia().scanlines(),
myOSystem->console().getFramerate(), info.DisplayFormat.c_str()); myOSystem.console().getFramerate(), info.DisplayFormat.c_str());
myStatsMsg.surface->fillRect(0, 0, myStatsMsg.w, myStatsMsg.h, kBGColor); myStatsMsg.surface->fillRect(0, 0, myStatsMsg.w, myStatsMsg.h, kBGColor);
myStatsMsg.surface->drawString(infoFont(), myStatsMsg.surface->drawString(infoFont(),
msg, 1, 1, myStatsMsg.w, myStatsMsg.color, kTextAlignLeft); msg, 1, 1, myStatsMsg.w, myStatsMsg.color, kTextAlignLeft);
@ -306,10 +323,10 @@ void FrameBuffer::update()
{ {
// Only update the screen if it's been invalidated // Only update the screen if it's been invalidated
if(myRedrawEntireFrame) if(myRedrawEntireFrame)
drawTIA(true); drawTIA();
// Show a pause message every 5 seconds // Show a pause message every 5 seconds
if(myPausedCount++ >= 7*myOSystem->frameRate()) if(myPausedCount++ >= 7*myOSystem.frameRate())
{ {
myPausedCount = 0; myPausedCount = 0;
showMessage("Paused", kMiddleCenter); showMessage("Paused", kMiddleCenter);
@ -321,7 +338,7 @@ void FrameBuffer::update()
{ {
// When onscreen messages are enabled in double-buffer mode, // When onscreen messages are enabled in double-buffer mode,
// a full redraw is required // a full redraw is required
myOSystem->menu().draw(myMsg.enabled && isDoubleBuffered()); myOSystem.menu().draw(myMsg.enabled && isDoubleBuffered());
break; // S_MENU break; // S_MENU
} }
@ -329,7 +346,7 @@ void FrameBuffer::update()
{ {
// When onscreen messages are enabled in double-buffer mode, // When onscreen messages are enabled in double-buffer mode,
// a full redraw is required // a full redraw is required
myOSystem->commandMenu().draw(myMsg.enabled && isDoubleBuffered()); myOSystem.commandMenu().draw(myMsg.enabled && isDoubleBuffered());
break; // S_CMDMENU break; // S_CMDMENU
} }
@ -337,7 +354,7 @@ void FrameBuffer::update()
{ {
// When onscreen messages are enabled in double-buffer mode, // When onscreen messages are enabled in double-buffer mode,
// a full redraw is required // a full redraw is required
myOSystem->launcher().draw(myMsg.enabled && isDoubleBuffered()); myOSystem.launcher().draw(myMsg.enabled && isDoubleBuffered());
break; // S_LAUNCHER break; // S_LAUNCHER
} }
@ -346,7 +363,7 @@ void FrameBuffer::update()
{ {
// When onscreen messages are enabled in double-buffer mode, // When onscreen messages are enabled in double-buffer mode,
// a full redraw is required // a full redraw is required
myOSystem->debugger().draw(myMsg.enabled && isDoubleBuffered()); myOSystem.debugger().draw(myMsg.enabled && isDoubleBuffered());
break; // S_DEBUGGER break; // S_DEBUGGER
} }
#endif #endif
@ -371,7 +388,7 @@ void FrameBuffer::showMessage(const string& message, MessagePosition position,
bool force) bool force)
{ {
// Only show messages if they've been enabled // Only show messages if they've been enabled
if(!(force || myOSystem->settings().getBool("uimessages"))) if(!(force || myOSystem.settings().getBool("uimessages")))
return; return;
// Erase old messages on the screen // Erase old messages on the screen
@ -383,7 +400,7 @@ void FrameBuffer::showMessage(const string& message, MessagePosition position,
// Precompute the message coordinates // Precompute the message coordinates
myMsg.text = message; myMsg.text = message;
myMsg.counter = uInt32(myOSystem->frameRate()) << 1; // Show message for 2 seconds myMsg.counter = uInt32(myOSystem.frameRate()) << 1; // Show message for 2 seconds
myMsg.color = kBtnTextColor; myMsg.color = kBtnTextColor;
myMsg.w = font().getStringWidth(myMsg.text) + 10; myMsg.w = font().getStringWidth(myMsg.text) + 10;
@ -397,13 +414,13 @@ void FrameBuffer::showMessage(const string& message, MessagePosition position,
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::toggleFrameStats() void FrameBuffer::toggleFrameStats()
{ {
showFrameStats(!myOSystem->settings().getBool("stats")); showFrameStats(!myOSystem.settings().getBool("stats"));
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::showFrameStats(bool enable) void FrameBuffer::showFrameStats(bool enable)
{ {
myOSystem->settings().setValue("stats", enable); myOSystem.settings().setValue("stats", enable);
myStatsMsg.enabled = enable; myStatsMsg.enabled = enable;
refresh(); refresh();
} }
@ -414,7 +431,7 @@ void FrameBuffer::enableMessages(bool enable)
if(enable) if(enable)
{ {
// Only re-enable frame stats if they were already enabled before // Only re-enable frame stats if they were already enabled before
myStatsMsg.enabled = myOSystem->settings().getBool("stats"); myStatsMsg.enabled = myOSystem.settings().getBool("stats");
} }
else else
{ {
@ -502,6 +519,15 @@ inline void FrameBuffer::drawMessage()
} }
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
inline void FrameBuffer::drawTIA()
{
myTIASurface->render();
// Let postFrameUpdate() know that a change has been made
//FIXSDL invalidate();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::refresh() void FrameBuffer::refresh()
{ {
@ -514,66 +540,66 @@ void FrameBuffer::refresh()
// This method is in essence a FULL refresh, putting all rendering // This method is in essence a FULL refresh, putting all rendering
// buffers in a known, fully redrawn state // buffers in a known, fully redrawn state
switch(myOSystem->eventHandler().state()) switch(myOSystem.eventHandler().state())
{ {
case EventHandler::S_EMULATE: case EventHandler::S_EMULATE:
case EventHandler::S_PAUSE: case EventHandler::S_PAUSE:
invalidate(); invalidate();
drawTIA(true); drawTIA();
if(isDoubleBuffered()) if(isDoubleBuffered())
{ {
postFrameUpdate(); postFrameUpdate();
invalidate(); invalidate();
drawTIA(true); drawTIA();
} }
break; break;
case EventHandler::S_MENU: case EventHandler::S_MENU:
invalidate(); invalidate();
drawTIA(true); drawTIA();
myOSystem->menu().draw(true); myOSystem.menu().draw(true);
if(isDoubleBuffered()) if(isDoubleBuffered())
{ {
postFrameUpdate(); postFrameUpdate();
invalidate(); invalidate();
drawTIA(true); drawTIA();
myOSystem->menu().draw(true); myOSystem.menu().draw(true);
} }
break; break;
case EventHandler::S_CMDMENU: case EventHandler::S_CMDMENU:
invalidate(); invalidate();
drawTIA(true); drawTIA();
myOSystem->commandMenu().draw(true); myOSystem.commandMenu().draw(true);
if(isDoubleBuffered()) if(isDoubleBuffered())
{ {
postFrameUpdate(); postFrameUpdate();
invalidate(); invalidate();
drawTIA(true); drawTIA();
myOSystem->commandMenu().draw(true); myOSystem.commandMenu().draw(true);
} }
break; break;
case EventHandler::S_LAUNCHER: case EventHandler::S_LAUNCHER:
invalidate(); invalidate();
myOSystem->launcher().draw(true); myOSystem.launcher().draw(true);
if(isDoubleBuffered()) if(isDoubleBuffered())
{ {
postFrameUpdate(); postFrameUpdate();
invalidate(); invalidate();
myOSystem->launcher().draw(true); myOSystem.launcher().draw(true);
} }
break; break;
#ifdef DEBUGGER_SUPPORT #ifdef DEBUGGER_SUPPORT
case EventHandler::S_DEBUGGER: case EventHandler::S_DEBUGGER:
invalidate(); invalidate();
myOSystem->debugger().draw(true); myOSystem.debugger().draw(true);
if(isDoubleBuffered()) if(isDoubleBuffered())
{ {
postFrameUpdate(); postFrameUpdate();
invalidate(); invalidate();
myOSystem->debugger().draw(true); myOSystem.debugger().draw(true);
} }
break; break;
#endif #endif
@ -583,59 +609,6 @@ void FrameBuffer::refresh()
} }
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::setNTSC(NTSCFilter::Preset preset, bool show)
{
ostringstream buf;
if(preset == NTSCFilter::PRESET_OFF)
{
enableNTSC(false);
buf << "TV filtering disabled";
}
else
{
enableNTSC(true);
const string& mode = myNTSCFilter.setPreset(preset);
buf << "TV filtering (" << mode << " mode)";
}
myOSystem->settings().setValue("tv.filter", (int)preset);
if(show) showMessage(buf.str());
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::setScanlineIntensity(int amount)
{
ostringstream buf;
if(ntscEnabled())
{
uInt32 intensity = enableScanlines(amount);
buf << "Scanline intensity at " << intensity << "%";
myOSystem->settings().setValue("tv.scanlines", intensity);
}
else
buf << "Scanlines only available in TV filtering mode";
showMessage(buf.str());
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::toggleScanlineInterpolation()
{
ostringstream buf;
if(ntscEnabled())
{
bool enable = !myOSystem->settings().getBool("tv.scaninter");
enableScanlineInterpolation(enable);
buf << "Scanline interpolation " << (enable ? "enabled" : "disabled");
myOSystem->settings().setValue("tv.scaninter", enable);
}
else
buf << "Scanlines only available in TV filtering mode";
showMessage(buf.str());
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 FrameBuffer::allocateSurface(int w, int h) uInt32 FrameBuffer::allocateSurface(int w, int h)
{ {
@ -646,7 +619,7 @@ uInt32 FrameBuffer::allocateSurface(int w, int h)
mySurfaceList.insert(make_pair((uInt32)mySurfaceList.size(), surface)); mySurfaceList.insert(make_pair((uInt32)mySurfaceList.size(), surface));
// Return a reference to it // Return a reference to it
return mySurfaceList.size() - 1; return (uInt32)mySurfaceList.size() - 1;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -657,7 +630,7 @@ FBSurface* FrameBuffer::surface(uInt32 id) const
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::resetSurfaces(FBSurface* tiasurface) void FrameBuffer::resetSurfaces()
{ {
// Free all resources for each surface, then reload them // Free all resources for each surface, then reload them
// Due to possible timing and/or synchronization issues, all free()'s // Due to possible timing and/or synchronization issues, all free()'s
@ -668,75 +641,30 @@ void FrameBuffer::resetSurfaces(FBSurface* tiasurface)
map<uInt32,FBSurface*>::iterator iter; map<uInt32,FBSurface*>::iterator iter;
for(iter = mySurfaceList.begin(); iter != mySurfaceList.end(); ++iter) for(iter = mySurfaceList.begin(); iter != mySurfaceList.end(); ++iter)
iter->second->free(); iter->second->free();
if(tiasurface)
tiasurface->free();
for(iter = mySurfaceList.begin(); iter != mySurfaceList.end(); ++iter) for(iter = mySurfaceList.begin(); iter != mySurfaceList.end(); ++iter)
iter->second->reload(); iter->second->reload();
if(tiasurface)
tiasurface->reload();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 FrameBuffer::tiaPixel(uInt32 idx, uInt8 shift) const void FrameBuffer::setPalette(const uInt32* palette)
{ {
uInt8 c = *(myOSystem->console().tia().currentFrameBuffer() + idx) | shift; cerr << "FrameBuffer::setPalette\n";
uInt8 p = *(myOSystem->console().tia().previousFrameBuffer() + idx) | shift;
return (!myUsePhosphor ? myDefPalette[c] : myAvgPalette[c][p]);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::setTIAPalette(const uInt32* palette)
{
int i, j;
// Set palette for normal fill // Set palette for normal fill
for(i = 0; i < 256; ++i) for(int i = 0; i < 256; ++i)
{ {
Uint8 r = (palette[i] >> 16) & 0xff; Uint8 r = (palette[i] >> 16) & 0xff;
Uint8 g = (palette[i] >> 8) & 0xff; Uint8 g = (palette[i] >> 8) & 0xff;
Uint8 b = palette[i] & 0xff; Uint8 b = palette[i] & 0xff;
myDefPalette[i] = mapRGB(r, g, b); myPalette[i] = mapRGB(r, g, b);
} }
// Set palette for phosphor effect // Let the TIA surface know about the new palette
for(i = 0; i < 256; ++i) myTIASurface->setPalette(myPalette, palette);
{
for(j = 0; j < 256; ++j)
{
uInt8 ri = (palette[i] >> 16) & 0xff;
uInt8 gi = (palette[i] >> 8) & 0xff;
uInt8 bi = palette[i] & 0xff;
uInt8 rj = (palette[j] >> 16) & 0xff;
uInt8 gj = (palette[j] >> 8) & 0xff;
uInt8 bj = palette[j] & 0xff;
Uint8 r = (Uint8) getPhosphor(ri, rj);
Uint8 g = (Uint8) getPhosphor(gi, gj);
Uint8 b = (Uint8) getPhosphor(bi, bj);
myAvgPalette[i][j] = mapRGB(r, g, b);
}
}
myRedrawEntireFrame = true; myRedrawEntireFrame = true;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::setUIPalette()
{
// Set palette for GUI
for(int i = 0, j = 256; i < kNumColors-256; ++i, ++j)
{
Uint8 r = (ourGUIColors[i] >> 16) & 0xff;
Uint8 g = (ourGUIColors[i] >> 8) & 0xff;
Uint8 b = ourGUIColors[i] & 0xff;
myDefPalette[j] = mapRGB(r, g, b);
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::stateChanged(EventHandler::State state) void FrameBuffer::stateChanged(EventHandler::State state)
{ {
@ -758,7 +686,7 @@ enableFullscreen(enable);
#if 0 //FIXSDL #if 0 //FIXSDL
#ifdef WINDOWED_SUPPORT #ifdef WINDOWED_SUPPORT
// '-1' means fullscreen mode is completely disabled // '-1' means fullscreen mode is completely disabled
bool full = enable && myOSystem->settings().getString("fullscreen") != "-1"; bool full = enable && myOSystem.settings().getString("fullscreen") != "-1";
setHint(kFullScreen, full); setHint(kFullScreen, full);
// Do a dummy call to getSavedVidMode to set up the modelists // Do a dummy call to getSavedVidMode to set up the modelists
@ -782,7 +710,7 @@ void FrameBuffer::toggleFullscreen()
bool FrameBuffer::changeWindowedVidMode(int direction) bool FrameBuffer::changeWindowedVidMode(int direction)
{ {
#ifdef WINDOWED_SUPPORT #ifdef WINDOWED_SUPPORT
EventHandler::State state = myOSystem->eventHandler().state(); EventHandler::State state = myOSystem.eventHandler().state();
bool tiaMode = (state != EventHandler::S_DEBUGGER && bool tiaMode = (state != EventHandler::S_DEBUGGER &&
state != EventHandler::S_LAUNCHER); state != EventHandler::S_LAUNCHER);
@ -800,10 +728,11 @@ bool FrameBuffer::changeWindowedVidMode(int direction)
const VideoMode& mode = myCurrentModeList->current(); const VideoMode& mode = myCurrentModeList->current();
myImageRect = mode.image; myImageRect = mode.image;
myScreenSize = mode.screen; myScreenSize = mode.screen;
if(setVideoMode(myScreenTitle, mode, false)) if(setVideoMode(myScreenTitle, mode))
{ {
resetSurfaces();
showMessage(mode.description); showMessage(mode.description);
myOSystem->settings().setValue("tia.zoom", mode.zoom); myOSystem.settings().setValue("tia.zoom", mode.zoom);
refresh(); refresh();
return true; return true;
} }
@ -817,29 +746,20 @@ void FrameBuffer::setCursorState()
// Always grab mouse in fullscreen or during emulation (if enabled), // Always grab mouse in fullscreen or during emulation (if enabled),
// and don't show the cursor during emulation // and don't show the cursor during emulation
bool emulation = bool emulation =
myOSystem->eventHandler().state() == EventHandler::S_EMULATE; myOSystem.eventHandler().state() == EventHandler::S_EMULATE;
grabMouse(fullScreen() || grabMouse(fullScreen() ||
(emulation && myOSystem->settings().getBool("grabmouse"))); (emulation && myOSystem.settings().getBool("grabmouse")));
showCursor(!emulation); showCursor(!emulation);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::toggleGrabMouse() void FrameBuffer::toggleGrabMouse()
{ {
bool state = myOSystem->settings().getBool("grabmouse"); bool state = myOSystem.settings().getBool("grabmouse");
myOSystem->settings().setValue("grabmouse", !state); myOSystem.settings().setValue("grabmouse", !state);
setCursorState(); setCursorState();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 FrameBuffer::getPhosphor(uInt8 c1, uInt8 c2) const
{
if(c2 > c1)
BSPF_swap(c1, c2);
return ((c1 - c2) * myPhosphorBlend)/100 + c2;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 FrameBuffer::maxWindowSizeForScreen(uInt32 baseWidth, uInt32 baseHeight, uInt32 FrameBuffer::maxWindowSizeForScreen(uInt32 baseWidth, uInt32 baseHeight,
uInt32 screenWidth, uInt32 screenHeight) uInt32 screenWidth, uInt32 screenHeight)
@ -867,7 +787,7 @@ void FrameBuffer::setAvailableVidModes(uInt32 baseWidth, uInt32 baseHeight)
// Check if zooming is allowed for this state (currently only allowed // Check if zooming is allowed for this state (currently only allowed
// for TIA screens) // for TIA screens)
EventHandler::State state = myOSystem->eventHandler().state(); EventHandler::State state = myOSystem.eventHandler().state();
bool tiaMode = (state != EventHandler::S_DEBUGGER && bool tiaMode = (state != EventHandler::S_DEBUGGER &&
state != EventHandler::S_LAUNCHER); state != EventHandler::S_LAUNCHER);
@ -880,8 +800,8 @@ void FrameBuffer::setAvailableVidModes(uInt32 baseWidth, uInt32 baseHeight)
myDesktopSize.w, myDesktopSize.h); myDesktopSize.w, myDesktopSize.h);
// Aspect ratio // Aspect ratio
bool ntsc = myOSystem->console().about().InitialFrameRate == "60"; bool ntsc = myOSystem.console().about().InitialFrameRate == "60";
uInt32 aspect = myOSystem->settings().getInt(ntsc ? uInt32 aspect = myOSystem.settings().getInt(ntsc ?
"tia.aspectn" : "tia.aspectp"); "tia.aspectn" : "tia.aspectp");
// Figure our the smallest zoom level we can use // Figure our the smallest zoom level we can use
@ -925,9 +845,9 @@ cerr << "Windowed modes:\n" << myWindowedModeList << endl
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const FrameBuffer::VideoMode& FrameBuffer::getSavedVidMode(bool fullscreen) const VideoMode& FrameBuffer::getSavedVidMode(bool fullscreen)
{ {
EventHandler::State state = myOSystem->eventHandler().state(); EventHandler::State state = myOSystem.eventHandler().state();
if(fullscreen) if(fullscreen)
myCurrentModeList = &myFullscreenModeList; myCurrentModeList = &myFullscreenModeList;
@ -940,7 +860,7 @@ const FrameBuffer::VideoMode& FrameBuffer::getSavedVidMode(bool fullscreen)
if(state == EventHandler::S_DEBUGGER || state == EventHandler::S_LAUNCHER) if(state == EventHandler::S_DEBUGGER || state == EventHandler::S_LAUNCHER)
myCurrentModeList->setZoom(1); myCurrentModeList->setZoom(1);
else else
myCurrentModeList->setZoom(myOSystem->settings().getInt("tia.zoom")); myCurrentModeList->setZoom(myOSystem.settings().getInt("tia.zoom"));
return myCurrentModeList->current(); return myCurrentModeList->current();
} }
@ -950,7 +870,7 @@ const FrameBuffer::VideoMode& FrameBuffer::getSavedVidMode(bool fullscreen)
// VideoMode implementation // VideoMode implementation
// //
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FrameBuffer::VideoMode::VideoMode() VideoMode::VideoMode()
: fullscreen(false), : fullscreen(false),
zoom(1), zoom(1),
description("") description("")
@ -958,7 +878,7 @@ FrameBuffer::VideoMode::VideoMode()
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FrameBuffer::VideoMode::VideoMode(uInt32 iw, uInt32 ih, uInt32 sw, uInt32 sh, VideoMode::VideoMode(uInt32 iw, uInt32 ih, uInt32 sw, uInt32 sh,
bool full, uInt32 z, const string& desc) bool full, uInt32 z, const string& desc)
: fullscreen(full), : fullscreen(full),
zoom(z), zoom(z),
@ -975,7 +895,7 @@ FrameBuffer::VideoMode::VideoMode(uInt32 iw, uInt32 ih, uInt32 sw, uInt32 sh,
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::VideoMode::applyAspectCorrection(uInt32 aspect, uInt32 stretch) void VideoMode::applyAspectCorrection(uInt32 aspect, uInt32 stretch)
{ {
// Width is modified by aspect ratio; other factors may be applied below // Width is modified by aspect ratio; other factors may be applied below
uInt32 iw = (uInt32)(float(image.width() * aspect) / 100.0); uInt32 iw = (uInt32)(float(image.width() * aspect) / 100.0);
@ -993,7 +913,7 @@ void FrameBuffer::VideoMode::applyAspectCorrection(uInt32 aspect, uInt32 stretch
float scaleY = float(mode.image_h) / mode.screen_h; float scaleY = float(mode.image_h) / mode.screen_h;
// Scale to actual or integral factors // Scale to actual or integral factors
if(myOSystem->settings().getBool("gl_fsscale")) if(myOSystem.settings().getBool("gl_fsscale"))
{ {
// Scale to full (non-integral) available space // Scale to full (non-integral) available space
if(scaleX > scaleY) if(scaleX > scaleY)
@ -1084,7 +1004,7 @@ void FrameBuffer::VideoModeList::previous()
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const FrameBuffer::VideoMode& FrameBuffer::VideoModeList::current() const const VideoMode& FrameBuffer::VideoModeList::current() const
{ {
return myModeList[myIdx]; return myModeList[myIdx];
} }

View File

@ -30,12 +30,12 @@ namespace GUI {
class Font; class Font;
} }
#include "FBSurface.hxx"
#include "EventHandler.hxx" #include "EventHandler.hxx"
#include "Rect.hxx" #include "Rect.hxx"
#include "StringList.hxx" #include "StringList.hxx"
#include "NTSCFilter.hxx"
#include "Variant.hxx" #include "Variant.hxx"
#include "FBSurface.hxx"
#include "TIASurface.hxx"
#include "bspf.hxx" #include "bspf.hxx"
// Return values for initialization of framebuffer window // Return values for initialization of framebuffer window
@ -85,6 +85,39 @@ enum {
kNumColors kNumColors
}; };
// Contains all relevant info for the dimensions of a video screen
// Also takes care of the case when the image should be 'centered'
// within the given screen:
// 'image' is the image dimensions into the screen
// 'screen' are the dimensions of the screen itself
class VideoMode
{
friend class FrameBuffer;
public:
GUI::Rect image;
GUI::Size screen;
bool fullscreen;
uInt32 zoom;
string description;
public:
VideoMode();
VideoMode(uInt32 iw, uInt32 ih, uInt32 sw, uInt32 sh, bool full,
uInt32 z = 1, const string& desc = "");
friend ostream& operator<<(ostream& os, const VideoMode& vm)
{
os << "image=" << vm.image << " screen=" << vm.screen << endl
<< "full= " << vm.fullscreen << " zoom=" << vm.zoom
<< " desc=" << vm.description;
return os;
}
private:
void applyAspectCorrection(uInt32 aspect, uInt32 stretch = false);
};
/** /**
This class encapsulates all video buffers and is the basis for the video This class encapsulates all video buffers and is the basis for the video
display in Stella. All graphics ports should derive from this class for display in Stella. All graphics ports should derive from this class for
@ -107,7 +140,7 @@ class FrameBuffer
/** /**
Creates a new Frame Buffer Creates a new Frame Buffer
*/ */
FrameBuffer(OSystem* osystem); FrameBuffer(OSystem& osystem);
/** /**
Destructor Destructor
@ -210,6 +243,11 @@ class FrameBuffer
*/ */
const VariantList& supportedRenderers() const { return myRenderers; } const VariantList& supportedRenderers() const { return myRenderers; }
/**
Get the supported TIA zoom levels (windowed mode) for the framebuffer.
*/
const VariantList& supportedTIAZoomLevels() const { return myTIAZoomLevels; }
/** /**
Get the font object(s) of the framebuffer Get the font object(s) of the framebuffer
*/ */
@ -218,6 +256,11 @@ class FrameBuffer
const GUI::Font& smallFont() const { return *mySmallFont; } const GUI::Font& smallFont() const { return *mySmallFont; }
const GUI::Font& launcherFont() const { return *myLauncherFont; } const GUI::Font& launcherFont() const { return *myLauncherFont; }
/**
Get the TIA surface associated with the framebuffer.
*/
TIASurface& tiaSurface() const { return *myTIASurface; }
/** /**
Refresh display according to the current state, taking single vs. Refresh display according to the current state, taking single vs.
double-buffered modes into account, and redrawing accordingly. double-buffered modes into account, and redrawing accordingly.
@ -256,91 +299,18 @@ class FrameBuffer
*/ */
void toggleGrabMouse(); void toggleGrabMouse();
/**
Get the supported TIA zoom levels (windowed mode) for the framebuffer.
*/
const VariantList& supportedTIAZoomLevels() { return myTIAZoomLevels; }
/**
Get the TIA pixel associated with the given TIA buffer index,
shifting by the given offset (for greyscale values).
*/
uInt32 tiaPixel(uInt32 idx, uInt8 shift = 0) const;
/** /**
Set up the TIA/emulation palette for a screen of any depth > 8. Set up the TIA/emulation palette for a screen of any depth > 8.
@param palette The array of colors @param palette The array of colors
*/ */
virtual void setTIAPalette(const uInt32* palette); void setPalette(const uInt32* palette);
/** /**
Informs the Framebuffer of a change in EventHandler state. Informs the Framebuffer of a change in EventHandler state.
*/ */
void stateChanged(EventHandler::State state); void stateChanged(EventHandler::State state);
/**
Get the NTSCFilter object associated with the framebuffer
*/
NTSCFilter& ntsc() { return myNTSCFilter; }
/**
Use NTSC filtering effects specified by the given preset.
*/
void setNTSC(NTSCFilter::Preset preset, bool show = true);
/**
Increase/decrease current scanline intensity by given relative amount.
*/
void setScanlineIntensity(int relative);
/**
Toggles interpolation/smoothing of scanlines in TV modes.
*/
void toggleScanlineInterpolation();
/**
Used to calculate an averaged color for the 'phosphor' effect.
@param c1 Color 1
@param c2 Color 2
@return Averaged value of the two colors
*/
uInt8 getPhosphor(uInt8 c1, uInt8 c2) const;
// Contains all relevant info for the dimensions of a video screen
// Also takes care of the case when the image should be 'centered'
// within the given screen:
// 'image' is the image dimensions into the screen
// 'screen' are the dimensions of the screen itself
class VideoMode
{
friend class FrameBuffer;
public:
GUI::Rect image;
GUI::Size screen;
bool fullscreen;
uInt32 zoom;
string description;
public:
VideoMode();
VideoMode(uInt32 iw, uInt32 ih, uInt32 sw, uInt32 sh, bool full,
uInt32 z = 1, const string& desc = "");
friend ostream& operator<<(ostream& os, const VideoMode& vm)
{
os << "image=" << vm.image << " screen=" << vm.screen << endl
<< "desc=" << vm.description << " zoom=" << vm.zoom;
return os;
}
private:
void applyAspectCorrection(uInt32 aspect, uInt32 stretch = false);
};
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// The following methods are system-specific and can/must be // The following methods are system-specific and can/must be
// implemented in derived classes. // implemented in derived classes.
@ -356,18 +326,6 @@ class FrameBuffer
*/ */
virtual bool fullScreen() const = 0; virtual bool fullScreen() const = 0;
/**
Enable/disable/query NTSC filtering effects.
*/
virtual void enableNTSC(bool enable) { }
virtual bool ntscEnabled() const { return false; }
virtual string effectsInfo() const { return "None / not available"; }
/**
Enable/disable phosphor effect.
*/
virtual void enablePhosphor(bool enable, int blend) = 0;
/** /**
This method is called to retrieve the R/G/B data from the given pixel. This method is called to retrieve the R/G/B data from the given pixel.
@ -411,16 +369,14 @@ class FrameBuffer
virtual void queryHardware(uInt32& w, uInt32& h, VariantList& ren) = 0; virtual void queryHardware(uInt32& w, uInt32& h, VariantList& ren) = 0;
/** /**
This method is called to change to the given video mode. If the mode This method is called to change to the given video mode.
is successfully changed, 'mode' holds the actual dimensions used.
@param title The title for the created window @param title The title for the created window
@param mode The video mode to use @param mode The video mode to use
@param full Whether this is a fullscreen or windowed mode
@return False on any errors, else true @return False on any errors, else true
*/ */
virtual bool setVideoMode(const string& title, const VideoMode& mode, bool full) = 0; virtual bool setVideoMode(const string& title, const VideoMode& mode) = 0;
/** /**
Enables/disables fullscreen mode. Enables/disables fullscreen mode.
@ -444,16 +400,6 @@ class FrameBuffer
*/ */
virtual FBSurface* createSurface(uInt32 w, uInt32 h) const = 0; virtual FBSurface* createSurface(uInt32 w, uInt32 h) const = 0;
/**
Change scanline intensity and interpolation.
@param relative If non-zero, change current intensity by
'relative' amount, otherwise set to 'absolute'
@return New current intensity
*/
virtual uInt32 enableScanlines(int relative, int absolute = 50) { return absolute; }
virtual void enableScanlineInterpolation(bool enable) { }
/** /**
Grabs or ungrabs the mouse based on the given boolean value. Grabs or ungrabs the mouse based on the given boolean value.
*/ */
@ -464,12 +410,6 @@ class FrameBuffer
*/ */
virtual void setWindowIcon() = 0; virtual void setWindowIcon() = 0;
/**
This method should be called anytime the TIA needs to be redrawn
to the screen (full indicating that a full redraw is required).
*/
virtual void drawTIA(bool full) = 0;
/** /**
This method is called after any drawing is done (per-frame). This method is called after any drawing is done (per-frame).
*/ */
@ -480,35 +420,15 @@ class FrameBuffer
*/ */
virtual string about() const = 0; virtual string about() const = 0;
/**
Issues a 'free' and 'reload' instruction to all surfaces that the
framebuffer knows about.
*/
void resetSurfaces(FBSurface* tiasurface = (FBSurface*)0);
protected: protected:
// The parent system for the framebuffer // The parent system for the framebuffer
OSystem* myOSystem; OSystem& myOSystem;
// Indicates if the entire frame need to redrawn // Indicates if the entire frame need to redrawn
bool myRedrawEntireFrame; bool myRedrawEntireFrame;
// NTSC object to use in TIA rendering mode // Color palette for TIA and UI modes
NTSCFilter myNTSCFilter; Uint32 myPalette[256+kNumColors];
// Use phosphor effect (aka no flicker on 30Hz screens)
bool myUsePhosphor;
// Amount to blend when using phosphor effect
int myPhosphorBlend;
// TIA palettes for normal and phosphor modes
// 'myDefPalette' also contains the UI palette
Uint32 myDefPalette[256+kNumColors];
Uint32 myAvgPalette[256][256];
// Names of the TIA zoom levels that can be used for this framebuffer
VariantList myTIAZoomLevels;
private: private:
/** /**
@ -516,6 +436,18 @@ class FrameBuffer
*/ */
void drawMessage(); void drawMessage();
/**
This method should be called anytime the TIA needs to be redrawn
to the screen.
*/
void drawTIA();
/**
Issues a 'free' and 'reload' instruction to all surfaces that the
framebuffer knows about.
*/
void resetSurfaces();
/** /**
Calculate the maximum level by which the base window can be zoomed and Calculate the maximum level by which the base window can be zoomed and
still fit in the given screen dimensions. still fit in the given screen dimensions.
@ -544,11 +476,6 @@ class FrameBuffer
*/ */
const VideoMode& getSavedVidMode(bool fullscreen); const VideoMode& getSavedVidMode(bool fullscreen);
/**
Set up the user interface palette for a screen of any depth > 8.
*/
void setUIPalette();
private: private:
/** /**
This class implements an iterator around an array of VideoMode objects. This class implements an iterator around an array of VideoMode objects.
@ -566,7 +493,7 @@ class FrameBuffer
uInt32 size() const; uInt32 size() const;
void previous(); void previous();
const FrameBuffer::VideoMode& current() const; const VideoMode& current() const;
void next(); void next();
void setZoom(uInt32 zoom); void setZoom(uInt32 zoom);
@ -619,6 +546,9 @@ class FrameBuffer
// The font object to use for the ROM launcher // The font object to use for the ROM launcher
GUI::Font* myLauncherFont; GUI::Font* myLauncherFont;
// The TIASurface class takes responsibility for TIA rendering
TIASurface* myTIASurface;
// Used for onscreen messages and frame statistics // Used for onscreen messages and frame statistics
// (scanline count and framerate) // (scanline count and framerate)
struct Message { struct Message {
@ -638,6 +568,9 @@ class FrameBuffer
VideoModeList myFullscreenModeList; VideoModeList myFullscreenModeList;
VideoModeList* myCurrentModeList; VideoModeList* myCurrentModeList;
// Names of the TIA zoom levels that can be used for this framebuffer
VariantList myTIAZoomLevels;
// Holds a reference to all the surfaces that have been created // Holds a reference to all the surfaces that have been created
map<uInt32,FBSurface*> mySurfaceList; map<uInt32,FBSurface*> mySurfaceList;

View File

@ -74,7 +74,7 @@ class MediaFactory
#endif #endif
} }
static Settings* createSettings(OSystem* osystem) static Settings* createSettings(OSystem& osystem)
{ {
#if defined(BSPF_UNIX) #if defined(BSPF_UNIX)
return new SettingsUNIX(osystem); return new SettingsUNIX(osystem);
@ -87,12 +87,12 @@ class MediaFactory
#endif #endif
} }
static FrameBuffer* createVideo(OSystem* osystem) static FrameBuffer* createVideo(OSystem& osystem)
{ {
return new FrameBufferSDL2(osystem); return new FrameBufferSDL2(osystem);
} }
static Sound* createAudio(OSystem* osystem) static Sound* createAudio(OSystem& osystem)
{ {
#ifdef SOUND_SUPPORT #ifdef SOUND_SUPPORT
return new SoundSDL2(osystem); return new SoundSDL2(osystem);
@ -101,7 +101,7 @@ class MediaFactory
#endif #endif
} }
static EventHandler* createEventHandler(OSystem* osystem) static EventHandler* createEventHandler(OSystem& osystem)
{ {
return new EventHandlerSDL2(osystem); return new EventHandlerSDL2(osystem);
} }

View File

@ -115,7 +115,7 @@ OSystem::OSystem()
<< " [" << BSPF_ARCH << "]"; << " [" << BSPF_ARCH << "]";
myBuildInfo = info.str(); myBuildInfo = info.str();
mySettings = MediaFactory::createSettings(this); mySettings = MediaFactory::createSettings(*this);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -174,12 +174,12 @@ bool OSystem::create()
// Get relevant information about the video hardware // Get relevant information about the video hardware
// This must be done before any graphics context is created, since // This must be done before any graphics context is created, since
// it may be needed to initialize the size of graphical objects // it may be needed to initialize the size of graphical objects
myFrameBuffer = MediaFactory::createVideo(this); myFrameBuffer = MediaFactory::createVideo(*this);
if(!myFrameBuffer->initialize()) if(!myFrameBuffer->initialize())
return false; return false;
// Create the event handler for the system // Create the event handler for the system
myEventHandler = MediaFactory::createEventHandler(this); myEventHandler = MediaFactory::createEventHandler(*this);
myEventHandler->initialize(); myEventHandler->initialize();
// Create a properties set for us to use and set it up // Create a properties set for us to use and set it up
@ -238,7 +238,7 @@ void OSystem::saveConfig()
{ {
// Ask all subsystems to save their settings // Ask all subsystems to save their settings
if(myFrameBuffer) if(myFrameBuffer)
myFrameBuffer->ntsc().saveConfig(*mySettings); myFrameBuffer->tiaSurface().ntsc().saveConfig(*mySettings);
mySettings->saveConfig(); mySettings->saveConfig();
} }
@ -352,7 +352,7 @@ FBInitStatus OSystem::createFrameBuffer()
void OSystem::createSound() void OSystem::createSound()
{ {
if(!mySound) if(!mySound)
mySound = MediaFactory::createAudio(this); mySound = MediaFactory::createAudio(*this);
#ifndef SOUND_SUPPORT #ifndef SOUND_SUPPORT
mySettings->setValue("sound", false); mySettings->setValue("sound", false);
#endif #endif
@ -626,7 +626,7 @@ Console* OSystem::openConsole(const FilesystemNode& romfile, string& md5,
// Finally, create the cart with the correct properties // Finally, create the cart with the correct properties
if(cart) if(cart)
console = new Console(this, cart, props); console = new Console(*this, *cart, props);
} }
// Free the image since we don't need it any longer // Free the image since we don't need it any longer

View File

@ -34,7 +34,7 @@
#include "Settings.hxx" #include "Settings.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Settings::Settings(OSystem* osystem) Settings::Settings(OSystem& osystem)
: myOSystem(osystem) : myOSystem(osystem)
{ {
// Video-related options // Video-related options
@ -165,10 +165,10 @@ void Settings::loadConfig()
string line, key, value; string line, key, value;
string::size_type equalPos, garbage; string::size_type equalPos, garbage;
ifstream in(myOSystem->configFile().c_str()); ifstream in(myOSystem.configFile().c_str());
if(!in || !in.is_open()) if(!in || !in.is_open())
{ {
myOSystem->logMessage("ERROR: Couldn't load settings file", 0); myOSystem.logMessage("ERROR: Couldn't load settings file", 0);
return; return;
} }
@ -236,7 +236,7 @@ string Settings::loadCommandLine(int argc, char** argv)
if(++i >= argc) if(++i >= argc)
{ {
buf << "Missing argument for '" << key << "'" << endl; buf << "Missing argument for '" << key << "'" << endl;
myOSystem->logMessage(buf.str(), 0); myOSystem.logMessage(buf.str(), 0);
return ""; return "";
} }
string value = argv[i]; string value = argv[i];
@ -257,7 +257,7 @@ string Settings::loadCommandLine(int argc, char** argv)
buf << "(E)\n"; buf << "(E)\n";
} }
myOSystem->logMessage(buf.str(), 2); myOSystem.logMessage(buf.str(), 2);
} }
else else
return key; return key;
@ -513,10 +513,10 @@ void Settings::saveConfig()
if(!settingsChanged) if(!settingsChanged)
return; return;
ofstream out(myOSystem->configFile().c_str()); ofstream out(myOSystem.configFile().c_str());
if(!out || !out.is_open()) if(!out || !out.is_open())
{ {
myOSystem->logMessage("ERROR: Couldn't save settings file", 0); myOSystem.logMessage("ERROR: Couldn't save settings file", 0);
return; return;
} }
@ -674,7 +674,8 @@ int Settings::setExternal(const string& key, const Variant& value,
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Settings::Settings(const Settings&) Settings::Settings(const Settings& s)
: myOSystem(s.myOSystem)
{ {
} }

View File

@ -40,7 +40,7 @@ class Settings
/** /**
Create a new settings abstract class Create a new settings abstract class
*/ */
Settings(OSystem* osystem); Settings(OSystem& osystem);
/** /**
Destructor Destructor
@ -122,7 +122,7 @@ class Settings
protected: protected:
// The parent OSystem object // The parent OSystem object
OSystem* myOSystem; OSystem& myOSystem;
// Structure used for storing settings // Structure used for storing settings
struct Setting struct Setting

View File

@ -39,7 +39,7 @@ class Sound : public Serializable
Create a new sound object. The init method must be invoked before Create a new sound object. The init method must be invoked before
using the object. using the object.
*/ */
Sound(OSystem* osystem) { myOSystem = osystem; } Sound(OSystem& osystem) : myOSystem(osystem) { }
/** /**
Destructor Destructor
@ -129,7 +129,7 @@ class Sound : public Serializable
protected: protected:
// The OSystem for this sound object // The OSystem for this sound object
OSystem* myOSystem; OSystem& myOSystem;
}; };
#endif #endif

371
src/emucore/TIASurface.cxx Normal file
View File

@ -0,0 +1,371 @@
//============================================================================
//
// 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-2014 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 "FrameBuffer.hxx"
#include "Settings.hxx"
#include "OSystem.hxx"
#include "Console.hxx"
#include "TIA.hxx"
#include "TIASurface.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TIASurface::TIASurface(FrameBuffer& buffer, OSystem& system)
: myFB(buffer),
myOSystem(system),
myTIA(NULL),
myTiaSurface(NULL),
mySLineSurface(NULL),
myFilterType(kNormal),
myUsePhosphor(false),
myPhosphorBlend(77),
myScanlinesEnabled(false)
{
// Load NTSC filter settings
myNTSCFilter.loadConfig(myOSystem.settings());
// Create a surface for the TIA image and scanlines; we'll need them eventually
uInt32 tiaID = myFB.allocateSurface(ATARI_NTSC_OUT_WIDTH(160), 320);
myTiaSurface = myFB.surface(tiaID);
uInt32 scanID = myFB.allocateSurface(1, 320);
mySLineSurface = myFB.surface(scanID);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TIASurface::~TIASurface()
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIASurface::initialize(const Console& console, const VideoMode& mode)
{
myTIA = &(console.tia());
#if 0
// FIX HERE ///////////////////////////////////
#if 0
bool enable = myProperties.get(Display_Phosphor) == "YES";
int blend = atoi(myProperties.get(Display_PPBlend).c_str());
myOSystem.frameBuffer().tiaSurface().enablePhosphor(enable, blend);
myOSystem.frameBuffer().tiaSurface().setNTSC(
(NTSCFilter::Preset)myOSystem.settings().getInt("tv.filter"), false);
#endif
// Grab the initial height before it's updated below
// We need it for the creating the TIA surface
uInt32 baseHeight = mode.image.height() / mode.zoom;
// The framebuffer only takes responsibility for TIA surfaces
// Other surfaces (such as the ones used for dialogs) are allocated
// in the Dialog class
if(inTIAMode)
{
// Since we have free hardware stretching, the base TIA surface is created
// only once, and its texture coordinates changed when we want to draw a
// smaller or larger image
if(!myTiaSurface)
myTiaSurface = new FBSurfaceTIA(*this);
myTiaSurface->updateCoords(baseHeight, mode.image.x(), mode.image.y(),
mode.image.width(), mode.image.height());
myTiaSurface->enableScanlines(ntscEnabled());
myTiaSurface->setTexInterpolation(myOSystem.settings().getBool("tia.inter"));
myTiaSurface->setScanIntensity(myOSystem.settings().getInt("tv.scanlines"));
myTiaSurface->setScanInterpolation(myOSystem.settings().getBool("tv.scaninter"));
myTiaSurface->setTIA(myOSystem.console().tia());
}
/////////////////////////////////////////////
#endif
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIASurface::setPalette(const uInt32* tia_palette, const uInt32* rgb_palette)
{
myPalette = tia_palette;
cerr << "TIASurface::setPalette\n";
for(int i = 0; i < 256; ++i)
cerr << myPalette[i] << " ";
cerr << endl;
// Set palette for phosphor effect
for(int i = 0; i < 256; ++i)
{
for(int j = 0; j < 256; ++j)
{
uInt8 ri = (rgb_palette[i] >> 16) & 0xff;
uInt8 gi = (rgb_palette[i] >> 8) & 0xff;
uInt8 bi = rgb_palette[i] & 0xff;
uInt8 rj = (rgb_palette[j] >> 16) & 0xff;
uInt8 gj = (rgb_palette[j] >> 8) & 0xff;
uInt8 bj = rgb_palette[j] & 0xff;
Uint8 r = (Uint8) getPhosphor(ri, rj);
Uint8 g = (Uint8) getPhosphor(gi, gj);
Uint8 b = (Uint8) getPhosphor(bi, bj);
myPhosphorPalette[i][j] = myFB.mapRGB(r, g, b);
}
}
// The NTSC filtering needs access to the raw RGB data, since it calculates
// its own internal palette
myNTSCFilter.setTIAPalette(*this, rgb_palette);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 TIASurface::pixel(uInt32 idx, uInt8 shift) const
{
uInt8 c = *(myTIA->currentFrameBuffer() + idx) | shift;
uInt8 p = *(myTIA->previousFrameBuffer() + idx) | shift;
return (!myUsePhosphor ? myPalette[c] : myPhosphorPalette[c][p]);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIASurface::setNTSC(NTSCFilter::Preset preset, bool show)
{
ostringstream buf;
if(preset == NTSCFilter::PRESET_OFF)
{
enableNTSC(false);
buf << "TV filtering disabled";
}
else
{
enableNTSC(true);
const string& mode = myNTSCFilter.setPreset(preset);
buf << "TV filtering (" << mode << " mode)";
}
myOSystem.settings().setValue("tv.filter", (int)preset);
if(show) myFB.showMessage(buf.str());
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIASurface::setScanlineIntensity(int amount)
{
ostringstream buf;
if(ntscEnabled())
{
uInt32 intensity = enableScanlines(amount);
buf << "Scanline intensity at " << intensity << "%";
myOSystem.settings().setValue("tv.scanlines", intensity);
}
else
buf << "Scanlines only available in TV filtering mode";
myFB.showMessage(buf.str());
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIASurface::toggleScanlineInterpolation()
{
ostringstream buf;
if(ntscEnabled())
{
bool enable = !myOSystem.settings().getBool("tv.scaninter");
enableScanlineInterpolation(enable);
buf << "Scanline interpolation " << (enable ? "enabled" : "disabled");
myOSystem.settings().setValue("tv.scaninter", enable);
}
else
buf << "Scanlines only available in TV filtering mode";
myFB.showMessage(buf.str());
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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);
mySLineSurface->applyAttributes();
//FIXSDL myRedrawEntireFrame = true;
return intensity;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIASurface::enableScanlineInterpolation(bool enable)
{
mySLineSurface->myAttributes.smoothing = enable;
mySLineSurface->applyAttributes();
//FIXSDL myRedrawEntireFrame = true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIASurface::enablePhosphor(bool enable, int blend)
{
myUsePhosphor = enable;
myPhosphorBlend = blend;
myFilterType = FilterType(enable ? myFilterType | 0x01 : myFilterType & 0x10);
//FIXSDL myRedrawEntireFrame = true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 TIASurface::getPhosphor(uInt8 c1, uInt8 c2) const
{
if(c2 > c1)
BSPF_swap(c1, c2);
return ((c1 - c2) * myPhosphorBlend)/100 + c2;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIASurface::enableNTSC(bool enable)
{
myFilterType = FilterType(enable ? myFilterType | 0x10 : myFilterType & 0x01);
// Normal vs NTSC mode uses different source widths
const GUI::Rect& src = myTiaSurface->srcRect();
myTiaSurface->setSrcSize(enable ? ATARI_NTSC_OUT_WIDTH(160) : 160, src.height());
myTiaSurface->myAttributes.smoothing =
myOSystem.settings().getBool("tia.inter");
myTiaSurface->applyAttributes();
myScanlinesEnabled = enable;
mySLineSurface->myAttributes.smoothing =
myOSystem.settings().getBool("tv.scaninter");
mySLineSurface->myAttributes.blendalpha =
myOSystem.settings().getInt("tv.scanlines");
mySLineSurface->applyAttributes();
//FIXSDL myRedrawEntireFrame = true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string TIASurface::effectsInfo() const
{
ostringstream buf;
switch(myFilterType)
{
case kNormal:
buf << "Disabled, normal mode";
break;
case kPhosphor:
buf << "Disabled, phosphor mode";
break;
case kBlarggNormal:
buf << myNTSCFilter.getPreset() << ", scanlines="
<< mySLineSurface->myAttributes.blendalpha << "/"
<< (mySLineSurface->myAttributes.smoothing ? "inter" : "nointer");
break;
case kBlarggPhosphor:
buf << myNTSCFilter.getPreset() << ", phosphor, scanlines="
<< mySLineSurface->myAttributes.blendalpha << "/"
<< (mySLineSurface->myAttributes.smoothing ? "inter" : "nointer");
break;
}
return buf.str();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIASurface::render()
{
#if 0
cerr << "src: " << myTiaSurface->srcRect() << endl
<< "dst: " << myTiaSurface->dstRect() << endl
<< endl;
#endif
// Copy the mediasource framebuffer to the RGB texture
// In hardware rendering mode, it's faster to just assume that the screen
// is dirty and always do an update
uInt8* currentFrame = myTIA->currentFrameBuffer();
uInt8* previousFrame = myTIA->previousFrameBuffer();
uInt32 width = myTIA->width();
uInt32 height = myTIA->height();
uInt32 *buffer, pitch;
myTiaSurface->basePtr(buffer, pitch);
//cerr << "buffer=" << buffer << ", pitch=" << pitch << endl;
// TODO - Eventually 'phosphor' won't be a separate mode, and will become
// a post-processing filter by blending several frames.
switch(myFilterType)
{
case kNormal:
{
uInt32 bufofsY = 0;
uInt32 screenofsY = 0;
for(uInt32 y = 0; y < height; ++y)
{
uInt32 pos = screenofsY;
for(uInt32 x = 0; x < width; ++x)
buffer[pos++] = (uInt32) myPalette[currentFrame[bufofsY + x]];
bufofsY += width;
screenofsY += pitch;
}
break;
}
case kPhosphor:
{
uInt32 bufofsY = 0;
uInt32 screenofsY = 0;
for(uInt32 y = 0; y < height; ++y)
{
uInt32 pos = screenofsY;
for(uInt32 x = 0; x < width; ++x)
{
const uInt32 bufofs = bufofsY + x;
buffer[pos++] = (uInt32)
myPhosphorPalette[currentFrame[bufofs]][previousFrame[bufofs]];
}
bufofsY += width;
screenofsY += pitch;
}
break;
}
case kBlarggNormal:
{
myNTSCFilter.blit_single(currentFrame, width, height,
buffer, pitch);
break;
}
case kBlarggPhosphor:
{
myNTSCFilter.blit_double(currentFrame, previousFrame, width, height,
buffer, pitch);
break;
}
}
// Draw TIA image
myTiaSurface->render();
// Draw overlaying scanlines
if(myScanlinesEnabled)
mySLineSurface->render();
}

174
src/emucore/TIASurface.hxx Normal file
View File

@ -0,0 +1,174 @@
//============================================================================
//
// 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-2014 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 TIASURFACE_HXX
#define TIASURFACE_HXX
class TIA;
class Console;
class OSystem;
class FrameBuffer;
class FBSurface;
class VideoMode;
#include "NTSCFilter.hxx"
#include "bspf.hxx"
/**
This class is basically a wrapper around all things related to rendering
the TIA image to FBSurface's, and presenting the results to the screen.
This is placed in a separate class since currently, rendering a TIA image
can consist of TV filters, a separate scanline surface, phosphor modes, etc.
@author Stephen Anthony
*/
class TIASurface
{
friend class FrameBuffer;
public:
/**
Creates a new TIASurface object
*/
TIASurface(FrameBuffer& buffer, OSystem& system);
/**
Destructor
*/
virtual ~TIASurface();
/**
Set the TIA object, which is needed for actually rendering the TIA image.
*/
void initialize(const Console& console, const VideoMode& mode);
/**
Set the palette for TIA rendering. This currently consists of two
components: the actual TIA palette, and a mixed TIA palette used
in phosphor mode. The latter may eventually disappear once a better
phosphor emulation is developed.
@param tia_palette An actual TIA palette, converted to data values
that are actually usable by the framebuffer
@param rgb_palette The RGB components of the palette, needed for
calculating a phosphor palette
*/
void setPalette(const uInt32* tia_palette, const uInt32* rgb_palette);
/**
Get the TIA pixel associated with the given TIA buffer index,
shifting by the given offset (for greyscale values).
*/
uInt32 pixel(uInt32 idx, uInt8 shift = 0) const;
/**
Get the NTSCFilter object associated with the framebuffer
*/
NTSCFilter& ntsc() { return myNTSCFilter; }
/**
Use NTSC filtering effects specified by the given preset.
*/
void setNTSC(NTSCFilter::Preset preset, bool show = true);
/**
Increase/decrease current scanline intensity by given relative amount.
*/
void setScanlineIntensity(int relative);
/**
Toggles interpolation/smoothing of scanlines in TV modes.
*/
void toggleScanlineInterpolation();
/**
Change scanline intensity and interpolation.
@param relative If non-zero, change current intensity by
'relative' amount, otherwise set to 'absolute'
@return New current intensity
*/
uInt32 enableScanlines(int relative, int absolute = 50);
void enableScanlineInterpolation(bool enable);
/**
Enable/disable phosphor effect.
*/
void enablePhosphor(bool enable, int blend);
/**
Used to calculate an averaged color for the 'phosphor' effect.
@param c1 Color 1
@param c2 Color 2
@return Averaged value of the two colors
*/
uInt8 getPhosphor(uInt8 c1, uInt8 c2) const;
/**
Enable/disable/query NTSC filtering effects.
*/
void enableNTSC(bool enable);
bool ntscEnabled() const { return myFilterType & 0x10; }
string effectsInfo() const;
/**
This method should be called to draw the TIA image(s) to the screen.
*/
void render();
private:
FrameBuffer& myFB;
OSystem& myOSystem;
TIA* myTIA;
FBSurface *myTiaSurface, *mySLineSurface;
// Enumeration created such that phosphor off/on is in LSB,
// and Blargg off/on is in MSB
enum FilterType {
kNormal = 0x00,
kPhosphor = 0x01,
kBlarggNormal = 0x10,
kBlarggPhosphor = 0x11
};
FilterType myFilterType;
// NTSC object to use in TIA rendering mode
NTSCFilter myNTSCFilter;
// Use phosphor effect (aka no flicker on 30Hz screens)
bool myUsePhosphor;
// Amount to blend when using phosphor effect
int myPhosphorBlend;
// Use scanlines in TIA rendering mode
bool myScanlinesEnabled;
// Palette for normal TIA rendering mode
const uInt32* myPalette;
// Palette for phosphor rendering mode
uInt32 myPhosphorPalette[256][256];
};
#endif

View File

@ -71,6 +71,7 @@ MODULE_OBJS := \
src/emucore/TIA.o \ src/emucore/TIA.o \
src/emucore/TIASnd.o \ src/emucore/TIASnd.o \
src/emucore/TIATables.o \ src/emucore/TIATables.o \
src/emucore/TIASurface.o \
src/emucore/TrackBall.o \ src/emucore/TrackBall.o \
src/emucore/Thumbulator.o src/emucore/Thumbulator.o

View File

@ -463,7 +463,7 @@ void VideoDialog::saveConfig()
adj.artifacts = myTVArtifacts->getValue(); adj.artifacts = myTVArtifacts->getValue();
adj.fringing = myTVFringe->getValue(); adj.fringing = myTVFringe->getValue();
adj.bleed = myTVBleed->getValue(); adj.bleed = myTVBleed->getValue();
instance().frameBuffer().ntsc().setCustomAdjustables(adj); instance().frameBuffer().tiaSurface().ntsc().setCustomAdjustables(adj);
// TV scanline intensity and interpolation // TV scanline intensity and interpolation
instance().settings().setValue("tv.scanlines", myTVScanIntenseLabel->getLabel()); instance().settings().setValue("tv.scanlines", myTVScanIntenseLabel->getLabel());
@ -565,7 +565,8 @@ void VideoDialog::handleTVModeChange(NTSCFilter::Preset preset)
void VideoDialog::loadTVAdjustables(NTSCFilter::Preset preset) void VideoDialog::loadTVAdjustables(NTSCFilter::Preset preset)
{ {
NTSCFilter::Adjustable adj; NTSCFilter::Adjustable adj;
instance().frameBuffer().ntsc().getAdjustables(adj, (NTSCFilter::Preset)preset); instance().frameBuffer().tiaSurface().ntsc().getAdjustables(
adj, (NTSCFilter::Preset)preset);
myTVSharp->setValue(adj.sharpness); myTVSharp->setValue(adj.sharpness);
myTVSharpLabel->setValue(adj.sharpness); myTVSharpLabel->setValue(adj.sharpness);
myTVHue->setValue(adj.hue); myTVHue->setValue(adj.hue);

View File

@ -26,7 +26,7 @@ extern "C" {
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SettingsMACOSX::SettingsMACOSX(OSystem* osystem) SettingsMACOSX::SettingsMACOSX(OSystem& osystem)
: Settings(osystem) : Settings(osystem)
{ {
} }

View File

@ -36,7 +36,7 @@ class SettingsMACOSX : public Settings
/** /**
Create a new UNIX settings object Create a new UNIX settings object
*/ */
SettingsMACOSX(OSystem* osystem); SettingsMACOSX(OSystem& osystem);
/** /**
Destructor Destructor

View File

@ -20,7 +20,7 @@
#include "SettingsUNIX.hxx" #include "SettingsUNIX.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SettingsUNIX::SettingsUNIX(OSystem* osystem) SettingsUNIX::SettingsUNIX(OSystem& osystem)
: Settings(osystem) : Settings(osystem)
{ {
} }

View File

@ -36,7 +36,7 @@ class SettingsUNIX : public Settings
/** /**
Create a new UNIX settings object Create a new UNIX settings object
*/ */
SettingsUNIX(OSystem* osystem); SettingsUNIX(OSystem& osystem);
/** /**
Destructor Destructor

View File

@ -20,7 +20,7 @@
#include "SettingsWINDOWS.hxx" #include "SettingsWINDOWS.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SettingsWINDOWS::SettingsWINDOWS(OSystem* osystem) SettingsWINDOWS::SettingsWINDOWS(OSystem& osystem)
: Settings(osystem) : Settings(osystem)
{ {
setInternal("fragsize", "1024"); setInternal("fragsize", "1024");

View File

@ -30,7 +30,7 @@ class SettingsWINDOWS : public Settings
/** /**
Create a new UNIX settings object Create a new UNIX settings object
*/ */
SettingsWINDOWS(OSystem* osystem); SettingsWINDOWS(OSystem& osystem);
/** /**
Destructor Destructor