mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-26 03:52:01 +02:00
Working Extractor, DefSplitter and pcx convertor
This commit is contained in:
parent
3b072b80d5
commit
93cf2682f3
@ -59,6 +59,7 @@
|
||||
#include "../lib/serializer/Connection.h"
|
||||
#include "CServerHandler.h"
|
||||
#include "gui/NotificationHandler.h"
|
||||
#include "resourceExtractor/ResourceConverter.h"
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
|
||||
@ -253,6 +254,7 @@ int main(int argc, char * argv[])
|
||||
|
||||
// Init filesystem and settings
|
||||
preinitDLL(::console);
|
||||
|
||||
settings.init();
|
||||
Settings session = settings.write["session"];
|
||||
auto setSettingBool = [](std::string key, std::string arg) {
|
||||
@ -464,6 +466,8 @@ int main(int argc, char * argv[])
|
||||
CCS->curh = new CCursorHandler();
|
||||
graphics = new Graphics(); // should be before curh->init()
|
||||
|
||||
ConvertOriginalResourceFiles();
|
||||
|
||||
CCS->curh->initCursor();
|
||||
logGlobal->info("Screen handler: %d ms", pomtime.getDiff());
|
||||
pomtime.getDiff();
|
||||
|
@ -54,6 +54,8 @@ set(client_SRCS
|
||||
lobby/OptionsTab.cpp
|
||||
lobby/RandomMapTab.cpp
|
||||
lobby/SelectionTab.cpp
|
||||
|
||||
resourceExtractor/ResourceConverter.cpp
|
||||
|
||||
CBitmapHandler.cpp
|
||||
CreatureCostBox.cpp
|
||||
@ -128,6 +130,8 @@ set(client_HEADERS
|
||||
lobby/OptionsTab.h
|
||||
lobby/RandomMapTab.h
|
||||
lobby/SelectionTab.h
|
||||
|
||||
resourceExtractor/ResourceConverter.h
|
||||
|
||||
CBitmapHandler.h
|
||||
CreatureCostBox.h
|
||||
|
@ -951,7 +951,7 @@ void CAnimation::initFromJson(const JsonNode & config)
|
||||
}
|
||||
}
|
||||
|
||||
void CAnimation::exportBitmaps(const boost::filesystem::path& path) const
|
||||
void CAnimation::exportBitmaps(const boost::filesystem::path& path, bool prependResourceName) const
|
||||
{
|
||||
if(images.empty())
|
||||
{
|
||||
@ -959,7 +959,7 @@ void CAnimation::exportBitmaps(const boost::filesystem::path& path) const
|
||||
return;
|
||||
}
|
||||
|
||||
boost::filesystem::path actualPath = path / "SPRITES" / name;
|
||||
boost::filesystem::path actualPath = path / "Sprites" / name;
|
||||
boost::filesystem::create_directories(actualPath);
|
||||
|
||||
size_t counter = 0;
|
||||
@ -974,9 +974,13 @@ void CAnimation::exportBitmaps(const boost::filesystem::path& path) const
|
||||
const auto img = imagePair.second;
|
||||
|
||||
boost::format fmt("%d_%d.bmp");
|
||||
fmt % group % frame;
|
||||
fmt% group% frame;
|
||||
std::string fileName = fmt.str();
|
||||
if (prependResourceName)
|
||||
fileName = name + "_" + fileName;
|
||||
|
||||
img->exportBitmap(actualPath / fileName);
|
||||
|
||||
img->exportBitmap(actualPath / fmt.str());
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
|
@ -122,7 +122,7 @@ public:
|
||||
|
||||
std::shared_ptr<IImage> getImage(size_t frame, size_t group=0, bool verbose=true) const;
|
||||
|
||||
void exportBitmaps(const boost::filesystem::path & path) const;
|
||||
void exportBitmaps(const boost::filesystem::path & path, bool prependResourceName = false) const;
|
||||
|
||||
//all available frames
|
||||
void load ();
|
||||
|
126
client/resourceExtractor/ResourceConverter.cpp
Normal file
126
client/resourceExtractor/ResourceConverter.cpp
Normal file
@ -0,0 +1,126 @@
|
||||
#include "StdInc.h"
|
||||
|
||||
#include "ResourceConverter.h"
|
||||
|
||||
#include "../lib/JsonNode.h"
|
||||
#include "../lib/VCMIDirs.h"
|
||||
#include "../lib/filesystem/Filesystem.h"
|
||||
|
||||
#include "SDL.h"
|
||||
#include "./gui/CAnimation.h"
|
||||
#include "CBitmapHandler.h"
|
||||
|
||||
#include "boost/filesystem/path.hpp"
|
||||
#include "boost/locale.hpp"
|
||||
|
||||
namespace bfs = boost::filesystem;
|
||||
|
||||
bool split_def_files = 1;
|
||||
bool convert_pcx_to_bmp = 1; // converts Images from .pcx to bmp. Can be used when you have .pcx converted already
|
||||
bool delete_source_files = 1; // delete source files or leave a copy in place.
|
||||
|
||||
// converts all pcx files into bmp (H3 saves images as .pcx)
|
||||
void convertPcxToBmp()
|
||||
{
|
||||
bfs::path extractedPath = VCMIDirs::get().userDataPath() / "extracted";
|
||||
bfs::path imagesPath = extractedPath / "Images";
|
||||
|
||||
bfs::directory_iterator end_iter;
|
||||
|
||||
for ( bfs::directory_iterator dir_itr(imagesPath); dir_itr != end_iter; ++dir_itr )
|
||||
{
|
||||
try
|
||||
{
|
||||
if ( bfs::is_regular_file( dir_itr->status() ) )
|
||||
{
|
||||
std::string filename = dir_itr->path().filename().string();
|
||||
filename = boost::locale::to_lower(filename);
|
||||
|
||||
if(filename.find(".pcx") != std::string::npos)
|
||||
{
|
||||
SDL_Surface *bitmap;
|
||||
|
||||
bitmap = BitmapHandler::loadBitmap(filename);
|
||||
|
||||
if(delete_source_files)
|
||||
bfs::remove(imagesPath / filename);
|
||||
|
||||
bfs::path outFilePath = imagesPath / filename;
|
||||
outFilePath.replace_extension(".bmp");
|
||||
SDL_SaveBMP(bitmap, outFilePath.string().c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logGlobal->info(dir_itr->path().filename().string() + " [other]\n");
|
||||
}
|
||||
}
|
||||
catch ( const std::exception & ex )
|
||||
{
|
||||
logGlobal->info(dir_itr->path().filename().string() + " " + ex.what() + "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// splits a def file into individual parts
|
||||
void splitDefFile(std::string fileName, bfs::path spritesPath)
|
||||
{
|
||||
if (CResourceHandler::get()->existsResource(ResourceID("SPRITES/" + fileName)))
|
||||
{
|
||||
std::string URI = fileName;
|
||||
std::unique_ptr<CAnimation> anim = make_unique<CAnimation>(URI);
|
||||
anim->preload();
|
||||
anim->exportBitmaps(VCMIDirs::get().userCachePath() / "extracted", true);
|
||||
|
||||
if(delete_source_files)
|
||||
bfs::remove(spritesPath / fileName);
|
||||
}
|
||||
else
|
||||
logGlobal->error("Def File Split error! " + fileName);
|
||||
}
|
||||
|
||||
// split def files, this way faction resources are independent
|
||||
void splitDefFiles()
|
||||
{
|
||||
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
|
||||
}
|
||||
|
||||
// Splits def files that are shared between factions and converts pcx to bmp
|
||||
void ConvertOriginalResourceFiles()
|
||||
{
|
||||
if (split_def_files)
|
||||
splitDefFiles();
|
||||
|
||||
if (convert_pcx_to_bmp)
|
||||
convertPcxToBmp();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
13
client/resourceExtractor/ResourceConverter.h
Normal file
13
client/resourceExtractor/ResourceConverter.h
Normal file
@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
/*
|
||||
* VCMI_Lib.cpp, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
|
||||
void ConvertOriginalResourceFiles();
|
@ -10,6 +10,7 @@
|
||||
#include "StdInc.h"
|
||||
#include "CArchiveLoader.h"
|
||||
|
||||
#include "VCMIDirs.h"
|
||||
#include "CFileInputStream.h"
|
||||
#include "CCompressedStream.h"
|
||||
|
||||
@ -17,13 +18,17 @@
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
namespace bfs = boost::filesystem;
|
||||
|
||||
const bool extractArchives = 1;
|
||||
|
||||
ArchiveEntry::ArchiveEntry()
|
||||
: offset(0), fullSize(0), compressedSize(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CArchiveLoader::CArchiveLoader(std::string _mountPoint, boost::filesystem::path _archive) :
|
||||
CArchiveLoader::CArchiveLoader(std::string _mountPoint, bfs::path _archive) :
|
||||
archive(std::move(_archive)),
|
||||
mountPoint(std::move(_mountPoint))
|
||||
{
|
||||
@ -77,6 +82,28 @@ void CArchiveLoader::initLODArchive(const std::string &mountPoint, CFileInputStr
|
||||
|
||||
// Add lod entry to local entries map
|
||||
entries[ResourceID(mountPoint + entry.name)] = entry;
|
||||
|
||||
if(extractArchives)
|
||||
{
|
||||
si64 currentPosition = fileStream.tell(); // save filestream position
|
||||
|
||||
boost::locale::generator gen;
|
||||
std::locale::global(gen("")); // Create locale generator
|
||||
|
||||
std::string fName = filename;
|
||||
boost::to_upper(fName);
|
||||
|
||||
if(fName.find(".PCX") != std::string::npos)
|
||||
extractToFolder("Images", mountPoint, entry);
|
||||
else if ((fName.find(".DEF") != std::string::npos ) || (fName.find(".MSK") != std::string::npos) || (fName.find(".FNT") != std::string::npos) || (fName.find(".PAL") != std::string::npos))
|
||||
extractToFolder("Sprites", mountPoint, entry);
|
||||
else if ((fName.find(".h3c") != std::string::npos))
|
||||
extractToFolder("Sprites", mountPoint, entry);
|
||||
else
|
||||
extractToFolder("Misc", mountPoint, entry);
|
||||
|
||||
fileStream.seek(currentPosition); // restore filestream position
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -112,6 +139,9 @@ void CArchiveLoader::initVIDArchive(const std::string &mountPoint, CFileInputStr
|
||||
auto it = offsets.find(entry.second.offset);
|
||||
it++;
|
||||
entry.second.fullSize = *it - entry.second.offset;
|
||||
|
||||
if(extractArchives)
|
||||
extractToFolder("Video", fileStream, entry.second);
|
||||
}
|
||||
}
|
||||
|
||||
@ -139,6 +169,9 @@ void CArchiveLoader::initSNDArchive(const std::string &mountPoint, CFileInputStr
|
||||
entry.fullSize = reader.readInt32();
|
||||
entry.compressedSize = 0;
|
||||
entries[ResourceID(mountPoint + entry.name)] = entry;
|
||||
|
||||
if(extractArchives)
|
||||
extractToFolder("Sound", fileStream, entry);
|
||||
}
|
||||
}
|
||||
|
||||
@ -182,4 +215,48 @@ std::unordered_set<ResourceID> CArchiveLoader::getFilteredFiles(std::function<bo
|
||||
return foundID;
|
||||
}
|
||||
|
||||
void CArchiveLoader::extractToFolder( std::string outputSubFolder, CFileInputStream& fileStream, ArchiveEntry entry)
|
||||
{
|
||||
si64 currentPosition = fileStream.tell(); // save filestream position
|
||||
|
||||
std::unique_ptr<char[]> data = std::unique_ptr<char[]>(new char[entry.fullSize]);
|
||||
fileStream.seek(entry.offset);
|
||||
fileStream.read((ui8*)data.get(), entry.fullSize);
|
||||
|
||||
bfs::path extractedFilePath = createExtractedFilePath(outputSubFolder, entry.name);
|
||||
|
||||
// writeToOutputFile
|
||||
std::ofstream out(extractedFilePath.string(), std::ofstream::binary);
|
||||
out.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
||||
out.write(data.get(), entry.fullSize);
|
||||
|
||||
fileStream.seek(currentPosition); // restore filestream position
|
||||
}
|
||||
|
||||
void CArchiveLoader::extractToFolder( std::string outputSubFolder, const std::string& mountPoint, ArchiveEntry entry)
|
||||
{
|
||||
|
||||
std::unique_ptr<CInputStream> & inputStream = load(ResourceID(mountPoint + entry.name));
|
||||
|
||||
std::unique_ptr<char[]> data = std::unique_ptr<char[]>(new char[entry.fullSize]);
|
||||
inputStream->read((ui8*)data.get(), entry.fullSize);
|
||||
|
||||
bfs::path extractedFilePath = createExtractedFilePath(outputSubFolder, entry.name);
|
||||
|
||||
// writeToOutputFile
|
||||
std::ofstream out(extractedFilePath.string(), std::ofstream::binary);
|
||||
out.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
||||
out.write(data.get(), entry.fullSize);
|
||||
}
|
||||
|
||||
bfs::path createExtractedFilePath(std::string outputSubFolder, std::string entryName)
|
||||
{
|
||||
bfs::path extractionFolderPath = VCMIDirs::get().userCachePath() / "extracted" / outputSubFolder;
|
||||
bfs::path extractedFilePath = extractionFolderPath / entryName;
|
||||
|
||||
bfs::create_directories(extractionFolderPath);
|
||||
|
||||
return extractedFilePath;
|
||||
}
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -64,6 +64,10 @@ public:
|
||||
std::string getMountPoint() const override;
|
||||
void updateFilteredFiles(std::function<bool(const std::string &)> filter) const override {}
|
||||
std::unordered_set<ResourceID> getFilteredFiles(std::function<bool(const ResourceID &)> filter) const override;
|
||||
/** Extracts one archive entry to the specified subfolder. Used for Video and Sound */
|
||||
void extractToFolder(std::string outputSubFolder, CFileInputStream & fileStream, ArchiveEntry entry);
|
||||
/** Extracts one archive entry to the specified subfolder. Used for Images, Sprites, etc */
|
||||
void extractToFolder(std::string outputSubFolder, const std::string &mountPoint, ArchiveEntry entry);
|
||||
|
||||
private:
|
||||
/**
|
||||
@ -96,4 +100,7 @@ private:
|
||||
std::unordered_map<ResourceID, ArchiveEntry> entries;
|
||||
};
|
||||
|
||||
/** Constructs the file path for the extracted file. Creates the subfolder hierarchy aswell **/
|
||||
boost::filesystem::path createExtractedFilePath(std::string outputSubFolder, std::string entryName);
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
Loading…
x
Reference in New Issue
Block a user