diff --git a/docs/ImportAll.hx b/docs/ImportAll.hx index fc6d74c8e..d653a9640 100644 --- a/docs/ImportAll.hx +++ b/docs/ImportAll.hx @@ -178,6 +178,7 @@ import lime.tools.platforms.IOSPlatform; import lime.tools.platforms.LinuxPlatform; import lime.tools.platforms.MacPlatform; import lime.tools.platforms.TizenPlatform; +import lime.tools.platforms.TVOSPlatform; import lime.tools.platforms.WebOSPlatform; import lime.tools.platforms.WindowsPlatform; #end diff --git a/include.xml b/include.xml index b01a1cddb..0b55bb24f 100644 --- a/include.xml +++ b/include.xml @@ -51,7 +51,7 @@ - + diff --git a/lime/_backend/native/NativeApplication.hx b/lime/_backend/native/NativeApplication.hx index b0b423af7..271c84868 100644 --- a/lime/_backend/native/NativeApplication.hx +++ b/lime/_backend/native/NativeApplication.hx @@ -60,7 +60,7 @@ class NativeApplication { AudioManager.init (); - #if (ios || android) + #if (ios || android || tvos) Sensor.registerSensor (SensorType.ACCELEROMETER, 0); #end @@ -89,7 +89,7 @@ class NativeApplication { lime_touch_event_manager_register (handleTouchEvent, touchEventInfo); lime_window_event_manager_register (handleWindowEvent, windowEventInfo); - #if (ios || android) + #if (ios || android || tvos) lime_sensor_event_manager_register (handleSensorEvent, sensorEventInfo); #end diff --git a/lime/project/HXProject.hx b/lime/project/HXProject.hx index 9e4ba8381..fe54b1afb 100644 --- a/lime/project/HXProject.hx +++ b/lime/project/HXProject.hx @@ -138,7 +138,7 @@ class HXProject { defaultWindow.height = 0; defaultWindow.fps = 60; - case ANDROID, BLACKBERRY, IOS, TIZEN, WEBOS: + case ANDROID, BLACKBERRY, IOS, TIZEN, WEBOS, TVOS: platformType = PlatformType.MOBILE; @@ -158,6 +158,8 @@ class HXProject { } + } else if (target == Platform.TVOS) { + architectures = [ Architecture.ARM64 ]; } else { architectures = [ Architecture.ARMV6 ]; diff --git a/lime/project/Platform.hx b/lime/project/Platform.hx index 1fae49ac0..48ee6172f 100644 --- a/lime/project/Platform.hx +++ b/lime/project/Platform.hx @@ -21,6 +21,7 @@ package lime.project; var WIIU = "wiiu"; var XBOX1 = "xbox1"; var EMSCRIPTEN = "emscripten"; + var TVOS = "tvos"; var CUSTOM = null; } diff --git a/lime/project/ProjectXMLParser.hx b/lime/project/ProjectXMLParser.hx index 1b0d6cd66..83895c59b 100644 --- a/lime/project/ProjectXMLParser.hx +++ b/lime/project/ProjectXMLParser.hx @@ -1580,6 +1580,59 @@ class ProjectXMLParser extends HXProject { } } + + case "tvos": + + if (target == Platform.TVOS) { + + if (element.has.deployment) { + + var deployment = Std.parseFloat (substitute (element.att.deployment)); + + // If it is specified, assume the dev knows what he is doing! + config.set ("tvos.deployment", deployment); + } + + if (element.has.binaries) { + + var binaries = substitute (element.att.binaries); + + switch (binaries) { + + case "arm64": + + ArrayHelper.addUnique (architectures, Architecture.ARM64); + + } + + } + + if (element.has.devices) { + + config.set ("tvos.device", substitute (element.att.devices).toLowerCase ()); + + } + + if (element.has.compiler) { + + config.set ("tvos.compiler", substitute (element.att.compiler)); + + } + + if (element.has.resolve ("prerendered-icon")) { + + config.set ("tvos.prerenderedIcon", substitute (element.att.resolve ("prerendered-icon"))); + + } + + if (element.has.resolve ("linker-flags")) { + + config.push ("tvos.linker-flags", substitute (element.att.resolve ("linker-flags"))); + //config.ios.linkerFlags.push (substitute (element.att.resolve ("linker-flags"))); + + } + + } case "config": diff --git a/lime/system/CFFI.hx b/lime/system/CFFI.hx index be82e8451..018bbd628 100644 --- a/lime/system/CFFI.hx +++ b/lime/system/CFFI.hx @@ -91,7 +91,7 @@ class CFFI { } else { - #if (iphone || emscripten || android || static_link) + #if (iphone || emscripten || android || static_link || tvos) return cpp.Lib.load (library, method, args); #end diff --git a/lime/tools/helpers/TVOSHelper.hx b/lime/tools/helpers/TVOSHelper.hx new file mode 100644 index 000000000..ae6caa49a --- /dev/null +++ b/lime/tools/helpers/TVOSHelper.hx @@ -0,0 +1,329 @@ +package lime.tools.helpers; + + +import haxe.io.Path; +import lime.tools.helpers.PathHelper; +import lime.tools.helpers.ProcessHelper; +import lime.project.Haxelib; +import lime.project.HXProject; +import sys.io.Process; +import sys.FileSystem; + + +class TVOSHelper { + + + private static var initialized = false; + + + public static function build (project:HXProject, workingDirectory:String, additionalArguments:Array = null):Void { + + initialize (project); + + var platformName = "appletvos"; + + if (project.targetFlags.exists ("simulator")) { + + platformName = "appletvsimulator"; + + } + + var configuration = "Release"; + + if (project.debug) { + + configuration = "Debug"; + + } + + var iphoneVersion = project.environment.get ("TVOS_VER"); + var commands = [ "-configuration", configuration, "PLATFORM_NAME=" + platformName, "SDKROOT=" + platformName + iphoneVersion ]; + + if (project.targetFlags.exists("simulator")) { + + commands.push ("-arch"); + commands.push ("i386"); + + } + + if (additionalArguments != null) { + + commands = commands.concat (additionalArguments); + + } + + ProcessHelper.runCommand (workingDirectory, "xcodebuild", commands); + + } + + + public static function getSDKDirectory (project:HXProject):String { + + initialize (project); + + var platformName = "AppleTVOS"; + + if (project.targetFlags.exists ("simulator")) { + + platformName = "AppleTVSimulator"; + + } + + var process = new Process ("xcode-select", [ "--print-path" ]); + var directory = process.stdout.readLine (); + process.close (); + + if (directory == "" || directory.indexOf ("Run xcode-select") > -1) { + + directory = "/Applications/Xcode.app/Contents/Developer"; + + } + + directory += "/Platforms/" + platformName + ".platform/Developer/SDKs/" + platformName + project.environment.get ("TVOS_VER") + ".sdk"; + LogHelper.info(directory); + return directory; + + } + + + private static function getIOSVersion (project:HXProject):Void { + + if (!project.environment.exists("TVOS_VER")) { + if (!project.environment.exists("DEVELOPER_DIR")) { + var proc = new Process("xcode-select", ["--print-path"]); + var developer_dir = proc.stdout.readLine(); + proc.close(); + project.environment.set("DEVELOPER_DIR", developer_dir); + } + var dev_path = project.environment.get("DEVELOPER_DIR") + "/Platforms/AppleTVOS.platform/Developer/SDKs"; + + if (FileSystem.exists (dev_path)) { + var best = ""; + var files = FileSystem.readDirectory (dev_path); + var extract_version = ~/^AppleTVOS(.*).sdk$/; + + for (file in files) { + if (extract_version.match (file)) { + var ver = extract_version.matched (1); + if (ver > best) + best = ver; + } + } + + if (best != "") + project.environment.set ("TVOS_VER", best); + } + } + + } + + + private static function getOSXVersion ():String { + + var output = ProcessHelper.runProcess ("", "sw_vers", [ "-productVersion" ]); + + return StringTools.trim (output); + + } + + + public static function getProvisioningFile ():String { + + var path = PathHelper.expand ("~/Library/MobileDevice/Provisioning Profiles"); + var files = FileSystem.readDirectory (path); + + for (file in files) { + + if (Path.extension (file) == "mobileprovision") { + + return path + "/" + file; + + } + + } + + return ""; + + } + + + private static function getXcodeVersion ():String { + + var output = ProcessHelper.runProcess ("", "xcodebuild", [ "-version" ]); + var firstLine = output.split ("\n").shift (); + + return StringTools.trim (firstLine.substring ("Xcode".length, firstLine.length)); + + } + + + private static function initialize (project:HXProject):Void { + + if (!initialized) { + + getIOSVersion (project); + + initialized = true; + + } + + } + + + public static function launch (project:HXProject, workingDirectory:String):Void { + + initialize (project); + + var configuration = "Release"; + + if (project.debug) { + + configuration = "Debug"; + + } + + if (project.targetFlags.exists ("simulator")) { + + var applicationPath = ""; + + if (Path.extension (workingDirectory) == "app" || Path.extension (workingDirectory) == "ipa") { + + applicationPath = workingDirectory; + + } else { + + applicationPath = workingDirectory + "/build/" + configuration + "-appletvsimulator/" + project.app.file + ".app"; + + } + + var templatePaths = [ PathHelper.combine (PathHelper.getHaxelib (new Haxelib ("lime")), "templates") ].concat (project.templatePaths); + var launcher = PathHelper.findTemplate (templatePaths, "bin/ios-sim"); + Sys.command ("chmod", [ "+x", launcher ]); + + // device config + var defaultDevice = "appletv"; + var devices:Array = ["appletv", "iphone-4s", "iphone-5", "iphone-5s", "iphone-6-plus", "iphone-6", "ipad-2", "ipad-retina", "ipad-air"]; + var oldDevices:Map = ["iphone" => "iphone-6", "ipad" => "ipad-air"]; + + var deviceFlag:String = null; + var deviceTypeID = null; + + // check if old device flag and convert to current + for (key in oldDevices.keys()) + { + if (project.targetFlags.exists(key)) + { + deviceFlag = oldDevices[key]; + break; + } + } + + // check known device in command line args + if(deviceFlag == null) + { + for( i in 0...devices.length ) + { + if (project.targetFlags.exists(devices[i])) + { + deviceFlag = devices[i]; + break; + } + } + } + + // default to iphone 6 + if(deviceFlag == null) + deviceFlag = defaultDevice; + + // check if device is available + // $ ios-sim showdevicetypes + var devicesOutput:String = ProcessHelper.runProcess ("", launcher, [ "showdevicetypes" ] ); + var deviceTypeList:Array = devicesOutput.split("\n"); + + for ( i in 0...deviceTypeList.length ) + { + var r:EReg = new EReg(deviceFlag+",", "i"); + if(r.match(deviceTypeList[i])) + { + deviceTypeID = deviceTypeList[i]; + break; + } + } + + if(deviceTypeID == null) + LogHelper.warn("Device \""+deviceFlag+"\" was not found"); + else + LogHelper.info("Launch app on \""+deviceTypeID+"\""); + + + // run command with --devicetypeid if exists + if(deviceTypeID != null) + ProcessHelper.runCommand ("", launcher, [ "launch", FileSystem.fullPath (applicationPath), /*"--sdk", project.environment.get ("IPHONE_VER"),*/ "--devicetypeid", deviceTypeID, "--timeout", "60" ] ); + else + ProcessHelper.runCommand ("", launcher, [ "launch", FileSystem.fullPath (applicationPath), /*"--sdk", project.environment.get ("IPHONE_VER"), "--devicetypeid", deviceTypeID,*/ "--timeout", "60" ] ); + + } else { + + var applicationPath = ""; + + if (Path.extension (workingDirectory) == "app" || Path.extension (workingDirectory) == "ipa") { + + applicationPath = workingDirectory; + + } else { + + applicationPath = workingDirectory + "/build/" + configuration + "-appletvos/" + project.app.file + ".app"; + + } + + var templatePaths = [ PathHelper.combine (PathHelper.getHaxelib (new Haxelib ("lime")), "templates") ].concat (project.templatePaths); + var launcher = PathHelper.findTemplate (templatePaths, "bin/ios-deploy"); + Sys.command ("chmod", [ "+x", launcher ]); + + var xcodeVersion = getXcodeVersion (); + + ProcessHelper.runCommand ("", launcher, [ "install", "--noninteractive", "--debug", "--timeout", "5", "--bundle", FileSystem.fullPath (applicationPath) ]); + + } + + } + + + public static function sign (project:HXProject, workingDirectory:String, entitlementsPath:String):Void { + + initialize (project); + + var configuration = "Release"; + + if (project.debug) { + + configuration = "Debug"; + + } + + var identity = "iPhone Developer"; + + if (project.certificate != null && project.certificate.identity != null) { + + identity = project.certificate.identity; + + } + + var commands = [ "-s", identity ]; + + if (entitlementsPath != null) { + + commands.push ("--entitlements"); + commands.push (entitlementsPath); + + } + + var applicationPath = "build/" + configuration + "-appletvos/" + project.app.file + ".app"; + commands.push (applicationPath); + + ProcessHelper.runCommand (workingDirectory, "codesign", commands, true, true); + + } + + +} diff --git a/lime/tools/platforms/MacPlatform.hx b/lime/tools/platforms/MacPlatform.hx index 6efd5b212..171a94a6e 100644 --- a/lime/tools/platforms/MacPlatform.hx +++ b/lime/tools/platforms/MacPlatform.hx @@ -238,6 +238,12 @@ class MacPlatform extends PlatformTarget { commands.push ([ "-Dmac", "-DHXCPP_M32" ]); } + + if (targetFlags.exists("tvos")) { + + commands.push ([ "-Dtvos", "-Dtoolchain=appletvos", "-DBINDIR=AppleTV" ]); + + } CPPHelper.rebuild (project, commands); diff --git a/lime/tools/platforms/TVOSPlatform.hx b/lime/tools/platforms/TVOSPlatform.hx new file mode 100644 index 000000000..4c51a9bb4 --- /dev/null +++ b/lime/tools/platforms/TVOSPlatform.hx @@ -0,0 +1,609 @@ +package lime.tools.platforms; + + +//import openfl.display.BitmapData; +import haxe.io.Path; +import haxe.Json; +import haxe.Template; +import lime.tools.helpers.ArrayHelper; +import lime.tools.helpers.AssetHelper; +import lime.tools.helpers.CPPHelper; +import lime.tools.helpers.DeploymentHelper; +import lime.tools.helpers.FileHelper; +import lime.tools.helpers.IconHelper; +import lime.tools.helpers.TVOSHelper; +import lime.tools.helpers.LogHelper; +import lime.tools.helpers.PathHelper; +import lime.tools.helpers.PlatformHelper; +import lime.tools.helpers.ProcessHelper; +import lime.tools.helpers.StringHelper; +import lime.graphics.Image; +import lime.project.Architecture; +import lime.project.Asset; +import lime.project.AssetType; +import lime.project.Haxelib; +import lime.project.HXProject; +import lime.project.Icon; +import lime.project.Keystore; +import lime.project.NDLL; +import lime.project.Platform; +import lime.project.PlatformTarget; +import sys.io.File; +import sys.FileSystem; + + +class TVOSPlatform extends PlatformTarget { + + + public function new (command:String, _project:HXProject, targetFlags:Map ) { + + super (command, _project, targetFlags); + + targetDirectory = PathHelper.combine (project.app.path, "tvos"); + + } + + + public override function build ():Void { + + if (project.targetFlags.exists ("xcode") && PlatformHelper.hostPlatform == Platform.MAC) { + + ProcessHelper.runCommand ("", "open", [ targetDirectory + "/" + project.app.file + ".xcodeproj" ] ); + + } else { + + TVOSHelper.build (project, targetDirectory); + + if (!project.targetFlags.exists ("simulator")) { + + var entitlements = targetDirectory + "/" + project.app.file + "/" + project.app.file + "-Entitlements.plist"; + TVOSHelper.sign (project, targetDirectory + "/bin", entitlements); + + } + + } + + } + + + public override function clean ():Void { + + if (FileSystem.exists (targetDirectory)) { + + PathHelper.removeDirectory (targetDirectory); + + } + + } + + + public override function deploy ():Void { + + DeploymentHelper.deploy (project, targetFlags, targetDirectory, "tvOS"); + + } + + + public override function display ():Void { + + var hxml = PathHelper.findTemplate (project.templatePaths, "tvos/PROJ/haxe/Build.hxml"); + var template = new Template (File.getContent (hxml)); + + Sys.println (template.execute (generateContext ())); + Sys.println ("-D display"); + + } + + + private function generateContext ():Dynamic { + + project = project.clone (); + + project.sources.unshift (""); + project.sources = PathHelper.relocatePaths (project.sources, PathHelper.combine (targetDirectory, project.app.file + "/haxe")); + //project.dependencies.push ("stdc++"); + + if (project.certificate == null || project.certificate.identity == null) { + + project.certificate = new Keystore (); + project.certificate.identity = "tvOS Developer"; + + } + + if (project.targetFlags.exists ("xml")) { + + project.haxeflags.push ("-xml " + targetDirectory + "/types.xml"); + + } + + if (project.targetFlags.exists ("final")) { + + project.haxedefs.set ("final", ""); + + } + + var context = project.templateContext; + + context.HAS_ICON = false; + context.HAS_LAUNCH_IMAGE = false; + context.OBJC_ARC = false; + + context.linkedLibraries = []; + + for (dependency in project.dependencies) { + + if (!StringTools.endsWith (dependency.name, ".framework") && !StringTools.endsWith (dependency.path, ".framework")) { + + if (dependency.path != "") { + + var name = Path.withoutDirectory (Path.withoutExtension (dependency.path)); + + project.config.push ("tvos.linker-flags", "-force_load $SRCROOT/$PRODUCT_NAME/lib/$CURRENT_ARCH/" + Path.withoutDirectory (dependency.path)); + + if (StringTools.startsWith (name, "lib")) { + + name = name.substring (3, name.length); + + } + + context.linkedLibraries.push (name); + + } else if (dependency.name != "") { + + context.linkedLibraries.push (dependency.name); + + } + + } + + } + + var valid_archs = new Array (); + var arm64 = false; + var architectures = project.architectures; + + if (architectures == null || architectures.length == 0) { + + architectures = [ Architecture.ARM64 ]; + + } + + /*if (project.config.getString ("ios.device", "universal") == "universal" || project.config.getString ("ios.device") == "iphone") { + + if (project.config.getFloat ("ios.deployment", 5.1) < 5) { + + ArrayHelper.addUnique (architectures, Architecture.ARMV6); + + } + + }*/ + + for (architecture in project.architectures) { + + switch (architecture) { + + case ARM64: valid_archs.push ("arm64"); arm64 = true; + default: + + } + + } + + context.CURRENT_ARCHS = "( " + valid_archs.join(",") + ") "; + + valid_archs.push ("i386"); + + context.VALID_ARCHS = valid_archs.join(" "); + context.THUMB_SUPPORT = ""; + + var requiredCapabilities = []; + + requiredCapabilities.push( { name: "arm64", value: true } ); + + context.REQUIRED_CAPABILITY = requiredCapabilities; + context.ARM64 = arm64; + context.TARGET_DEVICES = switch (project.config.getString ("tvos.device", "appletv")) { case "appletv": "3"; default: "3"; } + context.DEPLOYMENT = project.config.getString ("tvos.deployment", "9.0"); + + if (project.config.getString ("tvos.compiler") == "llvm" || project.config.getString ("tvos.compiler", "clang") == "clang") { + + context.OBJC_ARC = true; + + } + + context.ENABLE_BITCODE = project.config.getBool ("tvos.enable-bitcode", false); + context.IOS_COMPILER = project.config.getString ("tvos.compiler", "clang"); + context.CPP_BUILD_LIBRARY = project.config.getString ("cpp.buildLibrary", "hxcpp"); + + var json = Json.parse (File.getContent (PathHelper.getHaxelib (new Haxelib ("hxcpp"), true) + "/haxelib.json")); + + if (Std.parseFloat (json.version) > 3.1) { + + context.CPP_LIBPREFIX = "lib"; + + } else { + + context.CPP_LIBPREFIX = ""; + + } + + context.IOS_LINKER_FLAGS = ["-stdlib=libc++"].concat (project.config.getArrayString ("tvos.linker-flags")); + + switch (project.window.orientation) { + + case PORTRAIT: + context.IOS_APP_ORIENTATION = "UIInterfaceOrientationPortraitUIInterfaceOrientationPortraitUpsideDown"; + case LANDSCAPE: + context.IOS_APP_ORIENTATION = "UIInterfaceOrientationLandscapeLeftUIInterfaceOrientationLandscapeRight"; + case ALL: + context.IOS_APP_ORIENTATION = "UIInterfaceOrientationLandscapeLeftUIInterfaceOrientationLandscapeRightUIInterfaceOrientationPortraitUIInterfaceOrientationPortraitUpsideDown"; + //case "allButUpsideDown": + //context.IOS_APP_ORIENTATION = "UIInterfaceOrientationLandscapeLeftUIInterfaceOrientationLandscapeRightUIInterfaceOrientationPortrait"; + default: + context.IOS_APP_ORIENTATION = "UIInterfaceOrientationLandscapeLeftUIInterfaceOrientationLandscapeRightUIInterfaceOrientationPortraitUIInterfaceOrientationPortraitUpsideDown"; + + } + + context.ADDL_PBX_BUILD_FILE = ""; + context.ADDL_PBX_FILE_REFERENCE = ""; + context.ADDL_PBX_FRAMEWORKS_BUILD_PHASE = ""; + context.ADDL_PBX_FRAMEWORK_GROUP = ""; + + context.frameworkSearchPaths = []; + + for (dependency in project.dependencies) { + + var name = null; + var path = null; + + if (Path.extension (dependency.name) == "framework") { + + name = dependency.name; + path = "/System/Library/Frameworks/" + dependency.name; + + } else if (Path.extension (dependency.path) == "framework") { + + name = Path.withoutDirectory (dependency.path); + path = PathHelper.tryFullPath (dependency.path); + + } + + if (name != null) { + + var frameworkID = "11C0000000000018" + StringHelper.getUniqueID (); + var fileID = "11C0000000000018" + StringHelper.getUniqueID (); + + ArrayHelper.addUnique (context.frameworkSearchPaths, Path.directory (path)); + + context.ADDL_PBX_BUILD_FILE += " " + frameworkID + " /* " + name + " in Frameworks */ = {isa = PBXBuildFile; fileRef = " + fileID + " /* " + name + " */; };\n"; + context.ADDL_PBX_FILE_REFERENCE += " " + fileID + " /* " + name + " */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = \"" + name + "\"; path = \"" + path + "\"; sourceTree = SDKROOT; };\n"; + context.ADDL_PBX_FRAMEWORKS_BUILD_PHASE += " " + frameworkID + " /* " + name + " in Frameworks */,\n"; + context.ADDL_PBX_FRAMEWORK_GROUP += " " + fileID + " /* " + name + " */,\n"; + + } + + } + + context.HXML_PATH = PathHelper.findTemplate (project.templatePaths, "tvos/PROJ/haxe/Build.hxml"); + context.PRERENDERED_ICON = project.config.getBool ("tvos.prerenderedIcon", false); + + /*var assets = new Array (); + + for (asset in project.assets) { + + var newAsset = asset.clone (); + + assets.push (); + + }*/ + + //updateIcon (); + //updateLaunchImage (); + + return context; + + } + + + public override function rebuild ():Void { + + var arm64 = (command == "rebuild" || (project.architectures.indexOf (Architecture.ARM64) > -1 && !project.targetFlags.exists ("simulator"))); + var i386 = (command == "rebuild" || project.targetFlags.exists ("simulator")); + var x86_64 = (command == "rebuild" || project.targetFlags.exists ("simulator")); + + var commands = []; + + if (arm64) commands.push ([ "-Dtvos", "-Dappletvos", "-DHXCPP_CPP11", "-DHXCPP_ARM64" ]); + if (i386) commands.push ([ "-Dtvos", "-Dappletvsim", "-Dsimulator", "-DHXCPP_CPP11" ]); + if (x86_64) commands.push ([ "-Dtvos", "-Dappletvsim", "-Dsimulator", "-DHXCPP_M64", "-DHXCPP_CPP11" ]); + + CPPHelper.rebuild (project, commands); + + } + + + public override function run ():Void { + + if (project.targetFlags.exists ("xcode")) return; + + TVOSHelper.launch (project, targetDirectory); + + } + + + public override function update ():Void { + + project = project.clone (); + + var manifest = new Asset (); + manifest.id = "__manifest__"; + manifest.data = AssetHelper.createManifest (project); + manifest.resourceName = manifest.flatName = manifest.targetPath = "manifest"; + manifest.type = AssetType.TEXT; + project.assets.push (manifest); + + var context = generateContext (); + + var projectDirectory = targetDirectory + "/" + project.app.file + "/"; + + PathHelper.mkdir (targetDirectory); + PathHelper.mkdir (projectDirectory); + PathHelper.mkdir (projectDirectory + "/haxe"); + PathHelper.mkdir (projectDirectory + "/haxe/lime/installer"); + + var iconSizes:Array = [ + { name : "Icon-Small.png", size : 29 }, + { name : "Icon-Small-40.png", size : 40 }, + { name : "Icon-Small-50.png", size : 50 }, + { name : "Icon.png", size : 57 }, + { name : "Icon-Small@2x.png", size : 58 }, + { name : "Icon-72.png", size : 72 }, + { name : "Icon-76.png", size : 76 }, + { name : "Icon-Small-40@2x.png", size : 80 }, + { name : "Icon-Small-50@2x.png", size : 100 }, + { name : "Icon@2x.png", size : 114 }, + { name : "Icon-60@2x.png", size : 120 }, + { name : "Icon-72@2x.png", size : 144 }, + { name : "Icon-76@2x.png", size : 152 }, + { name : "Icon-60@3x.png", size : 180 }, + ]; + + context.HAS_ICON = true; + + var iconPath = PathHelper.combine (projectDirectory, "Images.xcassets/AppIcon.appiconset"); + PathHelper.mkdir (iconPath); + + var icons = project.icons; + + if (icons.length == 0) { + + icons = [ new Icon (PathHelper.findTemplate (project.templatePaths, "default/icon.svg")) ]; + + } + + for (iconSize in iconSizes) { + + if (!IconHelper.createIcon (icons, iconSize.size, iconSize.size, PathHelper.combine (iconPath, iconSize.name))) { + + context.HAS_ICON = false; + + } + + } + + var splashSizes:Array = [ + { name: "Default.png", w: 320, h: 480 }, // iPhone, portrait + { name: "Default@2x.png", w: 640, h: 960 }, // iPhone Retina, portrait + { name: "Default-568h@2x.png", w: 640, h: 1136 }, // iPhone 5, portrait + { name: "Default-Portrait.png", w: 768, h: 1024 }, // iPad, portrait + { name: "Default-Landscape.png", w: 1024, h: 768 }, // iPad, landscape + { name: "Default-Portrait@2x.png", w: 1536, h: 2048 }, // iPad Retina, portrait + { name: "Default-Landscape@2x.png", w: 2048, h: 1536 }, // iPad Retina, landscape + { name: "Default-667h@2x.png", w: 750, h: 1334 }, // iPhone 6, portrait + { name: "Default-736h@3x.png", w: 1242, h: 2208 }, // iPhone 6 Plus, portrait + { name: "Default-736h-Landscape@3x.png", w: 2208, h: 1242 }, // iPhone 6 Plus, landscape + ]; + + var splashScreenPath = PathHelper.combine (projectDirectory, "Images.xcassets/LaunchImage.launchimage"); + PathHelper.mkdir (splashScreenPath); + + for (size in splashSizes) { + + var match = false; + + for (splashScreen in project.splashScreens) { + + if (splashScreen.width == size.w && splashScreen.height == size.h && Path.extension (splashScreen.path) == "png") { + + FileHelper.copyFile (splashScreen.path, PathHelper.combine (splashScreenPath, size.name)); + match = true; + + } + + } + + if (!match) { + + var imagePath = PathHelper.combine (splashScreenPath, size.name); + + if (!FileSystem.exists (imagePath)) { + + LogHelper.info ("", " - \x1b[1mGenerating image:\x1b[0m " + imagePath); + + var image = new Image (null, 0, 0, size.w, size.h, (0xFF << 24) | (project.window.background & 0xFFFFFF)); + var bytes = image.encode ("png"); + + File.saveBytes (imagePath, bytes); + + } + + } + + } + + context.HAS_LAUNCH_IMAGE = true; + + PathHelper.mkdir (projectDirectory + "/resources"); + PathHelper.mkdir (projectDirectory + "/haxe/build"); + + FileHelper.recursiveCopyTemplate (project.templatePaths, "tvos/resources", projectDirectory + "/resources", context, true, false); + FileHelper.recursiveCopyTemplate (project.templatePaths, "tvos/PROJ/haxe", projectDirectory + "/haxe", context); + FileHelper.recursiveCopyTemplate (project.templatePaths, "haxe", projectDirectory + "/haxe", context); + FileHelper.recursiveCopyTemplate (project.templatePaths, "tvos/PROJ/Classes", projectDirectory + "/Classes", context); + FileHelper.recursiveCopyTemplate (project.templatePaths, "tvos/PROJ/Images.xcassets", projectDirectory + "/Images.xcassets", context); + FileHelper.copyFileTemplate (project.templatePaths, "tvos/PROJ/PROJ-Entitlements.plist", projectDirectory + "/" + project.app.file + "-Entitlements.plist", context); + FileHelper.copyFileTemplate (project.templatePaths, "tvos/PROJ/PROJ-Info.plist", projectDirectory + "/" + project.app.file + "-Info.plist", context); + FileHelper.copyFileTemplate (project.templatePaths, "tvos/PROJ/PROJ-Prefix.pch", projectDirectory + "/" + project.app.file + "-Prefix.pch", context); + FileHelper.recursiveCopyTemplate (project.templatePaths, "tvos/PROJ.xcodeproj", targetDirectory + "/" + project.app.file + ".xcodeproj", context); + + //SWFHelper.generateSWFClasses (project, projectDirectory + "/haxe"); + + PathHelper.mkdir (projectDirectory + "/lib"); + + for (archID in 0...3) { + + var arch = [ "arm64", "i386", "x86_64" ][archID]; + + if (arch == "arm64" && !context.ARM64) + continue; + + var libExt = [ ".appletvos-64.a", ".appletvsim.a", ".appletvsim-64.a" ][archID]; + + PathHelper.mkdir (projectDirectory + "/lib/" + arch); + PathHelper.mkdir (projectDirectory + "/lib/" + arch + "-debug"); + + for (ndll in project.ndlls) { + + //if (ndll.haxelib != null) { + + var releaseLib = PathHelper.getLibraryPath (ndll, "AppleTV", "lib", libExt); + LogHelper.info("releaseLib: " + releaseLib); + var debugLib = PathHelper.getLibraryPath (ndll, "AppleTV", "lib", libExt, true); + var releaseDest = projectDirectory + "/lib/" + arch + "/lib" + ndll.name + ".a"; + LogHelper.info("releaseDest: " + releaseDest); + var debugDest = projectDirectory + "/lib/" + arch + "-debug/lib" + ndll.name + ".a"; + + if (!FileSystem.exists (releaseLib)) { + + releaseLib = PathHelper.getLibraryPath (ndll, "AppleTV", "lib", ".appletvos-64.a"); + LogHelper.info("alternative releaseLib: " + releaseLib); + debugLib = PathHelper.getLibraryPath (ndll, "AppleTV", "lib", ".appletvos-64.a", true); + + } + + FileHelper.copyIfNewer (releaseLib, releaseDest); + + if (FileSystem.exists (debugLib) && debugLib != releaseLib) { + + FileHelper.copyIfNewer (debugLib, debugDest); + + } else if (FileSystem.exists (debugDest)) { + + FileSystem.deleteFile (debugDest); + + } + + //} + + } + + for (dependency in project.dependencies) { + + if (StringTools.endsWith (dependency.path, ".a")) { + + var fileName = Path.withoutDirectory (dependency.path); + + if (!StringTools.startsWith (fileName, "lib")) { + + fileName = "lib" + fileName; + + } + + FileHelper.copyIfNewer (dependency.path, projectDirectory + "/lib/" + arch + "/" + fileName); + + } + + } + + } + + PathHelper.mkdir (projectDirectory + "/assets"); + + for (asset in project.assets) { + + if (asset.type != AssetType.TEMPLATE) { + + var targetPath = PathHelper.combine (projectDirectory + "/assets/", asset.resourceName); + + //var sourceAssetPath:String = projectDirectory + "haxe/" + asset.sourcePath; + + PathHelper.mkdir (Path.directory (targetPath)); + FileHelper.copyAssetIfNewer (asset, targetPath); + + //PathHelper.mkdir (Path.directory (sourceAssetPath)); + //FileHelper.linkFile (flatAssetPath, sourceAssetPath, true, true); + + } else { + + var targetPath = PathHelper.combine (projectDirectory, asset.targetPath); + + PathHelper.mkdir (Path.directory (targetPath)); + FileHelper.copyAsset (asset, targetPath, context); + + } + + } + + if (project.targetFlags.exists ("xcode") && PlatformHelper.hostPlatform == Platform.MAC && command == "update") { + + ProcessHelper.runCommand ("", "open", [ targetDirectory + "/" + project.app.file + ".xcodeproj" ] ); + + } + + } + + + /*private function updateLaunchImage () { + + var destination = buildDirectory + "/ios"; + PathHelper.mkdir (destination); + + var has_launch_image = false; + if (launchImages.length > 0) has_launch_image = true; + + for (launchImage in launchImages) { + + var splitPath = launchImage.name.split ("/"); + var path = destination + "/" + splitPath[splitPath.length - 1]; + FileHelper.copyFile (launchImage.name, path, context, false); + + } + + context.HAS_LAUNCH_IMAGE = has_launch_image; + + }*/ + + + @ignore public override function install ():Void {} + @ignore public override function trace ():Void {} + @ignore public override function uninstall ():Void {} + + +} + + +private typedef IconSize = { + + name:String, + size:Int, + +} + + +private typedef SplashSize = { + + name:String, + w:Int, + h:Int, + +} diff --git a/project/Build.xml b/project/Build.xml index 16e71b58e..ef57f07a9 100644 --- a/project/Build.xml +++ b/project/Build.xml @@ -8,6 +8,7 @@ + @@ -147,6 +148,8 @@ + + @@ -185,7 +188,9 @@ - + + + @@ -200,7 +205,7 @@ - + @@ -262,7 +267,7 @@ - + @@ -350,6 +355,22 @@ +
+ + + + + + + + + + + + + + +
diff --git a/project/src/backend/sdl/SDLApplication.cpp b/project/src/backend/sdl/SDLApplication.cpp index d00e14e16..3e3a89a60 100644 --- a/project/src/backend/sdl/SDLApplication.cpp +++ b/project/src/backend/sdl/SDLApplication.cpp @@ -54,7 +54,7 @@ namespace lime { TouchEvent touchEvent; WindowEvent windowEvent; - #if defined(IOS) || defined(ANDROID) + #if defined(IOS) || defined(ANDROID) || defined(TVOS) for (int i = 0; i < SDL_NumJoysticks (); i++) { if (strstr (SDL_JoystickNameForIndex (i), "Accelerometer")) { @@ -166,7 +166,7 @@ namespace lime { case SDL_JOYAXISMOTION: - #if defined(IOS) || defined(ANDROID) + #if defined(IOS) || defined(ANDROID) || defined(TVOS) if (event->jaxis.which == accelerometerID) { ProcessSensorEvent (event); diff --git a/project/src/graphics/opengl/OpenGL.h b/project/src/graphics/opengl/OpenGL.h index 935855b2f..3a6d878e4 100644 --- a/project/src/graphics/opengl/OpenGL.h +++ b/project/src/graphics/opengl/OpenGL.h @@ -14,7 +14,7 @@ #include #include -#elif defined (IPHONE) +#elif defined (IPHONE) || defined(APPLETV) #define LIME_GLES #include diff --git a/templates/compatibility/DefaultAssetLibrary.hx b/templates/compatibility/DefaultAssetLibrary.hx index 5553ae9c6..bb2961f5e 100644 --- a/templates/compatibility/DefaultAssetLibrary.hx +++ b/templates/compatibility/DefaultAssetLibrary.hx @@ -23,7 +23,7 @@ import openfl.net.URLLoader; import sys.FileSystem; #end -#if ios +#if (ios || tvos) import openfl.utils.SystemPath; #end @@ -305,7 +305,7 @@ class DefaultAssetLibrary extends AssetLibrary { public override function getPath (id:String):String { - #if ios + #if (ios || tvos) return SystemPath.applicationDirectory + "/assets/" + path.get (id); diff --git a/templates/haxe/DefaultAssetLibrary.hx b/templates/haxe/DefaultAssetLibrary.hx index d2e9f8c20..579571601 100644 --- a/templates/haxe/DefaultAssetLibrary.hx +++ b/templates/haxe/DefaultAssetLibrary.hx @@ -315,14 +315,15 @@ class DefaultAssetLibrary extends AssetLibrary { #else if (className.exists (id)) { - var fontClass = className.get (id); return cast (Type.createInstance (fontClass, []), Image); } else { - + #if tvos + return Image.fromFile ("assets/" + path.get (id)); + #else return Image.fromFile (path.get (id)); - + #end } #end @@ -689,7 +690,7 @@ class DefaultAssetLibrary extends AssetLibrary { var bytes = ByteArray.readFile ("assets/manifest"); #elseif (mac && java) var bytes = ByteArray.readFile ("../Resources/manifest"); - #elseif ios + #elseif (ios || tvos) var bytes = ByteArray.readFile ("assets/manifest"); #else var bytes = ByteArray.readFile ("manifest"); @@ -711,7 +712,7 @@ class DefaultAssetLibrary extends AssetLibrary { if (!className.exists (asset.id)) { - #if ios + #if ios || tvos path.set (asset.id, "assets/" + asset.path); #else path.set (asset.id, asset.path); @@ -821,7 +822,7 @@ class DefaultAssetLibrary extends AssetLibrary { #else -::if (assets != null)::::foreach assets::::if (!embed)::::if (type == "font")::@:keep #if display private #end class __ASSET__::flatName:: extends lime.text.Font { public function new () { __fontPath = #if ios "assets/" + #end "::targetPath::"; name = "::fontName::"; super (); }} +::if (assets != null)::::foreach assets::::if (!embed)::::if (type == "font")::@:keep #if display private #end class __ASSET__::flatName:: extends lime.text.Font { public function new () { __fontPath = #if (ios || tvos) "assets/" + #end "::targetPath::"; name = "::fontName::"; super (); }} ::end::::end::::end::::end:: #if (windows || mac || linux || cpp) @@ -839,7 +840,7 @@ class DefaultAssetLibrary extends AssetLibrary { #end #if (openfl && !flash) -::if (assets != null)::::foreach assets::::if (type == "font")::@:keep #if display private #end class __ASSET__OPENFL__::flatName:: extends openfl.text.Font { public function new () { ::if (embed)::var font = new __ASSET__::flatName:: (); src = font.src; name = font.name;::else::__fontPath = #if ios "assets/" + #end "::targetPath::"; name = "::fontName::";::end:: super (); }} +::if (assets != null)::::foreach assets::::if (type == "font")::@:keep #if display private #end class __ASSET__OPENFL__::flatName:: extends openfl.text.Font { public function new () { ::if (embed)::var font = new __ASSET__::flatName:: (); src = font.src; name = font.name;::else::__fontPath = #if (ios || tvos) "assets/" + #end "::targetPath::"; name = "::fontName::";::end:: super (); }} ::end::::end::::end:: #end diff --git a/templates/tvos/PROJ.xcodeproj/project.pbxproj b/templates/tvos/PROJ.xcodeproj/project.pbxproj new file mode 100644 index 000000000..bf8762d52 --- /dev/null +++ b/templates/tvos/PROJ.xcodeproj/project.pbxproj @@ -0,0 +1,475 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1E2E17AD131E8B5D0048F3C7 /* ::APP_FILE::/assets in Resources */ = {isa = PBXBuildFile; fileRef = 1E2E17A5131E8B5D0048F3C7 /* Data */; }; + 1EF0A83B121ADB8E003F2F59 /* ::APP_FILE::/haxe/build in Sources */ = {isa = PBXBuildFile; fileRef = 1E2E17A5141E8B5D0048F3C7 /* haxe */; }; + 1EEEBA9B121AF1C60048A9DF /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1EEEBA9A121AF1C60048A9DF /* UIKit.framework */; }; + 1EEEBAA3121AF2210048A9DF /* OpenAL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1EEEBAA2121AF2210048A9DF /* OpenAL.framework */; }; + 1EEEBAA5121AF2210048A9DF /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1EEEBAA4121AF2210048A9DF /* OpenGLES.framework */; }; + 1EEEBAA7121AF2210048A9DF /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1EEEBAA6121AF2210048A9DF /* QuartzCore.framework */; }; + 1EEEBAB3121AF2880048A9D1 /* MediaPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1EEEBAB2121AF2880048A9D1 /* MediaPlayer.framework */; }; + 1EEEBAB3121AF2880048A9DF /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1EEEBAB2121AF2880048A9DF /* CoreAudio.framework */; }; + 1EEEBAB5121AF2880048A9DF /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1EEEBAB4121AF2880048A9DF /* CoreGraphics.framework */; }; + 1EEEBAFC121BE2980048A9DF /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1EEEBAFB121BE2980048A9DF /* AudioToolbox.framework */; }; + 1EEEBAFE121BE2980048A9DF /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1EEEBAFD121BE2980048A9DF /* AVFoundation.framework */; }; + 1EEEBB00121BE2B30048A9DF /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1EEEBAFF121BE2B30048A9DF /* Foundation.framework */; }; + 026D746C1BBED5C800EAA58A /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 026D746B1BBED5C800EAA58A /* GameController.framework */; }; + 1EF0A83A121ADB8E003F2F59 /* Main.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1EF0A839121ADB8E003F2F59 /* Main.mm */; }; + 4257533F1A5EFD8C004AA45B /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4257533E1A5EFD8C004AA45B /* Images.xcassets */; }; + ::ADDL_PBX_BUILD_FILE:: + +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 1EF0A882121AE1D2003F2F59 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; + proxyType = 1; + remoteGlobalIDString = 1EF0A87F121AE1CE003F2F59; + remoteInfo = "Build Haxe"; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 1D6058910D05DD3D006BFB54 /* ::APP_TITLE::.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "::APP_TITLE::.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 1E2E17A5131E8B5D0048F3C7 /* ::APP_FILE::/assets */ = {isa = PBXFileReference; lastKnownFileType = folder; path = "::APP_FILE::/assets"; sourceTree = ""; }; + 1E2E17A5141E8B5D0048F3C7 /* ::APP_FILE::/haxe/build */ = {isa = PBXFileReference; lastKnownFileType = folder; path = "::APP_FILE::/haxe/build"; sourceTree = SOURCE_ROOT; }; + 1EEEBA9A121AF1C60048A9DF /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 1EEEBAA2121AF2210048A9DF /* OpenAL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenAL.framework; path = System/Library/Frameworks/OpenAL.framework; sourceTree = SDKROOT; }; + 1EEEBAA4121AF2210048A9DF /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; }; + 1EEEBAA6121AF2210048A9DF /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; + 1EEEBAB2121AF2880048A9D1 /* MediaPlayer.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MediaPlayer.framework; path = System/Library/Frameworks/MediaPlayer.framework; sourceTree = SDKROOT; }; + 1EEEBAB2121AF2880048A9DF /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; }; + 1EEEBAB4121AF2880048A9DF /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 1EEEBAFB121BE2980048A9DF /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; + 1EEEBAFD121BE2980048A9DF /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; + 1EEEBAFF121BE2B30048A9DF /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 026D746B1BBED5C800EAA58A /* GameController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameController.framework; path = System/Library/Frameworks/GameController.framework; sourceTree = SDKROOT; }; + 1EF0A839121ADB8E003F2F59 /* Main.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Main.mm; path = "::APP_FILE::/Classes/Main.mm"; sourceTree = SOURCE_ROOT; }; + 4257533E1A5EFD8C004AA45B /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = "::APP_FILE::/Images.xcassets"; sourceTree = ""; }; + + ::ADDL_PBX_FILE_REFERENCE:: + + 8D1107310486CEB800E47090 /* ::APP_FILE::-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "::APP_FILE::/::APP_FILE::-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; +/* End PBXFileReference section */ + + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ::if ARMV6::1EF0A888121AE2F0003F2F59 /* lib/ApplicationMain.a in lib */,::end:: + ::if ARMV7::1EF0A888121AE2F0003F2F5A /* lib/ApplicationMain-v7.a in lib */,::end:: + 1EEEBA9B121AF1C60048A9DF /* UIKit.framework in Frameworks */, + 1EEEBAA3121AF2210048A9DF /* OpenAL.framework in Frameworks */, + 1EEEBAA5121AF2210048A9DF /* OpenGLES.framework in Frameworks */, + 1EEEBAA7121AF2210048A9DF /* QuartzCore.framework in Frameworks */, + 1EEEBAB3121AF2880048A9DF /* CoreAudio.framework in Frameworks */, + 1EEEBAB5121AF2880048A9DF /* CoreGraphics.framework in Frameworks */, + 1EEEBAFC121BE2980048A9DF /* AudioToolbox.framework in Frameworks */, + 1EEEBAFE121BE2980048A9DF /* AVFoundation.framework in Frameworks */, + 1EEEBB00121BE2B30048A9DF /* Foundation.framework in Frameworks */, + 1EEEBAB3121AF2880048A9D1 /* MediaPlayer.framework in Frameworks */, + 026D746C1BBED5C800EAA58A /* GameController.framework in Frameworks */, + ::ADDL_PBX_FRAMEWORKS_BUILD_PHASE:: + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 1EF0A839121ADB8E003F2F59 /* Main.mm */, + ); + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* ::APP_TITLE::.app */, + ); + name = Products; + sourceTree = ""; + }; + 1EEEBA99121AF18B0048A9DF /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1EEEBA9A121AF1C60048A9DF /* UIKit.framework */, + 1EEEBAA2121AF2210048A9DF /* OpenAL.framework */, + 1EEEBAA4121AF2210048A9DF /* OpenGLES.framework */, + 1EEEBAA6121AF2210048A9DF /* QuartzCore.framework */, + 1EEEBAB2121AF2880048A9DF /* CoreAudio.framework */, + 1EEEBAB4121AF2880048A9DF /* CoreGraphics.framework */, + 1EEEBAFF121BE2B30048A9DF /* Foundation.framework */, + 1EEEBAFB121BE2980048A9DF /* AudioToolbox.framework */, + 1EEEBAFD121BE2980048A9DF /* AVFoundation.framework */, + 1EEEBAB2121AF2880048A9D1 /* MediaPlayer.framework */, + 026D746B1BBED5C800EAA58A /* GameController.framework */, + ::ADDL_PBX_FRAMEWORK_GROUP:: + ); + name = Frameworks; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 1EEEBA99121AF18B0048A9DF /* Frameworks */, + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 1E2E17A5141E8B5D0048F3C7 /* ::APP_FILE::/haxe/build */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 4257533E1A5EFD8C004AA45B /* Images.xcassets */, + 8D1107310486CEB800E47090 /* ::APP_FILE::/::APP_FILE::-Info.plist */, + 1E2E17A5131E8B5D0048F3C7 /* ::APP_FILE::/assets */, + ); + name = Resources; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* "::APP_FILE::" */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "::APP_FILE::" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 1EF0A883121AE1D2003F2F59 /* PBXTargetDependency */, + ); + name = "::APP_FILE::"; + productName = "::APP_TITLE::"; + productReference = 1D6058910D05DD3D006BFB54 /* ::APP_TITLE::.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXLegacyTarget section */ + 1EF0A87F121AE1CE003F2F59 /* Build Haxe */ = { + isa = PBXLegacyTarget; + buildArgumentsString = ""; + buildConfigurationList = 1EF0A885121AE21C003F2F59 /* Build configuration list for PBXLegacyTarget "Build Haxe" */; + buildPhases = ( + ); + buildToolPath = make; + buildWorkingDirectory = "::APP_FILE::/haxe"; + dependencies = ( + ); + name = "Build Haxe"; + passBuildSettingsInEnvironment = 1; + productName = "Build Haxe"; + }; +/* End PBXLegacyTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "::APP_TITLE::" */; + compatibilityVersion = "Xcode 3.2"; + hasScannedForEncodings = 1; + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* ::APP_FILE:: */, + 1EF0A87F121AE1CE003F2F59 /* Build Haxe */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1E2E17AD131E8B5D0048F3C7 /* ::APP_FILE::/assets in Resources */, + 4257533F1A5EFD8C004AA45B /* Images.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1EF0A83A121ADB8E003F2F59 /* Main.mm in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 1EF0A883121AE1D2003F2F59 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 1EF0A87F121AE1CE003F2F59 /* Build Haxe */; + targetProxy = 1EF0A882121AE1D2003F2F59 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + C01FCF4F08A954540054247B /* Debug */ = {/* Build configuration list for PBXProject "::APP_TITLE::" */ + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = ::CURRENT_ARCHS::; + ::if (OBJC_ARC):: + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + ::end:: + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "::KEY_STORE_IDENTITY::"; + COPY_PHASE_STRIP = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = ::DEPLOYMENT::; + SDKROOT = appletvos; + TARGETED_DEVICE_FAMILY = "::TARGET_DEVICES::"; + ::THUMB_SUPPORT:: + VALID_ARCHS = "::VALID_ARCHS::"; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = {/* Build configuration list for PBXProject "::APP_TITLE::" */ + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = ::CURRENT_ARCHS::; + ::if (OBJC_ARC):: + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + ::end:: + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "::KEY_STORE_IDENTITY::"; + /* COMPRESS_PNG_FILES = NO; */ + COPY_PHASE_STRIP = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + /* GCC_ENABLE_SYMBOL_SEPARATION = YES; */ + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = ::DEPLOYMENT::; + OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; + /* PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = YES; */ + SDKROOT = appletvos; + TARGETED_DEVICE_FAMILY = "::TARGET_DEVICES::"; + ::THUMB_SUPPORT:: + VALID_ARCHS = "::VALID_ARCHS::"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 1D6058940D05DD3E006BFB54 /* Debug */ = {/* Build configuration list for PBXNativeTarget "::APP_TITLE::" */ + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + ENABLE_BITCODE = ::if (ENABLE_BITCODE)::YES::else::NO::end::; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + ::foreach frameworkSearchPaths:: "\"::__current__::\"", + ::end:: + ); + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "::APP_FILE::/::APP_FILE::-Prefix.pch"; + INFOPLIST_FILE = "::APP_FILE::/::APP_FILE::-Info.plist"; + "LIBRARY_SEARCH_PATHS[arch=arm64]" = ( + "$(inherited)", + "\"$(SRCROOT)/::APP_FILE::/lib/arm64-debug\"", + "\"$(SRCROOT)/::APP_FILE::/lib/arm64\"", + ); + "LIBRARY_SEARCH_PATHS[arch=armv6]" = ( + "$(inherited)", + "\"$(SRCROOT)/::APP_FILE::/lib/armv6-debug\"", + "\"$(SRCROOT)/::APP_FILE::/lib/armv6\"", + ); + "LIBRARY_SEARCH_PATHS[arch=armv7]" = ( + "$(inherited)", + "\"$(SRCROOT)/::APP_FILE::/lib/armv7-debug\"", + "\"$(SRCROOT)/::APP_FILE::/lib/armv7\"", + ); + "LIBRARY_SEARCH_PATHS[arch=i386]" = ( + "$(inherited)", + "\"$(SRCROOT)/::APP_FILE::/lib/i386-debug\"", + "\"$(SRCROOT)/::APP_FILE::/lib/i386\"", + ); + "LIBRARY_SEARCH_PATHS[arch=x86_64]" = ( + "$(inherited)", + "\"$(SRCROOT)/::APP_FILE::/lib/x86_64-debug\"", + "\"$(SRCROOT)/::APP_FILE::/lib/x86_64\"", + ); + OTHER_LDFLAGS = ( + ::foreach ndlls:: "-l::name::", + ::end:: + ::foreach linkedLibraries:: "-l::__current__::", + ::end:: + "-lApplicationMain", + ::foreach IOS_LINKER_FLAGS:: "::__current__::", + ::end:: + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + WRAPPER_EXTENSION = app; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = {/* Build configuration list for PBXNativeTarget "::APP_TITLE::" */ + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + ENABLE_BITCODE = ::if (ENABLE_BITCODE)::YES::else::NO::end::; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + ::foreach frameworkSearchPaths:: "\"::__current__::\"", + ::end:: + ); + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "::APP_FILE::/::APP_FILE::-Prefix.pch"; + INFOPLIST_FILE = "::APP_FILE::/::APP_FILE::-Info.plist"; + "LIBRARY_SEARCH_PATHS[arch=arm64]" = ( + "$(inherited)", + "\"$(SRCROOT)/::APP_FILE::/lib/arm64\"", + ); + "LIBRARY_SEARCH_PATHS[arch=armv6]" = ( + "$(inherited)", + "\"$(SRCROOT)/::APP_FILE::/lib/armv6\"", + ); + "LIBRARY_SEARCH_PATHS[arch=armv7]" = ( + "$(inherited)", + "\"$(SRCROOT)/::APP_FILE::/lib/armv7\"", + ); + "LIBRARY_SEARCH_PATHS[arch=i386]" = ( + "$(inherited)", + "\"$(SRCROOT)/::APP_FILE::/lib/i386\"", + ); + "LIBRARY_SEARCH_PATHS[arch=x86_64]" = ( + "$(inherited)", + "\"$(SRCROOT)/::APP_FILE::/lib/x86_64\"", + ); + OTHER_LDFLAGS = ( + ::foreach ndlls:: "-l::name::", + ::end:: + ::foreach linkedLibraries:: "-l::__current__::", + ::end:: + "-lApplicationMain", + ::foreach IOS_LINKER_FLAGS:: "::__current__::", + ::end:: + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + WRAPPER_EXTENSION = app; + }; + name = Release; + }; + 1EF0A880121AE1CE003F2F59 /* Debug */ = {/* Build configuration list for PBXLegacyTarget "Build Haxe" */ + isa = XCBuildConfiguration; + buildSettings = { + ::if (OBJC_ARC):: + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + ::end:: + COPY_PHASE_STRIP = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + }; + name = Debug; + }; + 1EF0A881121AE1CE003F2F59 /* Release */ = {/* Build configuration list for PBXLegacyTarget "Build Haxe" */ + isa = XCBuildConfiguration; + buildSettings = { + ::if (OBJC_ARC):: + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + ::end:: + COPY_PHASE_STRIP = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + ZERO_LINK = NO; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "::APP_TITLE::" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "::APP_TITLE::" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1EF0A885121AE21C003F2F59 /* Build configuration list for PBXLegacyTarget "Build Haxe" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1EF0A880121AE1CE003F2F59 /* Debug */, + 1EF0A881121AE1CE003F2F59 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; /* end objects */ + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} \ No newline at end of file diff --git a/templates/tvos/PROJ.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/templates/tvos/PROJ.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000..94b2795e2 --- /dev/null +++ b/templates/tvos/PROJ.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,4 @@ + + + diff --git a/templates/tvos/PROJ/Classes/Main.mm b/templates/tvos/PROJ/Classes/Main.mm new file mode 100644 index 000000000..442a5f78e --- /dev/null +++ b/templates/tvos/PROJ/Classes/Main.mm @@ -0,0 +1,35 @@ +#include + +extern "C" const char *hxRunLibrary (); +extern "C" void hxcpp_set_top_of_stack (); + +extern "C" int zlib_register_prims (); +extern "C" int lime_cairo_register_prims (); +extern "C" int lime_openal_register_prims (); +::foreach ndlls::::if (registerStatics):: +extern "C" int ::nameSafe::_register_prims ();::end::::end:: + + +extern "C" int SDL_main (int argc, char *argv[]) { + + hxcpp_set_top_of_stack (); + + zlib_register_prims (); + lime_cairo_register_prims (); + lime_openal_register_prims (); + ::foreach ndlls::::if (registerStatics):: + ::nameSafe::_register_prims ();::end::::end:: + + const char *err = NULL; + err = hxRunLibrary (); + + if (err) { + + printf ("Error %s\n", err); + return -1; + + } + + return 0; + +} \ No newline at end of file diff --git a/templates/tvos/PROJ/Images.xcassets/AppIcon.appiconset/Contents.json b/templates/tvos/PROJ/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 000000000..8ba31b764 --- /dev/null +++ b/templates/tvos/PROJ/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,110 @@ +{ + "images" : [ + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-Small.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-Small@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-Small-40@2x.png", + "scale" : "2x" + }, + { + "size" : "57x57", + "idiom" : "iphone", + "filename" : "Icon.png", + "scale" : "1x" + }, + { + "size" : "57x57", + "idiom" : "iphone", + "filename" : "Icon@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-60@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-Small.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-Small@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-Small-40.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-Small-40@2x.png", + "scale" : "2x" + }, + { + "size" : "50x50", + "idiom" : "ipad", + "filename" : "Icon-Small-50.png", + "scale" : "1x" + }, + { + "size" : "50x50", + "idiom" : "ipad", + "filename" : "Icon-Small-50@2x.png", + "scale" : "2x" + }, + { + "size" : "72x72", + "idiom" : "ipad", + "filename" : "Icon-72.png", + "scale" : "1x" + }, + { + "size" : "72x72", + "idiom" : "ipad", + "filename" : "Icon-72@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-76.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-76@2x.png", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/templates/tvos/PROJ/Images.xcassets/LaunchImage.launchimage/Contents.json b/templates/tvos/PROJ/Images.xcassets/LaunchImage.launchimage/Contents.json new file mode 100644 index 000000000..97c51d6b7 --- /dev/null +++ b/templates/tvos/PROJ/Images.xcassets/LaunchImage.launchimage/Contents.json @@ -0,0 +1,158 @@ +{ + "images" : [ + { + "extent" : "full-screen", + "idiom" : "iphone", + "subtype" : "736h", + "filename" : "Default-736h@3x.png", + "minimum-system-version" : "8.0", + "orientation" : "portrait", + "scale" : "3x" + }, + { + "extent" : "full-screen", + "idiom" : "iphone", + "subtype" : "736h", + "filename" : "Default-736h-Landscape@3x.png", + "minimum-system-version" : "8.0", + "orientation" : "landscape", + "scale" : "3x" + }, + { + "extent" : "full-screen", + "idiom" : "iphone", + "subtype" : "667h", + "filename" : "Default-667h@2x.png", + "minimum-system-version" : "8.0", + "orientation" : "portrait", + "scale" : "2x" + }, + { + "orientation" : "portrait", + "idiom" : "iphone", + "extent" : "full-screen", + "minimum-system-version" : "7.0", + "filename" : "Default@2x.png", + "scale" : "2x" + }, + { + "extent" : "full-screen", + "idiom" : "iphone", + "subtype" : "retina4", + "filename" : "Default-568h@2x.png", + "minimum-system-version" : "7.0", + "orientation" : "portrait", + "scale" : "2x" + }, + { + "orientation" : "portrait", + "idiom" : "ipad", + "extent" : "full-screen", + "minimum-system-version" : "7.0", + "filename" : "Default-Portrait.png", + "scale" : "1x" + }, + { + "orientation" : "landscape", + "idiom" : "ipad", + "extent" : "full-screen", + "minimum-system-version" : "7.0", + "filename" : "Default-Landscape.png", + "scale" : "1x" + }, + { + "orientation" : "portrait", + "idiom" : "ipad", + "extent" : "full-screen", + "minimum-system-version" : "7.0", + "filename" : "Default-Portrait@2x.png", + "scale" : "2x" + }, + { + "orientation" : "landscape", + "idiom" : "ipad", + "extent" : "full-screen", + "minimum-system-version" : "7.0", + "filename" : "Default-Landscape@2x.png", + "scale" : "2x" + }, + { + "orientation" : "portrait", + "idiom" : "iphone", + "extent" : "full-screen", + "filename" : "Default.png", + "scale" : "1x" + }, + { + "orientation" : "portrait", + "idiom" : "iphone", + "extent" : "full-screen", + "filename" : "Default@2x.png", + "scale" : "2x" + }, + { + "orientation" : "portrait", + "idiom" : "iphone", + "extent" : "full-screen", + "filename" : "Default-568h@2x.png", + "subtype" : "retina4", + "scale" : "2x" + }, + { + "orientation" : "portrait", + "idiom" : "ipad", + "extent" : "to-status-bar", + "scale" : "1x" + }, + { + "orientation" : "portrait", + "idiom" : "ipad", + "extent" : "full-screen", + "filename" : "Default-Portrait.png", + "scale" : "1x" + }, + { + "orientation" : "landscape", + "idiom" : "ipad", + "extent" : "to-status-bar", + "scale" : "1x" + }, + { + "orientation" : "landscape", + "idiom" : "ipad", + "extent" : "full-screen", + "filename" : "Default-Landscape.png", + "scale" : "1x" + }, + { + "orientation" : "portrait", + "idiom" : "ipad", + "extent" : "to-status-bar", + "scale" : "2x" + }, + { + "orientation" : "portrait", + "idiom" : "ipad", + "extent" : "full-screen", + "filename" : "Default-Portrait@2x.png", + "scale" : "2x" + }, + { + "orientation" : "landscape", + "idiom" : "ipad", + "extent" : "to-status-bar", + "scale" : "2x" + }, + { + "orientation" : "landscape", + "idiom" : "ipad", + "extent" : "full-screen", + "filename" : "Default-Landscape@2x.png", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/templates/tvos/PROJ/PROJ-Entitlements.plist b/templates/tvos/PROJ/PROJ-Entitlements.plist new file mode 100644 index 000000000..929c4e96d --- /dev/null +++ b/templates/tvos/PROJ/PROJ-Entitlements.plist @@ -0,0 +1,8 @@ + + + + + get-task-allow + + + \ No newline at end of file diff --git a/templates/tvos/PROJ/PROJ-Info.plist b/templates/tvos/PROJ/PROJ-Info.plist new file mode 100644 index 000000000..61ca41408 --- /dev/null +++ b/templates/tvos/PROJ/PROJ-Info.plist @@ -0,0 +1,42 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + ::APP_TITLE:: + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ::APP_PACKAGE:: + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleShortVersionString + ::APP_VERSION:: + CFBundleSignature + ???? + CFBundleVersion + ::APP_BUILD_NUMBER:: + LSRequiresIPhoneOS + + UIRequiredDeviceCapabilities + + ::foreach REQUIRED_CAPABILITY:: + ::name:: + ::if value::::else::::end:: + ::end:: + + UIStatusBarHidden + <::WIN_FULLSCREEN::/> + UIViewControllerBasedStatusBarAppearance + <::!WIN_FULLSCREEN::/> + ::if (IOS_APP_ORIENTATION != null):: + UISupportedInterfaceOrientations + ::IOS_APP_ORIENTATION::::end:: + + diff --git a/templates/tvos/PROJ/PROJ-Prefix.pch b/templates/tvos/PROJ/PROJ-Prefix.pch new file mode 100644 index 000000000..615bee923 --- /dev/null +++ b/templates/tvos/PROJ/PROJ-Prefix.pch @@ -0,0 +1,14 @@ +// +// Prefix header for all source files of the '::APP_FILE::' target in the '::APP_FILE::' project +// + +#import + +#ifndef __IPHONE_3_0 +#warning "This project uses features only available in iOS SDK 3.0 and later." +#endif + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/templates/tvos/PROJ/haxe/Build.hxml b/templates/tvos/PROJ/haxe/Build.hxml new file mode 100644 index 000000000..4d9355c97 --- /dev/null +++ b/templates/tvos/PROJ/haxe/Build.hxml @@ -0,0 +1,5 @@ +-main ApplicationMain ::HAXE_FLAGS:: +-D tvos +-D appletvos +--macro keep("::APP_MAIN::") +-D no-compilation \ No newline at end of file diff --git a/templates/tvos/PROJ/haxe/makefile b/templates/tvos/PROJ/haxe/makefile new file mode 100644 index 000000000..51d16aa93 --- /dev/null +++ b/templates/tvos/PROJ/haxe/makefile @@ -0,0 +1,70 @@ + +ifeq ("$(ARCHS)","normal") + ARCHS = arm64 i386 +endif + +HAXE_BUILDS := $(ARCHS:%=build-haxe-%) + +ifeq ("$(ACTION)","clean") +default: clean +else +default: $(HAXE_BUILDS) +endif + +ifeq ("$(CONFIGURATION)","Debug") + BUILD_STYLE := Debug +endif + +default: debug_print + +ifeq ("$(BUILD_STYLE)","Debug") + DEBUG := -debug + DEF_DEBUG := -Ddebug + CONFIG := Debug +else + DEBUG := + DEF_DEBUG := + CONFIG := Release +endif + +ifeq ("$(CLANG_ENABLE_OBJC_ARC)", "YES") + HXCPP_CLANG := -DHXCPP_CLANG -DOBJC_ARC +else + HXCPP_CLANG := +endif + +HAXE_OS := $(PLATFORM_NAME) +ifeq ("$(HAXE_OS)","appletvsimulator") + HAXE_OS := appletvsim +endif +CONFIG := $(CONFIG)-$(HAXE_OS) + +debug_print: + @echo "Make $(HAXE_BUILDS)" + +LIB_BASE := build/$(CONFIG)/::CPP_LIBPREFIX::ApplicationMain$(DEBUG) +LIB_DEST := $(DEBUG)/libApplicationMain.a + +build-haxe-i386: + @echo "Haxe simulator build: $(CONFIG)" + haxe Build.hxml -D simulator -cpp build/$(CONFIG) $(DEBUG) + cd build/$(CONFIG); export HXCPP_NO_COLOR=1; haxelib run ::CPP_BUILD_LIBRARY:: Build.xml -Dtvos -Dsimulator -DHXCPP_CPP11 $(DEF_DEBUG) $(HXCPP_CLANG) `cat Options.txt | while read LINE; do printf " -D$$LINE"; done` + cp build/$(CONFIG)/::CPP_LIBPREFIX::ApplicationMain$(DEBUG).appletvsim.a ../lib/i386$(LIB_DEST) + touch ../Classes/Main.mm + +build-haxe-x86_64: + @echo "Haxe simulator build: $(CONFIG)-64" + haxe Build.hxml -D simulator -D HXCPP_M64 -cpp build/$(CONFIG)-64 $(DEBUG) + cd build/$(CONFIG)-64; export HXCPP_NO_COLOR=1; haxelib run ::CPP_BUILD_LIBRARY:: Build.xml -Dtvos -Dsimulator -DHXCPP_M64 -DHXCPP_CPP11 $(DEF_DEBUG) $(HXCPP_CLANG) `cat Options.txt | while read LINE; do printf " -D$$LINE"; done` + cp build/$(CONFIG)-64/::CPP_LIBPREFIX::ApplicationMain$(DEBUG).appletvsim-64.a ../lib/x86_64$(LIB_DEST) + touch ../Classes/Main.mm + +build-haxe-arm64: + @echo "Haxe device build: $(CONFIG)-64" + haxe Build.hxml -D HXCPP_ARM64 -cpp build/$(CONFIG)-64 $(DEBUG) + cd build/$(CONFIG)-64; export HXCPP_NO_COLOR=1; haxelib run ::CPP_BUILD_LIBRARY:: Build.xml -Dtvos -DHXCPP_ARM64 -DHXCPP_CPP11 $(DEF_DEBUG) $(HXCPP_CLANG) `cat Options.txt | while read LINE; do printf " -D$$LINE"; done` + cp build/$(CONFIG)-64/::CPP_LIBPREFIX::ApplicationMain$(DEBUG).appletvos-64.a ../lib/arm64$(LIB_DEST) + touch ../Classes/Main.mm + +clean: + rm -rf build diff --git a/tools/CommandLineTools.hx b/tools/CommandLineTools.hx index be60b35da..6d34e3815 100644 --- a/tools/CommandLineTools.hx +++ b/tools/CommandLineTools.hx @@ -237,6 +237,15 @@ class CommandLineTools { target = Platform.FIREFOX; overrides.haxedefs.set ("firefoxos", ""); + case "appletv", "appletvos": + + target = Platform.TVOS; + + case "appletvsim": + + target = Platform.TVOS; + targetFlags.set ("simulator", ""); + default: target = cast targetName.toLowerCase (); @@ -582,6 +591,10 @@ class CommandLineTools { platform = new EmscriptenPlatform (command, project, targetFlags); + case TVOS: + + platform = new TVOSPlatform (command, project, targetFlags); + default: } @@ -746,6 +759,7 @@ class CommandLineTools { LogHelper.println (" \x1b[1mlinux\x1b[0m -- Create a Linux application"); LogHelper.println (" \x1b[1mmac\x1b[0m -- Create a Mac OS X application"); LogHelper.println (" \x1b[1mtizen\x1b[0m -- Create a Tizen application"); + LogHelper.println (" \x1b[1mtvos\x1b[0m -- Create an AppleTVOS application"); LogHelper.println (" \x1b[1mwebos\x1b[0m -- Create a webOS application"); LogHelper.println (" \x1b[1mwindows\x1b[0m -- Create a Windows application"); LogHelper.println (""); @@ -761,7 +775,7 @@ class CommandLineTools { LogHelper.println (" \x1b[3m(windows|mac|linux)\x1b[0m \x1b[1m-neko\x1b[0m -- Build with Neko instead of C++"); LogHelper.println (" \x1b[3m(mac|linux)\x1b[0m \x1b[1m-32\x1b[0m -- Compile for 32-bit instead of the OS default"); LogHelper.println (" \x1b[3m(mac|linux)\x1b[0m \x1b[1m-64\x1b[0m -- Compile for 64-bit instead of the OS default"); - LogHelper.println (" \x1b[3m(ios|blackberry|tizen|webos)\x1b[0m \x1b[1m-simulator\x1b[0m -- Target the device simulator"); + LogHelper.println (" \x1b[3m(ios|blackberry|tizen|tvos|webos)\x1b[0m \x1b[1m-simulator\x1b[0m -- Target the device simulator"); LogHelper.println (" \x1b[3m(ios)\x1b[0m \x1b[1m-simulator -ipad\x1b[0m -- Build/test for the iPad Simulator"); LogHelper.println (" \x1b[3m(android)\x1b[0m \x1b[1m-emulator\x1b[0m -- Target the device emulator"); LogHelper.println (" \x1b[3m(html5)\x1b[0m \x1b[1m-minify\x1b[0m -- Minify output using the Google Closure compiler"); diff --git a/tools/utils/PlatformSetup.hx b/tools/utils/PlatformSetup.hx index 0fbe6d743..53672dc23 100644 --- a/tools/utils/PlatformSetup.hx +++ b/tools/utils/PlatformSetup.hx @@ -475,6 +475,14 @@ class PlatformSetup { setupOpenFL (); + case "tvos": + + if (PlatformHelper.hostPlatform == Platform.MAC) { + + setupMac (); + + } + case "": switch (CommandLineTools.defaultLibrary) { @@ -1596,7 +1604,7 @@ class PlatformSetup { } createPath (path + "/lib"); - var libs = [ "android", "bada-wac", "bada", "blackberry", "ios", "mac", "qt", "tizen", "webos", "wp7" ]; + var libs = [ "android", "bada-wac", "bada", "blackberry", "ios", "mac", "qt", "tizen", "tvos", "webos", "wp7" ]; for (archive in childArchives) {