diff --git a/.efrocachemap b/.efrocachemap index 4008800b..03af762d 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -421,19 +421,19 @@ "build/assets/ba_data/audio/zoeOw.ogg": "74befe45a8417e95b6a2233c51992a26", "build/assets/ba_data/audio/zoePickup01.ogg": "48ab8cddfcde36a750856f3f81dd20c8", "build/assets/ba_data/audio/zoeScream01.ogg": "2b468aedfa8741090247f04eb9e6df55", - "build/assets/ba_data/data/langdata.json": "fae88cbb2a5b9c24096f2e43452114a2", + "build/assets/ba_data/data/langdata.json": "6ae92385835c7f270dc35d7b4be3deef", "build/assets/ba_data/data/languages/arabic.json": "0db32e21b6d5337ccca478381744aa88", "build/assets/ba_data/data/languages/belarussian.json": "a112dfca3e188387516788bd8229c5b0", - "build/assets/ba_data/data/languages/chinese.json": "ff9a595726f0aff42a39be576d0ff037", - "build/assets/ba_data/data/languages/chinesetraditional.json": "f858da49be0a5374157c627857751078", + "build/assets/ba_data/data/languages/chinese.json": "93f3ca9f90d86dc7c8d0923f5f11ef46", + "build/assets/ba_data/data/languages/chinesetraditional.json": "319565f8a15667488f48dbce59278e39", "build/assets/ba_data/data/languages/croatian.json": "766532c67af5bd0144c2d63cab0516fa", "build/assets/ba_data/data/languages/czech.json": "c9d518a324870066b987b8f412881dd3", "build/assets/ba_data/data/languages/danish.json": "3fd69080783d5c9dcc0af737f02b6f1e", - "build/assets/ba_data/data/languages/dutch.json": "22b44a33bf81142ba2befad14eb5746e", + "build/assets/ba_data/data/languages/dutch.json": "5cbf1a68a9d93dee00dbc27f834d878a", "build/assets/ba_data/data/languages/english.json": "2434e127b6788e3128d3523fcb1b8994", "build/assets/ba_data/data/languages/esperanto.json": "0e397cfa5f3fb8cef5f4a64f21cda880", "build/assets/ba_data/data/languages/filipino.json": "e750fb1a95e4c5611115f9ece9ecab53", - "build/assets/ba_data/data/languages/french.json": "163362f7b33866ef069cae62d0387551", + "build/assets/ba_data/data/languages/french.json": "8bc35eb4b20a0b30c3348bcc9a3844a6", "build/assets/ba_data/data/languages/german.json": "450fa41ae264f29a5d1af22143d0d0ad", "build/assets/ba_data/data/languages/gibberish.json": "e24d391c9fd12f9afa92f7ff65a06d23", "build/assets/ba_data/data/languages/greek.json": "287c0ec437b38772284ef9d3e4fb2fc3", @@ -450,13 +450,13 @@ "build/assets/ba_data/data/languages/russian.json": "9d0b40586301a82e532c4a250d5f6d58", "build/assets/ba_data/data/languages/serbian.json": "d7452dd72ac0e51680cb39b5ebaa1c69", "build/assets/ba_data/data/languages/slovak.json": "27962d53dc3f7dd4e877cd40faafeeef", - "build/assets/ba_data/data/languages/spanish.json": "42f857c40dbd4b637e3866849489f7d1", + "build/assets/ba_data/data/languages/spanish.json": "8d43556cb55cdfa4408fd19a4646b824", "build/assets/ba_data/data/languages/swedish.json": "5142a96597d17d8344be96a603da64ac", "build/assets/ba_data/data/languages/tamil.json": "b4de1a2851afe4869c82e9acd94cd89c", "build/assets/ba_data/data/languages/thai.json": "77755219bbf5fb7eea0d6b226684f403", - "build/assets/ba_data/data/languages/turkish.json": "ab149ebbd57cf4daa3cf8f310d91519a", + "build/assets/ba_data/data/languages/turkish.json": "72fac3a6fd13ebb74fb4d68b9323e7d4", "build/assets/ba_data/data/languages/ukrainian.json": "e5c861187c4c6db37d1a033f4ef3dd5a", - "build/assets/ba_data/data/languages/venetian.json": "a559a5608d2e0b4708f7a4dee42ff354", + "build/assets/ba_data/data/languages/venetian.json": "8e9714d98a85e428ce3543fc49188a46", "build/assets/ba_data/data/languages/vietnamese.json": "921cd1e50f60fe3e101f246e172750ba", "build/assets/ba_data/data/maps/big_g.json": "1dd301d490643088a435ce75df971054", "build/assets/ba_data/data/maps/bridgit.json": "6aea74805f4880cc11237c5734a24422", @@ -4060,26 +4060,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": "5f7e668a6a904ba8c0fe391654a8211b", - "build/prefab/full/linux_arm64_gui/release/ballisticakit": "77cd63dbc1760a3d1bb55753794701b0", - "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "9f674a5b767f798b350ef30d84968d44", - "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "84546f0452561d3f6519d296a9e9b2ca", - "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "3122dbce63fb248c9ebe66d545be8480", - "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "4004c01a3ea1a7b62544f08f14e76f9e", - "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "cd9b5b9ae925cef7417d2b86fd0f0489", - "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "35c2b307e5d228b105315b8d022d31d2", - "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "90993c873a2d1ca7b593992e52b1865a", - "build/prefab/full/mac_arm64_gui/release/ballisticakit": "46119cb9ff99629ca16471f51032bac7", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "8cac6eff8eb4f9e453a669b6f239b8a5", - "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "3e20c91bf8948354a0e167faa5c184e9", - "build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "52ff216e1b0394a07bf178b8eea8c269", - "build/prefab/full/mac_x86_64_gui/release/ballisticakit": "32d85cc58ade8e7a63dfb604ef175553", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "fdf3da5251bc0d3b8f4e5a5b2e0d4b94", - "build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "c03afc18b7aa72ab065381be985f48ae", - "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "67a58d483ac028f9fc59112b59463a99", - "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "0800d71a41320664bacba49822e8b442", - "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "9019d9b48cefa45a7a16bae6bd696896", - "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "90eca6cc81b0a2c39fd1d41d0d029f04", + "build/prefab/full/linux_arm64_gui/debug/ballisticakit": "6d1c198240f58211b14534263de11034", + "build/prefab/full/linux_arm64_gui/release/ballisticakit": "0e29ddb400da245f7425e2779278b936", + "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "887c68a7be4c8d25c6eae21feb2fd39a", + "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "99a237557104d145f061b674e158539f", + "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "c813eb17692868fc54741e962d8ecca6", + "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "67b39d7c54a801c2b65bd8beb55771a2", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "20af8a239c97cbb8fe876c06d57c3f1f", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "60d09bd4c59e27f2f3c8b6331b650ee1", + "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "84733128a50a14b046306419419862d4", + "build/prefab/full/mac_arm64_gui/release/ballisticakit": "b81062addf907d312a9409660733205c", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "2770d31f91042c005cb0fc5cb368112c", + "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "316e8424de85400d5b84c84395689776", + "build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "15bd20491afa0d90e3cea147d04e25a6", + "build/prefab/full/mac_x86_64_gui/release/ballisticakit": "4697883ea3e8f9e8d215c9a82396c8a4", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "cd24a57ef4815f02f3c4f054fc9ae878", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "13b8e37ea683de88bce49e06a6cba24d", + "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "50218a71f166a51c6bccec5f8a946835", + "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "e20e058060ef6acc1e1f4cbccd69a7ce", + "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "13a90cb0c4a15daa64c8d883afd895e9", + "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "6af4eddfe3ed8a825a5ebd7702536fd7", "build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "db535f0ca1e01af825f75f204fbc8928", "build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "97d51afca996ae15b61fd9f409a00459", "build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "db535f0ca1e01af825f75f204fbc8928", @@ -4096,21 +4096,21 @@ "build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "452623f0495dd4375e5b5d9b80d643d5", "build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "ca49b32ed573feea11613d62cd89840c", "build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "452623f0495dd4375e5b5d9b80d643d5", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "ff81e6eeea861f59e71db628bc64918b", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "ba89e5949d1cdf2b857089feb901285c", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "5e063f8acc0e0e9f35f82480d7dbf143", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "1f0d14fcc16dd0d4896d91c75e32be25", - "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "251d3dd0bc9a6418eb1cb5176bb5509c", - "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "96c003edb87b3f506d1b15af461487c3", - "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "274ebd634f05b23653719ef973119cf5", - "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "796edace73f874ebf46054b2a1ff0ba1", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "3b19ca383e1a88bd8a0599181da738ba", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "2b9ee84d34b41dd7d92df7c7dece5ecc", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "78fc011efdd0d3c5ad91ba5cc7e25b36", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "1c60cf6ee1b3b7f1c4ca10f18ad55c0b", + "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "a9d3d2dd577409f19129a2a14f03a871", + "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "c8cda906610d28b03a5d0abac69f752e", + "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "951e19df7d1f5d9befd0b1fe5e4f6390", + "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "b75ac3bc471e3b6121d27a83b07573da", "src/assets/ba_data/python/babase/_mgen/__init__.py": "f885fed7f2ed98ff2ba271f9dbe3391c", "src/assets/ba_data/python/babase/_mgen/enums.py": "28323912b56ec07701eda3d41a6a4101", "src/ballistica/base/mgen/pyembed/binding_base.inc": "72bfed2cce8ff19741989dec28302f3f", "src/ballistica/base/mgen/pyembed/binding_base_app.inc": "97efb93f4bfd8e8b09f2db24398e29fc", "src/ballistica/classic/mgen/pyembed/binding_classic.inc": "3ceb412513963f0818ab39c58bf292e3", "src/ballistica/core/mgen/pyembed/binding_core.inc": "9d0a3c9636138e35284923e0c8311c69", - "src/ballistica/core/mgen/pyembed/env.inc": "8be46e5818f360d10b7b0224a9e91d07", + "src/ballistica/core/mgen/pyembed/env.inc": "f015d726b44d2922112fc14d9f146d8b", "src/ballistica/core/mgen/python_modules_monolithic.h": "fb967ed1c7db0c77d8deb4f00a7103c5", "src/ballistica/scene_v1/mgen/pyembed/binding_scene_v1.inc": "c25b263f2a31fb5ebe057db07d144879", "src/ballistica/template_fs/mgen/pyembed/binding_template_fs.inc": "44a45492db057bf7f7158c3b0fa11f0f", diff --git a/CHANGELOG.md b/CHANGELOG.md index d84b9b62..7d709c47 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -### 1.7.33 (build 21743, api 8, 2023-12-21) +### 1.7.33 (build 21747, api 8, 2024-01-03) ### 1.7.32 (build 21741, api 8, 2023-12-20) - Fixed a screen message that no one will ever see (Thanks vishal332008?...) diff --git a/src/assets/ba_data/python/baenv.py b/src/assets/ba_data/python/baenv.py index c45c1c54..fb07e230 100644 --- a/src/assets/ba_data/python/baenv.py +++ b/src/assets/ba_data/python/baenv.py @@ -52,7 +52,7 @@ if TYPE_CHECKING: # Build number and version of the ballistica binary we expect to be # using. -TARGET_BALLISTICA_BUILD = 21743 +TARGET_BALLISTICA_BUILD = 21747 TARGET_BALLISTICA_VERSION = '1.7.33' @@ -350,9 +350,15 @@ def _setup_paths( # platforms where there is no write access to said built-in # stuff. check_dir = Path(user_python_dir, 'sys', TARGET_BALLISTICA_VERSION) - if check_dir.is_dir(): - app_python_dir = str(check_dir) - is_user_app_python_dir = True + try: + if check_dir.is_dir(): + app_python_dir = str(check_dir) + is_user_app_python_dir = True + except PermissionError: + logging.warning( + "PermissionError checking user-app-python-dir path '%s'.", + check_dir, + ) # Ok, now apply these to sys.path. diff --git a/src/ballistica/base/assets/assets.cc b/src/ballistica/base/assets/assets.cc index 1fe097d1..f95ebcb6 100644 --- a/src/ballistica/base/assets/assets.cc +++ b/src/ballistica/base/assets/assets.cc @@ -1610,10 +1610,6 @@ auto Assets::SysTexture(SysTextureID id) -> TextureAsset* { assert(asset_loads_allowed_ && sys_assets_loaded_); assert(g_base->InLogicThread()); assert(static_cast(id) < system_textures_.size()); - // TEMP - tracking down some crashes in the wild. - if (!sys_assets_loaded_) { - FatalError("SysTexture called before sys assets loaded."); - } return system_textures_[static_cast(id)].Get(); } @@ -1621,21 +1617,17 @@ auto Assets::SysCubeMapTexture(SysCubeMapTextureID id) -> TextureAsset* { assert(asset_loads_allowed_ && sys_assets_loaded_); assert(g_base->InLogicThread()); assert(static_cast(id) < system_cube_map_textures_.size()); - // TEMP - tracking down some crashes in the wild. - if (!sys_assets_loaded_) { - FatalError("SysCubeMapTexture called before sys assets loaded."); - } return system_cube_map_textures_[static_cast(id)].Get(); } +auto Assets::IsValidSysSound(SysSoundID id) -> bool { + return static_cast(id) < system_sounds_.size(); +} + auto Assets::SysSound(SysSoundID id) -> SoundAsset* { assert(asset_loads_allowed_ && sys_assets_loaded_); assert(g_base->InLogicThread()); - assert(static_cast(id) < system_sounds_.size()); - // TEMP - tracking down some crashes in the wild. - if (!sys_assets_loaded_) { - FatalError("SysSound called before sys assets loaded."); - } + assert(IsValidSysSound(id)); return system_sounds_[static_cast(id)].Get(); } @@ -1643,11 +1635,6 @@ auto Assets::SysMesh(SysMeshID id) -> MeshAsset* { assert(asset_loads_allowed_ && sys_assets_loaded_); assert(g_base->InLogicThread()); assert(static_cast(id) < system_meshes_.size()); - - // TEMP - tracking down some crashes in the wild. - if (!sys_assets_loaded_) { - FatalError("SysMesh called before sys assets loaded."); - } return system_meshes_[static_cast(id)].Get(); } diff --git a/src/ballistica/base/assets/assets.h b/src/ballistica/base/assets/assets.h index 8fa05722..aa396371 100644 --- a/src/ballistica/base/assets/assets.h +++ b/src/ballistica/base/assets/assets.h @@ -76,6 +76,7 @@ class Assets { // available. auto SysTexture(SysTextureID id) -> TextureAsset*; auto SysCubeMapTexture(SysCubeMapTextureID id) -> TextureAsset*; + auto IsValidSysSound(SysSoundID id) -> bool; auto SysSound(SysSoundID id) -> SoundAsset*; auto SysMesh(SysMeshID id) -> MeshAsset*; diff --git a/src/ballistica/base/audio/audio.cc b/src/ballistica/base/audio/audio.cc index 6e039ead..f37f4632 100644 --- a/src/ballistica/base/audio/audio.cc +++ b/src/ballistica/base/audio/audio.cc @@ -2,6 +2,7 @@ #include "ballistica/base/audio/audio.h" +#include "ballistica/base/assets/assets.h" #include "ballistica/base/assets/sound_asset.h" #include "ballistica/base/audio/audio_server.h" #include "ballistica/base/audio/audio_source.h" @@ -159,6 +160,32 @@ auto Audio::ShouldPlay(SoundAsset* sound) -> bool { return (time - sound->last_play_time() > 50); } +auto Audio::SafePlaySysSound(SysSoundID sound_id) -> std::optional { + // Save some time on headless. + if (g_core->HeadlessMode()) { + return {}; + } + if (!g_base->InLogicThread()) { + Log(LogLevel::kError, + "Audio::SafePlaySysSound called from non-logic thread. id=" + + std::to_string(static_cast(sound_id))); + return {}; + } + if (!g_base->assets->sys_assets_loaded()) { + Log(LogLevel::kWarning, + "Audio::SafePlaySysSound called before sys assets loaded. id=" + + std::to_string(static_cast(sound_id))); + return {}; + } + if (!g_base->assets->IsValidSysSound(sound_id)) { + Log(LogLevel::kWarning, + "Audio::SafePlaySysSound called with invalid sound_id. id=" + + std::to_string(static_cast(sound_id))); + return {}; + } + return PlaySound(g_base->assets->SysSound(sound_id)); +} + auto Audio::PlaySound(SoundAsset* sound, float volume) -> std::optional { assert(g_core); diff --git a/src/ballistica/base/audio/audio.h b/src/ballistica/base/audio/audio.h index af0d646d..bf42ce04 100644 --- a/src/ballistica/base/audio/audio.h +++ b/src/ballistica/base/audio/audio.h @@ -61,6 +61,10 @@ class Audio { auto PlaySoundAtPosition(SoundAsset* sound, float volume, float x, float y, float z) -> std::optional; + /// Load and play a sys sound if possible. Gracefully fail if not + /// (possibly logging warnings or errors). + auto SafePlaySysSound(SysSoundID sound_id) -> std::optional; + /// Call this if you want to prevent repeated plays of the same sound. It'll /// tell you if the sound has been played recently. The one-shot sound-play /// functions use this under the hood. (PlaySound, PlaySoundAtPosition). diff --git a/src/ballistica/base/graphics/component/render_component.h b/src/ballistica/base/graphics/component/render_component.h index c7fdaaa0..b0cc1b5e 100644 --- a/src/ballistica/base/graphics/component/render_component.h +++ b/src/ballistica/base/graphics/component/render_component.h @@ -240,7 +240,7 @@ class RenderComponent { } protected: - enum class State { kConfiguring, kDrawing, kSubmitted }; + enum class State : uint8_t { kConfiguring, kDrawing, kSubmitted }; void EnsureConfiguring() { if (state_ != State::kConfiguring) { #if BA_DEBUG_BUILD @@ -331,8 +331,8 @@ class RenderComponent { // stream. virtual void WriteConfig() = 0; - RenderCommandBuffer* cmd_buffer_{}; State state_{State::kConfiguring}; + RenderCommandBuffer* cmd_buffer_{}; RenderPass* pass_; public: diff --git a/src/ballistica/base/graphics/gl/mesh/mesh_asset_data_gl.h b/src/ballistica/base/graphics/gl/mesh/mesh_asset_data_gl.h index 50624eac..edc34e1a 100644 --- a/src/ballistica/base/graphics/gl/mesh/mesh_asset_data_gl.h +++ b/src/ballistica/base/graphics/gl/mesh/mesh_asset_data_gl.h @@ -19,7 +19,7 @@ class RendererGL::MeshAssetDataGL : public MeshAssetRendererData { enum BufferType { kVertices, kIndices, kBufferCount }; MeshAssetDataGL(const MeshAsset& model, RendererGL* renderer) - : renderer_(renderer), fake_vao_(nullptr) { + : renderer_(renderer) { #if BA_DEBUG_BUILD name_ = model.GetName(); #endif @@ -150,7 +150,7 @@ class RendererGL::MeshAssetDataGL : public MeshAssetRendererData { GLuint index_type_{}; GLuint vao_{}; GLuint vbos_[kBufferCount]{}; - FakeVertexArrayObject* fake_vao_{}; + // FakeVertexArrayObject* fake_vao_{}; }; } // namespace ballistica::base diff --git a/src/ballistica/base/graphics/gl/mesh/mesh_data_gl.h b/src/ballistica/base/graphics/gl/mesh/mesh_data_gl.h index b27129e0..e902ef97 100644 --- a/src/ballistica/base/graphics/gl/mesh/mesh_data_gl.h +++ b/src/ballistica/base/graphics/gl/mesh/mesh_data_gl.h @@ -202,7 +202,6 @@ class RendererGL::MeshDataGL : public MeshRendererData { RendererGL* renderer_{}; uint32_t elem_count_{}; GLuint index_type_{GL_UNSIGNED_SHORT}; - FakeVertexArrayObject* fake_vao_{}; }; } // namespace ballistica::base diff --git a/src/ballistica/base/graphics/gl/renderer_gl.cc b/src/ballistica/base/graphics/gl/renderer_gl.cc index c5cd9bd1..26f84d7c 100644 --- a/src/ballistica/base/graphics/gl/renderer_gl.cc +++ b/src/ballistica/base/graphics/gl/renderer_gl.cc @@ -2339,12 +2339,11 @@ void RendererGL::SetDrawAtEqualDepth(bool enable) { } } -// FIXME FIXME FIXME FIXME -// turning off GL_DEPTH_TEST also disables -// depth writing which we may not want. -// It sounds like the proper thing -// to do in that case is leave GL_DEPTH_TEST on -// and set glDepthFunc(GL_ALWAYS) +// FIXME FIXME FIXME FIXME: +// +// Turning off GL_DEPTH_TEST also disables depth writing which we may not +// want. It sounds like the proper thing to do in that case is leave +// GL_DEPTH_TEST on and set glDepthFunc(GL_ALWAYS). void RendererGL::SetDepthTesting(bool enable) { if (enable != depth_testing_enabled_) { diff --git a/src/ballistica/base/graphics/gl/renderer_gl.h b/src/ballistica/base/graphics/gl/renderer_gl.h index 16917d81..7793a70e 100644 --- a/src/ballistica/base/graphics/gl/renderer_gl.h +++ b/src/ballistica/base/graphics/gl/renderer_gl.h @@ -39,7 +39,6 @@ namespace ballistica::base { constexpr int kMaxGLTexUnitsUsed = 5; class RendererGL : public Renderer { - class FakeVertexArrayObject; class TextureDataGL; class MeshAssetDataGL; class MeshDataGL; diff --git a/src/ballistica/base/graphics/mesh/mesh.h b/src/ballistica/base/graphics/mesh/mesh.h index c556032f..963fa37e 100644 --- a/src/ballistica/base/graphics/mesh/mesh.h +++ b/src/ballistica/base/graphics/mesh/mesh.h @@ -9,7 +9,8 @@ namespace ballistica::base { -// A dynamically defined mesh (unlike a mesh asset which is completely static). +/// A dynamically defined mesh (unlike a mesh asset which is completely +/// static). class Mesh : public Object { public: auto type() const -> MeshDataType { return type_; } @@ -17,7 +18,7 @@ class Mesh : public Object { return mesh_data_client_handle_; } - // Return whether it is safe to attempt drawing with present data. + /// Return whether it is safe to attempt drawing with present data. virtual auto IsValid() const -> bool = 0; auto last_frame_def_num() const -> int64_t { return last_frame_def_num_; } void set_last_frame_def_num(int64_t f) { last_frame_def_num_ = f; } @@ -31,14 +32,14 @@ class Mesh : public Object { } private: - int64_t last_frame_def_num_{}; MeshDataType type_{}; - - // Renderer data for this mesh. We keep this as a shared pointer - // so that frame_defs or other things using this mesh can keep it alive - // even if we go away. - Object::Ref mesh_data_client_handle_; bool valid_{}; + int64_t last_frame_def_num_{}; + + /// Renderer data for this mesh. We keep this as a shared pointer so that + /// frame_defs or other things using this mesh can keep it alive even if + /// we go away. + Object::Ref mesh_data_client_handle_; }; } // namespace ballistica::base diff --git a/src/ballistica/base/graphics/mesh/mesh_data.h b/src/ballistica/base/graphics/mesh/mesh_data.h index 9520465b..83667c4c 100644 --- a/src/ballistica/base/graphics/mesh/mesh_data.h +++ b/src/ballistica/base/graphics/mesh/mesh_data.h @@ -9,8 +9,8 @@ namespace ballistica::base { -// The portion of a mesh that is owned by the graphics thread. -// This contains the renderer-specific data (GL buffers, etc) +/// The portion of a mesh that is owned by the graphics server. This +/// contains the renderer-specific data (GL buffers, etc). class MeshData { public: MeshData(MeshDataType type, MeshDrawType draw_type) diff --git a/src/ballistica/base/graphics/renderer/render_pass.h b/src/ballistica/base/graphics/renderer/render_pass.h index 90abb2b7..4a45176f 100644 --- a/src/ballistica/base/graphics/renderer/render_pass.h +++ b/src/ballistica/base/graphics/renderer/render_pass.h @@ -15,8 +15,8 @@ namespace ballistica::base { // shadow pass, a window, etc. class RenderPass { public: - enum class ReflectionSubPass { kRegular, kMirrored }; - enum class Type { + enum class ReflectionSubPass : uint8_t { kRegular, kMirrored }; + enum class Type : uint8_t { // 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 @@ -152,40 +152,43 @@ class RenderPass { private: void SetFrustum(float near_val, float far_val); + bool cam_use_fov_tangents_{}; + bool floor_reflection_{}; + Type type_{}; + + float cam_near_clip_{}; + float cam_far_clip_{}; + float cam_fov_x_{}; + float cam_fov_y_{}; + float physical_width_{}; + float physical_height_{}; + float virtual_width_{}; + float virtual_height_{}; + + // We can now alternately supply left, right, top, bottom frustum tangents. + float cam_fov_l_tan_{1.0f}; + float cam_fov_r_tan_{1.0f}; + float cam_fov_t_tan_{1.0f}; + float cam_fov_b_tan_{1.0f}; + + Vector3f cam_pos_{0.0f, 0.0f, 0.0f}; + Vector3f cam_target_{0.0f, 0.0f, 0.0f}; + Vector3f cam_up_{0.0f, 0.0f, 0.0f}; + + Matrix44f tex_project_matrix_{kMatrix44fIdentity}; + Matrix44f projection_matrix_{kMatrix44fIdentity}; + Matrix44f model_view_matrix_{kMatrix44fIdentity}; + Matrix44f model_view_projection_matrix_{kMatrix44fIdentity}; + FrameDef* frame_def_{}; + + std::vector cam_area_of_interest_points_; + // Our pass holds sets of draw-commands bucketed by section and // component-type. std::unique_ptr commands_[static_cast(ShadingType::kCount)]; std::unique_ptr commands_flat_; std::unique_ptr commands_flat_transparent_; - Vector3f cam_pos_{0.0f, 0.0f, 0.0f}; - Vector3f cam_target_{0.0f, 0.0f, 0.0f}; - Vector3f cam_up_{0.0f, 0.0f, 0.0f}; - float cam_near_clip_{}; - float cam_far_clip_{}; - float cam_fov_x_{}; - float cam_fov_y_{}; - - // We can now alternately supply left, right, top, bottom frustum tangents. - bool cam_use_fov_tangents_{}; - float cam_fov_l_tan_{1.0f}; - float cam_fov_r_tan_{1.0f}; - float cam_fov_t_tan_{1.0f}; - float cam_fov_b_tan_{1.0f}; - std::vector cam_area_of_interest_points_; - Type type_{}; - - // For lights/shadows. - Matrix44f tex_project_matrix_{kMatrix44fIdentity}; - Matrix44f projection_matrix_{kMatrix44fIdentity}; - Matrix44f model_view_matrix_{kMatrix44fIdentity}; - Matrix44f model_view_projection_matrix_{kMatrix44fIdentity}; - bool floor_reflection_{}; - FrameDef* frame_def_{}; - float physical_width_{}; - float physical_height_{}; - float virtual_width_{}; - float virtual_height_{}; }; } // namespace ballistica::base diff --git a/src/ballistica/base/graphics/renderer/render_target.cc b/src/ballistica/base/graphics/renderer/render_target.cc index b1e5b786..d6382f51 100644 --- a/src/ballistica/base/graphics/renderer/render_target.cc +++ b/src/ballistica/base/graphics/renderer/render_target.cc @@ -39,6 +39,7 @@ auto RenderTarget::GetScissorX(float x) const -> float { } } } + auto RenderTarget::GetScissorY(float y) const -> float { assert(g_core); if (g_core->vr_mode()) { @@ -60,6 +61,7 @@ auto RenderTarget::GetScissorY(float y) const -> float { } } } + auto RenderTarget::GetScissorScaleX() const -> float { assert(g_core); if (g_core->vr_mode()) { diff --git a/src/ballistica/base/graphics/renderer/render_target.h b/src/ballistica/base/graphics/renderer/render_target.h index 8ccc0a8d..7c28ce29 100644 --- a/src/ballistica/base/graphics/renderer/render_target.h +++ b/src/ballistica/base/graphics/renderer/render_target.h @@ -14,7 +14,7 @@ class RenderTarget : public Object { auto GetThreadOwnership() const -> ThreadOwnership override { return ThreadOwnership::kGraphicsContext; } - enum class Type { kScreen, kFramebuffer }; + enum class Type : uint8_t { kScreen, kFramebuffer }; explicit RenderTarget(Type type); ~RenderTarget() override; @@ -36,10 +36,10 @@ class RenderTarget : public Object { auto GetScissorY(float y) const -> float; protected: - float physical_width_{}; - float physical_height_{}; bool depth_{}; Type type_{}; + float physical_width_{}; + float physical_height_{}; }; } // namespace ballistica::base diff --git a/src/ballistica/base/graphics/renderer/renderer.h b/src/ballistica/base/graphics/renderer/renderer.h index 0ab47c42..3bc6ccc2 100644 --- a/src/ballistica/base/graphics/renderer/renderer.h +++ b/src/ballistica/base/graphics/renderer/renderer.h @@ -193,6 +193,7 @@ class Renderer { virtual void RenderFrameDefEnd() = 0; virtual void CardboardDisableScissor() = 0; virtual void CardboardEnableScissor() = 0; + #if BA_VR_BUILD void VRTransformToRightHand(); void VRTransformToLeftHand(); @@ -207,30 +208,24 @@ class Renderer { void DrawWorldToCameraBuffer(FrameDef* frame_def); void UpdatePixelScaleAndBackingBuffer(FrameDef* frame_def); void UpdateCameraRenderTargets(FrameDef* frame_def); - // #if BA_OSTYPE_MACOS && BA_SDL_BUILD && !BA_SDL2_BUILD - // void HandleFunkyMacGammaIssue(FrameDef* frame_def); - // #endif void LoadMedia(FrameDef* frame_def); void UpdateDOFParams(FrameDef* frame_def); + #if BA_VR_BUILD void VRPreprocess(FrameDef* frame_def); void VRUpdateForEyeRender(FrameDef* frame_def); void VRDrawOverlayFlatPass(FrameDef* frame_def); +#endif // BA_VR_BUILD + +#if BA_VR_BUILD + + bool vr_use_fov_tangents_{}; + // Raw values from vr system. VRHandsState vr_raw_hands_state_{}; - float vr_raw_head_tx_{}; - float vr_raw_head_ty_{}; - float vr_raw_head_tz_{}; - float vr_raw_head_yaw_{}; - float vr_raw_head_pitch_{}; - float vr_raw_head_roll_{}; - // Final game-space transforms. - Matrix44f vr_base_transform_{kMatrix44fIdentity}; - Matrix44f vr_transform_right_hand_{kMatrix44fIdentity}; - Matrix44f vr_transform_left_hand_{kMatrix44fIdentity}; - Matrix44f vr_transform_head_{kMatrix44fIdentity}; - // Values for current eye render. - bool vr_use_fov_tangents_{}; + int vr_eye_{}; + int vr_viewport_x_{}; + int vr_viewport_y_{}; float vr_fov_l_tan_{1.0f}; float vr_fov_r_tan_{1.0f}; float vr_fov_b_tan_{1.0f}; @@ -240,37 +235,59 @@ class Renderer { float vr_eye_x_{}; float vr_eye_y_{}; float vr_eye_z_{}; - int vr_eye_{}; float vr_eye_yaw_{}; float vr_eye_pitch_{}; float vr_eye_roll_{}; - int vr_viewport_x_{}; - int vr_viewport_y_{}; + float vr_raw_head_tx_{}; + float vr_raw_head_ty_{}; + float vr_raw_head_tz_{}; + float vr_raw_head_yaw_{}; + float vr_raw_head_pitch_{}; + float vr_raw_head_roll_{}; + Matrix44f vr_base_transform_{kMatrix44fIdentity}; + Matrix44f vr_transform_right_hand_{kMatrix44fIdentity}; + Matrix44f vr_transform_left_hand_{kMatrix44fIdentity}; + Matrix44f vr_transform_head_{kMatrix44fIdentity}; #endif // BA_VR_BUILD + // The *actual* current quality (set based on the currently-rendering + // frame_def) + GraphicsQuality last_render_quality_{GraphicsQuality::kLow}; + bool debug_draw_mode_{}; bool screen_size_dirty_{}; bool msaa_enabled_dirty_{}; - millisecs_t dof_update_time_{}; bool dof_delay_{true}; + bool drawing_reflection_{}; + bool shadow_ortho_{}; + + int last_commands_buffer_size_{}; + int last_f_vals_buffer_size_{}; + int last_i_vals_buffer_size_{}; + int last_meshes_buffer_size_{}; + int last_textures_buffer_size_{}; + int frames_rendered_count_{}; + int blur_res_count_{}; + int shadow_res_{-1}; + float dof_near_smoothed_{}; float dof_far_smoothed_{}; - bool drawing_reflection_{}; - int blur_res_count_{}; float light_pitch_{}; float light_heading_{}; float light_tz_{-22.0f}; - Vector3f shadow_offset_{0.0f, 0.0f, 0.0f}; float shadow_scale_x_{1.0f}; float shadow_scale_z_{1.0f}; - bool shadow_ortho_{}; + float screen_gamma_{1.0f}; + float pixel_scale_requested_{1.0f}; + float pixel_scale_{1.0f}; + + millisecs_t last_screen_gamma_update_time_{}; + millisecs_t dof_update_time_{}; + + Vector3f shadow_offset_{0.0f, 0.0f, 0.0f}; Vector3f tint_{1.0f, 1.0f, 1.0f}; Vector3f ambient_color_{1.0f, 1.0f, 1.0f}; Vector3f vignette_outer_{0.0f, 0.0f, 0.0f}; Vector3f vignette_inner_{1.0f, 1.0f, 1.0f}; - int shadow_res_{-1}; - float screen_gamma_{1.0f}; - float pixel_scale_requested_{1.0f}; - float pixel_scale_{1.0f}; Object::Ref screen_render_target_; Object::Ref backing_render_target_; Object::Ref camera_render_target_; @@ -278,18 +295,6 @@ class Renderer { Object::Ref light_render_target_; Object::Ref light_shadow_render_target_; Object::Ref vr_overlay_flat_render_target_; - millisecs_t last_screen_gamma_update_time_{}; - int last_commands_buffer_size_{}; - int last_f_vals_buffer_size_{}; - int last_i_vals_buffer_size_{}; - int last_meshes_buffer_size_{}; - int last_textures_buffer_size_{}; - bool debug_draw_mode_{}; - int frames_rendered_count_{}; - - // The *actual* current quality (set based on the - // currently-rendering frame_def) - GraphicsQuality last_render_quality_{GraphicsQuality::kLow}; }; } // namespace ballistica::base diff --git a/src/ballistica/base/input/input.cc b/src/ballistica/base/input/input.cc index 939e1c59..7718bc90 100644 --- a/src/ballistica/base/input/input.cc +++ b/src/ballistica/base/input/input.cc @@ -187,7 +187,7 @@ void Input::AnnounceConnects_() { ScreenMessage(s); } if (g_base->assets->sys_assets_loaded()) { - g_base->audio->PlaySound(g_base->assets->SysSound(SysSoundID::kGunCock)); + g_base->audio->SafePlaySysSound(SysSoundID::kGunCock); } } newly_connected_controllers_.clear(); @@ -210,7 +210,7 @@ void Input::AnnounceDisconnects_() { ScreenMessage(s); } if (g_base->assets->sys_assets_loaded()) { - g_base->audio->PlaySound(g_base->assets->SysSound(SysSoundID::kCorkPop)); + g_base->audio->SafePlaySysSound(SysSoundID::kCorkPop); } newly_disconnected_controllers_.clear(); diff --git a/src/ballistica/base/input/support/remote_app_server.cc b/src/ballistica/base/input/support/remote_app_server.cc index 268cb848..265c38ae 100644 --- a/src/ballistica/base/input/support/remote_app_server.cc +++ b/src/ballistica/base/input/support/remote_app_server.cc @@ -166,10 +166,8 @@ void RemoteAppServer::HandleData(int socket, uint8_t* buffer, size_t amt, g_base->graphics->screenmessages->AddScreenMessage( s, Vector3f(1, 1, 1)); }); - g_base->logic->event_loop()->PushCall([] { - g_base->audio->PlaySound( - g_base->assets->SysSound(SysSoundID::kCorkPop)); - }); + g_base->logic->event_loop()->PushCall( + [] { g_base->audio->SafePlaySysSound(SysSoundID::kCorkPop); }); g_base->input->PushRemoveInputDeviceCall(client->joystick_, false); client->joystick_ = nullptr; client->in_use = false; @@ -377,8 +375,7 @@ auto RemoteAppServer::GetClient(int request_id, struct sockaddr* addr, }); g_base->logic->event_loop()->PushCall([] { if (g_base->assets->asset_loads_allowed()) { - g_base->audio->PlaySound( - g_base->assets->SysSound(SysSoundID::kGunCock)); + g_base->audio->SafePlaySysSound(SysSoundID::kGunCock); } }); } @@ -429,8 +426,7 @@ auto RemoteAppServer::GetClient(int request_id, struct sockaddr* addr, g_base->logic->event_loop()->PushCall([] { if (g_base->assets->asset_loads_allowed()) { - g_base->audio->PlaySound( - g_base->assets->SysSound(SysSoundID::kGunCock)); + g_base->audio->SafePlaySysSound(SysSoundID::kGunCock); } }); diff --git a/src/ballistica/base/networking/network_reader.cc b/src/ballistica/base/networking/network_reader.cc index 0c44e9e1..40f64c25 100644 --- a/src/ballistica/base/networking/network_reader.cc +++ b/src/ballistica/base/networking/network_reader.cc @@ -218,7 +218,8 @@ auto NetworkReader::RunThread_() -> int { sd = sd6_; can_read = can_read_6; } else { - FatalError("Should not get here."); + FatalError("Should not get here; s_index=" + std::to_string(s_index) + + "."); sd = -1; can_read = false; } diff --git a/src/ballistica/base/ui/dev_console.cc b/src/ballistica/base/ui/dev_console.cc index 7360a9a0..abf1da1d 100644 --- a/src/ballistica/base/ui/dev_console.cc +++ b/src/ballistica/base/ui/dev_console.cc @@ -1110,7 +1110,7 @@ void DevConsole::ToggleState() { state_ = State_::kInactive; break; } - g_base->audio->PlaySound(g_base->assets->SysSound(SysSoundID::kBlip)); + g_base->audio->SafePlaySysSound(SysSoundID::kBlip); transition_start_ = g_base->logic->display_time(); } @@ -1445,8 +1445,7 @@ auto DevConsole::PasteFromClipboard() -> bool { if (g_base->ClipboardHasText()) { auto text = g_base->ClipboardGetText(); if (strstr(text.c_str(), "\n") || strstr(text.c_str(), "\r")) { - g_base->audio->PlaySound( - g_base->assets->SysSound(SysSoundID::kErrorBeep)); + g_base->audio->SafePlaySysSound(SysSoundID::kErrorBeep); ScreenMessage("Can only paste single lines of text.", Vector3f(1.0f, 0.0f, 0.0f)); } else { diff --git a/src/ballistica/base/ui/ui.cc b/src/ballistica/base/ui/ui.cc index eef389b3..aa20edb6 100644 --- a/src/ballistica/base/ui/ui.cc +++ b/src/ballistica/base/ui/ui.cc @@ -427,8 +427,7 @@ auto UI::GetWidgetForInput(InputDevice* input_device) -> ui_v1::Widget* { // they're not the chosen one. if (time - last_widget_input_reject_err_sound_time_ > 5000) { last_widget_input_reject_err_sound_time_ = time; - g_base->audio->PlaySound( - g_base->assets->SysSound(SysSoundID::kErrorBeep)); + g_base->audio->SafePlaySysSound(SysSoundID::kErrorBeep); print_menu_owner = true; } ret_val = nullptr; // Rejected! diff --git a/src/ballistica/core/core.cc b/src/ballistica/core/core.cc index f7bdc1ca..5cf8fb3f 100644 --- a/src/ballistica/core/core.cc +++ b/src/ballistica/core/core.cc @@ -8,6 +8,7 @@ #include "ballistica/core/platform/core_platform.h" #include "ballistica/core/python/core_python.h" #include "ballistica/shared/foundation/event_loop.h" +#include "ballistica/shared/foundation/types.h" namespace ballistica::core { @@ -75,7 +76,8 @@ void CoreFeatureSet::DoImport(const CoreConfig& config) { // didn't exist before. Can at least add an offset to give an accurate // time though. auto seconds_since_actual_start = - static_cast(CorePlatform::GetCurrentMillisecs() - start_millisecs) + static_cast(CorePlatform::GetCurrentMillisecs() + - start_millisecs) / 1000.0; g_core->LifecycleLog("core import begin", -seconds_since_actual_start); g_core->LifecycleLog("core import end"); @@ -320,9 +322,9 @@ auto CoreFeatureSet::GetAppTimeMicrosecs() -> microsecs_t { return app_time_microsecs_; } -auto CoreFeatureSet::GetAppTimeSeconds() -> double { +auto CoreFeatureSet::GetAppTimeSeconds() -> seconds_t { UpdateAppTime(); - return static_cast(app_time_microsecs_) / 1000000; + return static_cast(app_time_microsecs_) / 1000000; } void CoreFeatureSet::UpdateAppTime() { diff --git a/src/ballistica/core/core.h b/src/ballistica/core/core.h index d31d0e8d..7f42dc96 100644 --- a/src/ballistica/core/core.h +++ b/src/ballistica/core/core.h @@ -88,7 +88,7 @@ class CoreFeatureSet { /// App-time is basically the total time that the engine has been actively /// running. (The 'App' here is a slight misnomer). It will stop /// progressing while the app is suspended and will never go backwards. - auto GetAppTimeSeconds() -> double; + auto GetAppTimeSeconds() -> seconds_t; /// Are we in the 'main' thread? The thread that first inited Core is /// considered the 'main' thread; on most platforms it is the one where diff --git a/src/ballistica/core/python/core_python.cc b/src/ballistica/core/python/core_python.cc index 3c981e77..cc20c970 100644 --- a/src/ballistica/core/python/core_python.cc +++ b/src/ballistica/core/python/core_python.cc @@ -244,10 +244,12 @@ void CorePython::MonolithicModeBaEnvConfigure() { auto default_py_dir = std::string("ba_data") + BA_DIRSLASH + "python"; auto data_dir_mono_default = g_core->platform->GetDataDirectoryMonolithicDefault(); + // Keep path clean if data-dir val is ".". if (data_dir_mono_default != ".") { default_py_dir = data_dir_mono_default + BA_DIRSLASH + default_py_dir; } + auto args = PythonRef::Stolen(Py_BuildValue("(s)", default_py_dir.c_str())); objs().Get(ObjID::kPrependSysPathCall).Call(args); @@ -259,8 +261,9 @@ void CorePython::MonolithicModeBaEnvConfigure() { g_core->platform->GetDataDirectoryMonolithicDefault(); std::optional user_python_dir = g_core->platform->GetUserPythonDirectoryMonolithicDefault(); + + // clang-format off auto kwargs = - // clang-format off PythonRef::Stolen(Py_BuildValue( "{" "sO" // config_dir @@ -277,14 +280,15 @@ void CorePython::MonolithicModeBaEnvConfigure() { "contains_python_dist", g_buildconfig.contains_python_dist() ? Py_True : Py_False)); // clang-format on + auto result = objs() .Get(ObjID::kBaEnvConfigureCall) .Call(objs().Get(ObjID::kEmptyTuple), kwargs); if (!result.Exists()) { - FatalError( - "Environment setup failed.\n" - "This usually means you are running the app from the wrong location.\n" - "See log for details."); + FatalError("Environment setup failed (no error info available)."); + } + if (result.ValueIsString()) { + FatalError("Environment setup failed:\n" + result.ValueAsString()); } g_core->LifecycleLog("baenv.configure() end"); } diff --git a/src/ballistica/scene_v1/connection/connection_to_client.cc b/src/ballistica/scene_v1/connection/connection_to_client.cc index 896185b6..367e8e16 100644 --- a/src/ballistica/scene_v1/connection/connection_to_client.cc +++ b/src/ballistica/scene_v1/connection/connection_to_client.cc @@ -82,8 +82,9 @@ ConnectionToClient::~ConnectionToClient() { std::string s = g_base->assets->GetResourceString("playerLeftPartyText"); Utils::StringReplaceOne(&s, "${NAME}", peer_spec().GetDisplayString()); ScreenMessage(s, {1, 0.5f, 0.0f}); - g_base->audio->PlaySound( - g_base->assets->SysSound(base::SysSoundID::kCorkPop)); + if (g_base->assets->sys_assets_loaded()) { + g_base->audio->SafePlaySysSound(base::SysSoundID::kCorkPop); + } } } @@ -234,8 +235,9 @@ void ConnectionToClient::HandleGamePacket(const std::vector& data) { Utils::StringReplaceOne(&s, "${NAME}", peer_spec().GetDisplayString()); ScreenMessage(s, {0.5f, 1, 0.5f}); - g_base->audio->PlaySound( - g_base->assets->SysSound(base::SysSoundID::kGunCock)); + if (g_base->assets->sys_assets_loaded()) { + g_base->audio->SafePlaySysSound(base::SysSoundID::kGunCock); + } } // Also mark the time for flashing the 'someone just joined your diff --git a/src/ballistica/scene_v1/connection/connection_to_host.cc b/src/ballistica/scene_v1/connection/connection_to_host.cc index 93503988..e1093e14 100644 --- a/src/ballistica/scene_v1/connection/connection_to_host.cc +++ b/src/ballistica/scene_v1/connection/connection_to_host.cc @@ -45,8 +45,7 @@ ConnectionToHost::~ConnectionToHost() { Utils::StringReplaceOne(&s, "${NAME}", peer_spec().GetDisplayString()); } ScreenMessage(s, {1, 0.5f, 0.0f}); - g_base->audio->PlaySound( - g_base->assets->SysSound(base::SysSoundID::kCorkPop)); + g_base->audio->SafePlaySysSound(base::SysSoundID::kCorkPop); } else { ScreenMessage(g_base->assets->GetResourceString("connectionRejectedText"), {1, 0, 0}); @@ -413,8 +412,7 @@ void ConnectionToHost::HandleMessagePacket(const std::vector& buffer) { Utils::StringReplaceOne( &s, "${NAME}", PlayerSpec(str_buffer.data()).GetDisplayString()); ScreenMessage(s, {0.5f, 1.0f, 0.5f}); - g_base->audio->PlaySound( - g_base->assets->SysSound(base::SysSoundID::kGunCock)); + g_base->audio->SafePlaySysSound(base::SysSoundID::kGunCock); } break; } @@ -430,8 +428,7 @@ void ConnectionToHost::HandleMessagePacket(const std::vector& buffer) { Utils::StringReplaceOne( &s, "${NAME}", PlayerSpec(&(str_buffer[0])).GetDisplayString()); ScreenMessage(s, {1, 0.5f, 0.0f}); - g_base->audio->PlaySound( - g_base->assets->SysSound(base::SysSoundID::kCorkPop)); + g_base->audio->SafePlaySysSound(base::SysSoundID::kCorkPop); } break; } @@ -571,8 +568,7 @@ void ConnectionToHost::HandleMessagePacket(const std::vector& buffer) { Utils::StringReplaceOne(&s, "${NAME}", peer_spec().GetDisplayString()); } ScreenMessage(s, {0.5f, 1, 0.5f}); - g_base->audio->PlaySound( - g_base->assets->SysSound(base::SysSoundID::kGunCock)); + g_base->audio->SafePlaySysSound(base::SysSoundID::kGunCock); printed_connect_message_ = true; } diff --git a/src/ballistica/scene_v1/node/prop_node.cc b/src/ballistica/scene_v1/node/prop_node.cc index ed94268a..5153a1e7 100644 --- a/src/ballistica/scene_v1/node/prop_node.cc +++ b/src/ballistica/scene_v1/node/prop_node.cc @@ -100,7 +100,7 @@ void PropNode::SetIsAreaOfInterest(bool val) { void PropNode::Draw(base::FrameDef* frame_def) { #if !BA_HEADLESS_BUILD - // need our texture, mesh, and body to be present to draw.. + // We need a texture, mesh, and body to be present to draw. if ((!mesh_.Exists()) || (!color_texture_.Exists()) || (!body_.Exists())) { return; } diff --git a/src/ballistica/scene_v1/support/scene_v1_app_mode.cc b/src/ballistica/scene_v1/support/scene_v1_app_mode.cc index 72cfdbd2..d61238bc 100644 --- a/src/ballistica/scene_v1/support/scene_v1_app_mode.cc +++ b/src/ballistica/scene_v1/support/scene_v1_app_mode.cc @@ -1160,8 +1160,7 @@ void SceneV1AppMode::LocalDisplayChatMessage( g_scene_v1->python->HandleLocalChatMessage(final_message); } if (!chat_muted_) { - g_base->audio->PlaySound( - g_base->assets->SysSound(base::SysSoundID::kTap)); + g_base->audio->SafePlaySysSound(base::SysSoundID::kTap); } } } diff --git a/src/ballistica/shared/ballistica.cc b/src/ballistica/shared/ballistica.cc index c0da047b..ffd8e494 100644 --- a/src/ballistica/shared/ballistica.cc +++ b/src/ballistica/shared/ballistica.cc @@ -39,7 +39,7 @@ auto main(int argc, char** argv) -> int { namespace ballistica { // These are set automatically via script; don't modify them here. -const int kEngineBuildNumber = 21743; +const int kEngineBuildNumber = 21747; const char* kEngineVersion = "1.7.33"; const int kEngineApiVersion = 8; diff --git a/src/ballistica/shared/foundation/fatal_error.cc b/src/ballistica/shared/foundation/fatal_error.cc index 3fb5c7ea..5eca6f17 100644 --- a/src/ballistica/shared/foundation/fatal_error.cc +++ b/src/ballistica/shared/foundation/fatal_error.cc @@ -11,8 +11,9 @@ namespace ballistica { -// Note: implicitly using core's internal globals here, so our behavior is -// undefined if core has not been imported by *someone*. +// Note: implicitly using core's internal globals here, but we should try to +// behave reasonably if they're not inited since fatal errors can happen any +// time. using core::g_base_soft; using core::g_core; @@ -121,8 +122,8 @@ void FatalError::ReportFatalError(const std::string& message, std::string prefix = "FATAL-ERROR-LOG:"; std::string suffix; - // If we have no core state yet, include this message explicitly - // since it won't be part of the standard log. + // If we have no core state yet, include this message explicitly since it + // won't be part of the standard log. if (g_core == nullptr) { suffix = logmsg; } @@ -147,7 +148,7 @@ void FatalError::ReportFatalError(const std::string& message, } void FatalError::DoBlockingFatalErrorDialog(const std::string& message) { - // We should not get here without this intact. + // Should not be possible to get here without this intact. assert(g_core); // If we're in the main thread; just fire off the dialog directly. // Otherwise tell the main thread to do it and wait around until it's diff --git a/src/ballistica/shared/python/python_ref.cc b/src/ballistica/shared/python/python_ref.cc index 51f0d88c..eb74d121 100644 --- a/src/ballistica/shared/python/python_ref.cc +++ b/src/ballistica/shared/python/python_ref.cc @@ -157,6 +157,12 @@ auto PythonRef::ValueIsNone() const -> bool { return obj_ == Py_None; } +auto PythonRef::ValueIsString() const -> bool { + assert(Python::HaveGIL()); + ThrowIfUnset(); + return Python::IsPyString(obj_); +} + auto PythonRef::ValueAsLString() const -> std::string { assert(Python::HaveGIL()); ThrowIfUnset(); diff --git a/src/ballistica/shared/python/python_ref.h b/src/ballistica/shared/python/python_ref.h index b2455d26..9a7ae3b4 100644 --- a/src/ballistica/shared/python/python_ref.h +++ b/src/ballistica/shared/python/python_ref.h @@ -171,6 +171,7 @@ class PythonRef { /// Throws an exception for other types. auto ValueAsLString() const -> std::string; + auto ValueIsString() const -> bool; auto ValueAsString() const -> std::string; auto ValueAsStringSequence() const -> std::list; auto ValueAsOptionalString() const -> std::optional; diff --git a/src/ballistica/ui_v1/python/ui_v1_python.cc b/src/ballistica/ui_v1/python/ui_v1_python.cc index bc914d47..7abd295b 100644 --- a/src/ballistica/ui_v1/python/ui_v1_python.cc +++ b/src/ballistica/ui_v1/python/ui_v1_python.cc @@ -107,7 +107,7 @@ void UIV1Python::InvokeStringEditor(PyObject* string_edit_adapter_instance) { BA_PRECONDITION(string_edit_adapter_instance); base::ScopedSetContext ssc(nullptr); - g_base->audio->PlaySound(g_base->assets->SysSound(base::SysSoundID::kSwish)); + g_base->audio->SafePlaySysSound(base::SysSoundID::kSwish); PythonRef args(Py_BuildValue("(O)", string_edit_adapter_instance), PythonRef::kSteal); @@ -139,7 +139,7 @@ void UIV1Python::InvokeQuitWindow(QuitType quit_type) { } } - g_base->audio->PlaySound(g_base->assets->SysSound(base::SysSoundID::kSwish)); + g_base->audio->SafePlaySysSound(base::SysSoundID::kSwish); auto py_enum = g_base->python->PyQuitType(quit_type); auto args = PythonRef::Stolen(Py_BuildValue("(O)", py_enum.Get())); objs().Get(UIV1Python::ObjID::kQuitWindowCall).Call(args); diff --git a/src/ballistica/ui_v1/widget/button_widget.cc b/src/ballistica/ui_v1/widget/button_widget.cc index e992098c..9b84d87c 100644 --- a/src/ballistica/ui_v1/widget/button_widget.cc +++ b/src/ballistica/ui_v1/widget/button_widget.cc @@ -557,14 +557,11 @@ void ButtonWidget::DoActivate(bool is_repeat) { if (sound_enabled_) { int r = rand() % 3; // NOLINT if (r == 0) { - g_base->audio->PlaySound( - g_base->assets->SysSound(base::SysSoundID::kSwish)); + g_base->audio->SafePlaySysSound(base::SysSoundID::kSwish); } else if (r == 1) { - g_base->audio->PlaySound( - g_base->assets->SysSound(base::SysSoundID::kSwish2)); + g_base->audio->SafePlaySysSound(base::SysSoundID::kSwish2); } else { - g_base->audio->PlaySound( - g_base->assets->SysSound(base::SysSoundID::kSwish3)); + g_base->audio->SafePlaySysSound(base::SysSoundID::kSwish3); } } if (auto* call = on_activate_call_.Get()) { diff --git a/src/ballistica/ui_v1/widget/check_box_widget.cc b/src/ballistica/ui_v1/widget/check_box_widget.cc index 2159d048..c77a0ef8 100644 --- a/src/ballistica/ui_v1/widget/check_box_widget.cc +++ b/src/ballistica/ui_v1/widget/check_box_widget.cc @@ -237,7 +237,7 @@ void CheckBoxWidget::SetValue(bool value) { } void CheckBoxWidget::Activate() { - g_base->audio->PlaySound(g_base->assets->SysSound(base::SysSoundID::kSwish3)); + g_base->audio->SafePlaySysSound(base::SysSoundID::kSwish3); checked_ = !checked_; check_dirty_ = true; last_change_time_ = g_core->GetAppTimeMillisecs(); diff --git a/src/ballistica/ui_v1/widget/container_widget.cc b/src/ballistica/ui_v1/widget/container_widget.cc index 8d315738..37495e0a 100644 --- a/src/ballistica/ui_v1/widget/container_widget.cc +++ b/src/ballistica/ui_v1/widget/container_widget.cc @@ -607,8 +607,7 @@ auto ContainerWidget::HandleMessage(const base::WidgetMessage& m) -> bool { // First click just selects. if (click_count == 1) { - g_base->audio->PlaySound( - g_base->assets->SysSound(base::SysSoundID::kTap)); + g_base->audio->SafePlaySysSound(base::SysSoundID::kTap); } } else { // Special case: If we've got a child text widget that's @@ -1637,8 +1636,7 @@ void ContainerWidget::SelectDownWidget() { // Avoid tap sounds and whatnot if we're just re-selecting ourself. if (w != selected_widget_) { w->GlobalSelect(); - g_base->audio->PlaySound( - g_base->assets->SysSound(base::SysSoundID::kTap)); + g_base->audio->SafePlaySysSound(base::SysSoundID::kTap); } } } else { @@ -1702,8 +1700,7 @@ void ContainerWidget::SelectUpWidget() { // Avoid tap sounds and whatnot if we're just re-selecting ourself. if (w != selected_widget_) { w->GlobalSelect(); - g_base->audio->PlaySound( - g_base->assets->SysSound(base::SysSoundID::kTap)); + g_base->audio->SafePlaySysSound(base::SysSoundID::kTap); } } } else { @@ -1755,8 +1752,7 @@ void ContainerWidget::SelectLeftWidget() { // Avoid tap sounds and whatnot if we're just re-selecting ourself. if (w != selected_widget_) { w->GlobalSelect(); - g_base->audio->PlaySound( - g_base->assets->SysSound(base::SysSoundID::kTap)); + g_base->audio->SafePlaySysSound(base::SysSoundID::kTap); } } } else { @@ -1808,8 +1804,7 @@ void ContainerWidget::SelectRightWidget() { // Avoid tap sounds and whatnot if we're just re-selecting ourself. if (w != selected_widget_) { w->GlobalSelect(); - g_base->audio->PlaySound( - g_base->assets->SysSound(base::SysSoundID::kTap)); + g_base->audio->SafePlaySysSound(base::SysSoundID::kTap); } } } else { @@ -1891,8 +1886,7 @@ void ContainerWidget::SelectNextWidget() { } if ((**i).IsSelectable() && (**i).IsSelectableViaKeys()) { SelectWidget(&(**i), SelectionCause::NEXT_SELECTED); - g_base->audio->PlaySound( - g_base->assets->SysSound(base::SysSoundID::kTap)); + g_base->audio->SafePlaySysSound(base::SysSoundID::kTap); return; } i++; @@ -1907,8 +1901,7 @@ void ContainerWidget::PrintExitListInstructions( if ((t - old_last_prev_next_time > 250) && (t - last_list_exit_instructions_print_time_ > 5000)) { last_list_exit_instructions_print_time_ = t; - g_base->audio->PlaySound( - g_base->assets->SysSound(base::SysSoundID::kErrorBeep)); + g_base->audio->SafePlaySysSound(base::SysSoundID::kErrorBeep); std::string s = g_base->assets->GetResourceString("arrowsToExitListText"); { // Left arrow. @@ -1981,8 +1974,7 @@ void ContainerWidget::SelectPrevWidget() { if ((**i).IsSelectable() && (**i).IsSelectableViaKeys()) { SelectWidget(&(**i), SelectionCause::PREV_SELECTED); - g_base->audio->PlaySound( - g_base->assets->SysSound(base::SysSoundID::kTap)); + g_base->audio->SafePlaySysSound(base::SysSoundID::kTap); return; } i++; diff --git a/src/ballistica/ui_v1/widget/text_widget.cc b/src/ballistica/ui_v1/widget/text_widget.cc index cd291550..b9f422f0 100644 --- a/src/ballistica/ui_v1/widget/text_widget.cc +++ b/src/ballistica/ui_v1/widget/text_widget.cc @@ -711,8 +711,7 @@ auto TextWidget::HandleMessage(const base::WidgetMessage& m) -> bool { case SDLK_KP_ENTER: if (g_buildconfig.ostype_ios_tvos() || g_buildconfig.ostype_android()) { // On mobile, return currently just deselects us. - g_base->audio->PlaySound( - g_base->assets->SysSound(base::SysSoundID::kSwish)); + g_base->audio->SafePlaySysSound(base::SysSoundID::kSwish); parent_widget()->SelectWidget(nullptr); return true; } else { @@ -847,8 +846,7 @@ auto TextWidget::HandleMessage(const base::WidgetMessage& m) -> bool { pressed_activate_ = (click_count == 2 || click_activate_) && !editable_; if (click_count == 1) { - g_base->audio->PlaySound( - g_base->assets->SysSound(base::SysSoundID::kTap)); + g_base->audio->SafePlaySysSound(base::SysSoundID::kTap); } } return true; @@ -871,8 +869,7 @@ auto TextWidget::HandleMessage(const base::WidgetMessage& m) -> bool { carat_position_ = 0; text_group_dirty_ = true; clear_pressed_ = false; - g_base->audio->PlaySound( - g_base->assets->SysSound(base::SysSoundID::kTap)); + g_base->audio->SafePlaySysSound(base::SysSoundID::kTap); return true; } clear_pressed_ = false; diff --git a/src/meta/bacoremeta/pyembed/env.py b/src/meta/bacoremeta/pyembed/env.py index fde574a8..22912f88 100644 --- a/src/meta/bacoremeta/pyembed/env.py +++ b/src/meta/bacoremeta/pyembed/env.py @@ -23,16 +23,27 @@ def import_baenv_and_run_configure( data_dir: str | None, user_python_dir: str | None, contains_python_dist: bool, -) -> None: - """Import baenv and run its configure method.""" - import baenv +) -> None | str: + """Import baenv and run its configure method. - baenv.configure( - config_dir=config_dir, - data_dir=data_dir, - user_python_dir=user_python_dir, - contains_python_dist=contains_python_dist, - ) + On success, returns None. On Failure, attempts to return an error + traceback as a string (logging may not yet be functional at this point + so we need to be direct). + """ + try: + import baenv + + baenv.configure( + config_dir=config_dir, + data_dir=data_dir, + user_python_dir=user_python_dir, + contains_python_dist=contains_python_dist, + ) + return None + except Exception: + import traceback + + return traceback.format_exc() def get_env_config() -> baenv.EnvConfig: