mirror of
				https://github.com/TomHarte/CLK.git
				synced 2025-10-30 14:16:04 +00:00 
			
		
		
		
	Merge branch 'master' into MSX
This commit is contained in:
		| @@ -15,44 +15,7 @@ | |||||||
| #include "../Oric/Oric.hpp" | #include "../Oric/Oric.hpp" | ||||||
| #include "../ZX8081/ZX8081.hpp" | #include "../ZX8081/ZX8081.hpp" | ||||||
|  |  | ||||||
| namespace { | #include "TypedDynamicMachine.hpp" | ||||||
|  |  | ||||||
| template<typename T> class TypedDynamicMachine: public ::Machine::DynamicMachine { |  | ||||||
| 	public: |  | ||||||
| 		TypedDynamicMachine(T *machine) : machine_(machine) {} |  | ||||||
|  |  | ||||||
| 		ConfigurationTarget::Machine *configuration_target() override { |  | ||||||
| 			return get<ConfigurationTarget::Machine>(); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		CRTMachine::Machine *crt_machine() override { |  | ||||||
| 			return get<CRTMachine::Machine>(); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		JoystickMachine::Machine *joystick_machine() override { |  | ||||||
| 			return get<JoystickMachine::Machine>(); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		KeyboardMachine::Machine *keyboard_machine() override { |  | ||||||
| 			return get<KeyboardMachine::Machine>(); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		Configurable::Device *configurable_device() override { |  | ||||||
| 			return get<Configurable::Device>(); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		Utility::TypeRecipient *type_recipient() override { |  | ||||||
| 			return get<Utility::TypeRecipient>(); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 	private: |  | ||||||
| 		template <typename Class> Class *get() { |  | ||||||
| 			return dynamic_cast<Class *>(machine_.get()); |  | ||||||
| 		} |  | ||||||
| 		std::unique_ptr<T> machine_; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| } |  | ||||||
|  |  | ||||||
| ::Machine::DynamicMachine *::Machine::MachineForTarget(const StaticAnalyser::Target &target) { | ::Machine::DynamicMachine *::Machine::MachineForTarget(const StaticAnalyser::Target &target) { | ||||||
| 	switch(target.machine) { | 	switch(target.machine) { | ||||||
|   | |||||||
							
								
								
									
										61
									
								
								Machines/Utility/TypedDynamicMachine.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								Machines/Utility/TypedDynamicMachine.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,61 @@ | |||||||
|  | // | ||||||
|  | //  TypedDynamicMachine.hpp | ||||||
|  | //  Clock Signal | ||||||
|  | // | ||||||
|  | //  Created by Thomas Harte on 24/11/2017. | ||||||
|  | //  Copyright © 2017 Thomas Harte. All rights reserved. | ||||||
|  | // | ||||||
|  |  | ||||||
|  | #ifndef TypedDynamicMachine_h | ||||||
|  | #define TypedDynamicMachine_h | ||||||
|  |  | ||||||
|  | #include "MachineForTarget.hpp" | ||||||
|  |  | ||||||
|  | namespace Machine { | ||||||
|  |  | ||||||
|  | template<typename T> class TypedDynamicMachine: public ::Machine::DynamicMachine { | ||||||
|  | 	public: | ||||||
|  | 		TypedDynamicMachine(T *machine) : machine_(machine) {} | ||||||
|  | 		T *get() { return machine_.get(); } | ||||||
|  |  | ||||||
|  | 		TypedDynamicMachine() : TypedDynamicMachine(nullptr) {} | ||||||
|  | 		TypedDynamicMachine(TypedDynamicMachine &&rhs) : machine_(std::move(rhs.machine_)) {} | ||||||
|  | 		TypedDynamicMachine &operator=(TypedDynamicMachine &&rhs) { | ||||||
|  | 			machine_ = std::move(rhs.machine_); | ||||||
|  | 			return *this; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		ConfigurationTarget::Machine *configuration_target() override { | ||||||
|  | 			return get<ConfigurationTarget::Machine>(); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		CRTMachine::Machine *crt_machine() override { | ||||||
|  | 			return get<CRTMachine::Machine>(); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		JoystickMachine::Machine *joystick_machine() override { | ||||||
|  | 			return get<JoystickMachine::Machine>(); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		KeyboardMachine::Machine *keyboard_machine() override { | ||||||
|  | 			return get<KeyboardMachine::Machine>(); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		Configurable::Device *configurable_device() override { | ||||||
|  | 			return get<Configurable::Device>(); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		Utility::TypeRecipient *type_recipient() override { | ||||||
|  | 			return get<Utility::TypeRecipient>(); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 	private: | ||||||
|  | 		template <typename Class> Class *get() { | ||||||
|  | 			return dynamic_cast<Class *>(machine_.get()); | ||||||
|  | 		} | ||||||
|  | 		std::unique_ptr<T> machine_; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #endif /* TypedDynamicMachine_h */ | ||||||
| @@ -823,6 +823,7 @@ | |||||||
| 		4B7913CB1DFCD80E00175A82 /* Video.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Video.hpp; path = Electron/Video.hpp; sourceTree = "<group>"; }; | 		4B7913CB1DFCD80E00175A82 /* Video.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Video.hpp; path = Electron/Video.hpp; sourceTree = "<group>"; }; | ||||||
| 		4B79A4F91FC8FF9400EEDAD5 /* MSX.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = MSX.cpp; sourceTree = "<group>"; }; | 		4B79A4F91FC8FF9400EEDAD5 /* MSX.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = MSX.cpp; sourceTree = "<group>"; }; | ||||||
| 		4B79A4FA1FC8FF9400EEDAD5 /* MSX.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = MSX.hpp; sourceTree = "<group>"; }; | 		4B79A4FA1FC8FF9400EEDAD5 /* MSX.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = MSX.hpp; sourceTree = "<group>"; }; | ||||||
|  | 		4B79A4FE1FC9082300EEDAD5 /* TypedDynamicMachine.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = TypedDynamicMachine.hpp; sourceTree = "<group>"; }; | ||||||
| 		4B79E4411E3AF38600141F11 /* cassette.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = cassette.png; sourceTree = "<group>"; }; | 		4B79E4411E3AF38600141F11 /* cassette.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = cassette.png; sourceTree = "<group>"; }; | ||||||
| 		4B79E4421E3AF38600141F11 /* floppy35.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = floppy35.png; sourceTree = "<group>"; }; | 		4B79E4421E3AF38600141F11 /* floppy35.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = floppy35.png; sourceTree = "<group>"; }; | ||||||
| 		4B79E4431E3AF38600141F11 /* floppy525.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = floppy525.png; sourceTree = "<group>"; }; | 		4B79E4431E3AF38600141F11 /* floppy525.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = floppy525.png; sourceTree = "<group>"; }; | ||||||
| @@ -1475,11 +1476,12 @@ | |||||||
| 			isa = PBXGroup; | 			isa = PBXGroup; | ||||||
| 			children = ( | 			children = ( | ||||||
| 				4B055ABE1FAE98000060FFFF /* MachineForTarget.cpp */, | 				4B055ABE1FAE98000060FFFF /* MachineForTarget.cpp */, | ||||||
| 				4B055ABF1FAE98000060FFFF /* MachineForTarget.hpp */, |  | ||||||
| 				4B2B3A471F9B8FA70062DABF /* Typer.cpp */, |  | ||||||
| 				4B2B3A481F9B8FA70062DABF /* MemoryFuzzer.cpp */, | 				4B2B3A481F9B8FA70062DABF /* MemoryFuzzer.cpp */, | ||||||
|  | 				4B2B3A471F9B8FA70062DABF /* Typer.cpp */, | ||||||
|  | 				4B055ABF1FAE98000060FFFF /* MachineForTarget.hpp */, | ||||||
| 				4B2B3A491F9B8FA70062DABF /* MemoryFuzzer.hpp */, | 				4B2B3A491F9B8FA70062DABF /* MemoryFuzzer.hpp */, | ||||||
| 				4B2B3A4A1F9B8FA70062DABF /* Typer.hpp */, | 				4B2B3A4A1F9B8FA70062DABF /* Typer.hpp */, | ||||||
|  | 				4B79A4FE1FC9082300EEDAD5 /* TypedDynamicMachine.hpp */, | ||||||
| 			); | 			); | ||||||
| 			path = Utility; | 			path = Utility; | ||||||
| 			sourceTree = "<group>"; | 			sourceTree = "<group>"; | ||||||
|   | |||||||
| @@ -17,7 +17,7 @@ class ElectronOptionsPanel: MachinePanel { | |||||||
|  |  | ||||||
| 	@IBOutlet var displayTypeButton: NSPopUpButton? | 	@IBOutlet var displayTypeButton: NSPopUpButton? | ||||||
| 	@IBAction func setDisplayType(_ sender: NSPopUpButton!) { | 	@IBAction func setDisplayType(_ sender: NSPopUpButton!) { | ||||||
| 		electron.useTelevisionOutput = (sender.indexOfSelectedItem == 1) | 		electron.useCompositeOutput = (sender.indexOfSelectedItem == 1) | ||||||
| 		UserDefaults.standard.set(sender.indexOfSelectedItem, forKey: self.displayTypeUserDefaultsKey) | 		UserDefaults.standard.set(sender.indexOfSelectedItem, forKey: self.displayTypeUserDefaultsKey) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -29,7 +29,7 @@ class ElectronOptionsPanel: MachinePanel { | |||||||
| 		]) | 		]) | ||||||
|  |  | ||||||
| 		let displayType = standardUserDefaults.integer(forKey: self.displayTypeUserDefaultsKey) | 		let displayType = standardUserDefaults.integer(forKey: self.displayTypeUserDefaultsKey) | ||||||
| 		electron.useTelevisionOutput = (displayType == 1) | 		electron.useCompositeOutput = (displayType == 1) | ||||||
| 		self.displayTypeButton?.selectItem(at: displayType) | 		self.displayTypeButton?.selectItem(at: displayType) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -12,4 +12,5 @@ | |||||||
| @interface CSMachine (Subclassing) | @interface CSMachine (Subclassing) | ||||||
|  |  | ||||||
| - (void)setupOutputWithAspectRatio:(float)aspectRatio; | - (void)setupOutputWithAspectRatio:(float)aspectRatio; | ||||||
|  |  | ||||||
| @end | @end | ||||||
|   | |||||||
| @@ -22,7 +22,7 @@ | |||||||
| /*! | /*! | ||||||
| 	Initialises an instance of CSMachine. | 	Initialises an instance of CSMachine. | ||||||
|  |  | ||||||
| 	@param machine The pointer to an instance of @c CRTMachine::Machine* . C++ type is omitted because | 	@param machine The pointer to an instance of @c Machine::DynamicMachine . C++ type is omitted because | ||||||
| 	this header is visible to Swift, and the designated initialiser cannot be placed into a category. | 	this header is visible to Swift, and the designated initialiser cannot be placed into a category. | ||||||
| */ | */ | ||||||
| - (instancetype)initWithMachine:(void *)machine NS_DESIGNATED_INITIALIZER; | - (instancetype)initWithMachine:(void *)machine NS_DESIGNATED_INITIALIZER; | ||||||
| @@ -49,4 +49,8 @@ | |||||||
|  |  | ||||||
| - (void)paste:(NSString *)string; | - (void)paste:(NSString *)string; | ||||||
|  |  | ||||||
|  | @property (nonatomic, assign) BOOL useFastLoadingHack; | ||||||
|  | @property (nonatomic, assign) BOOL useCompositeOutput; | ||||||
|  | @property (nonatomic, assign) BOOL useAutomaticTapeMotorControl; | ||||||
|  |  | ||||||
| @end | @end | ||||||
|   | |||||||
| @@ -10,11 +10,13 @@ | |||||||
| #import "CSMachine+Subclassing.h" | #import "CSMachine+Subclassing.h" | ||||||
| #import "CSMachine+Target.h" | #import "CSMachine+Target.h" | ||||||
|  |  | ||||||
| #include "KeyCodes.h" |  | ||||||
| #include "Typer.hpp" |  | ||||||
| #include "ConfigurationTarget.hpp" | #include "ConfigurationTarget.hpp" | ||||||
| #include "JoystickMachine.hpp" | #include "JoystickMachine.hpp" | ||||||
| #include "KeyboardMachine.hpp" | #include "KeyboardMachine.hpp" | ||||||
|  | #include "KeyCodes.h" | ||||||
|  | #include "MachineForTarget.hpp" | ||||||
|  | #include "StandardOptions.hpp" | ||||||
|  | #include "Typer.hpp" | ||||||
|  |  | ||||||
| #import "NSBundle+DataResource.h" | #import "NSBundle+DataResource.h" | ||||||
| #import "NSData+StdVector.h" | #import "NSData+StdVector.h" | ||||||
| @@ -57,13 +59,13 @@ struct MachineDelegate: CRTMachine::Machine::Delegate, public LockProtectedDeleg | |||||||
| 	SpeakerDelegate _speakerDelegate; | 	SpeakerDelegate _speakerDelegate; | ||||||
| 	MachineDelegate _machineDelegate; | 	MachineDelegate _machineDelegate; | ||||||
| 	NSLock *_delegateMachineAccessLock; | 	NSLock *_delegateMachineAccessLock; | ||||||
| 	CRTMachine::Machine *_machine; | 	Machine::DynamicMachine *_machine; | ||||||
| } | } | ||||||
|  |  | ||||||
| - (instancetype)initWithMachine:(void *)machine { | - (instancetype)initWithMachine:(void *)machine { | ||||||
| 	self = [super init]; | 	self = [super init]; | ||||||
| 	if(self) { | 	if(self) { | ||||||
| 		_machine = (CRTMachine::Machine *)machine; | 		_machine = (Machine::DynamicMachine *)machine; | ||||||
| 		_delegateMachineAccessLock = [[NSLock alloc] init]; | 		_delegateMachineAccessLock = [[NSLock alloc] init]; | ||||||
|  |  | ||||||
| 		_machineDelegate.machine = self; | 		_machineDelegate.machine = self; | ||||||
| @@ -71,8 +73,8 @@ struct MachineDelegate: CRTMachine::Machine::Delegate, public LockProtectedDeleg | |||||||
| 		_machineDelegate.machineAccessLock = _delegateMachineAccessLock; | 		_machineDelegate.machineAccessLock = _delegateMachineAccessLock; | ||||||
| 		_speakerDelegate.machineAccessLock = _delegateMachineAccessLock; | 		_speakerDelegate.machineAccessLock = _delegateMachineAccessLock; | ||||||
|  |  | ||||||
| 		_machine->set_delegate(&_machineDelegate); | 		_machine->crt_machine()->set_delegate(&_machineDelegate); | ||||||
| 		_machine->set_rom_fetcher( [] (const std::string &machine, const std::vector<std::string> &names) -> std::vector<std::unique_ptr<std::vector<std::uint8_t>>> { | 		_machine->crt_machine()->set_rom_fetcher( [] (const std::string &machine, const std::vector<std::string> &names) -> std::vector<std::unique_ptr<std::vector<std::uint8_t>>> { | ||||||
| 			NSString *subDirectory = [@"ROMImages/" stringByAppendingString:[NSString stringWithUTF8String:machine.c_str()]]; | 			NSString *subDirectory = [@"ROMImages/" stringByAppendingString:[NSString stringWithUTF8String:machine.c_str()]]; | ||||||
| 			std::vector<std::unique_ptr<std::vector<std::uint8_t>>> results; | 			std::vector<std::unique_ptr<std::vector<std::uint8_t>>> results; | ||||||
| 			for(auto &name: names) { | 			for(auto &name: names) { | ||||||
| @@ -119,14 +121,14 @@ struct MachineDelegate: CRTMachine::Machine::Delegate, public LockProtectedDeleg | |||||||
|  |  | ||||||
| 	[_view performWithGLContext:^{ | 	[_view performWithGLContext:^{ | ||||||
| 		@synchronized(self) { | 		@synchronized(self) { | ||||||
| 			_machine->close_output(); | 			_machine->crt_machine()->close_output(); | ||||||
| 		} | 		} | ||||||
| 	}]; | 	}]; | ||||||
| } | } | ||||||
|  |  | ||||||
| - (float)idealSamplingRateFromRange:(NSRange)range { | - (float)idealSamplingRateFromRange:(NSRange)range { | ||||||
| 	@synchronized(self) { | 	@synchronized(self) { | ||||||
| 		std::shared_ptr<Outputs::Speaker> speaker = _machine->get_speaker(); | 		std::shared_ptr<Outputs::Speaker> speaker = _machine->crt_machine()->get_speaker(); | ||||||
| 		if(speaker) { | 		if(speaker) { | ||||||
| 			return speaker->get_ideal_clock_rate_in_range((float)range.location, (float)(range.location + range.length)); | 			return speaker->get_ideal_clock_rate_in_range((float)range.location, (float)(range.location + range.length)); | ||||||
| 		} | 		} | ||||||
| @@ -142,7 +144,7 @@ struct MachineDelegate: CRTMachine::Machine::Delegate, public LockProtectedDeleg | |||||||
|  |  | ||||||
| - (BOOL)setSpeakerDelegate:(Outputs::Speaker::Delegate *)delegate sampleRate:(float)sampleRate bufferSize:(NSUInteger)bufferSize { | - (BOOL)setSpeakerDelegate:(Outputs::Speaker::Delegate *)delegate sampleRate:(float)sampleRate bufferSize:(NSUInteger)bufferSize { | ||||||
| 	@synchronized(self) { | 	@synchronized(self) { | ||||||
| 		std::shared_ptr<Outputs::Speaker> speaker = _machine->get_speaker(); | 		std::shared_ptr<Outputs::Speaker> speaker = _machine->crt_machine()->get_speaker(); | ||||||
| 		if(speaker) { | 		if(speaker) { | ||||||
| 			speaker->set_output_rate(sampleRate, (int)bufferSize); | 			speaker->set_output_rate(sampleRate, (int)bufferSize); | ||||||
| 			speaker->set_delegate(delegate); | 			speaker->set_delegate(delegate); | ||||||
| @@ -154,7 +156,7 @@ struct MachineDelegate: CRTMachine::Machine::Delegate, public LockProtectedDeleg | |||||||
|  |  | ||||||
| - (void)runForNumberOfCycles:(int)numberOfCycles { | - (void)runForNumberOfCycles:(int)numberOfCycles { | ||||||
| 	@synchronized(self) { | 	@synchronized(self) { | ||||||
| 		_machine->run_for(Cycles(numberOfCycles)); | 		_machine->crt_machine()->run_for(Cycles(numberOfCycles)); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -166,49 +168,47 @@ struct MachineDelegate: CRTMachine::Machine::Delegate, public LockProtectedDeleg | |||||||
| } | } | ||||||
|  |  | ||||||
| - (void)setupOutputWithAspectRatio:(float)aspectRatio { | - (void)setupOutputWithAspectRatio:(float)aspectRatio { | ||||||
| 	_machine->setup_output(aspectRatio); | 	_machine->crt_machine()->setup_output(aspectRatio); | ||||||
|  |  | ||||||
| 	// Since OS X v10.6, Macs have had a gamma of 2.2. | 	// Since OS X v10.6, Macs have had a gamma of 2.2. | ||||||
| 	_machine->get_crt()->set_output_gamma(2.2f); | 	_machine->crt_machine()->get_crt()->set_output_gamma(2.2f); | ||||||
| 	_machine->get_crt()->set_target_framebuffer(0); | 	_machine->crt_machine()->get_crt()->set_target_framebuffer(0); | ||||||
| } | } | ||||||
|  |  | ||||||
| - (void)drawViewForPixelSize:(CGSize)pixelSize onlyIfDirty:(BOOL)onlyIfDirty { | - (void)drawViewForPixelSize:(CGSize)pixelSize onlyIfDirty:(BOOL)onlyIfDirty { | ||||||
| 	_machine->get_crt()->draw_frame((unsigned int)pixelSize.width, (unsigned int)pixelSize.height, onlyIfDirty ? true : false); | 	_machine->crt_machine()->get_crt()->draw_frame((unsigned int)pixelSize.width, (unsigned int)pixelSize.height, onlyIfDirty ? true : false); | ||||||
| } | } | ||||||
|  |  | ||||||
| - (double)clockRate { | - (double)clockRate { | ||||||
| 	return _machine->get_clock_rate(); | 	return _machine->crt_machine()->get_clock_rate(); | ||||||
| } | } | ||||||
|  |  | ||||||
| - (BOOL)clockIsUnlimited { | - (BOOL)clockIsUnlimited { | ||||||
| 	return _machine->get_clock_is_unlimited() ? YES : NO; | 	return _machine->crt_machine()->get_clock_is_unlimited() ? YES : NO; | ||||||
| } | } | ||||||
|  |  | ||||||
| - (void)paste:(NSString *)paste { | - (void)paste:(NSString *)paste { | ||||||
| 	Utility::TypeRecipient *typeRecipient = dynamic_cast<Utility::TypeRecipient *>(_machine); | 	Utility::TypeRecipient *typeRecipient = _machine->type_recipient(); | ||||||
| 	if(typeRecipient) | 	if(typeRecipient) | ||||||
| 		typeRecipient->set_typer_for_string([paste UTF8String]); | 		typeRecipient->set_typer_for_string([paste UTF8String]); | ||||||
| } | } | ||||||
|  |  | ||||||
| - (void)applyTarget:(const StaticAnalyser::Target &)target { | - (void)applyTarget:(const StaticAnalyser::Target &)target { | ||||||
| 	@synchronized(self) { | 	@synchronized(self) { | ||||||
| 		ConfigurationTarget::Machine *const configurationTarget = | 		ConfigurationTarget::Machine *const configurationTarget = _machine->configuration_target(); | ||||||
| 			dynamic_cast<ConfigurationTarget::Machine *>(_machine); |  | ||||||
| 		if(configurationTarget) configurationTarget->configure_as_target(target); | 		if(configurationTarget) configurationTarget->configure_as_target(target); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| - (void)applyMedia:(const StaticAnalyser::Media &)media { | - (void)applyMedia:(const StaticAnalyser::Media &)media { | ||||||
| 	@synchronized(self) { | 	@synchronized(self) { | ||||||
| 		ConfigurationTarget::Machine *const configurationTarget = | 		ConfigurationTarget::Machine *const configurationTarget = _machine->configuration_target(); | ||||||
| 			dynamic_cast<ConfigurationTarget::Machine *>(_machine); |  | ||||||
| 		if(configurationTarget) configurationTarget->insert_media(media); | 		if(configurationTarget) configurationTarget->insert_media(media); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| - (void)setKey:(uint16_t)key isPressed:(BOOL)isPressed { | - (void)setKey:(uint16_t)key isPressed:(BOOL)isPressed { | ||||||
| 	auto keyboard_machine = dynamic_cast<KeyboardMachine::Machine *>(_machine); | 	auto keyboard_machine = _machine->keyboard_machine(); | ||||||
| 	if(keyboard_machine) { | 	if(keyboard_machine) { | ||||||
| 		@synchronized(self) { | 		@synchronized(self) { | ||||||
| 			Inputs::Keyboard &keyboard = keyboard_machine->get_keyboard(); | 			Inputs::Keyboard &keyboard = keyboard_machine->get_keyboard(); | ||||||
| @@ -272,7 +272,7 @@ struct MachineDelegate: CRTMachine::Machine::Delegate, public LockProtectedDeleg | |||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	auto joystick_machine = dynamic_cast<JoystickMachine::Machine *>(_machine); | 	auto joystick_machine = _machine->joystick_machine(); | ||||||
| 	if(joystick_machine) { | 	if(joystick_machine) { | ||||||
| 		@synchronized(self) { | 		@synchronized(self) { | ||||||
| 			std::vector<std::unique_ptr<Inputs::Joystick>> &joysticks = joystick_machine->get_joysticks(); | 			std::vector<std::unique_ptr<Inputs::Joystick>> &joysticks = joystick_machine->get_joysticks(); | ||||||
| @@ -292,14 +292,14 @@ struct MachineDelegate: CRTMachine::Machine::Delegate, public LockProtectedDeleg | |||||||
| } | } | ||||||
|  |  | ||||||
| - (void)clearAllKeys { | - (void)clearAllKeys { | ||||||
| 	auto keyboard_machine = dynamic_cast<KeyboardMachine::Machine *>(_machine); | 	auto keyboard_machine = _machine->keyboard_machine(); | ||||||
| 	if(keyboard_machine) { | 	if(keyboard_machine) { | ||||||
| 		@synchronized(self) { | 		@synchronized(self) { | ||||||
| 			keyboard_machine->get_keyboard().reset_all_keys(); | 			keyboard_machine->get_keyboard().reset_all_keys(); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	auto joystick_machine = dynamic_cast<JoystickMachine::Machine *>(_machine); | 	auto joystick_machine = _machine->joystick_machine(); | ||||||
| 	if(joystick_machine) { | 	if(joystick_machine) { | ||||||
| 		@synchronized(self) { | 		@synchronized(self) { | ||||||
| 			for(auto &joystick : joystick_machine->get_joysticks()) { | 			for(auto &joystick : joystick_machine->get_joysticks()) { | ||||||
| @@ -309,4 +309,45 @@ struct MachineDelegate: CRTMachine::Machine::Delegate, public LockProtectedDeleg | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #pragma mark - Options | ||||||
|  |  | ||||||
|  | - (void)setUseFastLoadingHack:(BOOL)useFastLoadingHack { | ||||||
|  | 	Configurable::Device *configurable_device = _machine->configurable_device(); | ||||||
|  | 	if(!configurable_device) return; | ||||||
|  |  | ||||||
|  | 	@synchronized(self) { | ||||||
|  | 		_useFastLoadingHack = useFastLoadingHack; | ||||||
|  |  | ||||||
|  | 		Configurable::SelectionSet selection_set; | ||||||
|  | 		append_quick_load_tape_selection(selection_set, useFastLoadingHack ? true : false); | ||||||
|  | 		configurable_device->set_selections(selection_set); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | - (void)setUseCompositeOutput:(BOOL)useCompositeOutput { | ||||||
|  | 	Configurable::Device *configurable_device = _machine->configurable_device(); | ||||||
|  | 	if(!configurable_device) return; | ||||||
|  |  | ||||||
|  | 	@synchronized(self) { | ||||||
|  | 		_useCompositeOutput = useCompositeOutput; | ||||||
|  |  | ||||||
|  | 		Configurable::SelectionSet selection_set; | ||||||
|  | 		append_display_selection(selection_set, useCompositeOutput ? Configurable::Display::Composite : Configurable::Display::RGB); | ||||||
|  | 		configurable_device->set_selections(selection_set); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | - (void)setUseAutomaticTapeMotorControl:(BOOL)useAutomaticTapeMotorControl { | ||||||
|  | 	Configurable::Device *configurable_device = _machine->configurable_device(); | ||||||
|  | 	if(!configurable_device) return; | ||||||
|  |  | ||||||
|  | 	@synchronized(self) { | ||||||
|  | 		_useAutomaticTapeMotorControl = useAutomaticTapeMotorControl; | ||||||
|  |  | ||||||
|  | 		Configurable::SelectionSet selection_set; | ||||||
|  | 		append_automatic_tape_motor_control_selection(selection_set, useAutomaticTapeMotorControl ? true : false); | ||||||
|  | 		configurable_device->set_selections(selection_set); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| @end | @end | ||||||
|   | |||||||
| @@ -9,19 +9,15 @@ | |||||||
| #import "CSAmstradCPC.h" | #import "CSAmstradCPC.h" | ||||||
|  |  | ||||||
| #include "AmstradCPC.hpp" | #include "AmstradCPC.hpp" | ||||||
|  | #include "TypedDynamicMachine.hpp" | ||||||
|  |  | ||||||
| @implementation CSAmstradCPC { | @implementation CSAmstradCPC { | ||||||
| 	std::unique_ptr<AmstradCPC::Machine> _amstradCPC; | 	Machine::TypedDynamicMachine<AmstradCPC::Machine> _amstradCPC; | ||||||
| } | } | ||||||
|  |  | ||||||
| - (instancetype)init { | - (instancetype)init { | ||||||
| 	AmstradCPC::Machine *machine = AmstradCPC::Machine::AmstradCPC(); | 	_amstradCPC = Machine::TypedDynamicMachine<AmstradCPC::Machine>(AmstradCPC::Machine::AmstradCPC()); | ||||||
|  | 	return [super initWithMachine:&_amstradCPC]; | ||||||
| 	self = [super initWithMachine:machine]; |  | ||||||
| 	if(self) { |  | ||||||
| 		_amstradCPC.reset(machine); |  | ||||||
| 	} |  | ||||||
| 	return self; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| - (NSString *)userDefaultsPrefix {	return @"amstradCPC";	} | - (NSString *)userDefaultsPrefix {	return @"amstradCPC";	} | ||||||
|   | |||||||
| @@ -9,24 +9,21 @@ | |||||||
| #import "CSAtari2600.h" | #import "CSAtari2600.h" | ||||||
|  |  | ||||||
| #include "Atari2600.hpp" | #include "Atari2600.hpp" | ||||||
|  | #include "TypedDynamicMachine.hpp" | ||||||
| #import "CSMachine+Subclassing.h" | #import "CSMachine+Subclassing.h" | ||||||
|  |  | ||||||
| @implementation CSAtari2600 { | @implementation CSAtari2600 { | ||||||
| 	std::unique_ptr<Atari2600::Machine> _atari2600; | 	Machine::TypedDynamicMachine<Atari2600::Machine> _atari2600; | ||||||
| } | } | ||||||
|  |  | ||||||
| - (instancetype)init { | - (instancetype)init { | ||||||
| 	Atari2600::Machine *machine = Atari2600::Machine::Atari2600(); | 	_atari2600 = Machine::TypedDynamicMachine<Atari2600::Machine>(Atari2600::Machine::Atari2600()); | ||||||
| 	self = [super initWithMachine:machine]; | 	return [super initWithMachine:&_atari2600]; | ||||||
| 	if(self) { |  | ||||||
| 		_atari2600.reset(machine); |  | ||||||
| 	} |  | ||||||
| 	return self; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| - (void)setResetLineEnabled:(BOOL)enabled { | - (void)setResetLineEnabled:(BOOL)enabled { | ||||||
| 	@synchronized(self) { | 	@synchronized(self) { | ||||||
| 		_atari2600->set_reset_switch(enabled ? true : false); | 		_atari2600.get()->set_reset_switch(enabled ? true : false); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -41,31 +38,31 @@ | |||||||
| - (void)setColourButton:(BOOL)colourButton { | - (void)setColourButton:(BOOL)colourButton { | ||||||
| 	_colourButton = colourButton; | 	_colourButton = colourButton; | ||||||
| 	@synchronized(self) { | 	@synchronized(self) { | ||||||
| 		_atari2600->set_switch_is_enabled(Atari2600SwitchColour, colourButton); | 		_atari2600.get()->set_switch_is_enabled(Atari2600SwitchColour, colourButton); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| - (void)setLeftPlayerDifficultyButton:(BOOL)leftPlayerDifficultyButton { | - (void)setLeftPlayerDifficultyButton:(BOOL)leftPlayerDifficultyButton { | ||||||
| 	_leftPlayerDifficultyButton = leftPlayerDifficultyButton; | 	_leftPlayerDifficultyButton = leftPlayerDifficultyButton; | ||||||
| 	@synchronized(self) { | 	@synchronized(self) { | ||||||
| 		_atari2600->set_switch_is_enabled(Atari2600SwitchLeftPlayerDifficulty, leftPlayerDifficultyButton); | 		_atari2600.get()->set_switch_is_enabled(Atari2600SwitchLeftPlayerDifficulty, leftPlayerDifficultyButton); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| - (void)setRightPlayerDifficultyButton:(BOOL)rightPlayerDifficultyButton { | - (void)setRightPlayerDifficultyButton:(BOOL)rightPlayerDifficultyButton { | ||||||
| 	_rightPlayerDifficultyButton = rightPlayerDifficultyButton; | 	_rightPlayerDifficultyButton = rightPlayerDifficultyButton; | ||||||
| 	@synchronized(self) { | 	@synchronized(self) { | ||||||
| 		_atari2600->set_switch_is_enabled(Atari2600SwitchRightPlayerDifficulty, rightPlayerDifficultyButton); | 		_atari2600.get()->set_switch_is_enabled(Atari2600SwitchRightPlayerDifficulty, rightPlayerDifficultyButton); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| - (void)toggleSwitch:(Atari2600Switch)toggleSwitch { | - (void)toggleSwitch:(Atari2600Switch)toggleSwitch { | ||||||
| 	@synchronized(self) { | 	@synchronized(self) { | ||||||
| 		_atari2600->set_switch_is_enabled(toggleSwitch, true); | 		_atari2600.get()->set_switch_is_enabled(toggleSwitch, true); | ||||||
| 	} | 	} | ||||||
| 	dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ | 	dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ | ||||||
| 		@synchronized(self) { | 		@synchronized(self) { | ||||||
| 			_atari2600->set_switch_is_enabled(toggleSwitch, false); | 			_atari2600.get()->set_switch_is_enabled(toggleSwitch, false); | ||||||
| 		} | 		} | ||||||
| 	}); | 	}); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -13,7 +13,4 @@ | |||||||
|  |  | ||||||
| - (instancetype)init; | - (instancetype)init; | ||||||
|  |  | ||||||
| @property (nonatomic, assign) BOOL useFastLoadingHack; |  | ||||||
| @property (nonatomic, assign) BOOL useTelevisionOutput; |  | ||||||
|  |  | ||||||
| @end | @end | ||||||
|   | |||||||
| @@ -9,45 +9,19 @@ | |||||||
| #import "CSElectron.h" | #import "CSElectron.h" | ||||||
|  |  | ||||||
| #include "Electron.hpp" | #include "Electron.hpp" | ||||||
| #include "StandardOptions.hpp" | #include "TypedDynamicMachine.hpp" | ||||||
|  |  | ||||||
| @implementation CSElectron { | @implementation CSElectron { | ||||||
| 	std::unique_ptr<Electron::Machine> _electron; | 	Machine::TypedDynamicMachine<Electron::Machine> _electron; | ||||||
| } | } | ||||||
|  |  | ||||||
| - (instancetype)init { | - (instancetype)init { | ||||||
| 	Electron::Machine *machine = Electron::Machine::Electron(); | 	_electron = Machine::TypedDynamicMachine<Electron::Machine>(Electron::Machine::Electron()); | ||||||
|  | 	return [super initWithMachine:&_electron]; | ||||||
| 	self = [super initWithMachine:machine]; |  | ||||||
| 	if(self) { |  | ||||||
| 		_electron.reset(machine); |  | ||||||
| 	} |  | ||||||
| 	return self; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| #pragma mark - ROM setting | #pragma mark - ROM setting | ||||||
|  |  | ||||||
| - (NSString *)userDefaultsPrefix {	return @"electron";	} | - (NSString *)userDefaultsPrefix {	return @"electron";	} | ||||||
|  |  | ||||||
| #pragma mark - Options |  | ||||||
|  |  | ||||||
| - (void)setUseFastLoadingHack:(BOOL)useFastLoadingHack { |  | ||||||
| 	@synchronized(self) { |  | ||||||
| 		_useFastLoadingHack = useFastLoadingHack; |  | ||||||
|  |  | ||||||
| 		Configurable::SelectionSet selection_set; |  | ||||||
| 		append_quick_load_tape_selection(selection_set, useFastLoadingHack ? true : false); |  | ||||||
| 		_electron->set_selections(selection_set); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| - (void)setUseTelevisionOutput:(BOOL)useTelevisionOutput { |  | ||||||
| 	@synchronized(self) { |  | ||||||
| 		_useTelevisionOutput = useTelevisionOutput; |  | ||||||
|  |  | ||||||
| 		Configurable::SelectionSet selection_set; |  | ||||||
| 		append_display_selection(selection_set, useTelevisionOutput ? Configurable::Display::Composite : Configurable::Display::RGB); |  | ||||||
| 		_electron->set_selections(selection_set); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| @end | @end | ||||||
|   | |||||||
| @@ -13,7 +13,4 @@ | |||||||
|  |  | ||||||
| - (instancetype)init; | - (instancetype)init; | ||||||
|  |  | ||||||
| @property (nonatomic, assign) BOOL useFastLoadingHack; |  | ||||||
| @property (nonatomic, assign) BOOL useCompositeOutput; |  | ||||||
|  |  | ||||||
| @end | @end | ||||||
|   | |||||||
| @@ -9,42 +9,15 @@ | |||||||
| #import "CSOric.h" | #import "CSOric.h" | ||||||
|  |  | ||||||
| #include "Oric.hpp" | #include "Oric.hpp" | ||||||
| #include "StandardOptions.hpp" | #include "TypedDynamicMachine.hpp" | ||||||
|  |  | ||||||
| @implementation CSOric { | @implementation CSOric { | ||||||
| 	std::unique_ptr<Oric::Machine> _oric; | 	Machine::TypedDynamicMachine<Oric::Machine> _oric; | ||||||
| } | } | ||||||
|  |  | ||||||
| - (instancetype)init { | - (instancetype)init { | ||||||
| 	Oric::Machine *machine = Oric::Machine::Oric(); | 	_oric = Machine::TypedDynamicMachine<Oric::Machine>(Oric::Machine::Oric()); | ||||||
|  | 	return [super initWithMachine:&_oric]; | ||||||
| 	self = [super initWithMachine:machine]; |  | ||||||
| 	if(self) { |  | ||||||
| 		_oric.reset(machine); |  | ||||||
| 	} |  | ||||||
| 	return self; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #pragma mark - Options |  | ||||||
|  |  | ||||||
| - (void)setUseFastLoadingHack:(BOOL)useFastLoadingHack { |  | ||||||
| 	@synchronized(self) { |  | ||||||
| 		_useFastLoadingHack = useFastLoadingHack; |  | ||||||
|  |  | ||||||
| 		Configurable::SelectionSet selection_set; |  | ||||||
| 		append_quick_load_tape_selection(selection_set, useFastLoadingHack ? true : false); |  | ||||||
| 		_oric->set_selections(selection_set); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| - (void)setUseCompositeOutput:(BOOL)useCompositeOutput { |  | ||||||
| 	@synchronized(self) { |  | ||||||
| 		_useCompositeOutput = useCompositeOutput; |  | ||||||
|  |  | ||||||
| 		Configurable::SelectionSet selection_set; |  | ||||||
| 		append_display_selection(selection_set, useCompositeOutput ? Configurable::Display::Composite : Configurable::Display::RGB); |  | ||||||
| 		_oric->set_selections(selection_set); |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
|  |  | ||||||
| @end | @end | ||||||
|   | |||||||
| @@ -29,7 +29,6 @@ typedef NS_ENUM(NSInteger, CSVic20MemorySize) | |||||||
|  |  | ||||||
| - (instancetype)init; | - (instancetype)init; | ||||||
|  |  | ||||||
| @property (nonatomic, assign) BOOL useFastLoadingHack; |  | ||||||
| @property (nonatomic, assign) CSVic20Country country; | @property (nonatomic, assign) CSVic20Country country; | ||||||
| @property (nonatomic, assign) CSVic20MemorySize memorySize; | @property (nonatomic, assign) CSVic20MemorySize memorySize; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -9,28 +9,19 @@ | |||||||
| #import "CSVic20.h" | #import "CSVic20.h" | ||||||
|  |  | ||||||
| #include "Vic20.hpp" | #include "Vic20.hpp" | ||||||
| #include "StandardOptions.hpp" | #include "TypedDynamicMachine.hpp" | ||||||
|  |  | ||||||
| using namespace Commodore::Vic20; |  | ||||||
|  |  | ||||||
| @implementation CSVic20 { | @implementation CSVic20 { | ||||||
| 	std::unique_ptr<Machine> _vic20; | 	Machine::TypedDynamicMachine<Commodore::Vic20::Machine> _vic20; | ||||||
| 	BOOL _joystickMode; | } | ||||||
|  |  | ||||||
|  | - (instancetype)init { | ||||||
|  | 	_vic20 = Machine::TypedDynamicMachine<Commodore::Vic20::Machine>(Commodore::Vic20::Machine::Vic20()); | ||||||
|  | 	return [super initWithMachine:&_vic20]; | ||||||
| } | } | ||||||
|  |  | ||||||
| - (NSString *)userDefaultsPrefix		{	return @"vic20";	} | - (NSString *)userDefaultsPrefix		{	return @"vic20";	} | ||||||
|  |  | ||||||
| - (instancetype)init { |  | ||||||
| 	Machine *machine = Commodore::Vic20::Machine::Vic20(); |  | ||||||
|  |  | ||||||
| 	self = [super initWithMachine:machine]; |  | ||||||
| 	if(self) { |  | ||||||
| 		_vic20.reset(machine); |  | ||||||
| 		[self setCountry:CSVic20CountryEuropean]; |  | ||||||
| 	} |  | ||||||
| 	return self; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #pragma mark - Keyboard map | #pragma mark - Keyboard map | ||||||
|  |  | ||||||
| /*- (void)setKey:(uint16_t)key isPressed:(BOOL)isPressed { | /*- (void)setKey:(uint16_t)key isPressed:(BOOL)isPressed { | ||||||
| @@ -45,15 +36,6 @@ using namespace Commodore::Vic20; | |||||||
|  |  | ||||||
| #pragma mark - Public configuration options | #pragma mark - Public configuration options | ||||||
|  |  | ||||||
| - (void)setUseFastLoadingHack:(BOOL)useFastLoadingHack { |  | ||||||
| 	_useFastLoadingHack = useFastLoadingHack; |  | ||||||
| 	@synchronized(self) { |  | ||||||
| 		Configurable::SelectionSet selection_set; |  | ||||||
| 		append_quick_load_tape_selection(selection_set, useFastLoadingHack ? true : false); |  | ||||||
| 		_vic20->set_selections(selection_set); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| - (void)setCountry:(CSVic20Country)country { | - (void)setCountry:(CSVic20Country)country { | ||||||
| 	_country = country; | 	_country = country; | ||||||
| 	Commodore::Vic20::Region region; | 	Commodore::Vic20::Region region; | ||||||
| @@ -66,7 +48,7 @@ using namespace Commodore::Vic20; | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	@synchronized(self) { | 	@synchronized(self) { | ||||||
| 		_vic20->set_region(region); | 		_vic20.get()->set_region(region); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -74,9 +56,9 @@ using namespace Commodore::Vic20; | |||||||
| 	_memorySize = memorySize; | 	_memorySize = memorySize; | ||||||
| 	@synchronized(self) { | 	@synchronized(self) { | ||||||
| 		switch(memorySize) { | 		switch(memorySize) { | ||||||
| 			case CSVic20MemorySize5Kb: _vic20->set_memory_size(Commodore::Vic20::Default);	break; | 			case CSVic20MemorySize5Kb: _vic20.get()->set_memory_size(Commodore::Vic20::Default);		break; | ||||||
| 			case CSVic20MemorySize8Kb: _vic20->set_memory_size(Commodore::Vic20::ThreeKB);	break; | 			case CSVic20MemorySize8Kb: _vic20.get()->set_memory_size(Commodore::Vic20::ThreeKB);		break; | ||||||
| 			case CSVic20MemorySize32Kb: _vic20->set_memory_size(Commodore::Vic20::ThirtyTwoKB);	break; | 			case CSVic20MemorySize32Kb: _vic20.get()->set_memory_size(Commodore::Vic20::ThirtyTwoKB);	break; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -11,9 +11,6 @@ | |||||||
|  |  | ||||||
| @interface CSZX8081 : CSMachine <CSFastLoading> | @interface CSZX8081 : CSMachine <CSFastLoading> | ||||||
|  |  | ||||||
| @property (nonatomic, assign) BOOL useFastLoadingHack; |  | ||||||
|  |  | ||||||
| @property (nonatomic, assign) BOOL useAutomaticTapeMotorControl; |  | ||||||
| @property (nonatomic, assign) BOOL tapeIsPlaying; | @property (nonatomic, assign) BOOL tapeIsPlaying; | ||||||
|  |  | ||||||
| @end | @end | ||||||
|   | |||||||
| @@ -9,50 +9,25 @@ | |||||||
| #import "CSZX8081.h" | #import "CSZX8081.h" | ||||||
|  |  | ||||||
| #include "ZX8081.hpp" | #include "ZX8081.hpp" | ||||||
| #include "StandardOptions.hpp" | #include "TypedDynamicMachine.hpp" | ||||||
|  |  | ||||||
| @implementation CSZX8081 { | @implementation CSZX8081 { | ||||||
| 	std::unique_ptr<ZX8081::Machine> _zx8081; | 	Machine::TypedDynamicMachine<ZX8081::Machine> _zx8081; | ||||||
| } | } | ||||||
|  |  | ||||||
| - (instancetype)initWithIntendedTarget:(const StaticAnalyser::Target &)target { | - (instancetype)initWithIntendedTarget:(const StaticAnalyser::Target &)target { | ||||||
| 	ZX8081::Machine *machine = ZX8081::Machine::ZX8081(target); | 	_zx8081 = Machine::TypedDynamicMachine<ZX8081::Machine>(ZX8081::Machine::ZX8081(target)); | ||||||
|  | 	return [super initWithMachine:&_zx8081]; | ||||||
| 	self = [super initWithMachine:machine]; |  | ||||||
| 	if(self) { |  | ||||||
| 		_zx8081.reset(machine); |  | ||||||
| 	} |  | ||||||
| 	return self; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| - (NSString *)userDefaultsPrefix {	return @"zx8081";	} | - (NSString *)userDefaultsPrefix {	return @"zx8081";	} | ||||||
|  |  | ||||||
| #pragma mark - Options | #pragma mark - Options | ||||||
|  |  | ||||||
| - (void)setUseFastLoadingHack:(BOOL)useFastLoadingHack { |  | ||||||
| 	@synchronized(self) { |  | ||||||
| 		_useFastLoadingHack = useFastLoadingHack; |  | ||||||
|  |  | ||||||
| 		Configurable::SelectionSet selection_set; |  | ||||||
| 		append_quick_load_tape_selection(selection_set, useFastLoadingHack ? true : false); |  | ||||||
| 		_zx8081->set_selections(selection_set); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| - (void)setTapeIsPlaying:(BOOL)tapeIsPlaying { | - (void)setTapeIsPlaying:(BOOL)tapeIsPlaying { | ||||||
| 	@synchronized(self) { | 	@synchronized(self) { | ||||||
| 		_tapeIsPlaying = tapeIsPlaying; | 		_tapeIsPlaying = tapeIsPlaying; | ||||||
| 		_zx8081->set_tape_is_playing(tapeIsPlaying ? true : false); | 		_zx8081.get()->set_tape_is_playing(tapeIsPlaying ? true : false); | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| - (void)setUseAutomaticTapeMotorControl:(BOOL)useAutomaticTapeMotorControl { |  | ||||||
| 	@synchronized(self) { |  | ||||||
| 		_useAutomaticTapeMotorControl = useAutomaticTapeMotorControl; |  | ||||||
|  |  | ||||||
| 		Configurable::SelectionSet selection_set; |  | ||||||
| 		append_automatic_tape_motor_control_selection(selection_set, useAutomaticTapeMotorControl ? true : false); |  | ||||||
| 		_zx8081->set_selections(selection_set); |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user