mirror of
https://github.com/RYDE-WORK/ballistica.git
synced 2026-01-25 16:33:20 +08:00
dev-console work in progress
This commit is contained in:
parent
7579225a3d
commit
034094d0a3
80
.efrocachemap
generated
80
.efrocachemap
generated
@ -1108,10 +1108,6 @@
|
||||
"build/assets/ba_data/textures/agentIconColorMask.pvr": "075f61aae95df3456dc37dd598e73c93",
|
||||
"build/assets/ba_data/textures/agentIconColorMask_preview.png": "0f93c1b587d4da394a706ea975c02801",
|
||||
"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.ktx": "cfb95bf0ac3f489c2b715613a901d405",
|
||||
"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_preview.png": "47fa53145d34727c863a47830e378c4a",
|
||||
"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.ktx": "a5c386a4977d6d4538c6fc176e69b116",
|
||||
"build/assets/ba_data/textures/aliIcon.pvr": "9d2dad0e469eaec3de216f9cd43a6de3",
|
||||
@ -4064,26 +4056,26 @@
|
||||
"build/assets/windows/Win32/ucrtbased.dll": "2def5335207d41b21b9823f6805997f1",
|
||||
"build/assets/windows/Win32/vc_redist.x86.exe": "b08a55e2e77623fe657bea24f223a3ae",
|
||||
"build/assets/windows/Win32/vcruntime140d.dll": "865b2af4d1e26a1a8073c89acb06e599",
|
||||
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "e8a40affea4d63bc4ca150adfeb973db",
|
||||
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "fb00781c9574d0ca777eb5ced699dc18",
|
||||
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "d53b0c174af88e8a483896fdfd411579",
|
||||
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "bb6fd9371937ebe3f25d253d3046269e",
|
||||
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "f71e0d97424b7bf4b1ad57876ca4f01f",
|
||||
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "6c2ba3735f33f1fd3804bd89a71c75bc",
|
||||
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "cff1c33bb6725fb06020a256ac8e6b16",
|
||||
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "d9d6dbe7c5396a3adb8468fbecbf2b8c",
|
||||
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "2dcddcc4a939a290fd8974d575fa3761",
|
||||
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "cd7f47495207a86d2f72ea0749b69db8",
|
||||
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "e223f88277dafee40cd0e631ee4fa02d",
|
||||
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "1b8a5eac67370bed2a29f81525fbc6eb",
|
||||
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "91debaa22c5ce91586cfdad646a72afe",
|
||||
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "84c8c568e4daeef372806cdc96f4ed48",
|
||||
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "ebf0e8e22d53790b85ceb9f5c507db35",
|
||||
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "ba136eb04e177e264d459443bcde879f",
|
||||
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "fdc1b63de28ebd369b78b2bbeb3c6290",
|
||||
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "126e2eec53a5f7a00d95039ad506b9b4",
|
||||
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "7db3922abdbf3045ef814f235d514cdb",
|
||||
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "b5a1ff440599ccf09bd543d64a1d7aba",
|
||||
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "e7171e1db64d2c0fdebbaeb45d99422e",
|
||||
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "4f6ed2673aa7716c211c94baeb611da3",
|
||||
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "629d63c3627b863e817a98b891b38325",
|
||||
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "b6315ff0d68b436500e48de435b69c77",
|
||||
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "aa98cf408c857767bcbb41ce2b63ce76",
|
||||
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "fa56d6e2beb16a44eff88dd9ca3e0b3e",
|
||||
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "3f026a96404b41c4369bd40694eae4de",
|
||||
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "9713455275e8d7b6bc98fa85fbc1e3ee",
|
||||
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "051d1a2636fe1b5dadb1f9806b9040a3",
|
||||
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "ff117aec63d1413c9f48bac4fd20c9a5",
|
||||
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "0502bb185cf85e224628b3be5e18750a",
|
||||
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "8999ff0a5601c423e2fa10b59425bfa2",
|
||||
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "f2d0d08db00ee44a5c98023ea8521bcc",
|
||||
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "35e1d1017b406d9ed31b2b901a1d0dbe",
|
||||
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "6346c88ec18632ac3ad63beae6122569",
|
||||
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "a08613797c5064a0b2302b9468dc88e9",
|
||||
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "f3d4f9dc7162d7f736c32f8a8ead5477",
|
||||
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "dbddd278a058fb61b8ca5301a3ae4a09",
|
||||
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "aca30445a8fc28b69a2bce57bd651dc3",
|
||||
"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/release/libballisticaplus.a": "80db3e75458db18efe1657f8ce686996",
|
||||
"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_server/debug/libballisticaplus.a": "a29bc1b96b2422dce9154ef8a404a8e6",
|
||||
"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/release/libballisticaplus.a": "1b24bf754c66d424be3f3809b2523c61",
|
||||
"build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "8f3b213feb6207ab470a7318de8e5cc9",
|
||||
"build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "1b24bf754c66d424be3f3809b2523c61",
|
||||
"build/prefab/lib/mac_x86_64_gui/debug/libballisticaplus.a": "93ff05ad705918cf0c47e5946021a2e5",
|
||||
"build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "61ee5217ce8cfc2d471ffc5d1d8d4ad8",
|
||||
"build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "d57603910e6c8d153b05a5515ec99ab2",
|
||||
"build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "61ee5217ce8cfc2d471ffc5d1d8d4ad8",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "2312b4a091f482d64c22f71ca971efe8",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "0d5cb925a29f8185d615d6b954674c6b",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "eb53d93675b81c631d43f2283b59a9ae",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "f15e465066504b1bfadc6fef97bfa6d4",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "bad42242aa1c98b5e6c7318da8b0fa01",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "55366eb80cbd1b22c2636d29b780b6f6",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "c6870a6302ae49bac39f53b390797d8f",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "29ff7769db971f92b49917c3d61de3ec",
|
||||
"build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "d1e2aef8e1ba4fac62908efd3b8079c4",
|
||||
"build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "4dd471e8559a31c1425cd344646261b5",
|
||||
"build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "d1e2aef8e1ba4fac62908efd3b8079c4",
|
||||
"build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "4dd471e8559a31c1425cd344646261b5",
|
||||
"build/prefab/lib/mac_x86_64_gui/debug/libballisticaplus.a": "0bff76811b9640d20c7104b8dabf27e8",
|
||||
"build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "b6e72c87d43dbf2a93e9a0b74952677b",
|
||||
"build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "3c8593e81564012a7638a20c0dc0267b",
|
||||
"build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "b6e72c87d43dbf2a93e9a0b74952677b",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "a6b742a577b1a2a5b99ef4acc4949735",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "3019670a3df31b6ed2bbd5d3a847afbb",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "85335e293ae1433afdf40a83e346d379",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "172855f5f89e9bd36efe7bacad3d5fc9",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "6fa16da3c74bc305a550697b7b453b21",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "dc2d4d3655e8cd65d83e355e731441a8",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "24a6884294c6c6da095e24f0dfa0faf4",
|
||||
"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/enums.py": "f8cd3af311ac63147882590123b78318",
|
||||
"src/ballistica/base/mgen/pyembed/binding_base.inc": "c81b2b1f3a14b4cd20a7b93416fe893a",
|
||||
|
||||
@ -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
|
||||
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
|
||||
least simple things possible without an internet connection for most Android
|
||||
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
|
||||
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`.
|
||||
|
||||
@ -1129,10 +1129,6 @@
|
||||
"ba_data/textures/agentIconColorMask.pvr",
|
||||
"ba_data/textures/agentIconColorMask_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.ktx",
|
||||
"ba_data/textures/aliColor.pvr",
|
||||
@ -1141,10 +1137,6 @@
|
||||
"ba_data/textures/aliColorMask.pvr",
|
||||
"ba_data/textures/aliColorMask_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.ktx",
|
||||
"ba_data/textures/aliIcon.pvr",
|
||||
|
||||
@ -5624,10 +5624,8 @@ TEX2D_DDS_TARGETS = \
|
||||
$(BUILD_DIR)/ba_data/textures/agentColorMask.dds \
|
||||
$(BUILD_DIR)/ba_data/textures/agentIcon.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/aliColorMask.dds \
|
||||
$(BUILD_DIR)/ba_data/textures/aliControllerQR.dds \
|
||||
$(BUILD_DIR)/ba_data/textures/aliIcon.dds \
|
||||
$(BUILD_DIR)/ba_data/textures/aliIconColorMask.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/agentIcon.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/aliColorMask.pvr \
|
||||
$(BUILD_DIR)/ba_data/textures/aliControllerQR.pvr \
|
||||
$(BUILD_DIR)/ba_data/textures/aliIcon.pvr \
|
||||
$(BUILD_DIR)/ba_data/textures/aliIconColorMask.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/agentIcon.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/aliColorMask.ktx \
|
||||
$(BUILD_DIR)/ba_data/textures/aliControllerQR.ktx \
|
||||
$(BUILD_DIR)/ba_data/textures/aliIcon.ktx \
|
||||
$(BUILD_DIR)/ba_data/textures/aliIconColorMask.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/agentIconColorMask_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/aliColor_preview.png \
|
||||
$(BUILD_DIR)/ba_data/textures/aliControllerQR_preview.png \
|
||||
$(BUILD_DIR)/ba_data/textures/aliIconColorMask_preview.png \
|
||||
$(BUILD_DIR)/ba_data/textures/aliIcon_preview.png \
|
||||
$(BUILD_DIR)/ba_data/textures/aliSplash_preview.png \
|
||||
|
||||
@ -52,7 +52,7 @@ if TYPE_CHECKING:
|
||||
|
||||
# Build number and version of the ballistica binary we expect to be
|
||||
# using.
|
||||
TARGET_BALLISTICA_BUILD = 21337
|
||||
TARGET_BALLISTICA_BUILD = 21342
|
||||
TARGET_BALLISTICA_VERSION = '1.7.28'
|
||||
|
||||
|
||||
|
||||
@ -196,210 +196,158 @@ class HelpWindow(bui.Window):
|
||||
texture=logo_tex,
|
||||
)
|
||||
|
||||
force_test = False
|
||||
app = bui.app
|
||||
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:
|
||||
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',
|
||||
resource=self._r + '.devicesInfoText',
|
||||
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:
|
||||
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,
|
||||
)
|
||||
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
|
||||
|
||||
|
||||
@ -37,7 +37,7 @@ void AppModeEmpty::DrawWorld(base::FrameDef* frame_def) {
|
||||
// Draw some lovely spinning text.
|
||||
if (!hello_text_group_.Exists()) {
|
||||
hello_text_group_ = Object::New<TextGroup>();
|
||||
hello_text_group_->set_text("Potato!");
|
||||
hello_text_group_->SetText("Potato!");
|
||||
}
|
||||
auto& grp(*hello_text_group_);
|
||||
auto* pass = frame_def->overlay_pass();
|
||||
|
||||
@ -11,7 +11,7 @@ class PostProcessComponent : public RenderComponent {
|
||||
public:
|
||||
explicit PostProcessComponent(RenderPass* pass)
|
||||
: RenderComponent(pass), normal_distort_(0.0f), eyes_(false) {}
|
||||
void setNormalDistort(float d) {
|
||||
void SetNormalDistort(float d) {
|
||||
EnsureConfiguring();
|
||||
normal_distort_ = d;
|
||||
}
|
||||
|
||||
@ -162,12 +162,12 @@ class RenderComponent {
|
||||
}
|
||||
void Submit() {
|
||||
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 BA_DEBUG_BUILD
|
||||
assert(pass_->frame_def()->defining_component());
|
||||
pass_->frame_def()->set_defining_component(false);
|
||||
#endif // BA_DEBUG_BUILD
|
||||
#endif
|
||||
}
|
||||
state_ = State::kSubmitted;
|
||||
}
|
||||
|
||||
@ -357,7 +357,8 @@ class Graphics::ScreenMessageEntry {
|
||||
};
|
||||
|
||||
// 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());
|
||||
|
||||
// Every now and then, update our stats.
|
||||
@ -382,7 +383,7 @@ void Graphics::DrawMiscOverlays(RenderPass* pass) {
|
||||
if (!fps_text_group_.Exists()) {
|
||||
fps_text_group_ = Object::New<TextGroup>();
|
||||
}
|
||||
fps_text_group_->set_text(fps_string_);
|
||||
fps_text_group_->SetText(fps_string_);
|
||||
}
|
||||
SimpleComponent c(pass);
|
||||
c.SetTransparent(true);
|
||||
@ -415,7 +416,7 @@ void Graphics::DrawMiscOverlays(RenderPass* pass) {
|
||||
if (!ping_text_group_.Exists()) {
|
||||
ping_text_group_ = Object::New<TextGroup>();
|
||||
}
|
||||
ping_text_group_->set_text(ping_string_);
|
||||
ping_text_group_->SetText(ping_string_);
|
||||
}
|
||||
SimpleComponent c(pass);
|
||||
c.SetTransparent(true);
|
||||
@ -431,12 +432,13 @@ void Graphics::DrawMiscOverlays(RenderPass* pass) {
|
||||
for (int e = 0; e < text_elem_count; e++) {
|
||||
c.SetTexture(ping_text_group_->GetElementTexture(e));
|
||||
c.SetFlatness(1.0f);
|
||||
c.PushTransform();
|
||||
c.Translate(14.0f + (show_fps_ ? 30.0f : 0.0f), 0.1f,
|
||||
kScreenMessageZDepth);
|
||||
c.Scale(0.7f, 0.7f);
|
||||
c.DrawMesh(ping_text_group_->GetElementMesh(e));
|
||||
c.PopTransform();
|
||||
{
|
||||
auto xf = c.ScopedTransform();
|
||||
c.Translate(14.0f + (show_fps_ ? 30.0f : 0.0f), 0.1f,
|
||||
kScreenMessageZDepth);
|
||||
c.Scale(0.7f, 0.7f);
|
||||
c.DrawMesh(ping_text_group_->GetElementMesh(e));
|
||||
}
|
||||
}
|
||||
c.Submit();
|
||||
}
|
||||
@ -450,7 +452,7 @@ void Graphics::DrawMiscOverlays(RenderPass* pass) {
|
||||
if (!net_info_text_group_.Exists()) {
|
||||
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);
|
||||
c.SetTransparent(true);
|
||||
@ -459,11 +461,12 @@ void Graphics::DrawMiscOverlays(RenderPass* pass) {
|
||||
for (int e = 0; e < text_elem_count; e++) {
|
||||
c.SetTexture(net_info_text_group_->GetElementTexture(e));
|
||||
c.SetFlatness(1.0f);
|
||||
c.PushTransform();
|
||||
c.Translate(4.0f, (show_fps_ ? 66.0f : 40.0f), kScreenMessageZDepth);
|
||||
c.Scale(0.7f, 0.7f);
|
||||
c.DrawMesh(net_info_text_group_->GetElementMesh(e));
|
||||
c.PopTransform();
|
||||
{
|
||||
auto xf = c.ScopedTransform();
|
||||
c.Translate(4.0f, (show_fps_ ? 66.0f : 40.0f), kScreenMessageZDepth);
|
||||
c.Scale(0.7f, 0.7f);
|
||||
c.DrawMesh(net_info_text_group_->GetElementMesh(e));
|
||||
}
|
||||
}
|
||||
c.Submit();
|
||||
}
|
||||
@ -603,33 +606,35 @@ void Graphics::DrawMiscOverlays(RenderPass* pass) {
|
||||
}
|
||||
c.SetColor(r * fade, g * fade, b * fade, a);
|
||||
|
||||
c.PushTransform();
|
||||
if (i->v_smoothed == 0.0f) {
|
||||
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);
|
||||
{
|
||||
auto xf = c.ScopedTransform();
|
||||
|
||||
// Align our bottom with where we just scaled from.
|
||||
c.Translate(0, 0.5f, 0);
|
||||
} else {
|
||||
c.Scale((str_width + 110) * scale * s_extra,
|
||||
(str_height + 40) * scale * s_extra);
|
||||
if (i->v_smoothed == 0.0f) {
|
||||
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.
|
||||
c.Translate(0, 0.5f, 0);
|
||||
// Align our bottom with where we just scaled from.
|
||||
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);
|
||||
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.SetFlatness(i->GetText().GetElementMaxFlatness(e));
|
||||
c.PushTransform();
|
||||
c.Translate(screen_width * 0.5f, i->v_smoothed,
|
||||
vr ? 150 : kScreenMessageZDepth);
|
||||
c.Scale(scale * s_extra, scale * s_extra);
|
||||
c.Translate(0, 20);
|
||||
c.DrawMesh(i->GetText().GetElementMesh(e));
|
||||
c.PopTransform();
|
||||
{
|
||||
auto xf = c.ScopedTransform();
|
||||
c.Translate(screen_width * 0.5f, i->v_smoothed,
|
||||
vr ? 150 : kScreenMessageZDepth);
|
||||
c.Scale(scale * s_extra, scale * s_extra);
|
||||
c.Translate(0, 20);
|
||||
c.DrawMesh(i->GetText().GetElementMesh(e));
|
||||
}
|
||||
}
|
||||
|
||||
v += scale * (36 + str_height);
|
||||
@ -798,12 +804,13 @@ void Graphics::DrawMiscOverlays(RenderPass* pass) {
|
||||
g_base->assets->SysTexture(SysTextureID::kCharacterIconMask));
|
||||
}
|
||||
c2.SetColor(1, 1, 1, a);
|
||||
c2.PushTransform();
|
||||
c2.Translate(h - 14, v_base + 10 + i->v_smoothed,
|
||||
kScreenMessageZDepth);
|
||||
c2.Scale(22.0f * s_extra, 22.0f * s_extra);
|
||||
c2.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kImage1x1));
|
||||
c2.PopTransform();
|
||||
{
|
||||
auto xf = c2.ScopedTransform();
|
||||
c2.Translate(h - 14, v_base + 10 + i->v_smoothed,
|
||||
kScreenMessageZDepth);
|
||||
c2.Scale(22.0f * s_extra, 22.0f * s_extra);
|
||||
c2.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kImage1x1));
|
||||
}
|
||||
c2.Submit();
|
||||
}
|
||||
|
||||
@ -830,11 +837,12 @@ void Graphics::DrawMiscOverlays(RenderPass* pass) {
|
||||
1.0f * a);
|
||||
c.SetFlatness(i->GetText().GetElementMaxFlatness(e));
|
||||
c.SetMaskUV2Texture(i->GetText().GetElementMaskUV2Texture(e));
|
||||
c.PushTransform();
|
||||
c.Translate(h, v_base + 2 + i->v_smoothed, kScreenMessageZDepth);
|
||||
c.Scale(0.6f * s_extra, 0.6f * s_extra);
|
||||
c.DrawMesh(i->GetText().GetElementMesh(e));
|
||||
c.PopTransform();
|
||||
{
|
||||
auto xf = c.ScopedTransform();
|
||||
c.Translate(h, v_base + 2 + i->v_smoothed, kScreenMessageZDepth);
|
||||
c.Scale(0.6f * s_extra, 0.6f * s_extra);
|
||||
c.DrawMesh(i->GetText().GetElementMesh(e));
|
||||
}
|
||||
}
|
||||
assert(!i->translation_dirty);
|
||||
v -= g_base->text_graphics->GetStringHeight(i->s_translated.c_str())
|
||||
@ -1171,12 +1179,12 @@ void Graphics::BuildAndPushFrameDef() {
|
||||
g_base->input->Draw(frame_def);
|
||||
|
||||
RenderPass* overlay_pass = frame_def->overlay_pass();
|
||||
DrawMiscOverlays(overlay_pass);
|
||||
DrawMiscOverlays(frame_def);
|
||||
|
||||
// Let UI draw dev console and whatever else.
|
||||
DrawDevUI(frame_def);
|
||||
|
||||
DrawCursor(overlay_pass, app_time_millisecs);
|
||||
DrawCursor(frame_def);
|
||||
|
||||
// Draw our light/shadow images to the screen if desired.
|
||||
DrawDebugBuffers(overlay_pass);
|
||||
@ -1224,7 +1232,7 @@ void Graphics::BuildAndPushFrameDef() {
|
||||
frame_def->set_mesh_data_destroys(mesh_data_destroys_);
|
||||
mesh_data_destroys_.clear();
|
||||
|
||||
g_base->graphics_server->SetFrameDef(frame_def);
|
||||
g_base->graphics_server->EnqueueFrameDef(frame_def);
|
||||
|
||||
// Clean up frame_defs awaiting deletion.
|
||||
ClearFrameDefDeleteList();
|
||||
@ -1249,13 +1257,14 @@ void Graphics::DrawBoxingGlovesTest(FrameDef* frame_def) {
|
||||
// Blit.
|
||||
if (explicit_bool(true)) {
|
||||
PostProcessComponent c(frame_def->blit_pass());
|
||||
c.setNormalDistort(0.07f);
|
||||
c.PushTransform();
|
||||
c.Translate(0, 7, -3.3f);
|
||||
c.Scale(10, 10, 10);
|
||||
c.Rotate(a, 0, 0, 1);
|
||||
c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kBoxingGlove));
|
||||
c.PopTransform();
|
||||
c.SetNormalDistort(0.07f);
|
||||
{
|
||||
auto xf = c.ScopedTransform();
|
||||
c.Translate(0, 7, -3.3f);
|
||||
c.Scale(10, 10, 10);
|
||||
c.Rotate(a, 0, 0, 1);
|
||||
c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kBoxingGlove));
|
||||
}
|
||||
c.Submit();
|
||||
}
|
||||
|
||||
@ -1265,12 +1274,13 @@ void Graphics::DrawBoxingGlovesTest(FrameDef* frame_def) {
|
||||
c.SetTexture(g_base->assets->SysTexture(SysTextureID::kBoxingGlove));
|
||||
c.SetReflection(ReflectionType::kSoft);
|
||||
c.SetReflectionScale(0.4f, 0.4f, 0.4f);
|
||||
c.PushTransform();
|
||||
c.Translate(0.0f, 3.7f, -3.3f);
|
||||
c.Scale(10.0f, 10.0f, 10.0f);
|
||||
c.Rotate(a, 0.0f, 0.0f, 1.0f);
|
||||
c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kBoxingGlove));
|
||||
c.PopTransform();
|
||||
{
|
||||
auto xf = c.ScopedTransform();
|
||||
c.Translate(0.0f, 3.7f, -3.3f);
|
||||
c.Scale(10.0f, 10.0f, 10.0f);
|
||||
c.Rotate(a, 0.0f, 0.0f, 1.0f);
|
||||
c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kBoxingGlove));
|
||||
}
|
||||
c.Submit();
|
||||
}
|
||||
|
||||
@ -1279,12 +1289,13 @@ void Graphics::DrawBoxingGlovesTest(FrameDef* frame_def) {
|
||||
SimpleComponent c(frame_def->light_shadow_pass());
|
||||
c.SetColor(0.16f, 0.11f, 0.1f, 1.0f);
|
||||
c.SetTransparent(true);
|
||||
c.PushTransform();
|
||||
c.Translate(0.0f, 3.7f, -3.3f);
|
||||
c.Scale(10.0f, 10.0f, 10.0f);
|
||||
c.Rotate(a, 0.0f, 0.0f, 1.0f);
|
||||
c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kBoxingGlove));
|
||||
c.PopTransform();
|
||||
{
|
||||
auto xf = c.ScopedTransform();
|
||||
c.Translate(0.0f, 3.7f, -3.3f);
|
||||
c.Scale(10.0f, 10.0f, 10.0f);
|
||||
c.Rotate(a, 0.0f, 0.0f, 1.0f);
|
||||
c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kBoxingGlove));
|
||||
}
|
||||
c.Submit();
|
||||
}
|
||||
}
|
||||
@ -1295,21 +1306,23 @@ void Graphics::DrawDebugBuffers(RenderPass* pass) {
|
||||
{
|
||||
SpecialComponent c(pass, SpecialComponent::Source::kLightBuffer);
|
||||
float csize = 100;
|
||||
c.PushTransform();
|
||||
c.Translate(70, 400, kDebugImgZDepth);
|
||||
c.Scale(csize, csize);
|
||||
c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kImage1x1));
|
||||
c.PopTransform();
|
||||
{
|
||||
auto xf = c.ScopedTransform();
|
||||
c.Translate(70, 400, kDebugImgZDepth);
|
||||
c.Scale(csize, csize);
|
||||
c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kImage1x1));
|
||||
}
|
||||
c.Submit();
|
||||
}
|
||||
{
|
||||
SpecialComponent c(pass, SpecialComponent::Source::kLightShadowBuffer);
|
||||
float csize = 100;
|
||||
c.PushTransform();
|
||||
c.Translate(70, 250, kDebugImgZDepth);
|
||||
c.Scale(csize, csize);
|
||||
c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kImage1x1));
|
||||
c.PopTransform();
|
||||
{
|
||||
auto xf = c.ScopedTransform();
|
||||
c.Translate(70, 250, kDebugImgZDepth);
|
||||
c.Scale(csize, csize);
|
||||
c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kImage1x1));
|
||||
}
|
||||
c.Submit();
|
||||
}
|
||||
}
|
||||
@ -1364,7 +1377,9 @@ void Graphics::DrawFades(FrameDef* frame_def, millisecs_t real_time) {
|
||||
fade_ = 1.0f
|
||||
- (static_cast<float>(real_time - fade_start_)
|
||||
/ static_cast<float>(fade_time_));
|
||||
if (fade_ <= 0) fade_ = 0.00001f;
|
||||
if (fade_ <= 0) {
|
||||
fade_ = 0.00001f;
|
||||
}
|
||||
} else {
|
||||
fade_ = 0;
|
||||
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))
|
||||
* (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.
|
||||
//
|
||||
// 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();
|
||||
}
|
||||
DoDrawFade(frame_def, a);
|
||||
|
||||
// If we're doing a progress-bar fade, throw in the fading progress bar.
|
||||
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());
|
||||
|
||||
millisecs_t real_time = frame_def->real_time();
|
||||
|
||||
bool can_show_cursor = g_core->platform->IsRunningOnDesktop();
|
||||
bool should_show_cursor =
|
||||
camera_->manual() || g_base->input->IsCursorVisible();
|
||||
@ -1481,20 +1460,21 @@ void Graphics::DrawCursor(RenderPass* pass, millisecs_t real_time) {
|
||||
} else {
|
||||
// Draw software cursor.
|
||||
if (can_show_cursor && should_show_cursor) {
|
||||
SimpleComponent c(pass);
|
||||
SimpleComponent c(frame_def->overlay_front_pass());
|
||||
c.SetTransparent(true);
|
||||
float csize = 50.0f;
|
||||
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
|
||||
// renderer to insert the latest values on its end; this lessens cursor
|
||||
// lag substantially.
|
||||
c.CursorTranslate();
|
||||
c.Translate(csize * 0.44f, csize * -0.44f, kCursorZDepth);
|
||||
c.Scale(csize, csize);
|
||||
c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kImage1x1));
|
||||
c.PopTransform();
|
||||
// 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
|
||||
// lag substantially.
|
||||
c.CursorTranslate();
|
||||
c.Translate(csize * 0.44f, csize * -0.44f, kCursorZDepth);
|
||||
c.Scale(csize, csize);
|
||||
c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kImage1x1));
|
||||
}
|
||||
c.Submit();
|
||||
}
|
||||
}
|
||||
@ -1898,7 +1878,7 @@ auto Graphics::ScreenMessageEntry::GetText() -> TextGroup& {
|
||||
mesh_dirty = true;
|
||||
}
|
||||
if (mesh_dirty) {
|
||||
s_mesh_->set_text(
|
||||
s_mesh_->SetText(
|
||||
s_translated,
|
||||
align_left ? TextMesh::HAlign::kLeft : TextMesh::HAlign::kCenter,
|
||||
TextMesh::VAlign::kBottom);
|
||||
|
||||
@ -44,7 +44,8 @@ const float kBackingDepth1{0.0f};
|
||||
|
||||
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).
|
||||
class Graphics {
|
||||
@ -317,11 +318,14 @@ class Graphics {
|
||||
camera_gyro_explicitly_disabled_ = disabled;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void DoDrawFade(FrameDef* frame_def, float amt);
|
||||
|
||||
private:
|
||||
class ScreenMessageEntry;
|
||||
void DrawBoxingGlovesTest(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 DrawDebugBuffers(RenderPass* pass);
|
||||
|
||||
@ -331,7 +335,7 @@ class Graphics {
|
||||
float size, float r, float g, float b, float a);
|
||||
auto GetEmptyFrameDef() -> FrameDef*;
|
||||
void InitInternalComponents(FrameDef* frame_def);
|
||||
void DrawMiscOverlays(RenderPass* pass);
|
||||
void DrawMiscOverlays(FrameDef* frame_def);
|
||||
void DrawLoadDot(RenderPass* pass);
|
||||
void ClearFrameDefDeleteList();
|
||||
void DrawProgressBar(RenderPass* pass, float opacity);
|
||||
|
||||
@ -47,13 +47,12 @@ void GraphicsServer::OnMainThreadStartApp() {
|
||||
}
|
||||
}
|
||||
|
||||
void GraphicsServer::SetFrameDef(FrameDef* framedef) {
|
||||
// Note: we're just setting the framedef directly here
|
||||
// even though this gets called from the logic thread.
|
||||
// Ideally it would seem we should push these to our thread
|
||||
// event list, but currently we spin-lock waiting for new
|
||||
// frames to appear which would prevent that from working;
|
||||
// we would need to change that code.
|
||||
void GraphicsServer::EnqueueFrameDef(FrameDef* framedef) {
|
||||
// Note: we're just setting the framedef directly here even though this
|
||||
// gets called from the logic thread. Ideally it would seem we should push
|
||||
// these to our thread event list, but currently we may spin-lock waiting
|
||||
// for new frames to appear which would prevent that from working; we
|
||||
// would need to change that code.
|
||||
{
|
||||
std::scoped_lock llock(frame_def_mutex_);
|
||||
assert(frame_def_ == nullptr);
|
||||
@ -69,8 +68,8 @@ auto GraphicsServer::GetRenderFrameDef() -> FrameDef* {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// If the app says it's minimized, don't do anything.
|
||||
// (on iOS we'll get shut down if we make GL calls in this state, etc)
|
||||
// If the app says it's minimized, don't do anything (on iOS we'll get
|
||||
// shut down if we make GL calls in this state, etc).
|
||||
if (g_base->app_adapter->app_paused()) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -78,9 +77,7 @@ auto GraphicsServer::GetRenderFrameDef() -> FrameDef* {
|
||||
// Do some incremental loading every time we try to render.
|
||||
g_base->assets->RunPendingGraphicsLoads();
|
||||
|
||||
// Spin and wait for a short bit for a frame_def to appear. If it does, we
|
||||
// grab it, render it, and also message the logic thread to start generating
|
||||
// another one.
|
||||
// Spin and wait for a short bit for a frame_def to appear.
|
||||
while (true) {
|
||||
FrameDef* frame_def{};
|
||||
{
|
||||
@ -92,8 +89,8 @@ auto GraphicsServer::GetRenderFrameDef() -> FrameDef* {
|
||||
}
|
||||
if (frame_def) {
|
||||
// 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
|
||||
// pipelined.
|
||||
// thread to start working on the next one for us. Keeps things nice
|
||||
// and pipelined.
|
||||
g_base->logic->event_loop()->PushCall([] { g_base->logic->Draw(); });
|
||||
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
|
||||
// eye or in mono.
|
||||
// Does the default drawing to the screen, either from the left or right
|
||||
// stereo eye or in mono.
|
||||
void GraphicsServer::DrawRenderFrameDef(FrameDef* frame_def, int eye) {
|
||||
assert(renderer_);
|
||||
if (renderer_) {
|
||||
@ -175,15 +172,12 @@ void GraphicsServer::TryRender() {
|
||||
assert(g_base->InGraphicsThread());
|
||||
|
||||
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);
|
||||
|
||||
// Note: we always run mesh updates contained in the framedef
|
||||
// even if we don't actually render it.
|
||||
// (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.
|
||||
// Note: we run mesh-updates on each frame-def that comes through even
|
||||
// if we don't actually render the frame.
|
||||
RunFrameDefMeshUpdates(frame_def);
|
||||
|
||||
// Only actually render if we have a screen and aren't in a hold.
|
||||
|
||||
@ -15,18 +15,17 @@
|
||||
|
||||
namespace ballistica::base {
|
||||
|
||||
// Runs in the main thread and renders frame_defs shipped to it by the
|
||||
// Graphics
|
||||
/// A server that runs in the graphics thread and renders frame_defs shipped
|
||||
/// to it by the logic thread.
|
||||
class GraphicsServer {
|
||||
public:
|
||||
GraphicsServer();
|
||||
|
||||
void OnMainThreadStartApp();
|
||||
|
||||
/// Should be called to inform ballistica of screen size changes; this will be
|
||||
/// applied to the server and then sent to the logic thread to apply to
|
||||
/// various
|
||||
// app systems (ui, etc.).
|
||||
/// Should be called to inform ballistica of screen size changes; this
|
||||
/// will be applied to the server and then sent to the logic thread to
|
||||
/// apply to various app systems (ui, etc.).
|
||||
void SetScreenResolution(float h, float v);
|
||||
|
||||
void PushSetScreenGammaCall(float gamma);
|
||||
@ -42,14 +41,14 @@ class GraphicsServer {
|
||||
const std::vector<Object::Ref<Asset>*>& components);
|
||||
void SetRenderHold();
|
||||
|
||||
// Used by the logic thread to pass frame-defs to the graphics server
|
||||
// for rendering.
|
||||
void SetFrameDef(FrameDef* framedef);
|
||||
/// Used by the logic thread to pass frame-defs to the graphics server for
|
||||
/// rendering.
|
||||
void EnqueueFrameDef(FrameDef* framedef);
|
||||
|
||||
// returns the next frame_def needing to be rendered, waiting for it to arrive
|
||||
// if 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
|
||||
// of using the RenderFrameDef* calls
|
||||
// Returns the next frame_def to be rendered, waiting for it to arrive if
|
||||
// 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 of using the RenderFrameDef* calls.
|
||||
auto GetRenderFrameDef() -> FrameDef*;
|
||||
|
||||
void ApplyFrameDefSettings(FrameDef* frame_def);
|
||||
|
||||
@ -37,6 +37,49 @@ static auto ValueTestBool(bool* storage, double* absval, double* deltaval)
|
||||
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,
|
||||
double* deltaval, double* outval) -> bool {
|
||||
if (arg == "vrOverlayScale") {
|
||||
@ -165,15 +208,15 @@ void GraphicsVR::CalcVROverlayMatrices(FrameDef* frame_def) {
|
||||
|
||||
vr_overlay_matrix = CalcVROverlayMatrix(cam_pt, cam_target_pt);
|
||||
|
||||
// We also always calc a completely fixed matrix for some elements that
|
||||
// should *never* move such as score-screens.
|
||||
// We also always calc a completely fixed matrix for some elements
|
||||
// that should *never* move such as score-screens.
|
||||
cam_target_pt.y = fixed_y;
|
||||
cam_target_pt.z = fixed_z;
|
||||
vr_overlay_matrix_fixed = CalcVROverlayMatrix(cam_pt, cam_target_pt);
|
||||
}
|
||||
|
||||
// Calc a screen-matrix that gives us a drawing area of
|
||||
// kBaseVirtualResX by kBaseVirtualResY.
|
||||
// Calc a screen-matrix that gives us a drawing area of kBaseVirtualResX
|
||||
// by kBaseVirtualResY.
|
||||
frame_def->set_vr_overlay_screen_matrix(
|
||||
Matrix44fTranslate(-0.5f * kBaseVirtualResX, -0.5f * kBaseVirtualResY,
|
||||
0.0f)
|
||||
@ -225,9 +268,11 @@ auto GraphicsVR::CalcVROverlayMatrix(const Vector3f& cam_pt,
|
||||
base_scale))
|
||||
* m;
|
||||
}
|
||||
|
||||
void GraphicsVR::DrawVROverlay(FrameDef* frame_def) {
|
||||
// In vr mode we have draw our overlay-flat texture in to space
|
||||
// as part of our regular overlay pass.
|
||||
//
|
||||
// NOTE: this assumes nothing after this point gets drawn into
|
||||
// the overlay-flat pass (otherwise it may get skipped).
|
||||
// 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();
|
||||
}
|
||||
}
|
||||
|
||||
void GraphicsVR::DrawOverlayBounds(RenderPass* pass) {
|
||||
// We can optionally draw a guide to show the edges of the overlay pass
|
||||
if (draw_overlay_bounds_) {
|
||||
|
||||
@ -63,6 +63,9 @@ class GraphicsVR : public Graphics {
|
||||
vr_hands_state_ = state;
|
||||
}
|
||||
|
||||
protected:
|
||||
void DoDrawFade(FrameDef* frame_def, float amt) override;
|
||||
|
||||
private:
|
||||
void CalcVROverlayMatrices(FrameDef* frame_def);
|
||||
auto CalcVROverlayMatrix(const Vector3f& cam_pt,
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
|
||||
namespace ballistica::base {
|
||||
|
||||
// a mesh set up to draw images
|
||||
// A mesh set up to draw images.
|
||||
class ImageMesh : public MeshIndexedSimpleSplit {
|
||||
public:
|
||||
ImageMesh();
|
||||
|
||||
@ -7,10 +7,11 @@
|
||||
|
||||
namespace ballistica::base {
|
||||
|
||||
// Buffers used by the logic thread to pass indices/vertices/etc. to meshes in
|
||||
// the graphics thread. Note that it is safe to create these in other threads;
|
||||
// you just need to turn off thread-checks until you pass ownership to the game
|
||||
// thread. (or just avoid creating references outside of the logic thread)
|
||||
// Buffers used by the logic thread to pass indices/vertices/etc. to meshes
|
||||
// in the graphics thread. Note that it is safe to create these in other
|
||||
// threads; you just need to turn off thread-checks until you pass ownership
|
||||
// to the game thread. (or just avoid creating references outside of the
|
||||
// logic thread).
|
||||
class MeshBufferBase : public Object {
|
||||
public:
|
||||
uint32_t state; // which dynamicState value on the mesh this corresponds to
|
||||
|
||||
@ -8,9 +8,9 @@
|
||||
|
||||
namespace ballistica::base {
|
||||
|
||||
// Client-side (game-thread) handle to server-side (graphics-thread) mesh data.
|
||||
// Server-side data will be created when this object is instantiated and
|
||||
// cleared when this object goes down.
|
||||
// Client-side (logic-thread) handle to server-side (graphics-thread) mesh
|
||||
// data. Server-side data will be created when this object is instantiated
|
||||
// and cleared when this object goes down.
|
||||
class MeshDataClientHandle : public Object {
|
||||
public:
|
||||
explicit MeshDataClientHandle(MeshData* d);
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
|
||||
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
|
||||
: public MeshIndexedStaticDynamic<VertexObjectSplitStatic,
|
||||
VertexObjectSplitDynamic,
|
||||
|
||||
@ -7,8 +7,8 @@
|
||||
|
||||
namespace ballistica::base {
|
||||
|
||||
// mesh with static indices, some static vertex data,
|
||||
// and some dynamic vertex data
|
||||
/// A mesh with static indices, some static vertex data, and some dynamic
|
||||
/// vertex data.
|
||||
template <typename STATICDATA, typename DYNAMICDATA, MeshDataType T>
|
||||
class MeshIndexedStaticDynamic : public MeshIndexedBase {
|
||||
public:
|
||||
|
||||
@ -49,14 +49,14 @@ void RenderPass::Render(RenderTarget* render_target, bool transparent) {
|
||||
switch (type()) {
|
||||
case Type::kBeautyPass: {
|
||||
g_base->graphics_server->SetCamera(cam_pos_, cam_target_, cam_up_);
|
||||
// If this changes, make sure to change
|
||||
// it before _drawCameraBuffer() too.
|
||||
// If this changes, make sure to change it before _drawCameraBuffer()
|
||||
// too.
|
||||
|
||||
// FIXME:
|
||||
// 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
|
||||
// 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);
|
||||
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);
|
||||
} else {
|
||||
g_base->graphics_server->SetCamera(cam_pos_, cam_target_, cam_up_);
|
||||
// We set the same depth ranges as the overlay-3d pass since
|
||||
// we're essentially doing the same thing. See explanation in the
|
||||
// overlay-3d case above the one difference is that we split the
|
||||
// We set the same depth ranges as the overlay-3d pass since we're
|
||||
// essentially doing the same thing. See explanation in the
|
||||
// overlay-3d case above. The one difference is that we split the
|
||||
// range between our fixed overlay and our regular overlay passes
|
||||
// (we want fixed-overlay stuff on bottom).
|
||||
if (renderer->has_camera_render_target()) {
|
||||
@ -175,7 +175,7 @@ void RenderPass::Render(RenderTarget* render_target, bool transparent) {
|
||||
}
|
||||
}
|
||||
} 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();
|
||||
if (type() == Type::kOverlayFrontPass) {
|
||||
renderer->SetDepthRange(kBackingDepth1, kBackingDepth1B);
|
||||
@ -230,8 +230,8 @@ void RenderPass::Render(RenderTarget* render_target, bool transparent) {
|
||||
const Vector3f& soffs = renderer->shadow_offset();
|
||||
|
||||
// Well, this is slightly terrifying; '-soffs' is causing crashes
|
||||
// here but multing by -1.000001f works.
|
||||
// (generally just on android 4.3 on atom processors)
|
||||
// here but multing by -1.000001f works (generally just on Android
|
||||
// 4.3 on atom processors).
|
||||
g_base->graphics_server->Translate(Vector3f(
|
||||
-1.000001f * soffs.x, -1.000001f * soffs.y, -1.000001f * soffs.z));
|
||||
}
|
||||
|
||||
@ -11,23 +11,46 @@
|
||||
|
||||
namespace ballistica::base {
|
||||
|
||||
// A drawing context for one pass. This can be a render to the screen, a shadow
|
||||
// pass, a window, etc.
|
||||
// A drawing context for one pass. This can be a render to the screen, a
|
||||
// shadow pass, a window, etc.
|
||||
class RenderPass {
|
||||
public:
|
||||
enum class ReflectionSubPass { kRegular, kMirrored };
|
||||
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,
|
||||
// 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,
|
||||
// The pass where normal foreground scene geometry is drawn into.
|
||||
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,
|
||||
// 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,
|
||||
// Standard 2d overlay stuff. May be drawn in 2d or on a plane in 3d
|
||||
// space (in vr). In VR, each of these elements are drawn individually
|
||||
// and can thus have their own depth. also in VR this overlay repositions
|
||||
// itself per level; use kOverlayFixedPass for items that shouldn't.
|
||||
// this overlay may be obscured by UI. Use OVERLAY_FRONT_PASS if you need
|
||||
// things to show up in front of UI.
|
||||
// Standard 2d overlay stuff such as UI. May be drawn in 2d or on a
|
||||
// plane in 3d space (in vr). In VR, each of these elements are drawn
|
||||
// individually and can thus have their own depth. also in VR, this
|
||||
// overlay may be repositions based on the camera/map/etc; use
|
||||
// kOverlayFixedPass for items that shouldn't do this (for example,
|
||||
// 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,
|
||||
// Just like kOverlayPass but guaranteed to draw in front of UI.
|
||||
kOverlayFrontPass,
|
||||
@ -40,7 +63,9 @@ class RenderPass {
|
||||
/// Only used in VR - stuff that needs to cover absolutely everything
|
||||
/// else (like the 3d wipe fade).
|
||||
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
|
||||
};
|
||||
|
||||
@ -49,7 +74,7 @@ class RenderPass {
|
||||
|
||||
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_height() const -> float { return physical_height_; }
|
||||
|
||||
|
||||
@ -152,8 +152,8 @@ void NetGraph::Draw(RenderPass* pass, double time, double x, double y, double w,
|
||||
snprintf(val_str, sizeof(val_str), "%.3f",
|
||||
impl_->smoothed ? impl_->v_smoothed : val);
|
||||
}
|
||||
impl_->max_vel_text.set_text(val_str, TextMesh::HAlign::kLeft,
|
||||
TextMesh::VAlign::kTop);
|
||||
impl_->max_vel_text.SetText(val_str, TextMesh::HAlign::kLeft,
|
||||
TextMesh::VAlign::kTop);
|
||||
|
||||
SimpleComponent c2(pass);
|
||||
c2.SetTransparent(true);
|
||||
|
||||
@ -8,9 +8,9 @@
|
||||
|
||||
namespace ballistica::base {
|
||||
|
||||
void TextGroup::set_text(const std::string& text, TextMesh::HAlign alignment_h,
|
||||
TextMesh::VAlign alignment_v, bool big,
|
||||
float resolution_scale) {
|
||||
void TextGroup::SetText(const std::string& text, TextMesh::HAlign alignment_h,
|
||||
TextMesh::VAlign alignment_v, bool big,
|
||||
float resolution_scale) {
|
||||
text_ = text;
|
||||
|
||||
// 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));
|
||||
|
||||
// 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
|
||||
// the same one if we havn't changed)
|
||||
// It should stick around for a while; we'll be able to re-grab
|
||||
// the same one if we havn't changed.
|
||||
os_texture_.Clear();
|
||||
|
||||
// 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
|
||||
// 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
|
||||
// we'll need. we then hand that over to the OS to draw and create
|
||||
|
||||
@ -14,9 +14,9 @@
|
||||
|
||||
namespace ballistica::base {
|
||||
|
||||
// encapsulates the multiple meshes and textures necessary to
|
||||
// draw arbitrary text. To actually draw the text, iterate over the meshes
|
||||
// and textures this class provides to you, drawing each in the same manner
|
||||
// Encapsulates the multiple meshes and textures necessary to draw arbitrary
|
||||
// text. To actually draw the text, iterate over the meshes and textures
|
||||
// this class provides to you, drawing each in the same manner.
|
||||
class TextGroup : public Object {
|
||||
public:
|
||||
// the number of meshes needing to be drawn for this text
|
||||
@ -55,10 +55,10 @@ class TextGroup : public Object {
|
||||
? SysTextureID::kSoftRect2
|
||||
: SysTextureID::kSoftRect);
|
||||
}
|
||||
void set_text(const std::string& text,
|
||||
TextMesh::HAlign alignment_h = TextMesh::HAlign::kLeft,
|
||||
TextMesh::VAlign alignment_v = TextMesh::VAlign::kNone,
|
||||
bool big = false, float resolution_scale = 1.0f);
|
||||
void SetText(const std::string& text,
|
||||
TextMesh::HAlign alignment_h = TextMesh::HAlign::kLeft,
|
||||
TextMesh::VAlign alignment_v = TextMesh::VAlign::kNone,
|
||||
bool big = false, float resolution_scale = 1.0f);
|
||||
auto text() const -> const std::string& { return text_; }
|
||||
void GetCaratPts(const std::string& text_in, TextMesh::HAlign alignment_h,
|
||||
TextMesh::VAlign alignment_v, int carat_pos, float* carat_x,
|
||||
|
||||
@ -23,7 +23,6 @@ namespace ballistica::base {
|
||||
|
||||
// How much of the screen the console covers when it is at full size.
|
||||
const float kDevConsoleSize = 0.9f;
|
||||
const float kDevConsoleZDepth = 0.0f;
|
||||
const int kDevConsoleLineLimit = 80;
|
||||
const int kDevConsoleStringBreakUpSize = 1950;
|
||||
const int kDevConsoleActivateKey1 = SDLK_BACKQUOTE;
|
||||
@ -33,20 +32,65 @@ const double kTransitionSeconds = 0.1;
|
||||
|
||||
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:
|
||||
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;
|
||||
float x;
|
||||
float y;
|
||||
@ -55,27 +99,28 @@ class DevConsole::Button_ {
|
||||
bool pressed{};
|
||||
Object::Ref<Runnable> call;
|
||||
TextGroup text_group;
|
||||
bool text_group_built_{};
|
||||
float text_scale;
|
||||
|
||||
auto InUs(float mx, float my) -> bool {
|
||||
mx -= XOffs();
|
||||
return (mx >= x && mx <= (x + width) && my >= y && my <= (y + height));
|
||||
}
|
||||
auto XOffs() -> 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;
|
||||
template <typename F>
|
||||
Button_(const std::string& label, float text_scale, DevButtonAttach_ attach,
|
||||
float x, float y, float width, float height, const F& lambda)
|
||||
: attach{attach},
|
||||
x{x},
|
||||
y{y},
|
||||
width{width},
|
||||
height{height},
|
||||
call{NewLambdaRunnable(lambda)},
|
||||
text_scale{text_scale} {
|
||||
text_group.SetText(label, TextMesh::HAlign::kCenter,
|
||||
TextMesh::VAlign::kCenter);
|
||||
}
|
||||
|
||||
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)) {
|
||||
pressed = true;
|
||||
return true;
|
||||
@ -83,56 +128,156 @@ class DevConsole::Button_ {
|
||||
return false;
|
||||
}
|
||||
|
||||
void HandleMouseUp(float mx, float my) {
|
||||
pressed = false;
|
||||
if (InUs(mx, my)) {
|
||||
if (call.Exists()) {
|
||||
call.Get()->Run();
|
||||
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) {
|
||||
if (!text_group_built_) {
|
||||
text_group.set_text(label, TextMesh::HAlign::kCenter,
|
||||
TextMesh::VAlign::kCenter);
|
||||
void Draw(RenderPass* pass, float bottom) override {
|
||||
DrawBasicButton(
|
||||
pass, &text_group, text_scale, bottom, x + XOffs(attach), y, width,
|
||||
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);
|
||||
c.SetTransparent(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
void HandleMouseUp(float mx, float my) override {
|
||||
if (pressed) {
|
||||
c.SetColor(0.8f, 0.7f, 0.8f, 1.0f);
|
||||
} else {
|
||||
c.SetColor(0.25f, 0.2f, 0.3f, 1.0f);
|
||||
}
|
||||
{
|
||||
auto xf = c.ScopedTransform();
|
||||
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));
|
||||
pressed = false;
|
||||
if (InUs(mx, my)) {
|
||||
on = !on;
|
||||
auto&& call = on ? on_call : off_call;
|
||||
if (call.Exists()) {
|
||||
call.Get()->Run();
|
||||
}
|
||||
}
|
||||
}
|
||||
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& {
|
||||
if (!s_mesh_.Exists()) {
|
||||
s_mesh_ = Object::New<TextGroup>();
|
||||
s_mesh_->set_text(s);
|
||||
s_mesh_->SetText(s);
|
||||
}
|
||||
return *s_mesh_;
|
||||
}
|
||||
@ -164,32 +309,45 @@ DevConsole::DevConsole() {
|
||||
title += " (test)";
|
||||
}
|
||||
|
||||
title_text_group_.set_text(title);
|
||||
built_text_group_.set_text("Built: " __DATE__ " " __TIME__);
|
||||
prompt_text_group_.set_text(">");
|
||||
title_text_group_.SetText(title);
|
||||
built_text_group_.SetText("Built: " __DATE__ " " __TIME__);
|
||||
prompt_text_group_.SetText(">");
|
||||
|
||||
// NOTE: Once we can adjust UI scale on the fly we'll have to update
|
||||
// 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");
|
||||
// });
|
||||
Refresh();
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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).
|
||||
if (button == 1) {
|
||||
for (auto&& button : tab_buttons_) {
|
||||
if (button->HandleMouseDown(x, y - bottom)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (auto&& button : buttons_) {
|
||||
if (button.HandleMouseDown(x, y - bottom)) {
|
||||
if (button->HandleMouseDown(x, y - bottom)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -225,8 +388,11 @@ void DevConsole::HandleMouseUp(int button, float x, float y) {
|
||||
float bottom{Bottom_()};
|
||||
|
||||
if (button == 1) {
|
||||
for (auto&& button : tab_buttons_) {
|
||||
button->HandleMouseUp(x, y - bottom);
|
||||
}
|
||||
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.
|
||||
switch (keysym->sym) {
|
||||
case SDLK_ESCAPE:
|
||||
ToggleState();
|
||||
Dismiss();
|
||||
break;
|
||||
case SDLK_BACKSPACE:
|
||||
case SDLK_DELETE: {
|
||||
@ -530,11 +696,12 @@ auto DevConsole::Bottom_() const -> float {
|
||||
return bottom;
|
||||
}
|
||||
|
||||
void DevConsole::Draw(RenderPass* pass) {
|
||||
void DevConsole::Draw(FrameDef* frame_def) {
|
||||
float bs = PythonConsoleBaseScale_();
|
||||
RenderPass* pass = frame_def->overlay_front_pass();
|
||||
|
||||
// If we're not yet transitioning in for the first time OR have
|
||||
// completed transitioning out, do nothing.
|
||||
// If we're not yet transitioning in for the first time OR have completed
|
||||
// transitioning out, do nothing.
|
||||
if (transition_start_ <= 0.0
|
||||
|| state_ == State_::kInactive
|
||||
&& ((g_base->logic->display_time() - transition_start_)
|
||||
@ -543,155 +710,169 @@ void DevConsole::Draw(RenderPass* pass) {
|
||||
}
|
||||
|
||||
float bottom = Bottom_();
|
||||
|
||||
{
|
||||
bg_mesh_.SetPositionAndSize(0, bottom, kDevConsoleZDepth,
|
||||
pass->virtual_width(),
|
||||
(pass->virtual_height() - bottom));
|
||||
stripe_mesh_.SetPositionAndSize(0, bottom + 15.0f * bs, kDevConsoleZDepth,
|
||||
pass->virtual_width(), 15.0f * bs);
|
||||
shadow_mesh_.SetPositionAndSize(0, bottom - 7.0f * bs, kDevConsoleZDepth,
|
||||
pass->virtual_width(), 7.0f * bs);
|
||||
border_mesh_.SetPositionAndSize(0, bottom - 3.0f * bs, kDevConsoleZDepth,
|
||||
pass->virtual_width(), 3.0f * bs);
|
||||
SimpleComponent c(pass);
|
||||
c.SetTransparent(true);
|
||||
c.SetColor(0, 0, 0.1f, 0.9f);
|
||||
c.DrawMesh(&bg_mesh_);
|
||||
c.Submit();
|
||||
c.SetColor(1.0f, 1.0f, 1.0f, 0.1f);
|
||||
c.DrawMesh(&stripe_mesh_);
|
||||
c.Submit();
|
||||
c.SetColor(0, 0, 0, 0.1f);
|
||||
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));
|
||||
}
|
||||
if (active_tab_ == "Python") {
|
||||
c.SetColor(1.0f, 1.0f, 1.0f, 0.1f);
|
||||
c.DrawMesh(&stripe_mesh_);
|
||||
c.Submit();
|
||||
}
|
||||
c.SetColor(0.25f, 0.2f, 0.3f, 1.0f);
|
||||
c.DrawMesh(&border_mesh_);
|
||||
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);
|
||||
if (active_tab_ == "Python") {
|
||||
if (input_text_dirty_) {
|
||||
input_text_group_.SetText(input_string_);
|
||||
input_text_dirty_ = false;
|
||||
last_input_text_change_time_ = pass->frame_def()->real_time();
|
||||
}
|
||||
{
|
||||
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));
|
||||
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.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;
|
||||
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_->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&& button : tab_buttons_) {
|
||||
button->Draw(pass, bottom);
|
||||
}
|
||||
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.
|
||||
{
|
||||
for (auto&& button : buttons_) {
|
||||
button.Draw(pass, bottom);
|
||||
button->Draw(pass, bottom);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -706,6 +887,8 @@ auto DevConsole::PythonConsoleBaseScale_() const -> float {
|
||||
case UIScale::kLast:
|
||||
return 2.0f;
|
||||
}
|
||||
FatalError("Unhandled scale.");
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
} // namespace ballistica::base
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "ballistica/base/graphics/renderer/renderer.h"
|
||||
#include "ballistica/shared/foundation/object.h"
|
||||
@ -13,6 +14,9 @@
|
||||
|
||||
namespace ballistica::base {
|
||||
|
||||
/// Where on the overlay-front-pass we draw.
|
||||
const float kDevConsoleZDepth = 0.0f;
|
||||
|
||||
class DevConsole {
|
||||
public:
|
||||
DevConsole();
|
||||
@ -31,7 +35,7 @@ class DevConsole {
|
||||
|
||||
/// Print text to the console.
|
||||
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.
|
||||
void EnableInput();
|
||||
@ -47,18 +51,27 @@ class DevConsole {
|
||||
auto HandleMouseDown(int button, float x, float y) -> bool;
|
||||
void HandleMouseUp(int button, float x, float y);
|
||||
void Exec();
|
||||
void Refresh();
|
||||
|
||||
private:
|
||||
class Widget_;
|
||||
class Button_;
|
||||
class ToggleButton_;
|
||||
class TabButton_;
|
||||
class Line_;
|
||||
enum class State_ { kInactive, kMini, kFull };
|
||||
|
||||
auto Bottom_() const -> float;
|
||||
auto PythonConsoleBaseScale_() const -> float;
|
||||
void SubmitCommand_(const std::string& command);
|
||||
void InvokeStringEditor_();
|
||||
void RefreshTabsButtons_();
|
||||
|
||||
std::list<std::string> tabs_{"Python", "AppModes", "Logging", "Graphics"};
|
||||
std::string active_tab_{"Python"};
|
||||
ImageMesh bg_mesh_;
|
||||
ImageMesh stripe_mesh_;
|
||||
ImageMesh shadow_mesh_;
|
||||
ImageMesh border_mesh_;
|
||||
TextGroup built_text_group_;
|
||||
TextGroup title_text_group_;
|
||||
TextGroup prompt_text_group_;
|
||||
@ -78,7 +91,8 @@ class DevConsole {
|
||||
bool last_line_mesh_dirty_{true};
|
||||
bool python_console_pressed_{};
|
||||
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
|
||||
|
||||
@ -163,13 +163,14 @@ void UI::HandleMouseUp(int button, float x, float y) {
|
||||
if (dev_console_) {
|
||||
dev_console_->HandleMouseUp(button, x, y);
|
||||
}
|
||||
|
||||
if (dev_console_button_pressed_ && button == 1) {
|
||||
dev_console_button_pressed_ = false;
|
||||
if (InDevConsoleButton_(x, y)) {
|
||||
if (dev_console_) {
|
||||
dev_console_->ToggleState();
|
||||
}
|
||||
}
|
||||
dev_console_button_pressed_ = false;
|
||||
}
|
||||
|
||||
if (g_base->HaveUIV1()) {
|
||||
@ -386,7 +387,7 @@ void UI::Draw(FrameDef* frame_def) {
|
||||
void UI::DrawDev(FrameDef* frame_def) {
|
||||
// Draw dev console.
|
||||
if (dev_console_) {
|
||||
dev_console_->Draw(frame_def->overlay_pass());
|
||||
dev_console_->Draw(frame_def);
|
||||
}
|
||||
|
||||
// Draw dev console button.
|
||||
@ -422,14 +423,14 @@ auto UI::InDevConsoleButton_(float x, float y) const -> bool {
|
||||
void UI::DrawDevConsoleButton_(FrameDef* frame_def) {
|
||||
if (!dev_console_button_txt_.Exists()) {
|
||||
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_);
|
||||
float vwidth = g_base->graphics->screen_virtual_width();
|
||||
float vheight = g_base->graphics->screen_virtual_height();
|
||||
float bsz = DevConsoleButtonSize_();
|
||||
|
||||
SimpleComponent c(frame_def->overlay_pass());
|
||||
SimpleComponent c(frame_def->overlay_front_pass());
|
||||
c.SetTransparent(true);
|
||||
c.SetTexture(g_base->assets->SysTexture(SysTextureID::kCircleShadow));
|
||||
if (dev_console_button_pressed_) {
|
||||
@ -439,7 +440,7 @@ void UI::DrawDevConsoleButton_(FrameDef* frame_def) {
|
||||
}
|
||||
{
|
||||
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.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kImage1x1));
|
||||
{
|
||||
|
||||
@ -136,7 +136,7 @@ void ExplosionNode::Draw(base::FrameDef* frame_def) {
|
||||
float s = 1.0f;
|
||||
if (high_quality) {
|
||||
base::PostProcessComponent c(frame_def->blit_pass());
|
||||
c.setNormalDistort(0.5f * amt);
|
||||
c.SetNormalDistort(0.5f * amt);
|
||||
c.PushTransform();
|
||||
c.Translate(position_[0], position_[1], position_[2]);
|
||||
c.Scale(1.0f + s * 0.8f * 0.025f * age,
|
||||
|
||||
@ -268,7 +268,7 @@ void ShieldNode::Draw(base::FrameDef* frame_def) {
|
||||
}
|
||||
if (frame_def->has_depth_texture()) {
|
||||
base::PostProcessComponent c2(frame_def->blit_pass());
|
||||
c2.setNormalDistort(distort);
|
||||
c2.SetNormalDistort(distort);
|
||||
c2.PushTransform();
|
||||
c2.MultMatrix((om * m).m);
|
||||
c2.Scale(s, s, s);
|
||||
|
||||
@ -4783,7 +4783,7 @@ void SpazNode::Draw(base::FrameDef* frame_def) {
|
||||
snprintf(buffer, sizeof(buffer), "%d", static_cast<int>(diff));
|
||||
if (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;
|
||||
if (render_frame_count % 6 < 3) {
|
||||
@ -4911,7 +4911,7 @@ void SpazNode::Draw(base::FrameDef* frame_def) {
|
||||
{ // text
|
||||
if (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());
|
||||
c.SetTransparent(true);
|
||||
@ -4940,9 +4940,9 @@ void SpazNode::Draw(base::FrameDef* frame_def) {
|
||||
if (explicit_bool(true)) {
|
||||
if (name_mesh_txt_ != name_) {
|
||||
name_mesh_txt_ = name_;
|
||||
name_text_group_.set_text(name_mesh_txt_,
|
||||
base::TextMesh::HAlign::kCenter,
|
||||
base::TextMesh::VAlign::kCenter);
|
||||
name_text_group_.SetText(name_mesh_txt_,
|
||||
base::TextMesh::HAlign::kCenter,
|
||||
base::TextMesh::VAlign::kCenter);
|
||||
}
|
||||
base::SimpleComponent c(frame_def->overlay_3d_pass());
|
||||
c.SetTransparent(true);
|
||||
|
||||
@ -417,8 +417,8 @@ void TextNode::Draw(base::FrameDef* frame_def) {
|
||||
break;
|
||||
}
|
||||
|
||||
// update if need be
|
||||
text_group_.set_text(text_translated_, h_align, v_align, true, 2.5f);
|
||||
// Update if need be.
|
||||
text_group_.SetText(text_translated_, h_align, v_align, true, 2.5f);
|
||||
text_group_dirty_ = false;
|
||||
}
|
||||
|
||||
@ -589,7 +589,7 @@ void TextNode::Draw(base::FrameDef* frame_def) {
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
float z = vr_2d_text
|
||||
|
||||
@ -39,7 +39,7 @@ auto main(int argc, char** argv) -> int {
|
||||
namespace ballistica {
|
||||
|
||||
// These are set automatically via script; don't modify them here.
|
||||
const int kEngineBuildNumber = 21337;
|
||||
const int kEngineBuildNumber = 21342;
|
||||
const char* kEngineVersion = "1.7.28";
|
||||
const int kEngineApiVersion = 8;
|
||||
|
||||
|
||||
@ -265,9 +265,9 @@ void RootUI::Draw(base::FrameDef* frame_def) {
|
||||
party_button_text_group_ = Object::New<base::TextGroup>();
|
||||
}
|
||||
if (party_button_name != party_button_text_group_->text()) {
|
||||
party_button_text_group_->set_text(
|
||||
party_button_name, base::TextMesh::HAlign::kCenter,
|
||||
base::TextMesh::VAlign::kTop);
|
||||
party_button_text_group_->SetText(party_button_name,
|
||||
base::TextMesh::HAlign::kCenter,
|
||||
base::TextMesh::VAlign::kTop);
|
||||
}
|
||||
int text_elem_count = party_button_text_group_->GetElementCount();
|
||||
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()) {
|
||||
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_));
|
||||
|
||||
// ..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>();
|
||||
}
|
||||
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(
|
||||
"joinedPartyInstructionsText"),
|
||||
base::TextMesh::HAlign::kRight, base::TextMesh::VAlign::kTop);
|
||||
} else if (party_size > 2) {
|
||||
start_a_game_text_group_->set_text(
|
||||
start_a_game_text_group_->SetText(
|
||||
std::to_string(party_size - 1) +
|
||||
" friends have joined your party.\nGo to 'Play' to start "
|
||||
"a game.",
|
||||
|
||||
@ -298,7 +298,7 @@ void TextWidget::Draw(base::RenderPass* pass, bool draw_transparent) {
|
||||
text_group_ = Object::New<base::TextGroup>();
|
||||
}
|
||||
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_);
|
||||
|
||||
// FIXME: doesnt support big.
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// Released under the MIT License. See LICENSE for details.
|
||||
|
||||
// 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
|
||||
// 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
|
||||
// worker instances as needed. Though such a fancy setup might be
|
||||
// overkill.
|
||||
ctx->instance_num = rand() % 6;
|
||||
// ctx->instance_num = rand() % 6;
|
||||
|
||||
// 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
|
||||
// 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;
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user