public static void AssignPositions(IList <IResourceBlock> blocks, uint basePosition, out RpfResourcePageFlags pageFlags) { var sys = (basePosition == 0x50000000); long pad(long p) { return((ALIGN_SIZE - (p % ALIGN_SIZE)) % ALIGN_SIZE); } long largestBlockSize = 0; // find largest structure long startPageSize = BASE_SIZE; // 0x2000; // find starting page size long totalBlockSize = 0; foreach (var block in blocks) { var blockLength = block.BlockLength; totalBlockSize += blockLength; totalBlockSize += pad(totalBlockSize); if (largestBlockSize < blockLength) { largestBlockSize = blockLength; } } while (startPageSize < largestBlockSize) { startPageSize *= 2; } pageFlags = new RpfResourcePageFlags(); var pageSizeMult = 1; while (true) { if (blocks.Count == 0) { break; } var blockset = new ResourceBuilderBlockSet(blocks, sys); var rootblock = blockset.RootBlock; var currentPosition = 0L; var currentPageSize = startPageSize; var currentPageStart = 0L; var currentPageSpace = startPageSize; var currentRemainder = totalBlockSize; var pageCount = 1; var pageCounts = new uint[9]; var pageCountIndex = 0; var targetPageSize = Math.Max(65536 * pageSizeMult, startPageSize >> (sys ? 5 : 2)); var minPageSize = Math.Max(512 * pageSizeMult, Math.Min(targetPageSize, startPageSize) >> 4); var baseShift = 0u; var baseSize = 512; while (baseSize < minPageSize) { baseShift++; baseSize *= 2; if (baseShift >= 0xF) { break; } } var baseSizeMax = baseSize << 8; var baseSizeMaxTest = startPageSize; while (baseSizeMaxTest < baseSizeMax) { pageCountIndex++; baseSizeMaxTest *= 2; } pageCounts[pageCountIndex] = 1; while (true) { var isroot = sys && (currentPosition == 0); var block = isroot ? rootblock : blockset.TakeBestBlock(currentPageSpace); var blockLength = block?.Length ?? 0; if (block != null) { //add this block to the current page. block.Block.FilePosition = basePosition + currentPosition; var opos = currentPosition; currentPosition += blockLength; currentPosition += pad(currentPosition); var usedspace = currentPosition - opos; currentPageSpace -= usedspace; currentRemainder -= usedspace;//blockLength;// } else if (blockset.Count > 0) { //allocate a new page currentPageStart += currentPageSize; currentPosition = currentPageStart; block = blockset.FindBestBlock(long.MaxValue); //just find the biggest block blockLength = block?.Length ?? 0; while (blockLength <= (currentPageSize >> 1)) //determine best new page size { if (currentPageSize <= minPageSize) { break; } if (pageCountIndex >= 8) { break; } if ((currentPageSize <= targetPageSize) && (currentRemainder >= (currentPageSize - minPageSize))) { break; } currentPageSize = currentPageSize >> 1; pageCountIndex++; } currentPageSpace = currentPageSize; pageCounts[pageCountIndex]++; pageCount++; } else { break; } } pageFlags = new RpfResourcePageFlags(pageCounts, baseShift); if ((pageCount == pageFlags.Count) && (pageFlags.Size >= currentPosition)) //make sure page counts fit in the flags value { break; } startPageSize *= 2; pageSizeMult *= 2; } }