Skip to content

Commit 261fa77

Browse files
committed
apply stormlib optimizations using cmake patching
1 parent 61e304d commit 261fa77

File tree

2 files changed

+127
-0
lines changed

2 files changed

+127
-0
lines changed

cmake/dependencies/common.cmake

+4
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,14 @@ target_include_directories(ImGui PUBLIC ${imgui_SOURCE_DIR} ${imgui_SOURCE_DIR}/
3333

3434
# ========= StormLib =============
3535
if(NOT EXCLUDE_MPQ_SUPPORT)
36+
set(stormlib_optimizations_patch git apply ${CMAKE_CURRENT_SOURCE_DIR}/cmake/dependencies/patches/stormlib-optimizations.patch)
3637
FetchContent_Declare(
3738
StormLib
3839
GIT_REPOSITORY https://github.com/ladislav-zezula/StormLib.git
3940
GIT_TAG v9.25
41+
PATCH_COMMAND ${stormlib_optimizations_patch}
42+
# don't try to apply the patch multiple times https://stackoverflow.com/a/73725257
43+
UPDATE_DISCONNECTED 1
4044
)
4145
FetchContent_MakeAvailable(StormLib)
4246
list(APPEND ADDITIONAL_LIB_INCLUDES ${stormlib_SOURCE_DIR}/src)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
From ff338b230544f8b2bb68d2fbe075175ed2fd758c Mon Sep 17 00:00:00 2001
2+
From: briaguya <[email protected]>
3+
Date: Wed, 8 May 2024 02:44:49 -0400
4+
Subject: [PATCH] bring back optimizations
5+
6+
Co-authored-by: GaryOderNichts <[email protected]>
7+
---
8+
src/SBaseCommon.cpp | 6 +++++-
9+
src/SFileCreateArchive.cpp | 2 ++
10+
src/SFileListFile.cpp | 35 ++++++++++++++++++-----------------
11+
src/StormLib.h | 3 +++
12+
4 files changed, 28 insertions(+), 18 deletions(-)
13+
14+
diff --git a/src/SBaseCommon.cpp b/src/SBaseCommon.cpp
15+
index 77590d6..6fed00e 100644
16+
--- a/src/SBaseCommon.cpp
17+
+++ b/src/SBaseCommon.cpp
18+
@@ -884,8 +884,10 @@ ULONGLONG FindFreeMpqSpace(TMPQArchive * ha)
19+
ULONGLONG FreeSpacePos = ha->pHeader->dwHeaderSize;
20+
DWORD dwChunkCount;
21+
22+
+ TFileEntry* startEntry = (ha->useFreeSpaceOptimization && ha->lastFreeSpaceEntry != nullptr) ? ha->lastFreeSpaceEntry : ha->pFileTable;
23+
+
24+
// Parse the entire block table
25+
- for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++)
26+
+ for(pFileEntry = startEntry; pFileEntry < pFileTableEnd; pFileEntry++)
27+
{
28+
// Only take existing files with nonzero size
29+
if((pFileEntry->dwFlags & MPQ_FILE_EXISTS) && (pFileEntry->dwCmpSize != 0))
30+
@@ -906,6 +908,8 @@ ULONGLONG FindFreeMpqSpace(TMPQArchive * ha)
31+
dwChunkCount = ((pFileEntry->dwCmpSize - 1) / pHeader->dwRawChunkSize) + 1;
32+
FreeSpacePos += dwChunkCount * MD5_DIGEST_SIZE;
33+
}
34+
+
35+
+ ha->lastFreeSpaceEntry = pFileEntry;
36+
}
37+
}
38+
}
39+
diff --git a/src/SFileCreateArchive.cpp b/src/SFileCreateArchive.cpp
40+
index c0ea367..d392a83 100644
41+
--- a/src/SFileCreateArchive.cpp
42+
+++ b/src/SFileCreateArchive.cpp
43+
@@ -224,6 +224,8 @@ bool WINAPI SFileCreateArchive2(const TCHAR * szMpqName, PSFILE_CREATE_MPQ pCrea
44+
ha->dwFileFlags3 = pCreateInfo->dwFileFlags3 ? MPQ_FILE_EXISTS : 0;
45+
ha->dwAttrFlags = pCreateInfo->dwAttrFlags;
46+
ha->dwFlags = dwMpqFlags | MPQ_FLAG_CHANGED;
47+
+ ha->useFreeSpaceOptimization = true;
48+
+ ha->lastFreeSpaceEntry = nullptr;
49+
pStream = NULL;
50+
51+
// Fill the MPQ header
52+
diff --git a/src/SFileListFile.cpp b/src/SFileListFile.cpp
53+
index b2a3a3c..d0c3c67 100644
54+
--- a/src/SFileListFile.cpp
55+
+++ b/src/SFileListFile.cpp
56+
@@ -409,6 +409,7 @@ static LPBYTE CreateListFile(TMPQArchive * ha, DWORD * pcbListFile)
57+
static DWORD SListFileCreateNodeForAllLocales(TMPQArchive * ha, const char * szFileName)
58+
{
59+
TFileEntry * pFileEntry;
60+
+ TMPQHash * pFirstHash;
61+
TMPQHash * pHashEnd;
62+
TMPQHash * pHash;
63+
DWORD dwName1;
64+
@@ -443,25 +444,25 @@ static DWORD SListFileCreateNodeForAllLocales(TMPQArchive * ha, const char * szF
65+
pHashEnd = ha->pHashTable + (ha->dwRealHashTableSize / sizeof(TMPQHash));
66+
67+
// Go through the hash table and put the name in each item that has the same name pair
68+
- for(pHash = ha->pHashTable; pHash < pHashEnd; pHash++)
69+
- {
70+
- if(pHash->dwName1 == dwName1 && pHash->dwName2 == dwName2 && MPQ_BLOCK_INDEX(pHash) < ha->dwFileTableSize)
71+
- {
72+
- // Allocate file name for the file entry
73+
- AllocateFileName(ha, ha->pFileTable + MPQ_BLOCK_INDEX(pHash), szFileName);
74+
- }
75+
- }
76+
+ // for(pHash = ha->pHashTable; pHash < pHashEnd; pHash++)
77+
+ // {
78+
+ // if(pHash->dwName1 == dwName1 && pHash->dwName2 == dwName2 && MPQ_BLOCK_INDEX(pHash) < ha->dwFileTableSize)
79+
+ // {
80+
+ // // Allocate file name for the file entry
81+
+ // AllocateFileName(ha, ha->pFileTable + MPQ_BLOCK_INDEX(pHash), szFileName);
82+
+ // }
83+
+ // }
84+
85+
// Go while we found something
86+
- //pFirstHash = pHash = GetFirstHashEntry(ha, szFileName);
87+
- //while(pHash != NULL)
88+
- //{
89+
- // // Allocate file name for the file entry
90+
- // AllocateFileName(ha, ha->pFileTable + MPQ_BLOCK_INDEX(pHash), szFileName);
91+
-
92+
- // // Now find the next language version of the file
93+
- // pHash = GetNextHashEntry(ha, pFirstHash, pHash);
94+
- //}
95+
+ pFirstHash = pHash = GetFirstHashEntry(ha, szFileName);
96+
+ while(pHash != NULL)
97+
+ {
98+
+ // Allocate file name for the file entry
99+
+ AllocateFileName(ha, ha->pFileTable + MPQ_BLOCK_INDEX(pHash), szFileName);
100+
+
101+
+ // Now find the next language version of the file
102+
+ pHash = GetNextHashEntry(ha, pFirstHash, pHash);
103+
+ }
104+
105+
return ERROR_SUCCESS;
106+
}
107+
diff --git a/src/StormLib.h b/src/StormLib.h
108+
index 4aa51c1..bda11d3 100644
109+
--- a/src/StormLib.h
110+
+++ b/src/StormLib.h
111+
@@ -860,6 +860,9 @@ typedef struct _TMPQArchive
112+
ULONGLONG CompactBytesProcessed; // Amount of bytes that have been processed during a particular compact call
113+
ULONGLONG CompactTotalBytes; // Total amount of bytes to be compacted
114+
void * pvCompactUserData; // User data thats passed to the callback
115+
+
116+
+ TFileEntry* lastFreeSpaceEntry;
117+
+ bool useFreeSpaceOptimization;
118+
} TMPQArchive;
119+
120+
// File handle structure
121+
--
122+
2.43.0
123+

0 commit comments

Comments
 (0)