From 0d1b63a8c5447ccd52208e914dc64b698845e187 Mon Sep 17 00:00:00 2001
From: Thomas Harte <thomas.harte@gmail.com>
Date: Tue, 7 Nov 2017 22:29:57 -0500
Subject: [PATCH] Switches the Objective-C machine bindings to use the
 set_rom_fetcher path for supplying ROMs, simplifying and unifying.

---
 .../Mac/Clock Signal/Machine/CSMachine.mm     | 20 ++++++
 .../Machine/Wrappers/CSAmstradCPC.mm          | 29 --------
 .../Machine/Wrappers/CSElectron.mm            | 30 --------
 .../Clock Signal/Machine/Wrappers/CSOric.mm   | 19 -----
 .../Clock Signal/Machine/Wrappers/CSVic20.h   |  4 +-
 .../Clock Signal/Machine/Wrappers/CSVic20.mm  | 69 ++-----------------
 .../Clock Signal/Machine/Wrappers/CSZX8081.mm | 10 ---
 7 files changed, 27 insertions(+), 154 deletions(-)

diff --git a/OSBindings/Mac/Clock Signal/Machine/CSMachine.mm b/OSBindings/Mac/Clock Signal/Machine/CSMachine.mm
index 6c7746ac0..c1a3049f2 100644
--- a/OSBindings/Mac/Clock Signal/Machine/CSMachine.mm	
+++ b/OSBindings/Mac/Clock Signal/Machine/CSMachine.mm	
@@ -16,6 +16,9 @@
 #include "JoystickMachine.hpp"
 #include "KeyboardMachine.hpp"
 
+#import "NSBundle+DataResource.h"
+#import "NSData+StdVector.h"
+
 @interface CSMachine()
 - (void)speaker:(Outputs::Speaker *)speaker didCompleteSamples:(const int16_t *)samples length:(int)length;
 - (void)machineDidChangeClockRate;
@@ -69,6 +72,23 @@ struct MachineDelegate: CRTMachine::Machine::Delegate, public LockProtectedDeleg
 		_speakerDelegate.machineAccessLock = _delegateMachineAccessLock;
 
 		_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<uint8_t>>> {
+			NSString *subDirectory = [@"ROMImages/" stringByAppendingString:[NSString stringWithUTF8String:machine.c_str()]];
+			std::vector<std::unique_ptr<std::vector<uint8_t>>> results;
+			for(auto &name: names) {
+				NSData *fileData = [[NSBundle mainBundle] dataForResource:[NSString stringWithUTF8String:name.c_str()] withExtension:nil subdirectory:subDirectory];
+
+				if(!fileData)
+					results.emplace_back(nullptr);
+				else {
+					std::unique_ptr<std::vector<uint8_t>> data(new std::vector<uint8_t>);
+					*data = fileData.stdVector8;
+					results.emplace_back(std::move(data));
+				}
+			}
+
+			return results;
+		});
 	}
 	return self;
 }
diff --git a/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSAmstradCPC.mm b/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSAmstradCPC.mm
index f129bdecb..c3442c2c8 100644
--- a/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSAmstradCPC.mm	
+++ b/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSAmstradCPC.mm	
@@ -10,10 +10,6 @@
 
 #include "AmstradCPC.hpp"
 
-#import "CSMachine+Subclassing.h"
-#import "NSData+StdVector.h"
-#import "NSBundle+DataResource.h"
-
 @implementation CSAmstradCPC {
 	std::unique_ptr<AmstradCPC::Machine> _amstradCPC;
 }
@@ -24,35 +20,10 @@
 	self = [super initWithMachine:machine];
 	if(self) {
 		_amstradCPC.reset(machine);
-
-		NSDictionary *roms = @{
-			@(AmstradCPC::ROMType::OS464) : @"os464",
-			@(AmstradCPC::ROMType::OS664) : @"os664",
-			@(AmstradCPC::ROMType::OS6128) : @"os6128",
-			@(AmstradCPC::ROMType::BASIC464) : @"basic464",
-			@(AmstradCPC::ROMType::BASIC664) : @"basic664",
-			@(AmstradCPC::ROMType::BASIC6128) : @"basic6128",
-			@(AmstradCPC::ROMType::AMSDOS) : @"amsdos",
-		};
-
-		for(NSNumber *key in roms.allKeys) {
-			AmstradCPC::ROMType type = (AmstradCPC::ROMType)key.integerValue;
-			NSString *name = roms[key];
-			NSData *data = [self rom:name];
-			if(data) {
-				_amstradCPC->set_rom(type, data.stdVector8);
-			} else {
-				NSLog(@"Amstrad CPC ROM missing: %@", name);
-			}
-		}
 	}
 	return self;
 }
 
-- (NSData *)rom:(NSString *)name {
-	return [[NSBundle mainBundle] dataForResource:name withExtension:@"rom" subdirectory:@"ROMImages/AmstradCPC"];
-}
-
 - (NSString *)userDefaultsPrefix {	return @"amstradCPC";	}
 
 @end
diff --git a/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSElectron.mm b/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSElectron.mm
index 8a9611ed3..1f0aa2ba0 100644
--- a/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSElectron.mm	
+++ b/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSElectron.mm	
@@ -9,11 +9,7 @@
 #import "CSElectron.h"
 
 #include "Electron.hpp"
-#include "StaticAnalyser.hpp"
 
-#import "CSMachine+Subclassing.h"
-#import "NSData+StdVector.h"
-#import "NSBundle+DataResource.h"
 
 @implementation CSElectron {
 	std::unique_ptr<Electron::Machine> _electron;
@@ -25,38 +21,12 @@
 	self = [super initWithMachine:machine];
 	if(self) {
 		_electron.reset(machine);
-
-		[self setOSROM:[self rom:@"os"]];
-		[self setBASICROM:[self rom:@"basic"]];
-		[self setDFSROM:[self rom:@"DFS-1770-2.20"]];
-
-		NSMutableData *adfs = [[self rom:@"ADFS-E00_1"] mutableCopy];
-		[adfs appendData:[self rom:@"ADFS-E00_2"]];
-		[self setADFSROM:adfs];
 	}
 	return self;
 }
 
-- (NSData *)rom:(NSString *)name {
-	return [[NSBundle mainBundle] dataForResource:name withExtension:@"rom" subdirectory:@"ROMImages/Electron"];
-}
-
 #pragma mark - ROM setting
 
-- (void)setOSROM:(nonnull NSData *)rom		{	[self setROM:rom slot:Electron::ROMSlotOS];		}
-- (void)setBASICROM:(nonnull NSData *)rom	{	[self setROM:rom slot:Electron::ROMSlotBASIC];	}
-- (void)setADFSROM:(nonnull NSData *)rom	{	[self setROM:rom slot:Electron::ROMSlotADFS];	}
-- (void)setDFSROM:(nonnull NSData *)rom		{	[self setROM:rom slot:Electron::ROMSlotDFS];	}
-
-- (void)setROM:(nonnull NSData *)rom slot:(int)slot {
-	if(rom)
-	{
-		@synchronized(self) {
-			_electron->set_rom((Electron::ROMSlot)slot, rom.stdVector8, false);
-		}
-	}
-}
-
 - (NSString *)userDefaultsPrefix {	return @"electron";	}
 
 #pragma mark - Options
diff --git a/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSOric.mm b/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSOric.mm
index 2e9a5daf0..5c5a396f0 100644
--- a/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSOric.mm	
+++ b/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSOric.mm	
@@ -9,11 +9,6 @@
 #import "CSOric.h"
 
 #include "Oric.hpp"
-#include "StaticAnalyser.hpp"
-
-#import "CSMachine+Subclassing.h"
-#import "NSData+StdVector.h"
-#import "NSBundle+DataResource.h"
 
 @implementation CSOric {
 	std::unique_ptr<Oric::Machine> _oric;
@@ -25,24 +20,10 @@
 	self = [super initWithMachine:machine];
 	if(self) {
 		_oric.reset(machine);
-
-		NSData *basic10 = [self rom:@"basic10"];
-		NSData *basic11 = [self rom:@"basic11"];
-		NSData *colour = [self rom:@"colour"];
-		NSData *microdisc = [self rom:@"microdisc"];
-
-		if(basic10)		_oric->set_rom(Oric::BASIC10, basic10.stdVector8);
-		if(basic11)		_oric->set_rom(Oric::BASIC11, basic11.stdVector8);
-		if(colour)		_oric->set_rom(Oric::Colour, colour.stdVector8);
-		if(microdisc)	_oric->set_rom(Oric::Microdisc, microdisc.stdVector8);
 	}
 	return self;
 }
 
-- (NSData *)rom:(NSString *)name {
-	return [[NSBundle mainBundle] dataForResource:name withExtension:@"rom" subdirectory:@"ROMImages/Oric"];
-}
-
 #pragma mark - Options
 
 - (void)setUseFastLoadingHack:(BOOL)useFastLoadingHack {
diff --git a/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSVic20.h b/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSVic20.h
index 8a4af6136..0a71e6e3f 100644
--- a/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSVic20.h	
+++ b/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSVic20.h	
@@ -11,11 +11,11 @@
 
 typedef NS_ENUM(NSInteger, CSVic20Country)
 {
+	CSVic20CountryAmerican,
 	CSVic20CountryDanish,
 	CSVic20CountryEuropean,
 	CSVic20CountryJapanese,
-	CSVic20CountrySwedish,
-	CSVic20CountryAmerican
+	CSVic20CountrySwedish
 };
 
 typedef NS_ENUM(NSInteger, CSVic20MemorySize)
diff --git a/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSVic20.mm b/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSVic20.mm
index fbfbbe20c..0e4977b9b 100644
--- a/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSVic20.mm	
+++ b/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSVic20.mm	
@@ -9,12 +9,6 @@
 #import "CSVic20.h"
 
 #include "Vic20.hpp"
-#include "CommodoreTAP.hpp"
-#include "G64.hpp"
-#include "D64.hpp"
-
-#import "CSmachine+Subclassing.h"
-#import "NSBundle+DataResource.h"
 
 using namespace Commodore::Vic20;
 
@@ -31,41 +25,11 @@ using namespace Commodore::Vic20;
 	self = [super initWithMachine:machine];
 	if(self) {
 		_vic20.reset(machine);
-		[self setDriveROM:[[NSBundle mainBundle] dataForResource:@"1540" withExtension:@"bin" subdirectory:@"ROMImages/Commodore1540"]];
-		[self setBASICROM:[self rom:@"basic"]];
 		[self setCountry:CSVic20CountryEuropean];
 	}
 	return self;
 }
 
-- (NSData *)rom:(NSString *)name {
-	return [[NSBundle mainBundle] dataForResource:name withExtension:@"bin" subdirectory:@"ROMImages/Vic20"];
-}
-
-#pragma mark - ROM setting
-
-- (void)setROM:(nonnull NSData *)rom slot:(ROMSlot)slot {
-	@synchronized(self) {
-		_vic20->set_rom(slot, rom.length, (const uint8_t *)rom.bytes);
-	}
-}
-
-- (void)setKernelROM:(nonnull NSData *)rom {
-	[self setROM:rom slot:Kernel];
-}
-
-- (void)setBASICROM:(nonnull NSData *)rom {
-	[self setROM:rom slot:BASIC];
-}
-
-- (void)setCharactersROM:(nonnull NSData *)rom {
-	[self setROM:rom slot:Characters];
-}
-
-- (void)setDriveROM:(nonnull NSData *)rom {
-	[self setROM:rom slot:Drive];
-}
-
 #pragma mark - Keyboard map
 
 /*- (void)setKey:(uint16_t)key isPressed:(BOOL)isPressed {
@@ -89,40 +53,17 @@ using namespace Commodore::Vic20;
 
 - (void)setCountry:(CSVic20Country)country {
 	_country = country;
-	NSString *charactersROM, *kernelROM;
 	Commodore::Vic20::Region region;
 	switch(country) {
-		case CSVic20CountryDanish:
-			region = Commodore::Vic20::Region::PAL;
-			charactersROM = @"characters-danish";
-			kernelROM = @"kernel-danish";
-		break;
-		case CSVic20CountryEuropean:
-			region = Commodore::Vic20::Region::PAL;
-			charactersROM = @"characters-english";
-			kernelROM = @"kernel-pal";
-		break;
-		case CSVic20CountryJapanese:
-			region = Commodore::Vic20::Region::NTSC;
-			charactersROM = @"characters-japanese";
-			kernelROM = @"kernel-japanese";
-		break;
-		case CSVic20CountrySwedish:
-			region = Commodore::Vic20::Region::PAL;
-			charactersROM = @"characters-swedish";
-			kernelROM = @"kernel-swedish";
-		break;
-		case CSVic20CountryAmerican:
-			region = Commodore::Vic20::Region::NTSC;
-			charactersROM = @"characters-english";
-			kernelROM = @"kernel-ntsc";
-		break;
+		case CSVic20CountryDanish:		region = Commodore::Vic20::Danish;		break;
+		case CSVic20CountryEuropean:	region = Commodore::Vic20::European;	break;
+		case CSVic20CountryJapanese:	region = Commodore::Vic20::Japanese;	break;
+		case CSVic20CountrySwedish:		region = Commodore::Vic20::Swedish;		break;
+		case CSVic20CountryAmerican:	region = Commodore::Vic20::American;	break;
 	}
 
 	@synchronized(self) {
 		_vic20->set_region(region);
-		[self setCharactersROM:[self rom:charactersROM]];
-		[self setKernelROM:[self rom:kernelROM]];
 	}
 }
 
diff --git a/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSZX8081.mm b/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSZX8081.mm
index fb5d07578..800c1b6f7 100644
--- a/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSZX8081.mm	
+++ b/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSZX8081.mm	
@@ -10,10 +10,6 @@
 
 #include "ZX8081.hpp"
 
-#import "CSMachine+Subclassing.h"
-#import "NSData+StdVector.h"
-#import "NSBundle+DataResource.h"
-
 @implementation CSZX8081 {
 	std::unique_ptr<ZX8081::Machine> _zx8081;
 }
@@ -24,16 +20,10 @@
 	self = [super initWithMachine:machine];
 	if(self) {
 		_zx8081.reset(machine);
-		_zx8081->set_rom(ZX8081::ROMType::ZX80, [self rom:@"zx80"].stdVector8);
-		_zx8081->set_rom(ZX8081::ROMType::ZX81, [self rom:@"zx81"].stdVector8);
 	}
 	return self;
 }
 
-- (NSData *)rom:(NSString *)name {
-	return [[NSBundle mainBundle] dataForResource:name withExtension:@"rom" subdirectory:@"ROMImages/ZX8081"];
-}
-
 - (NSString *)userDefaultsPrefix {	return @"zx8081";	}
 
 #pragma mark - Options