Let the pick-up window's number count at least one a frame, so the window closes above 60 fps.

The window that shows a pick-up above the character counts its number up to the new total by a whole step a frame and closes once they are equal. The game rounds that step down, and below one 60 Hz frame per update it was 0: above 60 fps the window stayed until the area was left, and for larger amounts the counting sound was started again every frame. The step is now floored at 1, switchable with pickup_count.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
This commit is contained in:
chrg6
2026-11-10 13:10:34 -05:00
parent 5988871aba
commit 0a502ecf65
3 changed files with 17 additions and 2 deletions

View File

@@ -40,6 +40,10 @@
# in a frame shorter than 1/240 s, so things standing on moving platforms were left behind. 1 rounds the step count
# up instead; 0 is the game's own count.
# physics_steps = 1
# The number in the window that shows a pick-up (a rupee) counts up by whole steps a frame, and above 60 fps the game
# rounded that step down to nothing: the window stayed until the area was left and its counting sound went on. 1 lets
# it count at least one a frame; 0 is the game's own count.
# pickup_count = 1
# The step the game is given each frame: 1 keeps it steady (the same value from frame to frame while the frame rate
# holds, exactly one 60 Hz frame at a 60 fps limit) and makes up for a late frame over the next second; 0 is the mean
# of the last five frame times, which changes with every frame.

View File

@@ -19,6 +19,7 @@ set res_fixed NX2NAVI_PATCH_RES_FIXED 0
set ostep NX2NAVI_OCARINA_REALTIME 1
set zstd NX2NAVI_ZSTD_NATIVE 1
set osolver NX2NAVI_PHYSICS_STEPS 1
set opickup NX2NAVI_PICKUP_COUNT 1
# Real-time step: the framework's per-frame update (main+0x6e6be0) gives the time manager **[main+0x4c7e890] its
# nominal frame through main+0x3b4e300 (+0x10 frames per update, +0x14 the inverse, +0x18 seconds, +0x1c the rate),
@@ -48,6 +49,16 @@ site osolver main 38afd10 bd440d02 1e2a1002 # the same three words in the seco
site osolver main 38afd1c 1f010800 1f218800
site osolver main 38afd20 1e380001 1e280001
# Pick-up window count: the window that shows a pick-up above the character (its update is main+0xa67e50) moves the
# number it shows (+0x360) to the new total (+0x35c) by trunc(frames per update * max(1, difference / 50)) a frame, and
# closes only once the two are equal. Below one frame per update that is 0: above 60 fps, and at 60 while the step runs
# a little under one frame, the count never ends, so the window stayed until the area was left, and for an amount over
# 9 the counting sound was started again every frame and its closing sound never came. The increment is floored at 1
# without the flags (clz is 32 only for 0, so increment += clz >> 5); at one and two frames per update it is what the
# game computes. Above 60 fps a small amount then counts one a rendered frame, faster than at 60. w13 held the time
# manager, last read at main+0xa682ec, and every path from the site reaches a call before it reads x13 again.
site opickup main a68300 1e38000c 1e38000c 5ac0118d 53057dad 0b0d018c # fcvtzs w12, s0; clz w13, w12; lsr w13, w13, #5; add w12, w12, w13
# Game image: the graphics setup (main+0x1202ce0) fills the renderer's configuration with the size of the picture the
# game presents, 2560x1440 at every console mode (config +0x14, copied to renderer +0x9c, which main+0x346be50 reads
# for the main render target set, main+0xf49040), and the display settings object (main+0x31f3890) stores the same size

View File

@@ -31,7 +31,7 @@ static int save_ok = 1; // the last cfg_save_to wrote (o
// Every name the runtime reads (and the patch sets in generated/), without the prefix. A file key outside this list is
// logged as unknown. A new variable goes here too, or its ini key logs a harmless "unknown key" line.
static const char *const known[] = {
"CORES", "TM_DISPATCH", "NVN2_CS_TABLE", "SKIP_SHADERS", "MOVIE_DEBAND", "MOVIE_FPS", "MOVIE_SKIP", "MOVIE_OVERLAY", "MOVIES", "NPLN", "NVN2_PROGRAMS", "NVN_TRAP", "OCARINA_REALTIME", "ONESHOT_BUDGET", "ONESHOT_WAIT_MS", "OCARINA_STEP", "PHYSICS_STEPS", "STEP_STEADY", "VI_HZ", "VI_VRR", "TIME_DUMP", "SHADER_DUMP", "SHOT_AFTER", "SHOT_DIR", "SHOT_EVERY", // Switch 2 port: movie skip (romfs.c), NVN2 proc traps (nvn_procs.c)
"CORES", "TM_DISPATCH", "NVN2_CS_TABLE", "SKIP_SHADERS", "MOVIE_DEBAND", "MOVIE_FPS", "MOVIE_SKIP", "MOVIE_OVERLAY", "MOVIES", "NPLN", "NVN2_PROGRAMS", "NVN_TRAP", "OCARINA_REALTIME", "ONESHOT_BUDGET", "ONESHOT_WAIT_MS", "OCARINA_STEP", "PHYSICS_STEPS", "PICKUP_COUNT", "STEP_STEADY", "VI_HZ", "VI_VRR", "TIME_DUMP", "SHADER_DUMP", "SHOT_AFTER", "SHOT_DIR", "SHOT_EVERY", // Switch 2 port: movie skip (romfs.c), NVN2 proc traps (nvn_procs.c)
"AB", "AMIIBO_DIR", "ANISO", "APP_POOL", "ASPECT", "ASPECT_PATCH", "ASSUME_FOCUS", "ASTC", "ASTC_BC", "ASTC_TIME", "ASYNC_PREEMPT", "AUDIO", "AUDIO_CHANNELS", "AUDIO_DEVICE", "AUDIO_GAME_PRIO", "AUDIO_OFF", "AUDIO_PREFILL_MS", "AUDIO_STATS",
"BACKGROUND_WINDOW", "BIND_A", "BIND_B", "BIND_DOWN", "BIND_L", "BIND_LCLICK", "BIND_LEFT", "BIND_LSTICK_DOWN", "BIND_LSTICK_LEFT",
"BIND_LSTICK_RIGHT", "BIND_LSTICK_UP", "BIND_MINUS",
@@ -76,7 +76,7 @@ static const char *const known[] = {
static const struct { const char *key, *section; } sections[] = {
{"FPS_LIMIT", "frame rate"}, {"FPS60", "frame rate"}, {"RTSS", "frame rate"},
{"REALTIME", "frame rate"}, {"CLOTH_REALTIME", "frame rate"}, {"HIGHFPS_FIX", "frame rate"},
{"PHYSICS_STEPS", "frame rate"}, {"STEP_STEADY", "frame rate"},
{"PHYSICS_STEPS", "frame rate"}, {"PICKUP_COUNT", "frame rate"}, {"STEP_STEADY", "frame rate"},
{"FULLSCREEN", "display"}, {"WINDOW_SIZE", "display"}, {"PERF_OVERLAY", "display"}, {"VK_PRESENT", "display"},
{"GPU_INDEX", "display"}, {"MONITOR", "display"}, {"OUTPUT_RES", "display"}, {"GAME_ASPECT", "display"}, {"GAME_RES", "display"}, {"RENDER_SCALE", "display"}, {"UPSCALER", "display"},
{"SHARPNESS", "display"}, {"ASPECT", "display"}, {"FOV", "display"}, {"ANISO", "display"},