Fixed rare crashes on SDL joystick connections

This commit is contained in:
Eric 2024-09-30 12:20:56 -07:00
parent 1e7a17cb4a
commit fdd9d0455a
No known key found for this signature in database
GPG Key ID: 89C93F0F8D6D5A98
10 changed files with 85 additions and 435 deletions

62
.efrocachemap generated
View File

@ -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": "a3d27b587a1b206a3338ef820a802313",
"build/assets/ba_data/data/langdata.json": "84353324570add5ea6698d8a7ddd99be",
"build/assets/ba_data/data/languages/arabic.json": "609f5d698a488e40e61787b62ee8ea5e",
"build/assets/ba_data/data/languages/belarussian.json": "3d5523d0004293aa2df02f3f6f3b84f8",
"build/assets/ba_data/data/languages/chinese.json": "57d199cfd2a5cf493e777dd96cc12f7c",
@ -448,10 +448,10 @@
"build/assets/ba_data/data/languages/portuguese.json": "eb2563e245e1ea00b870264dced3ebd7",
"build/assets/ba_data/data/languages/romanian.json": "55a8744e466801013ea131266a856924",
"build/assets/ba_data/data/languages/russian.json": "0fcc60bf1e8e19a74f02b0798728ec68",
"build/assets/ba_data/data/languages/serbian.json": "d7452dd72ac0e51680cb39b5ebaa1c69",
"build/assets/ba_data/data/languages/serbian.json": "623fa4129a1154c2f32ed7867e56ff6a",
"build/assets/ba_data/data/languages/slovak.json": "3c08c748c96c71bd9e1d7291fb8817b6",
"build/assets/ba_data/data/languages/spanish.json": "0a37387183a6634fc8e9ac225fcf20b1",
"build/assets/ba_data/data/languages/swedish.json": "039c803fad78f1018ad363d2a0be8582",
"build/assets/ba_data/data/languages/swedish.json": "3b179e7333183c70adb0811246b09959",
"build/assets/ba_data/data/languages/tamil.json": "ead39b864228696a9b0d19344bc4b5ec",
"build/assets/ba_data/data/languages/thai.json": "1d665629361f302693dead39de8fa945",
"build/assets/ba_data/data/languages/turkish.json": "6153ca5248b8e4743e9501ac72378493",
@ -4096,26 +4096,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": "934beaf11fef829457ce148c66b5e585",
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "3a781083e1bad04cec163e9d16d45271",
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "6b32c8bfea5a1b4fc6f32844e2edcc57",
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "eebd9448a29f673119df718380dc6dd8",
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "4c946813d6cc95bb1e8aed1881913ddf",
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "3b26ce105d259eaee3d964f82956224f",
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "b8c814d170feb2faadb69164515842a9",
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "0e310eb8656a9d953155bbb8d976b2f2",
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "0b36408df8e2109827d4f7847268d736",
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "05977ff4eaa374af3d89c004e970568b",
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "ffdbeddc2b1821fbe19ab894b2bd72a4",
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "46854a9414fc4ed0ad06993e1588f7e1",
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "14454a00a0c004e0d1bcf21bcb78d936",
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "1df8d35253f5165ff0c4c524abe629e9",
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "99f7a778a0938759f21a90fcbe14248b",
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "1e11c3a36ff8eb9ca6103eadf3d158ed",
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "f24c4c859dc5b024bb5c512a3f0d232e",
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "c929e99f3e6f2842b72763fce20ebee7",
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "f9ff98d7f062d9440b4a729a0bc69f5e",
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "81b2fee39861009c1b3473eba05f16db",
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "fd2ccd57c412479ed03996a5e74a1ce4",
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "6a04d9c28b5d13fe33363e930aedd022",
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "e1e84f99447ecf5aa6c33d0780ae70f5",
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "98b55a2dbbaf1fd91b4f8dd1ac5249bd",
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "49e65d07d4d1c50a2c5aa670fb3fdc54",
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "a3b68c610903acc54e9cf595cb9c22e1",
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "e79806597b55297c2b6c39a0c0a89a9b",
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "af551c6316f51da5a768b12c2f970662",
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "b8d1821cadc35df59bfe89d8fa1bde56",
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "710532ecdf5162725223b3416ca1ca29",
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "afa36ce15429556c3b6ac972fa2e5245",
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "39e494cef6c263d793d81e99a1e51496",
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "e77092b692df532a19b7fd203cf8bb75",
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "75c02b6cfa892fbcfae8d55313fa3ac5",
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "f8e7cf715c1666c6cd367018c4187aeb",
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "9af412f7bfe3ac120de9d033e868b6b5",
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "3182401e9b600638c78f3bb849da4588",
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "c357f68d5e01e6caef1ac2eab2b81750",
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "ee2e732ddf920f3da89c2e46fe3fec5f",
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "5cbbbf35e5c3c5f71ad35ab3cb4e93e1",
"build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "0b5f8bdbe8221c4642d9f7f8584645ce",
"build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "e94dd06863796f17b9cfcbb5f79edd32",
"build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "0b5f8bdbe8221c4642d9f7f8584645ce",
@ -4132,14 +4132,14 @@
"build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "381953df0ba482ef485e4da3fd8e9e69",
"build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "3b706f71d9a4fd3e5e5ecae88c6087ee",
"build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "381953df0ba482ef485e4da3fd8e9e69",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "f96357e0b4eb4894c8a8327626797754",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "f7a7bce42dcd206e845ad35754343eb7",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "8f79fc85655f52cd6fb739fd732c91cd",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "90e403f165a8fbad55eb8f4bdaea6ade",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "b8634bbb5f5ee3e9f6359f09400aa490",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "c6166b7bb3fb6de97c76ab64632de139",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "c08318d39cab7eff0f81d1d276371d43",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "01d30f66b297e58129d66ecc45603199",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "9a5a41db9a2aa0f6fdc84bbc4d2a8ff7",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "12673b3a3699fae399e6129da992e9e6",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "659f4ce5759c8d7c910eec4a5e05b52d",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "83cfa6f843dad450f9c3a173e9717a3a",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "f50dfe45998077e38c808057b4a1d547",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "b059a1b92c6c093b54e48669564bdf1a",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "9b81340df4e2a4cb0ae7a1bd807ed7ec",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "6649f9be5b801b90ee692a1612c62e7b",
"src/assets/ba_data/python/babase/_mgen/__init__.py": "f885fed7f2ed98ff2ba271f9dbe3391c",
"src/assets/ba_data/python/babase/_mgen/enums.py": "794d258d59fd17a61752843a9a0551ad",
"src/ballistica/base/mgen/pyembed/binding_base.inc": "efa61468cf098f77cc6a234461d8b86d",

View File

@ -1,4 +1,4 @@
### 1.7.37 (build 22018, api 9, 2024-09-28)
### 1.7.37 (build 22019, api 9, 2024-09-30)
- Bumping api version to 9. As you'll see below, there's some UI changes that
will require a bit of work for any UI mods to adapt to. If your mods don't
touch UI stuff at all you can simply bump your api version and call it a day.
@ -108,6 +108,8 @@
the co-op screen and pressed the trophy toolbar icon to see your league rank
and then pressed back, you would be taken back to the top level main menu. Now
it will take you back to the co-op screen.
- (build 22018) Hardened SDL joystick handling code so the app won't crash if
SDL_JoystickOpen() returns nullptr for whatever reason.
### 1.7.36 (build 21944, api 8, 2024-07-26)
- Wired up Tokens, BombSquad's new purchasable currency. The first thing these

View File

@ -52,7 +52,7 @@ if TYPE_CHECKING:
# Build number and version of the ballistica binary we expect to be
# using.
TARGET_BALLISTICA_BUILD = 22018
TARGET_BALLISTICA_BUILD = 22019
TARGET_BALLISTICA_VERSION = '1.7.37'

View File

@ -5,7 +5,6 @@
#include "ballistica/base/app_adapter/app_adapter_sdl.h"
#include "ballistica/base/base.h"
#include "ballistica/base/dynamics/bg/bg_dynamics.h"
#include "ballistica/base/graphics/gl/gl_sys.h"
#include "ballistica/base/graphics/gl/renderer_gl.h"
#include "ballistica/base/graphics/graphics.h"
@ -555,8 +554,18 @@ void AppAdapterSDL::OnSDLJoystickAdded_(int device_index) {
// Create the joystick here in the main thread and then pass it over to
// the logic thread to be added to the action.
auto* j = Object::NewDeferred<JoystickInput>(device_index);
int instance_id = SDL_JoystickInstanceID(j->sdl_joystick());
JoystickInput* j{};
try {
j = Object::NewDeferred<JoystickInput>(device_index);
} catch (const std::exception& exc) {
Log(LogLevel::kError,
std::string("Error creating JoystickInput for SDL device-index "
+ std::to_string(device_index) + ": ")
+ exc.what());
return;
}
assert(j != nullptr);
auto instance_id = SDL_JoystickInstanceID(j->sdl_joystick());
AddSDLInputDevice_(j, instance_id);
}
@ -592,7 +601,7 @@ void AppAdapterSDL::RemoveSDLInputDevice_(int index) {
"GetSDLJoystickInput_() returned nullptr on RemoveSDLInputDevice_();"
" joysticks size is "
+ std::to_string(sdl_joysticks_.size()) + "; index is "
+ std::to_string(index));
+ std::to_string(index) + ".");
return;
}
@ -602,7 +611,7 @@ void AppAdapterSDL::RemoveSDLInputDevice_(int index) {
} else {
Log(LogLevel::kError, "Invalid index on RemoveSDLInputDevice: size is "
+ std::to_string(sdl_joysticks_.size())
+ "; index is " + std::to_string(index));
+ "; index is " + std::to_string(index) + ".");
}
g_base->input->PushRemoveInputDeviceCall(j, true);
}
@ -636,9 +645,9 @@ auto AppAdapterSDL::GetSDLJoystickInput_(const SDL_Event* e) const
auto AppAdapterSDL::GetSDLJoystickInput_(int sdl_joystick_id) const
-> JoystickInput* {
assert(g_core->InMainThread());
for (auto sdl_joystick : sdl_joysticks_) {
if ((sdl_joystick != nullptr) && (*sdl_joystick).sdl_joystick_id() >= 0
&& (*sdl_joystick).sdl_joystick_id() == sdl_joystick_id)
for (auto* sdl_joystick : sdl_joysticks_) {
if ((sdl_joystick != nullptr) && sdl_joystick->sdl_joystick_id() >= 0
&& sdl_joystick->sdl_joystick_id() == sdl_joystick_id)
return sdl_joystick;
}
return nullptr; // Epic fail.

View File

@ -46,7 +46,14 @@ auto InputDevice::GetPersistentIdentifier() const -> std::string {
return buffer;
}
InputDevice::~InputDevice() { assert(g_base->InLogicThread()); }
InputDevice::~InputDevice() {
// Once we've been added in the logic thread and given an index we
// should only be going down in the logic thread. If our constructor
// throws an exception its possible and valid to go down elsewhere.
if (index_ != -1) {
assert(g_base->InLogicThread());
}
}
// Called to let the current host/client-session know that we'd like to
// control something please.

View File

@ -13,6 +13,7 @@
#include "ballistica/base/ui/ui.h"
#include "ballistica/core/core.h"
#include "ballistica/shared/foundation/event_loop.h"
#include "ballistica/shared/foundation/macros.h"
#include "ballistica/shared/python/python.h"
#include "ballistica/shared/python/python_command.h"
@ -54,7 +55,13 @@ JoystickInput::JoystickInput(int sdl_joystick_id,
assert(g_core->InMainThread());
sdl_joystick_ = SDL_JoystickOpen(sdl_joystick_id);
assert(sdl_joystick_);
if (sdl_joystick_ == nullptr) {
auto* err = SDL_GetError();
if (!err) {
err = "Unknown SDL error.";
}
throw Exception(std::string("Error in SDL_JoystickOpen: ") + err + ".");
}
// In SDL2 we're passed a device-id but that's only used to open the
// joystick; events and most everything else use an instance ID, so we store

View File

@ -39,7 +39,7 @@ auto main(int argc, char** argv) -> int {
namespace ballistica {
// These are set automatically via script; don't modify them here.
const int kEngineBuildNumber = 22018;
const int kEngineBuildNumber = 22019;
const char* kEngineVersion = "1.7.37";
const int kEngineApiVersion = 9;

View File

@ -58,6 +58,15 @@ Exception::~Exception() { delete stack_trace_; }
auto Exception::what() const noexcept -> const char* {
// Return a nice pretty stack trace and other relevant info.
// Note: Design-wise it is a bit odd to have what() always return a stack
// trace. It would seem more reasonable and closer to how Python itself
// behaves to have what() simply give the exception message and have a
// separate method to extract the stack trace. However, in cases such as
// crash reports, what() often makes it into the reports and including the
// stack trace there is often useful, so we do things a bit backward;
// including the trace by default and having a separate method to get the
// message without it.
try {
// This call is const so we're technically not supposed to modify ourself,
// but a one-time flattening of our description into an internal buffer

View File

@ -262,6 +262,9 @@ enum class SpecialChar : uint8_t {
kLast // Sentinel
};
// NOTE: When adding exception types here, add a corresponding
// handler in Python::SetPythonException.
/// Python exception types we can raise from our own exceptions.
enum class PyExcType : uint8_t {
kRuntime,

View File

@ -15,23 +15,6 @@
namespace ballistica::ui_v1 {
// Color we mult toolbars by in medium and large ui modes (in small mode we
// keep them more the normal window color since everything overlaps).
#define TOOLBAR_COLOR_R 1.0f
#define TOOLBAR_COLOR_G 1.0f
#define TOOLBAR_COLOR_B 1.0f
// #define TOOLBAR_COLOR_R 0.75f
// #define TOOLBAR_COLOR_G 0.85f
// #define TOOLBAR_COLOR_B 0.85f
#define TOOLBAR_BACK_COLOR_R 1.0f
#define TOOLBAR_BACK_COLOR_G 1.0f
#define TOOLBAR_BACK_COLOR_B 1.0f
// Opacity in med/large.
#define TOOLBAR_OPACITY 1.0f
// Opacity in small.
#define TOOLBAR_OPACITY_2 1.0f
#define BOT_LEFT_COLOR_R 0.6
@ -175,24 +158,12 @@ auto RootWidget::AddCover_(float h_align, VAlign v_align, float x, float y,
bd.visibility_mask =
static_cast<uint32_t>(Widget::ToolbarVisibility::kMenuFullRoot);
// When the user specifies no backing it means they intend to cover the
// screen with a flat-ish window texture. However this only applies to
// phone-size; for other sizes we always draw a backing.
//
// UPDATE: We no longer do backings, so ignore that.
// if (g_base->ui->scale() != UIScale::kSmall) {
// bd.visibility_mask |=
// static_cast<uint32_t>(Widget::ToolbarVisibility::kMenuFull);
// }
Button* b = AddButton_(bd);
return b;
}
void RootWidget::AddMeter_(MeterType type, float h_align, float r, float g,
float b, bool plus, const std::string& s) {
// float yoffs = (g_base->ui->scale() == UIScale::kSmall) ? 0.0f : -7.0f;
float y_offs_small{7.0f};
float width = (type == MeterType::kTrophy) ? 80.0f : 110.0f;
@ -205,32 +176,16 @@ void RootWidget::AddMeter_(MeterType type, float h_align, float r, float g,
bd.v_align = VAlign::kTop;
bd.width = width;
bd.height = 36.0f;
// bd.x = x;
bd.y = -36.0f + 10.0f - y_offs_small;
bd.y_offs_small = y_offs_small;
bd.img = "uiAtlas2";
bd.mesh_transparent = "currencyMeter";
bd.selectable = true;
// bd.color_r = 0.32f;
// bd.color_g = 0.30f;
// bd.color_b = 0.4f;
bd.color_r = 0.4f;
bd.color_g = 0.38f;
bd.color_b = 0.5f;
// if (g_base->ui->scale() != UIScale::kSmall) {
// bd.color_r *= TOOLBAR_COLOR_R;
// bd.color_g *= TOOLBAR_COLOR_G;
// bd.color_b *= TOOLBAR_COLOR_B;
// }
// if (g_base->ui->scale() != UIScale::kSmall) {
// bd.color_r *= 2.0f;
// bd.color_g *= 2.0f;
// bd.color_b *= 2.0f;
// }
bd.depth_min = 0.3f;
bd.visibility_mask =
(static_cast<uint32_t>(Widget::ToolbarVisibility::kMenuFull)
@ -345,7 +300,6 @@ void RootWidget::AddMeter_(MeterType type, float h_align, float r, float g,
{
ImageDef imgd;
imgd.button = btn;
// id.x = 0.0f;
if (type == MeterType::kLevel || type == MeterType::kTrophy) {
imgd.x = -0.5 * width - 10.0f;
} else {
@ -393,76 +347,6 @@ void RootWidget::AddMeter_(MeterType type, float h_align, float r, float g,
}
}
}
// Icon on side.
{
// ButtonDef bd;
// bd.selectable = false;
// bd.h_align = h_align;
// bd.v_align = VAlign::kTop;
// bd.width = bd.height = 50.0f;
// if (type == MeterType::kLevel || type == MeterType::kTrophy) {
// bd.x = x - width * 0.5f - 10.0f;
// } else {
// bd.x = x + width * 0.5f + 10.0f;
// }
// bd.y = -32.0f + 7.0f + yoffs;
// bd.color_r = r;
// bd.color_g = g;
// bd.color_b = b;
// bd.depth_min = 0.3f;
// switch (type) {
// case MeterType::kLevel:
// bd.img = "levelIcon";
// bd.call = UIV1Python::ObjID::kRootUILevelIconPressCall;
// break;
// case MeterType::kTrophy:
// bd.img = "trophy";
// bd.call = UIV1Python::ObjID::kRootUITrophyMeterPressCall;
// break;
// case MeterType::kToken:
// bd.img = "coin";
// bd.call = UIV1Python::ObjID::kRootUITokensMeterPressCall;
// break;
// case MeterType::kTicket:
// bd.img = "tickets";
// bd.call = UIV1Python::ObjID::kRootUITicketIconPressCall;
// break;
// default:
// break;
// }
// bd.visibility_mask =
// (static_cast<uint32_t>(Widget::ToolbarVisibility::kMenuFull)
// | static_cast<uint32_t>(Widget::ToolbarVisibility::kMenuFullNoBack)
// | static_cast<uint32_t>(Widget::ToolbarVisibility::kMenuFullRoot));
// // Show some in store mode.
// if (type == MeterType::kLevel || type == MeterType::kTicket
// || type == MeterType::kToken) {
// bd.visibility_mask |=
// static_cast<uint32_t>(Widget::ToolbarVisibility::kMenuStore)
// |
// static_cast<uint32_t>(Widget::ToolbarVisibility::kMenuStoreNoBack);
// }
// // Show some in get-tokens mode.
// if (type == MeterType::kToken) {
// bd.visibility_mask |=
// static_cast<uint32_t>(Widget::ToolbarVisibility::kGetTokens);
// }
// Button* btn = AddButton_(bd);
// // Store certain ones.
// switch (type) {
// case MeterType::kLevel:
// level_icon_ = btn;
// break;
// case MeterType::kTrophy:
// trophy_icon_ = btn;
// break;
// break;
// default:
// break;
// }
}
// Plus button.
if (plus) {
@ -478,11 +362,6 @@ void RootWidget::AddMeter_(MeterType type, float h_align, float r, float g,
bd.color_r = 0.35f;
bd.color_g = 0.35f;
bd.color_b = 0.55f;
// if (g_base->ui->scale() != UIScale::kSmall) {
// bd.color_r *= TOOLBAR_COLOR_R;
// bd.color_g *= TOOLBAR_COLOR_G;
// bd.color_b *= TOOLBAR_COLOR_B;
// }
bd.depth_min = 0.3f;
switch (type) {
case MeterType::kTokens:
@ -529,8 +408,6 @@ void RootWidget::Setup() {
bd.color_r = 0.7f;
bd.color_g = 0.4f;
bd.color_b = 0.35f;
// bd.x = 40.0f;
bd.y = -40.0f;
bd.img = "nub";
bd.call = UIV1Python::ObjID::kRootUIBackButtonPressCall;
@ -559,57 +436,24 @@ void RootWidget::Setup() {
}
}
// Widen this a bit in small mode so it just covers most of the top
// - that looks funny in medium/large mode though
// if (g_ui->scale() == UIScale::kSmall) {
// AddCover(0.5f, VAlign::kTop, 0.0f, 320.0f,
// g_ui->scale() == UIScale::kSmall ? 1000.0f :
// 1000.0f, 800.0f, 0.4f);
// }
// if (c) {
// c->visibility_mask |=
// static_cast<uint32_t>(Widget::ToolbarVisibility::kMenuStore);
// }
// Top bar backing (currency only).
if (explicit_bool(false)) {
ButtonDef bd;
bd.h_align = 0.5f;
bd.v_align = VAlign::kTop;
bd.width = 370.0f;
// if (g_ui->scale() != UIScale::kSmall) {
// bd.width = 950.0f;
// }
bd.height = 90.0f;
bd.x = 256.0f;
bd.y = -20.0f;
bd.img = "uiAtlas2";
// if (g_ui->scale() != UIScale::kSmall) {
// bd.mesh_transparent = "toolbarBackingTop";
// } else {
bd.mesh_transparent = "toolbarBackingTop2";
// }
bd.selectable = false;
bd.color_r = 0.44f;
bd.color_g = 0.41f;
bd.color_b = 0.56f;
bd.opacity = 1.0f;
// if (g_ui->scale() != UIScale::kSmall) {
// bd.color_r *= TOOLBAR_COLOR_R;
// bd.color_g *= TOOLBAR_COLOR_G;
// bd.color_b *= TOOLBAR_COLOR_B;
// bd.opacity *= TOOLBAR_OPACITY;
// } else {
// bd.opacity *= TOOLBAR_OPACITY_2;
// }
bd.depth_min = 0.2f;
// bd.call = "";
bd.call = UIV1Python::ObjID::kEmptyCall;
// bd.visibility_mask =
// static_cast<uint32_t>(Widget::ToolbarVisibility::kMenuFullRoot);
// bd.visibility_mask |=
// static_cast<uint32_t>(Widget::ToolbarVisibility::kMenuFull);
bd.visibility_mask |=
static_cast<uint32_t>(Widget::ToolbarVisibility::kMenuStore);
AddButton_(bd);
@ -621,9 +465,6 @@ void RootWidget::Setup() {
bd.h_align = 0.5f;
bd.v_align = VAlign::kTop;
bd.width = 850.0f;
// if (g_base->ui->scale() != UIScale::kSmall) {
// bd.width = 850.0f;
// }
bd.height = 90.0f;
bd.x = 0.0f;
bd.y = -20.0f;
@ -634,14 +475,6 @@ void RootWidget::Setup() {
bd.color_g = 0.41f;
bd.color_b = 0.56f;
bd.opacity = 1.0f;
// if (g_base->ui->scale() != UIScale::kSmall) {
// bd.color_r *= TOOLBAR_COLOR_R * TOOLBAR_BACK_COLOR_R;
// bd.color_g *= TOOLBAR_COLOR_G * TOOLBAR_BACK_COLOR_G;
// bd.color_b *= TOOLBAR_COLOR_B * TOOLBAR_BACK_COLOR_B;
// bd.opacity *= TOOLBAR_OPACITY;
// } else {
// bd.opacity *= TOOLBAR_OPACITY_2;
// }
bd.depth_min = 0.2f;
// bd.call = "";
bd.call = UIV1Python::ObjID::kEmptyCall;
@ -649,14 +482,9 @@ void RootWidget::Setup() {
static_cast<uint32_t>(Widget::ToolbarVisibility::kMenuFullRoot);
bd.visibility_mask |=
static_cast<uint32_t>(Widget::ToolbarVisibility::kMenuFull);
// bd.visibility_mask |=
// static_cast<uint32_t>(Widget::ToolbarVisibility::kMenuStore);
AddButton_(bd);
}
// float xoffs = (g_base->ui->scale() == UIScale::kSmall) ? 90.0f : 0.0f;
// float yoffs = (g_base->ui->scale() == UIScale::kSmall) ? 0.0f : -10.0f;
// Account Button
{
ButtonDef bd;
@ -665,19 +493,12 @@ void RootWidget::Setup() {
bd.width = 160.0f;
bd.height = 60.0f;
bd.depth_min = 0.3f;
// bd.x = 110.0f + xoffs;
// bd.y = -24.0f + yoffs;
bd.y = -34.0f;
bd.y_offs_small = 10.0f;
bd.color_r = 0.56f;
bd.color_g = 0.5f;
bd.color_b = 0.73f;
bd.call = UIV1Python::ObjID::kRootUIAccountButtonPressCall;
// if (g_base->ui->scale() != UIScale::kSmall) {
// bd.color_r *= TOOLBAR_COLOR_R;
// bd.color_g *= TOOLBAR_COLOR_G;
// bd.color_b *= TOOLBAR_COLOR_B;
// }
bd.pre_buffer = 10.0f;
bd.visibility_mask =
(static_cast<uint32_t>(Widget::ToolbarVisibility::kMenuFull)
@ -704,30 +525,9 @@ void RootWidget::Setup() {
td.shadow = 1.0f;
AddText_(td);
}
// Clan.
// {
// TextDef td;
// td.button = b;
// td.y = -12.0f;
// td.width = bd.width * 0.9f;
// td.depth_min = 0.3f;
// td.text = "Clan Name";
// td.color_a = 0.6f;
// td.scale = 0.6f;
// td.flatness = 1.0f;
// td.shadow = 0.0f;
// AddText_(td);
// }
}
// float anchorx = 0.0f;
// float anchorx = (g_base->ui->scale() == UIScale::kSmall) ? 0.3f : 0.25f;
AddMeter_(MeterType::kLevel, 0.0f, 1.0f, 1.0f, 1.0f, false, "456/1000");
AddMeter_(MeterType::kTrophy, 0.0f, 1.0f, 1.0f, 1.0f, false, "#123");
// AddMeter(anchorx, 200.0f - 148.0f, 0, 1.0f, 1.0f, 1.0f, false, "456/1000");
// AddMeter(anchorx, 200.0f, 1, 1.0f, 1.0f, 1.0f, false, "123");
// Menu button (only shows up when we're not in a menu)
// FIXME - this should never be visible on TV or VR UI modes
@ -766,7 +566,6 @@ void RootWidget::Setup() {
b.h_align = 1.0f;
b.v_align = VAlign::kTop;
b.width = b.height = 70.0f;
// b.x = -110.0f;
b.y = b.height * -0.41f;
b.img = "usersButton";
b.call = UIV1Python::ObjID::kRootUISquadButtonPressCall;
@ -791,11 +590,6 @@ void RootWidget::Setup() {
AddMeter_(MeterType::kTokens, 1.0f, 1.0f, 1.0f, 1.0f, true, "123");
AddMeter_(MeterType::kTickets, 1.0f, 1.0f, 1.0f, 1.0f, false, "12345");
// Bot-left cover
// AddCover(0.0f, VAlign::kBottom, 0.0f, -210.0f, 600.0f, 600.0f, 0.25f);
// float bx = 55.0f;
// Inbox button.
{
ButtonDef b;
@ -819,8 +613,6 @@ void RootWidget::Setup() {
bottom_left_buttons_.push_back(inbox_button_);
}
// bx += 80.0f;
// Achievements button.
if (explicit_bool(true)) {
ButtonDef b;
@ -842,77 +634,11 @@ void RootWidget::Setup() {
b.allow_in_game = false;
achievements_button_ = AddButton_(b);
bottom_left_buttons_.push_back(achievements_button_);
// bx += 80.0f;
// Achievement count.
// {
// TextDef td;
// td.button = achievements_button_;
// td.width = 26.0f;
// td.text = "12/39";
// td.x = -1.5f;
// td.y = 8.0f;
// td.scale = 0.9f;
// td.flatness = 1.0f;
// td.shadow = 1.0f;
// td.depth_min = 0.3f;
// td.color_r = 1.0f;
// td.color_g = 1.0f;
// td.color_b = 1.0f;
// AddText_(td);
// }
auto centerx = -1.5f;
auto centery = 8.0f;
auto offsx = 5.5f;
auto offsy = 5.5f;
// {
// TextDef td;
// td.button = achievements_button_;
// td.width = 26.0f;
// td.text = "/";
// td.x = centerx;
// td.y = centery;
// td.scale = 0.3f;
// td.flatness = 1.0f;
// td.shadow = 1.0f;
// td.depth_min = 0.3f;
// td.color_r = 1.0f;
// td.color_g = 1.0f;
// td.color_b = 1.0f;
// AddText_(td);
// }
// {
// TextDef td;
// td.button = achievements_button_;
// td.width = 26.0f;
// td.text = "12";
// td.x = centerx - offsx;
// td.y = centery + offsy;
// td.scale = 0.4f;
// td.flatness = 1.0f;
// td.shadow = 1.0f;
// td.depth_min = 0.3f;
// td.color_r = 1.0f;
// td.color_g = 1.0f;
// td.color_b = 1.0f;
// AddText_(td);
// }
// {
// TextDef td;
// td.button = achievements_button_;
// td.width = 26.0f;
// td.text = "34";
// td.x = centerx + offsx;
// td.y = centery - offsy;
// td.scale = 0.4f;
// td.flatness = 1.0f;
// td.shadow = 1.0f;
// td.depth_min = 0.3f;
// td.color_r = 1.0f;
// td.color_g = 1.0f;
// td.color_b = 1.0f;
// AddText_(td);
// }
{
TextDef td;
td.button = achievements_button_;
@ -976,36 +702,19 @@ void RootWidget::Setup() {
// Chests.
{
// AddCover(0.5f, VAlign::kBottom, 0.0f, -180.0f, 600.0f, 550.0f,
// 0.35f);
float backing_r = 0.43f;
float backing_g = 0.40f;
float backing_b = 0.53f;
// float backingR = 0.44f;
// float backingG = 0.41f;
// float backingB = 0.56f;
float backing_cover_r = backing_r;
float backing_cover_g = backing_g;
float backing_cover_b = backing_b;
float backingA = 1.0f;
// if (g_base->ui->scale() != UIScale::kSmall) {
// backing_r *= TOOLBAR_COLOR_R * TOOLBAR_BACK_COLOR_R;
// backing_g *= TOOLBAR_COLOR_G * TOOLBAR_BACK_COLOR_G;
// backing_b *= TOOLBAR_COLOR_B * TOOLBAR_BACK_COLOR_B;
// backing_cover_r *= TOOLBAR_COLOR_R;
// backing_cover_g *= TOOLBAR_COLOR_G;
// backing_cover_b *= TOOLBAR_COLOR_B;
// backingA *= TOOLBAR_OPACITY;
// } else {
float backing_a = 1.0f;
backing_r *= 1.1f;
backing_g *= 1.1f;
backing_b *= 1.1f;
backing_cover_r *= 1.1f;
backing_cover_g *= 1.1f;
backing_cover_b *= 1.1f;
backingA *= TOOLBAR_OPACITY_2;
// }
// Bar backing.
{
@ -1022,10 +731,9 @@ void RootWidget::Setup() {
bd.color_r = backing_r;
bd.color_g = backing_g;
bd.color_b = backing_b;
bd.opacity = backingA;
bd.opacity = backing_a;
bd.depth_min = 0.2f;
// bd.call = "";
bd.call = UIV1Python::ObjID::kEmptyCall;
bd.visibility_mask =
(static_cast<uint32_t>(Widget::ToolbarVisibility::kMenuFull)
@ -1053,13 +761,6 @@ void RootWidget::Setup() {
b.allow_in_game = false;
AddButton_(b);
// b.x = -0.5f * spacing;
// b.img = "chestOpenIcon";
// b.y = b.height * 0.5f;
// b.call = UIV1Python::ObjID::kRootUIChestSlot2PressCall;
// AddButton_(b);
// test - empty icons
b.y = b.height * 0.4f;
b.x = 0.5f * spacing;
b.img = "chestIconEmpty";
@ -1077,32 +778,8 @@ void RootWidget::Setup() {
b.x = 1.5f * spacing;
b.call = UIV1Python::ObjID::kRootUIChestSlot4PressCall;
AddButton_(b);
// b.x = 2.0f * spacing;
// test - multi-icon tile
// b.img = "chestIconMulti";
// AddButton(b);
}
// bot-right cover
// AddCover(1.0f, VAlign::kBottom, 0.0f, -210.0f, 600.0f, 600.0f, 0.25f);
// // settings button
// {
// ButtonDef b;
// b.h_align = 1.0f;
// b.v_align = VAlign::kBottom;
// b.width = b.height = 50.0f;
// b.x = -225.0f;
// b.y = b.height * 0.5f + 10;
// b.img = "settingsIcon";
// b.visibility_mask =
// (static_cast<uint32_t>(Widget::ToolbarVisibility::kMenuFull)
// |
// static_cast<int>(Widget::ToolbarVisibility::kMenuFullRoot));
// AddButton(b);
// }
// Inventory button.
{
ButtonDef b;
@ -1309,8 +986,8 @@ void RootWidget::StepPositions_(float dt) {
bool enable_button =
static_cast<bool>(static_cast<uint32_t>(toolbar_visibility_)
& static_cast<uint32_t>(b.visibility_mask));
// When we're in the main menu, always disable the menu button and
// shift the party button a bit to the right
// When we're in the main menu, always disable the menu button and shift
// the party button a bit to the right
if (in_main_menu_) {
if (!b.allow_in_main_menu) {
enable_button = false;
@ -1323,12 +1000,6 @@ void RootWidget::StepPositions_(float dt) {
if (!b.allow_in_game) {
enable_button = false;
}
// Disallow most buttons in-game.
// if (&b == inbox_button_ || &b == achievements_button_
// || &b == account_button_ || &b == level_meter_button_
// || &b == trophy_meter_button_ || &b == store_button_ || &b == ) {
// enable_button = false;
// }
}
// Back button is always disabled in medium/large UI.
if (&b == back_button_ && !is_small) {
@ -1397,48 +1068,13 @@ void RootWidget::StepPositions_(float dt) {
b.y_target = b.y + (is_small ? b.y_offs_small : 0.0f);
float disable_offset = b.disable_offset_scale * 110.0f
* ((b.v_align == VAlign::kTop) ? 1.0f : -1.0f);
// float top_right_offset = 100.0f;
// Can turn this down to debug visibility.
if (explicit_bool(false)) {
disable_offset *= 0.1f;
// top_right_offset *= 0.5f;
}
// bool enable_button =
// static_cast<bool>(static_cast<uint32_t>(toolbar_visibility_)
// & static_cast<uint32_t>(b.visibility_mask));
// When the back button is hidden, move the account button to the left.
// bool move_left_for_back{};
// if (g_base->ui->scale() == UIScale::kSmall
// && !static_cast<bool>(
// static_cast<uint32_t>(toolbar_visibility_)
// & static_cast<uint32_t>(back_button_->visibility_mask))) {
// move_left_for_back = true;
// }
// if (move_left_for_back
// && (&b == account_button_ || &b == level_icon_
// || &b == level_meter_button_ || &b == trophy_icon_
// || &b == trophy_meter_button_)) {
// b.x_target -= 100.0f;
// }
// When we're in the main menu, always disable the menu button and
// shift the party button a bit to the right
if (in_main_menu_) {
// if (&b == menu_button_) {
// enable_button = false;
// }
// if (&b == squad_button_) {
// b.x_target += 70.0f;
// }
}
if (&b == back_button_) {
// Back button is always disabled in medium/large UI.
// if (g_base->ui->scale() != UIScale::kSmall) {
// enable_button = false;
// }
// Whenever back button is enabled, left on account button should go
// to it; otherwise it goes nowhere.
Widget* ab = account_button_->widget.Get();
@ -1451,17 +1087,6 @@ void RootWidget::StepPositions_(float dt) {
b.y_target += disable_offset;
}
// special case: we shift buttons on the top right to the right if the
// menu button is hidden (and also if the button is hidden; otherwise
// things come in diagonally)
//
// if (b.h_align == HAlign::kRight and b.v_align == VAlign::kTop
// if (b.h_align >= 1.0f and b.v_align == VAlign::kTop
// and (toolbar_visibility_ != ToolbarVisibility::kInGame or not
// enable_button)) {
// b.x_target += top_right_offset;
// }
// Now push our smooth value towards our target value.
b.x_smoothed += (b.x_target - b.x_smoothed) * 0.015f * dt;
b.y_smoothed += (b.y_target - b.y_smoothed) * 0.015f * dt;
@ -1553,18 +1178,6 @@ void RootWidget::UpdateLayout() {
break;
}
// TEST - cycle through our scales
if (explicit_bool(false)) {
auto foo = time(nullptr) % 3;
if (foo == 0) {
base_scale_ = 1.0f;
} else if (foo == 1) {
base_scale_ = 0.75f;
} else {
base_scale_ = 0.5f;
}
}
// Update the window stack.
BA_DEBUG_UI_READ_LOCK;
if (screen_stack_widget_ != nullptr) {