From 1e1efcdcb8c0749efd77031c53220955f86d2d41 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sun, 5 Nov 2017 12:49:28 -0500 Subject: [PATCH] Pushes far enough along the path of having the SDL version do work that it becomes obvious I've never figured out the correct course of action if there is no sound output. --- Machines/Utility/MachineForTarget.cpp | 56 +++++++++ Machines/Utility/MachineForTarget.hpp | 41 +++++++ .../Clock Signal.xcodeproj/project.pbxproj | 106 +++++++++++++++++- OSBindings/SDL/main.cpp | 78 ++++++++++++- 4 files changed, 276 insertions(+), 5 deletions(-) create mode 100644 Machines/Utility/MachineForTarget.cpp create mode 100644 Machines/Utility/MachineForTarget.hpp 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();