mirror of
https://github.com/RYDE-WORK/ballistica.git
synced 2026-01-19 21:37:57 +08:00
various input and config cleanup
This commit is contained in:
parent
03675a22a3
commit
1115983bcc
56
.efrocachemap
generated
56
.efrocachemap
generated
@ -4056,26 +4056,26 @@
|
||||
"build/assets/windows/Win32/ucrtbased.dll": "2def5335207d41b21b9823f6805997f1",
|
||||
"build/assets/windows/Win32/vc_redist.x86.exe": "b08a55e2e77623fe657bea24f223a3ae",
|
||||
"build/assets/windows/Win32/vcruntime140d.dll": "865b2af4d1e26a1a8073c89acb06e599",
|
||||
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "bd21ea70f4aace3ddd6e86d19ca04707",
|
||||
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "eb9196d69cb13de5c02f8f205396ac8d",
|
||||
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "20e1738da78d266882053a21ad74d2d4",
|
||||
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "f2a2815bbfcbeff6041ade83999132a6",
|
||||
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "21c30ed4e87963efa9bbb401903d9bdd",
|
||||
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "ee324f4377ffe3135f0ce6ad62609281",
|
||||
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "76046cdfbb2ee3a2906b230f347c4361",
|
||||
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "ef80af070e2fecda641469df8828375a",
|
||||
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "7ff933a5f3a8bac754897df4a3e3d723",
|
||||
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "c4d26e212c3c824e25cf5bbf27465f34",
|
||||
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "0ab3966d350a39c39a28fa7b93ef1d08",
|
||||
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "e76707372e761bfd1d3b1d56cb76b91f",
|
||||
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "f1581f72dbfe22cf7ba5be436e80a5a3",
|
||||
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "b52af8580dcd6cac224d840a043be2a4",
|
||||
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "3fb98c6e7c82b533441c437188bbd1ce",
|
||||
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "ba62c05d2486524a2eef989898a4e57f",
|
||||
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "e872cfeade334bf471ce71f536571ff3",
|
||||
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "d688622611dde4d4b3ef0e14f87d0931",
|
||||
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "81887892b133fdf6df2249f8b1265e50",
|
||||
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "9325a017d3382c6979afd0d597727c46",
|
||||
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "637b3e06d6536db39d816e0b5820c0ab",
|
||||
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "e3a0ad82944e80528a227807a9a9ba6d",
|
||||
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "f8252819a3d84a2c3be5e3ed938e5f8b",
|
||||
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "7e8682e4ef71b0d432576ce8f879b3b2",
|
||||
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "eb3a79d46714a2585da45f66ae5352eb",
|
||||
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "1ebb8b160059182d79b586f40f4bb207",
|
||||
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "b51ff49b8e145ebee0d5a3f8c2e517fb",
|
||||
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "9eecb06461e9798439c4d15399b7d28a",
|
||||
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "7ffd1e3961eb68f820ff044f2ba62cf9",
|
||||
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "3ab890f1e4116739bce0e2c141440773",
|
||||
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "d6d47b5b7bf720c0936a53deffe07359",
|
||||
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "0ce0fcd7d19e767db721eb43f58424f7",
|
||||
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "4fac89dcba67096cd2f84f0b687b1880",
|
||||
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "0df3b09ffdf3dc519cea1a3a9fb959d2",
|
||||
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "8eb92b2fa10d56cfee3fd8da179cfda7",
|
||||
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "b0764a6280bfbe926b655df8f946e8e2",
|
||||
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "f69383ecdafab7a37907898fcbf98fa1",
|
||||
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "617e7ca8f4ed3d3f726ba9567a15732e",
|
||||
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "9133fee71d08209b5ac82f772edae5c9",
|
||||
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "1cfd194e81bb849e337b34df43157ba8",
|
||||
"build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "476e9cf1fb229a023babd799a6e535f1",
|
||||
"build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "cf2a61fae8e8cd757864202a09e71255",
|
||||
"build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "476e9cf1fb229a023babd799a6e535f1",
|
||||
@ -4092,14 +4092,14 @@
|
||||
"build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "1920c5412307a78aa658c3366c86b7fc",
|
||||
"build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "b257bbc06d82fc912653806c01a42c15",
|
||||
"build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "1920c5412307a78aa658c3366c86b7fc",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "7dbcf548c44407baad81a680bf08856e",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "14d512d2c10d74907653e102b5e86592",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "50865a4f46834954473d94ef217a2420",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "6ae64c31cdd77da2ef0c29e7131c9a0c",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "1791fd1babc070e7d6dfb9fe257fc8bf",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "801cb1351809a815f60decd90fe8877c",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "9652a72608a71583785bac7495a5397f",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "5072cccbd6c70f3a2183bd0242ba1f76",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "693493fea9a0068d67d05ac32c53d938",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "0ad9cd9671e260ea90f97a3334a063d0",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "0dc8f56e25b1bb2b67bdb6f1b65c56b6",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "02bfe33e3189d0993aff1884cae95ccf",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "7867875c532b032ace05fef64e278635",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "7dfdd479341808a7301158591caac092",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "3604c049578423bce477d0be543529f4",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "57b11043daad1545cd2abb0c13f43db7",
|
||||
"src/assets/ba_data/python/babase/_mgen/__init__.py": "f885fed7f2ed98ff2ba271f9dbe3391c",
|
||||
"src/assets/ba_data/python/babase/_mgen/enums.py": "28323912b56ec07701eda3d41a6a4101",
|
||||
"src/ballistica/base/mgen/pyembed/binding_base.inc": "6df0f34207346d89a72924249ddd4706",
|
||||
|
||||
18
CHANGELOG.md
18
CHANGELOG.md
@ -1,4 +1,4 @@
|
||||
### 1.7.28 (build 21525, api 8, 2023-10-27)
|
||||
### 1.7.28 (build 21528, api 8, 2023-10-27)
|
||||
|
||||
- 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
|
||||
@ -176,6 +176,22 @@
|
||||
who never leave the party (Thanks EraOSBeta!).
|
||||
- Fixes an issue where servers could be crashed by flooding them with join
|
||||
requests (Thanks for the heads-up Era!).
|
||||
- The engine will now ignore empty device config dicts and fall back to
|
||||
defaults; these could theoretically happen if device config code fails
|
||||
somewhere and it previously would leave the device mysteriously inoperable.
|
||||
- The game will now show <unset> for controls with no bindings in the in-game
|
||||
guide and controller/keyboard config screens.
|
||||
- Fixed a crash that could occur if SDL couldn't find a name for connected
|
||||
joystick.
|
||||
- Simplified the app's handling of broken config files. Previously it would do
|
||||
various complex things such as offering to edit the broken config on desktop
|
||||
builds, avoiding overwriting broken configs, and automatically loading
|
||||
previous configs. Now, if it finds a broken config, it will simply back it up
|
||||
to a .broken file, log an error message, and then start up normally with a
|
||||
default config. This way, things are more consistent across platforms, and
|
||||
technical users can still fix and restore their old configs. Note that the app
|
||||
still also writes .prev configs for extra security, though it no longer uses
|
||||
them for anything itself.
|
||||
|
||||
### 1.7.27 (build 21282, api 8, 2023-08-30)
|
||||
|
||||
|
||||
@ -366,7 +366,6 @@
|
||||
"ba_data/python/bauiv1lib/__pycache__/characterpicker.cpython-311.opt-1.pyc",
|
||||
"ba_data/python/bauiv1lib/__pycache__/colorpicker.cpython-311.opt-1.pyc",
|
||||
"ba_data/python/bauiv1lib/__pycache__/config.cpython-311.opt-1.pyc",
|
||||
"ba_data/python/bauiv1lib/__pycache__/configerror.cpython-311.opt-1.pyc",
|
||||
"ba_data/python/bauiv1lib/__pycache__/confirm.cpython-311.opt-1.pyc",
|
||||
"ba_data/python/bauiv1lib/__pycache__/continues.cpython-311.opt-1.pyc",
|
||||
"ba_data/python/bauiv1lib/__pycache__/creditslist.cpython-311.opt-1.pyc",
|
||||
@ -417,7 +416,6 @@
|
||||
"ba_data/python/bauiv1lib/characterpicker.py",
|
||||
"ba_data/python/bauiv1lib/colorpicker.py",
|
||||
"ba_data/python/bauiv1lib/config.py",
|
||||
"ba_data/python/bauiv1lib/configerror.py",
|
||||
"ba_data/python/bauiv1lib/confirm.py",
|
||||
"ba_data/python/bauiv1lib/continues.py",
|
||||
"ba_data/python/bauiv1lib/coop/__init__.py",
|
||||
|
||||
@ -341,7 +341,6 @@ SCRIPT_TARGETS_PY_PUBLIC = \
|
||||
$(BUILD_DIR)/ba_data/python/bauiv1lib/characterpicker.py \
|
||||
$(BUILD_DIR)/ba_data/python/bauiv1lib/colorpicker.py \
|
||||
$(BUILD_DIR)/ba_data/python/bauiv1lib/config.py \
|
||||
$(BUILD_DIR)/ba_data/python/bauiv1lib/configerror.py \
|
||||
$(BUILD_DIR)/ba_data/python/bauiv1lib/confirm.py \
|
||||
$(BUILD_DIR)/ba_data/python/bauiv1lib/continues.py \
|
||||
$(BUILD_DIR)/ba_data/python/bauiv1lib/coop/__init__.py \
|
||||
@ -615,7 +614,6 @@ SCRIPT_TARGETS_PYC_PUBLIC = \
|
||||
$(BUILD_DIR)/ba_data/python/bauiv1lib/__pycache__/characterpicker.cpython-311.opt-1.pyc \
|
||||
$(BUILD_DIR)/ba_data/python/bauiv1lib/__pycache__/colorpicker.cpython-311.opt-1.pyc \
|
||||
$(BUILD_DIR)/ba_data/python/bauiv1lib/__pycache__/config.cpython-311.opt-1.pyc \
|
||||
$(BUILD_DIR)/ba_data/python/bauiv1lib/__pycache__/configerror.cpython-311.opt-1.pyc \
|
||||
$(BUILD_DIR)/ba_data/python/bauiv1lib/__pycache__/confirm.cpython-311.opt-1.pyc \
|
||||
$(BUILD_DIR)/ba_data/python/bauiv1lib/__pycache__/continues.cpython-311.opt-1.pyc \
|
||||
$(BUILD_DIR)/ba_data/python/bauiv1lib/coop/__pycache__/__init__.cpython-311.opt-1.pyc \
|
||||
|
||||
@ -184,7 +184,6 @@ class App:
|
||||
# foregrounded; can be a simple way to determine if network data
|
||||
# should be refreshed/etc.
|
||||
self.fg_state = 0
|
||||
self.config_file_healthy: bool = False
|
||||
|
||||
self._subsystems: list[AppSubsystem] = []
|
||||
self._native_bootstrapping_completed = False
|
||||
@ -433,7 +432,7 @@ class App:
|
||||
"""(internal)"""
|
||||
from babase._appconfig import read_app_config
|
||||
|
||||
self._config, self.config_file_healthy = read_app_config()
|
||||
self._config = read_app_config()
|
||||
|
||||
def handle_deep_link(self, url: str) -> None:
|
||||
"""Handle a deep link URL."""
|
||||
@ -583,19 +582,6 @@ class App:
|
||||
self._aioloop = _asyncio.setup_asyncio()
|
||||
self.health_monitor = AppHealthMonitor()
|
||||
|
||||
# Only proceed if our config file is healthy so we don't
|
||||
# overwrite a broken one or whatnot and wipe out data.
|
||||
if not self.config_file_healthy:
|
||||
if self.classic is not None:
|
||||
handled = self.classic.show_config_error_window()
|
||||
if handled:
|
||||
return
|
||||
|
||||
# For now on other systems we just overwrite the bum config.
|
||||
# At this point settings are already set; lets just commit
|
||||
# them to disk.
|
||||
_appconfig.commit_app_config(force=True)
|
||||
|
||||
# __FEATURESET_APP_SUBSYSTEM_CREATE_BEGIN__
|
||||
# This section generated by batools.appmodule; do not edit.
|
||||
|
||||
|
||||
@ -101,15 +101,13 @@ class AppConfig(dict):
|
||||
self.commit()
|
||||
|
||||
|
||||
def read_app_config() -> tuple[AppConfig, bool]:
|
||||
def read_app_config() -> AppConfig:
|
||||
"""Read the app config."""
|
||||
import os
|
||||
import json
|
||||
|
||||
config_file_healthy = False
|
||||
|
||||
# NOTE: it is assumed that this only gets called once and the
|
||||
# config object will not change from here on out
|
||||
# NOTE: it is assumed that this only gets called once and the config
|
||||
# object will not change from here on out
|
||||
config_file_path = _babase.app.env.config_file_path
|
||||
config_contents = ''
|
||||
try:
|
||||
@ -119,20 +117,16 @@ def read_app_config() -> tuple[AppConfig, bool]:
|
||||
config = AppConfig(json.loads(config_contents))
|
||||
else:
|
||||
config = AppConfig()
|
||||
config_file_healthy = True
|
||||
|
||||
except Exception:
|
||||
logging.exception(
|
||||
"Error reading config file at time %.3f: '%s'.",
|
||||
"Error reading config file '%s' at time %.3f.\n"
|
||||
"Backing up broken config to'%s.broken'.",
|
||||
config_file_path,
|
||||
_babase.apptime(),
|
||||
config_file_path,
|
||||
)
|
||||
|
||||
# Whenever this happens lets back up the broken one just in case it
|
||||
# gets overwritten accidentally.
|
||||
logging.info(
|
||||
"Backing up current config file to '%s.broken'", config_file_path
|
||||
)
|
||||
try:
|
||||
import shutil
|
||||
|
||||
@ -141,23 +135,10 @@ def read_app_config() -> tuple[AppConfig, bool]:
|
||||
logging.exception('Error copying broken config.')
|
||||
config = AppConfig()
|
||||
|
||||
# Now attempt to read one of our 'prev' backup copies.
|
||||
prev_path = config_file_path + '.prev'
|
||||
try:
|
||||
if os.path.exists(prev_path):
|
||||
with open(prev_path, encoding='utf-8') as infile:
|
||||
config_contents = infile.read()
|
||||
config = AppConfig(json.loads(config_contents))
|
||||
else:
|
||||
config = AppConfig()
|
||||
config_file_healthy = True
|
||||
logging.info('Successfully read backup config.')
|
||||
except Exception:
|
||||
logging.exception('Error reading prev backup config.')
|
||||
return config, config_file_healthy
|
||||
return config
|
||||
|
||||
|
||||
def commit_app_config(force: bool = False) -> None:
|
||||
def commit_app_config() -> None:
|
||||
"""Commit the config to persistent storage.
|
||||
|
||||
Category: **General Utility Functions**
|
||||
@ -167,10 +148,4 @@ def commit_app_config(force: bool = False) -> None:
|
||||
plus = _babase.app.plus
|
||||
assert plus is not None
|
||||
|
||||
if not _babase.app.config_file_healthy and not force:
|
||||
logging.warning(
|
||||
'Current config file is broken; '
|
||||
'skipping write to avoid losing settings.'
|
||||
)
|
||||
return
|
||||
plus.mark_config_dirty()
|
||||
|
||||
@ -40,7 +40,14 @@ def get_input_device_mapped_value(
|
||||
mapping = ccfgs[devicename][unique_id]
|
||||
elif 'default' in ccfgs[devicename]:
|
||||
mapping = ccfgs[devicename]['default']
|
||||
if mapping is not None:
|
||||
|
||||
# We now use the config mapping *only* if it is not empty.
|
||||
# There have been cases of config writing code messing up
|
||||
# and leaving empty dicts in the app config, which currently
|
||||
# leaves the device unusable. Alternatively, we'd perhaps
|
||||
# want to fall back to defaults for individual missing
|
||||
# values, but that is a bigger change we can make later.
|
||||
if isinstance(mapping, dict) and mapping:
|
||||
return mapping.get(name, -1)
|
||||
|
||||
if platform == 'windows':
|
||||
|
||||
@ -627,15 +627,6 @@ class ClassicSubsystem(babase.AppSubsystem):
|
||||
"""(internal)"""
|
||||
return bascenev1.get_foreground_host_activity()
|
||||
|
||||
def show_config_error_window(self) -> bool:
|
||||
"""(internal)"""
|
||||
if self.platform in ('mac', 'linux', 'windows'):
|
||||
from bauiv1lib.configerror import ConfigErrorWindow
|
||||
|
||||
babase.pushcall(ConfigErrorWindow)
|
||||
return True
|
||||
return False
|
||||
|
||||
def value_test(
|
||||
self,
|
||||
arg: str,
|
||||
|
||||
@ -52,7 +52,7 @@ if TYPE_CHECKING:
|
||||
|
||||
# Build number and version of the ballistica binary we expect to be
|
||||
# using.
|
||||
TARGET_BALLISTICA_BUILD = 21525
|
||||
TARGET_BALLISTICA_BUILD = 21528
|
||||
TARGET_BALLISTICA_VERSION = '1.7.28'
|
||||
|
||||
|
||||
|
||||
@ -264,10 +264,19 @@ class ControlsGuide(bs.Actor):
|
||||
bs.timer(delay, bs.WeakCall(self._start_updating))
|
||||
|
||||
@staticmethod
|
||||
def _meaningful_button_name(device: bs.InputDevice, button: int) -> str:
|
||||
def _meaningful_button_name(
|
||||
device: bs.InputDevice, button_name: str
|
||||
) -> str:
|
||||
"""Return a flattened string button name; empty for non-meaningful."""
|
||||
if not device.has_meaningful_button_names:
|
||||
return ''
|
||||
assert bs.app.classic is not None
|
||||
button = bs.app.classic.get_input_device_mapped_value(
|
||||
device, button_name
|
||||
)
|
||||
# -1 means unset; let's show that.
|
||||
if button == -1:
|
||||
return bs.Lstr(resource='configGamepadWindow.unsetText').evaluate()
|
||||
return device.get_button_name(button).evaluate()
|
||||
|
||||
def _start_updating(self) -> None:
|
||||
@ -289,10 +298,10 @@ class ControlsGuide(bs.Actor):
|
||||
def _check_fade_in(self) -> None:
|
||||
assert bs.app.classic is not None
|
||||
|
||||
# If we have a touchscreen, we only fade in if we have a player with
|
||||
# an input device that is *not* the touchscreen.
|
||||
# (otherwise it is confusing to see the touchscreen buttons right
|
||||
# next to our display buttons)
|
||||
# If we have a touchscreen, we only fade in if we have a player
|
||||
# with an input device that is *not* the touchscreen. Otherwise
|
||||
# it is confusing to see the touchscreen buttons right next to
|
||||
# our display buttons.
|
||||
touchscreen: bs.InputDevice | None = bs.getinputdevice(
|
||||
'TouchScreen', '#1', doraise=False
|
||||
)
|
||||
@ -318,15 +327,7 @@ class ControlsGuide(bs.Actor):
|
||||
'buttonBomb',
|
||||
'buttonPickUp',
|
||||
):
|
||||
if (
|
||||
self._meaningful_button_name(
|
||||
device,
|
||||
bs.app.classic.get_input_device_mapped_value(
|
||||
device, name
|
||||
),
|
||||
)
|
||||
!= ''
|
||||
):
|
||||
if self._meaningful_button_name(device, name) != '':
|
||||
fade_in = True
|
||||
break
|
||||
if fade_in:
|
||||
@ -401,58 +402,30 @@ class ControlsGuide(bs.Actor):
|
||||
# We only care about movement buttons in the case of keyboards.
|
||||
if all_keyboards:
|
||||
right_button_names.add(
|
||||
device.get_button_name(
|
||||
classic.get_input_device_mapped_value(
|
||||
device, 'buttonRight'
|
||||
)
|
||||
)
|
||||
self._meaningful_button_name(device, 'buttonRight')
|
||||
)
|
||||
left_button_names.add(
|
||||
device.get_button_name(
|
||||
classic.get_input_device_mapped_value(
|
||||
device, 'buttonLeft'
|
||||
)
|
||||
)
|
||||
self._meaningful_button_name(device, 'buttonLeft')
|
||||
)
|
||||
down_button_names.add(
|
||||
device.get_button_name(
|
||||
classic.get_input_device_mapped_value(
|
||||
device, 'buttonDown'
|
||||
)
|
||||
)
|
||||
self._meaningful_button_name(device, 'buttonDown')
|
||||
)
|
||||
up_button_names.add(
|
||||
device.get_button_name(
|
||||
classic.get_input_device_mapped_value(
|
||||
device, 'buttonUp'
|
||||
)
|
||||
)
|
||||
self._meaningful_button_name(device, 'buttonUp')
|
||||
)
|
||||
|
||||
# Ignore empty values; things like the remote app or
|
||||
# wiimotes can return these.
|
||||
bname = self._meaningful_button_name(
|
||||
device,
|
||||
classic.get_input_device_mapped_value(device, 'buttonPunch'),
|
||||
)
|
||||
bname = self._meaningful_button_name(device, 'buttonPunch')
|
||||
if bname != '':
|
||||
punch_button_names.add(bname)
|
||||
bname = self._meaningful_button_name(
|
||||
device,
|
||||
classic.get_input_device_mapped_value(device, 'buttonJump'),
|
||||
)
|
||||
bname = self._meaningful_button_name(device, 'buttonJump')
|
||||
if bname != '':
|
||||
jump_button_names.add(bname)
|
||||
bname = self._meaningful_button_name(
|
||||
device,
|
||||
classic.get_input_device_mapped_value(device, 'buttonBomb'),
|
||||
)
|
||||
bname = self._meaningful_button_name(device, 'buttonBomb')
|
||||
if bname != '':
|
||||
bomb_button_names.add(bname)
|
||||
bname = self._meaningful_button_name(
|
||||
device,
|
||||
classic.get_input_device_mapped_value(device, 'buttonPickUp'),
|
||||
)
|
||||
bname = self._meaningful_button_name(device, 'buttonPickUp')
|
||||
if bname != '':
|
||||
pickup_button_names.add(bname)
|
||||
|
||||
@ -582,8 +555,8 @@ class ControlsGuide(bs.Actor):
|
||||
if msg.immediate:
|
||||
self._die()
|
||||
else:
|
||||
# If they don't need immediate,
|
||||
# fade out our nodes and die later.
|
||||
# If they don't need immediate, fade out our nodes and
|
||||
# die later.
|
||||
for node in self._nodes:
|
||||
bs.animate(node, 'opacity', {0: node.opacity, 3.0: 0.0})
|
||||
bs.timer(3.1, bs.WeakCall(self._die))
|
||||
|
||||
@ -1,80 +0,0 @@
|
||||
# Released under the MIT License. See LICENSE for details.
|
||||
#
|
||||
"""UI for dealing with broken config files."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import bauiv1 as bui
|
||||
|
||||
|
||||
class ConfigErrorWindow(bui.Window):
|
||||
"""Window for dealing with a broken config."""
|
||||
|
||||
def __init__(self) -> None:
|
||||
self._config_file_path = bui.app.env.config_file_path
|
||||
width = 800
|
||||
super().__init__(
|
||||
bui.containerwidget(size=(width, 400), transition='in_right')
|
||||
)
|
||||
padding = 20
|
||||
bui.textwidget(
|
||||
parent=self._root_widget,
|
||||
position=(padding, 220 + 60),
|
||||
size=(width - 2 * padding, 100 - 2 * padding),
|
||||
h_align='center',
|
||||
v_align='top',
|
||||
scale=0.73,
|
||||
text=(
|
||||
f'Error reading {bui.appnameupper()} config file'
|
||||
':\n\n\nCheck the console'
|
||||
' (press ~ twice) for details.\n\nWould you like to quit and'
|
||||
' try to fix it by hand\nor overwrite it with defaults?\n\n'
|
||||
'(high scores, player profiles, etc will be lost if you'
|
||||
' overwrite)'
|
||||
),
|
||||
)
|
||||
bui.textwidget(
|
||||
parent=self._root_widget,
|
||||
position=(padding, 198 + 60),
|
||||
size=(width - 2 * padding, 100 - 2 * padding),
|
||||
h_align='center',
|
||||
v_align='top',
|
||||
scale=0.5,
|
||||
text=self._config_file_path,
|
||||
)
|
||||
quit_button = bui.buttonwidget(
|
||||
parent=self._root_widget,
|
||||
position=(35, 30),
|
||||
size=(240, 54),
|
||||
label='Quit and Edit',
|
||||
on_activate_call=self._quit,
|
||||
)
|
||||
bui.buttonwidget(
|
||||
parent=self._root_widget,
|
||||
position=(width - 370, 30),
|
||||
size=(330, 54),
|
||||
label='Overwrite with Defaults',
|
||||
on_activate_call=self._defaults,
|
||||
)
|
||||
bui.containerwidget(
|
||||
edit=self._root_widget,
|
||||
cancel_button=quit_button,
|
||||
selected_child=quit_button,
|
||||
)
|
||||
|
||||
def _quit(self) -> None:
|
||||
bui.apptimer(0.001, self._edit_and_quit)
|
||||
bui.lock_all_input()
|
||||
|
||||
def _edit_and_quit(self) -> None:
|
||||
bui.open_file_externally(self._config_file_path)
|
||||
bui.apptimer(0.1, bui.quit)
|
||||
|
||||
def _defaults(self) -> None:
|
||||
bui.containerwidget(edit=self._root_widget, transition='out_left')
|
||||
bui.getsound('gunCocking').play()
|
||||
bui.screenmessage('settings reset.', color=(1, 1, 0))
|
||||
|
||||
# At this point settings are already set; lets just commit them
|
||||
# to disk.
|
||||
bui.commit_app_config(force=True)
|
||||
@ -545,20 +545,25 @@ class GamepadSettingsWindow(bui.Window):
|
||||
if 'analogStickLR' + self._ext in self._settings
|
||||
else 5
|
||||
if self._is_secondary
|
||||
else 1
|
||||
else None
|
||||
)
|
||||
sval2 = (
|
||||
self._settings['analogStickUD' + self._ext]
|
||||
if 'analogStickUD' + self._ext in self._settings
|
||||
else 6
|
||||
if self._is_secondary
|
||||
else 2
|
||||
)
|
||||
return (
|
||||
self._input.get_axis_name(sval1)
|
||||
+ ' / '
|
||||
+ self._input.get_axis_name(sval2)
|
||||
else None
|
||||
)
|
||||
print('got', sval1, sval2)
|
||||
assert isinstance(sval1, (int, type(None)))
|
||||
assert isinstance(sval2, (int, type(None)))
|
||||
if sval1 is not None and sval2 is not None:
|
||||
return (
|
||||
self._input.get_axis_name(sval1)
|
||||
+ ' / '
|
||||
+ self._input.get_axis_name(sval2)
|
||||
)
|
||||
return bui.Lstr(resource=self._r + '.unsetText')
|
||||
|
||||
# If they're looking for triggers.
|
||||
if control in ['triggerRun1' + self._ext, 'triggerRun2' + self._ext]:
|
||||
@ -573,7 +578,7 @@ class GamepadSettingsWindow(bui.Window):
|
||||
return str(1.0)
|
||||
|
||||
# For dpad buttons: show individual buttons if any are set.
|
||||
# Otherwise show whichever dpad is set (defaulting to 1).
|
||||
# Otherwise show whichever dpad is set.
|
||||
dpad_buttons = [
|
||||
'buttonLeft' + self._ext,
|
||||
'buttonRight' + self._ext,
|
||||
@ -588,24 +593,28 @@ class GamepadSettingsWindow(bui.Window):
|
||||
return bui.Lstr(resource=self._r + '.unsetText')
|
||||
|
||||
# No dpad buttons - show the dpad number for all 4.
|
||||
return bui.Lstr(
|
||||
value='${A} ${B}',
|
||||
subs=[
|
||||
('${A}', bui.Lstr(resource=self._r + '.dpadText')),
|
||||
(
|
||||
'${B}',
|
||||
str(
|
||||
self._settings['dpad' + self._ext]
|
||||
if 'dpad' + self._ext in self._settings
|
||||
else 2
|
||||
if self._is_secondary
|
||||
else 1
|
||||
),
|
||||
),
|
||||
],
|
||||
dpadnum = (
|
||||
self._settings['dpad' + self._ext]
|
||||
if 'dpad' + self._ext in self._settings
|
||||
else 2
|
||||
if self._is_secondary
|
||||
else None
|
||||
)
|
||||
assert isinstance(dpadnum, (int, type(None)))
|
||||
if dpadnum is not None:
|
||||
return bui.Lstr(
|
||||
value='${A} ${B}',
|
||||
subs=[
|
||||
('${A}', bui.Lstr(resource=self._r + '.dpadText')),
|
||||
(
|
||||
'${B}',
|
||||
str(dpadnum),
|
||||
),
|
||||
],
|
||||
)
|
||||
return bui.Lstr(resource=self._r + '.unsetText')
|
||||
|
||||
# other buttons..
|
||||
# Other buttons.
|
||||
if control in self._settings:
|
||||
return self._input.get_button_name(self._settings[control])
|
||||
return bui.Lstr(resource=self._r + '.unsetText')
|
||||
@ -616,9 +625,7 @@ class GamepadSettingsWindow(bui.Window):
|
||||
event: dict[str, Any],
|
||||
dialog: AwaitGamepadInputWindow,
|
||||
) -> None:
|
||||
# pylint: disable=too-many-nested-blocks
|
||||
# pylint: disable=too-many-branches
|
||||
# pylint: disable=too-many-statements
|
||||
assert self._settings is not None
|
||||
ext = self._ext
|
||||
|
||||
@ -648,10 +655,6 @@ class GamepadSettingsWindow(bui.Window):
|
||||
if btn in self._settings:
|
||||
del self._settings[btn]
|
||||
if event['hat'] == (2 if self._is_secondary else 1):
|
||||
# Exclude value in default case.
|
||||
if 'dpad' + ext in self._settings:
|
||||
del self._settings['dpad' + ext]
|
||||
else:
|
||||
self._settings['dpad' + ext] = event['hat']
|
||||
|
||||
# Update the 4 dpad button txt widgets.
|
||||
@ -680,10 +683,6 @@ class GamepadSettingsWindow(bui.Window):
|
||||
if abs(event['value']) > 0.5:
|
||||
axis = event['axis']
|
||||
if axis == (5 if self._is_secondary else 1):
|
||||
# Exclude value in default case.
|
||||
if 'analogStickLR' + ext in self._settings:
|
||||
del self._settings['analogStickLR' + ext]
|
||||
else:
|
||||
self._settings['analogStickLR' + ext] = axis
|
||||
bui.textwidget(
|
||||
edit=self._textwidgets['analogStickLR' + ext],
|
||||
@ -713,10 +712,6 @@ class GamepadSettingsWindow(bui.Window):
|
||||
lr_axis = 5 if self._is_secondary else 1
|
||||
if axis != lr_axis:
|
||||
if axis == (6 if self._is_secondary else 2):
|
||||
# Exclude value in default case.
|
||||
if 'analogStickUD' + ext in self._settings:
|
||||
del self._settings['analogStickUD' + ext]
|
||||
else:
|
||||
self._settings['analogStickUD' + ext] = axis
|
||||
bui.textwidget(
|
||||
edit=self._textwidgets['analogStickLR' + ext],
|
||||
@ -795,7 +790,7 @@ class GamepadSettingsWindow(bui.Window):
|
||||
),
|
||||
)
|
||||
|
||||
bui.apptimer(0, doit)
|
||||
bui.pushcall(doit)
|
||||
return btn
|
||||
|
||||
def _cancel(self) -> None:
|
||||
|
||||
@ -452,7 +452,7 @@ class GamepadAdvancedSettingsWindow(bui.Window):
|
||||
),
|
||||
)
|
||||
|
||||
bui.apptimer(0, doit)
|
||||
bui.pushcall(doit)
|
||||
return btn, btn2
|
||||
|
||||
def _inc(
|
||||
|
||||
@ -213,6 +213,12 @@ class ConfigKeyboardWindow(bui.Window):
|
||||
scale=1.0,
|
||||
)
|
||||
|
||||
def _pretty_button_name(self, button_name: str) -> bui.Lstr:
|
||||
button_id = self._settings[button_name]
|
||||
if button_id == -1:
|
||||
return bs.Lstr(resource='configGamepadWindow.unsetText')
|
||||
return self._input.get_button_name(button_id)
|
||||
|
||||
def _capture_button(
|
||||
self,
|
||||
pos: tuple[float, float],
|
||||
@ -250,7 +256,7 @@ class ConfigKeyboardWindow(bui.Window):
|
||||
v_align='top',
|
||||
scale=uiscale,
|
||||
maxwidth=maxwidth,
|
||||
text=self._input.get_button_name(self._settings[button]),
|
||||
text=self._pretty_button_name(button),
|
||||
)
|
||||
bui.buttonwidget(
|
||||
edit=btn,
|
||||
|
||||
@ -65,7 +65,12 @@ JoystickInput::JoystickInput(int sdl_joystick_id,
|
||||
// that instead.
|
||||
// #if BA_SDL2_BUILD
|
||||
sdl_joystick_id_ = SDL_JoystickInstanceID(sdl_joystick_);
|
||||
raw_sdl_joystick_name_ = SDL_JoystickName(sdl_joystick_);
|
||||
if (auto* name = SDL_JoystickName(sdl_joystick_)) {
|
||||
raw_sdl_joystick_name_ = name;
|
||||
} else {
|
||||
// This can return nullptr if SDL can't find a name.
|
||||
raw_sdl_joystick_name_ = "Unknown Controller";
|
||||
}
|
||||
|
||||
// Special case: on windows, xinput stuff comes in with unique names
|
||||
// "XInput Controller #3", etc. Let's replace these with simply "XInput
|
||||
|
||||
@ -126,12 +126,12 @@ class JoystickInput : public InputDevice {
|
||||
bool calibrate_ : 1 {};
|
||||
bool can_configure_ : 1 {};
|
||||
|
||||
int hat_{};
|
||||
int analog_lr_{};
|
||||
int hat_{0};
|
||||
int analog_lr_{0};
|
||||
int analog_ud_{1};
|
||||
|
||||
// Mappings of ba buttons to SDL buttons.
|
||||
int jump_button_{};
|
||||
int jump_button_{0};
|
||||
int punch_button_{1};
|
||||
int bomb_button_{2};
|
||||
int pickup_button_{3};
|
||||
|
||||
@ -602,7 +602,7 @@ static auto PyCommitConfig(PyObject* self, PyObject* args, PyObject* keywds)
|
||||
}
|
||||
fclose(f_out);
|
||||
|
||||
// Now backup any existing config to .prev.
|
||||
// Now move any existing config to .prev.
|
||||
if (g_core->platform->FilePathExists(path)) {
|
||||
// On windows, rename doesn't overwrite existing files.. need to kill
|
||||
// the old explicitly.
|
||||
|
||||
@ -864,7 +864,7 @@ auto DevConsole::HandleKeyPress(const SDL_Keysym* keysym) -> bool {
|
||||
bool found_valid{};
|
||||
// Move until we've found at least one valid char and the
|
||||
// stop at the first invalid one.
|
||||
while (carat_char_ < unichars.size()) {
|
||||
while (carat_char_ < static_cast<int>(unichars.size())) {
|
||||
assert(CaratCharValid_());
|
||||
auto this_char = unichars[carat_char_];
|
||||
auto is_valid = IsValidHungryChar_(this_char);
|
||||
@ -995,8 +995,8 @@ void DevConsole::Exec() {
|
||||
// Just for sanity testing.
|
||||
auto DevConsole::CaratCharValid_() -> bool {
|
||||
return carat_char_ >= 0
|
||||
&& carat_char_
|
||||
<= Utils::UnicodeFromUTF8(input_string_, "fwewffe").size();
|
||||
&& carat_char_ <= static_cast<int>(
|
||||
Utils::UnicodeFromUTF8(input_string_, "fwewffe").size());
|
||||
}
|
||||
|
||||
void DevConsole::SubmitPythonCommand_(const std::string& command) {
|
||||
@ -1419,7 +1419,7 @@ void DevConsole::UpdateCarat_() {
|
||||
// Use a base width if we're not covering a char, and use the char's width
|
||||
// if we are.
|
||||
float width = 14.0f;
|
||||
if (carat_char_ < unichars.size()) {
|
||||
if (carat_char_ < static_cast<int>(unichars.size())) {
|
||||
std::vector<uint32_t> covered_char{unichars[carat_char_]};
|
||||
auto covered_char_str = Utils::UTF8FromUnicode(covered_char);
|
||||
width =
|
||||
|
||||
@ -39,7 +39,7 @@ auto main(int argc, char** argv) -> int {
|
||||
namespace ballistica {
|
||||
|
||||
// These are set automatically via script; don't modify them here.
|
||||
const int kEngineBuildNumber = 21525;
|
||||
const int kEngineBuildNumber = 21528;
|
||||
const char* kEngineVersion = "1.7.28";
|
||||
const int kEngineApiVersion = 8;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user