dev-console work in progress

This commit is contained in:
Eric 2023-09-13 09:59:46 -07:00
parent 7579225a3d
commit 034094d0a3
No known key found for this signature in database
GPG Key ID: 89C93F0F8D6D5A98
36 changed files with 944 additions and 758 deletions

80
.efrocachemap generated
View File

@ -1108,10 +1108,6 @@
"build/assets/ba_data/textures/agentIconColorMask.pvr": "075f61aae95df3456dc37dd598e73c93", "build/assets/ba_data/textures/agentIconColorMask.pvr": "075f61aae95df3456dc37dd598e73c93",
"build/assets/ba_data/textures/agentIconColorMask_preview.png": "0f93c1b587d4da394a706ea975c02801", "build/assets/ba_data/textures/agentIconColorMask_preview.png": "0f93c1b587d4da394a706ea975c02801",
"build/assets/ba_data/textures/agentIcon_preview.png": "4dd9bed5d6b0d9fd06ad3c7245bd0af3", "build/assets/ba_data/textures/agentIcon_preview.png": "4dd9bed5d6b0d9fd06ad3c7245bd0af3",
"build/assets/ba_data/textures/aliBSRemoteIOSQR.dds": "36f0109aab733ac8c564134a5c6b8565",
"build/assets/ba_data/textures/aliBSRemoteIOSQR.ktx": "154b455d458339bae37f4f83ed3bf9ba",
"build/assets/ba_data/textures/aliBSRemoteIOSQR.pvr": "17c9acb519e98485cd063375aab43b3a",
"build/assets/ba_data/textures/aliBSRemoteIOSQR_preview.png": "a6babeb7c3cc08e781c743d15e80f44d",
"build/assets/ba_data/textures/aliColor.dds": "7f87ef5a6d6465a09f9ed651bbc47040", "build/assets/ba_data/textures/aliColor.dds": "7f87ef5a6d6465a09f9ed651bbc47040",
"build/assets/ba_data/textures/aliColor.ktx": "cfb95bf0ac3f489c2b715613a901d405", "build/assets/ba_data/textures/aliColor.ktx": "cfb95bf0ac3f489c2b715613a901d405",
"build/assets/ba_data/textures/aliColor.pvr": "098d12386d71cdbf1d8b8f8ea6658ba8", "build/assets/ba_data/textures/aliColor.pvr": "098d12386d71cdbf1d8b8f8ea6658ba8",
@ -1120,10 +1116,6 @@
"build/assets/ba_data/textures/aliColorMask.pvr": "44160498f3290b08a0c8619b46f38d62", "build/assets/ba_data/textures/aliColorMask.pvr": "44160498f3290b08a0c8619b46f38d62",
"build/assets/ba_data/textures/aliColorMask_preview.png": "47fa53145d34727c863a47830e378c4a", "build/assets/ba_data/textures/aliColorMask_preview.png": "47fa53145d34727c863a47830e378c4a",
"build/assets/ba_data/textures/aliColor_preview.png": "5a23819c762d483bf9fc7b12ad29acce", "build/assets/ba_data/textures/aliColor_preview.png": "5a23819c762d483bf9fc7b12ad29acce",
"build/assets/ba_data/textures/aliControllerQR.dds": "9436ee9bd470325835d92538b68eddf6",
"build/assets/ba_data/textures/aliControllerQR.ktx": "acda0b3c72369ddc403e832105021dd8",
"build/assets/ba_data/textures/aliControllerQR.pvr": "1483008a770dcb7a315a293bfa6c3aaf",
"build/assets/ba_data/textures/aliControllerQR_preview.png": "c8e05aeea062254af18319b09753a376",
"build/assets/ba_data/textures/aliIcon.dds": "edfacc0e398df035a6c02297dfbfd7a9", "build/assets/ba_data/textures/aliIcon.dds": "edfacc0e398df035a6c02297dfbfd7a9",
"build/assets/ba_data/textures/aliIcon.ktx": "a5c386a4977d6d4538c6fc176e69b116", "build/assets/ba_data/textures/aliIcon.ktx": "a5c386a4977d6d4538c6fc176e69b116",
"build/assets/ba_data/textures/aliIcon.pvr": "9d2dad0e469eaec3de216f9cd43a6de3", "build/assets/ba_data/textures/aliIcon.pvr": "9d2dad0e469eaec3de216f9cd43a6de3",
@ -4064,26 +4056,26 @@
"build/assets/windows/Win32/ucrtbased.dll": "2def5335207d41b21b9823f6805997f1", "build/assets/windows/Win32/ucrtbased.dll": "2def5335207d41b21b9823f6805997f1",
"build/assets/windows/Win32/vc_redist.x86.exe": "b08a55e2e77623fe657bea24f223a3ae", "build/assets/windows/Win32/vc_redist.x86.exe": "b08a55e2e77623fe657bea24f223a3ae",
"build/assets/windows/Win32/vcruntime140d.dll": "865b2af4d1e26a1a8073c89acb06e599", "build/assets/windows/Win32/vcruntime140d.dll": "865b2af4d1e26a1a8073c89acb06e599",
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "e8a40affea4d63bc4ca150adfeb973db", "build/prefab/full/linux_arm64_gui/debug/ballisticakit": "e7171e1db64d2c0fdebbaeb45d99422e",
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "fb00781c9574d0ca777eb5ced699dc18", "build/prefab/full/linux_arm64_gui/release/ballisticakit": "4f6ed2673aa7716c211c94baeb611da3",
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "d53b0c174af88e8a483896fdfd411579", "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "629d63c3627b863e817a98b891b38325",
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "bb6fd9371937ebe3f25d253d3046269e", "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "b6315ff0d68b436500e48de435b69c77",
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "f71e0d97424b7bf4b1ad57876ca4f01f", "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "aa98cf408c857767bcbb41ce2b63ce76",
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "6c2ba3735f33f1fd3804bd89a71c75bc", "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "fa56d6e2beb16a44eff88dd9ca3e0b3e",
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "cff1c33bb6725fb06020a256ac8e6b16", "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "3f026a96404b41c4369bd40694eae4de",
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "d9d6dbe7c5396a3adb8468fbecbf2b8c", "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "9713455275e8d7b6bc98fa85fbc1e3ee",
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "2dcddcc4a939a290fd8974d575fa3761", "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "051d1a2636fe1b5dadb1f9806b9040a3",
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "cd7f47495207a86d2f72ea0749b69db8", "build/prefab/full/mac_arm64_gui/release/ballisticakit": "ff117aec63d1413c9f48bac4fd20c9a5",
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "e223f88277dafee40cd0e631ee4fa02d", "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "0502bb185cf85e224628b3be5e18750a",
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "1b8a5eac67370bed2a29f81525fbc6eb", "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "8999ff0a5601c423e2fa10b59425bfa2",
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "91debaa22c5ce91586cfdad646a72afe", "build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "f2d0d08db00ee44a5c98023ea8521bcc",
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "84c8c568e4daeef372806cdc96f4ed48", "build/prefab/full/mac_x86_64_gui/release/ballisticakit": "35e1d1017b406d9ed31b2b901a1d0dbe",
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "ebf0e8e22d53790b85ceb9f5c507db35", "build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "6346c88ec18632ac3ad63beae6122569",
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "ba136eb04e177e264d459443bcde879f", "build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "a08613797c5064a0b2302b9468dc88e9",
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "fdc1b63de28ebd369b78b2bbeb3c6290", "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "f3d4f9dc7162d7f736c32f8a8ead5477",
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "126e2eec53a5f7a00d95039ad506b9b4", "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "dbddd278a058fb61b8ca5301a3ae4a09",
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "7db3922abdbf3045ef814f235d514cdb", "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "aca30445a8fc28b69a2bce57bd651dc3",
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "b5a1ff440599ccf09bd543d64a1d7aba", "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "1ba63aa89b4b45d893499a491e3047cd",
"build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "1e786451b0abe1451f17b908c2d8abb3", "build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "1e786451b0abe1451f17b908c2d8abb3",
"build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "80db3e75458db18efe1657f8ce686996", "build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "80db3e75458db18efe1657f8ce686996",
"build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "1e786451b0abe1451f17b908c2d8abb3", "build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "1e786451b0abe1451f17b908c2d8abb3",
@ -4092,22 +4084,22 @@
"build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "c36dc72d78f9df240ae9f640dee470c2", "build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "c36dc72d78f9df240ae9f640dee470c2",
"build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "a29bc1b96b2422dce9154ef8a404a8e6", "build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "a29bc1b96b2422dce9154ef8a404a8e6",
"build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "c36dc72d78f9df240ae9f640dee470c2", "build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "c36dc72d78f9df240ae9f640dee470c2",
"build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "8f3b213feb6207ab470a7318de8e5cc9", "build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "d1e2aef8e1ba4fac62908efd3b8079c4",
"build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "1b24bf754c66d424be3f3809b2523c61", "build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "4dd471e8559a31c1425cd344646261b5",
"build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "8f3b213feb6207ab470a7318de8e5cc9", "build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "d1e2aef8e1ba4fac62908efd3b8079c4",
"build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "1b24bf754c66d424be3f3809b2523c61", "build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "4dd471e8559a31c1425cd344646261b5",
"build/prefab/lib/mac_x86_64_gui/debug/libballisticaplus.a": "93ff05ad705918cf0c47e5946021a2e5", "build/prefab/lib/mac_x86_64_gui/debug/libballisticaplus.a": "0bff76811b9640d20c7104b8dabf27e8",
"build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "61ee5217ce8cfc2d471ffc5d1d8d4ad8", "build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "b6e72c87d43dbf2a93e9a0b74952677b",
"build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "d57603910e6c8d153b05a5515ec99ab2", "build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "3c8593e81564012a7638a20c0dc0267b",
"build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "61ee5217ce8cfc2d471ffc5d1d8d4ad8", "build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "b6e72c87d43dbf2a93e9a0b74952677b",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "2312b4a091f482d64c22f71ca971efe8", "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "a6b742a577b1a2a5b99ef4acc4949735",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "0d5cb925a29f8185d615d6b954674c6b", "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "3019670a3df31b6ed2bbd5d3a847afbb",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "eb53d93675b81c631d43f2283b59a9ae", "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "85335e293ae1433afdf40a83e346d379",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "f15e465066504b1bfadc6fef97bfa6d4", "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "172855f5f89e9bd36efe7bacad3d5fc9",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "bad42242aa1c98b5e6c7318da8b0fa01", "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "6fa16da3c74bc305a550697b7b453b21",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "55366eb80cbd1b22c2636d29b780b6f6", "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "dc2d4d3655e8cd65d83e355e731441a8",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "c6870a6302ae49bac39f53b390797d8f", "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "24a6884294c6c6da095e24f0dfa0faf4",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "29ff7769db971f92b49917c3d61de3ec", "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "68f39e024d3ca6bef9a0dc593ba139ab",
"src/assets/ba_data/python/babase/_mgen/__init__.py": "f885fed7f2ed98ff2ba271f9dbe3391c", "src/assets/ba_data/python/babase/_mgen/__init__.py": "f885fed7f2ed98ff2ba271f9dbe3391c",
"src/assets/ba_data/python/babase/_mgen/enums.py": "f8cd3af311ac63147882590123b78318", "src/assets/ba_data/python/babase/_mgen/enums.py": "f8cd3af311ac63147882590123b78318",
"src/ballistica/base/mgen/pyembed/binding_base.inc": "c81b2b1f3a14b4cd20a7b93416fe893a", "src/ballistica/base/mgen/pyembed/binding_base.inc": "c81b2b1f3a14b4cd20a7b93416fe893a",

View File

@ -1,4 +1,4 @@
### 1.7.28 (build 21337, api 8, 2023-09-11) ### 1.7.28 (build 21342, api 8, 2023-09-13)
- Renamed Console to DevConsole, and added an option under advanced settings to - Renamed Console to DevConsole, and added an option under advanced settings to
always show a 'dev' button onscreen which can be used to toggle it. The always show a 'dev' button onscreen which can be used to toggle it. The
@ -16,6 +16,8 @@
console is probably still a better way to go for most people but this makes at console is probably still a better way to go for most people but this makes at
least simple things possible without an internet connection for most Android least simple things possible without an internet connection for most Android
users. users.
- Pressing esc when the DevConsole is in its small form now dismisses it
instead of toggling it to its large form.
- Added some high level functionality for copying and deleting feature-sets to - Added some high level functionality for copying and deleting feature-sets to
the `spinoff` tool. For example, to create your own `poo` feature-set based on the `spinoff` tool. For example, to create your own `poo` feature-set based on
the existing `template_fs` one, do `tools/spinoff fset-copy template_fs poo`. the existing `template_fs` one, do `tools/spinoff fset-copy template_fs poo`.

View File

@ -1129,10 +1129,6 @@
"ba_data/textures/agentIconColorMask.pvr", "ba_data/textures/agentIconColorMask.pvr",
"ba_data/textures/agentIconColorMask_preview.png", "ba_data/textures/agentIconColorMask_preview.png",
"ba_data/textures/agentIcon_preview.png", "ba_data/textures/agentIcon_preview.png",
"ba_data/textures/aliBSRemoteIOSQR.dds",
"ba_data/textures/aliBSRemoteIOSQR.ktx",
"ba_data/textures/aliBSRemoteIOSQR.pvr",
"ba_data/textures/aliBSRemoteIOSQR_preview.png",
"ba_data/textures/aliColor.dds", "ba_data/textures/aliColor.dds",
"ba_data/textures/aliColor.ktx", "ba_data/textures/aliColor.ktx",
"ba_data/textures/aliColor.pvr", "ba_data/textures/aliColor.pvr",
@ -1141,10 +1137,6 @@
"ba_data/textures/aliColorMask.pvr", "ba_data/textures/aliColorMask.pvr",
"ba_data/textures/aliColorMask_preview.png", "ba_data/textures/aliColorMask_preview.png",
"ba_data/textures/aliColor_preview.png", "ba_data/textures/aliColor_preview.png",
"ba_data/textures/aliControllerQR.dds",
"ba_data/textures/aliControllerQR.ktx",
"ba_data/textures/aliControllerQR.pvr",
"ba_data/textures/aliControllerQR_preview.png",
"ba_data/textures/aliIcon.dds", "ba_data/textures/aliIcon.dds",
"ba_data/textures/aliIcon.ktx", "ba_data/textures/aliIcon.ktx",
"ba_data/textures/aliIcon.pvr", "ba_data/textures/aliIcon.pvr",

View File

@ -5624,10 +5624,8 @@ TEX2D_DDS_TARGETS = \
$(BUILD_DIR)/ba_data/textures/agentColorMask.dds \ $(BUILD_DIR)/ba_data/textures/agentColorMask.dds \
$(BUILD_DIR)/ba_data/textures/agentIcon.dds \ $(BUILD_DIR)/ba_data/textures/agentIcon.dds \
$(BUILD_DIR)/ba_data/textures/agentIconColorMask.dds \ $(BUILD_DIR)/ba_data/textures/agentIconColorMask.dds \
$(BUILD_DIR)/ba_data/textures/aliBSRemoteIOSQR.dds \
$(BUILD_DIR)/ba_data/textures/aliColor.dds \ $(BUILD_DIR)/ba_data/textures/aliColor.dds \
$(BUILD_DIR)/ba_data/textures/aliColorMask.dds \ $(BUILD_DIR)/ba_data/textures/aliColorMask.dds \
$(BUILD_DIR)/ba_data/textures/aliControllerQR.dds \
$(BUILD_DIR)/ba_data/textures/aliIcon.dds \ $(BUILD_DIR)/ba_data/textures/aliIcon.dds \
$(BUILD_DIR)/ba_data/textures/aliIconColorMask.dds \ $(BUILD_DIR)/ba_data/textures/aliIconColorMask.dds \
$(BUILD_DIR)/ba_data/textures/aliSplash.dds \ $(BUILD_DIR)/ba_data/textures/aliSplash.dds \
@ -6029,10 +6027,8 @@ TEX2D_PVR_TARGETS = \
$(BUILD_DIR)/ba_data/textures/agentColorMask.pvr \ $(BUILD_DIR)/ba_data/textures/agentColorMask.pvr \
$(BUILD_DIR)/ba_data/textures/agentIcon.pvr \ $(BUILD_DIR)/ba_data/textures/agentIcon.pvr \
$(BUILD_DIR)/ba_data/textures/agentIconColorMask.pvr \ $(BUILD_DIR)/ba_data/textures/agentIconColorMask.pvr \
$(BUILD_DIR)/ba_data/textures/aliBSRemoteIOSQR.pvr \
$(BUILD_DIR)/ba_data/textures/aliColor.pvr \ $(BUILD_DIR)/ba_data/textures/aliColor.pvr \
$(BUILD_DIR)/ba_data/textures/aliColorMask.pvr \ $(BUILD_DIR)/ba_data/textures/aliColorMask.pvr \
$(BUILD_DIR)/ba_data/textures/aliControllerQR.pvr \
$(BUILD_DIR)/ba_data/textures/aliIcon.pvr \ $(BUILD_DIR)/ba_data/textures/aliIcon.pvr \
$(BUILD_DIR)/ba_data/textures/aliIconColorMask.pvr \ $(BUILD_DIR)/ba_data/textures/aliIconColorMask.pvr \
$(BUILD_DIR)/ba_data/textures/aliSplash.pvr \ $(BUILD_DIR)/ba_data/textures/aliSplash.pvr \
@ -6434,10 +6430,8 @@ TEX2D_KTX_TARGETS = \
$(BUILD_DIR)/ba_data/textures/agentColorMask.ktx \ $(BUILD_DIR)/ba_data/textures/agentColorMask.ktx \
$(BUILD_DIR)/ba_data/textures/agentIcon.ktx \ $(BUILD_DIR)/ba_data/textures/agentIcon.ktx \
$(BUILD_DIR)/ba_data/textures/agentIconColorMask.ktx \ $(BUILD_DIR)/ba_data/textures/agentIconColorMask.ktx \
$(BUILD_DIR)/ba_data/textures/aliBSRemoteIOSQR.ktx \
$(BUILD_DIR)/ba_data/textures/aliColor.ktx \ $(BUILD_DIR)/ba_data/textures/aliColor.ktx \
$(BUILD_DIR)/ba_data/textures/aliColorMask.ktx \ $(BUILD_DIR)/ba_data/textures/aliColorMask.ktx \
$(BUILD_DIR)/ba_data/textures/aliControllerQR.ktx \
$(BUILD_DIR)/ba_data/textures/aliIcon.ktx \ $(BUILD_DIR)/ba_data/textures/aliIcon.ktx \
$(BUILD_DIR)/ba_data/textures/aliIconColorMask.ktx \ $(BUILD_DIR)/ba_data/textures/aliIconColorMask.ktx \
$(BUILD_DIR)/ba_data/textures/aliSplash.ktx \ $(BUILD_DIR)/ba_data/textures/aliSplash.ktx \
@ -6839,10 +6833,8 @@ TEX2D_PREVIEW_PNG_TARGETS = \
$(BUILD_DIR)/ba_data/textures/agentColor_preview.png \ $(BUILD_DIR)/ba_data/textures/agentColor_preview.png \
$(BUILD_DIR)/ba_data/textures/agentIconColorMask_preview.png \ $(BUILD_DIR)/ba_data/textures/agentIconColorMask_preview.png \
$(BUILD_DIR)/ba_data/textures/agentIcon_preview.png \ $(BUILD_DIR)/ba_data/textures/agentIcon_preview.png \
$(BUILD_DIR)/ba_data/textures/aliBSRemoteIOSQR_preview.png \
$(BUILD_DIR)/ba_data/textures/aliColorMask_preview.png \ $(BUILD_DIR)/ba_data/textures/aliColorMask_preview.png \
$(BUILD_DIR)/ba_data/textures/aliColor_preview.png \ $(BUILD_DIR)/ba_data/textures/aliColor_preview.png \
$(BUILD_DIR)/ba_data/textures/aliControllerQR_preview.png \
$(BUILD_DIR)/ba_data/textures/aliIconColorMask_preview.png \ $(BUILD_DIR)/ba_data/textures/aliIconColorMask_preview.png \
$(BUILD_DIR)/ba_data/textures/aliIcon_preview.png \ $(BUILD_DIR)/ba_data/textures/aliIcon_preview.png \
$(BUILD_DIR)/ba_data/textures/aliSplash_preview.png \ $(BUILD_DIR)/ba_data/textures/aliSplash_preview.png \

View File

@ -52,7 +52,7 @@ if TYPE_CHECKING:
# Build number and version of the ballistica binary we expect to be # Build number and version of the ballistica binary we expect to be
# using. # using.
TARGET_BALLISTICA_BUILD = 21337 TARGET_BALLISTICA_BUILD = 21342
TARGET_BALLISTICA_VERSION = '1.7.28' TARGET_BALLISTICA_VERSION = '1.7.28'

View File

@ -196,210 +196,158 @@ class HelpWindow(bui.Window):
texture=logo_tex, texture=logo_tex,
) )
force_test = False
app = bui.app app = bui.app
assert app.classic is not None assert app.classic is not None
if (
app.classic.platform == 'android'
and app.classic.subplatform == 'alibaba'
) or force_test:
v -= 120.0
txtv = (
'\xe8\xbf\x99\xe6\x98\xaf\xe4\xb8\x80\xe4\xb8\xaa\xe5\x8f\xaf'
'\xe4\xbb\xa5\xe5\x92\x8c\xe5\xae\xb6\xe4\xba\xba\xe6\x9c\x8b'
'\xe5\x8f\x8b\xe4\xb8\x80\xe8\xb5\xb7\xe7\x8e\xa9\xe7\x9a\x84'
'\xe6\xb8\xb8\xe6\x88\x8f,\xe5\x90\x8c\xe6\x97\xb6\xe6\x94\xaf'
'\xe6\x8c\x81\xe8\x81\x94 \xe2\x80\xa8\xe7\xbd\x91\xe5\xaf\xb9'
'\xe6\x88\x98\xe3\x80\x82\n'
'\xe5\xa6\x82\xe6\xb2\xa1\xe6\x9c\x89\xe6\xb8\xb8\xe6\x88\x8f'
'\xe6\x89\x8b\xe6\x9f\x84,\xe5\x8f\xaf\xe4\xbb\xa5\xe4\xbd\xbf'
'\xe7\x94\xa8\xe7\xa7\xbb\xe5\x8a\xa8\xe8\xae\xbe\xe5\xa4\x87'
'\xe6\x89\xab\xe7\xa0\x81\xe4\xb8\x8b\xe8\xbd\xbd\xe2\x80\x9c'
'\xe9\x98\xbf\xe9\x87\x8c\xc2'
'\xa0TV\xc2\xa0\xe5\x8a\xa9\xe6\x89'
'\x8b\xe2\x80\x9d\xe7\x94\xa8 \xe6\x9d\xa5\xe4\xbb\xa3\xe6\x9b'
'\xbf\xe5\xa4\x96\xe8\xae\xbe\xe3\x80\x82\n'
'\xe6\x9c\x80\xe5\xa4\x9a\xe6\x94\xaf\xe6\x8c\x81\xe6\x8e\xa5'
'\xe5\x85\xa5\xc2\xa08\xc2\xa0\xe4\xb8\xaa\xe5\xa4\x96\xe8'
'\xae\xbe'
)
bui.textwidget(
parent=self._subcontainer,
size=(0, 0),
h_align='center',
v_align='center',
maxwidth=self._sub_width * 0.9,
position=(self._sub_width * 0.5, v - 180),
text=txtv,
)
bui.imagewidget(
parent=self._subcontainer,
position=(self._sub_width - 320, v - 120),
size=(200, 200),
texture=bui.gettexture('aliControllerQR'),
)
bui.imagewidget(
parent=self._subcontainer,
position=(90, v - 130),
size=(210, 210),
texture=bui.gettexture('multiplayerExamples'),
)
v -= 120.0
v -= spacing * 50.0
txt = bui.Lstr(resource=self._r + '.someDaysText').evaluate()
bui.textwidget(
parent=self._subcontainer,
position=(h, v),
size=(0, 0),
scale=1.2,
maxwidth=self._sub_width * 0.9,
text=txt,
h_align='center',
color=paragraph,
v_align='center',
flatness=1.0,
)
v -= spacing * 25.0 + getres(self._r + '.someDaysExtraSpace')
txt_scale = 0.66
txt = bui.Lstr(resource=self._r + '.orPunchingSomethingText').evaluate()
bui.textwidget(
parent=self._subcontainer,
position=(h, v),
size=(0, 0),
scale=txt_scale,
maxwidth=self._sub_width * 0.9,
text=txt,
h_align='center',
color=paragraph,
v_align='center',
flatness=1.0,
)
v -= spacing * 27.0 + getres(self._r + '.orPunchingSomethingExtraSpace')
txt_scale = 1.0
txt = bui.Lstr(
resource=self._r + '.canHelpText',
subs=[('${APP_NAME}', bui.Lstr(resource='titleText'))],
).evaluate()
bui.textwidget(
parent=self._subcontainer,
position=(h, v),
size=(0, 0),
scale=txt_scale,
flatness=1.0,
text=txt,
h_align='center',
color=paragraph,
v_align='center',
)
v -= spacing * 70.0
txt_scale = 1.0
txt = bui.Lstr(resource=self._r + '.toGetTheMostText').evaluate()
bui.textwidget(
parent=self._subcontainer,
position=(h, v),
size=(0, 0),
scale=txt_scale,
maxwidth=self._sub_width * 0.9,
text=txt,
h_align='center',
color=header,
v_align='center',
flatness=1.0,
)
v -= spacing * 40.0
txt_scale = 0.74
txt = bui.Lstr(resource=self._r + '.friendsText').evaluate()
hval2 = h - 220
bui.textwidget(
parent=self._subcontainer,
position=(hval2, v),
size=(0, 0),
scale=txt_scale,
maxwidth=100,
text=txt,
h_align='right',
color=header,
v_align='center',
flatness=1.0,
)
txt = bui.Lstr(
resource=self._r + '.friendsGoodText',
subs=[('${APP_NAME}', bui.Lstr(resource='titleText'))],
).evaluate()
txt_scale = 0.7
bui.textwidget(
parent=self._subcontainer,
position=(hval2 + 10, v + 8),
size=(0, 0),
scale=txt_scale,
maxwidth=500,
text=txt,
h_align='left',
color=paragraph,
flatness=1.0,
)
app = bui.app
v -= spacing * 45.0
txt = (
bui.Lstr(resource=self._r + '.devicesText').evaluate()
if app.env.vr
else bui.Lstr(resource=self._r + '.controllersText').evaluate()
)
txt_scale = 0.74
hval2 = h - 220
bui.textwidget(
parent=self._subcontainer,
position=(hval2, v),
size=(0, 0),
scale=txt_scale,
maxwidth=100,
text=txt,
h_align='right',
v_align='center',
color=header,
flatness=1.0,
)
txt_scale = 0.7
if not app.env.vr:
infotxt = '.controllersInfoText'
txt = bui.Lstr(
resource=self._r + infotxt,
fallback_resource=self._r + '.controllersInfoText',
subs=[
('${APP_NAME}', bui.Lstr(resource='titleText')),
('${REMOTE_APP_NAME}', bui.get_remote_app_name()),
],
).evaluate()
else: else:
v -= spacing * 50.0
txt = bui.Lstr(resource=self._r + '.someDaysText').evaluate()
bui.textwidget(
parent=self._subcontainer,
position=(h, v),
size=(0, 0),
scale=1.2,
maxwidth=self._sub_width * 0.9,
text=txt,
h_align='center',
color=paragraph,
v_align='center',
flatness=1.0,
)
v -= spacing * 25.0 + getres(self._r + '.someDaysExtraSpace')
txt_scale = 0.66
txt = bui.Lstr( txt = bui.Lstr(
resource=self._r + '.orPunchingSomethingText' resource=self._r + '.devicesInfoText',
).evaluate()
bui.textwidget(
parent=self._subcontainer,
position=(h, v),
size=(0, 0),
scale=txt_scale,
maxwidth=self._sub_width * 0.9,
text=txt,
h_align='center',
color=paragraph,
v_align='center',
flatness=1.0,
)
v -= spacing * 27.0 + getres(
self._r + '.orPunchingSomethingExtraSpace'
)
txt_scale = 1.0
txt = bui.Lstr(
resource=self._r + '.canHelpText',
subs=[('${APP_NAME}', bui.Lstr(resource='titleText'))], subs=[('${APP_NAME}', bui.Lstr(resource='titleText'))],
).evaluate() ).evaluate()
bui.textwidget(
parent=self._subcontainer,
position=(h, v),
size=(0, 0),
scale=txt_scale,
flatness=1.0,
text=txt,
h_align='center',
color=paragraph,
v_align='center',
)
v -= spacing * 70.0 bui.textwidget(
txt_scale = 1.0 parent=self._subcontainer,
txt = bui.Lstr(resource=self._r + '.toGetTheMostText').evaluate() position=(hval2 + 10, v + 8),
bui.textwidget( size=(0, 0),
parent=self._subcontainer, scale=txt_scale,
position=(h, v), maxwidth=500,
size=(0, 0), max_height=105,
scale=txt_scale, text=txt,
maxwidth=self._sub_width * 0.9, h_align='left',
text=txt, color=paragraph,
h_align='center', flatness=1.0,
color=header, )
v_align='center',
flatness=1.0,
)
v -= spacing * 40.0
txt_scale = 0.74
txt = bui.Lstr(resource=self._r + '.friendsText').evaluate()
hval2 = h - 220
bui.textwidget(
parent=self._subcontainer,
position=(hval2, v),
size=(0, 0),
scale=txt_scale,
maxwidth=100,
text=txt,
h_align='right',
color=header,
v_align='center',
flatness=1.0,
)
txt = bui.Lstr(
resource=self._r + '.friendsGoodText',
subs=[('${APP_NAME}', bui.Lstr(resource='titleText'))],
).evaluate()
txt_scale = 0.7
bui.textwidget(
parent=self._subcontainer,
position=(hval2 + 10, v + 8),
size=(0, 0),
scale=txt_scale,
maxwidth=500,
text=txt,
h_align='left',
color=paragraph,
flatness=1.0,
)
app = bui.app
v -= spacing * 45.0
txt = (
bui.Lstr(resource=self._r + '.devicesText').evaluate()
if app.env.vr
else bui.Lstr(resource=self._r + '.controllersText').evaluate()
)
txt_scale = 0.74
hval2 = h - 220
bui.textwidget(
parent=self._subcontainer,
position=(hval2, v),
size=(0, 0),
scale=txt_scale,
maxwidth=100,
text=txt,
h_align='right',
v_align='center',
color=header,
flatness=1.0,
)
txt_scale = 0.7
if not app.env.vr:
infotxt = '.controllersInfoText'
txt = bui.Lstr(
resource=self._r + infotxt,
fallback_resource=self._r + '.controllersInfoText',
subs=[
('${APP_NAME}', bui.Lstr(resource='titleText')),
('${REMOTE_APP_NAME}', bui.get_remote_app_name()),
],
).evaluate()
else:
txt = bui.Lstr(
resource=self._r + '.devicesInfoText',
subs=[('${APP_NAME}', bui.Lstr(resource='titleText'))],
).evaluate()
bui.textwidget(
parent=self._subcontainer,
position=(hval2 + 10, v + 8),
size=(0, 0),
scale=txt_scale,
maxwidth=500,
max_height=105,
text=txt,
h_align='left',
color=paragraph,
flatness=1.0,
)
v -= spacing * 150.0 v -= spacing * 150.0

View File

@ -37,7 +37,7 @@ void AppModeEmpty::DrawWorld(base::FrameDef* frame_def) {
// Draw some lovely spinning text. // Draw some lovely spinning text.
if (!hello_text_group_.Exists()) { if (!hello_text_group_.Exists()) {
hello_text_group_ = Object::New<TextGroup>(); hello_text_group_ = Object::New<TextGroup>();
hello_text_group_->set_text("Potato!"); hello_text_group_->SetText("Potato!");
} }
auto& grp(*hello_text_group_); auto& grp(*hello_text_group_);
auto* pass = frame_def->overlay_pass(); auto* pass = frame_def->overlay_pass();

View File

@ -11,7 +11,7 @@ class PostProcessComponent : public RenderComponent {
public: public:
explicit PostProcessComponent(RenderPass* pass) explicit PostProcessComponent(RenderPass* pass)
: RenderComponent(pass), normal_distort_(0.0f), eyes_(false) {} : RenderComponent(pass), normal_distort_(0.0f), eyes_(false) {}
void setNormalDistort(float d) { void SetNormalDistort(float d) {
EnsureConfiguring(); EnsureConfiguring();
normal_distort_ = d; normal_distort_ = d;
} }

View File

@ -162,12 +162,12 @@ class RenderComponent {
} }
void Submit() { void Submit() {
if (state_ != State::kSubmitted) { if (state_ != State::kSubmitted) {
// if we were drawing, make note that we're done // If we were drawing, make note that we're done.
if (state_ == State::kDrawing) { if (state_ == State::kDrawing) {
#if BA_DEBUG_BUILD #if BA_DEBUG_BUILD
assert(pass_->frame_def()->defining_component()); assert(pass_->frame_def()->defining_component());
pass_->frame_def()->set_defining_component(false); pass_->frame_def()->set_defining_component(false);
#endif // BA_DEBUG_BUILD #endif
} }
state_ = State::kSubmitted; state_ = State::kSubmitted;
} }

View File

@ -357,7 +357,8 @@ class Graphics::ScreenMessageEntry {
}; };
// Draw controls and things that lie on top of the action. // Draw controls and things that lie on top of the action.
void Graphics::DrawMiscOverlays(RenderPass* pass) { void Graphics::DrawMiscOverlays(FrameDef* frame_def) {
RenderPass* pass = frame_def->overlay_pass();
assert(g_base && g_base->InLogicThread()); assert(g_base && g_base->InLogicThread());
// Every now and then, update our stats. // Every now and then, update our stats.
@ -382,7 +383,7 @@ void Graphics::DrawMiscOverlays(RenderPass* pass) {
if (!fps_text_group_.Exists()) { if (!fps_text_group_.Exists()) {
fps_text_group_ = Object::New<TextGroup>(); fps_text_group_ = Object::New<TextGroup>();
} }
fps_text_group_->set_text(fps_string_); fps_text_group_->SetText(fps_string_);
} }
SimpleComponent c(pass); SimpleComponent c(pass);
c.SetTransparent(true); c.SetTransparent(true);
@ -415,7 +416,7 @@ void Graphics::DrawMiscOverlays(RenderPass* pass) {
if (!ping_text_group_.Exists()) { if (!ping_text_group_.Exists()) {
ping_text_group_ = Object::New<TextGroup>(); ping_text_group_ = Object::New<TextGroup>();
} }
ping_text_group_->set_text(ping_string_); ping_text_group_->SetText(ping_string_);
} }
SimpleComponent c(pass); SimpleComponent c(pass);
c.SetTransparent(true); c.SetTransparent(true);
@ -431,12 +432,13 @@ void Graphics::DrawMiscOverlays(RenderPass* pass) {
for (int e = 0; e < text_elem_count; e++) { for (int e = 0; e < text_elem_count; e++) {
c.SetTexture(ping_text_group_->GetElementTexture(e)); c.SetTexture(ping_text_group_->GetElementTexture(e));
c.SetFlatness(1.0f); c.SetFlatness(1.0f);
c.PushTransform(); {
c.Translate(14.0f + (show_fps_ ? 30.0f : 0.0f), 0.1f, auto xf = c.ScopedTransform();
kScreenMessageZDepth); c.Translate(14.0f + (show_fps_ ? 30.0f : 0.0f), 0.1f,
c.Scale(0.7f, 0.7f); kScreenMessageZDepth);
c.DrawMesh(ping_text_group_->GetElementMesh(e)); c.Scale(0.7f, 0.7f);
c.PopTransform(); c.DrawMesh(ping_text_group_->GetElementMesh(e));
}
} }
c.Submit(); c.Submit();
} }
@ -450,7 +452,7 @@ void Graphics::DrawMiscOverlays(RenderPass* pass) {
if (!net_info_text_group_.Exists()) { if (!net_info_text_group_.Exists()) {
net_info_text_group_ = Object::New<TextGroup>(); net_info_text_group_ = Object::New<TextGroup>();
} }
net_info_text_group_->set_text(net_info_string_); net_info_text_group_->SetText(net_info_string_);
} }
SimpleComponent c(pass); SimpleComponent c(pass);
c.SetTransparent(true); c.SetTransparent(true);
@ -459,11 +461,12 @@ void Graphics::DrawMiscOverlays(RenderPass* pass) {
for (int e = 0; e < text_elem_count; e++) { for (int e = 0; e < text_elem_count; e++) {
c.SetTexture(net_info_text_group_->GetElementTexture(e)); c.SetTexture(net_info_text_group_->GetElementTexture(e));
c.SetFlatness(1.0f); c.SetFlatness(1.0f);
c.PushTransform(); {
c.Translate(4.0f, (show_fps_ ? 66.0f : 40.0f), kScreenMessageZDepth); auto xf = c.ScopedTransform();
c.Scale(0.7f, 0.7f); c.Translate(4.0f, (show_fps_ ? 66.0f : 40.0f), kScreenMessageZDepth);
c.DrawMesh(net_info_text_group_->GetElementMesh(e)); c.Scale(0.7f, 0.7f);
c.PopTransform(); c.DrawMesh(net_info_text_group_->GetElementMesh(e));
}
} }
c.Submit(); c.Submit();
} }
@ -603,33 +606,35 @@ void Graphics::DrawMiscOverlays(RenderPass* pass) {
} }
c.SetColor(r * fade, g * fade, b * fade, a); c.SetColor(r * fade, g * fade, b * fade, a);
c.PushTransform(); {
if (i->v_smoothed == 0.0f) { auto xf = c.ScopedTransform();
i->v_smoothed = v + v_extra;
} else {
float smoothing = 0.8f;
i->v_smoothed =
smoothing * i->v_smoothed + (1.0f - smoothing) * (v + v_extra);
}
c.Translate(screen_width * 0.5f, i->v_smoothed,
vr ? 60 : kScreenMessageZDepth);
if (vr) {
// Let's drop down a bit in vr mode.
c.Translate(0, -10.0f, 0);
c.Scale((str_width + 60) * scale * s_extra,
(str_height + 20) * scale * s_extra);
// Align our bottom with where we just scaled from. if (i->v_smoothed == 0.0f) {
c.Translate(0, 0.5f, 0); i->v_smoothed = v + v_extra;
} else { } else {
c.Scale((str_width + 110) * scale * s_extra, float smoothing = 0.8f;
(str_height + 40) * scale * s_extra); i->v_smoothed = smoothing * i->v_smoothed
+ (1.0f - smoothing) * (v + v_extra);
}
c.Translate(screen_width * 0.5f, i->v_smoothed,
vr ? 60 : kScreenMessageZDepth);
if (vr) {
// Let's drop down a bit in vr mode.
c.Translate(0, -10.0f, 0);
c.Scale((str_width + 60) * scale * s_extra,
(str_height + 20) * scale * s_extra);
// Align our bottom with where we just scaled from. // Align our bottom with where we just scaled from.
c.Translate(0, 0.5f, 0); c.Translate(0, 0.5f, 0);
} else {
c.Scale((str_width + 110) * scale * s_extra,
(str_height + 40) * scale * s_extra);
// Align our bottom with where we just scaled from.
c.Translate(0, 0.5f, 0);
}
c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kImage1x1));
} }
c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kImage1x1));
c.PopTransform();
v += scale * (36 + str_height); v += scale * (36 + str_height);
if (v > g_base->graphics->screen_virtual_height() + 30) { if (v > g_base->graphics->screen_virtual_height() + 30) {
@ -698,13 +703,14 @@ void Graphics::DrawMiscOverlays(RenderPass* pass) {
c.SetColor(1, 1, 1, a); c.SetColor(1, 1, 1, a);
} }
c.SetFlatness(i->GetText().GetElementMaxFlatness(e)); c.SetFlatness(i->GetText().GetElementMaxFlatness(e));
c.PushTransform(); {
c.Translate(screen_width * 0.5f, i->v_smoothed, auto xf = c.ScopedTransform();
vr ? 150 : kScreenMessageZDepth); c.Translate(screen_width * 0.5f, i->v_smoothed,
c.Scale(scale * s_extra, scale * s_extra); vr ? 150 : kScreenMessageZDepth);
c.Translate(0, 20); c.Scale(scale * s_extra, scale * s_extra);
c.DrawMesh(i->GetText().GetElementMesh(e)); c.Translate(0, 20);
c.PopTransform(); c.DrawMesh(i->GetText().GetElementMesh(e));
}
} }
v += scale * (36 + str_height); v += scale * (36 + str_height);
@ -798,12 +804,13 @@ void Graphics::DrawMiscOverlays(RenderPass* pass) {
g_base->assets->SysTexture(SysTextureID::kCharacterIconMask)); g_base->assets->SysTexture(SysTextureID::kCharacterIconMask));
} }
c2.SetColor(1, 1, 1, a); c2.SetColor(1, 1, 1, a);
c2.PushTransform(); {
c2.Translate(h - 14, v_base + 10 + i->v_smoothed, auto xf = c2.ScopedTransform();
kScreenMessageZDepth); c2.Translate(h - 14, v_base + 10 + i->v_smoothed,
c2.Scale(22.0f * s_extra, 22.0f * s_extra); kScreenMessageZDepth);
c2.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kImage1x1)); c2.Scale(22.0f * s_extra, 22.0f * s_extra);
c2.PopTransform(); c2.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kImage1x1));
}
c2.Submit(); c2.Submit();
} }
@ -830,11 +837,12 @@ void Graphics::DrawMiscOverlays(RenderPass* pass) {
1.0f * a); 1.0f * a);
c.SetFlatness(i->GetText().GetElementMaxFlatness(e)); c.SetFlatness(i->GetText().GetElementMaxFlatness(e));
c.SetMaskUV2Texture(i->GetText().GetElementMaskUV2Texture(e)); c.SetMaskUV2Texture(i->GetText().GetElementMaskUV2Texture(e));
c.PushTransform(); {
c.Translate(h, v_base + 2 + i->v_smoothed, kScreenMessageZDepth); auto xf = c.ScopedTransform();
c.Scale(0.6f * s_extra, 0.6f * s_extra); c.Translate(h, v_base + 2 + i->v_smoothed, kScreenMessageZDepth);
c.DrawMesh(i->GetText().GetElementMesh(e)); c.Scale(0.6f * s_extra, 0.6f * s_extra);
c.PopTransform(); c.DrawMesh(i->GetText().GetElementMesh(e));
}
} }
assert(!i->translation_dirty); assert(!i->translation_dirty);
v -= g_base->text_graphics->GetStringHeight(i->s_translated.c_str()) v -= g_base->text_graphics->GetStringHeight(i->s_translated.c_str())
@ -1171,12 +1179,12 @@ void Graphics::BuildAndPushFrameDef() {
g_base->input->Draw(frame_def); g_base->input->Draw(frame_def);
RenderPass* overlay_pass = frame_def->overlay_pass(); RenderPass* overlay_pass = frame_def->overlay_pass();
DrawMiscOverlays(overlay_pass); DrawMiscOverlays(frame_def);
// Let UI draw dev console and whatever else. // Let UI draw dev console and whatever else.
DrawDevUI(frame_def); DrawDevUI(frame_def);
DrawCursor(overlay_pass, app_time_millisecs); DrawCursor(frame_def);
// Draw our light/shadow images to the screen if desired. // Draw our light/shadow images to the screen if desired.
DrawDebugBuffers(overlay_pass); DrawDebugBuffers(overlay_pass);
@ -1224,7 +1232,7 @@ void Graphics::BuildAndPushFrameDef() {
frame_def->set_mesh_data_destroys(mesh_data_destroys_); frame_def->set_mesh_data_destroys(mesh_data_destroys_);
mesh_data_destroys_.clear(); mesh_data_destroys_.clear();
g_base->graphics_server->SetFrameDef(frame_def); g_base->graphics_server->EnqueueFrameDef(frame_def);
// Clean up frame_defs awaiting deletion. // Clean up frame_defs awaiting deletion.
ClearFrameDefDeleteList(); ClearFrameDefDeleteList();
@ -1249,13 +1257,14 @@ void Graphics::DrawBoxingGlovesTest(FrameDef* frame_def) {
// Blit. // Blit.
if (explicit_bool(true)) { if (explicit_bool(true)) {
PostProcessComponent c(frame_def->blit_pass()); PostProcessComponent c(frame_def->blit_pass());
c.setNormalDistort(0.07f); c.SetNormalDistort(0.07f);
c.PushTransform(); {
c.Translate(0, 7, -3.3f); auto xf = c.ScopedTransform();
c.Scale(10, 10, 10); c.Translate(0, 7, -3.3f);
c.Rotate(a, 0, 0, 1); c.Scale(10, 10, 10);
c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kBoxingGlove)); c.Rotate(a, 0, 0, 1);
c.PopTransform(); c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kBoxingGlove));
}
c.Submit(); c.Submit();
} }
@ -1265,12 +1274,13 @@ void Graphics::DrawBoxingGlovesTest(FrameDef* frame_def) {
c.SetTexture(g_base->assets->SysTexture(SysTextureID::kBoxingGlove)); c.SetTexture(g_base->assets->SysTexture(SysTextureID::kBoxingGlove));
c.SetReflection(ReflectionType::kSoft); c.SetReflection(ReflectionType::kSoft);
c.SetReflectionScale(0.4f, 0.4f, 0.4f); c.SetReflectionScale(0.4f, 0.4f, 0.4f);
c.PushTransform(); {
c.Translate(0.0f, 3.7f, -3.3f); auto xf = c.ScopedTransform();
c.Scale(10.0f, 10.0f, 10.0f); c.Translate(0.0f, 3.7f, -3.3f);
c.Rotate(a, 0.0f, 0.0f, 1.0f); c.Scale(10.0f, 10.0f, 10.0f);
c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kBoxingGlove)); c.Rotate(a, 0.0f, 0.0f, 1.0f);
c.PopTransform(); c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kBoxingGlove));
}
c.Submit(); c.Submit();
} }
@ -1279,12 +1289,13 @@ void Graphics::DrawBoxingGlovesTest(FrameDef* frame_def) {
SimpleComponent c(frame_def->light_shadow_pass()); SimpleComponent c(frame_def->light_shadow_pass());
c.SetColor(0.16f, 0.11f, 0.1f, 1.0f); c.SetColor(0.16f, 0.11f, 0.1f, 1.0f);
c.SetTransparent(true); c.SetTransparent(true);
c.PushTransform(); {
c.Translate(0.0f, 3.7f, -3.3f); auto xf = c.ScopedTransform();
c.Scale(10.0f, 10.0f, 10.0f); c.Translate(0.0f, 3.7f, -3.3f);
c.Rotate(a, 0.0f, 0.0f, 1.0f); c.Scale(10.0f, 10.0f, 10.0f);
c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kBoxingGlove)); c.Rotate(a, 0.0f, 0.0f, 1.0f);
c.PopTransform(); c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kBoxingGlove));
}
c.Submit(); c.Submit();
} }
} }
@ -1295,21 +1306,23 @@ void Graphics::DrawDebugBuffers(RenderPass* pass) {
{ {
SpecialComponent c(pass, SpecialComponent::Source::kLightBuffer); SpecialComponent c(pass, SpecialComponent::Source::kLightBuffer);
float csize = 100; float csize = 100;
c.PushTransform(); {
c.Translate(70, 400, kDebugImgZDepth); auto xf = c.ScopedTransform();
c.Scale(csize, csize); c.Translate(70, 400, kDebugImgZDepth);
c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kImage1x1)); c.Scale(csize, csize);
c.PopTransform(); c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kImage1x1));
}
c.Submit(); c.Submit();
} }
{ {
SpecialComponent c(pass, SpecialComponent::Source::kLightShadowBuffer); SpecialComponent c(pass, SpecialComponent::Source::kLightShadowBuffer);
float csize = 100; float csize = 100;
c.PushTransform(); {
c.Translate(70, 250, kDebugImgZDepth); auto xf = c.ScopedTransform();
c.Scale(csize, csize); c.Translate(70, 250, kDebugImgZDepth);
c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kImage1x1)); c.Scale(csize, csize);
c.PopTransform(); c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kImage1x1));
}
c.Submit(); c.Submit();
} }
} }
@ -1364,7 +1377,9 @@ void Graphics::DrawFades(FrameDef* frame_def, millisecs_t real_time) {
fade_ = 1.0f fade_ = 1.0f
- (static_cast<float>(real_time - fade_start_) - (static_cast<float>(real_time - fade_start_)
/ static_cast<float>(fade_time_)); / static_cast<float>(fade_time_));
if (fade_ <= 0) fade_ = 0.00001f; if (fade_ <= 0) {
fade_ = 0.00001f;
}
} else { } else {
fade_ = 0; fade_ = 0;
if (!was_done && fade_end_call_.Exists()) { if (!was_done && fade_end_call_.Exists()) {
@ -1386,60 +1401,8 @@ void Graphics::DrawFades(FrameDef* frame_def, millisecs_t real_time) {
/ static_cast<float>(kProgressBarFadeTime)) / static_cast<float>(kProgressBarFadeTime))
* (1.0f - a); * (1.0f - a);
} }
// TODO(ericf): move this to GraphicsVR.
if (g_core->IsVRMode()) {
#if BA_VR_BUILD
SimpleComponent c(frame_def->vr_cover_pass());
c.SetTransparent(false);
Vector3f cam_pt = {0.0f, 0.0f, 0.0f};
Vector3f cam_target_pt = {0.0f, 0.0f, 0.0f};
cam_pt =
Vector3f(frame_def->cam_original().x, frame_def->cam_original().y,
frame_def->cam_original().z);
// In vr follow-mode the cam point gets tweaked. DoDrawFade(frame_def, a);
//
// FIXME: should probably just do this on the camera end.
if (frame_def->camera_mode() == CameraMode::kOrbit) {
// fudge this one up a bit; looks better that way..
cam_target_pt = Vector3f(frame_def->cam_target_original().x,
frame_def->cam_target_original().y + 6.0f,
frame_def->cam_target_original().z);
} else {
cam_target_pt = Vector3f(frame_def->cam_target_original().x,
frame_def->cam_target_original().y,
frame_def->cam_target_original().z);
}
Vector3f diff = cam_target_pt - cam_pt;
diff.Normalize();
Vector3f side = Vector3f::Cross(diff, Vector3f(0.0f, 1.0f, 0.0f));
Vector3f up = Vector3f::Cross(diff, side);
c.SetColor(0, 0, 0);
c.PushTransform();
// we start in vr-overlay screen space; get back to world..
c.Translate(cam_pt.x, cam_pt.y, cam_pt.z);
c.MultMatrix(Matrix44fOrient(diff, up).m);
// at the very end we stay turned around so we get 100% black
if (a < 0.98f) {
c.Translate(0, 0, 40.0f * a);
c.Rotate(180, 1, 0, 0);
}
float inv_a = 1.0f - a;
float s = 100.0f * inv_a + 5.0f * a;
c.Scale(s, s, s);
c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kVRFade));
c.PopTransform();
c.Submit();
#else // BA_VR_BUILD
throw Exception();
#endif
} else {
SimpleComponent c(overlay_pass);
c.SetTransparent(a < 1.0f);
c.SetColor(0, 0, 0, a);
c.DrawMesh(screen_mesh_.Get());
c.Submit();
}
// If we're doing a progress-bar fade, throw in the fading progress bar. // If we're doing a progress-bar fade, throw in the fading progress bar.
if (real_time - progress_bar_end_time_ < kProgressBarFadeTime / 2) { if (real_time - progress_bar_end_time_ < kProgressBarFadeTime / 2) {
@ -1452,9 +1415,25 @@ void Graphics::DrawFades(FrameDef* frame_def, millisecs_t real_time) {
} }
} }
void Graphics::DrawCursor(RenderPass* pass, millisecs_t real_time) { void Graphics::DoDrawFade(FrameDef* frame_def, float amt) {
SimpleComponent c(frame_def->overlay_front_pass());
c.SetTransparent(amt < 1.0f);
c.SetColor(0, 0, 0, amt);
{
// Draw this at the front of this overlay pass; should never really
// need stuff covering this methinks.
auto xf = c.ScopedTransform();
c.Translate(0.0f, 0.0f, 1.0f);
c.DrawMesh(screen_mesh_.Get());
}
c.Submit();
}
void Graphics::DrawCursor(FrameDef* frame_def) {
assert(g_base->InLogicThread()); assert(g_base->InLogicThread());
millisecs_t real_time = frame_def->real_time();
bool can_show_cursor = g_core->platform->IsRunningOnDesktop(); bool can_show_cursor = g_core->platform->IsRunningOnDesktop();
bool should_show_cursor = bool should_show_cursor =
camera_->manual() || g_base->input->IsCursorVisible(); camera_->manual() || g_base->input->IsCursorVisible();
@ -1481,20 +1460,21 @@ void Graphics::DrawCursor(RenderPass* pass, millisecs_t real_time) {
} else { } else {
// Draw software cursor. // Draw software cursor.
if (can_show_cursor && should_show_cursor) { if (can_show_cursor && should_show_cursor) {
SimpleComponent c(pass); SimpleComponent c(frame_def->overlay_front_pass());
c.SetTransparent(true); c.SetTransparent(true);
float csize = 50.0f; float csize = 50.0f;
c.SetTexture(g_base->assets->SysTexture(SysTextureID::kCursor)); c.SetTexture(g_base->assets->SysTexture(SysTextureID::kCursor));
c.PushTransform(); {
auto xf = c.ScopedTransform();
// Note: we don't plug in known cursor position values here; we tell the // Note: we don't plug in known cursor position values here; we tell the
// renderer to insert the latest values on its end; this lessens cursor // renderer to insert the latest values on its end; this lessens cursor
// lag substantially. // lag substantially.
c.CursorTranslate(); c.CursorTranslate();
c.Translate(csize * 0.44f, csize * -0.44f, kCursorZDepth); c.Translate(csize * 0.44f, csize * -0.44f, kCursorZDepth);
c.Scale(csize, csize); c.Scale(csize, csize);
c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kImage1x1)); c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kImage1x1));
c.PopTransform(); }
c.Submit(); c.Submit();
} }
} }
@ -1898,7 +1878,7 @@ auto Graphics::ScreenMessageEntry::GetText() -> TextGroup& {
mesh_dirty = true; mesh_dirty = true;
} }
if (mesh_dirty) { if (mesh_dirty) {
s_mesh_->set_text( s_mesh_->SetText(
s_translated, s_translated,
align_left ? TextMesh::HAlign::kLeft : TextMesh::HAlign::kCenter, align_left ? TextMesh::HAlign::kLeft : TextMesh::HAlign::kCenter,
TextMesh::VAlign::kBottom); TextMesh::VAlign::kBottom);

View File

@ -44,7 +44,8 @@ const float kBackingDepth1{0.0f};
const float kShadowNeutral{0.5f}; const float kShadowNeutral{0.5f};
const float kCursorZDepth{-0.1f}; // Cursor depth within the front-overlay (not related to above depths).
const float kCursorZDepth{0.9f};
// Client class for graphics operations (used from the logic thread). // Client class for graphics operations (used from the logic thread).
class Graphics { class Graphics {
@ -317,11 +318,14 @@ class Graphics {
camera_gyro_explicitly_disabled_ = disabled; camera_gyro_explicitly_disabled_ = disabled;
} }
protected:
virtual void DoDrawFade(FrameDef* frame_def, float amt);
private: private:
class ScreenMessageEntry; class ScreenMessageEntry;
void DrawBoxingGlovesTest(FrameDef* frame_def); void DrawBoxingGlovesTest(FrameDef* frame_def);
void DrawBlotches(FrameDef* frame_def); void DrawBlotches(FrameDef* frame_def);
void DrawCursor(RenderPass* pass, millisecs_t real_time); void DrawCursor(FrameDef* frame_def);
void DrawFades(FrameDef* frame_def, millisecs_t real_time); void DrawFades(FrameDef* frame_def, millisecs_t real_time);
void DrawDebugBuffers(RenderPass* pass); void DrawDebugBuffers(RenderPass* pass);
@ -331,7 +335,7 @@ class Graphics {
float size, float r, float g, float b, float a); float size, float r, float g, float b, float a);
auto GetEmptyFrameDef() -> FrameDef*; auto GetEmptyFrameDef() -> FrameDef*;
void InitInternalComponents(FrameDef* frame_def); void InitInternalComponents(FrameDef* frame_def);
void DrawMiscOverlays(RenderPass* pass); void DrawMiscOverlays(FrameDef* frame_def);
void DrawLoadDot(RenderPass* pass); void DrawLoadDot(RenderPass* pass);
void ClearFrameDefDeleteList(); void ClearFrameDefDeleteList();
void DrawProgressBar(RenderPass* pass, float opacity); void DrawProgressBar(RenderPass* pass, float opacity);

View File

@ -47,13 +47,12 @@ void GraphicsServer::OnMainThreadStartApp() {
} }
} }
void GraphicsServer::SetFrameDef(FrameDef* framedef) { void GraphicsServer::EnqueueFrameDef(FrameDef* framedef) {
// Note: we're just setting the framedef directly here // Note: we're just setting the framedef directly here even though this
// even though this gets called from the logic thread. // gets called from the logic thread. Ideally it would seem we should push
// Ideally it would seem we should push these to our thread // these to our thread event list, but currently we may spin-lock waiting
// event list, but currently we spin-lock waiting for new // for new frames to appear which would prevent that from working; we
// frames to appear which would prevent that from working; // would need to change that code.
// we would need to change that code.
{ {
std::scoped_lock llock(frame_def_mutex_); std::scoped_lock llock(frame_def_mutex_);
assert(frame_def_ == nullptr); assert(frame_def_ == nullptr);
@ -69,8 +68,8 @@ auto GraphicsServer::GetRenderFrameDef() -> FrameDef* {
return nullptr; return nullptr;
} }
// If the app says it's minimized, don't do anything. // If the app says it's minimized, don't do anything (on iOS we'll get
// (on iOS we'll get shut down if we make GL calls in this state, etc) // shut down if we make GL calls in this state, etc).
if (g_base->app_adapter->app_paused()) { if (g_base->app_adapter->app_paused()) {
return nullptr; return nullptr;
} }
@ -78,9 +77,7 @@ auto GraphicsServer::GetRenderFrameDef() -> FrameDef* {
// Do some incremental loading every time we try to render. // Do some incremental loading every time we try to render.
g_base->assets->RunPendingGraphicsLoads(); g_base->assets->RunPendingGraphicsLoads();
// Spin and wait for a short bit for a frame_def to appear. If it does, we // Spin and wait for a short bit for a frame_def to appear.
// grab it, render it, and also message the logic thread to start generating
// another one.
while (true) { while (true) {
FrameDef* frame_def{}; FrameDef* frame_def{};
{ {
@ -92,8 +89,8 @@ auto GraphicsServer::GetRenderFrameDef() -> FrameDef* {
} }
if (frame_def) { if (frame_def) {
// As soon as we start working on rendering a frame, ask the logic // As soon as we start working on rendering a frame, ask the logic
// thread to start working on the next one for us. Keeps things nice and // thread to start working on the next one for us. Keeps things nice
// pipelined. // and pipelined.
g_base->logic->event_loop()->PushCall([] { g_base->logic->Draw(); }); g_base->logic->event_loop()->PushCall([] { g_base->logic->Draw(); });
return frame_def; return frame_def;
} }
@ -150,8 +147,8 @@ void GraphicsServer::PreprocessRenderFrameDef(FrameDef* frame_def) {
} }
} }
// Does the default drawing to the screen, either from the left or right stereo // Does the default drawing to the screen, either from the left or right
// eye or in mono. // stereo eye or in mono.
void GraphicsServer::DrawRenderFrameDef(FrameDef* frame_def, int eye) { void GraphicsServer::DrawRenderFrameDef(FrameDef* frame_def, int eye) {
assert(renderer_); assert(renderer_);
if (renderer_) { if (renderer_) {
@ -175,15 +172,12 @@ void GraphicsServer::TryRender() {
assert(g_base->InGraphicsThread()); assert(g_base->InGraphicsThread());
if (FrameDef* frame_def = GetRenderFrameDef()) { if (FrameDef* frame_def = GetRenderFrameDef()) {
// Apply settings such as tv-mode passed along on the frame-def. // Apply settings such as tv-mode that were passed along on the
// frame-def.
ApplyFrameDefSettings(frame_def); ApplyFrameDefSettings(frame_def);
// Note: we always run mesh updates contained in the framedef // Note: we run mesh-updates on each frame-def that comes through even
// even if we don't actually render it. // if we don't actually render the frame.
// (Hmm this seems flaky; will TryRender always get called
// for each FrameDef?... perhaps we should separate mesh updates
// from FrameDefs? Or change our logic so that frame-defs *always* get
// rendered.
RunFrameDefMeshUpdates(frame_def); RunFrameDefMeshUpdates(frame_def);
// Only actually render if we have a screen and aren't in a hold. // Only actually render if we have a screen and aren't in a hold.

View File

@ -15,18 +15,17 @@
namespace ballistica::base { namespace ballistica::base {
// Runs in the main thread and renders frame_defs shipped to it by the /// A server that runs in the graphics thread and renders frame_defs shipped
// Graphics /// to it by the logic thread.
class GraphicsServer { class GraphicsServer {
public: public:
GraphicsServer(); GraphicsServer();
void OnMainThreadStartApp(); void OnMainThreadStartApp();
/// Should be called to inform ballistica of screen size changes; this will be /// Should be called to inform ballistica of screen size changes; this
/// applied to the server and then sent to the logic thread to apply to /// will be applied to the server and then sent to the logic thread to
/// various /// apply to various app systems (ui, etc.).
// app systems (ui, etc.).
void SetScreenResolution(float h, float v); void SetScreenResolution(float h, float v);
void PushSetScreenGammaCall(float gamma); void PushSetScreenGammaCall(float gamma);
@ -42,14 +41,14 @@ class GraphicsServer {
const std::vector<Object::Ref<Asset>*>& components); const std::vector<Object::Ref<Asset>*>& components);
void SetRenderHold(); void SetRenderHold();
// Used by the logic thread to pass frame-defs to the graphics server /// Used by the logic thread to pass frame-defs to the graphics server for
// for rendering. /// rendering.
void SetFrameDef(FrameDef* framedef); void EnqueueFrameDef(FrameDef* framedef);
// returns the next frame_def needing to be rendered, waiting for it to arrive // Returns the next frame_def to be rendered, waiting for it to arrive if
// if necessary. this can return nullptr if no frame_defs come in within a // necessary. this can return nullptr if no frame_defs come in within a
// reasonable amount of time. a frame_def here *must* be rendered and disposed // reasonable amount of time. a frame_def here *must* be rendered and
// of using the RenderFrameDef* calls // disposed of using the RenderFrameDef* calls.
auto GetRenderFrameDef() -> FrameDef*; auto GetRenderFrameDef() -> FrameDef*;
void ApplyFrameDefSettings(FrameDef* frame_def); void ApplyFrameDefSettings(FrameDef* frame_def);

View File

@ -37,6 +37,49 @@ static auto ValueTestBool(bool* storage, double* absval, double* deltaval)
return static_cast<double>(*storage); return static_cast<double>(*storage);
} }
void GraphicsVR::DoDrawFade(FrameDef* frame_def, float amt) {
SimpleComponent c(frame_def->vr_cover_pass());
c.SetTransparent(false);
Vector3f cam_pt = {0.0f, 0.0f, 0.0f};
Vector3f cam_target_pt = {0.0f, 0.0f, 0.0f};
cam_pt = Vector3f(frame_def->cam_original().x, frame_def->cam_original().y,
frame_def->cam_original().z);
// In vr follow-mode the cam point gets tweaked.
//
// FIXME: should probably just do this on the camera end.
if (frame_def->camera_mode() == CameraMode::kOrbit) {
// fudge this one up a bit; looks better that way..
cam_target_pt = Vector3f(frame_def->cam_target_original().x,
frame_def->cam_target_original().y + 6.0f,
frame_def->cam_target_original().z);
} else {
cam_target_pt = Vector3f(frame_def->cam_target_original().x,
frame_def->cam_target_original().y,
frame_def->cam_target_original().z);
}
Vector3f diff = cam_target_pt - cam_pt;
diff.Normalize();
Vector3f side = Vector3f::Cross(diff, Vector3f(0.0f, 1.0f, 0.0f));
Vector3f up = Vector3f::Cross(diff, side);
c.SetColor(0, 0, 0);
c.PushTransform();
// We start in vr-overlay screen space; get back to world.
c.Translate(cam_pt.x, cam_pt.y, cam_pt.z);
c.MultMatrix(Matrix44fOrient(diff, up).m);
// At the very end we stay turned around so we get 100% black.
if (amt < 0.98f) {
c.Translate(0, 0, 40.0f * amt);
c.Rotate(180, 1, 0, 0);
}
float inv_a = 1.0f - amt;
float s = 100.0f * inv_a + 5.0f * amt;
c.Scale(s, s, s);
c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kVRFade));
c.PopTransform();
c.Submit();
}
auto GraphicsVR::ValueTest(const std::string& arg, double* absval, auto GraphicsVR::ValueTest(const std::string& arg, double* absval,
double* deltaval, double* outval) -> bool { double* deltaval, double* outval) -> bool {
if (arg == "vrOverlayScale") { if (arg == "vrOverlayScale") {
@ -165,15 +208,15 @@ void GraphicsVR::CalcVROverlayMatrices(FrameDef* frame_def) {
vr_overlay_matrix = CalcVROverlayMatrix(cam_pt, cam_target_pt); vr_overlay_matrix = CalcVROverlayMatrix(cam_pt, cam_target_pt);
// We also always calc a completely fixed matrix for some elements that // We also always calc a completely fixed matrix for some elements
// should *never* move such as score-screens. // that should *never* move such as score-screens.
cam_target_pt.y = fixed_y; cam_target_pt.y = fixed_y;
cam_target_pt.z = fixed_z; cam_target_pt.z = fixed_z;
vr_overlay_matrix_fixed = CalcVROverlayMatrix(cam_pt, cam_target_pt); vr_overlay_matrix_fixed = CalcVROverlayMatrix(cam_pt, cam_target_pt);
} }
// Calc a screen-matrix that gives us a drawing area of // Calc a screen-matrix that gives us a drawing area of kBaseVirtualResX
// kBaseVirtualResX by kBaseVirtualResY. // by kBaseVirtualResY.
frame_def->set_vr_overlay_screen_matrix( frame_def->set_vr_overlay_screen_matrix(
Matrix44fTranslate(-0.5f * kBaseVirtualResX, -0.5f * kBaseVirtualResY, Matrix44fTranslate(-0.5f * kBaseVirtualResX, -0.5f * kBaseVirtualResY,
0.0f) 0.0f)
@ -225,9 +268,11 @@ auto GraphicsVR::CalcVROverlayMatrix(const Vector3f& cam_pt,
base_scale)) base_scale))
* m; * m;
} }
void GraphicsVR::DrawVROverlay(FrameDef* frame_def) { void GraphicsVR::DrawVROverlay(FrameDef* frame_def) {
// In vr mode we have draw our overlay-flat texture in to space // In vr mode we have draw our overlay-flat texture in to space
// as part of our regular overlay pass. // as part of our regular overlay pass.
//
// NOTE: this assumes nothing after this point gets drawn into // NOTE: this assumes nothing after this point gets drawn into
// the overlay-flat pass (otherwise it may get skipped). // the overlay-flat pass (otherwise it may get skipped).
// This should be a safe assumption since this is pretty much just for // This should be a safe assumption since this is pretty much just for
@ -246,6 +291,7 @@ void GraphicsVR::DrawVROverlay(FrameDef* frame_def) {
c.Submit(); c.Submit();
} }
} }
void GraphicsVR::DrawOverlayBounds(RenderPass* pass) { void GraphicsVR::DrawOverlayBounds(RenderPass* pass) {
// We can optionally draw a guide to show the edges of the overlay pass // We can optionally draw a guide to show the edges of the overlay pass
if (draw_overlay_bounds_) { if (draw_overlay_bounds_) {

View File

@ -63,6 +63,9 @@ class GraphicsVR : public Graphics {
vr_hands_state_ = state; vr_hands_state_ = state;
} }
protected:
void DoDrawFade(FrameDef* frame_def, float amt) override;
private: private:
void CalcVROverlayMatrices(FrameDef* frame_def); void CalcVROverlayMatrices(FrameDef* frame_def);
auto CalcVROverlayMatrix(const Vector3f& cam_pt, auto CalcVROverlayMatrix(const Vector3f& cam_pt,

View File

@ -7,7 +7,7 @@
namespace ballistica::base { namespace ballistica::base {
// a mesh set up to draw images // A mesh set up to draw images.
class ImageMesh : public MeshIndexedSimpleSplit { class ImageMesh : public MeshIndexedSimpleSplit {
public: public:
ImageMesh(); ImageMesh();

View File

@ -7,10 +7,11 @@
namespace ballistica::base { namespace ballistica::base {
// Buffers used by the logic thread to pass indices/vertices/etc. to meshes in // Buffers used by the logic thread to pass indices/vertices/etc. to meshes
// the graphics thread. Note that it is safe to create these in other threads; // in the graphics thread. Note that it is safe to create these in other
// you just need to turn off thread-checks until you pass ownership to the game // threads; you just need to turn off thread-checks until you pass ownership
// thread. (or just avoid creating references outside of the logic thread) // to the game thread. (or just avoid creating references outside of the
// logic thread).
class MeshBufferBase : public Object { class MeshBufferBase : public Object {
public: public:
uint32_t state; // which dynamicState value on the mesh this corresponds to uint32_t state; // which dynamicState value on the mesh this corresponds to

View File

@ -8,9 +8,9 @@
namespace ballistica::base { namespace ballistica::base {
// Client-side (game-thread) handle to server-side (graphics-thread) mesh data. // Client-side (logic-thread) handle to server-side (graphics-thread) mesh
// Server-side data will be created when this object is instantiated and // data. Server-side data will be created when this object is instantiated
// cleared when this object goes down. // and cleared when this object goes down.
class MeshDataClientHandle : public Object { class MeshDataClientHandle : public Object {
public: public:
explicit MeshDataClientHandle(MeshData* d); explicit MeshDataClientHandle(MeshData* d);

View File

@ -7,7 +7,7 @@
namespace ballistica::base { namespace ballistica::base {
// a mesh with static indices and UVs and dynamic positions and normals /// A mesh with static indices and UVs and dynamic positions and normals.
class MeshIndexedObjectSplit class MeshIndexedObjectSplit
: public MeshIndexedStaticDynamic<VertexObjectSplitStatic, : public MeshIndexedStaticDynamic<VertexObjectSplitStatic,
VertexObjectSplitDynamic, VertexObjectSplitDynamic,

View File

@ -7,8 +7,8 @@
namespace ballistica::base { namespace ballistica::base {
// mesh with static indices, some static vertex data, /// A mesh with static indices, some static vertex data, and some dynamic
// and some dynamic vertex data /// vertex data.
template <typename STATICDATA, typename DYNAMICDATA, MeshDataType T> template <typename STATICDATA, typename DYNAMICDATA, MeshDataType T>
class MeshIndexedStaticDynamic : public MeshIndexedBase { class MeshIndexedStaticDynamic : public MeshIndexedBase {
public: public:

View File

@ -49,14 +49,14 @@ void RenderPass::Render(RenderTarget* render_target, bool transparent) {
switch (type()) { switch (type()) {
case Type::kBeautyPass: { case Type::kBeautyPass: {
g_base->graphics_server->SetCamera(cam_pos_, cam_target_, cam_up_); g_base->graphics_server->SetCamera(cam_pos_, cam_target_, cam_up_);
// If this changes, make sure to change // If this changes, make sure to change it before _drawCameraBuffer()
// it before _drawCameraBuffer() too. // too.
// FIXME: // FIXME:
// If we're drawing our cam into its own buffer we could technically // If we're drawing our cam into its own buffer we could technically
// use its full depth range ...otherwise we need to share with the // use its full depth range ...otherwise we need to share with the
// other onscreen elements (but maybe its good to use the limited // other onscreen elements (but maybe its good to use the limited
// range regardless to make sure we can) // range regardless to make sure we can get by that way).
renderer->SetDepthRange(kBackingDepth3, kBackingDepth4); renderer->SetDepthRange(kBackingDepth3, kBackingDepth4);
SetFrustum(cam_near_clip_, cam_far_clip_); SetFrustum(cam_near_clip_, cam_far_clip_);
@ -139,9 +139,9 @@ void RenderPass::Render(RenderTarget* render_target, bool transparent) {
-amt * w, (1.0f + amt) * w, -amt * h, (1.0f + amt) * h, -1, 1); -amt * w, (1.0f + amt) * w, -amt * h, (1.0f + amt) * h, -1, 1);
} else { } else {
g_base->graphics_server->SetCamera(cam_pos_, cam_target_, cam_up_); g_base->graphics_server->SetCamera(cam_pos_, cam_target_, cam_up_);
// We set the same depth ranges as the overlay-3d pass since // We set the same depth ranges as the overlay-3d pass since we're
// we're essentially doing the same thing. See explanation in the // essentially doing the same thing. See explanation in the
// overlay-3d case above the one difference is that we split the // overlay-3d case above. The one difference is that we split the
// range between our fixed overlay and our regular overlay passes // range between our fixed overlay and our regular overlay passes
// (we want fixed-overlay stuff on bottom). // (we want fixed-overlay stuff on bottom).
if (renderer->has_camera_render_target()) { if (renderer->has_camera_render_target()) {
@ -175,7 +175,7 @@ void RenderPass::Render(RenderTarget* render_target, bool transparent) {
} }
} }
} else { } else {
// Nn non-vr mode both our overlays are just ortho projected. // In non-vr mode both our overlays are just ortho projected.
g_base->graphics_server->ModelViewReset(); g_base->graphics_server->ModelViewReset();
if (type() == Type::kOverlayFrontPass) { if (type() == Type::kOverlayFrontPass) {
renderer->SetDepthRange(kBackingDepth1, kBackingDepth1B); renderer->SetDepthRange(kBackingDepth1, kBackingDepth1B);
@ -230,8 +230,8 @@ void RenderPass::Render(RenderTarget* render_target, bool transparent) {
const Vector3f& soffs = renderer->shadow_offset(); const Vector3f& soffs = renderer->shadow_offset();
// Well, this is slightly terrifying; '-soffs' is causing crashes // Well, this is slightly terrifying; '-soffs' is causing crashes
// here but multing by -1.000001f works. // here but multing by -1.000001f works (generally just on Android
// (generally just on android 4.3 on atom processors) // 4.3 on atom processors).
g_base->graphics_server->Translate(Vector3f( g_base->graphics_server->Translate(Vector3f(
-1.000001f * soffs.x, -1.000001f * soffs.y, -1.000001f * soffs.z)); -1.000001f * soffs.x, -1.000001f * soffs.y, -1.000001f * soffs.z));
} }

View File

@ -11,23 +11,46 @@
namespace ballistica::base { namespace ballistica::base {
// A drawing context for one pass. This can be a render to the screen, a shadow // A drawing context for one pass. This can be a render to the screen, a
// pass, a window, etc. // shadow pass, a window, etc.
class RenderPass { class RenderPass {
public: public:
enum class ReflectionSubPass { kRegular, kMirrored }; enum class ReflectionSubPass { kRegular, kMirrored };
enum class Type { enum class Type {
// A pass whose results are projected onto the scene for lighting and
// shadow effects. Values lighter than kShadowNeutral will show up as
// light and darker than neutral will show up as shadowing. This version
// should be used by anything wanting to draw with both shadows and
// lighting cast on it. Note that there is no z-depth used in shadow
// calculations, so objects casting shadows should not show shadows or
// else they will shadow themselves.
kLightShadowPass, kLightShadowPass,
// A pass whose results are projected onto the scene for lighting and
// shadow effects. Values lighter than kShadowNeutral will show up as
// light and darker than neutral will show up as shadowing. This pass is
// intended to only contain lights however. Objects that cast shadows
// generally should use this light texture when drawing themselves; if
// they use the kLightShadowPass texture, they will shadow themselves.
kLightPass, kLightPass,
// The pass where normal foreground scene geometry is drawn into.
kBeautyPass, kBeautyPass,
// Background geometry is drawn into this; it has a separate depth range
// so that far off mountains can properly occlude each other and whatnot
// without sacrificing depth fidelity of the regular beauty pass.
kBeautyPassBG, kBeautyPassBG,
// Geometry used to blit the camera buffer on-screen for final display.
// This geometry can make use of shaders for effects such as
// depth-of-field or can distort the texture lookup UVs for distortion
// shock-waves or other effects.
kBlitPass, kBlitPass,
// Standard 2d overlay stuff. May be drawn in 2d or on a plane in 3d // Standard 2d overlay stuff such as UI. May be drawn in 2d or on a
// space (in vr). In VR, each of these elements are drawn individually // plane in 3d space (in vr). In VR, each of these elements are drawn
// and can thus have their own depth. also in VR this overlay repositions // individually and can thus have their own depth. also in VR, this
// itself per level; use kOverlayFixedPass for items that shouldn't. // overlay may be repositions based on the camera/map/etc; use
// this overlay may be obscured by UI. Use OVERLAY_FRONT_PASS if you need // kOverlayFixedPass for items that shouldn't do this (for example,
// things to show up in front of UI. // elements visible across map transitions). Be aware that things here
// may be obscured by UI depending on depth/etc. Use OVERLAY_FRONT_PASS
// if you need things to always show up in front of UI.
kOverlayPass, kOverlayPass,
// Just like kOverlayPass but guaranteed to draw in front of UI. // Just like kOverlayPass but guaranteed to draw in front of UI.
kOverlayFrontPass, kOverlayFrontPass,
@ -40,7 +63,9 @@ class RenderPass {
/// Only used in VR - stuff that needs to cover absolutely everything /// Only used in VR - stuff that needs to cover absolutely everything
/// else (like the 3d wipe fade). /// else (like the 3d wipe fade).
kVRCoverPass, kVRCoverPass,
// Only used in VR - overlay elements that should always be fixed in space. // Only used in VR - overlay elements that should always be fixed in
// space. Use this for stuff that may be visible across map transitions
// or other events that can cause the regular overlay to move around.
kOverlayFixedPass kOverlayFixedPass
}; };
@ -49,7 +74,7 @@ class RenderPass {
auto type() const -> Type { return type_; } auto type() const -> Type { return type_; }
// The physical size of the drawing surface. // The physical size of the drawing surface (pixels).
auto physical_width() const -> float { return physical_width_; } auto physical_width() const -> float { return physical_width_; }
auto physical_height() const -> float { return physical_height_; } auto physical_height() const -> float { return physical_height_; }

View File

@ -152,8 +152,8 @@ void NetGraph::Draw(RenderPass* pass, double time, double x, double y, double w,
snprintf(val_str, sizeof(val_str), "%.3f", snprintf(val_str, sizeof(val_str), "%.3f",
impl_->smoothed ? impl_->v_smoothed : val); impl_->smoothed ? impl_->v_smoothed : val);
} }
impl_->max_vel_text.set_text(val_str, TextMesh::HAlign::kLeft, impl_->max_vel_text.SetText(val_str, TextMesh::HAlign::kLeft,
TextMesh::VAlign::kTop); TextMesh::VAlign::kTop);
SimpleComponent c2(pass); SimpleComponent c2(pass);
c2.SetTransparent(true); c2.SetTransparent(true);

View File

@ -8,9 +8,9 @@
namespace ballistica::base { namespace ballistica::base {
void TextGroup::set_text(const std::string& text, TextMesh::HAlign alignment_h, void TextGroup::SetText(const std::string& text, TextMesh::HAlign alignment_h,
TextMesh::VAlign alignment_v, bool big, TextMesh::VAlign alignment_v, bool big,
float resolution_scale) { float resolution_scale) {
text_ = text; text_ = text;
// In order to *actually* draw big, all our letters // In order to *actually* draw big, all our letters
@ -18,8 +18,8 @@ void TextGroup::set_text(const std::string& text, TextMesh::HAlign alignment_h,
big_ = (big && TextGraphics::HaveBigChars(text)); big_ = (big && TextGraphics::HaveBigChars(text));
// If we had an OS texture for custom drawing, release it. // If we had an OS texture for custom drawing, release it.
// (it should stick around for a while; we'll be able to re-grab // It should stick around for a while; we'll be able to re-grab
// the same one if we havn't changed) // the same one if we havn't changed.
os_texture_.Clear(); os_texture_.Clear();
// If we're drawing big we always just need 1 font page (the big one). // If we're drawing big we always just need 1 font page (the big one).
@ -89,7 +89,9 @@ void TextGroup::set_text(const std::string& text, TextMesh::HAlign alignment_h,
// For the few we can't color, we don't want to be able to // For the few we can't color, we don't want to be able to
// flatten them either. // flatten them either.
if (!entry->can_color) entry->max_flatness = 0.0f; if (!entry->can_color) {
entry->max_flatness = 0.0f;
}
// For OS-rendered text we fill out a text-packer will all the spans // For OS-rendered text we fill out a text-packer will all the spans
// we'll need. we then hand that over to the OS to draw and create // we'll need. we then hand that over to the OS to draw and create

View File

@ -14,9 +14,9 @@
namespace ballistica::base { namespace ballistica::base {
// encapsulates the multiple meshes and textures necessary to // Encapsulates the multiple meshes and textures necessary to draw arbitrary
// draw arbitrary text. To actually draw the text, iterate over the meshes // text. To actually draw the text, iterate over the meshes and textures
// and textures this class provides to you, drawing each in the same manner // this class provides to you, drawing each in the same manner.
class TextGroup : public Object { class TextGroup : public Object {
public: public:
// the number of meshes needing to be drawn for this text // the number of meshes needing to be drawn for this text
@ -55,10 +55,10 @@ class TextGroup : public Object {
? SysTextureID::kSoftRect2 ? SysTextureID::kSoftRect2
: SysTextureID::kSoftRect); : SysTextureID::kSoftRect);
} }
void set_text(const std::string& text, void SetText(const std::string& text,
TextMesh::HAlign alignment_h = TextMesh::HAlign::kLeft, TextMesh::HAlign alignment_h = TextMesh::HAlign::kLeft,
TextMesh::VAlign alignment_v = TextMesh::VAlign::kNone, TextMesh::VAlign alignment_v = TextMesh::VAlign::kNone,
bool big = false, float resolution_scale = 1.0f); bool big = false, float resolution_scale = 1.0f);
auto text() const -> const std::string& { return text_; } auto text() const -> const std::string& { return text_; }
void GetCaratPts(const std::string& text_in, TextMesh::HAlign alignment_h, void GetCaratPts(const std::string& text_in, TextMesh::HAlign alignment_h,
TextMesh::VAlign alignment_v, int carat_pos, float* carat_x, TextMesh::VAlign alignment_v, int carat_pos, float* carat_x,

View File

@ -23,7 +23,6 @@ namespace ballistica::base {
// How much of the screen the console covers when it is at full size. // How much of the screen the console covers when it is at full size.
const float kDevConsoleSize = 0.9f; const float kDevConsoleSize = 0.9f;
const float kDevConsoleZDepth = 0.0f;
const int kDevConsoleLineLimit = 80; const int kDevConsoleLineLimit = 80;
const int kDevConsoleStringBreakUpSize = 1950; const int kDevConsoleStringBreakUpSize = 1950;
const int kDevConsoleActivateKey1 = SDLK_BACKQUOTE; const int kDevConsoleActivateKey1 = SDLK_BACKQUOTE;
@ -33,20 +32,65 @@ const double kTransitionSeconds = 0.1;
enum class DevButtonAttach_ { kLeft, kCenter, kRight }; enum class DevButtonAttach_ { kLeft, kCenter, kRight };
class DevConsole::Button_ { static auto XOffs(DevButtonAttach_ attach) -> float {
switch (attach) {
case DevButtonAttach_::kLeft:
return 0.0f;
case DevButtonAttach_::kRight:
return g_base->graphics->screen_virtual_width();
case DevButtonAttach_::kCenter:
return g_base->graphics->screen_virtual_width() * 0.5f;
}
assert(false);
return 0.0f;
}
static void DrawBasicButton(RenderPass* pass, TextGroup* tgrp, float tscale,
float bottom, float x, float y, float width,
float height, const Vector3f& fgcolor,
const Vector3f& bgcolor) {
SimpleComponent c(pass);
c.SetTransparent(true);
c.SetColor(bgcolor.x, bgcolor.y, bgcolor.z, 1.0f);
{
auto xf = c.ScopedTransform();
c.Translate(x + width * 0.5f, y + bottom + height * 0.5f,
kDevConsoleZDepth);
// Draw our backing.
{
auto xf = c.ScopedTransform();
c.Scale(width, height);
c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kImage1x1));
}
// Draw our text.
c.SetColor(fgcolor.x, fgcolor.y, fgcolor.z, 1.0f);
c.SetFlatness(1.0f);
int elem_count = tgrp->GetElementCount();
for (int e = 0; e < elem_count; e++) {
c.SetTexture(tgrp->GetElementTexture(e));
{
auto xf = c.ScopedTransform();
float sc{0.6f * tscale};
c.Scale(sc, sc, 1.0f);
c.DrawMesh(tgrp->GetElementMesh(e));
}
}
}
c.Submit();
}
/// Super-simple widget type for populating dev-console
/// (we don't want to depend on any of our full UI feature-sets).
class DevConsole::Widget_ {
public:
virtual ~Widget_() = default;
virtual auto HandleMouseDown(float mx, float my) -> bool = 0;
virtual void HandleMouseUp(float mx, float my) = 0;
virtual void Draw(RenderPass* pass, float bottom) = 0;
};
class DevConsole::Button_ : public DevConsole::Widget_ {
public: public:
template <typename F>
Button_(const std::string& label, float text_scale, DevButtonAttach_ attach,
float x, float y, float width, float height, const F& lambda)
: label{label},
attach{attach},
x{x},
y{y},
width{width},
height{height},
call{NewLambdaRunnable(lambda)},
text_scale{text_scale} {}
std::string label;
DevButtonAttach_ attach; DevButtonAttach_ attach;
float x; float x;
float y; float y;
@ -55,27 +99,28 @@ class DevConsole::Button_ {
bool pressed{}; bool pressed{};
Object::Ref<Runnable> call; Object::Ref<Runnable> call;
TextGroup text_group; TextGroup text_group;
bool text_group_built_{};
float text_scale; float text_scale;
auto InUs(float mx, float my) -> bool { template <typename F>
mx -= XOffs(); Button_(const std::string& label, float text_scale, DevButtonAttach_ attach,
return (mx >= x && mx <= (x + width) && my >= y && my <= (y + height)); float x, float y, float width, float height, const F& lambda)
} : attach{attach},
auto XOffs() -> float { x{x},
switch (attach) { y{y},
case DevButtonAttach_::kLeft: width{width},
return 0.0f; height{height},
case DevButtonAttach_::kRight: call{NewLambdaRunnable(lambda)},
return g_base->graphics->screen_virtual_width(); text_scale{text_scale} {
case DevButtonAttach_::kCenter: text_group.SetText(label, TextMesh::HAlign::kCenter,
return g_base->graphics->screen_virtual_width() * 0.5f; TextMesh::VAlign::kCenter);
}
assert(false);
return 0.0f;
} }
auto HandleMouseDown(float mx, float my) -> bool { auto InUs(float mx, float my) -> bool {
mx -= XOffs(attach);
return (mx >= x && mx <= (x + width) && my >= y && my <= (y + height));
}
auto HandleMouseDown(float mx, float my) -> bool override {
if (InUs(mx, my)) { if (InUs(mx, my)) {
pressed = true; pressed = true;
return true; return true;
@ -83,56 +128,156 @@ class DevConsole::Button_ {
return false; return false;
} }
void HandleMouseUp(float mx, float my) { void HandleMouseUp(float mx, float my) override {
pressed = false; if (pressed) {
if (InUs(mx, my)) { pressed = false;
if (call.Exists()) { if (InUs(mx, my)) {
call.Get()->Run(); if (call.Exists()) {
call.Get()->Run();
}
} }
} }
} }
void Draw(RenderPass* pass, float bottom) { void Draw(RenderPass* pass, float bottom) override {
if (!text_group_built_) { DrawBasicButton(
text_group.set_text(label, TextMesh::HAlign::kCenter, pass, &text_group, text_scale, bottom, x + XOffs(attach), y, width,
TextMesh::VAlign::kCenter); height,
pressed ? Vector3f{0.0f, 0.0f, 0.0f} : Vector3f{0.8f, 0.7f, 0.8f},
pressed ? Vector3f{0.8f, 0.7f, 0.8f} : Vector3f{0.25, 0.2f, 0.3f});
}
};
class DevConsole::ToggleButton_ : public DevConsole::Widget_ {
public:
DevButtonAttach_ attach;
float x;
float y;
float width;
float height;
bool pressed{};
bool on{};
Object::Ref<Runnable> on_call;
Object::Ref<Runnable> off_call;
TextGroup text_group;
float text_scale;
template <typename F, typename G>
ToggleButton_(const std::string& label, float text_scale,
DevButtonAttach_ attach, float x, float y, float width,
float height, const F& on_call, const G& off_call)
: attach{attach},
x{x},
y{y},
width{width},
height{height},
on_call{NewLambdaRunnable(on_call)},
off_call{NewLambdaRunnable(off_call)},
text_scale{text_scale} {
text_group.SetText(label, TextMesh::HAlign::kCenter,
TextMesh::VAlign::kCenter);
}
auto InUs(float mx, float my) -> bool {
mx -= XOffs(attach);
return (mx >= x && mx <= (x + width) && my >= y && my <= (y + height));
}
auto HandleMouseDown(float mx, float my) -> bool override {
if (InUs(mx, my)) {
pressed = true;
return true;
} }
SimpleComponent c(pass); return false;
c.SetTransparent(true); }
void HandleMouseUp(float mx, float my) override {
if (pressed) { if (pressed) {
c.SetColor(0.8f, 0.7f, 0.8f, 1.0f); pressed = false;
} else { if (InUs(mx, my)) {
c.SetColor(0.25f, 0.2f, 0.3f, 1.0f); on = !on;
} auto&& call = on ? on_call : off_call;
{ if (call.Exists()) {
auto xf = c.ScopedTransform(); call.Get()->Run();
c.Translate(x + XOffs() + width * 0.5f, y + bottom + height * 0.5f,
kDevConsoleZDepth);
// Draw our backing.
{
auto xf = c.ScopedTransform();
c.Scale(width, height);
c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kImage1x1));
}
// Draw our text.
if (pressed) {
c.SetColor(0.0f, 0.0f, 0.0f, 1.0f);
} else {
c.SetColor(0.8f, 0.7f, 0.8f, 1.0f);
}
c.SetFlatness(1.0f);
int elem_count = text_group.GetElementCount();
for (int e = 0; e < elem_count; e++) {
c.SetTexture(text_group.GetElementTexture(e));
{
auto xf = c.ScopedTransform();
float sc{0.6f * text_scale};
c.Scale(sc, sc, 1.0f);
c.DrawMesh(text_group.GetElementMesh(e));
} }
} }
} }
c.Submit(); }
void Draw(RenderPass* pass, float bottom) override {
DrawBasicButton(pass, &text_group, text_scale, bottom, x + XOffs(attach), y,
width, height,
pressed ? Vector3f{1.0f, 1.0f, 1.0f}
: on ? Vector3f{1.0f, 1.0f, 1.0f}
: Vector3f{0.8f, 0.7f, 0.8f},
pressed ? Vector3f{0.5f, 0.2f, 1.0f}
: on ? Vector3f{0.5f, 0.4f, 0.6f}
: Vector3f{0.25, 0.2f, 0.3f});
}
};
class DevConsole::TabButton_ : public DevConsole::Widget_ {
public:
DevButtonAttach_ attach;
float x;
float y;
float width;
float height;
bool pressed{};
bool selected{};
Object::Ref<Runnable> call;
TextGroup text_group;
float text_scale;
template <typename F>
TabButton_(const std::string& label, bool selected, float text_scale,
DevButtonAttach_ attach, float x, float y, float width,
float height, const F& call)
: attach{attach},
x{x},
y{y},
selected{selected},
width{width},
height{height},
call{NewLambdaRunnable(call)},
text_scale{text_scale} {
text_group.SetText(label, TextMesh::HAlign::kCenter,
TextMesh::VAlign::kCenter);
}
auto InUs(float mx, float my) -> bool {
mx -= XOffs(attach);
return (mx >= x && mx <= (x + width) && my >= y && my <= (y + height));
}
auto HandleMouseDown(float mx, float my) -> bool override {
if (InUs(mx, my) && !selected) {
pressed = true;
return true;
}
return false;
}
void HandleMouseUp(float mx, float my) override {
if (pressed) {
pressed = false;
if (InUs(mx, my)) {
if (call.Exists()) {
call.Get()->Run();
}
}
}
}
void Draw(RenderPass* pass, float bottom) override {
DrawBasicButton(pass, &text_group, text_scale, bottom, x + XOffs(attach), y,
width, height,
pressed ? Vector3f{1.0f, 1.0f, 1.0f}
: selected ? Vector3f{1.0f, 1.0f, 1.0f}
: Vector3f{0.8f, 0.7f, 0.8f},
pressed ? Vector3f{0.5f, 0.2f, 1.0f}
: selected ? Vector3f{0.5f, 0.4f, 0.6f}
: Vector3f{0.25, 0.2f, 0.3f});
} }
}; };
@ -144,7 +289,7 @@ class DevConsole::Line_ {
auto GetText() -> TextGroup& { auto GetText() -> TextGroup& {
if (!s_mesh_.Exists()) { if (!s_mesh_.Exists()) {
s_mesh_ = Object::New<TextGroup>(); s_mesh_ = Object::New<TextGroup>();
s_mesh_->set_text(s); s_mesh_->SetText(s);
} }
return *s_mesh_; return *s_mesh_;
} }
@ -164,32 +309,45 @@ DevConsole::DevConsole() {
title += " (test)"; title += " (test)";
} }
title_text_group_.set_text(title); title_text_group_.SetText(title);
built_text_group_.set_text("Built: " __DATE__ " " __TIME__); built_text_group_.SetText("Built: " __DATE__ " " __TIME__);
prompt_text_group_.set_text(">"); prompt_text_group_.SetText(">");
// NOTE: Once we can adjust UI scale on the fly we'll have to update Refresh();
// this to recalc accordingly.
float bs = PythonConsoleBaseScale_();
buttons_.emplace_back("Exec", 0.75f * bs, DevButtonAttach_::kRight,
-33.0f * bs, 15.95f * bs, 32.0f * bs, 13.0f * bs,
[this] { Exec(); });
// buttons_.emplace_back("TestButton", 1.0f, DevButtonAttach_::kLeft, 100.0f,
// 100.0f, 100.0f, 30.0f, [] { printf("B1 PRESSED!\n");
// });
// buttons_.emplace_back("TestButton2", 1.0f, DevButtonAttach_::kCenter,
// -50.0f,
// 120.0f, 100.0f, 30.0f, [] { printf("B2 PRESSED!\n");
// });
// buttons_.emplace_back("TestButton3", 0.8f, DevButtonAttach_::kRight,
// -200.0f,
// 140.0f, 100.0f, 30.0f, [] { printf("B3 PRESSED!\n");
// });
} }
void DevConsole::Refresh() {
BA_PRECONDITION(g_base->InLogicThread());
buttons_.clear();
tab_buttons_.clear();
RefreshTabsButtons_();
if (active_tab_ == "Python") {
float bs = PythonConsoleBaseScale_();
buttons_.emplace_back(std::make_unique<Button_>(
"Exec", 0.75f * bs, DevButtonAttach_::kRight, -33.0f * bs, 15.95f * bs,
32.0f * bs, 13.0f * bs, [this] { Exec(); }));
}
}
void DevConsole::RefreshTabsButtons_() {
float bs = PythonConsoleBaseScale_();
float bwidth = 90.0f * bs;
float bheight = 26.0f * bs;
float bscale = 0.8f * bs;
float total_width = tabs_.size() * bwidth;
float x = total_width * -0.5f;
for (auto&& tab : tabs_) {
tab_buttons_.emplace_back(std::make_unique<TabButton_>(
tab, active_tab_ == tab, bscale, DevButtonAttach_::kCenter, x, -bheight,
bwidth, bheight, [this, tab] {
active_tab_ = tab;
Refresh();
}));
x += bwidth;
}
}
DevConsole::~DevConsole() = default; DevConsole::~DevConsole() = default;
auto DevConsole::HandleMouseDown(int button, float x, float y) -> bool { auto DevConsole::HandleMouseDown(int button, float x, float y) -> bool {
@ -202,8 +360,13 @@ auto DevConsole::HandleMouseDown(int button, float x, float y) -> bool {
// Pass to any buttons (in bottom-local space). // Pass to any buttons (in bottom-local space).
if (button == 1) { if (button == 1) {
for (auto&& button : tab_buttons_) {
if (button->HandleMouseDown(x, y - bottom)) {
return true;
}
}
for (auto&& button : buttons_) { for (auto&& button : buttons_) {
if (button.HandleMouseDown(x, y - bottom)) { if (button->HandleMouseDown(x, y - bottom)) {
return true; return true;
} }
} }
@ -225,8 +388,11 @@ void DevConsole::HandleMouseUp(int button, float x, float y) {
float bottom{Bottom_()}; float bottom{Bottom_()};
if (button == 1) { if (button == 1) {
for (auto&& button : tab_buttons_) {
button->HandleMouseUp(x, y - bottom);
}
for (auto&& button : buttons_) { for (auto&& button : buttons_) {
button.HandleMouseUp(x, y - bottom); button->HandleMouseUp(x, y - bottom);
} }
} }
@ -311,7 +477,7 @@ auto DevConsole::HandleKeyPress(const SDL_Keysym* keysym) -> bool {
// The rest of these presses we only handle while active. // The rest of these presses we only handle while active.
switch (keysym->sym) { switch (keysym->sym) {
case SDLK_ESCAPE: case SDLK_ESCAPE:
ToggleState(); Dismiss();
break; break;
case SDLK_BACKSPACE: case SDLK_BACKSPACE:
case SDLK_DELETE: { case SDLK_DELETE: {
@ -530,11 +696,12 @@ auto DevConsole::Bottom_() const -> float {
return bottom; return bottom;
} }
void DevConsole::Draw(RenderPass* pass) { void DevConsole::Draw(FrameDef* frame_def) {
float bs = PythonConsoleBaseScale_(); float bs = PythonConsoleBaseScale_();
RenderPass* pass = frame_def->overlay_front_pass();
// If we're not yet transitioning in for the first time OR have // If we're not yet transitioning in for the first time OR have completed
// completed transitioning out, do nothing. // transitioning out, do nothing.
if (transition_start_ <= 0.0 if (transition_start_ <= 0.0
|| state_ == State_::kInactive || state_ == State_::kInactive
&& ((g_base->logic->display_time() - transition_start_) && ((g_base->logic->display_time() - transition_start_)
@ -543,155 +710,169 @@ void DevConsole::Draw(RenderPass* pass) {
} }
float bottom = Bottom_(); float bottom = Bottom_();
{ {
bg_mesh_.SetPositionAndSize(0, bottom, kDevConsoleZDepth, bg_mesh_.SetPositionAndSize(0, bottom, kDevConsoleZDepth,
pass->virtual_width(), pass->virtual_width(),
(pass->virtual_height() - bottom)); (pass->virtual_height() - bottom));
stripe_mesh_.SetPositionAndSize(0, bottom + 15.0f * bs, kDevConsoleZDepth, stripe_mesh_.SetPositionAndSize(0, bottom + 15.0f * bs, kDevConsoleZDepth,
pass->virtual_width(), 15.0f * bs); pass->virtual_width(), 15.0f * bs);
shadow_mesh_.SetPositionAndSize(0, bottom - 7.0f * bs, kDevConsoleZDepth, border_mesh_.SetPositionAndSize(0, bottom - 3.0f * bs, kDevConsoleZDepth,
pass->virtual_width(), 7.0f * bs); pass->virtual_width(), 3.0f * bs);
SimpleComponent c(pass); SimpleComponent c(pass);
c.SetTransparent(true); c.SetTransparent(true);
c.SetColor(0, 0, 0.1f, 0.9f); c.SetColor(0, 0, 0.1f, 0.9f);
c.DrawMesh(&bg_mesh_); c.DrawMesh(&bg_mesh_);
c.Submit(); c.Submit();
c.SetColor(1.0f, 1.0f, 1.0f, 0.1f); if (active_tab_ == "Python") {
c.DrawMesh(&stripe_mesh_); c.SetColor(1.0f, 1.0f, 1.0f, 0.1f);
c.Submit(); c.DrawMesh(&stripe_mesh_);
c.SetColor(0, 0, 0, 0.1f); c.Submit();
c.DrawMesh(&shadow_mesh_);
c.Submit();
}
if (input_text_dirty_) {
input_text_group_.set_text(input_string_);
input_text_dirty_ = false;
last_input_text_change_time_ = pass->frame_def()->real_time();
}
{
SimpleComponent c(pass);
c.SetFlatness(1.0f);
c.SetTransparent(true);
c.SetColor(0.5f, 0.5f, 0.7f, 0.8f);
int elem_count = built_text_group_.GetElementCount();
for (int e = 0; e < elem_count; e++) {
c.SetTexture(built_text_group_.GetElementTexture(e));
{
auto xf = c.ScopedTransform();
c.Translate(pass->virtual_width() - 115.0f * bs, bottom + 4.0f,
kDevConsoleZDepth);
c.Scale(0.35f * bs, 0.35f * bs, 1.0f);
c.DrawMesh(built_text_group_.GetElementMesh(e));
}
}
elem_count = title_text_group_.GetElementCount();
for (int e = 0; e < elem_count; e++) {
c.SetTexture(title_text_group_.GetElementTexture(e));
{
auto xf = c.ScopedTransform();
c.Translate(10.0f * bs, bottom + 4.0f, kDevConsoleZDepth);
c.Scale(0.35f * bs, 0.35f * bs, 1.0f);
c.DrawMesh(title_text_group_.GetElementMesh(e));
}
}
elem_count = prompt_text_group_.GetElementCount();
for (int e = 0; e < elem_count; e++) {
c.SetTexture(prompt_text_group_.GetElementTexture(e));
c.SetColor(1, 1, 1, 1);
{
auto xf = c.ScopedTransform();
c.Translate(5.0f * bs, bottom + 14.5f * bs, kDevConsoleZDepth);
c.Scale(0.5f * bs, 0.5f * bs, 1.0f);
c.DrawMesh(prompt_text_group_.GetElementMesh(e));
}
}
elem_count = input_text_group_.GetElementCount();
for (int e = 0; e < elem_count; e++) {
c.SetTexture(input_text_group_.GetElementTexture(e));
{
auto xf = c.ScopedTransform();
c.Translate(15.0f * bs, bottom + 14.5f * bs, kDevConsoleZDepth);
c.Scale(0.5f * bs, 0.5f * bs, 1.0f);
c.DrawMesh(input_text_group_.GetElementMesh(e));
}
} }
c.SetColor(0.25f, 0.2f, 0.3f, 1.0f);
c.DrawMesh(&border_mesh_);
c.Submit(); c.Submit();
} }
// Carat. if (active_tab_ == "Python") {
millisecs_t real_time = pass->frame_def()->real_time(); if (input_text_dirty_) {
if (real_time % 200 < 100 input_text_group_.SetText(input_string_);
|| (real_time - last_input_text_change_time_ < 100)) { input_text_dirty_ = false;
SimpleComponent c(pass); last_input_text_change_time_ = pass->frame_def()->real_time();
c.SetTransparent(true); }
c.SetColor(1, 1, 1, 0.7f);
{ {
auto xf = c.ScopedTransform(); SimpleComponent c(pass);
c.Translate( c.SetFlatness(1.0f);
(19.0f + g_base->text_graphics->GetStringWidth(input_string_) * 0.5f) c.SetTransparent(true);
* bs, c.SetColor(0.5f, 0.5f, 0.7f, 0.8f);
bottom + 22.5f * bs, kDevConsoleZDepth); int elem_count = built_text_group_.GetElementCount();
c.Scale(6.0f * bs, 12.0f * bs, 1.0f); for (int e = 0; e < elem_count; e++) {
c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kImage1x1)); c.SetTexture(built_text_group_.GetElementTexture(e));
{
auto xf = c.ScopedTransform();
c.Translate(pass->virtual_width() - 115.0f * bs, bottom + 4.0f,
kDevConsoleZDepth);
c.Scale(0.35f * bs, 0.35f * bs, 1.0f);
c.DrawMesh(built_text_group_.GetElementMesh(e));
}
}
elem_count = title_text_group_.GetElementCount();
for (int e = 0; e < elem_count; e++) {
c.SetTexture(title_text_group_.GetElementTexture(e));
{
auto xf = c.ScopedTransform();
c.Translate(10.0f * bs, bottom + 4.0f, kDevConsoleZDepth);
c.Scale(0.35f * bs, 0.35f * bs, 1.0f);
c.DrawMesh(title_text_group_.GetElementMesh(e));
}
}
elem_count = prompt_text_group_.GetElementCount();
for (int e = 0; e < elem_count; e++) {
c.SetTexture(prompt_text_group_.GetElementTexture(e));
c.SetColor(1, 1, 1, 1);
{
auto xf = c.ScopedTransform();
c.Translate(5.0f * bs, bottom + 14.5f * bs, kDevConsoleZDepth);
c.Scale(0.5f * bs, 0.5f * bs, 1.0f);
c.DrawMesh(prompt_text_group_.GetElementMesh(e));
}
}
elem_count = input_text_group_.GetElementCount();
for (int e = 0; e < elem_count; e++) {
c.SetTexture(input_text_group_.GetElementTexture(e));
{
auto xf = c.ScopedTransform();
c.Translate(15.0f * bs, bottom + 14.5f * bs, kDevConsoleZDepth);
c.Scale(0.5f * bs, 0.5f * bs, 1.0f);
c.DrawMesh(input_text_group_.GetElementMesh(e));
}
}
c.Submit();
}
// Carat.
millisecs_t real_time = pass->frame_def()->real_time();
if (real_time % 200 < 100
|| (real_time - last_input_text_change_time_ < 100)) {
SimpleComponent c(pass);
c.SetTransparent(true);
c.SetColor(1, 1, 1, 0.7f);
{
auto xf = c.ScopedTransform();
c.Translate(
(19.0f
+ g_base->text_graphics->GetStringWidth(input_string_) * 0.5f)
* bs,
bottom + 22.5f * bs, kDevConsoleZDepth);
c.Scale(6.0f * bs, 12.0f * bs, 1.0f);
c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kImage1x1));
}
c.Submit();
}
// Draw output lines.
{
float draw_scale = 0.6f;
float v_inc = 18.0f;
SimpleComponent c(pass);
c.SetTransparent(true);
c.SetColor(1, 1, 1, 1);
c.SetFlatness(1.0f);
float h = 0.5f
* (g_base->graphics->screen_virtual_width()
- (kDevConsoleStringBreakUpSize * draw_scale));
float v = bottom + 32.0f * bs;
if (!last_line_.empty()) {
if (last_line_mesh_dirty_) {
if (!last_line_mesh_group_.Exists()) {
last_line_mesh_group_ = Object::New<TextGroup>();
}
last_line_mesh_group_->SetText(last_line_);
last_line_mesh_dirty_ = false;
}
int elem_count = last_line_mesh_group_->GetElementCount();
for (int e = 0; e < elem_count; e++) {
c.SetTexture(last_line_mesh_group_->GetElementTexture(e));
{
auto xf = c.ScopedTransform();
c.Translate(h, v + 2, kDevConsoleZDepth);
c.Scale(draw_scale, draw_scale);
c.DrawMesh(last_line_mesh_group_->GetElementMesh(e));
}
}
v += v_inc;
}
for (auto i = lines_.rbegin(); i != lines_.rend(); i++) {
int elem_count = i->GetText().GetElementCount();
for (int e = 0; e < elem_count; e++) {
c.SetTexture(i->GetText().GetElementTexture(e));
{
auto xf = c.ScopedTransform();
c.Translate(h, v + 2, kDevConsoleZDepth);
c.Scale(draw_scale, draw_scale);
c.DrawMesh(i->GetText().GetElementMesh(e));
}
}
v += v_inc;
if (v > pass->virtual_height() + v_inc) {
break;
}
}
c.Submit();
} }
c.Submit();
} }
// Draw output lines. // Tab Buttons.
{ {
float draw_scale = 0.6f; for (auto&& button : tab_buttons_) {
float v_inc = 18.0f; button->Draw(pass, bottom);
SimpleComponent c(pass);
c.SetTransparent(true);
c.SetColor(1, 1, 1, 1);
c.SetFlatness(1.0f);
float h = 0.5f
* (g_base->graphics->screen_virtual_width()
- (kDevConsoleStringBreakUpSize * draw_scale));
float v = bottom + 32.0f * bs;
if (!last_line_.empty()) {
if (last_line_mesh_dirty_) {
if (!last_line_mesh_group_.Exists()) {
last_line_mesh_group_ = Object::New<TextGroup>();
}
last_line_mesh_group_->set_text(last_line_);
last_line_mesh_dirty_ = false;
}
int elem_count = last_line_mesh_group_->GetElementCount();
for (int e = 0; e < elem_count; e++) {
c.SetTexture(last_line_mesh_group_->GetElementTexture(e));
{
auto xf = c.ScopedTransform();
c.Translate(h, v + 2, kDevConsoleZDepth);
c.Scale(draw_scale, draw_scale);
c.DrawMesh(last_line_mesh_group_->GetElementMesh(e));
}
}
v += v_inc;
} }
for (auto i = lines_.rbegin(); i != lines_.rend(); i++) {
int elem_count = i->GetText().GetElementCount();
for (int e = 0; e < elem_count; e++) {
c.SetTexture(i->GetText().GetElementTexture(e));
{
auto xf = c.ScopedTransform();
c.Translate(h, v + 2, kDevConsoleZDepth);
c.Scale(draw_scale, draw_scale);
c.DrawMesh(i->GetText().GetElementMesh(e));
}
}
v += v_inc;
if (v > pass->virtual_height() + v_inc) {
break;
}
}
c.Submit();
} }
// Buttons. // Buttons.
{ {
for (auto&& button : buttons_) { for (auto&& button : buttons_) {
button.Draw(pass, bottom); button->Draw(pass, bottom);
} }
} }
} }
@ -706,6 +887,8 @@ auto DevConsole::PythonConsoleBaseScale_() const -> float {
case UIScale::kLast: case UIScale::kLast:
return 2.0f; return 2.0f;
} }
FatalError("Unhandled scale.");
return 1.0f;
} }
} // namespace ballistica::base } // namespace ballistica::base

View File

@ -6,6 +6,7 @@
#include <list> #include <list>
#include <string> #include <string>
#include <utility> #include <utility>
#include <vector>
#include "ballistica/base/graphics/renderer/renderer.h" #include "ballistica/base/graphics/renderer/renderer.h"
#include "ballistica/shared/foundation/object.h" #include "ballistica/shared/foundation/object.h"
@ -13,6 +14,9 @@
namespace ballistica::base { namespace ballistica::base {
/// Where on the overlay-front-pass we draw.
const float kDevConsoleZDepth = 0.0f;
class DevConsole { class DevConsole {
public: public:
DevConsole(); DevConsole();
@ -31,7 +35,7 @@ class DevConsole {
/// Print text to the console. /// Print text to the console.
void Print(const std::string& s_in); void Print(const std::string& s_in);
void Draw(RenderPass* pass); void Draw(FrameDef* frame_def);
/// Called when the console should start accepting Python command input. /// Called when the console should start accepting Python command input.
void EnableInput(); void EnableInput();
@ -47,18 +51,27 @@ class DevConsole {
auto HandleMouseDown(int button, float x, float y) -> bool; auto HandleMouseDown(int button, float x, float y) -> bool;
void HandleMouseUp(int button, float x, float y); void HandleMouseUp(int button, float x, float y);
void Exec(); void Exec();
void Refresh();
private: private:
class Widget_;
class Button_; class Button_;
class ToggleButton_;
class TabButton_;
class Line_; class Line_;
enum class State_ { kInactive, kMini, kFull }; enum class State_ { kInactive, kMini, kFull };
auto Bottom_() const -> float; auto Bottom_() const -> float;
auto PythonConsoleBaseScale_() const -> float; auto PythonConsoleBaseScale_() const -> float;
void SubmitCommand_(const std::string& command); void SubmitCommand_(const std::string& command);
void InvokeStringEditor_(); void InvokeStringEditor_();
void RefreshTabsButtons_();
std::list<std::string> tabs_{"Python", "AppModes", "Logging", "Graphics"};
std::string active_tab_{"Python"};
ImageMesh bg_mesh_; ImageMesh bg_mesh_;
ImageMesh stripe_mesh_; ImageMesh stripe_mesh_;
ImageMesh shadow_mesh_; ImageMesh border_mesh_;
TextGroup built_text_group_; TextGroup built_text_group_;
TextGroup title_text_group_; TextGroup title_text_group_;
TextGroup prompt_text_group_; TextGroup prompt_text_group_;
@ -78,7 +91,8 @@ class DevConsole {
bool last_line_mesh_dirty_{true}; bool last_line_mesh_dirty_{true};
bool python_console_pressed_{}; bool python_console_pressed_{};
PythonRef string_edit_adapter_; PythonRef string_edit_adapter_;
std::list<Button_> buttons_; std::vector<std::unique_ptr<Widget_> > buttons_;
std::vector<std::unique_ptr<Widget_> > tab_buttons_;
}; };
} // namespace ballistica::base } // namespace ballistica::base

View File

@ -163,13 +163,14 @@ void UI::HandleMouseUp(int button, float x, float y) {
if (dev_console_) { if (dev_console_) {
dev_console_->HandleMouseUp(button, x, y); dev_console_->HandleMouseUp(button, x, y);
} }
if (dev_console_button_pressed_ && button == 1) { if (dev_console_button_pressed_ && button == 1) {
dev_console_button_pressed_ = false;
if (InDevConsoleButton_(x, y)) { if (InDevConsoleButton_(x, y)) {
if (dev_console_) { if (dev_console_) {
dev_console_->ToggleState(); dev_console_->ToggleState();
} }
} }
dev_console_button_pressed_ = false;
} }
if (g_base->HaveUIV1()) { if (g_base->HaveUIV1()) {
@ -386,7 +387,7 @@ void UI::Draw(FrameDef* frame_def) {
void UI::DrawDev(FrameDef* frame_def) { void UI::DrawDev(FrameDef* frame_def) {
// Draw dev console. // Draw dev console.
if (dev_console_) { if (dev_console_) {
dev_console_->Draw(frame_def->overlay_pass()); dev_console_->Draw(frame_def);
} }
// Draw dev console button. // Draw dev console button.
@ -422,14 +423,14 @@ auto UI::InDevConsoleButton_(float x, float y) const -> bool {
void UI::DrawDevConsoleButton_(FrameDef* frame_def) { void UI::DrawDevConsoleButton_(FrameDef* frame_def) {
if (!dev_console_button_txt_.Exists()) { if (!dev_console_button_txt_.Exists()) {
dev_console_button_txt_ = Object::New<TextGroup>(); dev_console_button_txt_ = Object::New<TextGroup>();
dev_console_button_txt_->set_text("dev"); dev_console_button_txt_->SetText("dev");
} }
auto& grp(*dev_console_button_txt_); auto& grp(*dev_console_button_txt_);
float vwidth = g_base->graphics->screen_virtual_width(); float vwidth = g_base->graphics->screen_virtual_width();
float vheight = g_base->graphics->screen_virtual_height(); float vheight = g_base->graphics->screen_virtual_height();
float bsz = DevConsoleButtonSize_(); float bsz = DevConsoleButtonSize_();
SimpleComponent c(frame_def->overlay_pass()); SimpleComponent c(frame_def->overlay_front_pass());
c.SetTransparent(true); c.SetTransparent(true);
c.SetTexture(g_base->assets->SysTexture(SysTextureID::kCircleShadow)); c.SetTexture(g_base->assets->SysTexture(SysTextureID::kCircleShadow));
if (dev_console_button_pressed_) { if (dev_console_button_pressed_) {
@ -439,7 +440,7 @@ void UI::DrawDevConsoleButton_(FrameDef* frame_def) {
} }
{ {
auto xf = c.ScopedTransform(); auto xf = c.ScopedTransform();
c.Translate(vwidth - bsz * 0.5f, vheight * 0.5f, kCursorZDepth - 0.01f); c.Translate(vwidth - bsz * 0.5f, vheight * 0.5f, kDevConsoleZDepth + 0.01f);
c.Scale(bsz, bsz, 1.0f); c.Scale(bsz, bsz, 1.0f);
c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kImage1x1)); c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kImage1x1));
{ {

View File

@ -136,7 +136,7 @@ void ExplosionNode::Draw(base::FrameDef* frame_def) {
float s = 1.0f; float s = 1.0f;
if (high_quality) { if (high_quality) {
base::PostProcessComponent c(frame_def->blit_pass()); base::PostProcessComponent c(frame_def->blit_pass());
c.setNormalDistort(0.5f * amt); c.SetNormalDistort(0.5f * amt);
c.PushTransform(); c.PushTransform();
c.Translate(position_[0], position_[1], position_[2]); c.Translate(position_[0], position_[1], position_[2]);
c.Scale(1.0f + s * 0.8f * 0.025f * age, c.Scale(1.0f + s * 0.8f * 0.025f * age,

View File

@ -268,7 +268,7 @@ void ShieldNode::Draw(base::FrameDef* frame_def) {
} }
if (frame_def->has_depth_texture()) { if (frame_def->has_depth_texture()) {
base::PostProcessComponent c2(frame_def->blit_pass()); base::PostProcessComponent c2(frame_def->blit_pass());
c2.setNormalDistort(distort); c2.SetNormalDistort(distort);
c2.PushTransform(); c2.PushTransform();
c2.MultMatrix((om * m).m); c2.MultMatrix((om * m).m);
c2.Scale(s, s, s); c2.Scale(s, s, s);

View File

@ -4783,7 +4783,7 @@ void SpazNode::Draw(base::FrameDef* frame_def) {
snprintf(buffer, sizeof(buffer), "%d", static_cast<int>(diff)); snprintf(buffer, sizeof(buffer), "%d", static_cast<int>(diff));
if (curse_timer_txt_ != buffer) { if (curse_timer_txt_ != buffer) {
curse_timer_txt_ = buffer; curse_timer_txt_ = buffer;
curse_timer_text_group_.set_text(curse_timer_txt_); curse_timer_text_group_.SetText(curse_timer_txt_);
} }
float r, g, b; float r, g, b;
if (render_frame_count % 6 < 3) { if (render_frame_count % 6 < 3) {
@ -4911,7 +4911,7 @@ void SpazNode::Draw(base::FrameDef* frame_def) {
{ // text { // text
if (counter_mesh_text_ != counter_text_) { if (counter_mesh_text_ != counter_text_) {
counter_mesh_text_ = counter_text_; counter_mesh_text_ = counter_text_;
counter_text_group_.set_text(counter_mesh_text_); counter_text_group_.SetText(counter_mesh_text_);
} }
base::SimpleComponent c(frame_def->overlay_3d_pass()); base::SimpleComponent c(frame_def->overlay_3d_pass());
c.SetTransparent(true); c.SetTransparent(true);
@ -4940,9 +4940,9 @@ void SpazNode::Draw(base::FrameDef* frame_def) {
if (explicit_bool(true)) { if (explicit_bool(true)) {
if (name_mesh_txt_ != name_) { if (name_mesh_txt_ != name_) {
name_mesh_txt_ = name_; name_mesh_txt_ = name_;
name_text_group_.set_text(name_mesh_txt_, name_text_group_.SetText(name_mesh_txt_,
base::TextMesh::HAlign::kCenter, base::TextMesh::HAlign::kCenter,
base::TextMesh::VAlign::kCenter); base::TextMesh::VAlign::kCenter);
} }
base::SimpleComponent c(frame_def->overlay_3d_pass()); base::SimpleComponent c(frame_def->overlay_3d_pass());
c.SetTransparent(true); c.SetTransparent(true);

View File

@ -417,8 +417,8 @@ void TextNode::Draw(base::FrameDef* frame_def) {
break; break;
} }
// update if need be // Update if need be.
text_group_.set_text(text_translated_, h_align, v_align, true, 2.5f); text_group_.SetText(text_translated_, h_align, v_align, true, 2.5f);
text_group_dirty_ = false; text_group_dirty_ = false;
} }
@ -589,7 +589,7 @@ void TextNode::Draw(base::FrameDef* frame_def) {
} }
// Update if need be. // Update if need be.
text_group_.set_text(text_translated_, h_align, v_align); text_group_.SetText(text_translated_, h_align, v_align);
text_group_dirty_ = false; text_group_dirty_ = false;
} }
float z = vr_2d_text float z = vr_2d_text

View File

@ -39,7 +39,7 @@ auto main(int argc, char** argv) -> int {
namespace ballistica { namespace ballistica {
// These are set automatically via script; don't modify them here. // These are set automatically via script; don't modify them here.
const int kEngineBuildNumber = 21337; const int kEngineBuildNumber = 21342;
const char* kEngineVersion = "1.7.28"; const char* kEngineVersion = "1.7.28";
const int kEngineApiVersion = 8; const int kEngineApiVersion = 8;

View File

@ -265,9 +265,9 @@ void RootUI::Draw(base::FrameDef* frame_def) {
party_button_text_group_ = Object::New<base::TextGroup>(); party_button_text_group_ = Object::New<base::TextGroup>();
} }
if (party_button_name != party_button_text_group_->text()) { if (party_button_name != party_button_text_group_->text()) {
party_button_text_group_->set_text( party_button_text_group_->SetText(party_button_name,
party_button_name, base::TextMesh::HAlign::kCenter, base::TextMesh::HAlign::kCenter,
base::TextMesh::VAlign::kTop); base::TextMesh::VAlign::kTop);
} }
int text_elem_count = party_button_text_group_->GetElementCount(); int text_elem_count = party_button_text_group_->GetElementCount();
for (int e = 0; e < text_elem_count; e++) { for (int e = 0; e < text_elem_count; e++) {
@ -301,7 +301,7 @@ void RootUI::Draw(base::FrameDef* frame_def) {
if (!party_size_text_group_.Exists()) { if (!party_size_text_group_.Exists()) {
party_size_text_group_ = Object::New<base::TextGroup>(); party_size_text_group_ = Object::New<base::TextGroup>();
} }
party_size_text_group_->set_text( party_size_text_group_->SetText(
std::to_string(party_size_text_group_num_)); std::to_string(party_size_text_group_num_));
// ..we also may want to update our 'someone joined' message if // ..we also may want to update our 'someone joined' message if
@ -311,12 +311,12 @@ void RootUI::Draw(base::FrameDef* frame_def) {
start_a_game_text_group_ = Object::New<base::TextGroup>(); start_a_game_text_group_ = Object::New<base::TextGroup>();
} }
if (party_size == 2) { // (includes us as host) if (party_size == 2) { // (includes us as host)
start_a_game_text_group_->set_text( start_a_game_text_group_->SetText(
g_base->assets->GetResourceString( g_base->assets->GetResourceString(
"joinedPartyInstructionsText"), "joinedPartyInstructionsText"),
base::TextMesh::HAlign::kRight, base::TextMesh::VAlign::kTop); base::TextMesh::HAlign::kRight, base::TextMesh::VAlign::kTop);
} else if (party_size > 2) { } else if (party_size > 2) {
start_a_game_text_group_->set_text( start_a_game_text_group_->SetText(
std::to_string(party_size - 1) + std::to_string(party_size - 1) +
" friends have joined your party.\nGo to 'Play' to start " " friends have joined your party.\nGo to 'Play' to start "
"a game.", "a game.",

View File

@ -298,7 +298,7 @@ void TextWidget::Draw(base::RenderPass* pass, bool draw_transparent) {
text_group_ = Object::New<base::TextGroup>(); text_group_ = Object::New<base::TextGroup>();
} }
if (text_group_dirty_) { if (text_group_dirty_) {
text_group_->set_text(text_translated_, align_h, align_v, big_, res_scale_); text_group_->SetText(text_translated_, align_h, align_v, big_, res_scale_);
text_width_ = g_base->text_graphics->GetStringWidth(text_translated_, big_); text_width_ = g_base->text_graphics->GetStringWidth(text_translated_, big_);
// FIXME: doesnt support big. // FIXME: doesnt support big.

View File

@ -1,7 +1,7 @@
// Released under the MIT License. See LICENSE for details. // Released under the MIT License. See LICENSE for details.
// An ultra-simple client app to forward commands to a pcommand server. This // An ultra-simple client app to forward commands to a pcommand server. This
// lets us run *lots* of small pcommands very fast. Normally the limiting // lets us run *lots* of small pcommands very fast. Often the limiting
// factor in such cases is the startup time of Python which this mostly // factor in such cases is the startup time of Python which this mostly
// eliminates. See tools/efrotools/pcommandbatch.py for more info. // eliminates. See tools/efrotools/pcommandbatch.py for more info.
@ -380,12 +380,20 @@ int calc_paths_(struct Context_* ctx) {
// might be to have a single 'controller' server instance that spins up // might be to have a single 'controller' server instance that spins up
// worker instances as needed. Though such a fancy setup might be // worker instances as needed. Though such a fancy setup might be
// overkill. // overkill.
ctx->instance_num = rand() % 6; // ctx->instance_num = rand() % 6;
// I was wondering if using pid would lead to a more even distribution, // I was wondering if using pid would lead to a more even distribution,
// but it didn't make a significant difference in my tests. And I worry // but it didn't make a significant difference in my tests. And I worry
// there would be some odd corner case where pid isn't going up evenly, so // there would be some odd corner case where pid isn't going up evenly, so
// sticking with rand() for now. ctx->instance_num = ctx->pid % 6; // sticking with rand() for now. ctx->instance_num = ctx->pid % 6;
// Actually I think this might be a good technique. This should deliver a
// few consecutive requests to a single server instance so it should
// reduce wasted spinup time when just a command or two is run, but it
// should still scale up to use all 6 instances when lots of commands go
// through. (tests show this to be the same speed as the others in that
// latter case).
ctx->instance_num = (ctx->pid / 4) % 6;
return 0; return 0;
} }