mirror of
https://github.com/valentderah/totk-pc-recomp.git
synced 2026-11-11 01:41:02 +00:00
Swap a mod's HeapDef for the game's own only when that table grows TextureHeap
heapdef_overlay replaced the served mod table whenever any switched-on mod grew the texture heap. With an HD pack and another mod that ships a HeapDef for other heaps on top of it, the other mod's sizes were lost. It now checks the served table itself (resolution.c res_heapdef_tex_grown): only a table with TextureHeap over the shipped size is swapped, any other stays the base and gets the growth on top. A mod HeapDef the port cannot read no longer logs "TextureHeap 0 KiB": the failure is logged with the mod's name. read_original sat between read_served and its comment; each function has its own comment again. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
caf53eb764
commit
df9ba65a91
3 files changed
+38
-21
No files matched your search
+2
-1
@@ -262,7 +262,8 @@ uint64_t res_heap_extra_bytes(void); // added to the appli
|
||||
uint64_t res_heap_extra_kib(void); // added to the HeapDef texture heap and its parent; 0 = none
|
||||
uint64_t res_tex_heap_extra_bytes(void); // TOTK_TEX_HEAP_EXTRA_MB: added to the application pool and
|
||||
// the heap cap (mem_init), 2 MiB steps; 0 = none
|
||||
int res_tex_heap_from_mod(void); // a switched-on mod's HeapDef grows the texture heap
|
||||
int res_heapdef_tex_grown(const void *in, size_t n); // the HeapDef table (.byml.zs) grows TextureHeap over the
|
||||
// shipped size (an HD texture pack's)
|
||||
int res_heapdef_build(const void *in, size_t n, void **out, size_t *out_n); // the HeapDef table (.byml.zs) with
|
||||
// the grown heaps, malloc'd; 0 = cannot (logged)
|
||||
void res_heapdef_served(void); // romfs.c serves the grown table
|
||||
|
||||
+24
-11
@@ -293,22 +293,31 @@ static int heapdef_open(const void *in, size_t n, Byml *b, uint32_t *heaps, cons
|
||||
#define HEAPDEF_REL "System/HeapSize/Product.Nin_NX_NVN.HeapDef.byml.zs"
|
||||
static struct { int done; uint64_t kib; } MT;
|
||||
|
||||
static void mod_heapdef(const char *name, const char *romfs, void *ctx) {
|
||||
(void)ctx;
|
||||
char path[2300];
|
||||
if (snprintf(path, sizeof path, "%s/%s", romfs, HEAPDEF_REL) >= (int)sizeof path) return;
|
||||
uint64_t n = 0;
|
||||
uint8_t *in = plat_file_read(path, &n);
|
||||
if (!in) return;
|
||||
// "TextureHeap" of the HeapDef table in[0..n) in KiB; 0 when the table cannot be read or has no such size (the failure
|
||||
// is logged with why).
|
||||
static int32_t heapdef_tex_kib(const void *in, size_t n, const char *why) {
|
||||
Byml b;
|
||||
uint32_t heaps;
|
||||
size_t th_at = 0;
|
||||
int32_t th = 0;
|
||||
if (heapdef_open(in, (size_t)n, &b, &heaps, "its texture heap is left out") &&
|
||||
(th_at = heap_size_field(&b, heaps, "TextureHeap")))
|
||||
memcpy(&th, b.p + th_at, 4);
|
||||
if (!heapdef_open(in, n, &b, &heaps, why)) return 0;
|
||||
if ((th_at = heap_size_field(&b, heaps, "TextureHeap"))) memcpy(&th, b.p + th_at, 4);
|
||||
else rt_log("resolution: the HeapDef table has no TextureHeap size; %s", why);
|
||||
free(b.p);
|
||||
return th;
|
||||
}
|
||||
|
||||
static void mod_heapdef(const char *name, const char *romfs, void *ctx) {
|
||||
(void)ctx;
|
||||
char path[2300], why[400];
|
||||
if (snprintf(path, sizeof path, "%s/%s", romfs, HEAPDEF_REL) >= (int)sizeof path) return;
|
||||
uint64_t n = 0;
|
||||
uint8_t *in = plat_file_read(path, &n);
|
||||
if (!in) return;
|
||||
snprintf(why, sizeof why, "mod %s: its texture heap growth is left out", name);
|
||||
int32_t th = heapdef_tex_kib(in, (size_t)n, why);
|
||||
free(in);
|
||||
if (!th) return;
|
||||
int64_t grow = (int64_t)th - (int64_t)TEX_HEAP_KIB;
|
||||
if (grow > (int64_t)(4096u << 10)) grow = 4096u << 10;
|
||||
if (grow > 0 && (uint64_t)grow > MT.kib) MT.kib = (uint64_t)grow;
|
||||
@@ -321,7 +330,11 @@ static uint64_t mod_tex_heap_kib(void) {
|
||||
return MT.kib;
|
||||
}
|
||||
|
||||
int res_tex_heap_from_mod(void) { return mod_tex_heap_kib() > 0; }
|
||||
// Only such a table is swapped for the game's own (romfs.c heapdef_overlay): a mod table that changes other heaps
|
||||
// keeps them. A table it cannot read stays the base (logged).
|
||||
int res_heapdef_tex_grown(const void *in, size_t n) {
|
||||
return heapdef_tex_kib(in, n, "the mod's table stays the base") > (int32_t)TEX_HEAP_KIB;
|
||||
}
|
||||
|
||||
int res_heapdef_build(const void *in, size_t n, void **out, size_t *out_n) {
|
||||
uint64_t extra = res_heap_extra_kib(), tex = tex_heap_extra_kib();
|
||||
|
||||
+12
-9
@@ -533,9 +533,8 @@ static void added_init(void) {
|
||||
rt_log("RomFS overlay: %zu files added to the RomFS", nadded);
|
||||
}
|
||||
|
||||
// RomFS file `rel` as the game would read it: from an overlay that replaces it (*base), else from the image. malloc'd;
|
||||
// NULL when it is missing, unreadable or 16 MiB or more (logged with `keeps`, what the game does without it).
|
||||
// RomFS file rel as the RomFS holds it, whatever overlays replace it; NULL (logged) when it cannot be read.
|
||||
// RomFS file `rel` as the image holds it, whatever overlays replace it. malloc'd; NULL when it is missing, unreadable
|
||||
// or 16 MiB or more (logged with `keeps`, what the game does without it).
|
||||
static void *read_original(const char *rel, size_t *n, const char *keeps) {
|
||||
uint64_t i = lower(rel);
|
||||
if (i >= file_count || strcmp(entry_name(entry(i)), rel)) return NULL;
|
||||
@@ -550,6 +549,8 @@ static void *read_original(const char *rel, size_t *n, const char *keeps) {
|
||||
return in;
|
||||
}
|
||||
|
||||
// RomFS file `rel` as the game would read it: from an overlay that replaces it (*base), else from the image. malloc'd;
|
||||
// NULL when it is missing, unreadable or 16 MiB or more (logged with `keeps`, what the game does without it).
|
||||
static void *read_served(const char *rel, Overlay **base, size_t *n, const char *keeps) {
|
||||
uint64_t i = lower(rel);
|
||||
*base = NULL;
|
||||
@@ -846,9 +847,10 @@ static void restbl_overlay(void) {
|
||||
|
||||
// The HeapDef table a bigger game resolution or TOTK_TEX_HEAP_EXTRA_MB needs (resolution.c): its texture heaps and
|
||||
// their parents grow. The base is an overlay that replaces the table (a mod's heap sizes stay), else the RomFS
|
||||
// original; the grown table is written to <profile>/resolution/ and served in the base's place. A mod's table whose
|
||||
// texture heap is grown (an HD texture pack's, resolution.c mod_tex_heap_kib) is not the base: that growth is already
|
||||
// in the amount, so the RomFS original grows by it and is served in the mod's place.
|
||||
// original; the grown table is written to <profile>/resolution/ and served in the base's place. A served mod table
|
||||
// whose own TextureHeap is grown (an HD texture pack's, resolution.c res_heapdef_tex_grown) is not the base: its
|
||||
// growth is already in the amount (resolution.c mod_tex_heap_kib), so the RomFS original grows by it and is served in
|
||||
// the mod's place. A mod table that changes other heaps only stays the base.
|
||||
#define HEAPDEF "System/HeapSize/Product.Nin_NX_NVN.HeapDef.byml.zs"
|
||||
static void heapdef_overlay(void) {
|
||||
if (!res_heap_extra_kib() && !res_tex_heap_extra_bytes()) return;
|
||||
@@ -857,11 +859,12 @@ static void heapdef_overlay(void) {
|
||||
size_t n;
|
||||
void *in = read_served(HEAPDEF, &base, &n, keeps), *out = NULL;
|
||||
size_t out_n = 0;
|
||||
if (in && base && base->mod && res_tex_heap_from_mod()) {
|
||||
if (in && base && base->mod && res_heapdef_tex_grown(in, n)) {
|
||||
free(in);
|
||||
in = read_original(HEAPDEF, &n, keeps);
|
||||
rt_log("RomFS: %s: the game's own HeapDef with the mod's texture heap growth in place of the mod's table",
|
||||
mods_at(base->mod - 1)->name);
|
||||
if (in)
|
||||
rt_log("RomFS: %s: the game's own HeapDef with the mod's texture heap growth in place of the mod's table",
|
||||
mods_at(base->mod - 1)->name);
|
||||
}
|
||||
int ok = in && res_heapdef_build(in, n, &out, &out_n);
|
||||
free(in);
|
||||
|
||||
Reference in new issue
Block a user