mirror of https://github.com/stella-emu/stella.git
Hook up new ystart autodetection.
This commit is contained in:
parent
dc5c68bb80
commit
23c2901d14
|
@ -80,7 +80,8 @@ Console::Console(OSystem& osystem, unique_ptr<Cartridge>& cart,
|
||||||
myCart(std::move(cart)),
|
myCart(std::move(cart)),
|
||||||
myDisplayFormat(""), // Unknown TV format @ start
|
myDisplayFormat(""), // Unknown TV format @ start
|
||||||
myFramerate(0.0), // Unknown framerate @ start
|
myFramerate(0.0), // Unknown framerate @ start
|
||||||
myCurrentFormat(0), // Unknown format @ start
|
myCurrentFormat(0), // Unknown format @ start,
|
||||||
|
myAutodetectedYstart(0),
|
||||||
myUserPaletteDefined(false),
|
myUserPaletteDefined(false),
|
||||||
myConsoleTiming(ConsoleTiming::ntsc)
|
myConsoleTiming(ConsoleTiming::ntsc)
|
||||||
{
|
{
|
||||||
|
@ -120,43 +121,17 @@ Console::Console(OSystem& osystem, unique_ptr<Cartridge>& cart,
|
||||||
|
|
||||||
if(myDisplayFormat == "AUTO" || myOSystem.settings().getBool("rominfo"))
|
if(myDisplayFormat == "AUTO" || myOSystem.settings().getBool("rominfo"))
|
||||||
{
|
{
|
||||||
// Run the TIA, looking for PAL scanline patterns
|
autodetectFrameLayout();
|
||||||
// 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);
|
|
||||||
|
|
||||||
FrameLayoutDetector frameLayoutDetector;
|
|
||||||
myTIA->setFrameManager(&frameLayoutDetector);
|
|
||||||
mySystem->reset(true);
|
|
||||||
|
|
||||||
for(int i = 0; i < 60; ++i) myTIA->update();
|
|
||||||
|
|
||||||
myTIA->setFrameManager(myFrameManager.get());
|
|
||||||
|
|
||||||
myDisplayFormat = frameLayoutDetector.detectedLayout() == FrameLayout::pal ? "PAL" : "NTSC";
|
|
||||||
|
|
||||||
if(myProperties.get(Display_Format) == "AUTO")
|
if(myProperties.get(Display_Format) == "AUTO")
|
||||||
{
|
{
|
||||||
autodetected = "*";
|
autodetected = "*";
|
||||||
myCurrentFormat = 0;
|
myCurrentFormat = 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Don't forget to reset the SC progress bars again
|
if (atoi(myProperties.get(Display_YStart).c_str()) == 0) {
|
||||||
myOSystem.settings().setValue("fastscbios", fastscbios);
|
autodetectYStart();
|
||||||
|
|
||||||
// TODO: move! move! move! (temporary for testing)
|
|
||||||
YStartDetector ystartDetector;
|
|
||||||
ystartDetector.setLayout(frameLayoutDetector.detectedLayout());
|
|
||||||
myTIA->setFrameManager(&ystartDetector);
|
|
||||||
mySystem->reset();
|
|
||||||
|
|
||||||
for (int i = 0; i < 80; i++) myTIA->update();
|
|
||||||
|
|
||||||
myTIA->setFrameManager(myFrameManager.get());
|
|
||||||
|
|
||||||
(cout << "detected ystart value: " << ystartDetector.detectedYStart() << std::endl).flush();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
myConsoleInfo.DisplayFormat = myDisplayFormat + autodetected;
|
myConsoleInfo.DisplayFormat = myDisplayFormat + autodetected;
|
||||||
|
@ -232,6 +207,54 @@ Console::~Console()
|
||||||
myRightControl->close();
|
myRightControl->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void Console::autodetectFrameLayout()
|
||||||
|
{
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
FrameLayoutDetector frameLayoutDetector;
|
||||||
|
myTIA->setFrameManager(&frameLayoutDetector);
|
||||||
|
mySystem->reset(true);
|
||||||
|
|
||||||
|
for(int i = 0; i < 60; ++i) myTIA->update();
|
||||||
|
|
||||||
|
myTIA->setFrameManager(myFrameManager.get());
|
||||||
|
|
||||||
|
myDisplayFormat = frameLayoutDetector.detectedLayout() == FrameLayout::pal ? "PAL" : "NTSC";
|
||||||
|
|
||||||
|
// Don't forget to reset the SC progress bars again
|
||||||
|
myOSystem.settings().setValue("fastscbios", fastscbios);
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void Console::autodetectYStart()
|
||||||
|
{
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
YStartDetector ystartDetector;
|
||||||
|
ystartDetector.setLayout(myDisplayFormat == "PAL" ? FrameLayout::pal : FrameLayout::ntsc);
|
||||||
|
myTIA->setFrameManager(&ystartDetector);
|
||||||
|
mySystem->reset();
|
||||||
|
|
||||||
|
for (int i = 0; i < 80; i++) myTIA->update();
|
||||||
|
|
||||||
|
myTIA->setFrameManager(myFrameManager.get());
|
||||||
|
|
||||||
|
myAutodetectedYstart = ystartDetector.detectedYStart();
|
||||||
|
|
||||||
|
// Don't forget to reset the SC progress bars again
|
||||||
|
myOSystem.settings().setValue("fastscbios", fastscbios);
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool Console::save(Serializer& out) const
|
bool Console::save(Serializer& out) const
|
||||||
{
|
{
|
||||||
|
@ -593,11 +616,17 @@ void Console::changeYStart(int direction)
|
||||||
}
|
}
|
||||||
else if(direction == -1) // decrease YStart
|
else if(direction == -1) // decrease YStart
|
||||||
{
|
{
|
||||||
if(ystart == TIAConstants::minYStart-1)
|
if (ystart == TIAConstants::minYStart && myAutodetectedYstart == 0) {
|
||||||
|
myOSystem.frameBuffer().showMessage("Autodetected YStart not available");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ystart == TIAConstants::minYStart-1 && myAutodetectedYstart > 0)
|
||||||
{
|
{
|
||||||
myOSystem.frameBuffer().showMessage("YStart at minimum");
|
myOSystem.frameBuffer().showMessage("YStart at minimum");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ystart--;
|
ystart--;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -609,7 +638,7 @@ void Console::changeYStart(int direction)
|
||||||
myOSystem.frameBuffer().showMessage("YStart autodetected");
|
myOSystem.frameBuffer().showMessage("YStart autodetected");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(myTIA->ystartIsAuto(ystart))
|
if(myAutodetectedYstart > 0 && myAutodetectedYstart == ystart)
|
||||||
{
|
{
|
||||||
// We've reached the auto-detect value, so reset
|
// We've reached the auto-detect value, so reset
|
||||||
myOSystem.frameBuffer().showMessage("YStart " + val.str() + " (Auto)");
|
myOSystem.frameBuffer().showMessage("YStart " + val.str() + " (Auto)");
|
||||||
|
@ -688,7 +717,7 @@ void Console::setTIAProperties()
|
||||||
myTIA->setLayout(FrameLayout::pal);
|
myTIA->setLayout(FrameLayout::pal);
|
||||||
}
|
}
|
||||||
|
|
||||||
myTIA->setYStart(ystart);
|
myTIA->setYStart(ystart != 0 ? ystart : myAutodetectedYstart);
|
||||||
myTIA->setHeight(height);
|
myTIA->setHeight(height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -305,6 +305,16 @@ class Console : public Serializable
|
||||||
void toggleJitter() const;
|
void toggleJitter() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/**
|
||||||
|
* Dry-run the emulation and detect the frame layout (PAL / NTSC).
|
||||||
|
*/
|
||||||
|
void autodetectFrameLayout();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dryrun the emulation and detect ystart (the first visible scanline).
|
||||||
|
*/
|
||||||
|
void autodetectYStart();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Sets various properties of the TIA (YStart, Height, etc) based on
|
Sets various properties of the TIA (YStart, Height, etc) based on
|
||||||
the current display format.
|
the current display format.
|
||||||
|
@ -385,6 +395,9 @@ class Console : public Serializable
|
||||||
// Display format currently in use
|
// Display format currently in use
|
||||||
uInt32 myCurrentFormat;
|
uInt32 myCurrentFormat;
|
||||||
|
|
||||||
|
// Autodetected ystart.
|
||||||
|
uInt32 myAutodetectedYstart;
|
||||||
|
|
||||||
// Indicates whether an external palette was found and
|
// Indicates whether an external palette was found and
|
||||||
// successfully loaded
|
// successfully loaded
|
||||||
bool myUserPaletteDefined;
|
bool myUserPaletteDefined;
|
||||||
|
|
|
@ -206,7 +206,6 @@ class TIA : public Device
|
||||||
uInt32 width() const { return 160; }
|
uInt32 width() const { return 160; }
|
||||||
uInt32 height() const { return myFrameManager->height(); }
|
uInt32 height() const { return myFrameManager->height(); }
|
||||||
uInt32 ystart() const { return myFrameManager->ystart(); }
|
uInt32 ystart() const { return myFrameManager->ystart(); }
|
||||||
bool ystartIsAuto(uInt32 line) const { return myFrameManager->ystartIsAuto(line); }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Changes the current Height/YStart properties.
|
Changes the current Height/YStart properties.
|
||||||
|
|
|
@ -185,11 +185,6 @@ class AbstractFrameManager : public Serializable
|
||||||
*/
|
*/
|
||||||
virtual uInt32 ystart() const { return 0; }
|
virtual uInt32 ystart() const { return 0; }
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO: this looks pretty weird --- does this actually work?
|
|
||||||
*/
|
|
||||||
virtual bool ystartIsAuto(uInt32 line) const { return false; }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the frame layout. This may be a noop (on the autodetection manager).
|
* Set the frame layout. This may be a noop (on the autodetection manager).
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -57,9 +57,6 @@ void FrameManager::onReset()
|
||||||
myVsyncLines = 0;
|
myVsyncLines = 0;
|
||||||
myY = 0;
|
myY = 0;
|
||||||
myFramePending = false;
|
myFramePending = false;
|
||||||
myStabilizationFrames = 0;
|
|
||||||
myStableFrames = 0;
|
|
||||||
myHasStabilized = false;
|
|
||||||
|
|
||||||
myStableFrameLines = -1;
|
myStableFrameLines = -1;
|
||||||
myStableFrameHeightCountdown = 0;
|
myStableFrameHeightCountdown = 0;
|
||||||
|
@ -158,21 +155,6 @@ void FrameManager::setState(FrameManager::State state)
|
||||||
|
|
||||||
switch (myState) {
|
switch (myState) {
|
||||||
case State::waitForFrameStart:
|
case State::waitForFrameStart:
|
||||||
if (!myHasStabilized) {
|
|
||||||
myHasStabilized =
|
|
||||||
myStableFrames >= Metrics::minStableFrames ||
|
|
||||||
myStabilizationFrames >= Metrics::maxStabilizationFrames;
|
|
||||||
|
|
||||||
updateIsRendering();
|
|
||||||
|
|
||||||
myStabilizationFrames++;
|
|
||||||
|
|
||||||
if (myVblankManager.isStable())
|
|
||||||
myStableFrames++;
|
|
||||||
else
|
|
||||||
myStableFrames = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (myFramePending) finalizeFrame();
|
if (myFramePending) finalizeFrame();
|
||||||
notifyFrameStart();
|
notifyFrameStart();
|
||||||
|
|
||||||
|
@ -297,7 +279,7 @@ void FrameManager::enableJitter(bool enabled)
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void FrameManager::updateIsRendering() {
|
void FrameManager::updateIsRendering() {
|
||||||
myIsRendering = myState == State::frame && myHasStabilized;
|
myIsRendering = myState == State::frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -312,10 +294,6 @@ bool FrameManager::onSave(Serializer& out) const
|
||||||
out.putInt(myLastY);
|
out.putInt(myLastY);
|
||||||
out.putBool(myFramePending);
|
out.putBool(myFramePending);
|
||||||
|
|
||||||
out.putInt(myStableFrames);
|
|
||||||
out.putInt(myStabilizationFrames);
|
|
||||||
out.putBool(myHasStabilized);
|
|
||||||
|
|
||||||
out.putInt(myVblankLines);
|
out.putInt(myVblankLines);
|
||||||
out.putInt(myKernelLines);
|
out.putInt(myKernelLines);
|
||||||
out.putInt(myOverscanLines);
|
out.putInt(myOverscanLines);
|
||||||
|
@ -343,10 +321,6 @@ bool FrameManager::onLoad(Serializer& in)
|
||||||
myLastY = in.getInt();
|
myLastY = in.getInt();
|
||||||
myFramePending = in.getBool();
|
myFramePending = in.getBool();
|
||||||
|
|
||||||
myStableFrames = in.getInt();
|
|
||||||
myStabilizationFrames = in.getInt();
|
|
||||||
myHasStabilized = in.getBool();
|
|
||||||
|
|
||||||
myVblankLines = in.getInt();
|
myVblankLines = in.getInt();
|
||||||
myKernelLines = in.getInt();
|
myKernelLines = in.getInt();
|
||||||
myOverscanLines = in.getInt();
|
myOverscanLines = in.getInt();
|
||||||
|
|
|
@ -50,8 +50,6 @@ class FrameManager: public AbstractFrameManager {
|
||||||
|
|
||||||
uInt32 ystart() const override { return myVblankManager.ystart(); }
|
uInt32 ystart() const override { return myVblankManager.ystart(); }
|
||||||
|
|
||||||
bool ystartIsAuto(uInt32 line) const override { return myVblankManager.ystartIsAuto(line); };
|
|
||||||
|
|
||||||
void setLayout(FrameLayout mode) override { layout(mode); }
|
void setLayout(FrameLayout mode) override { layout(mode); }
|
||||||
|
|
||||||
void onSetVblank() override;
|
void onSetVblank() override;
|
||||||
|
@ -103,10 +101,6 @@ class FrameManager: public AbstractFrameManager {
|
||||||
uInt32 myY, myLastY;
|
uInt32 myY, myLastY;
|
||||||
bool myFramePending;
|
bool myFramePending;
|
||||||
|
|
||||||
uInt32 myStableFrames;
|
|
||||||
uInt32 myStabilizationFrames;
|
|
||||||
bool myHasStabilized;
|
|
||||||
|
|
||||||
uInt32 myVblankLines;
|
uInt32 myVblankLines;
|
||||||
uInt32 myKernelLines;
|
uInt32 myKernelLines;
|
||||||
uInt32 myOverscanLines;
|
uInt32 myOverscanLines;
|
||||||
|
|
Loading…
Reference in New Issue