summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorerdgeist <erdgeist@erdgeist.org>2023-05-31 15:39:59 +0200
committererdgeist <erdgeist@erdgeist.org>2023-05-31 15:39:59 +0200
commit32773a08eb11d286682ca8cad41171ce804f1631 (patch)
treeaee35b1dadbf06d4c09e2004f96d3a4e11716f87
parent825d3442c320c5567317109947c8d1267704645b (diff)
Works
-rw-r--r--CCCB Display.xcodeproj/project.pbxproj14
-rw-r--r--CCCB Display.xcodeproj/xcuserdata/erdgeist.xcuserdatad/xcschemes/xcschememanagement.plist8
-rw-r--r--CCCB Display/AppDelegate.swift1
-rw-r--r--CCCB Display/Assets.xcassets/AppIcon.appiconset/Contents.json1
-rw-r--r--CCCB Display/Assets.xcassets/AppIcon.appiconset/IMG_4898.jpegbin0 -> 534617 bytes
-rw-r--r--CCCB Display/Assets.xcassets/IMG_4898.imageset/Contents.json21
-rw-r--r--CCCB Display/Assets.xcassets/IMG_4898.imageset/IMG_4898.jpegbin0 -> 534617 bytes
-rw-r--r--CCCB Display/Base.lproj/LaunchScreen.storyboard29
-rw-r--r--CCCB Display/Base.lproj/Main.storyboard129
-rw-r--r--CCCB Display/ConfigController.swift35
-rw-r--r--CCCB Display/ViewController.swift336
-rw-r--r--Makefile12
-rw-r--r--main.c70
13 files changed, 639 insertions, 17 deletions
diff --git a/CCCB Display.xcodeproj/project.pbxproj b/CCCB Display.xcodeproj/project.pbxproj
index e81c1d3..76c1843 100644
--- a/CCCB Display.xcodeproj/project.pbxproj
+++ b/CCCB Display.xcodeproj/project.pbxproj
@@ -13,6 +13,7 @@
13 65357C6D2A2013490096BC93 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 65357C6B2A2013490096BC93 /* Main.storyboard */; }; 13 65357C6D2A2013490096BC93 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 65357C6B2A2013490096BC93 /* Main.storyboard */; };
14 65357C6F2A20134C0096BC93 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 65357C6E2A20134C0096BC93 /* Assets.xcassets */; }; 14 65357C6F2A20134C0096BC93 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 65357C6E2A20134C0096BC93 /* Assets.xcassets */; };
15 65357C722A20134C0096BC93 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 65357C702A20134C0096BC93 /* LaunchScreen.storyboard */; }; 15 65357C722A20134C0096BC93 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 65357C702A20134C0096BC93 /* LaunchScreen.storyboard */; };
16 65357C7A2A2105100096BC93 /* ConfigController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65357C792A2105100096BC93 /* ConfigController.swift */; };
16/* End PBXBuildFile section */ 17/* End PBXBuildFile section */
17 18
18/* Begin PBXFileReference section */ 19/* Begin PBXFileReference section */
@@ -24,6 +25,7 @@
24 65357C6E2A20134C0096BC93 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; }; 25 65357C6E2A20134C0096BC93 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
25 65357C712A20134C0096BC93 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; }; 26 65357C712A20134C0096BC93 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
26 65357C732A20134C0096BC93 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 27 65357C732A20134C0096BC93 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
28 65357C792A2105100096BC93 /* ConfigController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigController.swift; sourceTree = "<group>"; };
27/* End PBXFileReference section */ 29/* End PBXFileReference section */
28 30
29/* Begin PBXFrameworksBuildPhase section */ 31/* Begin PBXFrameworksBuildPhase section */
@@ -57,6 +59,7 @@
57 isa = PBXGroup; 59 isa = PBXGroup;
58 children = ( 60 children = (
59 65357C652A2013490096BC93 /* AppDelegate.swift */, 61 65357C652A2013490096BC93 /* AppDelegate.swift */,
62 65357C792A2105100096BC93 /* ConfigController.swift */,
60 65357C672A2013490096BC93 /* SceneDelegate.swift */, 63 65357C672A2013490096BC93 /* SceneDelegate.swift */,
61 65357C692A2013490096BC93 /* ViewController.swift */, 64 65357C692A2013490096BC93 /* ViewController.swift */,
62 65357C6B2A2013490096BC93 /* Main.storyboard */, 65 65357C6B2A2013490096BC93 /* Main.storyboard */,
@@ -141,6 +144,7 @@
141 65357C6A2A2013490096BC93 /* ViewController.swift in Sources */, 144 65357C6A2A2013490096BC93 /* ViewController.swift in Sources */,
142 65357C662A2013490096BC93 /* AppDelegate.swift in Sources */, 145 65357C662A2013490096BC93 /* AppDelegate.swift in Sources */,
143 65357C682A2013490096BC93 /* SceneDelegate.swift in Sources */, 146 65357C682A2013490096BC93 /* SceneDelegate.swift in Sources */,
147 65357C7A2A2105100096BC93 /* ConfigController.swift in Sources */,
144 ); 148 );
145 runOnlyForDeploymentPostprocessing = 0; 149 runOnlyForDeploymentPostprocessing = 0;
146 }; 150 };
@@ -287,13 +291,14 @@
287 ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 291 ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
288 CODE_SIGN_STYLE = Automatic; 292 CODE_SIGN_STYLE = Automatic;
289 CURRENT_PROJECT_VERSION = 1; 293 CURRENT_PROJECT_VERSION = 1;
294 DEVELOPMENT_TEAM = 8DUP9J636N;
290 GENERATE_INFOPLIST_FILE = YES; 295 GENERATE_INFOPLIST_FILE = YES;
291 INFOPLIST_FILE = "CCCB Display/Info.plist"; 296 INFOPLIST_FILE = "CCCB Display/Info.plist";
297 INFOPLIST_KEY_NSCameraUsageDescription = "This app accesses the camera to display a monochrome representation on the CCCB Display";
292 INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 298 INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
293 INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; 299 INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
294 INFOPLIST_KEY_UIMainStoryboardFile = Main; 300 INFOPLIST_KEY_UIMainStoryboardFile = Main;
295 INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 301 INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
296 INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
297 LD_RUNPATH_SEARCH_PATHS = ( 302 LD_RUNPATH_SEARCH_PATHS = (
298 "$(inherited)", 303 "$(inherited)",
299 "@executable_path/Frameworks", 304 "@executable_path/Frameworks",
@@ -314,13 +319,14 @@
314 ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 319 ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
315 CODE_SIGN_STYLE = Automatic; 320 CODE_SIGN_STYLE = Automatic;
316 CURRENT_PROJECT_VERSION = 1; 321 CURRENT_PROJECT_VERSION = 1;
322 DEVELOPMENT_TEAM = 8DUP9J636N;
317 GENERATE_INFOPLIST_FILE = YES; 323 GENERATE_INFOPLIST_FILE = YES;
318 INFOPLIST_FILE = "CCCB Display/Info.plist"; 324 INFOPLIST_FILE = "CCCB Display/Info.plist";
325 INFOPLIST_KEY_NSCameraUsageDescription = "This app accesses the camera to display a monochrome representation on the CCCB Display";
319 INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 326 INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
320 INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; 327 INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
321 INFOPLIST_KEY_UIMainStoryboardFile = Main; 328 INFOPLIST_KEY_UIMainStoryboardFile = Main;
322 INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 329 INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
323 INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
324 LD_RUNPATH_SEARCH_PATHS = ( 330 LD_RUNPATH_SEARCH_PATHS = (
325 "$(inherited)", 331 "$(inherited)",
326 "@executable_path/Frameworks", 332 "@executable_path/Frameworks",
diff --git a/CCCB Display.xcodeproj/xcuserdata/erdgeist.xcuserdatad/xcschemes/xcschememanagement.plist b/CCCB Display.xcodeproj/xcuserdata/erdgeist.xcuserdatad/xcschemes/xcschememanagement.plist
index f15d7db..a661d77 100644
--- a/CCCB Display.xcodeproj/xcuserdata/erdgeist.xcuserdatad/xcschemes/xcschememanagement.plist
+++ b/CCCB Display.xcodeproj/xcuserdata/erdgeist.xcuserdatad/xcschemes/xcschememanagement.plist
@@ -10,5 +10,13 @@
10 <integer>0</integer> 10 <integer>0</integer>
11 </dict> 11 </dict>
12 </dict> 12 </dict>
13 <key>SuppressBuildableAutocreation</key>
14 <dict>
15 <key>65357C612A2013490096BC93</key>
16 <dict>
17 <key>primary</key>
18 <true/>
19 </dict>
20 </dict>
13</dict> 21</dict>
14</plist> 22</plist>
diff --git a/CCCB Display/AppDelegate.swift b/CCCB Display/AppDelegate.swift
index 8639c64..a3e61dc 100644
--- a/CCCB Display/AppDelegate.swift
+++ b/CCCB Display/AppDelegate.swift
@@ -14,6 +14,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
14 14
15 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 15 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
16 // Override point for customization after application launch. 16 // Override point for customization after application launch.
17 UIApplication.shared.isIdleTimerDisabled = true
17 return true 18 return true
18 } 19 }
19 20
diff --git a/CCCB Display/Assets.xcassets/AppIcon.appiconset/Contents.json b/CCCB Display/Assets.xcassets/AppIcon.appiconset/Contents.json
index 13613e3..bfe77c1 100644
--- a/CCCB Display/Assets.xcassets/AppIcon.appiconset/Contents.json
+++ b/CCCB Display/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -1,6 +1,7 @@
1{ 1{
2 "images" : [ 2 "images" : [
3 { 3 {
4 "filename" : "IMG_4898.jpeg",
4 "idiom" : "universal", 5 "idiom" : "universal",
5 "platform" : "ios", 6 "platform" : "ios",
6 "size" : "1024x1024" 7 "size" : "1024x1024"
diff --git a/CCCB Display/Assets.xcassets/AppIcon.appiconset/IMG_4898.jpeg b/CCCB Display/Assets.xcassets/AppIcon.appiconset/IMG_4898.jpeg
new file mode 100644
index 0000000..b9f2603
--- /dev/null
+++ b/CCCB Display/Assets.xcassets/AppIcon.appiconset/IMG_4898.jpeg
Binary files differ
diff --git a/CCCB Display/Assets.xcassets/IMG_4898.imageset/Contents.json b/CCCB Display/Assets.xcassets/IMG_4898.imageset/Contents.json
new file mode 100644
index 0000000..ce6efb2
--- /dev/null
+++ b/CCCB Display/Assets.xcassets/IMG_4898.imageset/Contents.json
@@ -0,0 +1,21 @@
1{
2 "images" : [
3 {
4 "filename" : "IMG_4898.jpeg",
5 "idiom" : "universal",
6 "scale" : "1x"
7 },
8 {
9 "idiom" : "universal",
10 "scale" : "2x"
11 },
12 {
13 "idiom" : "universal",
14 "scale" : "3x"
15 }
16 ],
17 "info" : {
18 "author" : "xcode",
19 "version" : 1
20 }
21}
diff --git a/CCCB Display/Assets.xcassets/IMG_4898.imageset/IMG_4898.jpeg b/CCCB Display/Assets.xcassets/IMG_4898.imageset/IMG_4898.jpeg
new file mode 100644
index 0000000..b9f2603
--- /dev/null
+++ b/CCCB Display/Assets.xcassets/IMG_4898.imageset/IMG_4898.jpeg
Binary files differ
diff --git a/CCCB Display/Base.lproj/LaunchScreen.storyboard b/CCCB Display/Base.lproj/LaunchScreen.storyboard
index 865e932..37c47c1 100644
--- a/CCCB Display/Base.lproj/LaunchScreen.storyboard
+++ b/CCCB Display/Base.lproj/LaunchScreen.storyboard
@@ -1,8 +1,10 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?> 1<?xml version="1.0" encoding="UTF-8"?>
2<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM"> 2<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="21701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
3 <device id="retina6_12" orientation="landscape" appearance="light"/>
3 <dependencies> 4 <dependencies>
4 <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/> 5 <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21678"/>
5 <capability name="Safe area layout guides" minToolsVersion="9.0"/> 6 <capability name="Safe area layout guides" minToolsVersion="9.0"/>
7 <capability name="System colors in document resources" minToolsVersion="11.0"/>
6 <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> 8 <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
7 </dependencies> 9 </dependencies>
8 <scenes> 10 <scenes>
@@ -11,10 +13,21 @@
11 <objects> 13 <objects>
12 <viewController id="01J-lp-oVM" sceneMemberID="viewController"> 14 <viewController id="01J-lp-oVM" sceneMemberID="viewController">
13 <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3"> 15 <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
14 <rect key="frame" x="0.0" y="0.0" width="375" height="667"/> 16 <rect key="frame" x="0.0" y="0.0" width="852" height="393"/>
15 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> 17 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
16 <color key="backgroundColor" xcode11CocoaTouchSystemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/> 18 <subviews>
19 <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="IMG_4898" translatesAutoresizingMaskIntoConstraints="NO" id="pnd-eL-XdQ">
20 <rect key="frame" x="59" y="0.0" width="734" height="372"/>
21 </imageView>
22 </subviews>
17 <viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/> 23 <viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
24 <color key="backgroundColor" systemColor="systemBackgroundColor"/>
25 <constraints>
26 <constraint firstItem="pnd-eL-XdQ" firstAttribute="top" secondItem="6Tk-OE-BBY" secondAttribute="top" id="Nv3-O9-veR"/>
27 <constraint firstItem="6Tk-OE-BBY" firstAttribute="bottom" secondItem="pnd-eL-XdQ" secondAttribute="bottom" id="fB9-uM-dp6"/>
28 <constraint firstItem="6Tk-OE-BBY" firstAttribute="trailing" secondItem="pnd-eL-XdQ" secondAttribute="trailing" id="i5C-Km-vv3"/>
29 <constraint firstItem="pnd-eL-XdQ" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" id="wKN-64-4YA"/>
30 </constraints>
18 </view> 31 </view>
19 </viewController> 32 </viewController>
20 <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/> 33 <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
@@ -22,4 +35,10 @@
22 <point key="canvasLocation" x="53" y="375"/> 35 <point key="canvasLocation" x="53" y="375"/>
23 </scene> 36 </scene>
24 </scenes> 37 </scenes>
38 <resources>
39 <image name="IMG_4898" width="1024" height="1024"/>
40 <systemColor name="systemBackgroundColor">
41 <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
42 </systemColor>
43 </resources>
25</document> 44</document>
diff --git a/CCCB Display/Base.lproj/Main.storyboard b/CCCB Display/Base.lproj/Main.storyboard
index 25a7638..247b634 100644
--- a/CCCB Display/Base.lproj/Main.storyboard
+++ b/CCCB Display/Base.lproj/Main.storyboard
@@ -1,24 +1,143 @@
1<?xml version="1.0" encoding="UTF-8"?> 1<?xml version="1.0" encoding="UTF-8"?>
2<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r"> 2<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="21701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
3 <device id="retina6_12" orientation="landscape" appearance="light"/>
3 <dependencies> 4 <dependencies>
4 <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/> 5 <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21678"/>
5 <capability name="Safe area layout guides" minToolsVersion="9.0"/> 6 <capability name="Safe area layout guides" minToolsVersion="9.0"/>
7 <capability name="System colors in document resources" minToolsVersion="11.0"/>
6 <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> 8 <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
7 </dependencies> 9 </dependencies>
8 <scenes> 10 <scenes>
9 <!--View Controller--> 11 <!--View Controller-->
10 <scene sceneID="tne-QT-ifu"> 12 <scene sceneID="tne-QT-ifu">
11 <objects> 13 <objects>
12 <viewController id="BYZ-38-t0r" customClass="ViewController" customModuleProvider="target" sceneMemberID="viewController"> 14 <viewController id="BYZ-38-t0r" customClass="ViewController" customModule="CCCB_Display" customModuleProvider="target" sceneMemberID="viewController">
13 <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC"> 15 <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
14 <rect key="frame" x="0.0" y="0.0" width="375" height="667"/> 16 <rect key="frame" x="0.0" y="0.0" width="852" height="393"/>
15 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> 17 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
16 <color key="backgroundColor" xcode11CocoaTouchSystemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/> 18 <subviews>
19 <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Zg1-dS-4VN">
20 <rect key="frame" x="0.0" y="0.0" width="852" height="393"/>
21 <color key="backgroundColor" systemColor="systemBackgroundColor"/>
22 </view>
23 <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="LB5-99-rhM">
24 <rect key="frame" x="689" y="8" width="72" height="35"/>
25 <state key="normal" title="Button"/>
26 <buttonConfiguration key="configuration" style="filled" title="config"/>
27 <connections>
28 <segue destination="Srg-Ai-hZD" kind="popoverPresentation" popoverAnchorView="LB5-99-rhM" id="qNt-fx-jP2">
29 <popoverArrowDirection key="popoverArrowDirection" up="YES" down="YES" left="YES" right="YES"/>
30 </segue>
31 </connections>
32 </button>
33 <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="right" contentVerticalAlignment="bottom" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="4IW-d6-qWW">
34 <rect key="frame" x="630" y="8" width="51" height="35"/>
35 <state key="normal" title="Button"/>
36 <buttonConfiguration key="configuration" style="filled" title="Flip"/>
37 <connections>
38 <action selector="switchCameraSideWithSender:" destination="BYZ-38-t0r" eventType="touchUpInside" id="15B-T0-yhg"/>
39 </connections>
40 </button>
41 <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="FPx-ZU-vSE">
42 <rect key="frame" x="59" y="8" width="80" height="22"/>
43 <color key="backgroundColor" systemColor="systemGreenColor"/>
44 <fontDescription key="fontDescription" type="system" pointSize="17"/>
45 <nil key="textColor"/>
46 <nil key="highlightedColor"/>
47 </label>
48 </subviews>
17 <viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/> 49 <viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
50 <color key="backgroundColor" systemColor="systemBackgroundColor"/>
51 <constraints>
52 <constraint firstItem="LB5-99-rhM" firstAttribute="leading" secondItem="4IW-d6-qWW" secondAttribute="trailing" constant="8" id="0JW-YO-OfQ"/>
53 <constraint firstItem="FPx-ZU-vSE" firstAttribute="top" secondItem="6Tk-OE-BBY" secondAttribute="top" constant="8" id="2HN-cV-t4S"/>
54 <constraint firstItem="FPx-ZU-vSE" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" id="3qY-jD-MCQ"/>
55 <constraint firstItem="Zg1-dS-4VN" firstAttribute="bottom" secondItem="8bC-Xf-vdC" secondAttribute="bottom" id="8Uw-BH-OnX"/>
56 <constraint firstItem="Zg1-dS-4VN" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leading" id="AJu-22-uph"/>
57 <constraint firstItem="Zg1-dS-4VN" firstAttribute="top" secondItem="8bC-Xf-vdC" secondAttribute="top" id="EDS-vg-saF"/>
58 <constraint firstItem="6Tk-OE-BBY" firstAttribute="trailing" secondItem="LB5-99-rhM" secondAttribute="trailing" constant="32" id="FMt-88-9e3"/>
59 <constraint firstItem="4IW-d6-qWW" firstAttribute="top" secondItem="6Tk-OE-BBY" secondAttribute="top" constant="8" id="G8m-hM-E2u"/>
60 <constraint firstItem="LB5-99-rhM" firstAttribute="top" secondItem="6Tk-OE-BBY" secondAttribute="top" constant="8" id="OP9-7G-8by"/>
61 <constraint firstAttribute="trailing" secondItem="Zg1-dS-4VN" secondAttribute="trailing" id="esB-po-Jgq"/>
62 <constraint firstItem="Zg1-dS-4VN" firstAttribute="centerX" secondItem="8bC-Xf-vdC" secondAttribute="centerX" id="wPB-mw-ptE"/>
63 </constraints>
18 </view> 64 </view>
65 <connections>
66 <outlet property="cameraView" destination="Zg1-dS-4VN" id="27A-lq-3JJ"/>
67 <outlet property="frameRateLabel" destination="FPx-ZU-vSE" id="twM-qM-WQM"/>
68 </connections>
19 </viewController> 69 </viewController>
20 <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/> 70 <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
21 </objects> 71 </objects>
72 <point key="canvasLocation" x="111.9718309859155" y="-2.2900763358778624"/>
73 </scene>
74 <!--Config Controller-->
75 <scene sceneID="Ozy-FI-kCz">
76 <objects>
77 <viewController modalPresentationStyle="pageSheet" id="Srg-Ai-hZD" customClass="ConfigController" customModule="CCCB_Display" customModuleProvider="target" sceneMemberID="viewController">
78 <view key="view" contentMode="scaleToFill" id="RKC-6a-725">
79 <rect key="frame" x="0.0" y="0.0" width="852" height="393"/>
80 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
81 <subviews>
82 <textField opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="248" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="IP Address" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="XB9-tI-41p">
83 <rect key="frame" x="210.99999999999997" y="68" width="401.33333333333326" height="35"/>
84 <fontDescription key="fontDescription" type="system" pointSize="14"/>
85 <textInputTraits key="textInputTraits"/>
86 </textField>
87 <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Display Address" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="eRN-cy-tvC">
88 <rect key="frame" x="80" y="75" width="123" height="21"/>
89 <fontDescription key="fontDescription" type="system" pointSize="17"/>
90 <nil key="textColor"/>
91 <nil key="highlightedColor"/>
92 </label>
93 <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="eoj-db-q0p">
94 <rect key="frame" x="705" y="68" width="65" height="35"/>
95 <state key="normal" title="Button"/>
96 <buttonConfiguration key="configuration" style="filled" title="Done"/>
97 <connections>
98 <action selector="donePressed:" destination="Srg-Ai-hZD" eventType="touchUpInside" id="RFf-QJ-Omk"/>
99 </connections>
100 </button>
101 <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="dKt-Le-k5D">
102 <rect key="frame" x="620.33333333333337" y="68" width="76.666666666666629" height="35"/>
103 <state key="normal" title="Button"/>
104 <buttonConfiguration key="configuration" style="filled" title="Cancel"/>
105 <connections>
106 <action selector="cancelPressed:" destination="Srg-Ai-hZD" eventType="touchUpInside" id="8qq-Jm-VhP"/>
107 </connections>
108 </button>
109 </subviews>
110 <viewLayoutGuide key="safeArea" id="D96-4o-bMR"/>
111 <color key="backgroundColor" systemColor="systemBackgroundColor"/>
112 <constraints>
113 <constraint firstItem="XB9-tI-41p" firstAttribute="top" secondItem="eoj-db-q0p" secondAttribute="top" id="1Aw-0G-Omh"/>
114 <constraint firstItem="XB9-tI-41p" firstAttribute="leading" secondItem="eRN-cy-tvC" secondAttribute="trailing" constant="8" id="3FR-zi-YS0"/>
115 <constraint firstItem="dKt-Le-k5D" firstAttribute="top" secondItem="eoj-db-q0p" secondAttribute="top" id="6db-VB-pbU"/>
116 <constraint firstItem="XB9-tI-41p" firstAttribute="centerY" secondItem="eRN-cy-tvC" secondAttribute="centerY" id="Ob5-Ea-9SL"/>
117 <constraint firstItem="XB9-tI-41p" firstAttribute="centerY" secondItem="eoj-db-q0p" secondAttribute="centerY" id="R2J-lD-arp"/>
118 <constraint firstItem="dKt-Le-k5D" firstAttribute="leading" secondItem="XB9-tI-41p" secondAttribute="trailing" constant="8" id="TNp-0v-8LR"/>
119 <constraint firstItem="eRN-cy-tvC" firstAttribute="leading" secondItem="D96-4o-bMR" secondAttribute="leading" constant="80" id="aD8-8R-LiO"/>
120 <constraint firstItem="eoj-db-q0p" firstAttribute="leading" secondItem="dKt-Le-k5D" secondAttribute="trailing" constant="8" id="dSO-oI-Wci"/>
121 <constraint firstItem="D96-4o-bMR" firstAttribute="trailing" secondItem="eoj-db-q0p" secondAttribute="trailing" constant="82" id="riC-ZY-AgB"/>
122 <constraint firstItem="XB9-tI-41p" firstAttribute="top" secondItem="D96-4o-bMR" secondAttribute="top" constant="68" id="sUl-XQ-UGi"/>
123 </constraints>
124 </view>
125 <extendedEdge key="edgesForExtendedLayout" bottom="YES"/>
126 <connections>
127 <outlet property="display_address" destination="XB9-tI-41p" id="EZU-kl-5r7"/>
128 </connections>
129 </viewController>
130 <placeholder placeholderIdentifier="IBFirstResponder" id="XVb-PU-k6x" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
131 </objects>
132 <point key="canvasLocation" x="904" y="-2"/>
22 </scene> 133 </scene>
23 </scenes> 134 </scenes>
135 <resources>
136 <systemColor name="systemBackgroundColor">
137 <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
138 </systemColor>
139 <systemColor name="systemGreenColor">
140 <color red="0.20392156862745098" green="0.7803921568627451" blue="0.34901960784313724" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
141 </systemColor>
142 </resources>
24</document> 143</document>
diff --git a/CCCB Display/ConfigController.swift b/CCCB Display/ConfigController.swift
new file mode 100644
index 0000000..92b6e37
--- /dev/null
+++ b/CCCB Display/ConfigController.swift
@@ -0,0 +1,35 @@
1//
2// ConfigController.swift
3// CCCB Display
4//
5// Created by Dirk Engling on 26.05.23.
6//
7
8import Foundation
9import UIKit
10
11
12class ConfigController: UIViewController {
13
14 @IBOutlet weak var display_address: UITextField!
15
16 override func viewWillAppear(_ animated: Bool) {
17 super.viewWillAppear(animated)
18 let defaults = UserDefaults.standard
19 if let ip = defaults.string(forKey: "Display_Address") {
20 display_address.text = ip
21 } else {
22 display_address.text = "172.23.42.29"
23 }
24 }
25
26 @IBAction func cancelPressed(_ sender: Any) {
27 self.dismiss(animated: true)
28 }
29
30 @IBAction func donePressed(_ sender: Any) {
31 self.dismiss(animated: true)
32 let defaults = UserDefaults.standard
33 defaults.set(display_address.text, forKey: "Display_Address")
34 }
35}
diff --git a/CCCB Display/ViewController.swift b/CCCB Display/ViewController.swift
index 53f3cee..d0f8dbe 100644
--- a/CCCB Display/ViewController.swift
+++ b/CCCB Display/ViewController.swift
@@ -6,14 +6,344 @@
6// 6//
7 7
8import UIKit 8import UIKit
9import AVFoundation
10import CoreImage
11import Network
9 12
10class ViewController: UIViewController { 13class ViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate, ObservableObject, AVCaptureVideoDataOutputSampleBufferDelegate {
14
15 @IBOutlet weak var frameRateLabel: UILabel!
16 @IBOutlet weak var cameraView: UIView!
17
18 var device: AVCaptureDevice?
19 var input: AVCaptureDeviceInput?
20 var prevLayer: AVCaptureVideoPreviewLayer?
21
22 private let captureSession = AVCaptureSession()
23 private let videoDataOutput = AVCaptureVideoDataOutput()
24 private let sessionQueue = DispatchQueue(label: "sessionQueue")
25 private let context = CIContext()
26
27// var hostUDP: NWEndpoint.Host = "172.23.42.29"
28 var hostUDP: NWEndpoint.Host?
29 var portUDP: NWEndpoint.Port = 2342
30 var connectionUDP: NWConnection?
31
32 var lastTimeStamp: CFTimeInterval = CACurrentMediaTime()
33
34 /* Physical Display control packet parameters: */
35 private let HEADERLEN = 10
36 private let WIDTH = 448
37 private let HEIGHT = 160
38 private let VHEIGHT = 236
11 39
12 override func viewDidLoad() { 40 override func viewDidLoad() {
13 super.viewDidLoad() 41 super.viewDidLoad()
14 // Do any additional setup after loading the view. 42
43 UserDefaults.standard.addObserver(self, forKeyPath: "Display_Address", options: .new, context: nil)
44 constructSocket()
45
46 switch AVCaptureDevice.authorizationStatus(for: .video) {
47 case .authorized: // the user has already authorized to access the camera.
48 DispatchQueue.main.async {
49 self.createSession()
50 }
51 case .notDetermined:
52 AVCaptureDevice.requestAccess (for: .video) { (granted) in
53 if granted {
54 print("the user has granted to access the camera")
55 DispatchQueue.main.async {
56 self.createSession ()
57 }
58 } else {
59 print("the user has not granted to access the camera")
60 let dialogMessage = UIAlertController(title: "Attention", message: "Can not work without camera access", preferredStyle: .alert)
61 self.present(dialogMessage, animated: true, completion: nil)
62 }
63 }
64 case .denied:
65 print("the user has denied previously to access the camera.")
66 let dialogMessage = UIAlertController(title: "Attention", message: "Can not work without camera access", preferredStyle: .alert)
67 self.present(dialogMessage, animated: true, completion: nil)
68
69 case .restricted:
70 print("the user can't give camera access due to some restriction.")
71 let dialogMessage = UIAlertController(title: "Attention", message: "Can not work without camera access", preferredStyle: .alert)
72 self.present(dialogMessage, animated: true, completion: nil)
73
74 default:
75 print("something has wrong due to we can't access the camera.")
76 let dialogMessage = UIAlertController(title: "Attention", message: "Can not work without camera access", preferredStyle: .alert)
77 self.present(dialogMessage, animated: true, completion: nil)
78 }
79 }
80
81 override func viewDidAppear(_ animated: Bool) {
82 super.viewDidAppear(animated)
83 prevLayer?.frame.size = cameraView.frame.size
15 } 84 }
16 85
86 func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
17 87
18} 88 let now = CACurrentMediaTime()
89 let freq = (Int)(1 / (now - lastTimeStamp))
90// print ("Elapsed: \(now - lastTimeStamp) - Frequency: \(1 / (now - lastTimeStamp))")
91 lastTimeStamp = now
92
93 guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { return }
94
95 CVPixelBufferLockBaseAddress(pixelBuffer, .readOnly)
96 let bufferWidth = CVPixelBufferGetWidth(pixelBuffer)
97 let bufferHeight = CVPixelBufferGetHeight(pixelBuffer)
98 let bytesPerRow = CVPixelBufferGetBytesPerRow(pixelBuffer)
99 let kBytesPerPixel = 4
100
101 print("\(bufferWidth) \(bufferHeight) \(bytesPerRow)")
102 guard let baseAddress = CVPixelBufferGetBaseAddress(pixelBuffer) else { return }
103
104 var packet: [UInt8] = [0, 0x12, 0, 0, 0x23, 0, 0, 0, 0, 0]
105 var scratch: [Int] = Array(repeating: 0, count: WIDTH*(2+VHEIGHT))
106
107 let t1 = CACurrentMediaTime()
108
109 // 160 real rows are interleaved with 19 gaps of 4 pixels height on the display
110 // so we create 20 virtual blocks of 8 real and 4 virtual pixels
111 // we overlay VHEIGHT==236 virtual rows on the image and later skip the 4 invisble rows
112 var off = 0
113 for row in 0..<VHEIGHT {
114 let zeile = (Int)(((Double)(row) / (Double)(VHEIGHT)) * (Double)(bufferHeight)) * bytesPerRow
115 for column in 0..<WIDTH {
116 let pixel = kBytesPerPixel * (Int)(((Double)(column) / (Double)(WIDTH)) * (Double)(bufferWidth))
117
118 let red = (Int)(baseAddress.load(fromByteOffset: zeile + pixel + 0, as: UInt8.self)) * 19535
119 let green = (Int)(baseAddress.load(fromByteOffset: zeile + pixel + 1, as: UInt8.self)) * 38470
120 let blue = (Int)(baseAddress.load(fromByteOffset: zeile + pixel + 2, as: UInt8.self)) * 7448
121 //scratch[row * WIDTH + column] = red + blue + green
122 scratch[off] = red + blue + green
123 off += 1
124 }
125 }
126
127 var acc = 0
128 var accv = 0
129
130 for row in 0..<VHEIGHT {
131 for column in 0..<WIDTH {
132 let pixel = scratch[row * WIDTH + column]
133 let bwpixel = (pixel < 0x810000) ? 0 : 0xffffff
134
135 // account for gaps on display (virtual lines 9-12)
136 if (row % 12) < 8 {
137 acc = (acc << 1) + (bwpixel >> 23)
138 accv += 1
139 if accv == 8 {
140 packet.append((UInt8)(acc))
141 acc = 0
142 accv = 0
143 }
144 }
145
146 let err = (pixel - bwpixel) / 42
147
148 func AddSatShift(_ scr: inout Array<Int>, _ X: Int, _ Y: Int, _ SHIFT: Int) {
149 let inner_p = (row + Y) * WIDTH + column + X
150 var r = scr[inner_p] + (err << (16 - SHIFT))
151 if r < 0 {
152 r = 0
153 }
154 if r > 0xffffff {
155 r = 0xffffff
156 }
157 scr[inner_p] = r
158 }
159
160 AddSatShift(&scratch, 0, 1, 13)
161 AddSatShift(&scratch, 0, 2, 14)
162 if (column > 0) {
163 AddSatShift(&scratch, -1, 1, 14)
164 AddSatShift(&scratch, -1, 2, 15)
165 }
166
167 if (column > 1) {
168 AddSatShift(&scratch, -2, 1, 15)
169 AddSatShift(&scratch, -2, 2, 16)
170 }
171
172 if (column < WIDTH - 1) {
173 AddSatShift(&scratch, 1, 0, 13)
174 AddSatShift(&scratch, 1, 1, 14)
175 AddSatShift(&scratch, 1, 2, 15)
176 }
177
178 if (column < WIDTH - 2) {
179 AddSatShift(&scratch, 2, 0, 14)
180 AddSatShift(&scratch, 2, 1, 15)
181 AddSatShift(&scratch, 2, 2, 16)
182 }
183
184 }
185 }
186
187 let t2 = CACurrentMediaTime()
188
189// print("dur \(t2 - t1)")
190 DispatchQueue.main.async {
191 self.frameRateLabel.text = String(format: "%.04f (%d Hz)", t2 - t1, freq)
192 }
193
194 self.connectionUDP?.send(content: packet, completion: NWConnection.SendCompletion.contentProcessed(({ (NWError) in
195 if (NWError == nil) {
196 print("Data was sent to UDP")
197 } else {
198 print("ERROR! Error when data (Type: Data) sending. NWError: \n \(NWError!)")
199 self.constructSocket()
200 }
201 })))
202 }
19 203
204 func createSession() {
205 guard let device = AVCaptureDevice.default(for: AVMediaType.video) else { return }
206 do {
207 input = try AVCaptureDeviceInput(device: device)
208 }
209 catch {
210 print(error)
211 }
212
213 captureSession.sessionPreset = AVCaptureSession.Preset.vga640x480
214 if let input = input {
215 captureSession.addInput(input)
216 }
217
218 prevLayer = AVCaptureVideoPreviewLayer(session: captureSession)
219 prevLayer?.frame.size = cameraView.frame.size
220 prevLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill
221
222 cameraView.layer.addSublayer(prevLayer!)
223 captureSession.addOutput(videoDataOutput)
224 captureSession.commitConfiguration()
225
226 videoDataOutput.videoSettings.updateValue(kCVPixelFormatType_32BGRA, forKey: "PixelFormatType")
227 videoDataOutput.setSampleBufferDelegate(self, queue: self.sessionQueue)
228
229 do {
230 try device.lockForConfiguration()
231 device.activeVideoMaxFrameDuration = CMTimeMake(value: 1, timescale: 60)
232 device.activeVideoMinFrameDuration = CMTimeMake(value: 1, timescale: 60)
233 device.unlockForConfiguration()
234 } catch {
235 print(error)
236 }
237
238 let captureConnection = videoDataOutput.connection(with: .video)
239 captureConnection?.isEnabled = true
240 deviceOrientationDidChange(Notification(name: UIDevice.orientationDidChangeNotification))
241 // captureConnection?.videoOrientation = .landscapeRight
242
243 sessionQueue.async { self.captureSession.startRunning() }
244 }
245
246 func cameraWithPosition(position: AVCaptureDevice.Position) -> AVCaptureDevice? {
247 if #available(iOS 11.1, *) {
248 let deviceDiscoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInDualCamera, .builtInTelephotoCamera, .builtInTrueDepthCamera, .builtInWideAngleCamera, ], mediaType: .video, position: position)
249
250 if let device = deviceDiscoverySession.devices.first {
251 return device
252 }
253 else {
254 //add code here
255 }
256 return nil
257 }
258
259 return device
260 }
261
262 func transformOrientation(orientation: UIInterfaceOrientation) -> AVCaptureVideoOrientation {
263 switch orientation {
264 case .landscapeLeft:
265 return .landscapeLeft
266 case .landscapeRight:
267 return .landscapeRight
268 case .portraitUpsideDown:
269 return .portraitUpsideDown
270 default:
271 return .portrait
272 }
273 }
274
275 override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
276 if keyPath == "Display_Address" {
277 constructSocket()
278 }
279 }
280
281 func constructSocket() {
282 let defaults = UserDefaults.standard
283 if let ip = defaults.string(forKey: "Display_Address") {
284 hostUDP = NWEndpoint.Host(ip)
285 } else {
286 hostUDP = NWEndpoint.Host("172.23.42.29")
287 // hostUDP = NWEndpoint.Host("84.200.61.9")
288 // hostUDP = NWEndpoint.Host("192.168.178.69")
289 }
290// hostUDP = NWEndpoint.Host("192.168.178.69")
291
292 self.connectionUDP = NWConnection(host: hostUDP!, port: portUDP, using: .udp)
293 self.connectionUDP?.start(queue: .global())
294 }
295
296 @IBAction func switchCameraSide(sender: AnyObject) {
297 let currentCameraInput: AVCaptureInput = captureSession.inputs[0]
298 captureSession.removeInput(currentCameraInput)
299 var newCamera: AVCaptureDevice
300 if (currentCameraInput as! AVCaptureDeviceInput).device.position == .back {
301 newCamera = self.cameraWithPosition(position: .front)!
302 } else {
303 newCamera = self.cameraWithPosition(position: .back)!
304 }
305
306 var newVideoInput: AVCaptureDeviceInput?
307 do{
308 newVideoInput = try AVCaptureDeviceInput(device: newCamera)
309 }
310 catch{
311 print(error)
312 }
313
314 if let newVideoInput = newVideoInput{
315 captureSession.addInput(newVideoInput)
316 deviceOrientationDidChange(Notification(name: UIDevice.orientationDidChangeNotification))
317 }
318 }
319
320 override func viewWillAppear(_ animated: Bool) {
321 super.viewWillAppear(animated)
322
323 NotificationCenter.default.addObserver(self, selector: #selector(deviceOrientationDidChange),
324 name: UIDevice.orientationDidChangeNotification, object: nil)
325 deviceOrientationDidChange(Notification(name: UIDevice.orientationDidChangeNotification))
326
327 sessionQueue.async { self.captureSession.startRunning() }
328 }
329
330 override func viewWillDisappear(_ animated: Bool) {
331 super.viewWillDisappear(animated)
332
333 sessionQueue.async { self.captureSession.stopRunning() }
334 NotificationCenter.default.removeObserver(self)
335 }
336
337 @objc func deviceOrientationDidChange(_ notification: Notification) {
338 let orientation = UIDevice.current.orientation
339 let captureConnection = videoDataOutput.connection(with: .video)
340
341 if orientation == .landscapeLeft {
342 self.prevLayer?.connection?.videoOrientation = .landscapeRight
343 captureConnection?.videoOrientation = .landscapeRight
344 } else {
345 self.prevLayer?.connection?.videoOrientation = .landscapeLeft
346 captureConnection?.videoOrientation = .landscapeLeft
347 }
348 }
349}
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..6ec9f52
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,12 @@
1all: main
2
3SDL_LIBRARIES=/usr/local/lib/libSDL2.a /usr/local/lib/libSDL2main.a /usr/local/lib/libSDL2_gfx.a
4SDL_DEPEND_FRAMEWORKS=-framework Carbon -framework Cocoa -framework CoreAudio -framework AudioToolbox -framework CoreVideo -framework ForceFeedback -framework IOKit -framework CoreHaptics -framework GameController -framework Metal
5SDL_DEPEND_LIBRARIES=/usr/local/lib/libpng.a /usr/local/lib/libfreetype.a -lbz2 -liconv -lz
6
7main: main.c
8 cc -g -O3 -o CCCBDisplay main.c -I /usr/local/include -lm $(SDL_LIBRARIES) $(SDL_DEPEND_FRAMEWORKS) $(SDL_DEPEND_LIBRARIES)
9
10.PHONY: clean
11clean:
12 rm -f CCCBDisplay
diff --git a/main.c b/main.c
new file mode 100644
index 0000000..82b3c07
--- /dev/null
+++ b/main.c
@@ -0,0 +1,70 @@
1#include <sys/socket.h>
2#include <arpa/inet.h>
3#include <stdlib.h>
4#include <stdint.h>
5#include <stdio.h>
6
7#include "SDL2/SDL.h"
8#include "SDL2/SDL2_gfxPrimitives.h"
9
10int main() {
11 int sock_in = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
12 struct sockaddr_in server_addr;
13
14 SDL_Window *screen;
15 SDL_Renderer *renderer;
16 int screen_width = 448;
17 //int screen_height = 236;
18 int screen_height = 160;
19 uint8_t inbuf[screen_width * screen_height / 8 + 10];
20
21 if (SDL_Init(SDL_INIT_EVERYTHING) == -1) {
22 fprintf(stderr, "Can't initialize SDL.\n");
23 exit(1);
24 }
25 screen = SDL_CreateWindow("Laserharfe", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, screen_width, screen_height, SDL_WINDOW_OPENGL);
26 if (!screen) {
27 fprintf(stderr, "Can't set video mode.\n");
28 exit(1);
29 }
30 renderer = SDL_CreateRenderer(screen, -1, 0);
31
32 SDL_RenderClear(renderer);
33
34 memset(&server_addr, 0, sizeof(server_addr));
35 server_addr.sin_family = AF_INET;
36 server_addr.sin_port = htons(2342);
37 server_addr.sin_addr.s_addr = inet_addr("192.168.178.69");
38
39 if (bind(sock_in, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0){
40 fprintf(stderr, "Couldn't bind to the port\n");
41 exit(1);
42 }
43
44 struct timeval tv;
45 memset(&tv, 0, sizeof(tv));
46 tv.tv_usec = 30000;
47 setsockopt(sock_in, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
48
49 while (1) {
50 SDL_Event ev;
51 SDL_PollEvent(&ev);
52 if (ev.type == SDL_QUIT) exit(0);
53
54 size_t received = recvfrom(sock_in, inbuf, sizeof(inbuf), 0, NULL, 0);
55 if (received == -1)
56 continue;
57
58 printf("Packet received, size: %zd\n", received);
59 SDL_RenderClear(renderer);
60
61 for (int row = 0; row < screen_height; ++row) {
62 for (int col = 0; col < screen_width; ++col) {
63 uint8_t pixel = inbuf[10 + (row * screen_width + col) / 8];
64 int on = pixel << (col & 7);
65 filledCircleColor(renderer, col, row, 1, (on & 0x80) ? 0xffffffff : 0);
66 }
67 }
68 SDL_RenderPresent(renderer);
69 }
70}