mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-05-02 02:24:54 +00:00
Add IWD project type.
This commit is contained in:
parent
6ca9485b55
commit
c4a527eb57
@ -9,6 +9,7 @@
|
|||||||
#include "LinkerSearchPaths.h"
|
#include "LinkerSearchPaths.h"
|
||||||
#include "ObjContainer/IPak/IPakWriter.h"
|
#include "ObjContainer/IPak/IPakWriter.h"
|
||||||
#include "ObjContainer/IWD/IWD.h"
|
#include "ObjContainer/IWD/IWD.h"
|
||||||
|
#include "ObjContainer/IWD/IWDWriter.h"
|
||||||
#include "ObjLoading.h"
|
#include "ObjLoading.h"
|
||||||
#include "ObjWriting.h"
|
#include "ObjWriting.h"
|
||||||
#include "SearchPath/SearchPaths.h"
|
#include "SearchPath/SearchPaths.h"
|
||||||
@ -45,7 +46,7 @@ enum class ProjectType
|
|||||||
NONE,
|
NONE,
|
||||||
FASTFILE,
|
FASTFILE,
|
||||||
IPAK,
|
IPAK,
|
||||||
|
IWD,
|
||||||
MAX
|
MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -53,7 +54,7 @@ constexpr const char* PROJECT_TYPE_NAMES[static_cast<unsigned>(ProjectType::MAX)
|
|||||||
"none",
|
"none",
|
||||||
"fastfile",
|
"fastfile",
|
||||||
"ipak",
|
"ipak",
|
||||||
};
|
"iwd"};
|
||||||
|
|
||||||
class LinkerImpl final : public Linker
|
class LinkerImpl final : public Linker
|
||||||
{
|
{
|
||||||
@ -462,6 +463,32 @@ class LinkerImpl final : public Linker
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BuildIWD(const std::string& projectName, const ZoneDefinition& zoneDefinition, SearchPaths& assetSearchPaths) const
|
||||||
|
{
|
||||||
|
const fs::path iwdFolderPath(m_args.GetOutputFolderPathForProject(projectName));
|
||||||
|
auto iwdFilePath(iwdFolderPath);
|
||||||
|
const auto iwdFileName = zoneDefinition.m_name + ".iwd";
|
||||||
|
iwdFilePath.append(iwdFileName);
|
||||||
|
|
||||||
|
fs::create_directories(iwdFolderPath);
|
||||||
|
|
||||||
|
const auto iwdWriter = IWDWriter::Create(iwdFilePath.string(), &assetSearchPaths);
|
||||||
|
for (const auto& assetEntry : zoneDefinition.m_assets)
|
||||||
|
{
|
||||||
|
iwdWriter->AddFile(assetEntry.m_asset_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!iwdWriter->Write())
|
||||||
|
{
|
||||||
|
std::cout << "Writing iwd failed." << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "Created iwd \"" << iwdFilePath.string() << "\"\n";
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool BuildReferencedTargets(const std::string& projectName, const std::string& targetName, const ZoneDefinition& zoneDefinition)
|
bool BuildReferencedTargets(const std::string& projectName, const std::string& targetName, const ZoneDefinition& zoneDefinition)
|
||||||
{
|
{
|
||||||
return std::all_of(zoneDefinition.m_targets_to_build.begin(),
|
return std::all_of(zoneDefinition.m_targets_to_build.begin(),
|
||||||
@ -512,6 +539,10 @@ class LinkerImpl final : public Linker
|
|||||||
result = BuildIPak(projectName, *zoneDefinition, assetSearchPaths);
|
result = BuildIPak(projectName, *zoneDefinition, assetSearchPaths);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ProjectType::IWD:
|
||||||
|
result = BuildIWD(projectName, *zoneDefinition, assetSearchPaths);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(false);
|
assert(false);
|
||||||
result = false;
|
result = false;
|
||||||
|
@ -0,0 +1,105 @@
|
|||||||
|
#include "IWDWriter.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <iostream>
|
||||||
|
#include "../minizip/zip.h"
|
||||||
|
|
||||||
|
class IWDWriterImpl final : public IWDWriter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit IWDWriterImpl(const std::string& iwdFileName, ISearchPath* assetSearchPath)
|
||||||
|
: m_filename(iwdFileName),
|
||||||
|
m_asset_search_path(assetSearchPath),
|
||||||
|
m_files(0)
|
||||||
|
{
|
||||||
|
m_zipfile = zipOpen(m_filename.c_str(), APPEND_STATUS_CREATE);
|
||||||
|
if (!m_zipfile)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Error creating IWD file: \"" + m_filename + "\"");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddFile(std::string fileName) override
|
||||||
|
{
|
||||||
|
m_files.emplace_back(std::move(fileName));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AddFileToArchive(const std::string& fileName, const std::unique_ptr<char []>& fileData, const size_t& fileSize)
|
||||||
|
{
|
||||||
|
zip_fileinfo zi = {};
|
||||||
|
|
||||||
|
if (zipOpenNewFileInZip(m_zipfile, fileName.c_str(), &zi, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION) != ZIP_OK)
|
||||||
|
{
|
||||||
|
zipClose(m_zipfile, NULL);
|
||||||
|
throw std::runtime_error( "Could not open new file in IWD \"" + fileName + "\"\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zipWriteInFileInZip(m_zipfile, fileData.get(), fileSize) != ZIP_OK)
|
||||||
|
{
|
||||||
|
zipClose(m_zipfile, NULL);
|
||||||
|
throw std::runtime_error("Could not write file data to IWD \"" + fileName + "\"\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zipCloseFileInZip(m_zipfile) != ZIP_OK)
|
||||||
|
{
|
||||||
|
zipClose(m_zipfile, NULL);
|
||||||
|
throw std::runtime_error("Could not close file in IWD \"" + fileName + "\"\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<char[]> ReadFileDataFromSearchPath(const std::string& fileName, size_t& fileSize) const
|
||||||
|
{
|
||||||
|
const auto openFile = m_asset_search_path->Open(fileName);
|
||||||
|
if (!openFile.IsOpen())
|
||||||
|
{
|
||||||
|
std::cerr << "Could not open file for writing to IWD \"" << fileName << "\"\n";
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
fileSize = static_cast<size_t>(openFile.m_length);
|
||||||
|
auto fileData = std::make_unique<char[]>(fileSize);
|
||||||
|
openFile.m_stream->read(fileData.get(), fileSize);
|
||||||
|
|
||||||
|
return fileData;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WriteFileData(const std::string& fileName)
|
||||||
|
{
|
||||||
|
size_t fileSize;
|
||||||
|
const auto fileData = ReadFileDataFromSearchPath(fileName, fileSize);
|
||||||
|
if (!fileData)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
AddFileToArchive(fileName, fileData, fileSize);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Write() override
|
||||||
|
{
|
||||||
|
const auto result = std::all_of(m_files.begin(),
|
||||||
|
m_files.end(),
|
||||||
|
[this](const std::string& fileName)
|
||||||
|
{
|
||||||
|
return WriteFileData(fileName);
|
||||||
|
});
|
||||||
|
|
||||||
|
zipClose(m_zipfile, NULL);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const std::string m_filename;
|
||||||
|
|
||||||
|
ISearchPath* m_asset_search_path;
|
||||||
|
std::vector<std::string> m_files;
|
||||||
|
|
||||||
|
zipFile m_zipfile;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unique_ptr<IWDWriter> IWDWriter::Create(const std::string& iwdFileName, ISearchPath* assetSearchPath)
|
||||||
|
{
|
||||||
|
return std::make_unique<IWDWriterImpl>(iwdFileName, assetSearchPath);
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "SearchPath/ISearchPath.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <ostream>
|
||||||
|
|
||||||
|
class IWDWriter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static constexpr auto USE_COMPRESSION = true;
|
||||||
|
|
||||||
|
IWDWriter() = default;
|
||||||
|
virtual ~IWDWriter() = default;
|
||||||
|
|
||||||
|
IWDWriter(const IWDWriter& other) = default;
|
||||||
|
IWDWriter(IWDWriter&& other) noexcept = default;
|
||||||
|
IWDWriter& operator=(const IWDWriter& other) = default;
|
||||||
|
IWDWriter& operator=(IWDWriter&& other) noexcept = default;
|
||||||
|
|
||||||
|
virtual void AddFile(std::string fileName) = 0;
|
||||||
|
virtual bool Write() = 0;
|
||||||
|
|
||||||
|
static std::unique_ptr<IWDWriter> Create(const std::string& iwdFileName, ISearchPath* assetSearchPath);
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user