1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Resource extractor "enablers" are now command line options

In VCMI_lib the extractArchives will be passed all the way down the call chain!
This commit is contained in:
krs 2022-11-20 18:48:31 +02:00
parent cca1f074bf
commit eecaa20693
10 changed files with 100 additions and 50 deletions

View File

@ -39,13 +39,13 @@ VCMI_LIB_NAMESPACE_BEGIN
LibClasses * VLC = nullptr;
DLL_LINKAGE void preinitDLL(CConsoleHandler * Console, bool onlyEssential)
DLL_LINKAGE void preinitDLL(CConsoleHandler * Console, bool onlyEssential, bool extractArchives)
{
console = Console;
VLC = new LibClasses();
try
{
VLC->loadFilesystem(onlyEssential);
VLC->loadFilesystem(onlyEssential, extractArchives);
}
catch(...)
{
@ -157,7 +157,7 @@ void LibClasses::updateEntity(Metatype metatype, int32_t index, const JsonNode &
}
}
void LibClasses::loadFilesystem(bool onlyEssential)
void LibClasses::loadFilesystem(bool onlyEssential, bool extractArchives)
{
CStopWatch totalTime;
CStopWatch loadTime;
@ -165,7 +165,7 @@ void LibClasses::loadFilesystem(bool onlyEssential)
CResourceHandler::initialize();
logGlobal->info("\tInitialization: %d ms", loadTime.getDiff());
CResourceHandler::load("config/filesystem.json");
CResourceHandler::load("config/filesystem.json", extractArchives);
logGlobal->info("\tData loading: %d ms", loadTime.getDiff());
modh = new CModHandler();

View File

@ -100,8 +100,8 @@ public:
void init(bool onlyEssential); //uses standard config file
void clear(); //deletes all handlers and its data
void loadFilesystem(bool onlyEssential);// basic initialization. should be called before init()
// basic initialization. should be called before init(). Can also extract original H3 archives
void loadFilesystem(bool onlyEssential, bool extractArchives = false);
#if SCRIPTING_ENABLED
void scriptsLoaded();
@ -151,7 +151,7 @@ public:
extern DLL_LINKAGE LibClasses * VLC;
DLL_LINKAGE void preinitDLL(CConsoleHandler * Console, bool onlyEssential = false);
DLL_LINKAGE void preinitDLL(CConsoleHandler * Console, bool onlyEssential = false, bool extractArchives = false);
DLL_LINKAGE void loadDLLClasses(bool onlyEssential = false);

View File

@ -20,18 +20,18 @@ VCMI_LIB_NAMESPACE_BEGIN
namespace bfs = boost::filesystem;
const bool extractArchives = false;
ArchiveEntry::ArchiveEntry()
: offset(0), fullSize(0), compressedSize(0)
{
}
CArchiveLoader::CArchiveLoader(std::string _mountPoint, bfs::path _archive) :
CArchiveLoader::CArchiveLoader(std::string _mountPoint, bfs::path _archive, bool extractArchives) :
archive(std::move(_archive)),
mountPoint(std::move(_mountPoint))
{
this->extractArchives = extractArchives;
// Open archive file(.snd, .vid, .lod)
CFileInputStream fileStream(archive);

View File

@ -52,10 +52,11 @@ public:
* These are valid extensions: .LOD, .SND, .VID
*
* @param archive Specifies the file path to the archive which should be indexed and loaded.
* @param extractArchives Specifies if the original H3 archives should be extracted to a separate folder.
*
* @throws std::runtime_error if the archive wasn't found or if the archive isn't supported
*/
CArchiveLoader(std::string mountPoint, boost::filesystem::path archive);
CArchiveLoader(std::string mountPoint, boost::filesystem::path archive, bool extractArchives = false);
/// Interface implementation
/// @see ISimpleResourceLoader
@ -98,6 +99,9 @@ private:
/** Holds all entries of the archive file. An entry can be accessed via the entry name. **/
std::unordered_map<ResourceID, ArchiveEntry> entries;
/** Specifies if Original H3 archives should be extracted to a separate folder **/
bool extractArchives;
};
/** Constructs the file path for the extracted file. Creates the subfolder hierarchy aswell **/

View File

@ -26,10 +26,11 @@ VCMI_LIB_NAMESPACE_BEGIN
std::map<std::string, ISimpleResourceLoader*> CResourceHandler::knownLoaders = std::map<std::string, ISimpleResourceLoader*>();
CResourceHandler CResourceHandler::globalResourceHandler;
CFilesystemGenerator::CFilesystemGenerator(std::string prefix):
CFilesystemGenerator::CFilesystemGenerator(std::string prefix, bool extractArchives):
filesystem(new CFilesystemList()),
prefix(prefix)
{
this->extractArchives = extractArchives;
}
CFilesystemGenerator::TLoadFunctorMap CFilesystemGenerator::genFunctorMap()
@ -105,7 +106,7 @@ void CFilesystemGenerator::loadArchive(const std::string &mountPoint, const Json
std::string URI = prefix + config["path"].String();
auto filename = CResourceHandler::get("initial")->getResourceName(ResourceID(URI, archiveType));
if (filename)
filesystem->addLoader(new CArchiveLoader(mountPoint, *filename), false);
filesystem->addLoader(new CArchiveLoader(mountPoint, *filename, extractArchives), false);
}
void CFilesystemGenerator::loadJsonMap(const std::string &mountPoint, const JsonNode & config)
@ -200,16 +201,16 @@ ISimpleResourceLoader * CResourceHandler::get(std::string identifier)
return knownLoaders.at(identifier);
}
void CResourceHandler::load(const std::string &fsConfigURI)
void CResourceHandler::load(const std::string &fsConfigURI, bool extractArchives)
{
auto fsConfigData = get("initial")->load(ResourceID(fsConfigURI, EResType::TEXT))->readAll();
const JsonNode fsConfig((char*)fsConfigData.first.get(), fsConfigData.second);
addFilesystem("data", "core", createFileSystem("", fsConfig["filesystem"]));
addFilesystem("data", "core", createFileSystem("", fsConfig["filesystem"], extractArchives));
}
void CResourceHandler::addFilesystem(const std::string & parent, const std::string & identifier, ISimpleResourceLoader * loader)
void CResourceHandler::addFilesystem(const std::string & parent, const std::string & identifier, ISimpleResourceLoader * loader, bool extractArchives)
{
if(knownLoaders.count(identifier) != 0)
{
@ -246,9 +247,9 @@ bool CResourceHandler::removeFilesystem(const std::string & parent, const std::s
return true;
}
ISimpleResourceLoader * CResourceHandler::createFileSystem(const std::string & prefix, const JsonNode &fsConfig)
ISimpleResourceLoader * CResourceHandler::createFileSystem(const std::string & prefix, const JsonNode &fsConfig, bool extractArchives)
{
CFilesystemGenerator generator(prefix);
CFilesystemGenerator generator(prefix, extractArchives);
generator.loadConfig(fsConfig);
return generator.getFilesystem();
}

View File

@ -36,7 +36,8 @@ class DLL_LINKAGE CFilesystemGenerator
TLoadFunctorMap genFunctorMap();
public:
/// prefix = prefix that will be given to file entries in all nodes of this filesystem
CFilesystemGenerator(std::string prefix);
/// extractArchives = Specifies if Original H3 archives should be extracted to a separate folder
CFilesystemGenerator(std::string prefix, bool extractArchives = false);
/// loads configuration from json
/// config - configuration to load, using format of "filesystem" entry in config/filesystem.json
@ -44,6 +45,9 @@ public:
/// returns generated filesystem
CFilesystemList * getFilesystem();
/** Specifies if Original H3 archives should be extracted to a separate folder **/
bool extractArchives;
};
/**
@ -81,14 +85,14 @@ public:
* Will load all filesystem data from Json data at this path (normally - config/filesystem.json)
* @param fsConfigURI - URI from which data will be loaded
*/
static void load(const std::string & fsConfigURI);
static void load(const std::string & fsConfigURI, bool extractArchives = false);
/**
* @brief addFilesystem adds filesystem into global resource loader
* @param identifier name of this loader by which it can be retrieved later
* @param loader resource loader to add
*/
static void addFilesystem(const std::string & parent, const std::string & identifier, ISimpleResourceLoader * loader);
static void addFilesystem(const std::string & parent, const std::string & identifier, ISimpleResourceLoader * loader, bool extractArchives = false);
/**
* @brief removeFilesystem removes previously added filesystem from global resouce holder
@ -104,7 +108,7 @@ public:
* @param fsConfig - configuration to load
* @return generated filesystem that contains all config entries
*/
static ISimpleResourceLoader * createFileSystem(const std::string &prefix, const JsonNode & fsConfig);
static ISimpleResourceLoader * createFileSystem(const std::string &prefix, const JsonNode & fsConfig, bool extractArchives = false);
~CResourceHandler() = default;
private:

View File

@ -89,6 +89,39 @@ void MainWindow::saveUserSettings()
s.setValue(mainWindowPositionSetting, pos());
}
void MainWindow::parseCommandLine()
{
QCommandLineParser parser;
parser.addHelpOption();
parser.addPositionalArgument("map", QCoreApplication::translate("main", "Filepath of the map to open."));
parser.addOptions({
{"e", QCoreApplication::translate("main", "Extract original H3 archives into a separate folder.")},
{"s", QCoreApplication::translate("main", "From an extracted archive, it Splits TwCrPort, CPRSMALL, FlagPort, ITPA, ITPt, Un32 and Un44 into individual PNG's.")},
{"c", QCoreApplication::translate("main", "From an extracted archive, Converts single Images (found in Images folder) from .pcx to png.")},
{"d", QCoreApplication::translate("main", "Delete original files, for the ones splitted / converted.")},
});
parser.process(qApp->arguments());
const QStringList positionalArgs = parser.positionalArguments();
if (!positionalArgs.isEmpty())
mapFilePath = positionalArgs.at(0);
if (parser.isSet("e"))
extractArchives = true;
if (parser.isSet("s"))
splitDefs = true;
if (parser.isSet("c"))
convertPcxToPng = true;
if (parser.isSet("d"))
deleteOriginals = true;
}
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
@ -102,15 +135,17 @@ MainWindow::MainWindow(QWidget *parent) :
// This is important on Mac for relative paths to work inside DMG.
QDir::setCurrent(QApplication::applicationDirPath());
parseCommandLine();
//configure logging
const boost::filesystem::path logPath = VCMIDirs::get().userLogsPath() / "VCMI_Editor_log.txt";
console = new CConsoleHandler();
logConfig = new CBasicLogConfigurator(logPath, console);
logConfig->configureDefault();
logGlobal->info("The log file will be saved to %s", logPath);
//init
preinitDLL(::console);
preinitDLL(::console, false, extractArchives);
settings.init();
// Initialize logging based on settings
@ -140,7 +175,8 @@ MainWindow::MainWindow(QWidget *parent) :
graphics = new Graphics(); // should be before curh->init()
graphics->load();//must be after Content loading but should be in main thread
ConvertOriginalResourceFiles();
ConvertExtractedResourceFiles(splitDefs, convertPcxToPng, deleteOriginals);
ui->mapView->setScene(controller.scene(0));
ui->mapView->setController(&controller);
@ -169,8 +205,8 @@ MainWindow::MainWindow(QWidget *parent) :
show();
//Load map from command line
if(qApp->arguments().size() >= 2)
openMap(qApp->arguments().at(1));
if(!mapFilePath.isEmpty())
openMap(mapFilePath);
}
MainWindow::~MainWindow()

View File

@ -129,6 +129,8 @@ private:
void loadUserSettings();
void saveUserSettings();
void parseCommandLine();
private:
Ui::MainWindow * ui;
ObjectBrowser * objectBrowser = nullptr;
@ -142,4 +144,11 @@ private:
int mapLevel = 0;
std::set<int> catalog;
// command line options
QString mapFilePath; // FilePath to the H3 or VCMI map to open
bool extractArchives = false; // extract original H3 archives into a separate folder
bool splitDefs = false; // splits TwCrPort, CPRSMALL, FlagPort, ITPA, ITPt, Un32 and Un44 into individual PNG's
bool convertPcxToPng = false; // converts single Images (found in Images folder) from .pcx to png.
bool deleteOriginals = false; // delete original files, for the ones splitted / converted.
};

View File

@ -14,12 +14,8 @@
namespace bfs = boost::filesystem;
bool split_def_files = false; // splits TwCrPort, CPRSMALL, FlagPort, ITPA, ITPt, Un32 and Un44 into individual PNG's
bool convert_pcx_to_png = false; // converts single Images (found in Images folder) from .pcx to png.
bool delete_source_files = false; // delete source files after splitting / conversion.
// converts all pcx files from /Images into PNG
void convertPcxToPng()
void ConvertPcxToPng(bool deleteOriginals)
{
bfs::path imagesPath = VCMIDirs::get().userCachePath() / "extracted" / "Images";
bfs::directory_iterator end_iter;
@ -42,7 +38,7 @@ void convertPcxToPng()
bfs::path pngFilePath = imagesPath / (fileStem + ".png");
img.save(QStringFromPath(pngFilePath), "PNG");
if (delete_source_files)
if (deleteOriginals)
bfs::remove(filePath);
}
}
@ -54,7 +50,7 @@ void convertPcxToPng()
}
// splits a def file into individual parts and converts the output to PNG format
void splitDefFile(std::string fileName, bfs::path spritesPath)
void SplitDefFile(std::string fileName, bfs::path spritesPath, bool deleteOriginals)
{
if (CResourceHandler::get()->existsResource(ResourceID("SPRITES/" + fileName)))
{
@ -63,7 +59,7 @@ void splitDefFile(std::string fileName, bfs::path spritesPath)
anim->preload();
anim->exportBitmaps(VCMIDirs::get().userCachePath() / "extracted", true);
if(delete_source_files)
if(deleteOriginals)
bfs::remove(spritesPath / fileName);
}
else
@ -71,26 +67,25 @@ void splitDefFile(std::string fileName, bfs::path spritesPath)
}
// splits def files (TwCrPort, CPRSMALL, FlagPort, ITPA, ITPt, Un32 and Un44), this way faction resources are independent
void splitDefFiles()
void splitDefFiles(bool deleteOriginals)
{
bfs::path extractedPath = VCMIDirs::get().userDataPath() / "extracted";
bfs::path spritesPath = extractedPath / "Sprites";
splitDefFile("TwCrPort.def", spritesPath); // split town creature portraits
splitDefFile("CPRSMALL.def", spritesPath); // split hero army creature portraits
splitDefFile("FlagPort.def", spritesPath); // adventure map dwellings
splitDefFile("ITPA.def", spritesPath); // small town icons
splitDefFile("ITPt.def", spritesPath); // big town icons
splitDefFile("Un32.def", spritesPath); // big town icons
splitDefFile("Un44.def", spritesPath); // big town icons
SplitDefFile("TwCrPort.def", spritesPath, deleteOriginals); // split town creature portraits
SplitDefFile("CPRSMALL.def", spritesPath, deleteOriginals); // split hero army creature portraits
SplitDefFile("FlagPort.def", spritesPath, deleteOriginals); // adventure map dwellings
SplitDefFile("ITPA.def", spritesPath, deleteOriginals); // small town icons
SplitDefFile("ITPt.def", spritesPath, deleteOriginals); // big town icons
SplitDefFile("Un32.def", spritesPath, deleteOriginals); // big town icons
SplitDefFile("Un44.def", spritesPath, deleteOriginals); // big town icons
}
// Splits def files that are shared between factions and converts pcx to bmp
void ConvertOriginalResourceFiles()
void ConvertExtractedResourceFiles(bool splitDefs, bool convertPcxToPng, bool deleteOriginals)
{
if (split_def_files)
splitDefFiles();
if (splitDefs)
splitDefFiles(deleteOriginals);
if (convert_pcx_to_png)
convertPcxToPng();
if (convertPcxToPng)
ConvertPcxToPng(deleteOriginals);
}

View File

@ -10,4 +10,5 @@
*
*/
void ConvertOriginalResourceFiles();
// Splits def files that are shared between factions and converts pcx to bmp
void ConvertExtractedResourceFiles(bool splitDefs, bool convertPcxToPng, bool deleteOriginals);