diff --git a/nx2navi.ini.example b/nx2navi.ini.example index a60402ea..7fe8d4e6 100644 --- a/nx2navi.ini.example +++ b/nx2navi.ini.example @@ -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. diff --git a/recomp/patches-v111.txt b/recomp/patches-v111.txt index 98b54a1a..2292999c 100644 --- a/recomp/patches-v111.txt +++ b/recomp/patches-v111.txt @@ -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 diff --git a/runtime/cfg.c b/runtime/cfg.c index 2605166f..557cdb95 100644 --- a/runtime/cfg.c +++ b/runtime/cfg.c @@ -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"},