Skip to content

Commit

Permalink
Add optional cmdline to decompress or compress all worlds
Browse files Browse the repository at this point in the history
  • Loading branch information
IonAgorria committed Sep 11, 2023
1 parent 185e5d3 commit 1c2d07e
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 1 deletion.
1 change: 1 addition & 0 deletions Source/Game/Runtime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -830,6 +830,7 @@ void show_help() {
" not_triggerchains_binary=1 - Disallows loading triggerchain stored in .bin instead of .spg\n"
" debug_key_handler=1 - Enables debug key handler\n"
" explore=1 - Opens Debug.prm editor and closes game\n"
" compress_worlds=0/1 - Attempts to decompress or compress all worlds\n"
" start_splash=0/1 - Enables or disables intro movies\n"
" show_fps=0/1 - Displays FPS counter\n"
" convert=1 - Saves opened map and closes game\n"
Expand Down
75 changes: 74 additions & 1 deletion Source/Terra/VMAP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,73 @@ bool isWorldIDValid(int worldID) {
return (worldID < vMap.maxWorld && worldID >= 0);
}

void vrtMap::compressWorlds(int mode) {
fprintf(stdout, "compressWorlds: mode %d\n", mode);
sVmpHeader VmpHeader;
XStream fstream;
fstream.ErrHUsed = false;
for (int id = 0; id < vMap.maxWorld; ++id) {
std::string output_vmp = GetTargetName(id, worldDataFileLinear);
fprintf(stdout, "%s\n", vMap.wTable[id].name.c_str());

//Read file
XBuffer fmap(0, true);
if (!fstream.open(output_vmp, XS_IN)) {
fprintf(stderr, "VMP file not found\n");
continue;
}
fstream.seek(0,XS_BEG);
fstream.read(&VmpHeader,sizeof(VmpHeader));
int64_t flen = fstream.size() - fstream.tell();

//Decode header
if (VmpHeader.cmpID("S2T0")) {
if (mode == 0) {
continue;
}
fmap.realloc(flen);
fstream.read(fmap.buf, flen);
fmap.set(flen, XB_BEG);
} else if (VmpHeader.cmpID("S2T1")) {
if (mode == 1) {
continue;
}
XBuffer tmp(flen, false);
fstream.read(tmp.buf, flen);
if (tmp.uncompress(fmap) != 0) {
ErrH.Abort("Error decompressing world");
}
}
fstream.close();

//Act on mode
if (mode == 0) {
VmpHeader.setID("S2T0");
//fmap is already uncompressed
} else if (mode == 1) {
VmpHeader.setID("S2T1");
XBuffer tmp(fmap.length(), true);
int result = fmap.compress(tmp);
if (result != 0) {
ErrH.Abort("Error compressing world");
}
fmap = std::move(tmp);
} else {
ErrH.Abort("Unsupported compression mode");
}

//Write back
fprintf(stdout, "%s %s\n", VmpHeader.id, output_vmp.c_str());
if (!fstream.open(output_vmp, XS_OUT)) {
ErrH.Abort("Error opening VMP for write");
}
fstream.seek(0,XS_BEG);
fstream.write(&VmpHeader, sizeof(VmpHeader));
fstream.write(fmap.buf, fmap.tell());
fstream.close();
}
}

std::string GetTargetName(int numWorld, const char* name)
{
if ( !isWorldIDValid(numWorld) ) ErrH.Abort("World Index out of range");
Expand Down Expand Up @@ -420,14 +487,20 @@ void vrtMap::prepare(char* name)

//Scan resources worlds and create table with name and path
wTable.clear();
for (const auto& entry : get_content_entries_directory("resource/worlds")) {
for (const auto& entry : get_content_entries_directory(name)) {
if (entry->is_directory) {
std::filesystem::path path = std::filesystem::u8path(entry->path_content);
wTable.emplace_back(path.filename().u8string(), entry->key);
}
}
maxWorld = wTable.size();
if(maxWorld < 1) ErrH.Abort("Empty world list");

int compress_mode = -1;
check_command_line_parameter("compress_worlds", compress_mode);
if (0 <= compress_mode) {
compressWorlds(compress_mode);
}
}

//Для Периметра
Expand Down
1 change: 1 addition & 0 deletions Source/Terra/VMAP.h
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,7 @@ struct vrtMap {
void selectUsedWorld(char* _patch2WorldIniFile);
#elif _PERIMETER_
void prepare(char* name);
void compressWorlds(int mode);
void selectUsedWorld(int nWorld);
#endif
void ShadowControl(bool shadow);
Expand Down

0 comments on commit 1c2d07e

Please sign in to comment.