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) // Assume we've got ~262 scanlines (NTSC-like format)
myTIA->setLayout(FrameLayout::ntsc); myTIA->setLayout(FrameLayout::ntsc);
myTIA->setAdjustScanlines(myOSystem.settings().getInt("tia.adjustscanlines.ntsc"));
} }
else else
{ {
// Assume we've got ~312 scanlines (PAL-like format) // Assume we've got ~312 scanlines (PAL-like format)
myTIA->setLayout(FrameLayout::pal); myTIA->setLayout(FrameLayout::pal);
myTIA->setAdjustScanlines(myOSystem.settings().getInt("tia.adjustscanlines.pal"));
} }
myTIA->setVcenter(vcenter); myTIA->setVcenter(vcenter);

View File

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

View File

@ -932,14 +932,6 @@ void FrameBuffer::setAvailableVidModes(uInt32 baseWidth, uInt32 baseHeight)
uInt32 minZoom = supportedTIAMinZoom(); uInt32 minZoom = supportedTIAMinZoom();
myTIAMaxZoom = maxZoomForScreen(baseWidth, baseHeight, myTIAMaxZoom = maxZoomForScreen(baseWidth, baseHeight,
myAbsDesktopSize.w, myAbsDesktopSize.h); 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 // Determine all zoom levels
for(float zoom = minZoom; zoom <= myTIAMaxZoom; zoom += ZOOM_STEPS) for(float zoom = minZoom; zoom <= myTIAMaxZoom; zoom += ZOOM_STEPS)
{ {

View File

@ -50,8 +50,8 @@ Settings::Settings()
// TIA specific options // TIA specific options
setPermanent("tia.zoom", "3"); setPermanent("tia.zoom", "3");
setPermanent("tia.inter", "false"); setPermanent("tia.inter", "false");
setPermanent("tia.aspectn", "100"); setPermanent("tia.adjustscanlines.ntsc", "0");
setPermanent("tia.aspectp", "100"); setPermanent("tia.adjustscanlines.pal", "0");
setPermanent("fullscreen", "false"); setPermanent("fullscreen", "false");
setPermanent("tia.fs_stretch", "false"); setPermanent("tia.fs_stretch", "false");
setPermanent("tia.fs_overscan", "0"); setPermanent("tia.fs_overscan", "0");
@ -255,10 +255,10 @@ void Settings::validate()
f = getFloat("speed"); f = getFloat("speed");
if (f <= 0) setValue("speed", "1.0"); if (f <= 0) setValue("speed", "1.0");
i = getInt("tia.aspectn"); i = getInt("tia.adjustscanlines.ntsc");
if(i < 80 || i > 120) setValue("tia.aspectn", "90"); if(i < -25 || i > 25) setValue("tia.adjustscanlines.ntsc", "90");
i = getInt("tia.aspectp"); i = getInt("tia.adjustscanlines.pal");
if(i < 80 || i > 120) setValue("tia.aspectp", "100"); if(i < -25 || i > 25) setValue("tia.adjustscanlines.pal", "100");
s = getString("tia.dbgcolors"); s = getString("tia.dbgcolors");
sort(s.begin(), s.end()); sort(s.begin(), s.end());
@ -410,10 +410,8 @@ void Settings::usage() const
<< " for TIA image\n" << " for TIA image\n"
<< " -tia.inter <1|0> Enable interpolated (smooth) scaling for TIA\n" << " -tia.inter <1|0> Enable interpolated (smooth) scaling for TIA\n"
<< " image\n" << " image\n"
<< " -tia.aspectn <number> Scale TIA width by the given percentage in NTS\n" << " -tia.adjustscanlines.ntsc <number> Adjust the visible number if TIA scanlines on NTSC\n"
<< " mode\n" << " -tia.adjustscanlines.pal <number> Adjust the visible number if TIA scanlines on PAL\n"
<< " -tia.aspectp <number> Scale TIA width by the given percentage in PAL\n"
<< " mode\n"
<< " -tia.fs_stretch <1|0> Stretch TIA image to fill fullscreen mode\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.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" << " -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); myFilter = Filter(enable ? uInt8(myFilter) | 0x10 : uInt8(myFilter) & 0x01);
// Normal vs NTSC mode uses different source widths uInt32 surfaceWidth = enable ?
myTiaSurface->setSrcSize(enable ? AtariNTSC::outWidth(TIAConstants::frameBufferWidth) AtariNTSC::outWidth(TIAConstants::frameBufferWidth) : TIAConstants::frameBufferWidth;
: TIAConstants::frameBufferWidth, myTIA->height());
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()); mySLineSurface->setSrcSize(1, 2 * myTIA->height());

View File

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

View File

@ -244,6 +244,8 @@ class TIA : public Device
*/ */
uInt8* frameBuffer() { return myFramebuffer.data(); } uInt8* frameBuffer() { return myFramebuffer.data(); }
void clearFrameBuffer();
/** /**
Answers dimensional info about the framebuffer. Answers dimensional info about the framebuffer.
*/ */
@ -260,6 +262,9 @@ class TIA : public Device
void setLayout(FrameLayout layout) { myFrameManager->setLayout(layout); } void setLayout(FrameLayout layout) { myFrameManager->setLayout(layout); }
FrameLayout frameLayout() const { return myFrameManager->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. 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 Int32 vcenter() const { return 0; }
virtual void setAdjustScanlines(Int32 adjustScanlines) {}
virtual Int32 adjustScanlines() const { return 0; }
/** /**
* The corresponding start line. * The corresponding start line.
*/ */

View File

@ -24,13 +24,12 @@
enum Metrics: uInt32 { enum Metrics: uInt32 {
vblankNTSC = 37, vblankNTSC = 37,
vblankPAL = 45, vblankPAL = 45,
kernelNTSC = 192,
kernelPAL = 228,
overscanNTSC = 30,
overscanPAL = 36,
vsync = 3, vsync = 3,
frameSizeNTSC = 262,
frameSizePAL = 312,
baseHeightNTSC = 240,
baseHeightPAL = 288,
maxLinesVsync = 50, maxLinesVsync = 50,
visibleOverscan = 20,
initialGarbageFrames = TIAConstants::initialGarbageFrames, initialGarbageFrames = TIAConstants::initialGarbageFrames,
ystartNTSC = 34, ystartNTSC = 34,
ystartPAL = 39 ystartPAL = 39
@ -40,8 +39,7 @@ enum Metrics: uInt32 {
FrameManager::FrameManager() FrameManager::FrameManager()
{ {
reset(); reset();
updateYStart(); recalculateMetrics();
onLayoutChange();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -118,7 +116,14 @@ void FrameManager::setVcenter(Int32 vcenter)
if (vcenter < TIAConstants::minVcenter || vcenter > TIAConstants::maxVcenter) return; if (vcenter < TIAConstants::minVcenter || vcenter > TIAConstants::maxVcenter) return;
myVcenter = vcenter; 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() void FrameManager::onLayoutChange()
{ {
switch (layout()) recalculateMetrics();
{
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;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -202,8 +188,6 @@ bool FrameManager::onSave(Serializer& out) const
out.putInt(myLastY); out.putInt(myLastY);
out.putInt(myVblankLines); out.putInt(myVblankLines);
out.putInt(myKernelLines);
out.putInt(myOverscanLines);
out.putInt(myFrameLines); out.putInt(myFrameLines);
out.putInt(myHeight); out.putInt(myHeight);
out.putInt(myYStart); out.putInt(myYStart);
@ -225,8 +209,6 @@ bool FrameManager::onLoad(Serializer& in)
myLastY = in.getInt(); myLastY = in.getInt();
myVblankLines = in.getInt(); myVblankLines = in.getInt();
myKernelLines = in.getInt();
myOverscanLines = in.getInt();
myFrameLines = in.getInt(); myFrameLines = in.getInt();
myHeight = in.getInt(); myHeight = in.getInt();
myYStart = in.getInt(); myYStart = in.getInt();
@ -237,7 +219,32 @@ bool FrameManager::onLoad(Serializer& in)
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameManager::updateYStart() { void FrameManager::recalculateMetrics() {
myYStart = (layout() == FrameLayout::ntsc ? Metrics::ystartNTSC : Metrics::ystartPAL) - myVcenter; 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); myJitterEmulation.setYStart(myYStart);
} }

View File

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

View File

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

View File

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

View File

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