Files
NX2navi/runtime/debug_tools.h
epicmeme546 5a69bdc91f Add a debug menu for testing Ocarina of Time: the game's flags by name, the game's speed, and a memory search, on F9.
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>
2026-11-11 06:19:47 -05:00

44 lines
2.0 KiB
C

// The debug menu's access to the game (debug_tools.c). Everything but dbg_tick is for the menu's thread.
#pragma once
#include <stdint.h>
#ifndef __cplusplus
#include "cpu.h"
void dbg_tick(Cpu *c); // the game's thread, at its pad read (ov_input.c): does what the menu asked for
#endif
#ifdef __cplusplus
extern "C" {
#endif
int dbg_supported(void); // this game build's structures are known (Ocarina of Time 1.1.1)
int dbg_player_pos(float xyz[3]); // Link's position in metres; 0 while there is no player
float dbg_speed_factor(void); // the game's speed: 1 normal, 0.05 to 8 (frame_rate.c multiplies the game's step)
void dbg_speed_set(float factor);
// The game's on/off flags, sorted by hash. dbg_flags_refresh reads their values and returns their number (0 until a
// save is loaded). A change is made by the game's own function at the next frame.
int dbg_flags_refresh(void);
uint32_t dbg_flag_hash(int i);
int dbg_flag_value(int i);
const char *dbg_flag_name(int i); // NULL: no name found for it
void dbg_flag_set(uint32_t hash, int on);
int dbg_names(int *found); // 0 not started, 1 being read from the game's files, 2 read (*found of them)
// Memory: values of 1, 2 or 4 bytes in the game's heap.
int dbg_search_new(uint32_t value, int size); // returns the number of places
int dbg_search_next(int mode, uint32_t value); // 0 equals value, 1 changed, 2 unchanged, 3 greater, 4 less
int dbg_search_count(int *over); // *over: the first search found more than are kept
uint64_t dbg_search_addr(int i);
int dbg_search_size(void);
void dbg_search_clear(void);
int dbg_mem_read(uint64_t addr, int size, uint32_t *v);
void dbg_mem_write(uint64_t addr, uint64_t value, int size);
int dbg_freeze(uint64_t addr, uint64_t value, int size, int on); // written every frame while on; 0: the list is full
int dbg_frozen(uint64_t addr);
int dbg_frozen_count(void);
void dbg_unfreeze_all(void);
#ifdef __cplusplus
}
#endif