diff --git a/project.hxp b/project.hxp index ebc118339..f90d3f3e2 100644 --- a/project.hxp +++ b/project.hxp @@ -18,44 +18,45 @@ using StringTools; * and improves management of feature flag logic. */ @:nullSafety -class Project extends HXProject { - // - // METADATA - // +class Project extends HXProject +{ + // + // METADATA + // - /** - * The game's version number, as a Semantic Versioning string with no prefix. - * REMEMBER TO CHANGE THIS WHEN THE GAME UPDATES! - * You only have to change it here, the rest of the game will query this value. - */ - static final VERSION:String = "0.7.0"; + /** + * The game's version number, as a Semantic Versioning string with no prefix. + * REMEMBER TO CHANGE THIS WHEN THE GAME UPDATES! + * You only have to change it here, the rest of the game will query this value. + */ + static final VERSION:String = "0.7.0"; - /** - * The game's name. Used as the default window title. - */ - static final TITLE:String = "Friday Night Funkin'"; + /** + * The game's name. Used as the default window title. + */ + static final TITLE:String = "Friday Night Funkin'"; - /** - * The name of the generated executable file. - * For example, `"Funkin"` will create a file called `Funkin.exe`. - */ - static final EXECUTABLE_NAME:String = "Funkin"; + /** + * The name of the generated executable file. + * For example, `"Funkin"` will create a file called `Funkin.exe`. + */ + static final EXECUTABLE_NAME:String = "Funkin"; - /** - * The relative location of the source code. - */ - static final SOURCE_DIR:String = "source"; + /** + * The relative location of the source code. + */ + static final SOURCE_DIR:String = "source"; - /** - * The fully qualified class path for the game's preloader. - * Particularly important on HTML5 but we use it on all platforms. - */ - static final PRELOADER:String = "funkin.ui.transition.preload.FunkinPreloader"; + /** + * The fully qualified class path for the game's preloader. + * Particularly important on HTML5 but we use it on all platforms. + */ + static final PRELOADER:String = "funkin.ui.transition.preload.FunkinPreloader"; - /** - * A package name used for identifying the app on various app stores. - */ - static final PACKAGE_NAME:String = "me.funkin.fnf"; + /** + * A package name used for identifying the app on various app stores. + */ + static final PACKAGE_NAME:String = "me.funkin.fnf"; /** * The build's number and version code. @@ -68,11 +69,11 @@ class Project extends HXProject { */ static final MAIN_CLASS:String = "Main"; - /** - * The company name for the game. - * This appears in metadata in places I think. - */ - static final COMPANY:String = "The Funkin' Crew"; + /** + * The company name for the game. + * This appears in metadata in places I think. + */ + static final COMPANY:String = "The Funkin' Crew"; /** * Path to the Haxe script run before building the game. @@ -84,29 +85,30 @@ class Project extends HXProject { */ static final POSTBUILD_HX:String = "source/Postbuild.hx"; - /** - * Asset path globs to always exclude from asset libraries. - */ - static final EXCLUDE_ASSETS:Array = [".*", "cvs", "thumbs.db", "desktop.ini", "*.hash", "*.md"]; + /** + * Asset path globs to always exclude from asset libraries. + */ + static final EXCLUDE_ASSETS:Array = [".*", "cvs", "thumbs.db", "desktop.ini", "*.hash", "*.md"]; - /** - * Asset path globs to exclude on web platforms. - */ - static final EXCLUDE_ASSETS_WEB:Array = ["*.ogg"]; - /** - * Asset path globs to exclude on native platforms. - */ - static final EXCLUDE_ASSETS_NATIVE:Array = ["*.mp3"]; + /** + * Asset path globs to exclude on web platforms. + */ + static final EXCLUDE_ASSETS_WEB:Array = ["*.ogg"]; - /** - * `-DGITHUB_BUILD` - * If this flag is enabled, the game will use the configuration used by GitHub Actions - * to generate playtest builds to be pushed to the launcher. - * - * This is generally used to forcibly enable debugging features, - * even when the game is built in release mode for performance reasons. - */ - static final GITHUB_BUILD:FeatureFlag = "GITHUB_BUILD"; + /** + * Asset path globs to exclude on native platforms. + */ + static final EXCLUDE_ASSETS_NATIVE:Array = ["*.mp3"]; + + /** + * `-DGITHUB_BUILD` + * If this flag is enabled, the game will use the configuration used by GitHub Actions + * to generate playtest builds to be pushed to the launcher. + * + * This is generally used to forcibly enable debugging features, + * even when the game is built in release mode for performance reasons. + */ + static final GITHUB_BUILD:FeatureFlag = "GITHUB_BUILD"; /** * The app's localization languages. @@ -118,70 +120,70 @@ class Project extends HXProject { */ static final ANDROID_MINIMUM_SDK_VERSION:Int = 28; - /** + /** * The app's target android SDK version. */ static final ANDROID_TARGET_SDK_VERSION:Int = 35; - /** - * The block size of the ASTC compressed textures. + /** + * The block size of the ASTC compressed textures. * Higher block size means lower quality and lighter file size for the generated compressed textures. * possible block sizes: 4x4, 4x6, 6x6, 8x8 ... 12x12. - */ + */ static var ASTC_BLOCKSIZE:String = "12x12"; /** - * The quality of the compression process. + * The quality of the compression process. * This doesn't exactly reduce the quality of the outputted texture.. * But it changes how hard the CPU gotta work to maintin the quality and details of the image while compressing. * possible values: fastest, fast, medium, thorough, exhaustive. - */ + */ static var ASTC_QUALITY:String = "medium"; - /** - * A list of asset file globs to exclude from ASTC compression. - */ - static var astcExcludes:Array = []; + /** + * A list of asset file globs to exclude from ASTC compression. + */ + static var astcExcludes:Array = []; /** - * The contents of the user's environment config. - * Read from the `.env` file. - */ - static var envConfig:Null> = null; + * The contents of the user's environment config. + * Read from the `.env` file. + */ + static var envConfig:Null> = null; // // FEATURE FLAGS // Inverse feature flags are automatically populated. // - /** - * `-DREDIRECT_ASSETS_FOLDER` - * If this flag is enabled, the game will redirect the `assets` folder from the `export` folder - * to the `assets` folder at the root of the workspace. - * This is useful for ensuring hot reloaded changes don't get lost when rebuilding the game. - */ - static final REDIRECT_ASSETS_FOLDER:FeatureFlag = "REDIRECT_ASSETS_FOLDER"; + /** + * `-DREDIRECT_ASSETS_FOLDER` + * If this flag is enabled, the game will redirect the `assets` folder from the `export` folder + * to the `assets` folder at the root of the workspace. + * This is useful for ensuring hot reloaded changes don't get lost when rebuilding the game. + */ + static final REDIRECT_ASSETS_FOLDER:FeatureFlag = "REDIRECT_ASSETS_FOLDER"; - /** - * `-DTOUCH_HERE_TO_PLAY` - * If this flag is enabled, the game will display a prompt to the user after the preloader completes, - * requiring them to click anywhere on the screen to start the game. - * This is done to ensure that the audio context can initialize properly on HTML5. Not necessary on desktop. - */ - static final TOUCH_HERE_TO_PLAY:FeatureFlag = "TOUCH_HERE_TO_PLAY"; + /** + * `-DTOUCH_HERE_TO_PLAY` + * If this flag is enabled, the game will display a prompt to the user after the preloader completes, + * requiring them to click anywhere on the screen to start the game. + * This is done to ensure that the audio context can initialize properly on HTML5. Not necessary on desktop. + */ + static final TOUCH_HERE_TO_PLAY:FeatureFlag = "TOUCH_HERE_TO_PLAY"; - /** - * `-DPRELOAD_ALL` - * Whether to preload all asset libraries. - * Disabled on web, enabled on desktop. - */ - static final PRELOAD_ALL:FeatureFlag = "PRELOAD_ALL"; + /** + * `-DPRELOAD_ALL` + * Whether to preload all asset libraries. + * Disabled on web, enabled on desktop. + */ + static final PRELOAD_ALL:FeatureFlag = "PRELOAD_ALL"; - /** - * `-DEMBED_ASSETS` - * Whether to embed all asset libraries into the executable. - */ - static final EMBED_ASSETS:FeatureFlag = "EMBED_ASSETS"; + /** + * `-DEMBED_ASSETS` + * Whether to embed all asset libraries into the executable. + */ + static final EMBED_ASSETS:FeatureFlag = "EMBED_ASSETS"; /** * `-DEXCLUDE_ARMV7` @@ -196,184 +198,184 @@ class Project extends HXProject { */ static final HARDCODED_CREDITS:FeatureFlag = "HARDCODED_CREDITS"; - /** - * `-DTESTING_ADS` - * If this flag is enabled, mobile advertisements will use testing mode. - */ - static final TESTING_ADS:FeatureFlag = "TESTING_ADS"; - - /** - * `-DUNLOCK_EVERYTHING` - * If this flag is enabled, the game will assume all songs have been beaten and all content is available. - */ - static final UNLOCK_EVERYTHING:FeatureFlag = "UNLOCK_EVERYTHING"; - - /** - * `-DFEATURE_DEBUG_FUNCTIONS` - * If this flag is enabled, the game will have all playtester-only debugging functionality enabled. - * This includes debug hotkeys like time travel in the Play State. - * By default, enabled on debug builds or playtester builds and disabled on release builds. - */ - static final FEATURE_DEBUG_FUNCTIONS:FeatureFlag = "FEATURE_DEBUG_FUNCTIONS"; - - /** - * `-DFEATURE_DEBUG_TRACY` - * If this flag is enabled, the game will have the necessary hooks for the Tracy profiler. - * Only enable this if you're using the correct fork of Haxe to support this. - * @see https://github.com/HaxeFoundation/hxcpp/pull/1153 - */ - static final FEATURE_DEBUG_TRACY:FeatureFlag = "FEATURE_DEBUG_TRACY"; - - /** - * `-DFEATURE_LOG_TRACE` - * If this flag is enabled, the game will print debug traces to the console. - * Disable to improve performance a bunch. - */ - static final FEATURE_LOG_TRACE:FeatureFlag = "FEATURE_LOG_TRACE"; - - /** - * `-DFEATURE_DISCORD_RPC` - * If this flag is enabled, the game will enable the Discord Remote Procedure Call library. - * This is used to provide Discord Rich Presence support. - */ - static final FEATURE_DISCORD_RPC:FeatureFlag = "FEATURE_DISCORD_RPC"; - - /** - * `-DFEATURE_NEWGROUNDS` - * If this flag is enabled, the game will enable the Newgrounds library. - * This is used to provide Medal and Leaderboard support. - */ - static final FEATURE_NEWGROUNDS:FeatureFlag = "FEATURE_NEWGROUNDS"; - - /** - * `-DFEATURE_NEWGROUNDS_DEBUG` - * If this flag is enabled, the game will enable Newgrounds.io's debug functions. - * This provides additional information in requests, as well as "faking" medal and leaderboard submissions. - */ - static final FEATURE_NEWGROUNDS_DEBUG:FeatureFlag = "FEATURE_NEWGROUNDS_DEBUG"; - - /** - * `-DFEATURE_NEWGROUNDS_AUTOLOGIN` - * If this flag is enabled, the game will attempt to automatically login to Newgrounds on startup. - */ - static final FEATURE_NEWGROUNDS_AUTOLOGIN:FeatureFlag = "FEATURE_NEWGROUNDS_AUTOLOGIN"; - - /** - * `-DFEATURE_NEWGROUNDS_TESTING_MEDALS` - * If this flag is enabled, use the medal IDs from the debug test bench. - * If disabled, use the actual medal IDs from the release project on Newgrounds. - */ - static final FEATURE_NEWGROUNDS_TESTING_MEDALS:FeatureFlag = "FEATURE_NEWGROUNDS_TESTING_MEDALS"; - - /** - * `-DFEATURE_NEWGROUNDS_EVENTS` - * If this flag is enabled, the game will attempt to send events to Newgrounds when the user does stuff. - * This lets us see cool anonymized stats! It only works if the user is logged in. - */ - static final FEATURE_NEWGROUNDS_EVENTS:FeatureFlag = "FEATURE_NEWGROUNDS_EVENTS"; - - /** - * `-DFEATURE_FUNKVIS` - * If this flag is enabled, the game will enable the Funkin Visualizer library. - * This is used to provide audio visualization like Nene's speaker. - * Disabling this will make some waveforms inactive. - */ - static final FEATURE_FUNKVIS:FeatureFlag = "FEATURE_FUNKVIS"; - - /** - * `-DFEATURE_PARTIAL_SOUNDS` - * If this flag is enabled, the game will enable the FlxPartialSound library. - * This is used to provide audio previews in Freeplay. - * Disabling this will make those previews not play. - */ - static final FEATURE_PARTIAL_SOUNDS:FeatureFlag = "FEATURE_PARTIAL_SOUNDS"; - - /** - * `-DFEATURE_VIDEO_PLAYBACK` - * If this flag is enabled, the game will enable support for video playback. - * This requires the hxvlc library on desktop platforms. - */ - static final FEATURE_VIDEO_PLAYBACK:FeatureFlag = "FEATURE_VIDEO_PLAYBACK"; + /** + * `-DTESTING_ADS` + * If this flag is enabled, mobile advertisements will use testing mode. + */ + static final TESTING_ADS:FeatureFlag = "TESTING_ADS"; /** - * `-DFEATURE_FILE_DROP` + * `-DUNLOCK_EVERYTHING` + * If this flag is enabled, the game will assume all songs have been beaten and all content is available. + */ + static final UNLOCK_EVERYTHING:FeatureFlag = "UNLOCK_EVERYTHING"; + + /** + * `-DFEATURE_DEBUG_FUNCTIONS` + * If this flag is enabled, the game will have all playtester-only debugging functionality enabled. + * This includes debug hotkeys like time travel in the Play State. + * By default, enabled on debug builds or playtester builds and disabled on release builds. + */ + static final FEATURE_DEBUG_FUNCTIONS:FeatureFlag = "FEATURE_DEBUG_FUNCTIONS"; + + /** + * `-DFEATURE_DEBUG_TRACY` + * If this flag is enabled, the game will have the necessary hooks for the Tracy profiler. + * Only enable this if you're using the correct fork of Haxe to support this. + * @see https://github.com/HaxeFoundation/hxcpp/pull/1153 + */ + static final FEATURE_DEBUG_TRACY:FeatureFlag = "FEATURE_DEBUG_TRACY"; + + /** + * `-DFEATURE_LOG_TRACE` + * If this flag is enabled, the game will print debug traces to the console. + * Disable to improve performance a bunch. + */ + static final FEATURE_LOG_TRACE:FeatureFlag = "FEATURE_LOG_TRACE"; + + /** + * `-DFEATURE_DISCORD_RPC` + * If this flag is enabled, the game will enable the Discord Remote Procedure Call library. + * This is used to provide Discord Rich Presence support. + */ + static final FEATURE_DISCORD_RPC:FeatureFlag = "FEATURE_DISCORD_RPC"; + + /** + * `-DFEATURE_NEWGROUNDS` + * If this flag is enabled, the game will enable the Newgrounds library. + * This is used to provide Medal and Leaderboard support. + */ + static final FEATURE_NEWGROUNDS:FeatureFlag = "FEATURE_NEWGROUNDS"; + + /** + * `-DFEATURE_NEWGROUNDS_DEBUG` + * If this flag is enabled, the game will enable Newgrounds.io's debug functions. + * This provides additional information in requests, as well as "faking" medal and leaderboard submissions. + */ + static final FEATURE_NEWGROUNDS_DEBUG:FeatureFlag = "FEATURE_NEWGROUNDS_DEBUG"; + + /** + * `-DFEATURE_NEWGROUNDS_AUTOLOGIN` + * If this flag is enabled, the game will attempt to automatically login to Newgrounds on startup. + */ + static final FEATURE_NEWGROUNDS_AUTOLOGIN:FeatureFlag = "FEATURE_NEWGROUNDS_AUTOLOGIN"; + + /** + * `-DFEATURE_NEWGROUNDS_TESTING_MEDALS` + * If this flag is enabled, use the medal IDs from the debug test bench. + * If disabled, use the actual medal IDs from the release project on Newgrounds. + */ + static final FEATURE_NEWGROUNDS_TESTING_MEDALS:FeatureFlag = "FEATURE_NEWGROUNDS_TESTING_MEDALS"; + + /** + * `-DFEATURE_NEWGROUNDS_EVENTS` + * If this flag is enabled, the game will attempt to send events to Newgrounds when the user does stuff. + * This lets us see cool anonymized stats! It only works if the user is logged in. + */ + static final FEATURE_NEWGROUNDS_EVENTS:FeatureFlag = "FEATURE_NEWGROUNDS_EVENTS"; + + /** + * `-DFEATURE_FUNKVIS` + * If this flag is enabled, the game will enable the Funkin Visualizer library. + * This is used to provide audio visualization like Nene's speaker. + * Disabling this will make some waveforms inactive. + */ + static final FEATURE_FUNKVIS:FeatureFlag = "FEATURE_FUNKVIS"; + + /** + * `-DFEATURE_PARTIAL_SOUNDS` + * If this flag is enabled, the game will enable the FlxPartialSound library. + * This is used to provide audio previews in Freeplay. + * Disabling this will make those previews not play. + */ + static final FEATURE_PARTIAL_SOUNDS:FeatureFlag = "FEATURE_PARTIAL_SOUNDS"; + + /** + * `-DFEATURE_VIDEO_PLAYBACK` + * If this flag is enabled, the game will enable support for video playback. + * This requires the hxvlc library on desktop platforms. + */ + static final FEATURE_VIDEO_PLAYBACK:FeatureFlag = "FEATURE_VIDEO_PLAYBACK"; + + /** + * `-DFEATURE_FILE_DROP` * If this flag is enabled, the game will support dragging and dropping files onto it for various features. * Disabled on MacOS. */ static final FEATURE_FILE_DROP:FeatureFlag = "FEATURE_FILE_DROP"; /** - * `-DFEATURE_OPEN_URL` + * `-DFEATURE_OPEN_URL` * If this flag is enabled, the game will support opening URLs (such as the merch page). */ static final FEATURE_OPEN_URL:FeatureFlag = "FEATURE_OPEN_URL"; /** - * `-DFEATURE_SCREENSHOTS` + * `-DFEATURE_SCREENSHOTS` * If this flag is enabled, the game will support the screenshots feature. */ static final FEATURE_SCREENSHOTS:FeatureFlag = "FEATURE_SCREENSHOTS"; - /** + /** * `-DFEATURE_CHART_EDITOR` - * If this flag is enabled, the Chart Editor will be accessible from the debug menu. - */ - static final FEATURE_CHART_EDITOR:FeatureFlag = "FEATURE_CHART_EDITOR"; + * If this flag is enabled, the Chart Editor will be accessible from the debug menu. + */ + static final FEATURE_CHART_EDITOR:FeatureFlag = "FEATURE_CHART_EDITOR"; - /** - * `-DFEATURE_STAGE_EDITOR` + /** + * `-DFEATURE_STAGE_EDITOR` * If this flag is enabled, the Stage Editor will be accessible from the debug menu. - */ + */ static final FEATURE_STAGE_EDITOR:FeatureFlag = "FEATURE_STAGE_EDITOR"; - /** - * `-DFEATURE_RESULTS_DEBUG` - * If this flag is enabled, a debug menu for Results screen will be accessible from the debug menu. - */ - static final FEATURE_RESULTS_DEBUG:FeatureFlag = "FEATURE_RESULTS_DEBUG"; + /** + * `-DFEATURE_RESULTS_DEBUG` + * If this flag is enabled, a debug menu for Results screen will be accessible from the debug menu. + */ + static final FEATURE_RESULTS_DEBUG:FeatureFlag = "FEATURE_RESULTS_DEBUG"; - /** - * `-DFEATURE_POLYMOD_MODS` - * If this flag is enabled, the game will enable the Polymod library's support for atomic mod loading from the `./mods` folder. - * If this flag is disabled, no mods will be loaded. - */ - static final FEATURE_POLYMOD_MODS:FeatureFlag = "FEATURE_POLYMOD_MODS"; + /** + * `-DFEATURE_POLYMOD_MODS` + * If this flag is enabled, the game will enable the Polymod library's support for atomic mod loading from the `./mods` folder. + * If this flag is disabled, no mods will be loaded. + */ + static final FEATURE_POLYMOD_MODS:FeatureFlag = "FEATURE_POLYMOD_MODS"; - /** - * `-DFEATURE_GHOST_TAPPING` - * If this flag is enabled, misses will not be counted when it is not the player's turn. - * Misses are still counted when the player has notes to hit. - */ - static final FEATURE_GHOST_TAPPING:FeatureFlag = "FEATURE_GHOST_TAPPING"; + /** + * `-DFEATURE_GHOST_TAPPING` + * If this flag is enabled, misses will not be counted when it is not the player's turn. + * Misses are still counted when the player has notes to hit. + */ + static final FEATURE_GHOST_TAPPING:FeatureFlag = "FEATURE_GHOST_TAPPING"; - /** - * `-DFEATURE_HAPTICS` - * If this flag is enabled, the game provide haptic feedback vibrations. - * Works for mobile targets (Android and iOS). - */ - static final FEATURE_HAPTICS:FeatureFlag = "FEATURE_HAPTICS"; + /** + * `-DFEATURE_HAPTICS` + * If this flag is enabled, the game provide haptic feedback vibrations. + * Works for mobile targets (Android and iOS). + */ + static final FEATURE_HAPTICS:FeatureFlag = "FEATURE_HAPTICS"; - /** - * `-DFEATURE_TOUCH_CONTROLS` - * If this flag is enabled, the touch controls for the game is also enabled. - * Works with desktop builds. - */ - static final FEATURE_TOUCH_CONTROLS:FeatureFlag = "FEATURE_TOUCH_CONTROLS"; + /** + * `-DFEATURE_TOUCH_CONTROLS` + * If this flag is enabled, the touch controls for the game is also enabled. + * Works with desktop builds. + */ + static final FEATURE_TOUCH_CONTROLS:FeatureFlag = "FEATURE_TOUCH_CONTROLS"; - /** - * `-DFEATURE_COMPRESSED_TEXTURES` - * If this flag is enabled, ASTC compressed textures will be used over uncompressed PNGs. - * Compressed ASTC textures provide lower memory usage but at the cost of a higher files size. - * ASTC textures are GPU Rendered so they have a few cons: - * - Pixel Data cannot be read directly. - * - Some filters specifically the ones in openfl.filters package won't work properly because they directly modify the bitmap pixels. - * - ASync loading for GPU Textures seem bugged and results in a black texture (This is meant to be fixed soon because it's not supposed to happen.). - * One thing to note is that ASTC textures aren't available on all platforms: - * - For iOS it's available starting from phones with A8 chips, so anything from iPhone 6 and beyond has it. - * - For Android it's sorta mixed, but mostly any mid range phone from around 2018 does support ASTC. - * - For desktop it really all just depends on the GPU, but Windows with DirectX 12 should have supported. - */ - static final FEATURE_COMPRESSED_TEXTURES:FeatureFlag = "FEATURE_COMPRESSED_TEXTURES"; + /** + * `-DFEATURE_COMPRESSED_TEXTURES` + * If this flag is enabled, ASTC compressed textures will be used over uncompressed PNGs. + * Compressed ASTC textures provide lower memory usage but at the cost of a higher files size. + * ASTC textures are GPU Rendered so they have a few cons: + * - Pixel Data cannot be read directly. + * - Some filters specifically the ones in openfl.filters package won't work properly because they directly modify the bitmap pixels. + * - ASync loading for GPU Textures seem bugged and results in a black texture (This is meant to be fixed soon because it's not supposed to happen.). + * One thing to note is that ASTC textures aren't available on all platforms: + * - For iOS it's available starting from phones with A8 chips, so anything from iPhone 6 and beyond has it. + * - For Android it's sorta mixed, but mostly any mid range phone from around 2018 does support ASTC. + * - For desktop it really all just depends on the GPU, but Windows with DirectX 12 should have supported. + */ + static final FEATURE_COMPRESSED_TEXTURES:FeatureFlag = "FEATURE_COMPRESSED_TEXTURES"; /** * `-DFEATURE_MOBILE_ADVERTISEMENTS` @@ -381,17 +383,18 @@ class Project extends HXProject { */ static final FEATURE_MOBILE_ADVERTISEMENTS:FeatureFlag = "FEATURE_MOBILE_ADVERTISEMENTS"; - /** + /** * `-DFEATURE_MOBILE_IAP` * If this flag is enabled, ADs from AdMob will be disabled. */ static final FEATURE_MOBILE_IAP:FeatureFlag = "FEATURE_MOBILE_IAP"; - // - // CONFIGURATION FUNCTIONS - // + // + // CONFIGURATION FUNCTIONS + // - public function new() { + public function new() + { super(); envConfig = readEnvironmentFile("./.env"); @@ -431,21 +434,23 @@ class Project extends HXProject { } } - if (isIOS()) { + if (isIOS()) + { config.set("ios.non-exempt-encryption", "false"); - config.set("ios.team-id", "Z7G7AVNGSH"); + config.set("ios.team-id", "Z7G7AVNGSH"); - launchStoryboard = new LaunchStoryboard(); - launchStoryboard.path = "./LaunchScreen.storyboard"; + launchStoryboard = new LaunchStoryboard(); + launchStoryboard.path = "./LaunchScreen.storyboard"; } info("Done configuring project."); - } + } - /** - * Do something before building, display some ASCII or something IDK - */ - function flair() { + /** + * Do something before building, display some ASCII or something IDK + */ + function flair() + { // TODO: Implement this. info("Friday Night Funkin'"); info("Initializing build..."); @@ -455,13 +460,14 @@ class Project extends HXProject { info("Git Commit: " + getGitCommit()); info("Git Modified? " + getGitModified()); info("Display? " + isDisplay()); - } + } - /** - * Apply basic project metadata, such as the game title and version number, - * as well as info like the package name and company (used by various app stores). - */ - function configureApp() { + /** + * Apply basic project metadata, such as the game title and version number, + * as well as info like the package name and company (used by various app stores). + */ + function configureApp() + { this.meta.title = TITLE; this.meta.version = VERSION; this.meta.packageName = PACKAGE_NAME; @@ -510,141 +516,167 @@ class Project extends HXProject { // force / allow high DPI this.window.allowHighDPI = true; - if (isWeb()) { - this.window.resizable = true; + if (isWeb()) + { + this.window.resizable = true; } - if (isDesktop()) { - this.window.orientation = Orientation.LANDSCAPE; - this.window.fullscreen = false; - this.window.resizable = true; - this.window.vsync = false; + if (isDesktop()) + { + this.window.orientation = Orientation.LANDSCAPE; + this.window.fullscreen = false; + this.window.resizable = true; + this.window.vsync = false; } - if (isMobile()) { - this.window.orientation = Orientation.LANDSCAPE; - this.window.fullscreen = true; - this.window.resizable = false; - this.window.borderless = true; - this.window.width = 0; - this.window.height = 0; + if (isMobile()) + { + this.window.orientation = Orientation.LANDSCAPE; + this.window.fullscreen = true; + this.window.resizable = false; + this.window.borderless = true; + this.window.width = 0; + this.window.height = 0; } if (isAndroid()) { - if (EXCLUDE_ARMV7.isEnabled(this)) { + if (EXCLUDE_ARMV7.isEnabled(this)) + { this.excludeArchitectures.push(Architecture.ARMV7); - } + } - config.set("android.minimum-sdk-version", ANDROID_MINIMUM_SDK_VERSION); - config.set("android.target-sdk-version", ANDROID_TARGET_SDK_VERSION); + config.set("android.minimum-sdk-version", ANDROID_MINIMUM_SDK_VERSION); + config.set("android.target-sdk-version", ANDROID_TARGET_SDK_VERSION); } - } + } - /** - * Log information about the configured target platform. - */ - function displayTarget() { + /** + * Log information about the configured target platform. + */ + function displayTarget() + { // Display the target operating system. - switch (this.target) { - case Platform.WINDOWS: + switch (this.target) + { + case Platform.WINDOWS: info('Target Platform: Windows'); - case Platform.MAC: + case Platform.MAC: info('Target Platform: MacOS'); - case Platform.LINUX: + case Platform.LINUX: info('Target Platform: Linux'); - case Platform.ANDROID: + case Platform.ANDROID: info('Target Platform: Android'); - case Platform.IOS: + case Platform.IOS: info('Target Platform: IOS'); - case Platform.HTML5: + case Platform.HTML5: info('Target Platform: HTML5'); - // See lime.tools.Platform for a full list. - // case Platform.EMSCRITEN: // A WebAssembly build might be interesting... - // case Platform.AIR: - // case Platform.BLACKBERRY: - // case Platform.CONSOLE_PC: - // case Platform.FIREFOX: - // case Platform.FLASH: - // case Platform.PS3: - // case Platform.PS4: - // case Platform.TIZEN: - // case Platform.TVOS: - // case Platform.VITA: - // case Platform.WEBOS: - // case Platform.WIIU: - // case Platform.XBOX1: - default: + // See lime.tools.Platform for a full list. + // case Platform.EMSCRITEN: // A WebAssembly build might be interesting... + // case Platform.AIR: + // case Platform.BLACKBERRY: + // case Platform.CONSOLE_PC: + // case Platform.FIREFOX: + // case Platform.FLASH: + // case Platform.PS3: + // case Platform.PS4: + // case Platform.TIZEN: + // case Platform.TVOS: + // case Platform.VITA: + // case Platform.WEBOS: + // case Platform.WIIU: + // case Platform.XBOX1: + default: error('Unsupported platform (got ${target})'); } - switch (this.platformType) { - case PlatformType.DESKTOP: + switch (this.platformType) + { + case PlatformType.DESKTOP: info('Platform Type: Desktop'); - case PlatformType.MOBILE: + case PlatformType.MOBILE: info('Platform Type: Mobile'); - case PlatformType.WEB: + case PlatformType.WEB: info('Platform Type: Web'); - case PlatformType.CONSOLE: + case PlatformType.CONSOLE: info('Platform Type: Console'); - default: + default: error('Unknown platform type (got ${platformType})'); } // Print whether we are using HXCPP, HashLink, or something else. - if (isWeb()) { + if (isWeb()) + { info('Target Language: JavaScript (HTML5)'); - } else if (isHashLink()) { + } + else if (isHashLink()) + { info('Target Language: HashLink'); - } else if (isNeko()) { + } + else if (isNeko()) + { info('Target Language: Neko'); - } else if (isJava()) { + } + else if (isJava()) + { info('Target Language: Java'); - } else if (isNodeJS()) { + } + else if (isNodeJS()) + { info('Target Language: JavaScript (NodeJS)'); - } else if (isCSharp()) { + } + else if (isCSharp()) + { info('Target Language: C#'); - } else { + } + else + { info('Target Language: C++'); } - for (arch in this.architectures) { - // Display the list of target architectures. - switch (arch) { + for (arch in this.architectures) + { + // Display the list of target architectures. + switch (arch) + { case Architecture.X86: - info('Architecture: x86'); + info('Architecture: x86'); case Architecture.X64: - info('Architecture: x64'); + info('Architecture: x64'); case Architecture.ARMV5: - info('Architecture: ARMv5'); + info('Architecture: ARMv5'); case Architecture.ARMV6: - info('Architecture: ARMv6'); + info('Architecture: ARMv6'); case Architecture.ARMV7: - info('Architecture: ARMv7'); + info('Architecture: ARMv7'); case Architecture.ARMV7S: - info('Architecture: ARMv7S'); + info('Architecture: ARMv7S'); case Architecture.ARM64: - info('Architecture: ARMx64'); + info('Architecture: ARMx64'); case Architecture.MIPS: - info('Architecture: MIPS'); + info('Architecture: MIPS'); case Architecture.MIPSEL: - info('Architecture: MIPSEL'); + info('Architecture: MIPSEL'); case null: - if (!isWeb()) { + if (!isWeb()) + { error('Unsupported architecture (got null on non-web platform)'); - } else { + } + else + { info('Architecture: Web'); - } + } default: - error('Unsupported architecture (got ${arch})'); - } + error('Unsupported architecture (got ${arch})'); + } } - } + } - /** - * Apply various feature flags based on the target platform and the user-provided build flags. - */ - function configureFeatureFlags() { + /** + * Apply various feature flags based on the target platform and the user-provided build flags. + */ + function configureFeatureFlags() + { // You can explicitly override any of these. // For example, `-DGITHUB_BUILD` or `-DNO_HARDCODED_CREDITS` @@ -725,7 +757,8 @@ class Project extends HXProject { /** * Set compilation flags which are not feature flags. */ - function configureCompileDefines() { + function configureCompileDefines() + { // Enable OpenFL's error handler. Required for the crash logger. setHaxedef("openfl-enable-handle-error"); @@ -738,8 +771,9 @@ class Project extends HXProject { setHaxedef("safeMode"); // If we aren't using the Flixel debugger, strip it out. - if (FEATURE_DEBUG_FUNCTIONS.isDisabled(this)) { - setHaxedef("FLX_NO_DEBUG"); + if (FEATURE_DEBUG_FUNCTIONS.isDisabled(this)) + { + setHaxedef("FLX_NO_DEBUG"); } // Disable the built in pause screen when unfocusing the game. @@ -750,30 +784,33 @@ class Project extends HXProject { setHaxedef("haxeui_focus_out_on_click"); // Unfocus a dialog when clicking out of it setHaxedef("haxeui_dont_impose_base_class"); // Suppress a macro error - if (isRelease()) { - // Improve performance on Nape - // TODO: Do we even use Nape? - setHaxedef("NAPE_RELEASE_BUILD"); + if (isRelease()) + { + // Improve performance on Nape + // TODO: Do we even use Nape? + setHaxedef("NAPE_RELEASE_BUILD"); } // Cleaner looking compiler errors. setHaxedef("message.reporting", "pretty"); - if (FEATURE_DEBUG_TRACY.isEnabled(this)) { - setHaxedef("HXCPP_TELEMETRY"); // Enable telemetry - setHaxedef("HXCPP_TRACY"); // Enable Tracy telemetry - setHaxedef("HXCPP_TRACY_MEMORY"); // Track memory allocations - setHaxedef("HXCPP_TRACY_ON_DEMAND"); // Only collect telemetry when Tracy is open and reachable - // setHaxedef("HXCPP_TRACY_INCLUDE_CALLSTACKS"); // Inspect callstacks per zone, inflating telemetry data + if (FEATURE_DEBUG_TRACY.isEnabled(this)) + { + setHaxedef("HXCPP_TELEMETRY"); // Enable telemetry + setHaxedef("HXCPP_TRACY"); // Enable Tracy telemetry + setHaxedef("HXCPP_TRACY_MEMORY"); // Track memory allocations + setHaxedef("HXCPP_TRACY_ON_DEMAND"); // Only collect telemetry when Tracy is open and reachable + // setHaxedef("HXCPP_TRACY_INCLUDE_CALLSTACKS"); // Inspect callstacks per zone, inflating telemetry data setHaxedef("absolute-paths"); // Fix source locations so Tracy can see them } } - /** - * Set compilation flags which manage dead code elimination. - */ - function configureIncludeMacros() { + /** + * Set compilation flags which manage dead code elimination. + */ + function configureIncludeMacros() + { // Disable dead code elimination. // This prevents functions that are unused by the base game from being unavailable to HScript. addHaxeFlag("-dce no"); @@ -782,8 +819,9 @@ class Project extends HXProject { // This prevents classes that are unused by the base game from being unavailable to HScript. addHaxeMacro("include('funkin', true, ['funkin.mobile.*'])"); - if (isMobile()) { - addHaxeMacro("include('funkin.mobile')"); + if (isMobile()) + { + addHaxeMacro("include('funkin.mobile')"); } // Ensure all HaxeUI components are available at runtime. @@ -798,60 +836,70 @@ class Project extends HXProject { // Ensure all Flixel classes are available at runtime. // Explicitly ignore packages which require additional dependencies. addHaxeMacro("include('flixel', true, [ 'flixel.addons.editors.spine.*', 'flixel.addons.nape.*', 'flixel.system.macros.*', 'flixel.addons.tile.FlxRayCastTilemap' ])"); - } + } - /** - * Set compilation flags which manage bespoke build-time macros. - */ - function configureCustomMacros() { + /** + * Set compilation flags which manage bespoke build-time macros. + */ + function configureCustomMacros() + { // This macro allows addition of new functionality to existing Flixel. --> addHaxeMacro("addMetadata('@:build(funkin.util.macro.FlxMacro.buildFlxBasic())', 'flixel.FlxBasic')"); - } + } - function configureOutputDir() { + function configureOutputDir() + { // Set the output directory. Depends on the target platform and build type. var buildDir = 'export/${isDebug() ? 'debug' : 'release'}'; // we use a dedicated 'tracy' folder, since it generally needs a recompile when in use - if (FEATURE_DEBUG_TRACY.isEnabled(this)) - buildDir += "-tracy"; + if (FEATURE_DEBUG_TRACY.isEnabled(this)) buildDir += "-tracy"; // trailing slash might not be needed, works fine on macOS without it, but I haven't tested on Windows! buildDir += "/"; - info('Output directory: $buildDir'); // setenv('BUILD_DIR', buildDir); app.path = buildDir; } - function configureAndroidRelease() { - if (envConfig != null) { - keystore = new Keystore(); - keystore.path = Std.string(envConfig.get('ANDROID_KEYSTORE_PATH')); - keystore.alias = Std.string(envConfig.get('ANDROID_KEYSTORE_ALIAS')); - keystore.password = Std.string(envConfig.get('ANDROID_KEYSTORE_PASSWORD')); + function configureAndroidRelease() + { + if (envConfig != null) + { + keystore = new Keystore(); + keystore.path = Std.string(envConfig.get('ANDROID_KEYSTORE_PATH')); + keystore.alias = Std.string(envConfig.get('ANDROID_KEYSTORE_ALIAS')); + keystore.password = Std.string(envConfig.get('ANDROID_KEYSTORE_PASSWORD')); } Reflect.setField(config.get('android.manifest'), 'xmlns:tools', 'http://schemas.android.com/tools'); - final permissionsConfig:Array = ['', '']; + final permissionsConfig:Array = [ + '', + '' + ]; final xmlChildren:Null> = config.get('android.manifest').xmlChildren; - if (xmlChildren != null) { - config.get('android.manifest').xmlChildren = xmlChildren.concat(permissionsConfig); - } else { - config.get('android.manifest').xmlChildren = permissionsConfig; + if (xmlChildren != null) + { + config.get('android.manifest').xmlChildren = xmlChildren.concat(permissionsConfig); + } + else + { + config.get('android.manifest').xmlChildren = permissionsConfig; } - if (isBundle()) { + if (isBundle()) + { config.set("android.gradle-build-directory", "bin-bundle"); } - } + } - function configurePolymod() { + function configurePolymod() + { // The file extension to use for script files. setHaxedef("POLYMOD_SCRIPT_EXT", ".hscript"); // Which asset library to use for scripts. @@ -867,13 +915,15 @@ class Project extends HXProject { // Determines the file in the mod folder used for the icon. setHaxedef("POLYMOD_MOD_ICON_FILE", "_polymod_icon.png"); - if (isDebug()) { + if (isDebug()) + { // Turns on additional debug logging. setHaxedef("POLYMOD_DEBUG"); } } - function configureHaxelibs() { + function configureHaxelibs() + { // Don't enforce // addHaxelib('lime'); // Game engine backend // addHaxelib('openfl'); // Game engine backend @@ -896,59 +946,73 @@ class Project extends HXProject { addHaxelib('thx.core'); // General utility library, "the lodash of Haxe" addHaxelib('thx.semver'); // Version string handling - if (isDebug()) { - addHaxelib('hxcpp-debug-server'); // VSCode debug support + if (isDebug()) + { + addHaxelib('hxcpp-debug-server'); // VSCode debug support } - if (isDesktop() || isMobile() && !isHashLink() && FEATURE_VIDEO_PLAYBACK.isEnabled(this)) { + if (isDesktop() || isMobile() && !isHashLink() && FEATURE_VIDEO_PLAYBACK.isEnabled(this)) + { // hxvlc doesn't function on HashLink or non-desktop platforms - // It's also unnecessary if video playback is disabled + // It's also unnecessary if video playback is disabled addHaxelib('hxvlc'); // Video playback } - if (isAndroid()) { + if (isAndroid()) + { addHaxelib('extension-androidtools'); // Android Functions } - if (FEATURE_DISCORD_RPC.isEnabled(this)) { - addHaxelib('hxdiscord_rpc'); // Discord API + if (FEATURE_DISCORD_RPC.isEnabled(this)) + { + addHaxelib('hxdiscord_rpc'); // Discord API } - if (FEATURE_NEWGROUNDS.isEnabled(this)) { - addHaxelib('newgrounds'); // Newgrounds API + if (FEATURE_NEWGROUNDS.isEnabled(this)) + { + addHaxelib('newgrounds'); // Newgrounds API } - if (FEATURE_FUNKVIS.isEnabled(this)) { - addHaxelib('funkin.vis'); // Audio visualization + if (FEATURE_FUNKVIS.isEnabled(this)) + { + addHaxelib('funkin.vis'); // Audio visualization addHaxelib('grig.audio'); // Audio data utilities } - if (FEATURE_PARTIAL_SOUNDS.isEnabled(this)) { + if (FEATURE_PARTIAL_SOUNDS.isEnabled(this)) + { addHaxelib('FlxPartialSound'); // Partial sound } - if (FEATURE_MOBILE_ADVERTISEMENTS.isEnabled(this)) { + if (FEATURE_MOBILE_ADVERTISEMENTS.isEnabled(this)) + { addHaxelib('extension-admob'); // Ads Extension } - if (FEATURE_HAPTICS.isEnabled(this)) { - addHaxelib('extension-haptics'); // Haptic feedback + if (FEATURE_HAPTICS.isEnabled(this)) + { + addHaxelib('extension-haptics'); // Haptic feedback } - if (FEATURE_MOBILE_IAP.isEnabled(this)) { - addHaxelib('extension-iapcore'); // In-app purchases Extension + if (FEATURE_MOBILE_IAP.isEnabled(this)) + { + addHaxelib('extension-iapcore'); // In-app purchases Extension } } - function configureAssets() { + function configureAssets() + { var exclude = EXCLUDE_ASSETS.concat(isWeb() ? EXCLUDE_ASSETS_WEB : EXCLUDE_ASSETS_NATIVE); var shouldPreload = PRELOAD_ALL.isEnabled(this); var shouldEmbed = EMBED_ASSETS.isEnabled(this); - if (shouldEmbed) { - info('Embedding assets into executable...'); - } else { - info('Including assets alongside executable...'); + if (shouldEmbed) + { + info('Embedding assets into executable...'); + } + else + { + info('Including assets alongside executable...'); } // Default asset library @@ -1000,7 +1064,7 @@ class Project extends HXProject { addAsset("LICENSE.md", "LICENSE.md", "art", shouldEmbedArt); info('Done configuring assets.'); - } + } /** * Configure the application's favicon and executable icon. @@ -1008,12 +1072,15 @@ class Project extends HXProject { function configureIcons() { info('Configuring application icons...'); - if (!isIOS()) { + if (!isIOS()) + { addIcon("art/icon16.png", 16); addIcon("art/icon32.png", 32); addIcon("art/icon64.png", 64); addIcon("art/iconOG.png"); - } else { + } + else + { addIcon("icon16_noalpha.png", 16); addIcon("art/icon32_noalpha.png", 32); addIcon("art/icon64_noalpha.png", 64); @@ -1022,103 +1089,123 @@ class Project extends HXProject { info('Done configuring icons.'); } - /** - * Configure the platforms' Ad Mob application keys. - */ - function configureAdMobKeys() { + /** + * Configure the platforms' Ad Mob application keys. + */ + function configureAdMobKeys() + { if (envConfig == null) return; if (isAndroid()) { - setenv("ADMOB_APPID", Std.string(envConfig.get('ANDROID_ADMOB_APP_ID'))); + setenv("ADMOB_APPID", Std.string(envConfig.get('ANDROID_ADMOB_APP_ID'))); } if (isIOS()) { - setenv("ADMOB_APPID", Std.string(envConfig.get('IOS_ADMOB_APP_ID'))); + setenv("ADMOB_APPID", Std.string(envConfig.get('IOS_ADMOB_APP_ID'))); } - } + } - // - // HELPER FUNCTIONS - // Easy functions to make the code more readable. - // + // + // HELPER FUNCTIONS + // Easy functions to make the code more readable. + // - public function isWeb():Bool { + public function isWeb():Bool + { return this.platformType == PlatformType.WEB; - } + } - public function isMobile():Bool { + public function isMobile():Bool + { return this.platformType == PlatformType.MOBILE; - } + } - public function isDesktop():Bool { + public function isDesktop():Bool + { return this.platformType == PlatformType.DESKTOP; - } + } - public function isConsole():Bool { + public function isConsole():Bool + { return this.platformType == PlatformType.CONSOLE; - } + } - public function is32Bit():Bool { + public function is32Bit():Bool + { return this.architectures.contains(Architecture.X86); - } + } - public function is64Bit():Bool { + public function is64Bit():Bool + { return this.architectures.contains(Architecture.X64); - } + } - public function isWindows():Bool { + public function isWindows():Bool + { return this.target == Platform.WINDOWS; - } + } - public function isMac():Bool { + public function isMac():Bool + { return this.target == Platform.MAC; - } + } - public function isLinux():Bool { + public function isLinux():Bool + { return this.target == Platform.LINUX; - } + } - public function isAndroid():Bool { + public function isAndroid():Bool + { return this.target == Platform.ANDROID; - } + } - public function isIOS():Bool { + public function isIOS():Bool + { return this.target == Platform.IOS; - } + } - public function isHashLink():Bool { + public function isHashLink():Bool + { return this.targetFlags.exists("hl"); } - public function isNeko():Bool { + public function isNeko():Bool + { return this.targetFlags.exists("neko"); } - public function isJava():Bool { + public function isJava():Bool + { return this.targetFlags.exists("java"); } - public function isNodeJS():Bool { + public function isNodeJS():Bool + { return this.targetFlags.exists("nodejs"); } - public function isCSharp():Bool { + public function isCSharp():Bool + { return this.targetFlags.exists("cs"); } - public function isDisplay():Bool { + public function isDisplay():Bool + { return this.command == "display"; } - public function isDebug():Bool { + public function isDebug():Bool + { return this.debug; - } + } - public function isRelease():Bool { + public function isRelease():Bool + { return !isDebug(); - } + } public function isBundle():Bool { @@ -1130,55 +1217,63 @@ class Project extends HXProject { return this.haxedefs.get(name); } - public function setHaxedef(name:String, ?value:String):Void { + public function setHaxedef(name:String, ?value:String):Void + { if (value == null) value = ""; this.haxedefs.set(name, value); } - public function unsetHaxedef(name:String):Void { + public function unsetHaxedef(name:String):Void + { this.haxedefs.remove(name); } - public function getDefine(name:String):Null { + public function getDefine(name:String):Null + { return this.defines.get(name); - } + } - public function hasDefine(name:String):Bool { + public function hasDefine(name:String):Bool + { return this.defines.exists(name); - } + } - /** - * Add a library to the list of dependencies for the project. - * @param name The name of the library to add. - * @param version The version of the library to add. Optional. - */ - public function addHaxelib(name:String, version:String = ""):Void { + /** + * Add a library to the list of dependencies for the project. + * @param name The name of the library to add. + * @param version The version of the library to add. Optional. + */ + public function addHaxelib(name:String, version:String = ""):Void + { this.haxelibs.push(new Haxelib(name, version)); - } + } - /** - * Add a `haxeflag` to the project. - */ - public function addHaxeFlag(value:String):Void { + /** + * Add a `haxeflag` to the project. + */ + public function addHaxeFlag(value:String):Void + { this.haxeflags.push(value); - } + } - /** - * Call a Haxe build macro. - */ - public function addHaxeMacro(value:String):Void { + /** + * Call a Haxe build macro. + */ + public function addHaxeMacro(value:String):Void + { addHaxeFlag('--macro ${value}'); - } + } - /** - * Add an icon to the project. - * @param icon The path to the icon. - * @param size The size of the icon. Optional. - */ - public function addIcon(icon:String, ?size:Int):Void { + /** + * Add an icon to the project. + * @param icon The path to the icon. + * @param size The size of the icon. Optional. + */ + public function addIcon(icon:String, ?size:Int):Void + { this.icons.push(new Icon(icon, size)); - } + } /** * Add an asset to the game build. @@ -1193,14 +1288,13 @@ class Project extends HXProject { // path, rename, type, embed, setDefaults if (Path.extension(path) == 'png' && FEATURE_COMPRESSED_TEXTURES.isEnabled(this)) { - final astcPath:String = "astc-textures/" + path.substr(0, path.length - 3) + "astc"; - if (!isASTCExcluded(path) && FileSystem.exists(astcPath)) - { + final astcPath:String = "astc-textures/" + path.substr(0, path.length - 3) + "astc"; + if (!isASTCExcluded(path) && FileSystem.exists(astcPath)) + { path = astcPath; - if (rename != null) - rename = rename.substr(0, rename.length - 3) + "astc"; - } + if (rename != null) rename = rename.substr(0, rename.length - 3) + "astc"; + } } var asset = new Asset(path, rename, null, embed, true); @@ -1227,7 +1321,8 @@ class Project extends HXProject { * @param embed Whether to embed the assets in the executable. * @param padName The name of the Play Assets Delivery that this asset path will be added to. (Android only) */ - public function addAssetPath(path:String, ?rename:String, library:String, ?include:Array, ?exclude:Array, embed:Bool = false, ?padName:String):Void + public function addAssetPath(path:String, ?rename:String, library:String, ?include:Array, ?exclude:Array, embed:Bool = false, + ?padName:String):Void { // Argument parsing. if (path == "") return; @@ -1240,64 +1335,80 @@ class Project extends HXProject { if (targetPath != "") targetPath += "/"; // Validate path. - if (!sys.FileSystem.exists(path)) { - error('Could not find asset path "${path}".'); - } else if (!sys.FileSystem.isDirectory(path)) { - error('Could not parse asset path "${path}", expected a directory.'); - } else { - // info(' Found asset path "${path}".'); + if (!sys.FileSystem.exists(path)) + { + error('Could not find asset path "${path}".'); + } + else if (!sys.FileSystem.isDirectory(path)) + { + error('Could not parse asset path "${path}", expected a directory.'); + } + else + { + // info(' Found asset path "${path}".'); } - for (file in sys.FileSystem.readDirectory(path)) { - if (sys.FileSystem.isDirectory('${path}/${file}')) { + for (file in sys.FileSystem.readDirectory(path)) + { + if (sys.FileSystem.isDirectory('${path}/${file}')) + { // Attempt to recursively add all assets in the directory. - if (this.filter(file, ["*"], exclude)) { - addAssetPath('${path}/${file}', '${targetPath}${file}', library, include, exclude, embed, padName); + if (this.filter(file, ["*"], exclude)) + { + addAssetPath('${path}/${file}', '${targetPath}${file}', library, include, exclude, embed, padName); } - } else { - if (this.filter(file, include, exclude)) { - addAsset('${path}/${file}', '${targetPath}${file}', library, embed, padName); + } + else + { + if (this.filter(file, include, exclude)) + { + addAsset('${path}/${file}', '${targetPath}${file}', library, embed, padName); } - } + } } - } + } - /** - * Add an asset library to the game build. - * @param name The name of the library. - * @param embed - * @param preload - */ - public function addAssetLibrary(name:String, embed:Bool = false, preload:Bool = false):Void { + /** + * Add an asset library to the game build. + * @param name The name of the library. + * @param embed + * @param preload + */ + public function addAssetLibrary(name:String, embed:Bool = false, preload:Bool = false):Void + { // sourcePath, name, type, embed, preload, generate, prefix var sourcePath = ''; this.libraries.push(new Library(sourcePath, name, null, embed, preload, false, "")); - } + } - // - // PROCESS FUNCTIONS - // + // + // PROCESS FUNCTIONS + // /** * A CLI command to run a command in the shell. */ - public function buildCLICommand(cmd:String):CLICommand { + public function buildCLICommand(cmd:String):CLICommand + { return CommandHelper.fromSingleString(cmd); } /** * A CLI command to run a Haxe script via `--interp`. */ - public function buildHaxeCLICommand(path:String):CLICommand { + public function buildHaxeCLICommand(path:String):CLICommand + { return CommandHelper.interpretHaxe(path); } - public function getGitCommit():String { + public function getGitCommit():String + { // Cannibalized from GitCommit.hx var process = new sys.io.Process('git', ['rev-parse', 'HEAD']); - if (process.exitCode() != 0) { - var message = process.stderr.readAll().toString(); - error('[ERROR] Could not determine current git commit; is this a proper Git repository?'); + if (process.exitCode() != 0) + { + var message = process.stderr.readAll().toString(); + error('[ERROR] Could not determine current git commit; is this a proper Git repository?'); } var commitHash:String = process.stdout.readLine(); @@ -1306,15 +1417,17 @@ class Project extends HXProject { process.close(); return commitHashSplice; - } + } - public function getGitBranch():String { + public function getGitBranch():String + { // Cannibalized from GitCommit.hx var branchProcess = new sys.io.Process('git', ['rev-parse', '--abbrev-ref', 'HEAD']); - if (branchProcess.exitCode() != 0) { - var message = branchProcess.stderr.readAll().toString(); - error('Could not determine current git branch; is this a proper Git repository?'); + if (branchProcess.exitCode() != 0) + { + var message = branchProcess.stderr.readAll().toString(); + error('Could not determine current git branch; is this a proper Git repository?'); } var branchName:String = branchProcess.stdout.readLine(); @@ -1322,113 +1435,133 @@ class Project extends HXProject { branchProcess.close(); return branchName; - } + } - public function getGitModified():Bool { + public function getGitModified():Bool + { var branchProcess = new sys.io.Process('git', ['status', '--porcelain']); - if (branchProcess.exitCode() != 0) { - var message = branchProcess.stderr.readAll().toString(); - error('Could not determine current git status; is this a proper Git repository?'); + if (branchProcess.exitCode() != 0) + { + var message = branchProcess.stderr.readAll().toString(); + error('Could not determine current git status; is this a proper Git repository?'); } var output:String = ''; - try { - output = branchProcess.stdout.readLine(); - } catch (e) { - if (e.message == 'Eof') { + try + { + output = branchProcess.stdout.readLine(); + } + catch (e) + { + if (e.message == 'Eof') + { // Do nothing. // Eof = No output. - } else { + } + else + { // Rethrow other exceptions. throw e; - } + } } branchProcess.close(); return output.length > 0; - } + } - // - // LOGGING FUNCTIONS - // + // + // LOGGING FUNCTIONS + // - /** - * Display an error message. This should stop the build process. - */ - public function error(message:String):Void { + /** + * Display an error message. This should stop the build process. + */ + public function error(message:String):Void + { Log.error('${message}'); - } + } - /** - * Display an info message. This should not interfere with the build process. - */ - public function info(message:String):Void { - if(command != "display") { Log.info('[INFO] ${message}'); } - } + /** + * Display an info message. This should not interfere with the build process. + */ + public function info(message:String):Void + { + if (command != "display") + { + Log.info('[INFO] ${message}'); + } + } - /** - * Read the contents of the `.env` file into a map. - * This is used to store secret keys as environment variables. - */ - public function readEnvironmentFile(file:String):Null> { - if (!FileSystem.exists(file)) { - info('Environment file does not exist: ${file}'); - return null; + /** + * Read the contents of the `.env` file into a map. + * This is used to store secret keys as environment variables. + */ + public function readEnvironmentFile(file:String):Null> + { + if (!FileSystem.exists(file)) + { + info('Environment file does not exist: ${file}'); + return null; } var envFile = File.getContent(file); - if (envFile == null) { - info('Failed to parse environment file: ${file}'); - return null; + if (envFile == null) + { + info('Failed to parse environment file: ${file}'); + return null; } var env = new Map(); - for (line in envFile.split('\n')) { - if (line == "" || line.startsWith("#")) continue; + for (line in envFile.split('\n')) + { + if (line == "" || line.startsWith("#")) continue; - var parts = line.split('='); - if (parts.length != 2) continue; + var parts = line.split('='); + if (parts.length != 2) continue; - env.set(parts[0], parts[1]); + env.set(parts[0], parts[1]); } return env; - } + } - public function readASTCExclusion():Void { + public function readASTCExclusion():Void + { astcExcludes = File.getContent('./compression-excludes.txt').trim().split('\n'); for (i in 0...astcExcludes.length) - astcExcludes[i] = astcExcludes[i].trim(); - } + astcExcludes[i] = astcExcludes[i].trim(); + } - public function isASTCExcluded(filePath:String):Bool { - for (exclusion in astcExcludes) { - if (exclusion.endsWith("/*")) { + public function isASTCExcluded(filePath:String):Bool + { + for (exclusion in astcExcludes) + { + if (exclusion.endsWith("/*")) + { var normalizedFilePath = Path.normalize(filePath); var normalizedExclusion = Path.normalize(exclusion.substr(0, exclusion.length - 2)); - if (normalizedFilePath.startsWith(normalizedExclusion)) - return true; + if (normalizedFilePath.startsWith(normalizedExclusion)) return true; } - else if (exclusion.endsWith("/")) { + else if (exclusion.endsWith("/")) + { var normalizedExclusion = Path.normalize(exclusion); var fileDirectory = Path.directory(Path.normalize(filePath)); - if (fileDirectory == normalizedExclusion) - return true; + if (fileDirectory == normalizedExclusion) return true; } - else { - if (filePath == exclusion) - return true; + else + { + if (filePath == exclusion) return true; } } return false; - } + } public function runASTCCompressor():Void { @@ -1451,97 +1584,117 @@ class Project extends HXProject { * An object representing a feature flag, which can be enabled or disabled. * Includes features such as automatic generation of compile defines and inversion. */ -abstract FeatureFlag(String) { - static final INVERSE_PREFIX:String = "NO_"; +abstract FeatureFlag(String) +{ + static final INVERSE_PREFIX:String = "NO_"; - public function new(input:String) { + public function new(input:String) + { this = input; - } + } - @:from - public static function fromString(input:String):FeatureFlag { + @:from + public static function fromString(input:String):FeatureFlag + { return new FeatureFlag(input); - } + } - /** - * Enable/disable a feature flag if it is unset, and handle the inverse flag. - * Doesn't override a feature flag that was set explicitly. - * @param enableByDefault Whether to enable this feature flag if it is unset. - */ - public function apply(project:Project, enableByDefault:Bool = false):Void { + /** + * Enable/disable a feature flag if it is unset, and handle the inverse flag. + * Doesn't override a feature flag that was set explicitly. + * @param enableByDefault Whether to enable this feature flag if it is unset. + */ + public function apply(project:Project, enableByDefault:Bool = false):Void + { // TODO: Name this function better? - if (isEnabled(project)) { - // If this flag was already enabled, disable the inverse. - project.info('Enabling feature flag ${this}'); - getInverse().disable(project, false); - } else if (getInverse().isEnabled(project)) { - // If the inverse flag was already enabled, disable this flag. - project.info('Disabling feature flag ${this}'); - disable(project, false); - } else { - if (enableByDefault) { + if (isEnabled(project)) + { + // If this flag was already enabled, disable the inverse. + project.info('Enabling feature flag ${this}'); + getInverse().disable(project, false); + } + else if (getInverse().isEnabled(project)) + { + // If the inverse flag was already enabled, disable this flag. + project.info('Disabling feature flag ${this}'); + disable(project, false); + } + else + { + if (enableByDefault) + { // Enable this flag if it was unset, and disable the inverse. project.info('Enabling feature flag ${this}'); enable(project, true); - } else { + } + else + { // Disable this flag if it was unset, and enable the inverse. project.info('Disabling feature flag ${this}'); disable(project, true); - } + } } - } + } - /** - * Enable this feature flag by setting the appropriate compile define. - * - * @param project The project to modify. - * @param andInverse Also disable the feature flag's inverse. - */ - public function enable(project:Project, andInverse:Bool = true) { + /** + * Enable this feature flag by setting the appropriate compile define. + * + * @param project The project to modify. + * @param andInverse Also disable the feature flag's inverse. + */ + public function enable(project:Project, andInverse:Bool = true) + { project.setHaxedef(this, ""); - if (andInverse) { - getInverse().disable(project, false); + if (andInverse) + { + getInverse().disable(project, false); } - } + } - /** - * Disable this feature flag by removing the appropriate compile define. - * - * @param project The project to modify. - * @param andInverse Also enable the feature flag's inverse. - */ - public function disable(project:Project, andInverse:Bool = true) { + /** + * Disable this feature flag by removing the appropriate compile define. + * + * @param project The project to modify. + * @param andInverse Also enable the feature flag's inverse. + */ + public function disable(project:Project, andInverse:Bool = true) + { project.unsetHaxedef(this); - if (andInverse) { - getInverse().enable(project, false); + if (andInverse) + { + getInverse().enable(project, false); } - } + } - /** - * Query if this feature flag is enabled. - * @param project The project to query. - */ - public function isEnabled(project:Project):Bool { + /** + * Query if this feature flag is enabled. + * @param project The project to query. + */ + public function isEnabled(project:Project):Bool + { // Check both Haxedefs and Defines for this flag. return project.haxedefs.exists(this) || project.defines.exists(this); - } + } - /** - * Query if this feature flag's inverse is enabled. - */ - public function isDisabled(project:Project):Bool { + /** + * Query if this feature flag's inverse is enabled. + */ + public function isDisabled(project:Project):Bool + { return getInverse().isEnabled(project); - } + } - /** - * Return the inverse of this feature flag. - * @return A new feature flag that is the inverse of this one. - */ - public function getInverse():FeatureFlag { - if (this.startsWith(INVERSE_PREFIX)) { - return this.substring(INVERSE_PREFIX.length); + /** + * Return the inverse of this feature flag. + * @return A new feature flag that is the inverse of this one. + */ + public function getInverse():FeatureFlag + { + if (this.startsWith(INVERSE_PREFIX)) + { + return this.substring(INVERSE_PREFIX.length); } return INVERSE_PREFIX + this; - } + } }