2017-10-30 23:44:40 +01:00
|
|
|
#include "loaders/LoaderIMG.hpp"
|
2013-07-02 08:40:43 +02:00
|
|
|
|
2016-08-09 14:03:38 +02:00
|
|
|
#include <boost/algorithm/string/predicate.hpp>
|
2017-10-30 23:44:40 +01:00
|
|
|
#include <cstdio>
|
|
|
|
|
2018-06-21 16:49:05 +02:00
|
|
|
#include "rw/debug.hpp"
|
2013-07-02 08:06:03 +02:00
|
|
|
|
2016-09-09 22:13:21 +02:00
|
|
|
LoaderIMG::LoaderIMG() : m_version(GTAIIIVC), m_assetCount(0) {
|
2013-07-02 08:06:03 +02:00
|
|
|
}
|
|
|
|
|
2017-11-02 05:01:00 +01:00
|
|
|
bool LoaderIMG::load(const rwfs::path& filepath) {
|
|
|
|
auto dirPath = filepath;
|
|
|
|
dirPath.replace_extension(".dir");
|
2016-09-09 22:13:21 +02:00
|
|
|
|
2017-11-02 05:01:00 +01:00
|
|
|
FILE* fp = fopen(dirPath.string().c_str(), "rb");
|
2016-09-09 22:13:21 +02:00
|
|
|
if (fp) {
|
|
|
|
fseek(fp, 0, SEEK_END);
|
|
|
|
unsigned long fileSize = ftell(fp);
|
|
|
|
fseek(fp, 0, SEEK_SET);
|
|
|
|
|
|
|
|
m_assetCount = fileSize / 32;
|
|
|
|
m_assets.resize(m_assetCount);
|
|
|
|
|
|
|
|
if ((m_assetCount = fread(&m_assets[0], sizeof(LoaderIMGFile),
|
|
|
|
m_assetCount, fp)) != fileSize / 32) {
|
|
|
|
m_assets.resize(m_assetCount);
|
2017-10-30 23:44:40 +01:00
|
|
|
RW_ERROR("Error reading records in IMG archive");
|
2016-09-09 22:13:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
fclose(fp);
|
2017-11-02 05:01:00 +01:00
|
|
|
auto imgPath = filepath;
|
|
|
|
imgPath.replace_extension(".img");
|
|
|
|
m_archive = imgPath;
|
2016-09-09 22:13:21 +02:00
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
2013-07-02 08:06:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Get the information of a asset in the examining archive
|
2016-09-09 22:13:21 +02:00
|
|
|
bool LoaderIMG::findAssetInfo(const std::string& assetname,
|
|
|
|
LoaderIMGFile& out) {
|
2018-01-26 16:47:07 +01:00
|
|
|
for (auto &asset : m_assets) {
|
|
|
|
if (boost::iequals(asset.name, assetname)) {
|
|
|
|
out = asset;
|
2016-09-09 22:13:21 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
2013-07-02 08:06:03 +02:00
|
|
|
}
|
|
|
|
|
2018-08-05 18:28:59 +02:00
|
|
|
std::unique_ptr<char[]> LoaderIMG::loadToMemory(const std::string& assetname) {
|
2016-09-09 22:13:21 +02:00
|
|
|
LoaderIMGFile assetInfo;
|
|
|
|
bool found = findAssetInfo(assetname, assetInfo);
|
|
|
|
|
|
|
|
if (!found) {
|
2017-10-30 23:44:40 +01:00
|
|
|
RW_ERROR("Asset '" << assetname << "' not found!");
|
2016-09-09 22:13:21 +02:00
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2017-11-02 05:01:00 +01:00
|
|
|
auto imgName = m_archive;
|
2016-09-09 22:13:21 +02:00
|
|
|
|
2017-11-02 05:01:00 +01:00
|
|
|
FILE* fp = fopen(imgName.string().c_str(), "rb");
|
2016-09-09 22:13:21 +02:00
|
|
|
if (fp) {
|
2018-08-05 18:28:59 +02:00
|
|
|
auto raw_data = std::make_unique<char[]>(assetInfo.size * 2048);
|
2016-09-09 22:13:21 +02:00
|
|
|
|
|
|
|
fseek(fp, assetInfo.offset * 2048, SEEK_SET);
|
2018-08-05 18:28:59 +02:00
|
|
|
if (fread(raw_data.get(), 2048, assetInfo.size, fp) != assetInfo.size) {
|
2017-10-30 23:44:40 +01:00
|
|
|
RW_ERROR("Error reading asset " << assetInfo.name);
|
2016-09-09 22:13:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
fclose(fp);
|
|
|
|
return raw_data;
|
|
|
|
} else
|
2018-08-05 18:28:59 +02:00
|
|
|
return nullptr;
|
2013-07-02 08:06:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Writes the contents of assetname to filename
|
2016-09-09 22:13:21 +02:00
|
|
|
bool LoaderIMG::saveAsset(const std::string& assetname,
|
|
|
|
const std::string& filename) {
|
2018-08-05 18:28:59 +02:00
|
|
|
auto raw_data = loadToMemory(assetname);
|
2016-09-09 22:13:21 +02:00
|
|
|
if (!raw_data) return false;
|
|
|
|
|
|
|
|
FILE* dumpFile = fopen(filename.c_str(), "wb");
|
|
|
|
if (dumpFile) {
|
|
|
|
LoaderIMGFile asset;
|
|
|
|
if (findAssetInfo(assetname, asset)) {
|
2018-08-05 18:28:59 +02:00
|
|
|
fwrite(raw_data.get(), 2048, asset.size, dumpFile);
|
2016-09-09 22:13:21 +02:00
|
|
|
printf("=> IMG: Saved %s to disk with filename %s\n",
|
|
|
|
assetname.c_str(), filename.c_str());
|
|
|
|
}
|
|
|
|
fclose(dumpFile);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
2013-07-02 08:06:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Get the information of an asset by its index
|
2016-09-09 22:13:21 +02:00
|
|
|
const LoaderIMGFile& LoaderIMG::getAssetInfoByIndex(size_t index) const {
|
|
|
|
return m_assets[index];
|
2013-07-02 08:06:03 +02:00
|
|
|
}
|
|
|
|
|
2016-09-09 22:13:21 +02:00
|
|
|
uint32_t LoaderIMG::getAssetCount() const {
|
|
|
|
return m_assetCount;
|
2013-07-02 08:06:03 +02:00
|
|
|
}
|