diff --git a/.efrocachemap b/.efrocachemap index d43fdca8f..f331743e9 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": "dca47b4976752e76e852f7a4be2c7aa3", + "build/assets/ba_data/data/langdata.json": "02522e0d2593baf2e57a97fbfbfe3368", "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", @@ -439,22 +439,22 @@ "build/assets/ba_data/data/languages/greek.json": "287c0ec437b38772284ef9d3e4fb2fc3", "build/assets/ba_data/data/languages/hindi.json": "8ea0c58a44a24edb131d0e53b074d1f6", "build/assets/ba_data/data/languages/hungarian.json": "796a290a8c44a1e7635208c2ff5fdc6e", - "build/assets/ba_data/data/languages/indonesian.json": "ba39cade3c965b2ddbee122880b6f0db", + "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": "7374b6a5cadcf573ee4ab4a5b4bc8c0a", + "build/assets/ba_data/data/languages/portuguese.json": "c738cc76396305060d4f94cb77db5bec", "build/assets/ba_data/data/languages/romanian.json": "aeebdd54f65939c2facc6ac50c117826", - "build/assets/ba_data/data/languages/russian.json": "9e068a3afdec43b207c83aedfb812e82", + "build/assets/ba_data/data/languages/russian.json": "cdaac43afde13ab622babe403b9858a4", "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/swedish.json": "5142a96597d17d8344be96a603da64ac", "build/assets/ba_data/data/languages/tamil.json": "b4de1a2851afe4869c82e9acd94cd89c", - "build/assets/ba_data/data/languages/thai.json": "33f63753c9af9a5b238d229a0bf23fbc", - "build/assets/ba_data/data/languages/turkish.json": "c3674336e746bf7b23617a6ff296c69a", + "build/assets/ba_data/data/languages/thai.json": "77755219bbf5fb7eea0d6b226684f403", + "build/assets/ba_data/data/languages/turkish.json": "326bcc54b69cb6a1bda4abb732f9f56f", "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": "66647fb41b54b221cf4189161a696698", - "build/prefab/full/linux_arm64_gui/release/ballisticakit": "81a9bec829a30860a260df58c258b7d0", - "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "1930fa43a702b2fd3601b032afd9ad31", - "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "e9fdc1e724495d36a1ae9c1898b2dbeb", - "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "5cb78d708e8dc3911d1e5a345e535bd2", - "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "9aa815a258a476f02490cf58db28340a", - "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "dd932540bbef37a3e0580ef81206090c", - "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "d34c3fcf54ae4c362dafb442e5e2e57a", - "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "a74979683c4e58bfefde5235996551db", - "build/prefab/full/mac_arm64_gui/release/ballisticakit": "cbbecde45fb204a8f39cbf5448d248a2", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "37d71f1f72191bb29645146a5d7fdd09", - "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "10cb64bd655ad3ff562496bb66693dd6", - "build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "7d9ab35e63602e682a533495022728d3", - "build/prefab/full/mac_x86_64_gui/release/ballisticakit": "d98edee305c488c3a082ef98deae8a6c", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "a12f0a05ed17ef48554356b6087cdee0", - "build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "de7e6c726c6ace4bba28f59a84cdf6b5", - "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "fd7b381ca67b31c088d4e98b6c0ddfe1", - "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "1d074c3b15b2bdf6c32e145ea83f1fa2", - "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "0b47cfab278418386ac29009402c9f59", - "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "213a68414bac47cbe051db9fbb0cbb43", - "build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "a5e255155289f502a6662e5f9bb7819c", - "build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "ae044789e56e5d2999f55e2f4eeb6a4d", - "build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "a5e255155289f502a6662e5f9bb7819c", - "build/prefab/lib/linux_arm64_server/release/libballisticaplus.a": "ae044789e56e5d2999f55e2f4eeb6a4d", - "build/prefab/lib/linux_x86_64_gui/debug/libballisticaplus.a": "48d81af91942519355b066d7bf8d3468", - "build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "2c4f37722cb283a8405f35a0c9bbbfbb", - "build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "48d81af91942519355b066d7bf8d3468", - "build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "2c4f37722cb283a8405f35a0c9bbbfbb", - "build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "09abcf532a2c0fba00e5e7860f495ba8", - "build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "699291d36e42e3214946aab9798446ea", - "build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "09abcf532a2c0fba00e5e7860f495ba8", - "build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "699291d36e42e3214946aab9798446ea", - "build/prefab/lib/mac_x86_64_gui/debug/libballisticaplus.a": "ef1356360fb3701b0976a0ef37eae4bf", - "build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "50cfe82580f1ef2698c5508f46bd2e4c", - "build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "7b6afdb6b8d8722cbcee3bff944ec038", - "build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "50cfe82580f1ef2698c5508f46bd2e4c", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "b29d085453e251a7e6866ac7efcd0513", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "e8da891dd0f5a441d781793f641f215d", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "982dc78eabf4eca6ccbfd3bf2537c706", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "d02505b956c8a0d5b2cb310408492df6", - "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "c95c26eed8a2c5e8573d35c58b2c99f2", - "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "d5a04d68e7818912b1f689fb1a3e8b53", - "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "b612531dedbb057f48868e43ce05636a", - "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "499914dfdd9a5fd051013ab5ae845f41", + "build/prefab/full/linux_arm64_gui/debug/ballisticakit": "96ba5c40a9216f4efed502e29a0bc762", + "build/prefab/full/linux_arm64_gui/release/ballisticakit": "bbe152b83087e223b9f9f0336d4f03d3", + "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "c22b27747e16c1dfa7e7a43264555cd5", + "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "06b779dfd042cb832e4546b177b333a7", + "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "a18464f5e02af14e3b34ccb2154fb1de", + "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "56d0b3ff53e9d4ac46c8ef2aa4d729b6", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "7d00156ec8e56af0d8a39ea7eb20f6fd", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "b933746e1b64608aab7e6bf8ebf32a8d", + "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "824515c2fc33e06c7ecb866a2818a546", + "build/prefab/full/mac_arm64_gui/release/ballisticakit": "d0a8783b736e196cfaaefbb62271e337", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "741f777205eddf8a2500625e3ba18ee6", + "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "01697d3e58c63d3f23c74720f7738da6", + "build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "a86b1855a709c6b654195a8a0e308057", + "build/prefab/full/mac_x86_64_gui/release/ballisticakit": "9567d63a4c02d393a8110953f1c2e9b5", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "7199a245c7e946222125f0e8640285a0", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "a5e0788917285460f40d1beacabd0ca2", + "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "4cc6912cd58e026baa523d8081411506", + "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "754fed064c8a87448617ef7b9c3479cb", + "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "047c6dcda71e7c4e0c4ffa5f1aac5bfa", + "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "56976efa146ae9972dd6ba53ec75d451", + "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": "767e7b15de08ffe850d3bbc7def2fab2", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "d482806656749efd090c6c28c124eecf", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "07abac6aa3c528bd594bdf5b53e9c823", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "b16b8780811a583824491b80a45b839d", + "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "33806447e8ab2bd3a55509d8a5d8b64c", + "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "786967e43a719120d339de9cd791e58b", + "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "70162e33973c253efdc386e421c50ebe", + "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "4ab0adfd6cc8934f0340d4bb6c73b78d", "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 5125064f3..333407387 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -### 1.7.28 (build 21585, api 8, 2023-11-10) +### 1.7.28 (build 21588, api 8, 2023-11-13) - 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 @@ -209,6 +209,13 @@ - The V2 account id for the signed in account is now available at `ba*.app.plus.accounts.primary.accountid` (alongside some other existing account info). +- (build 21585) Fixed an issue where some navigation key presses were getting + incorrectly absorbed by text widgets. (Thanks for the heads-up Temp!) +- (build 21585) Fixed an issue where texture quality changes would not take + effect until next launch. +- Added a 'glow_type' arg to `bauiv1.textwidget()` to adjust the glow used when + the text is selected. The default is 'gradient' but there is now a 'uniform' + option which may look better in some circumstances. ### 1.7.27 (build 21282, api 8, 2023-08-30) diff --git a/src/assets/ba_data/python/babase/_cloud.py b/src/assets/ba_data/python/babase/_cloud.py index b380bc3b5..3f5643db7 100644 --- a/src/assets/ba_data/python/babase/_cloud.py +++ b/src/assets/ba_data/python/babase/_cloud.py @@ -26,6 +26,11 @@ class CloudSubsystem(AppSubsystem): """Manages communication with cloud components.""" + @property + def connected(self) -> bool: + """Property equivalent of CloudSubsystem.is_connected().""" + return self.is_connected() + def is_connected(self) -> bool: """Return whether a connection to the cloud is present. diff --git a/src/assets/ba_data/python/babase/modutils.py b/src/assets/ba_data/python/babase/modutils.py index 240c5cbfa..7780d1f68 100644 --- a/src/assets/ba_data/python/babase/modutils.py +++ b/src/assets/ba_data/python/babase/modutils.py @@ -104,8 +104,8 @@ def show_user_scripts() -> None: _error.print_exception('error writing about_this_folder stuff') - # On a few platforms we try to open the dir in the UI. - if app.classic is not None and app.classic.platform in ['mac', 'windows']: + # On platforms that support it, open the dir in the UI. + if _babase.supports_open_dir_externally(): _babase.open_dir_externally(env.python_directory_user) # Otherwise we just print a pretty version of it. diff --git a/src/assets/ba_data/python/baenv.py b/src/assets/ba_data/python/baenv.py index 67a86fe7a..2ec6cb9b0 100644 --- a/src/assets/ba_data/python/baenv.py +++ b/src/assets/ba_data/python/baenv.py @@ -52,7 +52,7 @@ # Build number and version of the ballistica binary we expect to be # using. -TARGET_BALLISTICA_BUILD = 21585 +TARGET_BALLISTICA_BUILD = 21588 TARGET_BALLISTICA_VERSION = '1.7.28' diff --git a/src/assets/ba_data/python/bauiv1lib/account/settings.py b/src/assets/ba_data/python/bauiv1lib/account/settings.py index 4e48873a8..46c5313a4 100644 --- a/src/assets/ba_data/python/bauiv1lib/account/settings.py +++ b/src/assets/ba_data/python/bauiv1lib/account/settings.py @@ -486,20 +486,21 @@ def _refresh(self) -> None: self._account_name_what_is_text = bui.textwidget( parent=self._subcontainer, position=(0.0, self._account_name_what_is_y), - size=(200.0, 60), + size=(220.0, 60), text=bui.Lstr( value='${WHAT} -->', subs=[('${WHAT}', bui.Lstr(resource='whatIsThisText'))], ), scale=0.6, color=(0.3, 0.7, 0.05), - maxwidth=200.0, + maxwidth=130.0, h_align='right', v_align='center', autoselect=True, selectable=True, on_activate_call=show_what_is_v2_page, click_activate=True, + glow_type='uniform', ) if first_selectable is None: first_selectable = self._account_name_what_is_text @@ -1281,11 +1282,21 @@ def _on_what_is_v2_press(self) -> None: show_what_is_v2_page() def _on_manage_account_press(self) -> None: - bui.screenmessage(bui.Lstr(resource='oneMomentText')) - plus = bui.app.plus assert plus is not None + # Preemptively fail if it looks like we won't be able to talk to + # the server anyway. + if not plus.cloud.connected: + bui.screenmessage( + bui.Lstr(resource='internal.unavailableNoConnectionText'), + color=(1, 0, 0), + ) + bui.getsound('error').play() + return + + bui.screenmessage(bui.Lstr(resource='oneMomentText')) + # We expect to have a v2 account signed in if we get here. if plus.accounts.primary is None: logging.exception( @@ -1445,7 +1456,7 @@ def _refresh_account_name_text(self) -> None: swidth = bui.get_string_width(name_str, suppress_warning=True) # Eww; number-fudging. Need to recalibrate this if # account name scaling changes. - x = self._sub_width * 0.5 - swidth * 0.75 - 170 + x = self._sub_width * 0.5 - swidth * 0.75 - 190 bui.textwidget( edit=self._account_name_what_is_text, diff --git a/src/assets/ba_data/python/bauiv1lib/gather/manualtab.py b/src/assets/ba_data/python/bauiv1lib/gather/manualtab.py index 3202d812b..b75f14c99 100644 --- a/src/assets/ba_data/python/bauiv1lib/gather/manualtab.py +++ b/src/assets/ba_data/python/bauiv1lib/gather/manualtab.py @@ -142,6 +142,7 @@ def on_activate( playsound=True, ), text=bui.Lstr(resource='gatherWindow.manualJoinSectionText'), + glow_type='uniform', ) self._favorites_text = bui.textwidget( parent=self._container, @@ -162,6 +163,7 @@ def on_activate( playsound=True, ), text=bui.Lstr(resource='gatherWindow.favoritesText'), + glow_type='uniform', ) bui.widget(edit=self._join_by_address_text, up_widget=tab_button) bui.widget( @@ -316,7 +318,7 @@ def _build_join_by_address_tab( self._check_button = bui.textwidget( parent=self._container, size=(250, 60), - text=bui.Lstr(resource='gatherWindow.' 'showMyAddressText'), + text=bui.Lstr(resource='gatherWindow.showMyAddressText'), v_align='center', h_align='center', click_activate=True, @@ -331,6 +333,7 @@ def _build_join_by_address_tab( self._container, c_width, ), + glow_type='uniform', ) bui.widget(edit=self._check_button, up_widget=btn) diff --git a/src/assets/ba_data/python/bauiv1lib/gather/privatetab.py b/src/assets/ba_data/python/bauiv1lib/gather/privatetab.py index 952b862c0..e66cd6c11 100644 --- a/src/assets/ba_data/python/bauiv1lib/gather/privatetab.py +++ b/src/assets/ba_data/python/bauiv1lib/gather/privatetab.py @@ -120,6 +120,7 @@ def on_activate( playsound=True, ), text=bui.Lstr(resource='gatherWindow.privatePartyJoinText'), + glow_type='uniform', ) self._host_sub_tab_text = bui.textwidget( parent=self._container, @@ -138,6 +139,7 @@ def on_activate( playsound=True, ), text=bui.Lstr(resource='gatherWindow.privatePartyHostText'), + glow_type='uniform', ) bui.widget(edit=self._join_sub_tab_text, up_widget=tab_button) bui.widget( diff --git a/src/assets/ba_data/python/bauiv1lib/gather/publictab.py b/src/assets/ba_data/python/bauiv1lib/gather/publictab.py index dc2b2dc33..e16194368 100644 --- a/src/assets/ba_data/python/bauiv1lib/gather/publictab.py +++ b/src/assets/ba_data/python/bauiv1lib/gather/publictab.py @@ -114,7 +114,7 @@ def update( self._name_widget = bui.textwidget( text=bui.Lstr(value=party.name), parent=columnwidget, - size=(sub_scroll_width * 0.63, 20), + size=(sub_scroll_width * 0.46, 20), position=(0 + hpos, 4 + vpos), selectable=True, on_select_call=bui.WeakCall( @@ -248,6 +248,7 @@ def __init__(self, call: Callable[[Any], Any]): self._call = call def run(self) -> None: + sock: socket.socket | None = None try: # FIXME: Update this to work with IPv6 at some point. import socket @@ -255,7 +256,6 @@ def run(self) -> None: sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.connect(('8.8.8.8', 80)) val = sock.getsockname()[0] - sock.close() bui.pushcall(bui.Call(self._call, val), from_other_thread=True) except Exception as exc: from efro.error import is_udp_communication_error @@ -265,6 +265,9 @@ def run(self) -> None: pass else: logging.exception('Error in addr-fetch-thread') + finally: + if sock is not None: + sock.close() class PingThread(Thread): @@ -432,6 +435,7 @@ def on_activate( text=bui.Lstr( resource='gatherWindow.' 'joinPublicPartyDescriptionText' ), + glow_type='uniform', ) self._host_text = bui.textwidget( parent=self._container, @@ -454,6 +458,7 @@ def on_activate( text=bui.Lstr( resource='gatherWindow.' 'hostPublicPartyDescriptionText' ), + glow_type='uniform', ) bui.widget(edit=self._join_text, up_widget=tab_button) bui.widget( diff --git a/src/assets/ba_data/python/bauiv1lib/playlist/addgame.py b/src/assets/ba_data/python/bauiv1lib/playlist/addgame.py index 47450726e..c8acdb8a3 100644 --- a/src/assets/ba_data/python/bauiv1lib/playlist/addgame.py +++ b/src/assets/ba_data/python/bauiv1lib/playlist/addgame.py @@ -198,7 +198,7 @@ def _doit() -> None: txt = bui.textwidget( parent=self._column, position=(0, 0), - size=(self._width - 88, 24), + size=(self._scroll_width * 1.1, 24), text=gametype.get_display_string(), h_align='left', v_align='center', diff --git a/src/assets/ba_data/python/bauiv1lib/profile/browser.py b/src/assets/ba_data/python/bauiv1lib/profile/browser.py index 55c1e1211..0fc51e144 100644 --- a/src/assets/ba_data/python/bauiv1lib/profile/browser.py +++ b/src/assets/ba_data/python/bauiv1lib/profile/browser.py @@ -382,12 +382,12 @@ def _refresh(self) -> None: txtw = bui.textwidget( parent=self._columnwidget, position=(0, 32), - size=((self._width - 40) / scl, 28), + size=((self._width - 210) / scl, 28), text=bui.Lstr(value=tval), h_align='left', v_align='center', on_select_call=bui.WeakCall(self._select, p_name, index), - maxwidth=self._scroll_width * 0.92, + maxwidth=self._scroll_width * 0.86, corner_scale=scl, color=bui.safecolor(color, 0.4), always_highlight=True, diff --git a/src/ballistica/base/base.h b/src/ballistica/base/base.h index 27243583a..707d70a23 100644 --- a/src/ballistica/base/base.h +++ b/src/ballistica/base/base.h @@ -90,6 +90,7 @@ class NetGraph; class Networking; class NetworkReader; class NetworkWriter; +class NinePatchMesh; class ObjectComponent; class PythonClassUISound; class PythonContextCall; diff --git a/src/ballistica/base/graphics/component/empty_component.h b/src/ballistica/base/graphics/component/empty_component.h index 1a8099365..6a3018121 100644 --- a/src/ballistica/base/graphics/component/empty_component.h +++ b/src/ballistica/base/graphics/component/empty_component.h @@ -11,8 +11,7 @@ namespace ballistica::base { // transform/scissor/etc state changes. class EmptyComponent : public RenderComponent { public: - explicit EmptyComponent(RenderPass* pass) - : RenderComponent(pass), transparent_(false) {} + explicit EmptyComponent(RenderPass* pass) : RenderComponent(pass) {} void SetTransparent(bool val) { EnsureConfiguring(); transparent_ = val; @@ -22,7 +21,7 @@ class EmptyComponent : public RenderComponent { void WriteConfig() override { ConfigForEmpty(transparent_); } private: - bool transparent_; + bool transparent_{}; }; } // namespace ballistica::base diff --git a/src/ballistica/base/graphics/component/object_component.h b/src/ballistica/base/graphics/component/object_component.h index 5c1bf11bf..6078ada98 100644 --- a/src/ballistica/base/graphics/component/object_component.h +++ b/src/ballistica/base/graphics/component/object_component.h @@ -113,6 +113,14 @@ class ObjectComponent : public RenderComponent { void WriteConfig() override; protected: + ReflectionType reflection_{ReflectionType::kNone}; + LightShadowType light_shadow_{LightShadowType::kObject}; + bool world_space_ : 1 {}; + bool transparent_ : 1 {}; + bool premultiplied_ : 1 {}; + bool have_color_add_ : 1 {}; + bool double_sided_ : 1 {}; + bool do_colorize_2_ : 1 {}; float color_r_{1.0f}; float color_g_{1.0f}; float color_b_{1.0f}; @@ -133,14 +141,6 @@ class ObjectComponent : public RenderComponent { float reflection_scale_b_{1.0f}; Object::Ref texture_; Object::Ref colorize_texture_; - ReflectionType reflection_{ReflectionType::kNone}; - LightShadowType light_shadow_{LightShadowType::kObject}; - bool world_space_{}; - bool transparent_{}; - bool premultiplied_{}; - bool have_color_add_{}; - bool double_sided_{}; - bool do_colorize_2_{}; }; } // namespace ballistica::base diff --git a/src/ballistica/base/graphics/component/post_process_component.h b/src/ballistica/base/graphics/component/post_process_component.h index 516bcd864..3deff54ae 100644 --- a/src/ballistica/base/graphics/component/post_process_component.h +++ b/src/ballistica/base/graphics/component/post_process_component.h @@ -9,8 +9,7 @@ namespace ballistica::base { class PostProcessComponent : public RenderComponent { public: - explicit PostProcessComponent(RenderPass* pass) - : RenderComponent(pass), normal_distort_(0.0f), eyes_(false) {} + explicit PostProcessComponent(RenderPass* pass) : RenderComponent(pass) {} void SetNormalDistort(float d) { EnsureConfiguring(); normal_distort_ = d; @@ -22,8 +21,8 @@ class PostProcessComponent : public RenderComponent { protected: void WriteConfig() override; - bool eyes_; - float normal_distort_; + bool eyes_ : 1 {}; + float normal_distort_{}; }; } // namespace ballistica::base diff --git a/src/ballistica/base/graphics/component/simple_component.h b/src/ballistica/base/graphics/component/simple_component.h index 6452401a8..384ade436 100644 --- a/src/ballistica/base/graphics/component/simple_component.h +++ b/src/ballistica/base/graphics/component/simple_component.h @@ -7,35 +7,10 @@ namespace ballistica::base { -// used for UI and overlays and things - no world tinting/etc is applied +/// Used for UI and overlays and things; no world tinting/etc is applied. class SimpleComponent : public RenderComponent { public: - explicit SimpleComponent(RenderPass* pass) - : RenderComponent(pass), - color_r_(1.0f), - color_g_(1.0f), - color_b_(1.0f), - color_a_(1.0f), - colorize_color_r_(1.0f), - colorize_color_g_(1.0f), - colorize_color_b_(1.0f), - colorize_color_a_(1.0f), - colorize_color2_r_(1.0f), - colorize_color2_g_(1.0f), - colorize_color2_b_(1.0f), - colorize_color2_a_(1.0f), - shadow_offset_x_(0.0f), - shadow_offset_y_(0.0f), - shadow_blur_(0.0f), - shadow_opacity_(0.0f), - glow_amount_(0.0f), - glow_blur_(0.0f), - flatness_(0.0f), - transparent_(false), - premultiplied_(false), - have_color_(false), - double_sided_(false), - do_colorize_2_(false) {} + explicit SimpleComponent(RenderPass* pass) : RenderComponent(pass) {} void SetPremultiplied(bool val) { EnsureConfiguring(); @@ -56,16 +31,16 @@ class SimpleComponent : public RenderComponent { EnsureConfiguring(); texture_ = t; } - // used with colorize color 1 and 2 - // red areas of the texture will get multiplied by colorize-color1 - // and green areas by colorize-color2 + + /// Used with colorize color 1 and 2. Red areas of the texture will get + /// multiplied by colorize-color1 and green areas by colorize-color2. void SetColorizeTexture(TextureAsset* t) { EnsureConfiguring(); colorize_texture_ = t; } - // Red multiplies source color, green adds colorize1-color, and blue adds - // white (currently requires colorize1 and colorize 2 to be set). + /// Red multiplies source color, green adds colorize1-color, and blue adds + /// white (currently requires colorize1 and colorize 2 to be set). void SetMaskTexture(TextureAsset* t) { EnsureConfiguring(); mask_texture_ = t; @@ -124,10 +99,10 @@ class SimpleComponent : public RenderComponent { do_colorize_2_ = true; } - void SetShadow(float offsetX, float offsetY, float blur, float opacity) { + void SetShadow(float offset_x, float offset_y, float blur, float opacity) { EnsureConfiguring(); - shadow_offset_x_ = offsetX; - shadow_offset_y_ = offsetY; + shadow_offset_x_ = offset_x; + shadow_offset_y_ = offset_y; shadow_blur_ = blur; shadow_opacity_ = opacity; } @@ -147,23 +122,34 @@ class SimpleComponent : public RenderComponent { void WriteConfig() override; protected: - float color_r_, color_g_, color_b_, color_a_; - float colorize_color_r_, colorize_color_g_, colorize_color_b_, - colorize_color_a_; - float colorize_color2_r_, colorize_color2_g_, colorize_color2_b_, - colorize_color2_a_; - float shadow_offset_x_, shadow_offset_y_, shadow_blur_, shadow_opacity_; - float glow_amount_, glow_blur_; - float flatness_; + bool do_colorize_2_ : 1 {}; + bool transparent_ : 1 {}; + bool premultiplied_ : 1 {}; + bool have_color_ : 1 {}; + bool double_sided_ : 1 {}; + float color_r_{1.0f}; + float color_g_{1.0f}; + float color_b_{1.0f}; + float color_a_{1.0f}; + float colorize_color_r_{1.0f}; + float colorize_color_g_{1.0f}; + float colorize_color_b_{1.0f}; + float colorize_color_a_{1.0f}; + float colorize_color2_r_{1.0f}; + float colorize_color2_g_{1.0f}; + float colorize_color2_b_{1.0f}; + float colorize_color2_a_{1.0f}; + float shadow_offset_x_{}; + float shadow_offset_y_{}; + float shadow_blur_{}; + float shadow_opacity_{}; + float glow_amount_{}; + float glow_blur_{}; + float flatness_{}; Object::Ref texture_; Object::Ref colorize_texture_; Object::Ref mask_texture_; Object::Ref mask_uv2_texture_; - bool do_colorize_2_; - bool transparent_; - bool premultiplied_; - bool have_color_; - bool double_sided_; }; } // namespace ballistica::base diff --git a/src/ballistica/base/graphics/component/smoke_component.h b/src/ballistica/base/graphics/component/smoke_component.h index 45fa1e921..bb81bfb73 100644 --- a/src/ballistica/base/graphics/component/smoke_component.h +++ b/src/ballistica/base/graphics/component/smoke_component.h @@ -9,13 +9,8 @@ namespace ballistica::base { class SmokeComponent : public RenderComponent { public: - explicit SmokeComponent(RenderPass* pass) - : RenderComponent(pass), - color_r_(1.0f), - color_g_(1.0f), - color_b_(1.0f), - color_a_(1.0f), - overlay_(false) {} + explicit SmokeComponent(RenderPass* pass) : RenderComponent(pass) {} + void SetColor(float r, float g, float b, float a = 1.0f) { EnsureConfiguring(); color_r_ = r; @@ -23,6 +18,7 @@ class SmokeComponent : public RenderComponent { color_b_ = b; color_a_ = a; } + void SetOverlay(bool overlay) { EnsureConfiguring(); overlay_ = overlay; @@ -30,8 +26,12 @@ class SmokeComponent : public RenderComponent { protected: void WriteConfig() override; - float color_r_, color_g_, color_b_, color_a_; - bool overlay_; + + bool overlay_ : 1 {}; + float color_r_{1.0f}; + float color_g_{1.0f}; + float color_b_{1.0f}; + float color_a_{1.0f}; }; } // namespace ballistica::base diff --git a/src/ballistica/base/graphics/component/sprite_component.h b/src/ballistica/base/graphics/component/sprite_component.h index 01f67e108..f1f3c7e7e 100644 --- a/src/ballistica/base/graphics/component/sprite_component.h +++ b/src/ballistica/base/graphics/component/sprite_component.h @@ -37,9 +37,9 @@ class SpriteComponent : public RenderComponent { protected: void WriteConfig() override; - bool have_color_{}; - bool camera_aligned_{}; - bool overlay_{}; + bool have_color_ : 1 {}; + bool camera_aligned_ : 1 {}; + bool overlay_ : 1 {}; uint8_t exponent_{1}; float color_r_{1.0f}; float color_g_{1.0f}; diff --git a/src/ballistica/base/graphics/graphics.cc b/src/ballistica/base/graphics/graphics.cc index 7fe3f3e9e..6fc3c216d 100644 --- a/src/ballistica/base/graphics/graphics.cc +++ b/src/ballistica/base/graphics/graphics.cc @@ -106,8 +106,6 @@ void Graphics::DoApplyAppConfig() { show_fps_ = g_base->app_config->Resolve(AppConfig::BoolID::kShowFPS); show_ping_ = g_base->app_config->Resolve(AppConfig::BoolID::kShowPing); - // tv_border_ = - // g_base->app_config->Resolve(AppConfig::BoolID::kEnableTVBorder); bool disable_camera_shake = g_base->app_config->Resolve(AppConfig::BoolID::kDisableCameraShake); @@ -133,6 +131,7 @@ void Graphics::UpdateInitialGraphicsSettingsSend_() { // We need to send an initial graphics-settings to the server to kick // things off, but we need a few things to be in place first. auto app_config_ready = applied_app_config_; + // At some point we may want to wait to know our actual screen res before // sending. This won't apply everywhere though since on some platforms the // screen doesn't exist until we send this. @@ -149,7 +148,7 @@ void Graphics::UpdateInitialGraphicsSettingsSend_() { // explicitly increment its refcount here in the logic thread now and // then push a call back here to decrement it when we're done. settings->ObjectIncrementStrongRefCount(); - // auto* s = settings_.Get(); + g_base->app_adapter->PushGraphicsContextCall([settings] { assert(g_base->app_adapter->InGraphicsContext()); g_base->graphics_server->ApplySettings(settings->Get()); @@ -466,9 +465,8 @@ void Graphics::DrawMiscOverlays(FrameDef* frame_def) { if (now - it->second->LastUsedTime() > 1000) { it = debug_graphs_.erase(it); } else { - it->second->Draw(pass, - static_cast(g_core->GetAppTimeMillisecs()), - 50.0f, debug_graph_y, 500.0f, 100.0f); + it->second->Draw(pass, g_base->logic->display_time() * 1000.0, 50.0f, + debug_graph_y, 500.0f, 100.0f); debug_graph_y += 110.0f; ++it; @@ -581,6 +579,9 @@ auto Graphics::GetGraphicsSettingsSnapshot() -> Snapshot* { new_settings->index = next_settings_index_++; settings_snapshot_ = Object::New>(new_settings); graphics_settings_dirty_ = false; + + // This can affect placeholder settings; keep those up to date. + UpdatePlaceholderSettings(); } assert(settings_snapshot_.Exists()); return settings_snapshot_.Get(); @@ -1618,7 +1619,6 @@ void Graphics::LanguageChanged() { Log(LogLevel::kWarning, "Graphics::LanguageChanged() called during draw; should not happen."); } - screenmessages->ClearScreenMessageTranslations(); } @@ -1665,19 +1665,31 @@ auto Graphics::TextureQualityFromRequest(TextureQualityRequest request, void Graphics::set_client_context(Snapshot* context) { assert(g_base->InLogicThread()); - // Currently we only expect this to be set once. That will change - // once we support renderer swapping/etc. + // Currently we only expect this to be set once. That will change once we + // support renderer swapping/etc. assert(!g_base->logic->graphics_ready()); assert(!client_context_snapshot_.Exists()); client_context_snapshot_ = context; - // Update our static placeholder value (we don't want to calc it dynamically - // since it can be accessed from other threads). - texture_quality_placeholder_ = TextureQualityFromRequest( - settings()->texture_quality, client_context()->auto_texture_quality); + // Placeholder settings are affected by client context, so update them + // when it changes. + UpdatePlaceholderSettings(); // Let the logic system know its free to proceed beyond bootstrapping. g_base->logic->OnGraphicsReady(); } +// This call exists for the graphics-server to call when they've changed +void Graphics::UpdatePlaceholderSettings() { + assert(g_base->InLogicThread()); + + // Need both of these in place. + if (!settings_snapshot_.Exists() || !has_client_context()) { + return; + } + + texture_quality_placeholder_ = TextureQualityFromRequest( + settings()->texture_quality, client_context()->auto_texture_quality); +} + } // namespace ballistica::base diff --git a/src/ballistica/base/graphics/graphics.h b/src/ballistica/base/graphics/graphics.h index 115f0adc7..58d24e83f 100644 --- a/src/ballistica/base/graphics/graphics.h +++ b/src/ballistica/base/graphics/graphics.h @@ -320,6 +320,8 @@ class Graphics { /// Called by the graphics-server when a new client context is ready. void set_client_context(Snapshot* context); + void UpdatePlaceholderSettings(); + auto has_client_context() -> bool { return client_context_snapshot_.Exists(); } diff --git a/src/ballistica/base/graphics/graphics_server.cc b/src/ballistica/base/graphics/graphics_server.cc index 949efcedb..0082f1250 100644 --- a/src/ballistica/base/graphics/graphics_server.cc +++ b/src/ballistica/base/graphics/graphics_server.cc @@ -66,7 +66,8 @@ void GraphicsServer::ApplySettings(const GraphicsSettings* settings) { // gathered for themself. g_base->app_adapter->ApplyGraphicsSettings(settings); - // Lastly, if we've not yet sent a context to the client, do so. + // If we've not yet sent a context to the client, do so. At some point we + // may support re-sending this if there are settings that change. if (client_context_ == nullptr) { set_client_context(g_base->app_adapter->GetGraphicsClientContext()); } @@ -387,58 +388,6 @@ void GraphicsServer::UnloadRenderer() { renderer_loaded_ = false; } -// Given physical res, calculate virtual res. -// void GraphicsServer::CalcVirtualRes_(float* x, float* y) { -// float x_in = *x; -// float y_in = *y; -// if (*x / *y > static_cast(kBaseVirtualResX) -// / static_cast(kBaseVirtualResY)) { -// *y = kBaseVirtualResY; -// *x = *y * (x_in / y_in); -// } else { -// *x = kBaseVirtualResX; -// *y = *x * (y_in / x_in); -// } -// } - -// void GraphicsServer::UpdateVirtualScreenRes_() { -// assert(g_base->app_adapter->InGraphicsContext()); - -// // In vr mode our virtual res is independent of our screen size. -// // (since it gets drawn to an overlay) -// if (g_core->IsVRMode()) { -// res_x_virtual_ = kBaseVirtualResX; -// res_y_virtual_ = kBaseVirtualResY; -// } else { -// res_x_virtual_ = res_x_; -// res_y_virtual_ = res_y_; -// CalcVirtualRes_(&res_x_virtual_, &res_y_virtual_); -// } -// } - -// void GraphicsServer::SetScreenResolution(float h, float v) { -// assert(g_base->app_adapter->InGraphicsContext()); - -// // Ignore redundant sets. -// if (res_x_ == h && res_y_ == v) { -// return; -// } -// res_x_ = h; -// res_y_ = v; -// // UpdateVirtualScreenRes_(); - -// // Inform renderer of the change. -// if (renderer_) { -// renderer_->OnScreenSizeChange(); -// } - -// // Inform all logic thread bits of this change. -// g_base->logic->event_loop()->PushCall( -// [vx = res_x_virtual_, vy = res_y_virtual_, x = res_x_, y = res_y_] { -// g_base->graphics->SetScreenSize(vx, vy, x, y); -// }); -// } - // FIXME: Shouldn't have android-specific code in here. void GraphicsServer::HandlePushAndroidRes(const std::string& android_res) { if (g_buildconfig.ostype_android()) { @@ -578,16 +527,6 @@ void GraphicsServer::PushReloadMediaCall() { g_base->app_adapter->PushGraphicsContextCall([this] { ReloadMedia_(); }); } -// void GraphicsServer::PushSetScreenPixelScaleCall(float pixel_scale) { -// g_base->app_adapter->PushGraphicsContextCall([this, pixel_scale] { -// assert(g_base->app_adapter->InGraphicsContext()); -// if (!renderer_) { -// return; -// } -// renderer_->set_pixel_scale(pixel_scale); -// }); -// } - void GraphicsServer::PushComponentUnloadCall( const std::vector*>& components) { g_base->app_adapter->PushGraphicsContextCall([components] { diff --git a/src/ballistica/base/graphics/graphics_server.h b/src/ballistica/base/graphics/graphics_server.h index dc3df09ed..54efe05ab 100644 --- a/src/ballistica/base/graphics/graphics_server.h +++ b/src/ballistica/base/graphics/graphics_server.h @@ -330,7 +330,6 @@ class GraphicsServer { bool cam_orient_matrix_dirty_ : 1 {true}; bool shutting_down_ : 1 {}; bool shutdown_completed_ : 1 {}; - Snapshot* client_context_{}; float res_x_{}; float res_y_{}; float res_x_virtual_{}; @@ -353,6 +352,7 @@ class GraphicsServer { Vector3f cam_target_{0.0f, 0.0f, 0.0f}; Matrix44f light_shadow_projection_matrix_{kMatrix44fIdentity}; Matrix44f cam_orient_matrix_ = kMatrix44fIdentity; + Snapshot* client_context_{}; std::vector model_view_stack_; std::list mesh_datas_; Renderer* renderer_{}; diff --git a/src/ballistica/base/input/device/input_device.cc b/src/ballistica/base/input/device/input_device.cc index df8fdbdbe..8086e2b6e 100644 --- a/src/ballistica/base/input/device/input_device.cc +++ b/src/ballistica/base/input/device/input_device.cc @@ -48,42 +48,30 @@ auto InputDevice::GetPersistentIdentifier() const -> std::string { InputDevice::~InputDevice() { assert(g_base->InLogicThread()); } -// Called to let the current host/client-session know that we'd like to control -// something please. +// Called to let the current host/client-session know that we'd like to +// control something please. void InputDevice::RequestPlayer() { assert(g_base->InLogicThread()); // Make note that we're being used in some way. last_input_time_millisecs_ = static_cast(g_base->logic->display_time() * 1000.0); - // Tracking down a bug. - BA_PRECONDITION_FATAL(delegate_.Exists()); delegate_->RequestPlayer(); } -// If we're attached to a remote player, ship completed packets every now and -// then. -void InputDevice::Update() { - // Tracking down a bug. - BA_PRECONDITION_FATAL(delegate_.Exists()); - delegate_->Update(); -} +// If we're attached to a remote player, ship completed packets every now +// and then. +void InputDevice::Update() { delegate_->Update(); } auto InputDevice::AttachedToPlayer() const -> bool { - // Tracking down a bug. - BA_PRECONDITION_FATAL(delegate_.Exists()); return delegate_->AttachedToPlayer(); } -void InputDevice::DetachFromPlayer() { - // Tracking down a bug. - BA_PRECONDITION_FATAL(delegate_.Exists()); - delegate_->DetachFromPlayer(); -} +void InputDevice::DetachFromPlayer() { delegate_->DetachFromPlayer(); } void InputDevice::UpdateLastInputTime() { - // Keep our own individual time, and also let - // the overall input system know something happened. + // Keep our own individual time, and also let the overall input system + // know something happened. last_input_time_millisecs_ = static_cast(g_base->logic->display_time() * 1000.0); g_base->input->MarkInputActive(); @@ -95,8 +83,6 @@ void InputDevice::InputCommand(InputType type, float value) { // Make note that we're being used in some way. UpdateLastInputTime(); - // Tracking down a bug. - BA_PRECONDITION_FATAL(delegate_.Exists()); delegate_->InputCommand(type, value); } diff --git a/src/ballistica/base/input/input.cc b/src/ballistica/base/input/input.cc index fe66c1a91..e741a7f30 100644 --- a/src/ballistica/base/input/input.cc +++ b/src/ballistica/base/input/input.cc @@ -112,10 +112,11 @@ auto Input::GetNewNumberedIdentifier_(const std::string& name, } if (!in_use) { // Ok so far its unused.. however input devices that provide non-empty - // identifiers (serial number, usb-id, etc) reserve their number for the - // duration of the game, so we need to check against all reserved numbers - // so we don't steal someones... (so that if they disconnect and reconnect - // they'll get the same number and thus the same name, etc) + // identifiers (serial number, usb-id, etc) reserve their number for + // the duration of the game, so we need to check against all reserved + // numbers so we don't steal someones... (so that if they disconnect + // and reconnect they'll get the same number and thus the same name, + // etc) if (!identifier.empty()) { auto i = reserved_identifiers_.find(name); if (i != reserved_identifiers_.end()) { @@ -144,10 +145,6 @@ auto Input::GetNewNumberedIdentifier_(const std::string& name, return full_id; } -// void Input::CreateTouchInput() { -// assert(g_core->InMainThread()); -// } - void Input::AnnounceConnects_() { assert(g_base->InLogicThread()); @@ -308,10 +305,10 @@ void Input::AddInputDevice(InputDevice* device, bool standard_message) { } // We also want to give this input-device as unique an identifier as - // possible. We ask it for its own string which hopefully includes a serial - // or something, but if it doesn't and thus matches an already-existing one, - // we tack an index on to it. that way we can at least uniquely address them - // based off how many are connected. + // possible. We ask it for its own string which hopefully includes a + // serial or something, but if it doesn't and thus matches an + // already-existing one, we tack an index on to it. that way we can at + // least uniquely address them based off how many are connected. device->set_number(GetNewNumberedIdentifier_(device->GetRawDeviceName(), device->GetDeviceIdentifier())); @@ -325,23 +322,11 @@ void Input::AddInputDevice(InputDevice* device, bool standard_message) { device->UpdateMapping(); // Need to do this after updating controls, as some control settings can - // affect things we count (such as whether start activates default button). + // affect things we count (such as whether start activates default + // button). UpdateInputDeviceCounts_(); } - if (g_buildconfig.ostype_macos()) { - // Special case: on mac, the first time a iOS/Mac controller is connected, - // let the user know they may want to enable them if they're currently set - // as ignored. (the default at the moment is to only use classic device - // support). - static bool printed_ios_mac_controller_warning = false; - if (!printed_ios_mac_controller_warning && ignore_mfi_controllers_ - && device->IsMFiController()) { - ScreenMessage(R"({"r":"macControllerSubsystemMFiNoteText"})", {1, 1, 0}); - printed_ios_mac_controller_warning = true; - } - } - if (standard_message && !device->ShouldBeHiddenFromUser()) { ShowStandardInputDeviceConnectedMessage_(device); } @@ -362,16 +347,16 @@ void Input::RemoveInputDevice(InputDevice* input, bool standard_message) { ShowStandardInputDeviceDisconnectedMessage_(input); } - // Just look for it in our list.. if we find it, simply clear the ref - // (we need to keep the ref around so our list indices don't change). + // Just look for it in our list.. if we find it, simply clear the ref (we + // need to keep the ref around so our list indices don't change). for (auto& input_device : input_devices_) { if (input_device.Exists() && (input_device.Get() == input)) { // Pull it off the list before killing it (in case it tries to trigger // another kill itself). auto device = Object::Ref(input_device); - // Ok we cleared its slot in our vector; now we just have - // the local variable 'device' keeping it alive. + // Ok we cleared its slot in our vector; now we just have the local + // variable 'device' keeping it alive. input_device.Clear(); // Tell it to detach from anything it is controlling. @@ -519,41 +504,7 @@ auto Input::GetConfigurableGamePads() -> std::vector { auto Input::ShouldCompletelyIgnoreInputDevice(InputDevice* input_device) -> bool { - if (g_buildconfig.ostype_macos()) { - if (ignore_mfi_controllers_ && input_device->IsMFiController()) { - return true; - } - } - return ignore_sdl_controllers_ && input_device->IsSDLController(); -} - -void Input::UpdateEnabledControllerSubsystems_() { - assert(g_base); - - // First off, on mac, let's update whether we want to completely ignore - // either the classic or the iOS/Mac controller subsystems. - // - // UPDATE - these days we're mfi-only on our xcode builds (which should - // support older controllers too). So we don't need to touch ignore vals - // anywhere since we'll not get sdl ones on those builds. - - // if (g_buildconfig.ostype_macos()) { - // std::string sys = g_base->app_config->Resolve( - // AppConfig::StringID::kMacControllerSubsystem); - // if (sys == "Classic") { - // ignore_mfi_controllers_ = true; - // ignore_sdl_controllers_ = false; - // } else if (sys == "MFi") { - // ignore_mfi_controllers_ = false; - // ignore_sdl_controllers_ = true; - // } else if (sys == "Both") { - // ignore_mfi_controllers_ = false; - // ignore_sdl_controllers_ = false; - // } else { - // BA_LOG_ONCE(LogLevel::kError, - // "Invalid mac-controller-subsystem value: '" + sys + "'"); - // } - // } + return false; } void Input::OnAppStart() { @@ -577,8 +528,6 @@ void Input::OnAppShutdownComplete() { assert(g_base->InLogicThread()); } void Input::DoApplyAppConfig() { assert(g_base->InLogicThread()); - UpdateEnabledControllerSubsystems_(); - // It's technically possible that updating these controls will add or // remove devices, thus changing the input_devices_ list, so lets work // with a copy of it. @@ -612,10 +561,11 @@ void Input::StepDisplayTime() { } } - // We now need to update our input-device numbers dynamically since they're - // based on recently-active devices. - // ..we do this much more often for the first few seconds to keep - // controller-usage from being as annoying. + // We now need to update our input-device numbers dynamically since + // they're based on recently-active devices. We do this much more often + // for the first few seconds to keep controller-usage from being as + // annoying. + // millisecs_t incr = (real_time > 10000) ? 468 : 98; // Update: don't remember why that was annoying; trying a single value for // now. @@ -780,18 +730,18 @@ void Input::PushTextInputEvent(const std::string& text) { return; } - // Also ignore if there are any mod keys being held. - // We process some of our own keyboard shortcuts and don't - // want text input to come through at the same time. + // Also ignore if there are any mod keys being held. We process some of + // our own keyboard shortcuts and don't want text input to come through + // at the same time. if (keys_held_.contains(SDLK_LCTRL) || keys_held_.contains(SDLK_RCTRL) || keys_held_.contains(SDLK_LALT) || keys_held_.contains(SDLK_RALT) || keys_held_.contains(SDLK_LGUI) || keys_held_.contains(SDLK_RGUI)) { return; } - // Ignore back-tick and tilde because we use that key to toggle the console. - // FIXME: Perhaps should allow typing it if some control-character is - // held? + // Ignore back-tick and tilde because we use that key to toggle the + // console. FIXME: Perhaps should allow typing it if some + // control-character is held? if (text == "`" || text == "~") { return; } @@ -958,10 +908,9 @@ void Input::HandleKeyPress_(const SDL_Keysym& keysym) { return; } - // Nowadays we don't want the OS to deliver repeat events to us, - // so filter out any that we get and make noise that they should stop. We - // explicitly handle repeats for UI purposes at the InputDevice or Widget - // level now. + // Nowadays we don't want the OS to deliver repeat events to us, so filter + // out any that we get and make noise that they should stop. We explicitly + // handle repeats for UI purposes at the InputDevice or Widget level now. if (keys_held_.find(keysym.sym) != keys_held_.end()) { // Look out for several repeats coming in within the span of a few // seconds and complain if it happens. This should allow for the random @@ -993,9 +942,9 @@ void Input::HandleKeyPress_(const SDL_Keysym& keysym) { } } - // Regardless of what else we do, keep track of mod key states. - // (for things like manual camera moves. For individual key presses - // ideally we should use the modifiers bundled with the key presses) + // Regardless of what else we do, keep track of mod key states. (for + // things like manual camera moves. For individual key presses ideally we + // should use the modifiers bundled with the key presses) UpdateModKeyStates_(&keysym, true); // Mobile-specific stuff. @@ -1317,9 +1266,9 @@ void Input::HandleMouseMotion_(const Vector2f& position) { last_mouse_move_time_ = g_core->GetAppTimeSeconds(); mouse_move_count_++; - // If we have a touch-input in editing mode, pass along events to it. - // (it usually handles its own events but here we want it to play nice - // with stuff under it by blocking touches, etc) + // If we have a touch-input in editing mode, pass along events to it. (it + // usually handles its own events but here we want it to play nice with + // stuff under it by blocking touches, etc) if (touch_input_ && touch_input_->editing()) { touch_input_->HandleTouchMoved(reinterpret_cast(1), cursor_pos_x_, cursor_pos_y_); diff --git a/src/ballistica/base/input/input.h b/src/ballistica/base/input/input.h index aa4043851..a201dfb7a 100644 --- a/src/ballistica/base/input/input.h +++ b/src/ballistica/base/input/input.h @@ -157,7 +157,6 @@ class Input { void UpdateInputDeviceCounts_(); auto GetNewNumberedIdentifier_(const std::string& name, const std::string& identifier) -> int; - void UpdateEnabledControllerSubsystems_(); void AnnounceConnects_(); void AnnounceDisconnects_(); void HandleKeyPressSimple_(int keycode); @@ -190,8 +189,6 @@ class Input { bool have_button_using_inputs_ : 1 {}; bool have_start_activated_default_button_inputs_ : 1 {}; bool have_non_touch_inputs_ : 1 {}; - bool ignore_mfi_controllers_ : 1 {}; - bool ignore_sdl_controllers_ : 1 {}; millisecs_t input_idle_time_{}; millisecs_t last_get_local_active_input_device_count_check_time_{}; float cursor_pos_x_{}; diff --git a/src/ballistica/base/platform/apple/base_platform_apple.cc b/src/ballistica/base/platform/apple/base_platform_apple.cc index 66227ce87..aeeb69176 100644 --- a/src/ballistica/base/platform/apple/base_platform_apple.cc +++ b/src/ballistica/base/platform/apple/base_platform_apple.cc @@ -93,6 +93,30 @@ void BasePlatformApple::LoginAdapterBackEndActiveChange( #endif } +auto BasePlatformApple::SupportsOpenDirExternally() -> bool { +#if BA_XCODE_BUILD && BA_OSTYPE_MACOS + return true; +#else + return BasePlatform::SupportsOpenDirExternally(); +#endif +} + +void BasePlatformApple::OpenDirExternally(const std::string& path) { +#if BA_OSTYPE_MACOS && BA_XCODE_BUILD + BallisticaKit::CocoaFromCpp::openDirExternally(path); +#else + BasePlatform::OpenDirExternally(path); +#endif +} + +void BasePlatformApple::OpenFileExternally(const std::string& path) { +#if BA_OSTYPE_MACOS && BA_XCODE_BUILD + BallisticaKit::CocoaFromCpp::openFileExternally(path); +#else + BasePlatform::OpenFileExternally(path); +#endif +} + } // namespace ballistica::base #endif // BA_OSTYPE_MACOS || BA_OSTYPE_IOS_TVOS diff --git a/src/ballistica/base/platform/apple/base_platform_apple.h b/src/ballistica/base/platform/apple/base_platform_apple.h index 9ccc5bb12..f6e5362ba 100644 --- a/src/ballistica/base/platform/apple/base_platform_apple.h +++ b/src/ballistica/base/platform/apple/base_platform_apple.h @@ -20,6 +20,9 @@ class BasePlatformApple : public BasePlatform { int attempt_id) override; void LoginAdapterBackEndActiveChange(const std::string& login_type, bool active) override; + auto SupportsOpenDirExternally() -> bool override; + void OpenDirExternally(const std::string& path) override; + void OpenFileExternally(const std::string& path) override; }; } // namespace ballistica::base diff --git a/src/ballistica/base/platform/base_platform.cc b/src/ballistica/base/platform/base_platform.cc index d6a2cfffe..afddeaf13 100644 --- a/src/ballistica/base/platform/base_platform.cc +++ b/src/ballistica/base/platform/base_platform.cc @@ -221,4 +221,14 @@ void BasePlatform::DoInvokeStringEditor(const std::string& title, Log(LogLevel::kError, "FIXME: DoInvokeStringEditor() unimplemented"); } +auto BasePlatform::SupportsOpenDirExternally() -> bool { return false; } + +void BasePlatform::OpenDirExternally(const std::string& path) { + Log(LogLevel::kError, "OpenDirExternally() unimplemented"); +} + +void BasePlatform::OpenFileExternally(const std::string& path) { + Log(LogLevel::kError, "OpenFileExternally() unimplemented"); +} + } // namespace ballistica::base diff --git a/src/ballistica/base/platform/base_platform.h b/src/ballistica/base/platform/base_platform.h index 6470074ab..4e139bd79 100644 --- a/src/ballistica/base/platform/base_platform.h +++ b/src/ballistica/base/platform/base_platform.h @@ -98,6 +98,16 @@ class BasePlatform { auto ran_base_post_init() const { return ran_base_post_init_; } + /// Do we support opening dirs exteranlly? (via finder, windows explorer, + /// etc.) + virtual auto SupportsOpenDirExternally() -> bool; + + /// Open a directory using the system default method (Finder, etc.) + virtual void OpenDirExternally(const std::string& path); + + /// Open a file using the system default method (in another app, etc.) + virtual void OpenFileExternally(const std::string& path); + protected: /// Pop up a text edit dialog. virtual void DoInvokeStringEditor(const std::string& title, diff --git a/src/ballistica/base/platform/linux/base_platform_linux.cc b/src/ballistica/base/platform/linux/base_platform_linux.cc index 7e997ad16..f4b37acc3 100644 --- a/src/ballistica/base/platform/linux/base_platform_linux.cc +++ b/src/ballistica/base/platform/linux/base_platform_linux.cc @@ -17,6 +17,26 @@ void BasePlatformLinux::DoOpenURL(const std::string& url) { BasePlatform::DoOpenURL(url); } +auto BasePlatformLinux::SupportsOpenDirExternally() -> bool { return true; } + +void BasePlatformLinux::OpenDirExternally(const std::string& path) { + std::string cmd = std::string("xdg-open \"") + path + "\""; + int result = system(cmd.c_str()); + if (result != 0) { + Log(LogLevel::kError, "Got return value " + std::to_string(result) + + " on xdg-open cmd '" + cmd + "'"); + } +} + +void BasePlatformLinux::OpenFileExternally(const std::string& path) { + std::string cmd = std::string("xdg-open \"") + path + "\""; + int result = system(cmd.c_str()); + if (result != 0) { + Log(LogLevel::kError, "Got return value " + std::to_string(result) + + " on xdg-open cmd '" + cmd + "'"); + } +} + } // namespace ballistica::base #endif // BA_OSTYPE_LINUX diff --git a/src/ballistica/base/platform/linux/base_platform_linux.h b/src/ballistica/base/platform/linux/base_platform_linux.h index 9be9c1b89..795fe5dff 100644 --- a/src/ballistica/base/platform/linux/base_platform_linux.h +++ b/src/ballistica/base/platform/linux/base_platform_linux.h @@ -14,6 +14,9 @@ class BasePlatformLinux : public BasePlatform { public: BasePlatformLinux(); void DoOpenURL(const std::string& url) override; + auto SupportsOpenDirExternally() -> bool override; + void OpenDirExternally(const std::string& path) override; + void OpenFileExternally(const std::string& path) override; }; } // namespace ballistica::base diff --git a/src/ballistica/base/platform/windows/base_platform_windows.cc b/src/ballistica/base/platform/windows/base_platform_windows.cc index 80f30f812..ea3dd39bd 100644 --- a/src/ballistica/base/platform/windows/base_platform_windows.cc +++ b/src/ballistica/base/platform/windows/base_platform_windows.cc @@ -15,6 +15,7 @@ #include "ballistica/base/logic/logic.h" #include "ballistica/core/platform/windows/core_platform_windows.h" #include "ballistica/shared/foundation/event_loop.h" +#include "ballistica/shared/generic/utils.h" namespace ballistica::base { @@ -62,6 +63,30 @@ void BasePlatformWindows::SetupInterruptHandling() { } } +auto BasePlatformWindows::SupportsOpenDirExternally() -> bool { return true; } + +void BasePlatformWindows::OpenDirExternally(const std::string& path) { + auto r = reinterpret_cast( + ShellExecute(nullptr, _T("open"), _T("explorer.exe"), + core::CorePlatformWindows::UTF8Decode(path).c_str(), nullptr, + SW_SHOWNORMAL)); + if (r <= 32) { + Log(LogLevel::kError, "Error " + std::to_string(r) + + " on open_dir_externally for '" + path + "'"); + } +} + +void BasePlatformWindows::OpenFileExternally(const std::string& path) { + auto r = reinterpret_cast( + ShellExecute(nullptr, _T("open"), _T("notepad.exe"), + core::CorePlatformWindows::UTF8Decode(path).c_str(), nullptr, + SW_SHOWNORMAL)); + if (r <= 32) { + Log(LogLevel::kError, "Error " + std::to_string(r) + + " on open_file_externally for '" + path + "'"); + } +} + } // namespace ballistica::base #endif // BA_OSTYPE_WINDOWS diff --git a/src/ballistica/base/platform/windows/base_platform_windows.h b/src/ballistica/base/platform/windows/base_platform_windows.h index 8ce9b4a37..05025d8e3 100644 --- a/src/ballistica/base/platform/windows/base_platform_windows.h +++ b/src/ballistica/base/platform/windows/base_platform_windows.h @@ -16,6 +16,9 @@ class BasePlatformWindows : public BasePlatform { BasePlatformWindows(); void DoOpenURL(const std::string& url) override; void SetupInterruptHandling() override; + auto SupportsOpenDirExternally() -> bool override; + void OpenDirExternally(const std::string& path) override; + void OpenFileExternally(const std::string& path) override; }; } // namespace ballistica::base diff --git a/src/ballistica/base/python/methods/python_methods_misc.cc b/src/ballistica/base/python/methods/python_methods_misc.cc index bf4783e27..d8e59e453 100644 --- a/src/ballistica/base/python/methods/python_methods_misc.cc +++ b/src/ballistica/base/python/methods/python_methods_misc.cc @@ -1395,6 +1395,31 @@ static PyMethodDef PyNativeStackTraceDef = { "Only use them for debugging.", }; +// --------------------- supports_open_dir_externally -------------------------- + +static auto PySupportsOpenDirExternally(PyObject* self, PyObject* args, + PyObject* keywds) -> PyObject* { + BA_PYTHON_TRY; + if (g_base->platform->SupportsOpenDirExternally()) { + Py_RETURN_TRUE; + } + Py_RETURN_FALSE; + BA_PYTHON_CATCH; +} + +static PyMethodDef PySupportsOpenDirExternallyDef = { + "supports_open_dir_externally", // name + (PyCFunction)PySupportsOpenDirExternally, // method + METH_NOARGS, // flags + + "supports_open_dir_externally() -> bool\n" + "\n" + "(internal)\n" + "\n" + "Return whether the current app/platform supports opening dirs externally\n" + "(in the Mac Finder, Windows Explorer, etc.).", +}; + // -------------------------- open_dir_externally ------------------------------ static auto PyOpenDirExternally(PyObject* self, PyObject* args, @@ -1406,7 +1431,7 @@ static auto PyOpenDirExternally(PyObject* self, PyObject* args, const_cast(kwlist), &path)) { return nullptr; } - g_core->platform->OpenDirExternally(path); + g_base->platform->OpenDirExternally(path); Py_RETURN_NONE; BA_PYTHON_CATCH; } @@ -1816,6 +1841,7 @@ auto PythonMethodsMisc::GetMethods() -> std::vector { PyGetSimpleSoundDef, PyHasTouchScreenDef, PyNativeStackTraceDef, + PySupportsOpenDirExternallyDef, PyOpenDirExternallyDef, PyFatalErrorDef, PyDevConsoleAddButtonDef, diff --git a/src/ballistica/base/ui/dev_console.cc b/src/ballistica/base/ui/dev_console.cc index 437b81a4c..7f31eae3b 100644 --- a/src/ballistica/base/ui/dev_console.cc +++ b/src/ballistica/base/ui/dev_console.cc @@ -6,6 +6,7 @@ #include "ballistica/base/app_mode/app_mode.h" #include "ballistica/base/audio/audio.h" #include "ballistica/base/graphics/component/simple_component.h" +#include "ballistica/base/graphics/mesh/nine_patch_mesh.h" #include "ballistica/base/graphics/text/text_graphics.h" #include "ballistica/base/logic/logic.h" #include "ballistica/base/platform/base_platform.h" diff --git a/src/ballistica/base/ui/dev_console.h b/src/ballistica/base/ui/dev_console.h index 7e080acef..21672985f 100644 --- a/src/ballistica/base/ui/dev_console.h +++ b/src/ballistica/base/ui/dev_console.h @@ -8,7 +8,6 @@ #include #include -#include "ballistica/base/graphics/mesh/nine_patch_mesh.h" #include "ballistica/base/graphics/renderer/renderer.h" #include "ballistica/shared/foundation/object.h" #include "ballistica/shared/python/python_ref.h" diff --git a/src/ballistica/core/platform/apple/core_platform_apple.cc b/src/ballistica/core/platform/apple/core_platform_apple.cc index 2122cfe68..5d7fbeafd 100644 --- a/src/ballistica/core/platform/apple/core_platform_apple.cc +++ b/src/ballistica/core/platform/apple/core_platform_apple.cc @@ -25,13 +25,14 @@ namespace ballistica::core { CorePlatformApple::CorePlatformApple() = default; auto CorePlatformApple::GetDeviceV1AccountUUIDPrefix() -> std::string { -#if BA_OSTYPE_MACOS - return "m"; -#elif BA_OSTYPE_IOS_TVOS - return "i"; -#else -#error FIXME -#endif + if (g_buildconfig.ostype_macos()) { + return "m"; + } else if (g_buildconfig.ostype_ios_tvos()) { + return "i"; + } else { + FatalError("Unhandled V1 UUID case."); + return ""; + } } auto CorePlatformApple::DoGetDeviceName() -> std::string { @@ -349,22 +350,6 @@ auto CorePlatformApple::IsOSPlayingMusic() -> bool { #endif } -void CorePlatformApple::OpenFileExternally(const std::string& path) { -#if BA_OSTYPE_MACOS && BA_XCODE_BUILD - BallisticaKit::CocoaFromCpp::openFileExternally(path); -#else - CorePlatform::OpenFileExternally(path); -#endif -} - -void CorePlatformApple::OpenDirExternally(const std::string& path) { -#if BA_OSTYPE_MACOS && BA_XCODE_BUILD - BallisticaKit::CocoaFromCpp::openDirExternally(path); -#else - CorePlatform::OpenDirExternally(path); -#endif -} - void CorePlatformApple::MacMusicAppInit() { #if BA_OSTYPE_MACOS && BA_XCODE_BUILD BallisticaKit::CocoaFromCpp::macMusicAppInit(); diff --git a/src/ballistica/core/platform/apple/core_platform_apple.h b/src/ballistica/core/platform/apple/core_platform_apple.h index 3d8bc6dd4..8fe4972a5 100644 --- a/src/ballistica/core/platform/apple/core_platform_apple.h +++ b/src/ballistica/core/platform/apple/core_platform_apple.h @@ -44,10 +44,7 @@ class CorePlatformApple : public CorePlatform { void ShowOnlineScoreUI(const std::string& show, const std::string& game, const std::string& game_version) override; void ResetAchievements() override; - // void GameCenterLogin() override; auto IsOSPlayingMusic() -> bool override; - void OpenFileExternally(const std::string& path) override; - void OpenDirExternally(const std::string& path) override; void MacMusicAppInit() override; auto MacMusicAppGetVolume() -> int override; void MacMusicAppSetVolume(int volume) override; diff --git a/src/ballistica/core/platform/core_platform.cc b/src/ballistica/core/platform/core_platform.cc index e20c51559..c8de561d5 100644 --- a/src/ballistica/core/platform/core_platform.cc +++ b/src/ballistica/core/platform/core_platform.cc @@ -804,14 +804,6 @@ void CorePlatform::SignOutV1() { Log(LogLevel::kError, "SignOutV1() unimplemented"); } -void CorePlatform::OpenFileExternally(const std::string& path) { - Log(LogLevel::kError, "OpenFileExternally() unimplemented"); -} - -void CorePlatform::OpenDirExternally(const std::string& path) { - Log(LogLevel::kError, "OpenDirExternally() unimplemented"); -} - void CorePlatform::MacMusicAppInit() { Log(LogLevel::kError, "MacMusicAppInit() unimplemented"); } diff --git a/src/ballistica/core/platform/core_platform.h b/src/ballistica/core/platform/core_platform.h index d57bcb8b5..250708d8f 100644 --- a/src/ballistica/core/platform/core_platform.h +++ b/src/ballistica/core/platform/core_platform.h @@ -384,12 +384,6 @@ class CorePlatform { /// Pass platform-specific misc-read-vals along to the OS (as a json string). virtual void SetPlatformMiscReadVals(const std::string& vals); - /// Open a file using the system default method (in another app, etc.) - virtual void OpenFileExternally(const std::string& path); - - /// Open a directory using the system default method (Finder, etc.) - virtual void OpenDirExternally(const std::string& path); - /// Set the name of the current thread (for debugging). virtual void SetCurrentThreadName(const std::string& name); diff --git a/src/ballistica/core/platform/linux/core_platform_linux.cc b/src/ballistica/core/platform/linux/core_platform_linux.cc index c6e32e873..96686f143 100644 --- a/src/ballistica/core/platform/linux/core_platform_linux.cc +++ b/src/ballistica/core/platform/linux/core_platform_linux.cc @@ -100,24 +100,6 @@ auto CorePlatformLinux::GetDeviceUUIDInputs() -> std::list { bool CorePlatformLinux::DoHasTouchScreen() { return false; } -void CorePlatformLinux::OpenFileExternally(const std::string& path) { - std::string cmd = std::string("xdg-open \"") + path + "\""; - int result = system(cmd.c_str()); - if (result != 0) { - Log(LogLevel::kError, "Got return value " + std::to_string(result) - + " on xdg-open cmd '" + cmd + "'"); - } -} - -void CorePlatformLinux::OpenDirExternally(const std::string& path) { - std::string cmd = std::string("xdg-open \"") + path + "\""; - int result = system(cmd.c_str()); - if (result != 0) { - Log(LogLevel::kError, "Got return value " + std::to_string(result) - + " on xdg-open cmd '" + cmd + "'"); - } -} - std::string CorePlatformLinux::GetPlatformName() { return "linux"; } std::string CorePlatformLinux::GetSubplatformName() { diff --git a/src/ballistica/core/platform/linux/core_platform_linux.h b/src/ballistica/core/platform/linux/core_platform_linux.h index 22834b6c8..d37e1113d 100644 --- a/src/ballistica/core/platform/linux/core_platform_linux.h +++ b/src/ballistica/core/platform/linux/core_platform_linux.h @@ -16,8 +16,6 @@ class CorePlatformLinux : public CorePlatform { auto GetDeviceV1AccountUUIDPrefix() -> std::string override { return "l"; } auto GenerateUUID() -> std::string override; auto DoHasTouchScreen() -> bool override; - void OpenFileExternally(const std::string& path) override; - void OpenDirExternally(const std::string& path) override; auto GetPlatformName() -> std::string override; auto GetSubplatformName() -> std::string override; auto GetDeviceUUIDInputs() -> std::list override; diff --git a/src/ballistica/core/platform/windows/core_platform_windows.cc b/src/ballistica/core/platform/windows/core_platform_windows.cc index 7a3d06ac4..cfcff5e60 100644 --- a/src/ballistica/core/platform/windows/core_platform_windows.cc +++ b/src/ballistica/core/platform/windows/core_platform_windows.cc @@ -964,26 +964,6 @@ std::string CorePlatformWindows::GetCWD() { return UTF8Encode(buffer); } -void CorePlatformWindows::OpenFileExternally(const std::string& path) { - auto r = reinterpret_cast( - ShellExecute(nullptr, _T("open"), _T("notepad.exe"), - UTF8Decode(path).c_str(), nullptr, SW_SHOWNORMAL)); - if (r <= 32) { - Log(LogLevel::kError, "Error " + std::to_string(r) - + " on open_file_externally for '" + path + "'"); - } -} - -void CorePlatformWindows::OpenDirExternally(const std::string& path) { - auto r = reinterpret_cast( - ShellExecute(nullptr, _T("open"), _T("explorer.exe"), - UTF8Decode(path).c_str(), nullptr, SW_SHOWNORMAL)); - if (r <= 32) { - Log(LogLevel::kError, "Error " + std::to_string(r) - + " on open_dir_externally for '" + path + "'"); - } -} - void CorePlatformWindows::Unlink(const char* path) { _unlink(path); } void CorePlatformWindows::CloseSocket(int socket) { closesocket(socket); } diff --git a/src/ballistica/core/platform/windows/core_platform_windows.h b/src/ballistica/core/platform/windows/core_platform_windows.h index ede060eb4..fce895809 100644 --- a/src/ballistica/core/platform/windows/core_platform_windows.h +++ b/src/ballistica/core/platform/windows/core_platform_windows.h @@ -49,8 +49,6 @@ class CorePlatformWindows : public CorePlatform { auto GetIsStdinATerminal() -> bool override; auto GetOSVersionString() -> std::string override; auto GetCWD() -> std::string override; - void OpenFileExternally(const std::string& path) override; - void OpenDirExternally(const std::string& path) override; void Unlink(const char* path) override; void CloseSocket(int socket) override; auto GetBroadcastAddrs() -> std::vector override; diff --git a/src/ballistica/scene_v1/support/client_session_net.cc b/src/ballistica/scene_v1/support/client_session_net.cc index aaf089eec..a7d7c41f7 100644 --- a/src/ballistica/scene_v1/support/client_session_net.cc +++ b/src/ballistica/scene_v1/support/client_session_net.cc @@ -5,6 +5,7 @@ #include "ballistica/base/assets/assets_server.h" #include "ballistica/base/graphics/graphics.h" #include "ballistica/base/graphics/support/net_graph.h" +#include "ballistica/base/logic/logic.h" #include "ballistica/scene_v1/connection/connection_to_host.h" #include "ballistica/scene_v1/support/scene_v1_app_mode.h" @@ -118,24 +119,27 @@ void ClientSessionNet::UpdateBuffering() { set_consume_rate(new_consume_rate); if (g_base->graphics->network_debug_info_display_enabled()) { + // Plug display time into these graphs to get smoother looking updates. + auto now_d = g_base->logic->display_time() * 1000.0; + if (auto* graph = g_base->graphics->GetDebugGraph("1: packet delay", false)) { - graph->AddSample(now, current_delay_); + graph->AddSample(now_d, current_delay_); } if (auto* graph = g_base->graphics->GetDebugGraph("2: max delay bucketed", false)) { - graph->AddSample(now, last_bucket_max_delay_); + graph->AddSample(now_d, last_bucket_max_delay_); } if (auto* graph = g_base->graphics->GetDebugGraph("3: filtered delay", false)) { - graph->AddSample(now, max_delay_smoothed_); + graph->AddSample(now_d, max_delay_smoothed_); } if (auto* graph = g_base->graphics->GetDebugGraph("4: run rate", false)) { - graph->AddSample(now, new_consume_rate); + graph->AddSample(now_d, new_consume_rate); } if (auto* graph = g_base->graphics->GetDebugGraph("5: time buffered", true)) { - graph->AddSample(now, base_time_buffered()); + graph->AddSample(now_d, base_time_buffered()); } } } diff --git a/src/ballistica/shared/ballistica.cc b/src/ballistica/shared/ballistica.cc index 8a54713bf..60cb55c91 100644 --- a/src/ballistica/shared/ballistica.cc +++ b/src/ballistica/shared/ballistica.cc @@ -39,7 +39,7 @@ auto main(int argc, char** argv) -> int { namespace ballistica { // These are set automatically via script; don't modify them here. -const int kEngineBuildNumber = 21585; +const int kEngineBuildNumber = 21588; const char* kEngineVersion = "1.7.28"; const int kEngineApiVersion = 8; 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 f50fb4bab..87434540b 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 @@ -1868,6 +1868,7 @@ static auto PyTextWidget(PyObject* self, PyObject* args, PyObject* keywds) PyObject* query_max_chars_obj = Py_None; PyObject* query_description_obj = Py_None; PyObject* adapter_finished_obj = Py_None; + PyObject* glow_type_obj = Py_None; static const char* kwlist[] = {"edit", "parent", @@ -1907,9 +1908,10 @@ static auto PyTextWidget(PyObject* self, PyObject* args, PyObject* keywds) "query_max_chars", "query_description", "adapter_finished", + "glow_type", nullptr}; if (!PyArg_ParseTupleAndKeywords( - args, keywds, "|OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", + args, keywds, "|OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", const_cast(kwlist), &edit_obj, &parent_obj, &size_obj, &pos_obj, &text_obj, &v_align_obj, &h_align_obj, &editable_obj, &padding_obj, &on_return_press_call_obj, &on_activate_call_obj, @@ -1920,7 +1922,7 @@ static auto PyTextWidget(PyObject* self, PyObject* args, PyObject* keywds) &shadow_obj, &autoselect_obj, &rotate_obj, &enabled_obj, &force_internal_editing_obj, &always_show_carat_obj, &big_obj, &extra_touch_border_scale_obj, &res_scale_obj, &query_max_chars_obj, - &query_description_obj, &adapter_finished_obj)) + &query_description_obj, &adapter_finished_obj, &glow_type_obj)) return nullptr; if (!g_base->CurrentContext().IsEmpty()) { @@ -2123,8 +2125,20 @@ static auto PyTextWidget(PyObject* self, PyObject* args, PyObject* keywds) throw Exception("Unexpected value for adapter_finished"); } } + if (glow_type_obj != Py_None) { + auto glow_type_s = Python::GetPyString(glow_type_obj); + TextWidget::GlowType glow_type; + if (glow_type_s == "uniform") { + glow_type = TextWidget::GlowType::kUniform; + } else if (glow_type_s == "gradient") { + glow_type = TextWidget::GlowType::kGradient; + } else { + throw Exception("Invalid glow_type: " + glow_type_s, PyExcType::kValue); + } + widget->set_glow_type(glow_type); + } - // if making a new widget add it at the end + // If making a new widget, add it at the end. if (edit_obj == Py_None) { g_ui_v1->AddWidget(widget.Get(), parent_widget); } @@ -2175,7 +2189,8 @@ static PyMethodDef PyTextWidgetDef = { " res_scale: float | None = None," " query_max_chars: bauiv1.Widget | None = None,\n" " query_description: bauiv1.Widget | None = None,\n" - " adapter_finished: bool | None = None)\n" + " adapter_finished: bool | None = None,\n" + " glow_type: str | None = None)\n" " -> bauiv1.Widget\n" "\n" "Create or edit a text widget.\n" @@ -2725,7 +2740,7 @@ static auto PyOpenFileExternally(PyObject* self, PyObject* args, const_cast(kwlist), &path)) { return nullptr; } - g_core->platform->OpenFileExternally(path); + g_base->platform->OpenFileExternally(path); Py_RETURN_NONE; BA_PYTHON_CATCH; } diff --git a/src/ballistica/ui_v1/widget/text_widget.cc b/src/ballistica/ui_v1/widget/text_widget.cc index 61781355b..a40f15d4c 100644 --- a/src/ballistica/ui_v1/widget/text_widget.cc +++ b/src/ballistica/ui_v1/widget/text_widget.cc @@ -6,6 +6,7 @@ #include "ballistica/base/audio/audio.h" #include "ballistica/base/graphics/component/empty_component.h" #include "ballistica/base/graphics/component/simple_component.h" +#include "ballistica/base/graphics/mesh/nine_patch_mesh.h" #include "ballistica/base/graphics/text/text_graphics.h" #include "ballistica/base/input/device/keyboard_input.h" #include "ballistica/base/input/input.h" @@ -114,8 +115,9 @@ void TextWidget::Draw(base::RenderPass* pass, bool draw_transparent) { // another component at the end with the matching pop. This only works // because the components in the middle wind up writing to the same draw // list, but there is nothing checking or enforcing that so it would be - // easy to break. Should improve this somehow. (perhaps by using a single - // component and enforcing list uniformity between push/pop blocks?) + // easy to break. Should improve this somehow. (perhaps by using a + // single component and enforcing list uniformity between push/pop + // blocks?) c.PushTransform(); // Move to middle, scale down, move back. @@ -159,34 +161,68 @@ void TextWidget::Draw(base::RenderPass* pass, bool draw_transparent) { } if (highlight_dirty_) { - float l_border, r_border, b_border, t_border; - float l2 = bound_l; - float r2 = bound_r; - float t2 = bound_t; - float b2 = bound_b; - l_border = std::max(10.0f, (r2 - l2) * 0.05f); - r_border = 0; - b_border = std::max(16.0f, (t2 - b2) * 0.16f); - t_border = std::max(14.0f, (t2 - b2) * 0.14f); - highlight_width_ = r2 - l2 + l_border + r_border; - highlight_height_ = t2 - b2 + b_border + t_border; - highlight_center_x_ = l2 - l_border + highlight_width_ * 0.5f; - highlight_center_y_ = b2 - b_border + highlight_height_ * 0.5f; + if (glow_type_ == GlowType::kGradient) { + float l_border, r_border, b_border, t_border; + float l2 = bound_l; + float r2 = bound_r; + float t2 = bound_t; + float b2 = bound_b; + l_border = std::max(10.0f, (r2 - l2) * 0.05f); + r_border = 0; + b_border = std::max(16.0f, (t2 - b2) * 0.16f); + t_border = std::max(14.0f, (t2 - b2) * 0.14f); + highlight_width_ = r2 - l2 + l_border + r_border; + highlight_height_ = t2 - b2 + b_border + t_border; + highlight_center_x_ = l2 - l_border + highlight_width_ * 0.5f; + highlight_center_y_ = b2 - b_border + highlight_height_ * 0.5f; + highlight_mesh_.Clear(); + } else { + assert(glow_type_ == GlowType::kUniform); + float corner_radius{30.0f}; + float width{bound_r - bound_l}; + float height{bound_t - bound_b}; + float x_extend{12.0f}; + float y_extend{6.0f}; + float x_offset{0.0f}; + float width_fin = width + x_extend * 2.0f; + float height_fin = height + y_extend * 2.0f; + float x_border = base::NinePatchMesh::BorderForRadius( + corner_radius, width_fin, height_fin); + float y_border = base::NinePatchMesh::BorderForRadius( + corner_radius, height_fin, width_fin); + + highlight_mesh_ = Object::New( + -x_extend + x_offset, -y_extend, 0.0f, width_fin, height_fin, + x_border, y_border, x_border, y_border); + } highlight_dirty_ = false; } - base::SimpleComponent c(pass); - c.SetTransparent(true); - c.SetPremultiplied(true); - c.SetColor(0.25f * m, 0.3f * m, 0, 0.3f * m); - c.SetTexture(g_base->assets->SysTexture(base::SysTextureID::kGlow)); - { - auto xf = c.ScopedTransform(); - c.Translate(highlight_center_x_, highlight_center_y_, 0.1f); - c.Scale(highlight_width_, highlight_height_); - c.DrawMeshAsset(g_base->assets->SysMesh(base::SysMeshID::kImage4x1)); + if (glow_type_ == GlowType::kGradient) { + base::SimpleComponent c(pass); + c.SetTransparent(true); + c.SetPremultiplied(true); + c.SetColor(0.25f * m, 0.3f * m, 0, 0.3f * m); + c.SetTexture(g_base->assets->SysTexture(base::SysTextureID::kGlow)); + { + auto xf = c.ScopedTransform(); + c.Translate(highlight_center_x_, highlight_center_y_, 0.1f); + c.Scale(highlight_width_, highlight_height_); + c.DrawMeshAsset(g_base->assets->SysMesh(base::SysMeshID::kImage4x1)); + } + } else { + assert(glow_type_ == GlowType::kUniform); + base::SimpleComponent c(pass); + c.SetTransparent(true); + c.SetColor(0.9 * m, 1.0f * m, 0, 0.3f * m); + c.SetTexture( + g_base->assets->SysTexture(base::SysTextureID::kShadowSharp)); + { + auto xf = c.ScopedTransform(); + c.Translate(bound_l, bound_b, 0.1f); + c.DrawMesh(highlight_mesh_.Get()); + } } - c.Submit(); } // Outline. @@ -660,7 +696,7 @@ auto TextWidget::HandleMessage(const base::WidgetMessage& m) -> bool { } } // If we're doing inline editing, handle some key events. - if (m.has_keysym && !ShouldUseStringEditor_()) { + if (editable() && m.has_keysym && !ShouldUseStringEditor_()) { last_carat_change_time_millisecs_ = static_cast(g_base->logic->display_time() * 1000.0); text_group_dirty_ = true; diff --git a/src/ballistica/ui_v1/widget/text_widget.h b/src/ballistica/ui_v1/widget/text_widget.h index 1d295803e..c247e3aa6 100644 --- a/src/ballistica/ui_v1/widget/text_widget.h +++ b/src/ballistica/ui_v1/widget/text_widget.h @@ -21,8 +21,9 @@ class TextWidget : public Widget { void SetHeight(float heightIn); auto GetWidth() -> float override; auto GetHeight() -> float override; - enum class HAlign { kLeft, kCenter, kRight }; - enum class VAlign { kTop, kCenter, kBottom }; + enum class HAlign : uint8_t { kLeft, kCenter, kRight }; + enum class VAlign : uint8_t { kTop, kCenter, kBottom }; + enum class GlowType : uint8_t { kGradient, kUniform }; auto HandleMessage(const base::WidgetMessage& m) -> bool override; auto IsSelectable() -> bool override { return (enabled_ && (editable_ || selectable_)); @@ -87,6 +88,13 @@ class TextWidget : public Widget { void set_extra_touch_border_scale(float scale) { extra_touch_border_scale_ = scale; } + void set_glow_type(GlowType glow_type) { + if (glow_type == glow_type_) { + return; + } + glow_type_ = glow_type; + highlight_dirty_ = true; + } private: auto ScaleAdjustedX_(float x) -> float; @@ -101,18 +109,35 @@ class TextWidget : public Widget { float max_height_scale); void DoDrawText_(base::RenderPass* pass, float x_offset, float y_offset, float max_width_scale, float max_height_scale); + + HAlign alignment_h_{HAlign::kLeft}; + VAlign alignment_v_{VAlign::kTop}; + GlowType glow_type_{GlowType::kGradient}; + bool enabled_ : 1 {true}; + bool big_ : 1 {}; + bool force_internal_editing_ : 1 {}; + bool always_show_carat_ : 1 {}; + bool highlight_dirty_ : 1 {true}; + bool text_translation_dirty_ : 1 {true}; + bool text_group_dirty_ : 1 {true}; + bool outline_dirty_ : 1 {true}; + bool click_activate_ : 1 {}; + bool mouse_over_ : 1 {}; + bool pressed_ : 1 {}; + bool pressed_activate_ : 1 {}; + bool always_highlight_ : 1 {}; + bool editable_ : 1 {}; + bool selectable_ : 1 {}; + bool clear_pressed_ : 1 {}; + bool clear_mouse_over_ : 1 {}; + bool do_clear_button_ : 1 {true}; + int carat_position_{9999}; + int max_chars_{99999}; float res_scale_{1.0f}; - bool enabled_{true}; - millisecs_t birth_time_millisecs_{}; float transition_delay_{}; float max_width_{-1.0f}; float max_height_{-1.0f}; float extra_touch_border_scale_{1.0f}; - Object::Ref text_group_; - bool big_{}; - bool force_internal_editing_{}; - bool always_show_carat_{}; - std::string description_{"Text"}; float highlight_width_{}; float highlight_height_{}; float highlight_center_x_{}; @@ -124,42 +149,28 @@ class TextWidget : public Widget { float text_width_{}; float text_height_{}; float rotate_{}; - bool highlight_dirty_{true}; - bool text_translation_dirty_{true}; - bool text_group_dirty_{true}; - bool outline_dirty_{true}; - bool click_activate_{}; - int max_chars_{99999}; float color_r_{1.0f}; float color_g_{1.0f}; float color_b_{1.0f}; float color_a_{1.0f}; - bool mouse_over_{}; + float flatness_{}; + float shadow_{0.5f}; float padding_{}; - bool pressed_{}; - bool pressed_activate_{}; - bool always_highlight_{}; - int carat_position_{9999}; - bool editable_{}; - bool selectable_{}; float width_{50.0f}; float height_{30.0f}; - bool clear_pressed_{}; - bool clear_mouse_over_{}; - bool do_clear_button_{true}; float center_scale_{1.0f}; std::string text_raw_; std::string text_translated_; - HAlign alignment_h_{HAlign::kLeft}; - VAlign alignment_v_{VAlign::kTop}; - float flatness_{}; - float shadow_{0.5f}; + millisecs_t birth_time_millisecs_{}; millisecs_t last_activate_time_millisecs_{}; millisecs_t last_carat_change_time_millisecs_{}; + std::string description_{"Text"}; + Object::Ref text_group_; // We keep these at the bottom so they're torn down first. Object::Ref on_return_press_call_; Object::Ref on_activate_call_; + Object::Ref highlight_mesh_; PythonRef string_edit_adapter_; };