mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-24 17:32:55 +00:00
Edges further towards providing enough information for dynamic user-provided machine creation.
This commit is contained in:
parent
880bed04f5
commit
fc3d3c76f8
@ -26,19 +26,19 @@
|
||||
#include "../../Analyser/Static/Acorn/Target.hpp"
|
||||
#include "../../Analyser/Static/AmstradCPC/Target.hpp"
|
||||
#include "../../Analyser/Static/AppleII/Target.hpp"
|
||||
#include "../../Analyser/Static/Atari2600/Target.hpp"
|
||||
#include "../../Analyser/Static/AtariST/Target.hpp"
|
||||
#include "../../Analyser/Static/Commodore/Target.hpp"
|
||||
#include "../../Analyser/Static/Macintosh/Target.hpp"
|
||||
#include "../../Analyser/Static/MSX/Target.hpp"
|
||||
#include "../../Analyser/Static/Oric/Target.hpp"
|
||||
#include "../../Analyser/Static/Sega/Target.hpp"
|
||||
#include "../../Analyser/Static/ZX8081/Target.hpp"
|
||||
|
||||
#include "../../Analyser/Dynamic/MultiMachine/MultiMachine.hpp"
|
||||
#include "TypedDynamicMachine.hpp"
|
||||
|
||||
namespace {
|
||||
|
||||
::Machine::DynamicMachine *MachineForTarget(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher, Machine::Error &error) {
|
||||
Machine::DynamicMachine *Machine::MachineForTarget(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher, Machine::Error &error) {
|
||||
error = Machine::Error::None;
|
||||
|
||||
Machine::DynamicMachine *machine = nullptr;
|
||||
@ -78,9 +78,7 @@ namespace {
|
||||
return machine;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
::Machine::DynamicMachine *::Machine::MachineForTargets(const Analyser::Static::TargetList &targets, const ROMMachine::ROMFetcher &rom_fetcher, Error &error) {
|
||||
Machine::DynamicMachine *Machine::MachineForTargets(const Analyser::Static::TargetList &targets, const ROMMachine::ROMFetcher &rom_fetcher, Error &error) {
|
||||
// Zero targets implies no machine.
|
||||
if(targets.empty()) {
|
||||
error = Error::NoTargets;
|
||||
@ -193,8 +191,8 @@ std::map<std::string, std::vector<std::unique_ptr<Configurable::Option>>> Machin
|
||||
return options;
|
||||
}
|
||||
|
||||
std::map<std::string, std::unique_ptr<Reflection::Struct>> Machine::ConstructionOptionsByMachineName() {
|
||||
std::map<std::string, std::unique_ptr<Reflection::Struct>> options;
|
||||
std::map<std::string, std::unique_ptr<Analyser::Static::Target>> Machine::TargetsByMachineName(bool meaningful_without_media_only) {
|
||||
std::map<std::string, std::unique_ptr<Analyser::Static::Target>> options;
|
||||
|
||||
#define AddMapped(Name, TargetNamespace) \
|
||||
options.emplace(std::make_pair(LongNameForTargetMachine(Analyser::Machine::Name), new Analyser::Static::TargetNamespace::Target));
|
||||
@ -210,6 +208,12 @@ std::map<std::string, std::unique_ptr<Reflection::Struct>> Machine::Construction
|
||||
AddMapped(Vic20, Commodore);
|
||||
Add(ZX8081);
|
||||
|
||||
if(!meaningful_without_media_only) {
|
||||
Add(Atari2600);
|
||||
options.emplace(std::make_pair(LongNameForTargetMachine(Analyser::Machine::ColecoVision), new Analyser::Static::Target(Analyser::Machine::ColecoVision)));
|
||||
AddMapped(MasterSystem, Sega);
|
||||
}
|
||||
|
||||
#undef Add
|
||||
#undef AddTwo
|
||||
|
||||
|
@ -19,6 +19,8 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
/*!
|
||||
*/
|
||||
namespace Machine {
|
||||
|
||||
enum class Error {
|
||||
@ -36,6 +38,12 @@ enum class Error {
|
||||
*/
|
||||
DynamicMachine *MachineForTargets(const Analyser::Static::TargetList &targets, const ::ROMMachine::ROMFetcher &rom_fetcher, Error &error);
|
||||
|
||||
/*!
|
||||
Allocates an instance of DynamicMaachine holding the machine described
|
||||
by @c target. It is the caller's responsibility to delete the class when finished.
|
||||
*/
|
||||
DynamicMachine *MachineForTarget(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher, Machine::Error &error);
|
||||
|
||||
/*!
|
||||
Returns a short string name for the machine identified by the target,
|
||||
which is guaranteed not to have any spaces or other potentially
|
||||
@ -55,12 +63,17 @@ std::string LongNameForTargetMachine(const Analyser::Machine target);
|
||||
std::vector<std::string> AllMachines(bool meaningful_without_media_only, bool long_names);
|
||||
|
||||
/*!
|
||||
Returns a map from machine name to the list of options that machine
|
||||
Returns a map from long machine name to the list of options that machine
|
||||
exposes, for all machines.
|
||||
*/
|
||||
std::map<std::string, std::vector<std::unique_ptr<Configurable::Option>>> AllOptionsByMachineName();
|
||||
|
||||
std::map<std::string, std::unique_ptr<Reflection::Struct>> ConstructionOptionsByMachineName();
|
||||
/*!
|
||||
Returns a map from long machine name to appropriate instances of Target for the machine.
|
||||
|
||||
NB: Usually the instances of Target can be dynamic_casted to Reflection::Struct in order to determine available properties.
|
||||
*/
|
||||
std::map<std::string, std::unique_ptr<Analyser::Static::Target>> TargetsByMachineName(bool meaningful_without_media_only);
|
||||
|
||||
}
|
||||
|
||||
|
@ -13,10 +13,11 @@
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <map>
|
||||
#include <variant>
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
@ -363,7 +364,7 @@ bool KeyboardKeyForSDLScancode(SDL_Scancode scancode, Inputs::Keyboard::Key &key
|
||||
|
||||
struct ParsedArguments {
|
||||
std::string file_name;
|
||||
Configurable::SelectionSet selections;
|
||||
std::map<std::string, std::variant<std::string, bool>> selections;
|
||||
};
|
||||
|
||||
/*! Parses an argc/argv pair to discern program arguments. */
|
||||
@ -388,11 +389,11 @@ ParsedArguments parse_arguments(int argc, char *argv[]) {
|
||||
std::size_t split_index = argument.find("=");
|
||||
|
||||
if(split_index == std::string::npos) {
|
||||
arguments.selections[argument] = std::make_unique<Configurable::BooleanSelection>(true);
|
||||
arguments.selections[argument] = true;
|
||||
} else {
|
||||
std::string name = argument.substr(0, split_index);
|
||||
std::string value = argument.substr(split_index+1, std::string::npos);
|
||||
arguments.selections[name] = std::make_unique<Configurable::ListSelection>(value);
|
||||
arguments.selections[name] = value;
|
||||
}
|
||||
} else {
|
||||
arguments.file_name = arg;
|
||||
@ -506,12 +507,14 @@ int main(int argc, char *argv[]) {
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
const auto construction_options = Machine::ConstructionOptionsByMachineName();
|
||||
for(const auto &options: construction_options) {
|
||||
std::cout << options.first << ":" << std::endl;
|
||||
for(const auto &option: options.second->all_keys()) {
|
||||
const auto targets = Machine::TargetsByMachineName(false);
|
||||
for(const auto &target: targets) {
|
||||
const auto reflectable = dynamic_cast<Reflection::Struct *>(target.second.get());
|
||||
|
||||
std::cout << target.first << ":" << std::endl;
|
||||
for(const auto &option: reflectable->all_keys()) {
|
||||
std::cout << '\t' << "--" << option;
|
||||
const auto type = options.second->type_of(option);
|
||||
const auto type = reflectable->type_of(option);
|
||||
|
||||
// Is this a registered enum? If so, list options.
|
||||
if(!Reflection::Enum::name(*type).empty()) {
|
||||
@ -565,14 +568,14 @@ int main(int argc, char *argv[]) {
|
||||
"/usr/local/share/CLK/",
|
||||
"/usr/share/CLK/"
|
||||
};
|
||||
if(arguments.selections.find("rompath") != arguments.selections.end()) {
|
||||
const std::string user_path = arguments.selections["rompath"]->list_selection()->value;
|
||||
if(user_path.back() != '/') {
|
||||
paths.push_back(user_path + "/");
|
||||
} else {
|
||||
paths.push_back(user_path);
|
||||
}
|
||||
}
|
||||
// if(arguments.selections.find("rompath") != arguments.selections.end()) {
|
||||
// const std::string user_path = arguments.selections["rompath"]->list_selection()->value;
|
||||
// if(user_path.back() != '/') {
|
||||
// paths.push_back(user_path + "/");
|
||||
// } else {
|
||||
// paths.push_back(user_path);
|
||||
// }
|
||||
// }
|
||||
|
||||
std::vector<std::unique_ptr<std::vector<uint8_t>>> results;
|
||||
for(const auto &rom: roms) {
|
||||
@ -630,17 +633,17 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
// Apply the speed multiplier, if one was requested.
|
||||
if(arguments.selections.find("speed") != arguments.selections.end()) {
|
||||
const char *speed_string = arguments.selections["speed"]->list_selection()->value.c_str();
|
||||
char *end;
|
||||
double speed = strtod(speed_string, &end);
|
||||
|
||||
if(size_t(end - speed_string) != strlen(speed_string)) {
|
||||
std::cerr << "Unable to parse speed: " << speed_string << std::endl;
|
||||
} else if(speed <= 0.0) {
|
||||
std::cerr << "Cannot run at speed " << speed_string << "; speeds must be positive." << std::endl;
|
||||
} else {
|
||||
machine_runner.set_speed_multiplier(speed);
|
||||
}
|
||||
// const char *speed_string = arguments.selections["speed"]->list_selection()->value.c_str();
|
||||
// char *end;
|
||||
// double speed = strtod(speed_string, &end);
|
||||
//
|
||||
// if(size_t(end - speed_string) != strlen(speed_string)) {
|
||||
// std::cerr << "Unable to parse speed: " << speed_string << std::endl;
|
||||
// } else if(speed <= 0.0) {
|
||||
// std::cerr << "Cannot run at speed " << speed_string << "; speeds must be positive." << std::endl;
|
||||
// } else {
|
||||
// machine_runner.set_speed_multiplier(speed);
|
||||
// }
|
||||
}
|
||||
|
||||
// Check whether a 'logical' keyboard has been requested.
|
||||
@ -718,7 +721,7 @@ int main(int argc, char *argv[]) {
|
||||
int window_width, window_height;
|
||||
SDL_GetWindowSize(window, &window_width, &window_height);
|
||||
|
||||
Configurable::Device *const configurable_device = machine->configurable_device();
|
||||
/* Configurable::Device *const configurable_device = machine->configurable_device();
|
||||
if(configurable_device) {
|
||||
// Establish user-friendly options by default.
|
||||
configurable_device->set_selections(configurable_device->get_user_friendly_selections());
|
||||
@ -741,7 +744,7 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
// Apply the user's actual selections to final the defaults.
|
||||
configurable_device->set_selections(arguments.selections);
|
||||
}
|
||||
}*/
|
||||
|
||||
// If this is a joystick machine, check for and open attached joysticks.
|
||||
/*!
|
||||
|
Loading…
x
Reference in New Issue
Block a user