Browse Source

Initial Apple TV / tvOS support.

The Apple TV remote is currently exposed as a joystick with its touch surface treated as two axes. Key presses are also generated when its buttons and touch surface are used.

A new hint has been added to help deal with deciding whether to background the app when the remote's menu button is pressed: SDL_HINT_APPLE_TV_CONTROLLER_UI_EVENTS.
Alex Szpakowski 8 years ago
parent
commit
f050576665

+ 199 - 0
Xcode-iOS/Demos/Demos.xcodeproj/project.pbxproj

@@ -10,6 +10,20 @@
 		1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */; };
 		1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; };
 		1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; };
+		FA30DEB01BBF5A8F009C397F /* common.c in Sources */ = {isa = PBXBuildFile; fileRef = FD77A0060E26BC0500F39101 /* common.c */; };
+		FA30DEB11BBF5A93009C397F /* happy.c in Sources */ = {isa = PBXBuildFile; fileRef = FD77A0080E26BC0500F39101 /* happy.c */; };
+		FA30DEB31BBF5AD7009C397F /* icon.bmp in Resources */ = {isa = PBXBuildFile; fileRef = FDB651CC0E43D19800F688B5 /* icon.bmp */; };
+		FA30DEB41BBF5ADD009C397F /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = FD925B180E0F276600E92347 /* Icon.png */; };
+		FA30DEB61BBF5AE6009C397F /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = FD787AA00E22A5CC003E8E36 /* Default.png */; };
+		FA30DEB71BBF5BB8009C397F /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FA30DEAC1BBF59D9009C397F /* libSDL2.a */; };
+		FA30DEC81BBF5C14009C397F /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FAE0E9691BAF96A00098DFA4 /* GameController.framework */; };
+		FA30DEC91BBF5C14009C397F /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDF0D7220E12D31800247964 /* AudioToolbox.framework */; };
+		FA30DECA1BBF5C14009C397F /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDB96EDF0DEFC9DC00FAF19F /* QuartzCore.framework */; };
+		FA30DECB1BBF5C14009C397F /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDB96ED30DEFC9C700FAF19F /* OpenGLES.framework */; };
+		FA30DECC1BBF5C14009C397F /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */; };
+		FA30DECD1BBF5C14009C397F /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; };
+		FA30DECE1BBF5C14009C397F /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; };
+		FA30DECF1BBF5C14009C397F /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDF0D71D0E12D2AB00247964 /* CoreAudio.framework */; };
 		FA8B4BA31967070A00F8EB7C /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA8B4BA21967070A00F8EB7C /* CoreMotion.framework */; };
 		FA8B4BA41967071300F8EB7C /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA8B4BA21967070A00F8EB7C /* CoreMotion.framework */; };
 		FA8B4BA51967071A00F8EB7C /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA8B4BA21967070A00F8EB7C /* CoreMotion.framework */; };
@@ -168,6 +182,20 @@
 			remoteGlobalIDString = FD6526620DE8FCCB002AD96B;
 			remoteInfo = libSDL;
 		};
+		FA30DEAB1BBF59D9009C397F /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = FD1B48920E313154007AB34E /* SDL.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = FAB598141BB5C1B100BE72C5;
+			remoteInfo = "libSDL-tv";
+		};
+		FA30DEAE1BBF5A69009C397F /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = FD1B48920E313154007AB34E /* SDL.xcodeproj */;
+			proxyType = 1;
+			remoteGlobalIDString = FAB598131BB5C1B100BE72C5;
+			remoteInfo = "libSDL-tv";
+		};
 		FD1B489D0E313154007AB34E /* PBXContainerItemProxy */ = {
 			isa = PBXContainerItemProxy;
 			containerPortal = FD1B48920E313154007AB34E /* SDL.xcodeproj */;
@@ -183,6 +211,7 @@
 		1D6058910D05DD3D006BFB54 /* Rectangles.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Rectangles.app; sourceTree = BUILT_PRODUCTS_DIR; };
 		1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
 		8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+		FA30DE961BBF59D9009C397F /* Happy-TV.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Happy-TV.app"; sourceTree = BUILT_PRODUCTS_DIR; };
 		FA8B4BA21967070A00F8EB7C /* CoreMotion.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMotion.framework; path = System/Library/Frameworks/CoreMotion.framework; sourceTree = SDKROOT; };
 		FAE0E9691BAF96A00098DFA4 /* GameController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameController.framework; path = System/Library/Frameworks/GameController.framework; sourceTree = SDKROOT; };
 		FD15FCB20E086866003BDF25 /* Happy.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Happy.app; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -237,6 +266,22 @@
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
+		FA30DE931BBF59D9009C397F /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				FA30DEB71BBF5BB8009C397F /* libSDL2.a in Frameworks */,
+				FA30DEC81BBF5C14009C397F /* GameController.framework in Frameworks */,
+				FA30DEC91BBF5C14009C397F /* AudioToolbox.framework in Frameworks */,
+				FA30DECA1BBF5C14009C397F /* QuartzCore.framework in Frameworks */,
+				FA30DECB1BBF5C14009C397F /* OpenGLES.framework in Frameworks */,
+				FA30DECC1BBF5C14009C397F /* CoreGraphics.framework in Frameworks */,
+				FA30DECD1BBF5C14009C397F /* UIKit.framework in Frameworks */,
+				FA30DECE1BBF5C14009C397F /* Foundation.framework in Frameworks */,
+				FA30DECF1BBF5C14009C397F /* CoreAudio.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
 		FD15FCB00E086866003BDF25 /* Frameworks */ = {
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
@@ -352,6 +397,7 @@
 				FDF0D6A40E12D05400247964 /* Mixer.app */,
 				FDC52EDE0E2843D6008D768C /* Fireworks.app */,
 				FDB6520C0E43D1F300F688B5 /* Keyboard.app */,
+				FA30DE961BBF59D9009C397F /* Happy-TV.app */,
 			);
 			name = Products;
 			sourceTree = "<group>";
@@ -399,6 +445,7 @@
 			isa = PBXGroup;
 			children = (
 				FD1B489E0E313154007AB34E /* libSDL2.a */,
+				FA30DEAC1BBF59D9009C397F /* libSDL2.a */,
 			);
 			name = Products;
 			sourceTree = "<group>";
@@ -473,6 +520,24 @@
 			productReference = 1D6058910D05DD3D006BFB54 /* Rectangles.app */;
 			productType = "com.apple.product-type.application";
 		};
+		FA30DE951BBF59D9009C397F /* Happy-TV */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = FA30DEAD1BBF59D9009C397F /* Build configuration list for PBXNativeTarget "Happy-TV" */;
+			buildPhases = (
+				FA30DE921BBF59D9009C397F /* Sources */,
+				FA30DE941BBF59D9009C397F /* Resources */,
+				FA30DE931BBF59D9009C397F /* Frameworks */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+				FA30DEAF1BBF5A69009C397F /* PBXTargetDependency */,
+			);
+			name = "Happy-TV";
+			productName = "Happy-TV";
+			productReference = FA30DE961BBF59D9009C397F /* Happy-TV.app */;
+			productType = "com.apple.product-type.application";
+		};
 		FD15FCB10E086866003BDF25 /* Happy */ = {
 			isa = PBXNativeTarget;
 			buildConfigurationList = FD15FCB70E086867003BDF25 /* Build configuration list for PBXNativeTarget "Happy" */;
@@ -588,6 +653,12 @@
 			isa = PBXProject;
 			attributes = {
 				LastUpgradeCheck = 0630;
+				TargetAttributes = {
+					FA30DE951BBF59D9009C397F = {
+						CreatedOnToolsVersion = 7.1;
+						DevelopmentTeam = DJN9C5VR5G;
+					};
+				};
 			};
 			buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Demos" */;
 			compatibilityVersion = "Xcode 3.2";
@@ -598,6 +669,7 @@
 				Japanese,
 				French,
 				German,
+				Base,
 			);
 			mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */;
 			projectDirPath = "";
@@ -611,6 +683,7 @@
 			targets = (
 				1D6058900D05DD3D006BFB54 /* Rectangles */,
 				FD15FCB10E086866003BDF25 /* Happy */,
+				FA30DE951BBF59D9009C397F /* Happy-TV */,
 				FD5F9BE30E0DEBEA008E885B /* Accel */,
 				FDC202DD0E107B1200ABAC90 /* Touch */,
 				FDF0D6920E12D05400247964 /* Mixer */,
@@ -621,6 +694,13 @@
 /* End PBXProject section */
 
 /* Begin PBXReferenceProxy section */
+		FA30DEAC1BBF59D9009C397F /* libSDL2.a */ = {
+			isa = PBXReferenceProxy;
+			fileType = archive.ar;
+			path = libSDL2.a;
+			remoteRef = FA30DEAB1BBF59D9009C397F /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
 		FD1B489E0E313154007AB34E /* libSDL2.a */ = {
 			isa = PBXReferenceProxy;
 			fileType = archive.ar;
@@ -640,6 +720,16 @@
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
+		FA30DE941BBF59D9009C397F /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				FA30DEB31BBF5AD7009C397F /* icon.bmp in Resources */,
+				FA30DEB41BBF5ADD009C397F /* Icon.png in Resources */,
+				FA30DEB61BBF5AE6009C397F /* Default.png in Resources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
 		FD15FCAE0E086866003BDF25 /* Resources */ = {
 			isa = PBXResourcesBuildPhase;
 			buildActionMask = 2147483647;
@@ -717,6 +807,15 @@
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
+		FA30DE921BBF59D9009C397F /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				FA30DEB01BBF5A8F009C397F /* common.c in Sources */,
+				FA30DEB11BBF5A93009C397F /* happy.c in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
 		FD15FCAF0E086866003BDF25 /* Sources */ = {
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
@@ -809,6 +908,11 @@
 			name = libSDL;
 			targetProxy = 049F36A0130CD8A000FF080F /* PBXContainerItemProxy */;
 		};
+		FA30DEAF1BBF5A69009C397F /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			name = "libSDL-tv";
+			targetProxy = FA30DEAE1BBF5A69009C397F /* PBXContainerItemProxy */;
+		};
 /* End PBXTargetDependency section */
 
 /* Begin XCBuildConfiguration section */
@@ -852,6 +956,92 @@
 			};
 			name = Release;
 		};
+		FA30DEA71BBF59D9009C397F /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				COPY_PHASE_STRIP = NO;
+				DEBUG_INFORMATION_FORMAT = dwarf;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				ENABLE_TESTABILITY = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"DEBUG=1",
+					"$(inherited)",
+				);
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				INFOPLIST_FILE = Info.plist;
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+				MTL_ENABLE_DEBUG_INFO = YES;
+				PRODUCT_BUNDLE_IDENTIFIER = "com.Happy-TV";
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				SDKROOT = appletvos;
+				TARGETED_DEVICE_FAMILY = 3;
+				TVOS_DEPLOYMENT_TARGET = 9.0;
+			};
+			name = Debug;
+		};
+		FA30DEA81BBF59D9009C397F /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				COPY_PHASE_STRIP = NO;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				ENABLE_NS_ASSERTIONS = NO;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				INFOPLIST_FILE = Info.plist;
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+				MTL_ENABLE_DEBUG_INFO = NO;
+				PRODUCT_BUNDLE_IDENTIFIER = "com.Happy-TV";
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				SDKROOT = appletvos;
+				TARGETED_DEVICE_FAMILY = 3;
+				TVOS_DEPLOYMENT_TARGET = 9.0;
+				VALIDATE_PRODUCT = YES;
+			};
+			name = Release;
+		};
 		FD15FCB50E086866003BDF25 /* Debug */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
@@ -982,6 +1172,15 @@
 			defaultConfigurationIsVisible = 0;
 			defaultConfigurationName = Release;
 		};
+		FA30DEAD1BBF59D9009C397F /* Build configuration list for PBXNativeTarget "Happy-TV" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				FA30DEA71BBF59D9009C397F /* Debug */,
+				FA30DEA81BBF59D9009C397F /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
 		FD15FCB70E086867003BDF25 /* Build configuration list for PBXNativeTarget "Happy" */ = {
 			isa = XCConfigurationList;
 			buildConfigurations = (

+ 5 - 0
Xcode-iOS/Demos/src/common.h

@@ -4,8 +4,13 @@
  *  use however you want
  */
 
+#if __TVOS__
+#define SCREEN_WIDTH 1920
+#define SCREEN_HEIGHT 1080
+#else
 #define SCREEN_WIDTH 320
 #define SCREEN_HEIGHT 480
+#endif
 
 extern int randomInt(int min, int max);
 extern float randomFloat(float min, float max);

+ 306 - 17
Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj

@@ -145,7 +145,102 @@
 		AADA5B8F16CCAB7C00107CF7 /* SDL_bits.h in Headers */ = {isa = PBXBuildFile; fileRef = AADA5B8E16CCAB7C00107CF7 /* SDL_bits.h */; };
 		FA1DC2721C62BE65008F99A0 /* SDL_uikitclipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = FA1DC2701C62BE65008F99A0 /* SDL_uikitclipboard.h */; };
 		FA1DC2731C62BE65008F99A0 /* SDL_uikitclipboard.m in Sources */ = {isa = PBXBuildFile; fileRef = FA1DC2711C62BE65008F99A0 /* SDL_uikitclipboard.m */; };
+		FAB5981D1BB5C31500BE72C5 /* SDL_atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = 04FFAB8912E23B8D00BA343D /* SDL_atomic.c */; };
+		FAB5981E1BB5C31500BE72C5 /* SDL_spinlock.c in Sources */ = {isa = PBXBuildFile; fileRef = 04FFAB8A12E23B8D00BA343D /* SDL_spinlock.c */; };
+		FAB5981F1BB5C31500BE72C5 /* SDL_coreaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = 56EA86F913E9EC2B002E47EB /* SDL_coreaudio.c */; };
+		FAB598211BB5C31500BE72C5 /* SDL_dummyaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = FD99B91D0DD52EDC00FB1D6B /* SDL_dummyaudio.c */; };
+		FAB598231BB5C31500BE72C5 /* SDL_audio.c in Sources */ = {isa = PBXBuildFile; fileRef = FD99B9440DD52EDC00FB1D6B /* SDL_audio.c */; };
+		FAB598251BB5C31500BE72C5 /* SDL_audiocvt.c in Sources */ = {isa = PBXBuildFile; fileRef = FD99B9460DD52EDC00FB1D6B /* SDL_audiocvt.c */; };
+		FAB598271BB5C31500BE72C5 /* SDL_audiotypecvt.c in Sources */ = {isa = PBXBuildFile; fileRef = FD99B94A0DD52EDC00FB1D6B /* SDL_audiotypecvt.c */; };
+		FAB598281BB5C31500BE72C5 /* SDL_mixer.c in Sources */ = {isa = PBXBuildFile; fileRef = FD99B94B0DD52EDC00FB1D6B /* SDL_mixer.c */; };
+		FAB5982A1BB5C31500BE72C5 /* SDL_wave.c in Sources */ = {isa = PBXBuildFile; fileRef = FD99B9530DD52EDC00FB1D6B /* SDL_wave.c */; };
+		FAB5982C1BB5C31500BE72C5 /* SDL_cpuinfo.c in Sources */ = {isa = PBXBuildFile; fileRef = FD99B98B0DD52EDC00FB1D6B /* SDL_cpuinfo.c */; };
+		FAB5982F1BB5C31500BE72C5 /* SDL_dynapi.c in Sources */ = {isa = PBXBuildFile; fileRef = 56A6703318565E760007D20F /* SDL_dynapi.c */; };
+		FAB598361BB5C31500BE72C5 /* SDL_clipboardevents.c in Sources */ = {isa = PBXBuildFile; fileRef = 0420496F11E6F03D007E7EC9 /* SDL_clipboardevents.c */; };
+		FAB598381BB5C31500BE72C5 /* SDL_dropevents.c in Sources */ = {isa = PBXBuildFile; fileRef = AA704DD5162AA90A0076D1C1 /* SDL_dropevents.c */; };
+		FAB5983A1BB5C31500BE72C5 /* SDL_events.c in Sources */ = {isa = PBXBuildFile; fileRef = FD99B9930DD52EDC00FB1D6B /* SDL_events.c */; };
+		FAB5983C1BB5C31500BE72C5 /* SDL_gesture.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BA9D6011EF474A00B60E01 /* SDL_gesture.c */; };
+		FAB5983E1BB5C31500BE72C5 /* SDL_keyboard.c in Sources */ = {isa = PBXBuildFile; fileRef = FD99B9950DD52EDC00FB1D6B /* SDL_keyboard.c */; };
+		FAB598401BB5C31500BE72C5 /* SDL_mouse.c in Sources */ = {isa = PBXBuildFile; fileRef = FD99B9970DD52EDC00FB1D6B /* SDL_mouse.c */; };
+		FAB598421BB5C31500BE72C5 /* SDL_quit.c in Sources */ = {isa = PBXBuildFile; fileRef = FD99B9990DD52EDC00FB1D6B /* SDL_quit.c */; };
+		FAB598441BB5C31500BE72C5 /* SDL_touch.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BA9D6211EF474A00B60E01 /* SDL_touch.c */; };
+		FAB598461BB5C31500BE72C5 /* SDL_windowevents.c in Sources */ = {isa = PBXBuildFile; fileRef = FD99B99B0DD52EDC00FB1D6B /* SDL_windowevents.c */; };
+		FAB598491BB5C31600BE72C5 /* SDL_rwopsbundlesupport.m in Sources */ = {isa = PBXBuildFile; fileRef = 006E9887119552DD001DE610 /* SDL_rwopsbundlesupport.m */; };
+		FAB5984A1BB5C31600BE72C5 /* SDL_rwops.c in Sources */ = {isa = PBXBuildFile; fileRef = FD99B99E0DD52EDC00FB1D6B /* SDL_rwops.c */; };
+		FAB5984B1BB5C31600BE72C5 /* SDL_sysfilesystem.m in Sources */ = {isa = PBXBuildFile; fileRef = 56C181E117C44D7A00406AE3 /* SDL_sysfilesystem.m */; };
+		FAB5984C1BB5C31600BE72C5 /* SDL_syshaptic.c in Sources */ = {isa = PBXBuildFile; fileRef = 047677B80EA76A31008ABAF1 /* SDL_syshaptic.c */; };
+		FAB5984D1BB5C31600BE72C5 /* SDL_haptic.c in Sources */ = {isa = PBXBuildFile; fileRef = 047677B90EA76A31008ABAF1 /* SDL_haptic.c */; };
+		FAB598501BB5C31600BE72C5 /* SDL_sysjoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = FD689F000E26E5B600F90B21 /* SDL_sysjoystick.m */; };
+		FAB598511BB5C31600BE72C5 /* SDL_gamecontroller.c in Sources */ = {isa = PBXBuildFile; fileRef = AA0AD06116647BBB00CE5896 /* SDL_gamecontroller.c */; };
+		FAB598521BB5C31600BE72C5 /* SDL_joystick.c in Sources */ = {isa = PBXBuildFile; fileRef = FD5F9D1E0E0E08B3008E885B /* SDL_joystick.c */; };
+		FAB598551BB5C31600BE72C5 /* SDL_sysloadso.c in Sources */ = {isa = PBXBuildFile; fileRef = 047AF1B20EA98D6C00811173 /* SDL_sysloadso.c */; };
+		FAB598561BB5C31600BE72C5 /* SDL_sysloadso.c in Sources */ = {isa = PBXBuildFile; fileRef = FD8BD8190E27E25900B52CD5 /* SDL_sysloadso.c */; };
+		FAB598571BB5C31600BE72C5 /* SDL_power.c in Sources */ = {isa = PBXBuildFile; fileRef = 56ED04E0118A8EE200A56AA6 /* SDL_power.c */; };
+		FAB598581BB5C31600BE72C5 /* SDL_syspower.m in Sources */ = {isa = PBXBuildFile; fileRef = 56ED04E2118A8EFD00A56AA6 /* SDL_syspower.m */; };
+		FAB598591BB5C31600BE72C5 /* SDL_render_gles.c in Sources */ = {isa = PBXBuildFile; fileRef = 0442EC5212FE1C28004C9285 /* SDL_render_gles.c */; };
+		FAB5985A1BB5C31600BE72C5 /* SDL_render_gles2.c in Sources */ = {isa = PBXBuildFile; fileRef = 0402A85512FE70C600CECEE3 /* SDL_render_gles2.c */; };
+		FAB5985B1BB5C31600BE72C5 /* SDL_shaders_gles2.c in Sources */ = {isa = PBXBuildFile; fileRef = 0402A85612FE70C600CECEE3 /* SDL_shaders_gles2.c */; };
+		FAB5985D1BB5C31600BE72C5 /* SDL_blendfillrect.c in Sources */ = {isa = PBXBuildFile; fileRef = 04F7806A12FB751400FC43C0 /* SDL_blendfillrect.c */; };
+		FAB5985F1BB5C31600BE72C5 /* SDL_blendline.c in Sources */ = {isa = PBXBuildFile; fileRef = 04F7806C12FB751400FC43C0 /* SDL_blendline.c */; };
+		FAB598611BB5C31600BE72C5 /* SDL_blendpoint.c in Sources */ = {isa = PBXBuildFile; fileRef = 04F7806E12FB751400FC43C0 /* SDL_blendpoint.c */; };
+		FAB598641BB5C31600BE72C5 /* SDL_drawline.c in Sources */ = {isa = PBXBuildFile; fileRef = 04F7807112FB751400FC43C0 /* SDL_drawline.c */; };
+		FAB598661BB5C31600BE72C5 /* SDL_drawpoint.c in Sources */ = {isa = PBXBuildFile; fileRef = 04F7807312FB751400FC43C0 /* SDL_drawpoint.c */; };
+		FAB598681BB5C31600BE72C5 /* SDL_render_sw.c in Sources */ = {isa = PBXBuildFile; fileRef = 0442EC4F12FE1C1E004C9285 /* SDL_render_sw.c */; };
+		FAB5986A1BB5C31600BE72C5 /* SDL_rotate.c in Sources */ = {isa = PBXBuildFile; fileRef = AA628AD9159369E3005138DD /* SDL_rotate.c */; };
+		FAB5986D1BB5C31600BE72C5 /* SDL_render.c in Sources */ = {isa = PBXBuildFile; fileRef = 041B2CEA12FA0F680087D585 /* SDL_render.c */; };
+		FAB5986F1BB5C31600BE72C5 /* SDL_yuv_mmx.c in Sources */ = {isa = PBXBuildFile; fileRef = 04409BA312FA989600FB9AA8 /* SDL_yuv_mmx.c */; };
+		FAB598711BB5C31600BE72C5 /* SDL_yuv_sw.c in Sources */ = {isa = PBXBuildFile; fileRef = 04409BA512FA989600FB9AA8 /* SDL_yuv_sw.c */; };
+		FAB598721BB5C31600BE72C5 /* SDL_getenv.c in Sources */ = {isa = PBXBuildFile; fileRef = FD3F4A700DEA620800C5B771 /* SDL_getenv.c */; };
+		FAB598731BB5C31600BE72C5 /* SDL_iconv.c in Sources */ = {isa = PBXBuildFile; fileRef = FD3F4A710DEA620800C5B771 /* SDL_iconv.c */; };
+		FAB598741BB5C31600BE72C5 /* SDL_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = FD3F4A720DEA620800C5B771 /* SDL_malloc.c */; };
+		FAB598751BB5C31600BE72C5 /* SDL_qsort.c in Sources */ = {isa = PBXBuildFile; fileRef = FD3F4A730DEA620800C5B771 /* SDL_qsort.c */; };
+		FAB598761BB5C31600BE72C5 /* SDL_stdlib.c in Sources */ = {isa = PBXBuildFile; fileRef = FD3F4A740DEA620800C5B771 /* SDL_stdlib.c */; };
+		FAB598771BB5C31600BE72C5 /* SDL_string.c in Sources */ = {isa = PBXBuildFile; fileRef = FD3F4A750DEA620800C5B771 /* SDL_string.c */; };
+		FAB598781BB5C31600BE72C5 /* SDL_syscond.c in Sources */ = {isa = PBXBuildFile; fileRef = FD99BA070DD52EDC00FB1D6B /* SDL_syscond.c */; };
+		FAB598791BB5C31600BE72C5 /* SDL_sysmutex.c in Sources */ = {isa = PBXBuildFile; fileRef = FD99BA080DD52EDC00FB1D6B /* SDL_sysmutex.c */; };
+		FAB5987B1BB5C31600BE72C5 /* SDL_syssem.c in Sources */ = {isa = PBXBuildFile; fileRef = FD99BA0A0DD52EDC00FB1D6B /* SDL_syssem.c */; };
+		FAB5987C1BB5C31600BE72C5 /* SDL_systhread.c in Sources */ = {isa = PBXBuildFile; fileRef = FD99BA0B0DD52EDC00FB1D6B /* SDL_systhread.c */; };
+		FAB5987E1BB5C31600BE72C5 /* SDL_systls.c in Sources */ = {isa = PBXBuildFile; fileRef = AA0F8494178D5F1A00823F9D /* SDL_systls.c */; };
+		FAB598801BB5C31600BE72C5 /* SDL_thread.c in Sources */ = {isa = PBXBuildFile; fileRef = FD99BA150DD52EDC00FB1D6B /* SDL_thread.c */; };
+		FAB598821BB5C31600BE72C5 /* SDL_systimer.c in Sources */ = {isa = PBXBuildFile; fileRef = FD99BA310DD52EDC00FB1D6B /* SDL_systimer.c */; };
+		FAB598831BB5C31600BE72C5 /* SDL_timer.c in Sources */ = {isa = PBXBuildFile; fileRef = FD99BA2E0DD52EDC00FB1D6B /* SDL_timer.c */; };
+		FAB598871BB5C31600BE72C5 /* SDL_uikitappdelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = FD689FCC0E26E9D400F90B21 /* SDL_uikitappdelegate.m */; };
+		FAB598891BB5C31600BE72C5 /* SDL_uikitevents.m in Sources */ = {isa = PBXBuildFile; fileRef = FD689F0D0E26E5D900F90B21 /* SDL_uikitevents.m */; };
+		FAB5988B1BB5C31600BE72C5 /* SDL_uikitmessagebox.m in Sources */ = {isa = PBXBuildFile; fileRef = AABCC3931640643D00AB8930 /* SDL_uikitmessagebox.m */; };
+		FAB5988D1BB5C31600BE72C5 /* SDL_uikitmodes.m in Sources */ = {isa = PBXBuildFile; fileRef = AA126AD31617C5E6005ABC8F /* SDL_uikitmodes.m */; };
+		FAB5988F1BB5C31600BE72C5 /* SDL_uikitopengles.m in Sources */ = {isa = PBXBuildFile; fileRef = FD689F0F0E26E5D900F90B21 /* SDL_uikitopengles.m */; };
+		FAB598911BB5C31600BE72C5 /* SDL_uikitopenglview.m in Sources */ = {isa = PBXBuildFile; fileRef = FD689F170E26E5D900F90B21 /* SDL_uikitopenglview.m */; };
+		FAB598931BB5C31600BE72C5 /* SDL_uikitvideo.m in Sources */ = {isa = PBXBuildFile; fileRef = FD689F110E26E5D900F90B21 /* SDL_uikitvideo.m */; };
+		FAB598951BB5C31600BE72C5 /* SDL_uikitview.m in Sources */ = {isa = PBXBuildFile; fileRef = FD689F130E26E5D900F90B21 /* SDL_uikitview.m */; };
+		FAB598971BB5C31600BE72C5 /* SDL_uikitviewcontroller.m in Sources */ = {isa = PBXBuildFile; fileRef = 93CB792513FC5F5300BD3E05 /* SDL_uikitviewcontroller.m */; };
+		FAB598991BB5C31600BE72C5 /* SDL_uikitwindow.m in Sources */ = {isa = PBXBuildFile; fileRef = FD689F150E26E5D900F90B21 /* SDL_uikitwindow.m */; };
+		FAB5989A1BB5C31600BE72C5 /* SDL_nullevents.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA685F50DF244C800F98A1A /* SDL_nullevents.c */; };
+		FAB5989D1BB5C31600BE72C5 /* SDL_nullframebuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 04F7808312FB753F00FC43C0 /* SDL_nullframebuffer.c */; };
+		FAB5989E1BB5C31600BE72C5 /* SDL_nullvideo.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA685F90DF244C800F98A1A /* SDL_nullvideo.c */; };
+		FAB598A01BB5C31600BE72C5 /* SDL_blit.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA683000DF2374E00F98A1A /* SDL_blit.c */; };
+		FAB598A21BB5C31600BE72C5 /* SDL_blit_0.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA683020DF2374E00F98A1A /* SDL_blit_0.c */; };
+		FAB598A31BB5C31600BE72C5 /* SDL_blit_1.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA683030DF2374E00F98A1A /* SDL_blit_1.c */; };
+		FAB598A41BB5C31600BE72C5 /* SDL_blit_A.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA683040DF2374E00F98A1A /* SDL_blit_A.c */; };
+		FAB598A51BB5C31600BE72C5 /* SDL_blit_auto.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA683050DF2374E00F98A1A /* SDL_blit_auto.c */; };
+		FAB598A71BB5C31600BE72C5 /* SDL_blit_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA683070DF2374E00F98A1A /* SDL_blit_copy.c */; };
+		FAB598A91BB5C31600BE72C5 /* SDL_blit_N.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA683090DF2374E00F98A1A /* SDL_blit_N.c */; };
+		FAB598AA1BB5C31600BE72C5 /* SDL_blit_slow.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA6830A0DF2374E00F98A1A /* SDL_blit_slow.c */; };
+		FAB598AC1BB5C31600BE72C5 /* SDL_bmp.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA6830B0DF2374E00F98A1A /* SDL_bmp.c */; };
+		FAB598AD1BB5C31600BE72C5 /* SDL_clipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = 044E5FB711E606EB0076F181 /* SDL_clipboard.c */; };
+		FAB598AE1BB5C31600BE72C5 /* SDL_fillrect.c in Sources */ = {isa = PBXBuildFile; fileRef = 0463873E0F0B5B7D0041FD65 /* SDL_fillrect.c */; };
+		FAB598AF1BB5C31600BE72C5 /* SDL_pixels.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA6830F0DF2374E00F98A1A /* SDL_pixels.c */; };
+		FAB598B11BB5C31600BE72C5 /* SDL_rect.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA683110DF2374E00F98A1A /* SDL_rect.c */; };
+		FAB598B21BB5C31600BE72C5 /* SDL_RLEaccel.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA683150DF2374E00F98A1A /* SDL_RLEaccel.c */; };
+		FAB598B41BB5C31600BE72C5 /* SDL_stretch.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA683170DF2374E00F98A1A /* SDL_stretch.c */; };
+		FAB598B51BB5C31600BE72C5 /* SDL_surface.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA683190DF2374E00F98A1A /* SDL_surface.c */; };
+		FAB598B71BB5C31600BE72C5 /* SDL_video.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA6831B0DF2374E00F98A1A /* SDL_video.c */; };
+		FAB598B91BB5C31600BE72C5 /* SDL_assert.c in Sources */ = {isa = PBXBuildFile; fileRef = 04F2AF551104ABD200D6DDF7 /* SDL_assert.c */; };
+		FAB598BC1BB5C31600BE72C5 /* SDL_error.c in Sources */ = {isa = PBXBuildFile; fileRef = FD99B9D50DD52EDC00FB1D6B /* SDL_error.c */; };
+		FAB598BD1BB5C31600BE72C5 /* SDL_hints.c in Sources */ = {isa = PBXBuildFile; fileRef = 0442EC5412FE1C3F004C9285 /* SDL_hints.c */; };
+		FAB598BE1BB5C31600BE72C5 /* SDL_log.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BAC09B1300C1290055DE28 /* SDL_log.c */; };
+		FAB598BF1BB5C31600BE72C5 /* SDL.c in Sources */ = {isa = PBXBuildFile; fileRef = FD99B9D80DD52EDC00FB1D6B /* SDL.c */; };
 		FAD4F7021BA3C4E8008346CE /* SDL_sysjoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = FAD4F7011BA3C4E8008346CE /* SDL_sysjoystick_c.h */; };
+		FAFDF8C61D88D4530083E6F2 /* SDL_uikitclipboard.m in Sources */ = {isa = PBXBuildFile; fileRef = FA1DC2711C62BE65008F99A0 /* SDL_uikitclipboard.m */; };
 		FD3F4A760DEA620800C5B771 /* SDL_getenv.c in Sources */ = {isa = PBXBuildFile; fileRef = FD3F4A700DEA620800C5B771 /* SDL_getenv.c */; };
 		FD3F4A770DEA620800C5B771 /* SDL_iconv.c in Sources */ = {isa = PBXBuildFile; fileRef = FD3F4A710DEA620800C5B771 /* SDL_iconv.c */; };
 		FD3F4A780DEA620800C5B771 /* SDL_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = FD3F4A720DEA620800C5B771 /* SDL_malloc.c */; };
@@ -344,6 +439,7 @@
 		AADA5B8E16CCAB7C00107CF7 /* SDL_bits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_bits.h; sourceTree = "<group>"; };
 		FA1DC2701C62BE65008F99A0 /* SDL_uikitclipboard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_uikitclipboard.h; sourceTree = "<group>"; };
 		FA1DC2711C62BE65008F99A0 /* SDL_uikitclipboard.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_uikitclipboard.m; sourceTree = "<group>"; };
+		FAB598141BB5C1B100BE72C5 /* libSDL2.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSDL2.a; sourceTree = BUILT_PRODUCTS_DIR; };
 		FAD4F7011BA3C4E8008346CE /* SDL_sysjoystick_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_sysjoystick_c.h; sourceTree = "<group>"; };
 		FD0BBFEF0E3933DD00D833B1 /* SDL_uikitview.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_uikitview.h; sourceTree = "<group>"; };
 		FD3F4A700DEA620800C5B771 /* SDL_getenv.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_getenv.c; sourceTree = "<group>"; };
@@ -549,6 +645,7 @@
 			isa = PBXGroup;
 			children = (
 				FD6526630DE8FCCB002AD96B /* libSDL2.a */,
+				FAB598141BB5C1B100BE72C5 /* libSDL2.a */,
 			);
 			name = Products;
 			sourceTree = "<group>";
@@ -1069,6 +1166,21 @@
 /* End PBXHeadersBuildPhase section */
 
 /* Begin PBXNativeTarget section */
+		FAB598131BB5C1B100BE72C5 /* libSDL-tv */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = FAB5981A1BB5C1B100BE72C5 /* Build configuration list for PBXNativeTarget "libSDL-tv" */;
+			buildPhases = (
+				FAB598101BB5C1B100BE72C5 /* Sources */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = "libSDL-tv";
+			productName = "libSDL-tv";
+			productReference = FAB598141BB5C1B100BE72C5 /* libSDL2.a */;
+			productType = "com.apple.product-type.library.static";
+		};
 		FD6526620DE8FCCB002AD96B /* libSDL */ = {
 			isa = PBXNativeTarget;
 			buildConfigurationList = FD6526990DE8FD14002AD96B /* Build configuration list for PBXNativeTarget "libSDL" */;
@@ -1092,6 +1204,11 @@
 			isa = PBXProject;
 			attributes = {
 				LastUpgradeCheck = 0800;
+				TargetAttributes = {
+					FAB598131BB5C1B100BE72C5 = {
+						CreatedOnToolsVersion = 7.1;
+					};
+				};
 			};
 			buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "SDL" */;
 			compatibilityVersion = "Xcode 3.2";
@@ -1108,6 +1225,7 @@
 			projectRoot = ../..;
 			targets = (
 				FD6526620DE8FCCB002AD96B /* libSDL */,
+				FAB598131BB5C1B100BE72C5 /* libSDL-tv */,
 				00B4F48B12F6A69C0084EC00 /* PrepareXcodeProjectTemplate */,
 			);
 		};
@@ -1131,6 +1249,108 @@
 /* End PBXShellScriptBuildPhase section */
 
 /* Begin PBXSourcesBuildPhase section */
+		FAB598101BB5C1B100BE72C5 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				FAB5981D1BB5C31500BE72C5 /* SDL_atomic.c in Sources */,
+				FAB5981E1BB5C31500BE72C5 /* SDL_spinlock.c in Sources */,
+				FAB5981F1BB5C31500BE72C5 /* SDL_coreaudio.c in Sources */,
+				FAB598211BB5C31500BE72C5 /* SDL_dummyaudio.c in Sources */,
+				FAB598231BB5C31500BE72C5 /* SDL_audio.c in Sources */,
+				FAB598251BB5C31500BE72C5 /* SDL_audiocvt.c in Sources */,
+				FAB598271BB5C31500BE72C5 /* SDL_audiotypecvt.c in Sources */,
+				FAB598281BB5C31500BE72C5 /* SDL_mixer.c in Sources */,
+				FAB5982A1BB5C31500BE72C5 /* SDL_wave.c in Sources */,
+				FAFDF8C61D88D4530083E6F2 /* SDL_uikitclipboard.m in Sources */,
+				FAB5982C1BB5C31500BE72C5 /* SDL_cpuinfo.c in Sources */,
+				FAB5982F1BB5C31500BE72C5 /* SDL_dynapi.c in Sources */,
+				FAB598361BB5C31500BE72C5 /* SDL_clipboardevents.c in Sources */,
+				FAB598381BB5C31500BE72C5 /* SDL_dropevents.c in Sources */,
+				FAB5983A1BB5C31500BE72C5 /* SDL_events.c in Sources */,
+				FAB5983C1BB5C31500BE72C5 /* SDL_gesture.c in Sources */,
+				FAB5983E1BB5C31500BE72C5 /* SDL_keyboard.c in Sources */,
+				FAB598401BB5C31500BE72C5 /* SDL_mouse.c in Sources */,
+				FAB598421BB5C31500BE72C5 /* SDL_quit.c in Sources */,
+				FAB598441BB5C31500BE72C5 /* SDL_touch.c in Sources */,
+				FAB598461BB5C31500BE72C5 /* SDL_windowevents.c in Sources */,
+				FAB598491BB5C31600BE72C5 /* SDL_rwopsbundlesupport.m in Sources */,
+				FAB5984A1BB5C31600BE72C5 /* SDL_rwops.c in Sources */,
+				FAB5984B1BB5C31600BE72C5 /* SDL_sysfilesystem.m in Sources */,
+				FAB5984C1BB5C31600BE72C5 /* SDL_syshaptic.c in Sources */,
+				FAB5984D1BB5C31600BE72C5 /* SDL_haptic.c in Sources */,
+				FAB598501BB5C31600BE72C5 /* SDL_sysjoystick.m in Sources */,
+				FAB598511BB5C31600BE72C5 /* SDL_gamecontroller.c in Sources */,
+				FAB598521BB5C31600BE72C5 /* SDL_joystick.c in Sources */,
+				FAB598551BB5C31600BE72C5 /* SDL_sysloadso.c in Sources */,
+				FAB598561BB5C31600BE72C5 /* SDL_sysloadso.c in Sources */,
+				FAB598571BB5C31600BE72C5 /* SDL_power.c in Sources */,
+				FAB598581BB5C31600BE72C5 /* SDL_syspower.m in Sources */,
+				FAB598591BB5C31600BE72C5 /* SDL_render_gles.c in Sources */,
+				FAB5985A1BB5C31600BE72C5 /* SDL_render_gles2.c in Sources */,
+				FAB5985B1BB5C31600BE72C5 /* SDL_shaders_gles2.c in Sources */,
+				FAB5985D1BB5C31600BE72C5 /* SDL_blendfillrect.c in Sources */,
+				FAB5985F1BB5C31600BE72C5 /* SDL_blendline.c in Sources */,
+				FAB598611BB5C31600BE72C5 /* SDL_blendpoint.c in Sources */,
+				FAB598641BB5C31600BE72C5 /* SDL_drawline.c in Sources */,
+				FAB598661BB5C31600BE72C5 /* SDL_drawpoint.c in Sources */,
+				FAB598681BB5C31600BE72C5 /* SDL_render_sw.c in Sources */,
+				FAB5986A1BB5C31600BE72C5 /* SDL_rotate.c in Sources */,
+				FAB5986D1BB5C31600BE72C5 /* SDL_render.c in Sources */,
+				FAB5986F1BB5C31600BE72C5 /* SDL_yuv_mmx.c in Sources */,
+				FAB598711BB5C31600BE72C5 /* SDL_yuv_sw.c in Sources */,
+				FAB598721BB5C31600BE72C5 /* SDL_getenv.c in Sources */,
+				FAB598731BB5C31600BE72C5 /* SDL_iconv.c in Sources */,
+				FAB598741BB5C31600BE72C5 /* SDL_malloc.c in Sources */,
+				FAB598751BB5C31600BE72C5 /* SDL_qsort.c in Sources */,
+				FAB598761BB5C31600BE72C5 /* SDL_stdlib.c in Sources */,
+				FAB598771BB5C31600BE72C5 /* SDL_string.c in Sources */,
+				FAB598781BB5C31600BE72C5 /* SDL_syscond.c in Sources */,
+				FAB598791BB5C31600BE72C5 /* SDL_sysmutex.c in Sources */,
+				FAB5987B1BB5C31600BE72C5 /* SDL_syssem.c in Sources */,
+				FAB5987C1BB5C31600BE72C5 /* SDL_systhread.c in Sources */,
+				FAB5987E1BB5C31600BE72C5 /* SDL_systls.c in Sources */,
+				FAB598801BB5C31600BE72C5 /* SDL_thread.c in Sources */,
+				FAB598821BB5C31600BE72C5 /* SDL_systimer.c in Sources */,
+				FAB598831BB5C31600BE72C5 /* SDL_timer.c in Sources */,
+				FAB598871BB5C31600BE72C5 /* SDL_uikitappdelegate.m in Sources */,
+				FAB598891BB5C31600BE72C5 /* SDL_uikitevents.m in Sources */,
+				FAB5988B1BB5C31600BE72C5 /* SDL_uikitmessagebox.m in Sources */,
+				FAB5988D1BB5C31600BE72C5 /* SDL_uikitmodes.m in Sources */,
+				FAB5988F1BB5C31600BE72C5 /* SDL_uikitopengles.m in Sources */,
+				FAB598911BB5C31600BE72C5 /* SDL_uikitopenglview.m in Sources */,
+				FAB598931BB5C31600BE72C5 /* SDL_uikitvideo.m in Sources */,
+				FAB598951BB5C31600BE72C5 /* SDL_uikitview.m in Sources */,
+				FAB598971BB5C31600BE72C5 /* SDL_uikitviewcontroller.m in Sources */,
+				FAB598991BB5C31600BE72C5 /* SDL_uikitwindow.m in Sources */,
+				FAB5989A1BB5C31600BE72C5 /* SDL_nullevents.c in Sources */,
+				FAB5989D1BB5C31600BE72C5 /* SDL_nullframebuffer.c in Sources */,
+				FAB5989E1BB5C31600BE72C5 /* SDL_nullvideo.c in Sources */,
+				FAB598A01BB5C31600BE72C5 /* SDL_blit.c in Sources */,
+				FAB598A21BB5C31600BE72C5 /* SDL_blit_0.c in Sources */,
+				FAB598A31BB5C31600BE72C5 /* SDL_blit_1.c in Sources */,
+				FAB598A41BB5C31600BE72C5 /* SDL_blit_A.c in Sources */,
+				FAB598A51BB5C31600BE72C5 /* SDL_blit_auto.c in Sources */,
+				FAB598A71BB5C31600BE72C5 /* SDL_blit_copy.c in Sources */,
+				FAB598A91BB5C31600BE72C5 /* SDL_blit_N.c in Sources */,
+				FAB598AA1BB5C31600BE72C5 /* SDL_blit_slow.c in Sources */,
+				FAB598AC1BB5C31600BE72C5 /* SDL_bmp.c in Sources */,
+				FAB598AD1BB5C31600BE72C5 /* SDL_clipboard.c in Sources */,
+				FAB598AE1BB5C31600BE72C5 /* SDL_fillrect.c in Sources */,
+				FAB598AF1BB5C31600BE72C5 /* SDL_pixels.c in Sources */,
+				FAB598B11BB5C31600BE72C5 /* SDL_rect.c in Sources */,
+				FAB598B21BB5C31600BE72C5 /* SDL_RLEaccel.c in Sources */,
+				FAB598B41BB5C31600BE72C5 /* SDL_stretch.c in Sources */,
+				FAB598B51BB5C31600BE72C5 /* SDL_surface.c in Sources */,
+				FAB598B71BB5C31600BE72C5 /* SDL_video.c in Sources */,
+				FAB598B91BB5C31600BE72C5 /* SDL_assert.c in Sources */,
+				FAB598BC1BB5C31600BE72C5 /* SDL_error.c in Sources */,
+				FAB598BD1BB5C31600BE72C5 /* SDL_hints.c in Sources */,
+				FAB598BE1BB5C31600BE72C5 /* SDL_log.c in Sources */,
+				FAB598BF1BB5C31600BE72C5 /* SDL.c in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
 		FD6526600DE8FCCB002AD96B /* Sources */ = {
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
@@ -1259,59 +1479,119 @@
 		C01FCF4F08A954540054247B /* Debug */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
+				CLANG_ENABLE_OBJC_ARC = YES;
+				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+				ENABLE_TESTABILITY = YES;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_SYMBOLS_PRIVATE_EXTERN = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES;
+				IPHONEOS_DEPLOYMENT_TARGET = 5.1.1;
+				ONLY_ACTIVE_ARCH = YES;
+				SDKROOT = iphoneos;
+				TARGETED_DEVICE_FAMILY = "1,2";
+			};
+			name = Debug;
+		};
+		C01FCF5008A954540054247B /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CLANG_ENABLE_OBJC_ARC = YES;
+				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+				GCC_SYMBOLS_PRIVATE_EXTERN = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES;
+				IPHONEOS_DEPLOYMENT_TARGET = 5.1.1;
+				SDKROOT = iphoneos;
+				TARGETED_DEVICE_FAMILY = "1,2";
+			};
+			name = Release;
+		};
+		FAB5981B1BB5C1B100BE72C5 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
 				CLANG_WARN_BOOL_CONVERSION = YES;
 				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
 				CLANG_WARN_EMPTY_BODY = YES;
 				CLANG_WARN_ENUM_CONVERSION = YES;
 				CLANG_WARN_INFINITE_RECURSION = YES;
 				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
 				CLANG_WARN_SUSPICIOUS_MOVE = YES;
 				CLANG_WARN_UNREACHABLE_CODE = YES;
 				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
-				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+				COPY_PHASE_STRIP = NO;
+				DEBUG_INFORMATION_FORMAT = dwarf;
 				ENABLE_STRICT_OBJC_MSGSEND = YES;
 				ENABLE_TESTABILITY = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_DYNAMIC_NO_PIC = NO;
 				GCC_NO_COMMON_BLOCKS = YES;
-				GCC_OPTIMIZATION_LEVEL = 0;
-				GCC_SYMBOLS_PRIVATE_EXTERN = YES;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"DEBUG=1",
+					"$(inherited)",
+				);
 				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
 				GCC_WARN_UNDECLARED_SELECTOR = YES;
-				GCC_WARN_UNINITIALIZED_AUTOS = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
 				GCC_WARN_UNUSED_FUNCTION = YES;
 				GCC_WARN_UNUSED_VARIABLE = YES;
-				IPHONEOS_DEPLOYMENT_TARGET = 5.1.1;
-				ONLY_ACTIVE_ARCH = YES;
-				SDKROOT = iphoneos;
-				TARGETED_DEVICE_FAMILY = "1,2";
+				MTL_ENABLE_DEBUG_INFO = YES;
+				OTHER_LDFLAGS = "-ObjC";
+				PRODUCT_NAME = SDL2;
+				SDKROOT = appletvos;
+				SKIP_INSTALL = YES;
+				SUPPORTED_PLATFORMS = "appletvsimulator appletvos";
+				TARGETED_DEVICE_FAMILY = 3;
+				TVOS_DEPLOYMENT_TARGET = 9.0;
 			};
 			name = Debug;
 		};
-		C01FCF5008A954540054247B /* Release */ = {
+		FAB5981C1BB5C1B100BE72C5 /* Release */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
 				CLANG_WARN_BOOL_CONVERSION = YES;
 				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
 				CLANG_WARN_EMPTY_BODY = YES;
 				CLANG_WARN_ENUM_CONVERSION = YES;
 				CLANG_WARN_INFINITE_RECURSION = YES;
 				CLANG_WARN_INT_CONVERSION = YES;
-				CLANG_WARN_SUSPICIOUS_MOVE = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
 				CLANG_WARN_UNREACHABLE_CODE = YES;
 				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
-				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+				COPY_PHASE_STRIP = NO;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				ENABLE_NS_ASSERTIONS = NO;
 				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
 				GCC_NO_COMMON_BLOCKS = YES;
 				GCC_SYMBOLS_PRIVATE_EXTERN = YES;
 				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
 				GCC_WARN_UNDECLARED_SELECTOR = YES;
-				GCC_WARN_UNINITIALIZED_AUTOS = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
 				GCC_WARN_UNUSED_FUNCTION = YES;
 				GCC_WARN_UNUSED_VARIABLE = YES;
-				IPHONEOS_DEPLOYMENT_TARGET = 5.1.1;
-				SDKROOT = iphoneos;
-				TARGETED_DEVICE_FAMILY = "1,2";
+				MTL_ENABLE_DEBUG_INFO = NO;
+				OTHER_LDFLAGS = "-ObjC";
+				PRODUCT_NAME = SDL2;
+				SDKROOT = appletvos;
+				SKIP_INSTALL = YES;
+				SUPPORTED_PLATFORMS = "appletvsimulator appletvos";
+				TARGETED_DEVICE_FAMILY = 3;
+				TVOS_DEPLOYMENT_TARGET = 9.0;
+				VALIDATE_PRODUCT = YES;
 			};
 			name = Release;
 		};
@@ -1366,6 +1646,15 @@
 			defaultConfigurationIsVisible = 0;
 			defaultConfigurationName = Release;
 		};
+		FAB5981A1BB5C1B100BE72C5 /* Build configuration list for PBXNativeTarget "libSDL-tv" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				FAB5981B1BB5C1B100BE72C5 /* Debug */,
+				FAB5981C1BB5C1B100BE72C5 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
 		FD6526990DE8FD14002AD96B /* Build configuration list for PBXNativeTarget "libSDL" */ = {
 			isa = XCConfigurationList;
 			buildConfigurations = (

+ 143 - 2
Xcode-iOS/SDLtest/SDL2test.xcodeproj/project.pbxproj

@@ -21,8 +21,34 @@
 		AA1EE46D176059AB0029C7A5 /* SDL_test_log.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE45F176059AB0029C7A5 /* SDL_test_log.c */; };
 		AA1EE46E176059AB0029C7A5 /* SDL_test_md5.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE460176059AB0029C7A5 /* SDL_test_md5.c */; };
 		AA1EE46F176059AB0029C7A5 /* SDL_test_random.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE461176059AB0029C7A5 /* SDL_test_random.c */; };
+		FA3D99011BC4E5BC002C96C8 /* SDL_test_common.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE454176059AB0029C7A5 /* SDL_test_common.c */; };
+		FA3D99021BC4E5BC002C96C8 /* SDL_test_compare.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE455176059AB0029C7A5 /* SDL_test_compare.c */; };
+		FA3D99031BC4E5BC002C96C8 /* SDL_test_crc32.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE456176059AB0029C7A5 /* SDL_test_crc32.c */; };
+		FA3D99041BC4E5BC002C96C8 /* SDL_test_font.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE457176059AB0029C7A5 /* SDL_test_font.c */; };
+		FA3D99051BC4E5BC002C96C8 /* SDL_test_fuzzer.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE458176059AB0029C7A5 /* SDL_test_fuzzer.c */; };
+		FA3D99061BC4E5BC002C96C8 /* SDL_test_harness.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE459176059AB0029C7A5 /* SDL_test_harness.c */; };
+		FA3D99071BC4E5BC002C96C8 /* SDL_test_imageBlit.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE45A176059AB0029C7A5 /* SDL_test_imageBlit.c */; };
+		FA3D99081BC4E5BC002C96C8 /* SDL_test_imageBlitBlend.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE45B176059AB0029C7A5 /* SDL_test_imageBlitBlend.c */; };
+		FA3D99091BC4E5BC002C96C8 /* SDL_test_imageFace.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE45C176059AB0029C7A5 /* SDL_test_imageFace.c */; };
+		FA3D990A1BC4E5BC002C96C8 /* SDL_test_imagePrimitives.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE45D176059AB0029C7A5 /* SDL_test_imagePrimitives.c */; };
+		FA3D990B1BC4E5BC002C96C8 /* SDL_test_imagePrimitivesBlend.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE45E176059AB0029C7A5 /* SDL_test_imagePrimitivesBlend.c */; };
+		FA3D990C1BC4E5BC002C96C8 /* SDL_test_log.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE45F176059AB0029C7A5 /* SDL_test_log.c */; };
+		FA3D990D1BC4E5BC002C96C8 /* SDL_test_md5.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE460176059AB0029C7A5 /* SDL_test_md5.c */; };
+		FA3D990E1BC4E5BC002C96C8 /* SDL_test_random.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE461176059AB0029C7A5 /* SDL_test_random.c */; };
 /* End PBXBuildFile section */
 
+/* Begin PBXCopyFilesBuildPhase section */
+		FA3D98F61BC4E5A2002C96C8 /* CopyFiles */ = {
+			isa = PBXCopyFilesBuildPhase;
+			buildActionMask = 2147483647;
+			dstPath = "include/$(PRODUCT_NAME)";
+			dstSubfolderSpec = 16;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXCopyFilesBuildPhase section */
+
 /* Begin PBXFileReference section */
 		AA1EE4461760589B0029C7A5 /* libSDL2test.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSDL2test.a; sourceTree = BUILT_PRODUCTS_DIR; };
 		AA1EE454176059AB0029C7A5 /* SDL_test_common.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_test_common.c; path = ../../src/test/SDL_test_common.c; sourceTree = "<group>"; };
@@ -39,6 +65,7 @@
 		AA1EE45F176059AB0029C7A5 /* SDL_test_log.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_test_log.c; path = ../../src/test/SDL_test_log.c; sourceTree = "<group>"; };
 		AA1EE460176059AB0029C7A5 /* SDL_test_md5.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_test_md5.c; path = ../../src/test/SDL_test_md5.c; sourceTree = "<group>"; };
 		AA1EE461176059AB0029C7A5 /* SDL_test_random.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_test_random.c; path = ../../src/test/SDL_test_random.c; sourceTree = "<group>"; };
+		FA3D98F81BC4E5A2002C96C8 /* libSDL2test-TV.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libSDL2test-TV.a"; sourceTree = BUILT_PRODUCTS_DIR; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
@@ -49,6 +76,13 @@
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
+		FA3D98F51BC4E5A2002C96C8 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
 /* End PBXFrameworksBuildPhase section */
 
 /* Begin PBXGroup section */
@@ -64,6 +98,7 @@
 			isa = PBXGroup;
 			children = (
 				AA1EE4461760589B0029C7A5 /* libSDL2test.a */,
+				FA3D98F81BC4E5A2002C96C8 /* libSDL2test-TV.a */,
 			);
 			name = Products;
 			sourceTree = "<group>";
@@ -119,6 +154,23 @@
 			productReference = AA1EE4461760589B0029C7A5 /* libSDL2test.a */;
 			productType = "com.apple.product-type.library.static";
 		};
+		FA3D98F71BC4E5A2002C96C8 /* SDL2test-TV */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = FA3D99001BC4E5A3002C96C8 /* Build configuration list for PBXNativeTarget "SDL2test-TV" */;
+			buildPhases = (
+				FA3D98F41BC4E5A2002C96C8 /* Sources */,
+				FA3D98F51BC4E5A2002C96C8 /* Frameworks */,
+				FA3D98F61BC4E5A2002C96C8 /* CopyFiles */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = "SDL2test-TV";
+			productName = "SDL2test-TV";
+			productReference = FA3D98F81BC4E5A2002C96C8 /* libSDL2test-TV.a */;
+			productType = "com.apple.product-type.library.static";
+		};
 /* End PBXNativeTarget section */
 
 /* Begin PBXProject section */
@@ -127,6 +179,11 @@
 			attributes = {
 				LastUpgradeCheck = 0460;
 				ORGANIZATIONNAME = "Sam Lantinga";
+				TargetAttributes = {
+					FA3D98F71BC4E5A2002C96C8 = {
+						CreatedOnToolsVersion = 7.1;
+					};
+				};
 			};
 			buildConfigurationList = AA1EE4411760589B0029C7A5 /* Build configuration list for PBXProject "SDL2test" */;
 			compatibilityVersion = "Xcode 3.2";
@@ -141,6 +198,7 @@
 			projectRoot = "";
 			targets = (
 				AA1EE4451760589B0029C7A5 /* SDL2test */,
+				FA3D98F71BC4E5A2002C96C8 /* SDL2test-TV */,
 			);
 		};
 /* End PBXProject section */
@@ -167,6 +225,27 @@
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
+		FA3D98F41BC4E5A2002C96C8 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				FA3D99011BC4E5BC002C96C8 /* SDL_test_common.c in Sources */,
+				FA3D99021BC4E5BC002C96C8 /* SDL_test_compare.c in Sources */,
+				FA3D99031BC4E5BC002C96C8 /* SDL_test_crc32.c in Sources */,
+				FA3D99041BC4E5BC002C96C8 /* SDL_test_font.c in Sources */,
+				FA3D99051BC4E5BC002C96C8 /* SDL_test_fuzzer.c in Sources */,
+				FA3D99061BC4E5BC002C96C8 /* SDL_test_harness.c in Sources */,
+				FA3D99071BC4E5BC002C96C8 /* SDL_test_imageBlit.c in Sources */,
+				FA3D99081BC4E5BC002C96C8 /* SDL_test_imageBlitBlend.c in Sources */,
+				FA3D99091BC4E5BC002C96C8 /* SDL_test_imageFace.c in Sources */,
+				FA3D990A1BC4E5BC002C96C8 /* SDL_test_imagePrimitives.c in Sources */,
+				FA3D990B1BC4E5BC002C96C8 /* SDL_test_imagePrimitivesBlend.c in Sources */,
+				FA3D990C1BC4E5BC002C96C8 /* SDL_test_log.c in Sources */,
+				FA3D990D1BC4E5BC002C96C8 /* SDL_test_md5.c in Sources */,
+				FA3D990E1BC4E5BC002C96C8 /* SDL_test_random.c in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
 /* End PBXSourcesBuildPhase section */
 
 /* Begin XCBuildConfiguration section */
@@ -195,6 +274,7 @@
 				GCC_WARN_ABOUT_RETURN_TYPE = YES;
 				GCC_WARN_UNINITIALIZED_AUTOS = YES;
 				GCC_WARN_UNUSED_VARIABLE = YES;
+				HEADER_SEARCH_PATHS = ../../include;
 				MACOSX_DEPLOYMENT_TARGET = 10.8;
 				ONLY_ACTIVE_ARCH = YES;
 				SDKROOT = iphoneos;
@@ -220,6 +300,7 @@
 				GCC_WARN_ABOUT_RETURN_TYPE = YES;
 				GCC_WARN_UNINITIALIZED_AUTOS = YES;
 				GCC_WARN_UNUSED_VARIABLE = YES;
+				HEADER_SEARCH_PATHS = ../../include;
 				MACOSX_DEPLOYMENT_TARGET = 10.8;
 				SDKROOT = iphoneos;
 			};
@@ -229,7 +310,6 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				EXECUTABLE_PREFIX = lib;
-				HEADER_SEARCH_PATHS = ../../include;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 			};
 			name = Debug;
@@ -238,11 +318,63 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				EXECUTABLE_PREFIX = lib;
-				HEADER_SEARCH_PATHS = ../../include;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 			};
 			name = Release;
 		};
+		FA3D98FE1BC4E5A3002C96C8 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				DEBUG_INFORMATION_FORMAT = dwarf;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				ENABLE_TESTABILITY = YES;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				MTL_ENABLE_DEBUG_INFO = YES;
+				OTHER_LDFLAGS = "-ObjC";
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				SDKROOT = appletvos;
+				SKIP_INSTALL = YES;
+				TVOS_DEPLOYMENT_TARGET = 9.0;
+			};
+			name = Debug;
+		};
+		FA3D98FF1BC4E5A3002C96C8 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				COPY_PHASE_STRIP = NO;
+				ENABLE_NS_ASSERTIONS = NO;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				MTL_ENABLE_DEBUG_INFO = NO;
+				OTHER_LDFLAGS = "-ObjC";
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				SDKROOT = appletvos;
+				SKIP_INSTALL = YES;
+				TVOS_DEPLOYMENT_TARGET = 9.0;
+				VALIDATE_PRODUCT = YES;
+			};
+			name = Release;
+		};
 /* End XCBuildConfiguration section */
 
 /* Begin XCConfigurationList section */
@@ -264,6 +396,15 @@
 			defaultConfigurationIsVisible = 0;
 			defaultConfigurationName = Release;
 		};
+		FA3D99001BC4E5A3002C96C8 /* Build configuration list for PBXNativeTarget "SDL2test-TV" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				FA3D98FE1BC4E5A3002C96C8 /* Debug */,
+				FA3D98FF1BC4E5A3002C96C8 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
 /* End XCConfigurationList section */
 	};
 	rootObject = AA1EE43E1760589B0029C7A5 /* Project object */;

+ 223 - 5
Xcode-iOS/Test/TestiPhoneOS.xcodeproj/project.pbxproj

@@ -65,7 +65,20 @@
 		AAE7DFAC14CBB54E00DF1A0E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A89D0E2D111A00EA573E /* Foundation.framework */; };
 		AAE7DFAD14CBB54E00DF1A0E /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A89E0E2D111A00EA573E /* CoreAudio.framework */; };
 		AAE7DFB514CBB5F700DF1A0E /* testrendertarget.c in Sources */ = {isa = PBXBuildFile; fileRef = AAE7DFB414CBB5F700DF1A0E /* testrendertarget.c */; };
-		FA0EF22E1BAF4654000E07A6 /* testjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA8A74E0E2D0F1600EA573E /* testjoystick.c */; settings = {ASSET_TAGS = (); }; };
+		FA0EF22E1BAF4654000E07A6 /* testjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA8A74E0E2D0F1600EA573E /* testjoystick.c */; };
+		FA3D99481BC4E6AD002C96C8 /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA684F7A1BAF1A4400DCFD1A /* GameController.framework */; };
+		FA3D994A1BC4E6AD002C96C8 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A8980E2D111A00EA573E /* AudioToolbox.framework */; };
+		FA3D994B1BC4E6AD002C96C8 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A8990E2D111A00EA573E /* QuartzCore.framework */; };
+		FA3D994C1BC4E6AD002C96C8 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A89A0E2D111A00EA573E /* OpenGLES.framework */; };
+		FA3D994D1BC4E6AD002C96C8 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A89B0E2D111A00EA573E /* CoreGraphics.framework */; };
+		FA3D994E1BC4E6AD002C96C8 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A89C0E2D111A00EA573E /* UIKit.framework */; };
+		FA3D994F1BC4E6AD002C96C8 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A89D0E2D111A00EA573E /* Foundation.framework */; };
+		FA3D99501BC4E6AD002C96C8 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A89E0E2D111A00EA573E /* CoreAudio.framework */; };
+		FA3D99521BC4E70C002C96C8 /* controllermap.bmp in Resources */ = {isa = PBXBuildFile; fileRef = FA0EF22A1BAF4487000E07A6 /* controllermap.bmp */; };
+		FA3D99531BC4E70E002C96C8 /* axis.bmp in Resources */ = {isa = PBXBuildFile; fileRef = FA0EF2281BAF4487000E07A6 /* axis.bmp */; };
+		FA3D99541BC4E70F002C96C8 /* button.bmp in Resources */ = {isa = PBXBuildFile; fileRef = FA0EF2291BAF4487000E07A6 /* button.bmp */; };
+		FA3D99551BC4E712002C96C8 /* icon.bmp in Resources */ = {isa = PBXBuildFile; fileRef = FDA8AAD90E2D33B000EA573E /* icon.bmp */; };
+		FA3D99561BC4E719002C96C8 /* testgamecontroller.c in Sources */ = {isa = PBXBuildFile; fileRef = FA0EF2221BAF43DE000E07A6 /* testgamecontroller.c */; };
 		FA684F7B1BAF1A4400DCFD1A /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA684F7A1BAF1A4400DCFD1A /* GameController.framework */; };
 		FA684F7F1BAF1A4D00DCFD1A /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA684F7A1BAF1A4400DCFD1A /* GameController.framework */; };
 		FA684F801BAF1A5000DCFD1A /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA684F7A1BAF1A4400DCFD1A /* GameController.framework */; };
@@ -112,6 +125,8 @@
 		FA8B4BDF196766F100F8EB7C /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA8B4BAC1967076F00F8EB7C /* CoreMotion.framework */; };
 		FA8B4BE0196766F400F8EB7C /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA8B4BAC1967076F00F8EB7C /* CoreMotion.framework */; };
 		FA8B4BE1196766F600F8EB7C /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA8B4BAC1967076F00F8EB7C /* CoreMotion.framework */; };
+		FAA8CEE31BDF057F00D3BD45 /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FAA8CEE21BDF057F00D3BD45 /* GameController.framework */; };
+		FAA8CEE41BDF06D600D3BD45 /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FA3D992B1BC4E619002C96C8 /* libSDL2.a */; };
 		FAE0E9821BAF9B230098DFA4 /* icon.bmp in Resources */ = {isa = PBXBuildFile; fileRef = FDA8AAD90E2D33B000EA573E /* icon.bmp */; };
 		FAE0E9861BAF9B230098DFA4 /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FD1B48B80E3131CA007AB34E /* libSDL2.a */; };
 		FAE0E9871BAF9B230098DFA4 /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA684F7A1BAF1A4400DCFD1A /* GameController.framework */; };
@@ -123,10 +138,10 @@
 		FAE0E98D1BAF9B230098DFA4 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A89C0E2D111A00EA573E /* UIKit.framework */; };
 		FAE0E98E1BAF9B230098DFA4 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A89D0E2D111A00EA573E /* Foundation.framework */; };
 		FAE0E98F1BAF9B230098DFA4 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A89E0E2D111A00EA573E /* CoreAudio.framework */; };
-		FAE0E9951BAF9B510098DFA4 /* testgamecontroller.c in Sources */ = {isa = PBXBuildFile; fileRef = FA0EF2221BAF43DE000E07A6 /* testgamecontroller.c */; settings = {ASSET_TAGS = (); }; };
-		FAE0E9961BAF9B650098DFA4 /* controllermap.bmp in Resources */ = {isa = PBXBuildFile; fileRef = FA0EF22A1BAF4487000E07A6 /* controllermap.bmp */; settings = {ASSET_TAGS = (); }; };
-		FAE0E9971BAF9B6A0098DFA4 /* button.bmp in Resources */ = {isa = PBXBuildFile; fileRef = FA0EF2291BAF4487000E07A6 /* button.bmp */; settings = {ASSET_TAGS = (); }; };
-		FAE0E9981BAF9B6E0098DFA4 /* axis.bmp in Resources */ = {isa = PBXBuildFile; fileRef = FA0EF2281BAF4487000E07A6 /* axis.bmp */; settings = {ASSET_TAGS = (); }; };
+		FAE0E9951BAF9B510098DFA4 /* testgamecontroller.c in Sources */ = {isa = PBXBuildFile; fileRef = FA0EF2221BAF43DE000E07A6 /* testgamecontroller.c */; };
+		FAE0E9961BAF9B650098DFA4 /* controllermap.bmp in Resources */ = {isa = PBXBuildFile; fileRef = FA0EF22A1BAF4487000E07A6 /* controllermap.bmp */; };
+		FAE0E9971BAF9B6A0098DFA4 /* button.bmp in Resources */ = {isa = PBXBuildFile; fileRef = FA0EF2291BAF4487000E07A6 /* button.bmp */; };
+		FAE0E9981BAF9B6E0098DFA4 /* axis.bmp in Resources */ = {isa = PBXBuildFile; fileRef = FA0EF2281BAF4487000E07A6 /* axis.bmp */; };
 		FDA8A79C0E2D0F9300EA573E /* testwm2.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA8A75F0E2D0F1600EA573E /* testwm2.c */; };
 		FDA8A89F0E2D111A00EA573E /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A8980E2D111A00EA573E /* AudioToolbox.framework */; };
 		FDA8A8A00E2D111A00EA573E /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A8990E2D111A00EA573E /* QuartzCore.framework */; };
@@ -304,6 +319,27 @@
 			remoteGlobalIDString = AA1EE4461760589B0029C7A5;
 			remoteInfo = SDL2test;
 		};
+		FA3D992A1BC4E619002C96C8 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = FD1B48AC0E3131CA007AB34E /* SDL.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = FAB598141BB5C1B100BE72C5;
+			remoteInfo = "libSDL-tv";
+		};
+		FA3D992E1BC4E619002C96C8 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = AA1EE44D176059220029C7A5 /* SDL2test.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = FA3D98F81BC4E5A2002C96C8;
+			remoteInfo = "SDL2test-TV";
+		};
+		FAA8CEE51BDF06DC00D3BD45 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = FD1B48AC0E3131CA007AB34E /* SDL.xcodeproj */;
+			proxyType = 1;
+			remoteGlobalIDString = FAB598131BB5C1B100BE72C5;
+			remoteInfo = "libSDL-tv";
+		};
 		FD1B48B70E3131CA007AB34E /* PBXContainerItemProxy */ = {
 			isa = PBXContainerItemProxy;
 			containerPortal = FD1B48AC0E3131CA007AB34E /* SDL.xcodeproj */;
@@ -330,8 +366,10 @@
 		FA0EF2281BAF4487000E07A6 /* axis.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; name = axis.bmp; path = ../../test/axis.bmp; sourceTree = "<group>"; };
 		FA0EF2291BAF4487000E07A6 /* button.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; name = button.bmp; path = ../../test/button.bmp; sourceTree = "<group>"; };
 		FA0EF22A1BAF4487000E07A6 /* controllermap.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; name = controllermap.bmp; path = ../../test/controllermap.bmp; sourceTree = "<group>"; };
+		FA3D99341BC4E644002C96C8 /* testgamecontroller-TV.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "testgamecontroller-TV.app"; sourceTree = BUILT_PRODUCTS_DIR; };
 		FA684F7A1BAF1A4400DCFD1A /* GameController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameController.framework; path = System/Library/Frameworks/GameController.framework; sourceTree = SDKROOT; };
 		FA8B4BAC1967076F00F8EB7C /* CoreMotion.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMotion.framework; path = System/Library/Frameworks/CoreMotion.framework; sourceTree = SDKROOT; };
+		FAA8CEE21BDF057F00D3BD45 /* GameController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameController.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS9.0.sdk/System/Library/Frameworks/GameController.framework; sourceTree = DEVELOPER_DIR; };
 		FAE0E9931BAF9B230098DFA4 /* testgamecontroller.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testgamecontroller.app; sourceTree = BUILT_PRODUCTS_DIR; };
 		FD1B48AC0E3131CA007AB34E /* SDL.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = SDL.xcodeproj; path = ../SDL/SDL.xcodeproj; sourceTree = SOURCE_ROOT; };
 		FDA8A7410E2D0F1600EA573E /* testaudioinfo.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = testaudioinfo.c; path = ../../test/testaudioinfo.c; sourceTree = SOURCE_ROOT; };
@@ -492,6 +530,23 @@
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
+		FA3D99311BC4E644002C96C8 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				FAA8CEE41BDF06D600D3BD45 /* libSDL2.a in Frameworks */,
+				FAA8CEE31BDF057F00D3BD45 /* GameController.framework in Frameworks */,
+				FA3D99481BC4E6AD002C96C8 /* GameController.framework in Frameworks */,
+				FA3D994A1BC4E6AD002C96C8 /* AudioToolbox.framework in Frameworks */,
+				FA3D994B1BC4E6AD002C96C8 /* QuartzCore.framework in Frameworks */,
+				FA3D994C1BC4E6AD002C96C8 /* OpenGLES.framework in Frameworks */,
+				FA3D994D1BC4E6AD002C96C8 /* CoreGraphics.framework in Frameworks */,
+				FA3D994E1BC4E6AD002C96C8 /* UIKit.framework in Frameworks */,
+				FA3D994F1BC4E6AD002C96C8 /* Foundation.framework in Frameworks */,
+				FA3D99501BC4E6AD002C96C8 /* CoreAudio.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
 		FAE0E9851BAF9B230098DFA4 /* Frameworks */ = {
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
@@ -831,6 +886,7 @@
 				AAE7DEEC14CBB1E100DF1A0E /* testscale.app */,
 				AAE7DFB114CBB54E00DF1A0E /* testrendertarget.app */,
 				FAE0E9931BAF9B230098DFA4 /* testgamecontroller.app */,
+				FA3D99341BC4E644002C96C8 /* testgamecontroller-TV.app */,
 			);
 			name = Products;
 			sourceTree = "<group>";
@@ -838,6 +894,7 @@
 		29B97314FDCFA39411CA2CEA /* CustomTemplate */ = {
 			isa = PBXGroup;
 			children = (
+				FAA8CEE21BDF057F00D3BD45 /* GameController.framework */,
 				AA1EE44D176059220029C7A5 /* SDL2test.xcodeproj */,
 				FD1B48AC0E3131CA007AB34E /* SDL.xcodeproj */,
 				FDA8AAD60E2D339A00EA573E /* Resources */,
@@ -852,6 +909,7 @@
 			isa = PBXGroup;
 			children = (
 				AA1EE452176059230029C7A5 /* libSDL2test.a */,
+				FA3D992F1BC4E619002C96C8 /* libSDL2test-TV.a */,
 			);
 			name = Products;
 			sourceTree = "<group>";
@@ -860,6 +918,7 @@
 			isa = PBXGroup;
 			children = (
 				FD1B48B80E3131CA007AB34E /* libSDL2.a */,
+				FA3D992B1BC4E619002C96C8 /* libSDL2.a */,
 			);
 			name = Products;
 			sourceTree = "<group>";
@@ -1033,6 +1092,24 @@
 			productReference = AAE7DFB114CBB54E00DF1A0E /* testrendertarget.app */;
 			productType = "com.apple.product-type.application";
 		};
+		FA3D99331BC4E644002C96C8 /* testgamecontroller-TV */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = FA3D99451BC4E645002C96C8 /* Build configuration list for PBXNativeTarget "testgamecontroller-TV" */;
+			buildPhases = (
+				FA3D99301BC4E644002C96C8 /* Sources */,
+				FA3D99311BC4E644002C96C8 /* Frameworks */,
+				FA3D99321BC4E644002C96C8 /* Resources */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+				FAA8CEE61BDF06DC00D3BD45 /* PBXTargetDependency */,
+			);
+			name = "testgamecontroller-TV";
+			productName = "testgamecontroller-TV";
+			productReference = FA3D99341BC4E644002C96C8 /* testgamecontroller-TV.app */;
+			productType = "com.apple.product-type.application";
+		};
 		FAE0E9801BAF9B230098DFA4 /* testgamecontroller */ = {
 			isa = PBXNativeTarget;
 			buildConfigurationList = FAE0E9901BAF9B230098DFA4 /* Build configuration list for PBXNativeTarget "testgamecontroller" */;
@@ -1346,6 +1423,11 @@
 			isa = PBXProject;
 			attributes = {
 				LastUpgradeCheck = 0630;
+				TargetAttributes = {
+					FA3D99331BC4E644002C96C8 = {
+						CreatedOnToolsVersion = 7.1;
+					};
+				};
 			};
 			buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "TestiPhoneOS" */;
 			compatibilityVersion = "Xcode 3.2";
@@ -1356,6 +1438,7 @@
 				Japanese,
 				French,
 				German,
+				Base,
 			);
 			mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */;
 			projectDirPath = "";
@@ -1378,6 +1461,7 @@
 				FDAAC58A0E2D5429001DB1D8 /* testerror */,
 				FDAAC5B80E2D55B5001DB1D8 /* testfile */,
 				FAE0E9801BAF9B230098DFA4 /* testgamecontroller */,
+				FA3D99331BC4E644002C96C8 /* testgamecontroller-TV */,
 				046CEF7513254F23007AD51D /* testgesture */,
 				FDAAC6150E2D5914001DB1D8 /* testgles */,
 				FDD2C1700E2E52C000B7A85F /* testiconv */,
@@ -1407,6 +1491,20 @@
 			remoteRef = AA1EE451176059230029C7A5 /* PBXContainerItemProxy */;
 			sourceTree = BUILT_PRODUCTS_DIR;
 		};
+		FA3D992B1BC4E619002C96C8 /* libSDL2.a */ = {
+			isa = PBXReferenceProxy;
+			fileType = archive.ar;
+			path = libSDL2.a;
+			remoteRef = FA3D992A1BC4E619002C96C8 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		FA3D992F1BC4E619002C96C8 /* libSDL2test-TV.a */ = {
+			isa = PBXReferenceProxy;
+			fileType = archive.ar;
+			path = "libSDL2test-TV.a";
+			remoteRef = FA3D992E1BC4E619002C96C8 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
 		FD1B48B80E3131CA007AB34E /* libSDL2.a */ = {
 			isa = PBXReferenceProxy;
 			fileType = archive.ar;
@@ -1465,6 +1563,17 @@
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
+		FA3D99321BC4E644002C96C8 /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				FA3D99521BC4E70C002C96C8 /* controllermap.bmp in Resources */,
+				FA3D99541BC4E70F002C96C8 /* button.bmp in Resources */,
+				FA3D99531BC4E70E002C96C8 /* axis.bmp in Resources */,
+				FA3D99551BC4E712002C96C8 /* icon.bmp in Resources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
 		FAE0E9811BAF9B230098DFA4 /* Resources */ = {
 			isa = PBXResourcesBuildPhase;
 			buildActionMask = 2147483647;
@@ -1652,6 +1761,14 @@
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
+		FA3D99301BC4E644002C96C8 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				FA3D99561BC4E719002C96C8 /* testgamecontroller.c in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
 		FAE0E9831BAF9B230098DFA4 /* Sources */ = {
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
@@ -1798,6 +1915,14 @@
 		};
 /* End PBXSourcesBuildPhase section */
 
+/* Begin PBXTargetDependency section */
+		FAA8CEE61BDF06DC00D3BD45 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			name = "libSDL-tv";
+			targetProxy = FAA8CEE51BDF06DC00D3BD45 /* PBXContainerItemProxy */;
+		};
+/* End PBXTargetDependency section */
+
 /* Begin XCBuildConfiguration section */
 		046CEF8413254F23007AD51D /* Debug */ = {
 			isa = XCBuildConfiguration;
@@ -1921,6 +2046,90 @@
 			};
 			name = Release;
 		};
+		FA3D99461BC4E645002C96C8 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				COPY_PHASE_STRIP = NO;
+				DEBUG_INFORMATION_FORMAT = dwarf;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				ENABLE_TESTABILITY = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"DEBUG=1",
+					"$(inherited)",
+				);
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				INFOPLIST_FILE = Info.plist;
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+				MTL_ENABLE_DEBUG_INFO = YES;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				SDKROOT = appletvos;
+				TARGETED_DEVICE_FAMILY = 3;
+				TVOS_DEPLOYMENT_TARGET = 9.0;
+			};
+			name = Debug;
+		};
+		FA3D99471BC4E645002C96C8 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				COPY_PHASE_STRIP = NO;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				ENABLE_NS_ASSERTIONS = NO;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				INFOPLIST_FILE = Info.plist;
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+				MTL_ENABLE_DEBUG_INFO = NO;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				SDKROOT = appletvos;
+				TARGETED_DEVICE_FAMILY = 3;
+				TVOS_DEPLOYMENT_TARGET = 9.0;
+				VALIDATE_PRODUCT = YES;
+			};
+			name = Release;
+		};
 		FAE0E9911BAF9B230098DFA4 /* Debug */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
@@ -2275,6 +2484,15 @@
 			defaultConfigurationIsVisible = 0;
 			defaultConfigurationName = Release;
 		};
+		FA3D99451BC4E645002C96C8 /* Build configuration list for PBXNativeTarget "testgamecontroller-TV" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				FA3D99461BC4E645002C96C8 /* Debug */,
+				FA3D99471BC4E645002C96C8 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
 		FAE0E9901BAF9B230098DFA4 /* Build configuration list for PBXNativeTarget "testgamecontroller" */ = {
 			isa = XCConfigurationList;
 			buildConfigurations = (

+ 19 - 1
include/SDL_hints.h

@@ -276,7 +276,25 @@ extern "C" {
  *    "LandscapeLeft", "LandscapeRight", "Portrait" "PortraitUpsideDown"
  */
 #define SDL_HINT_ORIENTATIONS "SDL_IOS_ORIENTATIONS"
-    
+
+/**
+ *  \brief  A variable controlling whether controllers used with the Apple TV
+ *  generate UI events.
+ *
+ * When UI events are generated by controller input, the app will be
+ * backgrounded when the Apple TV remote's menu button is pressed, and when the
+ * pause or B buttons on gamepads are pressed.
+ *
+ * More information about properly making use of controllers for the Apple TV
+ * can be found here:
+ * https://developer.apple.com/tvos/human-interface-guidelines/remote-and-interaction/
+ *
+ *  This variable can be set to the following values:
+ *    "0"       - Controller input does not generate UI events (the default).
+ *    "1"       - Controller input generates UI events.
+ */
+#define SDL_HINT_APPLE_TV_CONTROLLER_UI_EVENTS "SDL_APPLE_TV_CONTROLLER_UI_EVENTS"
+
 /**
  *  \brief  A variable controlling whether the Android / iOS built-in
  *  accelerometer should be listed as a joystick device, rather than listing

+ 6 - 2
include/SDL_platform.h

@@ -70,13 +70,17 @@
 /* lets us know what version of Mac OS X we're compiling on */
 #include "AvailabilityMacros.h"
 #include "TargetConditionals.h"
+#if TARGET_OS_TV
+#undef __TVOS__
+#define __TVOS__ 1
+#endif
 #if TARGET_OS_IPHONE
-/* if compiling for iPhone */
+/* if compiling for iOS */
 #undef __IPHONEOS__
 #define __IPHONEOS__ 1
 #undef __MACOSX__
 #else
-/* if not compiling for iPhone */
+/* if not compiling for iOS */
 #undef __MACOSX__
 #define __MACOSX__  1
 #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060

+ 2 - 0
src/SDL.c

@@ -443,6 +443,8 @@ SDL_GetPlatform()
     return "Windows";
 #elif __WINRT__
     return "WinRT";
+#elif __TVOS__
+    return "tvOS";
 #elif __IPHONEOS__
     return "iOS";
 #elif __PSP__

+ 4 - 2
src/audio/coreaudio/SDL_coreaudio.c

@@ -274,7 +274,7 @@ static int open_capture_devices = 0;
 
 static void update_audio_session()
 {
-#if !MACOSX_COREAUDIO
+#if !MACOSX_COREAUDIO && !TARGET_OS_TV
     /* !!! FIXME: move this to AVAudioSession. This is deprecated, and the new version is available as of (ancient!) iOS 3.0 */
     UInt32 category;
     if (open_playback_devices && open_capture_devices) {
@@ -569,8 +569,8 @@ prepare_audioqueue(_THIS)
     /* We're running! */
     return 1;
 }
-
 static int
+
 audioqueue_thread(void *arg)
 {
     SDL_AudioDevice *this = (SDL_AudioDevice *) arg;
@@ -725,9 +725,11 @@ COREAUDIO_Init(SDL_AudioDriverImpl * impl)
        !!! FIXME: do this when a device is opened, and deinitialize when all devices close.
     */
     /* !!! FIXME: move this to AVAudioSession. This is deprecated, and the new version is available as of (ancient!) iOS 3.0 */
+#if !TARGET_OS_TV
     AudioSessionInitialize(NULL, NULL, NULL, nil);
     UInt32 category = kAudioSessionCategory_AmbientSound;
     AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(UInt32), &category);
+#endif /* !TARGET_OS_TV */
 #endif
 
     impl->ProvidesOwnCallbackThread = 1;

+ 71 - 6
src/joystick/iphoneos/SDL_sysjoystick.m

@@ -33,7 +33,13 @@
 #include "../SDL_sysjoystick.h"
 #include "../SDL_joystick_c.h"
 
+#if !SDL_EVENTS_DISABLED
+#include "../../events/SDL_events_c.h"
+#endif
+
+#if !TARGET_OS_TV
 #import <CoreMotion/CoreMotion.h>
+#endif
 
 #ifdef SDL_JOYSTICK_MFI
 #import <GameController/GameController.h>
@@ -42,8 +48,10 @@ static id connectObserver = nil;
 static id disconnectObserver = nil;
 #endif /* SDL_JOYSTICK_MFI */
 
+#if !TARGET_OS_TV
 static const char *accelerometerName = "iOS Accelerometer";
 static CMMotionManager *motionManager = nil;
+#endif /* !TARGET_OS_TV */
 
 static SDL_JoystickDeviceItem *deviceList = NULL;
 
@@ -102,6 +110,11 @@ SDL_SYS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *contr
     } else if (controller.gamepad) {
         device->guid.data[10] = 2;
     }
+#if TARGET_OS_TV
+    else if (controller.microGamepad) {
+        device->guid.data[10] = 3;
+    }
+#endif /* TARGET_OS_TV */
 
     if (controller.extendedGamepad) {
         device->naxes = 6; /* 2 thumbsticks and 2 triggers */
@@ -112,12 +125,19 @@ SDL_SYS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *contr
         device->nhats = 1; /* d-pad */
         device->nbuttons = 7; /* ABXY, shoulder buttons, pause button */
     }
-    /* TODO: Handle micro profiles on tvOS. */
+#if TARGET_OS_TV
+    else if (controller.microGamepad) {
+        device->naxes = 2; /* treat the touch surface as two axes */
+        device->nhats = 0; /* apparently the touch surface-as-dpad is buggy */
+        device->nbuttons = 3; /* AX, pause button */
+    }
+#endif /* TARGET_OS_TV */
 
     /* This will be set when the first button press of the controller is
      * detected. */
     controller.playerIndex = -1;
-#endif
+
+#endif /* SDL_JOYSTICK_MFI */
 }
 
 static void
@@ -143,6 +163,10 @@ SDL_SYS_AddJoystickDevice(GCController *controller, SDL_bool accelerometer)
     device->instance_id = instancecounter++;
 
     if (accelerometer) {
+#if TARGET_OS_TV
+        SDL_free(device);
+        return;
+#else
         device->name = SDL_strdup(accelerometerName);
         device->naxes = 3; /* Device acceleration in the x, y, and z axes. */
         device->nhats = 0;
@@ -150,6 +174,7 @@ SDL_SYS_AddJoystickDevice(GCController *controller, SDL_bool accelerometer)
 
         /* Use the accelerometer name as a GUID. */
         SDL_memcpy(&device->guid.data, device->name, SDL_min(sizeof(SDL_JoystickGUID), SDL_strlen(device->name)));
+#endif /* TARGET_OS_TV */
     } else if (controller) {
         SDL_SYS_AddMFIJoystickDevice(device, controller);
     }
@@ -232,12 +257,14 @@ SDL_SYS_JoystickInit(void)
 {
     @autoreleasepool {
         NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
-        const char *hint = SDL_GetHint(SDL_HINT_ACCELEROMETER_AS_JOYSTICK);
 
+#if !TARGET_OS_TV
+        const char *hint = SDL_GetHint(SDL_HINT_ACCELEROMETER_AS_JOYSTICK);
         if (!hint || SDL_atoi(hint)) {
             /* Default behavior, accelerometer as joystick */
             SDL_SYS_AddJoystickDevice(nil, SDL_TRUE);
         }
+#endif /* !TARGET_OS_TV */
 
 #ifdef SDL_JOYSTICK_MFI
         /* GameController.framework was added in iOS 7. */
@@ -326,6 +353,7 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index)
 
     @autoreleasepool {
         if (device->accelerometer) {
+#if !TARGET_OS_TV
             if (motionManager == nil) {
                 motionManager = [[CMMotionManager alloc] init];
             }
@@ -333,6 +361,7 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index)
             /* Shorter times between updates can significantly increase CPU usage. */
             motionManager.accelerometerUpdateInterval = 0.1;
             [motionManager startAccelerometerUpdates];
+#endif /* !TARGET_OS_TV */
         } else {
 #ifdef SDL_JOYSTICK_MFI
             GCController *controller = device->controller;
@@ -358,6 +387,7 @@ SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
 static void
 SDL_SYS_AccelerometerUpdate(SDL_Joystick * joystick)
 {
+#if !TARGET_OS_TV
     const float maxgforce = SDL_IPHONE_MAX_GFORCE;
     const SInt16 maxsint16 = 0x7FFF;
     CMAcceleration accel;
@@ -395,6 +425,7 @@ SDL_SYS_AccelerometerUpdate(SDL_Joystick * joystick)
     SDL_PrivateJoystickAxis(joystick, 0,  (accel.x / maxgforce) * maxsint16);
     SDL_PrivateJoystickAxis(joystick, 1, -(accel.y / maxgforce) * maxsint16);
     SDL_PrivateJoystickAxis(joystick, 2,  (accel.z / maxgforce) * maxsint16);
+#endif /* !TARGET_OS_TV */
 }
 
 #ifdef SDL_JOYSTICK_MFI
@@ -426,7 +457,7 @@ SDL_SYS_MFIJoystickHatStateForDPad(GCControllerDirectionPad *dpad)
 static void
 SDL_SYS_MFIJoystickUpdate(SDL_Joystick * joystick)
 {
-#ifdef SDL_JOYSTICK_MFI
+#if SDL_JOYSTICK_MFI
     @autoreleasepool {
         GCController *controller = joystick->hwdata->controller;
         Uint8 hatstate = SDL_HAT_CENTERED;
@@ -482,13 +513,43 @@ SDL_SYS_MFIJoystickUpdate(SDL_Joystick * joystick)
             };
 
             hatstate = SDL_SYS_MFIJoystickHatStateForDPad(gamepad.dpad);
+            SDL_PrivateJoystickHat(joystick, 0, hatstate);
 
             for (i = 0; i < SDL_arraysize(buttons); i++) {
                 updateplayerindex |= (joystick->buttons[i] != buttons[i]);
                 SDL_PrivateJoystickButton(joystick, i, buttons[i]);
             }
         }
-        /* TODO: Handle micro profiles on tvOS. */
+#if TARGET_OS_TV
+        else if (controller.microGamepad) {
+            GCMicroGamepad *gamepad = controller.microGamepad;
+
+            Sint16 axes[] = {
+                (Sint16) (gamepad.dpad.xAxis.value * 32767),
+                (Sint16) (gamepad.dpad.yAxis.value * -32767),
+            };
+
+            for (i = 0; i < SDL_arraysize(axes); i++) {
+                updateplayerindex |= (joystick->axes[i] != axes[i]);
+                SDL_PrivateJoystickAxis(joystick, i, axes[i]);
+            }
+
+            /* Apparently the dpad values are not accurate enough to be useful. */
+            /* hatstate = SDL_SYS_MFIJoystickHatStateForDPad(gamepad.dpad); */
+
+            Uint8 buttons[] = {
+                gamepad.buttonA.isPressed,
+                gamepad.buttonX.isPressed,
+            };
+
+            for (i = 0; i < SDL_arraysize(buttons); i++) {
+                updateplayerindex |= (joystick->buttons[i] != buttons[i]);
+                SDL_PrivateJoystickButton(joystick, i, buttons[i]);
+            }
+
+            /* TODO: Figure out what to do with reportsAbsoluteDpadValues */
+        }
+#endif /* TARGET_OS_TV */
 
         if (joystick->nhats > 0) {
             updateplayerindex |= (joystick->hats[0] != hatstate);
@@ -528,7 +589,7 @@ SDL_SYS_MFIJoystickUpdate(SDL_Joystick * joystick)
             }
         }
     }
-#endif
+#endif /* SDL_JOYSTICK_MFI */
 }
 
 /* Function to update the state of a joystick - called as a device poll.
@@ -566,7 +627,9 @@ SDL_SYS_JoystickClose(SDL_Joystick * joystick)
 
     @autoreleasepool {
         if (device->accelerometer) {
+#if !TARGET_OS_TV
             [motionManager stopAccelerometerUpdates];
+#endif /* !TARGET_OS_TV */
         } else if (device->controller) {
 #ifdef SDL_JOYSTICK_MFI
             GCController *controller = device->controller;
@@ -600,7 +663,9 @@ SDL_SYS_JoystickQuit(void)
             SDL_SYS_RemoveJoystickDevice(deviceList);
         }
 
+#if !TARGET_OS_TV
         motionManager = nil;
+#endif /* !TARGET_OS_TV */
     }
 
     numjoysticks = 0;

+ 16 - 1
src/power/uikit/SDL_syspower.m

@@ -30,6 +30,7 @@
 #include "SDL_assert.h"
 #include "SDL_syspower.h"
 
+#if !TARGET_OS_TV
 /* turn off the battery monitor if it's been more than X ms since last check. */
 static const int BATTERY_MONITORING_TIMEOUT = 3000;
 static Uint32 SDL_UIKitLastPowerInfoQuery = 0;
@@ -46,10 +47,22 @@ SDL_UIKit_UpdateBatteryMonitoring(void)
         }
     }
 }
+#else
+void
+SDL_UIKit_UpdateBatteryMonitoring(void)
+{
+    /* Do nothing. */
+}
+#endif /* !TARGET_OS_TV */
 
 SDL_bool
 SDL_GetPowerInfo_UIKit(SDL_PowerState * state, int *seconds, int *percent)
 {
+#if TARGET_OS_TV
+    *state = SDL_POWERSTATE_NO_BATTERY;
+    *seconds = -1;
+    *percent = -1;
+#else /* TARGET_OS_TV */
     @autoreleasepool {
         UIDevice *uidev = [UIDevice currentDevice];
 
@@ -88,8 +101,10 @@ SDL_GetPowerInfo_UIKit(SDL_PowerState * state, int *seconds, int *percent)
 
         const float level = uidev.batteryLevel;
         *percent = ( (level < 0.0f) ? -1 : ((int) ((level * 100) + 0.5f)) );
-        return SDL_TRUE; /* always the definitive answer on iOS. */
     }
+#endif /* TARGET_OS_TV */
+
+    return SDL_TRUE; /* always the definitive answer on iOS. */
 }
 
 #endif /* SDL_POWER_UIKIT */

+ 1 - 1
src/render/software/SDL_rotate.c

@@ -343,7 +343,7 @@ SDLgfx_rotateSurface(SDL_Surface * src, double angle, int centerx, int centery,
     SDL_Surface *rz_dst;
     int is32bit;
     int i;
-    Uint8 r,g,b;
+    Uint8 r = 0,g = 0,b = 0;
     Uint32 colorkey = 0;
     int colorKeyAvailable = 0;
     double sangleinv, cangleinv;

+ 0 - 1
src/video/uikit/SDL_uikitappdelegate.h

@@ -25,7 +25,6 @@
 
 - (instancetype)init;
 - (void)loadView;
-- (NSUInteger)supportedInterfaceOrientations;
 
 @end
 

+ 18 - 0
src/video/uikit/SDL_uikitappdelegate.m

@@ -76,6 +76,7 @@ SDL_IdleTimerDisabledChanged(void *userdata, const char *name, const char *oldVa
     [UIApplication sharedApplication].idleTimerDisabled = disable;
 }
 
+#if !TARGET_OS_TV
 /* Load a launch image using the old UILaunchImageFile-era naming rules. */
 static UIImage *
 SDL_LoadLaunchImageNamed(NSString *name, int screenh)
@@ -114,6 +115,15 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh)
 
     return image;
 }
+#endif /* !TARGET_OS_TV */
+
+@interface SDLLaunchScreenController ()
+
+#if !TARGET_OS_TV
+- (NSUInteger)supportedInterfaceOrientations;
+#endif
+
+@end
 
 @implementation SDLLaunchScreenController
 
@@ -140,6 +150,7 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh)
     }
 
     if (!self.view) {
+#if !TARGET_OS_TV
         NSArray *launchimages = [bundle objectForInfoDictionaryKey:@"UILaunchImages"];
         UIInterfaceOrientation curorient = [UIApplication sharedApplication].statusBarOrientation;
         NSString *imagename = nil;
@@ -244,6 +255,9 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh)
 
             self.view = view;
         }
+#else /* !TARGET_OS_TV */
+        return nil;
+#endif
     }
 
     return self;
@@ -254,6 +268,7 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh)
     /* Do nothing. */
 }
 
+#if !TARGET_OS_TV
 - (BOOL)shouldAutorotate
 {
     /* If YES, the launch image will be incorrectly rotated in some cases. */
@@ -267,6 +282,7 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh)
      * the ones set here (it will cause an exception in that case.) */
     return UIInterfaceOrientationMaskAll;
 }
+#endif /* !TARGET_OS_TV */
 
 @end
 
@@ -381,6 +397,7 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh)
     SDL_SendAppEvent(SDL_APP_LOWMEMORY);
 }
 
+#if !TARGET_OS_TV
 - (void)application:(UIApplication *)application didChangeStatusBarOrientation:(UIInterfaceOrientation)oldStatusBarOrientation
 {
     BOOL isLandscape = UIInterfaceOrientationIsLandscape(application.statusBarOrientation);
@@ -408,6 +425,7 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh)
         }
     }
 }
+#endif
 
 - (void)applicationWillResignActive:(UIApplication*)application
 {

+ 12 - 0
src/video/uikit/SDL_uikitclipboard.m

@@ -30,15 +30,22 @@
 int
 UIKit_SetClipboardText(_THIS, const char *text)
 {
+#if TARGET_OS_TV
+    return SDL_SetError("The clipboard is not available on tvOS");
+#else
     @autoreleasepool {
         [UIPasteboard generalPasteboard].string = @(text);
         return 0;
     }
+#endif
 }
 
 char *
 UIKit_GetClipboardText(_THIS)
 {
+#if TARGET_OS_TV
+    return SDL_strdup(""); // Unsupported.
+#else
     @autoreleasepool {
         UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
         NSString *string = pasteboard.string;
@@ -49,15 +56,18 @@ UIKit_GetClipboardText(_THIS)
             return SDL_strdup("");
         }
     }
+#endif
 }
 
 SDL_bool
 UIKit_HasClipboardText(_THIS)
 {
     @autoreleasepool {
+#if !TARGET_OS_TV
         if ([UIPasteboard generalPasteboard].string != nil) {
             return SDL_TRUE;
         }
+#endif
         return SDL_FALSE;
     }
 }
@@ -65,6 +75,7 @@ UIKit_HasClipboardText(_THIS)
 void
 UIKit_InitClipboard(_THIS)
 {
+#if !TARGET_OS_TV
     @autoreleasepool {
         SDL_VideoData *data = (__bridge SDL_VideoData *) _this->driverdata;
         NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
@@ -78,6 +89,7 @@ UIKit_InitClipboard(_THIS)
 
         data.pasteboardObserver = observer;
     }
+#endif
 }
 
 void

+ 38 - 15
src/video/uikit/SDL_uikitmodes.m

@@ -156,9 +156,12 @@ UIKit_AddDisplay(UIScreen *uiscreen)
 SDL_bool
 UIKit_IsDisplayLandscape(UIScreen *uiscreen)
 {
+#if !TARGET_OS_TV
     if (uiscreen == [UIScreen mainScreen]) {
         return UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation);
-    } else {
+    } else
+#endif /* !TARGET_OS_TV */
+    {
         CGSize size = uiscreen.bounds.size;
         return (size.width > size.height);
     }
@@ -187,6 +190,14 @@ UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
         SDL_bool isLandscape = UIKit_IsDisplayLandscape(data.uiscreen);
         SDL_bool addRotation = (data.uiscreen == [UIScreen mainScreen]);
         CGFloat scale = data.uiscreen.scale;
+        NSArray *availableModes = nil;
+
+#if TARGET_OS_TV
+        addRotation = SDL_FALSE;
+        availableModes = @[data.uiscreen.currentMode];
+#else
+        availableModes = data.uiscreen.availableModes;
+#endif
 
 #ifdef __IPHONE_8_0
         /* The UIScreenMode of an iPhone 6 Plus should be 1080x1920 rather than
@@ -196,7 +207,7 @@ UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
         }
 #endif
 
-        for (UIScreenMode *uimode in data.uiscreen.availableModes) {
+        for (UIScreenMode *uimode in availableModes) {
             /* The size of a UIScreenMode is in pixels, but we deal exclusively
              * in points (except in SDL_GL_GetDrawableSize.) */
             int w = (int)(uimode.size.width / scale);
@@ -219,9 +230,11 @@ UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
 {
     @autoreleasepool {
         SDL_DisplayData *data = (__bridge SDL_DisplayData *) display->driverdata;
-        SDL_DisplayModeData *modedata = (__bridge SDL_DisplayModeData *)mode->driverdata;
 
+#if !TARGET_OS_TV
+        SDL_DisplayModeData *modedata = (__bridge SDL_DisplayModeData *)mode->driverdata;
         [data.uiscreen setCurrentMode:modedata.uiscreenmode];
+#endif
 
         if (data.uiscreen == [UIScreen mainScreen]) {
             /* [UIApplication setStatusBarOrientation:] no longer works reliably
@@ -245,20 +258,30 @@ UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
 int
 UIKit_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect)
 {
-    /* the default function iterates displays to make a fake offset,
-       as if all the displays were side-by-side, which is fine for iOS. */
-    const int displayIndex = (int) (display - _this->displays);
-    if (SDL_GetDisplayBounds(displayIndex, rect) < 0) {
-        return -1;
+    @autoreleasepool {
+        int displayIndex = (int) (display - _this->displays);
+        SDL_DisplayData *data = (__bridge SDL_DisplayData *) display->driverdata;
+
+        /* the default function iterates displays to make a fake offset,
+         as if all the displays were side-by-side, which is fine for iOS. */
+        if (SDL_GetDisplayBounds(displayIndex, rect) < 0) {
+            return -1;
+        }
+
+        CGRect frame = data.uiscreen.bounds;
+
+#if !TARGET_OS_TV
+        if (!UIKit_IsSystemVersionAtLeast(7.0)) {
+            frame = [data.uiscreen applicationFrame];
+        }
+#endif
+
+        rect->x += frame.origin.x;
+        rect->y += frame.origin.y;
+        rect->w = frame.size.width;
+        rect->h = frame.size.height;
     }
 
-    SDL_DisplayData *data = (__bridge SDL_DisplayData *) display->driverdata;
-    const CGRect frame = [data.uiscreen applicationFrame];
-    const float scale = (float) data.uiscreen.scale;
-    rect->x += (int) (frame.origin.x * scale);
-    rect->y += (int) (frame.origin.y * scale);
-    rect->w = (int) (frame.size.width * scale);
-    rect->h = (int) (frame.size.height * scale);
     return 0;
 }
 

+ 4 - 0
src/video/uikit/SDL_uikitvideo.m

@@ -176,6 +176,7 @@ UIKit_IsSystemVersionAtLeast(double version)
 CGRect
 UIKit_ComputeViewFrame(SDL_Window *window, UIScreen *screen)
 {
+#if !TARGET_OS_TV && (__IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_7_0)
     BOOL hasiOS7 = UIKit_IsSystemVersionAtLeast(7.0);
 
     if (hasiOS7 || (window->flags & (SDL_WINDOW_BORDERLESS|SDL_WINDOW_FULLSCREEN))) {
@@ -184,6 +185,9 @@ UIKit_ComputeViewFrame(SDL_Window *window, UIScreen *screen)
     } else {
         return screen.applicationFrame;
     }
+#else
+    return screen.bounds;
+#endif
 }
 
 /*

+ 65 - 0
src/video/uikit/SDL_uikitview.m

@@ -45,7 +45,9 @@
         self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
         self.autoresizesSubviews = YES;
 
+#if !TARGET_OS_TV
         self.multipleTouchEnabled = YES;
+#endif
 
         touchId = 1;
         SDL_AddTouch(touchId, "");
@@ -197,6 +199,69 @@
     }
 }
 
+#if TARGET_OS_TV || defined(__IPHONE_9_1)
+- (SDL_Scancode)scancodeFromPressType:(UIPressType)presstype
+{
+    switch (presstype) {
+    case UIPressTypeUpArrow:
+        return SDL_SCANCODE_UP;
+    case UIPressTypeDownArrow:
+        return SDL_SCANCODE_DOWN;
+    case UIPressTypeLeftArrow:
+        return SDL_SCANCODE_LEFT;
+    case UIPressTypeRightArrow:
+        return SDL_SCANCODE_RIGHT;
+    case UIPressTypeSelect:
+        /* HIG says: "primary button behavior" */
+        return SDL_SCANCODE_SELECT;
+    case UIPressTypeMenu:
+        /* HIG says: "returns to previous screen" */
+        return SDL_SCANCODE_MENU;
+    case UIPressTypePlayPause:
+        /* HIG says: "secondary button behavior" */
+        return SDL_SCANCODE_PAUSE;
+    default:
+        return SDL_SCANCODE_UNKNOWN;
+    }
+}
+
+- (void)pressesBegan:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event
+{
+    for (UIPress *press in presses) {
+        SDL_Scancode scancode = [self scancodeFromPressType:press.type];
+        SDL_SendKeyboardKey(SDL_PRESSED, scancode);
+    }
+
+    [super pressesBegan:presses withEvent:event];
+}
+
+- (void)pressesEnded:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event
+{
+    for (UIPress *press in presses) {
+        SDL_Scancode scancode = [self scancodeFromPressType:press.type];
+        SDL_SendKeyboardKey(SDL_RELEASED, scancode);
+    }
+
+    [super pressesEnded:presses withEvent:event];
+}
+
+- (void)pressesCancelled:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event
+{
+    for (UIPress *press in presses) {
+        SDL_Scancode scancode = [self scancodeFromPressType:press.type];
+        SDL_SendKeyboardKey(SDL_RELEASED, scancode);
+    }
+
+    [super pressesCancelled:presses withEvent:event];
+}
+
+- (void)pressesChanged:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event
+{
+    /* This is only called when the force of a press changes. */
+    [super pressesChanged:presses withEvent:event];
+}
+#endif /* TARGET_OS_TV || defined(__IPHONE_9_1) */
+
 @end
 
 #endif /* SDL_VIDEO_DRIVER_UIKIT */

+ 13 - 2
src/video/uikit/SDL_uikitviewcontroller.h

@@ -18,6 +18,7 @@
      misrepresented as being the original software.
   3. This notice may not be removed or altered from any source distribution.
 */
+#include "../../SDL_internal.h"
 
 #import <UIKit/UIKit.h>
 
@@ -25,10 +26,17 @@
 
 #include "SDL_touch.h"
 
+#if TARGET_OS_TV
+#import <GameController/GameController.h>
+#define SDLRootViewController GCEventViewController
+#else
+#define SDLRootViewController UIViewController
+#endif
+
 #if SDL_IPHONE_KEYBOARD
-@interface SDL_uikitviewcontroller : UIViewController <UITextFieldDelegate>
+@interface SDL_uikitviewcontroller : SDLRootViewController <UITextFieldDelegate>
 #else
-@interface SDL_uikitviewcontroller : UIViewController
+@interface SDL_uikitviewcontroller : SDLRootViewController
 #endif
 
 @property (nonatomic, assign) SDL_Window *window;
@@ -46,8 +54,11 @@
 
 - (void)loadView;
 - (void)viewDidLayoutSubviews;
+
+#if !TARGET_OS_TV
 - (NSUInteger)supportedInterfaceOrientations;
 - (BOOL)prefersStatusBarHidden;
+#endif
 
 #if SDL_IPHONE_KEYBOARD
 - (void)showKeyboard;

+ 31 - 0
src/video/uikit/SDL_uikitviewcontroller.m

@@ -39,6 +39,17 @@
 #include "keyinfotable.h"
 #endif
 
+#if TARGET_OS_TV
+static void
+SDL_AppleTVControllerUIHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
+{
+    @autoreleasepool {
+        SDL_uikitviewcontroller *viewcontroller = (__bridge SDL_uikitviewcontroller *) userdata;
+        viewcontroller.controllerUserInteractionEnabled = hint && (*hint != '0');
+    }
+}
+#endif
+
 @implementation SDL_uikitviewcontroller {
     CADisplayLink *displayLink;
     int animationInterval;
@@ -60,6 +71,12 @@
 #if SDL_IPHONE_KEYBOARD
         [self initKeyboard];
 #endif
+
+#if TARGET_OS_TV
+        SDL_AddHintCallback(SDL_HINT_APPLE_TV_CONTROLLER_UI_EVENTS,
+                            SDL_AppleTVControllerUIHintChanged,
+                            (__bridge void *) self);
+#endif
     }
     return self;
 }
@@ -69,6 +86,12 @@
 #if SDL_IPHONE_KEYBOARD
     [self deinitKeyboard];
 #endif
+
+#if TARGET_OS_TV
+    SDL_DelHintCallback(SDL_HINT_APPLE_TV_CONTROLLER_UI_EVENTS,
+                        SDL_AppleTVControllerUIHintChanged,
+                        (__bridge void *) self);
+#endif
 }
 
 - (void)setAnimationCallback:(int)interval
@@ -124,6 +147,7 @@
     SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, w, h);
 }
 
+#if !TARGET_OS_TV
 - (NSUInteger)supportedInterfaceOrientations
 {
     return UIKit_GetSupportedOrientations(window);
@@ -138,6 +162,7 @@
 {
     return (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) != 0;
 }
+#endif
 
 /*
  ---- Keyboard related functionality below this line ----
@@ -168,9 +193,11 @@
     textField.hidden = YES;
     keyboardVisible = NO;
 
+#if !TARGET_OS_TV
     NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
     [center addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
     [center addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
+#endif
 }
 
 - (void)setView:(UIView *)view
@@ -186,9 +213,11 @@
 
 - (void)deinitKeyboard
 {
+#if !TARGET_OS_TV
     NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
     [center removeObserver:self name:UIKeyboardWillShowNotification object:nil];
     [center removeObserver:self name:UIKeyboardWillHideNotification object:nil];
+#endif
 }
 
 /* reveal onscreen virtual keyboard */
@@ -209,6 +238,7 @@
 
 - (void)keyboardWillShow:(NSNotification *)notification
 {
+#if !TARGET_OS_TV
     CGRect kbrect = [[notification userInfo][UIKeyboardFrameBeginUserInfoKey] CGRectValue];
 
     /* The keyboard rect is in the coordinate space of the screen/window, but we
@@ -216,6 +246,7 @@
     kbrect = [self.view convertRect:kbrect fromView:nil];
 
     [self setKeyboardHeight:(int)kbrect.size.height];
+#endif
 }
 
 - (void)keyboardWillHide:(NSNotification *)notification

+ 9 - 1
src/video/uikit/SDL_uikitwindow.m

@@ -107,6 +107,7 @@ static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bo
         window->flags |= SDL_WINDOW_BORDERLESS;  /* never has a status bar. */
     }
 
+#if !TARGET_OS_TV
     if (displaydata.uiscreen == [UIScreen mainScreen]) {
         NSUInteger orients = UIKit_GetSupportedOrientations(window);
         BOOL supportsLandscape = (orients & UIInterfaceOrientationMaskLandscape) != 0;
@@ -119,6 +120,7 @@ static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bo
             height = temp;
         }
     }
+#endif /* !TARGET_OS_TV */
 
     window->x = 0;
     window->y = 0;
@@ -152,7 +154,6 @@ UIKit_CreateWindow(_THIS, SDL_Window *window)
     @autoreleasepool {
         SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
         SDL_DisplayData *data = (__bridge SDL_DisplayData *) display->driverdata;
-        const CGSize origsize = data.uiscreen.currentMode.size;
 
         /* SDL currently puts this window at the start of display's linked list. We rely on this. */
         SDL_assert(_this->windows == window);
@@ -165,6 +166,8 @@ UIKit_CreateWindow(_THIS, SDL_Window *window)
         /* If monitor has a resolution of 0x0 (hasn't been explicitly set by the
          * user, so it's in standby), try to force the display to a resolution
          * that most closely matches the desired window size. */
+#if !TARGET_OS_TV
+        const CGSize origsize = data.uiscreen.currentMode.size;
         if ((origsize.width == 0.0f) && (origsize.height == 0.0f)) {
             if (display->num_display_modes == 0) {
                 _this->GetDisplayModes(_this, display);
@@ -197,6 +200,7 @@ UIKit_CreateWindow(_THIS, SDL_Window *window)
                 [UIApplication sharedApplication].statusBarHidden = NO;
             }
         }
+#endif /* !TARGET_OS_TV */
 
         /* ignore the size user requested, and make a fullscreen window */
         /* !!! FIXME: can we have a smaller view? */
@@ -258,6 +262,7 @@ UIKit_UpdateWindowBorder(_THIS, SDL_Window * window)
     SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
     SDL_uikitviewcontroller *viewcontroller = data.viewcontroller;
 
+#if !TARGET_OS_TV
     if (data.uiwindow.screen == [UIScreen mainScreen]) {
         if (window->flags & (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_BORDERLESS)) {
             [UIApplication sharedApplication].statusBarHidden = YES;
@@ -273,6 +278,7 @@ UIKit_UpdateWindowBorder(_THIS, SDL_Window * window)
 
     /* Update the view's frame to account for the status bar change. */
     viewcontroller.view.frame = UIKit_ComputeViewFrame(window, data.uiwindow.screen);
+#endif /* !TARGET_OS_TV */
 
 #ifdef SDL_IPHONE_KEYBOARD
     /* Make sure the view is offset correctly when the keyboard is visible. */
@@ -363,6 +369,7 @@ UIKit_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
     }
 }
 
+#if !TARGET_OS_TV
 NSUInteger
 UIKit_GetSupportedOrientations(SDL_Window * window)
 {
@@ -428,6 +435,7 @@ UIKit_GetSupportedOrientations(SDL_Window * window)
 
     return orientationMask;
 }
+#endif /* !TARGET_OS_TV */
 
 int
 SDL_iPhoneSetAnimationCallback(SDL_Window * window, int interval, void (*callback)(void*), void *callbackParam)