From 0db8938d27915cd556db943aee119ed763413389 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 6 Jan 2016 23:14:36 -0500 Subject: [PATCH] Added the option for the CSCathodeRayView to show only a subsection of the full scan area. Zoomed in a little on the 2600. Put in enough piping to give the Electron sight of its ROMs at least. --- Machines/Electron/Electron.cpp | 2 + .../Clock Signal.xcodeproj/project.pbxproj | 24 +++++++++ .../Documents/Atari2600Document.swift | 1 + .../Documents/ElectronDocument.swift | 7 +++ .../Mac/Clock Signal/Views/CSCathodeRayView.h | 4 ++ .../Mac/Clock Signal/Views/CSCathodeRayView.m | 49 +++++++++++++++++-- .../Mac/Clock Signal/Wrappers/CSElectron.h | 3 ++ .../Mac/Clock Signal/Wrappers/CSElectron.mm | 8 +++ 8 files changed, 93 insertions(+), 5 deletions(-) diff --git a/Machines/Electron/Electron.cpp b/Machines/Electron/Electron.cpp index 6d8a0fd2c..7967c06a6 100644 --- a/Machines/Electron/Electron.cpp +++ b/Machines/Electron/Electron.cpp @@ -23,6 +23,8 @@ Machine::~Machine() unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uint16_t address, uint8_t *value) { + printf("%04x\n", address); + if(address < 32768) { if(isReadOperation(operation)) diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index f84d757ea..a6e376595 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -298,6 +298,8 @@ 4BB73EAC1B587A5100552FC2 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4BB73EAA1B587A5100552FC2 /* MainMenu.xib */; }; 4BB73EB71B587A5100552FC2 /* AllSuiteATests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BB73EB61B587A5100552FC2 /* AllSuiteATests.swift */; }; 4BB73EC21B587A5100552FC2 /* Clock_SignalUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BB73EC11B587A5100552FC2 /* Clock_SignalUITests.swift */; }; + 4BE5F85E1C3E1C2500C43F01 /* basic.rom in Resources */ = {isa = PBXBuildFile; fileRef = 4BE5F85C1C3E1C2500C43F01 /* basic.rom */; }; + 4BE5F85F1C3E1C2500C43F01 /* os.rom in Resources */ = {isa = PBXBuildFile; fileRef = 4BE5F85D1C3E1C2500C43F01 /* os.rom */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -630,6 +632,8 @@ 4BB73EC11B587A5100552FC2 /* Clock_SignalUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Clock_SignalUITests.swift; sourceTree = ""; }; 4BB73EC31B587A5100552FC2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 4BB73ECF1B587A6700552FC2 /* Clock Signal.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "Clock Signal.entitlements"; sourceTree = ""; }; + 4BE5F85C1C3E1C2500C43F01 /* basic.rom */ = {isa = PBXFileReference; lastKnownFileType = file; path = basic.rom; sourceTree = ""; }; + 4BE5F85D1C3E1C2500C43F01 /* os.rom */ = {isa = PBXFileReference; lastKnownFileType = file; path = os.rom; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -1040,6 +1044,7 @@ 4BB73EA01B587A5100552FC2 /* Clock Signal */ = { isa = PBXGroup; children = ( + 4BE5F85A1C3E1C2500C43F01 /* Resources */, 4BB73ECF1B587A6700552FC2 /* Clock Signal.entitlements */, 4B1414501B58848C00E04248 /* ClockSignal-Bridging-Header.h */, 4BB73EAD1B587A5100552FC2 /* Info.plist */, @@ -1097,6 +1102,23 @@ path = ../../Processors; sourceTree = ""; }; + 4BE5F85A1C3E1C2500C43F01 /* Resources */ = { + isa = PBXGroup; + children = ( + 4BE5F85B1C3E1C2500C43F01 /* Electron */, + ); + path = Resources; + sourceTree = ""; + }; + 4BE5F85B1C3E1C2500C43F01 /* Electron */ = { + isa = PBXGroup; + children = ( + 4BE5F85C1C3E1C2500C43F01 /* basic.rom */, + 4BE5F85D1C3E1C2500C43F01 /* os.rom */, + ); + path = Electron; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -1208,8 +1230,10 @@ files = ( 4B2E2D951C399D1200138695 /* ElectronDocument.xib in Resources */, 4BB73EA91B587A5100552FC2 /* Assets.xcassets in Resources */, + 4BE5F85F1C3E1C2500C43F01 /* os.rom in Resources */, 4BB73EA71B587A5100552FC2 /* Atari2600Document.xib in Resources */, 4BB73EAC1B587A5100552FC2 /* MainMenu.xib in Resources */, + 4BE5F85E1C3E1C2500C43F01 /* basic.rom in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/OSBindings/Mac/Clock Signal/Documents/Atari2600Document.swift b/OSBindings/Mac/Clock Signal/Documents/Atari2600Document.swift index 835597711..ba88e0797 100644 --- a/OSBindings/Mac/Clock Signal/Documents/Atari2600Document.swift +++ b/OSBindings/Mac/Clock Signal/Documents/Atari2600Document.swift @@ -19,6 +19,7 @@ class Atari2600Document: MachineDocument { override func windowControllerDidLoadNib(aController: NSWindowController) { super.windowControllerDidLoadNib(aController) atari2600.view = openGLView + openGLView.frameBounds = CGRectMake(0.1, 0.1, 0.8, 0.8) } override class func autosavesInPlace() -> Bool { diff --git a/OSBindings/Mac/Clock Signal/Documents/ElectronDocument.swift b/OSBindings/Mac/Clock Signal/Documents/ElectronDocument.swift index 026e0bb1c..0756920e9 100644 --- a/OSBindings/Mac/Clock Signal/Documents/ElectronDocument.swift +++ b/OSBindings/Mac/Clock Signal/Documents/ElectronDocument.swift @@ -14,6 +14,13 @@ class ElectronDocument: MachineDocument { override init() { super.init() self.intendedCyclesPerSecond = 2000000 + + if let osPath = NSBundle.mainBundle().pathForResource("os", ofType: "rom") { + electron.setOSROM(NSData(contentsOfFile: osPath)!) + } + if let basicPath = NSBundle.mainBundle().pathForResource("basic", ofType: "rom") { + electron.setBASICROM(NSData(contentsOfFile: basicPath)!) + } } // override func windowControllerDidLoadNib(aController: NSWindowController) { diff --git a/OSBindings/Mac/Clock Signal/Views/CSCathodeRayView.h b/OSBindings/Mac/Clock Signal/Views/CSCathodeRayView.h index d07416c8e..5eff05a12 100644 --- a/OSBindings/Mac/Clock Signal/Views/CSCathodeRayView.h +++ b/OSBindings/Mac/Clock Signal/Views/CSCathodeRayView.h @@ -37,4 +37,8 @@ typedef NS_ENUM(NSInteger, CSCathodeRayViewSignalType) { - (BOOL)pushFrame:(nonnull CRTFrame *)crtFrame; - (void)setSignalDecoder:(nonnull NSString *)decoder type:(CSCathodeRayViewSignalType)type; +// these are relative to a [0, 1] range in both width and height; +// default is .origin = (0, 0), .size = (1, 1) +@property (nonatomic, assign) CGRect frameBounds; + @end diff --git a/OSBindings/Mac/Clock Signal/Views/CSCathodeRayView.m b/OSBindings/Mac/Clock Signal/Views/CSCathodeRayView.m index d9d4870f1..bbbaa3628 100644 --- a/OSBindings/Mac/Clock Signal/Views/CSCathodeRayView.m +++ b/OSBindings/Mac/Clock Signal/Views/CSCathodeRayView.m @@ -25,6 +25,7 @@ GLint _lateralAttribute; GLint _textureSizeUniform, _windowSizeUniform; + GLint _boundsOriginUniform, _boundsSizeUniform; GLint _alphaUniform; GLuint _textureName, _shadowMaskTextureName; @@ -117,6 +118,12 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt glDeleteProgram(_shaderProgram); } +- (NSPoint)backingViewSize +{ + NSPoint backingSize = {.x = self.bounds.size.width, .y = self.bounds.size.height}; + return [self convertPointToBacking:backingSize]; +} + - (void)reshape { [super reshape]; @@ -124,15 +131,35 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt [self.openGLContext makeCurrentContext]; CGLLockContext([[self openGLContext] CGLContextObj]); - NSPoint backingSize = {.x = self.bounds.size.width, .y = self.bounds.size.height}; - NSPoint viewSize = [self convertPointToBacking:backingSize]; + NSPoint viewSize = [self backingViewSize]; glViewport(0, 0, (GLsizei)viewSize.x, (GLsizei)viewSize.y); - glUniform2f(_windowSizeUniform, (GLfloat)viewSize.x, (GLfloat)viewSize.y); + [self pushSizeUniforms]; CGLUnlockContext([[self openGLContext] CGLContextObj]); } +- (void)setFrameBounds:(CGRect)frameBounds +{ + _frameBounds = frameBounds; + + [self.openGLContext makeCurrentContext]; + CGLLockContext([[self openGLContext] CGLContextObj]); + + [self pushSizeUniforms]; + + CGLUnlockContext([[self openGLContext] CGLContextObj]); +} + +- (void)pushSizeUniforms +{ + NSPoint viewSize = [self backingViewSize]; + glUniform2f(_windowSizeUniform, (GLfloat)viewSize.x, (GLfloat)viewSize.y); + + glUniform2f(_boundsOriginUniform, (GLfloat)_frameBounds.origin.x, (GLfloat)_frameBounds.origin.y); + glUniform2f(_boundsSizeUniform, (GLfloat)_frameBounds.size.width, (GLfloat)_frameBounds.size.height); +} + - (void)awakeFromNib { NSOpenGLPixelFormatAttribute attributes[] = @@ -159,6 +186,9 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt self.pixelFormat = pixelFormat; self.openGLContext = context; self.wantsBestResolutionOpenGLSurface = YES; + + // establish default instance variable values + self.frameBounds = CGRectMake(0.0, 0.0, 1.0, 1.0); } - (GLint)formatForDepth:(unsigned int)depth @@ -267,6 +297,9 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt "in vec2 srcCoordinates;\n" "in float lateral;\n" "\n" + "uniform vec2 boundsOrigin;\n" + "uniform vec2 boundsSize;\n" + "\n" "out float lateralVarying;\n" "out vec2 shadowMaskCoordinates;\n" "\n" @@ -283,9 +316,12 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt "\n" "%@\n" "\n" - "gl_Position = vec4(position.x * 2.0 - 1.0, 1.0 - position.y * 2.0 + position.x / 131.0, 0.0, 1.0);\n" + "vec2 mappedPosition = (position - boundsOrigin) / boundsSize;" + "gl_Position = vec4(mappedPosition.x * 2.0 - 1.0, 1.0 - mappedPosition.y * 2.0, 0.0, 1.0);\n" "}\n"; +// + mappedPosition.x / 131.0 + switch(_signalType) { case CSCathodeRayViewSignalTypeNTSC: return [NSString stringWithFormat:vertexShader, ntscVertexShaderGlobals, ntscVertexShaderBody]; @@ -295,7 +331,6 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt - (nonnull NSString *)fragmentShaderForType:(CSCathodeRayViewSignalType)type { - NSString *const fragmentShader = @"#version 150\n" "\n" @@ -396,10 +431,14 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt _alphaUniform = glGetUniformLocation(_shaderProgram, "alpha"); _textureSizeUniform = glGetUniformLocation(_shaderProgram, "textureSize"); _windowSizeUniform = glGetUniformLocation(_shaderProgram, "windowSize"); + _boundsSizeUniform = glGetUniformLocation(_shaderProgram, "boundsSize"); + _boundsOriginUniform = glGetUniformLocation(_shaderProgram, "boundsOrigin"); GLint texIDUniform = glGetUniformLocation(_shaderProgram, "texID"); GLint shadowMaskTexIDUniform = glGetUniformLocation(_shaderProgram, "shadowMaskTexID"); + [self pushSizeUniforms]; + glUniform1i(texIDUniform, 0); glUniform1i(shadowMaskTexIDUniform, 1); diff --git a/OSBindings/Mac/Clock Signal/Wrappers/CSElectron.h b/OSBindings/Mac/Clock Signal/Wrappers/CSElectron.h index d95b9dd32..1826efd24 100644 --- a/OSBindings/Mac/Clock Signal/Wrappers/CSElectron.h +++ b/OSBindings/Mac/Clock Signal/Wrappers/CSElectron.h @@ -10,4 +10,7 @@ @interface CSElectron : CSMachine +- (void)setOSROM:(nonnull NSData *)rom; +- (void)setBASICROM:(nonnull NSData *)rom; + @end diff --git a/OSBindings/Mac/Clock Signal/Wrappers/CSElectron.mm b/OSBindings/Mac/Clock Signal/Wrappers/CSElectron.mm index 9bd8f32fc..459e5eb00 100644 --- a/OSBindings/Mac/Clock Signal/Wrappers/CSElectron.mm +++ b/OSBindings/Mac/Clock Signal/Wrappers/CSElectron.mm @@ -19,4 +19,12 @@ _electron.run_for_cycles(numberOfCycles); } +- (void)setOSROM:(nonnull NSData *)rom { + _electron.set_rom(Electron::ROMTypeOS, rom.length, (const uint8_t *)rom.bytes); +} + +- (void)setBASICROM:(nonnull NSData *)rom { + _electron.set_rom(Electron::ROMTypeBASIC, rom.length, (const uint8_t *)rom.bytes); +} + @end