diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index faa4e010c..f340bb52b 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -23,7 +23,6 @@ 4B2A53A21D117D36003C6002 /* CSElectron.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B2A539C1D117D36003C6002 /* CSElectron.mm */; }; 4B2A53A31D117D36003C6002 /* CSVic20.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B2A539E1D117D36003C6002 /* CSVic20.mm */; }; 4B2BFC5F1D613E0200BA3AA9 /* TapePRG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2BFC5D1D613E0200BA3AA9 /* TapePRG.cpp */; }; - 4B2E2D951C399D1200138695 /* ElectronDocument.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4B2E2D931C399D1200138695 /* ElectronDocument.xib */; }; 4B2E2D9A1C3A06EC00138695 /* Atari2600.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2E2D971C3A06EC00138695 /* Atari2600.cpp */; }; 4B2E2D9D1C3A070400138695 /* Electron.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2E2D9B1C3A070400138695 /* Electron.cpp */; }; 4B30512D1D989E2200B4FED8 /* Drive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B30512B1D989E2200B4FED8 /* Drive.cpp */; }; @@ -38,8 +37,6 @@ 4B4DC8211D2C2425003C5BF8 /* Vic20.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DC81F1D2C2425003C5BF8 /* Vic20.cpp */; }; 4B4DC8281D2C2470003C5BF8 /* C1540.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DC8261D2C2470003C5BF8 /* C1540.cpp */; }; 4B4DC82B1D2C27A4003C5BF8 /* SerialBus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DC8291D2C27A4003C5BF8 /* SerialBus.cpp */; }; - 4B55CE581C3B7D360093A61B /* Atari2600Document.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B55CE561C3B7D360093A61B /* Atari2600Document.swift */; }; - 4B55CE591C3B7D360093A61B /* ElectronDocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B55CE571C3B7D360093A61B /* ElectronDocument.swift */; }; 4B55CE5D1C3B7D6F0093A61B /* CSOpenGLView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B55CE5C1C3B7D6F0093A61B /* CSOpenGLView.m */; }; 4B55CE5F1C3B7D960093A61B /* MachineDocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B55CE5E1C3B7D960093A61B /* MachineDocument.swift */; }; 4B643F3A1D77AD1900D431D6 /* CSStaticAnalyser.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B643F391D77AD1900D431D6 /* CSStaticAnalyser.mm */; }; @@ -48,10 +45,17 @@ 4B69FB441C4D941400B5F0AA /* TapeUEF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B69FB421C4D941400B5F0AA /* TapeUEF.cpp */; }; 4B69FB461C4D950F00B5F0AA /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B69FB451C4D950F00B5F0AA /* libz.tbd */; }; 4B6C73BD1D387AE500AFCFCA /* DiskController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B6C73BB1D387AE500AFCFCA /* DiskController.cpp */; }; - 4B73C71A1D036BD90074D992 /* Vic20Document.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B73C7191D036BD90074D992 /* Vic20Document.swift */; }; - 4B73C71D1D036C030074D992 /* Vic20Document.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4B73C71B1D036C030074D992 /* Vic20Document.xib */; }; + 4B8FE21B1DA19D5F0090D3CE /* Atari2600Options.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4B8FE2131DA19D5F0090D3CE /* Atari2600Options.xib */; }; + 4B8FE21C1DA19D5F0090D3CE /* MachineDocument.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4B8FE2151DA19D5F0090D3CE /* MachineDocument.xib */; }; + 4B8FE21D1DA19D5F0090D3CE /* ElectronOptions.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4B8FE2171DA19D5F0090D3CE /* ElectronOptions.xib */; }; + 4B8FE21E1DA19D5F0090D3CE /* Vic20Options.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4B8FE2191DA19D5F0090D3CE /* Vic20Options.xib */; }; + 4B8FE2201DA19D7C0090D3CE /* Atari2600OptionsPanel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B8FE21F1DA19D7C0090D3CE /* Atari2600OptionsPanel.swift */; }; + 4B8FE2221DA19FB20090D3CE /* MachinePanel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B8FE2211DA19FB20090D3CE /* MachinePanel.swift */; }; + 4B8FE2271DA1DE2D0090D3CE /* NSBundle+DataResource.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B8FE2261DA1DE2D0090D3CE /* NSBundle+DataResource.m */; }; + 4B8FE2291DA1EDDF0090D3CE /* ElectronOptionsPanel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B8FE2281DA1EDDF0090D3CE /* ElectronOptionsPanel.swift */; }; 4B92EACA1B7C112B00246143 /* 6502TimingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B92EAC91B7C112B00246143 /* 6502TimingTests.swift */; }; 4B96F7221D75119A0058BB2D /* Tape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B96F7201D75119A0058BB2D /* Tape.cpp */; }; + 4B9CCDA11DA279CA0098B625 /* Vic20OptionsPanel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B9CCDA01DA279CA0098B625 /* Vic20OptionsPanel.swift */; }; 4BA22B071D8817CE0008C640 /* Disk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BA22B051D8817CE0008C640 /* Disk.cpp */; }; 4BA61EB01D91515900B3C876 /* NSData+StdVector.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BA61EAF1D91515900B3C876 /* NSData+StdVector.mm */; }; 4BA799951D8B656E0045123D /* StaticAnalyser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BA799931D8B656E0045123D /* StaticAnalyser.cpp */; }; @@ -328,7 +332,6 @@ 4BB697CB1D4B6D3E00248BDF /* TimedEventLoop.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BB697C91D4B6D3E00248BDF /* TimedEventLoop.cpp */; }; 4BB697CE1D4BA44400248BDF /* CommodoreGCR.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BB697CC1D4BA44400248BDF /* CommodoreGCR.cpp */; }; 4BB73EA21B587A5100552FC2 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BB73EA11B587A5100552FC2 /* AppDelegate.swift */; }; - 4BB73EA71B587A5100552FC2 /* Atari2600Document.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4BB73EA51B587A5100552FC2 /* Atari2600Document.xib */; }; 4BB73EA91B587A5100552FC2 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4BB73EA81B587A5100552FC2 /* Assets.xcassets */; }; 4BB73EAC1B587A5100552FC2 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4BB73EAA1B587A5100552FC2 /* MainMenu.xib */; }; 4BB73EB71B587A5100552FC2 /* AllSuiteATests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BB73EB61B587A5100552FC2 /* AllSuiteATests.swift */; }; @@ -420,7 +423,6 @@ 4B2A539E1D117D36003C6002 /* CSVic20.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CSVic20.mm; sourceTree = ""; }; 4B2BFC5D1D613E0200BA3AA9 /* TapePRG.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TapePRG.cpp; sourceTree = ""; }; 4B2BFC5E1D613E0200BA3AA9 /* TapePRG.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = TapePRG.hpp; sourceTree = ""; }; - 4B2E2D941C399D1200138695 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/ElectronDocument.xib; sourceTree = ""; }; 4B2E2D971C3A06EC00138695 /* Atari2600.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Atari2600.cpp; sourceTree = ""; }; 4B2E2D981C3A06EC00138695 /* Atari2600.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Atari2600.hpp; sourceTree = ""; }; 4B2E2D991C3A06EC00138695 /* Atari2600Inputs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Atari2600Inputs.h; sourceTree = ""; }; @@ -450,8 +452,6 @@ 4B4DC8271D2C2470003C5BF8 /* C1540.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = C1540.hpp; sourceTree = ""; }; 4B4DC8291D2C27A4003C5BF8 /* SerialBus.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SerialBus.cpp; sourceTree = ""; }; 4B4DC82A1D2C27A4003C5BF8 /* SerialBus.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = SerialBus.hpp; sourceTree = ""; }; - 4B55CE561C3B7D360093A61B /* Atari2600Document.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Atari2600Document.swift; sourceTree = ""; }; - 4B55CE571C3B7D360093A61B /* ElectronDocument.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ElectronDocument.swift; sourceTree = ""; }; 4B55CE5B1C3B7D6F0093A61B /* CSOpenGLView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSOpenGLView.h; sourceTree = ""; }; 4B55CE5C1C3B7D6F0093A61B /* CSOpenGLView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSOpenGLView.m; sourceTree = ""; }; 4B55CE5E1C3B7D960093A61B /* MachineDocument.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MachineDocument.swift; sourceTree = ""; }; @@ -466,11 +466,20 @@ 4B69FB451C4D950F00B5F0AA /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; }; 4B6C73BB1D387AE500AFCFCA /* DiskController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DiskController.cpp; sourceTree = ""; }; 4B6C73BC1D387AE500AFCFCA /* DiskController.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = DiskController.hpp; sourceTree = ""; }; - 4B73C7191D036BD90074D992 /* Vic20Document.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Vic20Document.swift; sourceTree = ""; }; - 4B73C71C1D036C030074D992 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = "Clock Signal/Base.lproj/Vic20Document.xib"; sourceTree = SOURCE_ROOT; }; + 4B8FE2141DA19D5F0090D3CE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = "Clock Signal/Base.lproj/Atari2600Options.xib"; sourceTree = SOURCE_ROOT; }; + 4B8FE2161DA19D5F0090D3CE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = "Clock Signal/Base.lproj/MachineDocument.xib"; sourceTree = SOURCE_ROOT; }; + 4B8FE2181DA19D5F0090D3CE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = "Clock Signal/Base.lproj/ElectronOptions.xib"; sourceTree = SOURCE_ROOT; }; + 4B8FE21A1DA19D5F0090D3CE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = "Clock Signal/Base.lproj/Vic20Options.xib"; sourceTree = SOURCE_ROOT; }; + 4B8FE21F1DA19D7C0090D3CE /* Atari2600OptionsPanel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Atari2600OptionsPanel.swift; sourceTree = ""; }; + 4B8FE2211DA19FB20090D3CE /* MachinePanel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MachinePanel.swift; sourceTree = ""; }; + 4B8FE2251DA1DE2D0090D3CE /* NSBundle+DataResource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSBundle+DataResource.h"; sourceTree = ""; }; + 4B8FE2261DA1DE2D0090D3CE /* NSBundle+DataResource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSBundle+DataResource.m"; sourceTree = ""; }; + 4B8FE2281DA1EDDF0090D3CE /* ElectronOptionsPanel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ElectronOptionsPanel.swift; sourceTree = ""; }; 4B92EAC91B7C112B00246143 /* 6502TimingTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = 6502TimingTests.swift; sourceTree = ""; }; 4B96F7201D75119A0058BB2D /* Tape.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Tape.cpp; path = ../../StaticAnalyser/Acorn/Tape.cpp; sourceTree = ""; }; 4B96F7211D75119A0058BB2D /* Tape.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Tape.hpp; path = ../../StaticAnalyser/Acorn/Tape.hpp; sourceTree = ""; }; + 4B9CCDA01DA279CA0098B625 /* Vic20OptionsPanel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Vic20OptionsPanel.swift; sourceTree = ""; }; + 4B9CCDA21DA27C3F0098B625 /* CSJoystickMachine.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CSJoystickMachine.h; sourceTree = ""; }; 4BA22B051D8817CE0008C640 /* Disk.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Disk.cpp; path = ../../StaticAnalyser/Commodore/Disk.cpp; sourceTree = ""; }; 4BA22B061D8817CE0008C640 /* Disk.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Disk.hpp; path = ../../StaticAnalyser/Commodore/Disk.hpp; sourceTree = ""; }; 4BA61EAE1D91515900B3C876 /* NSData+StdVector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+StdVector.h"; sourceTree = ""; }; @@ -759,7 +768,6 @@ 4BB697CD1D4BA44400248BDF /* CommodoreGCR.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = CommodoreGCR.hpp; path = Encodings/CommodoreGCR.hpp; sourceTree = ""; }; 4BB73E9E1B587A5100552FC2 /* Clock Signal.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Clock Signal.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 4BB73EA11B587A5100552FC2 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 4BB73EA61B587A5100552FC2 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/Atari2600Document.xib; sourceTree = ""; }; 4BB73EA81B587A5100552FC2 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 4BB73EAB1B587A5100552FC2 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; 4BB73EAD1B587A5100552FC2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -929,16 +937,19 @@ isa = PBXGroup; children = ( 4BBC34241D2208B100FFC9DF /* CSFastLoading.h */, + 4B9CCDA21DA27C3F0098B625 /* CSJoystickMachine.h */, 4B2A53931D117D36003C6002 /* CSKeyboardMachine.h */, 4B2A53951D117D36003C6002 /* CSMachine.h */, 4B2A53941D117D36003C6002 /* CSMachine+Subclassing.h */, 4B643F3C1D77AE5C00D431D6 /* CSMachine+Target.h */, 4B2A53971D117D36003C6002 /* KeyCodes.h */, + 4B8FE2251DA1DE2D0090D3CE /* NSBundle+DataResource.h */, + 4BA61EAE1D91515900B3C876 /* NSData+StdVector.h */, + 4B8FE2261DA1DE2D0090D3CE /* NSBundle+DataResource.m */, 4B2A53961D117D36003C6002 /* CSMachine.mm */, + 4BA61EAF1D91515900B3C876 /* NSData+StdVector.mm */, 4B643F3B1D77AD6D00D431D6 /* StaticAnalyser */, 4B2A53981D117D36003C6002 /* Wrappers */, - 4BA61EAE1D91515900B3C876 /* NSData+StdVector.h */, - 4BA61EAF1D91515900B3C876 /* NSData+StdVector.mm */, ); path = Machine; sourceTree = ""; @@ -1037,13 +1048,15 @@ 4B55CE551C3B7D360093A61B /* Documents */ = { isa = PBXGroup; children = ( - 4B55CE561C3B7D360093A61B /* Atari2600Document.swift */, - 4BB73EA51B587A5100552FC2 /* Atari2600Document.xib */, - 4B55CE571C3B7D360093A61B /* ElectronDocument.swift */, - 4B2E2D931C399D1200138695 /* ElectronDocument.xib */, + 4B8FE21F1DA19D7C0090D3CE /* Atari2600OptionsPanel.swift */, + 4B8FE2281DA1EDDF0090D3CE /* ElectronOptionsPanel.swift */, 4B55CE5E1C3B7D960093A61B /* MachineDocument.swift */, - 4B73C7191D036BD90074D992 /* Vic20Document.swift */, - 4B73C71B1D036C030074D992 /* Vic20Document.xib */, + 4B8FE2211DA19FB20090D3CE /* MachinePanel.swift */, + 4B9CCDA01DA279CA0098B625 /* Vic20OptionsPanel.swift */, + 4B8FE2131DA19D5F0090D3CE /* Atari2600Options.xib */, + 4B8FE2171DA19D5F0090D3CE /* ElectronOptions.xib */, + 4B8FE2151DA19D5F0090D3CE /* MachineDocument.xib */, + 4B8FE2191DA19D5F0090D3CE /* Vic20Options.xib */, ); path = Documents; sourceTree = ""; @@ -1825,11 +1838,12 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 4B2E2D951C399D1200138695 /* ElectronDocument.xib in Resources */, 4BB73EA91B587A5100552FC2 /* Assets.xcassets in Resources */, - 4BB73EA71B587A5100552FC2 /* Atari2600Document.xib in Resources */, - 4B73C71D1D036C030074D992 /* Vic20Document.xib in Resources */, + 4B8FE21B1DA19D5F0090D3CE /* Atari2600Options.xib in Resources */, + 4B8FE21C1DA19D5F0090D3CE /* MachineDocument.xib in Resources */, + 4B8FE21E1DA19D5F0090D3CE /* Vic20Options.xib in Resources */, 4BB73EAC1B587A5100552FC2 /* MainMenu.xib in Resources */, + 4B8FE21D1DA19D5F0090D3CE /* ElectronOptions.xib in Resources */, 4BC9DF451D044FCA00F44158 /* ROMImages in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -2133,16 +2147,14 @@ 4B643F3F1D77B88000D431D6 /* DocumentController.swift in Sources */, 4BA799951D8B656E0045123D /* StaticAnalyser.cpp in Sources */, 4BF829601D8F3C87001BAE39 /* CRC.cpp in Sources */, - 4B55CE591C3B7D360093A61B /* ElectronDocument.swift in Sources */, 4B4DC82B1D2C27A4003C5BF8 /* SerialBus.cpp in Sources */, 4BC3B74F1CD194CC00F86E85 /* Shader.cpp in Sources */, - 4B55CE581C3B7D360093A61B /* Atari2600Document.swift in Sources */, + 4B8FE2221DA19FB20090D3CE /* MachinePanel.swift in Sources */, 4BBB14311CD2CECE00BDB55C /* IntermediateShader.cpp in Sources */, 4BD5F1951D13528900631CD1 /* CSBestEffortUpdater.m in Sources */, 4B96F7221D75119A0058BB2D /* Tape.cpp in Sources */, 4B0BE4281D3481E700D5256B /* DigitalPhaseLockedLoop.cpp in Sources */, 4BD69F941D98760000243FE1 /* AcornADF.cpp in Sources */, - 4B73C71A1D036BD90074D992 /* Vic20Document.swift in Sources */, 4BBF99181C8FBA6F0075DAFB /* TextureTarget.cpp in Sources */, 4BC76E691C98E31700E6EF73 /* FIRFilter.cpp in Sources */, 4B55CE5F1C3B7D960093A61B /* MachineDocument.swift in Sources */, @@ -2168,12 +2180,15 @@ 4B2E2D9D1C3A070400138695 /* Electron.cpp in Sources */, 4BAB62B81D3302CA00DF5BA0 /* PCMTrack.cpp in Sources */, 4B69FB3D1C4D908A00B5F0AA /* Tape.cpp in Sources */, + 4B8FE2291DA1EDDF0090D3CE /* ElectronOptionsPanel.swift in Sources */, 4B55CE5D1C3B7D6F0093A61B /* CSOpenGLView.m in Sources */, 4BB697CB1D4B6D3E00248BDF /* TimedEventLoop.cpp in Sources */, 4BF1354C1D6D2C300054B2EA /* StaticAnalyser.cpp in Sources */, 4B2A53A31D117D36003C6002 /* CSVic20.mm in Sources */, 4B2A53A21D117D36003C6002 /* CSElectron.mm in Sources */, + 4B8FE2201DA19D7C0090D3CE /* Atari2600OptionsPanel.swift in Sources */, 4B2E2D9A1C3A06EC00138695 /* Atari2600.cpp in Sources */, + 4B9CCDA11DA279CA0098B625 /* Vic20OptionsPanel.swift in Sources */, 4B3051301D98ACC600B4FED8 /* Plus3.cpp in Sources */, 4B30512D1D989E2200B4FED8 /* Drive.cpp in Sources */, 4BCA6CC81D9DD9F000C2D7B2 /* CommodoreROM.cpp in Sources */, @@ -2183,6 +2198,7 @@ 4B14145B1B58879D00E04248 /* CPU6502.cpp in Sources */, 4BEE0A6F1D72496600532C7B /* Cartridge.cpp in Sources */, 4BEE0A701D72496600532C7B /* PRG.cpp in Sources */, + 4B8FE2271DA1DE2D0090D3CE /* NSBundle+DataResource.m in Sources */, 4B2A53A01D117D36003C6002 /* CSMachine.mm in Sources */, 4BC91B831D1F160E00884B76 /* CommodoreTAP.cpp in Sources */, 4B2A539F1D117D36003C6002 /* CSAudioQueue.m in Sources */, @@ -2238,30 +2254,36 @@ /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ - 4B2E2D931C399D1200138695 /* ElectronDocument.xib */ = { + 4B8FE2131DA19D5F0090D3CE /* Atari2600Options.xib */ = { isa = PBXVariantGroup; children = ( - 4B2E2D941C399D1200138695 /* Base */, + 4B8FE2141DA19D5F0090D3CE /* Base */, ); - name = ElectronDocument.xib; - path = ..; + name = Atari2600Options.xib; sourceTree = ""; }; - 4B73C71B1D036C030074D992 /* Vic20Document.xib */ = { + 4B8FE2151DA19D5F0090D3CE /* MachineDocument.xib */ = { isa = PBXVariantGroup; children = ( - 4B73C71C1D036C030074D992 /* Base */, + 4B8FE2161DA19D5F0090D3CE /* Base */, ); - name = Vic20Document.xib; + name = MachineDocument.xib; sourceTree = ""; }; - 4BB73EA51B587A5100552FC2 /* Atari2600Document.xib */ = { + 4B8FE2171DA19D5F0090D3CE /* ElectronOptions.xib */ = { isa = PBXVariantGroup; children = ( - 4BB73EA61B587A5100552FC2 /* Base */, + 4B8FE2181DA19D5F0090D3CE /* Base */, ); - name = Atari2600Document.xib; - path = ..; + name = ElectronOptions.xib; + sourceTree = ""; + }; + 4B8FE2191DA19D5F0090D3CE /* Vic20Options.xib */ = { + isa = PBXVariantGroup; + children = ( + 4B8FE21A1DA19D5F0090D3CE /* Base */, + ); + name = Vic20Options.xib; sourceTree = ""; }; 4BB73EAA1B587A5100552FC2 /* MainMenu.xib */ = { diff --git a/OSBindings/Mac/Clock Signal/Base.lproj/Atari2600Document.xib b/OSBindings/Mac/Clock Signal/Base.lproj/Atari2600Options.xib similarity index 72% rename from OSBindings/Mac/Clock Signal/Base.lproj/Atari2600Document.xib rename to OSBindings/Mac/Clock Signal/Base.lproj/Atari2600Options.xib index a66a7f187..c05cc35cd 100644 --- a/OSBindings/Mac/Clock Signal/Base.lproj/Atari2600Document.xib +++ b/OSBindings/Mac/Clock Signal/Base.lproj/Atari2600Options.xib @@ -1,51 +1,17 @@ - - + + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -63,7 +29,7 @@ - + @@ -125,6 +91,13 @@ + + + + + + + diff --git a/OSBindings/Mac/Clock Signal/Base.lproj/ElectronDocument.xib b/OSBindings/Mac/Clock Signal/Base.lproj/ElectronOptions.xib similarity index 72% rename from OSBindings/Mac/Clock Signal/Base.lproj/ElectronDocument.xib rename to OSBindings/Mac/Clock Signal/Base.lproj/ElectronOptions.xib index a74f5d383..39521bbd1 100644 --- a/OSBindings/Mac/Clock Signal/Base.lproj/ElectronDocument.xib +++ b/OSBindings/Mac/Clock Signal/Base.lproj/ElectronOptions.xib @@ -1,36 +1,17 @@ - - + + - + - + - - - - - - - - - - - - - - - - - - - - + @@ -48,7 +29,7 @@ - + @@ -64,7 +45,7 @@ - + @@ -77,6 +58,10 @@ + + + + diff --git a/OSBindings/Mac/Clock Signal/Base.lproj/MachineDocument.xib b/OSBindings/Mac/Clock Signal/Base.lproj/MachineDocument.xib new file mode 100644 index 000000000..ba4710992 --- /dev/null +++ b/OSBindings/Mac/Clock Signal/Base.lproj/MachineDocument.xib @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OSBindings/Mac/Clock Signal/Base.lproj/Vic20Document.xib b/OSBindings/Mac/Clock Signal/Base.lproj/Vic20Options.xib similarity index 73% rename from OSBindings/Mac/Clock Signal/Base.lproj/Vic20Document.xib rename to OSBindings/Mac/Clock Signal/Base.lproj/Vic20Options.xib index d96154920..4c477e080 100644 --- a/OSBindings/Mac/Clock Signal/Base.lproj/Vic20Document.xib +++ b/OSBindings/Mac/Clock Signal/Base.lproj/Vic20Options.xib @@ -1,49 +1,17 @@ - - + + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -59,7 +27,7 @@ - + @@ -86,7 +54,7 @@ - + @@ -105,7 +73,7 @@ - + @@ -125,6 +93,12 @@ + + + + + + diff --git a/OSBindings/Mac/Clock Signal/Document Controller/DocumentController.swift b/OSBindings/Mac/Clock Signal/Document Controller/DocumentController.swift index b2c7d2e18..01ec875bb 100644 --- a/OSBindings/Mac/Clock Signal/Document Controller/DocumentController.swift +++ b/OSBindings/Mac/Clock Signal/Document Controller/DocumentController.swift @@ -9,18 +9,4 @@ import Cocoa class DocumentController: NSDocumentController { - override func makeDocument(withContentsOf url: URL, ofType typeName: String) throws -> NSDocument { - if let analyser = CSStaticAnalyser(fileAt: url) { - if let documentClass = analyser.documentClass as? NSDocument.Type { - let document = documentClass.init() - if let machineDocument = document as? MachineDocument { - machineDocument.displayName = analyser.displayName - machineDocument.configureAs(analyser) - return machineDocument - } - } - } - - return try super.makeDocument(withContentsOf: url, ofType: typeName) - } } diff --git a/OSBindings/Mac/Clock Signal/Documents/Atari2600Document.swift b/OSBindings/Mac/Clock Signal/Documents/Atari2600Document.swift deleted file mode 100644 index e48144448..000000000 --- a/OSBindings/Mac/Clock Signal/Documents/Atari2600Document.swift +++ /dev/null @@ -1,107 +0,0 @@ -// -// Atari2600Document.swift -// Clock Signal -// -// Created by Thomas Harte on 16/07/2015. -// Copyright © 2015 Thomas Harte. All rights reserved. -// - -import Cocoa - -class Atari2600Document: MachineDocument { - - fileprivate var atari2600 = CSAtari2600() - override var machine: CSMachine! { - get { - return atari2600 - } - } - override var name: String! { - get { - return "atari2600" - } - } - - // MARK: NSDocument overrides - override class func autosavesInPlace() -> Bool { - return true - } - - override var windowNibName: String? { - return "Atari2600Document" - } - - override func windowControllerDidLoadNib(_ aController: NSWindowController) { - super.windowControllerDidLoadNib(aController) - - // push whatever settings the switches have in the NIB into the emulation - pushSwitchValues() - - // show the options window but ensure the OpenGL view is key - showOptions(self) - self.openGLView.window?.makeKey() - } - - // MARK: CSOpenGLViewResponderDelegate - fileprivate func inputForKey(_ event: NSEvent) -> Atari2600DigitalInput? { - switch event.keyCode { - case 123: return Atari2600DigitalInputJoy1Left - case 126: return Atari2600DigitalInputJoy1Up - case 124: return Atari2600DigitalInputJoy1Right - case 125: return Atari2600DigitalInputJoy1Down - case 0: return Atari2600DigitalInputJoy1Fire - default: - Swift.print("\(event.keyCode)") - return nil - } - } - - override func keyDown(_ event: NSEvent) { - super.keyDown(event) - - if let input = inputForKey(event) { - atari2600.setState(true, for: input) - } - - if event.keyCode == 36 { - atari2600.setResetLineEnabled(true) - } - } - - override func keyUp(_ event: NSEvent) { - super.keyUp(event) - - if let input = inputForKey(event) { - atari2600.setState(false, for: input) - } - - if event.keyCode == 36 { - atari2600.setResetLineEnabled(false) - } - } - - // MARK: Options - @IBOutlet var resetButton: NSButton! - @IBOutlet var selectButton: NSButton! - @IBOutlet var colourButton: NSButton! - @IBOutlet var leftPlayerDifficultyButton: NSButton! - @IBOutlet var rightPlayerDifficultyButton: NSButton! - - @IBAction func optionDidChange(_ sender: AnyObject!) { - pushSwitchValues() - } - - fileprivate func pushSwitchValues() { - atari2600.colourButton = colourButton.state == NSOnState - atari2600.leftPlayerDifficultyButton = leftPlayerDifficultyButton.state == NSOnState - atari2600.rightPlayerDifficultyButton = rightPlayerDifficultyButton.state == NSOnState - } - - @IBAction func optionWasPressed(_ sender: NSButton!) { - if sender == resetButton { - atari2600.pressResetButton() - } else { - atari2600.pressSelectButton() - } - } -} diff --git a/OSBindings/Mac/Clock Signal/Documents/Atari2600OptionsPanel.swift b/OSBindings/Mac/Clock Signal/Documents/Atari2600OptionsPanel.swift new file mode 100644 index 000000000..7f343a200 --- /dev/null +++ b/OSBindings/Mac/Clock Signal/Documents/Atari2600OptionsPanel.swift @@ -0,0 +1,39 @@ +// +// Atari2600Options.swift +// Clock Signal +// +// Created by Thomas Harte on 02/10/2016. +// Copyright © 2016 Thomas Harte. All rights reserved. +// + +class Atari2600OptionsPanel: MachinePanel { + var atari2600: CSAtari2600! { + get { + return self.machine as! CSAtari2600 + } + } + + @IBOutlet var resetButton: NSButton! + @IBOutlet var selectButton: NSButton! + @IBOutlet var colourButton: NSButton! + @IBOutlet var leftPlayerDifficultyButton: NSButton! + @IBOutlet var rightPlayerDifficultyButton: NSButton! + + @IBAction func optionDidChange(_ sender: AnyObject!) { + pushSwitchValues() + } + + fileprivate func pushSwitchValues() { + atari2600.colourButton = colourButton.state == NSOnState + atari2600.leftPlayerDifficultyButton = leftPlayerDifficultyButton.state == NSOnState + atari2600.rightPlayerDifficultyButton = rightPlayerDifficultyButton.state == NSOnState + } + + @IBAction func optionWasPressed(_ sender: NSButton!) { + if sender == resetButton { + atari2600.pressResetButton() + } else { + atari2600.pressSelectButton() + } + } +} diff --git a/OSBindings/Mac/Clock Signal/Documents/ElectronDocument.swift b/OSBindings/Mac/Clock Signal/Documents/ElectronDocument.swift deleted file mode 100644 index a577b2b77..000000000 --- a/OSBindings/Mac/Clock Signal/Documents/ElectronDocument.swift +++ /dev/null @@ -1,99 +0,0 @@ -// -// ElectronDocument.swift -// Clock Signal -// -// Created by Thomas Harte on 03/01/2016. -// Copyright © 2016 Thomas Harte. All rights reserved. -// - -import Foundation -import AudioToolbox - -class ElectronDocument: MachineDocument { - - fileprivate lazy var electron = CSElectron() - override var machine: CSMachine! { - get { - return electron - } - } - override var name: String! { - get { - return "electron" - } - } - - override func aspectRatio() -> NSSize { - return NSSize(width: 11.0, height: 10.0) - } - - fileprivate func rom(_ name: String) -> Data? { - return dataForResource(name, ofType: "rom", inDirectory: "ROMImages/Electron") - } - - override init() { - super.init(); - - if let os = rom("os"), let basic = rom("basic") { - self.electron.setOSROM(os) - self.electron.setBASICROM(basic) - } - if let dfs = rom("DFS-1770-2.20") { - self.electron.setDFSROM(dfs) - } - if let adfs1 = rom("ADFS-E00_1"), let adfs2 = rom("ADFS-E00_2") { - var fullADFS = adfs1 - fullADFS.append(adfs2) - self.electron.setADFSROM(fullADFS as Data) - } - } - -// override func windowControllerDidLoadNib(_ aController: NSWindowController) { -// super.windowControllerDidLoadNib(aController) -// } - - override var windowNibName: String? { - return "ElectronDocument" - } - -/* override func readFromURL(url: NSURL, ofType typeName: String) throws { - if let pathExtension = url.pathExtension { - switch pathExtension.lowercaseString { - case "uef": - electron.openUEFAtURL(url) - return - default: break; - } - } - - let fileWrapper = try NSFileWrapper(URL: url, options: NSFileWrapperReadingOptions(rawValue: 0)) - try self.readFromFileWrapper(fileWrapper, ofType: typeName) - } - - override func readFromData(data: NSData, ofType typeName: String) throws { - if let plus1ROM = rom("plus1") { - electron.setROM(plus1ROM, slot: 12) - } - electron.setROM(data, slot: 15) - }*/ - - // MARK: IBActions - @IBOutlet var displayTypeButton: NSPopUpButton? - @IBAction func setDisplayType(_ sender: NSPopUpButton!) { - electron.useTelevisionOutput = (sender.indexOfSelectedItem == 1) - UserDefaults.standard.set(sender.indexOfSelectedItem, forKey: self.displayTypeUserDefaultsKey) - } - - fileprivate let displayTypeUserDefaultsKey = "electron.displayType" - override func establishStoredOptions() { - super.establishStoredOptions() - let standardUserDefaults = UserDefaults.standard - standardUserDefaults.register(defaults: [ - displayTypeUserDefaultsKey: 0, - ]) - - let displayType = standardUserDefaults.integer(forKey: self.displayTypeUserDefaultsKey) - electron.useTelevisionOutput = (displayType == 1) - self.displayTypeButton?.selectItem(at: displayType) - } -} diff --git a/OSBindings/Mac/Clock Signal/Documents/ElectronOptionsPanel.swift b/OSBindings/Mac/Clock Signal/Documents/ElectronOptionsPanel.swift new file mode 100644 index 000000000..44926194b --- /dev/null +++ b/OSBindings/Mac/Clock Signal/Documents/ElectronOptionsPanel.swift @@ -0,0 +1,35 @@ +// +// ElectronOptionsPanel.swift +// Clock Signal +// +// Created by Thomas Harte on 02/10/2016. +// Copyright © 2016 Thomas Harte. All rights reserved. +// + +class ElectronOptionsPanel: MachinePanel { + var electron: CSElectron! { + get { + return self.machine as! CSElectron + } + } + + fileprivate let displayTypeUserDefaultsKey = "electron.displayType" + + @IBOutlet var displayTypeButton: NSPopUpButton? + @IBAction func setDisplayType(_ sender: NSPopUpButton!) { + electron.useTelevisionOutput = (sender.indexOfSelectedItem == 1) + UserDefaults.standard.set(sender.indexOfSelectedItem, forKey: self.displayTypeUserDefaultsKey) + } + + override func establishStoredOptions() { + super.establishStoredOptions() + let standardUserDefaults = UserDefaults.standard + standardUserDefaults.register(defaults: [ + displayTypeUserDefaultsKey: 0, + ]) + + let displayType = standardUserDefaults.integer(forKey: self.displayTypeUserDefaultsKey) + electron.useTelevisionOutput = (displayType == 1) + self.displayTypeButton?.selectItem(at: displayType) + } +} diff --git a/OSBindings/Mac/Clock Signal/Documents/MachineDocument.swift b/OSBindings/Mac/Clock Signal/Documents/MachineDocument.swift index 03c3333c0..5ef302a53 100644 --- a/OSBindings/Mac/Clock Signal/Documents/MachineDocument.swift +++ b/OSBindings/Mac/Clock Signal/Documents/MachineDocument.swift @@ -20,11 +20,7 @@ class MachineDocument: { lazy var actionLock = NSLock() lazy var drawLock = NSLock() - var machine: CSMachine! { - get { - return nil - } - } + var machine: CSMachine! var name: String! { get { return nil @@ -42,7 +38,7 @@ class MachineDocument: } } - @IBOutlet weak var optionsPanel: NSPanel! + @IBOutlet var optionsPanel: MachinePanel! @IBAction func showOptions(_ sender: AnyObject!) { optionsPanel?.setIsVisible(true) } @@ -54,6 +50,10 @@ class MachineDocument: return updater }() + override var windowNibName: String? { + return "MachineDocument" + } + override func windowControllerDidLoadNib(_ aController: NSWindowController) { super.windowControllerDidLoadNib(aController) @@ -66,7 +66,7 @@ class MachineDocument: setupClockRate() self.machine.delegate = self - establishStoredOptions() + self.optionsPanel?.establishStoredOptions() } func machineDidChangeClockRate(_ machine: CSMachine!) { @@ -104,7 +104,23 @@ class MachineDocument: // MARK: configuring func configureAs(_ analysis: CSStaticAnalyser) { + if let machine = analysis.newMachine() { + self.machine = machine + } analysis.apply(to: self.machine) + + if let optionsPanelNibName = analysis.optionsPanelNibName { + Bundle.main.loadNibNamed(optionsPanelNibName, owner: self, topLevelObjects: nil) + self.optionsPanel.machine = self.machine + showOptions(self) + } + } + + override func read(from url: URL, ofType typeName: String) throws { + if let analyser = CSStaticAnalyser(fileAt: url) { + self.displayName = analyser.displayName + self.configureAs(analyser) + } } // MARK: the pasteboard @@ -128,15 +144,6 @@ class MachineDocument: } } - // MARK: Utilities for children - func dataForResource(_ name : String, ofType type: String, inDirectory directory: String) -> Data? { - if let path = Bundle.main.path(forResource: name, ofType: type, inDirectory: directory) { - return (try? Data(contentsOf: URL(fileURLWithPath: path))) - } - - return nil - } - // MARK: CSAudioQueueDelegate final func audioQueueDidCompleteBuffer(_ audioQueue: CSAudioQueue) { bestEffortUpdater.update() @@ -156,23 +163,41 @@ class MachineDocument: throw NSError(domain: NSOSStatusErrorDomain, code: unimpErr, userInfo: nil) } - // MARK: Key forwarding + // MARK: Input management fileprivate func withKeyboardMachine(_ action: (CSKeyboardMachine) -> ()) { if let keyboardMachine = self.machine as? CSKeyboardMachine { action(keyboardMachine) } } + fileprivate func withJoystickMachine(_ action: (CSJoystickMachine) -> ()) { + if let joystickMachine = self.machine as? CSJoystickMachine { + action(joystickMachine) + } + } + + fileprivate func sendJoystickEvent(_ machine: CSJoystickMachine, keyCode: UInt16, isPressed: Bool) { + switch keyCode { + case 123: machine.setDirection(.left, onPad: 0, isPressed: isPressed) + case 126: machine.setDirection(.up, onPad: 0, isPressed: isPressed) + case 124: machine.setDirection(.right, onPad: 0, isPressed: isPressed) + case 125: machine.setDirection(.down, onPad: 0, isPressed: isPressed) + default: machine.setButtonAt(0, onPad: 0, isPressed: isPressed) + } + } + func windowDidResignKey(_ notification: Notification) { self.withKeyboardMachine { $0.clearAllKeys() } } func keyDown(_ event: NSEvent) { self.withKeyboardMachine { $0.setKey(event.keyCode, isPressed: true) } + self.withJoystickMachine { sendJoystickEvent($0, keyCode: event.keyCode, isPressed: false) } } func keyUp(_ event: NSEvent) { self.withKeyboardMachine { $0.setKey(event.keyCode, isPressed: false) } + self.withJoystickMachine { sendJoystickEvent($0, keyCode: event.keyCode, isPressed: true) } } func flagsChanged(_ newModifiers: NSEvent) { @@ -183,36 +208,4 @@ class MachineDocument: $0.setKey(VK_Option, isPressed: newModifiers.modifierFlags.contains(.option)) } } - - // MARK: IBActions - final func prefixedUserDefaultsKey(_ key: String) -> String { - return "\(self.name).\(key)" - } - var fastLoadingUserDefaultsKey: String { - get { - return prefixedUserDefaultsKey("fastLoading") - } - } - - @IBOutlet var fastLoadingButton: NSButton? - @IBAction func setFastLoading(_ sender: NSButton!) { - if let fastLoadingMachine = machine as? CSFastLoading { - let useFastLoadingHack = sender.state == NSOnState - fastLoadingMachine.useFastLoadingHack = useFastLoadingHack - UserDefaults.standard.set(useFastLoadingHack, forKey: fastLoadingUserDefaultsKey) - } - } - - func establishStoredOptions() { - let standardUserDefaults = UserDefaults.standard - standardUserDefaults.register(defaults: [ - fastLoadingUserDefaultsKey: true - ]) - - if let fastLoadingMachine = machine as? CSFastLoading { - let useFastLoadingHack = standardUserDefaults.bool(forKey: self.fastLoadingUserDefaultsKey) - fastLoadingMachine.useFastLoadingHack = useFastLoadingHack - self.fastLoadingButton?.state = useFastLoadingHack ? NSOnState : NSOffState - } - } } diff --git a/OSBindings/Mac/Clock Signal/Documents/MachinePanel.swift b/OSBindings/Mac/Clock Signal/Documents/MachinePanel.swift new file mode 100644 index 000000000..ff3dbc826 --- /dev/null +++ b/OSBindings/Mac/Clock Signal/Documents/MachinePanel.swift @@ -0,0 +1,45 @@ +// +// MachinePanel.swift +// Clock Signal +// +// Created by Thomas Harte on 02/10/2016. +// Copyright © 2016 Thomas Harte. All rights reserved. +// + +import Cocoa + +class MachinePanel: NSPanel { + var machine: CSMachine! + + // MARK: IBActions + final func prefixedUserDefaultsKey(_ key: String) -> String { + return "\(self.machine.userDefaultsPrefix).\(key)" + } + var fastLoadingUserDefaultsKey: String { + get { + return prefixedUserDefaultsKey("fastLoading") + } + } + + @IBOutlet var fastLoadingButton: NSButton? + @IBAction func setFastLoading(_ sender: NSButton!) { + if let fastLoadingMachine = machine as? CSFastLoading { + let useFastLoadingHack = sender.state == NSOnState + fastLoadingMachine.useFastLoadingHack = useFastLoadingHack + UserDefaults.standard.set(useFastLoadingHack, forKey: fastLoadingUserDefaultsKey) + } + } + + func establishStoredOptions() { + let standardUserDefaults = UserDefaults.standard + standardUserDefaults.register(defaults: [ + fastLoadingUserDefaultsKey: true + ]) + + if let fastLoadingMachine = machine as? CSFastLoading { + let useFastLoadingHack = standardUserDefaults.bool(forKey: self.fastLoadingUserDefaultsKey) + fastLoadingMachine.useFastLoadingHack = useFastLoadingHack + self.fastLoadingButton?.state = useFastLoadingHack ? NSOnState : NSOffState + } + } +} diff --git a/OSBindings/Mac/Clock Signal/Documents/Vic20Document.swift b/OSBindings/Mac/Clock Signal/Documents/Vic20OptionsPanel.swift similarity index 65% rename from OSBindings/Mac/Clock Signal/Documents/Vic20Document.swift rename to OSBindings/Mac/Clock Signal/Documents/Vic20OptionsPanel.swift index 249b7f9be..f491b6e1c 100644 --- a/OSBindings/Mac/Clock Signal/Documents/Vic20Document.swift +++ b/OSBindings/Mac/Clock Signal/Documents/Vic20OptionsPanel.swift @@ -1,50 +1,17 @@ // -// Vic20Document.swift +// Vic20OptionsPanel.swift // Clock Signal // -// Created by Thomas Harte on 04/06/2016. +// Created by Thomas Harte on 03/10/2016. // Copyright © 2016 Thomas Harte. All rights reserved. // -import Foundation - -class Vic20Document: MachineDocument { - - fileprivate lazy var vic20 = CSVic20() - override var machine: CSMachine! { +class Vic20OptionsPanel: MachinePanel { + var vic20: CSVic20! { get { - return vic20 + return self.machine as! CSVic20 } } - override var name: String! { - get { - return "vic20" - } - } - - // MARK: NSDocument overrides - override init() { - super.init() - - if let drive = dataForResource("1540", ofType: "bin", inDirectory: "ROMImages/Commodore1540") { - vic20.setDriveROM(drive) - } - - establishStoredOptions() - } - - override class func autosavesInPlace() -> Bool { - return true - } - - override var windowNibName: String? { - return "Vic20Document" - } - - // MARK: machine setup - fileprivate func rom(_ name: String) -> Data? { - return dataForResource(name, ofType: "bin", inDirectory: "ROMImages/Vic20") - } // MARK: automatic loading tick box @IBOutlet var loadAutomaticallyButton: NSButton? @@ -70,39 +37,19 @@ class Vic20Document: MachineDocument { } fileprivate func setCountry(_ countryID: Int) { - var charactersROM: String? - var kernelROM: String? switch countryID { case 0: // Danish - charactersROM = "characters-danish" - kernelROM = "kernel-danish" - vic20.region = .PAL + vic20.country = .danish case 1: // European - charactersROM = "characters-english" - kernelROM = "kernel-pal" - vic20.region = .PAL + vic20.country = .european case 2: // Japanese - charactersROM = "characters-japanese" - kernelROM = "kernel-japanese" - vic20.region = .NTSC + vic20.country = .japanese case 3: // Swedish - charactersROM = "characters-swedish" - kernelROM = "kernel-swedish" - vic20.region = .PAL + vic20.country = .swedish case 4: // US - charactersROM = "characters-english" - kernelROM = "kernel-ntsc" - vic20.region = .NTSC + vic20.country = .american default: break } - - if let charactersROM = charactersROM, let kernelROM = kernelROM { - if let kernel = rom(kernelROM), let basic = rom("basic"), let characters = rom(charactersROM) { - vic20.setKernelROM(kernel) - vic20.setBASICROM(basic) - vic20.setCharactersROM(characters) - } - } } // MARK: memory model selector diff --git a/OSBindings/Mac/Clock Signal/Info.plist b/OSBindings/Mac/Clock Signal/Info.plist index 5db4e8201..81a0c5b10 100644 --- a/OSBindings/Mac/Clock Signal/Info.plist +++ b/OSBindings/Mac/Clock Signal/Info.plist @@ -25,7 +25,7 @@ LSTypeIsPackage 0 NSDocumentClass - $(PRODUCT_MODULE_NAME).Atari2600Document + $(PRODUCT_MODULE_NAME).MachineDocument CFBundleTypeExtensions @@ -41,7 +41,7 @@ LSTypeIsPackage 0 NSDocumentClass - $(PRODUCT_MODULE_NAME).ElectronDocument + $(PRODUCT_MODULE_NAME).MachineDocument CFBundleTypeExtensions @@ -57,7 +57,7 @@ LSTypeIsPackage 0 NSDocumentClass - $(PRODUCT_MODULE_NAME).ElectronDocument + $(PRODUCT_MODULE_NAME).MachineDocument CFBundleTypeExtensions @@ -72,7 +72,7 @@ LSTypeIsPackage 0 NSDocumentClass - $(PRODUCT_MODULE_NAME).ElectronDocument + $(PRODUCT_MODULE_NAME).MachineDocument CFBundleTypeExtensions @@ -86,7 +86,7 @@ LSTypeIsPackage 0 NSDocumentClass - $(PRODUCT_MODULE_NAME).Vic20Document + $(PRODUCT_MODULE_NAME).MachineDocument CFBundleTypeExtensions @@ -100,7 +100,7 @@ LSTypeIsPackage 0 NSDocumentClass - $(PRODUCT_MODULE_NAME).Vic20Document + $(PRODUCT_MODULE_NAME).MachineDocument CFBundleTypeExtensions @@ -114,7 +114,7 @@ LSTypeIsPackage 0 NSDocumentClass - $(PRODUCT_MODULE_NAME).Vic20Document + $(PRODUCT_MODULE_NAME).MachineDocument CFBundleTypeExtensions @@ -128,7 +128,7 @@ LSTypeIsPackage 0 NSDocumentClass - $(PRODUCT_MODULE_NAME).Vic20Document + $(PRODUCT_MODULE_NAME).MachineDocument CFBundleTypeExtensions @@ -144,7 +144,7 @@ CFBundleTypeRole Viewer NSDocumentClass - $(PRODUCT_MODULE_NAME).ElectronDocument + $(PRODUCT_MODULE_NAME).MachineDocument CFBundleExecutable diff --git a/OSBindings/Mac/Clock Signal/Machine/CSJoystickMachine.h b/OSBindings/Mac/Clock Signal/Machine/CSJoystickMachine.h new file mode 100644 index 000000000..ed1cc5e67 --- /dev/null +++ b/OSBindings/Mac/Clock Signal/Machine/CSJoystickMachine.h @@ -0,0 +1,22 @@ +// +// CSJoystickMachine.h +// Clock Signal +// +// Created by Thomas Harte on 03/10/2016. +// Copyright © 2016 Thomas Harte. All rights reserved. +// + +typedef NS_ENUM(NSInteger, CSJoystickDirection) +{ + CSJoystickDirectionUp, + CSJoystickDirectionDown, + CSJoystickDirectionLeft, + CSJoystickDirectionRight +}; + +@protocol CSJoystickMachine + +- (void)setButtonAtIndex:(NSUInteger)button onPad:(NSUInteger)pad isPressed:(BOOL)isPressed; +- (void)setDirection:(CSJoystickDirection)direction onPad:(NSUInteger)pad isPressed:(BOOL)isPressed; + +@end diff --git a/OSBindings/Mac/Clock Signal/Machine/CSMachine.h b/OSBindings/Mac/Clock Signal/Machine/CSMachine.h index 843644503..8b601279c 100644 --- a/OSBindings/Mac/Clock Signal/Machine/CSMachine.h +++ b/OSBindings/Mac/Clock Signal/Machine/CSMachine.h @@ -33,6 +33,8 @@ @property (nonatomic, readonly) double clockRate; @property (nonatomic, readonly) BOOL clockIsUnlimited; +@property (nonatomic, readonly) NSString *userDefaultsPrefix; + - (void)paste:(NSString *)string; @end diff --git a/OSBindings/Mac/Clock Signal/Machine/NSBundle+DataResource.h b/OSBindings/Mac/Clock Signal/Machine/NSBundle+DataResource.h new file mode 100644 index 000000000..46833748c --- /dev/null +++ b/OSBindings/Mac/Clock Signal/Machine/NSBundle+DataResource.h @@ -0,0 +1,15 @@ +// +// NSBundle+DataResource.h +// Clock Signal +// +// Created by Thomas Harte on 02/10/2016. +// Copyright © 2016 Thomas Harte. All rights reserved. +// + +#import + +@interface NSBundle (DataResource) + +- (nullable NSData *)dataForResource:(nullable NSString *)resource withExtension:(nullable NSString *)extension subdirectory:(nullable NSString *)subdirectory; + +@end diff --git a/OSBindings/Mac/Clock Signal/Machine/NSBundle+DataResource.m b/OSBindings/Mac/Clock Signal/Machine/NSBundle+DataResource.m new file mode 100644 index 000000000..46c9e4035 --- /dev/null +++ b/OSBindings/Mac/Clock Signal/Machine/NSBundle+DataResource.m @@ -0,0 +1,20 @@ +// +// NSBundle+DataResource.m +// Clock Signal +// +// Created by Thomas Harte on 02/10/2016. +// Copyright © 2016 Thomas Harte. All rights reserved. +// + +#import "NSBundle+DataResource.h" + +@implementation NSBundle (DataResource) + +- (NSData *)dataForResource:(NSString *)resource withExtension:(NSString *)extension subdirectory:(NSString *)subdirectory +{ + NSURL *url = [self URLForResource:resource withExtension:extension subdirectory:subdirectory]; + if(!url) return nil; + return [NSData dataWithContentsOfURL:url]; +} + +@end diff --git a/OSBindings/Mac/Clock Signal/Machine/StaticAnalyser/CSStaticAnalyser.h b/OSBindings/Mac/Clock Signal/Machine/StaticAnalyser/CSStaticAnalyser.h index c0ef69354..90bf509a6 100644 --- a/OSBindings/Mac/Clock Signal/Machine/StaticAnalyser/CSStaticAnalyser.h +++ b/OSBindings/Mac/Clock Signal/Machine/StaticAnalyser/CSStaticAnalyser.h @@ -14,8 +14,11 @@ - (instancetype)initWithFileAtURL:(NSURL *)url; -@property(nonatomic, readonly) Class documentClass; +@property(nonatomic, readonly) NSString *optionsPanelNibName; +- (CSMachine *)newMachine; + @property(nonatomic, readonly) NSString *displayName; + - (void)applyToMachine:(CSMachine *)machine; @end diff --git a/OSBindings/Mac/Clock Signal/Machine/StaticAnalyser/CSStaticAnalyser.mm b/OSBindings/Mac/Clock Signal/Machine/StaticAnalyser/CSStaticAnalyser.mm index 29f985e3e..1cf33e3ee 100644 --- a/OSBindings/Mac/Clock Signal/Machine/StaticAnalyser/CSStaticAnalyser.mm +++ b/OSBindings/Mac/Clock Signal/Machine/StaticAnalyser/CSStaticAnalyser.mm @@ -34,18 +34,28 @@ return self; } -- (Class)documentClass +- (NSString *)optionsPanelNibName { switch(_target.machine) { - case StaticAnalyser::Target::Electron: return [ElectronDocument class]; - case StaticAnalyser::Target::Vic20: return [Vic20Document class]; - case StaticAnalyser::Target::Atari2600: return [Atari2600Document class]; + case StaticAnalyser::Target::Electron: return @"ElectronOptions"; + case StaticAnalyser::Target::Vic20: return @"Vic20Options"; + case StaticAnalyser::Target::Atari2600: return @"Atari2600Options"; } return nil; } +- (CSMachine *)newMachine +{ + switch(_target.machine) + { + case StaticAnalyser::Target::Electron: return [[CSElectron alloc] init]; + case StaticAnalyser::Target::Vic20: return [[CSVic20 alloc] init]; + case StaticAnalyser::Target::Atari2600: return [[CSAtari2600 alloc] init]; + } +} + - (void)applyToMachine:(CSMachine *)machine { [machine applyTarget:_target]; diff --git a/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSAtari2600.h b/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSAtari2600.h index 3fa47b124..7026f02d7 100644 --- a/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSAtari2600.h +++ b/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSAtari2600.h @@ -8,10 +8,10 @@ #include "CSMachine.h" #include "Atari2600Inputs.h" +#import "CSJoystickMachine.h" -@interface CSAtari2600 : CSMachine +@interface CSAtari2600 : CSMachine -- (void)setState:(BOOL)state forDigitalInput:(Atari2600DigitalInput)digitalInput; - (void)setResetLineEnabled:(BOOL)enabled; @property (nonatomic, assign) BOOL colourButton; diff --git a/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSAtari2600.mm b/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSAtari2600.mm index 44a16dee9..bf268669b 100644 --- a/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSAtari2600.mm +++ b/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSAtari2600.mm @@ -49,9 +49,23 @@ struct CRTDelegate: public Outputs::CRT::Delegate { } } -- (void)setState:(BOOL)state forDigitalInput:(Atari2600DigitalInput)digitalInput { +- (void)setDirection:(CSJoystickDirection)direction onPad:(NSUInteger)pad isPressed:(BOOL)isPressed { + Atari2600DigitalInput input; + switch(direction) + { + case CSJoystickDirectionUp: input = pad ? Atari2600DigitalInputJoy2Up : Atari2600DigitalInputJoy1Up; break; + case CSJoystickDirectionDown: input = pad ? Atari2600DigitalInputJoy2Down : Atari2600DigitalInputJoy1Down; break; + case CSJoystickDirectionLeft: input = pad ? Atari2600DigitalInputJoy2Left : Atari2600DigitalInputJoy1Left; break; + case CSJoystickDirectionRight: input = pad ? Atari2600DigitalInputJoy2Right : Atari2600DigitalInputJoy1Right; break; + } @synchronized(self) { - _atari2600.set_digital_input(digitalInput, state ? true : false); + _atari2600.set_digital_input(input, isPressed ? true : false); + } +} + +- (void)setButtonAtIndex:(NSUInteger)button onPad:(NSUInteger)pad isPressed:(BOOL)isPressed { + @synchronized(self) { + _atari2600.set_digital_input(pad ? Atari2600DigitalInputJoy2Fire : Atari2600DigitalInputJoy1Fire, isPressed ? true : false); } } @@ -115,4 +129,6 @@ struct CRTDelegate: public Outputs::CRT::Delegate { [self toggleSwitch:Atari2600SwitchSelect]; } +- (NSString *)userDefaultsPrefix { return @"atari2600"; } + @end diff --git a/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSElectron.h b/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSElectron.h index d96647745..622ab749b 100644 --- a/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSElectron.h +++ b/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSElectron.h @@ -10,15 +10,8 @@ #import "CSKeyboardMachine.h" #import "CSFastLoading.h" -@class CSStaticAnalyser; - @interface CSElectron : CSMachine -- (void)setOSROM:(nonnull NSData *)rom; -- (void)setBASICROM:(nonnull NSData *)rom; -- (void)setDFSROM:(nonnull NSData *)rom; -- (void)setADFSROM:(nonnull NSData *)rom; - @property (nonatomic, assign) BOOL useFastLoadingHack; @property (nonatomic, assign) BOOL useTelevisionOutput; diff --git a/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSElectron.mm b/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSElectron.mm index 97f3ed865..93a398b33 100644 --- a/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSElectron.mm +++ b/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSElectron.mm @@ -9,11 +9,13 @@ #import "CSElectron.h" #include "Electron.hpp" -#import "CSMachine+Subclassing.h" -#import "NSData+StdVector.h" #include "StaticAnalyser.hpp" #include "TapeUEF.hpp" +#import "CSMachine+Subclassing.h" +#import "NSData+StdVector.h" +#import "NSBundle+DataResource.h" + @implementation CSElectron { Electron::Machine _electron; } @@ -22,32 +24,43 @@ return &_electron; } -- (void)analyse:(NSURL *)url { - StaticAnalyser::GetTargets([url fileSystemRepresentation]); +- (instancetype)init { + self = [super init]; + if(self) + { + [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 { - @synchronized(self) { - _electron.set_rom((Electron::ROMSlot)slot, rom.stdVector8, false); + if(rom) + { + @synchronized(self) { + _electron.set_rom((Electron::ROMSlot)slot, rom.stdVector8, false); + } } } -/*- (BOOL)openUEFAtURL:(NSURL *)URL { - @synchronized(self) { - try { - std::shared_ptr tape(new Storage::Tape::UEF([URL fileSystemRepresentation])); - _electron.set_tape(tape); - return YES; - } catch(...) { - return NO; - } - } -}*/ +#pragma mark - Keyboard Mapping - (void)clearAllKeys { @synchronized(self) { @@ -135,6 +148,10 @@ } } +- (NSString *)userDefaultsPrefix { return @"electron"; } + +#pragma mark - Options + - (void)setUseFastLoadingHack:(BOOL)useFastLoadingHack { @synchronized(self) { _useFastLoadingHack = useFastLoadingHack; @@ -149,4 +166,8 @@ } } +//override func aspectRatio() -> NSSize { +// return NSSize(width: 11.0, height: 10.0) +// } + @end diff --git a/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSVic20.h b/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSVic20.h index 42d0aaee0..5ec512dc9 100644 --- a/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSVic20.h +++ b/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSVic20.h @@ -10,10 +10,13 @@ #import "CSKeyboardMachine.h" #import "CSFastLoading.h" -typedef NS_ENUM(NSInteger, CSVic20Region) +typedef NS_ENUM(NSInteger, CSVic20Country) { - CSVic20RegionPAL, - CSVic20RegionNTSC + CSVic20CountryDanish, + CSVic20CountryEuropean, + CSVic20CountryJapanese, + CSVic20CountrySwedish, + CSVic20CountryAmerican }; typedef NS_ENUM(NSInteger, CSVic20MemorySize) @@ -25,14 +28,9 @@ typedef NS_ENUM(NSInteger, CSVic20MemorySize) @interface CSVic20 : CSMachine -- (void)setKernelROM:(nonnull NSData *)rom; -- (void)setBASICROM:(nonnull NSData *)rom; -- (void)setCharactersROM:(nonnull NSData *)rom; -- (void)setDriveROM:(nonnull NSData *)rom; - @property (nonatomic, assign) BOOL useFastLoadingHack; @property (nonatomic, assign) BOOL shouldLoadAutomatically; -@property (nonatomic, assign) CSVic20Region region; +@property (nonatomic, assign) CSVic20Country country; @property (nonatomic, assign) CSVic20MemorySize memorySize; @end diff --git a/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSVic20.mm b/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSVic20.mm index 41aed0e6b..bcc3866c5 100644 --- a/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSVic20.mm +++ b/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSVic20.mm @@ -13,6 +13,8 @@ #include "G64.hpp" #include "D64.hpp" +#import "NSBundle+DataResource.h" + using namespace Commodore::Vic20; @implementation CSVic20 { @@ -20,10 +22,27 @@ using namespace Commodore::Vic20; BOOL _joystickMode; } -- (CRTMachine::Machine * const)machine { - return &_vic20; +- (CRTMachine::Machine * const)machine { return &_vic20; } +- (NSString *)userDefaultsPrefix { return @"vic20"; } + +- (instancetype)init { + self = [super init]; + if(self) + { + [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); @@ -46,6 +65,8 @@ using namespace Commodore::Vic20; [self setROM:rom slot:Drive]; } +#pragma mark - Keyboard map + - (void)setKey:(uint16_t)key isPressed:(BOOL)isPressed { static NSDictionary *vicKeysByKeys = @{ @(VK_ANSI_1): @(Key::Key1), @(VK_ANSI_2): @(Key::Key2), @@ -164,10 +185,43 @@ using namespace Commodore::Vic20; } } -- (void)setRegion:(CSVic20Region)region { - _region = region; +- (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; + } + @synchronized(self) { - _vic20.set_region( (region == CSVic20RegionPAL) ? Commodore::Vic20::Region::PAL : Commodore::Vic20::Region::NTSC); + _vic20.set_region(region); + [self setCharactersROM:[self rom:charactersROM]]; + [self setKernelROM:[self rom:kernelROM]]; } }