2
0
mirror of https://github.com/Laupetin/OpenAssetTools.git synced 2025-07-06 03:01:50 +00:00

IW5 support initial commit

This commit is contained in:
Jan
2021-07-23 01:12:36 +02:00
parent c6ea52018a
commit f201dfafd8
102 changed files with 8835 additions and 0 deletions

View File

@ -0,0 +1,27 @@
#define NOMINMAX
#include "AssetDumperAddonMapEnts.h"
#include <algorithm>
using namespace IW5;
bool AssetDumperAddonMapEnts::ShouldDump(XAssetInfo<AddonMapEnts>* asset)
{
return true;
}
bool AssetDumperAddonMapEnts::CanDumpAsRaw()
{
return true;
}
std::string AssetDumperAddonMapEnts::GetFileNameForAsset(Zone* zone, XAssetInfo<AddonMapEnts>* asset)
{
return asset->m_name;
}
void AssetDumperAddonMapEnts::DumpRaw(AssetDumpingContext& context, XAssetInfo<AddonMapEnts>* asset, std::ostream& stream)
{
const auto* addonMapEnts = asset->Asset();
stream.write(addonMapEnts->entityString, std::max(addonMapEnts->numEntityChars - 1, 0));
}

View File

@ -0,0 +1,16 @@
#pragma once
#include "Dumping/AbstractAssetDumper.h"
#include "Game/IW5/IW5.h"
namespace IW5
{
class AssetDumperAddonMapEnts final : public AbstractAssetDumper<AddonMapEnts>
{
protected:
bool ShouldDump(XAssetInfo<AddonMapEnts>* asset) override;
bool CanDumpAsRaw() override;
std::string GetFileNameForAsset(Zone* zone, XAssetInfo<AddonMapEnts>* asset) override;
void DumpRaw(AssetDumpingContext& context, XAssetInfo<AddonMapEnts>* asset, std::ostream& stream) override;
};
}

View File

@ -0,0 +1,62 @@
#include "AssetDumperGfxImage.h"
#include <cassert>
#include "ObjWriting.h"
#include "Image/IwiWriter8.h"
#include "Image/DdsWriter.h"
using namespace IW5;
AssetDumperGfxImage::AssetDumperGfxImage()
{
switch (ObjWriting::Configuration.ImageOutputFormat)
{
case ObjWriting::Configuration_t::ImageOutputFormat_e::DDS:
m_writer = std::make_unique<DdsWriter>();
break;
case ObjWriting::Configuration_t::ImageOutputFormat_e::IWI:
m_writer = std::make_unique<iwi8::IwiWriter>();
break;
default:
assert(false);
m_writer = nullptr;
break;
}
}
bool AssetDumperGfxImage::ShouldDump(XAssetInfo<GfxImage>* asset)
{
const auto* image = asset->Asset();
return image->cardMemory.platform[0] > 0;
}
bool AssetDumperGfxImage::CanDumpAsRaw()
{
return true;
}
std::string AssetDumperGfxImage::GetFileNameForAsset(Zone* zone, XAssetInfo<GfxImage>* asset)
{
std::string cleanAssetName = asset->m_name;
for (auto& c : cleanAssetName)
{
switch (c)
{
case '*':
c = '_';
break;
default:
break;
}
}
return "images/" + cleanAssetName + m_writer->GetFileExtension();
}
void AssetDumperGfxImage::DumpRaw(AssetDumpingContext& context, XAssetInfo<GfxImage>* asset, std::ostream& stream)
{
const auto* image = asset->Asset();
m_writer->DumpImage(stream, image->texture.texture);
}

View File

@ -0,0 +1,24 @@
#pragma once
#include <memory>
#include "Dumping/AbstractAssetDumper.h"
#include "Game/IW5/IW5.h"
#include "Image/IImageWriter.h"
namespace IW5
{
class AssetDumperGfxImage final : public AbstractAssetDumper<GfxImage>
{
std::unique_ptr<IImageWriter> m_writer;
protected:
bool ShouldDump(XAssetInfo<GfxImage>* asset) override;
bool CanDumpAsRaw() override;
std::string GetFileNameForAsset(Zone* zone, XAssetInfo<GfxImage>* asset) override;
void DumpRaw(AssetDumpingContext& context, XAssetInfo<GfxImage>* asset, std::ostream& stream) override;
public:
AssetDumperGfxImage();
};
}

View File

@ -0,0 +1,76 @@
#include "AssetDumperLoadedSound.h"
#include "Sound/WavTypes.h"
using namespace IW5;
bool AssetDumperLoadedSound::ShouldDump(XAssetInfo<LoadedSound>* asset)
{
return true;
}
bool AssetDumperLoadedSound::CanDumpAsRaw()
{
return true;
}
std::string AssetDumperLoadedSound::GetFileNameForAsset(Zone* zone, XAssetInfo<LoadedSound>* asset)
{
return "sound/" + asset->m_name;
}
void AssetDumperLoadedSound::DumpWavPcm(AssetDumpingContext& context, const LoadedSound* asset, std::ostream& stream)
{
const auto riffMasterChunkSize = sizeof(WAV_CHUNK_ID_RIFF)
+ sizeof(uint32_t)
+ sizeof(WAV_WAVE_ID)
+ sizeof(WavChunkHeader)
+ sizeof(WavFormatChunkPcm)
+ sizeof(WavChunkHeader)
+ sizeof(asset->sound.info.data_len);
stream.write(reinterpret_cast<const char*>(&WAV_CHUNK_ID_RIFF), sizeof(WAV_CHUNK_ID_RIFF));
stream.write(reinterpret_cast<const char*>(&riffMasterChunkSize), sizeof(riffMasterChunkSize));
stream.write(reinterpret_cast<const char*>(&WAV_WAVE_ID), sizeof(WAV_WAVE_ID));
const WavChunkHeader formatChunkHeader
{
WAV_CHUNK_ID_FMT,
sizeof(WavFormatChunkPcm)
};
stream.write(reinterpret_cast<const char*>(&formatChunkHeader), sizeof(formatChunkHeader));
WavFormatChunkPcm formatChunk
{
WavFormat::PCM,
static_cast<uint16_t>(asset->sound.info.channels),
asset->sound.info.rate,
asset->sound.info.rate * asset->sound.info.channels * asset->sound.info.bits / 8,
static_cast<uint16_t>(asset->sound.info.block_size),
static_cast<uint16_t>(asset->sound.info.bits)
};
stream.write(reinterpret_cast<const char*>(&formatChunk), sizeof(formatChunk));
const WavChunkHeader dataChunkHeader
{
WAV_CHUNK_ID_DATA,
asset->sound.info.data_len
};
stream.write(reinterpret_cast<const char*>(&dataChunkHeader), sizeof(dataChunkHeader));
stream.write(asset->sound.data, asset->sound.info.data_len);
}
void AssetDumperLoadedSound::DumpRaw(AssetDumpingContext& context, XAssetInfo<LoadedSound>* asset, std::ostream& stream)
{
const auto* loadedSound = asset->Asset();
switch (static_cast<WavFormat>(loadedSound->sound.info.format))
{
case WavFormat::PCM:
DumpWavPcm(context, loadedSound, stream);
break;
default:
printf("Unknown format %i for loaded sound: %s\n", loadedSound->sound.info.format, loadedSound->name);
break;
}
}

View File

@ -0,0 +1,17 @@
#pragma once
#include "Dumping/AbstractAssetDumper.h"
#include "Game/IW5/IW5.h"
namespace IW5
{
class AssetDumperLoadedSound final : public AbstractAssetDumper<LoadedSound>
{
static void DumpWavPcm(AssetDumpingContext& context, const LoadedSound* asset, std::ostream& stream);
protected:
bool ShouldDump(XAssetInfo<LoadedSound>* asset) override;
bool CanDumpAsRaw() override;
std::string GetFileNameForAsset(Zone* zone, XAssetInfo<LoadedSound>* asset) override;
void DumpRaw(AssetDumpingContext& context, XAssetInfo<LoadedSound>* asset, std::ostream& stream) override;
};
}

View File

@ -0,0 +1,53 @@
#include "AssetDumperLocalizeEntry.h"
#include <fstream>
#include <filesystem>
#include "Localize/LocalizeCommon.h"
#include "Dumping/Localize/StringFileDumper.h"
using namespace IW5;
namespace fs = std::filesystem;
void AssetDumperLocalizeEntry::DumpPool(AssetDumpingContext& context, AssetPool<LocalizeEntry>* pool)
{
if (pool->m_asset_lookup.empty())
return;
const auto language = LocalizeCommon::GetNameOfLanguage(context.m_zone->m_language);
fs::path stringsPath(context.m_base_path);
stringsPath.append(language);
stringsPath.append("localizedstrings");
create_directories(stringsPath);
auto stringFilePath(stringsPath);
stringFilePath.append(context.m_zone->m_name + ".str");
std::ofstream stringFile(stringFilePath, std::fstream::out | std::ofstream::binary);
if (stringFile.is_open())
{
StringFileDumper stringFileDumper(context.m_zone, stringFile);
stringFileDumper.SetLanguageName(language);
// Magic string. Original string files do have this config file. The purpose of the config file is unknown though.
stringFileDumper.SetConfigFile(R"(C:\trees\cod3\cod3\bin\StringEd.cfg)");
stringFileDumper.SetNotes("");
for (auto* localizeEntry : *pool)
{
stringFileDumper.WriteLocalizeEntry(localizeEntry->m_name, localizeEntry->Asset()->value);
}
stringFileDumper.Finalize();
stringFile.close();
}
else
{
printf("Could not create string file for dumping localized strings of zone '%s'\n", context.m_zone->m_name.c_str());
}
}

View File

@ -0,0 +1,13 @@
#pragma once
#include "Dumping/AbstractAssetDumper.h"
#include "Game/IW5/IW5.h"
namespace IW5
{
class AssetDumperLocalizeEntry final : public IAssetDumper<LocalizeEntry>
{
public:
void DumpPool(AssetDumpingContext& context, AssetPool<LocalizeEntry>* pool) override;
};
}

View File

@ -0,0 +1,70 @@
#include "AssetDumperRawFile.h"
#include <zlib.h>
#include <stdexcept>
using namespace IW5;
bool AssetDumperRawFile::ShouldDump(XAssetInfo<RawFile>* asset)
{
return true;
}
bool AssetDumperRawFile::CanDumpAsRaw()
{
return true;
}
std::string AssetDumperRawFile::GetFileNameForAsset(Zone* zone, XAssetInfo<RawFile>* asset)
{
return asset->m_name;
}
void AssetDumperRawFile::DumpRaw(AssetDumpingContext& context, XAssetInfo<RawFile>* asset, std::ostream& stream)
{
const auto* rawFile = asset->Asset();
if (rawFile->compressedLen > 0)
{
z_stream_s zs{};
zs.zalloc = Z_NULL;
zs.zfree = Z_NULL;
zs.opaque = Z_NULL;
zs.avail_in = 0;
zs.next_in = Z_NULL;
int ret = inflateInit(&zs);
if (ret != Z_OK)
{
throw std::runtime_error("Initializing inflate failed");
}
zs.next_in = reinterpret_cast<const Bytef*>(rawFile->data.compressedBuffer);
zs.avail_in = rawFile->compressedLen;
Bytef buffer[0x1000];
while (zs.avail_in > 0)
{
zs.next_out = buffer;
zs.avail_out = sizeof buffer;
ret = inflate(&zs, Z_SYNC_FLUSH);
if (ret < 0)
{
printf("Inflate failed for dumping rawfile '%s'\n", rawFile->name);
inflateEnd(&zs);
return;
}
stream.write(reinterpret_cast<char*>(buffer), sizeof buffer - zs.avail_out);
}
inflateEnd(&zs);
}
else if (rawFile->len > 0)
{
stream.write(rawFile->data.buffer, rawFile->len);
}
}

View File

@ -0,0 +1,16 @@
#pragma once
#include "Dumping/AbstractAssetDumper.h"
#include "Game/IW5/IW5.h"
namespace IW5
{
class AssetDumperRawFile final : public AbstractAssetDumper<RawFile>
{
protected:
bool ShouldDump(XAssetInfo<RawFile>* asset) override;
bool CanDumpAsRaw() override;
std::string GetFileNameForAsset(Zone* zone, XAssetInfo<RawFile>* asset) override;
void DumpRaw(AssetDumpingContext& context, XAssetInfo<RawFile>* asset, std::ostream& stream) override;
};
}

View File

@ -0,0 +1,37 @@
#include "AssetDumperStringTable.h"
#include "Csv/CsvStream.h"
using namespace IW5;
bool AssetDumperStringTable::ShouldDump(XAssetInfo<StringTable>* asset)
{
return true;
}
bool AssetDumperStringTable::CanDumpAsRaw()
{
return true;
}
std::string AssetDumperStringTable::GetFileNameForAsset(Zone* zone, XAssetInfo<StringTable>* asset)
{
return asset->m_name;
}
void AssetDumperStringTable::DumpRaw(AssetDumpingContext& context, XAssetInfo<StringTable>* asset, std::ostream& stream)
{
const auto* stringTable = asset->Asset();
CsvOutputStream csv(stream);
for (auto row = 0; row < stringTable->rowCount; row++)
{
for (auto column = 0; column < stringTable->columnCount; column++)
{
const auto* cell = &stringTable->values[column + row * stringTable->columnCount];
csv.WriteColumn(cell->string);
}
csv.NextRow();
}
}

View File

@ -0,0 +1,17 @@
#pragma once
#include "Dumping/AbstractAssetDumper.h"
#include "Game/IW5/IW5.h"
namespace IW5
{
class AssetDumperStringTable final : public AbstractAssetDumper<StringTable>
{
protected:
bool ShouldDump(XAssetInfo<StringTable>* asset) override;
bool CanDumpAsRaw() override;
std::string GetFileNameForAsset(Zone* zone, XAssetInfo<StringTable>* asset) override;
void DumpRaw(AssetDumpingContext& context, XAssetInfo<StringTable>* asset, std::ostream& stream) override;
};
}