Resource system: Difference between revisions

Added BFRES resource size estimation and analysis.
imported>Leoetlino
No edit summary
imported>Ginger
(Added BFRES resource size estimation and analysis.)
Line 21: Line 21:


Note that:
Note that:
* For ResourceLoadArg3 (used in model/bfres related code), the factory is hardcoded to be the ResourceBase factory.
* For ResourceLoadArg3 (used in model/bfres related code), the factory is hardcoded to be the ResourceBase factory.
* For ResourceLoadArg2 (used for actor resources and physics stuff) and ResourceLoadArg (everything else), the factory is determined from the file extension.
* For ResourceLoadArg2 (used for actor resources and physics stuff) and ResourceLoadArg (everything else), the factory is determined from the file extension.
Line 54: Line 55:
==== Cases where the AoC file device is used ====
==== Cases where the AoC file device is used ====
If the AoC version is >= 0x200 (in most cases) or >= 0x300 (for DLC Pack 2 content), and if the canonical resource name (without the <code>Aoc/0010/</code> prefix) matches any of the below patterns:
If the AoC version is >= 0x200 (in most cases) or >= 0x300 (for DLC Pack 2 content), and if the canonical resource name (without the <code>Aoc/0010/</code> prefix) matches any of the below patterns:
* <code>Terrain/A/AocField*</code>
* <code>Terrain/A/AocField*</code>
* Any dungeon pack (<code>Pack/%s.pack</code>): shrines, divine beasts, Final Trial (for shrines, the dungeon number must be > 119)
* Any dungeon pack (<code>Pack/%s.pack</code>): shrines, divine beasts, Final Trial (for shrines, the dungeon number must be > 119)
Line 72: Line 74:
* <code>Voice/*/Stream_Demo6*/*.bfstm</code>
* <code>Voice/*/Stream_Demo6*/*.bfstm</code>
* <code>System/AocVersion.txt</code>
* <code>System/AocVersion.txt</code>
There are two other situations where the <code>Aoc/0010/</code> prefix is supposed to be prepended:
There are two other situations where the <code>Aoc/0010/</code> prefix is supposed to be prepended:
* If the load file device is set to the <code>Pack/AocMainField.pack</code> archive file device explicitly
* If the load file device is set to the <code>Pack/AocMainField.pack</code> archive file device explicitly
* If the global resource pack is an AoC dungeon pack
* If the global resource pack is an AoC dungeon pack
However, the first case is irrelevant because that archive only contains Map/MainField/ (a case that is already handled by the path checks) and the second check appears to never pass.
However, the first case is irrelevant because that archive only contains Map/MainField/ (a case that is already handled by the path checks) and the second check appears to never pass.


Line 84: Line 89:
=== Heap size ===
=== Heap size ===
The size of the resource loading heap the system allocates every time a resource is loaded depends on the value that is listed in the [[#Resource size table]] (RSTB). If lookup fails, the game will fall back to the following formula (Switch on 1.5.0):
The size of the resource loading heap the system allocates every time a resource is loaded depends on the value that is listed in the [[#Resource size table]] (RSTB). If lookup fails, the game will fall back to the following formula (Switch on 1.5.0):
<syntaxhighlight lang="C++">
<syntaxhighlight lang="C++">
alignedFileSize = (actualFileSize + 31) & -32;
alignedFileSize = (actualFileSize + 31) & -32;
Line 95: Line 99:
+ 0x750
+ 0x750
</syntaxhighlight>
</syntaxhighlight>
'''Warning''': Failure to add entries to the RSTB for a large number of resources may result in system instability. The purpose of this fallback appears to be to allow loading resources during development even without an entry in the resource size table. As such, the system will often allocate way more memory than needed to account for any dynamic allocation that the resource class may do.  
'''Warning''': Failure to add entries to the RSTB for a large number of resources may result in system instability. The purpose of this fallback appears to be to allow loading resources during development even without an entry in the resource size table. As such, the system will often allocate way more memory than needed to account for any dynamic allocation that the resource class may do.  


Line 110: Line 113:


Therefore, the following formula should give a correct size value for all resource types:
Therefore, the following formula should give a correct size value for all resource types:
  (size rounded up to multiple of 32) + CONSTANT + sizeof(ResourceClass) + PARSE_SIZE
  (size rounded up to multiple of 32) + CONSTANT + sizeof(ResourceClass) + PARSE_SIZE
CONSTANT is 0x168 in the Switch version and 0xe4 on Wii U.
CONSTANT is 0x168 in the Switch version and 0xe4 on Wii U.


PARSE_SIZE is the amount of memory allocated from the resource heap in the <code>Resource::parse</code> function. Determining the exact value of PARSE_SIZE requires reversing that function and tracking calls to <code>operator new()</code> because the amount of dynamically allocated memory depends on the resource.
PARSE_SIZE is the amount of memory allocated from the resource heap in the <code>Resource::parse</code> function. Determining the exact value of PARSE_SIZE requires reversing that function and tracking calls to <code>operator new()</code> because the amount of dynamically allocated memory depends on the resource.


==== BFRES resource size estimation ====
[[File:Allrstb.png|alt=All BFRES RSTB entries|thumb|RSTB size analysis for all BFRES files. Y-axis: ratio, X-axis: BFRES file size, dot size: RSTB entry size.]]
Though exact RSTB entry sizes are currently unable to be calculated exactly, by analyzing the BFRES files Nintendo shipped with the game, a few revelations have been made to allow for acceptable RSTB entry size estimations.
There are two types of BFRES file: model, and texture. (Texture is further split into main textures, tex1, and mipmaps, tex2, but there seems to be no difference in RSTB calculations concerning these two types of textures)
<br />
[[File:Modelrstb.png|thumb|RSTB size analysis for BFRES model files. Y-axis: ratio, X-axis: BFRES file size, dot size: RSTB entry size.]]
For models, the ratio of RSTB entry size to BFRES file size increases early, but lazily, as BFRES file size decreases. The estimations are trickier for models than they are for textures, but they are still fairly simple overall.
* If your model BFRES is less than 100KB, your RSTB entry should be 200% of your BFRES file size.
* If your model BFRES is greater than 100KB, but less than 1MB, your RSTB entry should be 175% of your BFRES file size.
* If your model BFRES is greater then 1MB, but less than 2MB, your RSTB entry should be 150% of your BFRES file size.
* If your model BFRES is greater than 2MB, your RSTB entry should be 125% of your BFRES file size.
<br />
[[File:Tex1rstb.png|thumb|RSTB size analysis for BFRES tex1 texture files. Y-axis: ratio, X-axis: BFRES file size, dot size: RSTB entry size.]]
For textures, the ratio of RSTB entry size to BFRES file size increases late, but sharply, as BFRES file size decreases. This makes the estimates for RSTB entry size for textures incredibly easy
* If your texture BFRES is less than 100KB, your RSTB entry should be 200% of your BFRES file size.
* If your texture BFRES is greater than 100KB but less than 500KB, your RSTB entry should be 110% of your BFRES file size.
* If your texture BFRES is greater than 500KB, your RSTB entry should be 101% of your BFRES file size.
[[File:Tex2rstb.png|thumb|RSTB size analysis for BFRES tex2 texture files. Y-axis: ratio, X-axis: BFRES file size, dot size: RSTB entry size.]]
<br />
[[Category:Internals]]
[[Category:Internals]]
<references />
Anonymous user