1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-12-19 14:18:05 +00:00

Compare commits

...

13 Commits

Author SHA1 Message Date
Thomas Harte
33362298ec Merge pull request #1672 from TomHarte/QtLayouts
Minimise and normalise Qt tab layouts.
2025-12-18 22:14:55 -05:00
Thomas Harte
74f4b5e1a5 Add missing MSX colons. 2025-12-19 03:01:23 +00:00
Thomas Harte
f6066ddbc8 Minimise and normalise Qt tab layouts. 2025-12-18 21:49:47 -05:00
Thomas Harte
1f960bc864 Merge pull request #1671 from TomHarte/DynamicCropOption
Qt: add dynamic crop option, fix BBC startup.
2025-12-17 22:35:02 -05:00
Thomas Harte
df80ad77c5 Merge pull request #1670 from TomHarte/LoggerTypes
Avoid FILE * implicitly converting to bool.
2025-12-17 22:33:09 -05:00
Thomas Harte
67443f9287 Add dynamic cropping option, correct BBC startup. 2025-12-17 22:24:11 -05:00
Thomas Harte
f0394976cc Automate quick load/boot menu population. 2025-12-17 22:06:30 -05:00
Thomas Harte
69fd0b9dab Apply various rules for friendly naming. 2025-12-17 21:59:11 -05:00
Thomas Harte
959f26c195 Add limit on ZX Spectrum display outputs. 2025-12-17 21:44:52 -05:00
Thomas Harte
e4aea4781f Start trying to populate display menu programmatically. 2025-12-18 02:35:28 +00:00
Thomas Harte
3e37ef22ba Silence Xcode warnings. 2025-12-17 15:02:50 -05:00
Thomas Harte
89295b7b64 Tag stream as [[maybe_unused]]. 2025-12-17 15:02:10 -05:00
Thomas Harte
acf8dba51b Avoid FILE * implicitly converting to bool. 2025-12-17 15:00:40 -05:00
10 changed files with 772 additions and 1017 deletions

View File

@@ -47,6 +47,7 @@ struct Machine {
DeclareField(automatic_tape_motor_control);
declare_display_option();
declare_quickload_option();
limit_enum(&output, Configurable::Display::RGB, Configurable::Display::CompositeColour, -1);
}
};
};

View File

@@ -253,6 +253,7 @@ std::map<std::string, std::unique_ptr<Reflection::Struct>> Machine::AllOptionsBy
Emplace(AppleII, Apple::II::Machine);
Emplace(Archimedes, Archimedes::Machine);
Emplace(AtariST, Atari::ST::Machine);
Emplace(BBCMicro, BBCMicro::Machine);
Emplace(ColecoVision, Coleco::Vision::Machine);
Emplace(Electron, Electron::Machine);
Emplace(Enterprise, Enterprise::Machine);

View File

@@ -5714,7 +5714,7 @@
attributes = {
BuildIndependentTargetsInParallel = YES;
LastSwiftUpdateCheck = 0700;
LastUpgradeCheck = 2610;
LastUpgradeCheck = 2620;
ORGANIZATIONNAME = "Thomas Harte";
TargetAttributes = {
4B055A691FAE763F0060FFFF = {

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "2610"
LastUpgradeVersion = "2620"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -74,7 +74,7 @@
</CommandLineArgument>
<CommandLineArgument
argument = "--help"
isEnabled = "NO">
isEnabled = "YES">
</CommandLineArgument>
</CommandLineArguments>
</LaunchAction>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "2610"
LastUpgradeVersion = "2620"
version = "1.8">
<BuildAction
parallelizeBuildables = "YES"

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "2610"
LastUpgradeVersion = "2620"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View File

@@ -12,6 +12,7 @@
#include <QtWidgets>
#include <cstdio>
#include <memory>
#include "../../Numeric/CRC.hpp"
#include "../../Configurable/StandardOptions.hpp"
@@ -401,11 +402,74 @@ void MainWindow::launchMachine() {
// Add machine-specific UI.
const std::string settingsPrefix = Machine::ShortNameForTargetMachine(machineType);
switch(machineType) {
case Analyser::Machine::AmstradCPC:
addDisplayMenu(settingsPrefix, "Television", "", "", "Monitor");
break;
auto configurableMachine = machine->configurable_device();
if(configurableMachine) {
auto options = configurableMachine->get_options();
const auto allKeys = options->all_keys();
const auto allDisplayValues = options->values_for(Configurable::Options::DisplayOptionName);
const auto hasDynamicCrop = std::find(allKeys.begin(), allKeys.end(), Configurable::Options::DynamicCropOptionName) != allKeys.end();
if(hasDynamicCrop || allDisplayValues.size() > 1) {
const auto contains = [&](const Configurable::Display option) {
const auto name = Reflection::Enum::to_string<Configurable::Display>(option);
return std::find(allDisplayValues.begin(), allDisplayValues.end(), name) != allDisplayValues.end();
};
const bool hasCompositeColour = contains(Configurable::Display::CompositeColour);
const bool hasCompositeMonochrome = contains(Configurable::Display::CompositeMonochrome);
const bool hasSVideo = contains(Configurable::Display::SVideo);
const bool hasRGB = contains(Configurable::Display::RGB);
const bool differentiateComposite = hasCompositeColour && hasCompositeMonochrome;
const bool hasMultipleTelevisionConnections = hasSVideo && (hasCompositeColour || hasCompositeMonochrome);
const bool hasNonCompositeConnections = hasSVideo || hasRGB;
const auto compositeColourName = [&]() {
if(!hasNonCompositeConnections) {
return "Colour";
}
if(hasMultipleTelevisionConnections) {
return differentiateComposite ? "Colour Composite" : "Composite";
} else {
return differentiateComposite ? "Colour Television" : "Television";
}
};
const auto compositeMonochromeName = [&]() {
if(!hasNonCompositeConnections) {
return "Monochrome";
}
if(hasMultipleTelevisionConnections) {
return differentiateComposite ? "Monochrome Composite" : "Composite";
} else {
return differentiateComposite ? "Black and White Television" : "Television";
}
};
const auto rgbName = [&]() {
return hasMultipleTelevisionConnections ? "RGB" : "Monitor";
};
addDisplayMenu(
settingsPrefix,
hasCompositeColour ? compositeColourName() : "",
hasCompositeMonochrome ? compositeMonochromeName() : "",
hasSVideo ? "S-Video" : "",
hasRGB ? rgbName() : "",
hasDynamicCrop
);
}
// The ZX80 and ZX81 have a specialised version of this.
// It might become general later if I generalite automatic tape motor control, which I probably should.
if(machineType != Analyser::Machine::ZX8081) {
const auto hasQuickLoad = std::find(allKeys.begin(), allKeys.end(), Configurable::Options::QuickLoadOptionName) != allKeys.end();
const auto hasQuickBoot = std::find(allKeys.begin(), allKeys.end(), Configurable::Options::QuickBootOptionName) != allKeys.end();
addEnhancementsMenu(settingsPrefix, hasQuickLoad, hasQuickBoot);
}
}
switch(machineType) {
case Analyser::Machine::AppleII:
addAppleIIMenu();
break;
@@ -414,58 +478,10 @@ void MainWindow::launchMachine() {
addAtari2600Menu();
break;
case Analyser::Machine::Archimedes:
addEnhancementsMenu(settingsPrefix, true, false);
break;
case Analyser::Machine::AtariST:
addDisplayMenu(settingsPrefix, "Television", "", "", "Monitor");
break;
case Analyser::Machine::ColecoVision:
addDisplayMenu(settingsPrefix, "Composite", "", "S-Video", "");
break;
case Analyser::Machine::Electron:
addDisplayMenu(settingsPrefix, "Composite", "", "S-Video", "RGB");
addEnhancementsMenu(settingsPrefix, true, false);
break;
case Analyser::Machine::Enterprise:
addDisplayMenu(settingsPrefix, "Composite", "", "", "RGB");
break;
case Analyser::Machine::Macintosh:
addEnhancementsMenu(settingsPrefix, false, true);
break;
case Analyser::Machine::MasterSystem:
addDisplayMenu(settingsPrefix, "Composite", "", "S-Video", "SCART");
break;
case Analyser::Machine::MSX:
addDisplayMenu(settingsPrefix, "Composite", "", "S-Video", "SCART");
addEnhancementsMenu(settingsPrefix, true, false);
break;
case Analyser::Machine::Oric:
addDisplayMenu(settingsPrefix, "Composite", "", "", "SCART");
break;
case Analyser::Machine::Vic20:
addDisplayMenu(settingsPrefix, "Composite", "", "S-Video", "");
addEnhancementsMenu(settingsPrefix, true, false);
break;
case Analyser::Machine::ZX8081:
addZX8081Menu(settingsPrefix);
break;
case Analyser::Machine::ZXSpectrum:
addDisplayMenu(settingsPrefix, "Composite", "", "S-Video", "SCART");
addEnhancementsMenu(settingsPrefix, true, false);
break;
default: break;
}
@@ -476,7 +492,14 @@ void MainWindow::launchMachine() {
addActivityObserver();
}
void MainWindow::addDisplayMenu(const std::string &machinePrefix, const std::string &compositeColour, const std::string &compositeMono, const std::string &svideo, const std::string &rgb) {
void MainWindow::addDisplayMenu(
const std::string &machinePrefix,
const std::string &compositeColour,
const std::string &compositeMono,
const std::string &svideo,
const std::string &rgb,
const bool offerDynamicCrop
) {
// Create a display menu.
displayMenu = menuBar()->addMenu(tr("&Display"));
@@ -543,9 +566,37 @@ void MainWindow::addDisplayMenu(const std::string &machinePrefix, const std::str
machine->configurable_device()->set_options(options);
});
}
// Possibly add a dynamic crop selector.
if(offerDynamicCrop) {
displayMenu->addSeparator();
QAction *const action = new QAction(tr("Crop Dynamically"), this);
action->setCheckable(true);
displayMenu->addAction(action);
const auto dynamicCropSettingName = QString::fromStdString(machinePrefix + ".dynamicCrop");
if(settings.contains(dynamicCropSettingName)) {
const auto useDynamicCrop = settings.value(settingName).toBool();
action->setChecked(useDynamicCrop);
Reflection::set(*options, Configurable::Options::DynamicCropOptionName, useDynamicCrop);
}
connect(action, &QAction::toggled, this, [=, this] (const bool ticked) {
Settings settings;
settings.setValue(dynamicCropSettingName, ticked);
std::lock_guard lock_guard(machineMutex);
auto options = machine->configurable_device()->get_options();
Reflection::set(*options, Configurable::Options::DynamicCropOptionName, ticked);
machine->configurable_device()->set_options(options);
});
}
}
void MainWindow::addEnhancementsMenu(const std::string &machinePrefix, const bool offerQuickLoad, const bool offerQuickBoot) {
if(!offerQuickLoad && !offerQuickBoot) {
return;
}
enhancementsMenu = menuBar()->addMenu(tr("&Enhancements"));
addEnhancementsItems(machinePrefix, enhancementsMenu, offerQuickLoad, offerQuickBoot, false);
}
@@ -681,9 +732,6 @@ void MainWindow::toggleAtari2600Switch(const Atari2600Switch toggleSwitch) {
}
void MainWindow::addAppleIIMenu() {
// Add the standard display settings.
addDisplayMenu("appleII", "Colour", "Monochrome", "", "");
// Add an additional tick box, for square pixels.
QAction *const squarePixelsAction = new QAction(tr("Square Pixels"));
squarePixelsAction->setCheckable(true);

View File

@@ -127,7 +127,7 @@ class MainWindow : public QMainWindow, public Outputs::Speaker::Speaker::Delegat
void deleteMachine();
QMenu *displayMenu = nullptr;
void addDisplayMenu(const std::string &machinePrefix, const std::string &compositeColour, const std::string &compositeMono, const std::string &svideo, const std::string &rgb);
void addDisplayMenu(const std::string &machinePrefix, const std::string &compositeColour, const std::string &compositeMono, const std::string &svideo, const std::string &rgb, bool allowDynamicCrop);
QMenu *enhancementsMenu = nullptr;
QAction *automaticTapeControlAction = nullptr;

File diff suppressed because it is too large Load Diff

View File

@@ -16,7 +16,7 @@
#ifdef TARGET_QT
#include <QDebug>
namespace {
QDebug stream(const bool is_info) {
[[maybe_unused]] QDebug stream(const bool is_info) {
return (is_info ? qInfo() : qWarning()).noquote().nospace();
}
static constexpr char EndLine = 0;
@@ -24,7 +24,7 @@ static constexpr char EndLine = 0;
#else
#include <iostream>
namespace {
std::ostream &stream(const bool is_info) {
[[maybe_unused]] std::ostream &stream(const bool is_info) {
return is_info ? std::cout : std::cerr;
}
static constexpr char EndLine = '\n';
@@ -202,8 +202,7 @@ struct AccumulatingLog {
template <Source source>
struct LogLine<source, true>: private AccumulatingLog {
public:
explicit LogLine(bool is_info) noexcept :
is_info_(is_info) {}
explicit LogLine(const bool is_info) noexcept : is_info_(is_info) {}
~LogLine() {
if(output_ == accumulator_.last && source == accumulator_.source && is_info_ == accumulator_.is_info) {
@@ -262,7 +261,7 @@ private:
template <Source source>
struct LogLine<source, false> {
explicit LogLine(FILE *) noexcept {}
explicit LogLine(bool) noexcept {}
template <size_t size, typename... Args>
auto &append(const char (&)[size], Args...) { return *this; }
@@ -279,8 +278,8 @@ public:
static constexpr bool InfoEnabled = enabled_level(source) == EnabledLevel::ErrorsAndInfo;
static constexpr bool ErrorsEnabled = enabled_level(source) >= EnabledLevel::Errors;
static auto info() { return LogLine<source, InfoEnabled>(stdout); }
static auto error() { return LogLine<source, ErrorsEnabled>(stderr); }
static auto info() { return LogLine<source, InfoEnabled>(true); }
static auto error() { return LogLine<source, ErrorsEnabled>(false); }
};
}