1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-23 20:29:42 +00:00

Simplifies semantics a little and starts accepting a single buffer of pixel data.

This commit is contained in:
Thomas Harte 2018-11-06 22:23:38 -05:00
parent 9799aa0975
commit 55da1e9c0f
26 changed files with 343 additions and 118 deletions

View File

@ -47,7 +47,7 @@ VideoOutput::VideoOutput(uint8_t *memory, Outputs::Display::ScanTarget *scan_tar
crt_cycles_per_line,
1,
Outputs::Display::Type::PAL50,
Outputs::Display::ScanTarget::Modals::DataType::Red1Green1Blue1,
Outputs::Display::InputDataType::Red1Green1Blue1,
scan_target));
// crt_->set_rgb_sampling_function(

View File

@ -23,7 +23,7 @@ const std::size_t StandardAllocationSize = 320;
}
Video::Video(Outputs::Display::ScanTarget *scan_target) :
crt_(new Outputs::CRT::CRT(207 * 2, 1, Outputs::Display::Type::PAL50, Outputs::Display::ScanTarget::Modals::DataType::Luminance1, scan_target))
crt_(new Outputs::CRT::CRT(207 * 2, 1, Outputs::Display::Type::PAL50, Outputs::Display::InputDataType::Luminance1, scan_target))
{
// Set a composite sampling function that assumes two-level input; either a byte is 0, which is black,

View File

@ -613,6 +613,12 @@
4BC9E1EE1D23449A003FCEE4 /* 6502InterruptTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BC9E1ED1D23449A003FCEE4 /* 6502InterruptTests.swift */; };
4BCA6CC81D9DD9F000C2D7B2 /* CommodoreROM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BCA6CC61D9DD9F000C2D7B2 /* CommodoreROM.cpp */; };
4BCF1FA41DADC3DD0039D2E7 /* Oric.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BCF1FA21DADC3DD0039D2E7 /* Oric.cpp */; };
4BD191F0219117F90042E144 /* Rectangle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD191E6219113B80042E144 /* Rectangle.cpp */; };
4BD191F1219117FA0042E144 /* Rectangle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD191E6219113B80042E144 /* Rectangle.cpp */; };
4BD191F42191180E0042E144 /* ScanTarget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD191F22191180E0042E144 /* ScanTarget.cpp */; };
4BD191F52191180E0042E144 /* ScanTarget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD191F22191180E0042E144 /* ScanTarget.cpp */; };
4BD191F6219118390042E144 /* Shader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD191E2219113B80042E144 /* Shader.cpp */; };
4BD191F72191183A0042E144 /* Shader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD191E2219113B80042E144 /* Shader.cpp */; };
4BD3A30B1EE755C800B5B501 /* Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD3A3091EE755C800B5B501 /* Video.cpp */; };
4BD468F71D8DF41D0084958B /* 1770.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD468F51D8DF41D0084958B /* 1770.cpp */; };
4BD4A8D01E077FD20020D856 /* PCMTrackTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BD4A8CF1E077FD20020D856 /* PCMTrackTests.mm */; };
@ -856,8 +862,6 @@
4B4DC8271D2C2470003C5BF8 /* C1540.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = C1540.hpp; sourceTree = "<group>"; };
4B4DC8291D2C27A4003C5BF8 /* SerialBus.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SerialBus.cpp; sourceTree = "<group>"; };
4B4DC82A1D2C27A4003C5BF8 /* SerialBus.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = SerialBus.hpp; sourceTree = "<group>"; };
4B5073051DDD3B9400C48FBD /* ArrayBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ArrayBuilder.cpp; sourceTree = "<group>"; };
4B5073061DDD3B9400C48FBD /* ArrayBuilder.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ArrayBuilder.hpp; sourceTree = "<group>"; };
4B5073091DDFCFDF00C48FBD /* ArrayBuilderTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ArrayBuilderTests.mm; sourceTree = "<group>"; };
4B51F70920A521D700AFA2C1 /* Source.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Source.hpp; sourceTree = "<group>"; };
4B51F70A20A521D700AFA2C1 /* Observer.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Observer.hpp; sourceTree = "<group>"; };
@ -1322,8 +1326,6 @@
4BB73EC11B587A5100552FC2 /* Clock_SignalUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Clock_SignalUITests.swift; sourceTree = "<group>"; };
4BB73EC31B587A5100552FC2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
4BB73ECF1B587A6700552FC2 /* Clock Signal.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "Clock Signal.entitlements"; sourceTree = "<group>"; };
4BBB142F1CD2CECE00BDB55C /* IntermediateShader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IntermediateShader.cpp; sourceTree = "<group>"; };
4BBB14301CD2CECE00BDB55C /* IntermediateShader.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = IntermediateShader.hpp; sourceTree = "<group>"; };
4BBB709C2020109C002FE009 /* DynamicMachine.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = DynamicMachine.hpp; sourceTree = "<group>"; };
4BBB70A2202011C2002FE009 /* MultiMediaTarget.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = MultiMediaTarget.hpp; sourceTree = "<group>"; };
4BBB70A3202011C2002FE009 /* MultiMediaTarget.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MultiMediaTarget.cpp; sourceTree = "<group>"; };
@ -1333,14 +1335,7 @@
4BBC951C1F368D83008F4C34 /* i8272.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = i8272.cpp; path = 8272/i8272.cpp; sourceTree = "<group>"; };
4BBC951D1F368D83008F4C34 /* i8272.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = i8272.hpp; path = 8272/i8272.hpp; sourceTree = "<group>"; };
4BBF49AE1ED2880200AB3669 /* FUSETests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FUSETests.swift; sourceTree = "<group>"; };
4BBF99081C8FBA6F0075DAFB /* TextureBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextureBuilder.cpp; sourceTree = "<group>"; };
4BBF99091C8FBA6F0075DAFB /* TextureBuilder.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = TextureBuilder.hpp; sourceTree = "<group>"; };
4BBF990A1C8FBA6F0075DAFB /* CRTOpenGL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CRTOpenGL.cpp; sourceTree = "<group>"; };
4BBF990B1C8FBA6F0075DAFB /* CRTOpenGL.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CRTOpenGL.hpp; sourceTree = "<group>"; };
4BBF990E1C8FBA6F0075DAFB /* Flywheel.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Flywheel.hpp; sourceTree = "<group>"; };
4BBF990F1C8FBA6F0075DAFB /* OpenGL.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = OpenGL.hpp; sourceTree = "<group>"; };
4BBF99121C8FBA6F0075DAFB /* TextureTarget.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextureTarget.cpp; sourceTree = "<group>"; };
4BBF99131C8FBA6F0075DAFB /* TextureTarget.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = TextureTarget.hpp; sourceTree = "<group>"; };
4BBFBB6A1EE8401E00C01E7A /* ZX8081.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ZX8081.cpp; path = Parsers/ZX8081.cpp; sourceTree = "<group>"; };
4BBFBB6B1EE8401E00C01E7A /* ZX8081.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ZX8081.hpp; path = Parsers/ZX8081.hpp; sourceTree = "<group>"; };
4BBFE83C21015D9C00BF1C40 /* CSJoystickManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSJoystickManager.m; sourceTree = "<group>"; };
@ -1349,17 +1344,11 @@
4BC39565208EDFCE0044766B /* Card.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Card.hpp; sourceTree = "<group>"; };
4BC39566208EE6CF0044766B /* DiskIICard.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DiskIICard.cpp; sourceTree = "<group>"; };
4BC39567208EE6CF0044766B /* DiskIICard.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = DiskIICard.hpp; sourceTree = "<group>"; };
4BC3B74D1CD194CC00F86E85 /* Shader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Shader.cpp; sourceTree = "<group>"; };
4BC3B74E1CD194CC00F86E85 /* Shader.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Shader.hpp; sourceTree = "<group>"; };
4BC3B7501CD1956900F86E85 /* OutputShader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OutputShader.cpp; sourceTree = "<group>"; };
4BC3B7511CD1956900F86E85 /* OutputShader.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = OutputShader.hpp; sourceTree = "<group>"; };
4BC5FC2F20CDDDEE00410AA0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = "Clock Signal/Base.lproj/AppleIIOptions.xib"; sourceTree = SOURCE_ROOT; };
4BC751B11D157E61006C31D9 /* 6522Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = 6522Tests.swift; sourceTree = "<group>"; };
4BC76E671C98E31700E6EF73 /* FIRFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FIRFilter.cpp; sourceTree = "<group>"; };
4BC76E681C98E31700E6EF73 /* FIRFilter.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = FIRFilter.hpp; sourceTree = "<group>"; };
4BC76E6A1C98F43700E6EF73 /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; };
4BC891AB20F6EAB300EDE5B3 /* Rectangle.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Rectangle.cpp; sourceTree = "<group>"; };
4BC891AC20F6EAB300EDE5B3 /* Rectangle.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Rectangle.hpp; sourceTree = "<group>"; };
4BC91B811D1F160E00884B76 /* CommodoreTAP.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CommodoreTAP.cpp; sourceTree = "<group>"; };
4BC91B821D1F160E00884B76 /* CommodoreTAP.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CommodoreTAP.hpp; sourceTree = "<group>"; };
4BC9DF441D044FCA00F44158 /* ROMImages */ = {isa = PBXFileReference; lastKnownFileType = folder; name = ROMImages; path = ../../../../ROMImages; sourceTree = "<group>"; };
@ -1372,6 +1361,25 @@
4BCF1FA21DADC3DD0039D2E7 /* Oric.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Oric.cpp; path = Oric/Oric.cpp; sourceTree = "<group>"; };
4BCF1FA31DADC3DD0039D2E7 /* Oric.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Oric.hpp; path = Oric/Oric.hpp; sourceTree = "<group>"; };
4BD060A51FE49D3C006E14BE /* Speaker.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Speaker.hpp; sourceTree = "<group>"; };
4BD191D6219113B80042E144 /* ArrayBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ArrayBuilder.cpp; sourceTree = "<group>"; };
4BD191D7219113B80042E144 /* CRTOpenGL.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CRTOpenGL.hpp; sourceTree = "<group>"; };
4BD191D8219113B80042E144 /* TextureBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextureBuilder.cpp; sourceTree = "<group>"; };
4BD191D9219113B80042E144 /* OpenGL.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = OpenGL.hpp; sourceTree = "<group>"; };
4BD191DA219113B80042E144 /* TextureTarget.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextureTarget.cpp; sourceTree = "<group>"; };
4BD191DB219113B80042E144 /* Rectangle.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Rectangle.hpp; sourceTree = "<group>"; };
4BD191DC219113B80042E144 /* CRTOpenGL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CRTOpenGL.cpp; sourceTree = "<group>"; };
4BD191DD219113B80042E144 /* TextureBuilder.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = TextureBuilder.hpp; sourceTree = "<group>"; };
4BD191DE219113B80042E144 /* TextureTarget.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = TextureTarget.hpp; sourceTree = "<group>"; };
4BD191E0219113B80042E144 /* IntermediateShader.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = IntermediateShader.hpp; sourceTree = "<group>"; };
4BD191E1219113B80042E144 /* OutputShader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OutputShader.cpp; sourceTree = "<group>"; };
4BD191E2219113B80042E144 /* Shader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Shader.cpp; sourceTree = "<group>"; };
4BD191E3219113B80042E144 /* IntermediateShader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IntermediateShader.cpp; sourceTree = "<group>"; };
4BD191E4219113B80042E144 /* OutputShader.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = OutputShader.hpp; sourceTree = "<group>"; };
4BD191E5219113B80042E144 /* Shader.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Shader.hpp; sourceTree = "<group>"; };
4BD191E6219113B80042E144 /* Rectangle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Rectangle.cpp; sourceTree = "<group>"; };
4BD191E7219113B90042E144 /* ArrayBuilder.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ArrayBuilder.hpp; sourceTree = "<group>"; };
4BD191F22191180E0042E144 /* ScanTarget.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ScanTarget.cpp; sourceTree = "<group>"; };
4BD191F32191180E0042E144 /* ScanTarget.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ScanTarget.hpp; sourceTree = "<group>"; };
4BD388411FE34E010042B588 /* 9918Base.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = 9918Base.hpp; path = 9918/Implementation/9918Base.hpp; sourceTree = "<group>"; };
4BD3A3091EE755C800B5B501 /* Video.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Video.cpp; path = ZX8081/Video.cpp; sourceTree = "<group>"; };
4BD3A30A1EE755C800B5B501 /* Video.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Video.hpp; path = ZX8081/Video.hpp; sourceTree = "<group>"; };
@ -1774,6 +1782,7 @@
4B366DFD1B5C165F0026627B /* Outputs */ = {
isa = PBXGroup;
children = (
4BD191D5219113B80042E144 /* OpenGL */,
4BD601A920D89F2A00CBCE57 /* Log.hpp */,
4BF52672218E752E00313227 /* ScanTarget.hpp */,
4B0CCC411C62D0B3001CAC5F /* CRT */,
@ -2923,20 +2932,8 @@
4BBF99071C8FBA6F0075DAFB /* Internals */ = {
isa = PBXGroup;
children = (
4B5073051DDD3B9400C48FBD /* ArrayBuilder.cpp */,
4BBF990A1C8FBA6F0075DAFB /* CRTOpenGL.cpp */,
4BC891AB20F6EAB300EDE5B3 /* Rectangle.cpp */,
4BBF99081C8FBA6F0075DAFB /* TextureBuilder.cpp */,
4BBF99121C8FBA6F0075DAFB /* TextureTarget.cpp */,
4B5073061DDD3B9400C48FBD /* ArrayBuilder.hpp */,
4B0B6E121C9DBD5D00FFB60D /* CRTConstants.hpp */,
4BBF990B1C8FBA6F0075DAFB /* CRTOpenGL.hpp */,
4BBF990E1C8FBA6F0075DAFB /* Flywheel.hpp */,
4BBF990F1C8FBA6F0075DAFB /* OpenGL.hpp */,
4BC891AC20F6EAB300EDE5B3 /* Rectangle.hpp */,
4BBF99091C8FBA6F0075DAFB /* TextureBuilder.hpp */,
4BBF99131C8FBA6F0075DAFB /* TextureTarget.hpp */,
4BC3B74C1CD194CC00F86E85 /* Shaders */,
);
path = Internals;
sourceTree = "<group>";
@ -2950,19 +2947,6 @@
path = "Joystick Manager";
sourceTree = "<group>";
};
4BC3B74C1CD194CC00F86E85 /* Shaders */ = {
isa = PBXGroup;
children = (
4BBB142F1CD2CECE00BDB55C /* IntermediateShader.cpp */,
4BC3B7501CD1956900F86E85 /* OutputShader.cpp */,
4BC3B74D1CD194CC00F86E85 /* Shader.cpp */,
4BBB14301CD2CECE00BDB55C /* IntermediateShader.hpp */,
4BC3B7511CD1956900F86E85 /* OutputShader.hpp */,
4BC3B74E1CD194CC00F86E85 /* Shader.hpp */,
);
path = Shaders;
sourceTree = "<group>";
};
4BC9DF4A1D04691600F44158 /* Components */ = {
isa = PBXGroup;
children = (
@ -3036,6 +3020,41 @@
path = ../../Outputs/Speaker;
sourceTree = "<group>";
};
4BD191D5219113B80042E144 /* OpenGL */ = {
isa = PBXGroup;
children = (
4BD191D6219113B80042E144 /* ArrayBuilder.cpp */,
4BD191DC219113B80042E144 /* CRTOpenGL.cpp */,
4BD191E6219113B80042E144 /* Rectangle.cpp */,
4BD191F22191180E0042E144 /* ScanTarget.cpp */,
4BD191D8219113B80042E144 /* TextureBuilder.cpp */,
4BD191DA219113B80042E144 /* TextureTarget.cpp */,
4BD191E7219113B90042E144 /* ArrayBuilder.hpp */,
4BD191D7219113B80042E144 /* CRTOpenGL.hpp */,
4BD191D9219113B80042E144 /* OpenGL.hpp */,
4BD191DB219113B80042E144 /* Rectangle.hpp */,
4BD191F32191180E0042E144 /* ScanTarget.hpp */,
4BD191DD219113B80042E144 /* TextureBuilder.hpp */,
4BD191DE219113B80042E144 /* TextureTarget.hpp */,
4BD191DF219113B80042E144 /* Shaders */,
);
name = OpenGL;
path = ../../Outputs/OpenGL;
sourceTree = "<group>";
};
4BD191DF219113B80042E144 /* Shaders */ = {
isa = PBXGroup;
children = (
4BD191E3219113B80042E144 /* IntermediateShader.cpp */,
4BD191E1219113B80042E144 /* OutputShader.cpp */,
4BD191E2219113B80042E144 /* Shader.cpp */,
4BD191E0219113B80042E144 /* IntermediateShader.hpp */,
4BD191E4219113B80042E144 /* OutputShader.hpp */,
4BD191E5219113B80042E144 /* Shader.hpp */,
);
path = Shaders;
sourceTree = "<group>";
};
4BD388431FE34E060042B588 /* Implementation */ = {
isa = PBXGroup;
children = (
@ -3676,8 +3695,10 @@
4B89451B201967B4007DE474 /* ConfidenceSummary.cpp in Sources */,
4B1B88C1202E3DB200B67DFF /* MultiConfigurable.cpp in Sources */,
4B055AA31FAE85DF0060FFFF /* ImplicitSectors.cpp in Sources */,
4BD191F1219117FA0042E144 /* Rectangle.cpp in Sources */,
4B055AAE1FAE85FD0060FFFF /* TrackSerialiser.cpp in Sources */,
4B89452B201967B4007DE474 /* File.cpp in Sources */,
4BD191F6219118390042E144 /* Shader.cpp in Sources */,
4B055A981FAE85C50060FFFF /* Drive.cpp in Sources */,
4B4B1A3D200198CA00A0F866 /* KonamiSCC.cpp in Sources */,
4B055AC31FAE9AE80060FFFF /* AmstradCPC.cpp in Sources */,
@ -3761,6 +3782,7 @@
4B894537201967B4007DE474 /* Z80.cpp in Sources */,
4B055A9F1FAE85DA0060FFFF /* HFE.cpp in Sources */,
4B07835B1FC11D42001D12BB /* Configurable.cpp in Sources */,
4BD191F52191180E0042E144 /* ScanTarget.cpp in Sources */,
4B894523201967B4007DE474 /* StaticAnalyser.cpp in Sources */,
4B055AEC1FAE9BA20060FFFF /* Z80Base.cpp in Sources */,
4B0F94FF208C1A1600FE41D9 /* NIB.cpp in Sources */,
@ -3826,11 +3848,13 @@
4BBFFEE61F7B27F1005F3FEB /* TrackSerialiser.cpp in Sources */,
4BAE49582032881E004BE78E /* CSZX8081.mm in Sources */,
4B0333AF2094081A0050B93D /* AppleDSK.cpp in Sources */,
4BD191F72191183A0042E144 /* Shader.cpp in Sources */,
4B894518201967B4007DE474 /* ConfidenceCounter.cpp in Sources */,
4B89452E201967B4007DE474 /* StaticAnalyser.cpp in Sources */,
4B38F3481F2EC11D00D9235D /* AmstradCPC.cpp in Sources */,
4B8FE2221DA19FB20090D3CE /* MachinePanel.swift in Sources */,
4B4518A41F75FD1C00926311 /* OricMFMDSK.cpp in Sources */,
4BD191F0219117F90042E144 /* Rectangle.cpp in Sources */,
4B4B1A3C200198CA00A0F866 /* KonamiSCC.cpp in Sources */,
4BB0A65B2044FD3000FB3688 /* SN76489.cpp in Sources */,
4BD5F1951D13528900631CD1 /* CSBestEffortUpdater.mm in Sources */,
@ -3864,6 +3888,7 @@
4B4518851F75E91A00926311 /* DiskController.cpp in Sources */,
4B8334841F5DA0360097E338 /* Z80Storage.cpp in Sources */,
4BA61EB01D91515900B3C876 /* NSData+StdVector.mm in Sources */,
4BD191F42191180E0042E144 /* ScanTarget.cpp in Sources */,
4B0F94FE208C1A1600FE41D9 /* NIB.cpp in Sources */,
4B89452A201967B4007DE474 /* File.cpp in Sources */,
4B4DC8211D2C2425003C5BF8 /* Vic20.cpp in Sources */,

View File

@ -29,7 +29,7 @@
#import <OpenGL/OpenGL.h>
#include <OpenGL/gl3.h>
#include "ScanTarget.hpp"
#include "../../../../Outputs/OpenGL/ScanTarget.hpp"
@interface CSMachine() <CSFastLoading>
- (void)speaker:(Outputs::Speaker::Speaker *)speaker didCompleteSamples:(const int16_t *)samples length:(int)length;
@ -73,31 +73,43 @@ struct ActivityObserver: public Activity::Observer {
__unsafe_unretained CSMachine *machine;
};
class ScanTarget: public Outputs::Display::ScanTarget {
public:
void set_modals(Modals m) {
modals_ = m;
}
Scan *get_scan() {
scans_.emplace_back();
return &scans_.back();
}
uint8_t *allocate_write_area(size_t required_length, size_t required_alignment) {
write_area_.resize(required_length);
return write_area_.data();
}
void submit(bool only_if_no_allocation_failures) {
scans_.clear();
}
private:
std::vector<Scan> scans_;
std::vector<uint8_t> write_area_;
Modals modals_;
};
//class ScanTarget: public Outputs::Display::ScanTarget {
// public:
// void set_modals(Modals m) {
// modals_ = m;
// }
//
// Scan *get_scan() {
// scans_.emplace_back();
// return &scans_.back();
// }
//
// uint8_t *allocate_write_area(size_t required_length, size_t required_alignment) {
// write_area_.resize(required_length);
// return write_area_.data();
// }
//
// void submit(bool only_if_no_allocation_failures) {
// for(const auto &scan: scans_) {
// printf("%0.2f %0.2f [%0.2f] -> %0.2f %0.2f [%0.2f] => %0.2f\n",
// float(scan.end_points[0].x) / float(modals_.output_scale.x),
// float(scan.end_points[0].y) / float(modals_.output_scale.y),
// float(scan.end_points[0].composite_angle) / 64.0f,
// float(scan.end_points[1].x) / float(modals_.output_scale.x),
// float(scan.end_points[1].y) / float(modals_.output_scale.y),
// float(scan.end_points[1].composite_angle) / 64.0f,
// (float(scan.end_points[1].composite_angle - scan.end_points[0].composite_angle) / 64.0f) / (float(scan.end_points[1].x - scan.end_points[0].x) / float(modals_.output_scale.x))
// );
// }
//
// scans_.clear();
// }
//
// private:
// std::vector<Scan> scans_;
// std::vector<uint8_t> write_area_;
// Modals modals_;
//};
@implementation CSMachine {
SpeakerDelegate _speakerDelegate;
@ -112,7 +124,7 @@ class ScanTarget: public Outputs::Display::ScanTarget {
std::bitset<65536> _depressedKeys;
NSMutableArray<NSString *> *_leds;
ScanTarget _scanTarget;
Outputs::Display::OpenGL::ScanTarget _scanTarget;
}
- (instancetype)initWithAnalyser:(CSStaticAnalyser *)result {

View File

@ -65,8 +65,8 @@ void CRT::set_new_timing(int cycles_per_line, int height_of_display, Outputs::Di
scan_target_->set_modals(scan_target_modals_);
}
void CRT::set_new_data_type(Outputs::Display::ScanTarget::Modals::DataType data_type) {
scan_target_modals_.source_data_type = data_type;
void CRT::set_new_data_type(Outputs::Display::InputDataType data_type) {
scan_target_modals_.input_data_type = data_type;
scan_target_->set_modals(scan_target_modals_);
}
@ -109,10 +109,10 @@ CRT::CRT( int cycles_per_line,
int colour_cycle_numerator, int colour_cycle_denominator,
int vertical_sync_half_lines,
bool should_alternate,
Outputs::Display::ScanTarget::Modals::DataType data_type,
Outputs::Display::InputDataType data_type,
Outputs::Display::ScanTarget *scan_target) {
scan_target_ = scan_target;
scan_target_modals_.source_data_type = data_type;
scan_target_modals_.input_data_type = data_type;
scan_target_modals_.cycles_per_line = cycles_per_line;
scan_target_modals_.clocks_per_pixel_greatest_common_divisor = clocks_per_pixel_greatest_common_divisor;
set_new_timing(cycles_per_line, height_of_display, colour_space, colour_cycle_numerator, colour_cycle_denominator, vertical_sync_half_lines, should_alternate);
@ -121,10 +121,10 @@ CRT::CRT( int cycles_per_line,
CRT::CRT( int cycles_per_line,
int clocks_per_pixel_greatest_common_divisor,
Outputs::Display::Type display_type,
Outputs::Display::ScanTarget::Modals::DataType data_type,
Outputs::Display::InputDataType data_type,
Outputs::Display::ScanTarget *scan_target) {
scan_target_ = scan_target;
scan_target_modals_.source_data_type = data_type;
scan_target_modals_.input_data_type = data_type;
scan_target_modals_.cycles_per_line = cycles_per_line;
scan_target_modals_.clocks_per_pixel_greatest_common_divisor = clocks_per_pixel_greatest_common_divisor;
set_new_display_type(cycles_per_line, display_type);

View File

@ -118,7 +118,7 @@ class CRT {
int colour_cycle_denominator,
int vertical_sync_half_lines,
bool should_alternate,
Outputs::Display::ScanTarget::Modals::DataType data_type,
Outputs::Display::InputDataType data_type,
Outputs::Display::ScanTarget *scan_target);
/*! Exactly identical to calling the designated constructor with colour subcarrier information
@ -127,7 +127,7 @@ class CRT {
CRT(int cycles_per_line,
int minimum_cycles_per_pixel,
Outputs::Display::Type display_type,
Outputs::Display::ScanTarget::Modals::DataType data_type,
Outputs::Display::InputDataType data_type,
Outputs::Display::ScanTarget *scan_target);
/*! Resets the CRT with new timing information. The CRT then continues as though the new timing had
@ -149,7 +149,7 @@ class CRT {
/*! Changes the type of data being supplied as input.
*/
void set_new_data_type(Outputs::Display::ScanTarget::Modals::DataType data_type);
void set_new_data_type(Outputs::Display::InputDataType data_type);
/*! Output at the sync level.

View File

@ -0,0 +1,93 @@
//
// ScanTarget.cpp
// Clock Signal
//
// Created by Thomas Harte on 05/11/2018.
// Copyright © 2018 Thomas Harte. All rights reserved.
//
#include "ScanTarget.hpp"
using namespace Outputs::Display::OpenGL;
namespace {
const int WriteAreaWidth = 2048;
const int WriteAreaHeight = 2048;
}
void ScanTarget::set_modals(Modals modals) {
// TODO: consider resizing the write_area_texture_, and setting
// write_area_texture_line_length_ appropriately.
modals_ = modals;
const auto data_type_size = Outputs::Display::size_for_data_type(modals.input_data_type);
if(data_type_size != data_type_size_) {
// TODO: flush output.
data_type_size_ = data_type_size;
write_area_texture_.resize(2048*2048*data_type_size_);
write_area_x_ = 0;
write_area_pointers_.write_pointer = 0;
}
}
Outputs::Display::ScanTarget::Scan *ScanTarget::get_scan() {
if(allocation_has_failed_) return nullptr;
const auto result = &scan_buffer_[scan_buffer_pointers_.write_pointer];
// Advance the pointer.
const auto next_write_pointer = (scan_buffer_pointers_.write_pointer + 1) % scan_buffer_.size();
// Check whether that's too many.
if(next_write_pointer == scan_buffer_pointers_.read_pointer) {
allocation_has_failed_ = true;
return nullptr;
}
scan_buffer_pointers_.write_pointer = next_write_pointer;
// Fill in extra OpenGL-specific details.
result->data_y = write_area_pointers_.write_pointer;
result->composite_y = 0;
return static_cast<Outputs::Display::ScanTarget::Scan *>(result);
}
uint8_t *ScanTarget::allocate_write_area(size_t required_length, size_t required_alignment) {
if(allocation_has_failed_) return nullptr;
// Will this fit on the current line? If so, job done.
uint16_t aligned_start = write_area_x_ + 1;
aligned_start += uint16_t((required_alignment - aligned_start%required_alignment)%required_alignment);
const uint16_t end =
aligned_start
+ uint16_t(2 + required_length);
if(end <= WriteAreaWidth) {
last_supplied_x_ = aligned_start;
return &write_area_texture_[write_area_pointers_.write_pointer*WriteAreaHeight + aligned_start];
}
// Otherwise, look for the next line. But if that's where the read pointer is, don't proceed.
const uint16_t next_y = (write_area_pointers_.write_pointer + 1) % WriteAreaHeight;
if(next_y == write_area_pointers_.read_pointer) {
allocation_has_failed_ = true;
return nullptr;
}
// Advance then.
last_supplied_x_ = uint16_t(required_alignment);
write_area_pointers_.write_pointer = next_y;
return &write_area_texture_[write_area_pointers_.write_pointer*WriteAreaHeight + last_supplied_x_];
}
void ScanTarget::reduce_previous_allocation_to(size_t actual_length) {
if(allocation_has_failed_) return;
write_area_x_ = 2 + uint16_t(actual_length) + last_supplied_x_;
}
void ScanTarget::submit() {
// TODO.
}

View File

@ -0,0 +1,71 @@
//
// ScanTarget.hpp
// Clock Signal
//
// Created by Thomas Harte on 05/11/2018.
// Copyright © 2018 Thomas Harte. All rights reserved.
//
#ifndef ScanTarget_hpp
#define ScanTarget_hpp
#include "../ScanTarget.hpp"
#include <array>
#include <atomic>
#include <cstdint>
#include <vector>
namespace Outputs {
namespace Display {
namespace OpenGL {
class ScanTarget: public Outputs::Display::ScanTarget {
public:
void set_modals(Modals) override;
Scan *get_scan() override;
uint8_t *allocate_write_area(size_t required_length, size_t required_alignment) override;
void reduce_previous_allocation_to(size_t actual_length) override;
void submit() override;
private:
// Extends the definition of a Scan to include two extra fields,
// relevant to the way that this scan target processes video.
struct Scan: public Outputs::Display::ScanTarget::Scan {
/// Stores the y coordinate that this scan's data is at, within the write area texture.
uint16_t data_y;
/// Stores the y coordinate of this continuous composite segment within the conversion buffer.
uint16_t composite_y;
};
template <typename T> struct PointerSet {
/// A pointer to the final thing currently cleared for submission.
T submit_pointer;
/// A pointer to the next thing that should be provided to the caller for data.
T write_pointer;
/// A pointer to the first thing not yet submitted for display.
std::atomic<T> read_pointer;
};
// Maintains a buffer of the most recent 3072 scans.
std::array<Scan, 3072> scan_buffer_;
PointerSet<size_t> scan_buffer_pointers_;
// Uses a texture to vend write areas.
std::vector<uint8_t> write_area_texture_;
size_t data_type_size_ = 0;
uint16_t write_area_x_ = 0, last_supplied_x_ = 0;
PointerSet<uint16_t> write_area_pointers_;
// Track allocation failures.
bool allocation_has_failed_ = false;
// Receives scan target modals.
Modals modals_;
};
}
}
}
#endif /* ScanTarget_hpp */

View File

@ -12,7 +12,7 @@
#include <cstring>
#include <sstream>
#include "../../../../SignalProcessing/FIRFilter.hpp"
#include "../../../SignalProcessing/FIRFilter.hpp"
using namespace OpenGL;

View File

@ -10,6 +10,7 @@
#define Outputs_Display_ScanTarget_h
#include <cstddef>
#include <cstdint>
namespace Outputs {
namespace Display {
@ -47,6 +48,52 @@ enum class ColourSpace {
YUV
};
/*!
Enumerates the potential formats of input data.
*/
enum class InputDataType {
// The luminance types can be used to feed only two video pipelines:
// black and white video, or composite colour.
Luminance1, // 1 byte/pixel; any bit set => white; no bits set => black.
Luminance8, // 1 byte/pixel; linear scale.
// The luminance plus phase types describe a luminance and the phase offset
// of a colour subcarrier. So they can be used to generate a luminance signal,
// or an s-video pipeline.
Phase8Luminance8, // 2 bytes/pixel; first is phase, second is luminance.
// Phase is encoded on a 192-unit circle; anything
// greater than 192 implies that the colour part of
// the signal should be omitted.
// The RGB types can directly feed an RGB pipeline, naturally, or can be mapped
// to phase+luminance, or just to luminance.
Red1Green1Blue1, // 1 byte/pixel; bit 0 is blue on or off, bit 1 is green, bit 2 is red.
Red2Green2Blue2, // 1 byte/pixel; bits 0 and 1 are blue, bits 2 and 3 are green, bits 4 and 5 are blue.
Red4Green4Blue4, // 2 bytes/pixel; first nibble is red, second is green, third is blue.
Red8Green8Blue8, // 4 bytes/pixel; first is red, second is green, third is blue, fourth is vacant.
};
inline size_t size_for_data_type(InputDataType data_type) {
switch(data_type) {
case InputDataType::Luminance1:
case InputDataType::Luminance8:
case InputDataType::Red1Green1Blue1:
case InputDataType::Red2Green2Blue2:
return 1;
case InputDataType::Phase8Luminance8:
case InputDataType::Red4Green4Blue4:
return 2;
case InputDataType::Red8Green8Blue8:
return 4;
}
}
/*!
Provides an abstract target for 'scans' i.e. continuous sweeps of output data,
which are identified by 2d start and end coordinates, and the PCM-sampled data
@ -66,34 +113,8 @@ struct ScanTarget {
*/
struct Modals {
/*!
Enumerates the potential formats of input data.
*/
enum class DataType {
// The luminance types can be used to feed only two video pipelines:
// black and white video, or composite colour.
Luminance1, // 1 byte/pixel; any bit set => white; no bits set => black.
Luminance8, // 1 byte/pixel; linear scale.
// The luminance plus phase types describe a luminance and the phase offset
// of a colour subcarrier. So they can be used to generate a luminance signal,
// or an s-video pipeline.
Phase8Luminance8, // 2 bytes/pixel; first is phase, second is luminance.
// Phase is encoded on a 192-unit circle; anything
// greater than 192 implies that the colour part of
// the signal should be omitted.
// The RGB types can directly feed an RGB pipeline, naturally, or can be mapped
// to phase+luminance, or just to luminance.
Red1Green1Blue1, // 1 byte/pixel; bit 0 is blue on or off, bit 1 is green, bit 2 is red.
Red2Green2Blue2, // 1 byte/pixel; bits 0 and 1 are blue, bits 2 and 3 are green, bits 4 and 5 are blue.
Red4Green4Blue4, // 2 bytes/pixel; first nibble is red, second is green, third is blue.
Red8Green8Blue8, // 4 bytes/pixel; first is red, second is green, third is blue, fourth is vacant.
} source_data_type;
/// Describes the format of input data.
InputDataType input_data_type;
/// If being fed composite data, this defines the colour space in use.
ColourSpace composite_colour_space;
@ -187,19 +208,22 @@ struct ScanTarget {
/// Announces that the owner is finished with the region created by the most recent @c allocate_write_area
/// and indicates that its actual final size was @c actual_length.
virtual void reduce_previous_allocation_to(size_t actual_length) {};
///
/// It is required that every call to allocate_write_area be paired with a call to reduce_previous_allocation_to.
virtual void reduce_previous_allocation_to(size_t actual_length) {}
/// Announces that all endpoint pairs and write areas obtained since the last @c submit have now been
/// populated with appropriate data.
/// Marks the end of an atomic set of data. Drawing is best effort, so the scan target should either:
///
/// (i) output everything received since the previous submit; or
/// (ii) output nothing.
///
/// If there were any allocation failures — i.e. any null responses to allocate_write_area or
/// get_scan — then (ii) is a required response. But a scan target may also need to opt for (ii)
/// for any other reason.
///
/// The ScanTarget isn't bound to take any drawing action immediately; it may sit on submitted data for
/// as long as it feels is appropriate subject to an @c flush.
virtual void submit(bool only_if_no_allocation_failures = true) = 0;
/// Announces that any submitted data not yet output should be output now, but needn't block while
/// doing so. This generally communicates that processing is now otherwise 'up to date', so no
/// further delay should be allowed.
// virtual void flush() = 0;
virtual void submit() = 0;
/*