Merge branch 'rework-aspect'

This commit is contained in:
Christian Speckner 2020-01-07 21:15:53 +01:00
commit f7cb631ed4
13 changed files with 114 additions and 88 deletions

View File

@ -696,11 +696,13 @@ void Console::setTIAProperties()
{
// Assume we've got ~262 scanlines (NTSC-like format)
myTIA->setLayout(FrameLayout::ntsc);
myTIA->setAdjustScanlines(myOSystem.settings().getInt("tia.adjustscanlines.ntsc"));
}
else
{
// Assume we've got ~312 scanlines (PAL-like format)
myTIA->setLayout(FrameLayout::pal);
myTIA->setAdjustScanlines(myOSystem.settings().getInt("tia.adjustscanlines.pal"));
}
myTIA->setVcenter(vcenter);

View File

@ -311,6 +311,12 @@ class Console : public Serializable, public ConsoleIO
*/
void updateVcenter(Int32 vcenter);
/**
Set up various properties of the TIA (vcenter, Height, etc) based on
the current display format.
*/
void setTIAProperties();
private:
/**
* Dry-run the emulation and detect the frame layout (PAL / NTSC).
@ -322,12 +328,6 @@ class Console : public Serializable, public ConsoleIO
*/
void redetectFrameLayout();
/**
Sets various properties of the TIA (vcenter, Height, etc) based on
the current display format.
*/
void setTIAProperties();
/**
Create the audio queue
*/

View File

@ -932,14 +932,6 @@ void FrameBuffer::setAvailableVidModes(uInt32 baseWidth, uInt32 baseHeight)
uInt32 minZoom = supportedTIAMinZoom();
myTIAMaxZoom = maxZoomForScreen(baseWidth, baseHeight,
myAbsDesktopSize.w, myAbsDesktopSize.h);
#if 0 // FIXME - does this apply any longer??
// Aspect ratio
uInt32 aspect = myOSystem.settings().getInt(
myOSystem.console().tia().frameLayout() == FrameLayout::ntsc ?
"tia.aspectn" : "tia.aspectp");
#endif
// Determine all zoom levels
for(float zoom = minZoom; zoom <= myTIAMaxZoom; zoom += ZOOM_STEPS)
{

View File

@ -50,8 +50,8 @@ Settings::Settings()
// TIA specific options
setPermanent("tia.zoom", "3");
setPermanent("tia.inter", "false");
setPermanent("tia.aspectn", "100");
setPermanent("tia.aspectp", "100");
setPermanent("tia.adjustscanlines.ntsc", "0");
setPermanent("tia.adjustscanlines.pal", "0");
setPermanent("fullscreen", "false");
setPermanent("tia.fs_stretch", "false");
setPermanent("tia.fs_overscan", "0");
@ -255,10 +255,10 @@ void Settings::validate()
f = getFloat("speed");
if (f <= 0) setValue("speed", "1.0");
i = getInt("tia.aspectn");
if(i < 80 || i > 120) setValue("tia.aspectn", "90");
i = getInt("tia.aspectp");
if(i < 80 || i > 120) setValue("tia.aspectp", "100");
i = getInt("tia.adjustscanlines.ntsc");
if(i < -25 || i > 25) setValue("tia.adjustscanlines.ntsc", "90");
i = getInt("tia.adjustscanlines.pal");
if(i < -25 || i > 25) setValue("tia.adjustscanlines.pal", "100");
s = getString("tia.dbgcolors");
sort(s.begin(), s.end());
@ -410,10 +410,8 @@ void Settings::usage() const
<< " for TIA image\n"
<< " -tia.inter <1|0> Enable interpolated (smooth) scaling for TIA\n"
<< " image\n"
<< " -tia.aspectn <number> Scale TIA width by the given percentage in NTS\n"
<< " mode\n"
<< " -tia.aspectp <number> Scale TIA width by the given percentage in PAL\n"
<< " mode\n"
<< " -tia.adjustscanlines.ntsc <number> Adjust the visible number if TIA scanlines on NTSC\n"
<< " -tia.adjustscanlines.pal <number> Adjust the visible number if TIA scanlines on PAL\n"
<< " -tia.fs_stretch <1|0> Stretch TIA image to fill fullscreen mode\n"
<< " -tia.fs_overscan <0-10> Add overscan to TIA image in fill fullscreen mode\n"
<< " -tia.dbgcolors <string> Debug colors to use for each object (see manual\n"

View File

@ -219,9 +219,15 @@ void TIASurface::enableNTSC(bool enable)
{
myFilter = Filter(enable ? uInt8(myFilter) | 0x10 : uInt8(myFilter) & 0x01);
// Normal vs NTSC mode uses different source widths
myTiaSurface->setSrcSize(enable ? AtariNTSC::outWidth(TIAConstants::frameBufferWidth)
: TIAConstants::frameBufferWidth, myTIA->height());
uInt32 surfaceWidth = enable ?
AtariNTSC::outWidth(TIAConstants::frameBufferWidth) : TIAConstants::frameBufferWidth;
if (surfaceWidth != myTiaSurface->srcRect().w() || myTIA->height() != myTiaSurface->srcRect().h()) {
myTiaSurface->setSrcSize(surfaceWidth, myTIA->height());
myTiaSurface->invalidate();
myTIA->clearFrameBuffer();
}
mySLineSurface->setSrcSize(1, 2 * myTIA->height());

View File

@ -899,6 +899,13 @@ void TIA::renderToFrameBuffer()
myFrameBufferScanlines = myFrontBufferScanlines;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIA::clearFrameBuffer()
{
myFramebuffer.fill(0);
myFrontBuffer.fill(0);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIA::update(uInt64 maxCycles)
{

View File

@ -244,6 +244,8 @@ class TIA : public Device
*/
uInt8* frameBuffer() { return myFramebuffer.data(); }
void clearFrameBuffer();
/**
Answers dimensional info about the framebuffer.
*/
@ -260,6 +262,9 @@ class TIA : public Device
void setLayout(FrameLayout layout) { myFrameManager->setLayout(layout); }
FrameLayout frameLayout() const { return myFrameManager->layout(); }
void setAdjustScanlines(Int32 adjustScanlines) { myFrameManager->setAdjustScanlines(adjustScanlines); }
Int32 adjustScanlines() const { return myFrameManager->adjustScanlines(); }
/**
Enables/disables color-loss for PAL modes only.

View File

@ -170,6 +170,10 @@ class AbstractFrameManager : public Serializable
*/
virtual Int32 vcenter() const { return 0; }
virtual void setAdjustScanlines(Int32 adjustScanlines) {}
virtual Int32 adjustScanlines() const { return 0; }
/**
* The corresponding start line.
*/

View File

@ -24,13 +24,12 @@
enum Metrics: uInt32 {
vblankNTSC = 37,
vblankPAL = 45,
kernelNTSC = 192,
kernelPAL = 228,
overscanNTSC = 30,
overscanPAL = 36,
vsync = 3,
frameSizeNTSC = 262,
frameSizePAL = 312,
baseHeightNTSC = 240,
baseHeightPAL = 288,
maxLinesVsync = 50,
visibleOverscan = 20,
initialGarbageFrames = TIAConstants::initialGarbageFrames,
ystartNTSC = 34,
ystartPAL = 39
@ -40,8 +39,7 @@ enum Metrics: uInt32 {
FrameManager::FrameManager()
{
reset();
updateYStart();
onLayoutChange();
recalculateMetrics();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -118,7 +116,14 @@ void FrameManager::setVcenter(Int32 vcenter)
if (vcenter < TIAConstants::minVcenter || vcenter > TIAConstants::maxVcenter) return;
myVcenter = vcenter;
updateYStart();
recalculateMetrics();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameManager::setAdjustScanlines(Int32 adjustScanlines)
{
myAdjustScanlines = adjustScanlines;
recalculateMetrics();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -163,26 +168,7 @@ void FrameManager::setState(FrameManager::State state)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameManager::onLayoutChange()
{
switch (layout())
{
case FrameLayout::ntsc:
myVblankLines = Metrics::vblankNTSC;
myKernelLines = Metrics::kernelNTSC;
myOverscanLines = Metrics::overscanNTSC;
break;
case FrameLayout::pal:
myVblankLines = Metrics::vblankPAL;
myKernelLines = Metrics::kernelPAL;
myOverscanLines = Metrics::overscanPAL;
break;
default:
throw runtime_error("frame manager: invalid TV mode");
}
myFrameLines = Metrics::vsync + myVblankLines + myKernelLines + myOverscanLines;
myHeight = myKernelLines + Metrics::visibleOverscan;
recalculateMetrics();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -202,8 +188,6 @@ bool FrameManager::onSave(Serializer& out) const
out.putInt(myLastY);
out.putInt(myVblankLines);
out.putInt(myKernelLines);
out.putInt(myOverscanLines);
out.putInt(myFrameLines);
out.putInt(myHeight);
out.putInt(myYStart);
@ -225,8 +209,6 @@ bool FrameManager::onLoad(Serializer& in)
myLastY = in.getInt();
myVblankLines = in.getInt();
myKernelLines = in.getInt();
myOverscanLines = in.getInt();
myFrameLines = in.getInt();
myHeight = in.getInt();
myYStart = in.getInt();
@ -237,7 +219,32 @@ bool FrameManager::onLoad(Serializer& in)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameManager::updateYStart() {
myYStart = (layout() == FrameLayout::ntsc ? Metrics::ystartNTSC : Metrics::ystartPAL) - myVcenter;
void FrameManager::recalculateMetrics() {
Int32 ystartBase;
Int32 baseHeight;
switch (layout())
{
case FrameLayout::ntsc:
myVblankLines = Metrics::vblankNTSC;
myFrameLines = Metrics::frameSizeNTSC;
ystartBase = Metrics::ystartNTSC;
baseHeight = Metrics::baseHeightNTSC;
break;
case FrameLayout::pal:
myVblankLines = Metrics::vblankPAL;
myFrameLines = Metrics::frameSizePAL;
ystartBase = Metrics::ystartPAL;
baseHeight = Metrics::baseHeightPAL;
break;
default:
throw runtime_error("frame manager: invalid TV mode");
}
myHeight = BSPF::clamp<uInt32>(baseHeight + myAdjustScanlines * 2, 0, myFrameLines);
myYStart = BSPF::clamp<uInt32>(ystartBase + (baseHeight - static_cast<Int32>(myHeight)) / 2 + myVcenter, 0, myFrameLines);
myJitterEmulation.setYStart(myYStart);
}

View File

@ -48,6 +48,10 @@ class FrameManager: public AbstractFrameManager {
Int32 vcenter() const override { return myVcenter; }
void setAdjustScanlines(Int32 adjustScanlines) override;
Int32 adjustScanlines() const override { return myAdjustScanlines; }
uInt32 startLine() const override { return myYStart; }
void setLayout(FrameLayout mode) override { layout(mode); }
@ -79,7 +83,7 @@ class FrameManager: public AbstractFrameManager {
void updateIsRendering();
void updateYStart();
void recalculateMetrics();
private:
@ -89,12 +93,11 @@ class FrameManager: public AbstractFrameManager {
uInt32 myY{0}, myLastY{0};
uInt32 myVblankLines{0};
uInt32 myKernelLines{0};
uInt32 myOverscanLines{0};
uInt32 myFrameLines{0};
uInt32 myHeight{0};
uInt32 myYStart{0};
Int32 myVcenter{0};
Int32 myAdjustScanlines{0};
bool myJitterEnabled{false};

View File

@ -86,7 +86,7 @@ VideoDialog::VideoDialog(OSystem& osystem, DialogContainer& parent,
fontWidth = font.getMaxCharWidth(),
buttonHeight = font.getLineHeight() + 4;
int xpos, ypos, tabID;
int lwidth = font.getStringWidth("TIA Palette "),
int lwidth = font.getStringWidth("NTSC scanlines adjust "),
pwidth = font.getStringWidth("XXXXxXXXX"),
swidth = font.getMaxCharWidth() * 10 - 2;
@ -94,7 +94,7 @@ VideoDialog::VideoDialog(OSystem& osystem, DialogContainer& parent,
VariantList items;
// Set real dimensions
setSize(55 * fontWidth + HBORDER * 2, 14 * (lineHeight + VGAP) + 14 + _th, max_w, max_h);
setSize(65 * fontWidth + HBORDER * 2, 14 * (lineHeight + VGAP) + 14 + _th, max_w, max_h);
// The tab widget
xpos = 2; ypos = 4;
@ -136,23 +136,23 @@ VideoDialog::VideoDialog(OSystem& osystem, DialogContainer& parent,
ypos += lineHeight + VGAP;
// Aspect ratio (NTSC mode)
myNAspectRatio =
myAdjustScanlinesNTSC =
new SliderWidget(myTab, font, xpos, ypos-1, swidth, lineHeight,
"NTSC aspect ", lwidth, 0,
fontWidth * 4, "%");
myNAspectRatio->setMinValue(80); myNAspectRatio->setMaxValue(120);
myNAspectRatio->setTickmarkIntervals(2);
wid.push_back(myNAspectRatio);
"NTSC scanlines adjust ", lwidth, 0,
fontWidth * 4, "");
myAdjustScanlinesNTSC->setMinValue(-25); myAdjustScanlinesNTSC->setMaxValue(25);
myAdjustScanlinesNTSC->setTickmarkIntervals(2);
wid.push_back(myAdjustScanlinesNTSC);
ypos += lineHeight + VGAP;
// Aspect ratio (PAL mode)
myPAspectRatio =
myAdjustScanlinesPAL =
new SliderWidget(myTab, font, xpos, ypos-1, swidth, lineHeight,
"PAL aspect ", lwidth, 0,
fontWidth * 4, "%");
myPAspectRatio->setMinValue(80); myPAspectRatio->setMaxValue(120);
myPAspectRatio->setTickmarkIntervals(2);
wid.push_back(myPAspectRatio);
"PAL scanlines adjust ", lwidth, 0,
fontWidth * 4, "");
myAdjustScanlinesPAL->setMinValue(-25); myAdjustScanlinesPAL->setMaxValue(25);
myAdjustScanlinesPAL->setTickmarkIntervals(2);
wid.push_back(myAdjustScanlinesPAL);
ypos += lineHeight + VGAP;
// Speed
@ -353,8 +353,8 @@ void VideoDialog::loadConfig()
myTIAInterpolate->setState(instance().settings().getBool("tia.inter"));
// Aspect ratio setting (NTSC and PAL)
myNAspectRatio->setValue(instance().settings().getInt("tia.aspectn"));
myPAspectRatio->setValue(instance().settings().getInt("tia.aspectp"));
myAdjustScanlinesNTSC->setValue(instance().settings().getInt("tia.adjustscanlines.ntsc"));
myAdjustScanlinesPAL->setValue(instance().settings().getInt("tia.adjustscanlines.pal"));
// Emulation speed
int speed = mapSpeed(instance().settings().getFloat("speed"));
@ -426,8 +426,8 @@ void VideoDialog::saveConfig()
instance().settings().setValue("tia.inter", myTIAInterpolate->getState());
// Aspect ratio setting (NTSC and PAL)
instance().settings().setValue("tia.aspectn", myNAspectRatio->getValueLabel());
instance().settings().setValue("tia.aspectp", myPAspectRatio->getValueLabel());
instance().settings().setValue("tia.adjustscanlines.ntsc", myAdjustScanlinesNTSC->getValueLabel());
instance().settings().setValue("tia.adjustscanlines.pal", myAdjustScanlinesPAL->getValueLabel());
// Speed
int speedup = mySpeed->getValue();
@ -487,6 +487,8 @@ void VideoDialog::saveConfig()
// TV scanline intensity
instance().settings().setValue("tv.scanlines", myTVScanIntense->getValueLabel());
instance().console().setTIAProperties();
// Finally, issue a complete framebuffer re-initialization...
instance().createFrameBuffer();
@ -505,8 +507,8 @@ void VideoDialog::setDefaults()
myTIAZoom->setValue(300);
myTIAPalette->setSelected("standard", "");
myTIAInterpolate->setState(false);
myNAspectRatio->setValue(91);
myPAspectRatio->setValue(109);
myAdjustScanlinesNTSC->setValue(0);
myAdjustScanlinesPAL->setValue(0);
mySpeed->setValue(0);
myFullscreen->setState(false);

View File

@ -58,8 +58,8 @@ class VideoDialog : public Dialog
SliderWidget* myTIAZoom{nullptr};
PopUpWidget* myTIAPalette{nullptr};
CheckboxWidget* myTIAInterpolate{nullptr};
SliderWidget* myNAspectRatio{nullptr};
SliderWidget* myPAspectRatio{nullptr};
SliderWidget* myAdjustScanlinesNTSC{nullptr};
SliderWidget* myAdjustScanlinesPAL{nullptr};
SliderWidget* mySpeed{nullptr};
CheckboxWidget* myFullscreen{nullptr};

View File

@ -90,8 +90,8 @@ bool StellaLIBRETRO::create(bool logging)
settings.setValue("tia.zoom", 1);
settings.setValue("tia.inter", false);
settings.setValue("tia.aspectn", 100);
settings.setValue("tia.aspectp", 100);
settings.setValue("tia.adjustscanlines.ntsc", 0);
settings.setValue("tia.adjustscanlines.ntsc", 0);
//fastscbios
// Fast loading of Supercharger BIOS