Use UTF-8 exclusively internally

This removes SystemString, SystemChar, etc.
All filepaths and log strings are assumed to be UTF-8,
with conversions to UTF-16 for Windows APIs as appropriate.

Updates amuse, athena, boo, kabufua and nod
This commit is contained in:
Luke Street 2021-06-30 14:20:45 -04:00
parent 6e12554026
commit 9ca1a38171
160 changed files with 2029 additions and 2753 deletions

View File

@ -36,7 +36,7 @@ void LoadAssetMap(athena::io::MemoryReader& ar) {
if (magic != FOURCC('AIDM'))
Log.report(
logvisor::Warning,
FMT_STRING(_SYS_STR("Unable to load asset map; Assets will not have proper filenames for most files.")));
FMT_STRING("Unable to load asset map; Assets will not have proper filenames for most files."));
else {
uint32_t assetCount = ar.readUint32Big();
g_AssetNameMap.reserve(assetCount);
@ -67,7 +67,7 @@ void InitAssetNameMap() {
} else {
Log.report(
logvisor::Warning,
FMT_STRING(_SYS_STR("AssetNameMap32 unavailable; Assets will not have proper filenames for most files.")));
FMT_STRING("AssetNameMap32 unavailable; Assets will not have proper filenames for most files."));
}
/* Now load the 64bit map for MP3 */
if (ASSET_NAME_MP64_DECOMPRESSED_SZ != 0u) {
@ -80,7 +80,7 @@ void InitAssetNameMap() {
} else {
Log.report(
logvisor::Warning,
FMT_STRING(_SYS_STR("AssetNameMap64 unavailable; Assets will not have proper filenames for most files.")));
FMT_STRING("AssetNameMap64 unavailable; Assets will not have proper filenames for most files."));
}
g_AssetNameMapInit = true;
}

View File

@ -73,7 +73,7 @@ add_library(AssetNameMapNull
AssetNameMapNull.cpp)
get_target_property(HECL_INCLUDES hecl-full INCLUDE_DIRECTORIES)
target_include_directories(RetroDataSpec PUBLIC ${PNG_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR}
target_include_directories(RetroDataSpec PUBLIC ${PNG_INCLUDE_DIR}
${HECL_INCLUDES} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR})
target_link_libraries(RetroDataSpec PUBLIC amuse zeus nod squish ${PNG_LIBRARIES} ${ZLIB_LIBRARIES} lzokay logvisor)
if (COMMAND add_sanitizers)

View File

@ -17,7 +17,7 @@ namespace DataSpec::DNAANCS {
template <class PAKRouter, class ANCSDNA, class MaterialSet, class SurfaceHeader, atUint32 CMDLVersion>
bool ReadANCSToBlender(hecl::blender::Token& btok, const ANCSDNA& ancs, const hecl::ProjectPath& outPath,
PAKRouter& pakRouter, const typename PAKRouter::EntryType& entry, const SpecBase& dataspec,
std::function<void(const hecl::SystemChar*)> fileChanged, bool force) {
std::function<void(const char*)> fileChanged, bool force) {
auto& conn = btok.getBlenderConnection();
/* Extract character CMDL/CSKR/CINF first */
std::vector<CharacterResInfo<typename PAKRouter::IDType>> chResInfo;
@ -32,8 +32,7 @@ bool ReadANCSToBlender(hecl::blender::Token& btok, const ANCSDNA& ancs, const he
return false;
std::string bestName = pakRouter.getBestEntryName(*cmdlE);
hecl::SystemStringConv bestNameView(bestName);
fileChanged(bestNameView.c_str());
fileChanged(bestName.c_str());
typename ANCSDNA::CSKRType cskr;
pakRouter.lookupAndReadDNA(info.cskr, cskr);
@ -75,8 +74,7 @@ bool ReadANCSToBlender(hecl::blender::Token& btok, const ANCSDNA& ancs, const he
}
std::string bestName = pakRouter.getBestEntryName(*cmdlE);
hecl::SystemStringConv bestNameView(bestName);
fileChanged(bestNameView.c_str());
fileChanged(bestName.c_str());
const auto* rp = pakRouter.lookupCMDLRigPair(cmdlid);
typename ANCSDNA::CSKRType cskr;
@ -106,8 +104,7 @@ bool ReadANCSToBlender(hecl::blender::Token& btok, const ANCSDNA& ancs, const he
}
std::string bestName = pakRouter.getBestEntryName(entry);
hecl::SystemStringConv bestNameView(bestName);
fileChanged(bestNameView.c_str());
fileChanged(bestName.c_str());
/* Establish ANCS blend */
if (!conn.createBlend(outPath, hecl::blender::BlendType::Actor))
@ -142,7 +139,7 @@ bool ReadANCSToBlender(hecl::blender::Token& btok, const ANCSDNA& ancs, const he
if (cinfsDone.find(info.cinf) == cinfsDone.end()) {
if (const typename PAKRouter::EntryType* cinfE = pakRouter.lookupEntry(info.cinf, nullptr, true, false)) {
hecl::ProjectPath cinfPath = pakRouter.getWorking(cinfE);
os.linkArmature(cinfPath.getAbsolutePathUTF8(), fmt::format(FMT_STRING("CINF_{}"), info.cinf));
os.linkArmature(cinfPath.getAbsolutePath(), fmt::format(FMT_STRING("CINF_{}"), info.cinf));
os << "if obj.name not in bpy.context.scene.objects:\n"
" bpy.context.scene.collection.objects.link(obj)\n";
}
@ -158,7 +155,7 @@ bool ReadANCSToBlender(hecl::blender::Token& btok, const ANCSDNA& ancs, const he
/* Link CMDL */
if (const typename PAKRouter::EntryType* cmdlE = pakRouter.lookupEntry(info.cmdl, nullptr, true, false)) {
hecl::ProjectPath cmdlPath = pakRouter.getWorking(cmdlE);
os.linkMesh(cmdlPath.getAbsolutePathUTF8(), pakRouter.getBestEntryName(*cmdlE));
os.linkMesh(cmdlPath.getAbsolutePath(), pakRouter.getBestEntryName(*cmdlE));
/* Attach CMDL to CINF */
os << "if obj.name not in bpy.context.scene.objects:\n"
@ -177,7 +174,7 @@ bool ReadANCSToBlender(hecl::blender::Token& btok, const ANCSDNA& ancs, const he
if (const typename PAKRouter::EntryType* cmdlE =
pakRouter.lookupEntry(overlay.second.first, nullptr, true, false)) {
hecl::ProjectPath cmdlPath = pakRouter.getWorking(cmdlE);
os.linkMesh(cmdlPath.getAbsolutePathUTF8(), pakRouter.getBestEntryName(*cmdlE));
os.linkMesh(cmdlPath.getAbsolutePath(), pakRouter.getBestEntryName(*cmdlE));
/* Attach CMDL to CINF */
os << "if obj.name not in bpy.context.scene.objects:\n"
@ -202,7 +199,7 @@ bool ReadANCSToBlender(hecl::blender::Token& btok, const ANCSDNA& ancs, const he
if (cinfsDone.find(cinfid) == cinfsDone.end()) {
if (const typename PAKRouter::EntryType* cinfE = pakRouter.lookupEntry(cinfid, nullptr, true, false)) {
hecl::ProjectPath cinfPath = pakRouter.getWorking(cinfE);
os.linkArmature(cinfPath.getAbsolutePathUTF8(), fmt::format(FMT_STRING("CINF_{}"), cinfid));
os.linkArmature(cinfPath.getAbsolutePath(), fmt::format(FMT_STRING("CINF_{}"), cinfid));
os << "if obj.name not in bpy.context.scene.objects:\n"
" bpy.context.scene.collection.objects.link(obj)\n";
}
@ -219,7 +216,7 @@ bool ReadANCSToBlender(hecl::blender::Token& btok, const ANCSDNA& ancs, const he
/* Link CMDL */
if (const typename PAKRouter::EntryType* cmdlE = pakRouter.lookupEntry(cmdlid, nullptr, true, false)) {
hecl::ProjectPath cmdlPath = pakRouter.getWorking(cmdlE);
os.linkMesh(cmdlPath.getAbsolutePathUTF8(), pakRouter.getBestEntryName(*cmdlE));
os.linkMesh(cmdlPath.getAbsolutePath(), pakRouter.getBestEntryName(*cmdlE));
/* Attach CMDL to CINF */
os << "if obj.name not in bpy.context.scene.objects:\n"
@ -270,16 +267,16 @@ template bool
ReadANCSToBlender<PAKRouter<DNAMP1::PAKBridge>, DNAMP1::ANCS, DNAMP1::MaterialSet, DNACMDL::SurfaceHeader_1, 2>(
hecl::blender::Token& btok, const DNAMP1::ANCS& ancs, const hecl::ProjectPath& outPath,
PAKRouter<DNAMP1::PAKBridge>& pakRouter, const typename PAKRouter<DNAMP1::PAKBridge>::EntryType& entry,
const SpecBase& dataspec, std::function<void(const hecl::SystemChar*)> fileChanged, bool force);
const SpecBase& dataspec, std::function<void(const char*)> fileChanged, bool force);
template bool
ReadANCSToBlender<PAKRouter<DNAMP2::PAKBridge>, DNAMP2::ANCS, DNAMP2::MaterialSet, DNACMDL::SurfaceHeader_2, 4>(
hecl::blender::Token& btok, const DNAMP2::ANCS& ancs, const hecl::ProjectPath& outPath,
PAKRouter<DNAMP2::PAKBridge>& pakRouter, const typename PAKRouter<DNAMP2::PAKBridge>::EntryType& entry,
const SpecBase& dataspec, std::function<void(const hecl::SystemChar*)> fileChanged, bool force);
const SpecBase& dataspec, std::function<void(const char*)> fileChanged, bool force);
template bool
ReadANCSToBlender<PAKRouter<DNAMP3::PAKBridge>, DNAMP3::CHAR, DNAMP3::MaterialSet, DNACMDL::SurfaceHeader_3, 4>(
hecl::blender::Token& btok, const DNAMP3::CHAR& ancs, const hecl::ProjectPath& outPath,
PAKRouter<DNAMP3::PAKBridge>& pakRouter, const typename PAKRouter<DNAMP3::PAKBridge>::EntryType& entry,
const SpecBase& dataspec, std::function<void(const hecl::SystemChar*)> fileChanged, bool force);
const SpecBase& dataspec, std::function<void(const char*)> fileChanged, bool force);
} // namespace DataSpec::DNAANCS

View File

@ -7,7 +7,6 @@
#include "athena/Types.hpp"
#include "hecl/Blender/Connection.hpp"
#include "hecl/SystemChar.hpp"
namespace DataSpec {
struct SpecBase;
@ -43,6 +42,6 @@ struct AnimationResInfo {
template <class PAKRouter, class ANCSDNA, class MaterialSet, class SurfaceHeader, atUint32 CMDLVersion>
bool ReadANCSToBlender(hecl::blender::Token& btok, const ANCSDNA& ancs, const hecl::ProjectPath& outPath,
PAKRouter& pakRouter, const typename PAKRouter::EntryType& entry, const SpecBase& dataspec,
std::function<void(const hecl::SystemChar*)> fileChanged, bool force = false);
std::function<void(const char*)> fileChanged, bool force = false);
} // namespace DataSpec::DNAANCS

View File

@ -82,8 +82,7 @@ void ReadMaterialSetToBlender_1_2(hecl::blender::PyOutStream& os, const Material
PAKEntryReadStream rs = texEntry->beginReadStream(*node);
TXTR::Extract(rs, txtrPath);
}
hecl::SystemString resPath = pakRouter.getResourceRelativePath(entry, tex);
hecl::SystemUTF8Conv resPathView(resPath);
std::string resPath = pakRouter.getResourceRelativePath(entry, tex);
os.format(FMT_STRING("if '{}' in bpy.data.images:\n"
" image = bpy.data.images['{}']\n"
"else:\n"
@ -91,7 +90,7 @@ void ReadMaterialSetToBlender_1_2(hecl::blender::PyOutStream& os, const Material
" image.name = '{}'\n"
"texmap_list.append(image)\n"
"\n"),
texName, texName, resPathView, texName);
texName, texName, resPath, texName);
}
unsigned m = 0;
@ -468,7 +467,7 @@ void InitGeomBlenderContext(hecl::blender::PyOutStream& os, const hecl::ProjectP
"with bpy.data.libraries.load('{}', link=True, relative=True) as (data_from, data_to):\n"
" data_to.node_groups = data_from.node_groups\n"
"\n"),
masterShaderPath.getAbsolutePathUTF8());
masterShaderPath.getAbsolutePath());
}
void FinishBlenderMesh(hecl::blender::PyOutStream& os, unsigned matSetCount, int meshIdx) {
@ -1195,7 +1194,7 @@ bool WriteCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath
size_t endOff = 0;
for (const Material& mat : mset) {
std::string diagName = fmt::format(FMT_STRING("{}:{}"), inPath.getLastComponentUTF8(), mat.name);
std::string diagName = fmt::format(FMT_STRING("{}:{}"), inPath.getLastComponent(), mat.name);
hecl::Frontend::IR matIR = FE.compileSource(mat.source, diagName);
setBackends.emplace_back();
hecl::Backend::GX& matGX = setBackends.back();

View File

@ -83,7 +83,7 @@ void UniqueID32::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& write
hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(*this);
if (!path)
return;
writer.writeString(path.getEncodableStringUTF8());
writer.writeString(path.getEncodableString());
}
template <>
void UniqueID32::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s) {
@ -133,7 +133,7 @@ void UniqueID64::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& write
hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(*this);
if (!path)
return;
writer.writeString(path.getEncodableStringUTF8());
writer.writeString(path.getEncodableString());
}
template <>
void UniqueID64::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s) {
@ -164,7 +164,7 @@ void UniqueID128::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& writ
hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(*this);
if (!path)
return;
writer.writeString(path.getEncodableStringUTF8());
writer.writeString(path.getEncodableString());
}
template <>
void UniqueID128::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s) {
@ -189,7 +189,7 @@ void WordBitmap::write(athena::io::IStreamWriter& writer) const {
void WordBitmap::binarySize(size_t& __isz) const { __isz += m_words.size() * 4; }
hecl::ProjectPath GetPathBeginsWith(const hecl::DirectoryEnumerator& dEnum, const hecl::ProjectPath& parentPath,
hecl::SystemStringView test) {
std::string_view test) {
for (const auto& ent : dEnum)
if (hecl::StringUtils::BeginsWith(ent.m_name, test))
return hecl::ProjectPath(parentPath, ent.m_name);

View File

@ -144,12 +144,6 @@ public:
copy[8] = '\0';
assign(strtoul(copy, nullptr, 16));
}
UniqueID32(const wchar_t* hexStr) noexcept {
wchar_t copy[9];
wcsncpy(copy, hexStr, 8);
copy[8] = L'\0';
assign(wcstoul(copy, nullptr, 16));
}
static constexpr size_t BinarySize() noexcept { return 4; }
};
@ -194,12 +188,6 @@ public:
copy[16] = '\0';
assign(std::strtoull(copy, nullptr, 16));
}
UniqueID64(const wchar_t* hexStr) noexcept {
wchar_t copy[17];
std::wcsncpy(copy, hexStr, 16);
copy[16] = L'\0';
assign(std::wcstoull(copy, nullptr, 16));
}
static constexpr size_t BinarySize() noexcept { return 8; }
};
@ -370,8 +358,8 @@ struct CharacterAssociations {
};
hecl::ProjectPath GetPathBeginsWith(const hecl::DirectoryEnumerator& dEnum, const hecl::ProjectPath& parentPath,
hecl::SystemStringView test);
inline hecl::ProjectPath GetPathBeginsWith(const hecl::ProjectPath& parentPath, hecl::SystemStringView test) {
std::string_view test);
inline hecl::ProjectPath GetPathBeginsWith(const hecl::ProjectPath& parentPath, std::string_view test) {
return GetPathBeginsWith(hecl::DirectoryEnumerator(parentPath.getAbsolutePath()), parentPath, test);
}

View File

@ -287,10 +287,9 @@ bool ReadMAPAToBlender(hecl::blender::Connection& conn, const MAPA& mapa, const
/* World background */
hecl::ProjectPath worldDir = outPath.getParentPath().getParentPath();
for (const auto& ent : hecl::DirectoryEnumerator(worldDir.getAbsolutePath())) {
if (hecl::StringUtils::BeginsWith(ent.m_name, _SYS_STR("!world")) &&
hecl::StringUtils::EndsWith(ent.m_name, _SYS_STR(".blend"))) {
hecl::SystemUTF8Conv conv(ent.m_name);
os.linkBackground(fmt::format(FMT_STRING("//../{}"), conv), "World"sv);
if (hecl::StringUtils::BeginsWith(ent.m_name, "!world") &&
hecl::StringUtils::EndsWith(ent.m_name, ".blend")) {
os.linkBackground(fmt::format(FMT_STRING("//../{}"), ent.m_name), "World"sv);
break;
}
}
@ -322,7 +321,7 @@ template bool ReadMAPAToBlender<PAKRouter<DNAMP3::PAKBridge>>(hecl::blender::Con
template <typename MAPAType>
bool Cook(const hecl::blender::MapArea& mapaIn, const hecl::ProjectPath& out) {
if (mapaIn.verts.size() >= 256) {
Log.report(logvisor::Error, FMT_STRING(_SYS_STR("MAPA {} vertex range exceeded [{}/{}]")), out.getRelativePath(),
Log.report(logvisor::Error, FMT_STRING("MAPA {} vertex range exceeded [{}/{}]"), out.getRelativePath(),
mapaIn.verts.size(), 255);
return false;
}

View File

@ -33,7 +33,7 @@ bool ReadMAPUToBlender(hecl::blender::Connection& conn, const MAPU& mapu, const
"\n";
hecl::ProjectPath hexPath = pakRouter.getWorking(mapu.hexMapa);
os.linkMesh(hexPath.getAbsolutePathUTF8(), "MAP");
os.linkMesh(hexPath.getAbsolutePath(), "MAP");
os << "hexMesh = bpy.data.objects['MAP'].data\n";
for (const MAPU::World& wld : mapu.worlds) {
@ -55,7 +55,7 @@ bool ReadMAPUToBlender(hecl::blender::Connection& conn, const MAPU& mapu, const
"bpy.context.scene.collection.objects.link(wldObj)\n"),
wld.name, wldXfF[0][0], wldXfF[0][1], wldXfF[0][2], wldXfF[0][3], wldXfF[1][0], wldXfF[1][1],
wldXfF[1][2], wldXfF[1][3], wldXfF[2][0], wldXfF[2][1], wldXfF[2][2], wldXfF[2][3], hexColorF[0],
hexColorF[1], hexColorF[2], hexColorF[3], path.getParentPath().getRelativePathUTF8());
hexColorF[1], hexColorF[2], hexColorF[3], path.getParentPath().getRelativePath());
int idx = 0;
for (const MAPU::Transform& hexXf : wld.hexTransforms) {
zeus::simd_floats hexXfF[3];
@ -113,8 +113,8 @@ bool MAPU::Cook(const hecl::blender::MapUniverse& mapuIn, const hecl::ProjectPat
MAPU::World& wldOut = mapu.worlds.back();
wldOut.name = wld.name;
for (const auto& ent : wld.worldPath.enumerateDir()) {
if (hecl::StringUtils::BeginsWith(ent.m_name, _SYS_STR("!world")) &&
hecl::StringUtils::EndsWith(ent.m_name, _SYS_STR(".blend"))) {
if (hecl::StringUtils::BeginsWith(ent.m_name, "!world") &&
hecl::StringUtils::EndsWith(ent.m_name, ".blend")) {
wldOut.mlvl = hecl::ProjectPath(wld.worldPath, ent.m_name);
break;
}

View File

@ -12,8 +12,8 @@ namespace DataSpec::DNAMLVL {
template <class PAKRouter, typename MLVL>
bool ReadMLVLToBlender(hecl::blender::Connection& conn, const MLVL& mlvl, const hecl::ProjectPath& outPath,
PAKRouter& pakRouter, const typename PAKRouter::EntryType& entry, bool force,
std::function<void(const hecl::SystemChar*)> fileChanged) {
hecl::ProjectPath blendPath = outPath.getWithExtension(_SYS_STR(".blend"), true);
std::function<void(const char*)> fileChanged) {
hecl::ProjectPath blendPath = outPath.getWithExtension(".blend", true);
if (!force && blendPath.isFile())
return true;
@ -35,7 +35,6 @@ bool ReadMLVLToBlender(hecl::blender::Connection& conn, const MLVL& mlvl, const
int areaIdx = 0;
for (const auto& area : mlvl.areas) {
const typename PAKRouter::EntryType* mreaEntry = pakRouter.lookupEntry(area.areaMREAId);
hecl::SystemUTF8Conv areaDirName(*mreaEntry->unique.m_areaName);
os.AABBToBMesh(area.aabb[0], area.aabb[1]);
zeus::simd_floats xfMtxF[3];
@ -52,7 +51,7 @@ bool ReadMLVLToBlender(hecl::blender::Connection& conn, const MLVL& mlvl, const
"box.location = mtxd[0]\n"
"box.rotation_quaternion = mtxd[1]\n"
"box.scale = mtxd[2]\n"),
areaDirName, xfMtxF[0][0], xfMtxF[0][1], xfMtxF[0][2], xfMtxF[0][3], xfMtxF[1][0], xfMtxF[1][1],
*mreaEntry->unique.m_areaName, xfMtxF[0][0], xfMtxF[0][1], xfMtxF[0][2], xfMtxF[0][3], xfMtxF[1][0], xfMtxF[1][1],
xfMtxF[1][2], xfMtxF[1][3], xfMtxF[2][0], xfMtxF[2][1], xfMtxF[2][2], xfMtxF[2][3]);
/* Insert dock planes */
@ -95,16 +94,16 @@ bool ReadMLVLToBlender(hecl::blender::Connection& conn, const MLVL& mlvl, const
template bool ReadMLVLToBlender<PAKRouter<DNAMP1::PAKBridge>, DNAMP1::MLVL>(
hecl::blender::Connection& conn, const DNAMP1::MLVL& mlvl, const hecl::ProjectPath& outPath,
PAKRouter<DNAMP1::PAKBridge>& pakRouter, const PAKRouter<DNAMP1::PAKBridge>::EntryType& entry, bool force,
std::function<void(const hecl::SystemChar*)> fileChanged);
std::function<void(const char*)> fileChanged);
template bool ReadMLVLToBlender<PAKRouter<DNAMP2::PAKBridge>, DNAMP2::MLVL>(
hecl::blender::Connection& conn, const DNAMP2::MLVL& mlvl, const hecl::ProjectPath& outPath,
PAKRouter<DNAMP2::PAKBridge>& pakRouter, const PAKRouter<DNAMP2::PAKBridge>::EntryType& entry, bool force,
std::function<void(const hecl::SystemChar*)> fileChanged);
std::function<void(const char*)> fileChanged);
template bool ReadMLVLToBlender<PAKRouter<DNAMP3::PAKBridge>, DNAMP3::MLVL>(
hecl::blender::Connection& conn, const DNAMP3::MLVL& mlvl, const hecl::ProjectPath& outPath,
PAKRouter<DNAMP3::PAKBridge>& pakRouter, const PAKRouter<DNAMP3::PAKBridge>::EntryType& entry, bool force,
std::function<void(const hecl::SystemChar*)> fileChanged);
std::function<void(const char*)> fileChanged);
} // namespace DataSpec::DNAMLVL

View File

@ -4,8 +4,6 @@
#include "DataSpec/DNACommon/DNACommon.hpp"
#include <hecl/SystemChar.hpp>
namespace hecl {
class ProjectPath;
}
@ -19,6 +17,6 @@ namespace DataSpec::DNAMLVL {
template <class PAKRouter, typename MLVL>
bool ReadMLVLToBlender(hecl::blender::Connection& conn, const MLVL& mlvl, const hecl::ProjectPath& outPath,
PAKRouter& pakRouter, const typename PAKRouter::EntryType& entry, bool force,
std::function<void(const hecl::SystemChar*)> fileChanged);
std::function<void(const char*)> fileChanged);
}

View File

@ -10,7 +10,7 @@ template <class PAKBRIDGE>
void UniqueResult::checkEntry(const PAKBRIDGE& pakBridge, const typename PAKBRIDGE::PAKType::Entry& entry) {
UniqueResult::Type resultType = UniqueResult::Type::NotFound;
bool foundOneLayer = false;
const hecl::SystemString* levelName = nullptr;
const std::string* levelName = nullptr;
typename PAKBRIDGE::PAKType::IDType useLevelId;
typename PAKBRIDGE::PAKType::IDType useAreaId;
unsigned layerIdx = 0;
@ -123,10 +123,9 @@ void PAKRouter<BRIDGETYPE>::build(std::vector<BRIDGETYPE>& bridges, std::functio
size_t bridgeIdx = 0;
for (BRIDGETYPE& bridge : bridges) {
const auto& name = bridge.getName();
hecl::SystemStringConv sysName(name);
hecl::SystemStringView::const_iterator extit = sysName.sys_str().end() - 4;
hecl::SystemString baseName(sysName.sys_str().begin(), extit);
std::string_view::const_iterator extit = name.end() - 4;
std::string baseName(name.begin(), extit);
m_bridgePaths.emplace_back(
std::make_pair(hecl::ProjectPath(m_gameWorking, baseName), hecl::ProjectPath(m_gameCooked, baseName)));
@ -173,13 +172,13 @@ void PAKRouter<BRIDGETYPE>::build(std::vector<BRIDGETYPE>& bridges, std::functio
continue; /* Problematic corner case */
if (auto rec = catalogWriter.enterSubRecord(namedEntry.name)) {
hecl::ProjectPath working = getWorking(namedEntry.id);
if (working.getAuxInfoUTF8().size()) {
if (working.getAuxInfo().size()) {
if (auto v = catalogWriter.enterSubVector()) {
catalogWriter.writeString(working.getRelativePathUTF8());
catalogWriter.writeString(working.getAuxInfoUTF8());
catalogWriter.writeString(working.getRelativePath());
catalogWriter.writeString(working.getAuxInfo());
}
} else
catalogWriter.writeString(working.getRelativePathUTF8());
catalogWriter.writeString(working.getRelativePath());
}
}
@ -217,8 +216,8 @@ hecl::ProjectPath PAKRouter<BRIDGETYPE>::getCharacterWorking(const EntryType* en
if (characterSearch != m_charAssoc.m_cskrToCharacter.cend()) {
hecl::ProjectPath characterPath = getWorking(characterSearch->second.first);
if (entry->type == FOURCC('EVNT')) {
hecl::SystemStringConv wideStr(characterSearch->second.second);
return characterPath.getWithExtension((hecl::SystemString(_SYS_STR(".")) + wideStr.c_str()).c_str(), true);
std::string extension(characterSearch->second.second);
return characterPath.getWithExtension((std::string(".") + extension.c_str()).c_str(), true);
}
return characterPath.ensureAuxInfo(characterSearch->second.second);
}
@ -241,12 +240,12 @@ hecl::ProjectPath PAKRouter<BRIDGETYPE>::getWorking(const EntryType* entry,
const EntryType* singleSearch = pak->lookupEntry(entry->id);
if (singleSearch) {
const hecl::ProjectPath& pakPath = m_bridgePaths[curBridgeIdx].first;
hecl::SystemString entName = hecl::UTF8StringToSysString(getBestEntryName(*entry));
hecl::SystemString auxInfo;
std::string entName = getBestEntryName(*entry);
std::string auxInfo;
if (extractor.fileExts[0] && !extractor.fileExts[1])
entName += extractor.fileExts[0];
else if (extractor.fileExts[0])
entName += _SYS_STR(".*");
entName += ".*";
else if (hecl::ProjectPath chWork = getCharacterWorking(entry))
return chWork;
return hecl::ProjectPath(pakPath, entName).ensureAuxInfo(auxInfo);
@ -257,12 +256,12 @@ hecl::ProjectPath PAKRouter<BRIDGETYPE>::getWorking(const EntryType* entry,
if (uniqueSearch != m_uniqueEntries.end()) {
const BRIDGETYPE& bridge = m_bridges->at(uniqueSearch->second.first);
const hecl::ProjectPath& pakPath = m_bridgePaths[uniqueSearch->second.first].first;
hecl::SystemString entName = hecl::UTF8StringToSysString(getBestEntryName(*entry));
hecl::SystemString auxInfo;
std::string entName = getBestEntryName(*entry);
std::string auxInfo;
if (extractor.fileExts[0] && !extractor.fileExts[1])
entName += extractor.fileExts[0];
else if (extractor.fileExts[0])
entName += _SYS_STR(".*");
entName += ".*";
else if (hecl::ProjectPath chWork = getCharacterWorking(entry))
return chWork;
if (bridge.getPAK().m_noShare) {
@ -275,13 +274,13 @@ hecl::ProjectPath PAKRouter<BRIDGETYPE>::getWorking(const EntryType* entry,
auto sharedSearch = m_sharedEntries.find(entry->id);
if (sharedSearch != m_sharedEntries.end()) {
hecl::SystemString entBase = hecl::UTF8StringToSysString(getBestEntryName(*entry));
hecl::SystemString auxInfo;
hecl::SystemString entName = entBase;
std::string entBase = getBestEntryName(*entry);
std::string auxInfo;
std::string entName = entBase;
if (extractor.fileExts[0] && !extractor.fileExts[1])
entName += extractor.fileExts[0];
else if (extractor.fileExts[0])
entName += _SYS_STR(".*");
entName += ".*";
else if (hecl::ProjectPath chWork = getCharacterWorking(entry))
return chWork;
hecl::ProjectPath sharedPath(m_sharedWorking, entName);
@ -349,7 +348,7 @@ hecl::ProjectPath PAKRouter<BRIDGETYPE>::getCooked(const IDType& id, bool silenc
}
template <class BRIDGETYPE>
hecl::SystemString PAKRouter<BRIDGETYPE>::getResourceRelativePath(const EntryType& a, const IDType& b) const {
std::string PAKRouter<BRIDGETYPE>::getResourceRelativePath(const EntryType& a, const IDType& b) const {
const nod::Node* node = m_node.get();
const PAKType* pak = m_pak.get();
if (!pak)
@ -358,11 +357,11 @@ hecl::SystemString PAKRouter<BRIDGETYPE>::getResourceRelativePath(const EntryTyp
FMT_STRING("PAKRouter::enterPAKBridge() must be called before PAKRouter::getResourceRelativePath()"));
const typename BRIDGETYPE::PAKType::Entry* be = lookupEntry(b);
if (!be)
return hecl::SystemString();
return std::string();
hecl::ProjectPath aPath = getWorking(&a, BRIDGETYPE::LookupExtractor(*node, *pak, a));
hecl::SystemString ret;
std::string ret;
for (size_t i = 0; i < aPath.levelCount(); ++i)
ret += _SYS_STR("../");
ret += "../";
hecl::ProjectPath bPath = getWorking(be, BRIDGETYPE::LookupExtractor(*node, *pak, *be));
ret += bPath.getRelativePath();
return ret;
@ -434,7 +433,7 @@ std::string PAKRouter<BRIDGETYPE>::getBestEntryName(const IDType& entry, bool st
template <class BRIDGETYPE>
bool PAKRouter<BRIDGETYPE>::extractResources(const BRIDGETYPE& pakBridge, bool force, hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*, float)> progress) {
std::function<void(const char*, float)> progress) {
enterPAKBridge(pakBridge);
size_t count = 0;
size_t sz = m_pak->m_entries.size();
@ -447,9 +446,8 @@ bool PAKRouter<BRIDGETYPE>::extractResources(const BRIDGETYPE& pakBridge, bool f
continue;
std::string bestName = getBestEntryName(*entryPtr, false);
hecl::SystemStringConv bestNameView(bestName);
float thisFac = ++count / fsz;
progress(bestNameView.c_str(), thisFac);
progress(bestName.c_str(), thisFac);
const nod::Node* node = m_node.get();
@ -464,7 +462,7 @@ bool PAKRouter<BRIDGETYPE>::extractResources(const BRIDGETYPE& pakBridge, bool f
if (force || cooked.isNone()) {
cooked.makeDirChain(false);
PAKEntryReadStream s = entryPtr->beginReadStream(*node);
const auto fout = hecl::FopenUnique(cooked.getAbsolutePath().data(), _SYS_STR("wb"));
const auto fout = hecl::FopenUnique(cooked.getAbsolutePath().data(), "wb");
std::fwrite(s.data(), 1, s.length(), fout.get());
}
@ -479,7 +477,7 @@ bool PAKRouter<BRIDGETYPE>::extractResources(const BRIDGETYPE& pakBridge, bool f
if (force || !extractor.IsFullyExtracted(working)) {
PAKEntryReadStream s = entryPtr->beginReadStream(*node);
extractor.func_b(m_dataSpec, s, working, *this, *entryPtr, force, btok,
[&progress, thisFac](const hecl::SystemChar* update) { progress(update, thisFac); });
[&progress, thisFac](const char* update) { progress(update, thisFac); });
}
}
}

View File

@ -60,9 +60,9 @@ public:
struct UniqueResult {
enum class Type { NotFound, Pak, Level, Area, Layer } m_type = Type::NotFound;
const hecl::SystemString* m_levelName = nullptr;
const hecl::SystemString* m_areaName = nullptr;
const hecl::SystemString* m_layerName = nullptr;
const std::string* m_levelName = nullptr;
const std::string* m_areaName = nullptr;
const std::string* m_layerName = nullptr;
UniqueResult() = default;
UniqueResult(Type tp) : m_type(tp) {}
@ -81,9 +81,9 @@ struct ResExtractor {
std::function<bool(PAKEntryReadStream&, const hecl::ProjectPath&)> func_a;
std::function<bool(const SpecBase&, PAKEntryReadStream&, const hecl::ProjectPath&, PAKRouter<PAKBRIDGE>&,
const typename PAKBRIDGE::PAKType::Entry&, bool, hecl::blender::Token&,
std::function<void(const hecl::SystemChar*)>)>
std::function<void(const char*)>)>
func_b;
std::array<const hecl::SystemChar*, 6> fileExts = {};
std::array<const char*, 6> fileExts = {};
unsigned weight = 0;
std::function<void(const SpecBase&, PAKEntryReadStream&, PAKRouter<PAKBRIDGE>&, typename PAKBRIDGE::PAKType::Entry&)>
func_name;
@ -91,7 +91,7 @@ struct ResExtractor {
ResExtractor() = default;
ResExtractor(std::function<bool(PAKEntryReadStream&, const hecl::ProjectPath&)> func,
std::array<const hecl::SystemChar*, 6>&& fileExtsIn, unsigned weightin = 0,
std::array<const char*, 6>&& fileExtsIn, unsigned weightin = 0,
std::function<void(const SpecBase&, PAKEntryReadStream&, PAKRouter<PAKBRIDGE>&,
typename PAKBRIDGE::PAKType::Entry&)>
nfunc = {})
@ -99,9 +99,9 @@ struct ResExtractor {
ResExtractor(std::function<bool(const SpecBase&, PAKEntryReadStream&, const hecl::ProjectPath&, PAKRouter<PAKBRIDGE>&,
const typename PAKBRIDGE::PAKType::Entry&, bool, hecl::blender::Token&,
std::function<void(const hecl::SystemChar*)>)>
std::function<void(const char*)>)>
func,
std::array<const hecl::SystemChar*, 6>&& fileExtsIn, unsigned weightin = 0,
std::array<const char*, 6>&& fileExtsIn, unsigned weightin = 0,
std::function<void(const SpecBase&, PAKEntryReadStream&, PAKRouter<PAKBRIDGE>&,
typename PAKBRIDGE::PAKType::Entry&)>
nfunc = {})
@ -127,11 +127,11 @@ struct ResExtractor {
/** Level hierarchy representation */
template <class IDType>
struct Level {
hecl::SystemString name;
std::string name;
struct Area {
hecl::SystemString name;
std::string name;
struct Layer {
hecl::SystemString name;
std::string name;
bool active;
std::unordered_set<IDType> resources;
};
@ -188,13 +188,13 @@ public:
hecl::ProjectPath getCooked(const EntryType* entry) const;
hecl::ProjectPath getCooked(const IDType& id, bool silenceWarnings = false) const;
hecl::SystemString getResourceRelativePath(const EntryType& a, const IDType& b) const;
std::string getResourceRelativePath(const EntryType& a, const IDType& b) const;
std::string getBestEntryName(const EntryType& entry, bool stdOverride = true) const;
std::string getBestEntryName(const IDType& entry, bool stdOverride = true) const;
bool extractResources(const BRIDGETYPE& pakBridge, bool force, hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*, float)> progress);
std::function<void(const char*, float)> progress);
const typename BRIDGETYPE::PAKType::Entry* lookupEntry(const IDType& entry, const nod::Node** nodeOut = nullptr,
bool silenceWarnings = false, bool currentPAK = false) const;

View File

@ -180,7 +180,7 @@ template <class PAKBridge>
bool PATH<PAKBridge>::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const typename PAKBridge::PAKType::Entry& entry,
bool force, hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*)> fileChanged) {
std::function<void(const char*)> fileChanged) {
PATH path;
path.read(rs);
hecl::blender::Connection& conn = btok.getBlenderConnection();
@ -189,8 +189,8 @@ bool PATH<PAKBridge>::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs,
std::string areaPath;
for (const auto& ent : hecl::DirectoryEnumerator(outPath.getParentPath().getAbsolutePath())) {
if (hecl::StringUtils::BeginsWith(ent.m_name, _SYS_STR("!area_"))) {
areaPath = hecl::SystemUTF8Conv(ent.m_name).str();
if (hecl::StringUtils::BeginsWith(ent.m_name, "!area_")) {
areaPath = ent.m_name;
break;
}
}
@ -223,7 +223,7 @@ bool PATH<PAKBridge>::Cook(const hecl::ProjectPath& outPath, const hecl::Project
#if DUMP_OCTREE
{
hecl::blender::Connection& conn = btok.getBlenderConnection();
if (!conn.createBlend(inPath.getWithExtension(_SYS_STR(".octree.blend"), true), hecl::blender::BlendType::PathMesh))
if (!conn.createBlend(inPath.getWithExtension(".octree.blend", true), hecl::blender::BlendType::PathMesh))
return false;
zeus::CMatrix4f xf;

View File

@ -104,7 +104,7 @@ struct AT_SPECIALIZE_PARMS(DataSpec::DNAMP1::PAKBridge, DataSpec::DNAMP2::PAKBri
static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const typename PAKBridge::PAKType::Entry& entry, bool force,
hecl::blender::Token& btok, std::function<void(const hecl::SystemChar*)> fileChanged);
hecl::blender::Token& btok, std::function<void(const char*)> fileChanged);
static bool Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const PathMesh& mesh,
hecl::blender::Token& btok);

View File

@ -15,29 +15,29 @@ std::unique_ptr<ISTRG> LoadSTRG(athena::io::IStreamReader& reader) {
uint32_t magic = reader.readUint32Big();
if (magic != 0x87654321) {
LogDNACommon.report(logvisor::Error, FMT_STRING("invalid STRG magic"));
return std::unique_ptr<ISTRG>();
return {};
}
uint32_t version = reader.readUint32Big();
switch (version) {
case 0: {
DNAMP1::STRG* newStrg = new DNAMP1::STRG;
auto* newStrg = new DNAMP1::STRG;
newStrg->_read(reader);
return std::unique_ptr<ISTRG>(newStrg);
}
case 1: {
DNAMP2::STRG* newStrg = new DNAMP2::STRG;
auto* newStrg = new DNAMP2::STRG;
newStrg->_read(reader);
return std::unique_ptr<ISTRG>(newStrg);
}
case 3: {
DNAMP3::STRG* newStrg = new DNAMP3::STRG;
auto* newStrg = new DNAMP3::STRG;
newStrg->_read(reader);
return std::unique_ptr<ISTRG>(newStrg);
}
default:
break;
}
return std::unique_ptr<ISTRG>();
return {};
}
} // namespace DataSpec

View File

@ -21,7 +21,6 @@ struct ISTRG : BigDNAVYaml {
virtual size_t count() const = 0;
virtual std::string getUTF8(const FourCC& lang, size_t idx) const = 0;
virtual std::u16string getUTF16(const FourCC& lang, size_t idx) const = 0;
virtual hecl::SystemString getSystemString(const FourCC& lang, size_t idx) const = 0;
virtual int32_t lookupIdx(std::string_view name) const = 0;
virtual void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const;

View File

@ -836,9 +836,9 @@ bool TXTR::Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
const uint16_t height = rs.readUint16Big();
const uint32_t numMips = rs.readUint32Big();
auto fp = hecl::FopenUnique(outPath.getAbsolutePath().data(), _SYS_STR("wb"));
auto fp = hecl::FopenUnique(outPath.getAbsolutePath().data(), "wb");
if (fp == nullptr) {
Log.report(logvisor::Error, FMT_STRING(_SYS_STR("Unable to open '{}' for writing")), outPath.getAbsolutePath());
Log.report(logvisor::Error, FMT_STRING("Unable to open '{}' for writing"), outPath.getAbsolutePath());
return false;
}
png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, PNGErr, PNGWarn);
@ -1039,9 +1039,9 @@ static int GetNumPaletteEntriesForGCN(png_structp png, png_infop info) {
}
bool TXTR::Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath) {
auto inf = hecl::FopenUnique(inPath.getAbsolutePath().data(), _SYS_STR("rb"));
auto inf = hecl::FopenUnique(inPath.getAbsolutePath().data(), "rb");
if (inf == nullptr) {
Log.report(logvisor::Error, FMT_STRING(_SYS_STR("Unable to open '{}' for reading")), inPath.getAbsolutePath());
Log.report(logvisor::Error, FMT_STRING("Unable to open '{}' for reading"), inPath.getAbsolutePath());
return false;
}
@ -1049,7 +1049,7 @@ bool TXTR::Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPat
char header[8];
std::fread(header, 1, sizeof(header), inf.get());
if (png_sig_cmp((png_const_bytep)header, 0, 8)) {
Log.report(logvisor::Error, FMT_STRING(_SYS_STR("invalid PNG signature in '{}'")), inPath.getAbsolutePath());
Log.report(logvisor::Error, FMT_STRING("invalid PNG signature in '{}'"), inPath.getAbsolutePath());
return false;
}
@ -1067,7 +1067,7 @@ bool TXTR::Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPat
}
if (setjmp(png_jmpbuf(pngRead))) {
Log.report(logvisor::Error, FMT_STRING(_SYS_STR("unable to initialize libpng I/O for '{}'")),
Log.report(logvisor::Error, FMT_STRING("unable to initialize libpng I/O for '{}'"),
inPath.getAbsolutePath());
png_destroy_read_struct(&pngRead, &info, nullptr);
return false;
@ -1113,7 +1113,7 @@ bool TXTR::Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPat
}
if (bitDepth != 8) {
Log.report(logvisor::Error, FMT_STRING(_SYS_STR("'{}' is not 8 bits-per-channel")), inPath.getAbsolutePath());
Log.report(logvisor::Error, FMT_STRING("'{}' is not 8 bits-per-channel"), inPath.getAbsolutePath());
png_destroy_read_struct(&pngRead, &info, nullptr);
return false;
}
@ -1144,7 +1144,7 @@ bool TXTR::Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPat
nComps = 1;
break;
default:
Log.report(logvisor::Error, FMT_STRING(_SYS_STR("unsupported color type in '{}'")), inPath.getAbsolutePath());
Log.report(logvisor::Error, FMT_STRING("unsupported color type in '{}'"), inPath.getAbsolutePath());
png_destroy_read_struct(&pngRead, &info, nullptr);
return false;
}
@ -1164,7 +1164,7 @@ bool TXTR::Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPat
bufOut.reset(new uint8_t[bufLen]);
if (setjmp(png_jmpbuf(pngRead))) {
Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("unable to read image in '{}'")), inPath.getAbsolutePath());
Log.report(logvisor::Fatal, FMT_STRING("unable to read image in '{}'"), inPath.getAbsolutePath());
png_destroy_read_struct(&pngRead, &info, nullptr);
return false;
}
@ -1345,7 +1345,7 @@ bool TXTR::Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPat
/* Do write out */
athena::io::FileWriter outf(outPath.getAbsolutePath(), true, false);
if (outf.hasError()) {
Log.report(logvisor::Error, FMT_STRING(_SYS_STR("Unable to open '{}' for writing")), outPath.getAbsolutePath());
Log.report(logvisor::Error, FMT_STRING("Unable to open '{}' for writing"), outPath.getAbsolutePath());
return false;
}
@ -1359,9 +1359,9 @@ bool TXTR::Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPat
}
bool TXTR::CookPC(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath) {
auto inf = hecl::FopenUnique(inPath.getAbsolutePath().data(), _SYS_STR("rb"));
auto inf = hecl::FopenUnique(inPath.getAbsolutePath().data(), "rb");
if (inf == nullptr) {
Log.report(logvisor::Error, FMT_STRING(_SYS_STR("Unable to open '{}' for reading")), inPath.getAbsolutePath());
Log.report(logvisor::Error, FMT_STRING("Unable to open '{}' for reading"), inPath.getAbsolutePath());
return false;
}
@ -1369,7 +1369,7 @@ bool TXTR::CookPC(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outP
char header[8];
std::fread(header, 1, sizeof(header), inf.get());
if (png_sig_cmp((png_const_bytep)header, 0, 8)) {
Log.report(logvisor::Error, FMT_STRING(_SYS_STR("invalid PNG signature in '{}'")), inPath.getAbsolutePath());
Log.report(logvisor::Error, FMT_STRING("invalid PNG signature in '{}'"), inPath.getAbsolutePath());
return false;
}
@ -1387,7 +1387,7 @@ bool TXTR::CookPC(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outP
}
if (setjmp(png_jmpbuf(pngRead))) {
Log.report(logvisor::Error, FMT_STRING(_SYS_STR("unable to initialize libpng I/O for '{}'")),
Log.report(logvisor::Error, FMT_STRING("unable to initialize libpng I/O for '{}'"),
inPath.getAbsolutePath());
png_destroy_read_struct(&pngRead, &info, nullptr);
return false;
@ -1427,7 +1427,7 @@ bool TXTR::CookPC(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outP
}
if (bitDepth != 8) {
Log.report(logvisor::Error, FMT_STRING(_SYS_STR("'{}' is not 8 bits-per-channel")), inPath.getAbsolutePath());
Log.report(logvisor::Error, FMT_STRING("'{}' is not 8 bits-per-channel"), inPath.getAbsolutePath());
png_destroy_read_struct(&pngRead, &info, nullptr);
return false;
}
@ -1456,7 +1456,7 @@ bool TXTR::CookPC(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outP
paletteBuf = ReadPalette(pngRead, info, paletteSize);
break;
default:
Log.report(logvisor::Error, FMT_STRING(_SYS_STR("unsupported color type in '{}'")), inPath.getAbsolutePath());
Log.report(logvisor::Error, FMT_STRING("unsupported color type in '{}'"), inPath.getAbsolutePath());
png_destroy_read_struct(&pngRead, &info, nullptr);
return false;
}
@ -1474,7 +1474,7 @@ bool TXTR::CookPC(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outP
bufOut.reset(new uint8_t[bufLen]);
if (setjmp(png_jmpbuf(pngRead))) {
Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("unable to read image in '{}'")), inPath.getAbsolutePath());
Log.report(logvisor::Fatal, FMT_STRING("unable to read image in '{}'"), inPath.getAbsolutePath());
png_destroy_read_struct(&pngRead, &info, nullptr);
return false;
}
@ -1595,7 +1595,7 @@ bool TXTR::CookPC(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outP
/* Do write out */
athena::io::FileWriter outf(outPath.getAbsolutePath(), true, false);
if (outf.hasError()) {
Log.report(logvisor::Error, FMT_STRING(_SYS_STR("Unable to open '{}' for writing")), outPath.getAbsolutePath());
Log.report(logvisor::Error, FMT_STRING("Unable to open '{}' for writing"), outPath.getAbsolutePath());
return false;
}

View File

@ -181,7 +181,7 @@ bool AGSC::Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& dir) {
group.getSdir().extractAllCompressed(dir.getAbsolutePath(), data.getSamp());
/* Import C headers */
auto lastComp = dir.getLastComponentUTF8();
auto lastComp = dir.getLastComponent();
auto search = std::lower_bound(std::cbegin(Headers), std::cend(Headers), lastComp,
[](const auto& a, const auto& b) { return a.first < b; });
if (search != std::cend(Headers) && search->first == lastComp)
@ -190,7 +190,7 @@ bool AGSC::Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& dir) {
/* Write out project/pool */
{
auto projd = group.getProj().toYAML();
athena::io::FileWriter fo(hecl::ProjectPath(dir, _SYS_STR("!project.yaml")).getAbsolutePath());
athena::io::FileWriter fo(hecl::ProjectPath(dir, "!project.yaml").getAbsolutePath());
if (fo.hasError())
return false;
fo.writeUBytes(projd.data(), projd.size());
@ -198,7 +198,7 @@ bool AGSC::Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& dir) {
{
auto poold = group.getPool().toYAML();
athena::io::FileWriter fo(hecl::ProjectPath(dir, _SYS_STR("!pool.yaml")).getAbsolutePath());
athena::io::FileWriter fo(hecl::ProjectPath(dir, "!pool.yaml").getAbsolutePath());
if (fo.hasError())
return false;
fo.writeUBytes(poold.data(), poold.size());
@ -232,7 +232,7 @@ bool AGSC::Cook(const hecl::ProjectPath& dir, const hecl::ProjectPath& refOutPat
Header head;
head.audioDir = "Audio/"sv;
head.groupName = path.getLastComponentUTF8();
head.groupName = path.getLastComponent();
head.write(w);
amuse::AudioGroupDatabase group(path.getAbsolutePath());

View File

@ -957,10 +957,10 @@ std::string_view ANCS::AnimationSet::DNAType() { return "DNAMP1::ANCS::Animation
bool ANCS::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*)> fileChanged) {
hecl::ProjectPath yamlPath = outPath.getWithExtension(_SYS_STR(".yaml"), true);
std::function<void(const char*)> fileChanged) {
hecl::ProjectPath yamlPath = outPath.getWithExtension(".yaml", true);
hecl::ProjectPath::Type yamlType = yamlPath.getPathType();
hecl::ProjectPath blendPath = outPath.getWithExtension(_SYS_STR(".blend"), true);
hecl::ProjectPath blendPath = outPath.getWithExtension(".blend", true);
hecl::ProjectPath::Type blendType = blendPath.getPathType();
ANCS ancs;
@ -983,21 +983,21 @@ bool ANCS::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
bool ANCS::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor) {
/* Search for yaml */
hecl::ProjectPath yamlPath = inPath.getWithExtension(_SYS_STR(".yaml"), true);
hecl::ProjectPath yamlPath = inPath.getWithExtension(".yaml", true);
if (!yamlPath.isFile())
Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("'{}' not found as file")), yamlPath.getRelativePath());
Log.report(logvisor::Fatal, FMT_STRING("'{}' not found as file"), yamlPath.getRelativePath());
athena::io::FileReader reader(yamlPath.getAbsolutePath());
if (!reader.isOpen())
Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("can't open '{}' for reading")), yamlPath.getRelativePath());
Log.report(logvisor::Fatal, FMT_STRING("can't open '{}' for reading"), yamlPath.getRelativePath());
if (!athena::io::ValidateFromYAMLStream<ANCS>(reader)) {
Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("'{}' is not DNAMP1::ANCS type")), yamlPath.getRelativePath());
Log.report(logvisor::Fatal, FMT_STRING("'{}' is not DNAMP1::ANCS type"), yamlPath.getRelativePath());
}
athena::io::YAMLDocReader yamlReader;
if (!yamlReader.parse(&reader)) {
Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("unable to parse '{}'")), yamlPath.getRelativePath());
Log.report(logvisor::Fatal, FMT_STRING("unable to parse '{}'"), yamlPath.getRelativePath());
}
ANCS ancs;
ancs.read(yamlReader);
@ -1014,12 +1014,10 @@ bool ANCS::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
ch.animAABBs.clear();
for (const DNAANCS::Actor::Subtype& sub : actor.subtypes) {
if (sub.name == ch.name) {
hecl::SystemStringConv chSysName(ch.name);
if (!sub.cskrId.empty()) {
hecl::SystemStringConv cskrSysName(sub.cskrId);
ch.cskr = inPath.ensureAuxInfo(fmt::format(FMT_STRING(_SYS_STR("{}_{}.CSKR")), chSysName, cskrSysName));
ch.cskr = inPath.ensureAuxInfo(fmt::format(FMT_STRING("{}_{}.CSKR"), ch.name, sub.cskrId));
} else {
ch.cskr = inPath.ensureAuxInfo(fmt::format(FMT_STRING(_SYS_STR("{}.CSKR")), chSysName));
ch.cskr = inPath.ensureAuxInfo(fmt::format(FMT_STRING("{}.CSKR"), ch.name));
}
/* Add subtype AABBs */
@ -1040,14 +1038,12 @@ bool ANCS::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
auto search = std::find_if(sub.overlayMeshes.cbegin(), sub.overlayMeshes.cend(),
[](const auto& p) { return p.name == "ICE"; });
if (search != sub.overlayMeshes.cend()) {
hecl::SystemStringConv overlaySys(search->name);
ch.cmdlIce = search->mesh;
if (!search->cskrId.empty()) {
hecl::SystemStringConv cskrSys(search->cskrId);
ch.cskrIce = inPath.ensureAuxInfo(
fmt::format(FMT_STRING(_SYS_STR("{}.{}_{}.CSKR")), chSysName, overlaySys, cskrSys));
fmt::format(FMT_STRING("{}.{}_{}.CSKR"), ch.name, search->name, search->cskrId));
} else {
ch.cskrIce = inPath.ensureAuxInfo(fmt::format(FMT_STRING(_SYS_STR("{}.{}.CSKR")), chSysName, overlaySys));
ch.cskrIce = inPath.ensureAuxInfo(fmt::format(FMT_STRING("{}.{}.CSKR"), ch.name, search->name));
}
}
}
@ -1064,15 +1060,13 @@ bool ANCS::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
/* Set Animation Resource IDs */
ancs.enumeratePrimitives([&](AnimationSet::MetaAnimPrimitive& prim) {
hecl::SystemStringConv sysStr(prim.animName);
for (const DNAANCS::Action& act : actor.actions) {
if (act.name == prim.animName) {
hecl::ProjectPath pathOut;
if (!act.animId.empty()) {
hecl::SystemStringConv idSys(act.animId);
pathOut = inPath.ensureAuxInfo(fmt::format(FMT_STRING(_SYS_STR("{}_{}.ANIM")), sysStr, idSys));
pathOut = inPath.ensureAuxInfo(fmt::format(FMT_STRING("{}_{}.ANIM"), prim.animName, act.animId));
} else {
inPath.ensureAuxInfo(fmt::format(FMT_STRING(_SYS_STR("{}.ANIM")), sysStr));
inPath.ensureAuxInfo(fmt::format(FMT_STRING("{}.ANIM"), prim.animName));
}
prim.animId = pathOut;
break;
@ -1085,31 +1079,29 @@ bool ANCS::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
hecl::DirectoryEnumerator dEnum(inPath.getParentPath().getAbsolutePath());
ancs.animationSet.animResources.reserve(actor.actions.size());
for (const DNAANCS::Action& act : actor.actions) {
hecl::SystemStringConv sysStr(act.name);
hecl::ProjectPath pathOut;
if (!act.animId.empty()) {
hecl::SystemStringConv animIdSys(act.animId);
pathOut = inPath.ensureAuxInfo(fmt::format(FMT_STRING(_SYS_STR("{}_{}.ANIM")), sysStr, animIdSys));
pathOut = inPath.ensureAuxInfo(fmt::format(FMT_STRING("{}_{}.ANIM"), act.name, act.animId));
} else {
pathOut = inPath.ensureAuxInfo(fmt::format(FMT_STRING(_SYS_STR("{}.ANIM")), sysStr));
pathOut = inPath.ensureAuxInfo(fmt::format(FMT_STRING("{}.ANIM"), act.name));
}
ancs.animationSet.animResources.emplace_back();
ancs.animationSet.animResources.back().animId = pathOut;
/* Check for associated EVNT YAML */
hecl::SystemString testPrefix(
inPath.getWithExtension(fmt::format(FMT_STRING(_SYS_STR(".{}_")), sysStr).c_str(), true).getLastComponent());
std::string testPrefix(
inPath.getWithExtension(fmt::format(FMT_STRING(".{}_"), act.name).c_str(), true).getLastComponent());
hecl::ProjectPath evntYamlPath;
for (const auto& ent : dEnum) {
if (hecl::StringUtils::BeginsWith(ent.m_name, testPrefix.c_str()) &&
hecl::StringUtils::EndsWith(ent.m_name, _SYS_STR(".evnt.yaml"))) {
hecl::StringUtils::EndsWith(ent.m_name, ".evnt.yaml")) {
evntYamlPath = hecl::ProjectPath(inPath.getParentPath(), ent.m_name);
break;
}
}
if (evntYamlPath.isFile()) {
evntYamlPath = evntYamlPath.ensureAuxInfo(_SYS_STR(""));
evntYamlPath = evntYamlPath.ensureAuxInfo("");
ancs.animationSet.animResources.back().evntId = evntYamlPath;
}
}
@ -1121,27 +1113,25 @@ bool ANCS::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
return true;
}
static const hecl::SystemRegex regCskrNameId(_SYS_STR(R"((.*)_[0-9a-fA-F]{8}\.CSKR)"),
static const std::regex regCskrNameId(R"((.*)_[0-9a-fA-F]{8}\.CSKR)",
std::regex::ECMAScript | std::regex::optimize);
static const hecl::SystemRegex regCskrName(_SYS_STR(R"((.*)\.CSKR)"), std::regex::ECMAScript | std::regex::optimize);
static const std::regex regCskrName(R"((.*)\.CSKR)", std::regex::ECMAScript | std::regex::optimize);
bool ANCS::CookCSKR(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor,
const std::function<bool(const hecl::ProjectPath& modelPath)>& modelCookFunc) {
auto auxInfo = inPath.getAuxInfo();
hecl::SystemViewRegexMatch match;
std::match_results<std::string_view::const_iterator> match;
if (!std::regex_search(auxInfo.begin(), auxInfo.end(), match, regCskrNameId) &&
!std::regex_search(auxInfo.begin(), auxInfo.end(), match, regCskrName))
return false;
hecl::SystemString subName = match[1].str();
hecl::SystemString overName;
auto dotPos = subName.rfind(_SYS_STR('.'));
if (dotPos != hecl::SystemString::npos) {
overName = hecl::SystemString(subName.begin() + dotPos + 1, subName.end());
subName = hecl::SystemString(subName.begin(), subName.begin() + dotPos);
std::string subName = match[1].str();
std::string overName;
auto dotPos = subName.rfind('.');
if (dotPos != std::string::npos) {
overName = std::string(subName.begin() + dotPos + 1, subName.end());
subName = std::string(subName.begin(), subName.begin() + dotPos);
}
hecl::SystemUTF8Conv subNameView(subName);
hecl::SystemUTF8Conv overNameView(overName);
/* Build bone ID map */
std::unordered_map<std::string, atInt32> boneIdMap;
@ -1150,48 +1140,48 @@ bool ANCS::CookCSKR(const hecl::ProjectPath& outPath, const hecl::ProjectPath& i
}
const DNAANCS::Actor::Subtype* subtype = nullptr;
if (subName != _SYS_STR("ATTACH")) {
if (subName != "ATTACH") {
for (const DNAANCS::Actor::Subtype& sub : actor.subtypes) {
if (sub.name == subNameView.str()) {
if (sub.name == subName) {
subtype = &sub;
break;
}
}
if (!subtype)
Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("unable to find subtype '{}'")), subName);
Log.report(logvisor::Fatal, FMT_STRING("unable to find subtype '{}'"), subName);
}
const hecl::ProjectPath* modelPath = nullptr;
if (subName == _SYS_STR("ATTACH")) {
if (subName == "ATTACH") {
const DNAANCS::Actor::Attachment* attachment = nullptr;
for (const DNAANCS::Actor::Attachment& att : actor.attachments) {
if (att.name == overNameView.str()) {
if (att.name == overName) {
attachment = &att;
break;
}
}
if (!attachment)
Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("unable to find attachment '{}'")), overName);
Log.report(logvisor::Fatal, FMT_STRING("unable to find attachment '{}'"), overName);
modelPath = &attachment->mesh;
} else if (overName.empty()) {
modelPath = &subtype->mesh;
} else {
for (const auto& overlay : subtype->overlayMeshes)
if (overlay.name == overNameView.str()) {
if (overlay.name == overName) {
modelPath = &overlay.mesh;
break;
}
}
if (!modelPath)
Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("unable to resolve model path of {}:{}")), subName, overName);
Log.report(logvisor::Fatal, FMT_STRING("unable to resolve model path of {}:{}"), subName, overName);
if (!modelPath->isFile())
Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("unable to resolve '{}'")), modelPath->getRelativePath());
Log.report(logvisor::Fatal, FMT_STRING("unable to resolve '{}'"), modelPath->getRelativePath());
hecl::ProjectPath skinIntPath = modelPath->getCookedPath(SpecEntMP1).getWithExtension(_SYS_STR(".skinint"));
hecl::ProjectPath skinIntPath = modelPath->getCookedPath(SpecEntMP1).getWithExtension(".skinint");
if (!skinIntPath.isFileOrGlob() || skinIntPath.getModtime() < modelPath->getModtime())
if (!modelCookFunc(*modelPath))
Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("unable to cook '{}'")), modelPath->getRelativePath());
Log.report(logvisor::Fatal, FMT_STRING("unable to cook '{}'"), modelPath->getRelativePath());
std::vector<std::pair<std::vector<std::pair<uint32_t, float>>, uint32_t>> skins;
uint32_t posCount = 0;
@ -1216,7 +1206,7 @@ bool ANCS::CookCSKR(const hecl::ProjectPath& outPath, const hecl::ProjectPath& i
const std::string& name = boneNames[bIdx];
auto search = boneIdMap.find(name);
if (search == boneIdMap.cend())
Log.report(logvisor::Fatal, FMT_STRING("unable to find bone '{}' in {}"), name, inPath.getRelativePathUTF8());
Log.report(logvisor::Fatal, FMT_STRING("unable to find bone '{}' in {}"), name, inPath.getRelativePath());
virtualBone.first.emplace_back(search->second, weight);
}
virtualBone.second = skinIO.readUint32Big();
@ -1251,20 +1241,18 @@ bool ANCS::CookCSKR(const hecl::ProjectPath& outPath, const hecl::ProjectPath& i
bool ANCS::CookCSKRPC(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor,
const std::function<bool(const hecl::ProjectPath& modelPath)>& modelCookFunc) {
auto auxInfo = inPath.getAuxInfo();
hecl::SystemViewRegexMatch match;
std::match_results<std::string_view::const_iterator> match;
if (!std::regex_search(auxInfo.begin(), auxInfo.end(), match, regCskrNameId) &&
!std::regex_search(auxInfo.begin(), auxInfo.end(), match, regCskrName))
return false;
hecl::SystemString subName = match[1].str();
hecl::SystemString overName;
auto dotPos = subName.rfind(_SYS_STR('.'));
if (dotPos != hecl::SystemString::npos) {
overName = hecl::SystemString(subName.begin() + dotPos + 1, subName.end());
subName = hecl::SystemString(subName.begin(), subName.begin() + dotPos);
std::string subName = match[1].str();
std::string overName;
auto dotPos = subName.rfind('.');
if (dotPos != std::string::npos) {
overName = std::string(subName.begin() + dotPos + 1, subName.end());
subName = std::string(subName.begin(), subName.begin() + dotPos);
}
hecl::SystemUTF8Conv subNameView(subName);
hecl::SystemUTF8Conv overNameView(overName);
/* Build bone ID map */
std::unordered_map<std::string, atInt32> boneIdMap;
@ -1273,48 +1261,48 @@ bool ANCS::CookCSKRPC(const hecl::ProjectPath& outPath, const hecl::ProjectPath&
}
const DNAANCS::Actor::Subtype* subtype = nullptr;
if (subName != _SYS_STR("ATTACH")) {
if (subName != "ATTACH") {
for (const DNAANCS::Actor::Subtype& sub : actor.subtypes) {
if (sub.name == subNameView.str()) {
if (sub.name == subName) {
subtype = &sub;
break;
}
}
if (!subtype)
Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("unable to find subtype '{}'")), subName);
Log.report(logvisor::Fatal, FMT_STRING("unable to find subtype '{}'"), subName);
}
const hecl::ProjectPath* modelPath = nullptr;
if (subName == _SYS_STR("ATTACH")) {
if (subName == "ATTACH") {
const DNAANCS::Actor::Attachment* attachment = nullptr;
for (const DNAANCS::Actor::Attachment& att : actor.attachments) {
if (att.name == overNameView.str()) {
if (att.name == overName) {
attachment = &att;
break;
}
}
if (!attachment)
Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("unable to find attachment '{}'")), overName);
Log.report(logvisor::Fatal, FMT_STRING("unable to find attachment '{}'"), overName);
modelPath = &attachment->mesh;
} else if (overName.empty()) {
modelPath = &subtype->mesh;
} else {
for (const auto& overlay : subtype->overlayMeshes)
if (overlay.name == overNameView.str()) {
if (overlay.name == overName) {
modelPath = &overlay.mesh;
break;
}
}
if (!modelPath)
Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("unable to resolve model path of {}:{}")), subName, overName);
Log.report(logvisor::Fatal, FMT_STRING("unable to resolve model path of {}:{}"), subName, overName);
if (!modelPath->isFile())
Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("unable to resolve '{}'")), modelPath->getRelativePath());
Log.report(logvisor::Fatal, FMT_STRING("unable to resolve '{}'"), modelPath->getRelativePath());
hecl::ProjectPath skinIntPath = modelPath->getCookedPath(SpecEntMP1PC).getWithExtension(_SYS_STR(".skinint"));
hecl::ProjectPath skinIntPath = modelPath->getCookedPath(SpecEntMP1PC).getWithExtension(".skinint");
if (!skinIntPath.isFileOrGlob() || skinIntPath.getModtime() < modelPath->getModtime())
if (!modelCookFunc(*modelPath))
Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("unable to cook '{}'")), modelPath->getRelativePath());
Log.report(logvisor::Fatal, FMT_STRING("unable to cook '{}'"), modelPath->getRelativePath());
uint32_t bankCount = 0;
std::vector<std::vector<uint32_t>> skinBanks;
@ -1354,7 +1342,7 @@ bool ANCS::CookCSKRPC(const hecl::ProjectPath& outPath, const hecl::ProjectPath&
const std::string& name = boneNames[bIdx];
auto search = boneIdMap.find(name);
if (search == boneIdMap.cend())
Log.report(logvisor::Fatal, FMT_STRING("unable to find bone '{}' in {}"), name, inPath.getRelativePathUTF8());
Log.report(logvisor::Fatal, FMT_STRING("unable to find bone '{}' in {}"), name, inPath.getRelativePath());
virtualBone.emplace_back(search->second, weight);
}
}
@ -1374,7 +1362,7 @@ bool ANCS::CookCSKRPC(const hecl::ProjectPath& outPath, const hecl::ProjectPath&
const std::string& name = boneNames[bIdx];
auto search = boneIdMap.find(name);
if (search == boneIdMap.cend())
Log.report(logvisor::Fatal, FMT_STRING("unable to find bone '{}' in {}"), name, inPath.getRelativePathUTF8());
Log.report(logvisor::Fatal, FMT_STRING("unable to find bone '{}' in {}"), name, inPath.getRelativePath());
skinOut.writeUint32Big(search->second);
}
}
@ -1394,24 +1382,23 @@ bool ANCS::CookCSKRPC(const hecl::ProjectPath& outPath, const hecl::ProjectPath&
return true;
}
static const hecl::SystemRegex regAnimNameId(_SYS_STR(R"((.*)_[0-9a-fA-F]{8}\.ANIM)"),
static const std::regex regAnimNameId(R"((.*)_[0-9a-fA-F]{8}\.ANIM)",
std::regex::ECMAScript | std::regex::optimize);
static const hecl::SystemRegex regAnimName(_SYS_STR(R"((.*)\.ANIM)"), std::regex::ECMAScript | std::regex::optimize);
static const std::regex regAnimName(R"((.*)\.ANIM)", std::regex::ECMAScript | std::regex::optimize);
bool ANCS::CookANIM(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor,
hecl::blender::DataStream& ds, bool pc) {
auto auxInfo = inPath.getAuxInfo();
hecl::SystemViewRegexMatch match;
std::match_results<std::string_view::const_iterator> match;
if (!std::regex_search(auxInfo.begin(), auxInfo.end(), match, regAnimNameId) &&
!std::regex_search(auxInfo.begin(), auxInfo.end(), match, regAnimName))
return false;
hecl::SystemString actName = match[1].str();
hecl::SystemUTF8Conv actNameView(actName);
DNAANCS::Action action = ds.compileActionChannelsOnly(actNameView.str());
std::string actName = match[1].str();
DNAANCS::Action action = ds.compileActionChannelsOnly(actName);
if (!actor.armatures.size())
Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("0 armatures in {}")), inPath.getRelativePath());
Log.report(logvisor::Fatal, FMT_STRING("0 armatures in {}"), inPath.getRelativePath());
/* Build bone ID map */
std::unordered_map<std::string, atInt32> boneIdMap;
@ -1430,18 +1417,18 @@ bool ANCS::CookANIM(const hecl::ProjectPath& outPath, const hecl::ProjectPath& i
ANIM anim(action, boneIdMap, *rigInv, pc);
/* Check for associated EVNT YAML */
hecl::SystemString testPrefix(
inPath.getWithExtension(fmt::format(FMT_STRING(_SYS_STR(".{}_")), actName).c_str(), true).getLastComponent());
std::string testPrefix(
inPath.getWithExtension(fmt::format(FMT_STRING(".{}_"), actName).c_str(), true).getLastComponent());
hecl::ProjectPath evntYamlPath;
for (const auto& ent : hecl::DirectoryEnumerator(inPath.getParentPath().getAbsolutePath())) {
if (hecl::StringUtils::BeginsWith(ent.m_name, testPrefix.c_str()) &&
hecl::StringUtils::EndsWith(ent.m_name, _SYS_STR(".evnt.yaml"))) {
hecl::StringUtils::EndsWith(ent.m_name, ".evnt.yaml")) {
evntYamlPath = hecl::ProjectPath(inPath.getParentPath(), ent.m_name);
break;
}
}
if (evntYamlPath.isFile()) {
evntYamlPath = evntYamlPath.ensureAuxInfo(_SYS_STR(""));
evntYamlPath = evntYamlPath.ensureAuxInfo("");
anim.m_anim->evnt = evntYamlPath;
}

View File

@ -404,7 +404,7 @@ struct ANCS : BigDNA {
static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*)> fileChanged);
std::function<void(const char*)> fileChanged);
static bool Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor);

View File

@ -190,9 +190,8 @@ struct ANIM : BigDNA {
void extractEVNT(const DNAANCS::AnimationResInfo<UniqueID32>& animInfo, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, bool force) const {
if (m_anim->evnt.isValid()) {
hecl::SystemStringConv sysStr(animInfo.name);
hecl::ProjectPath evntYamlPath = outPath.getWithExtension(
fmt::format(FMT_STRING(_SYS_STR(".{}_{}.evnt.yaml")), sysStr, m_anim->evnt).c_str(), true);
fmt::format(FMT_STRING(".{}_{}.evnt.yaml"), animInfo.name, m_anim->evnt).c_str(), true);
hecl::ProjectPath::Type evntYamlType = evntYamlPath.getPathType();
if (force || evntYamlType == hecl::ProjectPath::Type::None) {

View File

@ -156,7 +156,7 @@ CINF::CINF(const Armature& armature, std::unordered_map<std::string, atInt32>& i
bool CINF::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*)> fileChanged) {
std::function<void(const char*)> fileChanged) {
if (!force && outPath.isFile())
return true;

View File

@ -48,7 +48,7 @@ struct CINF : BigDNA {
static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*)> fileChanged);
std::function<void(const char*)> fileChanged);
static bool Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath,
const hecl::blender::Armature& armature);

View File

@ -5,7 +5,7 @@ namespace DataSpec::DNAMP1 {
bool CMDL::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*)> fileChanged) {
std::function<void(const char*)> fileChanged) {
/* Check for RigPair */
CINF cinf;
CSKR cskr;
@ -28,14 +28,14 @@ bool CMDL::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
#if 0
/* Cook and re-extract test */
hecl::ProjectPath tempOut = outPath.getWithExtension(_SYS_STR(".recook"), true);
hecl::ProjectPath tempOut = outPath.getWithExtension(".recook", true);
hecl::blender::Connection::DataStream ds = conn.beginData();
DNACMDL::Mesh mesh = ds.compileMesh(hecl::TopologyTriStrips, -1);
ds.close();
DNACMDL::WriteCMDL<MaterialSet, DNACMDL::SurfaceHeader_1_2, 2>(tempOut, outPath, mesh);
athena::io::FileReader reader(tempOut.getAbsolutePath());
hecl::ProjectPath tempBlend = outPath.getWithExtension(_SYS_STR(".recook.blend"), true);
hecl::ProjectPath tempBlend = outPath.getWithExtension(".recook.blend", true);
if (!conn.createBlend(tempBlend, hecl::blender::Connection::TypeMesh))
return false;
DNACMDL::ReadCMDLToBlender<PAKRouter<PAKBridge>, MaterialSet, std::pair<CSKR*,CINF*>, DNACMDL::SurfaceHeader_1_2, 2>
@ -43,7 +43,7 @@ bool CMDL::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
return conn.saveBlend();
#elif 0
/* HMDL cook test */
hecl::ProjectPath tempOut = outPath.getWithExtension(_SYS_STR(".recook"), true);
hecl::ProjectPath tempOut = outPath.getWithExtension(".recook", true);
hecl::blender::Connection::DataStream ds = conn.beginData();
DNACMDL::Mesh mesh = ds.compileMesh(hecl::HMDLTopology::TriStrips, 16);
ds.close();
@ -61,7 +61,7 @@ bool CMDL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
/* Output skinning intermediate */
auto vertCountIt = skinMesh.contiguousSkinVertCounts.cbegin();
athena::io::FileWriter writer(outPath.getWithExtension(_SYS_STR(".skinint")).getAbsolutePath());
athena::io::FileWriter writer(outPath.getWithExtension(".skinint").getAbsolutePath());
writer.writeUint32Big(skinMesh.boneNames.size());
for (const std::string& boneName : skinMesh.boneNames)
writer.writeString(boneName);
@ -90,7 +90,7 @@ bool CMDL::HMDLCook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& i
return false;
/* Output skinning intermediate */
athena::io::FileWriter writer(outPath.getWithExtension(_SYS_STR(".skinint")).getAbsolutePath());
athena::io::FileWriter writer(outPath.getWithExtension(".skinint").getAbsolutePath());
writer.writeUint32Big(mesh.skinBanks.banks.size());
for (const DNACMDL::Mesh::SkinBanks::Bank& sb : mesh.skinBanks.banks) {
writer.writeUint32Big(sb.m_boneIdxs.size());

View File

@ -14,7 +14,7 @@ namespace DataSpec::DNAMP1 {
struct CMDL {
static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*)> fileChanged);
std::function<void(const char*)> fileChanged);
static void Name(const SpecBase& dataSpec, PAKEntryReadStream& rs, PAKRouter<PAKBridge>& pakRouter,
PAK::Entry& entry) {

View File

@ -4,8 +4,8 @@
namespace DataSpec::DNAMP1 {
bool CSNG::Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
hecl::ProjectPath midPath = outPath.getWithExtension(_SYS_STR(".mid"), true);
hecl::ProjectPath yamlPath = outPath.getWithExtension(_SYS_STR(".yaml"), true);
hecl::ProjectPath midPath = outPath.getWithExtension(".mid", true);
hecl::ProjectPath yamlPath = outPath.getWithExtension(".yaml", true);
Header head;
head.read(rs);
@ -36,16 +36,16 @@ bool CSNG::Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
}
/* Update !songs.yaml for Amuse editor */
hecl::ProjectPath audGrp(outPath.getParentPath().getParentPath(), _SYS_STR("AudioGrp"));
hecl::ProjectPath audGrp(outPath.getParentPath().getParentPath(), "AudioGrp");
audGrp.makeDirChain(true);
hecl::ProjectPath songsPath(audGrp, _SYS_STR("!songs.yaml"));
hecl::ProjectPath songsPath(audGrp, "!songs.yaml");
std::optional<athena::io::FileReader> r;
if (songsPath.isFile())
r.emplace(songsPath.getAbsolutePath());
athena::io::YAMLDocWriter ydw("amuse::Songs", r ? &*r : nullptr);
r = std::nullopt;
ydw.writeString(fmt::format(FMT_STRING("{:04X}"), head.midiSetupId),
fmt::format(FMT_STRING("../MidiData/{}"), midPath.getLastComponentUTF8()));
fmt::format(FMT_STRING("../MidiData/{}"), midPath.getLastComponent()));
athena::io::FileWriter w(songsPath.getAbsolutePath());
ydw.finish(&w);
@ -53,8 +53,8 @@ bool CSNG::Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
}
bool CSNG::Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath) {
hecl::ProjectPath midPath = inPath.getWithExtension(_SYS_STR(".mid"), true);
hecl::ProjectPath yamlPath = inPath.getWithExtension(_SYS_STR(".yaml"), true);
hecl::ProjectPath midPath = inPath.getWithExtension(".mid", true);
hecl::ProjectPath yamlPath = inPath.getWithExtension(".yaml", true);
std::vector<uint8_t> sngData;
{

View File

@ -54,7 +54,7 @@ void DCLN::sendToBlender(hecl::blender::Connection& conn, std::string_view entry
bool DCLN::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*)> fileChanged) {
std::function<void(const char*)> fileChanged) {
DCLN dcln;
dcln.read(rs);
hecl::blender::Connection& conn = btok.getBlenderConnection();
@ -78,7 +78,7 @@ bool DCLN::Cook(const hecl::ProjectPath& outPath, const std::vector<Mesh>& meshe
#if DCLN_DUMP_OBB
hecl::blender::Connection& conn = hecl::blender::SharedBlenderToken.getBlenderConnection();
conn.createBlend(outPath.getWithExtension(_SYS_STR(".blend")), hecl::blender::BlendType::ColMesh);
conn.createBlend(outPath.getWithExtension(".blend"), hecl::blender::BlendType::ColMesh);
dcln.sendToBlender(conn, "BLAH");
conn.saveBlend();
#endif

View File

@ -86,7 +86,7 @@ struct DCLN : BigDNA {
static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*)> fileChanged);
std::function<void(const char*)> fileChanged);
static bool Cook(const hecl::ProjectPath& outPath, const std::vector<Mesh>& meshes);
};

View File

@ -78,18 +78,18 @@ PAKBridge::PAKBridge(const nod::Node& node, bool doExtract)
STRG mlvlName;
mlvlName.read(rs);
if (m_levelString.size())
m_levelString += _SYS_STR(", ");
m_levelString += mlvlName.getSystemString(FOURCC('ENGL'), 0);
m_levelString += ", ";
m_levelString += mlvlName.getUTF8(FOURCC('ENGL'), 0);
}
}
}
}
static hecl::SystemString LayerName(std::string_view name) {
hecl::SystemString ret(hecl::SystemStringConv(name).sys_str());
static std::string LayerName(std::string_view name) {
std::string ret(name);
for (auto& ch : ret)
if (ch == _SYS_STR('/') || ch == _SYS_STR('\\'))
ch = _SYS_STR('-');
if (ch == '/' || ch == '\\')
ch = '-';
return ret;
}
@ -106,7 +106,7 @@ void PAKBridge::build() {
}
std::string catalogueName;
std::string bestName = m_pak.bestEntryName(m_node, entry, catalogueName);
level.name = hecl::SystemStringConv(bestName).sys_str();
level.name = bestName;
level.areas.reserve(mlvl.areaCount);
unsigned layerIdx = 0;
@ -148,17 +148,17 @@ void PAKBridge::build() {
PAKEntryReadStream rs = areaNameEnt->beginReadStream(m_node);
areaName.read(rs);
}
areaDeps.name = areaName.getSystemString(FOURCC('ENGL'), 0);
areaDeps.name = areaName.getUTF8(FOURCC('ENGL'), 0);
areaDeps.name = hecl::StringUtils::TrimWhitespace(areaDeps.name);
}
if (areaDeps.name.empty()) {
std::string idStr = area.areaMREAId.toString();
areaDeps.name = hecl::SystemString(_SYS_STR("MREA_")) + hecl::SystemStringConv(idStr).c_str();
areaDeps.name = std::string("MREA_") + idStr;
}
hecl::SystemString num = fmt::format(FMT_STRING(_SYS_STR("{:02d} ")), ai);
std::string num = fmt::format(FMT_STRING("{:02d} "), ai);
areaDeps.name = num + areaDeps.name;
std::string lowerName(hecl::SystemUTF8Conv(areaDeps.name).str());
std::string lowerName(areaDeps.name);
for (char& ch : lowerName) {
ch = tolower(ch);
if (ch == ' ')
@ -179,7 +179,7 @@ void PAKBridge::build() {
layer.active = layerFlags.flags >> (l - 1) & 0x1;
layer.name = hecl::StringUtils::TrimWhitespace(layer.name);
num = fmt::format(FMT_STRING(_SYS_STR("{:02d} ")), l - 1);
num = fmt::format(FMT_STRING("{:02d} "), l - 1);
layer.name = num + layer.name;
layer.resources.reserve(area.depLayers[l] - r);
@ -277,7 +277,7 @@ void PAKBridge::addMAPATransforms(PAKRouter<PAKBridge>& pakRouter,
if (mlvl.worldNameId.isValid())
pathOverrides[mlvl.worldNameId] =
hecl::ProjectPath(mlvlDirPath, fmt::format(FMT_STRING(_SYS_STR("!name_{}.yaml")), mlvl.worldNameId));
hecl::ProjectPath(mlvlDirPath, fmt::format(FMT_STRING("!name_{}.yaml"), mlvl.worldNameId));
for (const MLVL::Area& area : mlvl.areas) {
{
@ -294,7 +294,7 @@ void PAKBridge::addMAPATransforms(PAKRouter<PAKBridge>& pakRouter,
hecl::ProjectPath areaDirPath = pakRouter.getWorking(area.areaMREAId).getParentPath();
if (area.areaNameId.isValid())
pathOverrides[area.areaNameId] =
hecl::ProjectPath(areaDirPath, fmt::format(FMT_STRING(_SYS_STR("!name_{}.yaml")), area.areaNameId));
hecl::ProjectPath(areaDirPath, fmt::format(FMT_STRING("!name_{}.yaml"), area.areaNameId));
}
if (mlvl.worldMap.isValid()) {
@ -324,61 +324,61 @@ void PAKBridge::addMAPATransforms(PAKRouter<PAKBridge>& pakRouter,
ResExtractor<PAKBridge> PAKBridge::LookupExtractor(const nod::Node& pakNode, const PAK& pak, const PAK::Entry& entry) {
switch (entry.type.toUint32()) {
case SBIG('STRG'):
return {STRG::Extract, {_SYS_STR(".yaml")}};
return {STRG::Extract, {".yaml"}};
case SBIG('SCAN'):
return {SCAN::Extract, {_SYS_STR(".yaml")}, 0, SCAN::Name};
return {SCAN::Extract, {".yaml"}, 0, SCAN::Name};
case SBIG('HINT'):
return {HINT::Extract, {_SYS_STR(".yaml")}};
return {HINT::Extract, {".yaml"}};
case SBIG('TXTR'):
return {TXTR::Extract, {_SYS_STR(".png")}};
return {TXTR::Extract, {".png"}};
case SBIG('AFSM'):
return {AFSM::Extract, {_SYS_STR(".yaml")}};
return {AFSM::Extract, {".yaml"}};
case SBIG('FRME'):
return {FRME::Extract, {_SYS_STR(".blend")}, 2};
return {FRME::Extract, {".blend"}, 2};
case SBIG('CINF'):
return {CINF::Extract, {_SYS_STR(".blend")}, 1};
return {CINF::Extract, {".blend"}, 1};
case SBIG('CMDL'):
return {CMDL::Extract, {_SYS_STR(".blend")}, 1, CMDL::Name};
return {CMDL::Extract, {".blend"}, 1, CMDL::Name};
case SBIG('DCLN'):
return {DCLN::Extract, {_SYS_STR(".blend")}};
return {DCLN::Extract, {".blend"}};
case SBIG('ANCS'):
return {ANCS::Extract, {_SYS_STR(".yaml"), _SYS_STR(".blend")}, 2};
return {ANCS::Extract, {".yaml", ".blend"}, 2};
case SBIG('MLVL'):
return {MLVL::Extract, {_SYS_STR(".yaml"), _SYS_STR(".blend")}, 3};
return {MLVL::Extract, {".yaml", ".blend"}, 3};
case SBIG('SAVW'):
return {MLVL::ExtractSAVW, {_SYS_STR(".yaml")}, 3};
return {MLVL::ExtractSAVW, {".yaml"}, 3};
case SBIG('MREA'):
return {MREA::Extract, {_SYS_STR(".blend")}, 4, MREA::Name};
return {MREA::Extract, {".blend"}, 4, MREA::Name};
case SBIG('MAPA'):
return {MAPA::Extract, {_SYS_STR(".blend")}, 4};
return {MAPA::Extract, {".blend"}, 4};
case SBIG('MAPW'):
return {MLVL::ExtractMAPW, {_SYS_STR(".yaml")}, 4};
return {MLVL::ExtractMAPW, {".yaml"}, 4};
case SBIG('MAPU'):
return {MAPU::Extract, {_SYS_STR(".blend")}, 5};
return {MAPU::Extract, {".blend"}, 5};
case SBIG('PATH'):
return {PATH::Extract, {_SYS_STR(".blend")}, 5};
return {PATH::Extract, {".blend"}, 5};
case SBIG('PART'):
return {DNAParticle::ExtractGPSM<UniqueID32>, {_SYS_STR(".gpsm.yaml")}};
return {DNAParticle::ExtractGPSM<UniqueID32>, {".gpsm.yaml"}};
case SBIG('ELSC'):
return {DNAParticle::ExtractELSM<UniqueID32>, {_SYS_STR(".elsm.yaml")}};
return {DNAParticle::ExtractELSM<UniqueID32>, {".elsm.yaml"}};
case SBIG('SWHC'):
return {DNAParticle::ExtractSWSH<UniqueID32>, {_SYS_STR(".swsh.yaml")}};
return {DNAParticle::ExtractSWSH<UniqueID32>, {".swsh.yaml"}};
case SBIG('CRSC'):
return {DNAParticle::ExtractCRSM<UniqueID32>, {_SYS_STR(".crsm.yaml")}};
return {DNAParticle::ExtractCRSM<UniqueID32>, {".crsm.yaml"}};
case SBIG('WPSC'):
return {DNAParticle::ExtractWPSM<UniqueID32>, {_SYS_STR(".wpsm.yaml")}};
return {DNAParticle::ExtractWPSM<UniqueID32>, {".wpsm.yaml"}};
case SBIG('DPSC'):
return {DNAParticle::ExtractDPSM<UniqueID32>, {_SYS_STR(".dpsm.yaml")}};
return {DNAParticle::ExtractDPSM<UniqueID32>, {".dpsm.yaml"}};
case SBIG('FONT'):
return {DNAFont::ExtractFONT<UniqueID32>, {_SYS_STR(".yaml")}};
return {DNAFont::ExtractFONT<UniqueID32>, {".yaml"}};
case SBIG('DGRP'):
return {DNADGRP::ExtractDGRP<UniqueID32>, {_SYS_STR(".yaml")}};
return {DNADGRP::ExtractDGRP<UniqueID32>, {".yaml"}};
case SBIG('AGSC'):
return {AGSC::Extract, {}};
case SBIG('CSNG'):
return {CSNG::Extract, {_SYS_STR(".mid"), _SYS_STR(".yaml")}};
return {CSNG::Extract, {".mid", ".yaml"}};
case SBIG('ATBL'):
return {DNAAudio::ATBL::Extract, {_SYS_STR(".yaml")}};
return {DNAAudio::ATBL::Extract, {".yaml"}};
case SBIG('CTWK'):
case SBIG('DUMB'): {
std::string catalogueName;
@ -387,47 +387,47 @@ ResExtractor<PAKBridge> PAKBridge::LookupExtractor(const nod::Node& pakNode, con
if (catalogueName == "PlayerRes"sv) {
if (isCurrentSpecWii() || getCurrentRegion() == ERegion::PAL || getCurrentRegion() == ERegion::NTSC_J) {
/* We need to use the new rep for these tweaks */
return {ExtractTweak<CTweakPlayerRes<true>>, {_SYS_STR(".yaml")}};
return {ExtractTweak<CTweakPlayerRes<true>>, {".yaml"}};
}
/* We need to use the old rep for these tweaks */
return {ExtractTweak<CTweakPlayerRes<false>>, {_SYS_STR(".yaml")}};
return {ExtractTweak<CTweakPlayerRes<false>>, {".yaml"}};
}
if (catalogueName == "GunRes"sv)
return {ExtractTweak<CTweakGunRes>, {_SYS_STR(".yaml")}};
return {ExtractTweak<CTweakGunRes>, {".yaml"}};
if (catalogueName == "Player"sv)
return {ExtractTweak<CTweakPlayer>, {_SYS_STR(".yaml")}};
return {ExtractTweak<CTweakPlayer>, {".yaml"}};
if (catalogueName == "CameraBob"sv)
return {ExtractTweak<CTweakCameraBob>, {_SYS_STR(".yaml")}};
return {ExtractTweak<CTweakCameraBob>, {".yaml"}};
if (catalogueName == "SlideShow"sv)
return {ExtractTweak<CTweakSlideShow>, {_SYS_STR(".yaml")}};
return {ExtractTweak<CTweakSlideShow>, {".yaml"}};
if (catalogueName == "Game"sv)
return {ExtractTweak<CTweakGame>, {_SYS_STR(".yaml")}};
return {ExtractTweak<CTweakGame>, {".yaml"}};
if (catalogueName == "Targeting"sv) {
if (isCurrentSpecWii() || getCurrentRegion() == ERegion::PAL || getCurrentRegion() == ERegion::NTSC_J) {
/* We need to use the new rep for these tweaks */
return {ExtractTweak<CTweakTargeting<true>>, {_SYS_STR(".yaml")}};
return {ExtractTweak<CTweakTargeting<true>>, {".yaml"}};
}
/* We need to use the old rep for these tweaks */
return {ExtractTweak<CTweakTargeting<false>>, {_SYS_STR(".yaml")}};
return {ExtractTweak<CTweakTargeting<false>>, {".yaml"}};
}
if (catalogueName == "Gui"sv)
return {ExtractTweak<CTweakGui>, {_SYS_STR(".yaml")}};
return {ExtractTweak<CTweakGui>, {".yaml"}};
if (catalogueName == "AutoMapper"sv)
return {ExtractTweak<CTweakAutoMapper>, {_SYS_STR(".yaml")}};
return {ExtractTweak<CTweakAutoMapper>, {".yaml"}};
if (catalogueName == "PlayerControls"sv || catalogueName == "PlayerControls2"sv)
return {ExtractTweak<CTweakPlayerControl>, {_SYS_STR(".yaml")}};
return {ExtractTweak<CTweakPlayerControl>, {".yaml"}};
if (catalogueName == "Ball"sv)
return {ExtractTweak<CTweakBall>, {_SYS_STR(".yaml")}};
return {ExtractTweak<CTweakBall>, {".yaml"}};
if (catalogueName == "Particle"sv)
return {ExtractTweak<CTweakParticle>, {_SYS_STR(".yaml")}};
return {ExtractTweak<CTweakParticle>, {".yaml"}};
if (catalogueName == "GuiColors"sv)
return {ExtractTweak<CTweakGuiColors>, {_SYS_STR(".yaml")}};
return {ExtractTweak<CTweakGuiColors>, {".yaml"}};
if (catalogueName == "PlayerGun"sv)
return {ExtractTweak<CTweakPlayerGun>, {_SYS_STR(".yaml")}};
return {ExtractTweak<CTweakPlayerGun>, {".yaml"}};
if (catalogueName == "DUMB_MazeSeeds"sv)
return {ExtractTweak<MazeSeeds>, {_SYS_STR(".yaml")}};
return {ExtractTweak<MazeSeeds>, {".yaml"}};
if (catalogueName == "DUMB_SnowForces"sv)
return {ExtractTweak<SnowForces>, {_SYS_STR(".yaml")}};
return {ExtractTweak<SnowForces>, {".yaml"}};
}
break;
}

View File

@ -18,14 +18,14 @@ public:
using Level = DataSpec::Level<UniqueID32>;
std::unordered_map<UniqueID32, Level> m_levelDeps;
UniqueID32 m_levelId;
hecl::SystemString m_levelString;
std::string m_levelString;
PAKBridge(const nod::Node& node, bool doExtract = true);
void build();
static ResExtractor<PAKBridge> LookupExtractor(const nod::Node& pakNode, const PAK& pak, const PAK::Entry& entry);
std::string_view getName() const { return m_node.getName(); }
UniqueID32 getLevelId() const { return m_levelId; }
hecl::SystemStringView getLevelString() const { return m_levelString; }
std::string_view getLevelString() const { return m_levelString; }
using PAKType = PAK;
const PAKType& getPAK() const { return m_pak; }
const nod::Node& getNode() const { return m_node; }

View File

@ -93,7 +93,7 @@ void FRME::Widget::Enumerate<BigDNA::Read>(athena::io::IStreamReader& __dna_read
widgetInfo = std::make_unique<SLGPInfo>();
break;
default:
Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("Unsupported FRME widget type {}")), type);
Log.report(logvisor::Fatal, FMT_STRING("Unsupported FRME widget type {}"), type);
}
/* widgetInfo */
@ -174,7 +174,7 @@ void FRME::Widget::CAMRInfo::Enumerate<BigDNA::Read>(athena::io::IStreamReader&
} else if (projectionType == ProjectionType::Orthographic) {
projection = std::make_unique<OrthographicProjection>();
} else {
Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("Invalid CAMR projection mode! {}")), int(projectionType));
Log.report(logvisor::Fatal, FMT_STRING("Invalid CAMR projection mode! {}"), int(projectionType));
}
projection->read(__dna_reader);
@ -183,9 +183,9 @@ void FRME::Widget::CAMRInfo::Enumerate<BigDNA::Read>(athena::io::IStreamReader&
template <>
void FRME::Widget::CAMRInfo::Enumerate<BigDNA::Write>(athena::io::IStreamWriter& __dna_writer) {
if (!projection)
Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("Invalid CAMR projection object!")));
Log.report(logvisor::Fatal, FMT_STRING("Invalid CAMR projection object!"));
if (projection->type != projectionType)
Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("CAMR projection type does not match actual projection type!")));
Log.report(logvisor::Fatal, FMT_STRING("CAMR projection type does not match actual projection type!"));
__dna_writer.writeUint32Big(atUint32(projectionType));
projection->write(__dna_writer);
@ -274,7 +274,7 @@ AT_SPECIALIZE_DNA(FRME::Widget::TXPNInfo)
bool FRME::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*)> fileChanged) {
std::function<void(const char*)> fileChanged) {
if (!force && outPath.isFile())
return true;
@ -390,7 +390,7 @@ bool FRME::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
using IMGPInfo = Widget::IMGPInfo;
if (IMGPInfo* info = static_cast<IMGPInfo*>(w.widgetInfo.get())) {
std::string texName;
hecl::SystemString resPath;
std::string resPath;
if (info->texture.isValid()) {
texName = pakRouter.getBestEntryName(info->texture);
const nod::Node* node;
@ -405,13 +405,12 @@ bool FRME::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
}
if (resPath.size()) {
hecl::SystemUTF8Conv resPathView(resPath);
os.format(FMT_STRING("if '{}' in bpy.data.images:\n"
" image = bpy.data.images['{}']\n"
"else:\n"
" image = bpy.data.images.load('''//{}''')\n"
" image.name = '{}'\n"),
texName, texName, resPathView, texName);
texName, texName, resPath, texName);
} else {
os << "image = None\n";
}
@ -489,7 +488,7 @@ bool FRME::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
hecl::ProjectPath modelPath = pakRouter.getWorking(info->model);
const PAKRouter<PAKBridge>::EntryType* cmdlE = pakRouter.lookupEntry(info->model, nullptr, true, true);
os.linkMesh(modelPath.getAbsolutePathUTF8(), pakRouter.getBestEntryName(*cmdlE));
os.linkMesh(modelPath.getAbsolutePath(), pakRouter.getBestEntryName(*cmdlE));
os.format(FMT_STRING("frme_obj.retro_model_light_mask = {}\n"), info->lightMask);
os << "print(obj.name)\n"
@ -536,10 +535,10 @@ bool FRME::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
"bpy.types.Object.retro_textpane_hjustification[1]['items'][{}][0]\n"
"frme_obj.retro_textpane_vjustification = "
"bpy.types.Object.retro_textpane_vjustification[1]['items'][{}][0]\n"),
info->xDim, info->zDim, scaleF[0], scaleF[1], scaleF[2], fontPath.getRelativePathUTF8(),
info->xDim, info->zDim, scaleF[0], scaleF[1], scaleF[2], fontPath.getRelativePath(),
info->wordWrap ? "True" : "False", info->horizontal ? "True" : "False", fillF[0], fillF[1], fillF[2],
fillF[3], outlineF[0], outlineF[1], outlineF[2], outlineF[3], extentF[0], extentF[1],
jpFontPath.getRelativePathUTF8(), info->jpnPointScale[0], info->jpnPointScale[1],
jpFontPath.getRelativePath(), info->jpnPointScale[0], info->jpnPointScale[1],
int(info->justification), int(info->verticalJustification));
}
} else if (w.type == SBIG('TBGP')) {
@ -569,7 +568,7 @@ bool FRME::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
if (ENRGInfo* info = static_cast<ENRGInfo*>(w.widgetInfo.get())) {
hecl::ProjectPath txtrPath = pakRouter.getWorking(info->texture);
if (txtrPath)
os.format(FMT_STRING("frme_obj.retro_energybar_texture_path = '{}'\n"), txtrPath.getRelativePathUTF8());
os.format(FMT_STRING("frme_obj.retro_energybar_texture_path = '{}'\n"), txtrPath.getRelativePath());
}
} else if (w.type == SBIG('METR')) {
using METRInfo = Widget::METRInfo;

View File

@ -268,7 +268,7 @@ struct FRME : BigDNA {
Vector<Widget, AT_DNA_COUNT(widgetCount)> widgets;
static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*)> fileChanged);
std::function<void(const char*)> fileChanged);
};
} // namespace DataSpec::DNAMP1

View File

@ -11,7 +11,7 @@ namespace DataSpec::DNAMP1 {
struct MAPA : DNAMAPA::MAPA {
static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*)> fileChanged) {
std::function<void(const char*)> fileChanged) {
MAPA mapa;
mapa.read(rs);
hecl::blender::Connection& conn = btok.getBlenderConnection();

View File

@ -11,7 +11,7 @@ namespace DataSpec::DNAMP1 {
struct MAPU : DNAMAPU::MAPU {
static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*)> fileChanged) {
std::function<void(const char*)> fileChanged) {
MAPU mapu;
mapu.read(rs);
hecl::blender::Connection& conn = btok.getBlenderConnection();

View File

@ -16,7 +16,7 @@ namespace DNAMP1 {
bool MLVL::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*)> fileChanged) {
std::function<void(const char*)> fileChanged) {
MLVL mlvl;
mlvl.read(rs);
const nod::Node* node;
@ -31,13 +31,13 @@ bool MLVL::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
for (const MLVL::Area& area : mlvl.areas) {
hecl::ProjectPath areaDir = pakRouter.getWorking(area.areaMREAId).getParentPath();
{
athena::io::FileWriter fw(hecl::ProjectPath(areaDir, _SYS_STR("!memoryid.yaml")).getAbsolutePath());
athena::io::FileWriter fw(hecl::ProjectPath(areaDir, "!memoryid.yaml").getAbsolutePath());
athena::io::YAMLDocWriter w;
w.writeUint32("memoryid", area.areaId);
w.finish(&fw);
}
{
athena::io::FileWriter fw(hecl::ProjectPath(areaDir, _SYS_STR("!memoryrelays.yaml")).getAbsolutePath());
athena::io::FileWriter fw(hecl::ProjectPath(areaDir, "!memoryrelays.yaml").getAbsolutePath());
athena::io::YAMLDocWriter w;
std::vector<atUint32> relayIds;
@ -51,12 +51,12 @@ bool MLVL::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
w.finish(&fw);
}
if (pakRouter.mreaHasDupeResources(area.areaMREAId))
athena::io::FileWriter(hecl::ProjectPath(areaDir, _SYS_STR("!duperes")).getAbsolutePath());
athena::io::FileWriter(hecl::ProjectPath(areaDir, "!duperes").getAbsolutePath());
areaIdx++;
}
athena::io::FileWriter writer(outPath.getWithExtension(_SYS_STR(".yaml"), true).getAbsolutePath());
athena::io::FileWriter writer(outPath.getWithExtension(".yaml", true).getAbsolutePath());
athena::io::ToYAMLStream(mlvl, writer, &MLVL::writeMeta);
hecl::blender::Connection& conn = btok.getBlenderConnection();
return DNAMLVL::ReadMLVLToBlender(conn, mlvl, outPath, pakRouter, entry, force, fileChanged);
@ -104,7 +104,7 @@ struct LayerResources {
bool MLVL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const World& wld,
hecl::blender::Token& btok) {
MLVL mlvl = {};
athena::io::FileReader reader(inPath.getWithExtension(_SYS_STR(".yaml"), true).getAbsolutePath());
athena::io::FileReader reader(inPath.getWithExtension(".yaml", true).getAbsolutePath());
athena::io::FromYAMLStream(mlvl, reader, &MLVL::readMeta);
const hecl::ProjectPath parentPath = inPath.getParentPath();
@ -112,15 +112,15 @@ bool MLVL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
mlvl.magic = 0xDEAFBABE;
mlvl.version = 0x11;
hecl::ProjectPath namePath = GetPathBeginsWith(dEnum, parentPath, _SYS_STR("!name"));
hecl::ProjectPath namePath = GetPathBeginsWith(dEnum, parentPath, "!name");
if (namePath.isFile())
mlvl.worldNameId = namePath;
hecl::ProjectPath savwPath = GetPathBeginsWith(dEnum, parentPath, _SYS_STR("!savw"));
hecl::ProjectPath savwPath = GetPathBeginsWith(dEnum, parentPath, "!savw");
if (savwPath.isFile()) {
CookSAVW(savwPath.getCookedPath(SpecEntMP1), wld);
mlvl.saveWorldId = savwPath;
}
hecl::ProjectPath mapwPath = GetPathBeginsWith(dEnum, parentPath, _SYS_STR("!mapw"));
hecl::ProjectPath mapwPath = GetPathBeginsWith(dEnum, parentPath, "!mapw");
if (mapwPath.isFile()) {
CookMAPW(mapwPath.getCookedPath(SpecEntMP1), wld);
mlvl.worldMap = mapwPath;
@ -133,13 +133,13 @@ bool MLVL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
continue;
const hecl::DirectoryEnumerator areaDEnum(area.path.getAbsolutePath());
const hecl::ProjectPath areaPath = GetPathBeginsWith(areaDEnum, area.path, _SYS_STR("!area"));
const hecl::ProjectPath areaPath = GetPathBeginsWith(areaDEnum, area.path, "!area");
if (!areaPath.isFile())
continue;
Log.report(logvisor::Info, FMT_STRING(_SYS_STR("Visiting {}")), area.path.getRelativePath());
Log.report(logvisor::Info, FMT_STRING("Visiting {}"), area.path.getRelativePath());
hecl::ProjectPath memRelayPath(area.path, _SYS_STR("!memoryrelays.yaml"));
hecl::ProjectPath memRelayPath(area.path, "!memoryrelays.yaml");
std::vector<atUint32> memRelays;
@ -159,15 +159,15 @@ bool MLVL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
LayerResources layerResources;
for (const hecl::DirectoryEnumerator::Entry& e :
hecl::DirectoryEnumerator(area.path.getAbsolutePath(), hecl::DirectoryEnumerator::Mode::DirsSorted)) {
hecl::SystemString layerName;
hecl::SystemChar* endCh = nullptr;
std::string layerName;
char* endCh = nullptr;
hecl::StrToUl(e.m_name.c_str(), &endCh, 10);
if (!endCh)
layerName = hecl::StringUtils::TrimWhitespace(e.m_name);
else
layerName = hecl::StringUtils::TrimWhitespace(hecl::SystemString(endCh));
layerName = hecl::StringUtils::TrimWhitespace(std::string(endCh));
hecl::ProjectPath objectsPath(area.path, e.m_name + _SYS_STR("/!objects.yaml"));
hecl::ProjectPath objectsPath(area.path, e.m_name + "/!objects.yaml");
if (objectsPath.isNone())
continue;
@ -189,7 +189,7 @@ bool MLVL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
layerResources.beginLayer();
/* Set active flag state */
hecl::ProjectPath defActivePath(area.path, e.m_name + _SYS_STR("/!defaultactive"));
hecl::ProjectPath defActivePath(area.path, e.m_name + "/!defaultactive");
bool active = defActivePath.isNone() ? false : true;
if (!areaInit) {
@ -200,7 +200,7 @@ bool MLVL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
mlvl.areas.emplace_back();
MLVL::Area& areaOut = mlvl.areas.back();
namePath = GetPathBeginsWith(areaDEnum, area.path, _SYS_STR("!name"));
namePath = GetPathBeginsWith(areaDEnum, area.path, "!name");
if (namePath.isFile())
areaOut.areaNameId = namePath;
@ -212,7 +212,7 @@ bool MLVL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
areaOut.areaMREAId = areaPath;
areaOut.areaId = 0xffffffff;
hecl::ProjectPath memIdPath(area.path, _SYS_STR("!memoryid.yaml"));
hecl::ProjectPath memIdPath(area.path, "!memoryid.yaml");
if (memIdPath.isFile()) {
athena::io::FileReader fr(memIdPath.getAbsolutePath());
athena::io::YAMLDocReader r;
@ -298,8 +298,7 @@ bool MLVL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
layerResources.addPath(path, true);
}
hecl::SystemUTF8Conv layerU8(layerName);
mlvl.layerNames.emplace_back(layerU8.str());
mlvl.layerNames.emplace_back(layerName);
++nameStartIdx;
MLVL::LayerFlags& thisLayFlags = mlvl.layerFlags.back();
@ -311,7 +310,7 @@ bool MLVL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
}
if (!areaInit)
Log.report(logvisor::Info, FMT_STRING(_SYS_STR("No layer directories for area {}")), area.path.getRelativePath());
Log.report(logvisor::Info, FMT_STRING("No layer directories for area {}"), area.path.getRelativePath());
/* Build deplist */
MLVL::Area& areaOut = mlvl.areas.back();
@ -358,7 +357,7 @@ bool MLVL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
}
}
hecl::ProjectPath pathPath = GetPathBeginsWith(areaDEnum, area.path, _SYS_STR("!path"));
hecl::ProjectPath pathPath = GetPathBeginsWith(areaDEnum, area.path, "!path");
metaforce::SObjectTag pathTag = g_curSpec->buildTagFromPath(pathPath);
if (pathTag.id.IsValid()) {
areaOut.deps.emplace_back(pathTag.id.Value(), pathTag.type);
@ -400,7 +399,7 @@ bool MLVL::CookMAPW(const hecl::ProjectPath& outPath, const World& wld) {
continue;
/* Area map */
hecl::ProjectPath mapPath = GetPathBeginsWith(area.path, _SYS_STR("!map"));
hecl::ProjectPath mapPath = GetPathBeginsWith(area.path, "!map");
if (mapPath.isFile())
mapaTags.push_back(g_curSpec->buildTagFromPath(mapPath));
}
@ -432,11 +431,11 @@ bool MLVL::CookSAVW(const hecl::ProjectPath& outPath, const World& wld) {
if (area.path.getPathType() != hecl::ProjectPath::Type::Directory)
continue;
hecl::ProjectPath areaPath = GetPathBeginsWith(area.path, _SYS_STR("!area"));
hecl::ProjectPath areaPath = GetPathBeginsWith(area.path, "!area");
if (!areaPath.isFile())
continue;
hecl::ProjectPath memRelayPath(area.path, _SYS_STR("/!memoryrelays.yaml"));
hecl::ProjectPath memRelayPath(area.path, "/!memoryrelays.yaml");
std::vector<atUint32> memRelays;
if (memRelayPath.isFile()) {
athena::io::FileReader fr(memRelayPath.getAbsolutePath());
@ -448,7 +447,7 @@ bool MLVL::CookSAVW(const hecl::ProjectPath& outPath, const World& wld) {
for (const hecl::DirectoryEnumerator::Entry& e :
hecl::DirectoryEnumerator(area.path.getAbsolutePath(), hecl::DirectoryEnumerator::Mode::DirsSorted)) {
hecl::ProjectPath objectsPath(area.path, e.m_name + _SYS_STR("/!objects.yaml"));
hecl::ProjectPath objectsPath(area.path, e.m_name + "/!objects.yaml");
if (objectsPath.isNone())
continue;

View File

@ -129,7 +129,7 @@ struct MLVL : BigDNA {
static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*)> fileChanged);
std::function<void(const char*)> fileChanged);
static bool ExtractMAPW(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);

View File

@ -13,7 +13,7 @@
#define DUMP_OCTREE 0
extern hecl::SystemString ExeDir;
extern std::string ExeDir;
namespace DataSpec::DNAMP1 {
@ -179,7 +179,7 @@ static void OutputOctreeNode(hecl::blender::PyOutStream& os, athena::io::IStream
bool MREA::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*)>) {
std::function<void(const char*)>) {
using RigPair = std::pair<std::pair<UniqueID32, CSKR*>, std::pair<UniqueID32, CINF*>>;
RigPair dummy = {};
@ -285,7 +285,7 @@ bool MREA::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
{
rs.seek(secStart, athena::SeekOrigin::Begin);
auto visiData = rs.readUBytes(head.secSizes[curSec]);
athena::io::FileWriter visiOut(outPath.getWithExtension(_SYS_STR(".visi"), true).getAbsolutePath());
athena::io::FileWriter visiOut(outPath.getWithExtension(".visi", true).getAbsolutePath());
visiOut.writeUBytes(visiData.get(), head.secSizes[curSec]);
rs.seek(secStart + 4, athena::SeekOrigin::Begin);
}
@ -300,7 +300,7 @@ bool MREA::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
visiWriter.writeUint32(entityId);
}
}
hecl::ProjectPath visiMetadataPath(outPath.getParentPath(), _SYS_STR("!visi.yaml"));
hecl::ProjectPath visiMetadataPath(outPath.getParentPath(), "!visi.yaml");
athena::io::FileWriter visiMetadata(visiMetadataPath.getAbsolutePath());
visiWriter.finish(&visiMetadata);
}
@ -386,7 +386,7 @@ bool MREA::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
hecl::DirectoryEnumerator dEnum(inPath.getParentPath().getAbsolutePath(),
hecl::DirectoryEnumerator::Mode::DirsSorted, false, false, true);
for (const hecl::DirectoryEnumerator::Entry& ent : dEnum) {
hecl::ProjectPath layerScriptPath(areaDirPath, ent.m_name + _SYS_STR("/!objects.yaml"));
hecl::ProjectPath layerScriptPath(areaDirPath, ent.m_name + "/!objects.yaml");
if (layerScriptPath.isFile())
layerScriptPaths.push_back(std::move(layerScriptPath));
}
@ -464,7 +464,7 @@ bool MREA::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
#if DUMP_OCTREE
hecl::blender::Connection& conn = btok.getBlenderConnection();
if (!conn.createBlend(inPath.getWithExtension(_SYS_STR(".octree.blend"), true), hecl::blender::BlendType::Area))
if (!conn.createBlend(inPath.getWithExtension(".octree.blend", true), hecl::blender::BlendType::Area))
return false;
/* Open Py Stream and read sections */
@ -475,7 +475,7 @@ bool MREA::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
"from mathutils import Vector\n"
"\n"
"bpy.context.scene.name = '%s'\n",
inPath.getLastComponentUTF8().data());
inPath.getLastComponent().data());
athena::io::MemoryReader reader(secs.back().data(), secs.back().size());
reader.readUint32Big();
@ -534,7 +534,7 @@ bool MREA::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
#if DUMP_OCTREE
hecl::blender::Connection& conn = btok.getBlenderConnection();
if (!conn.createBlend(inPath.getWithExtension(_SYS_STR(".coctree.blend"), true), hecl::blender::BlendType::Area))
if (!conn.createBlend(inPath.getWithExtension(".coctree.blend", true), hecl::blender::BlendType::Area))
return false;
/* Open Py Stream and read sections */
@ -545,7 +545,7 @@ bool MREA::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
"from mathutils import Vector\n"
"\n"
"bpy.context.scene.name = '%s'\n",
inPath.getLastComponentUTF8().data());
inPath.getLastComponent().data());
athena::io::MemoryReader reader(collision.bspTree.get(), collision.bspSize);
zeus::CAABox colAABB(collision.aabb[0], collision.aabb[1]);
@ -603,7 +603,7 @@ bool MREA::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
}
/* VISI */
hecl::ProjectPath visiMetadataPath(areaDirPath, _SYS_STR("!visi.yaml"));
hecl::ProjectPath visiMetadataPath(areaDirPath, "!visi.yaml");
bool visiGood = false;
if (visiMetadataPath.isFile()) {
athena::io::FileReader visiReader(visiMetadataPath.getAbsolutePath());
@ -628,7 +628,7 @@ bool MREA::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
}
// Check if pre-generated visi exists, recycle if able
hecl::ProjectPath preVisiPath = inPath.getWithExtension(_SYS_STR(".visi"), true);
hecl::ProjectPath preVisiPath = inPath.getWithExtension(".visi", true);
if (preVisiPath.getPathType() == hecl::ProjectPath::Type::File) {
athena::io::FileReader preVisiReader(preVisiPath.getAbsolutePath());
atUint64 preVisiLen = preVisiReader.length();
@ -657,7 +657,7 @@ bool MREA::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
#if !WINDOWS_STORE
if (!visiGood) {
hecl::ProjectPath visiIntOut = outPath.getWithExtension(_SYS_STR(".visiint"));
hecl::ProjectPath visiIntOut = outPath.getWithExtension(".visiint");
athena::io::FileWriter w(visiIntOut.getAbsolutePath());
w.writeUint32Big(meshes.size());
for (const DNACMDL::Mesh& mesh : meshes) {
@ -695,18 +695,18 @@ bool MREA::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
w.close();
hecl::SystemString VisiGenPath = ExeDir + _SYS_STR("/visigen");
std::string VisiGenPath = ExeDir + "/visigen";
#if _WIN32
VisiGenPath += _SYS_STR(".exe");
VisiGenPath += ".exe";
#endif
hecl::SystemString thrIdx = fmt::format(FMT_STRING(_SYS_STR("{}")), hecl::ClientProcess::GetThreadWorkerIdx());
hecl::SystemString parPid;
std::string thrIdx = fmt::format(FMT_STRING("{}"), hecl::ClientProcess::GetThreadWorkerIdx());
std::string parPid;
#if _WIN32
parPid = fmt::format(FMT_STRING(_SYS_STR("{}")), reinterpret_cast<unsigned long long>(GetCurrentProcess()));
parPid = fmt::format(FMT_STRING("{}"), reinterpret_cast<unsigned long long>(GetCurrentProcess()));
#else
parPid = fmt::format(FMT_STRING(_SYS_STR("{}")), (unsigned long long)getpid());
parPid = fmt::format(FMT_STRING("{}"), (unsigned long long)getpid());
#endif
const hecl::SystemChar* args[] = {VisiGenPath.c_str(),
const char* args[] = {VisiGenPath.c_str(),
visiIntOut.getAbsolutePath().data(),
preVisiPath.getAbsolutePath().data(),
thrIdx.c_str(),
@ -719,7 +719,7 @@ bool MREA::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
r.readBytesToBuf(secs.back().data(), length);
visiGood = true;
} else {
Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("Unable to launch {}")), VisiGenPath);
Log.report(logvisor::Fatal, FMT_STRING("Unable to launch {}"), VisiGenPath);
}
}
#endif
@ -730,7 +730,7 @@ bool MREA::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
/* PATH */
{
const hecl::ProjectPath pathPath = GetPathBeginsWith(inPath.getParentPath(), _SYS_STR("!path"));
const hecl::ProjectPath pathPath = GetPathBeginsWith(inPath.getParentPath(), "!path");
UniqueID32 pathId;
if (pathPath.isFile())
pathId = pathPath;

View File

@ -97,7 +97,7 @@ struct MREA {
static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool, hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*)>);
std::function<void(const char*)>);
static void Name(const SpecBase& dataSpec, PAKEntryReadStream& rs, PAKRouter<PAKBridge>& pakRouter,
PAK::Entry& entry);

View File

@ -43,10 +43,10 @@ void SCLY::exportToLayerDirectories(const PAK::Entry& entry, PAKRouter<PAKBridge
if (active) {
const hecl::ProjectPath activePath(layerPath, "!defaultactive");
[[maybe_unused]] const auto fp = hecl::FopenUnique(activePath.getAbsolutePath().data(), _SYS_STR("wb"));
[[maybe_unused]] const auto fp = hecl::FopenUnique(activePath.getAbsolutePath().data(), "wb");
}
hecl::ProjectPath yamlFile(layerPath, _SYS_STR("!objects.yaml"));
hecl::ProjectPath yamlFile(layerPath, "!objects.yaml");
if (force || yamlFile.isNone()) {
athena::io::FileWriter writer(yamlFile.getAbsolutePath());
athena::io::ToYAMLStream(layers[i], writer);
@ -114,14 +114,13 @@ void SCLY::ScriptLayer::Enumerate<BigDNA::Read>(athena::io::IStreamReader& rs) {
objects.push_back(std::move(obj));
size_t actualLen = rs.position() - start;
if (actualLen != len)
Log.report(
logvisor::Fatal,
FMT_STRING(_SYS_STR("Error while reading object of type 0x{:02X}, did not read the expected amount of "
"data, read 0x{:x}, expected 0x{:x}")),
(atUint32)type, actualLen, len);
Log.report(logvisor::Fatal,
FMT_STRING("Error while reading object of type 0x{:02X}, did not read the expected amount of "
"data, read 0x{:x}, expected 0x{:x}"),
(atUint32)type, actualLen, len);
rs.seek(start + len, athena::SeekOrigin::Begin);
} else {
Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("Unable to find type 0x{:X} in object database")),
Log.report(logvisor::Fatal, FMT_STRING("Unable to find type 0x{:X} in object database"),
(atUint32)type);
}
}
@ -147,7 +146,7 @@ void SCLY::ScriptLayer::Enumerate<BigDNA::ReadYaml>(athena::io::YAMLDocReader& r
obj->type = type;
objects.push_back(std::move(obj));
} else
Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("Unable to find type 0x{:X} in object database")),
Log.report(logvisor::Fatal, FMT_STRING("Unable to find type 0x{:X} in object database"),
(atUint32)type);
}
}

View File

@ -37,7 +37,7 @@ static std::u16string_view::const_iterator UncookTextureList(std::u16string& ret
while (true) {
UniqueID32 id = ParseTag(&*it);
hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(id);
ret.append(hecl::UTF8ToChar16(path ? path.getRelativePathUTF8() : id.toString()));
ret.append(hecl::UTF8ToChar16(path ? path.getRelativePath() : id.toString()));
it += 8;
if (*it == u';') {
ret.push_back(u';');
@ -144,7 +144,7 @@ static std::u16string UncookString(std::u16string_view str) {
it += 5;
UniqueID32 id = ParseTag(&*it);
hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(id, true);
ret.append(hecl::UTF8ToChar16(path ? path.getRelativePathUTF8() : id.toString()));
ret.append(hecl::UTF8ToChar16(path ? path.getRelativePath() : id.toString()));
ret.push_back(u';');
auto scpos = str.find(u';', it - str.begin());

View File

@ -36,16 +36,6 @@ struct STRG : ISTRG {
return search->second->at(idx);
return std::u16string();
}
hecl::SystemString getSystemString(const FourCC& lang, size_t idx) const override {
auto search = langMap.find(lang);
if (search != langMap.end())
#if HECL_UCS2
return hecl::Char16ToWide(search->second->at(idx));
#else
return hecl::Char16ToUTF8(search->second->at(idx));
#endif
return hecl::SystemString();
}
static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
STRG strg;

View File

@ -15,7 +15,7 @@ zeus::CAABox Actor::getVISIAABB(hecl::blender::Token& btok) const {
aabbOut = zeus::CAABox(aabb.first, aabb.second);
} else if (animationParameters.animationCharacterSet.isValid()) {
hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(animationParameters.animationCharacterSet);
conn.openBlend(path.getWithExtension(_SYS_STR(".blend"), true));
conn.openBlend(path.getWithExtension(".blend", true));
hecl::blender::DataStream ds = conn.beginData();
auto aabb = ds.getMeshAABB();
aabbOut = zeus::CAABox(aabb.first, aabb.second);

View File

@ -9,7 +9,7 @@ zeus::CAABox DoorArea::getVISIAABB(hecl::blender::Token& btok) const {
if (animationParameters.animationCharacterSet.isValid()) {
hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(animationParameters.animationCharacterSet);
conn.openBlend(path.getWithExtension(_SYS_STR(".blend"), true));
conn.openBlend(path.getWithExtension(".blend", true));
hecl::blender::DataStream ds = conn.beginData();
auto aabb = ds.getMeshAABB();
aabbOut = zeus::CAABox(aabb.first, aabb.second);

View File

@ -15,7 +15,7 @@ zeus::CAABox Platform::getVISIAABB(hecl::blender::Token& btok) const {
aabbOut = zeus::CAABox(aabb.first, aabb.second);
} else if (animationParameters.animationCharacterSet.isValid()) {
hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(animationParameters.animationCharacterSet);
conn.openBlend(path.getWithExtension(_SYS_STR(".blend"), true));
conn.openBlend(path.getWithExtension(".blend", true));
hecl::blender::DataStream ds = conn.beginData();
auto aabb = ds.getMeshAABB();
aabbOut = zeus::CAABox(aabb.first, aabb.second);

View File

@ -30,7 +30,7 @@ bool AGSC::Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& dir) {
/* Write out project/pool */
{
auto projd = group.getProj().toYAML();
athena::io::FileWriter fo(hecl::ProjectPath(dir, _SYS_STR("!project.yaml")).getAbsolutePath());
athena::io::FileWriter fo(hecl::ProjectPath(dir, "!project.yaml").getAbsolutePath());
if (fo.hasError())
return false;
fo.writeUBytes(projd.data(), projd.size());
@ -38,7 +38,7 @@ bool AGSC::Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& dir) {
{
auto poold = group.getPool().toYAML();
athena::io::FileWriter fo(hecl::ProjectPath(dir, _SYS_STR("!pool.yaml")).getAbsolutePath());
athena::io::FileWriter fo(hecl::ProjectPath(dir, "!pool.yaml").getAbsolutePath());
if (fo.hasError())
return false;
fo.writeUBytes(poold.data(), poold.size());
@ -61,7 +61,7 @@ bool AGSC::Cook(const hecl::ProjectPath& dir, const hecl::ProjectPath& outPath)
auto sdirSamp = group.getSdir().toGCNData(group);
Header head;
head.groupName = dir.getLastComponentUTF8();
head.groupName = dir.getLastComponent();
for (const auto& p : group.getProj().sfxGroups())
head.groupId = p.first.id;
head.poolSz = pool.size();

View File

@ -199,10 +199,10 @@ struct ANCS : BigDNA {
static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const DNAMP2::PAK::Entry& entry, bool force,
hecl::blender::Token& btok, std::function<void(const hecl::SystemChar*)> fileChanged) {
hecl::ProjectPath yamlPath = outPath.getWithExtension(_SYS_STR(".yaml"), true);
hecl::blender::Token& btok, std::function<void(const char*)> fileChanged) {
hecl::ProjectPath yamlPath = outPath.getWithExtension(".yaml", true);
hecl::ProjectPath::Type yamlType = yamlPath.getPathType();
hecl::ProjectPath blendPath = outPath.getWithExtension(_SYS_STR(".blend"), true);
hecl::ProjectPath blendPath = outPath.getWithExtension(".blend", true);
hecl::ProjectPath::Type blendType = blendPath.getPathType();
if (force || yamlType == hecl::ProjectPath::Type::None || blendType == hecl::ProjectPath::Type::None) {

View File

@ -176,7 +176,7 @@ CINF::CINF(const Armature& armature, std::unordered_map<std::string, atInt32>& i
template <class PAKBridge>
bool CINF::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const typename PAKBridge::PAKType::Entry& entry, bool force,
hecl::blender::Token& btok, std::function<void(const hecl::SystemChar*)> fileChanged) {
hecl::blender::Token& btok, std::function<void(const char*)> fileChanged) {
if (!force && outPath.isFile())
return true;
@ -207,11 +207,11 @@ bool CINF::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
template bool CINF::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const typename PAKBridge::PAKType::Entry& entry,
bool force, hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*)> fileChanged);
std::function<void(const char*)> fileChanged);
template bool CINF::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<DNAMP3::PAKBridge>& pakRouter,
const typename DNAMP3::PAKBridge::PAKType::Entry& entry, bool force,
hecl::blender::Token& btok, std::function<void(const hecl::SystemChar*)> fileChanged);
hecl::blender::Token& btok, std::function<void(const char*)> fileChanged);
bool CINF::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath,
const hecl::blender::Armature& armature) {

View File

@ -53,7 +53,7 @@ struct CINF : BigDNA {
template <class PAKBridge>
static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const typename PAKBridge::PAKType::Entry& entry, bool force,
hecl::blender::Token& btok, std::function<void(const hecl::SystemChar*)> fileChanged);
hecl::blender::Token& btok, std::function<void(const char*)> fileChanged);
static bool Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath,
const hecl::blender::Armature& armature);

View File

@ -5,7 +5,7 @@ namespace DataSpec::DNAMP2 {
bool CMDL::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const DNAMP2::PAK::Entry& entry, bool, hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*)>) {
std::function<void(const char*)>) {
/* Check for RigPair */
CINF cinf;
CSKR cskr;

View File

@ -12,7 +12,7 @@ namespace DataSpec::DNAMP2 {
struct CMDL {
static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const DNAMP2::PAK::Entry& entry, bool,
hecl::blender::Token& btok, std::function<void(const hecl::SystemChar*)>);
hecl::blender::Token& btok, std::function<void(const char*)>);
};
} // namespace DataSpec::DNAMP2

View File

@ -52,18 +52,18 @@ PAKBridge::PAKBridge(const nod::Node& node, bool doExtract)
STRG mlvlName;
mlvlName.read(rs);
if (m_levelString.size())
m_levelString += _SYS_STR(", ");
m_levelString += mlvlName.getSystemString(FOURCC('ENGL'), 0);
m_levelString += ", ";
m_levelString += mlvlName.getUTF8(FOURCC('ENGL'), 0);
}
}
}
}
static hecl::SystemString LayerName(std::string_view name) {
hecl::SystemString ret(hecl::SystemStringConv(name).sys_str());
static std::string LayerName(std::string_view name) {
std::string ret(name);
for (auto& ch : ret)
if (ch == _SYS_STR('/') || ch == _SYS_STR('\\'))
ch = _SYS_STR('-');
if (ch == '/' || ch == '\\')
ch = '-';
return ret;
}
@ -80,8 +80,7 @@ void PAKBridge::build() {
mlvl.read(rs);
}
std::string catalogueName;
std::string bestName = m_pak.bestEntryName(m_node, e, catalogueName);
level.name = hecl::SystemStringConv(bestName).sys_str();
level.name = m_pak.bestEntryName(m_node, e, catalogueName);
level.areas.reserve(mlvl.areaCount);
unsigned layerIdx = 0;
@ -109,17 +108,16 @@ void PAKBridge::build() {
PAKEntryReadStream rs = areaNameEnt->beginReadStream(m_node);
areaName.read(rs);
}
areaDeps.name = areaName.getSystemString(FOURCC('ENGL'), 0);
areaDeps.name = areaName.getUTF8(FOURCC('ENGL'), 0);
areaDeps.name = hecl::StringUtils::TrimWhitespace(areaDeps.name);
}
if (areaDeps.name.empty()) {
areaDeps.name = hecl::SystemStringConv(area.internalAreaName).sys_str();
areaDeps.name = area.internalAreaName;
if (areaDeps.name.empty()) {
std::string idStr = area.areaMREAId.toString();
areaDeps.name = hecl::SystemString(_SYS_STR("MREA_")) + hecl::SystemStringConv(idStr).c_str();
areaDeps.name = "MREA_" + area.areaMREAId.toString();
}
}
hecl::SystemString num = fmt::format(FMT_STRING(_SYS_STR("{:02d} ")), ai);
std::string num = fmt::format(FMT_STRING("{:02d} "), ai);
areaDeps.name = num + areaDeps.name;
areaDeps.layers.reserve(area.depLayerCount - 1);
@ -130,7 +128,7 @@ void PAKBridge::build() {
layer.name = LayerName(mlvl.layerNames[layerIdx++]);
layer.active = layerFlags.flags >> (l - 1) & 0x1;
layer.name = hecl::StringUtils::TrimWhitespace(layer.name);
num = fmt::format(FMT_STRING(_SYS_STR("{:02d} ")), l - 1);
num = fmt::format(FMT_STRING("{:02d} "), l - 1);
layer.name = num + layer.name;
layer.resources.reserve(area.depLayers[l] - r);
@ -202,7 +200,7 @@ void PAKBridge::addMAPATransforms(PAKRouter<PAKBridge>& pakRouter,
if (mlvl.worldNameId.isValid())
pathOverrides[mlvl.worldNameId] =
hecl::ProjectPath(mlvlDirPath, fmt::format(FMT_STRING(_SYS_STR("!name_{}.yaml")), mlvl.worldNameId));
hecl::ProjectPath(mlvlDirPath, fmt::format(FMT_STRING("!name_{}.yaml"), mlvl.worldNameId));
for (const MLVL::Area& area : mlvl.areas) {
{
@ -218,7 +216,7 @@ void PAKBridge::addMAPATransforms(PAKRouter<PAKBridge>& pakRouter,
hecl::ProjectPath areaDirPath = pakRouter.getWorking(area.areaMREAId).getParentPath();
if (area.areaNameId.isValid())
pathOverrides[area.areaNameId] =
hecl::ProjectPath(areaDirPath, fmt::format(FMT_STRING(_SYS_STR("!name_{}.yaml")), area.areaNameId));
hecl::ProjectPath(areaDirPath, fmt::format(FMT_STRING("!name_{}.yaml"), area.areaNameId));
}
if (mlvl.worldMap.isValid()) {
@ -249,43 +247,43 @@ ResExtractor<PAKBridge> PAKBridge::LookupExtractor(const nod::Node& pakNode, con
const DNAMP2::PAK::Entry& entry) {
switch (entry.type.toUint32()) {
case SBIG('HINT'):
return {DNAMP1::HINT::Extract, {_SYS_STR(".yaml")}};
return {DNAMP1::HINT::Extract, {".yaml"}};
case SBIG('STRG'):
return {STRG::Extract, {_SYS_STR(".yaml")}};
return {STRG::Extract, {".yaml"}};
case SBIG('TXTR'):
return {TXTR::Extract, {_SYS_STR(".png")}};
return {TXTR::Extract, {".png"}};
case SBIG('AFSM'):
return {AFSM::Extract, {_SYS_STR(".yaml")}};
return {AFSM::Extract, {".yaml"}};
case SBIG('SAVW'):
return {SAVWCommon::ExtractSAVW<SAVW>, {_SYS_STR(".yaml")}};
return {SAVWCommon::ExtractSAVW<SAVW>, {".yaml"}};
case SBIG('CMDL'):
return {CMDL::Extract, {_SYS_STR(".blend")}, 1};
return {CMDL::Extract, {".blend"}, 1};
case SBIG('CINF'):
return {CINF::Extract<PAKBridge>, {_SYS_STR(".blend")}, 1};
return {CINF::Extract<PAKBridge>, {".blend"}, 1};
case SBIG('ANCS'):
return {ANCS::Extract, {_SYS_STR(".yaml"), _SYS_STR(".blend")}, 2};
return {ANCS::Extract, {".yaml", ".blend"}, 2};
case SBIG('MLVL'):
return {MLVL::Extract, {_SYS_STR(".yaml"), _SYS_STR(".blend")}, 3};
return {MLVL::Extract, {".yaml", ".blend"}, 3};
case SBIG('MREA'):
return {MREA::Extract, {_SYS_STR(".blend")}, 4};
return {MREA::Extract, {".blend"}, 4};
case SBIG('MAPA'):
return {MAPA::Extract, {_SYS_STR(".blend")}, 4};
return {MAPA::Extract, {".blend"}, 4};
case SBIG('MAPU'):
return {MAPU::Extract, {_SYS_STR(".blend")}, 5};
return {MAPU::Extract, {".blend"}, 5};
case SBIG('PATH'):
return {PATH::Extract, {_SYS_STR(".blend")}, 5};
return {PATH::Extract, {".blend"}, 5};
case SBIG('FSM2'):
return {DNAFSM2::ExtractFSM2<UniqueID32>, {_SYS_STR(".yaml")}};
return {DNAFSM2::ExtractFSM2<UniqueID32>, {".yaml"}};
case SBIG('FONT'):
return {DNAFont::ExtractFONT<UniqueID32>, {_SYS_STR(".yaml")}};
return {DNAFont::ExtractFONT<UniqueID32>, {".yaml"}};
case SBIG('DGRP'):
return {DNADGRP::ExtractDGRP<UniqueID32>, {_SYS_STR(".yaml")}};
return {DNADGRP::ExtractDGRP<UniqueID32>, {".yaml"}};
case SBIG('AGSC'):
return {AGSC::Extract, {}};
case SBIG('CSNG'):
return {DNAMP1::CSNG::Extract, {_SYS_STR(".mid"), _SYS_STR(".yaml")}};
return {DNAMP1::CSNG::Extract, {".mid", ".yaml"}};
case SBIG('ATBL'):
return {DNAAudio::ATBL::Extract, {_SYS_STR(".yaml")}};
return {DNAAudio::ATBL::Extract, {".yaml"}};
}
return {};
}

View File

@ -16,14 +16,14 @@ public:
bool m_doExtract;
using Level = DataSpec::Level<UniqueID32>;
std::unordered_map<UniqueID32, Level> m_levelDeps;
hecl::SystemString m_levelString;
std::string m_levelString;
PAKBridge(const nod::Node& node, bool doExtract = true);
void build();
static ResExtractor<PAKBridge> LookupExtractor(const nod::Node& pakNode, const DNAMP2::PAK& pak,
const DNAMP2::PAK::Entry& entry);
std::string_view getName() const { return m_node.getName(); }
hecl::SystemStringView getLevelString() const { return m_levelString; }
std::string_view getLevelString() const { return m_levelString; }
using PAKType = DNAMP2::PAK;
const PAKType& getPAK() const { return m_pak; }

View File

@ -8,7 +8,7 @@ namespace DataSpec::DNAMP2 {
struct MAPA : DNAMAPA::MAPA {
static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const DNAMP2::PAK::Entry& entry, bool force,
hecl::blender::Token& btok, std::function<void(const hecl::SystemChar*)> fileChanged) {
hecl::blender::Token& btok, std::function<void(const char*)> fileChanged) {
MAPA mapa;
mapa.read(rs);
hecl::blender::Connection& conn = btok.getBlenderConnection();

View File

@ -11,7 +11,7 @@ namespace DataSpec::DNAMP2 {
struct MAPU : DNAMAPU::MAPU {
static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const DNAMP2::PAK::Entry& entry, bool force,
hecl::blender::Token& btok, std::function<void(const hecl::SystemChar*)> fileChanged) {
hecl::blender::Token& btok, std::function<void(const char*)> fileChanged) {
MAPU mapu;
mapu.read(rs);
hecl::blender::Connection& conn = btok.getBlenderConnection();

View File

@ -85,10 +85,10 @@ struct MLVL : BigDNA {
static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const DNAMP2::PAK::Entry& entry, bool force,
hecl::blender::Token& btok, std::function<void(const hecl::SystemChar*)> fileChanged) {
hecl::blender::Token& btok, std::function<void(const char*)> fileChanged) {
MLVL mlvl;
mlvl.read(rs);
athena::io::FileWriter writer(outPath.getWithExtension(_SYS_STR(".yaml"), true).getAbsolutePath());
athena::io::FileWriter writer(outPath.getWithExtension(".yaml", true).getAbsolutePath());
athena::io::ToYAMLStream(mlvl, writer);
hecl::blender::Connection& conn = btok.getBlenderConnection();
return DNAMLVL::ReadMLVLToBlender(conn, mlvl, outPath, pakRouter, entry, force, fileChanged);

View File

@ -179,7 +179,7 @@ void MREA::StreamReader::writeDecompInfos(athena::io::IStreamWriter& writer) con
bool MREA::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const DNAMP2::PAK::Entry& entry, bool force,
hecl::blender::Token& btok, std::function<void(const hecl::SystemChar*)>) {
hecl::blender::Token& btok, std::function<void(const char*)>) {
using RigPair = std::pair<std::pair<UniqueID32, CSKR*>, std::pair<UniqueID32, CINF*>>;
RigPair dummy = {};
@ -193,7 +193,7 @@ bool MREA::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
/* MREA decompression stream */
StreamReader drs(rs, head.compressedBlockCount);
hecl::ProjectPath decompPath = outPath.getCookedPath(SpecEntMP2ORIG).getWithExtension(_SYS_STR(".decomp"));
hecl::ProjectPath decompPath = outPath.getCookedPath(SpecEntMP2ORIG).getWithExtension(".decomp");
decompPath.makeDirChain(false);
athena::io::FileWriter mreaDecompOut(decompPath.getAbsolutePath());
head.write(mreaDecompOut);

View File

@ -123,7 +123,7 @@ struct MREA {
static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const DNAMP2::PAK::Entry& entry, bool,
hecl::blender::Token& btok, std::function<void(const hecl::SystemChar*)>);
hecl::blender::Token& btok, std::function<void(const char*)>);
};
} // namespace DataSpec::DNAMP2

View File

@ -42,16 +42,6 @@ struct STRG : ISTRG {
return search->second->at(idx);
return std::u16string();
}
hecl::SystemString getSystemString(const FourCC& lang, size_t idx) const override {
auto search = langMap.find(lang);
if (search != langMap.end())
#if HECL_UCS2
return hecl::Char16ToWide(search->second->at(idx));
#else
return hecl::Char16ToUTF8(search->second->at(idx));
#endif
return hecl::SystemString();
}
static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
STRG strg;

View File

@ -267,10 +267,10 @@ struct CHAR : BigDNA {
static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*)> fileChanged) {
hecl::ProjectPath yamlPath = outPath.getWithExtension(_SYS_STR(".yaml"), true);
std::function<void(const char*)> fileChanged) {
hecl::ProjectPath yamlPath = outPath.getWithExtension(".yaml", true);
hecl::ProjectPath::Type yamlType = yamlPath.getPathType();
hecl::ProjectPath blendPath = outPath.getWithExtension(_SYS_STR(".blend"), true);
hecl::ProjectPath blendPath = outPath.getWithExtension(".blend", true);
hecl::ProjectPath::Type blendType = blendPath.getPathType();
if (force || yamlType == hecl::ProjectPath::Type::None || blendType == hecl::ProjectPath::Type::None) {

View File

@ -5,7 +5,7 @@ namespace DataSpec::DNAMP3 {
bool CMDL::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool, hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*)>) {
std::function<void(const char*)>) {
/* Check for RigPair */
CINF cinf;
CSKR cskr;

View File

@ -12,7 +12,7 @@ namespace DataSpec::DNAMP3 {
struct CMDL {
static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool, hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*)>);
std::function<void(const char*)>);
};
} // namespace DataSpec::DNAMP3

View File

@ -63,15 +63,14 @@ static void LoadTexture(Stream& out, const UniqueID64& tex, const PAKRouter<PAKB
PAKEntryReadStream rs = texEntry->beginReadStream(*node);
TXTR::Extract(rs, txtrPath);
}
hecl::SystemString resPath = pakRouter.getResourceRelativePath(entry, tex);
hecl::SystemUTF8Conv resPathView(resPath);
std::string resPath = pakRouter.getResourceRelativePath(entry, tex);
out.format(FMT_STRING("if '{}' in bpy.data.images:\n"
" image = bpy.data.images['{}']\n"
"else:\n"
" image = bpy.data.images.load('''//{}''')\n"
" image.name = '{}'\n"
"\n"),
texName, texName, resPathView, texName);
texName, texName, resPath, texName);
}
void MaterialSet::ConstructMaterial(Stream& out, const PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry,

View File

@ -35,7 +35,7 @@ PAKBridge::PAKBridge(const nod::Node& node, bool doExtract)
m_pak.read(rs);
/* Append Level String */
std::set<hecl::SystemString, hecl::CaseInsensitiveCompare> uniq;
std::set<std::string, hecl::CaseInsensitiveCompare> uniq;
for (auto& ent : m_pak.m_entries) {
PAK::Entry& entry = ent.second;
if (entry.type == FOURCC('MLVL')) {
@ -47,24 +47,24 @@ PAKBridge::PAKBridge(const nod::Node& node, bool doExtract)
PAKEntryReadStream rs = nameEnt->beginReadStream(m_node);
STRG mlvlName;
mlvlName.read(rs);
uniq.insert(mlvlName.getSystemString(FOURCC('ENGL'), 0));
uniq.insert(mlvlName.getUTF8(FOURCC('ENGL'), 0));
}
}
}
bool comma = false;
for (const hecl::SystemString& str : uniq) {
for (const std::string& str : uniq) {
if (comma)
m_levelString += _SYS_STR(", ");
m_levelString += ", ";
comma = true;
m_levelString += str;
}
}
static hecl::SystemString LayerName(std::string_view name) {
hecl::SystemString ret(hecl::SystemStringConv(name).sys_str());
static std::string LayerName(std::string_view name) {
std::string ret(name);
for (auto& ch : ret)
if (ch == _SYS_STR('/') || ch == _SYS_STR('\\'))
ch = _SYS_STR('-');
if (ch == '/' || ch == '\\')
ch = '-';
return ret;
}
@ -82,7 +82,7 @@ void PAKBridge::build() {
}
std::string catalogueName;
std::string bestName = m_pak.bestEntryName(m_node, entry, catalogueName);
level.name = hecl::SystemStringConv(bestName).sys_str();
level.name = bestName;
level.areas.reserve(mlvl.areaCount);
unsigned layerIdx = 0;
@ -110,17 +110,16 @@ void PAKBridge::build() {
PAKEntryReadStream rs = areaNameEnt->beginReadStream(m_node);
areaName.read(rs);
}
areaDeps.name = areaName.getSystemString(FOURCC('ENGL'), 0);
areaDeps.name = areaName.getUTF8(FOURCC('ENGL'), 0);
areaDeps.name = hecl::StringUtils::TrimWhitespace(areaDeps.name);
}
if (areaDeps.name.empty()) {
areaDeps.name = hecl::SystemStringConv(area.internalAreaName).sys_str();
areaDeps.name = area.internalAreaName;
if (areaDeps.name.empty()) {
std::string idStr = area.areaMREAId.toString();
areaDeps.name = hecl::SystemString(_SYS_STR("MREA_")) + hecl::SystemStringConv(idStr).c_str();
areaDeps.name = "MREA_" + area.areaMREAId.toString();
}
}
hecl::SystemString num = fmt::format(FMT_STRING(_SYS_STR("{:02d} ")), ai);
std::string num = fmt::format(FMT_STRING("{:02d} "), ai);
areaDeps.name = num + areaDeps.name;
const MLVL::LayerFlags& layerFlags = *layerFlagsIt++;
@ -132,7 +131,7 @@ void PAKBridge::build() {
layer.name = LayerName(mlvl.layerNames[layerIdx++]);
layer.active = layerFlags.flags >> (l - 1) & 0x1;
layer.name = hecl::StringUtils::TrimWhitespace(layer.name);
num = fmt::format(FMT_STRING(_SYS_STR("{:02d} ")), l - 1);
num = fmt::format(FMT_STRING("{:02d} "), l - 1);
layer.name = num + layer.name;
}
}
@ -192,7 +191,7 @@ void PAKBridge::addMAPATransforms(PAKRouter<PAKBridge>& pakRouter,
if (mlvl.worldNameId.isValid())
pathOverrides[mlvl.worldNameId] =
hecl::ProjectPath(mlvlDirPath, fmt::format(FMT_STRING(_SYS_STR("!name_{}.yaml")), mlvl.worldNameId));
hecl::ProjectPath(mlvlDirPath, fmt::format(FMT_STRING("!name_{}.yaml"), mlvl.worldNameId));
for (const MLVL::Area& area : mlvl.areas) {
{
@ -208,7 +207,7 @@ void PAKBridge::addMAPATransforms(PAKRouter<PAKBridge>& pakRouter,
hecl::ProjectPath areaDirPath = pakRouter.getWorking(area.areaMREAId).getParentPath();
if (area.areaNameId.isValid())
pathOverrides[area.areaNameId] =
hecl::ProjectPath(areaDirPath, fmt::format(FMT_STRING(_SYS_STR("!name_{}.yaml")), area.areaNameId));
hecl::ProjectPath(areaDirPath, fmt::format(FMT_STRING("!name_{}.yaml"), area.areaNameId));
}
if (mlvl.worldMap.isValid()) {
@ -238,35 +237,35 @@ void PAKBridge::addMAPATransforms(PAKRouter<PAKBridge>& pakRouter,
ResExtractor<PAKBridge> PAKBridge::LookupExtractor(const nod::Node& pakNode, const PAK& pak, const PAK::Entry& entry) {
switch (entry.type.toUint32()) {
case SBIG('CAUD'):
return {CAUD::Extract, {_SYS_STR(".yaml")}};
return {CAUD::Extract, {".yaml"}};
case SBIG('STRG'):
return {STRG::Extract, {_SYS_STR(".yaml")}};
return {STRG::Extract, {".yaml"}};
case SBIG('TXTR'):
return {TXTR::Extract, {_SYS_STR(".png")}};
return {TXTR::Extract, {".png"}};
case SBIG('SAVW'):
return {SAVWCommon::ExtractSAVW<SAVW>, {_SYS_STR(".yaml")}};
return {SAVWCommon::ExtractSAVW<SAVW>, {".yaml"}};
case SBIG('HINT'):
return {HINT::Extract, {_SYS_STR(".yaml")}};
return {HINT::Extract, {".yaml"}};
case SBIG('CMDL'):
return {CMDL::Extract, {_SYS_STR(".blend")}, 1};
return {CMDL::Extract, {".blend"}, 1};
case SBIG('CINF'):
return {CINF::Extract<PAKBridge>, {_SYS_STR(".blend")}, 1};
return {CINF::Extract<PAKBridge>, {".blend"}, 1};
case SBIG('CHAR'):
return {CHAR::Extract, {_SYS_STR(".yaml"), _SYS_STR(".blend")}, 2};
return {CHAR::Extract, {".yaml", ".blend"}, 2};
case SBIG('MLVL'):
return {MLVL::Extract, {_SYS_STR(".yaml"), _SYS_STR(".blend")}, 3};
return {MLVL::Extract, {".yaml", ".blend"}, 3};
case SBIG('MREA'):
return {MREA::Extract, {_SYS_STR(".blend")}, 4};
return {MREA::Extract, {".blend"}, 4};
case SBIG('MAPA'):
return {MAPA::Extract, {_SYS_STR(".blend")}, 4};
return {MAPA::Extract, {".blend"}, 4};
case SBIG('PATH'):
return {PATH::Extract, {_SYS_STR(".blend")}, 5};
return {PATH::Extract, {".blend"}, 5};
case SBIG('FSM2'):
return {DNAFSM2::ExtractFSM2<UniqueID64>, {_SYS_STR(".yaml")}};
return {DNAFSM2::ExtractFSM2<UniqueID64>, {".yaml"}};
case SBIG('FONT'):
return {DNAFont::ExtractFONT<UniqueID64>, {_SYS_STR(".yaml")}};
return {DNAFont::ExtractFONT<UniqueID64>, {".yaml"}};
case SBIG('DGRP'):
return {DNADGRP::ExtractDGRP<UniqueID64>, {_SYS_STR(".yaml")}};
return {DNADGRP::ExtractDGRP<UniqueID64>, {".yaml"}};
}
return {};
}

View File

@ -16,13 +16,13 @@ public:
bool m_doExtract;
using Level = DataSpec::Level<UniqueID64>;
std::unordered_map<UniqueID64, Level> m_levelDeps;
hecl::SystemString m_levelString;
std::string m_levelString;
PAKBridge(const nod::Node& node, bool doExtract = true);
void build();
static ResExtractor<PAKBridge> LookupExtractor(const nod::Node& pakNode, const PAK& pak, const PAK::Entry& entry);
std::string_view getName() const { return m_node.getName(); }
hecl::SystemStringView getLevelString() const { return m_levelString; }
std::string_view getLevelString() const { return m_levelString; }
using PAKType = PAK;
const PAKType& getPAK() const { return m_pak; }

View File

@ -8,7 +8,7 @@ namespace DataSpec::DNAMP3 {
struct MAPA : DNAMAPA::MAPA {
static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*)> fileChanged) {
std::function<void(const char*)> fileChanged) {
MAPA mapa;
mapa.read(rs);
hecl::blender::Connection& conn = btok.getBlenderConnection();

View File

@ -74,10 +74,10 @@ struct MLVL : BigDNA {
static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*)> fileChanged) {
std::function<void(const char*)> fileChanged) {
MLVL mlvl;
mlvl.read(rs);
athena::io::FileWriter writer(outPath.getWithExtension(_SYS_STR(".yaml"), true).getAbsolutePath());
athena::io::FileWriter writer(outPath.getWithExtension(".yaml", true).getAbsolutePath());
athena::io::ToYAMLStream(mlvl, writer);
hecl::blender::Connection& conn = btok.getBlenderConnection();
return DNAMLVL::ReadMLVLToBlender(conn, mlvl, outPath, pakRouter, entry, force, fileChanged);

View File

@ -65,7 +65,7 @@ void MREA::ReadBabeDeadToBlender_3(hecl::blender::PyOutStream& os, athena::io::I
bool MREA::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*)>) {
std::function<void(const char*)>) {
using RigPair = std::pair<std::pair<UniqueID64, CSKR*>, std::pair<UniqueID64, CINF*>>;
RigPair dummy = {};
@ -79,7 +79,7 @@ bool MREA::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
/* MREA decompression stream */
StreamReader drs(rs, head.compressedBlockCount, head.secIndexCount);
hecl::ProjectPath decompPath = outPath.getCookedPath(SpecEntMP3ORIG).getWithExtension(_SYS_STR(".decomp"));
hecl::ProjectPath decompPath = outPath.getCookedPath(SpecEntMP3ORIG).getWithExtension(".decomp");
decompPath.makeDirChain(false);
athena::io::FileWriter mreaDecompOut(decompPath.getAbsolutePath());
head.write(mreaDecompOut);

View File

@ -89,7 +89,7 @@ struct MREA {
static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool, hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*)>);
std::function<void(const char*)>);
static bool ExtractLayerDeps(PAKEntryReadStream& rs, PAKBridge::Level::Area& areaOut);
};

View File

@ -42,16 +42,6 @@ struct STRG : ISTRG {
return hecl::UTF8ToChar16(search->second->at(idx));
return std::u16string();
}
hecl::SystemString getSystemString(const FourCC& lang, size_t idx) const override {
auto search = langMap.find(lang);
if (search != langMap.end())
#if HECL_UCS2
return hecl::UTF8ToWide(search->second->at(idx));
#else
return search->second->at(idx);
#endif
return hecl::SystemString();
}
static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
std::unique_ptr<ISTRG> strg = LoadSTRG(rs);

View File

@ -24,18 +24,18 @@ namespace DataSpec {
static logvisor::Module Log("DataSpec::SpecBase");
static const hecl::SystemChar* MomErr[] = {_SYS_STR("Your metroid is in another castle"),
_SYS_STR("HECL is experiencing a PTSD attack"),
_SYS_STR("Unable to freeze metroids"),
_SYS_STR("Ridley ate your homework"),
_SYS_STR("Expected 0 maternal symbolisms, found 2147483647"),
_SYS_STR("Contradictive narratives unsupported"),
_SYS_STR("Wiimote profile \"NES + Zapper\" not recognized"),
_SYS_STR("Unable to find Waldo"),
_SYS_STR("Expected Ridley, found furby"),
_SYS_STR("Adam has not authorized this, please do not bug the developers"),
_SYS_STR("Lady returned objection"),
_SYS_STR("Unterminated plot thread 'Deleter' detected")};
static const char* MomErr[] = {"Your metroid is in another castle",
"HECL is experiencing a PTSD attack",
"Unable to freeze metroids",
"Ridley ate your homework",
"Expected 0 maternal symbolisms, found 2147483647",
"Contradictive narratives unsupported",
"Wiimote profile \"NES + Zapper\" not recognized",
"Unable to find Waldo",
"Expected Ridley, found furby",
"Adam has not authorized this, please do not bug the developers",
"Lady returned objection",
"Unterminated plot thread 'Deleter' detected"};
constexpr uint32_t MomErrCount = std::extent<decltype(MomErr)>::value;
@ -58,10 +58,10 @@ SpecBase::SpecBase(const hecl::Database::DataSpecEntry* specEntry, hecl::Databas
SpecBase::~SpecBase() { cancelBackgroundIndex(); }
static const hecl::SystemString regNONE = _SYS_STR("");
static const hecl::SystemString regE = _SYS_STR("NTSC");
static const hecl::SystemString regJ = _SYS_STR("NTSC-J");
static const hecl::SystemString regP = _SYS_STR("PAL");
static const std::string regNONE = "";
static const std::string regE = "NTSC";
static const std::string regJ = "NTSC-J";
static const std::string regP = "PAL";
void SpecBase::setThreadProject() { UniqueIDBridge::SetThreadProject(m_project); }
@ -74,7 +74,7 @@ bool SpecBase::canExtract(const ExtractPassInfo& info, std::vector<ExtractReport
if (!memcmp(gameID, "R3O", 3)) {
std::srand(std::time(0));
int r = std::rand() % MomErrCount;
Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("{}")), MomErr[r]);
Log.report(logvisor::Fatal, FMT_STRING("{}"), MomErr[r]);
}
m_standalone = true;
@ -85,7 +85,7 @@ bool SpecBase::canExtract(const ExtractPassInfo& info, std::vector<ExtractReport
return false;
m_region = ERegion(m_disc->getHeader().m_gameID[3]);
const hecl::SystemString* regstr = &regNONE;
const std::string* regstr = &regNONE;
switch (m_region) {
case ERegion::NTSC_U:
regstr = &regE;
@ -116,18 +116,18 @@ void SpecBase::doExtract(const ExtractPassInfo& info, const hecl::MultiProgressP
Log.report(logvisor::Fatal, FMT_STRING("Unable to build master shader blend"));
if (m_isWii) {
/* Extract root files for repacking later */
hecl::ProjectPath outDir(m_project.getProjectWorkingPath(), _SYS_STR("out"));
hecl::ProjectPath outDir(m_project.getProjectWorkingPath(), "out");
outDir.makeDirChain(true);
nod::ExtractionContext ctx = {info.force, nullptr};
if (!m_standalone) {
progress.print(_SYS_STR("Trilogy Files"), _SYS_STR(""), 0.0);
progress.print("Trilogy Files", "", 0.0);
nod::IPartition* data = m_disc->getDataPartition();
const nod::Node& root = data->getFSTRoot();
for (const nod::Node& child : root)
if (child.getKind() == nod::Node::Kind::File)
child.extractToDirectory(outDir.getAbsolutePath(), ctx);
progress.print(_SYS_STR("Trilogy Files"), _SYS_STR(""), 1.0);
progress.print("Trilogy Files", "", 1.0);
}
}
extractFromDisc(*m_disc, info.force, progress);
@ -135,15 +135,15 @@ void SpecBase::doExtract(const ExtractPassInfo& info, const hecl::MultiProgressP
bool IsPathAudioGroup(const hecl::ProjectPath& path) {
return (path.getPathType() == hecl::ProjectPath::Type::Directory &&
hecl::ProjectPath(path, _SYS_STR("!project.yaml")).isFile() &&
hecl::ProjectPath(path, _SYS_STR("!pool.yaml")).isFile());
hecl::ProjectPath(path, "!project.yaml").isFile() &&
hecl::ProjectPath(path, "!pool.yaml").isFile());
}
static bool IsPathSong(const hecl::ProjectPath& path) {
if (path.getPathType() != hecl::ProjectPath::Type::Glob || !path.getWithExtension(_SYS_STR(".mid"), true).isFile() ||
!path.getWithExtension(_SYS_STR(".yaml"), true).isFile()) {
return path.isFile() && path.getLastComponentExt() == _SYS_STR("mid") &&
path.getWithExtension(_SYS_STR(".yaml"), true).isFile();
if (path.getPathType() != hecl::ProjectPath::Type::Glob || !path.getWithExtension(".mid", true).isFile() ||
!path.getWithExtension(".yaml", true).isFile()) {
return path.isFile() && path.getLastComponentExt() == "mid" &&
path.getWithExtension(".yaml", true).isFile();
}
return true;
}
@ -154,7 +154,7 @@ bool SpecBase::canCook(const hecl::ProjectPath& path, hecl::blender::Token& btok
hecl::ProjectPath asBlend;
if (path.getPathType() == hecl::ProjectPath::Type::Glob)
asBlend = path.getWithExtension(_SYS_STR(".blend"), true);
asBlend = path.getWithExtension(".blend", true);
else
asBlend = path;
@ -184,18 +184,18 @@ const hecl::Database::DataSpecEntry* SpecBase::overrideDataSpec(const hecl::Proj
hecl::ProjectPath asBlend;
if (path.getPathType() == hecl::ProjectPath::Type::Glob)
asBlend = path.getWithExtension(_SYS_STR(".blend"), true);
asBlend = path.getWithExtension(".blend", true);
else
asBlend = path;
if (hecl::IsPathBlend(asBlend)) {
if (hecl::StringUtils::EndsWith(path.getAuxInfo(), _SYS_STR(".CSKR")) ||
hecl::StringUtils::EndsWith(path.getAuxInfo(), _SYS_STR(".ANIM")))
if (hecl::StringUtils::EndsWith(path.getAuxInfo(), ".CSKR") ||
hecl::StringUtils::EndsWith(path.getAuxInfo(), ".ANIM"))
return oldEntry;
hecl::blender::BlendType type = hecl::blender::GetBlendType(asBlend.getAbsolutePath());
if (type == hecl::blender::BlendType::None) {
Log.report(logvisor::Error, FMT_STRING(_SYS_STR("unable to cook '{}'")), path.getAbsolutePath());
Log.report(logvisor::Error, FMT_STRING("unable to cook '{}'"), path.getAbsolutePath());
return nullptr;
}
if (type == hecl::blender::BlendType::Mesh || type == hecl::blender::BlendType::Area)
@ -213,7 +213,7 @@ void SpecBase::doCook(const hecl::ProjectPath& path, const hecl::ProjectPath& co
hecl::ProjectPath asBlend;
if (path.getPathType() == hecl::ProjectPath::Type::Glob)
asBlend = path.getWithExtension(_SYS_STR(".blend"), true);
asBlend = path.getWithExtension(".blend", true);
else
asBlend = path;
@ -304,7 +304,7 @@ void SpecBase::flattenDependenciesBlend(const hecl::ProjectPath& in, std::vector
break;
}
case hecl::blender::BlendType::Actor: {
hecl::ProjectPath asGlob = in.getWithExtension(_SYS_STR(".*"), true);
hecl::ProjectPath asGlob = in.getWithExtension(".*", true);
hecl::ProjectPath parentPath = asGlob.getParentPath();
hecl::DirectoryEnumerator dEnum(parentPath.getAbsolutePath());
hecl::blender::DataStream ds = conn.beginData();
@ -319,13 +319,11 @@ void SpecBase::flattenDependenciesBlend(const hecl::ProjectPath& in, std::vector
pathsOut.push_back(sub.mesh);
}
hecl::SystemStringConv chSysName(sub.name);
if (!sub.cskrId.empty()) {
hecl::SystemStringConv cskrSysName(sub.cskrId);
pathsOut.push_back(
asGlob.ensureAuxInfo(fmt::format(FMT_STRING(_SYS_STR("{}_{}.CSKR")), chSysName, cskrSysName)));
asGlob.ensureAuxInfo(fmt::format(FMT_STRING("{}_{}.CSKR"), sub.name, sub.cskrId)));
} else {
pathsOut.push_back(asGlob.ensureAuxInfo(fmt::format(FMT_STRING(_SYS_STR("{}.CSKR")), chSysName)));
pathsOut.push_back(asGlob.ensureAuxInfo(fmt::format(FMT_STRING("{}.CSKR"), sub.name)));
}
const auto& arm = actor.armatures[sub.armature];
@ -333,14 +331,12 @@ void SpecBase::flattenDependenciesBlend(const hecl::ProjectPath& in, std::vector
pathsOut.push_back(arm.path);
for (const auto& overlay : sub.overlayMeshes) {
hecl::SystemStringConv overlaySys(overlay.name);
hecl::SystemStringConv overlayCskrId(overlay.cskrId);
if (hecl::IsPathBlend(overlay.mesh)) {
flattenDependenciesBlend(overlay.mesh, pathsOut, btok);
pathsOut.push_back(overlay.mesh);
}
pathsOut.push_back(asGlob.ensureAuxInfo(
fmt::format(FMT_STRING(_SYS_STR("{}.{}_{}.CSKR")), chSysName, overlaySys, overlayCskrId)));
fmt::format(FMT_STRING("{}.{}_{}.CSKR"), sub.name, overlay.name, overlay.cskrId)));
}
}
};
@ -356,10 +352,8 @@ void SpecBase::flattenDependenciesBlend(const hecl::ProjectPath& in, std::vector
pathsOut.push_back(att.mesh);
}
hecl::SystemStringConv chSysName(att.name);
hecl::SystemStringConv sysCskrId(att.cskrId);
pathsOut.push_back(
asGlob.ensureAuxInfo(fmt::format(FMT_STRING(_SYS_STR("ATTACH.{}_{}.CSKR")), chSysName, sysCskrId)));
asGlob.ensureAuxInfo(fmt::format(FMT_STRING("ATTACH.{}_{}.CSKR"), att.name, att.cskrId)));
if (att.armature >= 0) {
const auto& arm = actor.armatures[att.armature];
@ -369,16 +363,14 @@ void SpecBase::flattenDependenciesBlend(const hecl::ProjectPath& in, std::vector
}
for (const auto& act : actNames) {
hecl::SystemStringConv actSysName(act.first);
hecl::SystemStringConv actAnimId(act.second);
pathsOut.push_back(asGlob.ensureAuxInfo(fmt::format(FMT_STRING(_SYS_STR("{}_{}.ANIM")), actSysName, actAnimId)));
hecl::SystemString searchPrefix(
asGlob.getWithExtension(fmt::format(FMT_STRING(_SYS_STR(".{}_")), actSysName).c_str(), true)
pathsOut.push_back(asGlob.ensureAuxInfo(fmt::format(FMT_STRING("{}_{}.ANIM"), act.first, act.second)));
std::string searchPrefix(
asGlob.getWithExtension(fmt::format(FMT_STRING(".{}_"), act.first).c_str(), true)
.getLastComponent());
hecl::ProjectPath evntPath;
for (const auto& ent : dEnum) {
if (hecl::StringUtils::BeginsWith(ent.m_name, searchPrefix.c_str()) &&
hecl::StringUtils::EndsWith(ent.m_name, _SYS_STR(".evnt.yaml"))) {
hecl::StringUtils::EndsWith(ent.m_name, ".evnt.yaml")) {
evntPath = hecl::ProjectPath(parentPath, ent.m_name);
break;
}
@ -387,7 +379,7 @@ void SpecBase::flattenDependenciesBlend(const hecl::ProjectPath& in, std::vector
pathsOut.push_back(evntPath);
}
hecl::ProjectPath yamlPath = asGlob.getWithExtension(_SYS_STR(".yaml"), true);
hecl::ProjectPath yamlPath = asGlob.getWithExtension(".yaml", true);
if (yamlPath.isFile()) {
athena::io::FileReader reader(yamlPath.getAbsolutePath());
flattenDependenciesANCSYAML(reader, pathsOut, charIdx);
@ -408,7 +400,7 @@ void SpecBase::flattenDependencies(const hecl::ProjectPath& path, std::vector<he
hecl::ProjectPath asBlend;
if (path.getPathType() == hecl::ProjectPath::Type::Glob)
asBlend = path.getWithExtension(_SYS_STR(".blend"), true);
asBlend = path.getWithExtension(".blend", true);
else
asBlend = path;
@ -449,8 +441,8 @@ void SpecBase::recursiveBuildResourceList(std::vector<metaforce::SObjectTag>& li
for (const auto& ent : dEnum) {
hecl::ProjectPath childPath(path, ent.m_name);
if (ent.m_isDir) {
if (hecl::ProjectPath(childPath, _SYS_STR("!project.yaml")).isFile() &&
hecl::ProjectPath(childPath, _SYS_STR("!pool.yaml")).isFile()) {
if (hecl::ProjectPath(childPath, "!project.yaml").isFile() &&
hecl::ProjectPath(childPath, "!pool.yaml").isFile()) {
/* Handle AudioGroup case */
if (metaforce::SObjectTag tag = tagFromPath(childPath)) {
if (addedTags.find(tag) != addedTags.end())
@ -485,7 +477,7 @@ void SpecBase::copyBuildListData(std::vector<std::tuple<size_t, size_t, bool>>&
fileIndex.reserve(buildList.size());
int loadIdx = 0;
for (const auto& tag : buildList) {
hecl::SystemString str = fmt::format(FMT_STRING(_SYS_STR("Copying {}")), tag);
std::string str = fmt::format(FMT_STRING("Copying {}"), tag);
progress.print(str, std::nullopt, ++loadIdx / float(buildList.size()));
auto& [positionOut, sizeOut, compressedOut] = fileIndex.emplace_back();
@ -493,7 +485,7 @@ void SpecBase::copyBuildListData(std::vector<std::tuple<size_t, size_t, bool>>&
if (tag.type == FOURCC('MLVL')) {
auto search = mlvlData.find(tag.id);
if (search == mlvlData.end())
Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("Unable to find MLVL {}")), tag.id);
Log.report(logvisor::Fatal, FMT_STRING("Unable to find MLVL {}"), tag.id);
positionOut = pakOut.position();
sizeOut = ROUND_UP_32(search->second.size());
@ -509,7 +501,7 @@ void SpecBase::copyBuildListData(std::vector<std::tuple<size_t, size_t, bool>>&
hecl::ProjectPath cooked = getCookedPath(path, true);
athena::io::FileReader r(cooked.getAbsolutePath());
if (r.hasError())
Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("Unable to open resource {}")), cooked.getRelativePath());
Log.report(logvisor::Fatal, FMT_STRING("Unable to open resource {}"), cooked.getRelativePath());
atUint64 size = r.length();
auto data = r.readUBytes(size);
auto compData = compressPakData(tag, data.get(), size);
@ -536,8 +528,8 @@ void SpecBase::copyBuildListData(std::vector<std::tuple<size_t, size_t, bool>>&
static bool IsWorldBlend(const hecl::ProjectPath& path) {
if (path.isFile()) {
auto lastComp = path.getLastComponent();
return hecl::StringUtils::BeginsWith(lastComp, _SYS_STR("!world")) &&
hecl::StringUtils::EndsWith(lastComp, _SYS_STR(".blend"));
return hecl::StringUtils::BeginsWith(lastComp, "!world") &&
hecl::StringUtils::EndsWith(lastComp, ".blend");
}
return false;
}
@ -551,15 +543,15 @@ void SpecBase::doPackage(const hecl::ProjectPath& path, const hecl::Database::Da
waitForIndexComplete();
/* Name pak based on root-relative components */
auto components = path.getWithExtension(_SYS_STR(""), true).getPathComponents();
auto components = path.getWithExtension("", true).getPathComponents();
if (components.size() <= 1)
return;
hecl::ProjectPath outPath;
if (hecl::ProjectPath(m_project.getProjectWorkingPath(), _SYS_STR("out/files/") + components[0]).isDirectory())
if (hecl::ProjectPath(m_project.getProjectWorkingPath(), "out/files/" + components[0]).isDirectory())
outPath.assign(m_project.getProjectWorkingPath(),
_SYS_STR("out/files/") + components[0] + _SYS_STR("/") + components[1] + entry->m_pakExt.data());
"out/files/" + components[0] + "/" + components[1] + entry->m_pakExt.data());
else
outPath.assign(m_project.getProjectWorkingPath(), _SYS_STR("out/files/") + components[1] + entry->m_pakExt.data());
outPath.assign(m_project.getProjectWorkingPath(), "out/files/" + components[1] + entry->m_pakExt.data());
outPath.makeDirChain(false);
/* Output file */
@ -633,7 +625,7 @@ void SpecBase::doPackage(const hecl::ProjectPath& path, const hecl::Database::Da
/* Async cook resource list if using ClientProcess */
if (cp) {
Log.report(logvisor::Info, FMT_STRING(_SYS_STR("Validating resources")));
Log.report(logvisor::Info, FMT_STRING("Validating resources"));
progress.setMainIndeterminate(true);
std::vector<metaforce::SObjectTag> cookTags;
cookTags.reserve(buildList.size());
@ -656,7 +648,7 @@ void SpecBase::doPackage(const hecl::ProjectPath& path, const hecl::Database::Da
for (auto& tag : cookTags) {
hecl::ProjectPath depPath = pathFromTag(tag);
if (!depPath)
Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("Unable to resolve {}")), tag);
Log.report(logvisor::Fatal, FMT_STRING("Unable to resolve {}"), tag);
m_project.cookPath(depPath, progress, false, false, fast, entry, cp);
}
progress.setMainIndeterminate(false);
@ -666,7 +658,7 @@ void SpecBase::doPackage(const hecl::ProjectPath& path, const hecl::Database::Da
/* Write resource data and build file index */
std::vector<std::tuple<size_t, size_t, bool>> fileIndex;
Log.report(logvisor::Info, FMT_STRING(_SYS_STR("Copying data into {}")), outPath.getRelativePath());
Log.report(logvisor::Info, FMT_STRING("Copying data into {}"), outPath.getRelativePath());
copyBuildListData(fileIndex, buildList, entry, fast, progress, pakOut, mlvlData);
/* Write file index */
@ -680,8 +672,8 @@ std::optional<hecl::blender::World> SpecBase::compileWorldFromDir(const hecl::Pr
hecl::blender::Token& btok) const {
hecl::ProjectPath asBlend;
for (const auto& ent : hecl::DirectoryEnumerator(dir.getAbsolutePath())) {
if (hecl::StringUtils::BeginsWith(ent.m_name, _SYS_STR("!world"))) {
asBlend = hecl::ProjectPath(dir, ent.m_name).getWithExtension(_SYS_STR(".blend"), true);
if (hecl::StringUtils::BeginsWith(ent.m_name, "!world")) {
asBlend = hecl::ProjectPath(dir, ent.m_name).getWithExtension(".blend", true);
break;
}
}
@ -714,17 +706,17 @@ constexpr uint8_t Convert4To8(uint8_t v) {
}
void SpecBase::extractRandomStaticEntropy(const uint8_t* buf, const hecl::ProjectPath& pakPath) {
hecl::ProjectPath entropyPath(pakPath, _SYS_STR("RandomStaticEntropy.png"));
hecl::ProjectPath catalogPath(pakPath, _SYS_STR("!catalog.yaml"));
hecl::ProjectPath entropyPath(pakPath, "RandomStaticEntropy.png");
hecl::ProjectPath catalogPath(pakPath, "!catalog.yaml");
entropyPath.makeDirChain(false);
if (const auto fp = hecl::FopenUnique(catalogPath.getAbsolutePath().data(), _SYS_STR("a"))) {
fmt::print(fp.get(), FMT_STRING("RandomStaticEntropy: {}\n"), entropyPath.getRelativePathUTF8());
if (const auto fp = hecl::FopenUnique(catalogPath.getAbsolutePath().data(), "a")) {
fmt::print(fp.get(), FMT_STRING("RandomStaticEntropy: {}\n"), entropyPath.getRelativePath());
}
auto fp = hecl::FopenUnique(entropyPath.getAbsolutePath().data(), _SYS_STR("wb"));
auto fp = hecl::FopenUnique(entropyPath.getAbsolutePath().data(), "wb");
if (fp == nullptr) {
Log.report(logvisor::Error, FMT_STRING(_SYS_STR("Unable to open '{}' for writing")), entropyPath.getAbsolutePath());
Log.report(logvisor::Error, FMT_STRING("Unable to open '{}' for writing"), entropyPath.getAbsolutePath());
return;
}
png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, PNGErr, PNGWarn);
@ -870,10 +862,10 @@ static void WriteTag(athena::io::YAMLDocWriter& cacheWriter, const metaforce::SO
const hecl::ProjectPath& path) {
auto key = fmt::format(FMT_STRING("{}"), pathTag.id);
if (auto* existing = cacheWriter.getCurNode()->findMapChild(key)) {
existing->m_seqChildren.emplace_back(athena::io::ValToNode(path.getEncodableStringUTF8()));
existing->m_seqChildren.emplace_back(athena::io::ValToNode(path.getEncodableString()));
} else if (auto v = cacheWriter.enterSubVector(key)) {
cacheWriter.writeString(pathTag.type.toString());
cacheWriter.writeString(path.getEncodableStringUTF8());
cacheWriter.writeString(path.getEncodableString());
}
}
@ -944,7 +936,7 @@ void SpecBase::backgroundIndexRecursiveCatalogs(const hecl::ProjectPath& dir, at
continue;
/* Read catalog.yaml for .pak directory if exists */
if (level == 1 && ent.m_name == _SYS_STR("!catalog.yaml")) {
if (level == 1 && ent.m_name == "!catalog.yaml") {
readCatalog(path, nameWriter);
continue;
}
@ -964,7 +956,7 @@ void SpecBase::insertPathTag(athena::io::YAMLDocWriter& cacheWriter, const metaf
if (search != m_tagToPath.end() && search->second != path &&
tag.type != FOURCC('CINF') && tag.type != FOURCC('CSKR') &&
tag.type != FOURCC('ANIM') && tag.type != FOURCC('EVNT')) {
Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("'{}|{}' already exists for tag {} as '{}|{}'")),
Log.report(logvisor::Fatal, FMT_STRING("'{}|{}' already exists for tag {} as '{}|{}'"),
path.getRelativePath(), path.getAuxInfo(), tag,
search->second.getRelativePath(), search->second.getAuxInfo());
}
@ -974,7 +966,7 @@ void SpecBase::insertPathTag(athena::io::YAMLDocWriter& cacheWriter, const metaf
WriteTag(cacheWriter, tag, path);
#if DUMP_CACHE_FILL
if (dump)
fmt::print(stderr, FMT_STRING("{} {}\n"), tag, path.getRelativePathUTF8());
fmt::print(stderr, FMT_STRING("{} {}\n"), tag, path.getRelativePath());
#endif
}
@ -984,7 +976,7 @@ bool SpecBase::addFileToIndex(const hecl::ProjectPath& path, athena::io::YAMLDoc
return true;
/* Try as glob */
hecl::ProjectPath asGlob = path.getWithExtension(_SYS_STR(".*"), true);
hecl::ProjectPath asGlob = path.getWithExtension(".*", true);
if (m_pathToTag.find(asGlob.hash()) != m_pathToTag.cend())
return true;
@ -1009,25 +1001,21 @@ bool SpecBase::addFileToIndex(const hecl::ProjectPath& path, athena::io::YAMLDoc
std::vector<std::pair<std::string, std::string>> actionNames = ds.getActionNames();
for (const auto& sub : subtypeNames) {
hecl::SystemStringConv subName(sub.first);
hecl::ProjectPath subPath;
if (!sub.second.empty()) {
hecl::SystemStringConv cskrId(sub.second);
subPath = asGlob.ensureAuxInfo(fmt::format(FMT_STRING(_SYS_STR("{}_{}.CSKR")), subName, cskrId));
subPath = asGlob.ensureAuxInfo(fmt::format(FMT_STRING("{}_{}.CSKR"), sub.first, sub.second));
} else {
subPath = asGlob.ensureAuxInfo(fmt::format(FMT_STRING(_SYS_STR("{}.CSKR")), subName));
subPath = asGlob.ensureAuxInfo(fmt::format(FMT_STRING("{}.CSKR"), sub.first));
}
insertPathTag(cacheWriter, buildTagFromPath(subPath), subPath);
std::vector<std::pair<std::string, std::string>> overlayNames = ds.getSubtypeOverlayNames(sub.first);
for (const auto& overlay : overlayNames) {
hecl::SystemStringConv overlaySys(overlay.first);
hecl::SystemStringConv overlayCskrId(overlay.second);
if (!overlay.second.empty()) {
subPath = asGlob.ensureAuxInfo(
fmt::format(FMT_STRING(_SYS_STR("{}.{}_{}.CSKR")), subName, overlaySys, overlayCskrId));
fmt::format(FMT_STRING("{}.{}_{}.CSKR"), sub.first, overlay.first, overlay.second));
} else {
subPath = asGlob.ensureAuxInfo(fmt::format(FMT_STRING(_SYS_STR("{}.{}.CSKR")), subName, overlaySys));
subPath = asGlob.ensureAuxInfo(fmt::format(FMT_STRING("{}.{}.CSKR"), sub.first, overlay.first));
}
insertPathTag(cacheWriter, buildTagFromPath(subPath), subPath);
}
@ -1035,26 +1023,22 @@ bool SpecBase::addFileToIndex(const hecl::ProjectPath& path, athena::io::YAMLDoc
std::vector<std::pair<std::string, std::string>> attachmentNames = ds.getAttachmentNames();
for (const auto& attachment : attachmentNames) {
hecl::SystemStringConv attachmentSys(attachment.first);
hecl::SystemStringConv attachmentCskrId(attachment.second);
hecl::ProjectPath subPath;
if (!attachment.second.empty()) {
subPath = asGlob.ensureAuxInfo(
fmt::format(FMT_STRING(_SYS_STR("ATTACH.{}_{}.CSKR")), attachmentSys, attachmentCskrId));
fmt::format(FMT_STRING("ATTACH.{}_{}.CSKR"), attachment.first, attachment.second));
} else {
subPath = asGlob.ensureAuxInfo(fmt::format(FMT_STRING(_SYS_STR("ATTACH.{}.CSKR")), attachmentSys));
subPath = asGlob.ensureAuxInfo(fmt::format(FMT_STRING("ATTACH.{}.CSKR"), attachment.first));
}
insertPathTag(cacheWriter, buildTagFromPath(subPath), subPath);
}
for (const auto& act : actionNames) {
hecl::SystemStringConv sysStr(act.first);
hecl::SystemStringConv animId(act.second);
hecl::ProjectPath subPath;
if (!act.second.empty()) {
subPath = asGlob.ensureAuxInfo(fmt::format(FMT_STRING(_SYS_STR("{}_{}.ANIM")), sysStr, animId));
subPath = asGlob.ensureAuxInfo(fmt::format(FMT_STRING("{}_{}.ANIM"), act.first, act.second));
} else {
subPath = asGlob.ensureAuxInfo(fmt::format(FMT_STRING(_SYS_STR("{}.ANIM")), sysStr));
subPath = asGlob.ensureAuxInfo(fmt::format(FMT_STRING("{}.ANIM"), act.first));
}
insertPathTag(cacheWriter, buildTagFromPath(subPath), subPath);
}
@ -1096,7 +1080,7 @@ void SpecBase::backgroundIndexRecursiveProc(const hecl::ProjectPath& dir, athena
continue;
/* Read catalog.yaml for .pak directory if exists */
if (level == 1 && ent.m_name == _SYS_STR("!catalog.yaml")) {
if (level == 1 && ent.m_name == "!catalog.yaml") {
readCatalog(path, nameWriter);
continue;
}
@ -1110,8 +1094,8 @@ void SpecBase::backgroundIndexRecursiveProc(const hecl::ProjectPath& dir, athena
void SpecBase::backgroundIndexProc() {
logvisor::RegisterThreadName("Resource Index");
hecl::ProjectPath tagCachePath(m_project.getProjectCookedPath(getOriginalSpec()), _SYS_STR("tag_cache.yaml"));
hecl::ProjectPath nameCachePath(m_project.getProjectCookedPath(getOriginalSpec()), _SYS_STR("name_cache.yaml"));
hecl::ProjectPath tagCachePath(m_project.getProjectCookedPath(getOriginalSpec()), "tag_cache.yaml");
hecl::ProjectPath nameCachePath(m_project.getProjectCookedPath(getOriginalSpec()), "name_cache.yaml");
hecl::ProjectPath specRoot(m_project.getProjectWorkingPath(), getOriginalSpec().m_name);
/* Cache will be overwritten with validated entries afterwards */
@ -1122,7 +1106,7 @@ void SpecBase::backgroundIndexProc() {
if (tagCachePath.isFile()) {
athena::io::FileReader reader(tagCachePath.getAbsolutePath());
if (reader.isOpen()) {
Log.report(logvisor::Info, FMT_STRING(_SYS_STR("Cache index of '{}' loading")), getOriginalSpec().m_name);
Log.report(logvisor::Info, FMT_STRING("Cache index of '{}' loading"), getOriginalSpec().m_name);
athena::io::YAMLDocReader cacheReader;
if (cacheReader.parse(&reader)) {
std::unique_lock lk(m_backgroundIndexMutex);
@ -1152,12 +1136,12 @@ void SpecBase::backgroundIndexProc() {
}
fmt::print(stderr, FMT_STRING("\r {} / {}\n"), loadIdx, tagCount);
}
Log.report(logvisor::Info, FMT_STRING(_SYS_STR("Cache index of '{}' loaded; {} tags")), getOriginalSpec().m_name,
Log.report(logvisor::Info, FMT_STRING("Cache index of '{}' loaded; {} tags"), getOriginalSpec().m_name,
m_tagToPath.size());
if (nameCachePath.isFile()) {
/* Read in name cache */
Log.report(logvisor::Info, FMT_STRING(_SYS_STR("Name index of '{}' loading")), getOriginalSpec().m_name);
Log.report(logvisor::Info, FMT_STRING("Name index of '{}' loading"), getOriginalSpec().m_name);
athena::io::FileReader nreader(nameCachePath.getAbsolutePath());
athena::io::YAMLDocReader nameReader;
if (nameReader.parse(&nreader)) {
@ -1176,13 +1160,13 @@ void SpecBase::backgroundIndexProc() {
}
}
}
Log.report(logvisor::Info, FMT_STRING(_SYS_STR("Name index of '{}' loaded; {} names")),
Log.report(logvisor::Info, FMT_STRING("Name index of '{}' loaded; {} names"),
getOriginalSpec().m_name, m_catalogNameToTag.size());
}
}
}
Log.report(logvisor::Info, FMT_STRING(_SYS_STR("Background index of '{}' started")), getOriginalSpec().m_name);
Log.report(logvisor::Info, FMT_STRING("Background index of '{}' started"), getOriginalSpec().m_name);
backgroundIndexRecursiveProc(specRoot, cacheWriter, nameWriter, 0);
tagCachePath.makeDirChain(false);
@ -1193,7 +1177,7 @@ void SpecBase::backgroundIndexProc() {
nameWriter.finish(&nwriter);
m_backgroundBlender.shutdown();
Log.report(logvisor::Info, FMT_STRING(_SYS_STR("Background index of '{}' complete; {} tags, {} names")),
Log.report(logvisor::Info, FMT_STRING("Background index of '{}' complete; {} tags, {} names"),
getOriginalSpec().m_name, m_tagToPath.size(), m_catalogNameToTag.size());
m_backgroundRunning = false;
}
@ -1221,7 +1205,7 @@ void SpecBase::waitForIndexComplete() const {
}
void SpecBase::WriteVersionInfo(hecl::Database::Project& project, const hecl::ProjectPath& pakPath) {
hecl::ProjectPath versionPath(pakPath, _SYS_STR("version.yaml"));
hecl::ProjectPath versionPath(pakPath, "version.yaml");
versionPath.makeDirChain(false);
MetaforceVersionInfo info;

View File

@ -49,11 +49,11 @@ struct SpecBase : hecl::Database::IDataSpec {
/* Extract handlers */
virtual bool checkStandaloneID(const char* id) const = 0;
virtual bool checkFromStandaloneDisc(nod::DiscBase& disc, const hecl::SystemString& regstr,
const std::vector<hecl::SystemString>& args,
virtual bool checkFromStandaloneDisc(nod::DiscBase& disc, const std::string& regstr,
const std::vector<std::string>& args,
std::vector<ExtractReport>& reps) = 0;
virtual bool checkFromTrilogyDisc(nod::DiscBase& disc, const hecl::SystemString& regstr,
const std::vector<hecl::SystemString>& args, std::vector<ExtractReport>& reps) = 0;
virtual bool checkFromTrilogyDisc(nod::DiscBase& disc, const std::string& regstr,
const std::vector<std::string>& args, std::vector<ExtractReport>& reps) = 0;
virtual bool extractFromDisc(nod::DiscBase& disc, bool force, const hecl::MultiProgressPrinter& progress) = 0;
/* Convert path to object tag */

View File

@ -65,12 +65,12 @@ extern hecl::Database::DataSpecEntry SpecEntMP1ORIG;
struct TextureCache {
static void Generate(PAKRouter<DNAMP1::PAKBridge>& pakRouter, hecl::Database::Project& project,
const hecl::ProjectPath& pakPath) {
hecl::ProjectPath texturePath(pakPath, _SYS_STR("texture_cache.yaml"));
hecl::ProjectPath catalogPath(pakPath, _SYS_STR("!catalog.yaml"));
hecl::ProjectPath texturePath(pakPath, "texture_cache.yaml");
hecl::ProjectPath catalogPath(pakPath, "!catalog.yaml");
texturePath.makeDirChain(false);
if (const auto fp = hecl::FopenUnique(catalogPath.getAbsolutePath().data(), _SYS_STR("a"))) {
fmt::print(fp.get(), FMT_STRING("TextureCache: {}\n"), texturePath.getRelativePathUTF8());
if (const auto fp = hecl::FopenUnique(catalogPath.getAbsolutePath().data(), "a")) {
fmt::print(fp.get(), FMT_STRING("TextureCache: {}\n"), texturePath.getRelativePath());
}
Log.report(logvisor::Level::Info, FMT_STRING("Gathering Texture metadata (this can take up to 10 seconds)..."));
@ -87,7 +87,7 @@ struct TextureCache {
athena::io::YAMLDocWriter yamlW("MP1TextureCache");
for (const auto& pair : metaMap) {
hecl::ProjectPath path = pakRouter.getWorking(pair.first);
auto rec = yamlW.enterSubRecord(path.getRelativePathUTF8());
auto rec = yamlW.enterSubRecord(path.getRelativePath());
pair.second.write(yamlW);
}
@ -142,21 +142,21 @@ struct SpecMP1 : SpecBase {
SpecMP1(const hecl::Database::DataSpecEntry* specEntry, hecl::Database::Project& project, bool pc)
: SpecBase(specEntry, project, pc)
, m_workPath(project.getProjectWorkingPath(), _SYS_STR("MP1"))
, m_cookPath(project.getProjectCookedPath(SpecEntMP1), _SYS_STR("MP1"))
, m_workPath(project.getProjectWorkingPath(), "MP1")
, m_cookPath(project.getProjectCookedPath(SpecEntMP1), "MP1")
, m_pakRouter(*this, m_workPath, m_cookPath) {
m_game = EGame::MetroidPrime1;
SpecBase::setThreadProject();
}
void buildPaks(nod::Node& root, const std::vector<hecl::SystemString>& args, ExtractReport& rep) {
void buildPaks(nod::Node& root, const std::vector<std::string>& args, ExtractReport& rep) {
m_nonPaks.clear();
m_paks.clear();
for (const nod::Node& child : root) {
bool isPak = false;
auto name = child.getName();
std::string lowerName(name);
std::transform(lowerName.begin(), lowerName.end(), lowerName.begin(), tolower);
hecl::ToLower(lowerName);
if (name.size() > 4) {
std::string::iterator extit = lowerName.end() - 4;
if (std::string(extit, lowerName.end()) == ".pak") {
@ -169,8 +169,8 @@ struct SpecMP1 : SpecBase {
if (args.size()) {
good = false;
if (!lowerName.compare(0, 7, "metroid")) {
hecl::SystemChar idxChar = lowerName[7];
for (const hecl::SystemString& arg : args) {
char idxChar = lowerName[7];
for (const std::string& arg : args) {
if (arg.size() == 1 && iswdigit(arg[0]))
if (arg[0] == idxChar)
good = true;
@ -179,9 +179,9 @@ struct SpecMP1 : SpecBase {
good = true;
if (!good) {
for (const hecl::SystemString& arg : args) {
std::string lowerArg(hecl::SystemUTF8Conv(arg).str());
std::transform(lowerArg.begin(), lowerArg.end(), lowerArg.begin(), tolower);
for (const std::string& arg : args) {
std::string lowerArg(arg);
hecl::ToLower(lowerArg);
if (!lowerArg.compare(0, lowerBase.size(), lowerBase))
good = true;
}
@ -210,14 +210,13 @@ struct SpecMP1 : SpecBase {
}
ExtractReport& childRep = rep.childOpts.emplace_back();
hecl::SystemStringConv nameView(item.first);
childRep.name = nameView.sys_str();
childRep.name = item.first;
childRep.desc = item.second->getLevelString();
}
}
bool checkFromStandaloneDisc(nod::DiscBase& disc, const hecl::SystemString& regstr,
const std::vector<hecl::SystemString>& args, std::vector<ExtractReport>& reps) override {
bool checkFromStandaloneDisc(nod::DiscBase& disc, const std::string& regstr,
const std::vector<std::string>& args, std::vector<ExtractReport>& reps) override {
nod::IPartition* partition = disc.getDataPartition();
m_dolBuf = partition->getDOLBuf();
const char* buildInfo =
@ -229,11 +228,10 @@ struct SpecMP1 : SpecBase {
m_version = std::string(buildInfo);
/* Root Report */
ExtractReport& rep = reps.emplace_back();
rep.name = _SYS_STR("MP1");
rep.desc = _SYS_STR("Metroid Prime ") + regstr;
rep.name = "MP1";
rep.desc = "Metroid Prime " + regstr;
if (buildInfo) {
hecl::SystemStringConv buildView(m_version);
rep.desc += _SYS_STR(" (") + buildView + _SYS_STR(")");
rep.desc += " (" + m_version + ")";
}
/* Iterate PAKs and build level options */
@ -243,23 +241,23 @@ struct SpecMP1 : SpecBase {
return true;
}
bool checkFromTrilogyDisc(nod::DiscBase& disc, const hecl::SystemString& regstr,
const std::vector<hecl::SystemString>& args, std::vector<ExtractReport>& reps) override {
std::vector<hecl::SystemString> mp1args;
bool checkFromTrilogyDisc(nod::DiscBase& disc, const std::string& regstr,
const std::vector<std::string>& args, std::vector<ExtractReport>& reps) override {
std::vector<std::string> mp1args;
bool doExtract = false;
if (args.size()) {
/* Needs filter */
for (const hecl::SystemString& arg : args) {
hecl::SystemString lowerArg = arg;
for (const std::string& arg : args) {
std::string lowerArg = arg;
hecl::ToLower(lowerArg);
if (!lowerArg.compare(0, 3, _SYS_STR("mp1"))) {
if (!lowerArg.compare(0, 3, "mp1")) {
doExtract = true;
mp1args.reserve(args.size());
size_t slashPos = arg.find(_SYS_STR('/'));
if (slashPos == hecl::SystemString::npos)
slashPos = arg.find(_SYS_STR('\\'));
if (slashPos != hecl::SystemString::npos)
mp1args.emplace_back(hecl::SystemString(arg.begin() + slashPos + 1, arg.end()));
size_t slashPos = arg.find('/');
if (slashPos == std::string::npos)
slashPos = arg.find('\\');
if (slashPos != std::string::npos)
mp1args.emplace_back(std::string(arg.begin() + slashPos + 1, arg.end()));
}
}
} else
@ -282,12 +280,11 @@ struct SpecMP1 : SpecBase {
/* Root Report */
ExtractReport& rep = reps.emplace_back();
rep.name = _SYS_STR("MP1");
rep.desc = _SYS_STR("Metroid Prime ") + regstr;
rep.name = "MP1";
rep.desc = "Metroid Prime " + regstr;
if (buildInfo != nullptr) {
m_version = std::string(buildInfo);
hecl::SystemStringConv buildView(m_version);
rep.desc += _SYS_STR(" (") + buildView + _SYS_STR(")");
rep.desc += " (" + m_version + ")";
}
/* Iterate PAKs and build level options */
@ -303,36 +300,36 @@ struct SpecMP1 : SpecBase {
}
bool extractFromDisc(nod::DiscBase& disc, bool force, const hecl::MultiProgressPrinter& progress) override {
m_project.enableDataSpecs({_SYS_STR("MP1-PC")});
m_project.enableDataSpecs({"MP1-PC"});
nod::ExtractionContext ctx = {force, nullptr};
m_workPath.makeDir();
progress.startNewLine();
progress.print(_SYS_STR("Indexing PAKs"), _SYS_STR(""), 0.0);
progress.print("Indexing PAKs", "", 0.0);
m_pakRouter.build(m_paks,
[&progress](float factor) { progress.print(_SYS_STR("Indexing PAKs"), _SYS_STR(""), factor); });
progress.print(_SYS_STR("Indexing PAKs"), _SYS_STR(""), 1.0);
[&progress](float factor) { progress.print("Indexing PAKs", "", factor); });
progress.print("Indexing PAKs", "", 1.0);
hecl::ProjectPath outPath(m_project.getProjectWorkingPath(), _SYS_STR("out"));
hecl::ProjectPath outPath(m_project.getProjectWorkingPath(), "out");
outPath.makeDir();
disc.getDataPartition()->extractSysFiles(outPath.getAbsolutePath(), ctx);
hecl::ProjectPath mp1OutPath(outPath, _SYS_STR("files/MP1"));
hecl::ProjectPath mp1OutPath(outPath, "files/MP1");
mp1OutPath.makeDirChain(true);
/* Extract non-pak files */
progress.startNewLine();
progress.print(_SYS_STR("MP1 Root"), _SYS_STR(""), 0.0);
progress.print("MP1 Root", "", 0.0);
int prog = 0;
ctx.progressCB = [&](nod::SystemStringView name, float) {
progress.print(_SYS_STR("MP1 Root"), name, prog / (float)m_nonPaks.size());
ctx.progressCB = [&](std::string_view name, float) {
progress.print("MP1 Root", name, prog / (float)m_nonPaks.size());
};
for (const nod::Node* node : m_nonPaks) {
node->extractToDirectory(mp1OutPath.getAbsolutePath(), ctx);
prog++;
}
progress.print(_SYS_STR("MP1 Root"), _SYS_STR(""), 1.0);
progress.print("MP1 Root", "", 1.0);
/* Extract unique resources */
hecl::ClientProcess process;
@ -358,14 +355,11 @@ struct SpecMP1 : SpecBase {
if (!pak.m_doExtract)
continue;
auto name = pak.getName();
hecl::SystemStringConv sysName(name);
auto pakName = hecl::SystemString(sysName.sys_str());
auto pakName = std::string(pak.getName());
process.addLambdaTransaction([this, &progress, &pak, pakName, force](hecl::blender::Token& btok) {
int threadIdx = hecl::ClientProcess::GetThreadWorkerIdx();
m_pakRouter.extractResources(pak, force, btok,
[&progress, &pakName, threadIdx](const hecl::SystemChar* substr, float factor) {
[&progress, &pakName, threadIdx](const char* substr, float factor) {
progress.print(pakName, substr, factor, threadIdx);
});
});
@ -374,14 +368,14 @@ struct SpecMP1 : SpecBase {
process.waitUntilComplete();
/* Extract part of .dol for RandomStatic entropy */
hecl::ProjectPath noAramPath(m_project.getProjectWorkingPath(), _SYS_STR("MP1/URDE"));
hecl::ProjectPath noAramPath(m_project.getProjectWorkingPath(), "MP1/URDE");
extractRandomStaticEntropy(m_dolBuf.get() + 0x4f60, noAramPath);
/* Generate Texture Cache containing meta data for every texture file */
TextureCache::Generate(m_pakRouter, m_project, noAramPath);
/* Write version data */
hecl::ProjectPath versionPath = hecl::ProjectPath(m_project.getProjectWorkingPath(), _SYS_STR("out/files/MP1"));
hecl::ProjectPath versionPath = hecl::ProjectPath(m_project.getProjectWorkingPath(), "out/files/MP1");
WriteVersionInfo(m_project, versionPath);
return true;
}
@ -393,7 +387,7 @@ struct SpecMP1 : SpecBase {
hecl::ProjectPath getWorking(class UniqueID32& id) override { return m_pakRouter.getWorking(id); }
bool checkPathPrefix(const hecl::ProjectPath& path) const override {
return path.getRelativePath().compare(0, 4, _SYS_STR("MP1/")) == 0;
return path.getRelativePath().compare(0, 4, "MP1/") == 0;
}
bool validateYAMLDNAType(athena::io::IStreamReader& fp) const override {
@ -473,29 +467,29 @@ struct SpecMP1 : SpecBase {
}
metaforce::SObjectTag buildTagFromPath(const hecl::ProjectPath& path) const override {
if (hecl::StringUtils::EndsWith(path.getAuxInfo(), _SYS_STR(".CSKR")))
if (hecl::StringUtils::EndsWith(path.getAuxInfo(), ".CSKR"))
return {SBIG('CSKR'), path.parsedHash32()};
else if (hecl::StringUtils::EndsWith(path.getAuxInfo(), _SYS_STR(".ANIM")))
else if (hecl::StringUtils::EndsWith(path.getAuxInfo(), ".ANIM"))
return {SBIG('ANIM'), path.parsedHash32()};
else if (const hecl::SystemChar* ext = path.getLastComponentExt().data()) {
if (ext[0] == _SYS_STR('*') || !hecl::StrCmp(ext, _SYS_STR("mid"))) {
if (path.getWithExtension(_SYS_STR(".mid"), true).isFile() &&
path.getWithExtension(_SYS_STR(".yaml"), true).isFile()) {
hecl::ProjectPath glob = path.getWithExtension(_SYS_STR(".*"), true);
else if (const char* ext = path.getLastComponentExt().data()) {
if (ext[0] == '*' || !hecl::StrCmp(ext, "mid")) {
if (path.getWithExtension(".mid", true).isFile() &&
path.getWithExtension(".yaml", true).isFile()) {
hecl::ProjectPath glob = path.getWithExtension(".*", true);
return {SBIG('CSNG'), glob.parsedHash32()};
}
}
}
if (path.getPathType() == hecl::ProjectPath::Type::Directory) {
if (hecl::ProjectPath(path, _SYS_STR("!project.yaml")).isFile() &&
hecl::ProjectPath(path, _SYS_STR("!pool.yaml")).isFile())
if (hecl::ProjectPath(path, "!project.yaml").isFile() &&
hecl::ProjectPath(path, "!pool.yaml").isFile())
return {SBIG('AGSC'), path.parsedHash32()};
}
hecl::ProjectPath asBlend;
if (path.getPathType() == hecl::ProjectPath::Type::Glob)
asBlend = path.getWithExtension(_SYS_STR(".blend"), true);
asBlend = path.getWithExtension(".blend", true);
else
asBlend = path;
@ -511,16 +505,16 @@ struct SpecMP1 : SpecBase {
return {SBIG('PATH'), path.parsedHash32()};
case hecl::blender::BlendType::Actor:
if (path.getAuxInfo().size()) {
if (hecl::StringUtils::EndsWith(path.getAuxInfo(), _SYS_STR(".CSKR")))
return {SBIG('CSKR'), path.getWithExtension(_SYS_STR(".*"), true).parsedHash32()};
else if (hecl::StringUtils::EndsWith(path.getAuxInfo(), _SYS_STR(".ANIM")))
return {SBIG('ANIM'), path.getWithExtension(_SYS_STR(".*"), true).parsedHash32()};
if (hecl::StringUtils::EndsWith(path.getAuxInfo(), ".CSKR"))
return {SBIG('CSKR'), path.getWithExtension(".*", true).parsedHash32()};
else if (hecl::StringUtils::EndsWith(path.getAuxInfo(), ".ANIM"))
return {SBIG('ANIM'), path.getWithExtension(".*", true).parsedHash32()};
}
return {SBIG('ANCS'), path.getWithExtension(_SYS_STR(".*"), true).parsedHash32()};
return {SBIG('ANCS'), path.getWithExtension(".*", true).parsedHash32()};
case hecl::blender::BlendType::Area:
return {SBIG('MREA'), path.parsedHash32()};
case hecl::blender::BlendType::World:
return {SBIG('MLVL'), path.getWithExtension(_SYS_STR(".*"), true).parsedHash32()};
return {SBIG('MLVL'), path.getWithExtension(".*", true).parsedHash32()};
case hecl::blender::BlendType::MapArea:
return {SBIG('MAPA'), path.parsedHash32()};
case hecl::blender::BlendType::MapUniverse:
@ -533,7 +527,7 @@ struct SpecMP1 : SpecBase {
} else if (hecl::IsPathPNG(path)) {
return {SBIG('TXTR'), path.parsedHash32()};
} else if (hecl::IsPathYAML(path)) {
auto fp = hecl::FopenUnique(path.getAbsolutePath().data(), _SYS_STR("r"));
auto fp = hecl::FopenUnique(path.getAbsolutePath().data(), "r");
if (fp == nullptr) {
return {};
}
@ -640,7 +634,7 @@ struct SpecMP1 : SpecBase {
std::unique_lock lk(m_backgroundIndexMutex);
for (const auto& tag : m_tagToPath)
if (!tag.second.getRelativePathUTF8().compare(0, pathPrefix.size(), pathPrefix))
if (!tag.second.getRelativePath().compare(0, pathPrefix.size(), pathPrefix))
out.push_back(tag.first);
}
@ -677,7 +671,7 @@ struct SpecMP1 : SpecBase {
void cookActor(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast,
hecl::blender::Token& btok, FCookProgress progress) override {
if (hecl::StringUtils::EndsWith(in.getAuxInfo(), _SYS_STR(".CSKR"))) {
if (hecl::StringUtils::EndsWith(in.getAuxInfo(), ".CSKR")) {
Actor actor = ds.compileActorCharacterOnly();
ds.close();
if (m_pc) {
@ -693,7 +687,7 @@ struct SpecMP1 : SpecBase {
return true;
});
}
} else if (hecl::StringUtils::EndsWith(in.getAuxInfo(), _SYS_STR(".ANIM"))) {
} else if (hecl::StringUtils::EndsWith(in.getAuxInfo(), ".ANIM")) {
Actor actor = ds.compileActorCharacterOnly();
DNAMP1::ANCS::CookANIM(out, in, actor, ds, m_pc);
} else {
@ -711,8 +705,8 @@ struct SpecMP1 : SpecBase {
if (ent2.m_isDir) {
hecl::ProjectPath wldDir(pakPath, ent2.m_name);
for (const auto& ent3 : wldDir.enumerateDir()) {
if (hecl::StringUtils::BeginsWith(ent3.m_name, _SYS_STR("!world")) &&
hecl::StringUtils::EndsWith(ent3.m_name, _SYS_STR(".blend"))) {
if (hecl::StringUtils::BeginsWith(ent3.m_name, "!world") &&
hecl::StringUtils::EndsWith(ent3.m_name, ".blend")) {
hecl::ProjectPath wldPath(wldDir, ent3.m_name);
if (wldPath.isFile()) {
if (!conn.openBlend(wldPath))
@ -740,10 +734,9 @@ struct SpecMP1 : SpecBase {
std::optional<ColMesh> colMesh;
for (const std::string& mesh : meshes) {
hecl::SystemStringConv meshSys(mesh);
if (mesh == "CMESH") {
colMesh = ds.compileColMesh(mesh);
progress(_SYS_STR("Collision Mesh"));
progress("Collision Mesh");
continue;
}
meshCompiles.push_back(
@ -751,7 +744,7 @@ struct SpecMP1 : SpecBase {
}
if (!colMesh)
Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("unable to find mesh named 'CMESH' in {}")),
Log.report(logvisor::Fatal, FMT_STRING("unable to find mesh named 'CMESH' in {}"),
in.getAbsolutePath());
std::vector<Light> lights = ds.compileLights();
@ -922,7 +915,7 @@ struct SpecMP1 : SpecBase {
TextureCache::Cook(in, out);
}
}
progress(_SYS_STR("Done"));
progress("Done");
}
void flattenDependenciesYAML(athena::io::IStreamReader& fin, std::vector<hecl::ProjectPath>& pathsOut) override {
@ -998,7 +991,7 @@ struct SpecMP1 : SpecBase {
{
athena::io::FileReader r(worldPathCooked.getAbsolutePath());
if (r.hasError())
Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("Unable to open world {}")), worldPathCooked.getRelativePath());
Log.report(logvisor::Fatal, FMT_STRING("Unable to open world {}"), worldPathCooked.getRelativePath());
mlvl.read(r);
}
@ -1015,7 +1008,7 @@ struct SpecMP1 : SpecBase {
}
listOut.reserve(count);
metaforce::SObjectTag worldTag = tagFromPath(worldPath.getWithExtension(_SYS_STR(".*"), true));
metaforce::SObjectTag worldTag = tagFromPath(worldPath.getWithExtension(".*", true));
w.writeUint32Big(m_pc ? 0x80030005 : 0x00030005);
w.writeUint32Big(0);
@ -1026,7 +1019,7 @@ struct SpecMP1 : SpecBase {
nameEnt.type = worldTag.type;
nameEnt.id = worldTag.id.Value();
nameEnt.nameLen = atUint32(parentDir.getLastComponent().size());
nameEnt.name = parentDir.getLastComponentUTF8();
nameEnt.name = parentDir.getLastComponent();
nameEnt.write(w);
std::unordered_set<metaforce::CAssetId> addedTags;
@ -1035,7 +1028,7 @@ struct SpecMP1 : SpecBase {
bool dupeRes = false;
if (hecl::ProjectPath areaDir = pathFromTag(areaTag).getParentPath())
dupeRes = hecl::ProjectPath(areaDir, _SYS_STR("!duperes")).isFile();
dupeRes = hecl::ProjectPath(areaDir, "!duperes").isFile();
metaforce::SObjectTag nameTag(FOURCC('STRG'), area.areaNameId.toUint64());
if (nameTag)
@ -1094,10 +1087,10 @@ struct SpecMP1 : SpecBase {
if (hecl::ProjectPath mapCookedPath = getCookedPath(mapPath, true)) {
athena::io::FileReader r(mapCookedPath.getAbsolutePath());
if (r.hasError())
Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("Unable to open {}")), mapCookedPath.getRelativePath());
Log.report(logvisor::Fatal, FMT_STRING("Unable to open {}"), mapCookedPath.getRelativePath());
if (r.readUint32Big() != 0xDEADF00D)
Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("Corrupt MAPW {}")), mapCookedPath.getRelativePath());
Log.report(logvisor::Fatal, FMT_STRING("Corrupt MAPW {}"), mapCookedPath.getRelativePath());
r.readUint32Big();
atUint32 mapaCount = r.readUint32Big();
for (atUint32 i = 0; i < mapaCount; ++i) {
@ -1120,7 +1113,7 @@ struct SpecMP1 : SpecBase {
for (const auto& tex : textures) {
metaforce::SObjectTag texTag = tagFromPath(tex);
if (!texTag)
Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("Unable to resolve {}")), tex.getRelativePath());
Log.report(logvisor::Fatal, FMT_STRING("Unable to resolve {}"), tex.getRelativePath());
listOut.push_back(texTag);
}
}
@ -1233,12 +1226,12 @@ struct SpecMP1 : SpecBase {
void cookAudioGroup(const hecl::ProjectPath& out, const hecl::ProjectPath& in, FCookProgress progress) override {
DNAMP1::AGSC::Cook(in, out);
progress(_SYS_STR("Done"));
progress("Done");
}
void cookSong(const hecl::ProjectPath& out, const hecl::ProjectPath& in, FCookProgress progress) override {
DNAMP1::CSNG::Cook(in, out);
progress(_SYS_STR("Done"));
progress("Done");
}
void cookMapArea(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds,
@ -1246,7 +1239,7 @@ struct SpecMP1 : SpecBase {
hecl::blender::MapArea mapa = ds.compileMapArea();
ds.close();
DNAMP1::MAPA::Cook(mapa, out);
progress(_SYS_STR("Done"));
progress("Done");
}
void cookMapUniverse(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds,
@ -1254,18 +1247,18 @@ struct SpecMP1 : SpecBase {
hecl::blender::MapUniverse mapu = ds.compileMapUniverse();
ds.close();
DNAMAPU::MAPU::Cook(mapu, out);
progress(_SYS_STR("Done"));
progress("Done");
}
};
hecl::Database::DataSpecEntry SpecEntMP1 = {
_SYS_STR("MP1"sv), _SYS_STR("Data specification for original Metroid Prime engine"sv), _SYS_STR(".pak"sv),
"MP1"sv, "Data specification for original Metroid Prime engine"sv, ".pak"sv,
[](hecl::Database::Project& project, hecl::Database::DataSpecTool) -> std::unique_ptr<hecl::Database::IDataSpec> {
return std::make_unique<SpecMP1>(&SpecEntMP1, project, false);
}};
hecl::Database::DataSpecEntry SpecEntMP1PC = {
_SYS_STR("MP1-PC"sv), _SYS_STR("Data specification for PC-optimized Metroid Prime engine"sv), _SYS_STR(".upak"sv),
"MP1-PC"sv, "Data specification for PC-optimized Metroid Prime engine"sv, ".upak"sv,
[](hecl::Database::Project& project,
hecl::Database::DataSpecTool tool) -> std::unique_ptr<hecl::Database::IDataSpec> {
if (tool != hecl::Database::DataSpecTool::Extract)
@ -1274,5 +1267,5 @@ hecl::Database::DataSpecEntry SpecEntMP1PC = {
}};
hecl::Database::DataSpecEntry SpecEntMP1ORIG = {
_SYS_STR("MP1-ORIG"sv), _SYS_STR("Data specification for unmodified Metroid Prime resources"sv), {}, {}};
"MP1-ORIG"sv, "Data specification for unmodified Metroid Prime resources"sv, {}, {}};
} // namespace DataSpec

View File

@ -32,12 +32,12 @@ extern hecl::Database::DataSpecEntry SpecEntMP2ORIG;
struct TextureCache {
static void Generate(PAKRouter<DNAMP2::PAKBridge>& pakRouter, hecl::Database::Project& project,
const hecl::ProjectPath& pakPath) {
hecl::ProjectPath texturePath(pakPath, _SYS_STR("texture_cache.yaml"));
hecl::ProjectPath catalogPath(pakPath, _SYS_STR("!catalog.yaml"));
hecl::ProjectPath texturePath(pakPath, "texture_cache.yaml");
hecl::ProjectPath catalogPath(pakPath, "!catalog.yaml");
texturePath.makeDirChain(false);
if (const auto fp = hecl::FopenUnique(catalogPath.getAbsolutePath().data(), _SYS_STR("a"))) {
fmt::print(fp.get(), FMT_STRING("TextureCache: {}\n"), texturePath.getRelativePathUTF8());
if (const auto fp = hecl::FopenUnique(catalogPath.getAbsolutePath().data(), "a")) {
fmt::print(fp.get(), FMT_STRING("TextureCache: {}\n"), texturePath.getRelativePath());
}
Log.report(logvisor::Level::Info, FMT_STRING("Gathering Texture metadata (this can take up to 10 seconds)..."));
@ -54,7 +54,7 @@ struct TextureCache {
athena::io::YAMLDocWriter yamlW("MP2TextureCache");
for (const auto& pair : metaMap) {
hecl::ProjectPath path = pakRouter.getWorking(pair.first);
auto rec = yamlW.enterSubRecord(path.getRelativePathUTF8());
auto rec = yamlW.enterSubRecord(path.getRelativePath());
pair.second.write(yamlW);
}
@ -109,21 +109,21 @@ struct SpecMP2 : SpecBase {
SpecMP2(const hecl::Database::DataSpecEntry* specEntry, hecl::Database::Project& project, bool pc)
: SpecBase(specEntry, project, pc)
, m_workPath(project.getProjectWorkingPath(), _SYS_STR("MP2"))
, m_cookPath(project.getProjectCookedPath(SpecEntMP2), _SYS_STR("MP2"))
, m_workPath(project.getProjectWorkingPath(), "MP2")
, m_cookPath(project.getProjectCookedPath(SpecEntMP2), "MP2")
, m_pakRouter(*this, m_workPath, m_cookPath) {
m_game = EGame::MetroidPrime2;
SpecBase::setThreadProject();
}
void buildPaks(nod::Node& root, const std::vector<hecl::SystemString>& args, ExtractReport& rep) {
void buildPaks(nod::Node& root, const std::vector<std::string>& args, ExtractReport& rep) {
m_nonPaks.clear();
m_paks.clear();
for (const nod::Node& child : root) {
bool isPak = false;
auto name = child.getName();
std::string lowerName(name);
std::transform(lowerName.begin(), lowerName.end(), lowerName.begin(), tolower);
hecl::ToLower(lowerName);
if (name.size() > 4) {
std::string::iterator extit = lowerName.end() - 4;
if (std::string(extit, lowerName.end()) == ".pak") {
@ -136,8 +136,8 @@ struct SpecMP2 : SpecBase {
if (args.size()) {
good = false;
if (!lowerName.compare(0, 7, "metroid")) {
hecl::SystemChar idxChar = lowerName[7];
for (const hecl::SystemString& arg : args) {
char idxChar = lowerName[7];
for (const std::string& arg : args) {
if (arg.size() == 1 && iswdigit(arg[0]))
if (arg[0] == idxChar)
good = true;
@ -146,9 +146,9 @@ struct SpecMP2 : SpecBase {
good = true;
if (!good) {
for (const hecl::SystemString& arg : args) {
std::string lowerArg(hecl::SystemUTF8Conv(arg).str());
std::transform(lowerArg.begin(), lowerArg.end(), lowerArg.begin(), tolower);
for (const std::string& arg : args) {
std::string lowerArg(arg);
hecl::ToLower(lowerArg);
if (!lowerArg.compare(0, lowerBase.size(), lowerBase))
good = true;
}
@ -175,14 +175,13 @@ struct SpecMP2 : SpecBase {
}
ExtractReport& childRep = rep.childOpts.emplace_back();
hecl::SystemStringConv nameView(item.first);
childRep.name = hecl::SystemString(nameView.sys_str());
childRep.name = item.first;
childRep.desc = item.second->getLevelString();
}
}
bool checkFromStandaloneDisc(nod::DiscBase& disc, const hecl::SystemString& regstr,
const std::vector<hecl::SystemString>& args, std::vector<ExtractReport>& reps) override {
bool checkFromStandaloneDisc(nod::DiscBase& disc, const std::string& regstr,
const std::vector<std::string>& args, std::vector<ExtractReport>& reps) override {
nod::IPartition* partition = disc.getDataPartition();
std::unique_ptr<uint8_t[]> dolBuf = partition->getDOLBuf();
const char* buildInfo =
@ -194,10 +193,9 @@ struct SpecMP2 : SpecBase {
m_version = std::string(buildInfo);
/* Root Report */
ExtractReport& rep = reps.emplace_back();
rep.name = _SYS_STR("MP2");
rep.desc = _SYS_STR("Metroid Prime 2 ") + regstr;
hecl::SystemStringConv buildView(m_version);
rep.desc += _SYS_STR(" (") + buildView + _SYS_STR(")");
rep.name = "MP2";
rep.desc = "Metroid Prime 2 " + regstr;
rep.desc += " (" + m_version + ")";
/* Iterate PAKs and build level options */
nod::Node& root = partition->getFSTRoot();
@ -206,23 +204,23 @@ struct SpecMP2 : SpecBase {
return true;
}
bool checkFromTrilogyDisc(nod::DiscBase& disc, const hecl::SystemString& regstr,
const std::vector<hecl::SystemString>& args, std::vector<ExtractReport>& reps) override {
std::vector<hecl::SystemString> mp2args;
bool checkFromTrilogyDisc(nod::DiscBase& disc, const std::string& regstr,
const std::vector<std::string>& args, std::vector<ExtractReport>& reps) override {
std::vector<std::string> mp2args;
bool doExtract = false;
if (!args.empty()) {
/* Needs filter */
for (const hecl::SystemString& arg : args) {
hecl::SystemString lowerArg = arg;
for (const std::string& arg : args) {
std::string lowerArg = arg;
hecl::ToLower(lowerArg);
if (!lowerArg.compare(0, 3, _SYS_STR("mp2"))) {
if (!lowerArg.compare(0, 3, "mp2")) {
doExtract = true;
mp2args.reserve(args.size());
size_t slashPos = arg.find(_SYS_STR('/'));
if (slashPos == hecl::SystemString::npos)
slashPos = arg.find(_SYS_STR('\\'));
if (slashPos != hecl::SystemString::npos)
mp2args.emplace_back(hecl::SystemString(arg.begin() + slashPos + 1, arg.end()));
size_t slashPos = arg.find('/');
if (slashPos == std::string::npos)
slashPos = arg.find('\\');
if (slashPos != std::string::npos)
mp2args.emplace_back(std::string(arg.begin() + slashPos + 1, arg.end()));
}
}
} else
@ -245,12 +243,11 @@ struct SpecMP2 : SpecBase {
/* Root Report */
ExtractReport& rep = reps.emplace_back();
rep.name = _SYS_STR("MP2");
rep.desc = _SYS_STR("Metroid Prime 2 ") + regstr;
rep.name = "MP2";
rep.desc = "Metroid Prime 2 " + regstr;
if (buildInfo != nullptr) {
m_version = std::string(buildInfo);
hecl::SystemStringConv buildView(m_version);
rep.desc += _SYS_STR(" (") + buildView + _SYS_STR(")");
rep.desc += " (" + m_version + ")";
}
/* Iterate PAKs and build level options */
@ -271,28 +268,28 @@ struct SpecMP2 : SpecBase {
m_workPath.makeDir();
progress.startNewLine();
progress.print(_SYS_STR("Indexing PAKs"), _SYS_STR(""), 0.0);
progress.print("Indexing PAKs", "", 0.0);
m_pakRouter.build(m_paks,
[&progress](float factor) { progress.print(_SYS_STR("Indexing PAKs"), _SYS_STR(""), factor); });
progress.print(_SYS_STR("Indexing PAKs"), _SYS_STR(""), 1.0);
[&progress](float factor) { progress.print("Indexing PAKs", "", factor); });
progress.print("Indexing PAKs", "", 1.0);
hecl::ProjectPath outPath(m_project.getProjectWorkingPath(), _SYS_STR("out"));
hecl::ProjectPath outPath(m_project.getProjectWorkingPath(), "out");
outPath.makeDir();
disc.getDataPartition()->extractSysFiles(outPath.getAbsolutePath(), ctx);
hecl::ProjectPath mp2OutPath(outPath, _SYS_STR("files/MP2"));
hecl::ProjectPath mp2OutPath(outPath, "files/MP2");
mp2OutPath.makeDirChain(true);
progress.startNewLine();
progress.print(_SYS_STR("MP2 Root"), _SYS_STR(""), 0.0);
progress.print("MP2 Root", "", 0.0);
int prog = 0;
ctx.progressCB = [&prog, &progress](nod::SystemStringView name, float) {
progress.print(_SYS_STR("MP2 Root"), name, prog);
ctx.progressCB = [&prog, &progress](std::string_view name, float) {
progress.print("MP2 Root", name, prog);
};
for (const nod::Node* node : m_nonPaks) {
node->extractToDirectory(mp2OutPath.getAbsolutePath(), ctx);
prog++;
}
progress.print(_SYS_STR("MP2 Root"), _SYS_STR(""), 1.0);
progress.print("MP2 Root", "", 1.0);
hecl::ClientProcess process;
progress.startNewLine();
@ -301,14 +298,11 @@ struct SpecMP2 : SpecBase {
if (!pak.m_doExtract)
continue;
auto name = pak.getName();
hecl::SystemStringConv sysName(name);
auto pakName = hecl::SystemString(sysName.sys_str());
auto pakName = std::string(pak.getName());
process.addLambdaTransaction([this, &progress, &pak, pakName, force](hecl::blender::Token& btok) {
int threadIdx = hecl::ClientProcess::GetThreadWorkerIdx();
m_pakRouter.extractResources(pak, force, btok,
[&progress, &pakName, threadIdx](const hecl::SystemChar* substr, float factor) {
[&progress, &pakName, threadIdx](const char* substr, float factor) {
progress.print(pakName, substr, factor, threadIdx);
});
});
@ -317,11 +311,11 @@ struct SpecMP2 : SpecBase {
process.waitUntilComplete();
/* Generate Texture Cache containing meta data for every texture file */
hecl::ProjectPath noAramPath(m_project.getProjectWorkingPath(), _SYS_STR("MP2/URDE"));
hecl::ProjectPath noAramPath(m_project.getProjectWorkingPath(), "MP2/URDE");
TextureCache::Generate(m_pakRouter, m_project, noAramPath);
/* Write version data */
hecl::ProjectPath versionPath = hecl::ProjectPath(m_project.getProjectWorkingPath(), _SYS_STR("out/files/MP2"));
hecl::ProjectPath versionPath = hecl::ProjectPath(m_project.getProjectWorkingPath(), "out/files/MP2");
WriteVersionInfo(m_project, versionPath);
return true;
}
@ -333,7 +327,7 @@ struct SpecMP2 : SpecBase {
hecl::ProjectPath getWorking(class UniqueID32& id) override { return m_pakRouter.getWorking(id); }
bool checkPathPrefix(const hecl::ProjectPath& path) const override {
return path.getRelativePath().compare(0, 4, _SYS_STR("MP2/")) == 0;
return path.getRelativePath().compare(0, 4, "MP2/") == 0;
}
bool validateYAMLDNAType(athena::io::IStreamReader& fp) const override {
@ -390,12 +384,12 @@ struct SpecMP2 : SpecBase {
void cookAudioGroup(const hecl::ProjectPath& out, const hecl::ProjectPath& in, FCookProgress progress) override {
DNAMP2::AGSC::Cook(in, out);
progress(_SYS_STR("Done"));
progress("Done");
}
void cookSong(const hecl::ProjectPath& out, const hecl::ProjectPath& in, FCookProgress progress) override {
DNAMP1::CSNG::Cook(in, out);
progress(_SYS_STR("Done"));
progress("Done");
}
void cookMapArea(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds,
@ -403,7 +397,7 @@ struct SpecMP2 : SpecBase {
hecl::blender::MapArea mapa = ds.compileMapArea();
ds.close();
DNAMP2::MAPA::Cook(mapa, out);
progress(_SYS_STR("Done"));
progress("Done");
}
void cookMapUniverse(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds,
@ -411,18 +405,18 @@ struct SpecMP2 : SpecBase {
hecl::blender::MapUniverse mapu = ds.compileMapUniverse();
ds.close();
DNAMAPU::MAPU::Cook(mapu, out);
progress(_SYS_STR("Done"));
progress("Done");
}
};
hecl::Database::DataSpecEntry SpecEntMP2(
_SYS_STR("MP2"sv), _SYS_STR("Data specification for original Metroid Prime 2 engine"sv), _SYS_STR(".pak"sv),
"MP2"sv, "Data specification for original Metroid Prime 2 engine"sv, ".pak"sv,
[](hecl::Database::Project& project, hecl::Database::DataSpecTool) -> std::unique_ptr<hecl::Database::IDataSpec> {
return std::make_unique<SpecMP2>(&SpecEntMP2, project, false);
});
hecl::Database::DataSpecEntry SpecEntMP2PC = {
_SYS_STR("MP2-PC"sv), _SYS_STR("Data specification for PC-optimized Metroid Prime 2 engine"sv), _SYS_STR(".upak"sv),
"MP2-PC"sv, "Data specification for PC-optimized Metroid Prime 2 engine"sv, ".upak"sv,
[](hecl::Database::Project& project,
hecl::Database::DataSpecTool tool) -> std::unique_ptr<hecl::Database::IDataSpec> {
if (tool != hecl::Database::DataSpecTool::Extract)
@ -431,6 +425,6 @@ hecl::Database::DataSpecEntry SpecEntMP2PC = {
}};
hecl::Database::DataSpecEntry SpecEntMP2ORIG = {
_SYS_STR("MP2-ORIG"sv), _SYS_STR("Data specification for unmodified Metroid Prime 2 resources"sv), {}, {}};
"MP2-ORIG"sv, "Data specification for unmodified Metroid Prime 2 resources"sv, {}, {}};
} // namespace DataSpec

View File

@ -29,12 +29,12 @@ extern hecl::Database::DataSpecEntry SpecEntMP3ORIG;
struct TextureCache {
static void Generate(PAKRouter<DNAMP3::PAKBridge>& pakRouter, hecl::Database::Project& project,
const hecl::ProjectPath& pakPath) {
hecl::ProjectPath texturePath(pakPath, _SYS_STR("texture_cache.yaml"));
hecl::ProjectPath catalogPath(pakPath, _SYS_STR("!catalog.yaml"));
hecl::ProjectPath texturePath(pakPath, "texture_cache.yaml");
hecl::ProjectPath catalogPath(pakPath, "!catalog.yaml");
texturePath.makeDirChain(false);
if (const auto fp = hecl::FopenUnique(catalogPath.getAbsolutePath().data(), _SYS_STR("a"))) {
fmt::print(fp.get(), FMT_STRING("TextureCache: {}\n"), texturePath.getRelativePathUTF8());
if (const auto fp = hecl::FopenUnique(catalogPath.getAbsolutePath().data(), "a")) {
fmt::print(fp.get(), FMT_STRING("TextureCache: {}\n"), texturePath.getRelativePath());
}
Log.report(logvisor::Level::Info, FMT_STRING("Gathering Texture metadata (this can take up to 10 seconds)..."));
@ -51,7 +51,7 @@ struct TextureCache {
athena::io::YAMLDocWriter yamlW("MP3TextureCache");
for (const auto& pair : metaMap) {
hecl::ProjectPath path = pakRouter.getWorking(pair.first);
auto rec = yamlW.enterSubRecord(path.getRelativePathUTF8());
auto rec = yamlW.enterSubRecord(path.getRelativePath());
pair.second.write(yamlW);
}
@ -115,17 +115,17 @@ struct SpecMP3 : SpecBase {
SpecMP3(const hecl::Database::DataSpecEntry* specEntry, hecl::Database::Project& project, bool pc)
: SpecBase(specEntry, project, pc)
, m_workPath(project.getProjectWorkingPath(), _SYS_STR("MP3"))
, m_cookPath(project.getProjectCookedPath(SpecEntMP3), _SYS_STR("MP3"))
, m_workPath(project.getProjectWorkingPath(), "MP3")
, m_cookPath(project.getProjectCookedPath(SpecEntMP3), "MP3")
, m_pakRouter(*this, m_workPath, m_cookPath)
, m_feWorkPath(project.getProjectWorkingPath(), _SYS_STR("fe"))
, m_feCookPath(project.getProjectCookedPath(SpecEntMP3), _SYS_STR("fe"))
, m_feWorkPath(project.getProjectWorkingPath(), "fe")
, m_feCookPath(project.getProjectCookedPath(SpecEntMP3), "fe")
, m_fePakRouter(*this, m_feWorkPath, m_feCookPath) {
m_game = EGame::MetroidPrime3;
SpecBase::setThreadProject();
}
void buildPaks(nod::Node& root, const std::vector<hecl::SystemString>& args, ExtractReport& rep, bool fe) {
void buildPaks(nod::Node& root, const std::vector<std::string>& args, ExtractReport& rep, bool fe) {
if (fe) {
m_feNonPaks.clear();
m_fePaks.clear();
@ -137,7 +137,7 @@ struct SpecMP3 : SpecBase {
bool isPak = false;
auto name = child.getName();
std::string lowerName(name);
std::transform(lowerName.begin(), lowerName.end(), lowerName.begin(), tolower);
hecl::ToLower(lowerName);
if (name.size() > 4) {
std::string::iterator extit = lowerName.end() - 4;
if (std::string(extit, lowerName.end()) == ".pak") {
@ -150,8 +150,8 @@ struct SpecMP3 : SpecBase {
if (args.size()) {
good = false;
if (!lowerName.compare(0, 7, "metroid")) {
hecl::SystemChar idxChar = lowerName[7];
for (const hecl::SystemString& arg : args) {
char idxChar = lowerName[7];
for (const std::string& arg : args) {
if (arg.size() == 1 && iswdigit(arg[0]))
if (arg[0] == idxChar)
good = true;
@ -160,9 +160,9 @@ struct SpecMP3 : SpecBase {
good = true;
if (!good) {
for (const hecl::SystemString& arg : args) {
std::string lowerArg(hecl::SystemUTF8Conv(arg).str());
std::transform(lowerArg.begin(), lowerArg.end(), lowerArg.begin(), tolower);
for (const std::string& arg : args) {
std::string lowerArg(arg);
hecl::ToLower(lowerArg);
if (!lowerArg.compare(0, lowerBase.size(), lowerBase))
good = true;
}
@ -201,25 +201,24 @@ struct SpecMP3 : SpecBase {
continue;
ExtractReport& childRep = rep.childOpts.emplace_back();
hecl::SystemStringConv nameView(item.first);
childRep.name = hecl::SystemString(nameView.sys_str());
childRep.name = item.first;
if (item.first == "Worlds.pak")
continue;
else if (item.first == "Metroid6.pak") {
/* Phaaze doesn't have a world name D: */
childRep.desc = _SYS_STR("Phaaze");
childRep.desc = "Phaaze";
continue;
} else if (item.first == "Metroid8.pak") {
/* Space world is misnamed */
childRep.desc = _SYS_STR("Space");
childRep.desc = "Space";
continue;
}
childRep.desc = item.second->getLevelString();
}
}
bool checkFromStandaloneDisc(nod::DiscBase& disc, const hecl::SystemString& regstr,
const std::vector<hecl::SystemString>& args, std::vector<ExtractReport>& reps) override {
bool checkFromStandaloneDisc(nod::DiscBase& disc, const std::string& regstr,
const std::vector<std::string>& args, std::vector<ExtractReport>& reps) override {
doMP3 = true;
nod::IPartition* partition = disc.getDataPartition();
std::unique_ptr<uint8_t[]> dolBuf = partition->getDOLBuf();
@ -237,10 +236,9 @@ struct SpecMP3 : SpecBase {
m_version = std::string(buildInfo);
/* Root Report */
ExtractReport& rep = reps.emplace_back();
rep.name = _SYS_STR("MP3");
rep.desc = _SYS_STR("Metroid Prime 3 ") + regstr;
hecl::SystemStringConv buildView(m_version);
rep.desc += _SYS_STR(" (") + buildView + _SYS_STR(")");
rep.name = "MP3";
rep.desc = "Metroid Prime 3 " + regstr;
rep.desc += " (" + m_version + ")";
/* Iterate PAKs and build level options */
nod::Node& root = partition->getFSTRoot();
@ -249,37 +247,37 @@ struct SpecMP3 : SpecBase {
return true;
}
bool checkFromTrilogyDisc(nod::DiscBase& disc, const hecl::SystemString& regstr,
const std::vector<hecl::SystemString>& args, std::vector<ExtractReport>& reps) override {
std::vector<hecl::SystemString> mp3args;
std::vector<hecl::SystemString> feargs;
bool checkFromTrilogyDisc(nod::DiscBase& disc, const std::string& regstr,
const std::vector<std::string>& args, std::vector<ExtractReport>& reps) override {
std::vector<std::string> mp3args;
std::vector<std::string> feargs;
if (args.size()) {
/* Needs filter */
for (const hecl::SystemString& arg : args) {
hecl::SystemString lowerArg = arg;
for (const std::string& arg : args) {
std::string lowerArg = arg;
hecl::ToLower(lowerArg);
if (!lowerArg.compare(0, 3, _SYS_STR("mp3"))) {
if (!lowerArg.compare(0, 3, "mp3")) {
doMP3 = true;
mp3args.reserve(args.size());
size_t slashPos = arg.find(_SYS_STR('/'));
if (slashPos == hecl::SystemString::npos)
slashPos = arg.find(_SYS_STR('\\'));
if (slashPos != hecl::SystemString::npos)
mp3args.emplace_back(hecl::SystemString(arg.begin() + slashPos + 1, arg.end()));
size_t slashPos = arg.find('/');
if (slashPos == std::string::npos)
slashPos = arg.find('\\');
if (slashPos != std::string::npos)
mp3args.emplace_back(std::string(arg.begin() + slashPos + 1, arg.end()));
}
}
for (const hecl::SystemString& arg : args) {
hecl::SystemString lowerArg = arg;
for (const std::string& arg : args) {
std::string lowerArg = arg;
hecl::ToLower(lowerArg);
if (!lowerArg.compare(0, 2, _SYS_STR("fe"))) {
if (!lowerArg.compare(0, 2, "fe")) {
doMPTFE = true;
feargs.reserve(args.size());
size_t slashPos = arg.find(_SYS_STR('/'));
if (slashPos == hecl::SystemString::npos)
slashPos = arg.find(_SYS_STR('\\'));
if (slashPos != hecl::SystemString::npos)
feargs.emplace_back(hecl::SystemString(arg.begin() + slashPos + 1, arg.end()));
size_t slashPos = arg.find('/');
if (slashPos == std::string::npos)
slashPos = arg.find('\\');
if (slashPos != std::string::npos)
feargs.emplace_back(std::string(arg.begin() + slashPos + 1, arg.end()));
}
}
} else {
@ -317,12 +315,11 @@ struct SpecMP3 : SpecBase {
/* Root Report */
ExtractReport& rep = reps.emplace_back();
rep.name = _SYS_STR("MP3");
rep.desc = _SYS_STR("Metroid Prime 3 ") + regstr;
rep.name = "MP3";
rep.desc = "Metroid Prime 3 " + regstr;
m_version = std::string(buildInfo);
hecl::SystemStringConv buildView(m_version);
rep.desc += _SYS_STR(" (") + buildView + _SYS_STR(")");
rep.desc += " (" + m_version + ")";
/* Iterate PAKs and build level options */
nod::Node::DirectoryIterator mp3It = root.find("MP3");
@ -347,12 +344,11 @@ struct SpecMP3 : SpecBase {
/* Root Report */
ExtractReport& rep = reps.emplace_back();
rep.name = _SYS_STR("fe");
rep.desc = _SYS_STR("Metroid Prime Trilogy Frontend ") + regstr;
rep.name = "fe";
rep.desc = "Metroid Prime Trilogy Frontend " + regstr;
if (buildInfo) {
std::string buildStr(buildInfo);
hecl::SystemStringConv buildView(buildStr);
rep.desc += _SYS_STR(" (") + buildView + _SYS_STR(")");
rep.desc += " (" + buildStr + ")";
}
/* Iterate PAKs and build level options */
@ -369,30 +365,30 @@ struct SpecMP3 : SpecBase {
}
bool extractFromDisc(nod::DiscBase& disc, bool force, const hecl::MultiProgressPrinter& progress) override {
hecl::SystemString currentTarget;
std::string currentTarget;
size_t nodeCount = 0;
int prog = 0;
nod::ExtractionContext ctx = {force, [&](nod::SystemStringView name, float) {
nod::ExtractionContext ctx = {force, [&](std::string_view name, float) {
progress.print(currentTarget, name, prog / (float)nodeCount);
}};
if (doMP3) {
m_workPath.makeDir();
progress.startNewLine();
progress.print(_SYS_STR("Indexing PAKs"), _SYS_STR(""), 0.0);
progress.print("Indexing PAKs", "", 0.0);
m_pakRouter.build(m_paks,
[&progress](float factor) { progress.print(_SYS_STR("Indexing PAKs"), _SYS_STR(""), factor); });
progress.print(_SYS_STR("Indexing PAKs"), _SYS_STR(""), 1.0);
[&progress](float factor) { progress.print("Indexing PAKs", "", factor); });
progress.print("Indexing PAKs", "", 1.0);
progress.startNewLine();
hecl::ProjectPath outPath(m_project.getProjectWorkingPath(), _SYS_STR("out"));
hecl::ProjectPath outPath(m_project.getProjectWorkingPath(), "out");
outPath.makeDir();
disc.getDataPartition()->extractSysFiles(outPath.getAbsolutePath(), ctx);
m_outPath = {outPath, _SYS_STR("files/MP3")};
m_outPath = {outPath, "files/MP3"};
m_outPath.makeDirChain(true);
currentTarget = _SYS_STR("MP3 Root");
progress.print(currentTarget.c_str(), _SYS_STR(""), 0.0);
currentTarget = "MP3 Root";
progress.print(currentTarget.c_str(), "", 0.0);
prog = 0;
nodeCount = m_nonPaks.size();
@ -403,7 +399,7 @@ struct SpecMP3 : SpecBase {
}
ctx.progressCB = nullptr;
progress.print(currentTarget.c_str(), _SYS_STR(""), 1.0);
progress.print(currentTarget.c_str(), "", 1.0);
progress.startNewLine();
hecl::ClientProcess process;
@ -412,13 +408,10 @@ struct SpecMP3 : SpecBase {
if (!pak.m_doExtract)
continue;
auto name = pak.getName();
hecl::SystemStringConv sysName(name);
auto pakName = hecl::SystemString(sysName.sys_str());
auto pakName = std::string(pak.getName());
process.addLambdaTransaction([this, &progress, &pak, pakName, force](hecl::blender::Token& btok) {
m_pakRouter.extractResources(pak, force, btok,
[&progress, &pakName](const hecl::SystemChar* substr, float factor) {
[&progress, &pakName](const char* substr, float factor) {
progress.print(pakName, substr, factor);
});
});
@ -431,20 +424,20 @@ struct SpecMP3 : SpecBase {
m_feWorkPath.makeDir();
progress.startNewLine();
progress.print(_SYS_STR("Indexing PAKs"), _SYS_STR(""), 0.0);
progress.print("Indexing PAKs", "", 0.0);
m_fePakRouter.build(
m_fePaks, [&progress](float factor) { progress.print(_SYS_STR("Indexing PAKs"), _SYS_STR(""), factor); });
progress.print(_SYS_STR("Indexing PAKs"), _SYS_STR(""), 1.0);
m_fePaks, [&progress](float factor) { progress.print("Indexing PAKs", "", factor); });
progress.print("Indexing PAKs", "", 1.0);
progress.startNewLine();
hecl::ProjectPath outPath(m_project.getProjectWorkingPath(), _SYS_STR("out"));
hecl::ProjectPath outPath(m_project.getProjectWorkingPath(), "out");
outPath.makeDir();
disc.getDataPartition()->extractSysFiles(outPath.getAbsolutePath(), ctx);
m_feOutPath = {outPath, _SYS_STR("files/fe")};
m_feOutPath = {outPath, "files/fe"};
m_feOutPath.makeDirChain(true);
currentTarget = _SYS_STR("fe Root");
progress.print(currentTarget.c_str(), _SYS_STR(""), 0.0);
currentTarget = "fe Root";
progress.print(currentTarget.c_str(), "", 0.0);
prog = 0;
nodeCount = m_feNonPaks.size();
@ -453,7 +446,7 @@ struct SpecMP3 : SpecBase {
node->extractToDirectory(m_feOutPath.getAbsolutePath(), ctx);
prog++;
}
progress.print(currentTarget.c_str(), _SYS_STR(""), 1.0);
progress.print(currentTarget.c_str(), "", 1.0);
progress.startNewLine();
hecl::ClientProcess process;
@ -462,13 +455,10 @@ struct SpecMP3 : SpecBase {
if (!pak.m_doExtract)
continue;
auto name = pak.getName();
hecl::SystemStringConv sysName(name);
hecl::SystemString pakName(sysName.sys_str());
std::string pakName(pak.getName());
process.addLambdaTransaction([this, &progress, &pak, pakName, force](hecl::blender::Token& btok) {
m_fePakRouter.extractResources(pak, force, btok,
[&progress, &pakName](const hecl::SystemChar* substr, float factor) {
[&progress, &pakName](const char* substr, float factor) {
progress.print(pakName, substr, factor);
});
});
@ -479,11 +469,11 @@ struct SpecMP3 : SpecBase {
/* Generate Texture Cache containing meta data for every texture file */
if (doMP3) {
hecl::ProjectPath noAramPath(m_workPath, _SYS_STR("URDE"));
hecl::ProjectPath noAramPath(m_workPath, "URDE");
TextureCache::Generate(m_pakRouter, m_project, noAramPath);
}
if (doMPTFE) {
hecl::ProjectPath noAramPath(m_feWorkPath, _SYS_STR("URDE"));
hecl::ProjectPath noAramPath(m_feWorkPath, "URDE");
TextureCache::Generate(m_fePakRouter, m_project, noAramPath);
}
/* Write version data */
@ -503,7 +493,7 @@ struct SpecMP3 : SpecBase {
hecl::ProjectPath getWorking(class UniqueID64& id) override { return m_pakRouter.getWorking(id); }
bool checkPathPrefix(const hecl::ProjectPath& path) const override {
return path.getRelativePath().compare(0, 4, _SYS_STR("MP3/")) == 0;
return path.getRelativePath().compare(0, 4, "MP3/") == 0;
}
bool validateYAMLDNAType(athena::io::IStreamReader& fp) const override {
@ -559,7 +549,7 @@ struct SpecMP3 : SpecBase {
hecl::blender::MapArea mapa = ds.compileMapArea();
ds.close();
DNAMP3::MAPA::Cook(mapa, out);
progress(_SYS_STR("Done"));
progress("Done");
}
void cookMapUniverse(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds,
@ -567,13 +557,13 @@ struct SpecMP3 : SpecBase {
};
hecl::Database::DataSpecEntry SpecEntMP3(
_SYS_STR("MP3"sv), _SYS_STR("Data specification for original Metroid Prime 3 engine"sv), _SYS_STR(".pak"sv),
"MP3"sv, "Data specification for original Metroid Prime 3 engine"sv, ".pak"sv,
[](hecl::Database::Project& project, hecl::Database::DataSpecTool) -> std::unique_ptr<hecl::Database::IDataSpec> {
return std::make_unique<SpecMP3>(&SpecEntMP3, project, false);
});
hecl::Database::DataSpecEntry SpecEntMP3PC = {
_SYS_STR("MP3-PC"sv), _SYS_STR("Data specification for PC-optimized Metroid Prime 3 engine"sv), _SYS_STR(".upak"sv),
"MP3-PC"sv, "Data specification for PC-optimized Metroid Prime 3 engine"sv, ".upak"sv,
[](hecl::Database::Project& project,
hecl::Database::DataSpecTool tool) -> std::unique_ptr<hecl::Database::IDataSpec> {
if (tool != hecl::Database::DataSpecTool::Extract)
@ -582,6 +572,6 @@ hecl::Database::DataSpecEntry SpecEntMP3PC = {
}};
hecl::Database::DataSpecEntry SpecEntMP3ORIG = {
_SYS_STR("MP3-ORIG"sv), _SYS_STR("Data specification for unmodified Metroid Prime 3 resources"sv), {}, {}};
"MP3-ORIG"sv, "Data specification for unmodified Metroid Prime 3 resources"sv, {}, {}};
} // namespace DataSpec

View File

@ -14,6 +14,7 @@
#include "Runtime/Particle/CGenDescription.hpp"
#include "Runtime/World/CPlayer.hpp"
#include <fmt/xchar.h>
#include <zeus/CEulerAngles.hpp>
namespace metaforce {

View File

@ -123,9 +123,9 @@ void CDvdFile::RecursiveBuildCaseInsensitiveMap(const hecl::ProjectPath& path, s
RecursiveBuildCaseInsensitiveMap(hecl::ProjectPath(path, p.m_name), prefixLen);
} else {
hecl::ProjectPath ch(path, p.m_name);
std::string chStr(ch.getAbsolutePathUTF8().begin() + prefixLen, ch.getAbsolutePathUTF8().end());
std::string chStr(ch.getAbsolutePath().begin() + prefixLen, ch.getAbsolutePath().end());
std::string lowerChStr(chStr);
std::transform(lowerChStr.begin(), lowerChStr.end(), lowerChStr.begin(), ::tolower);
hecl::ToLower(lowerChStr);
m_caseInsensitiveMap[lowerChStr] = chStr;
}
}
@ -133,7 +133,7 @@ void CDvdFile::RecursiveBuildCaseInsensitiveMap(const hecl::ProjectPath& path, s
void CDvdFile::Initialize(const hecl::ProjectPath& path) {
m_DvdRoot = path;
RecursiveBuildCaseInsensitiveMap(path, path.getAbsolutePathUTF8().length() + 1);
RecursiveBuildCaseInsensitiveMap(path, path.getAbsolutePath().length() + 1);
if (m_WorkerRun.load()) {
return;
}

View File

@ -44,7 +44,7 @@ u8* CGameAllocator::Alloc(size_t len) {
void CGameAllocator::Free(u8* ptr) {
SChunkDescription* info = reinterpret_cast<SChunkDescription*>(ptr - sizeof(SChunkDescription));
if (info->magic != 0xE8E8E8E8 || info->sentinal != 0xEFEFEFEF) {
AllocLog.report(logvisor::Fatal, FMT_STRING(_SYS_STR("Invalid chunk description, memory corruption!")));
AllocLog.report(logvisor::Fatal, FMT_STRING("Invalid chunk description, memory corruption!"));
return;
}

View File

@ -101,41 +101,41 @@ private:
#endif
};
extern hecl::SystemString ExeDir;
extern std::string ExeDir;
namespace metaforce {
static logvisor::Module Log{"Metaforce"};
std::optional<MP1::CMain> g_mainMP1;
static hecl::SystemString CPUFeatureString(const zeus::CPUInfo& cpuInf) {
hecl::SystemString features;
static std::string CPUFeatureString(const zeus::CPUInfo& cpuInf) {
std::string features;
#if defined(__x86_64__) || defined(_M_X64)
auto AddFeature = [&features](const hecl::SystemChar* str) {
auto AddFeature = [&features](const char* str) {
if (!features.empty())
features += _SYS_STR(", ");
features += ", ";
features += str;
};
if (cpuInf.AESNI)
AddFeature(_SYS_STR("AES-NI"));
AddFeature("AES-NI");
if (cpuInf.SSE1)
AddFeature(_SYS_STR("SSE"));
AddFeature("SSE");
if (cpuInf.SSE2)
AddFeature(_SYS_STR("SSE2"));
AddFeature("SSE2");
if (cpuInf.SSE3)
AddFeature(_SYS_STR("SSE3"));
AddFeature("SSE3");
if (cpuInf.SSSE3)
AddFeature(_SYS_STR("SSSE3"));
AddFeature("SSSE3");
if (cpuInf.SSE4a)
AddFeature(_SYS_STR("SSE4a"));
AddFeature("SSE4a");
if (cpuInf.SSE41)
AddFeature(_SYS_STR("SSE4.1"));
AddFeature("SSE4.1");
if (cpuInf.SSE42)
AddFeature(_SYS_STR("SSE4.2"));
AddFeature("SSE4.2");
if (cpuInf.AVX)
AddFeature(_SYS_STR("AVX"));
AddFeature("AVX");
if (cpuInf.AVX2)
AddFeature(_SYS_STR("AVX2"));
AddFeature("AVX2");
#endif
return features;
}
@ -253,7 +253,7 @@ private:
std::string m_errorString;
boo::ObjToken<boo::ITextureR> m_renderTex;
hecl::SystemString m_deferredProject;
std::string m_deferredProject;
std::unique_ptr<hecl::Database::Project> m_proj;
std::optional<amuse::BooBackendVoiceAllocator> m_amuseAllocWrapper;
std::unique_ptr<boo::IAudioVoiceEngine> m_voiceEngine;
@ -275,7 +275,7 @@ public:
int appMain(boo::IApplication* app) override {
initialize(app);
m_window = app->newWindow(_SYS_STR("Metaforce"sv));
m_window = app->newWindow("Metaforce"sv);
if (!m_window) {
return 1;
}
@ -283,8 +283,7 @@ public:
m_window->showWindow();
boo::IGraphicsDataFactory* gfxF = m_window->getMainContextDataFactory();
m_window->setTitle(
fmt::format(FMT_STRING(_SYS_STR("Metaforce {} [{}]")), METAFORCE_WC_DESCRIBE_SYS, gfxF->platformName()));
m_window->setTitle(fmt::format(FMT_STRING("Metaforce {} [{}]"), METAFORCE_WC_DESCRIBE, gfxF->platformName()));
boo::SWindowRect rect = m_window->getWindowFrame();
m_windowCallback.m_lastRect = rect;
@ -303,26 +302,25 @@ public:
hecl::ProjectPath projectPath;
for (const auto& arg : app->getArgs()) {
hecl::Sstat theStat;
if (!hecl::Stat((arg + _SYS_STR("/out")).c_str(), &theStat) && S_ISDIR(theStat.st_mode)) {
if (!hecl::Stat((arg + "/out").c_str(), &theStat) && S_ISDIR(theStat.st_mode)) {
hecl::ProjectRootPath rootPath(arg);
hecl::Database::Project tmp(rootPath); // Force project creation
}
if (m_deferredProject.empty() && hecl::SearchForProject(arg))
m_deferredProject = arg;
if (arg == _SYS_STR("--no-shader-warmup"))
if (arg == "--no-shader-warmup")
m_noShaderWarmup = true;
else if (arg == _SYS_STR("--no-sound"))
else if (arg == "--no-sound")
m_voiceEngine->setVolume(0.f);
}
if (m_deferredProject.empty()) {
/* Default behavior - search upwards for packaged project containing the program */
if (hecl::ProjectRootPath projRoot = hecl::SearchForProject(ExeDir)) {
hecl::SystemString rootPath(projRoot.getAbsolutePath());
std::string rootPath(projRoot.getAbsolutePath());
hecl::Sstat theStat;
if (hecl::Stat((rootPath + _SYS_STR("/out/files/MP1/Metroid1.upak")).c_str(), &theStat) == 0 &&
S_ISREG(theStat.st_mode))
m_deferredProject = rootPath + _SYS_STR("/out");
if (hecl::Stat((rootPath + "/out/files/MP1/Metroid1.upak").c_str(), &theStat) == 0 && S_ISREG(theStat.st_mode))
m_deferredProject = rootPath + "/out";
}
}
@ -353,10 +351,9 @@ public:
void initialize(boo::IApplication* app) {
zeus::detectCPU();
for (const boo::SystemString& arg : app->getArgs()) {
if (arg.find(_SYS_STR("--verbosity=")) == 0 || arg.find(_SYS_STR("-v=")) == 0) {
hecl::SystemUTF8Conv utf8Arg(arg.substr(arg.find_last_of('=') + 1));
hecl::VerbosityLevel = atoi(utf8Arg.c_str());
for (const auto& arg : app->getArgs()) {
if (arg.find("--verbosity=") == 0 || arg.find("-v=") == 0) {
hecl::VerbosityLevel = atoi(arg.substr(arg.find_last_of('=') + 1).c_str());
hecl::LogModule.report(logvisor::Info, FMT_STRING("Set verbosity level to {}"), hecl::VerbosityLevel);
}
}
@ -364,22 +361,21 @@ public:
const zeus::CPUInfo& cpuInf = zeus::cpuFeatures();
Log.report(logvisor::Info, FMT_STRING("CPU Name: {}"), cpuInf.cpuBrand);
Log.report(logvisor::Info, FMT_STRING("CPU Vendor: {}"), cpuInf.cpuVendor);
Log.report(logvisor::Info, FMT_STRING(_SYS_STR("CPU Features: {}")), CPUFeatureString(cpuInf));
Log.report(logvisor::Info, FMT_STRING("CPU Features: {}"), CPUFeatureString(cpuInf));
}
void onAppIdle() noexcept {
if (!m_deferredProject.empty()) {
hecl::SystemString subPath;
std::string subPath;
hecl::ProjectRootPath projPath = hecl::SearchForProject(m_deferredProject, subPath);
if (projPath) {
m_proj = std::make_unique<hecl::Database::Project>(projPath);
m_deferredProject.clear();
hecl::ProjectPath projectPath{m_proj->getProjectWorkingPath(), _SYS_STR("out/files/MP1")};
hecl::ProjectPath projectPath{m_proj->getProjectWorkingPath(), "out/files/MP1"};
CDvdFile::Initialize(projectPath);
} else {
Log.report(logvisor::Error, FMT_STRING(_SYS_STR("Project doesn't exist at '{}'")), m_deferredProject);
hecl::SystemUTF8Conv conv{m_deferredProject};
m_errorString = fmt::format(FMT_STRING("Project not found at '{}'"), conv.str());
Log.report(logvisor::Error, FMT_STRING("Project doesn't exist at '{}'"), m_deferredProject);
m_errorString = fmt::format(FMT_STRING("Project not found at '{}'"), m_deferredProject);
m_deferredProject.clear();
}
}
@ -433,8 +429,7 @@ public:
}
}
if (!m_imGuiInitialized) {
hecl::SystemUTF8Conv configDir{m_fileMgr.getStoreRoot()};
ImGuiEngine::Initialize(gfxF, m_window.get(), scale, configDir.str());
ImGuiEngine::Initialize(gfxF, m_window.get(), scale, m_fileMgr.getStoreRoot());
m_imGuiInitialized = true;
}
@ -534,17 +529,17 @@ public:
} // namespace metaforce
static hecl::SystemChar CwdBuf[1024];
hecl::SystemString ExeDir;
static char CwdBuf[1024];
std::string ExeDir;
static void SetupBasics(bool logging) {
auto result = zeus::validateCPU();
if (!result.first) {
#if _WIN32 && !WINDOWS_STORE
std::wstring msg =
fmt::format(FMT_STRING(L"ERROR: This build of Metaforce requires the following CPU features:\n{}\n"),
std::string msg =
fmt::format(FMT_STRING("ERROR: This build of Metaforce requires the following CPU features:\n{}\n"),
metaforce::CPUFeatureString(result.second));
MessageBoxW(nullptr, msg.c_str(), L"CPU error", MB_OK | MB_ICONERROR);
MessageBoxW(nullptr, nowide::widen(msg).c_str(), L"CPU error", MB_OK | MB_ICONERROR);
#else
fmt::print(stderr, FMT_STRING("ERROR: This build of Metaforce requires the following CPU features:\n{}\n"),
metaforce::CPUFeatureString(result.second));
@ -558,58 +553,52 @@ static void SetupBasics(bool logging) {
atSetExceptionHandler(AthenaExc);
#if SENTRY_ENABLED
hecl::Runtime::FileStoreManager fileMgr{_SYS_STR("sentry-native-metaforce")};
hecl::SystemUTF8Conv cacheDir{fileMgr.getStoreRoot()};
hecl::Runtime::FileStoreManager fileMgr{"sentry-native-metaforce"};
std::string cacheDir{fileMgr.getStoreRoot()};
logvisor::RegisterSentry("metaforce", METAFORCE_WC_DESCRIBE, cacheDir.c_str());
#endif
}
static bool IsClientLoggingEnabled(int argc, const boo::SystemChar** argv) {
static bool IsClientLoggingEnabled(int argc, char** argv) {
for (int i = 1; i < argc; ++i)
if (!hecl::StrNCmp(argv[i], _SYS_STR("-l"), 2))
if (!hecl::StrNCmp(argv[i], "-l", 2))
return true;
return false;
}
#if !WINDOWS_STORE
#if _WIN32
int wmain(int argc, const boo::SystemChar** argv)
#else
int main(int argc, const boo::SystemChar** argv)
#endif
{
if (argc > 1 && !hecl::StrCmp(argv[1], _SYS_STR("--dlpackage"))) {
int main(int argc, char** argv) {
if (argc > 1 && !hecl::StrCmp(argv[1], "--dlpackage")) {
fmt::print(FMT_STRING("{}\n"), METAFORCE_DLPACKAGE);
return 100;
}
SetupBasics(IsClientLoggingEnabled(argc, argv));
hecl::Runtime::FileStoreManager fileMgr{_SYS_STR("metaforce")};
hecl::Runtime::FileStoreManager fileMgr{"metaforce"};
hecl::CVarManager cvarMgr{fileMgr};
hecl::CVarCommons cvarCmns{cvarMgr};
std::vector<boo::SystemString> args;
std::vector<std::string> args;
for (int i = 1; i < argc; ++i)
args.push_back(argv[i]);
args.emplace_back(argv[i]);
cvarMgr.parseCommandLine(args);
hecl::SystemString logFile{hecl::SystemStringConv(cvarCmns.getLogFile()).c_str()};
hecl::SystemString logFilePath;
std::string logFile = cvarCmns.getLogFile();
std::string logFilePath;
if (!logFile.empty()) {
std::time_t time = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
char buf[100];
std::strftime(buf, 100, "%Y-%m-%d_%H-%M-%S", std::localtime(&time));
hecl::SystemString timeStr = hecl::SystemStringConv(buf).c_str();
logFilePath = fmt::format(FMT_STRING(_SYS_STR("{}/{}-{}")), fileMgr.getStoreRoot(), timeStr, logFile);
logFilePath = fmt::format(FMT_STRING("{}/{}-{}"), fileMgr.getStoreRoot(), buf, logFile);
logvisor::RegisterFileLogger(logFilePath.c_str());
}
if (hecl::SystemChar* cwd = hecl::Getcwd(CwdBuf, 1024)) {
if (char* cwd = hecl::Getcwd(CwdBuf, 1024)) {
if (hecl::PathRelative(argv[0]))
ExeDir = hecl::SystemString(cwd) + _SYS_STR('/');
hecl::SystemString Argv0(argv[0]);
hecl::SystemString::size_type lastIdx = Argv0.find_last_of(_SYS_STR("/\\"));
if (lastIdx != hecl::SystemString::npos)
ExeDir = std::string(cwd) + '/';
std::string Argv0(argv[0]);
std::string::size_type lastIdx = Argv0.find_last_of("/\\");
if (lastIdx != std::string::npos)
ExeDir.insert(ExeDir.end(), Argv0.begin(), Argv0.begin() + lastIdx);
}
@ -617,9 +606,9 @@ int main(int argc, const boo::SystemChar** argv)
hecl::SetCpuCountOverride(argc, argv);
metaforce::Application appCb(fileMgr, cvarMgr, cvarCmns);
int ret = boo::ApplicationRun(boo::IApplication::EPlatformType::Auto, appCb, _SYS_STR("metaforce"),
_SYS_STR("Metaforce"), argc, argv, appCb.getGraphicsApi(), appCb.getSamples(),
appCb.getAnisotropy(), appCb.getDeepColor(), false);
int ret = boo::ApplicationRun(boo::IApplication::EPlatformType::Auto, appCb, "metaforce", "Metaforce", argv[0], args,
appCb.getGraphicsApi(), appCb.getSamples(), appCb.getAnisotropy(), appCb.getDeepColor(),
false);
return ret;
}
#endif
@ -631,30 +620,22 @@ using namespace Windows::ApplicationModel::Core;
[Platform::MTAThread] int WINAPIV main(Platform::Array<Platform::String ^> ^ params) {
SetupBasics(false);
metaforce::Application appCb;
auto viewProvider = ref new boo::ViewProvider(appCb, _SYS_STR("metaforce"), _SYS_STR("Metaforce"),
_SYS_STR("metaforce"), params, false);
auto viewProvider = ref new boo::ViewProvider(appCb, "metaforce", "Metaforce", "metaforce", params, false);
CoreApplication::Run(viewProvider);
return 0;
}
#elif _WIN32
#include <shellapi.h>
#include <nowide/args.hpp>
int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR lpCmdLine, int) {
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR lpCmdLine, int) {
int argc = 0;
const boo::SystemChar** argv;
if (lpCmdLine[0])
argv = (const wchar_t**)(CommandLineToArgvW(lpCmdLine, &argc));
static boo::SystemChar selfPath[1024];
GetModuleFileNameW(nullptr, selfPath, 1024);
static const boo::SystemChar* booArgv[32] = {};
booArgv[0] = selfPath;
for (int i = 0; i < argc; ++i)
booArgv[i + 1] = argv[i];
char** argv = nullptr;
nowide::args _(argc, argv);
const DWORD outType = GetFileType(GetStdHandle(STD_ERROR_HANDLE));
if (IsClientLoggingEnabled(argc + 1, booArgv) && outType == FILE_TYPE_UNKNOWN)
if (IsClientLoggingEnabled(argc, argv) && outType == FILE_TYPE_UNKNOWN)
logvisor::CreateWin32Console();
return wmain(argc + 1, booArgv);
return main(argc, argv);
}
#endif

View File

@ -13,7 +13,7 @@ namespace metaforce {
namespace {
using ECardResult = kabufuda::ECardResult;
static kabufuda::SystemString g_CardImagePaths[2] = {};
static std::string g_CardImagePaths[2] = {};
static kabufuda::Card g_CardStates[2] = {kabufuda::Card{"GM8E", "01"}, kabufuda::Card{"GM8E", "01"}};
// static kabufuda::ECardResult g_OpResults[2] = {};
hecl::CVar* mc_dolphinAPath = nullptr;
@ -336,24 +336,16 @@ ECardResult CMemoryCardSys::CCardFileInfo::WriteFile() {
}
ECardResult CMemoryCardSys::CCardFileInfo::CloseFile() { return CMemoryCardSys::CloseFile(m_handle); }
kabufuda::SystemString CMemoryCardSys::_GetDolphinCardPath(kabufuda::ECardSlot slot) {
std::string CMemoryCardSys::_GetDolphinCardPath(kabufuda::ECardSlot slot) {
return g_CardImagePaths[static_cast<u32>(slot)];
}
void CMemoryCardSys::_ResolveDolphinCardPath(const hecl::CVar* cv, kabufuda::ECardSlot slot) {
#if CARD_UCS2
if (cv != nullptr && cv->toWideLiteral().empty()) {
g_CardImagePaths[int(slot)] = ResolveDolphinCardPath(slot);
} else if (cv != nullptr) {
g_CardImagePaths[int(slot)] = cv->toWideLiteral();
}
#else
if (cv != nullptr && cv->toLiteral().empty()) {
g_CardImagePaths[int(slot)] = ResolveDolphinCardPath(slot);
} else if (cv != nullptr) {
g_CardImagePaths[int(slot)] = cv->toLiteral();
}
#endif
}
kabufuda::ProbeResults CMemoryCardSys::CardProbe(kabufuda::ECardSlot port) {
@ -563,7 +555,7 @@ void CMemoryCardSys::CommitToDisk(kabufuda::ECardSlot port) {
}
bool CMemoryCardSys::CreateDolphinCard(kabufuda::ECardSlot slot) {
kabufuda::SystemString path =
std::string path =
_CreateDolphinCard(slot, slot == kabufuda::ECardSlot::SlotA ? mc_dolphinAPath->hasDefaultValue()
: mc_dolphinBPath->hasDefaultValue());
if (CardProbe(slot).x0_error != ECardResult::READY) {

View File

@ -69,10 +69,10 @@ class CMemoryCardSys {
public:
static void _ResetCVar(kabufuda::ECardSlot slot);
static void _ResolveDolphinCardPath(const hecl::CVar* cv, kabufuda::ECardSlot slot);
static kabufuda::SystemString ResolveDolphinCardPath(kabufuda::ECardSlot slot);
static std::string ResolveDolphinCardPath(kabufuda::ECardSlot slot);
static bool CreateDolphinCard(kabufuda::ECardSlot slot);
static kabufuda::SystemString _GetDolphinCardPath(kabufuda::ECardSlot slot);
static kabufuda::SystemString _CreateDolphinCard(kabufuda::ECardSlot slot, bool dolphin);
static std::string _GetDolphinCardPath(kabufuda::ECardSlot slot);
static std::string _CreateDolphinCard(kabufuda::ECardSlot slot, bool dolphin);
using ECardResult = kabufuda::ECardResult;
struct CardResult {

View File

@ -4,7 +4,7 @@
namespace metaforce {
kabufuda::SystemString CMemoryCardSys::ResolveDolphinCardPath(kabufuda::ECardSlot slot) {
std::string CMemoryCardSys::ResolveDolphinCardPath(kabufuda::ECardSlot slot) {
if (g_Main->IsUSA() && !g_Main->IsTrilogy()) {
const char* home = getenv("HOME");
if (!home || home[0] != '/')
@ -12,8 +12,8 @@ kabufuda::SystemString CMemoryCardSys::ResolveDolphinCardPath(kabufuda::ECardSlo
const char* dataHome = getenv("XDG_DATA_HOME");
/* XDG-selected data path */
kabufuda::SystemString path =
((dataHome && dataHome[0] == '/') ? dataHome : hecl::SystemString(home)) + "/.local/share/dolphin-emu";
std::string path =
((dataHome && dataHome[0] == '/') ? dataHome : std::string(home)) + "/.local/share/dolphin-emu";
path += fmt::format(FMT_STRING("/GC/MemoryCard{:c}.USA.raw"), slot == kabufuda::ECardSlot::SlotA ? 'A' : 'B');
hecl::Sstat theStat;
@ -31,7 +31,7 @@ kabufuda::SystemString CMemoryCardSys::ResolveDolphinCardPath(kabufuda::ECardSlo
return {};
}
kabufuda::SystemString CMemoryCardSys::_CreateDolphinCard(kabufuda::ECardSlot slot, bool dolphin) {
std::string CMemoryCardSys::_CreateDolphinCard(kabufuda::ECardSlot slot, bool dolphin) {
if (g_Main->IsUSA() && !g_Main->IsTrilogy()) {
if (dolphin) {
const char* home = getenv("HOME");
@ -40,8 +40,8 @@ kabufuda::SystemString CMemoryCardSys::_CreateDolphinCard(kabufuda::ECardSlot sl
const char* dataHome = getenv("XDG_DATA_HOME");
/* XDG-selected data path */
kabufuda::SystemString path =
((dataHome && dataHome[0] == '/') ? dataHome : hecl::SystemString(home)) + "/.local/share/dolphin-emu/GC";
std::string path =
((dataHome && dataHome[0] == '/') ? dataHome : std::string(home)) + "/.local/share/dolphin-emu/GC";
if (hecl::RecursiveMakeDir(path.c_str()) < 0)
return {};
@ -52,12 +52,12 @@ kabufuda::SystemString CMemoryCardSys::_CreateDolphinCard(kabufuda::ECardSlot sl
return path;
}
} else {
kabufuda::SystemString path = _GetDolphinCardPath(slot);
std::string path = _GetDolphinCardPath(slot);
hecl::SanitizePath(path);
if (path.find('/') == kabufuda::SystemString::npos) {
path = hecl::GetcwdStr() + _SYS_STR("/") + _GetDolphinCardPath(slot);
if (path.find('/') == std::string::npos) {
path = hecl::GetcwdStr() + "/" + _GetDolphinCardPath(slot);
}
hecl::SystemString tmpPath = path.substr(0, path.find_last_of(_SYS_STR("/")));
std::string tmpPath = path.substr(0, path.find_last_of("/"));
hecl::RecursiveMakeDir(tmpPath.c_str());
const auto fp = hecl::FopenUnique(path.c_str(), "wb");
if (fp) {

View File

@ -3,13 +3,13 @@
#include "Runtime/IMain.hpp"
namespace metaforce {
kabufuda::SystemString CMemoryCardSys::ResolveDolphinCardPath(kabufuda::ECardSlot slot) {
std::string CMemoryCardSys::ResolveDolphinCardPath(kabufuda::ECardSlot slot) {
if (g_Main->IsUSA() && !g_Main->IsTrilogy()) {
const char* home = getenv("HOME");
if (!home)
return {};
kabufuda::SystemString path = home;
std::string path = home;
path += fmt::format(FMT_STRING("/Library/Application Support/Dolphin/GC/MemoryCard{:c}.USA.raw"),
slot == kabufuda::ECardSlot::SlotA ? 'A' : 'B');
@ -22,14 +22,14 @@ kabufuda::SystemString CMemoryCardSys::ResolveDolphinCardPath(kabufuda::ECardSlo
return {};
}
kabufuda::SystemString CMemoryCardSys::_CreateDolphinCard(kabufuda::ECardSlot slot, bool dolphin) {
std::string CMemoryCardSys::_CreateDolphinCard(kabufuda::ECardSlot slot, bool dolphin) {
if (g_Main->IsUSA() && !g_Main->IsTrilogy()) {
if (dolphin) {
const char* home = getenv("HOME");
if (!home)
return {};
kabufuda::SystemString path = home;
std::string path = home;
path += "/Library/Application Support/Dolphin/GC";
if (hecl::RecursiveMakeDir(path.c_str()) < 0)
return {};
@ -42,12 +42,12 @@ kabufuda::SystemString CMemoryCardSys::_CreateDolphinCard(kabufuda::ECardSlot sl
return path;
} else {
kabufuda::SystemString path = _GetDolphinCardPath(slot);
std::string path = _GetDolphinCardPath(slot);
hecl::SanitizePath(path);
if (path.find('/') == kabufuda::SystemString::npos) {
path = hecl::GetcwdStr() + _SYS_STR("/") + _GetDolphinCardPath(slot);
if (path.find('/') == std::string::npos) {
path = hecl::GetcwdStr() + "/" + _GetDolphinCardPath(slot);
}
hecl::SystemString tmpPath = path.substr(0, path.find_last_of(_SYS_STR("/")));
std::string tmpPath = path.substr(0, path.find_last_of("/"));
hecl::RecursiveMakeDir(tmpPath.c_str());
const auto fp = hecl::FopenUnique(path.c_str(), "wb");
if (fp) {

View File

@ -14,7 +14,7 @@ using namespace Windows::Storage;
/* Partial path-selection logic from
* https://github.com/dolphin-emu/dolphin/blob/master/Source/Core/UICommon/UICommon.cpp
* Modified to not use dolphin-binary-relative paths. */
kabufuda::SystemString CMemoryCardSys::ResolveDolphinCardPath(kabufuda::ECardSlot slot) {
std::string CMemoryCardSys::ResolveDolphinCardPath(kabufuda::ECardSlot slot) {
if (g_Main->IsUSA() && !g_Main->IsTrilogy()) {
#if !WINDOWS_STORE
/* Detect where the User directory is. There are two different cases
@ -26,35 +26,32 @@ kabufuda::SystemString CMemoryCardSys::ResolveDolphinCardPath(kabufuda::ECardSlo
/* Check our registry keys */
HKEY hkey;
kabufuda::SystemChar configPath[MAX_PATH] = {0};
if (RegOpenKeyEx(HKEY_CURRENT_USER, _SYS_STR("Software\\Dolphin Emulator"), 0, KEY_QUERY_VALUE, &hkey) ==
ERROR_SUCCESS) {
wchar_t configPath[MAX_PATH] = {0};
if (RegOpenKeyEx(HKEY_CURRENT_USER, L"Software\\Dolphin Emulator", 0, KEY_QUERY_VALUE, &hkey) == ERROR_SUCCESS) {
DWORD size = MAX_PATH;
if (RegQueryValueEx(hkey, _SYS_STR("UserConfigPath"), nullptr, nullptr, (LPBYTE)configPath, &size) !=
ERROR_SUCCESS)
if (RegQueryValueEx(hkey, L"UserConfigPath", nullptr, nullptr, (LPBYTE)configPath, &size) != ERROR_SUCCESS)
configPath[0] = 0;
RegCloseKey(hkey);
}
/* Get My Documents path in case we need it. */
kabufuda::SystemChar my_documents[MAX_PATH];
wchar_t my_documents[MAX_PATH];
bool my_documents_found =
SUCCEEDED(SHGetFolderPath(nullptr, CSIDL_MYDOCUMENTS, nullptr, SHGFP_TYPE_CURRENT, my_documents));
kabufuda::SystemString path;
std::string path;
if (configPath[0]) /* Case 1 */
path = configPath;
path = nowide::narrow(configPath);
else if (my_documents_found) /* Case 2 */
path = kabufuda::SystemString(my_documents) + _SYS_STR("/Dolphin Emulator");
path = nowide::narrow(my_documents) + "/Dolphin Emulator";
else /* Unable to find */
return {};
#else
StorageFolder ^ localFolder = ApplicationData::Current->LocalFolder;
kabufuda::SystemString path(localFolder->Path->Data());
std::string path(localFolder->Path->Data());
#endif
path += fmt::format(FMT_STRING(_SYS_STR("/GC/MemoryCard{}.USA.raw")),
slot == kabufuda::ECardSlot::SlotA ? _SYS_STR('A') : _SYS_STR('B'));
path += fmt::format(FMT_STRING("/GC/MemoryCard{}.USA.raw"), slot == kabufuda::ECardSlot::SlotA ? 'A' : 'B');
hecl::Sstat theStat;
if (hecl::Stat(path.c_str(), &theStat) || !S_ISREG(theStat.st_mode))
@ -65,7 +62,7 @@ kabufuda::SystemString CMemoryCardSys::ResolveDolphinCardPath(kabufuda::ECardSlo
return {};
}
kabufuda::SystemString CMemoryCardSys::_CreateDolphinCard(kabufuda::ECardSlot slot, bool dolphin) {
std::string CMemoryCardSys::_CreateDolphinCard(kabufuda::ECardSlot slot, bool dolphin) {
if (g_Main->IsUSA() && !g_Main->IsTrilogy()) {
if (dolphin) {
#if !WINDOWS_STORE
@ -78,54 +75,51 @@ kabufuda::SystemString CMemoryCardSys::_CreateDolphinCard(kabufuda::ECardSlot sl
/* Check our registry keys */
HKEY hkey;
kabufuda::SystemChar configPath[MAX_PATH] = {0};
if (RegOpenKeyEx(HKEY_CURRENT_USER, _SYS_STR("Software\\Dolphin Emulator"), 0, KEY_QUERY_VALUE, &hkey) ==
ERROR_SUCCESS) {
wchar_t configPath[MAX_PATH] = {0};
if (RegOpenKeyEx(HKEY_CURRENT_USER, L"Software\\Dolphin Emulator", 0, KEY_QUERY_VALUE, &hkey) == ERROR_SUCCESS) {
DWORD size = MAX_PATH;
if (RegQueryValueEx(hkey, _SYS_STR("UserConfigPath"), nullptr, nullptr, (LPBYTE)configPath, &size) !=
ERROR_SUCCESS)
if (RegQueryValueEx(hkey, L"UserConfigPath", nullptr, nullptr, (LPBYTE)configPath, &size) != ERROR_SUCCESS)
configPath[0] = 0;
RegCloseKey(hkey);
}
/* Get My Documents path in case we need it. */
kabufuda::SystemChar my_documents[MAX_PATH];
wchar_t my_documents[MAX_PATH];
bool my_documents_found =
SUCCEEDED(SHGetFolderPath(nullptr, CSIDL_MYDOCUMENTS, nullptr, SHGFP_TYPE_CURRENT, my_documents));
kabufuda::SystemString path;
std::string path;
if (configPath[0]) /* Case 1 */
path = configPath;
path = nowide::narrow(configPath);
else if (my_documents_found) /* Case 2 */
path = kabufuda::SystemString(my_documents) + _SYS_STR("/Dolphin Emulator");
path = nowide::narrow(my_documents) + "/Dolphin Emulator";
else /* Unable to find */
return {};
#else
StorageFolder ^ localFolder = ApplicationData::Current->LocalFolder;
kabufuda::SystemString path(localFolder->Path->Data());
std::string path(localFolder->Path->Data());
#endif
path += _SYS_STR("/GC");
path += "/GC";
if (hecl::RecursiveMakeDir(path.c_str()) < 0)
return {};
path += fmt::format(FMT_STRING(_SYS_STR("/MemoryCard{}.USA.raw")),
slot == kabufuda::ECardSlot::SlotA ? _SYS_STR('A') : _SYS_STR('B'));
const auto fp = hecl::FopenUnique(path.c_str(), _SYS_STR("wb"));
path += fmt::format(FMT_STRING("/MemoryCard{}.USA.raw"), slot == kabufuda::ECardSlot::SlotA ? 'A' : 'B');
const auto fp = hecl::FopenUnique(path.c_str(), "wb");
if (fp == nullptr) {
return {};
}
return path;
} else {
kabufuda::SystemString path = _GetDolphinCardPath(slot);
std::string path = _GetDolphinCardPath(slot);
hecl::SanitizePath(path);
if (path.find('/') == kabufuda::SystemString::npos) {
path = hecl::GetcwdStr() + _SYS_STR("/") + _GetDolphinCardPath(slot);
if (path.find('/') == std::string::npos) {
path = hecl::GetcwdStr() + "/" + _GetDolphinCardPath(slot);
}
hecl::SystemString tmpPath = path.substr(0, path.find_last_of(_SYS_STR("/")));
std::string tmpPath = path.substr(0, path.find_last_of("/"));
hecl::RecursiveMakeDir(tmpPath.c_str());
const auto fp = hecl::FopenUnique(path.c_str(), _SYS_STR("wb"));
const auto fp = hecl::FopenUnique(path.c_str(), "wb");
if (fp) {
return path;
}

View File

@ -466,7 +466,7 @@ boo::IGraphicsDataFactory::Platform CGraphics::g_BooPlatform = boo::IGraphicsDat
boo::IGraphicsDataFactory* CGraphics::g_BooFactory = nullptr;
boo::IGraphicsCommandQueue* CGraphics::g_BooMainCommandQueue = nullptr;
boo::ObjToken<boo::ITextureR> CGraphics::g_SpareTexture;
const boo::SystemChar* CGraphics::g_BooPlatformName = nullptr;
const char* CGraphics::g_BooPlatformName = nullptr;
const CTevCombiners::CTevPass CGraphics::sTevPass805a564c({GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_ZERO,
GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_RASC},

View File

@ -322,7 +322,7 @@ public:
static void UpdateFPSCounter();
static boo::IGraphicsDataFactory::Platform g_BooPlatform;
static const boo::SystemChar* g_BooPlatformName;
static const char* g_BooPlatformName;
static boo::IGraphicsDataFactory* g_BooFactory;
static boo::IGraphicsCommandQueue* g_BooMainCommandQueue;
static boo::ObjToken<boo::ITextureR> g_SpareTexture;
@ -344,7 +344,7 @@ public:
g_SpareTexture.reset();
}
static const boo::SystemChar* PlatformName() { return g_BooPlatformName; }
static const char* PlatformName() { return g_BooPlatformName; }
static void CommitResources(const boo::FactoryCommitFunc& commitFunc __BooTraceArgs) {
g_BooFactory->commitTransaction(commitFunc __BooTraceArgsUse);

View File

@ -25,7 +25,7 @@ CLineRenderer::CLineRenderer(boo::IGraphicsDataFactory::Context& ctx, EPrimitive
: m_mode(mode), m_maxVerts(maxVerts) {
OPTICK_EVENT();
if (maxVerts < 2) {
LineRendererLog.report(logvisor::Fatal, FMT_STRING(_SYS_STR("maxVerts < 2, maxVerts = {}")), maxVerts);
LineRendererLog.report(logvisor::Fatal, FMT_STRING("maxVerts < 2, maxVerts = {}"), maxVerts);
return;
}
m_textured = bool(texture);
@ -57,7 +57,7 @@ CLineRenderer::CLineRenderer(EPrimitiveMode mode, u32 maxVerts, const boo::ObjTo
: m_mode(mode), m_maxVerts(maxVerts) {
OPTICK_EVENT();
if (maxVerts < 2) {
LineRendererLog.report(logvisor::Fatal, FMT_STRING(_SYS_STR("maxVerts < 2, maxVerts = {}")), maxVerts);
LineRendererLog.report(logvisor::Fatal, FMT_STRING("maxVerts < 2, maxVerts = {}"), maxVerts);
return;
}
m_textured = bool(texture);

View File

@ -16,7 +16,7 @@ private:
bool x18_26_;
bool x18_27_;
bool x18_28_;
const wchar_t* x1c_msg;
const char16_t* x1c_msg;
public:
explicit CErrorOutputWindow(bool);

View File

@ -1,5 +1,7 @@
#include "Runtime/GuiSys/CGuiTextSupport.hpp"
#include <fmt/xchar.h>
#include "Runtime/CSimplePool.hpp"
#include "Runtime/Graphics/CGraphics.hpp"
#include "Runtime/Graphics/CGraphicsPalette.hpp"

View File

@ -52,7 +52,7 @@ s32 CTextParser::ParseInt(const char16_t* str, int len, bool signVal) {
int val = 0;
while (len > procCur) {
val *= 10;
wchar_t ch = str[procCur];
char16_t ch = str[procCur];
val += ch - u'0';
++procCur;
}

View File

@ -40,7 +40,7 @@ public:
Command x4_command;
u16 x8_xPos;
u16 xa_zPos;
wchar_t xc_glyph;
char16_t xc_glyph;
u8 xe_imageIndex;
};
#endif

View File

@ -8,13 +8,13 @@
namespace metaforce {
namespace {
struct CCharacterIdentifier {
wchar_t chr;
char16_t chr;
u32 rank;
};
constexpr std::array<CCharacterIdentifier, 63> sCantBeginChars{{
{L'!', 1}, {L')', 1}, {L',', 1}, {L'-', 1}, {L'.', 1}, {L':', 1}, {L';', 1}, {L'?', 1}, {L']', 1},
{L'}', 1}, {0x92, 1}, {0x94, 1}, {0xBB, 1}, {0x3001, 1}, {0x3002, 1}, {0x3005, 1}, {0x300D, 1}, {0x300F, 1},
{u'!', 1}, {u')', 1}, {u',', 1}, {u'-', 1}, {u'.', 1}, {u':', 1}, {u';', 1}, {u'?', 1}, {u']', 1},
{u'}', 1}, {0x92, 1}, {0x94, 1}, {0xBB, 1}, {0x3001, 1}, {0x3002, 1}, {0x3005, 1}, {0x300D, 1}, {0x300F, 1},
{0x3011, 1}, {0x3015, 1}, {0x3017, 1}, {0x3019, 1}, {0x301B, 1}, {0x301C, 3}, {0x301E, 1}, {0x302B, 3}, {0x3041, 2},
{0x3043, 2}, {0x3045, 2}, {0x3047, 2}, {0x3049, 2}, {0x3063, 2}, {0x3083, 2}, {0x3085, 2}, {0x3087, 2}, {0x308E, 2},
{0x309D, 3}, {0x309E, 3}, {0x30A1, 2}, {0x30A3, 2}, {0x30A5, 2}, {0x30A7, 2}, {0x30A9, 2}, {0x30C3, 2}, {0x30E3, 2},
@ -23,12 +23,12 @@ constexpr std::array<CCharacterIdentifier, 63> sCantBeginChars{{
}};
constexpr std::array<CCharacterIdentifier, 87> sCantEndChars{{
{L'#', 2}, {L'$', 2}, {L'(', 1}, {L'@', 2}, {L'B', 4}, {L'C', 4}, {L'D', 4}, {L'E', 4}, {L'F', 4},
{L'G', 4}, {L'J', 4}, {L'K', 4}, {L'L', 4}, {L'M', 4}, {L'N', 4}, {L'P', 4}, {L'Q', 4}, {L'R', 4},
{L'S', 4}, {L'T', 4}, {L'V', 4}, {L'W', 4}, {L'X', 4}, {L'Y', 4}, {L'Z', 4}, {L'b', 4}, {L'c', 4},
{L'd', 4}, {L'f', 4}, {L'g', 4}, {L'h', 4}, {L'j', 4}, {L'k', 4}, {L'l', 4}, {L'm', 4}, {L'n', 4},
{L'p', 4}, {L'q', 4}, {L'r', 4}, {L's', 4}, {L't', 4}, {L'v', 4}, {L'w', 4}, {L'x', 4}, {L'y', 4},
{L'z', 4}, {0xD1, 4}, {0xF1, 4}, {L'[', 1}, {L'{', 1}, {0x91, 1}, {0x93, 1}, {0xA2, 2}, {0xA3, 2},
{u'#', 2}, {u'$', 2}, {u'(', 1}, {u'@', 2}, {u'B', 4}, {u'C', 4}, {u'D', 4}, {u'E', 4}, {u'F', 4},
{u'G', 4}, {u'J', 4}, {u'K', 4}, {u'L', 4}, {u'M', 4}, {u'N', 4}, {u'P', 4}, {u'Q', 4}, {u'R', 4},
{u'S', 4}, {u'T', 4}, {u'V', 4}, {u'W', 4}, {u'X', 4}, {u'Y', 4}, {u'Z', 4}, {u'b', 4}, {u'c', 4},
{u'd', 4}, {u'f', 4}, {u'g', 4}, {u'h', 4}, {u'j', 4}, {u'k', 4}, {u'l', 4}, {u'm', 4}, {u'n', 4},
{u'p', 4}, {u'q', 4}, {u'r', 4}, {u's', 4}, {u't', 4}, {u'v', 4}, {u'w', 4}, {u'x', 4}, {u'y', 4},
{u'z', 4}, {0xD1, 4}, {0xF1, 4}, {u'[', 1}, {u'{', 1}, {0x91, 1}, {0x93, 1}, {0xA2, 2}, {0xA3, 2},
{0xA5, 2}, {0xA7, 2}, {0xA9, 2}, {0xAB, 1}, {0x20A0, 2}, {0x20A1, 2}, {0x20A2, 2}, {0x20A3, 2}, {0x20A4, 2},
{0x20A5, 2}, {0x20A6, 2}, {0x20A7, 2}, {0x20A8, 2}, {0x20A9, 2}, {0x20AA, 2}, {0x20AB, 2}, {0x20AC, 2}, {0x300C, 1},
{0x300E, 1}, {0x3010, 1}, {0x3012, 2}, {0x3014, 1}, {0x3016, 1}, {0x3018, 1}, {0x301A, 1}, {0xFF03, 2}, {0xFF04, 2},
@ -36,7 +36,7 @@ constexpr std::array<CCharacterIdentifier, 87> sCantEndChars{{
}};
} // Anonymous namespace
int CWordBreakTables::GetBeginRank(wchar_t ch) {
int CWordBreakTables::GetBeginRank(char16_t ch) {
const auto search = rstl::binary_find(sCantBeginChars.cbegin(), sCantBeginChars.cend(), ch,
[](const CCharacterIdentifier& item) { return item.chr; });
if (search == sCantBeginChars.cend()) {
@ -45,7 +45,7 @@ int CWordBreakTables::GetBeginRank(wchar_t ch) {
return search->rank;
}
int CWordBreakTables::GetEndRank(wchar_t ch) {
int CWordBreakTables::GetEndRank(char16_t ch) {
const auto search = rstl::binary_find(sCantEndChars.cbegin(), sCantEndChars.cend(), ch,
[](const CCharacterIdentifier& item) { return item.chr; });
if (search == sCantEndChars.cend()) {

View File

@ -4,8 +4,8 @@ namespace metaforce {
class CWordBreakTables {
public:
static int GetBeginRank(wchar_t ch);
static int GetEndRank(wchar_t ch);
static int GetBeginRank(char16_t ch);
static int GetEndRank(char16_t ch);
};
} // namespace metaforce

View File

@ -7,7 +7,7 @@ namespace metaforce {
struct CKeyboardMouseControllerData {
std::array<bool, 256> m_charKeys{};
std::array<bool, 26> m_specialKeys{};
std::array<bool, static_cast<size_t>(boo::ESpecialKey::MAX)> m_specialKeys{};
std::array<bool, 6> m_mouseButtons{};
boo::EModifierKey m_modMask = boo::EModifierKey::None;
boo::SWindowCoord m_mouseCoord;

View File

@ -3,6 +3,7 @@
#include <algorithm>
#include <array>
#include <ctime>
#include <fmt/xchar.h>
#include "NESEmulator/CNESEmulator.hpp"

View File

@ -1,6 +1,7 @@
#include "Runtime/MP1/CPauseScreenBase.hpp"
#include <array>
#include <fmt/xchar.h>
#include "Runtime/CGameState.hpp"
#include "Runtime/GameGlobalObjects.hpp"

View File

@ -799,22 +799,19 @@ void CMain::Init(const hecl::Runtime::FileStoreManager& storeMgr, hecl::CVarMana
MainLog.report(logvisor::Level::Fatal,
FMT_STRING("Attempted to initialize URDE in MP1 mode with non-MP1 data!!!!"));
}
hecl::SystemStringConv conv(GetVersionString());
boo::SystemStringView versionView(conv.sys_str());
MainLog.report(logvisor::Level::Info,
FMT_STRING(_SYS_STR("Loading data from Metroid Prime version {} from region {}{}")), versionView,
boo::SystemChar(GetRegion()), IsTrilogy() ? _SYS_STR(" from trilogy") : _SYS_STR(""));
MainLog.report(logvisor::Level::Info, FMT_STRING("Loading data from Metroid Prime version {} from region {}{}"),
GetVersionString(), GetRegion(), IsTrilogy() ? " from trilogy" : "");
} else {
MainLog.report(logvisor::Level::Fatal, FMT_STRING("Unable to load version info"));
}
const auto& args = boo::APP->getArgs();
for (auto it = args.begin(); it != args.end(); ++it) {
if (*it == _SYS_STR("--warp") && args.end() - it >= 3) {
const hecl::SystemChar* worldIdxStr = (*(it + 1)).c_str();
const hecl::SystemChar* areaIdxStr = (*(it + 2)).c_str();
if (*it == "--warp" && args.end() - it >= 3) {
const char* worldIdxStr = (*(it + 1)).c_str();
const char* areaIdxStr = (*(it + 2)).c_str();
hecl::SystemChar* endptr = nullptr;
char* endptr = nullptr;
m_warpWorldIdx = TAreaId(hecl::StrToUl(worldIdxStr, &endptr, 0));
if (endptr == worldIdxStr) {
m_warpWorldIdx = 0;
@ -838,13 +835,13 @@ void CMain::Init(const hecl::Runtime::FileStoreManager& storeMgr, hecl::CVarMana
}
while (args.end() - it >= 4) {
const hecl::SystemChar* layerStr = (*(it + 3)).c_str();
if (!(layerStr[0] == _SYS_STR('0') && layerStr[1] == _SYS_STR('x')) &&
(layerStr[0] == _SYS_STR('0') || layerStr[0] == _SYS_STR('1'))) {
for (const auto* cur = layerStr; *cur != _SYS_STR('\0'); ++cur)
if (*cur == _SYS_STR('1'))
const char* layerStr = (*(it + 3)).c_str();
if (!(layerStr[0] == '0' && layerStr[1] == 'x') &&
(layerStr[0] == '0' || layerStr[0] == '1')) {
for (const auto* cur = layerStr; *cur != '\0'; ++cur)
if (*cur == '1')
m_warpLayerBits |= u64(1) << (cur - layerStr);
} else if (layerStr[0] == _SYS_STR('0') && layerStr[1] == _SYS_STR('x')) {
} else if (layerStr[0] == '0' && layerStr[1] == 'x') {
m_warpMemoryRelays.emplace_back(TAreaId(hecl::StrToUl(layerStr + 2, nullptr, 16)));
}
++it;
@ -1014,7 +1011,7 @@ void CMain::Shutdown() {
boo::IWindow* CMain::GetMainWindow() const { return m_mainWindow; }
#if 0
int CMain::RsMain(int argc, boo::SystemChar** argv, boo::IAudioVoiceEngine* voiceEngine,
int CMain::RsMain(int argc, char** argv, boo::IAudioVoiceEngine* voiceEngine,
amuse::IBackendVoiceAllocator& backend) {
// PPCSetFpIEEEMode();
// uVar21 = OSGetTime();
@ -1048,7 +1045,7 @@ int CMain::RsMain(int argc, boo::SystemChar** argv, boo::IAudioVoiceEngine* voic
int CMain::appMain(boo::IApplication* app) {
zeus::detectCPU();
mainWindow = app->newWindow(_SYS_STR("Metroid Prime 1 Reimplementation vZygote"), 1);
mainWindow = app->newWindow("Metroid Prime 1 Reimplementation vZygote", 1);
mainWindow->showWindow();
TOneStatic<CGameGlobalObjects> globalObjs;
InitializeSubsystems();

View File

@ -280,7 +280,7 @@ public:
static void UpdateDiscordPresence(CAssetId worldSTRG = {});
// int RsMain(int argc, boo::SystemChar** argv, boo::IAudioVoiceEngine* voiceEngine, amuse::IBackendVoiceAllocator&
// int RsMain(int argc, char** argv, boo::IAudioVoiceEngine* voiceEngine, amuse::IBackendVoiceAllocator&
// backend);
void Init(const hecl::Runtime::FileStoreManager& storeMgr, hecl::CVarManager* cvarManager, boo::IWindow* window,
boo::IAudioVoiceEngine* voiceEngine, amuse::IBackendVoiceAllocator& backend) override;

View File

@ -1,6 +1,5 @@
add_executable(mkwmicon mkwmicon.c)
target_link_libraries(mkwmicon ${PNG_LIBRARIES} ${ZLIB_LIBRARIES})
target_include_directories(mkwmicon PRIVATE ${PNG_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR})
macro(declare_wmicon_target)
add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/Runtime/platforms/freedesktop/mainicon_netwm.bin

View File

@ -25,12 +25,9 @@
#define NOMINMAX
#endif
#include <Windows.h>
#include <cwchar>
#include <nowide/args.hpp>
#define strncasecmp _strnicmp
#define strcasecmp _stricmp
#if UNICODE
#define IS_UCS2 1
#endif
#endif
namespace {
@ -182,20 +179,10 @@ struct SAsset {
enum class FileLockType { None = 0, Read, Write };
#if IS_UCS2
using SystemChar = wchar_t;
using SystemString = std::wstring;
#ifndef _SYS_STR
#define _SYS_STR(val) L##val
#endif
using Sstat = struct _stat;
#if _WIN32
using Sstat = struct ::_stat64;
#else
using SystemChar = char;
using SystemString = std::string;
#ifndef _SYS_STR
#define _SYS_STR(val) val
#endif
using Sstat = struct stat;
using SStat = struct stat;
#endif
struct FILEDeleter {
@ -203,9 +190,11 @@ struct FILEDeleter {
};
using FILEPtr = std::unique_ptr<FILE, FILEDeleter>;
FILEPtr Fopen(const SystemChar* path, const SystemChar* mode, FileLockType lock = FileLockType::None) {
#if IS_UCS2
FILEPtr fp{_wfopen(path, mode)};
FILEPtr Fopen(const char* path, const char* mode, FileLockType lock = FileLockType::None) {
#if _WIN32
const nowide::wstackstring wpath(path);
const nowide::wshort_stackstring wmode(mode);
FILEPtr fp{_wfopen(wpath.get(), wmode.get())};
if (!fp) {
return nullptr;
}
@ -269,35 +258,34 @@ std::string getValidExtension(const std::string& type) {
return type;
}
int main(int argc, char* argv[]) {
#if _WIN32
int wmain(int argc, const wchar_t* argv[])
#else
int main(int argc, const char* argv[])
nowide::args _(argc, argv);
#endif
{
logvisor::RegisterStandardExceptions();
logvisor::RegisterConsoleLogger();
if (argc < 3) {
Log.report(logvisor::Error, FMT_STRING(_SYS_STR("Usage: {} <input> <output>")), argv[0]);
Log.report(logvisor::Error, FMT_STRING("Usage: {} <input> <output>"), argv[0]);
return 1;
}
SystemString inPath = argv[1];
SystemString outPath = argv[2];
std::string inPath = argv[1];
std::string outPath = argv[2];
tinyxml2::XMLDocument doc;
std::vector<SAsset> assets;
FILEPtr docF = Fopen(inPath.c_str(), _SYS_STR("rb"));
FILEPtr docF = Fopen(inPath.c_str(), "rb");
if (doc.LoadFile(docF.get()) == tinyxml2::XML_SUCCESS) {
const tinyxml2::XMLElement* elm = doc.RootElement();
if (strcmp(elm->Name(), "AssetNameMap") != 0) {
Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("Invalid database supplied")));
Log.report(logvisor::Fatal, FMT_STRING("Invalid database supplied"));
return 1;
}
elm = elm->FirstChildElement("AssetNameMap");
if (elm == nullptr) {
Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("Malformed AssetName database")));
Log.report(logvisor::Fatal, FMT_STRING("Malformed AssetName database"));
return 1;
}
@ -308,7 +296,7 @@ int main(int argc, const char* argv[])
const tinyxml2::XMLElement* valueElm = elm->FirstChildElement("Value");
if (keyElm == nullptr || valueElm == nullptr) {
Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("Malformed Asset entry, [Key,Value] required")));
Log.report(logvisor::Fatal, FMT_STRING("Malformed Asset entry, [Key,Value] required"));
return 0;
}
@ -319,7 +307,7 @@ int main(int argc, const char* argv[])
const tinyxml2::XMLElement* autoGenDirElm = valueElm->FirstChildElement("AutoGenDir");
if (nameElm == nullptr || dirElm == nullptr || typeElm == nullptr) {
Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("Malformed Value entry, [Name,Directory,Type] required")));
Log.report(logvisor::Fatal, FMT_STRING("Malformed Value entry, [Name,Directory,Type] required"));
return 0;
}
bool autoGen = strncasecmp(autoGenNameElm->GetText(), "true", 4) == 0 && strncasecmp(autoGenDirElm->GetText(), "true", 4) == 0;
@ -340,9 +328,9 @@ int main(int argc, const char* argv[])
elm = elm->NextSiblingElement("Asset");
}
FILEPtr f = Fopen(outPath.c_str(), _SYS_STR("wb"));
FILEPtr f = Fopen(outPath.c_str(), "wb");
if (f == nullptr) {
Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("Unable to open destination")));
Log.report(logvisor::Fatal, FMT_STRING("Unable to open destination"));
return 0;
}
@ -365,6 +353,6 @@ int main(int argc, const char* argv[])
return 0;
}
Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("failed to load")));
Log.report(logvisor::Fatal, FMT_STRING("failed to load"));
return 1;
}

Some files were not shown because too many files have changed in this diff Show More