mirror of https://github.com/stella-emu/stella.git
first try
This commit is contained in:
parent
8f0ea1a70b
commit
9e268dda0c
|
@ -268,6 +268,9 @@ class FBBackendSDL2 : public FBBackend
|
|||
// Center setting of current window
|
||||
bool myCenter{false};
|
||||
|
||||
// Flag for bezel mode
|
||||
bool myShowBezel{false};
|
||||
|
||||
// Does the renderer support render targets?
|
||||
bool myRenderTargetSupport{false};
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@ FBSurfaceSDL2::FBSurfaceSDL2(FBBackendSDL2& backend,
|
|||
: myBackend{backend},
|
||||
myInterpolationMode{inter}
|
||||
{
|
||||
//cerr << width << " x " << height << endl;
|
||||
createSurface(width, height, staticData);
|
||||
}
|
||||
|
||||
|
@ -233,6 +234,7 @@ void FBSurfaceSDL2::createSurface(uInt32 width, uInt32 height,
|
|||
|
||||
mySurface = SDL_CreateRGBSurface(0, width, height,
|
||||
pf.BitsPerPixel, pf.Rmask, pf.Gmask, pf.Bmask, pf.Amask);
|
||||
//SDL_SetSurfaceBlendMode(mySurface, SDL_BLENDMODE_ADD); // default: SDL_BLENDMODE_BLEND
|
||||
|
||||
// We start out with the src and dst rectangles containing the same
|
||||
// dimensions, indicating no scaling or re-positioning
|
||||
|
|
|
@ -35,6 +35,7 @@ PNGLibrary::PNGLibrary(OSystem& osystem)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void PNGLibrary::loadImage(const string& filename, FBSurface& surface, VariantList& metaData)
|
||||
{
|
||||
|
||||
png_structp png_ptr{nullptr};
|
||||
png_infop info_ptr{nullptr};
|
||||
png_uint_32 iwidth{0}, iheight{0};
|
||||
|
|
|
@ -36,6 +36,7 @@ const VideoModeHandler::Mode&
|
|||
VideoModeHandler::buildMode(const Settings& settings, bool inTIAMode)
|
||||
{
|
||||
const bool windowedRequested = myFSIndex == -1;
|
||||
const bool showBezel = inTIAMode&& settings.getBool("showbezel");
|
||||
|
||||
// TIA mode allows zooming at non-integral factors in most cases
|
||||
if(inTIAMode)
|
||||
|
@ -49,14 +50,14 @@ VideoModeHandler::buildMode(const Settings& settings, bool inTIAMode)
|
|||
// Image and screen (aka window) dimensions are the same
|
||||
// Overscan is not applicable in this mode
|
||||
myMode = Mode(myImage.w * zoom, myImage.h * zoom, Mode::Stretch::Fill,
|
||||
myFSIndex, desc.str(), zoom);
|
||||
myFSIndex, desc.str(), zoom, showBezel);
|
||||
}
|
||||
else
|
||||
{
|
||||
const float overscan = 1 - settings.getInt("tia.fs_overscan") / 100.0;
|
||||
|
||||
// First calculate maximum zoom that keeps aspect ratio
|
||||
const float scaleX = static_cast<float>(myImage.w) / myDisplay.w,
|
||||
const float scaleX = myImage.w / myDisplay.w,
|
||||
scaleY = static_cast<float>(myImage.h) / myDisplay.h;
|
||||
float zoom = 1.F / std::max(scaleX, scaleY);
|
||||
|
||||
|
@ -70,14 +71,16 @@ VideoModeHandler::buildMode(const Settings& settings, bool inTIAMode)
|
|||
myMode = Mode(myImage.w * zoom, myImage.h * zoom,
|
||||
myDisplay.w, myDisplay.h,
|
||||
Mode::Stretch::Preserve, myFSIndex,
|
||||
"Fullscreen: Preserve aspect, no stretch", zoom, overscan);
|
||||
"Fullscreen: Preserve aspect, no stretch",
|
||||
zoom, overscan, showBezel);
|
||||
}
|
||||
else // ignore aspect, use all space
|
||||
{
|
||||
myMode = Mode(myImage.w * zoom, myImage.h * zoom,
|
||||
myDisplay.w, myDisplay.h,
|
||||
Mode::Stretch::Fill, myFSIndex,
|
||||
"Fullscreen: Ignore aspect, full stretch", zoom, overscan);
|
||||
"Fullscreen: Ignore aspect, full stretch",
|
||||
zoom, overscan, showBezel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -96,38 +99,41 @@ VideoModeHandler::buildMode(const Settings& settings, bool inTIAMode)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
VideoModeHandler::Mode::Mode(uInt32 iw, uInt32 ih, Stretch smode,
|
||||
Int32 fsindex, string_view desc,
|
||||
float zoomLevel)
|
||||
: Mode(iw, ih, iw, ih, smode, fsindex, desc, zoomLevel)
|
||||
float zoomLevel, bool showBezel)
|
||||
: Mode(iw, ih, iw, ih, smode, fsindex, desc, zoomLevel, 1.F, showBezel)
|
||||
{
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
VideoModeHandler::Mode::Mode(uInt32 iw, uInt32 ih, uInt32 sw, uInt32 sh,
|
||||
Stretch smode, Int32 fsindex, string_view desc,
|
||||
float zoomLevel, float overscan)
|
||||
float zoomLevel, float overscan, bool showBezel)
|
||||
: screenS{sw, sh},
|
||||
stretch{smode},
|
||||
description{desc},
|
||||
zoom{zoomLevel},
|
||||
fsIndex{fsindex}
|
||||
{
|
||||
const float scaleW = showBezel ? (16.F / 9.F) / (4.F / 3.F) : 1;
|
||||
//const Int32 imageW = iw * scaleW;
|
||||
//screenS.w = screenS.w * scaleW;
|
||||
// Now resize based on windowed/fullscreen mode and stretch factor
|
||||
if(fsIndex != -1) // fullscreen mode
|
||||
{
|
||||
switch(stretch)
|
||||
{
|
||||
case Stretch::Preserve:
|
||||
iw *= overscan;
|
||||
iw *= overscan / scaleW;
|
||||
ih *= overscan;
|
||||
break;
|
||||
|
||||
case Stretch::Fill:
|
||||
// Scale to all available space
|
||||
iw = screenS.w * overscan;
|
||||
iw = screenS.w * (overscan / scaleW);
|
||||
ih = screenS.h * overscan;
|
||||
break;
|
||||
|
||||
case Stretch::None:
|
||||
case Stretch::None: // UI Mode
|
||||
// Don't do any scaling at all
|
||||
iw = std::min(iw, screenS.w) * overscan;
|
||||
ih = std::min(ih, screenS.h) * overscan;
|
||||
|
@ -142,11 +148,11 @@ VideoModeHandler::Mode::Mode(uInt32 iw, uInt32 ih, uInt32 sw, uInt32 sh,
|
|||
{
|
||||
case Stretch::Preserve:
|
||||
case Stretch::Fill:
|
||||
screenS.w = iw;
|
||||
screenS.w = iw * scaleW;
|
||||
screenS.h = ih;
|
||||
break;
|
||||
|
||||
case Stretch::None:
|
||||
case Stretch::None: // UI Mode
|
||||
break; // Do not change image or screen rects whatsoever
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,9 +50,9 @@ class VideoModeHandler
|
|||
Mode() = default;
|
||||
Mode(uInt32 iw, uInt32 ih, uInt32 sw, uInt32 sh, Stretch smode,
|
||||
Int32 fsindex = -1, string_view desc = "",
|
||||
float zoomLevel = 1.F, float overscan = 1.F);
|
||||
float zoomLevel = 1.F, float overscan = 1.F, bool showBezel = false);
|
||||
Mode(uInt32 iw, uInt32 ih, Stretch smode, Int32 fsindex = -1,
|
||||
string_view desc = "", float zoomLevel = 1.F);
|
||||
string_view desc = "", float zoomLevel = 1.F, bool showBezel = false);
|
||||
|
||||
friend ostream& operator<<(ostream& os, const Mode& vm)
|
||||
{
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "Sound.hxx"
|
||||
#include "AudioSettings.hxx"
|
||||
#include "MediaFactory.hxx"
|
||||
#include "PNGLibrary.hxx"
|
||||
|
||||
#include "FBSurface.hxx"
|
||||
#include "TIASurface.hxx"
|
||||
|
@ -70,6 +71,8 @@ FrameBuffer::FrameBuffer(OSystem& osystem)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
FrameBuffer::~FrameBuffer() // NOLINT (we need an empty d'tor)
|
||||
{
|
||||
if(myBezelSurface)
|
||||
deallocateSurface(myBezelSurface);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -605,6 +608,7 @@ void FrameBuffer::updateInEmulationMode(float framesPerSecond)
|
|||
if(myMsg.enabled)
|
||||
drawMessage();
|
||||
|
||||
myBezelSurface->render();
|
||||
// Push buffers to screen
|
||||
myBackend->renderToScreen();
|
||||
}
|
||||
|
@ -1303,6 +1307,23 @@ FBInitStatus FrameBuffer::applyVideoMode()
|
|||
myOSystem.settings().setValue("tia.zoom", myActiveVidMode.zoom);
|
||||
}
|
||||
|
||||
if(inTIAMode)
|
||||
{
|
||||
if(myBezelSurface)
|
||||
deallocateSurface(myBezelSurface);
|
||||
|
||||
myBezelSurface = allocateSurface(
|
||||
myActiveVidMode.screenS.w,
|
||||
myActiveVidMode.screenS.h);
|
||||
|
||||
// Get a valid filename representing a snapshot file for this rom and load the snapshot
|
||||
const string& path = myOSystem.snapshotLoadDir().getPath();
|
||||
|
||||
//loadBezel(path + "Atari-2600.png");
|
||||
//loadBezel(path + "Combat.png");
|
||||
loadBezel(path + "Asteroids (USA).png");
|
||||
}
|
||||
|
||||
resetSurfaces();
|
||||
setCursorState();
|
||||
myPendingRender = true;
|
||||
|
@ -1316,16 +1337,61 @@ FBInitStatus FrameBuffer::applyVideoMode()
|
|||
return status;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool FrameBuffer::loadBezel(const string& fileName)
|
||||
{
|
||||
try
|
||||
{
|
||||
VariantList metaData;
|
||||
myOSystem.png().loadImage(fileName, *myBezelSurface, metaData);
|
||||
|
||||
// Scale surface to available image area
|
||||
const Common::Rect& src = myBezelSurface->srcRect();
|
||||
const float scale = std::min(
|
||||
static_cast<float>(myActiveVidMode.screenS.w) / src.w(),
|
||||
static_cast<float>(myActiveVidMode.screenS.h) / src.h()
|
||||
) * myOSystem.frameBuffer().hidpiScaleFactor();
|
||||
myBezelSurface->setDstSize(
|
||||
static_cast<uInt32>(std::round(src.w() * scale)),
|
||||
static_cast<uInt32>(round(src.h() * scale)));
|
||||
//myActiveVidMode.screenS.w,
|
||||
//myActiveVidMode.screenS.h);
|
||||
myBezelSurface->setScalingInterpolation(ScalingInterpolation::sharp);
|
||||
|
||||
//Int32 w = round(src.w() * scale);
|
||||
//Int32 h = round(src.h() * scale);
|
||||
//cerr << scale << ": " << w << " x " << h << endl;
|
||||
|
||||
//// temp workaround:
|
||||
//FBSurface::Attributes& attr = myBezelSurface->attributes();
|
||||
//attr.blendalpha = 50; // 0..100
|
||||
//attr.blending = true;
|
||||
//myBezelSurface->applyAttributes();
|
||||
////SDL_SetSurfaceBlendMode(myBezelSurface, SDL_BLENDMODE_BLEND);
|
||||
|
||||
if(myBezelSurface)
|
||||
myBezelSurface->setVisible(true);
|
||||
}
|
||||
catch(const runtime_error&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
float FrameBuffer::maxWindowZoom() const
|
||||
{
|
||||
const int display = displayId(BufferType::Emulator);
|
||||
float multiplier = 1;
|
||||
|
||||
const bool showBezel = myOSystem.settings().getBool("showbezel");
|
||||
const double scaleW = showBezel ? (16. / 9.) / (4. / 3.) : 1; // = 1.333
|
||||
|
||||
for(;;)
|
||||
{
|
||||
// Figure out the zoomed size of the window
|
||||
const uInt32 width = TIAConstants::viewableWidth * multiplier;
|
||||
const uInt32 width = TIAConstants::viewableWidth * multiplier * scaleW;
|
||||
const uInt32 height = TIAConstants::viewableHeight * multiplier;
|
||||
|
||||
if((width > myAbsDesktopSize[display].w) || (height > myAbsDesktopSize[display].h))
|
||||
|
|
|
@ -443,6 +443,11 @@ class FrameBuffer
|
|||
*/
|
||||
FBInitStatus applyVideoMode();
|
||||
|
||||
/**
|
||||
Load the bezel for the given ROM filename.
|
||||
*/
|
||||
bool loadBezel(const string& romFileName);
|
||||
|
||||
/**
|
||||
Calculate the maximum level by which the base window can be zoomed and
|
||||
still fit in the desktop screen.
|
||||
|
@ -519,7 +524,10 @@ class FrameBuffer
|
|||
#endif
|
||||
|
||||
// The TIASurface class takes responsibility for TIA rendering
|
||||
unique_ptr<TIASurface> myTIASurface;
|
||||
shared_ptr<TIASurface> myTIASurface;
|
||||
|
||||
// The BezelSurface class takes responsibility for TIA rendering
|
||||
shared_ptr<FBSurface> myBezelSurface;
|
||||
|
||||
// Used for onscreen messages and frame statistics
|
||||
// (scanline count and framerate)
|
||||
|
|
|
@ -62,6 +62,7 @@ Settings::Settings()
|
|||
setPermanent("display", 0);
|
||||
setPermanent("uimessages", "true");
|
||||
setPermanent("pausedim", "true");
|
||||
setPermanent("showbezel", "true");
|
||||
// TIA specific options
|
||||
setPermanent("tia.inter", "false");
|
||||
setPermanent("tia.zoom", "3");
|
||||
|
|
|
@ -432,7 +432,7 @@ void TIASurface::createScanlineSurface()
|
|||
mySLineSurface = myFB.allocateSurface(width, height,
|
||||
interpolationModeFromSettings(myOSystem.settings()), data.data());
|
||||
|
||||
mySLineSurface->setSrcSize(mySLineSurface->width(), height);
|
||||
//mySLineSurface->setSrcSize(mySLineSurface->width(), height);
|
||||
mySLineSurface->setDstRect(myTiaSurface->dstRect());
|
||||
updateSurfaceSettings();
|
||||
|
||||
|
|
Loading…
Reference in New Issue