diff --git a/Machines/Utility/MachineForTarget.cpp b/Machines/Utility/MachineForTarget.cpp new file mode 100644 index 000000000..9638f340b --- /dev/null +++ b/Machines/Utility/MachineForTarget.cpp @@ -0,0 +1,56 @@ +// +// MachineForTarget.cpp +// Clock Signal +// +// Created by Thomas Harte on 04/11/2017. +// Copyright © 2017 Thomas Harte. All rights reserved. +// + +#include "MachineForTarget.hpp" + +#include "../AmstradCPC/AmstradCPC.hpp" +#include "../Atari2600/Atari2600.hpp" +#include "../Commodore/Vic-20/Vic20.hpp" +#include "../Electron/Electron.hpp" +#include "../Oric/Oric.hpp" +#include "../ZX8081/ZX8081.hpp" + +namespace { + +template class TypedDynamicMachine: public ::Machine::DynamicMachine { + public: + TypedDynamicMachine(T *machine) : machine_(machine) {} + + ConfigurationTarget::Machine *configuration_target() { + return dynamic_cast(machine_.get()); + } + + CRTMachine::Machine *crt_machine() { + return dynamic_cast(machine_.get()); + } + + JoystickMachine::Machine *joystick_machine() { + return dynamic_cast(machine_.get()); + } + + KeyboardMachine::Machine *keyboard_machine() { + return dynamic_cast(machine_.get()); + } + + private: + std::unique_ptr machine_; +}; + +} + +::Machine::DynamicMachine *::Machine::MachineForTarget(const StaticAnalyser::Target &target) { + switch(target.machine) { + case StaticAnalyser::Target::AmstradCPC: return new TypedDynamicMachine(AmstradCPC::Machine::AmstradCPC()); +// case StaticAnalyser::Target::Atari2600: return new TypedDynamicMachine(Atari2600::Machine::Atari2600()); +// case StaticAnalyser::Target::Electron: return new TypedDynamicMachine(Electron::Machine::Electron()); +// case StaticAnalyser::Target::Oric: return new TypedDynamicMachine(Oric::Machine::Oric()); +// case StaticAnalyser::Target::Vic20: return new TypedDynamicMachine(Commodore::Vic20::Machine::Vic20()); +// case StaticAnalyser::Target::ZX8081: return new TypedDynamicMachine(ZX8081::Machine::ZX8081(target)); + default: return nullptr; + } +} diff --git a/Machines/Utility/MachineForTarget.hpp b/Machines/Utility/MachineForTarget.hpp new file mode 100644 index 000000000..488382c35 --- /dev/null +++ b/Machines/Utility/MachineForTarget.hpp @@ -0,0 +1,41 @@ +// +// MachineForTarget.hpp +// Clock Signal +// +// Created by Thomas Harte on 04/11/2017. +// Copyright © 2017 Thomas Harte. All rights reserved. +// + +#ifndef MachineForTarget_hpp +#define MachineForTarget_hpp + +#include "../../StaticAnalyser/StaticAnalyser.hpp" + +#include "../ConfigurationTarget.hpp" +#include "../CRTMachine.hpp" +#include "../JoystickMachine.hpp" +#include "../KeyboardMachine.hpp" + +namespace Machine { + +/*! + Provides the structure for owning a machine and dynamically casting it as desired without knowledge of + the machine's parent class or, therefore, the need to establish a common one. +*/ +struct DynamicMachine { + virtual ConfigurationTarget::Machine *configuration_target() = 0; + virtual CRTMachine::Machine *crt_machine() = 0; + virtual JoystickMachine::Machine *joystick_machine() = 0; + virtual KeyboardMachine::Machine *keyboard_machine() = 0; +}; + +/*! + Allocates an instance of DynamicMachine holding a machine that can + receive the supplied target. The machine has been allocated on the heap. + It is the caller's responsibility to delete the class when finished. +*/ +DynamicMachine *MachineForTarget(const StaticAnalyser::Target &target); + +} + +#endif /* MachineForTarget_hpp */ diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index 575d34c4e..dbf307ba2 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -74,6 +74,55 @@ 4B055ABB1FAE86170060FFFF /* Oric.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8805F91DCFF807003085B1 /* Oric.cpp */; }; 4B055ABC1FAE86170060FFFF /* ZX8081.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBFBB6A1EE8401E00C01E7A /* ZX8081.cpp */; }; 4B055ABD1FAE86530060FFFF /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B69FB451C4D950F00B5F0AA /* libz.tbd */; }; + 4B055AC11FAE98DC0060FFFF /* MachineForTarget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B055ABE1FAE98000060FFFF /* MachineForTarget.cpp */; }; + 4B055AC21FAE9AE30060FFFF /* KeyboardMachine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B54C0BB1F8D8E790050900F /* KeyboardMachine.cpp */; }; + 4B055AC31FAE9AE80060FFFF /* AmstradCPC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B38F3461F2EC11D00D9235D /* AmstradCPC.cpp */; }; + 4B055AC41FAE9AE80060FFFF /* Keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B54C0C11F8D91CD0050900F /* Keyboard.cpp */; }; + 4B055AC51FAE9AEE0060FFFF /* Atari2600.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2E2D971C3A06EC00138695 /* Atari2600.cpp */; }; + 4B055AC61FAE9AEE0060FFFF /* Speaker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEA52641DF3472B007E74F2 /* Speaker.cpp */; }; + 4B055AC71FAE9AEE0060FFFF /* TIA.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BE7C9161E3D397100A5496D /* TIA.cpp */; }; + 4B055AC81FAE9AFB0060FFFF /* C1540.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8334941F5E25B60097E338 /* C1540.cpp */; }; + 4B055AC91FAE9AFB0060FFFF /* Keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B54C0C41F8D91D90050900F /* Keyboard.cpp */; }; + 4B055ACA1FAE9AFB0060FFFF /* Vic20.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DC81F1D2C2425003C5BF8 /* Vic20.cpp */; }; + 4B055ACB1FAE9AFB0060FFFF /* SerialBus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DC8291D2C27A4003C5BF8 /* SerialBus.cpp */; }; + 4B055ACC1FAE9B030060FFFF /* Electron.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2E2D9B1C3A070400138695 /* Electron.cpp */; }; + 4B055ACD1FAE9B030060FFFF /* Keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B54C0C61F8D91E50050900F /* Keyboard.cpp */; }; + 4B055ACE1FAE9B030060FFFF /* Plus3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B30512E1D98ACC600B4FED8 /* Plus3.cpp */; }; + 4B055ACF1FAE9B030060FFFF /* Speaker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEA52611DF339D7007E74F2 /* Speaker.cpp */; }; + 4B055AD01FAE9B030060FFFF /* Tape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEA525D1DF33323007E74F2 /* Tape.cpp */; }; + 4B055AD11FAE9B030060FFFF /* Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B7913CA1DFCD80E00175A82 /* Video.cpp */; }; + 4B055AD21FAE9B0B0060FFFF /* Keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B54C0BD1F8D8F450050900F /* Keyboard.cpp */; }; + 4B055AD31FAE9B0B0060FFFF /* Microdisc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B5FADBE1DE3BF2B00AEC565 /* Microdisc.cpp */; }; + 4B055AD41FAE9B0B0060FFFF /* Oric.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BCF1FA21DADC3DD0039D2E7 /* Oric.cpp */; }; + 4B055AD51FAE9B0B0060FFFF /* Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2BFDB01DAEF5FF001A68B8 /* Video.cpp */; }; + 4B055AD61FAE9B130060FFFF /* MemoryFuzzer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2B3A481F9B8FA70062DABF /* MemoryFuzzer.cpp */; }; + 4B055AD71FAE9B180060FFFF /* Keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B54C0CA1F8D92580050900F /* Keyboard.cpp */; }; + 4B055AD81FAE9B180060FFFF /* Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD3A3091EE755C800B5B501 /* Video.cpp */; }; + 4B055AD91FAE9B180060FFFF /* ZX8081.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1497901EE4B5A800CE2596 /* ZX8081.cpp */; }; + 4B055ADA1FAE9B460060FFFF /* 1770.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD468F51D8DF41D0084958B /* 1770.cpp */; }; + 4B055ADB1FAE9B460060FFFF /* 6560.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC9DF4D1D04691600F44158 /* 6560.cpp */; }; + 4B055ADC1FAE9B460060FFFF /* AY38910.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4A762E1DB1A3FA007AAE2E /* AY38910.cpp */; }; + 4B055ADD1FAE9B460060FFFF /* i8272.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBC951C1F368D83008F4C34 /* i8272.cpp */; }; + 4B055ADE1FAE9B4C0060FFFF /* 6522Base.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B83348B1F5DB99C0097E338 /* 6522Base.cpp */; }; + 4B055ADF1FAE9B4C0060FFFF /* IRQDelegatePortHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8334891F5DB94B0097E338 /* IRQDelegatePortHandler.cpp */; }; + 4B055AE01FAE9B660060FFFF /* CRT.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0CCC421C62D0B3001CAC5F /* CRT.cpp */; }; + 4B055AE11FAE9B6F0060FFFF /* ArrayBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B5073051DDD3B9400C48FBD /* ArrayBuilder.cpp */; }; + 4B055AE21FAE9B6F0060FFFF /* CRTOpenGL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBF990A1C8FBA6F0075DAFB /* CRTOpenGL.cpp */; }; + 4B055AE31FAE9B6F0060FFFF /* TextureBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBF99081C8FBA6F0075DAFB /* TextureBuilder.cpp */; }; + 4B055AE41FAE9B6F0060FFFF /* TextureTarget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBF99121C8FBA6F0075DAFB /* TextureTarget.cpp */; }; + 4B055AE51FAE9B6F0060FFFF /* IntermediateShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBB142F1CD2CECE00BDB55C /* IntermediateShader.cpp */; }; + 4B055AE61FAE9B6F0060FFFF /* OutputShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B7501CD1956900F86E85 /* OutputShader.cpp */; }; + 4B055AE71FAE9B6F0060FFFF /* Shader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B74D1CD194CC00F86E85 /* Shader.cpp */; }; + 4B055AE81FAE9B7B0060FFFF /* FIRFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC76E671C98E31700E6EF73 /* FIRFilter.cpp */; }; + 4B055AE91FAE9B990060FFFF /* 6502Base.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B6A4C951F58F09E00E3F787 /* 6502Base.cpp */; }; + 4B055AEA1FAE9B990060FFFF /* 6502Storage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8334851F5DA3780097E338 /* 6502Storage.cpp */; }; + 4B055AEB1FAE9BA20060FFFF /* PartialMachineCycle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8334811F5D9FF70097E338 /* PartialMachineCycle.cpp */; }; + 4B055AEC1FAE9BA20060FFFF /* Z80Base.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B322E031F5A2E3C004EB04C /* Z80Base.cpp */; }; + 4B055AED1FAE9BA20060FFFF /* Z80Storage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8334831F5DA0360097E338 /* Z80Storage.cpp */; }; + 4B055AEE1FAE9BBF0060FFFF /* Keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B86E2591F8C628F006FAA45 /* Keyboard.cpp */; }; + 4B055AEF1FAE9BF00060FFFF /* Typer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2B3A471F9B8FA70062DABF /* Typer.cpp */; }; + 4B055AF11FAE9C160060FFFF /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BC76E6A1C98F43700E6EF73 /* Accelerate.framework */; }; + 4B055AF21FAE9C1C0060FFFF /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B055AF01FAE9C080060FFFF /* OpenGL.framework */; }; 4B08A2751EE35D56008B7065 /* Z80InterruptTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B08A2741EE35D56008B7065 /* Z80InterruptTests.swift */; }; 4B08A2781EE39306008B7065 /* TestMachine.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B08A2771EE39306008B7065 /* TestMachine.mm */; }; 4B0CCC451C62D0B3001CAC5F /* CRT.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0CCC421C62D0B3001CAC5F /* CRT.cpp */; }; @@ -563,8 +612,11 @@ 4B046DC31CFE651500E9E45E /* CRTMachine.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CRTMachine.hpp; sourceTree = ""; }; 4B049CDC1DA3C82F00322067 /* BCDTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BCDTest.swift; sourceTree = ""; }; 4B055A6A1FAE763F0060FFFF /* Clock Signal Kiosk */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "Clock Signal Kiosk"; sourceTree = BUILT_PRODUCTS_DIR; }; - 4B055A771FAE78210060FFFF /* SDL2.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL2.framework; path = ../../../../Library/Frameworks/SDL2.framework; sourceTree = ""; }; + 4B055A771FAE78210060FFFF /* SDL2.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL2.framework; path = ../../../../Library/Frameworks/SDL2.framework; sourceTree = SOURCE_ROOT; }; 4B055A7C1FAE84A50060FFFF /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 4B055ABE1FAE98000060FFFF /* MachineForTarget.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = MachineForTarget.cpp; sourceTree = ""; }; + 4B055ABF1FAE98000060FFFF /* MachineForTarget.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = MachineForTarget.hpp; sourceTree = ""; }; + 4B055AF01FAE9C080060FFFF /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; }; 4B08A2741EE35D56008B7065 /* Z80InterruptTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Z80InterruptTests.swift; sourceTree = ""; }; 4B08A2761EE39306008B7065 /* TestMachine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestMachine.h; sourceTree = ""; }; 4B08A2771EE39306008B7065 /* TestMachine.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = TestMachine.mm; sourceTree = ""; }; @@ -1218,6 +1270,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 4B055AF21FAE9C1C0060FFFF /* OpenGL.framework in Frameworks */, + 4B055AF11FAE9C160060FFFF /* Accelerate.framework in Frameworks */, 4B055ABD1FAE86530060FFFF /* libz.tbd in Frameworks */, 4B055A7A1FAE78A00060FFFF /* SDL2.framework in Frameworks */, ); @@ -1252,6 +1306,7 @@ 4B055A761FAE78210060FFFF /* Frameworks */ = { isa = PBXGroup; children = ( + 4B055AF01FAE9C080060FFFF /* OpenGL.framework */, 4B055A771FAE78210060FFFF /* SDL2.framework */, ); name = Frameworks; @@ -1406,6 +1461,8 @@ 4B2B3A461F9B8FA70062DABF /* Utility */ = { isa = PBXGroup; children = ( + 4B055ABE1FAE98000060FFFF /* MachineForTarget.cpp */, + 4B055ABF1FAE98000060FFFF /* MachineForTarget.hpp */, 4B2B3A471F9B8FA70062DABF /* Typer.cpp */, 4B2B3A481F9B8FA70062DABF /* MemoryFuzzer.cpp */, 4B2B3A491F9B8FA70062DABF /* MemoryFuzzer.hpp */, @@ -3050,24 +3107,41 @@ files = ( 4B055AAA1FAE85F50060FFFF /* CPM.cpp in Sources */, 4B055A9A1FAE85CB0060FFFF /* MFMDiskController.cpp in Sources */, + 4B055ACB1FAE9AFB0060FFFF /* SerialBus.cpp in Sources */, 4B055AA41FAE85E50060FFFF /* DigitalPhaseLockedLoop.cpp in Sources */, + 4B055AE61FAE9B6F0060FFFF /* OutputShader.cpp in Sources */, 4B055A9B1FAE85DA0060FFFF /* AcornADF.cpp in Sources */, + 4B055AD51FAE9B0B0060FFFF /* Video.cpp in Sources */, 4B055A811FAE853A0060FFFF /* Disk.cpp in Sources */, + 4B055AE11FAE9B6F0060FFFF /* ArrayBuilder.cpp in Sources */, 4B055AA51FAE85EF0060FFFF /* Encoder.cpp in Sources */, + 4B055AEA1FAE9B990060FFFF /* 6502Storage.cpp in Sources */, 4B055A8A1FAE855B0060FFFF /* Tape.cpp in Sources */, 4B055AA71FAE85EF0060FFFF /* SegmentParser.cpp in Sources */, + 4B055AC11FAE98DC0060FFFF /* MachineForTarget.cpp in Sources */, + 4B055AD81FAE9B180060FFFF /* Video.cpp in Sources */, + 4B055AE51FAE9B6F0060FFFF /* IntermediateShader.cpp in Sources */, 4B055A851FAE85480060FFFF /* File.cpp in Sources */, + 4B055AD31FAE9B0B0060FFFF /* Microdisc.cpp in Sources */, 4B055AB41FAE860F0060FFFF /* OricTAP.cpp in Sources */, 4B055AB71FAE860F0060FFFF /* TZX.cpp in Sources */, 4B055A8C1FAE85670060FFFF /* StaticAnalyser.cpp in Sources */, + 4B055ADA1FAE9B460060FFFF /* 1770.cpp in Sources */, + 4B055ADC1FAE9B460060FFFF /* AY38910.cpp in Sources */, + 4B055AD71FAE9B180060FFFF /* Keyboard.cpp in Sources */, 4B055AB61FAE860F0060FFFF /* TapeUEF.cpp in Sources */, 4B055A9D1FAE85DA0060FFFF /* D64.cpp in Sources */, 4B055ABB1FAE86170060FFFF /* Oric.cpp in Sources */, + 4B055AE81FAE9B7B0060FFFF /* FIRFilter.cpp in Sources */, 4B055A901FAE85A90060FFFF /* TimedEventLoop.cpp in Sources */, 4B055AAB1FAE85FD0060FFFF /* PCMPatchedTrack.cpp in Sources */, + 4B055AC71FAE9AEE0060FFFF /* TIA.cpp in Sources */, + 4B055AD21FAE9B0B0060FFFF /* Keyboard.cpp in Sources */, 4B055AA31FAE85DF0060FFFF /* ImplicitSectors.cpp in Sources */, 4B055AAE1FAE85FD0060FFFF /* TrackSerialiser.cpp in Sources */, 4B055A981FAE85C50060FFFF /* Drive.cpp in Sources */, + 4B055AE21FAE9B6F0060FFFF /* CRTOpenGL.cpp in Sources */, + 4B055AC31FAE9AE80060FFFF /* AmstradCPC.cpp in Sources */, 4B055A9E1FAE85DA0060FFFF /* G64.cpp in Sources */, 4B055AB81FAE860F0060FFFF /* ZX80O81P.cpp in Sources */, 4B055A8E1FAE85920060FFFF /* BestEffortUpdater.cpp in Sources */, @@ -3075,41 +3149,71 @@ 4B055A801FAE85350060FFFF /* StaticAnalyser.cpp in Sources */, 4B055AAC1FAE85FD0060FFFF /* PCMSegment.cpp in Sources */, 4B055AB31FAE860F0060FFFF /* CSW.cpp in Sources */, + 4B055ACF1FAE9B030060FFFF /* Speaker.cpp in Sources */, + 4B055AEE1FAE9BBF0060FFFF /* Keyboard.cpp in Sources */, 4B055A881FAE85530060FFFF /* Disassembler6502.cpp in Sources */, + 4B055AED1FAE9BA20060FFFF /* Z80Storage.cpp in Sources */, + 4B055AD11FAE9B030060FFFF /* Video.cpp in Sources */, 4B055AA21FAE85DA0060FFFF /* SSD.cpp in Sources */, + 4B055ADD1FAE9B460060FFFF /* i8272.cpp in Sources */, + 4B055AC51FAE9AEE0060FFFF /* Atari2600.cpp in Sources */, 4B055A9C1FAE85DA0060FFFF /* CPCDSK.cpp in Sources */, + 4B055AE41FAE9B6F0060FFFF /* TextureTarget.cpp in Sources */, 4B055ABA1FAE86170060FFFF /* Commodore.cpp in Sources */, 4B055AA61FAE85EF0060FFFF /* Parser.cpp in Sources */, + 4B055AE91FAE9B990060FFFF /* 6502Base.cpp in Sources */, 4B055A861FAE854C0060FFFF /* StaticAnalyser.cpp in Sources */, + 4B055AEF1FAE9BF00060FFFF /* Typer.cpp in Sources */, + 4B055ACA1FAE9AFB0060FFFF /* Vic20.cpp in Sources */, 4B055ABC1FAE86170060FFFF /* ZX8081.cpp in Sources */, + 4B055AC91FAE9AFB0060FFFF /* Keyboard.cpp in Sources */, 4B055A991FAE85CB0060FFFF /* DiskController.cpp in Sources */, + 4B055ACC1FAE9B030060FFFF /* Electron.cpp in Sources */, 4B055AB11FAE86070060FFFF /* Tape.cpp in Sources */, 4B055AA91FAE85EF0060FFFF /* CommodoreGCR.cpp in Sources */, 4B055A7F1FAE852F0060FFFF /* StaticAnalyser.cpp in Sources */, + 4B055ADB1FAE9B460060FFFF /* 6560.cpp in Sources */, 4B055AA01FAE85DA0060FFFF /* MFMSectorDump.cpp in Sources */, 4B055AA11FAE85DA0060FFFF /* OricMFMDSK.cpp in Sources */, 4B055A951FAE85BB0060FFFF /* BitReverse.cpp in Sources */, 4B055A891FAE85580060FFFF /* StaticAnalyser.cpp in Sources */, + 4B055ACE1FAE9B030060FFFF /* Plus3.cpp in Sources */, 4B055A8D1FAE85920060FFFF /* AsyncTaskQueue.cpp in Sources */, + 4B055AC41FAE9AE80060FFFF /* Keyboard.cpp in Sources */, 4B055A941FAE85B50060FFFF /* CommodoreROM.cpp in Sources */, 4B055A971FAE85BB0060FFFF /* ZX8081.cpp in Sources */, 4B055AAD1FAE85FD0060FFFF /* PCMTrack.cpp in Sources */, 4B055A841FAE85450060FFFF /* Disk.cpp in Sources */, 4B055A831FAE85410060FFFF /* Tape.cpp in Sources */, + 4B055AC61FAE9AEE0060FFFF /* Speaker.cpp in Sources */, 4B055AA81FAE85EF0060FFFF /* Shifter.cpp in Sources */, + 4B055AC81FAE9AFB0060FFFF /* C1540.cpp in Sources */, 4B055A8F1FAE85A90060FFFF /* FileHolder.cpp in Sources */, 4B055A911FAE85B50060FFFF /* Cartridge.cpp in Sources */, + 4B055ACD1FAE9B030060FFFF /* Keyboard.cpp in Sources */, 4B055A8B1FAE85670060FFFF /* StaticAnalyser.cpp in Sources */, 4B055AB21FAE860F0060FFFF /* CommodoreTAP.cpp in Sources */, + 4B055ADF1FAE9B4C0060FFFF /* IRQDelegatePortHandler.cpp in Sources */, 4B055AB51FAE860F0060FFFF /* TapePRG.cpp in Sources */, + 4B055AE01FAE9B660060FFFF /* CRT.cpp in Sources */, + 4B055AD01FAE9B030060FFFF /* Tape.cpp in Sources */, 4B055A961FAE85BB0060FFFF /* Commodore.cpp in Sources */, + 4B055ADE1FAE9B4C0060FFFF /* 6522Base.cpp in Sources */, + 4B055AD41FAE9B0B0060FFFF /* Oric.cpp in Sources */, 4B055A821FAE853D0060FFFF /* StaticAnalyser.cpp in Sources */, 4B055A921FAE85B50060FFFF /* PRG.cpp in Sources */, 4B055AAF1FAE85FD0060FFFF /* UnformattedTrack.cpp in Sources */, 4B055A7E1FAE84AA0060FFFF /* main.cpp in Sources */, 4B055A9F1FAE85DA0060FFFF /* HFE.cpp in Sources */, + 4B055AE71FAE9B6F0060FFFF /* Shader.cpp in Sources */, + 4B055AEC1FAE9BA20060FFFF /* Z80Base.cpp in Sources */, + 4B055AE31FAE9B6F0060FFFF /* TextureBuilder.cpp in Sources */, 4B055AB91FAE86170060FFFF /* Acorn.cpp in Sources */, 4B055A931FAE85B50060FFFF /* BinaryDump.cpp in Sources */, + 4B055AD61FAE9B130060FFFF /* MemoryFuzzer.cpp in Sources */, + 4B055AC21FAE9AE30060FFFF /* KeyboardMachine.cpp in Sources */, + 4B055AD91FAE9B180060FFFF /* ZX8081.cpp in Sources */, + 4B055AEB1FAE9BA20060FFFF /* PartialMachineCycle.cpp in Sources */, 4B055A871FAE854F0060FFFF /* Tape.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/OSBindings/SDL/main.cpp b/OSBindings/SDL/main.cpp index e207105ca..9e3dda043 100644 --- a/OSBindings/SDL/main.cpp +++ b/OSBindings/SDL/main.cpp @@ -7,31 +7,84 @@ // #include +#include #include #include "../../StaticAnalyser/StaticAnalyser.hpp" +#include "../../Machines/Utility/MachineForTarget.hpp" + +#include "../../Machines/ConfigurationTarget.hpp" +#include "../../Machines/CRTMachine.hpp" + +#include "../../Concurrency/BestEffortUpdater.hpp" + +namespace { + +struct CRTMachineDelegate: public CRTMachine::Machine::Delegate { + + void machine_did_change_clock_rate(CRTMachine::Machine *machine) { + best_effort_updater->set_clock_rate(machine->get_clock_rate()); + } + + void machine_did_change_clock_is_unlimited(CRTMachine::Machine *machine) { + } + + Concurrency::BestEffortUpdater *best_effort_updater; +}; + +struct BestEffortUpdaterDelegate: public Concurrency::BestEffortUpdater::Delegate { + + void update(Concurrency::BestEffortUpdater *updater, int cycles, bool did_skip_previous_update) { + machine->crt_machine()->run_for(Cycles(cycles)); + } + + Machine::DynamicMachine *machine; +}; + +} int main(int argc, char *argv[]) { SDL_Window *window = nullptr; + // Perform a sanity check on arguments. if(argc < 2) { std::cerr << "Usage: " << argv[0] << " [file]" << std::endl; return -1; } - + + // Determine the machine for the supplied file. std::list targets = StaticAnalyser::GetTargets(argv[1]); if(targets.empty()) { std::cerr << "Cannot open " << argv[1] << std::endl; return -1; } + Concurrency::BestEffortUpdater updater; + BestEffortUpdaterDelegate best_effort_updater_delegate; + CRTMachineDelegate crt_delegate; + + // Create and configure a machine. + std::unique_ptr<::Machine::DynamicMachine> machine(::Machine::MachineForTarget(targets.front())); + machine->configuration_target()->configure_as_target(targets.front()); + + crt_delegate.best_effort_updater = &updater; + best_effort_updater_delegate.machine = machine.get(); + + machine->crt_machine()->set_delegate(&crt_delegate); + updater.set_delegate(&best_effort_updater_delegate); + + // Attempt to set up video and audio. if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0) { std::cerr << "SDL could not initialize! SDL_Error: " << SDL_GetError() << std::endl; return -1; } + // Ask for no depth buffer, a core profile and vsync-aligned rendering. SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + SDL_GL_SetSwapInterval(1); + window = SDL_CreateWindow( "Clock Signal", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 400, 300, @@ -43,21 +96,38 @@ int main(int argc, char *argv[]) { return -1; } + SDL_GLContext gl_context = SDL_GL_CreateContext(window); + SDL_GL_MakeCurrent(window, gl_context); + + // Setup output, assuming a CRT machine for now, and prepare a best-effort updater. + machine->crt_machine()->setup_output(4.0 / 3.0); + + // Run the main event loop until the OS tells us to quit. bool should_quit = false; while(!should_quit) { + // Process all pending events. SDL_Event event; - while (SDL_PollEvent(&event)) { + while(SDL_PollEvent(&event)) { switch(event.type) { + default: std::cout << "Unhandled " << event.type << std::endl; break; case SDL_QUIT: should_quit = true; break; - + case SDL_KEYDOWN: break; case SDL_KEYUP: break; } } + + // Display a new frame and wait for vsync. + updater.update(); + int width, height; + SDL_GetWindowSize(window, &width, &height); + machine->crt_machine()->get_crt()->draw_frame(static_cast(width), static_cast(height), true); + SDL_GL_SwapWindow(window); } - + + // Clean up. SDL_DestroyWindow( window ); SDL_Quit();