2
0
mirror of https://github.com/Laupetin/OpenAssetTools.git synced 2026-01-09 18:21:49 +00:00
Files
OpenAssetTools/src/ImageConverter/ImageConverter.cpp

209 lines
5.8 KiB
C++

#include "ImageConverter.h"
#include "Game/IGame.h"
#include "Image/DdsLoader.h"
#include "Image/DdsWriter.h"
#include "Image/IwiLoader.h"
#include "Image/IwiWriter13.h"
#include "Image/IwiWriter27.h"
#include "Image/IwiWriter6.h"
#include "Image/IwiWriter8.h"
#include "Image/Texture.h"
#include "ImageConverterArgs.h"
#include "Utils/Logging/Log.h"
#include "Utils/StringUtils.h"
#include <assert.h>
#include <filesystem>
#include <format>
#include <fstream>
#include <iostream>
#include <optional>
namespace fs = std::filesystem;
using namespace image;
namespace
{
constexpr auto EXTENSION_IWI = ".iwi";
constexpr auto EXTENSION_DDS = ".dds";
class ImageConverterImpl final : public ImageConverter
{
public:
ImageConverterImpl()
: m_game_to_convert_to(std::nullopt)
{
}
bool Start(const int argc, const char** argv) override
{
con::init();
auto shouldContinue = true;
if (!m_args.ParseArgs(argc, argv, shouldContinue))
return false;
if (!shouldContinue)
return true;
m_game_to_convert_to = m_args.m_game_to_convert_to;
for (const auto& file : m_args.m_files_to_convert)
Convert(file);
return true;
}
private:
void Convert(const std::string& file)
{
const fs::path filePath(file);
auto extension = filePath.extension().string();
utils::MakeStringLowerCase(extension);
if (extension == EXTENSION_IWI)
ConvertIwi(filePath);
else if (extension == EXTENSION_DDS)
ConvertDds(filePath);
else
con::error("Unsupported extension {}", extension);
}
bool ConvertIwi(const fs::path& iwiPath)
{
std::ifstream file(iwiPath, std::ios::in | std::ios::binary);
if (!file.is_open())
{
con::error("Failed to open input file {}", iwiPath.string());
return false;
}
const auto loadResult = image::LoadIwi(file);
if (!loadResult)
return false;
auto outPath = iwiPath;
outPath.replace_extension(".dds");
std::ofstream outFile(outPath, std::ios::out | std::ios::binary);
if (!outFile.is_open())
{
con::error("Failed to open output file {}", outPath.string());
return false;
}
m_dds_writer.DumpImage(outFile, loadResult->m_texture.get());
return true;
}
bool ConvertDds(const fs::path& ddsPath)
{
std::ifstream file(ddsPath, std::ios::in | std::ios::binary);
if (!file.is_open())
{
con::error("Failed to open input file {}", ddsPath.string());
return false;
}
const auto texture = image::LoadDds(file);
if (!texture)
return false;
if (!EnsureIwiWriterIsPresent())
return false;
auto outPath = ddsPath;
outPath.replace_extension(".iwi");
std::ofstream outFile(outPath, std::ios::out | std::ios::binary);
if (!outFile.is_open())
{
con::error("Failed to open output file {}", outPath.string());
return false;
}
m_iwi_writer->DumpImage(outFile, texture.get());
return true;
}
bool EnsureIwiWriterIsPresent()
{
if (m_iwi_writer)
return true;
if (!m_game_to_convert_to && !ShowGameTui())
return false;
switch (*m_game_to_convert_to)
{
case GameId::IW3:
m_iwi_writer = std::make_unique<image::iwi6::IwiWriter>();
break;
case GameId::IW4:
case GameId::IW5:
m_iwi_writer = std::make_unique<image::iwi8::IwiWriter>();
break;
case GameId::T5:
m_iwi_writer = std::make_unique<image::iwi13::IwiWriter>();
break;
case GameId::T6:
m_iwi_writer = std::make_unique<image::iwi27::IwiWriter>();
break;
default:
assert(false);
return false;
}
return true;
}
bool ShowGameTui()
{
con::info("Select the game to convert to:");
con::info(" 1 - Call Of Duty 4: Modern Warfare (IW3)");
con::info(" 2 - Call Of Duty: Modern Warfare 2 (IW4)");
con::info(" 3 - Call Of Duty: Modern Warfare 3 (IW5)");
con::info(" 4 - Call Of Duty: Black Ops (T5)");
con::info(" 5 - Call Of Duty: Black Ops 2 (T6)");
unsigned num;
std::cin >> num;
switch (num)
{
case 1:
m_game_to_convert_to = GameId::IW3;
break;
case 2:
m_game_to_convert_to = GameId::IW4;
break;
case 3:
m_game_to_convert_to = GameId::IW5;
break;
case 4:
m_game_to_convert_to = GameId::T5;
break;
case 5:
m_game_to_convert_to = GameId::T6;
break;
default:
con::error("Invalid input");
return false;
}
return true;
}
ImageConverterArgs m_args;
std::optional<GameId> m_game_to_convert_to;
DdsWriter m_dds_writer;
std::unique_ptr<ImageWriter> m_iwi_writer;
};
} // namespace
std::unique_ptr<ImageConverter> ImageConverter::Create()
{
return std::make_unique<ImageConverterImpl>();
}