Author Topic: POF Specs for pof versión 2200  (Read 246 times)

0 Members and 1 Guest are viewing this topic.

Offline ShivanSpS

  • 210
POF Specs for pof versión 2200
Ok, i will to keep this as short as possible.

The Problem:
Pof editing programs have been not enforcing proper data padding and they even remove them, this started with modelview,  :v: original pofs all come with proper padding that ensures there is no issues reading the pof data no matter the CPU arch. As it is now, the current, non-Volition pofs crash while loading on ARM32, this not longer happens on ARM64 as aarch64 fully supports unaligned access.
On top of that, the FSO SLDC system to accelerate shield collision detection uses unaligned access by design, what means that even if the pof somehow loads, if it has a SLDC chunk on it, FSO crashes on a shield impact if the cpu arch does not fully support unaligned access.

The Fix:
FSO version 21.4.0 already fixes the problems that causes the crashes by adding the proper padding to the BSP_data and converting the SLDC data at load, but this involves a addicional work to be done at load, the process is very, very fast and the loading time impact is almost 0 but this is where Pof Version #2200 comes into play.

POF v2200:
-Return to original :v: data specs
-The new SLC2 chunk for shield collision acceleration must be added
-SLDC must still be in file for backward FSO compatibility

The Original :v: data specs:
-The entire pof file size must be divisible by 4, that means that all data stored inside, on every POF and BSP chunks must be divisible by 4.
-On file read all pointer arithmetic must be divisible by 4, meaning you should never do a "pointer+17" to access any data. In those cases addicional padding is added to the trailing data, so instead of a "pointer+17", it is a "pointer+20".
-Null terminators are used as padding.
-BSP_Defpoints vertex_offset was the major cause of crashes on ARM32, it is also the only type of BSP chunks that can cause issues, proper padding must be enforced there.
-Same rule applies to strings stored in the chunks:

Bad:
int string_lenght 23
char[23] "this is a turret name\0"

Good:
int string_lenght 24
char[24] "this is a turret name\0\0"

The SLC2 chunk:
SLC2 is nothing more than a exact copy of SLDC but using an int for the chunk type instead of a char, so the same shield collision tree must be writen twice, once with a char as the type for the regular SLDC chunk, and again with a int for the SLC2 chunk, both SLDC and SLC2 must be present on pof version 2200.


Conversion function example:
I writen a pof conversion function in C some time ago, the version that works properly is currently used on the VPC compressor, this is petty much a single pof alignment function (i regret to have written it as single function but, it works so...)
https://github.com/Shivansps/VPC_Compressor/blob/main/VP%20Compressor/lib/pof/aligner.cpp