mirror of
https://github.com/RYDE-WORK/ballistica.git
synced 2026-01-24 07:53:30 +08:00
added show-demos-when-idle option
This commit is contained in:
parent
87bf4e3435
commit
6f2382fe69
66
.efrocachemap
generated
66
.efrocachemap
generated
@ -421,7 +421,7 @@
|
||||
"build/assets/ba_data/audio/zoeOw.ogg": "74befe45a8417e95b6a2233c51992a26",
|
||||
"build/assets/ba_data/audio/zoePickup01.ogg": "48ab8cddfcde36a750856f3f81dd20c8",
|
||||
"build/assets/ba_data/audio/zoeScream01.ogg": "2b468aedfa8741090247f04eb9e6df55",
|
||||
"build/assets/ba_data/data/langdata.json": "6ae92385835c7f270dc35d7b4be3deef",
|
||||
"build/assets/ba_data/data/langdata.json": "e71fd5c04d15c544dc15bc15bbe0798a",
|
||||
"build/assets/ba_data/data/languages/arabic.json": "0db32e21b6d5337ccca478381744aa88",
|
||||
"build/assets/ba_data/data/languages/belarussian.json": "a112dfca3e188387516788bd8229c5b0",
|
||||
"build/assets/ba_data/data/languages/chinese.json": "93f3ca9f90d86dc7c8d0923f5f11ef46",
|
||||
@ -430,12 +430,12 @@
|
||||
"build/assets/ba_data/data/languages/czech.json": "c9d518a324870066b987b8f412881dd3",
|
||||
"build/assets/ba_data/data/languages/danish.json": "3fd69080783d5c9dcc0af737f02b6f1e",
|
||||
"build/assets/ba_data/data/languages/dutch.json": "5cbf1a68a9d93dee00dbc27f834d878a",
|
||||
"build/assets/ba_data/data/languages/english.json": "2434e127b6788e3128d3523fcb1b8994",
|
||||
"build/assets/ba_data/data/languages/english.json": "1c4037fea1066d39d6eced419f314f35",
|
||||
"build/assets/ba_data/data/languages/esperanto.json": "0e397cfa5f3fb8cef5f4a64f21cda880",
|
||||
"build/assets/ba_data/data/languages/filipino.json": "e750fb1a95e4c5611115f9ece9ecab53",
|
||||
"build/assets/ba_data/data/languages/filipino.json": "f897776672925499ecda8960b3aae607",
|
||||
"build/assets/ba_data/data/languages/french.json": "8bc35eb4b20a0b30c3348bcc9a3844a6",
|
||||
"build/assets/ba_data/data/languages/german.json": "450fa41ae264f29a5d1af22143d0d0ad",
|
||||
"build/assets/ba_data/data/languages/gibberish.json": "e24d391c9fd12f9afa92f7ff65a06d23",
|
||||
"build/assets/ba_data/data/languages/gibberish.json": "b461539243e8efe3137137b886256ba7",
|
||||
"build/assets/ba_data/data/languages/greek.json": "287c0ec437b38772284ef9d3e4fb2fc3",
|
||||
"build/assets/ba_data/data/languages/hindi.json": "8848f6b0caec0fcf9d85bc6e683809ec",
|
||||
"build/assets/ba_data/data/languages/hungarian.json": "796a290a8c44a1e7635208c2ff5fdc6e",
|
||||
@ -455,7 +455,7 @@
|
||||
"build/assets/ba_data/data/languages/tamil.json": "b4de1a2851afe4869c82e9acd94cd89c",
|
||||
"build/assets/ba_data/data/languages/thai.json": "77755219bbf5fb7eea0d6b226684f403",
|
||||
"build/assets/ba_data/data/languages/turkish.json": "72fac3a6fd13ebb74fb4d68b9323e7d4",
|
||||
"build/assets/ba_data/data/languages/ukrainian.json": "e5c861187c4c6db37d1a033f4ef3dd5a",
|
||||
"build/assets/ba_data/data/languages/ukrainian.json": "b54a38e93deebafa5706ba2d1f626892",
|
||||
"build/assets/ba_data/data/languages/venetian.json": "8e9714d98a85e428ce3543fc49188a46",
|
||||
"build/assets/ba_data/data/languages/vietnamese.json": "921cd1e50f60fe3e101f246e172750ba",
|
||||
"build/assets/ba_data/data/maps/big_g.json": "1dd301d490643088a435ce75df971054",
|
||||
@ -4060,26 +4060,26 @@
|
||||
"build/assets/windows/Win32/ucrtbased.dll": "2def5335207d41b21b9823f6805997f1",
|
||||
"build/assets/windows/Win32/vc_redist.x86.exe": "b08a55e2e77623fe657bea24f223a3ae",
|
||||
"build/assets/windows/Win32/vcruntime140d.dll": "865b2af4d1e26a1a8073c89acb06e599",
|
||||
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "6d1c198240f58211b14534263de11034",
|
||||
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "0e29ddb400da245f7425e2779278b936",
|
||||
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "887c68a7be4c8d25c6eae21feb2fd39a",
|
||||
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "99a237557104d145f061b674e158539f",
|
||||
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "c813eb17692868fc54741e962d8ecca6",
|
||||
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "67b39d7c54a801c2b65bd8beb55771a2",
|
||||
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "20af8a239c97cbb8fe876c06d57c3f1f",
|
||||
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "60d09bd4c59e27f2f3c8b6331b650ee1",
|
||||
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "84733128a50a14b046306419419862d4",
|
||||
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "b81062addf907d312a9409660733205c",
|
||||
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "2770d31f91042c005cb0fc5cb368112c",
|
||||
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "316e8424de85400d5b84c84395689776",
|
||||
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "15bd20491afa0d90e3cea147d04e25a6",
|
||||
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "4697883ea3e8f9e8d215c9a82396c8a4",
|
||||
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "cd24a57ef4815f02f3c4f054fc9ae878",
|
||||
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "13b8e37ea683de88bce49e06a6cba24d",
|
||||
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "50218a71f166a51c6bccec5f8a946835",
|
||||
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "e20e058060ef6acc1e1f4cbccd69a7ce",
|
||||
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "13a90cb0c4a15daa64c8d883afd895e9",
|
||||
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "6af4eddfe3ed8a825a5ebd7702536fd7",
|
||||
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "8d62386f109621ee08bf6bc699e560b4",
|
||||
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "1ae0c73018caf6d563f7a2beed5630df",
|
||||
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "cec12563653f88526ab0cdd56c35a659",
|
||||
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "c406758148e6a19a8ba776de09c9cf31",
|
||||
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "ec6b2f954c73f0a44d25eb12b76ae3df",
|
||||
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "190572e9a537ab1cce44a3a307cfb65f",
|
||||
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "d1dd35ec23c4e42d7bcd05406375b3f3",
|
||||
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "790f5c6df9bc038b9b0c1561e30cc17f",
|
||||
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "946739e98d88bbcdb615a97f66a3a9f5",
|
||||
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "e625d8908634593ca1917ae7a42846ea",
|
||||
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "48b463fbb8ad28f4c9487feb5383a1a7",
|
||||
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "a8fd4ed9a9db5878d21eee6d4d8035ce",
|
||||
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "a40f333afd411df2323b236f7931c72f",
|
||||
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "8c1b885d6bcae9c43b8ca45c3538d9f7",
|
||||
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "10e25021c620ae9df514e952d6f7a14c",
|
||||
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "5fdbf8e2c9619f093e4c0505619178f2",
|
||||
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "74527ceb879d581e162eea3052b74b48",
|
||||
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "4cbf3fa8efd3ac8051fdf7776684e80c",
|
||||
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "0dc81a9db0d827fd803ba3eac90c4453",
|
||||
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "bbd66efc658747530ec46af2620066c2",
|
||||
"build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "db535f0ca1e01af825f75f204fbc8928",
|
||||
"build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "97d51afca996ae15b61fd9f409a00459",
|
||||
"build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "db535f0ca1e01af825f75f204fbc8928",
|
||||
@ -4096,14 +4096,14 @@
|
||||
"build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "452623f0495dd4375e5b5d9b80d643d5",
|
||||
"build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "ca49b32ed573feea11613d62cd89840c",
|
||||
"build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "452623f0495dd4375e5b5d9b80d643d5",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "3b19ca383e1a88bd8a0599181da738ba",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "2b9ee84d34b41dd7d92df7c7dece5ecc",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "78fc011efdd0d3c5ad91ba5cc7e25b36",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "1c60cf6ee1b3b7f1c4ca10f18ad55c0b",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "a9d3d2dd577409f19129a2a14f03a871",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "c8cda906610d28b03a5d0abac69f752e",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "951e19df7d1f5d9befd0b1fe5e4f6390",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "b75ac3bc471e3b6121d27a83b07573da",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "8d7a27873efa3595c3209a19de05ff9d",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "54322d4265553cc935840cb2b966c18c",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "50254a1075a671d50fbb1a86aac86cb9",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "fe1eb9d9b16128058c38c46646e37a79",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "b7095b4bdeba71cb04dba2765e8d497c",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "06303398d77e04dc56badaf9f8480132",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "61f5d7b685ab8948995c4eba78b2bf3b",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "45df75b7cbfba620aa63a23a47ecd42b",
|
||||
"src/assets/ba_data/python/babase/_mgen/__init__.py": "f885fed7f2ed98ff2ba271f9dbe3391c",
|
||||
"src/assets/ba_data/python/babase/_mgen/enums.py": "28323912b56ec07701eda3d41a6a4101",
|
||||
"src/ballistica/base/mgen/pyembed/binding_base.inc": "72bfed2cce8ff19741989dec28302f3f",
|
||||
|
||||
11
CHANGELOG.md
11
CHANGELOG.md
@ -1,5 +1,12 @@
|
||||
### 1.7.33 (build 21747, api 8, 2024-01-03)
|
||||
|
||||
### 1.7.33 (build 21751, api 8, 2024-01-05)
|
||||
- Stress test input-devices are now a bit smarter; they won't press any buttons
|
||||
while UIs are up (this could cause lots of chaos if it happened).
|
||||
- Added a 'Show Demos When Idle' option in advanced settings. If enabled, the
|
||||
game will show gameplay demos (a slightly modified form of the stress test)
|
||||
periodically after sitting idle at the main menu for a bit. Like an old arcade
|
||||
game. I added this for an upcoming conference appearance but though people
|
||||
might like to enable it in other cases.
|
||||
|
||||
### 1.7.32 (build 21741, api 8, 2023-12-20)
|
||||
- Fixed a screen message that no one will ever see (Thanks vishal332008?...)
|
||||
- Plugins window now displays 'No Plugins Installed' when no plugins are present (Thanks vishal332008!)
|
||||
|
||||
@ -48,6 +48,7 @@ from _babase import (
|
||||
fatal_error,
|
||||
get_display_resolution,
|
||||
get_immediate_return_code,
|
||||
get_input_idle_time,
|
||||
get_low_level_config_value,
|
||||
get_max_graphics_quality,
|
||||
get_replays_dir,
|
||||
@ -236,6 +237,7 @@ __all__ = [
|
||||
'garbage_collect',
|
||||
'get_display_resolution',
|
||||
'get_immediate_return_code',
|
||||
'get_input_idle_time',
|
||||
'get_ip_address_type',
|
||||
'get_low_level_config_value',
|
||||
'get_max_graphics_quality',
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import random
|
||||
from dataclasses import dataclass
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import babase
|
||||
@ -48,64 +49,74 @@ def run_cpu_benchmark() -> None:
|
||||
bascenev1.new_host_session(BenchmarkSession, benchmark_type='cpu')
|
||||
|
||||
|
||||
@dataclass
|
||||
class _StressTestArgs:
|
||||
playlist_type: str
|
||||
playlist_name: str
|
||||
player_count: int
|
||||
round_duration: int
|
||||
attract_mode: bool
|
||||
|
||||
|
||||
def run_stress_test(
|
||||
playlist_type: str = 'Random',
|
||||
playlist_name: str = '__default__',
|
||||
player_count: int = 8,
|
||||
round_duration: int = 30,
|
||||
attract_mode: bool = False,
|
||||
) -> None:
|
||||
"""Run a stress test."""
|
||||
|
||||
babase.screenmessage(
|
||||
"Beginning stress test.. use 'End Test' to stop testing.",
|
||||
color=(1, 1, 0),
|
||||
)
|
||||
with babase.ContextRef.empty():
|
||||
start_stress_test(
|
||||
{
|
||||
'playlist_type': playlist_type,
|
||||
'playlist_name': playlist_name,
|
||||
'player_count': player_count,
|
||||
'round_duration': round_duration,
|
||||
}
|
||||
if not attract_mode:
|
||||
babase.screenmessage(
|
||||
"Beginning stress test.. use 'End Test' to stop testing.",
|
||||
color=(1, 1, 0),
|
||||
)
|
||||
_start_stress_test(
|
||||
_StressTestArgs(
|
||||
playlist_type=playlist_type,
|
||||
playlist_name=playlist_name,
|
||||
player_count=player_count,
|
||||
round_duration=round_duration,
|
||||
attract_mode=attract_mode,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def stop_stress_test() -> None:
|
||||
"""End a running stress test."""
|
||||
|
||||
_baclassic.set_stress_testing(False, 0)
|
||||
assert babase.app.classic is not None
|
||||
try:
|
||||
if babase.app.classic.stress_test_reset_timer is not None:
|
||||
babase.screenmessage('Ending stress test...', color=(1, 1, 0))
|
||||
except Exception:
|
||||
pass
|
||||
babase.app.classic.stress_test_reset_timer = None
|
||||
|
||||
_baclassic.set_stress_testing(False, 0, False)
|
||||
babase.app.classic.stress_test_update_timer = None
|
||||
babase.app.classic.stress_test_update_timer_2 = None
|
||||
|
||||
|
||||
def start_stress_test(args: dict[str, Any]) -> None:
|
||||
def _start_stress_test(args: _StressTestArgs) -> None:
|
||||
"""(internal)"""
|
||||
from bascenev1 import DualTeamSession, FreeForAllSession
|
||||
|
||||
assert babase.app.classic is not None
|
||||
|
||||
appconfig = babase.app.config
|
||||
playlist_type = args['playlist_type']
|
||||
playlist_type = args.playlist_type
|
||||
if playlist_type == 'Random':
|
||||
if random.random() < 0.5:
|
||||
playlist_type = 'Teams'
|
||||
else:
|
||||
playlist_type = 'Free-For-All'
|
||||
babase.screenmessage(
|
||||
'Running Stress Test (listType="'
|
||||
+ playlist_type
|
||||
+ '", listName="'
|
||||
+ args['playlist_name']
|
||||
+ '")...'
|
||||
)
|
||||
if not args.attract_mode:
|
||||
babase.screenmessage(
|
||||
'Running Stress Test (listType="'
|
||||
+ playlist_type
|
||||
+ '", listName="'
|
||||
+ args.playlist_name
|
||||
+ '")...'
|
||||
)
|
||||
if playlist_type == 'Teams':
|
||||
appconfig['Team Tournament Playlist Selection'] = args['playlist_name']
|
||||
appconfig['Team Tournament Playlist Selection'] = args.playlist_name
|
||||
appconfig['Team Tournament Playlist Randomize'] = 1
|
||||
babase.apptimer(
|
||||
1.0,
|
||||
@ -115,7 +126,7 @@ def start_stress_test(args: dict[str, Any]) -> None:
|
||||
),
|
||||
)
|
||||
else:
|
||||
appconfig['Free-for-All Playlist Selection'] = args['playlist_name']
|
||||
appconfig['Free-for-All Playlist Selection'] = args.playlist_name
|
||||
appconfig['Free-for-All Playlist Randomize'] = 1
|
||||
babase.apptimer(
|
||||
1.0,
|
||||
@ -124,19 +135,38 @@ def start_stress_test(args: dict[str, Any]) -> None:
|
||||
babase.Call(bascenev1.new_host_session, FreeForAllSession),
|
||||
),
|
||||
)
|
||||
_baclassic.set_stress_testing(True, args['player_count'])
|
||||
babase.app.classic.stress_test_reset_timer = babase.AppTimer(
|
||||
args['round_duration'], babase.Call(_reset_stress_test, args)
|
||||
_baclassic.set_stress_testing(True, args.player_count, args.attract_mode)
|
||||
babase.app.classic.stress_test_update_timer = babase.AppTimer(
|
||||
args.round_duration, babase.Call(_reset_stress_test, args)
|
||||
)
|
||||
if args.attract_mode:
|
||||
babase.app.classic.stress_test_update_timer_2 = babase.AppTimer(
|
||||
0.48, babase.Call(_update_attract_mode_test, args), repeat=True
|
||||
)
|
||||
|
||||
|
||||
def _reset_stress_test(args: dict[str, Any]) -> None:
|
||||
_baclassic.set_stress_testing(False, args['player_count'])
|
||||
babase.screenmessage('Resetting stress test...')
|
||||
def _update_attract_mode_test(args: _StressTestArgs) -> None:
|
||||
if babase.get_input_idle_time() < 5.0:
|
||||
_reset_stress_test(args)
|
||||
|
||||
|
||||
def _reset_stress_test(args: _StressTestArgs) -> None:
|
||||
_baclassic.set_stress_testing(False, args.player_count, False)
|
||||
if not args.attract_mode:
|
||||
babase.screenmessage('Resetting stress test...')
|
||||
session = bascenev1.get_foreground_host_session()
|
||||
assert session is not None
|
||||
session.end()
|
||||
babase.apptimer(1.0, babase.Call(start_stress_test, args))
|
||||
|
||||
assert babase.app.classic is not None
|
||||
babase.app.classic.stress_test_update_timer = None
|
||||
babase.app.classic.stress_test_update_timer_2 = None
|
||||
|
||||
# For regular stress tests we keep the party going. For attract-mode
|
||||
# we just end back at the main menu. If things are idle there then
|
||||
# we'll get sent back to a new stress test.
|
||||
if not args.attract_mode:
|
||||
babase.apptimer(1.0, babase.Call(_start_stress_test, args))
|
||||
|
||||
|
||||
def run_gpu_benchmark() -> None:
|
||||
|
||||
@ -69,7 +69,8 @@ class ClassicSubsystem(babase.AppSubsystem):
|
||||
|
||||
# Misc.
|
||||
self.tips: list[str] = []
|
||||
self.stress_test_reset_timer: babase.AppTimer | None = None
|
||||
self.stress_test_update_timer: babase.AppTimer | None = None
|
||||
self.stress_test_update_timer_2: babase.AppTimer | None = None
|
||||
self.value_test_defaults: dict = {}
|
||||
self.special_offer: dict | None = None
|
||||
self.ping_thread_count = 0
|
||||
@ -555,11 +556,18 @@ class ClassicSubsystem(babase.AppSubsystem):
|
||||
playlist_name: str = '__default__',
|
||||
player_count: int = 8,
|
||||
round_duration: int = 30,
|
||||
attract_mode: bool = False,
|
||||
) -> None:
|
||||
"""Run a stress test."""
|
||||
from baclassic._benchmark import run_stress_test as run
|
||||
|
||||
run(playlist_type, playlist_name, player_count, round_duration)
|
||||
run(
|
||||
playlist_type=playlist_type,
|
||||
playlist_name=playlist_name,
|
||||
player_count=player_count,
|
||||
round_duration=round_duration,
|
||||
attract_mode=attract_mode,
|
||||
)
|
||||
|
||||
def get_input_device_mapped_value(
|
||||
self, device: bascenev1.InputDevice, name: str
|
||||
|
||||
@ -52,7 +52,7 @@ if TYPE_CHECKING:
|
||||
|
||||
# Build number and version of the ballistica binary we expect to be
|
||||
# using.
|
||||
TARGET_BALLISTICA_BUILD = 21747
|
||||
TARGET_BALLISTICA_BUILD = 21751
|
||||
TARGET_BALLISTICA_VERSION = '1.7.33'
|
||||
|
||||
|
||||
|
||||
@ -441,7 +441,7 @@ class Chooser:
|
||||
# list might have changed.
|
||||
input_device = self._sessionplayer.inputdevice
|
||||
is_remote = input_device.is_remote_client
|
||||
is_test_input = input_device.name.startswith('TestInput')
|
||||
is_test_input = input_device.is_test_input
|
||||
|
||||
# Pull this player's list of unlocked characters.
|
||||
if is_remote:
|
||||
|
||||
@ -70,6 +70,10 @@ class MultiTeamSession(Session):
|
||||
|
||||
show_tutorial = cfg.get('Show Tutorial', True)
|
||||
|
||||
# Special case: don't show tutorial while stress testing.
|
||||
if classic.stress_test_update_timer is not None:
|
||||
show_tutorial = False
|
||||
|
||||
self._tutorial_activity_instance: bascenev1.Activity | None
|
||||
if show_tutorial:
|
||||
from bascenev1lib.tutorial import TutorialActivity
|
||||
|
||||
@ -253,7 +253,7 @@ class Session:
|
||||
# Limit player counts *unless* we're in a stress test.
|
||||
if (
|
||||
babase.app.classic is not None
|
||||
and babase.app.classic.stress_test_reset_timer is None
|
||||
and babase.app.classic.stress_test_update_timer is None
|
||||
):
|
||||
if len(self.sessionplayers) >= self.max_players:
|
||||
# Print a rejection message *only* to the client trying to
|
||||
|
||||
@ -42,6 +42,7 @@ class MainMenuActivity(bs.Activity[bs.Player, bs.Team]):
|
||||
self._language: str | None = None
|
||||
self._update_timer: bs.Timer | None = None
|
||||
self._news: NewsDisplay | None = None
|
||||
self._attract_mode_timer: bs.Timer | None = None
|
||||
|
||||
def on_transition_in(self) -> None:
|
||||
# pylint: disable=too-many-locals
|
||||
@ -295,6 +296,10 @@ class MainMenuActivity(bs.Activity[bs.Player, bs.Team]):
|
||||
if not (env.demo or env.arcade) and not app.ui_v1.use_toolbars:
|
||||
self._news = NewsDisplay(self)
|
||||
|
||||
self._attract_mode_timer = bs.Timer(
|
||||
3.12, self._update_attract_mode, repeat=True
|
||||
)
|
||||
|
||||
# Bring up the last place we were, or start at the main menu otherwise.
|
||||
with bs.ContextRef.empty():
|
||||
from bauiv1lib import specialoffer
|
||||
@ -387,7 +392,7 @@ class MainMenuActivity(bs.Activity[bs.Player, bs.Team]):
|
||||
|
||||
bs.app.ui_v1.set_main_menu_window(
|
||||
MainMenuWindow(transition=None).get_root_widget(),
|
||||
from_window=None,
|
||||
from_window=False, # Disable check here.
|
||||
)
|
||||
|
||||
# attempt to show any pending offers immediately.
|
||||
@ -403,6 +408,7 @@ class MainMenuActivity(bs.Activity[bs.Player, bs.Team]):
|
||||
bui.apptimer(2.0, specialoffer.show_offer)
|
||||
|
||||
bui.apptimer(2.0, try_again)
|
||||
|
||||
app.classic.main_menu_did_initial_transition = True
|
||||
|
||||
def _update(self) -> None:
|
||||
@ -836,6 +842,26 @@ class MainMenuActivity(bs.Activity[bs.Player, bs.Team]):
|
||||
|
||||
bui.apptimer(0.5, _start_menu_music)
|
||||
|
||||
def _update_attract_mode(self) -> None:
|
||||
if bui.app.classic is None:
|
||||
return
|
||||
|
||||
if not bui.app.config.resolve('Show Demos When Idle'):
|
||||
return
|
||||
|
||||
threshold = 20.0
|
||||
|
||||
# If we're idle *and* have been in this activity for that long,
|
||||
# flip over to our cpu demo.
|
||||
if bui.get_input_idle_time() > threshold and bs.time() > threshold:
|
||||
bui.app.classic.run_stress_test(
|
||||
playlist_type='Random',
|
||||
playlist_name='__default__',
|
||||
player_count=8,
|
||||
round_duration=20,
|
||||
attract_mode=True,
|
||||
)
|
||||
|
||||
|
||||
class NewsDisplay:
|
||||
"""Wrangles news display."""
|
||||
|
||||
@ -47,6 +47,7 @@ from babase import (
|
||||
do_once,
|
||||
fade_screen,
|
||||
get_display_resolution,
|
||||
get_input_idle_time,
|
||||
get_ip_address_type,
|
||||
get_low_level_config_value,
|
||||
get_max_graphics_quality,
|
||||
@ -156,6 +157,7 @@ __all__ = [
|
||||
'do_once',
|
||||
'fade_screen',
|
||||
'get_display_resolution',
|
||||
'get_input_idle_time',
|
||||
'get_ip_address_type',
|
||||
'get_low_level_config_value',
|
||||
'get_max_graphics_quality',
|
||||
|
||||
@ -1110,7 +1110,7 @@ class MainMenuWindow(bui.Window):
|
||||
session = bs.get_foreground_host_session()
|
||||
return getattr(session, 'benchmark_type', None) == 'cpu' or (
|
||||
bui.app.classic is not None
|
||||
and bui.app.classic.stress_test_reset_timer is not None
|
||||
and bui.app.classic.stress_test_update_timer is not None
|
||||
)
|
||||
|
||||
def _confirm_end_game(self) -> None:
|
||||
|
||||
@ -94,7 +94,7 @@ class AdvancedSettingsWindow(bui.Window):
|
||||
self._scroll_width = self._width - (100 + 2 * x_inset)
|
||||
self._scroll_height = self._height - 115.0
|
||||
self._sub_width = self._scroll_width * 0.95
|
||||
self._sub_height = 766.0
|
||||
self._sub_height = 808.0
|
||||
|
||||
if self._show_always_use_internal_keyboard:
|
||||
self._sub_height += 62
|
||||
@ -489,6 +489,17 @@ class AdvancedSettingsWindow(bui.Window):
|
||||
maxwidth=430,
|
||||
)
|
||||
|
||||
v -= 42
|
||||
self._show_demos_when_idle_check_box = ConfigCheckBox(
|
||||
parent=self._subcontainer,
|
||||
position=(50, v),
|
||||
size=(self._sub_width - 100, 30),
|
||||
configkey='Show Demos When Idle',
|
||||
displayname=bui.Lstr(resource=f'{self._r}.showDemosWhenIdleText'),
|
||||
scale=1.0,
|
||||
maxwidth=430,
|
||||
)
|
||||
|
||||
v -= 42
|
||||
self._disable_camera_shake_check_box = ConfigCheckBox(
|
||||
parent=self._subcontainer,
|
||||
@ -575,12 +586,18 @@ class AdvancedSettingsWindow(bui.Window):
|
||||
up_widget=self._always_use_internal_keyboard_check_box.widget,
|
||||
)
|
||||
else:
|
||||
bui.widget(
|
||||
edit=self._modding_guide_button,
|
||||
up_widget=self._kick_idle_players_check_box.widget,
|
||||
# ew.
|
||||
next_widget_up = (
|
||||
self._disable_gyro_check_box.widget
|
||||
if self._disable_gyro_check_box is not None
|
||||
else self._disable_camera_shake_check_box.widget
|
||||
)
|
||||
bui.widget(
|
||||
edit=self._kick_idle_players_check_box.widget,
|
||||
edit=self._modding_guide_button,
|
||||
up_widget=next_widget_up,
|
||||
)
|
||||
bui.widget(
|
||||
edit=next_widget_up,
|
||||
down_widget=self._modding_guide_button,
|
||||
)
|
||||
|
||||
@ -803,6 +820,8 @@ class AdvancedSettingsWindow(bui.Window):
|
||||
sel_name = 'Benchmarks'
|
||||
elif sel == self._kick_idle_players_check_box.widget:
|
||||
sel_name = 'KickIdlePlayers'
|
||||
elif sel == self._show_demos_when_idle_check_box.widget:
|
||||
sel_name = 'ShowDemosWhenIdle'
|
||||
elif sel == self._show_game_ping_check_box.widget:
|
||||
sel_name = 'ShowPing'
|
||||
elif sel == self._disable_camera_shake_check_box.widget:
|
||||
@ -870,6 +889,8 @@ class AdvancedSettingsWindow(bui.Window):
|
||||
sel = self._benchmarks_button
|
||||
elif sel_name == 'KickIdlePlayers':
|
||||
sel = self._kick_idle_players_check_box.widget
|
||||
elif sel_name == 'ShowDemosWhenIdle':
|
||||
sel = self._show_demos_when_idle_check_box.widget
|
||||
elif sel_name == 'ShowPing':
|
||||
sel = self._show_game_ping_check_box.widget
|
||||
elif sel_name == 'DisableCameraShake':
|
||||
|
||||
@ -52,9 +52,9 @@ InputDevice::~InputDevice() { assert(g_base->InLogicThread()); }
|
||||
// control something please.
|
||||
void InputDevice::RequestPlayer() {
|
||||
assert(g_base->InLogicThread());
|
||||
|
||||
// Make note that we're being used in some way.
|
||||
last_input_time_millisecs_ =
|
||||
static_cast<millisecs_t>(g_base->logic->display_time() * 1000.0);
|
||||
UpdateLastActiveTime();
|
||||
|
||||
delegate_->RequestPlayer();
|
||||
}
|
||||
@ -69,11 +69,19 @@ auto InputDevice::AttachedToPlayer() const -> bool {
|
||||
|
||||
void InputDevice::DetachFromPlayer() { delegate_->DetachFromPlayer(); }
|
||||
|
||||
void InputDevice::UpdateLastInputTime() {
|
||||
// Keep our own individual time, and also let the overall input system
|
||||
// know something happened.
|
||||
last_input_time_millisecs_ =
|
||||
void InputDevice::UpdateLastActiveTime() {
|
||||
// Special case: in attract-mode, prevent our virtual test devices from
|
||||
// affecting input last-active times otherwise it'll kick us out of
|
||||
// attract mode.
|
||||
if (allow_input_in_attract_mode_ && g_base->input->attract_mode()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Mark active time on this specific device.
|
||||
last_active_time_millisecs_ =
|
||||
static_cast<millisecs_t>(g_base->logic->display_time() * 1000.0);
|
||||
|
||||
// Mark input in general as active also.
|
||||
g_base->input->MarkInputActive();
|
||||
}
|
||||
|
||||
@ -81,7 +89,7 @@ void InputDevice::InputCommand(InputType type, float value) {
|
||||
assert(g_base->InLogicThread());
|
||||
|
||||
// Make note that we're being used in some way.
|
||||
UpdateLastInputTime();
|
||||
UpdateLastActiveTime();
|
||||
|
||||
delegate_->InputCommand(type, value);
|
||||
}
|
||||
|
||||
@ -93,8 +93,8 @@ class InputDevice : public Object {
|
||||
/// that button activates default widgets (will cause a start icon to show up
|
||||
/// on them).
|
||||
virtual auto start_button_activates_default_widget() -> bool { return false; }
|
||||
auto last_input_time_millisecs() const -> millisecs_t {
|
||||
return last_input_time_millisecs_;
|
||||
auto last_active_time_millisecs() const -> millisecs_t {
|
||||
return last_active_time_millisecs_;
|
||||
}
|
||||
virtual auto ShouldBeHiddenFromUser() -> bool;
|
||||
|
||||
@ -117,7 +117,7 @@ class InputDevice : public Object {
|
||||
/// been added to the input-device list, have a valid ID, name, etc.
|
||||
virtual void OnAdded() {}
|
||||
|
||||
void UpdateLastInputTime();
|
||||
void UpdateLastActiveTime();
|
||||
|
||||
auto delegate() -> InputDeviceDelegate& {
|
||||
// TEMP - Tracking down a crash in the wild.
|
||||
@ -136,18 +136,27 @@ class InputDevice : public Object {
|
||||
auto custom_default_player_name() const -> std::string {
|
||||
return custom_default_player_name_;
|
||||
}
|
||||
|
||||
void set_custom_default_player_name(const std::string& val) {
|
||||
custom_default_player_name_ = val;
|
||||
}
|
||||
|
||||
auto allow_input_in_attract_mode() const {
|
||||
return allow_input_in_attract_mode_;
|
||||
}
|
||||
|
||||
void set_allow_input_in_attract_mode(bool allow) {
|
||||
allow_input_in_attract_mode_ = allow;
|
||||
}
|
||||
|
||||
private:
|
||||
Object::Ref<InputDeviceDelegate> delegate_;
|
||||
|
||||
// note: this is in base-net-time
|
||||
millisecs_t last_input_time_millisecs_{};
|
||||
millisecs_t last_active_time_millisecs_{};
|
||||
|
||||
int index_{-1}; // Our overall device index.
|
||||
int number_{-1}; // Our type-specific number.
|
||||
bool allow_input_in_attract_mode_{};
|
||||
|
||||
std::string custom_default_player_name_;
|
||||
|
||||
|
||||
@ -44,10 +44,6 @@ JoystickInput::JoystickInput(int sdl_joystick_id,
|
||||
analog_calibration_val = 0.6f;
|
||||
}
|
||||
|
||||
if (custom_device_name == "TestInput") {
|
||||
is_test_input_ = true;
|
||||
}
|
||||
|
||||
sdl_joystick_id_ = sdl_joystick_id;
|
||||
|
||||
// Non-negative values here mean its an SDL joystick.
|
||||
@ -799,7 +795,9 @@ void JoystickInput::HandleSDLEvent(const SDL_Event* e) {
|
||||
|
||||
// Anything that would go to ui also counts to mark us as 'recently-used'.
|
||||
if (would_go_to_ui) {
|
||||
UpdateLastInputTime();
|
||||
if (!(allow_input_in_attract_mode() && g_base->input->attract_mode())) {
|
||||
UpdateLastActiveTime();
|
||||
}
|
||||
}
|
||||
|
||||
if (would_go_to_ui && g_base->ui->GetWidgetForInput(this)) {
|
||||
|
||||
@ -59,6 +59,8 @@ class JoystickInput : public InputDevice {
|
||||
|
||||
auto IsUIOnly() -> bool override { return ui_only_; }
|
||||
|
||||
void set_is_test_input(bool val) { is_test_input_ = val; }
|
||||
|
||||
auto IsTestInput() -> bool override { return is_test_input_; }
|
||||
auto IsRemoteApp() -> bool override { return is_remote_app_; }
|
||||
auto IsMFiController() -> bool override { return is_mfi_controller_; }
|
||||
|
||||
@ -4,16 +4,24 @@
|
||||
|
||||
#include "ballistica/base/input/device/joystick_input.h"
|
||||
#include "ballistica/base/input/input.h"
|
||||
#include "ballistica/base/ui/ui.h"
|
||||
#include "ballistica/core/platform/support/min_sdl.h"
|
||||
#include "ballistica/shared/math/random.h"
|
||||
|
||||
namespace ballistica::base {
|
||||
|
||||
TestInput::TestInput() {
|
||||
// In attract-mode (pretty demos) we want this to look more like
|
||||
// real people connecting to the game, so just say 'Controller'.
|
||||
const char* device_name =
|
||||
g_base->input->attract_mode() ? "Controller" : "TestInput";
|
||||
|
||||
joystick_ = Object::NewDeferred<JoystickInput>(-1, // not an sdl joystick
|
||||
"TestInput", // device name
|
||||
device_name, // device name
|
||||
false, // allow configuring?
|
||||
false); // calibrate?;
|
||||
joystick_->set_allow_input_in_attract_mode(true);
|
||||
joystick_->set_is_test_input(true);
|
||||
g_base->input->PushAddInputDeviceCall(joystick_, true);
|
||||
}
|
||||
|
||||
@ -56,6 +64,11 @@ void TestInput::Process(millisecs_t time) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Do nothing while any UI is up.
|
||||
if (g_base->ui->MainMenuVisible()) {
|
||||
return;
|
||||
}
|
||||
|
||||
float r = RandomFloat();
|
||||
|
||||
SDL_Event e;
|
||||
|
||||
@ -170,9 +170,6 @@ void Input::AnnounceConnects_() {
|
||||
} else {
|
||||
// If there's been several connected, just give a number.
|
||||
if (newly_connected_controllers_.size() > 1) {
|
||||
for (auto&& s : newly_connected_controllers_) {
|
||||
Log(LogLevel::kInfo, "GOT CONTROLLER " + s);
|
||||
}
|
||||
std::string s =
|
||||
g_base->assets->GetResourceString("controllersConnectedText");
|
||||
Utils::StringReplaceOne(
|
||||
@ -392,9 +389,9 @@ void Input::UpdateInputDeviceCounts_() {
|
||||
// just due to those)
|
||||
if (input_device.Exists()
|
||||
&& ((*input_device).IsTouchScreen() || (*input_device).IsKeyboard()
|
||||
|| ((*input_device).last_input_time_millisecs() != 0
|
||||
|| ((*input_device).last_active_time_millisecs() != 0
|
||||
&& current_time_millisecs
|
||||
- (*input_device).last_input_time_millisecs()
|
||||
- (*input_device).last_active_time_millisecs()
|
||||
< 60000))) {
|
||||
total++;
|
||||
if (!(*input_device).IsTouchScreen()) {
|
||||
@ -441,9 +438,9 @@ auto Input::GetLocalActiveInputDeviceCount() -> int {
|
||||
if (input_device.Exists() && !input_device->IsKeyboard()
|
||||
&& !input_device->IsTouchScreen() && !input_device->IsUIOnly()
|
||||
&& input_device->IsLocal()
|
||||
&& (input_device->last_input_time_millisecs() != 0
|
||||
&& (input_device->last_active_time_millisecs() != 0
|
||||
&& current_time_millisecs
|
||||
- input_device->last_input_time_millisecs()
|
||||
- input_device->last_active_time_millisecs()
|
||||
< 60000)) {
|
||||
count++;
|
||||
}
|
||||
@ -639,8 +636,9 @@ void Input::UnlockAllInput(bool permanent, const std::string& label) {
|
||||
permanent ? "permanent unlock: "
|
||||
: "temp unlock: " + label + " time "
|
||||
+ std::to_string(g_core->GetAppTimeMillisecs()));
|
||||
while (recent_input_locks_unlocks_.size() > 10)
|
||||
while (recent_input_locks_unlocks_.size() > 10) {
|
||||
recent_input_locks_unlocks_.pop_front();
|
||||
}
|
||||
|
||||
if (permanent) {
|
||||
input_lock_count_permanent_--;
|
||||
@ -722,15 +720,15 @@ void Input::PrintLockLabels_() {
|
||||
void Input::PushTextInputEvent(const std::string& text) {
|
||||
assert(g_base->logic->event_loop());
|
||||
g_base->logic->event_loop()->PushCall([this, text] {
|
||||
// Mark as active even if input is locked.
|
||||
MarkInputActive();
|
||||
|
||||
// If the app doesn't want direct text input right now, ignore.
|
||||
if (!g_base->app_adapter->HasDirectKeyboardInput()) {
|
||||
if (IsInputLocked()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Ignore if input is locked.
|
||||
if (IsInputLocked()) {
|
||||
// If the app doesn't want direct text input right now, ignore.
|
||||
if (!g_base->app_adapter->HasDirectKeyboardInput()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -795,16 +793,14 @@ void Input::HandleJoystickEvent_(const SDL_Event& event,
|
||||
if (ShouldCompletelyIgnoreInputDevice(input_device)) {
|
||||
return;
|
||||
}
|
||||
if (IsInputLocked()) {
|
||||
|
||||
// Mark as active even if input is locked.
|
||||
input_device->UpdateLastActiveTime();
|
||||
|
||||
if (IsInputLocked(input_device)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Make note that we're not idle.
|
||||
MarkInputActive();
|
||||
|
||||
// And that this particular device isn't idle either.
|
||||
input_device->UpdateLastInputTime();
|
||||
|
||||
// If someone is capturing these events, give them a crack at it.
|
||||
if (joystick_input_capture_) {
|
||||
if (joystick_input_capture_(event, input_device)) {
|
||||
@ -905,9 +901,9 @@ void Input::HandleKeyReleaseSimple_(int keycode) {
|
||||
void Input::HandleKeyPress_(const SDL_Keysym& keysym) {
|
||||
assert(g_base->InLogicThread());
|
||||
|
||||
// Mark as active even if input is locked.
|
||||
MarkInputActive();
|
||||
|
||||
// Ignore all key presses if input is locked.
|
||||
if (IsInputLocked()) {
|
||||
return;
|
||||
}
|
||||
@ -1180,8 +1176,9 @@ void Input::PushMouseScrollEvent(const Vector2f& amount) {
|
||||
void Input::HandleMouseScroll_(const Vector2f& amount) {
|
||||
assert(g_base->InLogicThread());
|
||||
|
||||
// If input is locked, allow it to mark us active but nothing more.
|
||||
// Mark as active even if input is locked.
|
||||
MarkInputActive();
|
||||
|
||||
if (IsInputLocked()) {
|
||||
return;
|
||||
}
|
||||
@ -1217,8 +1214,9 @@ void Input::PushSmoothMouseScrollEvent(const Vector2f& velocity,
|
||||
void Input::HandleSmoothMouseScroll_(const Vector2f& velocity, bool momentum) {
|
||||
assert(g_base->InLogicThread());
|
||||
|
||||
// If input is locked, allow it to mark us active but nothing more.
|
||||
// Mark as active even if input is locked.
|
||||
MarkInputActive();
|
||||
|
||||
if (IsInputLocked()) {
|
||||
return;
|
||||
}
|
||||
@ -1259,6 +1257,7 @@ void Input::HandleMouseMotion_(const Vector2f& position) {
|
||||
assert(g_base);
|
||||
assert(g_base->InLogicThread());
|
||||
|
||||
// Mark as active even if input is locked.
|
||||
MarkInputActive();
|
||||
|
||||
if (IsInputLocked()) {
|
||||
@ -1309,6 +1308,7 @@ void Input::HandleMouseDown_(int button, const Vector2f& position) {
|
||||
assert(g_base);
|
||||
assert(g_base->InLogicThread());
|
||||
|
||||
// Mark as active even if input is locked.
|
||||
MarkInputActive();
|
||||
|
||||
if (IsInputLocked()) {
|
||||
@ -1416,12 +1416,13 @@ void Input::HandleTouchEvent_(const TouchEvent& e) {
|
||||
assert(g_base->InLogicThread());
|
||||
assert(g_base->graphics);
|
||||
|
||||
// Mark as active even if input is locked.
|
||||
MarkInputActive();
|
||||
|
||||
if (IsInputLocked()) {
|
||||
return;
|
||||
}
|
||||
|
||||
MarkInputActive();
|
||||
|
||||
if (g_buildconfig.ostype_ios_tvos()) {
|
||||
printf("FIXME: update touch handling\n");
|
||||
}
|
||||
@ -1564,4 +1565,11 @@ void Input::LsInputDevices() {
|
||||
Log(LogLevel::kInfo, out);
|
||||
}
|
||||
|
||||
auto Input::ShouldAllowInputInAttractMode_(InputDevice* device) const -> bool {
|
||||
if (device == nullptr) {
|
||||
return false;
|
||||
}
|
||||
return device->allow_input_in_attract_mode();
|
||||
}
|
||||
|
||||
} // namespace ballistica::base
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "ballistica/base/base.h"
|
||||
#include "ballistica/shared/foundation/macros.h"
|
||||
#include "ballistica/shared/foundation/object.h"
|
||||
#include "ballistica/shared/foundation/types.h"
|
||||
|
||||
@ -62,7 +63,14 @@ class Input {
|
||||
void Reset();
|
||||
void LockAllInput(bool permanent, const std::string& label);
|
||||
void UnlockAllInput(bool permanent, const std::string& label);
|
||||
auto IsInputLocked() const -> bool {
|
||||
auto IsInputLocked(InputDevice* device = nullptr) const -> bool {
|
||||
// Special case; in attract-mode we ignore all input except our
|
||||
// dummy controllers.
|
||||
if (attract_mode_) {
|
||||
if (!ShouldAllowInputInAttractMode_(device)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return input_lock_count_temp_ > 0 || input_lock_count_permanent_ > 0;
|
||||
}
|
||||
auto cursor_pos_x() const -> float { return cursor_pos_x_; }
|
||||
@ -92,12 +100,7 @@ class Input {
|
||||
}
|
||||
void Draw(FrameDef* frame_def);
|
||||
|
||||
// Get the total idle time for the system.
|
||||
// FIXME - should better coordinate this with InputDevice::getLastUsedTime().
|
||||
// auto GetIdleTime() const -> millisecs_t;
|
||||
|
||||
// Should be called whenever user-input of some form comes through.
|
||||
// void ResetIdleTime() { last_input_time_ = GetAppTimeMillisecs(); }
|
||||
/// Should be called whenever user-input of some form comes through.
|
||||
auto MarkInputActive() { input_active_ = true; }
|
||||
|
||||
// returns true if more than one non-keyboard device has been active recently
|
||||
@ -153,7 +156,11 @@ class Input {
|
||||
void ReleaseJoystickInput();
|
||||
void RebuildInputDeviceDelegates();
|
||||
|
||||
auto attract_mode() const { return attract_mode_; }
|
||||
void set_attract_mode(bool val) { attract_mode_ = val; }
|
||||
|
||||
private:
|
||||
auto ShouldAllowInputInAttractMode_(InputDevice* device) const -> bool;
|
||||
void UpdateInputDeviceCounts_();
|
||||
auto GetNewNumberedIdentifier_(const std::string& name,
|
||||
const std::string& identifier) -> int;
|
||||
@ -183,8 +190,9 @@ class Input {
|
||||
int max_controller_count_so_far_{};
|
||||
int local_active_input_device_count_{};
|
||||
int mouse_move_count_{};
|
||||
int input_lock_count_temp_{};
|
||||
int input_lock_count_permanent_{};
|
||||
int8_t input_lock_count_temp_{};
|
||||
int8_t input_lock_count_permanent_{};
|
||||
bool attract_mode_{};
|
||||
bool input_active_{};
|
||||
bool have_button_using_inputs_{};
|
||||
bool have_start_activated_default_button_inputs_{};
|
||||
|
||||
@ -1805,6 +1805,26 @@ static PyMethodDef PyOpenFileExternallyDef = {
|
||||
"Open the provided file in the default external app.",
|
||||
};
|
||||
|
||||
// --------------------------- get_input_idle_time -----------------------------
|
||||
|
||||
static auto PyGetInputIdleTime(PyObject* self) -> PyObject* {
|
||||
BA_PYTHON_TRY;
|
||||
|
||||
BA_PRECONDITION(g_base->InLogicThread());
|
||||
return PyFloat_FromDouble(0.001 * g_base->input->input_idle_time());
|
||||
|
||||
BA_PYTHON_CATCH;
|
||||
}
|
||||
|
||||
static PyMethodDef PyGetInputIdleTimeDef = {
|
||||
"get_input_idle_time", // name
|
||||
(PyCFunction)PyGetInputIdleTime, // method
|
||||
METH_NOARGS, // flags
|
||||
|
||||
"get_input_idle_time() -> float\n"
|
||||
"\n"
|
||||
"Return seconds since any local input occurred (touch, keypress, etc.).",
|
||||
};
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
auto PythonMethodsMisc::GetMethods() -> std::vector<PyMethodDef> {
|
||||
@ -1873,6 +1893,7 @@ auto PythonMethodsMisc::GetMethods() -> std::vector<PyMethodDef> {
|
||||
PyNativeReviewRequestDef,
|
||||
PyTempTestingDef,
|
||||
PyOpenFileExternallyDef,
|
||||
PyGetInputIdleTimeDef,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -169,7 +169,6 @@ void AppConfig::CompleteMap(const T& entry_map) {
|
||||
|
||||
void AppConfig::SetupEntries() {
|
||||
// Register all our typed entries.
|
||||
float_entries_[FloatID::kScreenGamma] = FloatEntry("Screen Gamma", 1.0F);
|
||||
float_entries_[FloatID::kScreenPixelScale] =
|
||||
FloatEntry("Screen Pixel Scale", 1.0F);
|
||||
float_entries_[FloatID::kTouchControlsScale] =
|
||||
@ -236,6 +235,8 @@ void AppConfig::SetupEntries() {
|
||||
BoolEntry("Disable Camera Shake", false);
|
||||
bool_entries_[BoolID::kDisableCameraGyro] =
|
||||
BoolEntry("Disable Camera Gyro", false);
|
||||
bool_entries_[BoolID::kShowDemosWhenIdle] =
|
||||
BoolEntry("Show Demos When Idle", false);
|
||||
|
||||
// Now add everything to our name map and make sure all is kosher.
|
||||
CompleteMap(float_entries_);
|
||||
|
||||
@ -9,9 +9,10 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
// FIXME: this system is old and dumb.
|
||||
// Should come up with a better one using the meta system
|
||||
// based on Python dataclassio types or whatnot.
|
||||
// FIXME: this system is old and dumb. It was built to make C++ stuff
|
||||
// type-safe but does not handle the Python side at all. We should come up
|
||||
// with something Python-centric using dataclasses/etc. where a C++
|
||||
// component gets autogenerated via the meta system/etc.
|
||||
|
||||
namespace ballistica::base {
|
||||
|
||||
@ -24,7 +25,6 @@ class AppConfig {
|
||||
// Our official config values:
|
||||
|
||||
enum class FloatID {
|
||||
kScreenGamma,
|
||||
kScreenPixelScale,
|
||||
kTouchControlsScale,
|
||||
kTouchControlsScaleMovement,
|
||||
@ -74,6 +74,7 @@ class AppConfig {
|
||||
kEnableRemoteApp,
|
||||
kDisableCameraShake,
|
||||
kDisableCameraGyro,
|
||||
kShowDemosWhenIdle,
|
||||
kLast // Sentinel.
|
||||
};
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
|
||||
#include "ballistica/base/graphics/graphics.h"
|
||||
#include "ballistica/base/graphics/support/camera.h"
|
||||
#include "ballistica/base/input/input.h"
|
||||
#include "ballistica/base/logic/logic.h"
|
||||
#include "ballistica/classic/support/stress_test.h"
|
||||
#include "ballistica/scene_v1/support/scene_v1_app_mode.h"
|
||||
@ -154,11 +155,13 @@ static auto PySetStressTesting(PyObject* self, PyObject* args) -> PyObject* {
|
||||
BA_PYTHON_TRY;
|
||||
int enable;
|
||||
int player_count;
|
||||
if (!PyArg_ParseTuple(args, "pi", &enable, &player_count)) {
|
||||
int attract_mode;
|
||||
if (!PyArg_ParseTuple(args, "pip", &enable, &player_count, &attract_mode)) {
|
||||
return nullptr;
|
||||
}
|
||||
g_base->logic->event_loop()->PushCall([enable, player_count] {
|
||||
g_classic->stress_test()->Set(enable, player_count);
|
||||
g_base->logic->event_loop()->PushCall([enable, player_count, attract_mode] {
|
||||
g_classic->stress_test()->Set(enable, player_count, attract_mode);
|
||||
g_base->input->set_attract_mode(enable && attract_mode);
|
||||
});
|
||||
Py_RETURN_NONE;
|
||||
BA_PYTHON_CATCH;
|
||||
@ -169,7 +172,9 @@ static PyMethodDef PySetStressTestingDef = {
|
||||
PySetStressTesting, // method
|
||||
METH_VARARGS, // flags
|
||||
|
||||
"set_stress_testing(testing: bool, player_count: int) -> None\n"
|
||||
"set_stress_testing(testing: bool,\n"
|
||||
" player_count: int,\n"
|
||||
" attract_mode: bool) -> None\n"
|
||||
"\n"
|
||||
"(internal)",
|
||||
};
|
||||
|
||||
@ -11,16 +11,16 @@
|
||||
|
||||
namespace ballistica::classic {
|
||||
|
||||
void StressTest::Set(bool enable, int player_count) {
|
||||
void StressTest::Set(bool enable, int player_count, bool attract_mode) {
|
||||
assert(g_base->InLogicThread());
|
||||
bool was_stress_testing = stress_testing_;
|
||||
stress_testing_ = enable;
|
||||
stress_test_player_count_ = player_count;
|
||||
attract_mode_ = attract_mode;
|
||||
|
||||
// If we're turning on, reset our intervals and things.
|
||||
if (!was_stress_testing && stress_testing_) {
|
||||
// So our first sample is 1 interval from now.
|
||||
// last_stress_test_update_time_ = g_core->GetAppTimeMillisecs();
|
||||
|
||||
// Reset our frames-rendered tally.
|
||||
if (g_base && g_base->graphics_server
|
||||
@ -71,9 +71,11 @@ void StressTest::ProcessInputs(int player_count) {
|
||||
test_inputs_.push_back(new base::TestInput());
|
||||
}
|
||||
|
||||
// Every so often lets kill the oldest one off.
|
||||
// Every so often lets kill the oldest one off (less often in attract-mode
|
||||
// though).
|
||||
int odds = attract_mode_ ? 10000 : 2000;
|
||||
if (explicit_bool(true)) {
|
||||
if (test_inputs_.size() > 0 && (rand() % 2000 < 3)) { // NOLINT
|
||||
if (test_inputs_.size() > 0 && (rand() % odds < 3)) { // NOLINT
|
||||
stress_test_last_leave_time_ = time;
|
||||
|
||||
// Usually do oldest; sometimes newest.
|
||||
|
||||
@ -11,7 +11,7 @@ namespace ballistica::classic {
|
||||
|
||||
class StressTest {
|
||||
public:
|
||||
void Set(bool enable, int player_count);
|
||||
void Set(bool enable, int player_count, bool attract_mode);
|
||||
void Update();
|
||||
|
||||
private:
|
||||
@ -23,8 +23,7 @@ class StressTest {
|
||||
int stress_test_player_count_{8};
|
||||
int last_total_frames_rendered_{};
|
||||
bool stress_testing_{};
|
||||
// millisecs_t last_stress_test_update_time_{};
|
||||
// FILE* stress_test_stats_file_{};
|
||||
bool attract_mode_{};
|
||||
Object::Ref<base::AppTimer> update_timer_{};
|
||||
};
|
||||
|
||||
|
||||
@ -73,6 +73,9 @@ void PythonClassInputDevice::SetupType(PyTypeObject* cls) {
|
||||
" is_remote_client (bool):\n"
|
||||
" Whether this input-device represents a remotely-connected\n"
|
||||
" client.\n"
|
||||
"\n"
|
||||
" is_test_input (bool):\n"
|
||||
" Whether this input-device is a dummy device for testing.\n"
|
||||
"\n";
|
||||
|
||||
cls->tp_new = tp_new;
|
||||
@ -265,6 +268,16 @@ auto PythonClassInputDevice::tp_getattro(PythonClassInputDevice* self,
|
||||
} else {
|
||||
Py_RETURN_FALSE;
|
||||
}
|
||||
} else if (!strcmp(s, "is_test_input")) {
|
||||
auto* delegate = self->input_device_delegate_->Get();
|
||||
if (!delegate) {
|
||||
throw Exception(PyExcType::kInputDeviceNotFound);
|
||||
}
|
||||
if (delegate->input_device().IsTestInput()) {
|
||||
Py_RETURN_TRUE;
|
||||
} else {
|
||||
Py_RETURN_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// Fall back to generic behavior.
|
||||
|
||||
@ -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 = 21747;
|
||||
const int kEngineBuildNumber = 21751;
|
||||
const char* kEngineVersion = "1.7.33";
|
||||
const int kEngineApiVersion = 8;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user