diff --git a/.efrocachemap b/.efrocachemap index dc12c592..9c6ef01f 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -421,7 +421,7 @@ "build/assets/ba_data/audio/zoeOw.ogg": "74befe45a8417e95b6a2233c51992a26", "build/assets/ba_data/audio/zoePickup01.ogg": "48ab8cddfcde36a750856f3f81dd20c8", "build/assets/ba_data/audio/zoeScream01.ogg": "2b468aedfa8741090247f04eb9e6df55", - "build/assets/ba_data/data/langdata.json": "02522e0d2593baf2e57a97fbfbfe3368", + "build/assets/ba_data/data/langdata.json": "229f9ecdddd777a0be2471979a0a01d6", "build/assets/ba_data/data/languages/arabic.json": "e0001d8542c904bc3c98a174f256efd9", "build/assets/ba_data/data/languages/belarussian.json": "7fe38341815ca6ff4d95224196e7a67e", "build/assets/ba_data/data/languages/chinese.json": "4e2f4f1f38216940953fcbee4da1563e", @@ -430,31 +430,31 @@ "build/assets/ba_data/data/languages/czech.json": "93c5fe0d884d95435da6c675f64e30e0", "build/assets/ba_data/data/languages/danish.json": "3fd69080783d5c9dcc0af737f02b6f1e", "build/assets/ba_data/data/languages/dutch.json": "22b44a33bf81142ba2befad14eb5746e", - "build/assets/ba_data/data/languages/english.json": "fe32cbe79483153db283e363da039a7a", + "build/assets/ba_data/data/languages/english.json": "bd43b77b1ccca059573acbde148b4767", "build/assets/ba_data/data/languages/esperanto.json": "0e397cfa5f3fb8cef5f4a64f21cda880", "build/assets/ba_data/data/languages/filipino.json": "afbda3adf14555e1567ee63c32e340e7", "build/assets/ba_data/data/languages/french.json": "49ff6d211537b8003b8241438dca661d", "build/assets/ba_data/data/languages/german.json": "450fa41ae264f29a5d1af22143d0d0ad", - "build/assets/ba_data/data/languages/gibberish.json": "00a9f70bccdfa407043e69a42e5b944c", + "build/assets/ba_data/data/languages/gibberish.json": "9aae526303a22372fe9b4cf1781520ef", "build/assets/ba_data/data/languages/greek.json": "287c0ec437b38772284ef9d3e4fb2fc3", - "build/assets/ba_data/data/languages/hindi.json": "8ea0c58a44a24edb131d0e53b074d1f6", + "build/assets/ba_data/data/languages/hindi.json": "8848f6b0caec0fcf9d85bc6e683809ec", "build/assets/ba_data/data/languages/hungarian.json": "796a290a8c44a1e7635208c2ff5fdc6e", "build/assets/ba_data/data/languages/indonesian.json": "97657eb2ab75d821045387b6d7a2b52d", "build/assets/ba_data/data/languages/italian.json": "cda5760f247500657722c279bc2f2bc7", "build/assets/ba_data/data/languages/korean.json": "ca1122a9ee551da3f75ae632012bd0e2", "build/assets/ba_data/data/languages/malay.json": "832562ce997fc70704b9234c95fb2e38", "build/assets/ba_data/data/languages/persian.json": "4f448b29ba04f2b789329600cb7f9ab7", - "build/assets/ba_data/data/languages/polish.json": "8bb8f7baa5efcf6cdd627140d209c2b2", - "build/assets/ba_data/data/languages/portuguese.json": "c738cc76396305060d4f94cb77db5bec", + "build/assets/ba_data/data/languages/polish.json": "b9a58b70ed5e99d8b7fa2392b2eb0cda", + "build/assets/ba_data/data/languages/portuguese.json": "556af4e8170356ad239412e1743e20d5", "build/assets/ba_data/data/languages/romanian.json": "aeebdd54f65939c2facc6ac50c117826", - "build/assets/ba_data/data/languages/russian.json": "cdaac43afde13ab622babe403b9858a4", + "build/assets/ba_data/data/languages/russian.json": "e120993371f52edd2d99f2236188933c", "build/assets/ba_data/data/languages/serbian.json": "d7452dd72ac0e51680cb39b5ebaa1c69", "build/assets/ba_data/data/languages/slovak.json": "27962d53dc3f7dd4e877cd40faafeeef", - "build/assets/ba_data/data/languages/spanish.json": "f73b0d4d534f030f95c00385bb06cbc1", + "build/assets/ba_data/data/languages/spanish.json": "80ea58bd3295a0252b7fdac9154aa22f", "build/assets/ba_data/data/languages/swedish.json": "5142a96597d17d8344be96a603da64ac", "build/assets/ba_data/data/languages/tamil.json": "b4de1a2851afe4869c82e9acd94cd89c", "build/assets/ba_data/data/languages/thai.json": "77755219bbf5fb7eea0d6b226684f403", - "build/assets/ba_data/data/languages/turkish.json": "326bcc54b69cb6a1bda4abb732f9f56f", + "build/assets/ba_data/data/languages/turkish.json": "b1e491b70cec59cfa1057b8c5e7801b2", "build/assets/ba_data/data/languages/ukrainian.json": "e5c861187c4c6db37d1a033f4ef3dd5a", "build/assets/ba_data/data/languages/venetian.json": "9fe1a58d9e5dfb00f31ce3b2eb9993f4", "build/assets/ba_data/data/languages/vietnamese.json": "921cd1e50f60fe3e101f246e172750ba", @@ -4056,50 +4056,50 @@ "build/assets/windows/Win32/ucrtbased.dll": "2def5335207d41b21b9823f6805997f1", "build/assets/windows/Win32/vc_redist.x86.exe": "b08a55e2e77623fe657bea24f223a3ae", "build/assets/windows/Win32/vcruntime140d.dll": "865b2af4d1e26a1a8073c89acb06e599", - "build/prefab/full/linux_arm64_gui/debug/ballisticakit": "abab400c9116a3825a5bb90d31ebe3b7", - "build/prefab/full/linux_arm64_gui/release/ballisticakit": "5641927c9074dc4e759d3761a42dd3cc", - "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "113eb282e6f5d7a082f8dfc2f19db078", - "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "cdee95f3c6bc21f7ff3016ff3c719178", - "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "a20fb4fd648a6e66bc5395f48796a5b8", - "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "be599ec099f2a1f4109ceda6a05a8c62", - "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "f22486755f0c0f2b106926d5a9ee97c9", - "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "ca382a4fa963a50af3675c811526ba76", - "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "00f392858c451a8d395c7cd7958f7af7", - "build/prefab/full/mac_arm64_gui/release/ballisticakit": "1f66a8a8f8d8041667a4b6cb71baffbd", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "c4153466b51a30b444d2350156a9fbb7", - "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "91c3c980de79faee6854c1c88408bd0c", - "build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "143bfda2b349f5505068dd874802413f", - "build/prefab/full/mac_x86_64_gui/release/ballisticakit": "293cb9525c241d1dda224461db34b631", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "6dc3c9f9637d3f4e16d0a9093a59b1e7", - "build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "bbce1ea501fc419f6d83882b2c283eb0", - "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "cceac583899afd4e97e4fd7dea2611fb", - "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "6ad184e11ae0b85137b37bbf2a75b331", - "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "a1b15a12b361ba60cead3f8045bbd545", - "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "1949706b21961783d428034b03982521", - "build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "dc8d1e0f82fe799cbbacfd89bbf04498", - "build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "c6be3757c2ee85a7f4f8a66d327a24a0", - "build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "dc8d1e0f82fe799cbbacfd89bbf04498", - "build/prefab/lib/linux_arm64_server/release/libballisticaplus.a": "c6be3757c2ee85a7f4f8a66d327a24a0", - "build/prefab/lib/linux_x86_64_gui/debug/libballisticaplus.a": "859470a05f3d968031ae9843bdf818c3", - "build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "bd8926fb9d12b7f4972870efea006d54", - "build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "859470a05f3d968031ae9843bdf818c3", - "build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "bd8926fb9d12b7f4972870efea006d54", - "build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "11eeb74f8cb307ed673768c0629ca302", - "build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "5f6ed20081020d554b1866389136b712", - "build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "11eeb74f8cb307ed673768c0629ca302", - "build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "5f6ed20081020d554b1866389136b712", - "build/prefab/lib/mac_x86_64_gui/debug/libballisticaplus.a": "d9407d62ab82cdf25e970e3fde8971fa", - "build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "856a05aadbe4b75baee3048296aa8eef", - "build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "c5eb4a9161b68775876c4d19bff1cc1b", - "build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "856a05aadbe4b75baee3048296aa8eef", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "f297a236664bf55b81f19e5c69d81b64", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "9eb9f987869a87ab1280d70c8069df6a", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "f269cab8edb50101fff358735255151d", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "2631845123a868a98ef1156c786d1cff", - "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "a5f59a9cd23e6b3ec18834a169d6a6e0", - "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "35b984001137f4bde7dc7bf4576da320", - "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "cf974280198d48a836b0f433ebf84b68", - "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "97260251b62485cc95da5b41aa90f9ca", + "build/prefab/full/linux_arm64_gui/debug/ballisticakit": "19f758d463a96209e647e651c611d1b9", + "build/prefab/full/linux_arm64_gui/release/ballisticakit": "49506eff59a21d3cfb6fc55db4edeeae", + "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "1cd9dfdc832995ba84386803c2eb3d7e", + "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "f9786e628a44b5d14dbd842e29f37b4d", + "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "a21e3ab1ec336eb8f957deeee96926e4", + "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "e93a34b23530cf29d443529af6a42d4c", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "2ecbe46fb8b6ddb96340e35e53d7e73e", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "37d5f679d73736214f8d12980028511d", + "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "b09fbdc4f44383ed0111ac19b13371dd", + "build/prefab/full/mac_arm64_gui/release/ballisticakit": "b8332772459f472a559e05002ce6921c", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "5e0cfb078710084739280d17cbc86732", + "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "6b25f48718896540a46e9aef9f993c51", + "build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "940db05971335a1a8a84e96adc948a84", + "build/prefab/full/mac_x86_64_gui/release/ballisticakit": "98ab1223c634600b44e2c407b3cee6e2", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "3c1be40378854bffa24a2e118979e252", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "a1a8830a0892b6a8ed8827241cf848aa", + "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "27b755855aa9ebe54e536ad04a82b867", + "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "f291bcc463de9b5172904304774d1c12", + "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "16bb769fd794945b09d6ed40ab11a411", + "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "83a5455b631ececcddf5330693c2d38a", + "build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "ac33b224e5b4e35712eb98fcc20cab5b", + "build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "81ac92010f7957feffde3573745976d2", + "build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "ac33b224e5b4e35712eb98fcc20cab5b", + "build/prefab/lib/linux_arm64_server/release/libballisticaplus.a": "81ac92010f7957feffde3573745976d2", + "build/prefab/lib/linux_x86_64_gui/debug/libballisticaplus.a": "1d2d67df52456863593f5a32ee591c5f", + "build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "4360984cf0a0e1664bd052894ebc522e", + "build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "1d2d67df52456863593f5a32ee591c5f", + "build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "4360984cf0a0e1664bd052894ebc522e", + "build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "f86bc9554c44e6a3041ee06ff7690ae2", + "build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "c6815480bdfcbbb30ffe06bfc25a3fd2", + "build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "f86bc9554c44e6a3041ee06ff7690ae2", + "build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "c6815480bdfcbbb30ffe06bfc25a3fd2", + "build/prefab/lib/mac_x86_64_gui/debug/libballisticaplus.a": "8e3f285a0d05918175c6054b3841621e", + "build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "5ec40f0445bc6415d9327c5b1cb0f645", + "build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "2793d3aea54fc937322393dd779412a7", + "build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "5ec40f0445bc6415d9327c5b1cb0f645", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "d254bb364aa44360cac2003934af76f6", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "0db2f48d7a46826de315df7ce473ab52", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "5ec488e800f024c0827deb229e4e1efc", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "430045c8d5f966488628ab5de5452e10", + "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "892c0eb2ec182ccbdcb604713d5d5ba9", + "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "3b2917f0882ac5889c12f2ca83269063", + "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "bef209af05f0af8ee5fe6d33246d846d", + "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "93a8f27c51283913e35b0e2d8b8a37b0", "src/assets/ba_data/python/babase/_mgen/__init__.py": "f885fed7f2ed98ff2ba271f9dbe3391c", "src/assets/ba_data/python/babase/_mgen/enums.py": "28323912b56ec07701eda3d41a6a4101", "src/ballistica/base/mgen/pyembed/binding_base.inc": "72bfed2cce8ff19741989dec28302f3f", diff --git a/CHANGELOG.md b/CHANGELOG.md index bcb97511..94d91285 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,16 @@ -### 1.7.28 (build 21596, api 8, 2023-11-14) +### 1.7.29 (build 21612, api 8, 2023-11-20) + +- Simply continued work on the big 1.7.28 update. I finally got the Mac App + Store version of the game updated (it had been stuck at 1.4!), and it turns + out that Apple AppStore submissions require the version number to increase + each time and not just the build number, so we may start seeing more minor + version bumps for that reason. +- Windows builds should now die with a clear error when the OpenGL version is + too old (OpenGL 3.0 or newer is required). Previously they could die with more + cryptic error messages such as "OpenGL function 'glActiveTexture2D' not + found". + +### 1.7.28 (build 21599, api 8, 2023-11-16) - Turning off ticket continues on all platforms. I'll be moving the game towards a new monetization scheme mostly based on cosmetics and this has always felt a diff --git a/config/spinoffconfig.py b/config/spinoffconfig.py index 1cbbc0f8..21b06551 100644 --- a/config/spinoffconfig.py +++ b/config/spinoffconfig.py @@ -103,7 +103,8 @@ ctx.src_unchecked_paths = { 'ballisticakit-xcode/BallisticaKit Shared/Assets.xcassets/*/*.png', 'ballisticakit-xcode/BallisticaKit Shared/Assets.xcassets/*/*/*.png', 'ballisticakit-xcode/BallisticaKit Shared/Assets.xcassets/*/*/*/*/*.png', - 'ballisticakit-xcode/BallisticaKit.xcodeproj/xcuserdata', + 'ballisticakit-xcode/BallisticaKit.xcodeproj/' + 'project.xcworkspace/xcuserdata', 'ballisticakit-android/BallisticaKit/src/*/res/*/*.png', 'ballisticakit-android/BallisticaKit/src/*/assets/ballistica_files', 'ballisticakit-android/local.properties', diff --git a/src/assets/ba_data/python/babase/_accountv2.py b/src/assets/ba_data/python/babase/_accountv2.py index 8738b8f1..f9617fcb 100644 --- a/src/assets/ba_data/python/babase/_accountv2.py +++ b/src/assets/ba_data/python/babase/_accountv2.py @@ -6,7 +6,7 @@ from __future__ import annotations import hashlib import logging -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, assert_never from efro.call import tpartial from efro.error import CommunicationError @@ -199,18 +199,26 @@ class AccountV2Subsystem: state.login_id ) - # Special case: if the user is already signed in but not with - # this implicit login, we may want to let them know that the - # 'Welcome back FOO' they likely just saw is not actually - # accurate. + # Special case: if the user is already signed in but not + # with this implicit login, let them know that the 'Welcome + # back FOO' they likely just saw is not actually accurate. if ( self.primary is not None and not self.login_adapters[login_type].is_back_end_active() ): + service_str: Lstr | None if login_type is LoginType.GPGS: service_str = Lstr(resource='googlePlayText') - else: + elif login_type is LoginType.GAME_CENTER: + # Note: Apparently Game Center is just called 'Game + # Center' in all languages. Can revisit if not true. + # https://developer.apple.com/forums/thread/725779 + service_str = Lstr(value='Game Center') + elif login_type is LoginType.EMAIL: + # Not possible; just here for exhaustive coverage. service_str = None + else: + assert_never(login_type) if service_str is not None: _babase.apptimer( 2.0, diff --git a/src/assets/ba_data/python/baenv.py b/src/assets/ba_data/python/baenv.py index 006b75f0..837fa6a7 100644 --- a/src/assets/ba_data/python/baenv.py +++ b/src/assets/ba_data/python/baenv.py @@ -52,8 +52,8 @@ if TYPE_CHECKING: # Build number and version of the ballistica binary we expect to be # using. -TARGET_BALLISTICA_BUILD = 21596 -TARGET_BALLISTICA_VERSION = '1.7.28' +TARGET_BALLISTICA_BUILD = 21612 +TARGET_BALLISTICA_VERSION = '1.7.29' @dataclass diff --git a/src/assets/ba_data/python/bauiv1/_subsystem.py b/src/assets/ba_data/python/bauiv1/_subsystem.py index 311650cb..83d88d87 100644 --- a/src/assets/ba_data/python/bauiv1/_subsystem.py +++ b/src/assets/ba_data/python/bauiv1/_subsystem.py @@ -66,6 +66,16 @@ class UIV1Subsystem(babase.AppSubsystem): # a more elegant way once we revamp high level UI stuff a bit. self.selecting_private_party_playlist: bool = False + @property + def available(self) -> bool: + """Can uiv1 currently be used? + + Code that may run in headless mode, before the UI has been spun up, + while other ui systems are active, etc. can check this to avoid + likely erroring. + """ + return _bauiv1.is_available() + @property def uiscale(self) -> babase.UIScale: """Current ui scale for the app.""" diff --git a/src/assets/ba_data/python/bauiv1lib/account/settings.py b/src/assets/ba_data/python/bauiv1lib/account/settings.py index 46c5313a..8c29aee5 100644 --- a/src/assets/ba_data/python/bauiv1lib/account/settings.py +++ b/src/assets/ba_data/python/bauiv1lib/account/settings.py @@ -654,6 +654,9 @@ class AccountSettingsWindow(bui.Window): position=((self._sub_width - button_width) * 0.5, v - 20), autoselect=True, size=(button_width, 60), + # Note: Apparently Game Center is just called 'Game Center' + # in all languages. Can revisit if not true. + # https://developer.apple.com/forums/thread/725779 label=bui.Lstr( value='${A}${B}', subs=[ @@ -860,7 +863,7 @@ class AccountSettingsWindow(bui.Window): button_width = 300 v -= game_service_button_space * 0.6 if game_center_active: - # Update: Apparently Game Center is just called 'Game Center' + # Note: Apparently Game Center is just called 'Game Center' # in all languages. Can revisit if not true. # https://developer.apple.com/forums/thread/725779 game_service_button_label = bui.Lstr( diff --git a/src/assets/ba_data/python/bauiv1lib/account/v2proxy.py b/src/assets/ba_data/python/bauiv1lib/account/v2proxy.py index 51d48061..a9ba5279 100644 --- a/src/assets/ba_data/python/bauiv1lib/account/v2proxy.py +++ b/src/assets/ba_data/python/bauiv1lib/account/v2proxy.py @@ -62,14 +62,11 @@ class V2ProxySignInWindow(bui.Window): label=bui.Lstr(resource='cancelText'), on_activate_call=self._done, autoselect=True, - color=(0.55, 0.5, 0.6), - textcolor=(0.75, 0.7, 0.8), ) - if bool(False): - bui.containerwidget( - edit=self._root_widget, cancel_button=self._cancel_button - ) + bui.containerwidget( + edit=self._root_widget, cancel_button=self._cancel_button + ) self._update_timer: bui.AppTimer | None = None diff --git a/src/assets/ba_data/python/bauiv1lib/promocode.py b/src/assets/ba_data/python/bauiv1lib/promocode.py index ae8d0549..3e7f035c 100644 --- a/src/assets/ba_data/python/bauiv1lib/promocode.py +++ b/src/assets/ba_data/python/bauiv1lib/promocode.py @@ -26,7 +26,7 @@ class PromoCodeWindow(bui.Window): transition = 'in_right' width = 450 - height = 230 + height = 330 self._modal = modal self._r = 'promoCodeWindow' @@ -62,17 +62,50 @@ class PromoCodeWindow(bui.Window): iconscale=1.2, ) + v = height - 74 + bui.textwidget( + parent=self._root_widget, + text=bui.Lstr(resource='codesExplainText'), + maxwidth=width * 0.9, + position=(width * 0.5, v), + color=(0.7, 0.7, 0.7, 1.0), + size=(0, 0), + scale=0.8, + h_align='center', + v_align='center', + ) + v -= 60 + + bui.textwidget( + parent=self._root_widget, + text=bui.Lstr( + resource='supportEmailText', + subs=[('${EMAIL}', 'support@froemling.net')], + ), + maxwidth=width * 0.9, + position=(width * 0.5, v), + color=(0.7, 0.7, 0.7, 1.0), + size=(0, 0), + scale=0.65, + h_align='center', + v_align='center', + ) + + v -= 80 + bui.textwidget( parent=self._root_widget, text=bui.Lstr(resource=self._r + '.codeText'), - position=(22, height - 113), + position=(22, v), color=(0.8, 0.8, 0.8, 1.0), size=(90, 30), h_align='right', ) + v -= 8 + self._text_field = bui.textwidget( parent=self._root_widget, - position=(125, height - 121), + position=(125, v), size=(280, 46), text='', h_align='left', @@ -86,10 +119,11 @@ class PromoCodeWindow(bui.Window): ) bui.widget(edit=btn, down_widget=self._text_field) + v -= 79 b_width = 200 self._enter_button = btn2 = bui.buttonwidget( parent=self._root_widget, - position=(width * 0.5 - b_width * 0.5, height - 200), + position=(width * 0.5 - b_width * 0.5, v), size=(b_width, 60), scale=1.0, label=bui.Lstr( diff --git a/src/ballistica/base/app_adapter/app_adapter_apple.cc b/src/ballistica/base/app_adapter/app_adapter_apple.cc index 885f8092..018f72db 100644 --- a/src/ballistica/base/app_adapter/app_adapter_apple.cc +++ b/src/ballistica/base/app_adapter/app_adapter_apple.cc @@ -27,7 +27,10 @@ namespace ballistica::base { class AppAdapterApple::ScopedAllowGraphics_ { public: explicit ScopedAllowGraphics_(AppAdapterApple* adapter) : adapter_{adapter} { + // We currently assume only one thread will be doing this at any given + // time; will need to add a lock if that's not always the case. assert(!adapter_->graphics_allowed_); + // Keep graphics thread updated each time through since it can change. adapter->graphics_thread_ = std::this_thread::get_id(); adapter->graphics_allowed_ = true; } @@ -99,9 +102,9 @@ void AppAdapterApple::ReloadRenderer_(const GraphicsSettings* settings) { gs->LoadRenderer(); } -void AppAdapterApple::UpdateScreenSizes_() { - assert(g_base->app_adapter->InGraphicsContext()); -} +// void AppAdapterApple::UpdateScreenSizes_() { +// assert(g_base->app_adapter->InGraphicsContext()); +// } auto AppAdapterApple::TryRender() -> bool { auto allow = ScopedAllowGraphics_(this); @@ -187,7 +190,7 @@ auto AppAdapterApple::ShouldUseCursor() -> bool { } auto AppAdapterApple::HasHardwareCursor() -> bool { - // (mac should be only build getting called here) + // Mac should be only build getting called here (see ShouldUseCursor). assert(g_buildconfig.ostype_macos()); return true; diff --git a/src/ballistica/base/app_adapter/app_adapter_apple.h b/src/ballistica/base/app_adapter/app_adapter_apple.h index 036bf820..520adaf8 100644 --- a/src/ballistica/base/app_adapter/app_adapter_apple.h +++ b/src/ballistica/base/app_adapter/app_adapter_apple.h @@ -66,7 +66,7 @@ class AppAdapterApple : public AppAdapter { private: class ScopedAllowGraphics_; - void UpdateScreenSizes_(); + // void UpdateScreenSizes_(); void ReloadRenderer_(const GraphicsSettings* settings); std::thread::id graphics_thread_{}; diff --git a/src/ballistica/base/base.cc b/src/ballistica/base/base.cc index 6a7a18cd..1819474f 100644 --- a/src/ballistica/base/base.cc +++ b/src/ballistica/base/base.cc @@ -239,9 +239,6 @@ void BaseFeatureSet::StartApp() { // to avoid crashing if called early. app_started_ = true; - // Inform anyone who wants to know that we're done starting. - platform->OnMainThreadStartAppComplete(); - // As the last step of this phase, tell the logic thread to apply the app // config which will kick off screen creation and otherwise get the ball // rolling. diff --git a/src/ballistica/base/graphics/gl/gl_sys.cc b/src/ballistica/base/graphics/gl/gl_sys.cc index 5d6e42ab..be6b3d40 100644 --- a/src/ballistica/base/graphics/gl/gl_sys.cc +++ b/src/ballistica/base/graphics/gl/gl_sys.cc @@ -52,7 +52,7 @@ bool g_sys_gl_inited{}; // Provide an empty implementation of this if noone provided a real one. #ifndef BA_HAS_SYS_GL_INIT -void SysGLInit() { assert(!g_sys_gl_inited); } +void SysGLInit(RendererGL* renderer) { assert(!g_sys_gl_inited); } #endif // BA_HAS_SYS_GL_INIT diff --git a/src/ballistica/base/graphics/gl/gl_sys.h b/src/ballistica/base/graphics/gl/gl_sys.h index e2519c70..a33eac0c 100644 --- a/src/ballistica/base/graphics/gl/gl_sys.h +++ b/src/ballistica/base/graphics/gl/gl_sys.h @@ -220,6 +220,7 @@ inline void glDepthRange(double min, double max) { #endif namespace ballistica::base { +class RendererGL; extern bool g_sys_gl_inited; @@ -228,7 +229,7 @@ extern bool g_sys_gl_inited; // called only once and then g_sys_gl_inited set. A platform that defines // this should define BA_HAS_SYS_GL_INIT; otherwise a default empty // implementation will be defined. -void SysGLInit(); +void SysGLInit(RendererGL* renderer); } // namespace ballistica::base diff --git a/src/ballistica/base/graphics/gl/gl_sys_windows.cc b/src/ballistica/base/graphics/gl/gl_sys_windows.cc index f627bcd1..ae65f49e 100644 --- a/src/ballistica/base/graphics/gl/gl_sys_windows.cc +++ b/src/ballistica/base/graphics/gl/gl_sys_windows.cc @@ -5,19 +5,22 @@ #include "SDL.h" #include "ballistica/base/graphics/gl/gl_sys.h" +#include "ballistica/base/graphics/gl/renderer_gl.h" #include "ballistica/shared/ballistica.h" #pragma comment(lib, "opengl32.lib") -// #pragma comment(lib, "glu32.lib") PFNGLGETINTERNALFORMATIVPROC glGetInternalformativ{}; PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glGetFramebufferAttachmentParameteriv{}; PFNGLBLENDFUNCSEPARATEPROC glBlendFuncSeparate{}; + +PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2DBA{}; PFNGLACTIVETEXTUREPROC glActiveTextureBA{}; +// PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImageARB{}; // PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTextureARB{}; + PFNGLPOINTPARAMETERFVARBPROC glPointParameterfvARB{}; -// PFNGLPOINTPARAMETERFARBPROC glPointParameterfARB{}; PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT{}; PFNGLCREATEPROGRAMPROC glCreateProgram{}; PFNGLCREATESHADERPROC glCreateShader{}; @@ -57,7 +60,6 @@ PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray{}; PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray{}; PFNGLUNIFORMMATRIX4FVARBPROC glUniformMatrix4fv{}; PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation{}; -PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2DBA{}; PFNGLGETSHADERIVPROC glGetShaderiv{}; PFNGLGETPROGRAMIVPROC glGetProgramiv{}; PFNGLDELETESHADERPROC glDeleteShader{}; @@ -90,11 +92,16 @@ static auto GetGLFunc_(const char* name, bool required) -> void* { #define GET2(PTRTYPE, FUNC, REQUIRED) \ FUNC##BA = (PTRTYPE)GetGLFunc_(#FUNC, REQUIRED) -void SysGLInit() { +void SysGLInit(RendererGL* renderer) { assert(!g_sys_gl_inited); SDL_GL_LoadLibrary(nullptr); + // Check overall GL version here before loading any extended functions. + // We'd rather die with a 'Your OpenGL is too old' error rather than a + // 'Could not load function foofDinglePlop2XZ'. + renderer->CheckGLVersion(); + void* testval{}; PFNGLGETINTERNALFORMATIVPROC fptr; @@ -104,18 +111,13 @@ void SysGLInit() { // so we can survive without it. GET(PFNGLGETINTERNALFORMATIVPROC, glGetInternalformativ, false); - // For checking srgb stuff. + GET(PFNGLBLENDFUNCSEPARATEPROC, glBlendFuncSeparate, true); GET(PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC, - glGetFramebufferAttachmentParameteriv, false); - - // Needed for VR overlay. - GET(PFNGLBLENDFUNCSEPARATEPROC, glBlendFuncSeparate, false); - + glGetFramebufferAttachmentParameteriv, true); + GET(PFNGLGETSTRINGIPROC, glGetStringi, true); GET2(PFNGLACTIVETEXTUREPROC, glActiveTexture, true); - // GET(PFNGLCLIENTACTIVETEXTUREARBPROC, glClientActiveTextureARB, true); GET(PFNWGLSWAPINTERVALEXTPROC, wglSwapIntervalEXT, true); GET(PFNGLPOINTPARAMETERFVARBPROC, glPointParameterfvARB, true); - // GET(PFNGLPOINTPARAMETERFARBPROC, glPointParameterfARB, true); GET(PFNGLCREATEPROGRAMPROC, glCreateProgram, true); GET(PFNGLCREATESHADERPROC, glCreateShader, true); GET(PFNGLSHADERSOURCEPROC, glShaderSource, true); @@ -159,7 +161,6 @@ void SysGLInit() { GET(PFNGLDETACHSHADERPROC, glDetachShader, true); GET(PFNGLGETSHADERINFOLOGPROC, glGetShaderInfoLog, true); GET(PFNGLGETPROGRAMINFOLOGPROC, glGetProgramInfoLog, true); - GET(PFNGLGETSTRINGIPROC, glGetStringi, true); GET(PFNGLBINDVERTEXARRAYPROC, glBindVertexArray, true); GET(PFNGLGENVERTEXARRAYSPROC, glGenVertexArrays, true); GET(PFNGLDELETEVERTEXARRAYSPROC, glDeleteVertexArrays, true); diff --git a/src/ballistica/base/graphics/gl/gl_sys_windows.h b/src/ballistica/base/graphics/gl/gl_sys_windows.h index 228543aa..60ce107e 100644 --- a/src/ballistica/base/graphics/gl/gl_sys_windows.h +++ b/src/ballistica/base/graphics/gl/gl_sys_windows.h @@ -31,9 +31,13 @@ extern PFNGLGETINTERNALFORMATIVPROC glGetInternalformativ; extern PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glGetFramebufferAttachmentParameteriv; extern PFNGLBLENDFUNCSEPARATEPROC glBlendFuncSeparate; + +// Hopefully can switch this back if SDL gets fixed. extern PFNGLACTIVETEXTUREPROC glActiveTextureBA; +extern PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2DBA; // extern PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTextureARB; // extern PFNGLPOINTPARAMETERFARBPROC glPointParameterfARB; + extern PFNGLPOINTPARAMETERFVARBPROC glPointParameterfvARB; extern PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT; extern PFNGLCREATEPROGRAMPROC glCreateProgram; @@ -74,7 +78,6 @@ extern PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray; extern PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray; extern PFNGLUNIFORMMATRIX4FVARBPROC glUniformMatrix4fv; extern PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation; -extern PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2DBA; extern PFNGLGETSHADERIVPROC glGetShaderiv; extern PFNGLGETPROGRAMIVPROC glGetProgramiv; extern PFNGLDELETESHADERPROC glDeleteShader; diff --git a/src/ballistica/base/graphics/gl/renderer_gl.cc b/src/ballistica/base/graphics/gl/renderer_gl.cc index c24db341..75fa0dae 100644 --- a/src/ballistica/base/graphics/gl/renderer_gl.cc +++ b/src/ballistica/base/graphics/gl/renderer_gl.cc @@ -72,7 +72,7 @@ RendererGL::RendererGL() { // Run any one-time setup the platform might need to do // (grabbing function pointers, etc.) if (!g_sys_gl_inited) { - SysGLInit(); + SysGLInit(this); g_sys_gl_inited = true; } @@ -152,10 +152,33 @@ static auto CheckGLExtension(const std::vector& exts, return false; } +// This is split into its own call because systems that load GL calls +// dynamically may want to run the check before trying to load said GL +// calls. It's better to die with a 'Your OpenGL is too old' error rather +// than a 'Could not load function foofDinglePlop2XZ'. +void RendererGL::CheckGLVersion() { + if (checked_gl_version_) { + return; + } + const char* version_str = (const char*)glGetString(GL_VERSION); + BA_PRECONDITION_FATAL(version_str); + // Do a rough check to make sure we're running 3 or newer of GL/GLES. + // This query should be available even on older versions. + if (version_str[0] != '3' && version_str[0] != '4') { + FatalError( + std::string("Your OpenGL version is too old (") + version_str + + "). We require 3.0 or later. Try updating your graphics drivers."); + } + checked_gl_version_ = true; +} + void RendererGL::CheckGLCapabilities_() { BA_DEBUG_CHECK_GL_ERROR; assert(g_base->app_adapter->InGraphicsContext()); + // Die if our overall GL version is too old. + CheckGLVersion(); + const char* renderer = (const char*)glGetString(GL_RENDERER); BA_PRECONDITION_FATAL(renderer); const char* vendor = (const char*)glGetString(GL_VENDOR); @@ -163,15 +186,9 @@ void RendererGL::CheckGLCapabilities_() { const char* version_str = (const char*)glGetString(GL_VERSION); BA_PRECONDITION_FATAL(version_str); - // Do a rough check to make sure we're running 3 or newer of GL/GLES. - // This query should be available even on older versions. - if (version_str[0] != '3' && version_str[0] != '4') { - FatalError(std::string("Invalid OpenGL version found (") + version_str - + "). We require 3.0 or later."); - } - // Now fetch exact major/minor versions. This query requires version 3.0 - // or newer which is why we checked that above. + // or newer which is why we checked overall version in CheckGLVersion() + // above. glGetError(); // Clear any existing error so we don't die on it here. glGetIntegerv(GL_MAJOR_VERSION, &gl_version_major_); BA_PRECONDITION_FATAL(glGetError() == GL_NO_ERROR); diff --git a/src/ballistica/base/graphics/gl/renderer_gl.h b/src/ballistica/base/graphics/gl/renderer_gl.h index c3afef5a..bc0a3cf7 100644 --- a/src/ballistica/base/graphics/gl/renderer_gl.h +++ b/src/ballistica/base/graphics/gl/renderer_gl.h @@ -64,6 +64,7 @@ class RendererGL : public Renderer { class ProgramSpriteGL; public: + void CheckGLVersion(); static void CheckGLError(const char* file, int line); static auto GLErrorToString(GLenum err) -> std::string; static auto GetGLTextureFormat(TextureFormat f) -> GLenum; @@ -259,22 +260,24 @@ class RendererGL : public Renderer { void SetBlend(bool b); void SetBlendPremult(bool b); - bool blend_{}; - bool blend_premult_{}; - bool first_extension_check_{true}; - bool is_tegra_4_{}; - bool is_tegra_k1_{}; - bool is_recent_adreno_{}; - bool is_adreno_{}; - bool enable_msaa_{}; - bool draw_at_equal_depth_{}; - bool depth_writing_enabled_{}; - bool depth_testing_enabled_{}; - bool data_loaded_{}; - bool draw_front_{}; - bool got_screen_framebuffer_{}; - bool double_sided_{}; - bool invalidate_framebuffer_support_{}; + GraphicsQuality vignette_quality_{}; + bool blend_ : 1 {}; + bool blend_premult_ : 1 {}; + bool first_extension_check_ : 1 {true}; + bool is_tegra_4_ : 1 {}; + bool is_tegra_k1_ : 1 {}; + bool is_recent_adreno_ : 1 {}; + bool is_adreno_ : 1 {}; + bool enable_msaa_ : 1 {}; + bool draw_at_equal_depth_ : 1 {}; + bool depth_writing_enabled_ : 1 {}; + bool depth_testing_enabled_ : 1 {}; + bool data_loaded_ : 1 {}; + bool draw_front_ : 1 {}; + bool got_screen_framebuffer_ : 1 {}; + bool double_sided_ : 1 {}; + bool invalidate_framebuffer_support_ : 1 {}; + bool checked_gl_version_ : 1 {}; GLint gl_version_major_{}; GLint gl_version_minor_{}; int last_blur_res_count_{}; @@ -291,7 +294,6 @@ class RendererGL : public Renderer { GLint screen_framebuffer_{}; GLuint random_tex_{}; GLuint vignette_tex_{}; - GraphicsQuality vignette_quality_{}; GLint viewport_x_{}; GLint viewport_y_{}; GLint viewport_width_{}; diff --git a/src/ballistica/base/platform/base_platform.cc b/src/ballistica/base/platform/base_platform.cc index afddeaf1..3bbc202d 100644 --- a/src/ballistica/base/platform/base_platform.cc +++ b/src/ballistica/base/platform/base_platform.cc @@ -165,8 +165,6 @@ void BasePlatform::SetupInterruptHandling() { #endif } -void BasePlatform::OnMainThreadStartAppComplete() {} - void BasePlatform::OnAppStart() { assert(g_base->InLogicThread()); } void BasePlatform::OnAppPause() { assert(g_base->InLogicThread()); } void BasePlatform::OnAppResume() { assert(g_base->InLogicThread()); } diff --git a/src/ballistica/base/platform/base_platform.h b/src/ballistica/base/platform/base_platform.h index 4e139bd7..35d9bfa6 100644 --- a/src/ballistica/base/platform/base_platform.h +++ b/src/ballistica/base/platform/base_platform.h @@ -24,10 +24,6 @@ class BasePlatform { #pragma mark APP EVENTS / LIFECYCLE -------------------------------------------- - /// Called to inform the platform that all subsystems are up and running - /// and it can start talking to them. - virtual void OnMainThreadStartAppComplete(); - // Logic thread callbacks. virtual void OnAppStart(); virtual void OnAppPause(); diff --git a/src/ballistica/shared/ballistica.cc b/src/ballistica/shared/ballistica.cc index 22603f36..197a4514 100644 --- a/src/ballistica/shared/ballistica.cc +++ b/src/ballistica/shared/ballistica.cc @@ -39,8 +39,8 @@ auto main(int argc, char** argv) -> int { namespace ballistica { // These are set automatically via script; don't modify them here. -const int kEngineBuildNumber = 21596; -const char* kEngineVersion = "1.7.28"; +const int kEngineBuildNumber = 21612; +const char* kEngineVersion = "1.7.29"; const int kEngineApiVersion = 8; #if BA_MONOLITHIC_BUILD diff --git a/src/ballistica/ui_v1/python/methods/python_methods_ui_v1.cc b/src/ballistica/ui_v1/python/methods/python_methods_ui_v1.cc index 87434540..79c28a3e 100644 --- a/src/ballistica/ui_v1/python/methods/python_methods_ui_v1.cc +++ b/src/ballistica/ui_v1/python/methods/python_methods_ui_v1.cc @@ -2821,7 +2821,7 @@ static PyMethodDef PyIsPartyIconVisibleDef = { "(internal)", }; -// ------------------------ is_party_icon_visible ------------------------------ +// ----------------------------- toolbar_test ---------------------------------- static auto PyToolbarTest(PyObject* self) -> PyObject* { BA_PYTHON_TRY; @@ -2843,6 +2843,31 @@ static PyMethodDef PyToolbarTestDef = { "(internal)", }; +// ----------------------------- is_available ---------------------------------- + +static auto PyIsAvailable(PyObject* self) -> PyObject* { + BA_PYTHON_TRY; + BA_PRECONDITION(g_base->InLogicThread()); + + // Consider ourself available if the active ui delegate is us. + if (dynamic_cast(g_base->ui->delegate()) != nullptr) { + Py_RETURN_TRUE; + } else { + Py_RETURN_FALSE; + } + BA_PYTHON_CATCH; +} + +static PyMethodDef PyIsAvailableDef = { + "is_available", // name + (PyCFunction)PyIsAvailable, // method + METH_NOARGS, // flags + + "is_available() -> bool\n" + "\n" + "(internal)", +}; + // ----------------------------------------------------------------------------- auto PythonMethodsUIV1::GetMethods() -> std::vector { @@ -2877,6 +2902,7 @@ auto PythonMethodsUIV1::GetMethods() -> std::vector { PyGetTextureDef, PyGetMeshDef, PyToolbarTestDef, + PyIsAvailableDef, }; } diff --git a/tools/batools/resourcesmakefile.py b/tools/batools/resourcesmakefile.py index a08ebdd5..b865a1fb 100755 --- a/tools/batools/resourcesmakefile.py +++ b/tools/batools/resourcesmakefile.py @@ -309,7 +309,22 @@ class ResourcesMakefileGenerator: ] for size in sizes: res = int(size[0] * size[1]) - src = os.path.join('icon', 'icon_clipped_mac.png') + # The largest size gets used by the Mac App Store, and lots + # of games seem to fill their entire icon canvas instead of + # sticking with the big-sur icon size, so ours looks kinda + # small next to those if we don't do the same. Strangely, + # iOS apps in the Mac App Store also show up large like that + # (as of Nov 2023). So we use a separate as-big-as-possible + # icon for our largest size only. The downside of this is + # our icon changes in appearance if someone cranks the + # finder view options icon size slider all the way up, but + # who actually does that? + srcname = ( + 'icon_clipped_mac_app_store.png' + if size[0] == 512 + else 'icon_clipped_mac.png' + ) + src = os.path.join('icon', srcname) dst = os.path.join( ROOT_DIR, f'{self.namel}-xcode', diff --git a/tools/efrotools/pybuild.py b/tools/efrotools/pybuild.py index 79a6dd7b..6d5a2a83 100644 --- a/tools/efrotools/pybuild.py +++ b/tools/efrotools/pybuild.py @@ -42,7 +42,7 @@ OPENSSL_VER_ANDROID = '3.0.12' LIBFFI_VER_APPLE = '3.4.4' BZIP2_VER_APPLE = '1.0.8' -XZ_VER_APPLE = '5.4.5' +XZ_VER_APPLE = '5.4.4' # Android repo doesn't seem to be getting updated much so manually # bumping various versions to keep things up to date.