mirror of
				https://github.com/TomHarte/CLK.git
				synced 2025-10-30 14:16:04 +00:00 
			
		
		
		
	Compare commits
	
		
			6 Commits
		
	
	
		
			2025-10-19
			...
			SoftwareOu
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 4078baa424 | ||
|  | 3179d0d963 | ||
|  | 6a8c792c63 | ||
|  | 678e1a38fa | ||
|  | f4004baff8 | ||
|  | f04e4faae2 | 
| @@ -13,6 +13,7 @@ | ||||
| 		4B0333B02094081A0050B93D /* AppleDSK.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0333AD2094081A0050B93D /* AppleDSK.cpp */; }; | ||||
| 		4B049CDD1DA3C82F00322067 /* BCDTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B049CDC1DA3C82F00322067 /* BCDTest.swift */; }; | ||||
| 		4B04C899285E3DC800AA8FD6 /* 65816ComparativeTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B04C898285E3DC800AA8FD6 /* 65816ComparativeTests.mm */; }; | ||||
| 		4B04C89F2870BDEC00AA8FD6 /* ScanTarget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B04C89E2870BDDD00AA8FD6 /* ScanTarget.cpp */; }; | ||||
| 		4B051C912669C90B00CA44E8 /* ROMCatalogue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B051C5826670A9300CA44E8 /* ROMCatalogue.cpp */; }; | ||||
| 		4B051C922669C90B00CA44E8 /* ROMCatalogue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B051C5826670A9300CA44E8 /* ROMCatalogue.cpp */; }; | ||||
| 		4B051C93266D9D6900CA44E8 /* ROMImages in Resources */ = {isa = PBXBuildFile; fileRef = 4BC9DF441D044FCA00F44158 /* ROMImages */; }; | ||||
| @@ -1113,6 +1114,8 @@ | ||||
| 		4B049CDC1DA3C82F00322067 /* BCDTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BCDTest.swift; sourceTree = "<group>"; }; | ||||
| 		4B04B65622A58CB40006AB58 /* Target.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Target.hpp; sourceTree = "<group>"; }; | ||||
| 		4B04C898285E3DC800AA8FD6 /* 65816ComparativeTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = 65816ComparativeTests.mm; sourceTree = "<group>"; }; | ||||
| 		4B04C89D2870BDDD00AA8FD6 /* ScanTarget.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ScanTarget.hpp; sourceTree = "<group>"; }; | ||||
| 		4B04C89E2870BDDD00AA8FD6 /* ScanTarget.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ScanTarget.cpp; sourceTree = "<group>"; }; | ||||
| 		4B051C5826670A9300CA44E8 /* ROMCatalogue.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ROMCatalogue.cpp; sourceTree = "<group>"; }; | ||||
| 		4B051C5926670A9300CA44E8 /* ROMCatalogue.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ROMCatalogue.hpp; sourceTree = "<group>"; }; | ||||
| 		4B051C94266EF50200CA44E8 /* AppleIIController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppleIIController.swift; sourceTree = "<group>"; }; | ||||
| @@ -2263,6 +2266,15 @@ | ||||
| /* End PBXFrameworksBuildPhase section */ | ||||
|  | ||||
| /* Begin PBXGroup section */ | ||||
| 		4B04C89C2870BDDD00AA8FD6 /* SoftwareRendering */ = { | ||||
| 			isa = PBXGroup; | ||||
| 			children = ( | ||||
| 				4B04C89D2870BDDD00AA8FD6 /* ScanTarget.hpp */, | ||||
| 				4B04C89E2870BDDD00AA8FD6 /* ScanTarget.cpp */, | ||||
| 			); | ||||
| 			path = SoftwareRendering; | ||||
| 			sourceTree = "<group>"; | ||||
| 		}; | ||||
| 		4B051C9F2676F52200CA44E8 /* Enterprise */ = { | ||||
| 			isa = PBXGroup; | ||||
| 			children = ( | ||||
| @@ -2731,6 +2743,7 @@ | ||||
| 				4B0CCC411C62D0B3001CAC5F /* CRT */, | ||||
| 				4BD191D5219113B80042E144 /* OpenGL */, | ||||
| 				4BB8616B24E22DC500A00E03 /* ScanTargets */, | ||||
| 				4B04C89C2870BDDD00AA8FD6 /* SoftwareRendering */, | ||||
| 				4BD060A41FE49D3C006E14BE /* Speaker */, | ||||
| 			); | ||||
| 			name = Outputs; | ||||
| @@ -5643,6 +5656,7 @@ | ||||
| 				4BBB70A5202011C2002FE009 /* MultiMediaTarget.cpp in Sources */, | ||||
| 				4B8318BC22D3E588006DB630 /* DisplayMetrics.cpp in Sources */, | ||||
| 				4BEDA40E25B2844B000C2DBD /* Decoder.cpp in Sources */, | ||||
| 				4B04C89F2870BDEC00AA8FD6 /* ScanTarget.cpp in Sources */, | ||||
| 				4B1B88BD202E3D3D00B67DFF /* MultiMachine.cpp in Sources */, | ||||
| 				4BE0A3EF237BB170002AB46F /* ST.cpp in Sources */, | ||||
| 				4B055A971FAE85BB0060FFFF /* ZX8081.cpp in Sources */, | ||||
|   | ||||
| @@ -82,19 +82,19 @@ | ||||
|          </CommandLineArgument> | ||||
|          <CommandLineArgument | ||||
|             argument = "--volume=0.001" | ||||
|             isEnabled = "YES"> | ||||
|             isEnabled = "NO"> | ||||
|          </CommandLineArgument> | ||||
|          <CommandLineArgument | ||||
|             argument = "--new=enterprise" | ||||
|             isEnabled = "YES"> | ||||
|             isEnabled = "NO"> | ||||
|          </CommandLineArgument> | ||||
|          <CommandLineArgument | ||||
|             argument = "--basic-version=any" | ||||
|             isEnabled = "YES"> | ||||
|             isEnabled = "NO"> | ||||
|          </CommandLineArgument> | ||||
|          <CommandLineArgument | ||||
|             argument = ""/Users/thomasharte/Library/Mobile Documents/com~apple~CloudDocs/Desktop/Soft/ColecoVision/Galaxian (1983)(Atari).col"" | ||||
|             isEnabled = "NO"> | ||||
|             isEnabled = "YES"> | ||||
|          </CommandLineArgument> | ||||
|          <CommandLineArgument | ||||
|             argument = ""/Users/thomasharte/Library/Mobile Documents/com~apple~CloudDocs/Desktop/Soft/Master System/R-Type (NTSC).sms"" | ||||
|   | ||||
| @@ -95,6 +95,9 @@ SOURCES += glob.glob('../../Machines/Sinclair/ZXSpectrum/*.cpp') | ||||
| SOURCES += glob.glob('../../Outputs/*.cpp') | ||||
| SOURCES += glob.glob('../../Outputs/CRT/*.cpp') | ||||
| SOURCES += glob.glob('../../Outputs/ScanTargets/*.cpp') | ||||
|  | ||||
| SOURCES += glob.glob('../../Outputs/SoftwareRendering/*.cpp') | ||||
|  | ||||
| SOURCES += glob.glob('../../Outputs/OpenGL/*.cpp') | ||||
| SOURCES += glob.glob('../../Outputs/OpenGL/Primitives/*.cpp') | ||||
|  | ||||
|   | ||||
| @@ -30,6 +30,9 @@ | ||||
| #include "../../Machines/MachineTypes.hpp" | ||||
|  | ||||
| #include "../../Activity/Observer.hpp" | ||||
|  | ||||
| #include "../../Outputs/SoftwareRendering/ScanTarget.hpp" | ||||
|  | ||||
| #include "../../Outputs/OpenGL/Primitives/Rectangle.hpp" | ||||
| #include "../../Outputs/OpenGL/ScanTarget.hpp" | ||||
| #include "../../Outputs/OpenGL/Screenshot.hpp" | ||||
| @@ -897,17 +900,18 @@ int main(int argc, char *argv[]) { | ||||
| 	glGetIntegerv(GL_FRAMEBUFFER_BINDING, &target_framebuffer); | ||||
|  | ||||
| 	// Setup output, assuming a CRT machine for now, and prepare a best-effort updater. | ||||
| 	Outputs::Display::OpenGL::ScanTarget scan_target(target_framebuffer); | ||||
| 	Outputs::Display::OpenGL::ScanTarget opengl_scan_target(target_framebuffer); | ||||
| 	Outputs::Display::Software::ScanTarget software_scan_target; | ||||
| 	std::unique_ptr<ActivityObserver> activity_observer; | ||||
| 	bool uses_mouse; | ||||
| 	std::vector<SDLJoystick> joysticks; | ||||
|  | ||||
| 	machine_runner.machine_mutex = &machine_mutex; | ||||
| 	const auto setup_machine_input_output = [&scan_target, &machine, &speaker_delegate, &activity_observer, &joysticks, &uses_mouse, &machine_runner] { | ||||
| 	const auto setup_machine_input_output = [&software_scan_target, &machine, &speaker_delegate, &activity_observer, &joysticks, &uses_mouse, &machine_runner] { | ||||
| 		// Wire up the best-effort updater, its delegate, and the speaker delegate. | ||||
| 		machine_runner.machine = machine.get(); | ||||
|  | ||||
| 		machine->scan_producer()->set_scan_target(&scan_target); | ||||
| 		machine->scan_producer()->set_scan_target(&software_scan_target); | ||||
|  | ||||
| 		// For now, lie about audio output intentions. | ||||
| 		const auto audio_producer = machine->audio_producer(); | ||||
| @@ -986,8 +990,8 @@ int main(int argc, char *argv[]) { | ||||
| 	machine_runner.start(); | ||||
| 	while(!should_quit) { | ||||
| 		// Draw a new frame, indicating completion of the draw to the machine runner. | ||||
| 		scan_target.update(int(window_width), int(window_height)); | ||||
| 		scan_target.draw(int(window_width), int(window_height)); | ||||
| //		opengl_scan_target.update(int(window_width), int(window_height)); | ||||
| //		opengl_scan_target.draw(int(window_width), int(window_height)); | ||||
| 		if(activity_observer) activity_observer->draw(); | ||||
| 		machine_runner.signal_did_draw(); | ||||
|  | ||||
| @@ -1012,7 +1016,7 @@ int main(int argc, char *argv[]) { | ||||
| 						case SDL_WINDOWEVENT_RESIZED: { | ||||
| 							GLint target_framebuffer = 0; | ||||
| 							glGetIntegerv(GL_FRAMEBUFFER_BINDING, &target_framebuffer); | ||||
| 							scan_target.set_target_framebuffer(target_framebuffer); | ||||
| 							opengl_scan_target.set_target_framebuffer(target_framebuffer); | ||||
| 							SDL_GetWindowSize(window, &window_width, &window_height); | ||||
| 							if(activity_observer) activity_observer->set_aspect_ratio(float(window_width) / float(window_height)); | ||||
| 						} break; | ||||
| @@ -1039,7 +1043,7 @@ int main(int argc, char *argv[]) { | ||||
| 					if(error != Machine::Error::None) break; | ||||
|  | ||||
| 					machine = std::move(new_machine); | ||||
| 					static_cast<Outputs::Display::ScanTarget *>(&scan_target)->will_change_owner(); | ||||
| 					static_cast<Outputs::Display::ScanTarget *>(&opengl_scan_target)->will_change_owner(); | ||||
| 					setup_machine_input_output(); | ||||
| 					window_titler.set_file_name(final_path_component(event.drop.file)); | ||||
| 				} break; | ||||
|   | ||||
| @@ -6,8 +6,8 @@ | ||||
| //  Copyright © 2018 Thomas Harte. All rights reserved. | ||||
| // | ||||
|  | ||||
| #ifndef ScanTarget_hpp | ||||
| #define ScanTarget_hpp | ||||
| #ifndef Outputs_OpenGL_ScanTarget_hpp | ||||
| #define Outputs_OpenGL_ScanTarget_hpp | ||||
|  | ||||
| #include "../Log.hpp" | ||||
| #include "../DisplayMetrics.hpp" | ||||
| @@ -160,4 +160,4 @@ class ScanTarget: public Outputs::Display::BufferingScanTarget {	// TODO: use pr | ||||
| } | ||||
| } | ||||
|  | ||||
| #endif /* ScanTarget_hpp */ | ||||
| #endif /* Outputs_OpenGL_ScanTarget_hpp */ | ||||
|   | ||||
| @@ -312,7 +312,7 @@ struct ScanTarget { | ||||
| 		/// @return A valid pointer, or @c nullptr if insufficient further storage is available. | ||||
| 		virtual Scan *begin_scan() = 0; | ||||
|  | ||||
| 		/// Requests a new scan to populate. | ||||
| 		/// Confirms that the scan returned by @c begin_scan (if any) is now fully populated. | ||||
| 		virtual void end_scan() {} | ||||
|  | ||||
| 		/// Finds the first available storage of at least @c required_length pixels in size which is | ||||
|   | ||||
							
								
								
									
										28
									
								
								Outputs/SoftwareRendering/ScanTarget.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								Outputs/SoftwareRendering/ScanTarget.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| // | ||||
| //  SoftwareScanTarget.cpp | ||||
| //  Clock Signal | ||||
| // | ||||
| //  Created by Thomas Harte on 02/07/2022. | ||||
| //  Copyright © 2022 Thomas Harte. All rights reserved. | ||||
| // | ||||
|  | ||||
| #include "ScanTarget.hpp" | ||||
|  | ||||
| using namespace Outputs::Display::Software; | ||||
|  | ||||
| template < | ||||
| 	Outputs::Display::InputDataType input_type, | ||||
| 	Outputs::Display::DisplayType display_type, | ||||
| 	Outputs::Display::ColourSpace colour_space | ||||
| > void ScanTarget::process() { | ||||
| 	// TODO. | ||||
| } | ||||
|  | ||||
| void ScanTarget::set_modals(Modals m) { | ||||
| 	printf(""); | ||||
| } | ||||
|  | ||||
| void ScanTarget::submit() { | ||||
| 	scan_buffer_pointer_ = sample_buffer_pointer_ = 0; | ||||
| 	has_failed_ = false; | ||||
| } | ||||
							
								
								
									
										82
									
								
								Outputs/SoftwareRendering/ScanTarget.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								Outputs/SoftwareRendering/ScanTarget.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,82 @@ | ||||
| // | ||||
| //  SoftwareScanTarget.hpp | ||||
| //  Clock Signal | ||||
| // | ||||
| //  Created by Thomas Harte on 02/07/2022. | ||||
| //  Copyright © 2022 Thomas Harte. All rights reserved. | ||||
| // | ||||
|  | ||||
| #ifndef SoftwareScanTarget_hpp | ||||
| #define SoftwareScanTarget_hpp | ||||
|  | ||||
| #include "../ScanTarget.hpp" | ||||
|  | ||||
| #include <array> | ||||
|  | ||||
| namespace Outputs { | ||||
| namespace Display { | ||||
| namespace Software { | ||||
|  | ||||
| /*! | ||||
| 	Provides a ScanTarget that does all intermediate processing on the CPU, | ||||
| 	and uses the FrameProducer interface to output results. | ||||
| */ | ||||
| class ScanTarget: public Outputs::Display::ScanTarget { | ||||
|  | ||||
| 	private: | ||||
| 		// The following are all overridden from Outputs::Display::ScanTarget; | ||||
| 		// some notes on their meaning to this specific scan target are given below. | ||||
|  | ||||
| 		void set_modals(Modals) override; | ||||
|  | ||||
| 		Scan *begin_scan() override { | ||||
| 			if(has_failed_ || scan_buffer_pointer_ == 8) { | ||||
| 				has_failed_ = true; | ||||
| 				return nullptr; | ||||
| 			} | ||||
|  | ||||
| 			vended_buffer_ = &scan_buffer_[scan_buffer_pointer_]; | ||||
| 			++scan_buffer_pointer_; | ||||
| 			return vended_buffer_; | ||||
| 		} | ||||
| 		void end_scan() override { | ||||
| 			// TODO: adjust sample buffer locations. | ||||
| 		} | ||||
|  | ||||
| 		uint8_t *begin_data(size_t, size_t required_alignment) override { | ||||
| 			// Achieve required alignment. | ||||
| 			sample_buffer_pointer_ += (required_alignment - sample_buffer_pointer_) & (required_alignment - 1); | ||||
|  | ||||
| 			// Return target. | ||||
| 			return &sample_buffer_[sample_buffer_pointer_]; | ||||
|  | ||||
| 			// TODO: nullptr case. | ||||
| 		} | ||||
| 		void end_data(size_t actual_length) override { | ||||
| 			sample_buffer_pointer_ += actual_length; | ||||
| 		} | ||||
|  | ||||
| 		// | ||||
| 		void submit() final; | ||||
|  | ||||
| 		template <InputDataType, DisplayType, ColourSpace> void process(); | ||||
|  | ||||
| 		// Temporaries; each set of scans is rasterised synchronously upon | ||||
| 		// its submit, so the storage here is a lot simpler than for | ||||
| 		// the GPU-powered scan targets. | ||||
| 		std::array<Scan, 8> scan_buffer_; | ||||
| 		Scan *vended_buffer_ = nullptr; | ||||
| 		size_t scan_buffer_pointer_ = 0; | ||||
|  | ||||
| 		std::array<uint8_t, 2048> sample_buffer_; | ||||
| 		size_t sample_buffer_pointer_ = 0; | ||||
|  | ||||
| 		bool has_failed_ = false; | ||||
|  | ||||
| }; | ||||
|  | ||||
| } | ||||
| } | ||||
| } | ||||
|  | ||||
| #endif /* SoftwareScanTarget_hpp */ | ||||
		Reference in New Issue
	
	Block a user