dev-console work in progress

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

80
.efrocachemap generated
View File

@ -1108,10 +1108,6 @@
"build/assets/ba_data/textures/agentIconColorMask.pvr": "075f61aae95df3456dc37dd598e73c93",
"build/assets/ba_data/textures/agentIconColorMask_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",

View File

@ -1,4 +1,4 @@
### 1.7.28 (build 21337, api 8, 2023-09-11)
### 1.7.28 (build 21342, api 8, 2023-09-13)
- Renamed Console to DevConsole, and added an option under advanced settings to
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`.

View File

@ -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",

View File

@ -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 \

View File

@ -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'

View File

@ -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

View File

@ -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();

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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.

View File

@ -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);

View File

@ -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_) {

View File

@ -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,

View File

@ -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();

View File

@ -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

View File

@ -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);

View File

@ -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,

View File

@ -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:

View File

@ -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));
}

View File

@ -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_; }

View File

@ -152,8 +152,8 @@ void NetGraph::Draw(RenderPass* pass, double time, double x, double y, double w,
snprintf(val_str, sizeof(val_str), "%.3f",
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);

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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));
{

View File

@ -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,

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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.",

View File

@ -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.

View File

@ -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;
}