mirror of https://github.com/stella-emu/stella.git
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:
parent
d57184a4fc
commit
c8b27ec114
|
@ -21,7 +21,7 @@
|
|||
#include "EventHandlerSDL2.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
EventHandlerSDL2::EventHandlerSDL2(OSystem* osystem)
|
||||
EventHandlerSDL2::EventHandlerSDL2(OSystem& osystem)
|
||||
: EventHandler(osystem)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ class EventHandlerSDL2 : public EventHandler
|
|||
/**
|
||||
Create a new SDL2 event handler object
|
||||
*/
|
||||
EventHandlerSDL2(OSystem* osystem);
|
||||
EventHandlerSDL2(OSystem& osystem);
|
||||
|
||||
/**
|
||||
Destructor
|
||||
|
|
|
@ -21,8 +21,7 @@
|
|||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
FBSurfaceSDL2::FBSurfaceSDL2(FrameBufferSDL2& buffer, uInt32 width, uInt32 height)
|
||||
: FBSurface(buffer.myDefPalette),
|
||||
myFB(buffer),
|
||||
: myFB(buffer),
|
||||
mySurface(NULL),
|
||||
myTexture(NULL),
|
||||
mySurfaceIsDirty(true),
|
||||
|
@ -111,19 +110,6 @@ void FBSurfaceSDL2::setStaticContents(const uInt32* pixels, uInt32 pitch)
|
|||
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
|
||||
{
|
||||
|
@ -236,3 +222,18 @@ void FBSurfaceSDL2::reload()
|
|||
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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,7 +33,6 @@ class FBSurfaceSDL2 : public FBSurface
|
|||
{
|
||||
public:
|
||||
FBSurfaceSDL2(FrameBufferSDL2& buffer, uInt32 width, uInt32 height);
|
||||
|
||||
virtual ~FBSurfaceSDL2();
|
||||
|
||||
// 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 setStaticContents(const uInt32* pixels, uInt32 pitch);
|
||||
void setInterpolationAndBlending(bool smoothScale, bool useBlend,
|
||||
uInt32 blendAlpha);
|
||||
|
||||
uInt32 width() const;
|
||||
uInt32 height() const;
|
||||
|
@ -63,6 +60,9 @@ class FBSurfaceSDL2 : public FBSurface
|
|||
void free();
|
||||
void reload();
|
||||
|
||||
protected:
|
||||
void applyAttributes(bool immediate);
|
||||
|
||||
private:
|
||||
FrameBufferSDL2& myFB;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -31,17 +31,14 @@
|
|||
#include "TIA.hxx"
|
||||
|
||||
#include "FBSurfaceSDL2.hxx"
|
||||
#include "FBSurfaceTIA.hxx"
|
||||
#include "FrameBufferSDL2.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
FrameBufferSDL2::FrameBufferSDL2(OSystem* osystem)
|
||||
FrameBufferSDL2::FrameBufferSDL2(OSystem& osystem)
|
||||
: FrameBuffer(osystem),
|
||||
myFilterType(kNormal),
|
||||
myWindow(NULL),
|
||||
myRenderer(NULL),
|
||||
myWindowFlags(0),
|
||||
myTiaSurface(NULL),
|
||||
myDirtyFlag(true),
|
||||
myDblBufferedFlag(true)
|
||||
{
|
||||
|
@ -50,7 +47,7 @@ FrameBufferSDL2::FrameBufferSDL2(OSystem* osystem)
|
|||
{
|
||||
ostringstream buf;
|
||||
buf << "ERROR: Couldn't initialize SDL: " << SDL_GetError() << endl;
|
||||
myOSystem->logMessage(buf.str(), 0);
|
||||
myOSystem.logMessage(buf.str(), 0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -76,9 +73,6 @@ FrameBufferSDL2::~FrameBufferSDL2()
|
|||
SDL_DestroyWindow(myWindow);
|
||||
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 full)
|
||||
bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode)
|
||||
{
|
||||
// If not initialized by this point, then immediately fail
|
||||
if(SDL_WasInit(SDL_INIT_VIDEO) == 0)
|
||||
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
|
||||
if(myRenderer)
|
||||
{
|
||||
|
@ -130,7 +115,7 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode,
|
|||
}
|
||||
|
||||
// Window centering option
|
||||
int pos = myOSystem->settings().getBool("center")
|
||||
int pos = myOSystem.settings().getBool("center")
|
||||
? SDL_WINDOWPOS_CENTERED : SDL_WINDOWPOS_UNDEFINED;
|
||||
myWindow = SDL_CreateWindow(title.c_str(),
|
||||
pos, pos, mode.image.width(), mode.image.height(),
|
||||
|
@ -138,60 +123,34 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode,
|
|||
if(myWindow == NULL)
|
||||
{
|
||||
string msg = "ERROR: Unable to open SDL window: " + string(SDL_GetError());
|
||||
myOSystem->logMessage(msg, 0);
|
||||
myOSystem.logMessage(msg, 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
// V'synced blits option
|
||||
Uint32 renderFlags = SDL_RENDERER_ACCELERATED;
|
||||
if(myOSystem->settings().getBool("vsync"))
|
||||
if(myOSystem.settings().getBool("vsync"))
|
||||
renderFlags |= SDL_RENDERER_PRESENTVSYNC;
|
||||
// Render hint
|
||||
const string& video = myOSystem->settings().getString("video");
|
||||
const string& video = myOSystem.settings().getString("video");
|
||||
if(video != "")
|
||||
SDL_SetHint(SDL_HINT_RENDER_DRIVER, video.c_str());
|
||||
myRenderer = SDL_CreateRenderer(myWindow, -1, renderFlags);
|
||||
if(myWindow == NULL)
|
||||
{
|
||||
string msg = "ERROR: Unable to create SDL renderer: " + string(SDL_GetError());
|
||||
myOSystem->logMessage(msg, 0);
|
||||
myOSystem.logMessage(msg, 0);
|
||||
return false;
|
||||
}
|
||||
SDL_RendererInfo renderinfo;
|
||||
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
|
||||
// Eventually, SDL may be updated to query this from the render backend
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -218,9 +177,8 @@ string FrameBufferSDL2::about() const
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferSDL2::invalidate()
|
||||
{
|
||||
SDL_RenderClear(myRenderer);
|
||||
if(myTiaSurface)
|
||||
myTiaSurface->invalidate();
|
||||
myDirtyFlag = true;
|
||||
// SDL_RenderClear(myRenderer);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -240,7 +198,7 @@ void FrameBufferSDL2::enableFullscreen(bool enable)
|
|||
{
|
||||
uInt32 flags = enable ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0;
|
||||
if(SDL_SetWindowFullscreen(myWindow, flags))
|
||||
myOSystem->settings().setValue("fullscreen", enable);
|
||||
myOSystem.settings().setValue("fullscreen", enable);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -253,13 +211,6 @@ bool FrameBufferSDL2::fullScreen() const
|
|||
#endif
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferSDL2::drawTIA(bool fullRedraw)
|
||||
{
|
||||
// The TIA surface takes all responsibility for drawing
|
||||
myTiaSurface->render();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
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
|
||||
{
|
||||
|
@ -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);
|
||||
#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();
|
||||
}
|
||||
|
|
|
@ -24,8 +24,6 @@
|
|||
|
||||
class OSystem;
|
||||
class FBSurfaceSDL2;
|
||||
class FBSurfaceTIA;
|
||||
class TIA;
|
||||
|
||||
#include "bspf.hxx"
|
||||
#include "FrameBuffer.hxx"
|
||||
|
@ -40,13 +38,12 @@ class TIA;
|
|||
class FrameBufferSDL2 : public FrameBuffer
|
||||
{
|
||||
friend class FBSurfaceSDL2;
|
||||
friend class FBSurfaceTIA;
|
||||
|
||||
public:
|
||||
/**
|
||||
Creates a new SDL2 framebuffer
|
||||
*/
|
||||
FrameBufferSDL2(OSystem* osystem);
|
||||
FrameBufferSDL2(OSystem& osystem);
|
||||
|
||||
/**
|
||||
Destructor
|
||||
|
@ -72,24 +69,6 @@ class FrameBufferSDL2 : public FrameBuffer
|
|||
*/
|
||||
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.
|
||||
|
||||
|
@ -116,11 +95,6 @@ class FrameBufferSDL2 : public FrameBuffer
|
|||
*/
|
||||
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.
|
||||
|
||||
|
@ -140,16 +114,14 @@ class FrameBufferSDL2 : public FrameBuffer
|
|||
void queryHardware(uInt32& w, uInt32& h, VariantList& renderers);
|
||||
|
||||
/**
|
||||
This method is called to change to the given video mode. If the mode
|
||||
is successfully changed, 'mode' holds the actual dimensions used.
|
||||
This method is called to change to the given video mode.
|
||||
|
||||
@param title The title for the created window
|
||||
@param mode The video mode to use
|
||||
@param full Whether this is a fullscreen or windowed mode
|
||||
|
||||
@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.
|
||||
|
@ -181,12 +153,6 @@ class FrameBufferSDL2 : public FrameBuffer
|
|||
*/
|
||||
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.
|
||||
*/
|
||||
|
@ -197,27 +163,6 @@ class FrameBufferSDL2 : public FrameBuffer
|
|||
*/
|
||||
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:
|
||||
// The SDL video buffer
|
||||
SDL_Window* myWindow;
|
||||
|
@ -229,10 +174,6 @@ class FrameBufferSDL2 : public FrameBuffer
|
|||
// it to point to the actual flags used by the SDL_Surface
|
||||
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)
|
||||
SDL_PixelFormat* myPixelFormat;
|
||||
|
||||
|
|
|
@ -156,8 +156,8 @@ string PNGLibrary::saveImage(const string& filename,
|
|||
buf_ptr += pitch; // add pitch
|
||||
}
|
||||
|
||||
return saveBufferToPNG(out, buffer, width, height,
|
||||
props, framebuffer.effectsInfo());
|
||||
return saveBufferToPNG(out, buffer, width, height, props,
|
||||
framebuffer.tiaSurface().effectsInfo());
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -180,7 +180,7 @@ string PNGLibrary::saveImage(const string& filename,
|
|||
*buf_ptr++ = 0; // first byte of row is filter type
|
||||
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);
|
||||
*buf_ptr++ = r;
|
||||
*buf_ptr++ = g;
|
||||
|
@ -191,8 +191,8 @@ string PNGLibrary::saveImage(const string& filename,
|
|||
}
|
||||
}
|
||||
|
||||
return saveBufferToPNG(out, buffer, width << 1, height,
|
||||
props, framebuffer.effectsInfo());
|
||||
return saveBufferToPNG(out, buffer, width << 1, height, props,
|
||||
framebuffer.tiaSurface().effectsInfo());
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -40,7 +40,7 @@ class SoundNull : public Sound
|
|||
Create a new sound object. The init method must be invoked before
|
||||
using the object.
|
||||
*/
|
||||
SoundNull(OSystem* osystem) : Sound(osystem)
|
||||
SoundNull(OSystem& osystem) : Sound(osystem)
|
||||
{
|
||||
myOSystem->logMessage("Sound disabled.\n", 1);
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
#include "SoundSDL2.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
SoundSDL2::SoundSDL2(OSystem* osystem)
|
||||
SoundSDL2::SoundSDL2(OSystem& osystem)
|
||||
: Sound(osystem),
|
||||
myIsEnabled(false),
|
||||
myIsInitializedFlag(false),
|
||||
|
@ -43,17 +43,17 @@ SoundSDL2::SoundSDL2(OSystem* osystem)
|
|||
myIsMuted(true),
|
||||
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
|
||||
// issues with opening and closing it multiple times
|
||||
// This fixes a bug most prevalent with ATI video cards in Windows,
|
||||
// whereby sound stopped working after the first video change
|
||||
SDL_AudioSpec desired;
|
||||
desired.freq = myOSystem->settings().getInt("freq");
|
||||
desired.freq = myOSystem.settings().getInt("freq");
|
||||
desired.format = AUDIO_S16SYS;
|
||||
desired.channels = 2;
|
||||
desired.samples = myOSystem->settings().getInt("fragsize");
|
||||
desired.samples = myOSystem.settings().getInt("fragsize");
|
||||
desired.callback = callback;
|
||||
desired.userdata = (void*)this;
|
||||
|
||||
|
@ -62,7 +62,7 @@ SoundSDL2::SoundSDL2(OSystem* osystem)
|
|||
{
|
||||
buf << "WARNING: Couldn't open SDL audio system! " << endl
|
||||
<< " " << SDL_GetError() << endl;
|
||||
myOSystem->logMessage(buf.str(), 0);
|
||||
myOSystem.logMessage(buf.str(), 0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,7 @@ SoundSDL2::SoundSDL2(OSystem* osystem)
|
|||
buf << "WARNING: Sound device doesn't support realtime audio! Make "
|
||||
<< "sure a sound" << endl
|
||||
<< " server isn't running. Audio is disabled." << endl;
|
||||
myOSystem->logMessage(buf.str(), 0);
|
||||
myOSystem.logMessage(buf.str(), 0);
|
||||
|
||||
SDL_CloseAudio();
|
||||
return;
|
||||
|
@ -87,7 +87,7 @@ SoundSDL2::SoundSDL2(OSystem* osystem)
|
|||
myIsInitializedFlag = true;
|
||||
SDL_PauseAudio(1);
|
||||
|
||||
myOSystem->logMessage("SoundSDL2::SoundSDL2 initialized", 2);
|
||||
myOSystem.logMessage("SoundSDL2::SoundSDL2 initialized", 2);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -100,27 +100,27 @@ SoundSDL2::~SoundSDL2()
|
|||
myIsEnabled = myIsInitializedFlag = false;
|
||||
}
|
||||
|
||||
myOSystem->logMessage("SoundSDL2 destroyed", 2);
|
||||
myOSystem.logMessage("SoundSDL2 destroyed", 2);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
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);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void SoundSDL2::open()
|
||||
{
|
||||
myOSystem->logMessage("SoundSDL2::open started ...", 2);
|
||||
myOSystem.logMessage("SoundSDL2::open started ...", 2);
|
||||
myIsEnabled = false;
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -130,7 +130,7 @@ void SoundSDL2::open()
|
|||
myTIASound.channels(myHardwareSpec.channels, myNumChannels == 2);
|
||||
|
||||
// Adjust volume to that defined in settings
|
||||
myVolume = myOSystem->settings().getInt("volume");
|
||||
myVolume = myOSystem.settings().getInt("volume");
|
||||
setVolume(myVolume);
|
||||
|
||||
// Show some info
|
||||
|
@ -142,13 +142,13 @@ void SoundSDL2::open()
|
|||
<< " Channels: " << (int)myHardwareSpec.channels
|
||||
<< " (" << chanResult << ")" << endl
|
||||
<< endl;
|
||||
myOSystem->logMessage(buf.str(), 1);
|
||||
myOSystem.logMessage(buf.str(), 1);
|
||||
|
||||
// And start the SDL sound subsystem ...
|
||||
myIsEnabled = true;
|
||||
mute(false);
|
||||
|
||||
myOSystem->logMessage("SoundSDL2::open finished", 2);
|
||||
myOSystem.logMessage("SoundSDL2::open finished", 2);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -161,7 +161,7 @@ void SoundSDL2::close()
|
|||
myLastRegisterSetCycle = 0;
|
||||
myTIASound.reset();
|
||||
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))
|
||||
{
|
||||
myOSystem->settings().setValue("volume", percent);
|
||||
myOSystem.settings().setValue("volume", percent);
|
||||
SDL_LockAudio();
|
||||
myVolume = percent;
|
||||
myTIASound.volume(percent);
|
||||
|
@ -224,7 +224,7 @@ void SoundSDL2::adjustVolume(Int8 direction)
|
|||
message = "Volume set to ";
|
||||
message += strval.str();
|
||||
|
||||
myOSystem->frameBuffer().showMessage(message);
|
||||
myOSystem.frameBuffer().showMessage(message);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -400,7 +400,7 @@ bool SoundSDL2::save(Serializer& out) const
|
|||
}
|
||||
catch(...)
|
||||
{
|
||||
myOSystem->logMessage("ERROR: SoundSDL2::save", 0);
|
||||
myOSystem.logMessage("ERROR: SoundSDL2::save", 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -441,7 +441,7 @@ bool SoundSDL2::load(Serializer& in)
|
|||
}
|
||||
catch(...)
|
||||
{
|
||||
myOSystem->logMessage("ERROR: SoundSDL2::load", 0);
|
||||
myOSystem.logMessage("ERROR: SoundSDL2::load", 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ class SoundSDL2 : public Sound
|
|||
Create a new sound object. The init method must be invoked before
|
||||
using the object.
|
||||
*/
|
||||
SoundSDL2(OSystem* osystem);
|
||||
SoundSDL2(OSystem& osystem);
|
||||
|
||||
/**
|
||||
Destructor
|
||||
|
|
|
@ -6,7 +6,6 @@ MODULE_OBJS := \
|
|||
src/common/EventHandlerSDL2.o \
|
||||
src/common/FrameBufferSDL2.o \
|
||||
src/common/FBSurfaceSDL2.o \
|
||||
src/common/FBSurfaceTIA.o \
|
||||
src/common/SoundSDL2.o \
|
||||
src/common/FSNodeZIP.o \
|
||||
src/common/PNGLibrary.o \
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
// $Id$
|
||||
//============================================================================
|
||||
|
||||
#include "FrameBuffer.hxx"
|
||||
#include "TIASurface.hxx"
|
||||
#include "Settings.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
|
||||
// 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 bj = palette[j] & 0xff;
|
||||
|
||||
*ptr++ = fb.getPhosphor(ri, rj);
|
||||
*ptr++ = fb.getPhosphor(gi, gj);
|
||||
*ptr++ = fb.getPhosphor(bi, bj);
|
||||
*ptr++ = tiaSurface.getPhosphor(ri, rj);
|
||||
*ptr++ = tiaSurface.getPhosphor(gi, gj);
|
||||
*ptr++ = tiaSurface.getPhosphor(bi, bj);
|
||||
}
|
||||
}
|
||||
// Set palette for normal fill
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#ifndef NTSC_FILTER_HXX
|
||||
#define NTSC_FILTER_HXX
|
||||
|
||||
class FrameBuffer;
|
||||
class TIASurface;
|
||||
class Settings;
|
||||
|
||||
#include "bspf.hxx"
|
||||
|
@ -67,7 +67,7 @@ class NTSCFilter
|
|||
uses this as a baseline for calculating its own internal palette
|
||||
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
|
||||
string setPreset(Preset preset);
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "Debugger.hxx"
|
||||
#include "DebuggerParser.hxx"
|
||||
#include "TIADebug.hxx"
|
||||
#include "TIASurface.hxx"
|
||||
#include "TIA.hxx"
|
||||
|
||||
#include "TiaOutputWidget.hxx"
|
||||
|
@ -150,7 +151,7 @@ void TiaOutputWidget::renderToSurface(FBSurface& s)
|
|||
for(uInt32 x = 0; x < width; ++x, ++i)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -66,14 +66,14 @@
|
|||
#include "Console.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Console::Console(OSystem* osystem, Cartridge* cart, const Properties& props)
|
||||
Console::Console(OSystem& osystem, Cartridge& cart, const Properties& props)
|
||||
: myOSystem(osystem),
|
||||
myEvent(osystem->eventHandler().event()),
|
||||
myCart(cart),
|
||||
myEvent(osystem.eventHandler().event()),
|
||||
myProperties(props),
|
||||
myTIA(0),
|
||||
mySwitches(0),
|
||||
mySystem(0),
|
||||
myCart(cart),
|
||||
myCMHandler(0),
|
||||
myDisplayFormat(""), // Unknown TV format @ 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[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());
|
||||
myTIA = new TIA(*this, myOSystem->sound(), myOSystem->settings());
|
||||
myRiot = new M6532(*this, myOSystem.settings());
|
||||
myTIA = new TIA(*this, myOSystem.sound(), myOSystem.settings());
|
||||
|
||||
mySystem->attach(m6502);
|
||||
mySystem->attach(myRiot);
|
||||
mySystem->attach(myTIA);
|
||||
mySystem->attach(myCart);
|
||||
mySystem->attach(&myCart);
|
||||
|
||||
// Auto-detect NTSC/PAL mode if it's requested
|
||||
string autodetected = "";
|
||||
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
|
||||
// We turn off the SuperCharger progress bars, otherwise the SC BIOS
|
||||
// will take over 250 frames!
|
||||
// The 'fastscbios' option must be changed before the system is reset
|
||||
bool fastscbios = myOSystem->settings().getBool("fastscbios");
|
||||
myOSystem->settings().setValue("fastscbios", true);
|
||||
bool fastscbios = myOSystem.settings().getBool("fastscbios");
|
||||
myOSystem.settings().setValue("fastscbios", true);
|
||||
mySystem->reset(true); // autodetect in reset enabled
|
||||
for(int i = 0; i < 60; ++i)
|
||||
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
|
||||
myOSystem->settings().setValue("fastscbios", fastscbios);
|
||||
myOSystem.settings().setValue("fastscbios", fastscbios);
|
||||
}
|
||||
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
|
||||
bool joyallow4 = md5 == "aa1c41f86ec44c0a44eb64c332ce08af" ||
|
||||
md5 == "1bf503c724001b09be79c515ecfcbd03" ||
|
||||
myOSystem->settings().getBool("joyallow4");
|
||||
myOSystem->eventHandler().allowAllDirections(joyallow4);
|
||||
myOSystem.settings().getBool("joyallow4");
|
||||
myOSystem.eventHandler().allowAllDirections(joyallow4);
|
||||
|
||||
// Reset the system to its power-on state
|
||||
mySystem->reset();
|
||||
|
@ -168,9 +168,9 @@ Console::Console(OSystem* osystem, Cartridge* cart, const Properties& props)
|
|||
myConsoleInfo.CartMD5 = myProperties.get(Cartridge_MD5);
|
||||
myConsoleInfo.Control0 = myControllers[0]->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);
|
||||
|
||||
setPalette(myOSystem->settings().getString("palette"));
|
||||
setPalette(myOSystem.settings().getString("palette"));
|
||||
setTIAProperties();
|
||||
myTIA->frameReset();
|
||||
initializeVideo(); // takes care of refreshing the screen
|
||||
|
||||
myOSystem->frameBuffer().showMessage(message);
|
||||
myOSystem.frameBuffer().showMessage(message);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Console::toggleColorLoss()
|
||||
{
|
||||
bool colorloss = !myOSystem->settings().getBool("colorloss");
|
||||
myOSystem->settings().setValue("colorloss", colorloss);
|
||||
bool colorloss = !myOSystem.settings().getBool("colorloss");
|
||||
myOSystem.settings().setValue("colorloss", colorloss);
|
||||
myTIA->enableColorLoss(colorloss);
|
||||
|
||||
string message = string("PAL color-loss ") +
|
||||
(colorloss ? "enabled" : "disabled");
|
||||
myOSystem->frameBuffer().showMessage(message);
|
||||
myOSystem.frameBuffer().showMessage(message);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -304,7 +304,7 @@ void Console::toggleColorLoss(bool state)
|
|||
void Console::togglePalette()
|
||||
{
|
||||
string palette, message;
|
||||
palette = myOSystem->settings().getString("palette");
|
||||
palette = myOSystem.settings().getString("palette");
|
||||
|
||||
if(palette == "standard") // switch to z26
|
||||
{
|
||||
|
@ -337,8 +337,8 @@ void Console::togglePalette()
|
|||
message = "Standard Stella palette";
|
||||
}
|
||||
|
||||
myOSystem->settings().setValue("palette", palette);
|
||||
myOSystem->frameBuffer().showMessage(message);
|
||||
myOSystem.settings().setValue("palette", palette);
|
||||
myOSystem.frameBuffer().showMessage(message);
|
||||
|
||||
setPalette(palette);
|
||||
}
|
||||
|
@ -369,7 +369,7 @@ void Console::setPalette(const string& type)
|
|||
(myDisplayFormat.compare(0, 5, "SECAM") == 0) ? palettes[paletteNum][2] :
|
||||
palettes[paletteNum][0];
|
||||
|
||||
myOSystem->frameBuffer().setTIAPalette(palette);
|
||||
myOSystem.frameBuffer().setPalette(palette);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -382,16 +382,16 @@ void Console::togglePhosphor()
|
|||
{
|
||||
myProperties.set(Display_Phosphor, "No");
|
||||
enable = false;
|
||||
myOSystem->frameBuffer().showMessage("Phosphor effect disabled");
|
||||
myOSystem.frameBuffer().showMessage("Phosphor effect disabled");
|
||||
}
|
||||
else
|
||||
{
|
||||
myProperties.set(Display_Phosphor, "Yes");
|
||||
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)
|
||||
{
|
||||
setPalette(myOSystem.settings().getString("palette"));
|
||||
|
||||
FBInitStatus fbstatus = kSuccess;
|
||||
|
||||
if(full)
|
||||
{
|
||||
const string& title = string("Stella ") + STELLA_VERSION +
|
||||
": \"" + myProperties.get(Cartridge_Name) + "\"";
|
||||
fbstatus = myOSystem->frameBuffer().createDisplay(title,
|
||||
fbstatus = myOSystem.frameBuffer().createDisplay(title,
|
||||
myTIA->width() << 1, myTIA->height());
|
||||
if(fbstatus != kSuccess)
|
||||
return fbstatus;
|
||||
|
||||
myOSystem->frameBuffer().showFrameStats(myOSystem->settings().getBool("stats"));
|
||||
setColorLossPalette();
|
||||
myOSystem.frameBuffer().showFrameStats(myOSystem.settings().getBool("stats"));
|
||||
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
|
||||
// This can be overridden by changing the framerate in the
|
||||
// VideoDialog box or on the commandline, but it can't be saved
|
||||
// (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);
|
||||
myOSystem->setFramerate(myFramerate);
|
||||
myOSystem.setFramerate(myFramerate);
|
||||
|
||||
// Make sure auto-frame calculation is only enabled when necessary
|
||||
myTIA->enableAutoFrame(framerate <= 0);
|
||||
|
@ -445,20 +440,19 @@ void Console::initializeAudio()
|
|||
// Initialize the sound interface.
|
||||
// The # of channels can be overridden in the AudioDialog box or on
|
||||
// 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);
|
||||
const string& sound = myProperties.get(Cartridge_Sound);
|
||||
|
||||
myOSystem->sound().close();
|
||||
myOSystem->sound().setChannels(sound == "STEREO" ? 2 : 1);
|
||||
myOSystem->sound().setFrameRate(myFramerate);
|
||||
myOSystem->sound().open();
|
||||
myOSystem.sound().close();
|
||||
myOSystem.sound().setChannels(sound == "STEREO" ? 2 : 1);
|
||||
myOSystem.sound().setFrameRate(myFramerate);
|
||||
myOSystem.sound().open();
|
||||
|
||||
// Make sure auto-frame calculation is only enabled when necessary
|
||||
myTIA->enableAutoFrame(framerate <= 0);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
/* Original frying research and code by Fred Quimby.
|
||||
I've tried the following variations on this code:
|
||||
- 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
|
||||
leaving this as Fred posted it. -- B.
|
||||
*/
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Console::fry() const
|
||||
{
|
||||
for (int ZPmem=0; ZPmem<0x100; ZPmem += rand() % 4)
|
||||
|
@ -493,7 +488,7 @@ void Console::changeYStart(int direction)
|
|||
{
|
||||
if(ystart >= 64)
|
||||
{
|
||||
myOSystem->frameBuffer().showMessage("YStart at maximum");
|
||||
myOSystem.frameBuffer().showMessage("YStart at maximum");
|
||||
return;
|
||||
}
|
||||
ystart++;
|
||||
|
@ -502,7 +497,7 @@ void Console::changeYStart(int direction)
|
|||
{
|
||||
if(ystart == 0)
|
||||
{
|
||||
myOSystem->frameBuffer().showMessage("YStart at minimum");
|
||||
myOSystem.frameBuffer().showMessage("YStart at minimum");
|
||||
return;
|
||||
}
|
||||
ystart--;
|
||||
|
@ -512,11 +507,11 @@ void Console::changeYStart(int direction)
|
|||
|
||||
myTIA->setYStart(ystart);
|
||||
myTIA->frameReset();
|
||||
myOSystem->frameBuffer().refresh();
|
||||
myOSystem.frameBuffer().refresh();
|
||||
|
||||
ostringstream val;
|
||||
val << ystart;
|
||||
myOSystem->frameBuffer().showMessage("YStart " + val.str());
|
||||
myOSystem.frameBuffer().showMessage("YStart " + val.str());
|
||||
myProperties.set(Display_YStart, val.str());
|
||||
}
|
||||
|
||||
|
@ -524,14 +519,14 @@ void Console::changeYStart(int direction)
|
|||
void Console::changeHeight(int direction)
|
||||
{
|
||||
uInt32 height = myTIA->height();
|
||||
uInt32 dheight = myOSystem->frameBuffer().desktopSize().h;
|
||||
uInt32 dheight = myOSystem.frameBuffer().desktopSize().h;
|
||||
|
||||
if(direction == +1) // increase Height
|
||||
{
|
||||
height++;
|
||||
if(height > 256 || height > dheight)
|
||||
{
|
||||
myOSystem->frameBuffer().showMessage("Height at maximum");
|
||||
myOSystem.frameBuffer().showMessage("Height at maximum");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -540,7 +535,7 @@ void Console::changeHeight(int direction)
|
|||
height--;
|
||||
if(height < 210)
|
||||
{
|
||||
myOSystem->frameBuffer().showMessage("Height at minimum");
|
||||
myOSystem.frameBuffer().showMessage("Height at minimum");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -553,7 +548,7 @@ void Console::changeHeight(int direction)
|
|||
|
||||
ostringstream val;
|
||||
val << height;
|
||||
myOSystem->frameBuffer().showMessage("Height " + val.str());
|
||||
myOSystem.frameBuffer().showMessage("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
|
||||
// If not, attempt to center vertically
|
||||
uInt32 dheight = myOSystem->frameBuffer().desktopSize().h;
|
||||
uInt32 dheight = myOSystem.frameBuffer().desktopSize().h;
|
||||
if(height > dheight)
|
||||
{
|
||||
ystart += height - dheight;
|
||||
|
@ -612,7 +607,7 @@ void Console::setControllers(const string& rommd5)
|
|||
if(left == "COMPUMATE" || right == "COMPUMATE")
|
||||
{
|
||||
delete myCMHandler;
|
||||
myCMHandler = new CompuMate(*((CartridgeCM*)myCart), myEvent, *mySystem);
|
||||
myCMHandler = new CompuMate(*((CartridgeCM*)&myCart), myEvent, *mySystem);
|
||||
myControllers[0] = myCMHandler->leftController();
|
||||
myControllers[1] = myCMHandler->rightController();
|
||||
return;
|
||||
|
@ -729,14 +724,14 @@ void Console::setControllers(const string& rommd5)
|
|||
}
|
||||
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,
|
||||
*mySystem, myOSystem->serialPort(),
|
||||
myOSystem->settings().getString("avoxport"), nvramfile);
|
||||
*mySystem, myOSystem.serialPort(),
|
||||
myOSystem.settings().getString("avoxport"), nvramfile);
|
||||
}
|
||||
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,
|
||||
nvramfile);
|
||||
}
|
||||
|
@ -761,7 +756,7 @@ void Console::setControllers(const string& rommd5)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Console::loadUserPalette()
|
||||
{
|
||||
const string& palette = myOSystem->paletteFile();
|
||||
const string& palette = myOSystem.paletteFile();
|
||||
ifstream in(palette.c_str(), ios::binary);
|
||||
if(!in)
|
||||
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
|
||||
// currently active
|
||||
|
@ -857,8 +852,8 @@ void Console::setColorLossPalette()
|
|||
void Console::setFramerate(float framerate)
|
||||
{
|
||||
myFramerate = framerate;
|
||||
myOSystem->setFramerate(framerate);
|
||||
myOSystem->sound().setFrameRate(framerate);
|
||||
myOSystem.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);
|
||||
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();
|
||||
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);
|
||||
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();
|
||||
string message = string("TIA collisions") + (enabled ? " enabled" : " disabled");
|
||||
myOSystem->frameBuffer().showMessage(message);
|
||||
myOSystem.frameBuffer().showMessage(message);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Console::toggleHMOVE() const
|
||||
{
|
||||
if(myTIA->toggleHMOVEBlank())
|
||||
myOSystem->frameBuffer().showMessage("HMOVE blanking enabled");
|
||||
myOSystem.frameBuffer().showMessage("HMOVE blanking enabled");
|
||||
else
|
||||
myOSystem->frameBuffer().showMessage("HMOVE blanking disabled");
|
||||
myOSystem.frameBuffer().showMessage("HMOVE blanking disabled");
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Console::toggleFixedColors() const
|
||||
{
|
||||
if(myTIA->toggleFixedColors())
|
||||
myOSystem->frameBuffer().showMessage("Fixed debug colors enabled");
|
||||
myOSystem.frameBuffer().showMessage("Fixed debug colors enabled");
|
||||
else
|
||||
myOSystem->frameBuffer().showMessage("Fixed debug colors disabled");
|
||||
myOSystem.frameBuffer().showMessage("Fixed debug colors disabled");
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Console::addDebugger()
|
||||
{
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
myOSystem->createDebugger(*this);
|
||||
mySystem->m6502().attach(myOSystem->debugger());
|
||||
myOSystem.createDebugger(*this);
|
||||
mySystem->m6502().attach(myOSystem.debugger());
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1156,6 +1151,7 @@ uInt32 Console::ourUserSECAMPalette[256] = { 0 }; // filled from external file
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Console::Console(const Console& console)
|
||||
: myOSystem(console.myOSystem),
|
||||
myCart(console.myCart),
|
||||
myEvent(console.myEvent)
|
||||
{
|
||||
assert(false);
|
||||
|
|
|
@ -68,7 +68,7 @@ class Console : public Serializable
|
|||
@param cart The cartridge to use with this console
|
||||
@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
|
||||
|
@ -126,7 +126,7 @@ class Console : public Serializable
|
|||
|
||||
@return The cartridge for this console
|
||||
*/
|
||||
Cartridge& cartridge() const { return *myCart; }
|
||||
Cartridge& cartridge() const { return myCart; }
|
||||
|
||||
/**
|
||||
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
|
||||
'greying out' the frame in the debugger.
|
||||
*/
|
||||
void setColorLossPalette();
|
||||
void generateColorLossPalette();
|
||||
|
||||
/**
|
||||
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;
|
||||
|
||||
private:
|
||||
// Pointer to the osystem object
|
||||
OSystem* myOSystem;
|
||||
// Reference to the osystem object
|
||||
OSystem& myOSystem;
|
||||
|
||||
// Pointer to the Cartridge (the debugger needs it)
|
||||
Cartridge& myCart;
|
||||
|
||||
// Reference to the event object to use
|
||||
Event& myEvent;
|
||||
|
@ -360,9 +363,6 @@ class Console : public Serializable
|
|||
// Pointer to the 6502 based system being emulated
|
||||
System* mySystem;
|
||||
|
||||
// Pointer to the Cartridge (the debugger needs it)
|
||||
Cartridge* myCart;
|
||||
|
||||
// Pointer to the 6532 (aka RIOT) (the debugger needs it)
|
||||
// A RIOT of my own! (...with apologies to The Clash...)
|
||||
M6532* myRiot;
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
#endif
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
EventHandler::EventHandler(OSystem* osystem)
|
||||
EventHandler::EventHandler(OSystem& osystem)
|
||||
: myOSystem(osystem),
|
||||
myOverlay(NULL),
|
||||
myMouseControl(NULL),
|
||||
|
@ -102,27 +102,27 @@ void EventHandler::initialize()
|
|||
setActionMappings(kEmulationMode);
|
||||
setActionMappings(kMenuMode);
|
||||
|
||||
myUseCtrlKeyFlag = myOSystem->settings().getBool("ctrlcombo");
|
||||
myUseCtrlKeyFlag = myOSystem.settings().getBool("ctrlcombo");
|
||||
|
||||
Joystick::setDeadZone(myOSystem->settings().getInt("joydeadzone"));
|
||||
Paddles::setDigitalSensitivity(myOSystem->settings().getInt("dsense"));
|
||||
Paddles::setMouseSensitivity(myOSystem->settings().getInt("msense"));
|
||||
Joystick::setDeadZone(myOSystem.settings().getInt("joydeadzone"));
|
||||
Paddles::setDigitalSensitivity(myOSystem.settings().getInt("dsense"));
|
||||
Paddles::setMouseSensitivity(myOSystem.settings().getInt("msense"));
|
||||
|
||||
// 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
|
||||
ScrollBarWidget::setWheelLines(myOSystem->settings().getInt("mwheel"));
|
||||
ScrollBarWidget::setWheelLines(myOSystem.settings().getInt("mwheel"));
|
||||
|
||||
// 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
|
||||
#ifdef JOYSTICK_SUPPORT
|
||||
initializeJoysticks();
|
||||
|
||||
// Map the stelladaptors we've found according to the specified ports
|
||||
mapStelladaptors(myOSystem->settings().getString("saport"));
|
||||
mapStelladaptors(myOSystem.settings().getString("saport"));
|
||||
|
||||
setJoymap();
|
||||
setActionMappings(kEmulationMode);
|
||||
|
@ -137,9 +137,9 @@ void EventHandler::initialize()
|
|||
for(uInt32 i = 0; i < myJoysticks.size(); ++i)
|
||||
buf << " " << i << ": " << myJoysticks[i]->about() << endl;
|
||||
}
|
||||
myOSystem->logMessage(buf.str(), 1);
|
||||
myOSystem.logMessage(buf.str(), 1);
|
||||
#else
|
||||
myOSystem->logMessage("Joystick support disabled.", 1);
|
||||
myOSystem.logMessage("Joystick support disabled.", 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -147,7 +147,7 @@ void EventHandler::initialize()
|
|||
void EventHandler::reset(State state)
|
||||
{
|
||||
setEventState(state);
|
||||
myOSystem->state().reset();
|
||||
myOSystem.state().reset();
|
||||
|
||||
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
|
||||
// the Event system, so we make sure all Stelladaptor-generated events
|
||||
|
@ -276,16 +276,16 @@ void EventHandler::mapStelladaptors(const string& saport)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void EventHandler::toggleSAPortOrder()
|
||||
{
|
||||
const string& saport = myOSystem->settings().getString("saport");
|
||||
const string& saport = myOSystem.settings().getString("saport");
|
||||
if(saport == "lr")
|
||||
{
|
||||
mapStelladaptors("rl");
|
||||
myOSystem->frameBuffer().showMessage("Stelladaptor ports right/left");
|
||||
myOSystem.frameBuffer().showMessage("Stelladaptor ports right/left");
|
||||
}
|
||||
else
|
||||
{
|
||||
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
|
||||
if(myState == S_EMULATE)
|
||||
{
|
||||
myOSystem->console().riot().update();
|
||||
myOSystem.console().riot().update();
|
||||
|
||||
#if 0
|
||||
// Now check if the StateManager should be saving or loading state
|
||||
// Per-frame cheats are disabled if the StateManager is active, since
|
||||
// it would interfere with proper playback
|
||||
if(myOSystem->state().isActive())
|
||||
if(myOSystem.state().isActive())
|
||||
{
|
||||
myOSystem->state().update();
|
||||
myOSystem.state().update();
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
#ifdef CHEATCODE_SUPPORT
|
||||
const CheatList& cheats = myOSystem->cheat().perFrame();
|
||||
const CheatList& cheats = myOSystem.cheat().perFrame();
|
||||
for(uInt32 i = 0; i < cheats.size(); i++)
|
||||
cheats[i]->evaluate();
|
||||
#endif
|
||||
|
@ -359,7 +359,7 @@ void EventHandler::handleKeyEvent(StellaKey key, StellaMod mod, char ascii, bool
|
|||
#endif
|
||||
if(key == KBDK_RETURN)
|
||||
{
|
||||
myOSystem->frameBuffer().toggleFullscreen();
|
||||
myOSystem.frameBuffer().toggleFullscreen();
|
||||
}
|
||||
// These only work when in emulation mode
|
||||
else if(myState == S_EMULATE)
|
||||
|
@ -367,160 +367,160 @@ void EventHandler::handleKeyEvent(StellaKey key, StellaMod mod, char ascii, bool
|
|||
switch(key)
|
||||
{
|
||||
case KBDK_EQUALS:
|
||||
myOSystem->frameBuffer().changeWindowedVidMode(+1);
|
||||
myOSystem.frameBuffer().changeWindowedVidMode(+1);
|
||||
break;
|
||||
|
||||
case KBDK_MINUS:
|
||||
myOSystem->frameBuffer().changeWindowedVidMode(-1);
|
||||
myOSystem.frameBuffer().changeWindowedVidMode(-1);
|
||||
break;
|
||||
|
||||
case KBDK_LEFTBRACKET:
|
||||
myOSystem->sound().adjustVolume(-1);
|
||||
myOSystem.sound().adjustVolume(-1);
|
||||
break;
|
||||
|
||||
case KBDK_RIGHTBRACKET:
|
||||
myOSystem->sound().adjustVolume(+1);
|
||||
myOSystem.sound().adjustVolume(+1);
|
||||
break;
|
||||
|
||||
case KBDK_PAGEUP: // Alt-PageUp increases YStart
|
||||
myOSystem->console().changeYStart(+1);
|
||||
myOSystem.console().changeYStart(+1);
|
||||
break;
|
||||
|
||||
case KBDK_PAGEDOWN: // Alt-PageDown decreases YStart
|
||||
myOSystem->console().changeYStart(-1);
|
||||
myOSystem.console().changeYStart(-1);
|
||||
break;
|
||||
|
||||
case KBDK_1: // Alt-1 turns off NTSC filtering
|
||||
myOSystem->frameBuffer().setNTSC(NTSCFilter::PRESET_OFF);
|
||||
myOSystem.frameBuffer().tiaSurface().setNTSC(NTSCFilter::PRESET_OFF);
|
||||
break;
|
||||
|
||||
case KBDK_2: // Alt-2 turns on 'composite' NTSC filtering
|
||||
myOSystem->frameBuffer().setNTSC(NTSCFilter::PRESET_COMPOSITE);
|
||||
myOSystem.frameBuffer().tiaSurface().setNTSC(NTSCFilter::PRESET_COMPOSITE);
|
||||
break;
|
||||
|
||||
case KBDK_3: // Alt-3 turns on 'svideo' NTSC filtering
|
||||
myOSystem->frameBuffer().setNTSC(NTSCFilter::PRESET_SVIDEO);
|
||||
myOSystem.frameBuffer().tiaSurface().setNTSC(NTSCFilter::PRESET_SVIDEO);
|
||||
break;
|
||||
|
||||
case KBDK_4: // Alt-4 turns on 'rgb' NTSC filtering
|
||||
myOSystem->frameBuffer().setNTSC(NTSCFilter::PRESET_RGB);
|
||||
myOSystem.frameBuffer().tiaSurface().setNTSC(NTSCFilter::PRESET_RGB);
|
||||
break;
|
||||
|
||||
case KBDK_5: // Alt-5 turns on 'bad' NTSC filtering
|
||||
myOSystem->frameBuffer().setNTSC(NTSCFilter::PRESET_BAD);
|
||||
myOSystem.frameBuffer().tiaSurface().setNTSC(NTSCFilter::PRESET_BAD);
|
||||
break;
|
||||
|
||||
case KBDK_6: // Alt-6 turns on 'custom' NTSC filtering
|
||||
myOSystem->frameBuffer().setNTSC(NTSCFilter::PRESET_CUSTOM);
|
||||
myOSystem.frameBuffer().tiaSurface().setNTSC(NTSCFilter::PRESET_CUSTOM);
|
||||
break;
|
||||
|
||||
case KBDK_7: // Alt-7 changes scanline intensity for NTSC filtering
|
||||
if(mod & KMOD_SHIFT)
|
||||
myOSystem->frameBuffer().setScanlineIntensity(-5);
|
||||
myOSystem.frameBuffer().tiaSurface().setScanlineIntensity(-5);
|
||||
else
|
||||
myOSystem->frameBuffer().setScanlineIntensity(+5);
|
||||
myOSystem.frameBuffer().tiaSurface().setScanlineIntensity(+5);
|
||||
break;
|
||||
|
||||
case KBDK_8: // Alt-8 turns toggles scanline interpolation
|
||||
myOSystem->frameBuffer().toggleScanlineInterpolation();
|
||||
myOSystem.frameBuffer().tiaSurface().toggleScanlineInterpolation();
|
||||
break;
|
||||
|
||||
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)
|
||||
myOSystem->frameBuffer().showMessage(
|
||||
myOSystem->frameBuffer().ntsc().setPreviousAdjustable());
|
||||
myOSystem.frameBuffer().showMessage(
|
||||
myOSystem.frameBuffer().tiaSurface().ntsc().setPreviousAdjustable());
|
||||
else
|
||||
myOSystem->frameBuffer().showMessage(
|
||||
myOSystem->frameBuffer().ntsc().setNextAdjustable());
|
||||
myOSystem.frameBuffer().showMessage(
|
||||
myOSystem.frameBuffer().tiaSurface().ntsc().setNextAdjustable());
|
||||
}
|
||||
break;
|
||||
|
||||
case KBDK_0: // Alt-0 changes custom adjustables for NTSC filtering
|
||||
if(myOSystem->frameBuffer().ntscEnabled())
|
||||
if(myOSystem.frameBuffer().tiaSurface().ntscEnabled())
|
||||
{
|
||||
if(mod & KMOD_SHIFT)
|
||||
myOSystem->frameBuffer().showMessage(
|
||||
myOSystem->frameBuffer().ntsc().decreaseAdjustable());
|
||||
myOSystem.frameBuffer().showMessage(
|
||||
myOSystem.frameBuffer().tiaSurface().ntsc().decreaseAdjustable());
|
||||
else
|
||||
myOSystem->frameBuffer().showMessage(
|
||||
myOSystem->frameBuffer().ntsc().increaseAdjustable());
|
||||
myOSystem.frameBuffer().showMessage(
|
||||
myOSystem.frameBuffer().tiaSurface().ntsc().increaseAdjustable());
|
||||
}
|
||||
break;
|
||||
|
||||
case KBDK_Z:
|
||||
if(mod & KMOD_SHIFT)
|
||||
myOSystem->console().toggleP0Collision();
|
||||
myOSystem.console().toggleP0Collision();
|
||||
else
|
||||
myOSystem->console().toggleP0Bit();
|
||||
myOSystem.console().toggleP0Bit();
|
||||
break;
|
||||
|
||||
case KBDK_X:
|
||||
if(mod & KMOD_SHIFT)
|
||||
myOSystem->console().toggleP1Collision();
|
||||
myOSystem.console().toggleP1Collision();
|
||||
else
|
||||
myOSystem->console().toggleP1Bit();
|
||||
myOSystem.console().toggleP1Bit();
|
||||
break;
|
||||
|
||||
case KBDK_C:
|
||||
if(mod & KMOD_SHIFT)
|
||||
myOSystem->console().toggleM0Collision();
|
||||
myOSystem.console().toggleM0Collision();
|
||||
else
|
||||
myOSystem->console().toggleM0Bit();
|
||||
myOSystem.console().toggleM0Bit();
|
||||
break;
|
||||
|
||||
case KBDK_V:
|
||||
if(mod & KMOD_SHIFT)
|
||||
myOSystem->console().toggleM1Collision();
|
||||
myOSystem.console().toggleM1Collision();
|
||||
else
|
||||
myOSystem->console().toggleM1Bit();
|
||||
myOSystem.console().toggleM1Bit();
|
||||
break;
|
||||
|
||||
case KBDK_B:
|
||||
if(mod & KMOD_SHIFT)
|
||||
myOSystem->console().toggleBLCollision();
|
||||
myOSystem.console().toggleBLCollision();
|
||||
else
|
||||
myOSystem->console().toggleBLBit();
|
||||
myOSystem.console().toggleBLBit();
|
||||
break;
|
||||
|
||||
case KBDK_N:
|
||||
if(mod & KMOD_SHIFT)
|
||||
myOSystem->console().togglePFCollision();
|
||||
myOSystem.console().togglePFCollision();
|
||||
else
|
||||
myOSystem->console().togglePFBit();
|
||||
myOSystem.console().togglePFBit();
|
||||
break;
|
||||
|
||||
case KBDK_M:
|
||||
myOSystem->console().toggleHMOVE();
|
||||
myOSystem.console().toggleHMOVE();
|
||||
break;
|
||||
|
||||
case KBDK_COMMA:
|
||||
myOSystem->console().toggleFixedColors();
|
||||
myOSystem.console().toggleFixedColors();
|
||||
break;
|
||||
|
||||
case KBDK_PERIOD:
|
||||
if(mod & KMOD_SHIFT)
|
||||
myOSystem->console().toggleCollisions();
|
||||
myOSystem.console().toggleCollisions();
|
||||
else
|
||||
myOSystem->console().toggleBits();
|
||||
myOSystem.console().toggleBits();
|
||||
break;
|
||||
|
||||
case KBDK_P: // Alt-p toggles phosphor effect
|
||||
myOSystem->console().togglePhosphor();
|
||||
myOSystem.console().togglePhosphor();
|
||||
break;
|
||||
|
||||
case KBDK_L:
|
||||
myOSystem->frameBuffer().toggleFrameStats();
|
||||
myOSystem.frameBuffer().toggleFrameStats();
|
||||
break;
|
||||
|
||||
case KBDK_S:
|
||||
if(myContSnapshotInterval == 0)
|
||||
{
|
||||
ostringstream buf;
|
||||
uInt32 interval = myOSystem->settings().getInt("ssinterval");
|
||||
uInt32 interval = myOSystem.settings().getInt("ssinterval");
|
||||
buf << "Enabling shotshots in " << interval << " second intervals";
|
||||
myOSystem->frameBuffer().showMessage(buf.str());
|
||||
myOSystem.frameBuffer().showMessage(buf.str());
|
||||
setContinuousSnapshots(interval);
|
||||
}
|
||||
else
|
||||
|
@ -529,7 +529,7 @@ void EventHandler::handleKeyEvent(StellaKey key, StellaMod mod, char ascii, bool
|
|||
buf << "Disabling snapshots, generated "
|
||||
<< (myContSnapshotCounter / myContSnapshotInterval)
|
||||
<< " files";
|
||||
myOSystem->frameBuffer().showMessage(buf.str());
|
||||
myOSystem.frameBuffer().showMessage(buf.str());
|
||||
setContinuousSnapshots(0);
|
||||
}
|
||||
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
|
||||
if(myMouseControl)
|
||||
myOSystem->frameBuffer().showMessage(myMouseControl->next());
|
||||
myOSystem.frameBuffer().showMessage(myMouseControl->next());
|
||||
break;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
case KBDK_G: // Ctrl-g (un)grabs mouse
|
||||
if(!myOSystem->frameBuffer().fullScreen())
|
||||
myOSystem->frameBuffer().toggleGrabMouse();
|
||||
if(!myOSystem.frameBuffer().fullScreen())
|
||||
myOSystem.frameBuffer().toggleGrabMouse();
|
||||
break;
|
||||
|
||||
case KBDK_L: // Ctrl-l toggles PAL color-loss effect
|
||||
myOSystem->console().toggleColorLoss();
|
||||
myOSystem.console().toggleColorLoss();
|
||||
break;
|
||||
|
||||
case KBDK_P: // Ctrl-p toggles different palettes
|
||||
myOSystem->console().togglePalette();
|
||||
myOSystem.console().togglePalette();
|
||||
break;
|
||||
|
||||
case KBDK_R: // Ctrl-r reloads the currently loaded ROM
|
||||
myOSystem->reloadConsole();
|
||||
myOSystem.reloadConsole();
|
||||
break;
|
||||
|
||||
case KBDK_PAGEUP: // Ctrl-PageUp increases Height
|
||||
myOSystem->console().changeHeight(+1);
|
||||
myOSystem.console().changeHeight(+1);
|
||||
break;
|
||||
|
||||
case KBDK_PAGEDOWN: // Ctrl-PageDown decreases Height
|
||||
myOSystem->console().changeHeight(-1);
|
||||
myOSystem.console().changeHeight(-1);
|
||||
break;
|
||||
|
||||
case KBDK_S: // Ctrl-s saves properties to a file
|
||||
{
|
||||
string filename = myOSystem->baseDir() +
|
||||
myOSystem->console().properties().get(Cartridge_Name) + ".pro";
|
||||
string filename = myOSystem.baseDir() +
|
||||
myOSystem.console().properties().get(Cartridge_Name) + ".pro";
|
||||
ofstream out(filename.c_str(), ios::out);
|
||||
if(out)
|
||||
{
|
||||
myOSystem->console().properties().save(out);
|
||||
myOSystem.console().properties().save(out);
|
||||
out.close();
|
||||
myOSystem->frameBuffer().showMessage("Properties saved");
|
||||
myOSystem.frameBuffer().showMessage("Properties saved");
|
||||
}
|
||||
else
|
||||
myOSystem->frameBuffer().showMessage("Error saving properties");
|
||||
myOSystem.frameBuffer().showMessage("Error saving properties");
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -718,7 +718,7 @@ void EventHandler::handleJoyEvent(int stick, int button, uInt8 state)
|
|||
// enum; subtracting four gives us Controller 0 and 1
|
||||
if(myState == S_EMULATE)
|
||||
{
|
||||
switch(myOSystem->console().controller(Controller::Left).type())
|
||||
switch(myOSystem.console().controller(Controller::Left).type())
|
||||
{
|
||||
case Controller::Keyboard:
|
||||
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:
|
||||
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:
|
||||
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)
|
||||
{
|
||||
case EVENT_WINDOW_EXPOSED:
|
||||
myOSystem->frameBuffer().refresh();
|
||||
myOSystem.frameBuffer().refresh();
|
||||
break;
|
||||
default: // handle other events as testing requires
|
||||
// cerr << "handleSystemEvent: " << e << endl;
|
||||
|
@ -964,23 +964,23 @@ void EventHandler::handleEvent(Event::Type event, int state)
|
|||
return;
|
||||
|
||||
case Event::VolumeDecrease:
|
||||
if(state) myOSystem->sound().adjustVolume(-1);
|
||||
if(state) myOSystem.sound().adjustVolume(-1);
|
||||
return;
|
||||
|
||||
case Event::VolumeIncrease:
|
||||
if(state) myOSystem->sound().adjustVolume(+1);
|
||||
if(state) myOSystem.sound().adjustVolume(+1);
|
||||
return;
|
||||
|
||||
case Event::SaveState:
|
||||
if(state) myOSystem->state().saveState();
|
||||
if(state) myOSystem.state().saveState();
|
||||
return;
|
||||
|
||||
case Event::ChangeState:
|
||||
if(state) myOSystem->state().changeState();
|
||||
if(state) myOSystem.state().changeState();
|
||||
return;
|
||||
|
||||
case Event::LoadState:
|
||||
if(state) myOSystem->state().loadState();
|
||||
if(state) myOSystem.state().loadState();
|
||||
return;
|
||||
|
||||
case Event::TakeSnapshot:
|
||||
|
@ -992,11 +992,11 @@ void EventHandler::handleEvent(Event::Type event, int state)
|
|||
myState == S_DEBUGGER) && state)
|
||||
{
|
||||
// Go back to the launcher, or immediately quit
|
||||
if(myOSystem->settings().getBool("exitlauncher") ||
|
||||
myOSystem->launcherUsed())
|
||||
if(myOSystem.settings().getBool("exitlauncher") ||
|
||||
myOSystem.launcherUsed())
|
||||
{
|
||||
myOSystem->deleteConsole();
|
||||
myOSystem->createLauncher();
|
||||
myOSystem.deleteConsole();
|
||||
myOSystem.createLauncher();
|
||||
}
|
||||
else
|
||||
handleEvent(Event::Quit, 1);
|
||||
|
@ -1008,7 +1008,7 @@ void EventHandler::handleEvent(Event::Type event, int state)
|
|||
{
|
||||
saveKeyMapping();
|
||||
saveJoyMapping();
|
||||
myOSystem->quit();
|
||||
myOSystem.quit();
|
||||
}
|
||||
return;
|
||||
|
||||
|
@ -1039,22 +1039,22 @@ void EventHandler::handleEvent(Event::Type event, int state)
|
|||
|
||||
// Events which generate messages
|
||||
case Event::ConsoleColor:
|
||||
if(state) myOSystem->frameBuffer().showMessage("Color Mode");
|
||||
if(state) myOSystem.frameBuffer().showMessage("Color Mode");
|
||||
break;
|
||||
case Event::ConsoleBlackWhite:
|
||||
if(state) myOSystem->frameBuffer().showMessage("BW Mode");
|
||||
if(state) myOSystem.frameBuffer().showMessage("BW Mode");
|
||||
break;
|
||||
case Event::ConsoleLeftDiffA:
|
||||
if(state) myOSystem->frameBuffer().showMessage("Left Difficulty A");
|
||||
if(state) myOSystem.frameBuffer().showMessage("Left Difficulty A");
|
||||
break;
|
||||
case Event::ConsoleLeftDiffB:
|
||||
if(state) myOSystem->frameBuffer().showMessage("Left Difficulty B");
|
||||
if(state) myOSystem.frameBuffer().showMessage("Left Difficulty B");
|
||||
break;
|
||||
case Event::ConsoleRightDiffA:
|
||||
if(state) myOSystem->frameBuffer().showMessage("Right Difficulty A");
|
||||
if(state) myOSystem.frameBuffer().showMessage("Right Difficulty A");
|
||||
break;
|
||||
case Event::ConsoleRightDiffB:
|
||||
if(state) myOSystem->frameBuffer().showMessage("Right Difficulty B");
|
||||
if(state) myOSystem.frameBuffer().showMessage("Right Difficulty B");
|
||||
break;
|
||||
|
||||
case Event::NoType: // Ignore unmapped events
|
||||
|
@ -1261,7 +1261,7 @@ void EventHandler::setKeymap()
|
|||
{
|
||||
// Since istringstream swallows whitespace, we have to make the
|
||||
// delimiters be spaces
|
||||
string list = myOSystem->settings().getString("keymap");
|
||||
string list = myOSystem.settings().getString("keymap");
|
||||
replace(list.begin(), list.end(), ':', ' ');
|
||||
istringstream buf(list);
|
||||
|
||||
|
@ -1300,7 +1300,7 @@ void EventHandler::setJoymap()
|
|||
setDefaultJoymap(Event::NoType, kMenuMode);
|
||||
|
||||
// Get all mappings from the settings
|
||||
istringstream buf(myOSystem->settings().getString("joymap"));
|
||||
istringstream buf(myOSystem.settings().getString("joymap"));
|
||||
string joymap;
|
||||
|
||||
// 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
|
||||
// delimiters be spaces
|
||||
string list = myOSystem->settings().getString("combomap");
|
||||
string list = myOSystem.settings().getString("combomap");
|
||||
replace(list.begin(), list.end(), ':', ' ');
|
||||
istringstream buf(list);
|
||||
|
||||
|
@ -1623,7 +1623,7 @@ void EventHandler::setDefaultJoymap(Event::Type event, EventMode mode)
|
|||
else
|
||||
myJoysticks[i]->eraseEvent(event, mode); // only reset the specific event
|
||||
}
|
||||
myOSystem->setDefaultJoymap(event, mode);
|
||||
myOSystem.setDefaultJoymap(event, mode);
|
||||
setActionMappings(mode);
|
||||
#endif
|
||||
}
|
||||
|
@ -1639,7 +1639,7 @@ void EventHandler::saveKeyMapping()
|
|||
for(int i = 0; i < KBDK_LAST; ++i)
|
||||
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)
|
||||
joybuf << "^" << iter->second;
|
||||
|
||||
myOSystem->settings().setValue("joymap", joybuf.str());
|
||||
myOSystem.settings().setValue("joymap", joybuf.str());
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1692,7 +1692,7 @@ void EventHandler::saveComboMapping()
|
|||
for(int j = 1; j < kEventsPerCombo; ++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
|
||||
string filename;
|
||||
bool showmessage = number == 0;
|
||||
string sspath = myOSystem->snapshotSaveDir() +
|
||||
(myOSystem->settings().getString("snapname") != "int" ?
|
||||
myOSystem->romFile().getNameWithExt("")
|
||||
: myOSystem->console().properties().get(Cartridge_Name));
|
||||
string sspath = myOSystem.snapshotSaveDir() +
|
||||
(myOSystem.settings().getString("snapname") != "int" ?
|
||||
myOSystem.romFile().getNameWithExt("")
|
||||
: myOSystem.console().properties().get(Cartridge_Name));
|
||||
|
||||
// Check whether we want multiple snapshots created
|
||||
if(number > 0)
|
||||
|
@ -1878,7 +1878,7 @@ void EventHandler::takeSnapshot(uInt32 number)
|
|||
buf << sspath << "_" << hex << setw(8) << setfill('0') << number << ".png";
|
||||
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
|
||||
// until one doesn't exist
|
||||
|
@ -1902,35 +1902,35 @@ void EventHandler::takeSnapshot(uInt32 number)
|
|||
filename = sspath + ".png";
|
||||
|
||||
// Now create a PNG snapshot
|
||||
if(myOSystem->settings().getBool("ss1x"))
|
||||
if(myOSystem.settings().getBool("ss1x"))
|
||||
{
|
||||
string msg =
|
||||
myOSystem->png().saveImage(filename, myOSystem->frameBuffer(),
|
||||
myOSystem->console().tia(),
|
||||
myOSystem->console().properties());
|
||||
myOSystem.png().saveImage(filename, myOSystem.frameBuffer(),
|
||||
myOSystem.console().tia(),
|
||||
myOSystem.console().properties());
|
||||
if(showmessage)
|
||||
myOSystem->frameBuffer().showMessage(msg);
|
||||
myOSystem.frameBuffer().showMessage(msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Make sure we have a 'clean' image, with no onscreen messages
|
||||
myOSystem->frameBuffer().enableMessages(false);
|
||||
myOSystem.frameBuffer().enableMessages(false);
|
||||
|
||||
string msg =
|
||||
myOSystem->png().saveImage(filename, myOSystem->frameBuffer(),
|
||||
myOSystem->console().properties());
|
||||
myOSystem.png().saveImage(filename, myOSystem.frameBuffer(),
|
||||
myOSystem.console().properties());
|
||||
|
||||
// Re-enable old messages
|
||||
myOSystem->frameBuffer().enableMessages(true);
|
||||
myOSystem.frameBuffer().enableMessages(true);
|
||||
if(showmessage)
|
||||
myOSystem->frameBuffer().showMessage(msg);
|
||||
myOSystem.frameBuffer().showMessage(msg);
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void EventHandler::setMouseControllerMode(const string& enable)
|
||||
{
|
||||
if(&myOSystem->console())
|
||||
if(&myOSystem.console())
|
||||
{
|
||||
delete myMouseControl; myMouseControl = NULL;
|
||||
|
||||
|
@ -1941,7 +1941,7 @@ void EventHandler::setMouseControllerMode(const string& enable)
|
|||
usemouse = false;
|
||||
else // 'analog'
|
||||
{
|
||||
switch(myOSystem->console().controller(Controller::Left).type())
|
||||
switch(myOSystem.console().controller(Controller::Left).type())
|
||||
{
|
||||
case Controller::Paddles:
|
||||
case Controller::Driving:
|
||||
|
@ -1954,7 +1954,7 @@ void EventHandler::setMouseControllerMode(const string& enable)
|
|||
default:
|
||||
break;
|
||||
}
|
||||
switch(myOSystem->console().controller(Controller::Right).type())
|
||||
switch(myOSystem.console().controller(Controller::Right).type())
|
||||
{
|
||||
case Controller::Paddles:
|
||||
case Controller::Driving:
|
||||
|
@ -1970,9 +1970,9 @@ void EventHandler::setMouseControllerMode(const string& enable)
|
|||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
@ -1980,7 +1980,7 @@ void EventHandler::setMouseControllerMode(const string& enable)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void EventHandler::setContinuousSnapshots(uInt32 interval)
|
||||
{
|
||||
myContSnapshotInterval = (uInt32) myOSystem->frameRate() * interval;
|
||||
myContSnapshotInterval = (uInt32) myOSystem.frameRate() * interval;
|
||||
myContSnapshotCounter = 0;
|
||||
}
|
||||
|
||||
|
@ -1989,44 +1989,44 @@ void EventHandler::enterMenuMode(State state)
|
|||
{
|
||||
setEventState(state);
|
||||
myOverlay->reStack();
|
||||
myOSystem->sound().mute(true);
|
||||
myOSystem.sound().mute(true);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void EventHandler::leaveMenuMode()
|
||||
{
|
||||
setEventState(S_EMULATE);
|
||||
myOSystem->sound().mute(false);
|
||||
myOSystem.sound().mute(false);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool EventHandler::enterDebugMode()
|
||||
{
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
if(myState == S_DEBUGGER || !(&myOSystem->console()))
|
||||
if(myState == S_DEBUGGER || !(&myOSystem.console()))
|
||||
return false;
|
||||
|
||||
// Make sure debugger starts in a consistent state
|
||||
// This absolutely *has* to come before we actually change to debugger
|
||||
// mode, since it takes care of locking the debugger state, which will
|
||||
// probably be modified below
|
||||
myOSystem->debugger().setStartState();
|
||||
myOSystem.debugger().setStartState();
|
||||
setEventState(S_DEBUGGER);
|
||||
|
||||
FBInitStatus fbstatus = myOSystem->createFrameBuffer();
|
||||
FBInitStatus fbstatus = myOSystem.createFrameBuffer();
|
||||
if(fbstatus != kSuccess)
|
||||
{
|
||||
myOSystem->debugger().setQuitState();
|
||||
myOSystem.debugger().setQuitState();
|
||||
setEventState(S_EMULATE);
|
||||
if(fbstatus == kFailTooLarge)
|
||||
myOSystem->frameBuffer().showMessage("Debugger window too large for screen",
|
||||
myOSystem.frameBuffer().showMessage("Debugger window too large for screen",
|
||||
kBottomCenter, true);
|
||||
return false;
|
||||
}
|
||||
myOverlay->reStack();
|
||||
myOSystem->sound().mute(true);
|
||||
myOSystem.sound().mute(true);
|
||||
#else
|
||||
myOSystem->frameBuffer().showMessage("Debugger support not included",
|
||||
myOSystem.frameBuffer().showMessage("Debugger support not included",
|
||||
kBottomCenter, true);
|
||||
#endif
|
||||
|
||||
|
@ -2042,11 +2042,11 @@ void EventHandler::leaveDebugMode()
|
|||
return;
|
||||
|
||||
// Make sure debugger quits in a consistent state
|
||||
myOSystem->debugger().setQuitState();
|
||||
myOSystem.debugger().setQuitState();
|
||||
|
||||
setEventState(S_EMULATE);
|
||||
myOSystem->createFrameBuffer();
|
||||
myOSystem->sound().mute(false);
|
||||
myOSystem.createFrameBuffer();
|
||||
myOSystem.sound().mute(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -2057,7 +2057,7 @@ void EventHandler::setEventState(State state)
|
|||
|
||||
// Normally, the usage of Control key is determined by 'ctrlcombo'
|
||||
// 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
|
||||
// Otherwise, it causes a performance hit, so leave it off
|
||||
|
@ -2065,37 +2065,37 @@ void EventHandler::setEventState(State state)
|
|||
{
|
||||
case S_EMULATE:
|
||||
myOverlay = NULL;
|
||||
myOSystem->sound().mute(false);
|
||||
myOSystem.sound().mute(false);
|
||||
//FIXME SDL_EnableUNICODE(0);
|
||||
if(myOSystem->console().controller(Controller::Left).type() ==
|
||||
if(myOSystem.console().controller(Controller::Left).type() ==
|
||||
Controller::CompuMate)
|
||||
myUseCtrlKeyFlag = false;
|
||||
break;
|
||||
|
||||
case S_PAUSE:
|
||||
myOverlay = NULL;
|
||||
myOSystem->sound().mute(true);
|
||||
myOSystem.sound().mute(true);
|
||||
//FIXME SDL_EnableUNICODE(0);
|
||||
break;
|
||||
|
||||
case S_MENU:
|
||||
myOverlay = &myOSystem->menu();
|
||||
myOverlay = &myOSystem.menu();
|
||||
//FIXME SDL_EnableUNICODE(1);
|
||||
break;
|
||||
|
||||
case S_CMDMENU:
|
||||
myOverlay = &myOSystem->commandMenu();
|
||||
myOverlay = &myOSystem.commandMenu();
|
||||
//FIXME SDL_EnableUNICODE(1);
|
||||
break;
|
||||
|
||||
case S_LAUNCHER:
|
||||
myOverlay = &myOSystem->launcher();
|
||||
myOverlay = &myOSystem.launcher();
|
||||
//FIXME SDL_EnableUNICODE(1);
|
||||
break;
|
||||
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
case S_DEBUGGER:
|
||||
myOverlay = &myOSystem->debugger();
|
||||
myOverlay = &myOSystem.debugger();
|
||||
//FIXME SDL_EnableUNICODE(1);
|
||||
break;
|
||||
#endif
|
||||
|
@ -2106,15 +2106,15 @@ void EventHandler::setEventState(State state)
|
|||
}
|
||||
|
||||
// Inform various subsystems about the new state
|
||||
myOSystem->stateChanged(myState);
|
||||
if(&myOSystem->frameBuffer())
|
||||
myOSystem.stateChanged(myState);
|
||||
if(&myOSystem.frameBuffer())
|
||||
{
|
||||
myOSystem->frameBuffer().stateChanged(myState);
|
||||
myOSystem->frameBuffer().setCursorState();
|
||||
myOSystem.frameBuffer().stateChanged(myState);
|
||||
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
|
||||
|
|
|
@ -86,7 +86,7 @@ class EventHandler
|
|||
/**
|
||||
Create a new event handler object
|
||||
*/
|
||||
EventHandler(OSystem* osystem);
|
||||
EventHandler(OSystem& osystem);
|
||||
|
||||
/**
|
||||
Destructor
|
||||
|
@ -319,7 +319,7 @@ class EventHandler
|
|||
|
||||
protected:
|
||||
// Global OSystem object
|
||||
OSystem* myOSystem;
|
||||
OSystem& myOSystem;
|
||||
|
||||
/**
|
||||
Methods which are called by derived classes to handle specific types
|
||||
|
|
|
@ -21,9 +21,8 @@
|
|||
#include "FBSurface.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
FBSurface::FBSurface(const uInt32* palette)
|
||||
: myPalette(palette),
|
||||
myPixels(NULL),
|
||||
FBSurface::FBSurface()
|
||||
: myPixels(NULL),
|
||||
myPitch(0)
|
||||
{
|
||||
// NOTE: myPixels and myPitch MUST be set in child classes that inherit
|
||||
|
@ -278,3 +277,6 @@ void FBSurface::drawSurface(const FBSurface* surface)
|
|||
dst += myPitch;
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
const uInt32* FBSurface::myPalette = 0;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#define FBSURFACE_HXX
|
||||
|
||||
class FrameBuffer;
|
||||
class TIASurface;
|
||||
|
||||
#include "bspf.hxx"
|
||||
#include "Font.hxx"
|
||||
|
@ -51,11 +52,13 @@ enum FrameStyle {
|
|||
|
||||
class FBSurface
|
||||
{
|
||||
friend class TIASurface;
|
||||
|
||||
public:
|
||||
/**
|
||||
Creates a new FBSurface object
|
||||
*/
|
||||
FBSurface(const uInt32* palette);
|
||||
FBSurface();
|
||||
|
||||
/**
|
||||
Destructor
|
||||
|
@ -259,17 +262,6 @@ class FBSurface
|
|||
*/
|
||||
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
|
||||
to the (destination) surface coordinates.
|
||||
|
@ -302,10 +294,35 @@ class FBSurface
|
|||
*/
|
||||
virtual void reload() = 0;
|
||||
|
||||
static void setPalette(const uInt32* palette) { myPalette = palette; }
|
||||
|
||||
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 myPitch;
|
||||
|
||||
Attributes myAttributes;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "TIA.hxx"
|
||||
|
||||
#include "FBSurface.hxx"
|
||||
#include "TIASurface.hxx"
|
||||
#include "FrameBuffer.hxx"
|
||||
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
|
@ -45,19 +46,15 @@
|
|||
#endif
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
FrameBuffer::FrameBuffer(OSystem* osystem)
|
||||
FrameBuffer::FrameBuffer(OSystem& osystem)
|
||||
: myOSystem(osystem),
|
||||
myRedrawEntireFrame(true),
|
||||
myUsePhosphor(false),
|
||||
myPhosphorBlend(77),
|
||||
myInitializedCount(0),
|
||||
myPausedCount(0)
|
||||
myPausedCount(0),
|
||||
myTIASurface(NULL)
|
||||
{
|
||||
myMsg.surface = myStatsMsg.surface = NULL;
|
||||
myMsg.enabled = myStatsMsg.enabled = false;
|
||||
|
||||
// Load NTSC filter settings
|
||||
myNTSCFilter.loadConfig(myOSystem->settings());
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -67,6 +64,7 @@ FrameBuffer::~FrameBuffer(void)
|
|||
delete myInfoFont;
|
||||
delete mySmallFont;
|
||||
delete myLauncherFont;
|
||||
delete myTIASurface;
|
||||
|
||||
// Free all allocated surfaces
|
||||
while(!mySurfaceList.empty())
|
||||
|
@ -85,7 +83,7 @@ bool FrameBuffer::initialize()
|
|||
|
||||
// Check the 'maxres' setting, which is an undocumented developer feature
|
||||
// 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)
|
||||
{
|
||||
query_w = s.w;
|
||||
|
@ -126,7 +124,7 @@ bool FrameBuffer::initialize()
|
|||
// very small screens
|
||||
if(!smallScreen)
|
||||
{
|
||||
const string& lf = myOSystem->settings().getString("launcherfont");
|
||||
const string& lf = myOSystem.settings().getString("launcherfont");
|
||||
if(lf == "small")
|
||||
myLauncherFont = new GUI::Font(GUI::consoleDesc);
|
||||
else if(lf == "medium")
|
||||
|
@ -150,6 +148,20 @@ bool FrameBuffer::initialize()
|
|||
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;
|
||||
}
|
||||
|
||||
|
@ -181,7 +193,7 @@ FBInitStatus FrameBuffer::createDisplay(const string& title,
|
|||
return kFailTooLarge;
|
||||
|
||||
// FIXSDL - remove size limitations here?
|
||||
if(myOSystem->settings().getString("fullscreen") == "1")
|
||||
if(myOSystem.settings().getString("fullscreen") == "1")
|
||||
{
|
||||
if(myDesktopSize.w < width || myDesktopSize.h < height)
|
||||
return kFailTooLarge;
|
||||
|
@ -208,15 +220,21 @@ FBInitStatus FrameBuffer::createDisplay(const string& title,
|
|||
myScreenSize = mode.screen;
|
||||
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?
|
||||
myOSystem->settings().setValue("fullscreen", fullScreen());
|
||||
myOSystem.settings().setValue("fullscreen", fullScreen());
|
||||
resetSurfaces();
|
||||
setCursorState();
|
||||
}
|
||||
else
|
||||
{
|
||||
myOSystem->logMessage("ERROR: Couldn't initialize video subsystem", 0);
|
||||
myOSystem.logMessage("ERROR: Couldn't initialize video subsystem", 0);
|
||||
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.
|
||||
if(myInitializedCount == 1)
|
||||
{
|
||||
myOSystem->logMessage(about(), 1);
|
||||
setUIPalette();
|
||||
myOSystem.logMessage(about(), 1);
|
||||
setWindowIcon();
|
||||
}
|
||||
else
|
||||
{
|
||||
string post_about = about();
|
||||
if(post_about != pre_about)
|
||||
myOSystem->logMessage(post_about, 1);
|
||||
myOSystem.logMessage(post_about, 1);
|
||||
}
|
||||
|
||||
return kSuccess;
|
||||
|
@ -265,31 +282,31 @@ void FrameBuffer::update()
|
|||
// Determine which mode we are in (from the EventHandler)
|
||||
// Take care of S_EMULATE mode here, otherwise let the GUI
|
||||
// figure out what to draw
|
||||
switch(myOSystem->eventHandler().state())
|
||||
switch(myOSystem.eventHandler().state())
|
||||
{
|
||||
case EventHandler::S_EMULATE:
|
||||
{
|
||||
// Run the console for one frame
|
||||
// Note that the debugger can cause a breakpoint to occur, which changes
|
||||
// the EventHandler state 'behind our back' - we need to check for that
|
||||
myOSystem->console().tia().update();
|
||||
myOSystem.console().tia().update();
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
if(myOSystem->eventHandler().state() != EventHandler::S_EMULATE) break;
|
||||
if(myOSystem.eventHandler().state() != EventHandler::S_EMULATE) break;
|
||||
#endif
|
||||
if(myOSystem->eventHandler().frying())
|
||||
myOSystem->console().fry();
|
||||
if(myOSystem.eventHandler().frying())
|
||||
myOSystem.console().fry();
|
||||
|
||||
// And update the screen
|
||||
drawTIA(myRedrawEntireFrame);
|
||||
drawTIA();
|
||||
|
||||
// Show frame statistics
|
||||
if(myStatsMsg.enabled)
|
||||
{
|
||||
const ConsoleInfo& info = myOSystem->console().about();
|
||||
const ConsoleInfo& info = myOSystem.console().about();
|
||||
char msg[30];
|
||||
BSPF_snprintf(msg, 30, "%3u @ %3.2ffps => %s",
|
||||
myOSystem->console().tia().scanlines(),
|
||||
myOSystem->console().getFramerate(), info.DisplayFormat.c_str());
|
||||
myOSystem.console().tia().scanlines(),
|
||||
myOSystem.console().getFramerate(), info.DisplayFormat.c_str());
|
||||
myStatsMsg.surface->fillRect(0, 0, myStatsMsg.w, myStatsMsg.h, kBGColor);
|
||||
myStatsMsg.surface->drawString(infoFont(),
|
||||
msg, 1, 1, myStatsMsg.w, myStatsMsg.color, kTextAlignLeft);
|
||||
|
@ -306,10 +323,10 @@ void FrameBuffer::update()
|
|||
{
|
||||
// Only update the screen if it's been invalidated
|
||||
if(myRedrawEntireFrame)
|
||||
drawTIA(true);
|
||||
drawTIA();
|
||||
|
||||
// Show a pause message every 5 seconds
|
||||
if(myPausedCount++ >= 7*myOSystem->frameRate())
|
||||
if(myPausedCount++ >= 7*myOSystem.frameRate())
|
||||
{
|
||||
myPausedCount = 0;
|
||||
showMessage("Paused", kMiddleCenter);
|
||||
|
@ -321,7 +338,7 @@ void FrameBuffer::update()
|
|||
{
|
||||
// When onscreen messages are enabled in double-buffer mode,
|
||||
// a full redraw is required
|
||||
myOSystem->menu().draw(myMsg.enabled && isDoubleBuffered());
|
||||
myOSystem.menu().draw(myMsg.enabled && isDoubleBuffered());
|
||||
break; // S_MENU
|
||||
}
|
||||
|
||||
|
@ -329,7 +346,7 @@ void FrameBuffer::update()
|
|||
{
|
||||
// When onscreen messages are enabled in double-buffer mode,
|
||||
// a full redraw is required
|
||||
myOSystem->commandMenu().draw(myMsg.enabled && isDoubleBuffered());
|
||||
myOSystem.commandMenu().draw(myMsg.enabled && isDoubleBuffered());
|
||||
break; // S_CMDMENU
|
||||
}
|
||||
|
||||
|
@ -337,7 +354,7 @@ void FrameBuffer::update()
|
|||
{
|
||||
// When onscreen messages are enabled in double-buffer mode,
|
||||
// a full redraw is required
|
||||
myOSystem->launcher().draw(myMsg.enabled && isDoubleBuffered());
|
||||
myOSystem.launcher().draw(myMsg.enabled && isDoubleBuffered());
|
||||
break; // S_LAUNCHER
|
||||
}
|
||||
|
||||
|
@ -346,7 +363,7 @@ void FrameBuffer::update()
|
|||
{
|
||||
// When onscreen messages are enabled in double-buffer mode,
|
||||
// a full redraw is required
|
||||
myOSystem->debugger().draw(myMsg.enabled && isDoubleBuffered());
|
||||
myOSystem.debugger().draw(myMsg.enabled && isDoubleBuffered());
|
||||
break; // S_DEBUGGER
|
||||
}
|
||||
#endif
|
||||
|
@ -371,7 +388,7 @@ void FrameBuffer::showMessage(const string& message, MessagePosition position,
|
|||
bool force)
|
||||
{
|
||||
// Only show messages if they've been enabled
|
||||
if(!(force || myOSystem->settings().getBool("uimessages")))
|
||||
if(!(force || myOSystem.settings().getBool("uimessages")))
|
||||
return;
|
||||
|
||||
// Erase old messages on the screen
|
||||
|
@ -383,7 +400,7 @@ void FrameBuffer::showMessage(const string& message, MessagePosition position,
|
|||
|
||||
// Precompute the message coordinates
|
||||
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.w = font().getStringWidth(myMsg.text) + 10;
|
||||
|
@ -397,13 +414,13 @@ void FrameBuffer::showMessage(const string& message, MessagePosition position,
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBuffer::toggleFrameStats()
|
||||
{
|
||||
showFrameStats(!myOSystem->settings().getBool("stats"));
|
||||
showFrameStats(!myOSystem.settings().getBool("stats"));
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBuffer::showFrameStats(bool enable)
|
||||
{
|
||||
myOSystem->settings().setValue("stats", enable);
|
||||
myOSystem.settings().setValue("stats", enable);
|
||||
myStatsMsg.enabled = enable;
|
||||
refresh();
|
||||
}
|
||||
|
@ -414,7 +431,7 @@ void FrameBuffer::enableMessages(bool enable)
|
|||
if(enable)
|
||||
{
|
||||
// Only re-enable frame stats if they were already enabled before
|
||||
myStatsMsg.enabled = myOSystem->settings().getBool("stats");
|
||||
myStatsMsg.enabled = myOSystem.settings().getBool("stats");
|
||||
}
|
||||
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()
|
||||
{
|
||||
|
@ -514,66 +540,66 @@ void FrameBuffer::refresh()
|
|||
// This method is in essence a FULL refresh, putting all rendering
|
||||
// buffers in a known, fully redrawn state
|
||||
|
||||
switch(myOSystem->eventHandler().state())
|
||||
switch(myOSystem.eventHandler().state())
|
||||
{
|
||||
case EventHandler::S_EMULATE:
|
||||
case EventHandler::S_PAUSE:
|
||||
invalidate();
|
||||
drawTIA(true);
|
||||
drawTIA();
|
||||
if(isDoubleBuffered())
|
||||
{
|
||||
postFrameUpdate();
|
||||
invalidate();
|
||||
drawTIA(true);
|
||||
drawTIA();
|
||||
}
|
||||
break;
|
||||
|
||||
case EventHandler::S_MENU:
|
||||
invalidate();
|
||||
drawTIA(true);
|
||||
myOSystem->menu().draw(true);
|
||||
drawTIA();
|
||||
myOSystem.menu().draw(true);
|
||||
if(isDoubleBuffered())
|
||||
{
|
||||
postFrameUpdate();
|
||||
invalidate();
|
||||
drawTIA(true);
|
||||
myOSystem->menu().draw(true);
|
||||
drawTIA();
|
||||
myOSystem.menu().draw(true);
|
||||
}
|
||||
break;
|
||||
|
||||
case EventHandler::S_CMDMENU:
|
||||
invalidate();
|
||||
drawTIA(true);
|
||||
myOSystem->commandMenu().draw(true);
|
||||
drawTIA();
|
||||
myOSystem.commandMenu().draw(true);
|
||||
if(isDoubleBuffered())
|
||||
{
|
||||
postFrameUpdate();
|
||||
invalidate();
|
||||
drawTIA(true);
|
||||
myOSystem->commandMenu().draw(true);
|
||||
drawTIA();
|
||||
myOSystem.commandMenu().draw(true);
|
||||
}
|
||||
break;
|
||||
|
||||
case EventHandler::S_LAUNCHER:
|
||||
invalidate();
|
||||
myOSystem->launcher().draw(true);
|
||||
myOSystem.launcher().draw(true);
|
||||
if(isDoubleBuffered())
|
||||
{
|
||||
postFrameUpdate();
|
||||
invalidate();
|
||||
myOSystem->launcher().draw(true);
|
||||
myOSystem.launcher().draw(true);
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
case EventHandler::S_DEBUGGER:
|
||||
invalidate();
|
||||
myOSystem->debugger().draw(true);
|
||||
myOSystem.debugger().draw(true);
|
||||
if(isDoubleBuffered())
|
||||
{
|
||||
postFrameUpdate();
|
||||
invalidate();
|
||||
myOSystem->debugger().draw(true);
|
||||
myOSystem.debugger().draw(true);
|
||||
}
|
||||
break;
|
||||
#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)
|
||||
{
|
||||
|
@ -646,7 +619,7 @@ uInt32 FrameBuffer::allocateSurface(int w, int h)
|
|||
mySurfaceList.insert(make_pair((uInt32)mySurfaceList.size(), surface));
|
||||
|
||||
// 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
|
||||
// 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;
|
||||
for(iter = mySurfaceList.begin(); iter != mySurfaceList.end(); ++iter)
|
||||
iter->second->free();
|
||||
if(tiasurface)
|
||||
tiasurface->free();
|
||||
for(iter = mySurfaceList.begin(); iter != mySurfaceList.end(); ++iter)
|
||||
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;
|
||||
uInt8 p = *(myOSystem->console().tia().previousFrameBuffer() + idx) | shift;
|
||||
|
||||
return (!myUsePhosphor ? myDefPalette[c] : myAvgPalette[c][p]);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBuffer::setTIAPalette(const uInt32* palette)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
cerr << "FrameBuffer::setPalette\n";
|
||||
// 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 g = (palette[i] >> 8) & 0xff;
|
||||
Uint8 b = palette[i] & 0xff;
|
||||
|
||||
myDefPalette[i] = mapRGB(r, g, b);
|
||||
myPalette[i] = mapRGB(r, g, b);
|
||||
}
|
||||
|
||||
// Set palette for phosphor effect
|
||||
for(i = 0; i < 256; ++i)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
// Let the TIA surface know about the new palette
|
||||
myTIASurface->setPalette(myPalette, palette);
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -758,7 +686,7 @@ enableFullscreen(enable);
|
|||
#if 0 //FIXSDL
|
||||
#ifdef WINDOWED_SUPPORT
|
||||
// '-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);
|
||||
|
||||
// Do a dummy call to getSavedVidMode to set up the modelists
|
||||
|
@ -782,7 +710,7 @@ void FrameBuffer::toggleFullscreen()
|
|||
bool FrameBuffer::changeWindowedVidMode(int direction)
|
||||
{
|
||||
#ifdef WINDOWED_SUPPORT
|
||||
EventHandler::State state = myOSystem->eventHandler().state();
|
||||
EventHandler::State state = myOSystem.eventHandler().state();
|
||||
bool tiaMode = (state != EventHandler::S_DEBUGGER &&
|
||||
state != EventHandler::S_LAUNCHER);
|
||||
|
||||
|
@ -800,10 +728,11 @@ bool FrameBuffer::changeWindowedVidMode(int direction)
|
|||
const VideoMode& mode = myCurrentModeList->current();
|
||||
myImageRect = mode.image;
|
||||
myScreenSize = mode.screen;
|
||||
if(setVideoMode(myScreenTitle, mode, false))
|
||||
if(setVideoMode(myScreenTitle, mode))
|
||||
{
|
||||
resetSurfaces();
|
||||
showMessage(mode.description);
|
||||
myOSystem->settings().setValue("tia.zoom", mode.zoom);
|
||||
myOSystem.settings().setValue("tia.zoom", mode.zoom);
|
||||
refresh();
|
||||
return true;
|
||||
}
|
||||
|
@ -817,29 +746,20 @@ void FrameBuffer::setCursorState()
|
|||
// Always grab mouse in fullscreen or during emulation (if enabled),
|
||||
// and don't show the cursor during emulation
|
||||
bool emulation =
|
||||
myOSystem->eventHandler().state() == EventHandler::S_EMULATE;
|
||||
myOSystem.eventHandler().state() == EventHandler::S_EMULATE;
|
||||
grabMouse(fullScreen() ||
|
||||
(emulation && myOSystem->settings().getBool("grabmouse")));
|
||||
(emulation && myOSystem.settings().getBool("grabmouse")));
|
||||
showCursor(!emulation);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBuffer::toggleGrabMouse()
|
||||
{
|
||||
bool state = myOSystem->settings().getBool("grabmouse");
|
||||
myOSystem->settings().setValue("grabmouse", !state);
|
||||
bool state = myOSystem.settings().getBool("grabmouse");
|
||||
myOSystem.settings().setValue("grabmouse", !state);
|
||||
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 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
|
||||
// for TIA screens)
|
||||
EventHandler::State state = myOSystem->eventHandler().state();
|
||||
EventHandler::State state = myOSystem.eventHandler().state();
|
||||
bool tiaMode = (state != EventHandler::S_DEBUGGER &&
|
||||
state != EventHandler::S_LAUNCHER);
|
||||
|
||||
|
@ -880,8 +800,8 @@ void FrameBuffer::setAvailableVidModes(uInt32 baseWidth, uInt32 baseHeight)
|
|||
myDesktopSize.w, myDesktopSize.h);
|
||||
|
||||
// Aspect ratio
|
||||
bool ntsc = myOSystem->console().about().InitialFrameRate == "60";
|
||||
uInt32 aspect = myOSystem->settings().getInt(ntsc ?
|
||||
bool ntsc = myOSystem.console().about().InitialFrameRate == "60";
|
||||
uInt32 aspect = myOSystem.settings().getInt(ntsc ?
|
||||
"tia.aspectn" : "tia.aspectp");
|
||||
|
||||
// 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)
|
||||
myCurrentModeList = &myFullscreenModeList;
|
||||
|
@ -940,7 +860,7 @@ const FrameBuffer::VideoMode& FrameBuffer::getSavedVidMode(bool fullscreen)
|
|||
if(state == EventHandler::S_DEBUGGER || state == EventHandler::S_LAUNCHER)
|
||||
myCurrentModeList->setZoom(1);
|
||||
else
|
||||
myCurrentModeList->setZoom(myOSystem->settings().getInt("tia.zoom"));
|
||||
myCurrentModeList->setZoom(myOSystem.settings().getInt("tia.zoom"));
|
||||
|
||||
return myCurrentModeList->current();
|
||||
}
|
||||
|
@ -950,7 +870,7 @@ const FrameBuffer::VideoMode& FrameBuffer::getSavedVidMode(bool fullscreen)
|
|||
// VideoMode implementation
|
||||
//
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
FrameBuffer::VideoMode::VideoMode()
|
||||
VideoMode::VideoMode()
|
||||
: fullscreen(false),
|
||||
zoom(1),
|
||||
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)
|
||||
: fullscreen(full),
|
||||
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
|
||||
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;
|
||||
|
||||
// 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
|
||||
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];
|
||||
}
|
||||
|
|
|
@ -30,12 +30,12 @@ namespace GUI {
|
|||
class Font;
|
||||
}
|
||||
|
||||
#include "FBSurface.hxx"
|
||||
#include "EventHandler.hxx"
|
||||
#include "Rect.hxx"
|
||||
#include "StringList.hxx"
|
||||
#include "NTSCFilter.hxx"
|
||||
#include "Variant.hxx"
|
||||
#include "FBSurface.hxx"
|
||||
#include "TIASurface.hxx"
|
||||
#include "bspf.hxx"
|
||||
|
||||
// Return values for initialization of framebuffer window
|
||||
|
@ -85,6 +85,39 @@ enum {
|
|||
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
|
||||
display in Stella. All graphics ports should derive from this class for
|
||||
|
@ -107,7 +140,7 @@ class FrameBuffer
|
|||
/**
|
||||
Creates a new Frame Buffer
|
||||
*/
|
||||
FrameBuffer(OSystem* osystem);
|
||||
FrameBuffer(OSystem& osystem);
|
||||
|
||||
/**
|
||||
Destructor
|
||||
|
@ -210,6 +243,11 @@ class FrameBuffer
|
|||
*/
|
||||
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
|
||||
*/
|
||||
|
@ -218,6 +256,11 @@ class FrameBuffer
|
|||
const GUI::Font& smallFont() const { return *mySmallFont; }
|
||||
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.
|
||||
double-buffered modes into account, and redrawing accordingly.
|
||||
|
@ -256,91 +299,18 @@ class FrameBuffer
|
|||
*/
|
||||
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.
|
||||
|
||||
@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.
|
||||
*/
|
||||
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
|
||||
// implemented in derived classes.
|
||||
|
@ -356,18 +326,6 @@ class FrameBuffer
|
|||
*/
|
||||
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.
|
||||
|
||||
|
@ -411,16 +369,14 @@ class FrameBuffer
|
|||
virtual void queryHardware(uInt32& w, uInt32& h, VariantList& ren) = 0;
|
||||
|
||||
/**
|
||||
This method is called to change to the given video mode. If the mode
|
||||
is successfully changed, 'mode' holds the actual dimensions used.
|
||||
This method is called to change to the given video mode.
|
||||
|
||||
@param title The title for the created window
|
||||
@param mode The video mode to use
|
||||
@param full Whether this is a fullscreen or windowed mode
|
||||
|
||||
@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.
|
||||
|
@ -444,16 +400,6 @@ class FrameBuffer
|
|||
*/
|
||||
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.
|
||||
*/
|
||||
|
@ -464,12 +410,6 @@ class FrameBuffer
|
|||
*/
|
||||
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).
|
||||
*/
|
||||
|
@ -480,35 +420,15 @@ class FrameBuffer
|
|||
*/
|
||||
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:
|
||||
// The parent system for the framebuffer
|
||||
OSystem* myOSystem;
|
||||
OSystem& myOSystem;
|
||||
|
||||
// Indicates if the entire frame need to redrawn
|
||||
bool myRedrawEntireFrame;
|
||||
|
||||
// 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;
|
||||
|
||||
// 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;
|
||||
// Color palette for TIA and UI modes
|
||||
Uint32 myPalette[256+kNumColors];
|
||||
|
||||
private:
|
||||
/**
|
||||
|
@ -516,6 +436,18 @@ class FrameBuffer
|
|||
*/
|
||||
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
|
||||
still fit in the given screen dimensions.
|
||||
|
@ -544,11 +476,6 @@ class FrameBuffer
|
|||
*/
|
||||
const VideoMode& getSavedVidMode(bool fullscreen);
|
||||
|
||||
/**
|
||||
Set up the user interface palette for a screen of any depth > 8.
|
||||
*/
|
||||
void setUIPalette();
|
||||
|
||||
private:
|
||||
/**
|
||||
This class implements an iterator around an array of VideoMode objects.
|
||||
|
@ -566,7 +493,7 @@ class FrameBuffer
|
|||
uInt32 size() const;
|
||||
|
||||
void previous();
|
||||
const FrameBuffer::VideoMode& current() const;
|
||||
const VideoMode& current() const;
|
||||
void next();
|
||||
|
||||
void setZoom(uInt32 zoom);
|
||||
|
@ -619,6 +546,9 @@ class FrameBuffer
|
|||
// The font object to use for the ROM launcher
|
||||
GUI::Font* myLauncherFont;
|
||||
|
||||
// The TIASurface class takes responsibility for TIA rendering
|
||||
TIASurface* myTIASurface;
|
||||
|
||||
// Used for onscreen messages and frame statistics
|
||||
// (scanline count and framerate)
|
||||
struct Message {
|
||||
|
@ -638,6 +568,9 @@ class FrameBuffer
|
|||
VideoModeList myFullscreenModeList;
|
||||
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
|
||||
map<uInt32,FBSurface*> mySurfaceList;
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ class MediaFactory
|
|||
#endif
|
||||
}
|
||||
|
||||
static Settings* createSettings(OSystem* osystem)
|
||||
static Settings* createSettings(OSystem& osystem)
|
||||
{
|
||||
#if defined(BSPF_UNIX)
|
||||
return new SettingsUNIX(osystem);
|
||||
|
@ -87,12 +87,12 @@ class MediaFactory
|
|||
#endif
|
||||
}
|
||||
|
||||
static FrameBuffer* createVideo(OSystem* osystem)
|
||||
static FrameBuffer* createVideo(OSystem& osystem)
|
||||
{
|
||||
return new FrameBufferSDL2(osystem);
|
||||
}
|
||||
|
||||
static Sound* createAudio(OSystem* osystem)
|
||||
static Sound* createAudio(OSystem& osystem)
|
||||
{
|
||||
#ifdef SOUND_SUPPORT
|
||||
return new SoundSDL2(osystem);
|
||||
|
@ -101,7 +101,7 @@ class MediaFactory
|
|||
#endif
|
||||
}
|
||||
|
||||
static EventHandler* createEventHandler(OSystem* osystem)
|
||||
static EventHandler* createEventHandler(OSystem& osystem)
|
||||
{
|
||||
return new EventHandlerSDL2(osystem);
|
||||
}
|
||||
|
|
|
@ -115,7 +115,7 @@ OSystem::OSystem()
|
|||
<< " [" << BSPF_ARCH << "]";
|
||||
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
|
||||
// This must be done before any graphics context is created, since
|
||||
// it may be needed to initialize the size of graphical objects
|
||||
myFrameBuffer = MediaFactory::createVideo(this);
|
||||
myFrameBuffer = MediaFactory::createVideo(*this);
|
||||
if(!myFrameBuffer->initialize())
|
||||
return false;
|
||||
|
||||
// Create the event handler for the system
|
||||
myEventHandler = MediaFactory::createEventHandler(this);
|
||||
myEventHandler = MediaFactory::createEventHandler(*this);
|
||||
myEventHandler->initialize();
|
||||
|
||||
// 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
|
||||
if(myFrameBuffer)
|
||||
myFrameBuffer->ntsc().saveConfig(*mySettings);
|
||||
myFrameBuffer->tiaSurface().ntsc().saveConfig(*mySettings);
|
||||
|
||||
mySettings->saveConfig();
|
||||
}
|
||||
|
@ -352,7 +352,7 @@ FBInitStatus OSystem::createFrameBuffer()
|
|||
void OSystem::createSound()
|
||||
{
|
||||
if(!mySound)
|
||||
mySound = MediaFactory::createAudio(this);
|
||||
mySound = MediaFactory::createAudio(*this);
|
||||
#ifndef SOUND_SUPPORT
|
||||
mySettings->setValue("sound", false);
|
||||
#endif
|
||||
|
@ -626,7 +626,7 @@ Console* OSystem::openConsole(const FilesystemNode& romfile, string& md5,
|
|||
|
||||
// Finally, create the cart with the correct properties
|
||||
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
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#include "Settings.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Settings::Settings(OSystem* osystem)
|
||||
Settings::Settings(OSystem& osystem)
|
||||
: myOSystem(osystem)
|
||||
{
|
||||
// Video-related options
|
||||
|
@ -165,10 +165,10 @@ void Settings::loadConfig()
|
|||
string line, key, value;
|
||||
string::size_type equalPos, garbage;
|
||||
|
||||
ifstream in(myOSystem->configFile().c_str());
|
||||
ifstream in(myOSystem.configFile().c_str());
|
||||
if(!in || !in.is_open())
|
||||
{
|
||||
myOSystem->logMessage("ERROR: Couldn't load settings file", 0);
|
||||
myOSystem.logMessage("ERROR: Couldn't load settings file", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -236,7 +236,7 @@ string Settings::loadCommandLine(int argc, char** argv)
|
|||
if(++i >= argc)
|
||||
{
|
||||
buf << "Missing argument for '" << key << "'" << endl;
|
||||
myOSystem->logMessage(buf.str(), 0);
|
||||
myOSystem.logMessage(buf.str(), 0);
|
||||
return "";
|
||||
}
|
||||
string value = argv[i];
|
||||
|
@ -257,7 +257,7 @@ string Settings::loadCommandLine(int argc, char** argv)
|
|||
buf << "(E)\n";
|
||||
}
|
||||
|
||||
myOSystem->logMessage(buf.str(), 2);
|
||||
myOSystem.logMessage(buf.str(), 2);
|
||||
}
|
||||
else
|
||||
return key;
|
||||
|
@ -513,10 +513,10 @@ void Settings::saveConfig()
|
|||
if(!settingsChanged)
|
||||
return;
|
||||
|
||||
ofstream out(myOSystem->configFile().c_str());
|
||||
ofstream out(myOSystem.configFile().c_str());
|
||||
if(!out || !out.is_open())
|
||||
{
|
||||
myOSystem->logMessage("ERROR: Couldn't save settings file", 0);
|
||||
myOSystem.logMessage("ERROR: Couldn't save settings file", 0);
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ class Settings
|
|||
/**
|
||||
Create a new settings abstract class
|
||||
*/
|
||||
Settings(OSystem* osystem);
|
||||
Settings(OSystem& osystem);
|
||||
|
||||
/**
|
||||
Destructor
|
||||
|
@ -122,7 +122,7 @@ class Settings
|
|||
|
||||
protected:
|
||||
// The parent OSystem object
|
||||
OSystem* myOSystem;
|
||||
OSystem& myOSystem;
|
||||
|
||||
// Structure used for storing settings
|
||||
struct Setting
|
||||
|
|
|
@ -39,7 +39,7 @@ class Sound : public Serializable
|
|||
Create a new sound object. The init method must be invoked before
|
||||
using the object.
|
||||
*/
|
||||
Sound(OSystem* osystem) { myOSystem = osystem; }
|
||||
Sound(OSystem& osystem) : myOSystem(osystem) { }
|
||||
|
||||
/**
|
||||
Destructor
|
||||
|
@ -129,7 +129,7 @@ class Sound : public Serializable
|
|||
|
||||
protected:
|
||||
// The OSystem for this sound object
|
||||
OSystem* myOSystem;
|
||||
OSystem& myOSystem;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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
|
|
@ -71,6 +71,7 @@ MODULE_OBJS := \
|
|||
src/emucore/TIA.o \
|
||||
src/emucore/TIASnd.o \
|
||||
src/emucore/TIATables.o \
|
||||
src/emucore/TIASurface.o \
|
||||
src/emucore/TrackBall.o \
|
||||
src/emucore/Thumbulator.o
|
||||
|
||||
|
|
|
@ -463,7 +463,7 @@ void VideoDialog::saveConfig()
|
|||
adj.artifacts = myTVArtifacts->getValue();
|
||||
adj.fringing = myTVFringe->getValue();
|
||||
adj.bleed = myTVBleed->getValue();
|
||||
instance().frameBuffer().ntsc().setCustomAdjustables(adj);
|
||||
instance().frameBuffer().tiaSurface().ntsc().setCustomAdjustables(adj);
|
||||
|
||||
// TV scanline intensity and interpolation
|
||||
instance().settings().setValue("tv.scanlines", myTVScanIntenseLabel->getLabel());
|
||||
|
@ -565,7 +565,8 @@ void VideoDialog::handleTVModeChange(NTSCFilter::Preset preset)
|
|||
void VideoDialog::loadTVAdjustables(NTSCFilter::Preset preset)
|
||||
{
|
||||
NTSCFilter::Adjustable adj;
|
||||
instance().frameBuffer().ntsc().getAdjustables(adj, (NTSCFilter::Preset)preset);
|
||||
instance().frameBuffer().tiaSurface().ntsc().getAdjustables(
|
||||
adj, (NTSCFilter::Preset)preset);
|
||||
myTVSharp->setValue(adj.sharpness);
|
||||
myTVSharpLabel->setValue(adj.sharpness);
|
||||
myTVHue->setValue(adj.hue);
|
||||
|
|
|
@ -26,7 +26,7 @@ extern "C" {
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
SettingsMACOSX::SettingsMACOSX(OSystem* osystem)
|
||||
SettingsMACOSX::SettingsMACOSX(OSystem& osystem)
|
||||
: Settings(osystem)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ class SettingsMACOSX : public Settings
|
|||
/**
|
||||
Create a new UNIX settings object
|
||||
*/
|
||||
SettingsMACOSX(OSystem* osystem);
|
||||
SettingsMACOSX(OSystem& osystem);
|
||||
|
||||
/**
|
||||
Destructor
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include "SettingsUNIX.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
SettingsUNIX::SettingsUNIX(OSystem* osystem)
|
||||
SettingsUNIX::SettingsUNIX(OSystem& osystem)
|
||||
: Settings(osystem)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ class SettingsUNIX : public Settings
|
|||
/**
|
||||
Create a new UNIX settings object
|
||||
*/
|
||||
SettingsUNIX(OSystem* osystem);
|
||||
SettingsUNIX(OSystem& osystem);
|
||||
|
||||
/**
|
||||
Destructor
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include "SettingsWINDOWS.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
SettingsWINDOWS::SettingsWINDOWS(OSystem* osystem)
|
||||
SettingsWINDOWS::SettingsWINDOWS(OSystem& osystem)
|
||||
: Settings(osystem)
|
||||
{
|
||||
setInternal("fragsize", "1024");
|
||||
|
|
|
@ -30,7 +30,7 @@ class SettingsWINDOWS : public Settings
|
|||
/**
|
||||
Create a new UNIX settings object
|
||||
*/
|
||||
SettingsWINDOWS(OSystem* osystem);
|
||||
SettingsWINDOWS(OSystem& osystem);
|
||||
|
||||
/**
|
||||
Destructor
|
||||
|
|
Loading…
Reference in New Issue