Sfoglia il codice sorgente

Resource extractor "enablers" are now command line options
In VCMI_lib the extractArchives will be passed all the way down the call chain!

krs 2 anni fa
parent
commit
eecaa20693

+ 4 - 4
lib/VCMI_Lib.cpp

@@ -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();

+ 3 - 3
lib/VCMI_Lib.h

@@ -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);
 
 

+ 3 - 3
lib/filesystem/CArchiveLoader.cpp

@@ -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);
 

+ 5 - 1
lib/filesystem/CArchiveLoader.h

@@ -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 **/

+ 8 - 7
lib/filesystem/Filesystem.cpp

@@ -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();
 }

+ 8 - 4
lib/filesystem/Filesystem.h

@@ -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:

+ 41 - 5
mapeditor/mainwindow.cpp

@@ -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()

+ 9 - 0
mapeditor/mainwindow.h

@@ -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.
 };

+ 17 - 22
mapeditor/resourceExtractor/ResourceConverter.cpp

@@ -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);
 }

+ 2 - 1
mapeditor/resourceExtractor/ResourceConverter.h

@@ -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);