mirror of
https://github.com/RYDE-WORK/ballistica.git
synced 2026-02-02 21:45:49 +08:00
work on user-defined dev-console tabs
This commit is contained in:
parent
50f91361f4
commit
f25f31cce4
60
.efrocachemap
generated
60
.efrocachemap
generated
@ -4056,26 +4056,26 @@
|
|||||||
"build/assets/windows/Win32/ucrtbased.dll": "2def5335207d41b21b9823f6805997f1",
|
"build/assets/windows/Win32/ucrtbased.dll": "2def5335207d41b21b9823f6805997f1",
|
||||||
"build/assets/windows/Win32/vc_redist.x86.exe": "b08a55e2e77623fe657bea24f223a3ae",
|
"build/assets/windows/Win32/vc_redist.x86.exe": "b08a55e2e77623fe657bea24f223a3ae",
|
||||||
"build/assets/windows/Win32/vcruntime140d.dll": "865b2af4d1e26a1a8073c89acb06e599",
|
"build/assets/windows/Win32/vcruntime140d.dll": "865b2af4d1e26a1a8073c89acb06e599",
|
||||||
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "fdcef1a7c77ad3cb23d7339fb1be2bf0",
|
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "06130b0dfceeb424ba1b66414cf6d930",
|
||||||
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "da17b5cc5f83bed3a0df7d238ba52d62",
|
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "9ea9b12078443053eee0e0be5137492d",
|
||||||
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "f550cb252d584f5ad7a100d9bb65d07a",
|
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "31f82f74a30d97d6bc66b2fa8d3abbcd",
|
||||||
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "6ce0af256949280a4820b96388e9d33c",
|
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "7ba3fa11b4e22b42aa16b8f0f904ea70",
|
||||||
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "65d75cd5909aa24e5c554c39d8aa7425",
|
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "230141db6263d696c28ad00c011f0f9e",
|
||||||
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "7e2267b47b1075da9737005d3d6821a3",
|
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "1e0a508a1fbd20f7e8a1ed79e361ecc6",
|
||||||
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "6429f3fbddc8f71a29588486c9e0135f",
|
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "ad6f15fdb1b3956b08d73abb4a0b240d",
|
||||||
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "48e5146f5a93e62d0c42d902d928f123",
|
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "49edc04b213fd8bb10d3227e27921fe8",
|
||||||
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "497c7b622b63b47268a4e55f439b00b1",
|
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "169375157927ea3a826d06a2f3339ccc",
|
||||||
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "2d54d79c942f48f6de4f07496b5c7d9c",
|
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "ed4a2bf5ef5c9e90c4a34a94e82e1752",
|
||||||
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "0959c5af017a58f487d353d56cfb3fc5",
|
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "4a8df3bd047824c139d271cb82db06d5",
|
||||||
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "ce4e095b7f36cf0f1c5d39bd196087a6",
|
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "a4b0933ce9220822302d660865766891",
|
||||||
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "3afafa7c2b660d60c740bc152898f1b8",
|
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "a22db827c37da85d73d248be95f07523",
|
||||||
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "db0e1929b4fcfc55295fd401a8c19e3a",
|
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "49bb13ad22a1f5a75246a21830689998",
|
||||||
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "78c06393fc28e1d5ba8dac8ab97ba07e",
|
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "98aa51efb0554fadd446f48b8cb6f31e",
|
||||||
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "fbada26a44865ad20b621641d4f1bf47",
|
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "4450820bb5a73e7b83004a3fe78a50d6",
|
||||||
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "63d57d508d8f9ae21e05ceda181e1a2d",
|
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "cff958f088a5bea303a846dbd0d96e14",
|
||||||
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "2c4f7247938de3d3fbb65b5766263866",
|
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "b2cbf2eee4db47d8d4e1ce0df1c80214",
|
||||||
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "85ef605dc94c4be74aac5b15a8931da5",
|
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "3aa845292833b423a7b96263b368bb13",
|
||||||
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "a39d6180a89b83463fc44f1b006ebc7d",
|
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "2b2a64c6fb1d73d6ddfc19dc597a0947",
|
||||||
"build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "6ce4983e76e1cc2d2803fe306d08ad58",
|
"build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "6ce4983e76e1cc2d2803fe306d08ad58",
|
||||||
"build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "4ea0cf78901f994215f215aebb0af1dc",
|
"build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "4ea0cf78901f994215f215aebb0af1dc",
|
||||||
"build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "6ce4983e76e1cc2d2803fe306d08ad58",
|
"build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "6ce4983e76e1cc2d2803fe306d08ad58",
|
||||||
@ -4092,18 +4092,18 @@
|
|||||||
"build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "de83e1b384abb333f457f2c9646f810f",
|
"build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "de83e1b384abb333f457f2c9646f810f",
|
||||||
"build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "0149ef8dae7720330416846919a834e7",
|
"build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "0149ef8dae7720330416846919a834e7",
|
||||||
"build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "de83e1b384abb333f457f2c9646f810f",
|
"build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "de83e1b384abb333f457f2c9646f810f",
|
||||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "e3ad15ecc9656a1a268582b14336bed7",
|
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "163fbb4576a5218685919cf04de63cc6",
|
||||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "fce3fd45ed78f84592ef914450817778",
|
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "66bbf458c1778685d38d6a2a537f6012",
|
||||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "feeb14560de0fa18d8b7654aa43534ea",
|
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "1ff129f72dc2dddc24d4dcdfb9b2826a",
|
||||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "7896041f53b6f076d032388d661413b0",
|
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "12d9566016a1bbd2aeb873d598d9ceed",
|
||||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "a5b84aaf028c8b13d55d2d99f3853f5d",
|
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "ba99295cfbcbb3f6da27e4fad8227d74",
|
||||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "4a8387851909f5cedabb5972b397a7b1",
|
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "8d53587d097910667fcb7f4958e55384",
|
||||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "53fa53d605a009a6ab592e30d45629a8",
|
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "4f3e5d9578c0b0c3bd1203755fe8d464",
|
||||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "2988d1791814f0ec0d64914d691a100e",
|
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "ab834d0257bec7c972a2587a0b34eeff",
|
||||||
"src/assets/ba_data/python/babase/_mgen/__init__.py": "f885fed7f2ed98ff2ba271f9dbe3391c",
|
"src/assets/ba_data/python/babase/_mgen/__init__.py": "f885fed7f2ed98ff2ba271f9dbe3391c",
|
||||||
"src/assets/ba_data/python/babase/_mgen/enums.py": "f8cd3af311ac63147882590123b78318",
|
"src/assets/ba_data/python/babase/_mgen/enums.py": "f8cd3af311ac63147882590123b78318",
|
||||||
"src/ballistica/base/mgen/pyembed/binding_base.inc": "c81b2b1f3a14b4cd20a7b93416fe893a",
|
"src/ballistica/base/mgen/pyembed/binding_base.inc": "9f71f171464dc004dbaab87e9bb4b03b",
|
||||||
"src/ballistica/base/mgen/pyembed/binding_base_app.inc": "b67add3e1346f63491bf3450148e60d4",
|
"src/ballistica/base/mgen/pyembed/binding_base_app.inc": "a521bc86a7e98e56fec14cea029996f8",
|
||||||
"src/ballistica/classic/mgen/pyembed/binding_classic.inc": "3ceb412513963f0818ab39c58bf292e3",
|
"src/ballistica/classic/mgen/pyembed/binding_classic.inc": "3ceb412513963f0818ab39c58bf292e3",
|
||||||
"src/ballistica/core/mgen/pyembed/binding_core.inc": "9d0a3c9636138e35284923e0c8311c69",
|
"src/ballistica/core/mgen/pyembed/binding_core.inc": "9d0a3c9636138e35284923e0c8311c69",
|
||||||
"src/ballistica/core/mgen/pyembed/env.inc": "8be46e5818f360d10b7b0224a9e91d07",
|
"src/ballistica/core/mgen/pyembed/env.inc": "8be46e5818f360d10b7b0224a9e91d07",
|
||||||
|
|||||||
3
.idea/dictionaries/ericf.xml
generated
3
.idea/dictionaries/ericf.xml
generated
@ -2923,6 +2923,8 @@
|
|||||||
<w>syslogmodule</w>
|
<w>syslogmodule</w>
|
||||||
<w>sysresponse</w>
|
<w>sysresponse</w>
|
||||||
<w>tabdefs</w>
|
<w>tabdefs</w>
|
||||||
|
<w>tabentry</w>
|
||||||
|
<w>tabname</w>
|
||||||
<w>tabtype</w>
|
<w>tabtype</w>
|
||||||
<w>tabtypes</w>
|
<w>tabtypes</w>
|
||||||
<w>tabval</w>
|
<w>tabval</w>
|
||||||
@ -3351,6 +3353,7 @@
|
|||||||
<w>xcworkspacedata</w>
|
<w>xcworkspacedata</w>
|
||||||
<w>xdrlib</w>
|
<w>xdrlib</w>
|
||||||
<w>xhdpi</w>
|
<w>xhdpi</w>
|
||||||
|
<w>xhost</w>
|
||||||
<w>xinput</w>
|
<w>xinput</w>
|
||||||
<w>xjtp</w>
|
<w>xjtp</w>
|
||||||
<w>xmlbuilder</w>
|
<w>xmlbuilder</w>
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
### 1.7.28 (build 21401, api 8, 2023-09-29)
|
### 1.7.28 (build 21405, api 8, 2023-10-02)
|
||||||
|
|
||||||
- Massively cleaned up code related to rendering and window systems (OpenGL,
|
- Massively cleaned up code related to rendering and window systems (OpenGL,
|
||||||
SDL, etc). This code had been growing into a nasty tangle for 15 years
|
SDL, etc). This code had been growing into a nasty tangle for 15 years
|
||||||
|
|||||||
12
Makefile
12
Makefile
@ -135,6 +135,7 @@ resources-clean:
|
|||||||
cd src/resources && $(MAKE) clean
|
cd src/resources && $(MAKE) clean
|
||||||
|
|
||||||
# Build our generated sources.
|
# Build our generated sources.
|
||||||
|
#
|
||||||
# Meta builds can affect sources used by asset builds, resource builds, and
|
# Meta builds can affect sources used by asset builds, resource builds, and
|
||||||
# compiles, so it should be listed as a dependency of any of those.
|
# compiles, so it should be listed as a dependency of any of those.
|
||||||
meta: prereqs
|
meta: prereqs
|
||||||
@ -146,8 +147,8 @@ meta-clean:
|
|||||||
rm -f $(LAZYBUILDDIR)/meta
|
rm -f $(LAZYBUILDDIR)/meta
|
||||||
cd src/meta && $(MAKE) clean
|
cd src/meta && $(MAKE) clean
|
||||||
|
|
||||||
# Remove ALL files and directories that aren't managed by git
|
# Remove ALL files and directories that aren't managed by git (except for a
|
||||||
# (except for a few things such as localconfig.json).
|
# few things such as localconfig.json).
|
||||||
clean:
|
clean:
|
||||||
$(CHECK_CLEAN_SAFETY)
|
$(CHECK_CLEAN_SAFETY)
|
||||||
rm -rf build # Handle this part ourself; can confuse git.
|
rm -rf build # Handle this part ourself; can confuse git.
|
||||||
@ -160,9 +161,10 @@ clean-list:
|
|||||||
git clean -dnx $(ROOT_CLEAN_IGNORES)
|
git clean -dnx $(ROOT_CLEAN_IGNORES)
|
||||||
|
|
||||||
# Build/update dummy python modules.
|
# Build/update dummy python modules.
|
||||||
# IMPORTANT - building this target can kick off full builds/cleans and so
|
#
|
||||||
# it should not be built in parallel with other targets.
|
# IMPORTANT - building this target can kick off full builds/cleans and so it
|
||||||
# See py_check_prereqs target for more info.
|
# should not be built in parallel with other targets. See py_check_prereqs
|
||||||
|
# target for more info.
|
||||||
dummymodules: prereqs meta
|
dummymodules: prereqs meta
|
||||||
@$(PCOMMAND) lazybuild dummymodules_src $(LAZYBUILDDIR)/$@ \
|
@$(PCOMMAND) lazybuild dummymodules_src $(LAZYBUILDDIR)/$@ \
|
||||||
rm -rf build/dummymodules \&\& $(PCOMMAND) gen_dummy_modules
|
rm -rf build/dummymodules \&\& $(PCOMMAND) gen_dummy_modules
|
||||||
|
|||||||
3
ballisticakit-cmake/.idea/dictionaries/ericf.xml
generated
3
ballisticakit-cmake/.idea/dictionaries/ericf.xml
generated
@ -1733,6 +1733,8 @@
|
|||||||
<w>syscalls</w>
|
<w>syscalls</w>
|
||||||
<w>sysresponse</w>
|
<w>sysresponse</w>
|
||||||
<w>tabdefs</w>
|
<w>tabdefs</w>
|
||||||
|
<w>tabentry</w>
|
||||||
|
<w>tabname</w>
|
||||||
<w>tabtype</w>
|
<w>tabtype</w>
|
||||||
<w>tabtypes</w>
|
<w>tabtypes</w>
|
||||||
<w>talloc</w>
|
<w>talloc</w>
|
||||||
@ -1972,6 +1974,7 @@
|
|||||||
<w>xcrun</w>
|
<w>xcrun</w>
|
||||||
<w>xdiff</w>
|
<w>xdiff</w>
|
||||||
<w>xdist</w>
|
<w>xdist</w>
|
||||||
|
<w>xhost</w>
|
||||||
<w>xinput</w>
|
<w>xinput</w>
|
||||||
<w>xmax</w>
|
<w>xmax</w>
|
||||||
<w>xmin</w>
|
<w>xmin</w>
|
||||||
|
|||||||
@ -51,11 +51,6 @@ if (HEADLESS)
|
|||||||
endif ()
|
endif ()
|
||||||
find_package(OpenGL REQUIRED)
|
find_package(OpenGL REQUIRED)
|
||||||
find_package(OpenAL REQUIRED)
|
find_package(OpenAL REQUIRED)
|
||||||
if (APPLE)
|
|
||||||
# On mac this sets an include path that we don't need since
|
|
||||||
# we're using the system framework... should clean this up.
|
|
||||||
set(OPENAL_INCLUDE_DIR "")
|
|
||||||
endif ()
|
|
||||||
find_library(OGG_LIBRARY ogg)
|
find_library(OGG_LIBRARY ogg)
|
||||||
find_library(VORBISFILE_LIBRARY vorbisfile)
|
find_library(VORBISFILE_LIBRARY vorbisfile)
|
||||||
if (NOT OGG_LIBRARY)
|
if (NOT OGG_LIBRARY)
|
||||||
@ -77,8 +72,7 @@ endif ()
|
|||||||
# on Raspberry Pi builds. We never need to care about C++ abi compatibility
|
# on Raspberry Pi builds. We never need to care about C++ abi compatibility
|
||||||
# so just silencing them for now. Can maybe remove this later if they stop.
|
# so just silencing them for now. Can maybe remove this later if they stop.
|
||||||
if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
|
if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
|
||||||
set(CMAKE_CXX_FLAGS
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-psabi")
|
||||||
"${CMAKE_CXX_FLAGS} -Wno-psabi")
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(BA_SRC_ROOT ../src)
|
set(BA_SRC_ROOT ../src)
|
||||||
@ -800,11 +794,6 @@ target_link_libraries(ballisticakitbin PRIVATE
|
|||||||
${CMAKE_CURRENT_BINARY_DIR}/prefablib/libballisticaplus.a ode pthread ${Python_LIBRARIES}
|
${CMAKE_CURRENT_BINARY_DIR}/prefablib/libballisticaplus.a ode pthread ${Python_LIBRARIES}
|
||||||
${SDL2_LIBRARIES} ${EXTRA_LIBRARIES} dl)
|
${SDL2_LIBRARIES} ${EXTRA_LIBRARIES} dl)
|
||||||
|
|
||||||
# Hack for building on rpi; need to update my pi so I can remove this.
|
|
||||||
if(EXISTS "/home/pi")
|
|
||||||
target_link_libraries(ballisticakitbin PRIVATE dl util stdc++fs)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
# BallisticaKit modular shared library
|
# BallisticaKit modular shared library
|
||||||
# (for use with vanilla Python interpreters).
|
# (for use with vanilla Python interpreters).
|
||||||
|
|||||||
@ -98,7 +98,7 @@
|
|||||||
<MinimalRebuild>false</MinimalRebuild>
|
<MinimalRebuild>false</MinimalRebuild>
|
||||||
<ExceptionHandling>SyncCThrow</ExceptionHandling>
|
<ExceptionHandling>SyncCThrow</ExceptionHandling>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<AdditionalIncludeDirectories>../../src;../../src/external/windows/include/SDL2;../../src/external/windows/include/python;../../src/external/windows/include;../../src/external/open_dynamics_engine-ef;../../src/external/qrencode-3.4.4</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>../../src;../../src/external/windows/include/SDL2;../../src/external/windows/include/AL;../../src/external/windows/include/python;../../src/external/windows/include;../../src/external/open_dynamics_engine-ef;../../src/external/qrencode-3.4.4</AdditionalIncludeDirectories>
|
||||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
<FloatingPointModel>Fast</FloatingPointModel>
|
<FloatingPointModel>Fast</FloatingPointModel>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@ -122,7 +122,7 @@
|
|||||||
<MinimalRebuild>false</MinimalRebuild>
|
<MinimalRebuild>false</MinimalRebuild>
|
||||||
<ExceptionHandling>SyncCThrow</ExceptionHandling>
|
<ExceptionHandling>SyncCThrow</ExceptionHandling>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<AdditionalIncludeDirectories>../../src;../../src/external/windows/include/SDL2;../../src/external/windows/include/python;../../src/external/windows/include;../../src/external/open_dynamics_engine-ef</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>../../src;../../src/external/windows/include/SDL2;../../src/external/windows/include/AL;../../src/external/windows/include/python;../../src/external/windows/include;../../src/external/open_dynamics_engine-ef</AdditionalIncludeDirectories>
|
||||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
<FloatingPointModel>Fast</FloatingPointModel>
|
<FloatingPointModel>Fast</FloatingPointModel>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@ -147,7 +147,7 @@
|
|||||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
<ExceptionHandling>SyncCThrow</ExceptionHandling>
|
<ExceptionHandling>SyncCThrow</ExceptionHandling>
|
||||||
<SDLCheck>false</SDLCheck>
|
<SDLCheck>false</SDLCheck>
|
||||||
<AdditionalIncludeDirectories>../../src;../../src/external/windows/include/SDL2;../../src/external/windows/include/python;../../src/external/windows/include;../../src/external/open_dynamics_engine-ef</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>../../src;../../src/external/windows/include/SDL2;../../src/external/windows/include/AL;../../src/external/windows/include/python;../../src/external/windows/include;../../src/external/open_dynamics_engine-ef</AdditionalIncludeDirectories>
|
||||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
<FloatingPointModel>Fast</FloatingPointModel>
|
<FloatingPointModel>Fast</FloatingPointModel>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@ -172,7 +172,7 @@
|
|||||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
<ExceptionHandling>SyncCThrow</ExceptionHandling>
|
<ExceptionHandling>SyncCThrow</ExceptionHandling>
|
||||||
<SDLCheck>false</SDLCheck>
|
<SDLCheck>false</SDLCheck>
|
||||||
<AdditionalIncludeDirectories>../../src;../../src/external/windows/include/SDL2;../../src/external/windows/include/python;../../src/external/windows/include;../../src/external/open_dynamics_engine-ef</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>../../src;../../src/external/windows/include/SDL2;../../src/external/windows/include/AL;../../src/external/windows/include/python;../../src/external/windows/include;../../src/external/open_dynamics_engine-ef</AdditionalIncludeDirectories>
|
||||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
<FloatingPointModel>Fast</FloatingPointModel>
|
<FloatingPointModel>Fast</FloatingPointModel>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
|||||||
@ -100,7 +100,7 @@
|
|||||||
<ForcedIncludeFiles>stdafx.h</ForcedIncludeFiles>
|
<ForcedIncludeFiles>stdafx.h</ForcedIncludeFiles>
|
||||||
<MinimalRebuild>false</MinimalRebuild>
|
<MinimalRebuild>false</MinimalRebuild>
|
||||||
<ExceptionHandling>SyncCThrow</ExceptionHandling>
|
<ExceptionHandling>SyncCThrow</ExceptionHandling>
|
||||||
<AdditionalIncludeDirectories>../../src;../../src/external/windows/include/SDL2;../../src/external/windows/include/python;../../src/external/windows/include;../../src/external/open_dynamics_engine-ef</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>../../src;../../src/external/windows/include/SDL2;../../src/external/windows/include/AL;../../src/external/windows/include/python;../../src/external/windows/include;../../src/external/open_dynamics_engine-ef</AdditionalIncludeDirectories>
|
||||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
<FloatingPointModel>Fast</FloatingPointModel>
|
<FloatingPointModel>Fast</FloatingPointModel>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@ -122,7 +122,7 @@
|
|||||||
<ForcedIncludeFiles>stdafx.h</ForcedIncludeFiles>
|
<ForcedIncludeFiles>stdafx.h</ForcedIncludeFiles>
|
||||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
<MinimalRebuild>false</MinimalRebuild>
|
<MinimalRebuild>false</MinimalRebuild>
|
||||||
<AdditionalIncludeDirectories>../../src;../../src/external/windows/include/SDL2;../../src/external/windows/include/python;../../src/external/windows/include;../../src/external/open_dynamics_engine-ef</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>../../src;../../src/external/windows/include/SDL2;../../src/external/windows/include/AL;../../src/external/windows/include/python;../../src/external/windows/include;../../src/external/open_dynamics_engine-ef</AdditionalIncludeDirectories>
|
||||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
<FloatingPointModel>Fast</FloatingPointModel>
|
<FloatingPointModel>Fast</FloatingPointModel>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@ -144,7 +144,7 @@
|
|||||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
<ForcedIncludeFiles>stdafx.h</ForcedIncludeFiles>
|
<ForcedIncludeFiles>stdafx.h</ForcedIncludeFiles>
|
||||||
<ExceptionHandling>SyncCThrow</ExceptionHandling>
|
<ExceptionHandling>SyncCThrow</ExceptionHandling>
|
||||||
<AdditionalIncludeDirectories>../../src;../../src/external/windows/include/SDL2;../../src/external/windows/include/python;../../src/external/windows/include;../../src/external/open_dynamics_engine-ef</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>../../src;../../src/external/windows/include/SDL2;../../src/external/windows/include/AL;../../src/external/windows/include/python;../../src/external/windows/include;../../src/external/open_dynamics_engine-ef</AdditionalIncludeDirectories>
|
||||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
<FloatingPointModel>Fast</FloatingPointModel>
|
<FloatingPointModel>Fast</FloatingPointModel>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@ -168,7 +168,7 @@
|
|||||||
<ExceptionHandling>SyncCThrow</ExceptionHandling>
|
<ExceptionHandling>SyncCThrow</ExceptionHandling>
|
||||||
<ForcedIncludeFiles>stdafx.h</ForcedIncludeFiles>
|
<ForcedIncludeFiles>stdafx.h</ForcedIncludeFiles>
|
||||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
<AdditionalIncludeDirectories>../../src;../../src/external/windows/include/SDL2;../../src/external/windows/include/python;../../src/external/windows/include;../../src/external/open_dynamics_engine-ef</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>../../src;../../src/external/windows/include/SDL2;../../src/external/windows/include/AL;../../src/external/windows/include/python;../../src/external/windows/include;../../src/external/open_dynamics_engine-ef</AdditionalIncludeDirectories>
|
||||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
<FloatingPointModel>Fast</FloatingPointModel>
|
<FloatingPointModel>Fast</FloatingPointModel>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
|||||||
@ -14,6 +14,7 @@
|
|||||||
"ba_data/python/babase/__pycache__/_assetmanager.cpython-311.opt-1.pyc",
|
"ba_data/python/babase/__pycache__/_assetmanager.cpython-311.opt-1.pyc",
|
||||||
"ba_data/python/babase/__pycache__/_asyncio.cpython-311.opt-1.pyc",
|
"ba_data/python/babase/__pycache__/_asyncio.cpython-311.opt-1.pyc",
|
||||||
"ba_data/python/babase/__pycache__/_cloud.cpython-311.opt-1.pyc",
|
"ba_data/python/babase/__pycache__/_cloud.cpython-311.opt-1.pyc",
|
||||||
|
"ba_data/python/babase/__pycache__/_devconsole.cpython-311.opt-1.pyc",
|
||||||
"ba_data/python/babase/__pycache__/_emptyappmode.cpython-311.opt-1.pyc",
|
"ba_data/python/babase/__pycache__/_emptyappmode.cpython-311.opt-1.pyc",
|
||||||
"ba_data/python/babase/__pycache__/_env.cpython-311.opt-1.pyc",
|
"ba_data/python/babase/__pycache__/_env.cpython-311.opt-1.pyc",
|
||||||
"ba_data/python/babase/__pycache__/_error.cpython-311.opt-1.pyc",
|
"ba_data/python/babase/__pycache__/_error.cpython-311.opt-1.pyc",
|
||||||
@ -43,6 +44,7 @@
|
|||||||
"ba_data/python/babase/_assetmanager.py",
|
"ba_data/python/babase/_assetmanager.py",
|
||||||
"ba_data/python/babase/_asyncio.py",
|
"ba_data/python/babase/_asyncio.py",
|
||||||
"ba_data/python/babase/_cloud.py",
|
"ba_data/python/babase/_cloud.py",
|
||||||
|
"ba_data/python/babase/_devconsole.py",
|
||||||
"ba_data/python/babase/_emptyappmode.py",
|
"ba_data/python/babase/_emptyappmode.py",
|
||||||
"ba_data/python/babase/_env.py",
|
"ba_data/python/babase/_env.py",
|
||||||
"ba_data/python/babase/_error.py",
|
"ba_data/python/babase/_error.py",
|
||||||
|
|||||||
@ -172,6 +172,7 @@ SCRIPT_TARGETS_PY_PUBLIC = \
|
|||||||
$(BUILD_DIR)/ba_data/python/babase/_assetmanager.py \
|
$(BUILD_DIR)/ba_data/python/babase/_assetmanager.py \
|
||||||
$(BUILD_DIR)/ba_data/python/babase/_asyncio.py \
|
$(BUILD_DIR)/ba_data/python/babase/_asyncio.py \
|
||||||
$(BUILD_DIR)/ba_data/python/babase/_cloud.py \
|
$(BUILD_DIR)/ba_data/python/babase/_cloud.py \
|
||||||
|
$(BUILD_DIR)/ba_data/python/babase/_devconsole.py \
|
||||||
$(BUILD_DIR)/ba_data/python/babase/_emptyappmode.py \
|
$(BUILD_DIR)/ba_data/python/babase/_emptyappmode.py \
|
||||||
$(BUILD_DIR)/ba_data/python/babase/_env.py \
|
$(BUILD_DIR)/ba_data/python/babase/_env.py \
|
||||||
$(BUILD_DIR)/ba_data/python/babase/_error.py \
|
$(BUILD_DIR)/ba_data/python/babase/_error.py \
|
||||||
@ -445,6 +446,7 @@ SCRIPT_TARGETS_PYC_PUBLIC = \
|
|||||||
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_assetmanager.cpython-311.opt-1.pyc \
|
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_assetmanager.cpython-311.opt-1.pyc \
|
||||||
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_asyncio.cpython-311.opt-1.pyc \
|
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_asyncio.cpython-311.opt-1.pyc \
|
||||||
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_cloud.cpython-311.opt-1.pyc \
|
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_cloud.cpython-311.opt-1.pyc \
|
||||||
|
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_devconsole.cpython-311.opt-1.pyc \
|
||||||
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_emptyappmode.cpython-311.opt-1.pyc \
|
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_emptyappmode.cpython-311.opt-1.pyc \
|
||||||
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_env.cpython-311.opt-1.pyc \
|
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_env.cpython-311.opt-1.pyc \
|
||||||
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_error.cpython-311.opt-1.pyc \
|
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_error.cpython-311.opt-1.pyc \
|
||||||
|
|||||||
@ -114,6 +114,11 @@ from babase._apputils import (
|
|||||||
AppHealthMonitor,
|
AppHealthMonitor,
|
||||||
)
|
)
|
||||||
from babase._cloud import CloudSubsystem
|
from babase._cloud import CloudSubsystem
|
||||||
|
from babase._devconsole import (
|
||||||
|
DevConsoleTab,
|
||||||
|
DevConsoleTabEntry,
|
||||||
|
DevConsoleSubsystem,
|
||||||
|
)
|
||||||
from babase._emptyappmode import EmptyAppMode
|
from babase._emptyappmode import EmptyAppMode
|
||||||
from babase._error import (
|
from babase._error import (
|
||||||
print_exception,
|
print_exception,
|
||||||
@ -206,6 +211,9 @@ __all__ = [
|
|||||||
'ContextError',
|
'ContextError',
|
||||||
'ContextRef',
|
'ContextRef',
|
||||||
'DelegateNotFoundError',
|
'DelegateNotFoundError',
|
||||||
|
'DevConsoleTab',
|
||||||
|
'DevConsoleTabEntry',
|
||||||
|
'DevConsoleSubsystem',
|
||||||
'DisplayTime',
|
'DisplayTime',
|
||||||
'displaytime',
|
'displaytime',
|
||||||
'displaytimer',
|
'displaytimer',
|
||||||
|
|||||||
@ -24,6 +24,7 @@ from babase._appcomponent import AppComponentSubsystem
|
|||||||
from babase._appmodeselector import AppModeSelector
|
from babase._appmodeselector import AppModeSelector
|
||||||
from babase._appintent import AppIntentDefault, AppIntentExec
|
from babase._appintent import AppIntentDefault, AppIntentExec
|
||||||
from babase._stringedit import StringEditSubsystem
|
from babase._stringedit import StringEditSubsystem
|
||||||
|
from babase._devconsole import DevConsoleSubsystem
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
import asyncio
|
import asyncio
|
||||||
@ -164,6 +165,7 @@ class App:
|
|||||||
self.workspaces = WorkspaceSubsystem()
|
self.workspaces = WorkspaceSubsystem()
|
||||||
self.components = AppComponentSubsystem()
|
self.components = AppComponentSubsystem()
|
||||||
self.stringedit = StringEditSubsystem()
|
self.stringedit = StringEditSubsystem()
|
||||||
|
self.devconsole = DevConsoleSubsystem()
|
||||||
|
|
||||||
# This is incremented any time the app is backgrounded or
|
# This is incremented any time the app is backgrounded or
|
||||||
# foregrounded; can be a simple way to determine if network data
|
# foregrounded; can be a simple way to determine if network data
|
||||||
|
|||||||
144
src/assets/ba_data/python/babase/_devconsole.py
Normal file
144
src/assets/ba_data/python/babase/_devconsole.py
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
# Released under the MIT License. See LICENSE for details.
|
||||||
|
#
|
||||||
|
"""Dev-Console functionality."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
from dataclasses import dataclass
|
||||||
|
import logging
|
||||||
|
|
||||||
|
import _babase
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from typing import Callable, Any, Literal
|
||||||
|
|
||||||
|
|
||||||
|
class DevConsoleTab:
|
||||||
|
"""Defines behavior for a tab in the dev-console."""
|
||||||
|
|
||||||
|
def refresh(self) -> None:
|
||||||
|
"""Called when the tab should refresh itself."""
|
||||||
|
|
||||||
|
def request_refresh(self) -> None:
|
||||||
|
"""The tab can call this to request that it be refreshed."""
|
||||||
|
_babase.dev_console_request_refresh()
|
||||||
|
|
||||||
|
def button(
|
||||||
|
self,
|
||||||
|
label: str,
|
||||||
|
pos: tuple[float, float],
|
||||||
|
size: tuple[float, float],
|
||||||
|
call: Callable[[], Any] | None = None,
|
||||||
|
h_anchor: Literal['left', 'center', 'right'] = 'center',
|
||||||
|
label_scale: float = 1.0,
|
||||||
|
corner_radius: float = 8.0,
|
||||||
|
) -> None:
|
||||||
|
"""Add a button to the tab being refreshed."""
|
||||||
|
assert _babase.app.devconsole.is_refreshing
|
||||||
|
_babase.dev_console_add_button(
|
||||||
|
label,
|
||||||
|
pos[0],
|
||||||
|
pos[1],
|
||||||
|
size[0],
|
||||||
|
size[1],
|
||||||
|
call,
|
||||||
|
h_anchor,
|
||||||
|
label_scale,
|
||||||
|
corner_radius,
|
||||||
|
)
|
||||||
|
|
||||||
|
def python_terminal(self) -> None:
|
||||||
|
"""Add a Python Terminal to the tab being refreshed."""
|
||||||
|
assert _babase.app.devconsole.is_refreshing
|
||||||
|
_babase.dev_console_add_python_terminal()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def width(self) -> float:
|
||||||
|
"""Return the current tab width. Only call during refreshes."""
|
||||||
|
assert _babase.app.devconsole.is_refreshing
|
||||||
|
return _babase.dev_console_tab_width()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def height(self) -> float:
|
||||||
|
"""Return the current tab height. Only call during refreshes."""
|
||||||
|
assert _babase.app.devconsole.is_refreshing
|
||||||
|
return _babase.dev_console_tab_height()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def base_scale(self) -> float:
|
||||||
|
"""A scale value set depending on the app's UI scale.
|
||||||
|
|
||||||
|
Dev-console tabs can incorporate this into their UI sizes and
|
||||||
|
positions if they desire. This must be done manually however.
|
||||||
|
"""
|
||||||
|
assert _babase.app.devconsole.is_refreshing
|
||||||
|
return _babase.dev_console_base_scale()
|
||||||
|
|
||||||
|
|
||||||
|
class DevConsoleTabPython(DevConsoleTab):
|
||||||
|
"""The Python dev-console tab."""
|
||||||
|
|
||||||
|
def refresh(self) -> None:
|
||||||
|
self.python_terminal()
|
||||||
|
|
||||||
|
|
||||||
|
class DevConsoleTabTest(DevConsoleTab):
|
||||||
|
"""Test dev-console tab."""
|
||||||
|
|
||||||
|
def refresh(self) -> None:
|
||||||
|
import random
|
||||||
|
|
||||||
|
self.button(
|
||||||
|
f'FLOOP-{random.randrange(200)}',
|
||||||
|
pos=(10, 10),
|
||||||
|
size=(100, 30),
|
||||||
|
h_anchor='left',
|
||||||
|
call=self.request_refresh,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class DevConsoleTabEntry:
|
||||||
|
"""Represents a distinct tab in the dev-console."""
|
||||||
|
|
||||||
|
name: str
|
||||||
|
factory: Callable[[], DevConsoleTab]
|
||||||
|
|
||||||
|
|
||||||
|
class DevConsoleSubsystem:
|
||||||
|
"""Wrangles the dev console."""
|
||||||
|
|
||||||
|
def __init__(self) -> None:
|
||||||
|
# All tabs in the dev-console. Add your own stuff here via
|
||||||
|
# plugins or whatnot.
|
||||||
|
self.tabs: list[DevConsoleTabEntry] = [
|
||||||
|
DevConsoleTabEntry('Python', DevConsoleTabPython),
|
||||||
|
DevConsoleTabEntry('Test', DevConsoleTabTest),
|
||||||
|
]
|
||||||
|
self.is_refreshing = False
|
||||||
|
|
||||||
|
def do_refresh_tab(self, tabname: str) -> None:
|
||||||
|
"""Called by the C++ layer when a tab should be filled out."""
|
||||||
|
assert _babase.in_logic_thread()
|
||||||
|
|
||||||
|
# FIXME: We currently won't handle multiple tabs with the same
|
||||||
|
# name. We should give a clean error or something in that case.
|
||||||
|
tab: DevConsoleTab | None = None
|
||||||
|
for tabentry in self.tabs:
|
||||||
|
if tabentry.name == tabname:
|
||||||
|
tab = tabentry.factory()
|
||||||
|
break
|
||||||
|
|
||||||
|
if tab is None:
|
||||||
|
logging.error(
|
||||||
|
'DevConsole got refresh request for tab'
|
||||||
|
" '%s' which does not exist.",
|
||||||
|
tabname,
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
self.is_refreshing = True
|
||||||
|
try:
|
||||||
|
tab.refresh()
|
||||||
|
finally:
|
||||||
|
self.is_refreshing = False
|
||||||
@ -372,3 +372,8 @@ def string_edit_adapter_can_be_replaced(adapter: StringEditAdapter) -> bool:
|
|||||||
|
|
||||||
assert isinstance(adapter, StringEditAdapter)
|
assert isinstance(adapter, StringEditAdapter)
|
||||||
return adapter.can_be_replaced()
|
return adapter.can_be_replaced()
|
||||||
|
|
||||||
|
|
||||||
|
def get_dev_console_tab_names() -> list[str]:
|
||||||
|
"""Return the current set of dev-console tab names."""
|
||||||
|
return [t.name for t in _babase.app.devconsole.tabs]
|
||||||
|
|||||||
@ -52,7 +52,7 @@ if TYPE_CHECKING:
|
|||||||
|
|
||||||
# Build number and version of the ballistica binary we expect to be
|
# Build number and version of the ballistica binary we expect to be
|
||||||
# using.
|
# using.
|
||||||
TARGET_BALLISTICA_BUILD = 21401
|
TARGET_BALLISTICA_BUILD = 21405
|
||||||
TARGET_BALLISTICA_VERSION = '1.7.28'
|
TARGET_BALLISTICA_VERSION = '1.7.28'
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -13,12 +13,12 @@
|
|||||||
#include <OpenAL/al.h>
|
#include <OpenAL/al.h>
|
||||||
#include <OpenAL/alc.h>
|
#include <OpenAL/alc.h>
|
||||||
#else
|
#else
|
||||||
#include <AL/al.h>
|
#include <al.h>
|
||||||
#include <AL/alc.h>
|
#include <alc.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if BA_OSTYPE_ANDROID
|
#if BA_OSTYPE_ANDROID
|
||||||
#include <AL/alext.h>
|
#include <alext.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define CHECK_AL_ERROR _check_al_error(__FILE__, __LINE__)
|
#define CHECK_AL_ERROR _check_al_error(__FILE__, __LINE__)
|
||||||
|
|||||||
@ -1,15 +1,12 @@
|
|||||||
// Released under the MIT License. See LICENSE for details.
|
// Released under the MIT License. See LICENSE for details.
|
||||||
|
|
||||||
#if BA_ENABLE_OPENGL
|
#if BA_ENABLE_OPENGL
|
||||||
|
|
||||||
#include "ballistica/base/graphics/gl/renderer_gl.h"
|
#include "ballistica/base/graphics/gl/renderer_gl.h"
|
||||||
|
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
#include "ballistica/base/graphics/component/special_component.h"
|
#include "ballistica/base/graphics/component/special_component.h"
|
||||||
#include "ballistica/base/graphics/gl/framebuffer_object_gl.h"
|
|
||||||
#include "ballistica/base/graphics/gl/gl_sys.h"
|
|
||||||
#include "ballistica/base/graphics/gl/mesh/mesh_asset_data_gl.h"
|
#include "ballistica/base/graphics/gl/mesh/mesh_asset_data_gl.h"
|
||||||
#include "ballistica/base/graphics/gl/mesh/mesh_data_dual_texture_full_gl.h"
|
#include "ballistica/base/graphics/gl/mesh/mesh_data_dual_texture_full_gl.h"
|
||||||
#include "ballistica/base/graphics/gl/mesh/mesh_data_gl.h"
|
#include "ballistica/base/graphics/gl/mesh/mesh_data_gl.h"
|
||||||
@ -29,11 +26,6 @@
|
|||||||
#include "ballistica/base/graphics/gl/render_target_gl.h"
|
#include "ballistica/base/graphics/gl/render_target_gl.h"
|
||||||
#include "ballistica/base/graphics/gl/texture_data_gl.h"
|
#include "ballistica/base/graphics/gl/texture_data_gl.h"
|
||||||
#include "ballistica/base/platform/base_platform.h"
|
#include "ballistica/base/platform/base_platform.h"
|
||||||
#include "ballistica/shared/buildconfig/buildconfig_common.h"
|
|
||||||
|
|
||||||
#if BA_OSTYPE_IOS_TVOS
|
|
||||||
#include "ballistica/base/platform/apple/apple_utils.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Turn this off to see how much blend overdraw is occurring.
|
// Turn this off to see how much blend overdraw is occurring.
|
||||||
#define BA_GL_ENABLE_BLEND 1
|
#define BA_GL_ENABLE_BLEND 1
|
||||||
@ -64,22 +56,6 @@ namespace ballistica::base {
|
|||||||
|
|
||||||
bool RendererGL::funky_depth_issue_set_{};
|
bool RendererGL::funky_depth_issue_set_{};
|
||||||
bool RendererGL::funky_depth_issue_{};
|
bool RendererGL::funky_depth_issue_{};
|
||||||
bool RendererGL::draws_shields_funny_{};
|
|
||||||
bool RendererGL::draws_shields_funny_set_{};
|
|
||||||
|
|
||||||
// FIXME - move this stuff to the renderer class.
|
|
||||||
// GLint g_combined_texture_image_unit_count{};
|
|
||||||
// bool g_anisotropic_support{};
|
|
||||||
// bool g_vao_support{};
|
|
||||||
// float g_max_anisotropy{};
|
|
||||||
// bool g_discard_framebuffer_support{};
|
|
||||||
// bool g_invalidate_framebuffer_support{};
|
|
||||||
// bool g_blit_framebuffer_support{};
|
|
||||||
// bool g_framebuffer_multisample_support{};
|
|
||||||
// bool g_running_es3{};
|
|
||||||
// bool g_seamless_cube_maps{};
|
|
||||||
// int g_msaa_max_samples_rgb565{};
|
|
||||||
// int g_msaa_max_samples_rgb8{};
|
|
||||||
|
|
||||||
#if BA_OSTYPE_ANDROID
|
#if BA_OSTYPE_ANDROID
|
||||||
bool RendererGL::is_speedy_android_device_{};
|
bool RendererGL::is_speedy_android_device_{};
|
||||||
@ -108,8 +84,11 @@ void RendererGL::CheckGLError(const char* file, int line) {
|
|||||||
GLenum err = glGetError();
|
GLenum err = glGetError();
|
||||||
if (err != GL_NO_ERROR) {
|
if (err != GL_NO_ERROR) {
|
||||||
const char* version = (const char*)glGetString(GL_VERSION);
|
const char* version = (const char*)glGetString(GL_VERSION);
|
||||||
|
BA_PRECONDITION_FATAL(version);
|
||||||
const char* vendor = (const char*)glGetString(GL_VENDOR);
|
const char* vendor = (const char*)glGetString(GL_VENDOR);
|
||||||
|
BA_PRECONDITION_FATAL(vendor);
|
||||||
const char* renderer = (const char*)glGetString(GL_RENDERER);
|
const char* renderer = (const char*)glGetString(GL_RENDERER);
|
||||||
|
BA_PRECONDITION_FATAL(renderer);
|
||||||
Log(LogLevel::kError,
|
Log(LogLevel::kError,
|
||||||
"OpenGL Error at " + std::string(file) + " line " + std::to_string(line)
|
"OpenGL Error at " + std::string(file) + " line " + std::to_string(line)
|
||||||
+ ": " + GLErrorToString(err) + "\nrenderer: " + renderer
|
+ ": " + GLErrorToString(err) + "\nrenderer: " + renderer
|
||||||
@ -177,11 +156,27 @@ void RendererGL::CheckGLCapabilities_() {
|
|||||||
BA_DEBUG_CHECK_GL_ERROR;
|
BA_DEBUG_CHECK_GL_ERROR;
|
||||||
assert(g_base->app_adapter->InGraphicsContext());
|
assert(g_base->app_adapter->InGraphicsContext());
|
||||||
|
|
||||||
draws_shields_funny_set_ = true;
|
|
||||||
|
|
||||||
const char* renderer = (const char*)glGetString(GL_RENDERER);
|
const char* renderer = (const char*)glGetString(GL_RENDERER);
|
||||||
|
BA_PRECONDITION_FATAL(renderer);
|
||||||
const char* vendor = (const char*)glGetString(GL_VENDOR);
|
const char* vendor = (const char*)glGetString(GL_VENDOR);
|
||||||
|
BA_PRECONDITION_FATAL(vendor);
|
||||||
const char* version_str = (const char*)glGetString(GL_VERSION);
|
const char* version_str = (const char*)glGetString(GL_VERSION);
|
||||||
|
BA_PRECONDITION_FATAL(version_str);
|
||||||
|
|
||||||
|
// Do a rough check to make sure we're running 3 or newer of GL/GLES.
|
||||||
|
// This query should be available even on older versions.
|
||||||
|
if (version_str[0] != '3' && version_str[0] != '4') {
|
||||||
|
FatalError(std::string("Invalid OpenGL version found (") + version_str
|
||||||
|
+ "). We require 3.0 or later.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now fetch exact major/minor versions. This query requires version 3.0
|
||||||
|
// or newer which is why we checked that above.
|
||||||
|
glGetError(); // Clear any existing error so we don't die on it here.
|
||||||
|
glGetIntegerv(GL_MAJOR_VERSION, &gl_version_major_);
|
||||||
|
BA_PRECONDITION_FATAL(glGetError() == GL_NO_ERROR);
|
||||||
|
glGetIntegerv(GL_MINOR_VERSION, &gl_version_minor_);
|
||||||
|
BA_PRECONDITION_FATAL(glGetError() == GL_NO_ERROR);
|
||||||
|
|
||||||
const char* basestr;
|
const char* basestr;
|
||||||
if (gl_is_es()) {
|
if (gl_is_es()) {
|
||||||
@ -200,28 +195,20 @@ void RendererGL::CheckGLCapabilities_() {
|
|||||||
std::vector<std::string> extensions;
|
std::vector<std::string> extensions;
|
||||||
bool used_num_extensions{};
|
bool used_num_extensions{};
|
||||||
|
|
||||||
// On the ES side we still support ES 2 which does not support the modern
|
// Do the modern gl thing of looking through a list of extensions; not a
|
||||||
// GL_NUM_EXTENSIONS route. Though I suppose we could just try it on ES
|
// single string.
|
||||||
// and do the fallback if we get GL_INVALID_ENUM.
|
if (auto num_extensions = GLGetIntOptional(GL_NUM_EXTENSIONS)) {
|
||||||
#if !BA_OPENGL_IS_ES
|
used_num_extensions = true;
|
||||||
{
|
extensions.reserve(*num_extensions);
|
||||||
GLint num_extensions{};
|
for (int i = 0; i < num_extensions; ++i) {
|
||||||
glGetError(); // Clear any existing error.
|
const char* extension = (const char*)glGetStringi(GL_EXTENSIONS, i);
|
||||||
glGetIntegerv(GL_NUM_EXTENSIONS, &num_extensions);
|
BA_PRECONDITION(extension);
|
||||||
if (glGetError() == GL_NO_ERROR) {
|
extensions.push_back(extension);
|
||||||
used_num_extensions = true;
|
|
||||||
extensions.reserve(num_extensions);
|
|
||||||
for (int i = 0; i < num_extensions; ++i) {
|
|
||||||
const char* extension = (const char*)glGetStringi(GL_EXTENSIONS, i);
|
|
||||||
BA_PRECONDITION(extension);
|
|
||||||
extensions.push_back(extension);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
#endif
|
Log(LogLevel::kWarning, "Falling back on legacy GL_EXTENSIONS parsing.");
|
||||||
|
// Fall back on parsing the single giant string if need be.
|
||||||
// Fall back on parsing the single giant string if need be.
|
// (Can probably kill this).
|
||||||
if (!used_num_extensions) {
|
|
||||||
auto* ex = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
|
auto* ex = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
|
||||||
BA_DEBUG_CHECK_GL_ERROR;
|
BA_DEBUG_CHECK_GL_ERROR;
|
||||||
BA_PRECONDITION_FATAL(ex);
|
BA_PRECONDITION_FATAL(ex);
|
||||||
@ -349,13 +336,15 @@ void RendererGL::CheckGLCapabilities_() {
|
|||||||
|
|
||||||
std::list<TextureCompressionType> c_types;
|
std::list<TextureCompressionType> c_types;
|
||||||
assert(g_base->graphics);
|
assert(g_base->graphics);
|
||||||
if (CheckGLExtension(extensions, "texture_compression_s3tc"))
|
if (CheckGLExtension(extensions, "texture_compression_s3tc")) {
|
||||||
c_types.push_back(TextureCompressionType::kS3TC);
|
c_types.push_back(TextureCompressionType::kS3TC);
|
||||||
|
}
|
||||||
|
|
||||||
// Limiting pvr support to iOS for the moment.
|
// Limiting pvr support to iOS for the moment.
|
||||||
if (!g_buildconfig.ostype_android()) {
|
if (!g_buildconfig.ostype_android()) {
|
||||||
if (CheckGLExtension(extensions, "texture_compression_pvrtc"))
|
if (CheckGLExtension(extensions, "texture_compression_pvrtc")) {
|
||||||
c_types.push_back(TextureCompressionType::kPVR);
|
c_types.push_back(TextureCompressionType::kPVR);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// All android devices should support etc1.
|
// All android devices should support etc1.
|
||||||
@ -375,33 +364,14 @@ void RendererGL::CheckGLCapabilities_() {
|
|||||||
|
|
||||||
g_base->graphics_server->SetTextureCompressionTypes(c_types);
|
g_base->graphics_server->SetTextureCompressionTypes(c_types);
|
||||||
|
|
||||||
// Check whether we support high-quality mode (requires a few things like
|
// Both GL 3 and GL ES 3.0 support depth textures (and thus our high
|
||||||
// depth textures) For now lets also disallow high-quality in some VR
|
// quality mode) as a core feature.
|
||||||
// environments.
|
|
||||||
|
|
||||||
// Both GL 3.2 and GL ES 3.0 support depth textures.
|
|
||||||
// if (!gl_is_es()) {
|
|
||||||
// supports_depth_textures_ = true;
|
|
||||||
g_base->graphics->SetSupportsHighQualityGraphics(true);
|
g_base->graphics->SetSupportsHighQualityGraphics(true);
|
||||||
|
|
||||||
// } else {
|
|
||||||
// if (CheckGLExtension(extensions, "depth_texture")) {
|
|
||||||
// supports_depth_textures_ = true;
|
|
||||||
// if (g_buildconfig.cardboard_build()) {
|
|
||||||
// g_base->graphics->SetSupportsHighQualityGraphics(false);
|
|
||||||
// } else {
|
|
||||||
// g_base->graphics->SetSupportsHighQualityGraphics(true);
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// supports_depth_textures_ = false;
|
|
||||||
// g_base->graphics->SetSupportsHighQualityGraphics(false);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Store the tex-compression type we support.
|
// Store the tex-compression type we support.
|
||||||
BA_DEBUG_CHECK_GL_ERROR;
|
BA_DEBUG_CHECK_GL_ERROR;
|
||||||
|
|
||||||
// Anisotropic sampling is still an extension as of both GL 3.2 and ES 3,
|
// Anisotropic sampling is still an extension as of both GL 3 and ES 3,
|
||||||
// so we need to test for it.
|
// so we need to test for it.
|
||||||
anisotropic_support_ =
|
anisotropic_support_ =
|
||||||
CheckGLExtension(extensions, "texture_filter_anisotropic");
|
CheckGLExtension(extensions, "texture_filter_anisotropic");
|
||||||
@ -411,40 +381,6 @@ void RendererGL::CheckGLCapabilities_() {
|
|||||||
|
|
||||||
BA_DEBUG_CHECK_GL_ERROR;
|
BA_DEBUG_CHECK_GL_ERROR;
|
||||||
|
|
||||||
// VAO support is everywhere now.
|
|
||||||
// #if BA_OPENGL_IS_ES
|
|
||||||
// // We can run with our without VAOs but they're nice to have.
|
|
||||||
// g_vao_support =
|
|
||||||
// (glGenVertexArrays != nullptr && glDeleteVertexArrays != nullptr
|
|
||||||
// && glBindVertexArray != nullptr
|
|
||||||
// && (g_running_es3
|
|
||||||
// || CheckGLExtension(extensions, "vertex_array_object")));
|
|
||||||
// #else
|
|
||||||
// g_vao_support = true;
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
// #if !BA_OPENGL_IS_ES
|
|
||||||
// Both of these are standard in GL 3.2 and GL ES 3; hooray!
|
|
||||||
// g_blit_framebuffer_support = true;
|
|
||||||
// g_framebuffer_multisample_support = true;
|
|
||||||
// #else
|
|
||||||
// #if BA_OSTYPE_IOS_TVOS
|
|
||||||
// g_blit_framebuffer_support = false;
|
|
||||||
// g_framebuffer_multisample_support = false;
|
|
||||||
// #elif BA_OSTYPE_MACOS
|
|
||||||
// g_blit_framebuffer_support = CheckGLExtension(extensions,
|
|
||||||
// "framebuffer_blit"); g_framebuffer_multisample_support = false;
|
|
||||||
// #else
|
|
||||||
// g_blit_framebuffer_support =
|
|
||||||
// (glBlitFramebuffer != nullptr
|
|
||||||
// && (g_running_es3 || CheckGLExtension(ex, "framebuffer_blit")));
|
|
||||||
// g_framebuffer_multisample_support =
|
|
||||||
// (glRenderbufferStorageMultisample != nullptr
|
|
||||||
// && (g_running_es3 || (CheckGLExtension(ex,
|
|
||||||
// "framebuffer_multisample"))));
|
|
||||||
// #endif
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
if (gl_is_es()) {
|
if (gl_is_es()) {
|
||||||
// GL ES 3 has glInvalidateFramebuffer as part of the standard.
|
// GL ES 3 has glInvalidateFramebuffer as part of the standard.
|
||||||
invalidate_framebuffer_support_ = true;
|
invalidate_framebuffer_support_ = true;
|
||||||
@ -454,68 +390,25 @@ void RendererGL::CheckGLCapabilities_() {
|
|||||||
invalidate_framebuffer_support_ = false;
|
invalidate_framebuffer_support_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// #if BA_OSTYPE_IOS_TVOS || BA_OSTYPE_ANDROID
|
combined_texture_image_unit_count_ =
|
||||||
// #if BA_OSTYPE_IOS_TVOS
|
GLGetInt(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS);
|
||||||
// g_discard_framebuffer_support = CheckGLExtension(ex,
|
|
||||||
// "discard_framebuffer");
|
|
||||||
// #else
|
|
||||||
// g_discard_framebuffer_support =
|
|
||||||
// (glDiscardFramebufferEXT != nullptr
|
|
||||||
// && CheckGLExtension(ex, "discard_framebuffer"));
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
// g_invalidate_framebuffer_support =
|
|
||||||
// (g_running_es3 && glInvalidateFramebuffer != nullptr);
|
|
||||||
// #else
|
|
||||||
// g_discard_framebuffer_support = false;
|
|
||||||
// g_invalidate_framebuffer_support = false;
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
// g_seamless_cube_maps = CheckGLExtension(ex, "seamless_cube_map");
|
|
||||||
|
|
||||||
// #if BA_OSTYPE_WINDOWS
|
|
||||||
// // The vmware gl driver breaks horrifically with VAOs turned on.
|
|
||||||
// const char* vendor = (const char*)glGetString(GL_VENDOR);
|
|
||||||
// if (strstr(vendor, "VMware")) {
|
|
||||||
// g_vao_support = false;
|
|
||||||
// }
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
// #if BA_OSTYPE_ANDROID
|
|
||||||
// // VAOs currently break my poor kindle fire hd to the point of rebooting
|
|
||||||
// it if (!g_running_es3 && !is_tegra_4_) {
|
|
||||||
// g_vao_support = false;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // also they seem to be problematic on zenfone2's gpu.
|
|
||||||
// if (strstr(renderer, "PowerVR Rogue G6430")) {
|
|
||||||
// g_vao_support = false;
|
|
||||||
// }
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,
|
|
||||||
&combined_texture_image_unit_count_);
|
|
||||||
|
|
||||||
// If we're running ES3, ask about our max multisample counts and whether we
|
// If we're running ES3, ask about our max multisample counts and whether we
|
||||||
// can enable MSAA.
|
// can enable MSAA.
|
||||||
// enable_msaa_ = false; // start pessimistic
|
|
||||||
msaa_max_samples_rgb565_ = msaa_max_samples_rgb8_ = 0; // start pessimistic
|
msaa_max_samples_rgb565_ = msaa_max_samples_rgb8_ = 0; // start pessimistic
|
||||||
|
|
||||||
// FIXME - NEED TO CHECK DESKTOP GL VERSION TO USE THIS THERE.
|
bool have_gl_get_internal_format_iv{};
|
||||||
#if BA_OSTYPE_ANDROID || BA_RIFT_BUILD
|
if (gl_is_es()) {
|
||||||
bool check_msaa = false;
|
// This is available on ES 3.
|
||||||
|
have_gl_get_internal_format_iv = true;
|
||||||
|
} else {
|
||||||
|
// This is available on GL 4.2 or newer.
|
||||||
|
if (gl_version_major() == 4 && gl_version_minor() >= 2) {
|
||||||
|
have_gl_get_internal_format_iv = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if BA_OSTYPE_ANDROID
|
if (have_gl_get_internal_format_iv) {
|
||||||
// if (g_running_es3) {
|
|
||||||
check_msaa = true;
|
|
||||||
// }
|
|
||||||
#endif // BA_OSTYPE_ANDROID
|
|
||||||
|
|
||||||
#if BA_RIFT_BUILD
|
|
||||||
check_msaa = true;
|
|
||||||
#endif // BA_RIFT_BUILD
|
|
||||||
|
|
||||||
if (check_msaa) {
|
|
||||||
GLint count;
|
GLint count;
|
||||||
glGetInternalformativ(GL_RENDERBUFFER, GL_RGB565, GL_NUM_SAMPLE_COUNTS, 1,
|
glGetInternalformativ(GL_RENDERBUFFER, GL_RGB565, GL_NUM_SAMPLE_COUNTS, 1,
|
||||||
&count);
|
&count);
|
||||||
@ -543,10 +436,17 @@ void RendererGL::CheckGLCapabilities_() {
|
|||||||
BA_LOG_ONCE(LogLevel::kError, "Got 0 samplecounts for RGB8");
|
BA_LOG_ONCE(LogLevel::kError, "Got 0 samplecounts for RGB8");
|
||||||
msaa_max_samples_rgb8_ = 0;
|
msaa_max_samples_rgb8_ = 0;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// For older GL (which includes all Macs) it sounds like this is the way
|
||||||
|
// to query max samples?.. but I don't know for sure if this applies to
|
||||||
|
// renderbuffer targets or just the default drawable. Will it ever be
|
||||||
|
// different?
|
||||||
|
auto max_samples = GLGetIntOptional(GL_MAX_SAMPLES);
|
||||||
|
if (max_samples.has_value()) {
|
||||||
|
msaa_max_samples_rgb565_ = msaa_max_samples_rgb8_ = *max_samples;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // BA_OSTYPE_ANDROID
|
|
||||||
|
|
||||||
BA_DEBUG_CHECK_GL_ERROR;
|
BA_DEBUG_CHECK_GL_ERROR;
|
||||||
|
|
||||||
first_extension_check_ = false;
|
first_extension_check_ = false;
|
||||||
@ -639,7 +539,7 @@ void RendererGL::BindTextureUnit(uint32_t tex_unit) {
|
|||||||
assert(tex_unit >= 0 && tex_unit < kMaxGLTexUnitsUsed);
|
assert(tex_unit >= 0 && tex_unit < kMaxGLTexUnitsUsed);
|
||||||
if (active_tex_unit_ != -1) {
|
if (active_tex_unit_ != -1) {
|
||||||
// Make sure our internal state stays correct.
|
// Make sure our internal state stays correct.
|
||||||
assert(DebugGLGetInt(GL_ACTIVE_TEXTURE) == GL_TEXTURE0 + active_tex_unit_);
|
assert(GLGetInt(GL_ACTIVE_TEXTURE) == GL_TEXTURE0 + active_tex_unit_);
|
||||||
}
|
}
|
||||||
if (active_tex_unit_ != tex_unit) {
|
if (active_tex_unit_ != tex_unit) {
|
||||||
active_tex_unit_ = tex_unit;
|
active_tex_unit_ = tex_unit;
|
||||||
@ -649,18 +549,39 @@ void RendererGL::BindTextureUnit(uint32_t tex_unit) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto RendererGL::DebugGLGetInt(GLenum name) -> int {
|
auto RendererGL::GLGetInt(GLenum name) -> int {
|
||||||
// This is probably inefficient so make sure we don't leave it on in
|
|
||||||
// release builds.
|
|
||||||
assert(g_buildconfig.debug_build());
|
|
||||||
assert(g_base->app_adapter->InGraphicsContext());
|
assert(g_base->app_adapter->InGraphicsContext());
|
||||||
|
|
||||||
// Clear any error coming in; don't want to die for something that's not
|
// Clear any error coming in; don't want to fail for something that's not
|
||||||
// ours.
|
// our problem.
|
||||||
BA_DEBUG_CHECK_GL_ERROR;
|
if (g_buildconfig.debug_build()) {
|
||||||
|
BA_DEBUG_CHECK_GL_ERROR;
|
||||||
|
} else {
|
||||||
|
glGetError();
|
||||||
|
}
|
||||||
GLint val;
|
GLint val;
|
||||||
glGetIntegerv(name, &val);
|
glGetIntegerv(name, &val);
|
||||||
assert(glGetError() == GL_NO_ERROR);
|
if (glGetError() != GL_NO_ERROR) {
|
||||||
|
FatalError("Unable to fetch GL int " + std::to_string(name));
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto RendererGL::GLGetIntOptional(GLenum name) -> std::optional<int> {
|
||||||
|
assert(g_base->app_adapter->InGraphicsContext());
|
||||||
|
|
||||||
|
// Clear any error coming in; don't want to fail for something that's not
|
||||||
|
// our problem.
|
||||||
|
if (g_buildconfig.debug_build()) {
|
||||||
|
BA_DEBUG_CHECK_GL_ERROR;
|
||||||
|
} else {
|
||||||
|
glGetError();
|
||||||
|
}
|
||||||
|
GLint val;
|
||||||
|
glGetIntegerv(name, &val);
|
||||||
|
if (glGetError() != GL_NO_ERROR) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -669,14 +590,14 @@ void RendererGL::BindFramebuffer(GLuint fb) {
|
|||||||
glBindFramebuffer(GL_FRAMEBUFFER, fb);
|
glBindFramebuffer(GL_FRAMEBUFFER, fb);
|
||||||
active_framebuffer_ = fb;
|
active_framebuffer_ = fb;
|
||||||
} else {
|
} else {
|
||||||
assert(DebugGLGetInt(GL_FRAMEBUFFER_BINDING) == fb);
|
assert(GLGetInt(GL_FRAMEBUFFER_BINDING) == fb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererGL::BindArrayBuffer(GLuint b) {
|
void RendererGL::BindArrayBuffer(GLuint b) {
|
||||||
if (active_array_buffer_ != -1) {
|
if (active_array_buffer_ != -1) {
|
||||||
// Make sure our internal state stays correct.
|
// Make sure our internal state stays correct.
|
||||||
assert(DebugGLGetInt(GL_ARRAY_BUFFER_BINDING) == active_array_buffer_);
|
assert(GLGetInt(GL_ARRAY_BUFFER_BINDING) == active_array_buffer_);
|
||||||
}
|
}
|
||||||
if (active_array_buffer_ != b) {
|
if (active_array_buffer_ != b) {
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, b);
|
glBindBuffer(GL_ARRAY_BUFFER, b);
|
||||||
@ -702,7 +623,7 @@ void RendererGL::BindTexture_(GLuint type, GLuint tex, GLuint tex_unit) {
|
|||||||
if (g_buildconfig.debug_build()) {
|
if (g_buildconfig.debug_build()) {
|
||||||
if (bound_textures_2d_[tex_unit] != -1) {
|
if (bound_textures_2d_[tex_unit] != -1) {
|
||||||
BindTextureUnit(tex_unit);
|
BindTextureUnit(tex_unit);
|
||||||
assert(DebugGLGetInt(GL_TEXTURE_BINDING_2D)
|
assert(GLGetInt(GL_TEXTURE_BINDING_2D)
|
||||||
== bound_textures_2d_[tex_unit]);
|
== bound_textures_2d_[tex_unit]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -718,7 +639,7 @@ void RendererGL::BindTexture_(GLuint type, GLuint tex, GLuint tex_unit) {
|
|||||||
if (g_buildconfig.debug_build()) {
|
if (g_buildconfig.debug_build()) {
|
||||||
if (bound_textures_cube_map_[tex_unit] != -1) {
|
if (bound_textures_cube_map_[tex_unit] != -1) {
|
||||||
BindTextureUnit(tex_unit);
|
BindTextureUnit(tex_unit);
|
||||||
assert(DebugGLGetInt(GL_TEXTURE_BINDING_CUBE_MAP)
|
assert(GLGetInt(GL_TEXTURE_BINDING_CUBE_MAP)
|
||||||
== bound_textures_cube_map_[tex_unit]);
|
== bound_textures_cube_map_[tex_unit]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -825,7 +746,6 @@ void RendererGL::InvalidateFramebuffer(bool color, bool depth,
|
|||||||
|
|
||||||
// Currently this is ES only for us.
|
// Currently this is ES only for us.
|
||||||
#if BA_OPENGL_IS_ES
|
#if BA_OPENGL_IS_ES
|
||||||
// #if BA_OSTYPE_IOS_TVOS || BA_OSTYPE_ANDROID
|
|
||||||
|
|
||||||
if (invalidate_framebuffer_support()) {
|
if (invalidate_framebuffer_support()) {
|
||||||
GLenum attachments[5];
|
GLenum attachments[5];
|
||||||
@ -834,11 +754,9 @@ void RendererGL::InvalidateFramebuffer(bool color, bool depth,
|
|||||||
if (active_framebuffer_ == 0 && !target_read_framebuffer) {
|
if (active_framebuffer_ == 0 && !target_read_framebuffer) {
|
||||||
if (color) {
|
if (color) {
|
||||||
attachments[count++] = GL_COLOR;
|
attachments[count++] = GL_COLOR;
|
||||||
// attachments[count++] = GL_COLOR_EXT;
|
|
||||||
}
|
}
|
||||||
if (depth) {
|
if (depth) {
|
||||||
attachments[count++] = GL_DEPTH;
|
attachments[count++] = GL_DEPTH;
|
||||||
// attachments[count++] = GL_DEPTH_EXT;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (color) {
|
if (color) {
|
||||||
@ -848,29 +766,16 @@ void RendererGL::InvalidateFramebuffer(bool color, bool depth,
|
|||||||
attachments[count++] = GL_DEPTH_ATTACHMENT;
|
attachments[count++] = GL_DEPTH_ATTACHMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apparently the oculus docs say glInvalidateFramebuffer errors on a
|
|
||||||
// mali es3 implementation so they always use glDiscard when present.
|
|
||||||
// if () {
|
|
||||||
// #if BA_OSTYPE_IOS_TVOS
|
|
||||||
// throw Exception(); // shouldnt happen
|
|
||||||
// #else
|
|
||||||
glInvalidateFramebuffer(
|
glInvalidateFramebuffer(
|
||||||
target_read_framebuffer ? GL_READ_FRAMEBUFFER : GL_FRAMEBUFFER, count,
|
target_read_framebuffer ? GL_READ_FRAMEBUFFER : GL_FRAMEBUFFER, count,
|
||||||
attachments);
|
attachments);
|
||||||
// #endif
|
|
||||||
}
|
}
|
||||||
// } else {
|
|
||||||
// // If we've got a read-framebuffer, we should have invalidate too.
|
|
||||||
// assert(!target_read_framebuffer);
|
|
||||||
// glDiscardFramebufferEXT(GL_FRAMEBUFFER, count, attachments);
|
|
||||||
// }
|
|
||||||
BA_DEBUG_CHECK_GL_ERROR;
|
BA_DEBUG_CHECK_GL_ERROR;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
// Make noise if we should be doing this here too...
|
// Make noise if we should be doing this here too at some point.
|
||||||
assert(!invalidate_framebuffer_support());
|
assert(!invalidate_framebuffer_support());
|
||||||
#endif // BA_OPENGL_IS_ES
|
#endif // BA_OPENGL_IS_ES
|
||||||
// #endif // BA_OSTYPE_IOS_TVOS || BA_OSTYPE_ANDROID
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RendererGL::~RendererGL() {
|
RendererGL::~RendererGL() {
|
||||||
@ -2701,8 +2606,7 @@ void RendererGL::Load() {
|
|||||||
// Grab the current framebuffer and consider that to be our 'screen'
|
// Grab the current framebuffer and consider that to be our 'screen'
|
||||||
// framebuffer. This can be 0 for the main framebuffer or can be
|
// framebuffer. This can be 0 for the main framebuffer or can be
|
||||||
// something else.
|
// something else.
|
||||||
glGetIntegerv(GL_FRAMEBUFFER_BINDING,
|
screen_framebuffer_ = GLGetInt(GL_FRAMEBUFFER_BINDING);
|
||||||
reinterpret_cast<GLint*>(&screen_framebuffer_));
|
|
||||||
}
|
}
|
||||||
Renderer::Load();
|
Renderer::Load();
|
||||||
int high_qual_pp_flag =
|
int high_qual_pp_flag =
|
||||||
@ -3340,9 +3244,7 @@ void RendererGL::VREyeRenderBegin() {
|
|||||||
glDisable(GL_FRAMEBUFFER_SRGB);
|
glDisable(GL_FRAMEBUFFER_SRGB);
|
||||||
#endif // BA_RIFT_BUILD
|
#endif // BA_RIFT_BUILD
|
||||||
|
|
||||||
GLuint fb;
|
screen_framebuffer_ = GLGetInt(GL_FRAMEBUFFER_BINDING);
|
||||||
glGetIntegerv(GL_FRAMEBUFFER_BINDING, reinterpret_cast<GLint*>(&fb));
|
|
||||||
screen_framebuffer_ = fb;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if BA_VR_BUILD
|
#if BA_VR_BUILD
|
||||||
|
|||||||
@ -217,7 +217,14 @@ class RendererGL : public Renderer {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
auto DebugGLGetInt(GLenum name) -> int;
|
auto gl_version_minor() const { return gl_version_minor_; }
|
||||||
|
auto gl_version_major() const { return gl_version_major_; }
|
||||||
|
|
||||||
|
// Wraps glGetIntegerv(). Triggers FatalError if get fails.
|
||||||
|
auto GLGetInt(GLenum name) -> int;
|
||||||
|
|
||||||
|
// Wraps glGetIntegerv(); returns empty value if get fails.
|
||||||
|
auto GLGetIntOptional(GLenum name) -> std::optional<int>;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static auto GetFunkyDepthIssue_() -> bool;
|
static auto GetFunkyDepthIssue_() -> bool;
|
||||||
@ -251,18 +258,28 @@ class RendererGL : public Renderer {
|
|||||||
void BindArrayBuffer(GLuint b);
|
void BindArrayBuffer(GLuint b);
|
||||||
void SetBlend(bool b);
|
void SetBlend(bool b);
|
||||||
void SetBlendPremult(bool b);
|
void SetBlendPremult(bool b);
|
||||||
millisecs_t dof_update_time_{};
|
|
||||||
std::vector<Object::Ref<FramebufferObjectGL> > blur_buffers_;
|
bool blend_{};
|
||||||
// bool supports_depth_textures_{};
|
bool blend_premult_{};
|
||||||
bool first_extension_check_{true};
|
bool first_extension_check_{true};
|
||||||
bool is_tegra_4_{};
|
bool is_tegra_4_{};
|
||||||
bool is_tegra_k1_{};
|
bool is_tegra_k1_{};
|
||||||
bool is_recent_adreno_{};
|
bool is_recent_adreno_{};
|
||||||
bool is_adreno_{};
|
bool is_adreno_{};
|
||||||
bool enable_msaa_{};
|
bool enable_msaa_{};
|
||||||
|
bool draw_at_equal_depth_{};
|
||||||
|
bool depth_writing_enabled_{};
|
||||||
|
bool depth_testing_enabled_{};
|
||||||
|
bool data_loaded_{};
|
||||||
|
bool draw_front_{};
|
||||||
|
bool got_screen_framebuffer_{};
|
||||||
|
bool double_sided_{};
|
||||||
|
bool invalidate_framebuffer_support_{};
|
||||||
|
GLint gl_version_major_{};
|
||||||
|
GLint gl_version_minor_{};
|
||||||
|
int last_blur_res_count_{};
|
||||||
float last_cam_buffer_width_{};
|
float last_cam_buffer_width_{};
|
||||||
float last_cam_buffer_height_{};
|
float last_cam_buffer_height_{};
|
||||||
int last_blur_res_count_{};
|
|
||||||
float vignette_tex_outer_r_{};
|
float vignette_tex_outer_r_{};
|
||||||
float vignette_tex_outer_g_{};
|
float vignette_tex_outer_g_{};
|
||||||
float vignette_tex_outer_b_{};
|
float vignette_tex_outer_b_{};
|
||||||
@ -271,13 +288,7 @@ class RendererGL : public Renderer {
|
|||||||
float vignette_tex_inner_b_{};
|
float vignette_tex_inner_b_{};
|
||||||
float depth_range_min_{};
|
float depth_range_min_{};
|
||||||
float depth_range_max_{};
|
float depth_range_max_{};
|
||||||
bool draw_at_equal_depth_{};
|
GLint screen_framebuffer_{};
|
||||||
bool depth_writing_enabled_{};
|
|
||||||
bool depth_testing_enabled_{};
|
|
||||||
bool data_loaded_{};
|
|
||||||
bool draw_front_{};
|
|
||||||
bool got_screen_framebuffer_{};
|
|
||||||
GLuint screen_framebuffer_{};
|
|
||||||
GLuint random_tex_{};
|
GLuint random_tex_{};
|
||||||
GLuint vignette_tex_{};
|
GLuint vignette_tex_{};
|
||||||
GraphicsQuality vignette_quality_{};
|
GraphicsQuality vignette_quality_{};
|
||||||
@ -285,6 +296,8 @@ class RendererGL : public Renderer {
|
|||||||
GLint viewport_y_{};
|
GLint viewport_y_{};
|
||||||
GLint viewport_width_{};
|
GLint viewport_width_{};
|
||||||
GLint viewport_height_{};
|
GLint viewport_height_{};
|
||||||
|
millisecs_t dof_update_time_{};
|
||||||
|
std::vector<Object::Ref<FramebufferObjectGL> > blur_buffers_;
|
||||||
std::vector<std::unique_ptr<ProgramGL> > shaders_;
|
std::vector<std::unique_ptr<ProgramGL> > shaders_;
|
||||||
ProgramSimpleGL* simple_color_prog_{};
|
ProgramSimpleGL* simple_color_prog_{};
|
||||||
ProgramSimpleGL* simple_tex_prog_{};
|
ProgramSimpleGL* simple_tex_prog_{};
|
||||||
@ -326,24 +339,18 @@ class RendererGL : public Renderer {
|
|||||||
ProgramPostProcessGL* postprocess_distort_prog_{};
|
ProgramPostProcessGL* postprocess_distort_prog_{};
|
||||||
static bool funky_depth_issue_set_;
|
static bool funky_depth_issue_set_;
|
||||||
static bool funky_depth_issue_;
|
static bool funky_depth_issue_;
|
||||||
static bool draws_shields_funny_set_;
|
|
||||||
static bool draws_shields_funny_;
|
|
||||||
#if BA_OSTYPE_ANDROID
|
#if BA_OSTYPE_ANDROID
|
||||||
static bool is_speedy_android_device_;
|
static bool is_speedy_android_device_;
|
||||||
static bool is_extra_speedy_android_device_;
|
static bool is_extra_speedy_android_device_;
|
||||||
#endif
|
#endif
|
||||||
ProgramGL* current_program_{};
|
ProgramGL* current_program_{};
|
||||||
bool double_sided_{};
|
|
||||||
std::vector<Rect> scissor_rects_;
|
std::vector<Rect> scissor_rects_;
|
||||||
GLuint current_vertex_array_{};
|
GLuint current_vertex_array_{};
|
||||||
bool vertex_attrib_arrays_enabled_[kVertexAttrCount]{};
|
|
||||||
int active_tex_unit_{};
|
int active_tex_unit_{};
|
||||||
int active_framebuffer_{};
|
int active_framebuffer_{};
|
||||||
int active_array_buffer_{};
|
int active_array_buffer_{};
|
||||||
int bound_textures_2d_[kMaxGLTexUnitsUsed]{};
|
int bound_textures_2d_[kMaxGLTexUnitsUsed]{};
|
||||||
int bound_textures_cube_map_[kMaxGLTexUnitsUsed]{};
|
int bound_textures_cube_map_[kMaxGLTexUnitsUsed]{};
|
||||||
bool blend_{};
|
|
||||||
bool blend_premult_{};
|
|
||||||
std::unique_ptr<MeshDataSimpleFullGL> screen_mesh_;
|
std::unique_ptr<MeshDataSimpleFullGL> screen_mesh_;
|
||||||
std::vector<MeshDataSimpleSplitGL*> recycle_mesh_datas_simple_split_;
|
std::vector<MeshDataSimpleSplitGL*> recycle_mesh_datas_simple_split_;
|
||||||
std::vector<MeshDataObjectSplitGL*> recycle_mesh_datas_object_split_;
|
std::vector<MeshDataObjectSplitGL*> recycle_mesh_datas_object_split_;
|
||||||
@ -355,7 +362,6 @@ class RendererGL : public Renderer {
|
|||||||
GLint combined_texture_image_unit_count_{};
|
GLint combined_texture_image_unit_count_{};
|
||||||
GLint anisotropic_support_{};
|
GLint anisotropic_support_{};
|
||||||
GLfloat max_anisotropy_{};
|
GLfloat max_anisotropy_{};
|
||||||
bool invalidate_framebuffer_support_{};
|
|
||||||
int msaa_max_samples_rgb565_{-1};
|
int msaa_max_samples_rgb565_{-1};
|
||||||
int msaa_max_samples_rgb8_{-1};
|
int msaa_max_samples_rgb8_{-1};
|
||||||
};
|
};
|
||||||
|
|||||||
@ -105,6 +105,8 @@ class BasePython {
|
|||||||
kAppPushApplyAppConfigCall,
|
kAppPushApplyAppConfigCall,
|
||||||
kStringEditAdapterCanBeReplacedCall,
|
kStringEditAdapterCanBeReplacedCall,
|
||||||
kDevConsoleStringEditAdapterClass,
|
kDevConsoleStringEditAdapterClass,
|
||||||
|
kGetDevConsoleTabNamesCall,
|
||||||
|
kAppDevConsoleDoRefreshTabCall,
|
||||||
kLast // Sentinel; must be at end.
|
kLast // Sentinel; must be at end.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -12,6 +12,7 @@
|
|||||||
#include "ballistica/base/python/base_python.h"
|
#include "ballistica/base/python/base_python.h"
|
||||||
#include "ballistica/base/python/class/python_class_simple_sound.h"
|
#include "ballistica/base/python/class/python_class_simple_sound.h"
|
||||||
#include "ballistica/base/support/app_config.h"
|
#include "ballistica/base/support/app_config.h"
|
||||||
|
#include "ballistica/base/ui/dev_console.h"
|
||||||
#include "ballistica/base/ui/ui.h"
|
#include "ballistica/base/ui/ui.h"
|
||||||
#include "ballistica/shared/generic/utils.h"
|
#include "ballistica/shared/generic/utils.h"
|
||||||
|
|
||||||
@ -1450,6 +1451,169 @@ static PyMethodDef PyFatalErrorDef = {
|
|||||||
"however, Exceptions should be preferred.",
|
"however, Exceptions should be preferred.",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ------------------------- dev_console_add_button ----------------------------
|
||||||
|
|
||||||
|
static auto PyDevConsoleAddButton(PyObject* self, PyObject* args) -> PyObject* {
|
||||||
|
BA_PYTHON_TRY;
|
||||||
|
BA_PRECONDITION(g_base->InLogicThread());
|
||||||
|
auto* dev_console = g_base->ui->dev_console();
|
||||||
|
BA_PRECONDITION(dev_console);
|
||||||
|
BA_PRECONDITION(dev_console->IsActive());
|
||||||
|
const char* label;
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
float width;
|
||||||
|
float height;
|
||||||
|
PyObject* call;
|
||||||
|
const char* h_anchor;
|
||||||
|
float label_scale;
|
||||||
|
float corner_radius;
|
||||||
|
if (!PyArg_ParseTuple(args, "sffffOsff", &label, &x, &y, &width, &height,
|
||||||
|
&call, &h_anchor, &label_scale, &corner_radius)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
dev_console->AddButton(label, x, y, width, height, call, h_anchor,
|
||||||
|
label_scale, corner_radius);
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
BA_PYTHON_CATCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyMethodDef PyDevConsoleAddButtonDef = {
|
||||||
|
"dev_console_add_button", // name
|
||||||
|
(PyCFunction)PyDevConsoleAddButton, // method
|
||||||
|
METH_VARARGS, // flags
|
||||||
|
|
||||||
|
"dev_console_add_button(\n"
|
||||||
|
" label: str,\n"
|
||||||
|
" x: float,\n"
|
||||||
|
" y: float,\n"
|
||||||
|
" width: float,\n"
|
||||||
|
" height: float,\n"
|
||||||
|
" call: Callable[[], Any] | None,\n"
|
||||||
|
" h_anchor: str,\n"
|
||||||
|
" label_scale: float,\n"
|
||||||
|
" corner_radius: float,\n"
|
||||||
|
") -> None\n"
|
||||||
|
"\n"
|
||||||
|
"(internal)",
|
||||||
|
};
|
||||||
|
|
||||||
|
// -------------------- dev_console_add_python_terminal ------------------------
|
||||||
|
|
||||||
|
static auto PyDevConsoleAddPythonTerminal(PyObject* self, PyObject* args)
|
||||||
|
-> PyObject* {
|
||||||
|
BA_PYTHON_TRY;
|
||||||
|
BA_PRECONDITION(g_base->InLogicThread());
|
||||||
|
auto* dev_console = g_base->ui->dev_console();
|
||||||
|
BA_PRECONDITION(dev_console);
|
||||||
|
BA_PRECONDITION(dev_console->IsActive());
|
||||||
|
if (!PyArg_ParseTuple(args, "")) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
dev_console->AddPythonTerminal();
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
BA_PYTHON_CATCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyMethodDef PyDevConsoleAddPythonTerminalDef = {
|
||||||
|
"dev_console_add_python_terminal", // name
|
||||||
|
(PyCFunction)PyDevConsoleAddPythonTerminal, // method
|
||||||
|
METH_VARARGS, // flags
|
||||||
|
|
||||||
|
"dev_console_add_python_terminal() -> None\n"
|
||||||
|
"\n"
|
||||||
|
"(internal)",
|
||||||
|
};
|
||||||
|
|
||||||
|
// ------------------------ dev_console_tab_width ------------------------------
|
||||||
|
|
||||||
|
static auto PyDevConsoleTabWidth(PyObject* self) -> PyObject* {
|
||||||
|
BA_PYTHON_TRY;
|
||||||
|
BA_PRECONDITION(g_base->InLogicThread());
|
||||||
|
auto* dev_console = g_base->ui->dev_console();
|
||||||
|
BA_PRECONDITION(dev_console);
|
||||||
|
BA_PRECONDITION(dev_console->IsActive());
|
||||||
|
return PyFloat_FromDouble(dev_console->Width());
|
||||||
|
BA_PYTHON_CATCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyMethodDef PyDevConsoleTabWidthDef = {
|
||||||
|
"dev_console_tab_width", // name
|
||||||
|
(PyCFunction)PyDevConsoleTabWidth, // method
|
||||||
|
METH_NOARGS, // flags
|
||||||
|
|
||||||
|
"dev_console_tab_width() -> float\n"
|
||||||
|
"\n"
|
||||||
|
"(internal)",
|
||||||
|
};
|
||||||
|
|
||||||
|
// ------------------------ dev_console_tab_height -----------------------------
|
||||||
|
|
||||||
|
static auto PyDevConsoleTabHeight(PyObject* self) -> PyObject* {
|
||||||
|
BA_PYTHON_TRY;
|
||||||
|
BA_PRECONDITION(g_base->InLogicThread());
|
||||||
|
auto* dev_console = g_base->ui->dev_console();
|
||||||
|
BA_PRECONDITION(dev_console);
|
||||||
|
BA_PRECONDITION(dev_console->IsActive());
|
||||||
|
return PyFloat_FromDouble(dev_console->Height());
|
||||||
|
BA_PYTHON_CATCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyMethodDef PyDevConsoleTabHeightDef = {
|
||||||
|
"dev_console_tab_height", // name
|
||||||
|
(PyCFunction)PyDevConsoleTabHeight, // method
|
||||||
|
METH_NOARGS, // flags
|
||||||
|
|
||||||
|
"dev_console_tab_height() -> float\n"
|
||||||
|
"\n"
|
||||||
|
"(internal)",
|
||||||
|
};
|
||||||
|
|
||||||
|
// ----------------------- dev_console_base_scale ------------------------------
|
||||||
|
|
||||||
|
static auto PyDevConsoleBaseScale(PyObject* self) -> PyObject* {
|
||||||
|
BA_PYTHON_TRY;
|
||||||
|
BA_PRECONDITION(g_base->InLogicThread());
|
||||||
|
auto* dev_console = g_base->ui->dev_console();
|
||||||
|
BA_PRECONDITION(dev_console);
|
||||||
|
BA_PRECONDITION(dev_console->IsActive());
|
||||||
|
return PyFloat_FromDouble(dev_console->BaseScale());
|
||||||
|
BA_PYTHON_CATCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyMethodDef PyDevConsoleBaseScaleDef = {
|
||||||
|
"dev_console_base_scale", // name
|
||||||
|
(PyCFunction)PyDevConsoleBaseScale, // method
|
||||||
|
METH_NOARGS, // flags
|
||||||
|
|
||||||
|
"dev_console_base_scale() -> float\n"
|
||||||
|
"\n"
|
||||||
|
"(internal)",
|
||||||
|
};
|
||||||
|
|
||||||
|
// -------------------- dev_console_request_refresh ----------------------------
|
||||||
|
|
||||||
|
static auto PyDevConsoleRequestRefresh(PyObject* self) -> PyObject* {
|
||||||
|
BA_PYTHON_TRY;
|
||||||
|
BA_PRECONDITION(g_base->InLogicThread());
|
||||||
|
auto* dev_console = g_base->ui->dev_console();
|
||||||
|
BA_PRECONDITION(dev_console);
|
||||||
|
BA_PRECONDITION(dev_console->IsActive());
|
||||||
|
dev_console->RequestRefresh();
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
BA_PYTHON_CATCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyMethodDef PyDevConsoleRequestRefreshDef = {
|
||||||
|
"dev_console_request_refresh", // name
|
||||||
|
(PyCFunction)PyDevConsoleRequestRefresh, // method
|
||||||
|
METH_NOARGS, // flags
|
||||||
|
|
||||||
|
"dev_console_request_refresh() -> None\n"
|
||||||
|
"\n"
|
||||||
|
"(internal)",
|
||||||
|
};
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
auto PythonMethodsMisc::GetMethods() -> std::vector<PyMethodDef> {
|
auto PythonMethodsMisc::GetMethods() -> std::vector<PyMethodDef> {
|
||||||
@ -1505,6 +1669,12 @@ auto PythonMethodsMisc::GetMethods() -> std::vector<PyMethodDef> {
|
|||||||
PyNativeStackTraceDef,
|
PyNativeStackTraceDef,
|
||||||
PyOpenDirExternallyDef,
|
PyOpenDirExternallyDef,
|
||||||
PyFatalErrorDef,
|
PyFatalErrorDef,
|
||||||
|
PyDevConsoleAddButtonDef,
|
||||||
|
PyDevConsoleAddPythonTerminalDef,
|
||||||
|
PyDevConsoleTabWidthDef,
|
||||||
|
PyDevConsoleTabHeightDef,
|
||||||
|
PyDevConsoleBaseScaleDef,
|
||||||
|
PyDevConsoleRequestRefreshDef,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -16,6 +16,7 @@
|
|||||||
#include "ballistica/core/core.h"
|
#include "ballistica/core/core.h"
|
||||||
#include "ballistica/core/platform/support/min_sdl.h"
|
#include "ballistica/core/platform/support/min_sdl.h"
|
||||||
#include "ballistica/shared/foundation/event_loop.h"
|
#include "ballistica/shared/foundation/event_loop.h"
|
||||||
|
#include "ballistica/shared/foundation/macros.h"
|
||||||
#include "ballistica/shared/generic/utils.h"
|
#include "ballistica/shared/generic/utils.h"
|
||||||
#include "ballistica/shared/python/python_command.h"
|
#include "ballistica/shared/python/python_command.h"
|
||||||
#include "ballistica/shared/python/python_sys.h"
|
#include "ballistica/shared/python/python_sys.h"
|
||||||
@ -103,7 +104,8 @@ class DevConsole::Button_ : public DevConsole::Widget_ {
|
|||||||
|
|
||||||
template <typename F>
|
template <typename F>
|
||||||
Button_(const std::string& label, float text_scale, DevButtonAttach_ attach,
|
Button_(const std::string& label, float text_scale, DevButtonAttach_ attach,
|
||||||
float x, float y, float width, float height, const F& lambda)
|
float x, float y, float width, float height, float corner_radius,
|
||||||
|
const F& lambda)
|
||||||
: attach{attach},
|
: attach{attach},
|
||||||
x{x},
|
x{x},
|
||||||
y{y},
|
y{y},
|
||||||
@ -112,14 +114,10 @@ class DevConsole::Button_ : public DevConsole::Widget_ {
|
|||||||
call{NewLambdaRunnable(lambda)},
|
call{NewLambdaRunnable(lambda)},
|
||||||
text_scale{text_scale},
|
text_scale{text_scale},
|
||||||
mesh(0.0f, 0.0f, 0.0f, width, height,
|
mesh(0.0f, 0.0f, 0.0f, width, height,
|
||||||
NinePatchMesh::BorderForRadius(kDevConsoleButtonCornerRadius,
|
NinePatchMesh::BorderForRadius(corner_radius, width, height),
|
||||||
width, height),
|
NinePatchMesh::BorderForRadius(corner_radius, height, width),
|
||||||
NinePatchMesh::BorderForRadius(kDevConsoleButtonCornerRadius,
|
NinePatchMesh::BorderForRadius(corner_radius, width, height),
|
||||||
height, width),
|
NinePatchMesh::BorderForRadius(corner_radius, height, width)) {
|
||||||
NinePatchMesh::BorderForRadius(kDevConsoleButtonCornerRadius,
|
|
||||||
width, height),
|
|
||||||
NinePatchMesh::BorderForRadius(kDevConsoleButtonCornerRadius,
|
|
||||||
height, width)) {
|
|
||||||
text_group.SetText(label, TextMesh::HAlign::kCenter,
|
text_group.SetText(label, TextMesh::HAlign::kCenter,
|
||||||
TextMesh::VAlign::kCenter);
|
TextMesh::VAlign::kCenter);
|
||||||
}
|
}
|
||||||
@ -309,9 +307,10 @@ class DevConsole::TabButton_ : public DevConsole::Widget_ {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class DevConsole::Line_ {
|
class DevConsole::OutputLine_ {
|
||||||
public:
|
public:
|
||||||
Line_(std::string s_in, double c) : creation_time(c), s(std::move(s_in)) {}
|
OutputLine_(std::string s_in, double c)
|
||||||
|
: creation_time(c), s(std::move(s_in)) {}
|
||||||
double creation_time;
|
double creation_time;
|
||||||
std::string s;
|
std::string s;
|
||||||
auto GetText() -> TextGroup& {
|
auto GetText() -> TextGroup& {
|
||||||
@ -340,43 +339,112 @@ DevConsole::DevConsole() {
|
|||||||
title_text_group_.SetText(title);
|
title_text_group_.SetText(title);
|
||||||
built_text_group_.SetText("Built: " __DATE__ " " __TIME__);
|
built_text_group_.SetText("Built: " __DATE__ " " __TIME__);
|
||||||
prompt_text_group_.SetText(">");
|
prompt_text_group_.SetText(">");
|
||||||
|
|
||||||
Refresh();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DevConsole::Refresh() {
|
DevConsole::~DevConsole() = default;
|
||||||
BA_PRECONDITION(g_base->InLogicThread());
|
|
||||||
buttons_.clear();
|
|
||||||
tab_buttons_.clear();
|
|
||||||
RefreshTabsButtons_();
|
|
||||||
|
|
||||||
if (active_tab_ == "Python") {
|
void DevConsole::RefreshTabButtons_() {
|
||||||
float bs = PythonConsoleBaseScale_();
|
// Ask the Python layer for the latest set of tabs.
|
||||||
buttons_.emplace_back(std::make_unique<Button_>(
|
tabs_ = g_base->python->objs()
|
||||||
"Exec", 0.75f * bs, DevButtonAttach_::kRight, -33.0f * bs, 15.95f * bs,
|
.Get(BasePython::ObjID::kGetDevConsoleTabNamesCall)
|
||||||
32.0f * bs, 13.0f * bs, [this] { Exec(); }));
|
.Call()
|
||||||
|
.ValueAsStringSequence();
|
||||||
|
// If we have tabs and none of them are selected, select the first.
|
||||||
|
if (!tabs_.empty()) {
|
||||||
|
bool found{};
|
||||||
|
for (auto&& tab : tabs_) {
|
||||||
|
if (active_tab_ == tab) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
active_tab_ = tabs_.front();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void DevConsole::RefreshTabsButtons_() {
|
// Now rebuild our buttons for them.
|
||||||
float bs = PythonConsoleBaseScale_();
|
tab_buttons_.clear();
|
||||||
|
float bs = BaseScale();
|
||||||
float bwidth = 90.0f * bs;
|
float bwidth = 90.0f * bs;
|
||||||
float bheight = 26.0f * bs;
|
float bheight = 26.0f * bs;
|
||||||
float bscale = 0.8f * bs;
|
float bscale = 0.8f * bs;
|
||||||
float total_width = tabs_.size() * bwidth;
|
float total_width = tabs_.size() * bwidth;
|
||||||
float x = total_width * -0.5f;
|
float x = total_width * -0.5f;
|
||||||
|
|
||||||
for (auto&& tab : tabs_) {
|
for (auto&& tab : tabs_) {
|
||||||
tab_buttons_.emplace_back(std::make_unique<TabButton_>(
|
tab_buttons_.emplace_back(std::make_unique<TabButton_>(
|
||||||
tab, active_tab_ == tab, bscale, DevButtonAttach_::kCenter, x, -bheight,
|
tab, active_tab_ == tab, bscale, DevButtonAttach_::kCenter, x, -bheight,
|
||||||
bwidth, bheight, [this, tab] {
|
bwidth, bheight, [this, tab] {
|
||||||
active_tab_ = tab;
|
active_tab_ = tab;
|
||||||
Refresh();
|
RefreshTabButtons_();
|
||||||
|
RefreshTabContents_();
|
||||||
}));
|
}));
|
||||||
x += bwidth;
|
x += bwidth;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DevConsole::~DevConsole() = default;
|
|
||||||
|
void DevConsole::RefreshTabContents_() {
|
||||||
|
BA_PRECONDITION(g_base->InLogicThread());
|
||||||
|
|
||||||
|
// Consider any refresh requests fulfilled. Subsequent refresh-requests
|
||||||
|
// will generate a new refresh at this point.
|
||||||
|
refresh_pending_ = false;
|
||||||
|
|
||||||
|
// Clear to an empty slate.
|
||||||
|
buttons_.clear();
|
||||||
|
python_terminal_visible_ = false;
|
||||||
|
|
||||||
|
// Now ask the Python layer to fill this tab in.
|
||||||
|
PythonRef args(Py_BuildValue("(s)", active_tab_.c_str()), PythonRef::kSteal);
|
||||||
|
g_base->python->objs()
|
||||||
|
.Get(BasePython::ObjID::kAppDevConsoleDoRefreshTabCall)
|
||||||
|
.Call(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DevConsole::AddButton(const char* label, float x, float y, float width,
|
||||||
|
float height, PyObject* call, const char* h_anchor,
|
||||||
|
float label_scale, float corner_radius) {
|
||||||
|
assert(g_base->InLogicThread());
|
||||||
|
|
||||||
|
DevButtonAttach_ anchor;
|
||||||
|
if (!strcmp(h_anchor, "left")) {
|
||||||
|
anchor = DevButtonAttach_::kLeft;
|
||||||
|
} else if (!strcmp(h_anchor, "right")) {
|
||||||
|
anchor = DevButtonAttach_::kRight;
|
||||||
|
} else {
|
||||||
|
assert(!strcmp(h_anchor, "center"));
|
||||||
|
anchor = DevButtonAttach_::kCenter;
|
||||||
|
}
|
||||||
|
|
||||||
|
// auto call_obj = PythonRef::Acquired(call);
|
||||||
|
buttons_.emplace_back(std::make_unique<Button_>(
|
||||||
|
label, label_scale, anchor, x, y, width, height, corner_radius,
|
||||||
|
[this, call_obj = PythonRef::Acquired(call)] {
|
||||||
|
if (call_obj.Get() != Py_None) {
|
||||||
|
call_obj.Call();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DevConsole::AddPythonTerminal() {
|
||||||
|
float bs = BaseScale();
|
||||||
|
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, 2.0 * bs, [this] { Exec(); }));
|
||||||
|
python_terminal_visible_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DevConsole::RequestRefresh() {
|
||||||
|
assert(g_base->InLogicThread());
|
||||||
|
|
||||||
|
// Schedule a refresh. If one is already scheduled but hasn't run, do
|
||||||
|
// nothing.
|
||||||
|
if (refresh_pending_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
refresh_pending_ = true;
|
||||||
|
g_base->logic->event_loop()->PushCall([this] { RefreshTabContents_(); });
|
||||||
|
}
|
||||||
|
|
||||||
auto DevConsole::HandleMouseDown(int button, float x, float y) -> bool {
|
auto DevConsole::HandleMouseDown(int button, float x, float y) -> bool {
|
||||||
assert(g_base->InLogicThread());
|
assert(g_base->InLogicThread());
|
||||||
@ -404,13 +472,21 @@ auto DevConsole::HandleMouseDown(int button, float x, float y) -> bool {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (button == 1) {
|
if (button == 1 && python_terminal_visible_) {
|
||||||
python_console_pressed_ = true;
|
python_terminal_pressed_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto DevConsole::Width() -> float {
|
||||||
|
return g_base->graphics->screen_virtual_width();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto DevConsole::Height() -> float {
|
||||||
|
return g_base->graphics->screen_virtual_height() - Bottom_();
|
||||||
|
}
|
||||||
|
|
||||||
void DevConsole::HandleMouseUp(int button, float x, float y) {
|
void DevConsole::HandleMouseUp(int button, float x, float y) {
|
||||||
assert(g_base->InLogicThread());
|
assert(g_base->InLogicThread());
|
||||||
float bottom{Bottom_()};
|
float bottom{Bottom_()};
|
||||||
@ -424,8 +500,8 @@ void DevConsole::HandleMouseUp(int button, float x, float y) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (button == 1 && python_console_pressed_) {
|
if (button == 1 && python_terminal_pressed_) {
|
||||||
python_console_pressed_ = false;
|
python_terminal_pressed_ = false;
|
||||||
if (y > bottom) {
|
if (y > bottom) {
|
||||||
// If we're not getting fed keyboard events and have a string editor
|
// If we're not getting fed keyboard events and have a string editor
|
||||||
// available, invoke it.
|
// available, invoke it.
|
||||||
@ -548,19 +624,6 @@ auto DevConsole::HandleKeyPress(const SDL_Keysym* keysym) -> bool {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
// #if BA_SDL2_BUILD || BA_MINSDL_BUILD
|
|
||||||
// // (in SDL2/Non-SDL we dont' get chars from keypress events;
|
|
||||||
// // they come through as text edit events)
|
|
||||||
// #else // BA_SDL2_BUILD
|
|
||||||
// if (keysym->unicode < 0x80 && keysym->unicode > 0) {
|
|
||||||
// std::vector<uint32_t> unichars =
|
|
||||||
// Utils::UnicodeFromUTF8(input_string_, "cjofrh0");
|
|
||||||
// unichars.push_back(keysym->unicode);
|
|
||||||
// input_string_ = Utils::GetValidUTF8(
|
|
||||||
// Utils::UTF8FromUnicode(unichars).c_str(), "sdkr");
|
|
||||||
// input_text_dirty_ = true;
|
|
||||||
// }
|
|
||||||
// #endif // BA_SDL2_BUILD
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -576,9 +639,9 @@ void DevConsole::Exec() {
|
|||||||
input_history_position_ = 0;
|
input_history_position_ = 0;
|
||||||
if (input_string_ == "clear") {
|
if (input_string_ == "clear") {
|
||||||
last_line_.clear();
|
last_line_.clear();
|
||||||
lines_.clear();
|
output_lines_.clear();
|
||||||
} else {
|
} else {
|
||||||
SubmitCommand_(input_string_);
|
SubmitPythonCommand_(input_string_);
|
||||||
}
|
}
|
||||||
input_history_.push_front(input_string_);
|
input_history_.push_front(input_string_);
|
||||||
if (input_history_.size() > 100) {
|
if (input_history_.size() > 100) {
|
||||||
@ -588,7 +651,7 @@ void DevConsole::Exec() {
|
|||||||
input_text_dirty_ = true;
|
input_text_dirty_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DevConsole::SubmitCommand_(const std::string& command) {
|
void DevConsole::SubmitPythonCommand_(const std::string& command) {
|
||||||
assert(g_base);
|
assert(g_base);
|
||||||
g_base->logic->event_loop()->PushCall([command, this] {
|
g_base->logic->event_loop()->PushCall([command, this] {
|
||||||
// These are always run in whichever context is 'visible'.
|
// These are always run in whichever context is 'visible'.
|
||||||
@ -631,9 +694,12 @@ void DevConsole::ToggleState() {
|
|||||||
switch (state_) {
|
switch (state_) {
|
||||||
case State_::kInactive:
|
case State_::kInactive:
|
||||||
state_ = State_::kMini;
|
state_ = State_::kMini;
|
||||||
|
RefreshTabButtons_();
|
||||||
|
RefreshTabContents_();
|
||||||
break;
|
break;
|
||||||
case State_::kMini:
|
case State_::kMini:
|
||||||
state_ = State_::kFull;
|
state_ = State_::kFull;
|
||||||
|
RefreshTabContents_();
|
||||||
break;
|
break;
|
||||||
case State_::kFull:
|
case State_::kFull:
|
||||||
state_ = State_::kInactive;
|
state_ = State_::kInactive;
|
||||||
@ -650,6 +716,9 @@ auto DevConsole::HandleTextEditing(const std::string& text) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Ignore back-tick because we use that key to toggle the console.
|
// Ignore back-tick because we use that key to toggle the console.
|
||||||
|
//
|
||||||
|
// FIXME: Perhaps should allow typing it if some control-character is
|
||||||
|
// held?
|
||||||
if (text == "`") {
|
if (text == "`") {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -679,9 +748,9 @@ void DevConsole::Print(const std::string& s_in) {
|
|||||||
|
|
||||||
// Spit out all completed lines and keep the last one as lastline.
|
// Spit out all completed lines and keep the last one as lastline.
|
||||||
for (size_t i = 0; i < broken_up.size() - 1; i++) {
|
for (size_t i = 0; i < broken_up.size() - 1; i++) {
|
||||||
lines_.emplace_back(broken_up[i], g_base->logic->display_time());
|
output_lines_.emplace_back(broken_up[i], g_base->logic->display_time());
|
||||||
if (lines_.size() > kDevConsoleLineLimit) {
|
if (output_lines_.size() > kDevConsoleLineLimit) {
|
||||||
lines_.pop_front();
|
output_lines_.pop_front();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
last_line_ = broken_up[broken_up.size() - 1];
|
last_line_ = broken_up[broken_up.size() - 1];
|
||||||
@ -689,13 +758,18 @@ void DevConsole::Print(const std::string& s_in) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto DevConsole::Bottom_() const -> float {
|
auto DevConsole::Bottom_() const -> float {
|
||||||
float bs = PythonConsoleBaseScale_();
|
|
||||||
float vh = g_base->graphics->screen_virtual_height();
|
float vh = g_base->graphics->screen_virtual_height();
|
||||||
|
|
||||||
float ratio =
|
float ratio =
|
||||||
(g_base->logic->display_time() - transition_start_) / kTransitionSeconds;
|
(g_base->logic->display_time() - transition_start_) / kTransitionSeconds;
|
||||||
float bottom;
|
float bottom;
|
||||||
float mini_size = 90.0f * bs;
|
|
||||||
|
// NOTE: Originally I was tweaking this based on UI scale, but I decided
|
||||||
|
// that it would be a better idea to have a constant value everywhere.
|
||||||
|
// dev-consoles are not meant to be especially pretty and I think it is
|
||||||
|
// more important for them to be able to be written to a known hard-coded
|
||||||
|
// mini-size.
|
||||||
|
float mini_size = 100.0f;
|
||||||
if (state_ == State_::kMini) {
|
if (state_ == State_::kMini) {
|
||||||
bottom = vh - mini_size;
|
bottom = vh - mini_size;
|
||||||
} else {
|
} else {
|
||||||
@ -724,7 +798,7 @@ auto DevConsole::Bottom_() const -> float {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DevConsole::Draw(FrameDef* frame_def) {
|
void DevConsole::Draw(FrameDef* frame_def) {
|
||||||
float bs = PythonConsoleBaseScale_();
|
float bs = BaseScale();
|
||||||
RenderPass* pass = frame_def->overlay_front_pass();
|
RenderPass* pass = frame_def->overlay_front_pass();
|
||||||
|
|
||||||
// If we're not yet transitioning in for the first time OR have completed
|
// If we're not yet transitioning in for the first time OR have completed
|
||||||
@ -753,7 +827,7 @@ void DevConsole::Draw(FrameDef* frame_def) {
|
|||||||
c.SetColor(0, 0, 0.1f, 0.9f);
|
c.SetColor(0, 0, 0.1f, 0.9f);
|
||||||
c.DrawMesh(&bg_mesh_);
|
c.DrawMesh(&bg_mesh_);
|
||||||
c.Submit();
|
c.Submit();
|
||||||
if (active_tab_ == "Python") {
|
if (python_terminal_visible_) {
|
||||||
c.SetColor(1.0f, 1.0f, 1.0f, 0.1f);
|
c.SetColor(1.0f, 1.0f, 1.0f, 0.1f);
|
||||||
c.DrawMesh(&stripe_mesh_);
|
c.DrawMesh(&stripe_mesh_);
|
||||||
c.Submit();
|
c.Submit();
|
||||||
@ -779,7 +853,7 @@ void DevConsole::Draw(FrameDef* frame_def) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (active_tab_ == "Python") {
|
if (python_terminal_visible_) {
|
||||||
if (input_text_dirty_) {
|
if (input_text_dirty_) {
|
||||||
input_text_group_.SetText(input_string_);
|
input_text_group_.SetText(input_string_);
|
||||||
input_text_dirty_ = false;
|
input_text_dirty_ = false;
|
||||||
@ -887,7 +961,7 @@ void DevConsole::Draw(FrameDef* frame_def) {
|
|||||||
}
|
}
|
||||||
v += v_inc;
|
v += v_inc;
|
||||||
}
|
}
|
||||||
for (auto i = lines_.rbegin(); i != lines_.rend(); i++) {
|
for (auto i = output_lines_.rbegin(); i != output_lines_.rend(); i++) {
|
||||||
int elem_count = i->GetText().GetElementCount();
|
int elem_count = i->GetText().GetElementCount();
|
||||||
for (int e = 0; e < elem_count; e++) {
|
for (int e = 0; e < elem_count; e++) {
|
||||||
c.SetTexture(i->GetText().GetElementTexture(e));
|
c.SetTexture(i->GetText().GetElementTexture(e));
|
||||||
@ -922,7 +996,7 @@ void DevConsole::Draw(FrameDef* frame_def) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto DevConsole::PythonConsoleBaseScale_() const -> float {
|
auto DevConsole::BaseScale() const -> float {
|
||||||
switch (g_base->ui->scale()) {
|
switch (g_base->ui->scale()) {
|
||||||
case UIScale::kLarge:
|
case UIScale::kLarge:
|
||||||
return 1.5f;
|
return 1.5f;
|
||||||
|
|||||||
@ -51,24 +51,42 @@ class DevConsole {
|
|||||||
auto HandleMouseDown(int button, float x, float y) -> bool;
|
auto HandleMouseDown(int button, float x, float y) -> bool;
|
||||||
void HandleMouseUp(int button, float x, float y);
|
void HandleMouseUp(int button, float x, float y);
|
||||||
void Exec();
|
void Exec();
|
||||||
void Refresh();
|
|
||||||
|
void AddButton(const char* label, float x, float y, float width, float height,
|
||||||
|
PyObject* call, const char* h_anchor, float label_scale,
|
||||||
|
float corner_radius);
|
||||||
|
void AddPythonTerminal();
|
||||||
|
|
||||||
|
auto Width() -> float;
|
||||||
|
auto Height() -> float;
|
||||||
|
auto BaseScale() const -> float;
|
||||||
|
void RequestRefresh();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Widget_;
|
class Widget_;
|
||||||
class Button_;
|
class Button_;
|
||||||
class ToggleButton_;
|
class ToggleButton_;
|
||||||
class TabButton_;
|
class TabButton_;
|
||||||
class Line_;
|
class OutputLine_;
|
||||||
enum class State_ { kInactive, kMini, kFull };
|
enum class State_ : uint8_t { kInactive, kMini, kFull };
|
||||||
|
|
||||||
auto Bottom_() const -> float;
|
auto Bottom_() const -> float;
|
||||||
auto PythonConsoleBaseScale_() const -> float;
|
void SubmitPythonCommand_(const std::string& command);
|
||||||
void SubmitCommand_(const std::string& command);
|
|
||||||
void InvokeStringEditor_();
|
void InvokeStringEditor_();
|
||||||
void RefreshTabsButtons_();
|
void RefreshTabButtons_();
|
||||||
|
void RefreshTabContents_();
|
||||||
|
|
||||||
std::list<std::string> tabs_{"Python", "AppModes", "Logging", "Graphics"};
|
bool input_text_dirty_{true};
|
||||||
std::string active_tab_{"Python"};
|
bool input_enabled_{};
|
||||||
|
bool last_line_mesh_dirty_{true};
|
||||||
|
bool python_terminal_visible_{};
|
||||||
|
bool python_terminal_pressed_{};
|
||||||
|
bool refresh_pending_{};
|
||||||
|
State_ state_{State_::kInactive};
|
||||||
|
State_ state_prev_{State_::kInactive};
|
||||||
|
millisecs_t last_input_text_change_time_{};
|
||||||
|
double transition_start_{};
|
||||||
|
int input_history_position_{};
|
||||||
ImageMesh bg_mesh_;
|
ImageMesh bg_mesh_;
|
||||||
ImageMesh stripe_mesh_;
|
ImageMesh stripe_mesh_;
|
||||||
ImageMesh border_mesh_;
|
ImageMesh border_mesh_;
|
||||||
@ -76,21 +94,15 @@ class DevConsole {
|
|||||||
TextGroup title_text_group_;
|
TextGroup title_text_group_;
|
||||||
TextGroup prompt_text_group_;
|
TextGroup prompt_text_group_;
|
||||||
TextGroup input_text_group_;
|
TextGroup input_text_group_;
|
||||||
millisecs_t last_input_text_change_time_{};
|
|
||||||
bool input_text_dirty_{true};
|
|
||||||
double transition_start_{};
|
|
||||||
State_ state_{State_::kInactive};
|
|
||||||
State_ state_prev_{State_::kInactive};
|
|
||||||
bool input_enabled_{};
|
|
||||||
std::string input_string_;
|
|
||||||
std::list<std::string> input_history_;
|
|
||||||
int input_history_position_{};
|
|
||||||
std::list<Line_> lines_;
|
|
||||||
std::string last_line_;
|
std::string last_line_;
|
||||||
Object::Ref<TextGroup> last_line_mesh_group_;
|
std::string input_string_;
|
||||||
bool last_line_mesh_dirty_{true};
|
std::list<std::string> tabs_{"Python", "AppModes", "Logging", "Graphics",
|
||||||
bool python_console_pressed_{};
|
"UI"};
|
||||||
|
std::string active_tab_{"Python"};
|
||||||
PythonRef string_edit_adapter_;
|
PythonRef string_edit_adapter_;
|
||||||
|
Object::Ref<TextGroup> last_line_mesh_group_;
|
||||||
|
std::list<std::string> input_history_;
|
||||||
|
std::list<OutputLine_> output_lines_;
|
||||||
std::vector<std::unique_ptr<Widget_> > buttons_;
|
std::vector<std::unique_ptr<Widget_> > buttons_;
|
||||||
std::vector<std::unique_ptr<Widget_> > tab_buttons_;
|
std::vector<std::unique_ptr<Widget_> > tab_buttons_;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -39,7 +39,7 @@ auto main(int argc, char** argv) -> int {
|
|||||||
namespace ballistica {
|
namespace ballistica {
|
||||||
|
|
||||||
// These are set automatically via script; don't modify them here.
|
// These are set automatically via script; don't modify them here.
|
||||||
const int kEngineBuildNumber = 21401;
|
const int kEngineBuildNumber = 21405;
|
||||||
const char* kEngineVersion = "1.7.28";
|
const char* kEngineVersion = "1.7.28";
|
||||||
const int kEngineApiVersion = 8;
|
const int kEngineApiVersion = 8;
|
||||||
|
|
||||||
|
|||||||
@ -21,7 +21,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define BA_OSTYPE_MACOS 1
|
#define BA_OSTYPE_MACOS 1
|
||||||
#define BA_HAVE_FRAMEWORK_OPENAL 1
|
// #define BA_HAVE_FRAMEWORK_OPENAL 1
|
||||||
|
|
||||||
#elif __linux__
|
#elif __linux__
|
||||||
|
|
||||||
|
|||||||
@ -225,7 +225,7 @@ auto Python::GetPyFloats(PyObject* o) -> std::vector<float> {
|
|||||||
return vals;
|
return vals;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Python::GetPyStrings(PyObject* o) -> std::list<std::string> {
|
auto Python::GetPyStringSequence(PyObject* o) -> std::list<std::string> {
|
||||||
assert(HaveGIL());
|
assert(HaveGIL());
|
||||||
BA_PRECONDITION_FATAL(o != nullptr);
|
BA_PRECONDITION_FATAL(o != nullptr);
|
||||||
|
|
||||||
|
|||||||
@ -125,7 +125,7 @@ class Python {
|
|||||||
static auto GetPyInts(PyObject* o) -> std::vector<int>;
|
static auto GetPyInts(PyObject* o) -> std::vector<int>;
|
||||||
static auto GetPyUInts64(PyObject* o) -> std::vector<uint64_t>;
|
static auto GetPyUInts64(PyObject* o) -> std::vector<uint64_t>;
|
||||||
static auto GetPyPoint2D(PyObject* o) -> Point2D;
|
static auto GetPyPoint2D(PyObject* o) -> Point2D;
|
||||||
static auto GetPyStrings(PyObject* o) -> std::list<std::string>;
|
static auto GetPyStringSequence(PyObject* o) -> std::list<std::string>;
|
||||||
|
|
||||||
/// Set Python exception from C++ Exception.
|
/// Set Python exception from C++ Exception.
|
||||||
static void SetPythonException(const Exception& exc);
|
static void SetPythonException(const Exception& exc);
|
||||||
|
|||||||
@ -162,6 +162,12 @@ auto PythonRef::ValueAsString() const -> std::string {
|
|||||||
return Python::GetPyString(obj_);
|
return Python::GetPyString(obj_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto PythonRef::ValueAsStringSequence() const -> std::list<std::string> {
|
||||||
|
assert(Python::HaveGIL());
|
||||||
|
ThrowIfUnset();
|
||||||
|
return Python::GetPyStringSequence(obj_);
|
||||||
|
}
|
||||||
|
|
||||||
auto PythonRef::ValueAsOptionalInt() const -> std::optional<int64_t> {
|
auto PythonRef::ValueAsOptionalInt() const -> std::optional<int64_t> {
|
||||||
assert(Python::HaveGIL());
|
assert(Python::HaveGIL());
|
||||||
ThrowIfUnset();
|
ThrowIfUnset();
|
||||||
@ -193,7 +199,7 @@ auto PythonRef::ValueAsOptionalStringSequence() const
|
|||||||
if (obj_ == Py_None) {
|
if (obj_ == Py_None) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
return Python::GetPyStrings(obj_);
|
return Python::GetPyStringSequence(obj_);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto PythonRef::ValueAsInt() const -> int64_t {
|
auto PythonRef::ValueAsInt() const -> int64_t {
|
||||||
|
|||||||
@ -166,6 +166,7 @@ class PythonRef {
|
|||||||
auto ValueAsLString() const -> std::string;
|
auto ValueAsLString() const -> std::string;
|
||||||
|
|
||||||
auto ValueAsString() const -> std::string;
|
auto ValueAsString() const -> std::string;
|
||||||
|
auto ValueAsStringSequence() const -> std::list<std::string>;
|
||||||
auto ValueAsOptionalString() const -> std::optional<std::string>;
|
auto ValueAsOptionalString() const -> std::optional<std::string>;
|
||||||
auto ValueAsOptionalStringSequence() const
|
auto ValueAsOptionalStringSequence() const
|
||||||
-> std::optional<std::list<std::string>>;
|
-> std::optional<std::list<std::string>>;
|
||||||
|
|||||||
@ -53,6 +53,7 @@ values = [
|
|||||||
_hooks.do_quit, # kQuitCall
|
_hooks.do_quit, # kQuitCall
|
||||||
_hooks.show_post_purchase_message, # kShowPostPurchaseMessageCall
|
_hooks.show_post_purchase_message, # kShowPostPurchaseMessageCall
|
||||||
_hooks.string_edit_adapter_can_be_replaced, # kStringEditAdapterCanBeReplacedCall
|
_hooks.string_edit_adapter_can_be_replaced, # kStringEditAdapterCanBeReplacedCall
|
||||||
|
_hooks.get_dev_console_tab_names, # kGetDevConsoleTabNamesCall
|
||||||
_language.Lstr, # kLStrClass
|
_language.Lstr, # kLStrClass
|
||||||
_general.Call, # kCallClass
|
_general.Call, # kCallClass
|
||||||
_apputils.garbage_collect_session_end, # kGarbageCollectSessionEndCall
|
_apputils.garbage_collect_session_end, # kGarbageCollectSessionEndCall
|
||||||
|
|||||||
@ -19,4 +19,5 @@ values = [
|
|||||||
app.on_native_shutdown, # kAppOnNativeShutdownCall
|
app.on_native_shutdown, # kAppOnNativeShutdownCall
|
||||||
app.on_native_shutdown_complete, # kAppOnNativeShutdownCompleteCall
|
app.on_native_shutdown_complete, # kAppOnNativeShutdownCompleteCall
|
||||||
app.read_config, # kAppReadConfigCall
|
app.read_config, # kAppReadConfigCall
|
||||||
|
app.devconsole.do_refresh_tab, # kAppDevConsoleDoRefreshTabCall
|
||||||
]
|
]
|
||||||
|
|||||||
@ -36,7 +36,6 @@ class HostConfig:
|
|||||||
mosh_shell: str = 'sh'
|
mosh_shell: str = 'sh'
|
||||||
workspaces_root: str = '/home/${USER}/cloudshell_workspaces'
|
workspaces_root: str = '/home/${USER}/cloudshell_workspaces'
|
||||||
sync_perms: bool = True
|
sync_perms: bool = True
|
||||||
precommand: str | None = None # KILL THIS
|
|
||||||
precommand_noninteractive: str | None = None
|
precommand_noninteractive: str | None = None
|
||||||
precommand_interactive: str | None = None
|
precommand_interactive: str | None = None
|
||||||
managed: bool = False
|
managed: bool = False
|
||||||
|
|||||||
@ -728,16 +728,18 @@ def echo() -> None:
|
|||||||
clrnames = {n for n in dir(clr) if n.isupper() and not n.startswith('_')}
|
clrnames = {n for n in dir(clr) if n.isupper() and not n.startswith('_')}
|
||||||
first = True
|
first = True
|
||||||
out: list[str] = []
|
out: list[str] = []
|
||||||
|
last_was_tag = False
|
||||||
for arg in pcommand.get_args():
|
for arg in pcommand.get_args():
|
||||||
if arg in clrnames:
|
if arg in clrnames:
|
||||||
out.append(getattr(clr, arg))
|
out.append(getattr(clr, arg))
|
||||||
|
last_was_tag = True
|
||||||
else:
|
else:
|
||||||
# Special case: a dot by itself is treated as a period for
|
# Special case: punctuation by itself after a tag doesn't
|
||||||
# the previous arg. This lets us do periods following color
|
# get a space before it.
|
||||||
# tags.
|
if not first and not (last_was_tag and arg in ('.', '?', '!')):
|
||||||
if not first and arg != '.':
|
|
||||||
out.append(' ')
|
out.append(' ')
|
||||||
first = False
|
first = False
|
||||||
|
last_was_tag = False
|
||||||
out.append(arg)
|
out.append(arg)
|
||||||
out.append(clr.RST)
|
out.append(clr.RST)
|
||||||
pcommand.clientprint(''.join(out))
|
pcommand.clientprint(''.join(out))
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user