mirror of https://github.com/stella-emu/stella.git
Ystart is sleeping with the fishes.
This commit is contained in:
parent
356f06598d
commit
ec35026329
|
@ -30,5 +30,4 @@ src/windows/Stella.vcxproj.user
|
||||||
src/**/*.psess
|
src/**/*.psess
|
||||||
src/**/*.vspx
|
src/**/*.vspx
|
||||||
src/**/**.pdb
|
src/**/**.pdb
|
||||||
|
Stella.xcscheme
|
||||||
|
|
||||||
|
|
|
@ -120,7 +120,7 @@ void TiaOutputWidget::handleMouseDown(int x, int y, MouseButton b, int clickCoun
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void TiaOutputWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
|
void TiaOutputWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
|
||||||
{
|
{
|
||||||
uInt32 ystart = instance().console().tia().ystart();
|
uInt32 startLine = instance().console().tia().startLine();
|
||||||
|
|
||||||
switch(cmd)
|
switch(cmd)
|
||||||
{
|
{
|
||||||
|
@ -131,7 +131,7 @@ void TiaOutputWidget::handleCommand(CommandSender* sender, int cmd, int data, in
|
||||||
if(rmb == "scanline")
|
if(rmb == "scanline")
|
||||||
{
|
{
|
||||||
ostringstream command;
|
ostringstream command;
|
||||||
int lines = myClickY + ystart - instance().console().tia().scanlines();
|
int lines = myClickY + startLine - instance().console().tia().scanlines();
|
||||||
|
|
||||||
if(lines < 0)
|
if(lines < 0)
|
||||||
lines += instance().console().tia().scanlinesLastFrame();
|
lines += instance().console().tia().scanlinesLastFrame();
|
||||||
|
@ -145,7 +145,7 @@ void TiaOutputWidget::handleCommand(CommandSender* sender, int cmd, int data, in
|
||||||
else if(rmb == "bp")
|
else if(rmb == "bp")
|
||||||
{
|
{
|
||||||
ostringstream command;
|
ostringstream command;
|
||||||
int scanline = myClickY + ystart;
|
int scanline = myClickY + startLine;
|
||||||
command << "breakif _scan==#" << scanline;
|
command << "breakif _scan==#" << scanline;
|
||||||
string message = instance().debugger().parser().run(command.str());
|
string message = instance().debugger().parser().run(command.str());
|
||||||
instance().frameBuffer().showMessage(message);
|
instance().frameBuffer().showMessage(message);
|
||||||
|
|
|
@ -249,13 +249,13 @@ void TiaZoomWidget::handleCommand(CommandSender* sender, int cmd, int data, int
|
||||||
{
|
{
|
||||||
case ContextMenu::kItemSelectedCmd:
|
case ContextMenu::kItemSelectedCmd:
|
||||||
{
|
{
|
||||||
uInt32 ystart = instance().console().tia().ystart();
|
uInt32 startLine = instance().console().tia().startLine();
|
||||||
const string& rmb = myMenu->getSelectedTag().toString();
|
const string& rmb = myMenu->getSelectedTag().toString();
|
||||||
|
|
||||||
if(rmb == "scanline")
|
if(rmb == "scanline")
|
||||||
{
|
{
|
||||||
ostringstream command;
|
ostringstream command;
|
||||||
int lines = myClickY / myZoomLevel + myOffY + ystart - instance().console().tia().scanlines();
|
int lines = myClickY / myZoomLevel + myOffY + startLine - instance().console().tia().scanlines();
|
||||||
|
|
||||||
if (lines < 0)
|
if (lines < 0)
|
||||||
lines += instance().console().tia().scanlinesLastFrame();
|
lines += instance().console().tia().scanlinesLastFrame();
|
||||||
|
@ -269,7 +269,7 @@ void TiaZoomWidget::handleCommand(CommandSender* sender, int cmd, int data, int
|
||||||
else if(rmb == "bp")
|
else if(rmb == "bp")
|
||||||
{
|
{
|
||||||
ostringstream command;
|
ostringstream command;
|
||||||
int scanline = myClickY / myZoomLevel + myOffY + ystart;
|
int scanline = myClickY / myZoomLevel + myOffY + startLine;
|
||||||
command << "breakif _scan==#" << scanline;
|
command << "breakif _scan==#" << scanline;
|
||||||
string message = instance().debugger().parser().run(command.str());
|
string message = instance().debugger().parser().run(command.str());
|
||||||
instance().frameBuffer().showMessage(message);
|
instance().frameBuffer().showMessage(message);
|
||||||
|
|
|
@ -60,7 +60,6 @@
|
||||||
#include "AudioSettings.hxx"
|
#include "AudioSettings.hxx"
|
||||||
#include "frame-manager/FrameManager.hxx"
|
#include "frame-manager/FrameManager.hxx"
|
||||||
#include "frame-manager/FrameLayoutDetector.hxx"
|
#include "frame-manager/FrameLayoutDetector.hxx"
|
||||||
#include "frame-manager/YStartDetector.hxx"
|
|
||||||
|
|
||||||
#ifdef CHEATCODE_SUPPORT
|
#ifdef CHEATCODE_SUPPORT
|
||||||
#include "CheatManager.hxx"
|
#include "CheatManager.hxx"
|
||||||
|
@ -71,10 +70,6 @@
|
||||||
|
|
||||||
#include "Console.hxx"
|
#include "Console.hxx"
|
||||||
|
|
||||||
namespace {
|
|
||||||
constexpr uInt8 YSTART_EXTRA = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
Console::Console(OSystem& osystem, unique_ptr<Cartridge>& cart,
|
Console::Console(OSystem& osystem, unique_ptr<Cartridge>& cart,
|
||||||
const Properties& props, AudioSettings& audioSettings)
|
const Properties& props, AudioSettings& audioSettings)
|
||||||
|
@ -84,8 +79,6 @@ 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
|
||||||
myCurrentFormat(0), // Unknown format @ start,
|
myCurrentFormat(0), // Unknown format @ start,
|
||||||
myAutodetectedYstart(0),
|
|
||||||
myYStartAutodetected(false),
|
|
||||||
myFormatAutodetected(false),
|
myFormatAutodetected(false),
|
||||||
myUserPaletteDefined(false),
|
myUserPaletteDefined(false),
|
||||||
myConsoleTiming(ConsoleTiming::ntsc),
|
myConsoleTiming(ConsoleTiming::ntsc),
|
||||||
|
@ -151,10 +144,6 @@ Console::Console(OSystem& osystem, unique_ptr<Cartridge>& cart,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (atoi(myProperties.get(PropType::Display_VCenter).c_str()) == 0) {
|
|
||||||
autodetectYStart();
|
|
||||||
}
|
|
||||||
|
|
||||||
myConsoleInfo.DisplayFormat = myDisplayFormat + autodetected;
|
myConsoleInfo.DisplayFormat = myDisplayFormat + autodetected;
|
||||||
|
|
||||||
// Set up the correct properties used when toggling format
|
// Set up the correct properties used when toggling format
|
||||||
|
@ -265,49 +254,6 @@ void Console::redetectFrameLayout()
|
||||||
save(s);
|
save(s);
|
||||||
|
|
||||||
autodetectFrameLayout(false);
|
autodetectFrameLayout(false);
|
||||||
if (myYStartAutodetected) autodetectYStart();
|
|
||||||
|
|
||||||
load(s);
|
|
||||||
initializeAudio();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void Console::autodetectYStart(bool reset)
|
|
||||||
{
|
|
||||||
// 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);
|
|
||||||
|
|
||||||
if (reset) {
|
|
||||||
mySystem->reset(true);
|
|
||||||
myRiot->update();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < 80; i++) myTIA->update();
|
|
||||||
|
|
||||||
myTIA->setFrameManager(myFrameManager.get());
|
|
||||||
|
|
||||||
myAutodetectedYstart = ystartDetector.detectedYStart() - YSTART_EXTRA;
|
|
||||||
|
|
||||||
// Don't forget to reset the SC progress bars again
|
|
||||||
myOSystem.settings().setValue("fastscbios", fastscbios);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void Console::redetectYStart()
|
|
||||||
{
|
|
||||||
Serializer s;
|
|
||||||
|
|
||||||
myOSystem.sound().close();
|
|
||||||
save(s);
|
|
||||||
|
|
||||||
autodetectYStart(false);
|
|
||||||
|
|
||||||
load(s);
|
load(s);
|
||||||
initializeAudio();
|
initializeAudio();
|
||||||
|
@ -696,75 +642,57 @@ void Console::fry() const
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void Console::changeVerticalCenter(int direction)
|
void Console::changeVerticalCenter(int direction)
|
||||||
{
|
{
|
||||||
uInt32 ystart = myTIA->ystart();
|
Int32 vcenter = myTIA->vcenter();
|
||||||
|
|
||||||
if(direction == +1) // increase YStart
|
if(direction == +1) // increase vcenter
|
||||||
{
|
{
|
||||||
if(ystart >= TIAConstants::maxYStart)
|
if(vcenter >= TIAConstants::maxVcenter)
|
||||||
{
|
{
|
||||||
myOSystem.frameBuffer().showMessage("V-Center at minimum");
|
myOSystem.frameBuffer().showMessage("V-Center at minimum");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
++ystart;
|
++vcenter;
|
||||||
myYStartAutodetected = false;
|
|
||||||
}
|
}
|
||||||
else if(direction == -1) // decrease YStart
|
else if(direction == -1) // decrease vcenter
|
||||||
{
|
{
|
||||||
if (ystart <= TIAConstants::minYStart)
|
if (vcenter <= TIAConstants::minVcenter)
|
||||||
{
|
{
|
||||||
myOSystem.frameBuffer().showMessage("V-Center at maximum");
|
myOSystem.frameBuffer().showMessage("V-Center at maximum");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
--ystart;
|
--vcenter;
|
||||||
myYStartAutodetected = false;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ostringstream ss;
|
ostringstream ss;
|
||||||
ss << ystart;
|
ss << vcenter;
|
||||||
|
|
||||||
myProperties.set(PropType::Display_VCenter, ss.str());
|
myProperties.set(PropType::Display_VCenter, ss.str());
|
||||||
if (ystart != myTIA->ystart()) myTIA->setYStart(ystart);
|
if (vcenter != myTIA->vcenter()) myTIA->setVcenter(vcenter);
|
||||||
|
|
||||||
// use vertical center instead of y-start for display
|
|
||||||
int vCenter = TIAConstants::defaultYStart - ystart;
|
|
||||||
ss.str("");
|
ss.str("");
|
||||||
ss << "V-Center " << vCenter;
|
ss << "V-Center " << vcenter;
|
||||||
|
|
||||||
myOSystem.frameBuffer().showMessage(ss.str());
|
myOSystem.frameBuffer().showMessage(ss.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void Console::updateYStart(uInt32 ystart)
|
void Console::updateVcenter(Int32 vcenter)
|
||||||
{
|
{
|
||||||
if (ystart > TIAConstants::maxYStart) return;
|
if (vcenter > TIAConstants::maxVcenter | vcenter < TIAConstants::minVcenter) return;
|
||||||
|
|
||||||
if (ystart == 0) {
|
if (vcenter != myTIA->vcenter()) myTIA->setVcenter(vcenter);
|
||||||
if (myYStartAutodetected) return;
|
|
||||||
|
|
||||||
redetectYStart();
|
|
||||||
myYStartAutodetected = true;
|
|
||||||
ystart = myAutodetectedYstart;
|
|
||||||
} else
|
|
||||||
myYStartAutodetected = false;
|
|
||||||
|
|
||||||
if (ystart != myTIA->ystart()) myTIA->setYStart(ystart);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void Console::setTIAProperties()
|
void Console::setTIAProperties()
|
||||||
{
|
{
|
||||||
// FIXME - ystart is probably disappearing soon, or at least autodetection is
|
Int32 vcenter = BSPF::clamp(
|
||||||
uInt32 ystart = atoi(myProperties.get(PropType::Display_VCenter).c_str());
|
static_cast<Int32>(atoi(myProperties.get(PropType::Display_VCenter).c_str())), TIAConstants::minVcenter, TIAConstants::maxVcenter
|
||||||
if(ystart != 0)
|
);
|
||||||
ystart = BSPF::clamp(ystart, 0u, TIAConstants::maxYStart);
|
|
||||||
else {
|
|
||||||
ystart = myAutodetectedYstart;
|
|
||||||
myYStartAutodetected = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(myDisplayFormat == "NTSC" || myDisplayFormat == "PAL60" ||
|
if(myDisplayFormat == "NTSC" || myDisplayFormat == "PAL60" ||
|
||||||
myDisplayFormat == "SECAM60")
|
myDisplayFormat == "SECAM60")
|
||||||
|
@ -778,7 +706,7 @@ void Console::setTIAProperties()
|
||||||
myTIA->setLayout(FrameLayout::pal);
|
myTIA->setLayout(FrameLayout::pal);
|
||||||
}
|
}
|
||||||
|
|
||||||
myTIA->setYStart(ystart);
|
myTIA->setVcenter(vcenter);
|
||||||
|
|
||||||
myEmulationTiming.updateFrameLayout(myTIA->frameLayout());
|
myEmulationTiming.updateFrameLayout(myTIA->frameLayout());
|
||||||
myEmulationTiming.updateConsoleTiming(myConsoleTiming);
|
myEmulationTiming.updateConsoleTiming(myConsoleTiming);
|
||||||
|
|
|
@ -306,9 +306,9 @@ class Console : public Serializable, public ConsoleIO
|
||||||
void toggleJitter() const;
|
void toggleJitter() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update yatart and run autodetection if necessary.
|
* Update vcenter
|
||||||
*/
|
*/
|
||||||
void updateYStart(uInt32 ystart);
|
void updateVcenter(Int32 vcenter);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
|
@ -316,23 +316,13 @@ class Console : public Serializable, public ConsoleIO
|
||||||
*/
|
*/
|
||||||
void autodetectFrameLayout(bool reset = true);
|
void autodetectFrameLayout(bool reset = true);
|
||||||
|
|
||||||
/**
|
|
||||||
* Dryrun the emulation and detect ystart (the first visible scanline).
|
|
||||||
*/
|
|
||||||
void autodetectYStart(bool reset = true);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rerun frame layout autodetection
|
* Rerun frame layout autodetection
|
||||||
*/
|
*/
|
||||||
void redetectFrameLayout();
|
void redetectFrameLayout();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rerun ystart autodetection.
|
Sets various properties of the TIA (vcenter, Height, etc) based on
|
||||||
*/
|
|
||||||
void redetectYStart();
|
|
||||||
|
|
||||||
/**
|
|
||||||
Sets various properties of the TIA (YStart, Height, etc) based on
|
|
||||||
the current display format.
|
the current display format.
|
||||||
*/
|
*/
|
||||||
void setTIAProperties();
|
void setTIAProperties();
|
||||||
|
@ -411,12 +401,6 @@ class Console : public Serializable, public ConsoleIO
|
||||||
// Display format currently in use
|
// Display format currently in use
|
||||||
uInt32 myCurrentFormat;
|
uInt32 myCurrentFormat;
|
||||||
|
|
||||||
// Autodetected ystart.
|
|
||||||
uInt32 myAutodetectedYstart;
|
|
||||||
|
|
||||||
// Is ystart currently autodetected?
|
|
||||||
bool myYStartAutodetected;
|
|
||||||
|
|
||||||
// Is the TV format autodetected?
|
// Is the TV format autodetected?
|
||||||
bool myFormatAutodetected;
|
bool myFormatAutodetected;
|
||||||
|
|
||||||
|
|
|
@ -587,7 +587,7 @@ unique_ptr<Console> OSystem::openConsole(const FilesystemNode& romfile, string&
|
||||||
CMDLINE_PROPS_UPDATE("rd", PropType::Console_RightDiff);
|
CMDLINE_PROPS_UPDATE("rd", PropType::Console_RightDiff);
|
||||||
CMDLINE_PROPS_UPDATE("tv", PropType::Console_TVType);
|
CMDLINE_PROPS_UPDATE("tv", PropType::Console_TVType);
|
||||||
CMDLINE_PROPS_UPDATE("format", PropType::Display_Format);
|
CMDLINE_PROPS_UPDATE("format", PropType::Display_Format);
|
||||||
CMDLINE_PROPS_UPDATE("ystart", PropType::Display_VCenter); // TODO (SA): change option
|
CMDLINE_PROPS_UPDATE("vcenter", PropType::Display_VCenter); // TODO (SA): change option
|
||||||
CMDLINE_PROPS_UPDATE("pp", PropType::Display_Phosphor);
|
CMDLINE_PROPS_UPDATE("pp", PropType::Display_Phosphor);
|
||||||
CMDLINE_PROPS_UPDATE("ppblend", PropType::Display_PPBlend);
|
CMDLINE_PROPS_UPDATE("ppblend", PropType::Display_PPBlend);
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,6 @@
|
||||||
#include "TIA.hxx"
|
#include "TIA.hxx"
|
||||||
#include "ConsoleTiming.hxx"
|
#include "ConsoleTiming.hxx"
|
||||||
#include "FrameManager.hxx"
|
#include "FrameManager.hxx"
|
||||||
#include "YStartDetector.hxx"
|
|
||||||
#include "FrameLayoutDetector.hxx"
|
#include "FrameLayoutDetector.hxx"
|
||||||
#include "EmulationTiming.hxx"
|
#include "EmulationTiming.hxx"
|
||||||
#include "ConsoleTiming.hxx"
|
#include "ConsoleTiming.hxx"
|
||||||
|
@ -159,20 +158,9 @@ bool ProfilingRunner::runOne(const ProfilingRun run)
|
||||||
|
|
||||||
(cout << endl).flush();
|
(cout << endl).flush();
|
||||||
|
|
||||||
YStartDetector ystartDetector;
|
|
||||||
tia.setFrameManager(&ystartDetector);
|
|
||||||
system.reset();
|
|
||||||
|
|
||||||
(cout << "detecting ystart... ").flush();
|
|
||||||
for (int i = 0; i < 80; i++) tia.update();
|
|
||||||
|
|
||||||
uInt32 yStart = ystartDetector.detectedYStart();
|
|
||||||
(cout << yStart << endl).flush();
|
|
||||||
|
|
||||||
FrameManager frameManager;
|
FrameManager frameManager;
|
||||||
tia.setFrameManager(&frameManager);
|
tia.setFrameManager(&frameManager);
|
||||||
tia.setLayout(frameLayout);
|
tia.setLayout(frameLayout);
|
||||||
tia.setYStart(yStart);
|
|
||||||
|
|
||||||
system.reset();
|
system.reset();
|
||||||
|
|
||||||
|
|
|
@ -553,7 +553,7 @@ void Settings::usage() const
|
||||||
<< " -bc <arg> Same as using both -lc and -rc\n"
|
<< " -bc <arg> Same as using both -lc and -rc\n"
|
||||||
<< " -cp <arg> Sets the 'Controller.SwapPaddles' property\n"
|
<< " -cp <arg> Sets the 'Controller.SwapPaddles' property\n"
|
||||||
<< " -format <arg> Sets the 'Display.Format' property\n"
|
<< " -format <arg> Sets the 'Display.Format' property\n"
|
||||||
<< " -ystart <arg> Sets the 'Display.YStart' property\n"
|
<< " -vcenter <arg> Sets the 'Display.vcenter' property\n"
|
||||||
<< " -pp <arg> Sets the 'Display.Phosphor' property\n"
|
<< " -pp <arg> Sets the 'Display.Phosphor' property\n"
|
||||||
<< " -ppblend <arg> Sets the 'Display.PPBlend' property\n"
|
<< " -ppblend <arg> Sets the 'Display.PPBlend' property\n"
|
||||||
<< endl
|
<< endl
|
||||||
|
|
|
@ -249,12 +249,13 @@ class TIA : public Device
|
||||||
*/
|
*/
|
||||||
uInt32 width() const { return TIAConstants::H_PIXEL; }
|
uInt32 width() const { return TIAConstants::H_PIXEL; }
|
||||||
uInt32 height() const { return myFrameManager->height(); }
|
uInt32 height() const { return myFrameManager->height(); }
|
||||||
uInt32 ystart() const { return myFrameManager->ystart(); }
|
Int32 vcenter() const { return myFrameManager->vcenter(); }
|
||||||
|
uInt32 startLine() const { return myFrameManager->startLine(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Changes the current YStart property.
|
Changes the current vcenter property.
|
||||||
*/
|
*/
|
||||||
void setYStart(uInt32 ystart) { myFrameManager->setYstart(ystart); }
|
void setVcenter(Int32 vcenter) { myFrameManager->setVcenter(vcenter); }
|
||||||
|
|
||||||
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(); }
|
||||||
|
|
|
@ -24,9 +24,8 @@ namespace TIAConstants {
|
||||||
|
|
||||||
static constexpr uInt32 frameBufferWidth = 160;
|
static constexpr uInt32 frameBufferWidth = 160;
|
||||||
static constexpr uInt32 frameBufferHeight = 320;
|
static constexpr uInt32 frameBufferHeight = 320;
|
||||||
static constexpr uInt32 defaultYStart = 34; // TODO: PAL-50 might need a different value here
|
static constexpr Int32 maxVcenter = 20; // limit to reasonable values
|
||||||
static constexpr uInt32 minYStart = defaultYStart - 15; // limit to reasonable values
|
static constexpr Int32 minVcenter = -20; // limit to reasonable values
|
||||||
static constexpr uInt32 maxYStart = defaultYStart + 15; // limit to reasonable values
|
|
||||||
static constexpr uInt32 viewableWidth = 320;
|
static constexpr uInt32 viewableWidth = 320;
|
||||||
static constexpr uInt32 viewableHeight = 240;
|
static constexpr uInt32 viewableHeight = 240;
|
||||||
static constexpr uInt32 initialGarbageFrames = 10;
|
static constexpr uInt32 initialGarbageFrames = 10;
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
#include "Serializable.hxx"
|
#include "Serializable.hxx"
|
||||||
#include "FrameLayout.hxx"
|
#include "FrameLayout.hxx"
|
||||||
|
#include "bspf.hxx"
|
||||||
|
|
||||||
class AbstractFrameManager : public Serializable
|
class AbstractFrameManager : public Serializable
|
||||||
{
|
{
|
||||||
|
@ -160,14 +161,19 @@ class AbstractFrameManager : public Serializable
|
||||||
virtual uInt32 scanlines() const { return 0; }
|
virtual uInt32 scanlines() const { return 0; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configure the ystart value.
|
* Configure the vcenter value.
|
||||||
*/
|
*/
|
||||||
virtual void setYstart(uInt32 ystart) {}
|
virtual void setVcenter(Int32 vcenter) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The configured ystart value.
|
* The configured vcenter value.
|
||||||
*/
|
*/
|
||||||
virtual uInt32 ystart() const { return 0; }
|
virtual Int32 vcenter() const { return 0; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The corresponding start line.
|
||||||
|
*/
|
||||||
|
virtual uInt32 startLine() const { return 0; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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).
|
||||||
|
|
|
@ -31,7 +31,9 @@ enum Metrics: uInt32 {
|
||||||
vsync = 3,
|
vsync = 3,
|
||||||
maxLinesVsync = 50,
|
maxLinesVsync = 50,
|
||||||
visibleOverscan = 20,
|
visibleOverscan = 20,
|
||||||
initialGarbageFrames = TIAConstants::initialGarbageFrames
|
initialGarbageFrames = TIAConstants::initialGarbageFrames,
|
||||||
|
ystartNTSC = 34,
|
||||||
|
ystartPAL = 39
|
||||||
};
|
};
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -46,9 +48,11 @@ FrameManager::FrameManager()
|
||||||
myFrameLines(0),
|
myFrameLines(0),
|
||||||
myHeight(0),
|
myHeight(0),
|
||||||
myYStart(0),
|
myYStart(0),
|
||||||
|
myVcenter(0),
|
||||||
myJitterEnabled(false)
|
myJitterEnabled(false)
|
||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
|
updateYStart();
|
||||||
onLayoutChange();
|
onLayoutChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,7 +102,7 @@ void FrameManager::onNextLine()
|
||||||
case State::frame:
|
case State::frame:
|
||||||
if (myLineInState >= myHeight)
|
if (myLineInState >= myHeight)
|
||||||
{
|
{
|
||||||
myLastY = ystart() + myY; // Last line drawn in this frame
|
myLastY = myYStart + myY; // Last line drawn in this frame
|
||||||
setState(State::waitForVsyncStart);
|
setState(State::waitForVsyncStart);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -121,10 +125,10 @@ Int32 FrameManager::missingScanlines() const
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void FrameManager::setYstart(uInt32 ystart)
|
void FrameManager::setVcenter(Int32 vcenter)
|
||||||
{
|
{
|
||||||
myYStart = ystart;
|
myVcenter = vcenter;
|
||||||
myJitterEmulation.setYStart(ystart);
|
updateYStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -241,3 +245,9 @@ bool FrameManager::onLoad(Serializer& in)
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void FrameManager::updateYStart() {
|
||||||
|
myYStart = (layout() == FrameLayout::ntsc ? Metrics::ystartNTSC : Metrics::ystartPAL) - myVcenter;
|
||||||
|
myJitterEmulation.setYStart(myYStart);
|
||||||
|
}
|
||||||
|
|
|
@ -44,9 +44,11 @@ class FrameManager: public AbstractFrameManager {
|
||||||
|
|
||||||
Int32 missingScanlines() const override;
|
Int32 missingScanlines() const override;
|
||||||
|
|
||||||
void setYstart(uInt32 ystart) override;
|
void setVcenter(Int32 vcenter) override;
|
||||||
|
|
||||||
uInt32 ystart() const override { return myYStart; }
|
Int32 vcenter() const override { return myVcenter; }
|
||||||
|
|
||||||
|
uInt32 startLine() const override { return myYStart; }
|
||||||
|
|
||||||
void setLayout(FrameLayout mode) override { layout(mode); }
|
void setLayout(FrameLayout mode) override { layout(mode); }
|
||||||
|
|
||||||
|
@ -77,6 +79,8 @@ class FrameManager: public AbstractFrameManager {
|
||||||
|
|
||||||
void updateIsRendering();
|
void updateIsRendering();
|
||||||
|
|
||||||
|
void updateYStart();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
State myState;
|
State myState;
|
||||||
|
@ -90,6 +94,7 @@ class FrameManager: public AbstractFrameManager {
|
||||||
uInt32 myFrameLines;
|
uInt32 myFrameLines;
|
||||||
uInt32 myHeight;
|
uInt32 myHeight;
|
||||||
uInt32 myYStart;
|
uInt32 myYStart;
|
||||||
|
Int32 myVcenter;
|
||||||
|
|
||||||
bool myJitterEnabled;
|
bool myJitterEnabled;
|
||||||
|
|
||||||
|
|
|
@ -1,230 +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-2019 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.
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
#include "YStartDetector.hxx"
|
|
||||||
#include "TIAConstants.hxx"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Misc. numeric constants used in the algorithm.
|
|
||||||
*/
|
|
||||||
enum Metrics: uInt32 {
|
|
||||||
// ideal world frame sizes
|
|
||||||
frameLinesNTSC = 262,
|
|
||||||
frameLinesPAL = 312,
|
|
||||||
|
|
||||||
// the ideal vblank zone
|
|
||||||
vblankNTSC = 37,
|
|
||||||
vblankPAL = 45,
|
|
||||||
|
|
||||||
// number of scanlines to wait for vsync to start (exceeding after the ideal frame size) and stop
|
|
||||||
waitForVsync = 50,
|
|
||||||
|
|
||||||
// max lines underscan
|
|
||||||
maxUnderscan = 10,
|
|
||||||
|
|
||||||
// max lines deviations from detected ystart before we switch back to floating
|
|
||||||
maxVblankViolations = 2,
|
|
||||||
|
|
||||||
// switch to fixed mode after this number of stable frames (+1)
|
|
||||||
minStableVblankFrames = 1,
|
|
||||||
|
|
||||||
// no transitions to fixed mode will happend during those
|
|
||||||
initialGarbageFrames = TIAConstants::initialGarbageFrames
|
|
||||||
};
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
YStartDetector::YStartDetector()
|
|
||||||
: myState(State::waitForVsyncStart),
|
|
||||||
myVblankMode(VblankMode::floating),
|
|
||||||
myLinesWaitingForVsyncToStart(0),
|
|
||||||
myCurrentVblankLines(0),
|
|
||||||
myLastVblankLines(0),
|
|
||||||
myVblankViolations(0),
|
|
||||||
myStableVblankFrames(0),
|
|
||||||
myVblankViolated(false)
|
|
||||||
{
|
|
||||||
reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt32 YStartDetector::detectedYStart() const
|
|
||||||
{
|
|
||||||
return myLastVblankLines;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void YStartDetector::onReset()
|
|
||||||
{
|
|
||||||
myState = State::waitForVsyncStart;
|
|
||||||
myVblankMode = VblankMode::floating;
|
|
||||||
myLinesWaitingForVsyncToStart = 0;
|
|
||||||
myCurrentVblankLines = 0;
|
|
||||||
myLastVblankLines = 0;
|
|
||||||
myVblankViolations = 0;
|
|
||||||
myStableVblankFrames = 0;
|
|
||||||
myVblankViolated = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void YStartDetector::onSetVsync()
|
|
||||||
{
|
|
||||||
if (myVsync)
|
|
||||||
setState(State::waitForVsyncEnd);
|
|
||||||
else
|
|
||||||
setState(State::waitForFrameStart);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void YStartDetector::onNextLine()
|
|
||||||
{
|
|
||||||
const uInt32 frameLines = layout() == FrameLayout::ntsc ? Metrics::frameLinesNTSC : Metrics::frameLinesPAL;
|
|
||||||
|
|
||||||
switch (myState) {
|
|
||||||
case State::waitForVsyncStart:
|
|
||||||
// We start counting the number of "lines spent while waiting for vsync start" from
|
|
||||||
// the "ideal" frame size (corrected by the three scanlines spent in vsync).
|
|
||||||
if (myCurrentFrameTotalLines > frameLines - 3 || myTotalFrames == 0)
|
|
||||||
++myLinesWaitingForVsyncToStart;
|
|
||||||
|
|
||||||
if (myLinesWaitingForVsyncToStart > Metrics::waitForVsync) setState(State::waitForVsyncEnd);
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case State::waitForVsyncEnd:
|
|
||||||
if (++myLinesWaitingForVsyncToStart > Metrics::waitForVsync) setState(State::waitForFrameStart);
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case State::waitForFrameStart:
|
|
||||||
if (shouldTransitionToFrame()) setState(State::waitForVsyncStart);
|
|
||||||
else ++myCurrentVblankLines;
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw runtime_error("cannot happen");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
bool YStartDetector::shouldTransitionToFrame()
|
|
||||||
{
|
|
||||||
uInt32 vblankLines = layout() == FrameLayout::pal ? Metrics::vblankPAL : Metrics::vblankNTSC;
|
|
||||||
|
|
||||||
// Are we free to transition as per vblank cycle?
|
|
||||||
bool shouldTransition = myCurrentVblankLines + 1 >= (myVblank ? vblankLines : vblankLines - Metrics::maxUnderscan);
|
|
||||||
|
|
||||||
// Do we **actually** transition? This depends on what mode we are in.
|
|
||||||
bool transition = false;
|
|
||||||
|
|
||||||
switch (myVblankMode) {
|
|
||||||
// Floating mode: we still are looking for a stable frame start
|
|
||||||
case VblankMode::floating:
|
|
||||||
|
|
||||||
// Are we free to transition?
|
|
||||||
if (shouldTransition) {
|
|
||||||
// Is this same scanline in which the transition ocurred last frame?
|
|
||||||
if (myTotalFrames > Metrics::initialGarbageFrames && myCurrentVblankLines == myLastVblankLines)
|
|
||||||
// Yes? -> Increase the number of stable frames
|
|
||||||
++myStableVblankFrames;
|
|
||||||
else
|
|
||||||
// No? -> Frame start shifted again, set the number of consecutive stable frames to zero
|
|
||||||
myStableVblankFrames = 0;
|
|
||||||
|
|
||||||
// Save the transition point for checking on it next frame
|
|
||||||
myLastVblankLines = myCurrentVblankLines;
|
|
||||||
|
|
||||||
// In floating mode, we transition whenever we can.
|
|
||||||
transition = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transition to locked mode if we saw enough stable frames in a row.
|
|
||||||
if (myStableVblankFrames >= Metrics::minStableVblankFrames) {
|
|
||||||
myVblankMode = VblankMode::locked;
|
|
||||||
myVblankViolations = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Locked mode: always transition at the same point, but check whether this is actually the
|
|
||||||
// detected transition point and revert state if applicable
|
|
||||||
case VblankMode::locked:
|
|
||||||
|
|
||||||
// Have we reached the transition point?
|
|
||||||
if (myCurrentVblankLines == myLastVblankLines) {
|
|
||||||
|
|
||||||
// Are we free to transition per the algorithm and didn't observe an violation before?
|
|
||||||
// (aka did the algorithm tell us to transition before reaching the actual line)
|
|
||||||
if (shouldTransition && !myVblankViolated)
|
|
||||||
// Reset the number of irregular frames (if any)
|
|
||||||
myVblankViolations = 0;
|
|
||||||
else {
|
|
||||||
// Record a violation if it wasn't recorded before
|
|
||||||
if (!myVblankViolated) ++myVblankViolations;
|
|
||||||
myVblankViolated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// transition
|
|
||||||
transition = true;
|
|
||||||
// The algorithm tells us to transition although we haven't reached the trip line before
|
|
||||||
} else if (shouldTransition) {
|
|
||||||
// Record a violation if it wasn't recorded before
|
|
||||||
if (!myVblankViolated) ++myVblankViolations;
|
|
||||||
myVblankViolated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Revert to floating mode if there were too many irregular frames in a row
|
|
||||||
if (myVblankViolations > Metrics::maxVblankViolations) {
|
|
||||||
myVblankMode = VblankMode::floating;
|
|
||||||
myStableVblankFrames = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw runtime_error("cannot happen");
|
|
||||||
}
|
|
||||||
|
|
||||||
return transition;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void YStartDetector::setState(State state)
|
|
||||||
{
|
|
||||||
if (state == myState) return;
|
|
||||||
|
|
||||||
myState = state;
|
|
||||||
myLinesWaitingForVsyncToStart = 0;
|
|
||||||
|
|
||||||
switch (state) {
|
|
||||||
case State::waitForVsyncEnd:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case State::waitForVsyncStart:
|
|
||||||
notifyFrameComplete();
|
|
||||||
notifyFrameStart();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case State::waitForFrameStart:
|
|
||||||
myVblankViolated = false;
|
|
||||||
myCurrentVblankLines = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw new runtime_error("cannot happen");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,155 +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-2019 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.
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
#ifndef TIA_YSTART_DETECTOR
|
|
||||||
#define TIA_YSTART_DETECTOR
|
|
||||||
|
|
||||||
#include "AbstractFrameManager.hxx"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This frame manager detects ystart from the first line with vblank = off.
|
|
||||||
*/
|
|
||||||
|
|
||||||
class YStartDetector: public AbstractFrameManager {
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
YStartDetector();
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Getter for the detected ystart value
|
|
||||||
*/
|
|
||||||
uInt32 detectedYStart() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* We require frame layout to be set from outside.
|
|
||||||
*/
|
|
||||||
void setLayout(FrameLayout layout) override { this->layout(layout); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* We need to track vsync changes.
|
|
||||||
*/
|
|
||||||
void onSetVsync() override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reset hook.
|
|
||||||
*/
|
|
||||||
void onReset() override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The workhorse.
|
|
||||||
*/
|
|
||||||
void onNextLine() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Our various states.
|
|
||||||
*/
|
|
||||||
enum class State {
|
|
||||||
// Wait for vsync on
|
|
||||||
waitForVsyncStart,
|
|
||||||
|
|
||||||
// Wait for vsync off
|
|
||||||
waitForVsyncEnd,
|
|
||||||
|
|
||||||
// Wait for the visible frame to start
|
|
||||||
waitForFrameStart
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Have we settled on a frame start?
|
|
||||||
*/
|
|
||||||
enum class VblankMode {
|
|
||||||
// We have settled on a frame start and have some hysteresis before we return to floating
|
|
||||||
locked,
|
|
||||||
|
|
||||||
// We are actively looking for the frame to start
|
|
||||||
floating
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Side effects for state transitions.
|
|
||||||
*/
|
|
||||||
void setState(State state);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform detection and decide whether the frame starts now.
|
|
||||||
*/
|
|
||||||
bool shouldTransitionToFrame();
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* State.
|
|
||||||
*/
|
|
||||||
State myState;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* locked / floating
|
|
||||||
*/
|
|
||||||
VblankMode myVblankMode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Counts the scanlines that we wait for vsync to start.
|
|
||||||
*/
|
|
||||||
uInt32 myLinesWaitingForVsyncToStart;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The number of lines we are currently waiting for the frame to start (and vblank to end).
|
|
||||||
*/
|
|
||||||
uInt32 myCurrentVblankLines;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The number of vblank lines on the last frame.
|
|
||||||
*/
|
|
||||||
uInt32 myLastVblankLines;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Count "vblank violations" in fixed mode (the number of consecutive frames where ystart
|
|
||||||
* differs from the previously detected value). Once a trip point is reached, we transition
|
|
||||||
* back to floating mode.
|
|
||||||
*/
|
|
||||||
uInt32 myVblankViolations;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The number of frames in floating mode with stable ystart. Once a trip point is reacted,
|
|
||||||
* we transition to fixed mode
|
|
||||||
*/
|
|
||||||
uInt32 myStableVblankFrames;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tracks deviations from the determined ystart value during a fixed mode frame in order to
|
|
||||||
* avoid double counting.
|
|
||||||
*/
|
|
||||||
bool myVblankViolated;
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
YStartDetector(const YStartDetector&) = delete;
|
|
||||||
YStartDetector(YStartDetector&&) = delete;
|
|
||||||
YStartDetector& operator=(const YStartDetector&) = delete;
|
|
||||||
YStartDetector& operator=(YStartDetector&&) = delete;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // TIA_YSTART_DETECTOR
|
|
|
@ -4,7 +4,6 @@ MODULE_OBJS := \
|
||||||
src/emucore/tia/frame-manager/FrameManager.o \
|
src/emucore/tia/frame-manager/FrameManager.o \
|
||||||
src/emucore/tia/frame-manager/AbstractFrameManager.o \
|
src/emucore/tia/frame-manager/AbstractFrameManager.o \
|
||||||
src/emucore/tia/frame-manager/FrameLayoutDetector.o \
|
src/emucore/tia/frame-manager/FrameLayoutDetector.o \
|
||||||
src/emucore/tia/frame-manager/YStartDetector.o \
|
|
||||||
src/emucore/tia/frame-manager/JitterEmulation.o
|
src/emucore/tia/frame-manager/JitterEmulation.o
|
||||||
|
|
||||||
MODULE_DIRS += \
|
MODULE_DIRS += \
|
||||||
|
|
|
@ -138,9 +138,9 @@ GameInfoDialog::GameInfoDialog(
|
||||||
t = new StaticTextWidget(myTab, font, HBORDER, ypos + 1, "V-Center ");
|
t = new StaticTextWidget(myTab, font, HBORDER, ypos + 1, "V-Center ");
|
||||||
myVCenter = new SliderWidget(myTab, font, t->getRight() + 2, ypos,
|
myVCenter = new SliderWidget(myTab, font, t->getRight() + 2, ypos,
|
||||||
"", 0, kVCenterChanged, 7 * fontWidth, "px");
|
"", 0, kVCenterChanged, 7 * fontWidth, "px");
|
||||||
// TODO (SA):check relationship of ystart and vcenter
|
|
||||||
myVCenter->setMinValue(TIAConstants::minYStart - TIAConstants::defaultYStart);
|
myVCenter->setMinValue(TIAConstants::minVcenter);
|
||||||
myVCenter->setMaxValue(TIAConstants::maxYStart - TIAConstants::defaultYStart);
|
myVCenter->setMaxValue(TIAConstants::maxVcenter);
|
||||||
myVCenter->setTickmarkIntervals(4);
|
myVCenter->setTickmarkIntervals(4);
|
||||||
wid.push_back(myVCenter);
|
wid.push_back(myVCenter);
|
||||||
|
|
||||||
|
@ -458,20 +458,10 @@ void GameInfoDialog::loadEmulationProperties(const Properties& props)
|
||||||
myPPBlend->setValue(atoi(blend.c_str()));
|
myPPBlend->setValue(atoi(blend.c_str()));
|
||||||
|
|
||||||
// set vertical center
|
// set vertical center
|
||||||
int vCenter = atoi(props.get(PropType::Display_VCenter).c_str());
|
Int32 vcenter = atoi(props.get(PropType::Display_VCenter).c_str());
|
||||||
if (vCenter)
|
myVCenter->setValueLabel(vcenter);
|
||||||
{
|
myVCenter->setValue(vcenter);
|
||||||
// convert y-start into v-center
|
myVCenter->setValueUnit(vcenter ? "px" : "");
|
||||||
// TODO (SA): fix this
|
|
||||||
vCenter = TIAConstants::defaultYStart - vCenter;
|
|
||||||
myVCenter->setValueLabel(vCenter);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
myVCenter->setValueLabel("default");
|
|
||||||
}
|
|
||||||
myVCenter->setValue(vCenter);
|
|
||||||
myVCenter->setValueUnit(vCenter ? "px" : "");
|
|
||||||
|
|
||||||
mySound->setState(props.get(PropType::Cart_Sound) == "STEREO");
|
mySound->setState(props.get(PropType::Cart_Sound) == "STEREO");
|
||||||
// if stereo is always enabled, disable game specific stereo setting
|
// if stereo is always enabled, disable game specific stereo setting
|
||||||
|
@ -548,11 +538,9 @@ void GameInfoDialog::saveConfig()
|
||||||
myGameProperties.set(PropType::Display_Phosphor, myPhosphor->getState() ? "YES" : "NO");
|
myGameProperties.set(PropType::Display_Phosphor, myPhosphor->getState() ? "YES" : "NO");
|
||||||
myGameProperties.set(PropType::Display_PPBlend, myPPBlend->getValueLabel() == "Off" ? "0" :
|
myGameProperties.set(PropType::Display_PPBlend, myPPBlend->getValueLabel() == "Off" ? "0" :
|
||||||
myPPBlend->getValueLabel());
|
myPPBlend->getValueLabel());
|
||||||
int vCenter = myVCenter->getValue();
|
Int32 vcenter = myVCenter->getValue();
|
||||||
if (vCenter)
|
|
||||||
// convert v-center into y-start TODO (SA): fix this
|
myGameProperties.set(PropType::Display_VCenter, std::to_string(vcenter));
|
||||||
vCenter = TIAConstants::defaultYStart - vCenter;
|
|
||||||
myGameProperties.set(PropType::Display_VCenter, std::to_string(vCenter));
|
|
||||||
myGameProperties.set(PropType::Cart_Sound, mySound->getState() ? "STEREO" : "MONO");
|
myGameProperties.set(PropType::Cart_Sound, mySound->getState() ? "STEREO" : "MONO");
|
||||||
|
|
||||||
// Console properties
|
// Console properties
|
||||||
|
@ -595,7 +583,7 @@ void GameInfoDialog::saveConfig()
|
||||||
// update 'Emulation' tab settings immediately
|
// update 'Emulation' tab settings immediately
|
||||||
instance().console().setFormat(myFormat->getSelected());
|
instance().console().setFormat(myFormat->getSelected());
|
||||||
instance().frameBuffer().tiaSurface().enablePhosphor(myPhosphor->getState(), myPPBlend->getValue());
|
instance().frameBuffer().tiaSurface().enablePhosphor(myPhosphor->getState(), myPPBlend->getValue());
|
||||||
instance().console().updateYStart(vCenter);
|
instance().console().updateVcenter(vcenter);
|
||||||
instance().console().initializeAudio();
|
instance().console().initializeAudio();
|
||||||
|
|
||||||
// update 'Console' tab settings immediately
|
// update 'Console' tab settings immediately
|
||||||
|
|
Loading…
Reference in New Issue