mirror of
https://github.com/tangerineturtle1/NX2navi.git
synced 2026-11-15 19:19:58 -04:00
With debug_menu = 1 (off by default; the Game tab has the switch) F9 opens a panel on the left edge in the performance overlay's look, with the game in view beside it. ui/menu.cpp lays it out in the settings menu's place, so its input and the game's blocked pad are the menu's own. Typed characters now reach the menu for its text fields. Flags: the game's 11,292 on/off flags are read from its game data manager, and a click changes one through the game's own function on the game's thread at its pad read (runtime/debug_tools.c dbg_tick), so the game applies it at its next update as it does its own changes. The game knows a flag by the hash of its name only; the names shown are found in the player's own event flow files, hashed and matched when the panel first opens (2,250 of them from 915 files in 0.2 s), and none is kept in the code. World: Link's position, and a speed factor from 0.05 to 8 that multiplies the step the runtime gives the game each frame (measured 0.50 at 0.5x). Memory: a search of the heap for a value of 1, 2 or 4 bytes or a float (about 2 s), narrowed by equals, changed, unchanged, went up or went down, with a value to set at a place or to hold there every frame. Tested through the window's own messages: F9 opened it, a click on a flag set that flag in the game, text typed into the filter narrowed the list, and F9 closed it; a scripted run set and held a value and put it back. Teleporting, a free camera and starting cutscenes are not in it: writing Link's position, or every copy of it in the heap, moved him back within three frames, so they need the game's own warp, scene-change and event functions. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
89 lines
4.0 KiB
C++
89 lines
4.0 KiB
C++
// SDL3 adapter of the in-game menu: the window's events to menu events (menu.h), as ui/menu_win.cpp does for Win32.
|
|
// Window thread (gfx_window_sdl.c's event loop, after input_sdl_event).
|
|
//
|
|
// F1 opens and closes the menu, Esc opens it (with the menu open, Esc goes to the menu, which closes). Esc also releases
|
|
// the cursor (input_sdl.c sees the event first; closing the menu gives the capture back). While the menu is open, its
|
|
// keys, the mouse and focus changes go to it; the game reads the keyboard through input_sdl.c and gets nothing while
|
|
// the menu is open (input_menu). Mouse positions come in window units and go to the menu in pixels.
|
|
#include <SDL3/SDL.h>
|
|
|
|
#include "imgui.h"
|
|
|
|
extern "C" {
|
|
#include "input.h"
|
|
#include "input_sdl.h"
|
|
#include "ui/menu.h"
|
|
}
|
|
|
|
static ImGuiKey key_of(SDL_Scancode sc) {
|
|
switch (sc) {
|
|
case SDL_SCANCODE_UP: return ImGuiKey_UpArrow;
|
|
case SDL_SCANCODE_DOWN: return ImGuiKey_DownArrow;
|
|
case SDL_SCANCODE_LEFT: return ImGuiKey_LeftArrow;
|
|
case SDL_SCANCODE_RIGHT: return ImGuiKey_RightArrow;
|
|
case SDL_SCANCODE_RETURN: case SDL_SCANCODE_KP_ENTER: return ImGuiKey_Enter;
|
|
case SDL_SCANCODE_SPACE: return ImGuiKey_Space;
|
|
case SDL_SCANCODE_ESCAPE: return ImGuiKey_Escape;
|
|
case SDL_SCANCODE_TAB: return ImGuiKey_Tab;
|
|
case SDL_SCANCODE_BACKSPACE: return ImGuiKey_Backspace;
|
|
case SDL_SCANCODE_DELETE: return ImGuiKey_Delete; // clears a cell of the remapping rows
|
|
case SDL_SCANCODE_HOME: return ImGuiKey_Home;
|
|
case SDL_SCANCODE_END: return ImGuiKey_End;
|
|
case SDL_SCANCODE_PAGEUP: return ImGuiKey_PageUp;
|
|
case SDL_SCANCODE_PAGEDOWN: return ImGuiKey_PageDown;
|
|
case SDL_SCANCODE_LSHIFT: case SDL_SCANCODE_RSHIFT: return ImGuiKey_LeftShift;
|
|
case SDL_SCANCODE_LCTRL: case SDL_SCANCODE_RCTRL: return ImGuiKey_LeftCtrl;
|
|
case SDL_SCANCODE_Q: return ImGuiKey_Q; // previous tab
|
|
case SDL_SCANCODE_E: return ImGuiKey_E; // next tab
|
|
default: return ImGuiKey_None;
|
|
}
|
|
}
|
|
|
|
extern "C" void menu_sdl_event(const SDL_Event *e) {
|
|
float d = (float)gfx_window_sdl_density();
|
|
switch (e->type) {
|
|
case SDL_EVENT_KEY_DOWN:
|
|
// Esc with the menu open (opened by F1 too) is not a toggle here: it goes to the menu, which closes itself
|
|
if (!e->key.repeat && (e->key.scancode == SDL_SCANCODE_F1 ||
|
|
(e->key.scancode == SDL_SCANCODE_ESCAPE && !menu_is_open()))) {
|
|
menu_toggle();
|
|
return;
|
|
}
|
|
if (e->key.scancode == SDL_SCANCODE_F9 && menu_debug_enabled()) { // the debug menu, while its setting is on
|
|
if (!e->key.repeat) menu_debug_toggle();
|
|
return;
|
|
}
|
|
if (e->key.scancode == SDL_SCANCODE_F10) {
|
|
if (!e->key.repeat) menu_perf_cycle();
|
|
return;
|
|
}
|
|
// a held Esc's repeats: the press that opened the menu is not queued, so its first repeat would close it
|
|
if (e->key.scancode == SDL_SCANCODE_ESCAPE && e->key.repeat) return;
|
|
[[fallthrough]];
|
|
case SDL_EVENT_KEY_UP:
|
|
if (!menu_is_open()) return;
|
|
if (ImGuiKey k = key_of(e->key.scancode)) menu_event_key(k, e->type == SDL_EVENT_KEY_DOWN);
|
|
return;
|
|
case SDL_EVENT_MOUSE_MOTION:
|
|
if (menu_is_open()) menu_event_mouse_pos(e->motion.x * d, e->motion.y * d);
|
|
return;
|
|
case SDL_EVENT_MOUSE_BUTTON_DOWN:
|
|
case SDL_EVENT_MOUSE_BUTTON_UP: {
|
|
if (!menu_is_open()) return;
|
|
int b = e->button.button == SDL_BUTTON_LEFT ? 0 : e->button.button == SDL_BUTTON_RIGHT ? 1
|
|
: e->button.button == SDL_BUTTON_MIDDLE ? 2 : -1;
|
|
if (b < 0) return;
|
|
menu_event_mouse_pos(e->button.x * d, e->button.y * d);
|
|
menu_event_mouse_button(b, e->type == SDL_EVENT_MOUSE_BUTTON_DOWN);
|
|
return;
|
|
}
|
|
case SDL_EVENT_MOUSE_WHEEL:
|
|
if (menu_is_open()) menu_event_wheel(e->wheel.x, e->wheel.y);
|
|
return;
|
|
case SDL_EVENT_WINDOW_FOCUS_GAINED:
|
|
case SDL_EVENT_WINDOW_FOCUS_LOST:
|
|
menu_event_focus(e->type == SDL_EVENT_WINDOW_FOCUS_GAINED);
|
|
return;
|
|
}
|
|
}
|