diff --git a/src/logic/pakpage.cpp b/src/logic/pakpage.cpp index 5e9eab8f..d805a741 100644 --- a/src/logic/pakpage.cpp +++ b/src/logic/pakpage.cpp @@ -41,6 +41,7 @@ // Constructors/Destructors //----------------------------------------------------------------------------- CPakPageBuilder::CPakPageBuilder() + : m_slabCount(0) { } CPakPageBuilder::~CPakPageBuilder() @@ -66,7 +67,7 @@ PakSlab_s& CPakPageBuilder::FindOrCreateSlab(const int flags, const int align) // Try and find a slab that has the same flags, and the closest alignment // of request. - for (size_t i = 0; i < m_slabs.size(); i++) + for (uint16_t i = 0; i < m_slabCount; i++) { PakSlab_s& slab = m_slabs[i]; PakSlabHdr_s& header = slab.header; @@ -105,10 +106,13 @@ PakSlab_s& CPakPageBuilder::FindOrCreateSlab(const int flags, const int align) return *toReturn; } + if (m_slabCount + 1 > PAK_MAX_SLAB_COUNT) + Error("Out of room while adding new slab; runtime has a limit of %hu.\n", PAK_MAX_SLAB_COUNT); + // If we didn't have a close match, create a new slab. - PakSlab_s& newSlab = m_slabs.emplace_back(); + PakSlab_s& newSlab = m_slabs[m_slabCount]; - newSlab.index = static_cast(m_slabs.size() - 1); + newSlab.index = m_slabCount++; newSlab.header.flags = flags; newSlab.header.alignment = align; newSlab.header.dataSize = 0; @@ -286,22 +290,28 @@ const PakPageLump_s CPakPageBuilder::CreatePageLump(const int size, const int fl //----------------------------------------------------------------------------- void CPakPageBuilder::PadSlabsAndPages() { - int lastPageSizeAligned = 0; - int lastPageAlign = 0; + struct PageAlignmentTracker_s + { + int lastPageSizeAligned = 0; + int lastPageAlign = 0; + }; + + PageAlignmentTracker_s alignTrack[PAK_MAX_SLAB_COUNT]; for (PakPage_s& page : m_pages) { PakPageHdr_s& pageHdr = page.header; PakSlab_s& slab = m_slabs[pageHdr.slabIndex]; PakSlabHdr_s& slabHdr = slab.header; + PageAlignmentTracker_s& track = alignTrack[pageHdr.slabIndex]; const int pageSize = pageHdr.dataSize; const int pageAlign = pageHdr.alignment; // The runtime pads the previous page to align our current page, we have // to add this extra size to the slab to accommodate for this. - if (lastPageSizeAligned > 0 && pageAlign > lastPageAlign) - slabHdr.dataSize += IALIGN(lastPageSizeAligned, pageAlign) - lastPageSizeAligned; + if (track.lastPageSizeAligned > 0 && pageAlign > track.lastPageAlign) + slabHdr.dataSize += IALIGN(track.lastPageSizeAligned, pageAlign) - track.lastPageSizeAligned; const int pagePadAmount = IALIGN(pageSize, pageAlign) - pageSize; @@ -312,8 +322,8 @@ void CPakPageBuilder::PadSlabsAndPages() if (pagePadAmount > 0) slabHdr.dataSize += pagePadAmount; - lastPageSizeAligned = pageSize + pagePadAmount; - lastPageAlign = pageAlign; + track.lastPageSizeAligned = pageSize + pagePadAmount; + track.lastPageAlign = pageAlign; } } @@ -322,8 +332,9 @@ void CPakPageBuilder::PadSlabsAndPages() //----------------------------------------------------------------------------- void CPakPageBuilder::WriteSlabHeaders(BinaryIO& out) const { - for (const PakSlab_s& slab : m_slabs) + for (uint16_t i = 0; i < m_slabCount; i++) { + const PakSlab_s& slab = m_slabs[i]; out.Write(slab.header); } } diff --git a/src/logic/pakpage.h b/src/logic/pakpage.h index ca6d61cd..ea1387ee 100644 --- a/src/logic/pakpage.h +++ b/src/logic/pakpage.h @@ -1,6 +1,9 @@ #pragma once #include "public/rpak.h" +// Maximum number of slabs that can be allocated into the runtime collection. +#define PAK_MAX_SLAB_COUNT 20 + // Pages can only be merged with other pages with equal flags and an alignment // equal or higher than its own if the combined size aligned to the page's // new alignment is below this value. @@ -62,7 +65,7 @@ class CPakPageBuilder CPakPageBuilder(); ~CPakPageBuilder(); - inline uint16_t GetSlabCount() const { return static_cast(m_slabs.size()); } + inline uint16_t GetSlabCount() const { return m_slabCount; } inline uint16_t GetPageCount() const { return static_cast(m_pages.size()); } const PakPageLump_s CreatePageLump(const int size, const int flags, const int align, void* const buf = nullptr); @@ -78,6 +81,8 @@ class CPakPageBuilder PakPage_s& FindOrCreatePage(const int flags, const int align, const int size); private: - std::vector m_slabs; + std::array m_slabs; + uint16_t m_slabCount; + std::vector m_pages; }; diff --git a/src/pch.h b/src/pch.h index 46b274ad..40fd697b 100644 --- a/src/pch.h +++ b/src/pch.h @@ -10,6 +10,7 @@ #include //#include #include +#include #include #include #include