Overhaul the VR menu UI: header, tabs, live video options, hover/click feedback, i18n, and dragging
build / build (push) Successful in 2m25s
build / build (push) Successful in 2m25s
- Header with title, git-tag-derived version, and a live FPS/frame-time/ CPU/GPU-utilization/free-memory stats ribbon below the tab bar (FPS via a new per-frame tracker in xr_session.c; CPU/GPU via the OpenXR XR_META_performance_metrics extension, gracefully unavailable on runtimes that don't support it) - Bottom tab bar with a live-editable Video Options tab (renderer/ resolution), applying changes immediately via qs_config.c - Hover and press feedback on every menu/keyboard button via a StateListDrawable (Android's default ripple never animates on this permanently unattached view tree), with a lighter default button color for visibility - i18n for all menu/keyboard chrome text, following the game's own language setting (Strings.java) - The main menu is now draggable via its header, matching the keyboard; xr_input.c's drag handling is generalized to per-overlay state instead of being keyboard-only - The keyboard's title bar now matches the menu header's style
This commit is contained in:
@@ -442,6 +442,21 @@ static const char *qs_current_resolution(void) {
|
||||
return "640x480"; // shouldn't happen - safe fallback for Save
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
// Read-only queries for the Video Options tab (see qs_config.h)
|
||||
// ===========================================================================
|
||||
|
||||
bool qs_config_current_renderer_is_opengl(void) { return gShockPrefs.doUseOpenGL; }
|
||||
|
||||
int qs_config_current_resolution_index(void) {
|
||||
for (size_t i = 0; i < QS_NUM_RESOLUTIONS; i++)
|
||||
if (kResolutions[i].mode == mode_id)
|
||||
return (int)i;
|
||||
return 3; // shouldn't happen - 640x480, matches qs_current_resolution()'s own fallback
|
||||
}
|
||||
|
||||
int qs_config_current_language(void) { return gShockPrefs.goLanguage; }
|
||||
|
||||
// ===========================================================================
|
||||
// Apply / Save orchestration
|
||||
// ===========================================================================
|
||||
@@ -557,16 +572,21 @@ static void qs_show_restart_dialog(const char *restart_needed) {
|
||||
|
||||
static Uint32 s_save_event_type;
|
||||
static Uint32 s_load_event_type;
|
||||
static Uint32 s_set_renderer_event_type;
|
||||
static Uint32 s_set_resolution_event_type;
|
||||
|
||||
void qs_config_load_startup(void) {
|
||||
// Registers the custom SDL event types qs_config_request_save()/_load()
|
||||
// enqueue - done here, once, on the engine's own thread and before the
|
||||
// menu/its buttons could possibly exist yet, rather than lazily from
|
||||
// those functions themselves (which run on Android's UI thread and
|
||||
// could otherwise race each other doing this lazily).
|
||||
Uint32 base = SDL_RegisterEvents(2);
|
||||
// Registers the custom SDL event types qs_config_request_save()/_load()/
|
||||
// _set_renderer()/_set_resolution() enqueue - done here, once, on the
|
||||
// engine's own thread and before the menu/its buttons could possibly
|
||||
// exist yet, rather than lazily from those functions themselves (which
|
||||
// run on Android's UI thread and could otherwise race each other doing
|
||||
// this lazily).
|
||||
Uint32 base = SDL_RegisterEvents(4);
|
||||
s_save_event_type = base;
|
||||
s_load_event_type = base + 1;
|
||||
s_set_renderer_event_type = base + 2;
|
||||
s_set_resolution_event_type = base + 3;
|
||||
|
||||
QsParsedConfig parsed;
|
||||
if (qs_config_read_file(&parsed))
|
||||
@@ -587,6 +607,22 @@ void qs_config_request_load(void) {
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
|
||||
void qs_config_request_set_renderer(bool opengl) {
|
||||
SDL_Event event;
|
||||
SDL_zero(event);
|
||||
event.type = s_set_renderer_event_type;
|
||||
event.user.code = opengl ? 1 : 0;
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
|
||||
void qs_config_request_set_resolution(int resolution_index) {
|
||||
SDL_Event event;
|
||||
SDL_zero(event);
|
||||
event.type = s_set_resolution_event_type;
|
||||
event.user.code = resolution_index;
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
|
||||
bool qs_config_handle_event(const SDL_Event *event) {
|
||||
if (event->type == s_save_event_type) {
|
||||
if (qs_config_write_file())
|
||||
@@ -609,5 +645,15 @@ bool qs_config_handle_event(const SDL_Event *event) {
|
||||
message_info("Configuration loaded");
|
||||
return true;
|
||||
}
|
||||
if (event->type == s_set_renderer_event_type) {
|
||||
qs_apply_renderer(event->user.code ? "opengl" : "software", /*live=*/true);
|
||||
return true;
|
||||
}
|
||||
if (event->type == s_set_resolution_event_type) {
|
||||
int index = event->user.code;
|
||||
if (index >= 0 && (size_t)index < QS_NUM_RESOLUTIONS)
|
||||
qs_apply_resolution(kResolutions[index].name, /*live=*/true);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user