Use UTF-8 exclusively internally

This commit is contained in:
Luke Street 2021-06-30 14:15:40 -04:00
parent 6e896fa1d3
commit 603e066eed
26 changed files with 531 additions and 605 deletions

View File

@ -7,20 +7,12 @@
#include <QProcess>
#include <QTransform>
boo::SystemString QStringToSysString(const QString& str) {
#ifdef _WIN32
return (wchar_t*)str.utf16();
#else
std::string QStringToUTF8(const QString& str) {
return str.toUtf8().toStdString();
#endif
}
QString SysStringToQString(const boo::SystemString& str) {
#ifdef _WIN32
return QString::fromStdWString(str);
#else
QString UTF8ToQString(const std::string& str) {
return QString::fromStdString(str);
#endif
}
bool MkPath(const QString& path, UIMessenger& messenger) {

View File

@ -37,8 +37,8 @@ signals:
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
};
boo::SystemString QStringToSysString(const QString& str);
QString SysStringToQString(const boo::SystemString& str);
std::string QStringToUTF8(const QString& str);
QString UTF8ToQString(const std::string& str);
bool MkPath(const QString& path, UIMessenger& messenger);
bool MkPath(const QDir& dir, const QString& file, UIMessenger& messenger);

View File

@ -200,7 +200,6 @@ MainWindow::MainWindow(QWidget* parent)
MainWindow::~MainWindow() {
m_backgroundThread.quit();
m_backgroundThread.wait();
fmt::print(FMT_STRING("IM DYING\n"));
}
void MainWindow::connectMessenger(UIMessenger* messenger, Qt::ConnectionType type) {
@ -910,7 +909,7 @@ void MainWindow::_importAction(const QString& path) {
return;
/* Validate input file */
amuse::ContainerRegistry::Type tp = amuse::ContainerRegistry::DetectContainerType(QStringToSysString(path).c_str());
amuse::ContainerRegistry::Type tp = amuse::ContainerRegistry::DetectContainerType(QStringToUTF8(path).c_str());
if (tp == amuse::ContainerRegistry::Type::Invalid) {
QString msg = QString(tr("The file at '%1' could not be interpreted as a MusyX container.")).arg(path);
m_mainMessenger.critical(tr("Unsupported MusyX Container"), msg);
@ -967,12 +966,12 @@ void MainWindow::_importAction(const QString& path) {
const QStringList files = dir.entryList(filters, QDir::Files);
for (const QString& fPath : files) {
auto data = amuse::ContainerRegistry::LoadContainer(QStringToSysString(dir.filePath(fPath)).c_str());
auto data = amuse::ContainerRegistry::LoadContainer(QStringToUTF8(dir.filePath(fPath)).c_str());
for (auto& p : data) {
task.setLabelText(tr("Importing %1").arg(SysStringToQString(p.first)));
task.setLabelText(tr("Importing %1").arg(UTF8ToQString(p.first)));
if (task.isCanceled())
return;
if (!model->importGroupData(SysStringToQString(p.first), p.second, importMode, task.uiMessenger()))
if (!model->importGroupData(UTF8ToQString(p.first), p.second, importMode, task.uiMessenger()))
return;
}
}
@ -1000,14 +999,14 @@ void MainWindow::_importAction(const QString& path) {
startBackgroundTask(
TaskImport, tr("Importing"), tr("Scanning Project"), [model, path, importMode](BackgroundTask& task) {
/* Handle single container */
auto data = amuse::ContainerRegistry::LoadContainer(QStringToSysString(path).c_str());
auto data = amuse::ContainerRegistry::LoadContainer(QStringToUTF8(path).c_str());
task.setMaximum(int(data.size()));
int curVal = 0;
for (auto& p : data) {
task.setLabelText(tr("Importing %1").arg(SysStringToQString(p.first)));
task.setLabelText(tr("Importing %1").arg(UTF8ToQString(p.first)));
if (task.isCanceled())
return;
if (!model->importGroupData(SysStringToQString(p.first), p.second, importMode, task.uiMessenger()))
if (!model->importGroupData(UTF8ToQString(p.first), p.second, importMode, task.uiMessenger()))
return;
task.setValue(++curVal);
}

View File

@ -524,7 +524,7 @@ bool ProjectModel::clearProjectData() {
bool ProjectModel::openGroupData(QString groupName, UIMessenger& messenger) {
m_projectDatabase.setIdDatabases();
const QString path = QFileInfo(m_dir, groupName).filePath();
m_groups.emplace(std::move(groupName), std::make_unique<amuse::AudioGroupDatabase>(QStringToSysString(path)));
m_groups.emplace(std::move(groupName), std::make_unique<amuse::AudioGroupDatabase>(QStringToUTF8(path)));
m_needsReset = true;
return true;
@ -550,7 +550,7 @@ void ProjectModel::openSongsData() {
m_midiFiles.clear();
QFileInfo songsFile(m_dir, QStringLiteral("!songs.yaml"));
if (songsFile.exists()) {
athena::io::FileReader r(QStringToSysString(songsFile.filePath()));
athena::io::FileReader r(QStringToUTF8(songsFile.filePath()));
if (!r.hasError()) {
athena::io::YAMLDocReader dr;
if (dr.parse(&r)) {
@ -573,15 +573,15 @@ void ProjectModel::openSongsData() {
}
void ProjectModel::importSongsData(const QString& path) {
std::vector<std::pair<amuse::SystemString, amuse::ContainerRegistry::SongData>> songs =
amuse::ContainerRegistry::LoadSongs(QStringToSysString(path).c_str());
std::vector<std::pair<std::string, amuse::ContainerRegistry::SongData>> songs =
amuse::ContainerRegistry::LoadSongs(QStringToUTF8(path).c_str());
for (const auto& song : songs) {
int version;
bool isBig;
auto midiData = amuse::SongConverter::SongToMIDI(song.second.m_data.get(), version, isBig);
if (!midiData.empty()) {
QFileInfo fi(m_dir, SysStringToQString(song.first + _SYS_STR(".mid")));
QFileInfo fi(m_dir, UTF8ToQString(song.first + ".mid"));
QFile f(fi.filePath());
if (f.open(QFile::WriteOnly)) {
f.write((const char*)midiData.data(), midiData.size());
@ -599,7 +599,7 @@ bool ProjectModel::reloadSampleData(const QString& groupName, UIMessenger&) {
QString path = QFileInfo(m_dir, groupName).filePath();
auto search = m_groups.find(groupName);
if (search != m_groups.end())
search->second->getSdir().reloadSampleData(QStringToSysString(path));
search->second->getSdir().reloadSampleData(QStringToUTF8(path));
m_needsReset = true;
return true;
@ -618,7 +618,7 @@ bool ProjectModel::importGroupData(const QString& groupName, const amuse::AudioG
if (!MkPath(dir.path(), messenger))
return false;
amuse::SystemString sysDir = QStringToSysString(dir.path());
std::string sysDir = QStringToUTF8(dir.path());
grp.setGroupPath(sysDir);
switch (mode) {
case ImportMode::Original:
@ -637,14 +637,14 @@ bool ProjectModel::importGroupData(const QString& groupName, const amuse::AudioG
{
auto proj = grp.getProj().toYAML();
athena::io::FileWriter fo(QStringToSysString(QFileInfo(dir, QStringLiteral("!project.yaml")).filePath()));
athena::io::FileWriter fo(QStringToUTF8(QFileInfo(dir, QStringLiteral("!project.yaml")).filePath()));
if (fo.hasError())
return false;
fo.writeUBytes(proj.data(), proj.size());
}
{
auto pool = grp.getPool().toYAML();
athena::io::FileWriter fo(QStringToSysString(QFileInfo(dir, QStringLiteral("!pool.yaml")).filePath()));
athena::io::FileWriter fo(QStringToUTF8(QFileInfo(dir, QStringLiteral("!pool.yaml")).filePath()));
if (fo.hasError())
return false;
fo.writeUBytes(pool.data(), pool.size());
@ -660,7 +660,7 @@ void ProjectModel::saveSongsIndex() {
athena::io::YAMLDocWriter dw("amuse::Songs");
for (auto& p : amuse::SortUnorderedMap(m_midiFiles))
dw.writeString(fmt::format(FMT_STRING("{}"), p.first), p.second.get().m_path.toUtf8().data());
athena::io::FileWriter w(QStringToSysString(songsFile.filePath()));
athena::io::FileWriter w(QStringToUTF8(songsFile.filePath()));
if (!w.hasError())
dw.finish(&w);
}
@ -678,14 +678,14 @@ bool ProjectModel::saveToFile(UIMessenger& messenger) {
return false;
{
auto proj = g.second->getProj().toYAML();
athena::io::FileWriter fo(QStringToSysString(QFileInfo(dir, QStringLiteral("!project.yaml")).filePath()));
athena::io::FileWriter fo(QStringToUTF8(QFileInfo(dir, QStringLiteral("!project.yaml")).filePath()));
if (fo.hasError())
return false;
fo.writeUBytes(proj.data(), proj.size());
}
{
auto pool = g.second->getPool().toYAML();
athena::io::FileWriter fo(QStringToSysString(QFileInfo(dir, QStringLiteral("!pool.yaml")).filePath()));
athena::io::FileWriter fo(QStringToUTF8(QFileInfo(dir, QStringLiteral("!pool.yaml")).filePath()));
if (fo.hasError())
return false;
fo.writeUBytes(pool.data(), pool.size());
@ -720,7 +720,7 @@ bool ProjectModel::exportGroup(const QString& path, const QString& groupName, UI
QString basePath = QFileInfo(QDir(path), groupName).filePath();
{
auto proj = group.getProj().toGCNData(group.getPool(), group.getSdir());
athena::io::FileWriter fo(QStringToSysString(basePath + QStringLiteral(".proj")));
athena::io::FileWriter fo(QStringToUTF8(basePath + QStringLiteral(".proj")));
if (fo.hasError()) {
messenger.critical(tr("Export Error"), tr("Unable to export %1.proj").arg(groupName));
return false;
@ -729,7 +729,7 @@ bool ProjectModel::exportGroup(const QString& path, const QString& groupName, UI
}
{
auto pool = group.getPool().toData<athena::Endian::Big>();
athena::io::FileWriter fo(QStringToSysString(basePath + QStringLiteral(".pool")));
athena::io::FileWriter fo(QStringToUTF8(basePath + QStringLiteral(".pool")));
if (fo.hasError()) {
messenger.critical(tr("Export Error"), tr("Unable to export %1.pool").arg(groupName));
return false;
@ -739,7 +739,7 @@ bool ProjectModel::exportGroup(const QString& path, const QString& groupName, UI
{
auto sdirSamp = group.getSdir().toGCNData(group);
{
athena::io::FileWriter fo(QStringToSysString(basePath + QStringLiteral(".sdir")));
athena::io::FileWriter fo(QStringToUTF8(basePath + QStringLiteral(".sdir")));
if (fo.hasError()) {
messenger.critical(tr("Export Error"), tr("Unable to export %1.sdir").arg(groupName));
return false;
@ -747,7 +747,7 @@ bool ProjectModel::exportGroup(const QString& path, const QString& groupName, UI
fo.writeUBytes(sdirSamp.first.data(), sdirSamp.first.size());
}
{
athena::io::FileWriter fo(QStringToSysString(basePath + QStringLiteral(".samp")));
athena::io::FileWriter fo(QStringToUTF8(basePath + QStringLiteral(".samp")));
if (fo.hasError()) {
messenger.critical(tr("Export Error"), tr("Unable to export %1.samp").arg(groupName));
return false;
@ -1229,7 +1229,7 @@ ProjectModel::GroupNode* ProjectModel::newSubproject(QString name) {
}
const QString path = QFileInfo(m_dir, name).filePath();
auto data = std::make_unique<amuse::AudioGroupDatabase>(QStringToSysString(path));
auto data = std::make_unique<amuse::AudioGroupDatabase>(QStringToUTF8(path));
auto node = amuse::MakeObj<GroupNode>(std::move(name));
_buildGroupNodeCollections(*node);
g_MainWindow->pushUndoCommand(new GroupNodeAddUndoCommand(tr("Add Subproject %1"), std::move(data), node.get()));
@ -1755,7 +1755,7 @@ QMimeData* ProjectModel::mimeData(const QModelIndexList& indexes) const {
return MakeMimeData(static_cast<LayersNode*>(n), QStringLiteral("application/x-amuse-layers"));
case INode::Type::Sample: {
GroupNode* gn = getGroupNode(n);
QString path = SysStringToQString(gn->getAudioGroup()->getSampleBasePath(static_cast<SampleNode*>(n)->id()));
QString path = UTF8ToQString(gn->getAudioGroup()->getSampleBasePath(static_cast<SampleNode*>(n)->id()));
QMimeData* data = new QMimeData;
data->setData(QStringLiteral("application/x-amuse-samplepath"), path.toUtf8());
return data;
@ -1783,7 +1783,7 @@ bool ProjectModel::dropMimeData(const QMimeData* data, Qt::DropAction action, in
QFile::copy(QFileInfo(oldDir, ent).filePath(), QFileInfo(newDir, ent).filePath());
}
auto dataNode = std::make_unique<amuse::AudioGroupDatabase>(QStringToSysString(newDir.path()));
auto dataNode = std::make_unique<amuse::AudioGroupDatabase>(QStringToUTF8(newDir.path()));
const auto node = amuse::MakeObj<GroupNode>(newName);
_buildGroupNode(*node, *dataNode);
g_MainWindow->pushUndoCommand(
@ -1817,9 +1817,9 @@ bool ProjectModel::dropMimeData(const QMimeData* data, Qt::DropAction action, in
const QString newName =
MakeDedupedName(QFileInfo(QString::fromUtf8(path)).completeBaseName(), amuse::SampleId::CurNameDB);
const QString newBasePath = QFileInfo(QFileInfo(m_dir, gn->name()).filePath(), newName).filePath();
const amuse::SystemString newBasePathStr = QStringToSysString(newBasePath);
const std::string newBasePathStr = QStringToUTF8(newBasePath);
gn->getAudioGroup()->copySampleInto(QStringToSysString(QString::fromUtf8(path)), newBasePathStr);
gn->getAudioGroup()->copySampleInto(QStringToUTF8(QString::fromUtf8(path)), newBasePathStr);
auto dataNode = amuse::MakeObj<amuse::SampleEntry>();
dataNode->loadLooseData(newBasePathStr);
const auto node = amuse::MakeObj<SampleNode>(newName, dataNode);
@ -1917,7 +1917,7 @@ QModelIndex ProjectModel::duplicate(const QModelIndex& index) {
QFile::copy(QFileInfo(oldDir, ent).filePath(), QFileInfo(newDir, ent).filePath());
}
auto data = std::make_unique<amuse::AudioGroupDatabase>(*cn->getAudioGroup(), QStringToSysString(newDir.path()));
auto data = std::make_unique<amuse::AudioGroupDatabase>(*cn->getAudioGroup(), QStringToUTF8(newDir.path()));
auto node = amuse::MakeObj<GroupNode>(newName);
_buildGroupNode(*node, *data);
cmd = new GroupNodeAddUndoCommand(tr("Add Subproject %1"), std::move(data), node.get());

View File

@ -579,7 +579,7 @@ void SampleControls::updateFileState() {
SampleEditor* editor = qobject_cast<SampleEditor*>(parentWidget());
ProjectModel::SampleNode* node = static_cast<ProjectModel::SampleNode*>(editor->currentNode());
amuse::SystemString path;
std::string path;
amuse::SampleFileState state = g_MainWindow->projectModel()->getGroupNode(node)->getAudioGroup()->getSampleFileState(
node->id(), node->m_obj.get(), &path);
disconnect(m_makeOtherConn);
@ -623,7 +623,7 @@ void SampleControls::updateFileState() {
m_loopEnd->setEnabled(data->isLooped());
if (!path.empty()) {
m_path = SysStringToQString(path);
m_path = UTF8ToQString(path);
m_showInBrowser->setDisabled(false);
} else {
m_path = QString();

View File

@ -36,20 +36,20 @@ static QIcon MakeAppIcon() {
/* This is for adapting the get*Name methods */
class BooInterface : public boo::IApplication {
std::vector<boo::SystemString> m_args;
std::vector<std::string> m_args;
void _deletedWindow(boo::IWindow* window) override {}
public:
EPlatformType getPlatformType() const override { return EPlatformType::Qt; }
int run() override { return 0; }
boo::SystemStringView getUniqueName() const override { return _SYS_STR("amuse-gui"sv); }
boo::SystemStringView getFriendlyName() const override { return _SYS_STR("Amuse"sv); }
boo::SystemStringView getProcessName() const override { return _SYS_STR("amuse-gui"sv); }
const std::vector<boo::SystemString>& getArgs() const override { return m_args; }
std::string_view getUniqueName() const override { return "amuse-gui"sv; }
std::string_view getFriendlyName() const override { return "Amuse"sv; }
std::string_view getProcessName() const override { return "amuse-gui"sv; }
const std::vector<std::string>& getArgs() const override { return m_args; }
/* Constructors/initializers for sub-objects */
std::shared_ptr<boo::IWindow> newWindow(boo::SystemStringView title) override { return {}; }
std::shared_ptr<boo::IWindow> newWindow(std::string_view title) override { return {}; }
};
MainWindow* g_MainWindow = nullptr;

View File

@ -1,6 +1,5 @@
add_executable(amuse-mkqticon mkqticon.c)
target_link_libraries(amuse-mkqticon ${PNG_LIBRARIES} ${ZLIB_LIBRARIES})
target_include_directories(amuse-mkqticon PRIVATE ${PNG_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR})
macro(declare_qticon_target)
add_custom_command(OUTPUT ${amuse_BINARY_DIR}/Editor/platforms/freedesktop/mainicon_qt.bin

View File

@ -270,7 +270,7 @@ void VSTEditor::addAction() {
return;
}
SystemString name(amuse::ContainerRegistry::TypeToName(containerType));
std::string name(amuse::ContainerRegistry::TypeToName(containerType));
if (containerType == amuse::ContainerRegistry::Type::Raw4) {
size_t dotpos = path.rfind(L'.');
if (dotpos != std::string::npos)

View File

@ -5,6 +5,10 @@
#include <cstdio>
#include <cstring>
#if _WIN32
#include <nowide/args.hpp>
#endif
static logvisor::Module Log("amuseconv");
enum ConvType { ConvN64, ConvGCN, ConvPC };
@ -12,37 +16,37 @@ enum ConvType { ConvN64, ConvGCN, ConvPC };
static void ReportConvType(ConvType tp) {
switch (tp) {
case ConvN64:
Log.report(logvisor::Info, FMT_STRING(_SYS_STR("using N64 format")));
Log.report(logvisor::Info, FMT_STRING("using N64 format"));
break;
case ConvPC:
Log.report(logvisor::Info, FMT_STRING(_SYS_STR("using PC format")));
Log.report(logvisor::Info, FMT_STRING("using PC format"));
break;
case ConvGCN:
default:
Log.report(logvisor::Info, FMT_STRING(_SYS_STR("using GameCube format")));
Log.report(logvisor::Info, FMT_STRING("using GameCube format"));
break;
}
}
static bool BuildAudioGroup(amuse::SystemStringView groupBase, amuse::SystemStringView targetPath) { return true; }
static bool BuildAudioGroup(std::string_view groupBase, std::string_view targetPath) { return true; }
static bool ExtractAudioGroup(amuse::SystemStringView inPath, amuse::SystemStringView targetPath) {
static bool ExtractAudioGroup(std::string_view inPath, std::string_view targetPath) {
amuse::ContainerRegistry::Type type;
auto groups = amuse::ContainerRegistry::LoadContainer(inPath.data(), type);
if (groups.size()) {
Log.report(logvisor::Info, FMT_STRING(_SYS_STR("Found '{}'")), amuse::ContainerRegistry::TypeToName(type));
Log.report(logvisor::Info, FMT_STRING("Found '{}'"), amuse::ContainerRegistry::TypeToName(type));
amuse::Mkdir(targetPath.data(), 0755);
Log.report(logvisor::Info, FMT_STRING(_SYS_STR("Established directory at {}")), targetPath);
Log.report(logvisor::Info, FMT_STRING("Established directory at {}"), targetPath);
for (auto& group : groups) {
Log.report(logvisor::Info, FMT_STRING(_SYS_STR("Extracting {}")), group.first);
Log.report(logvisor::Info, FMT_STRING("Extracting {}"), group.first);
}
}
auto songs = amuse::ContainerRegistry::LoadSongs(inPath.data());
amuse::SystemString songsDir = amuse::SystemString(targetPath) + _SYS_STR("/midifiles");
std::string songsDir = std::string(targetPath) + "/midifiles";
bool madeDir = false;
for (auto& pair : songs) {
if (!madeDir) {
@ -51,10 +55,10 @@ static bool ExtractAudioGroup(amuse::SystemStringView inPath, amuse::SystemStrin
madeDir = true;
}
amuse::SystemString songPath = songsDir + _SYS_STR('/') + pair.first + _SYS_STR(".mid");
FILE* fp = amuse::FOpen(songPath.c_str(), _SYS_STR("wb"));
std::string songPath = songsDir + '/' + pair.first + ".mid";
FILE* fp = amuse::FOpen(songPath.c_str(), "wb");
if (fp) {
Log.report(logvisor::Info, FMT_STRING(_SYS_STR("Extracting {}")), pair.first);
Log.report(logvisor::Info, FMT_STRING("Extracting {}"), pair.first);
int extractedVersion;
bool isBig;
std::vector<uint8_t> mid = amuse::SongConverter::SongToMIDI(pair.second.m_data.get(), extractedVersion, isBig);
@ -66,8 +70,8 @@ static bool ExtractAudioGroup(amuse::SystemStringView inPath, amuse::SystemStrin
return true;
}
static bool BuildSNG(amuse::SystemStringView inPath, amuse::SystemStringView targetPath, int version, bool big) {
FILE* fp = amuse::FOpen(inPath.data(), _SYS_STR("rb"));
static bool BuildSNG(std::string_view inPath, std::string_view targetPath, int version, bool big) {
FILE* fp = amuse::FOpen(inPath.data(), "rb");
if (!fp)
return false;
@ -82,15 +86,15 @@ static bool BuildSNG(amuse::SystemStringView inPath, amuse::SystemStringView tar
if (out.empty())
return false;
fp = amuse::FOpen(targetPath.data(), _SYS_STR("wb"));
fp = amuse::FOpen(targetPath.data(), "wb");
fwrite(out.data(), 1, out.size(), fp);
fclose(fp);
return true;
}
static bool ExtractSNG(amuse::SystemStringView inPath, amuse::SystemStringView targetPath) {
FILE* fp = amuse::FOpen(inPath.data(), _SYS_STR("rb"));
static bool ExtractSNG(std::string_view inPath, std::string_view targetPath) {
FILE* fp = amuse::FOpen(inPath.data(), "rb");
if (!fp)
return false;
@ -107,19 +111,18 @@ static bool ExtractSNG(amuse::SystemStringView inPath, amuse::SystemStringView t
if (out.empty())
return false;
fp = amuse::FOpen(targetPath.data(), _SYS_STR("wb"));
fp = amuse::FOpen(targetPath.data(), "wb");
fwrite(out.data(), 1, out.size(), fp);
fclose(fp);
return true;
}
int main(int argc, char** argv) {
#if _WIN32
int wmain(int argc, const amuse::SystemChar** argv)
#else
int main(int argc, const amuse::SystemChar** argv)
nowide::args _(argc, argv);
#endif
{
logvisor::RegisterConsoleLogger();
if (argc < 3) {
@ -129,32 +132,32 @@ int main(int argc, const amuse::SystemChar** argv)
ConvType type = ConvGCN;
if (argc >= 4) {
if (!amuse::CompareCaseInsensitive(argv[3], _SYS_STR("n64")))
if (!amuse::CompareCaseInsensitive(argv[3], "n64"))
type = ConvN64;
else if (!amuse::CompareCaseInsensitive(argv[3], _SYS_STR("gcn")))
else if (!amuse::CompareCaseInsensitive(argv[3], "gcn"))
type = ConvGCN;
else if (!amuse::CompareCaseInsensitive(argv[3], _SYS_STR("pc")))
else if (!amuse::CompareCaseInsensitive(argv[3], "pc"))
type = ConvPC;
else {
Log.report(logvisor::Error, FMT_STRING(_SYS_STR("unrecognized format: {}")), argv[3]);
Log.report(logvisor::Error, FMT_STRING("unrecognized format: {}"), argv[3]);
return 1;
}
}
bool good = false;
FILE* fin = amuse::FOpen(argv[1], _SYS_STR("rb"));
FILE* fin = amuse::FOpen(argv[1], "rb");
if (fin) {
fclose(fin);
amuse::SystemString barePath(argv[1]);
size_t dotPos = barePath.rfind(_SYS_STR('.'));
const amuse::SystemChar* dot = barePath.c_str() + dotPos;
if (dotPos != amuse::SystemString::npos) {
if (!amuse::CompareCaseInsensitive(dot, _SYS_STR(".mid")) ||
!amuse::CompareCaseInsensitive(dot, _SYS_STR(".midi"))) {
std::string barePath(argv[1]);
size_t dotPos = barePath.rfind('.');
const char* dot = barePath.c_str() + dotPos;
if (dotPos != std::string::npos) {
if (!amuse::CompareCaseInsensitive(dot, ".mid") ||
!amuse::CompareCaseInsensitive(dot, ".midi")) {
ReportConvType(type);
good = BuildSNG(barePath, argv[2], 1, true);
} else if (!amuse::CompareCaseInsensitive(dot, _SYS_STR(".son")) ||
!amuse::CompareCaseInsensitive(dot, _SYS_STR(".sng"))) {
} else if (!amuse::CompareCaseInsensitive(dot, ".son") ||
!amuse::CompareCaseInsensitive(dot, ".sng")) {
good = ExtractSNG(argv[1], argv[2]);
} else {
good = ExtractAudioGroup(argv[1], argv[2]);
@ -163,9 +166,9 @@ int main(int argc, const amuse::SystemChar** argv)
} else {
amuse::Sstat theStat;
if (!amuse::Stat(argv[1], &theStat) && S_ISDIR(theStat.st_mode)) {
amuse::SystemString projectPath(argv[1]);
projectPath += _SYS_STR("/project.yaml");
fin = amuse::FOpen(projectPath.c_str(), _SYS_STR("rb"));
std::string projectPath(argv[1]);
projectPath += "/project.yaml";
fin = amuse::FOpen(projectPath.c_str(), "rb");
if (fin) {
fclose(fin);
ReportConvType(type);
@ -175,7 +178,7 @@ int main(int argc, const amuse::SystemChar** argv)
}
if (!good) {
Log.report(logvisor::Error, FMT_STRING(_SYS_STR("unable to convert {} to {}")), argv[1], argv[2]);
Log.report(logvisor::Error, FMT_STRING("unable to convert {} to {}"), argv[1], argv[2]);
return 1;
}

View File

@ -5,6 +5,10 @@
#include <map>
#if _WIN32
#include <nowide/args.hpp>
#endif
#define EMITTER_TEST 0
static logvisor::Module Log("amuseplay");
@ -31,7 +35,7 @@ public:
struct AppCallback : boo::IApplicationCallback {
int m_argc;
const boo::SystemChar** m_argv;
char** m_argv;
/* Boo window and events */
EventCallback m_eventRec;
@ -560,7 +564,7 @@ struct AppCallback : boo::IApplicationCallback {
int appMain(boo::IApplication* app) override {
/* Event window */
m_win = app->newWindow(_SYS_STR("amuseplay"));
m_win = app->newWindow("amuseplay");
m_win->setCallback(&m_events);
m_win->setWindowFrame(100, 100, 100, 100);
m_win->setStyle(~boo::EWindowStyle::Resize);
@ -587,9 +591,9 @@ struct AppCallback : boo::IApplicationCallback {
Log.report(logvisor::Error, FMT_STRING("invalid/no data at path argument"));
return 1;
}
Log.report(logvisor::Info, FMT_STRING(_SYS_STR("Found '%s' Audio Group data")), amuse::ContainerRegistry::TypeToName(cType));
Log.report(logvisor::Info, FMT_STRING("Found '%s' Audio Group data"), amuse::ContainerRegistry::TypeToName(cType));
std::vector<std::pair<amuse::SystemString, amuse::IntrusiveAudioGroupData>> data =
std::vector<std::pair<std::string, amuse::IntrusiveAudioGroupData>> data =
amuse::ContainerRegistry::LoadContainer(m_argv[1]);
if (data.empty()) {
Log.report(logvisor::Error, FMT_STRING("invalid/no data at path argument"));
@ -597,10 +601,10 @@ struct AppCallback : boo::IApplicationCallback {
}
std::list<amuse::AudioGroupProject> m_projs;
std::map<amuse::GroupId, std::pair<std::pair<amuse::SystemString, amuse::IntrusiveAudioGroupData>*,
std::map<amuse::GroupId, std::pair<std::pair<std::string, amuse::IntrusiveAudioGroupData>*,
amuse::ObjToken<amuse::SongGroupIndex>>>
allSongGroups;
std::map<amuse::GroupId, std::pair<std::pair<amuse::SystemString, amuse::IntrusiveAudioGroupData>*,
std::map<amuse::GroupId, std::pair<std::pair<std::string, amuse::IntrusiveAudioGroupData>*,
amuse::ObjToken<amuse::SFXGroupIndex>>>
allSFXGroups;
size_t totalGroups = 0;
@ -623,7 +627,7 @@ struct AppCallback : boo::IApplicationCallback {
m_setupId = -1;
/* Attempt loading song */
std::vector<std::pair<amuse::SystemString, amuse::ContainerRegistry::SongData>> songs;
std::vector<std::pair<std::string, amuse::ContainerRegistry::SongData>> songs;
if (m_argc > 2)
songs = amuse::ContainerRegistry::LoadSongs(m_argv[2]);
else
@ -674,7 +678,7 @@ struct AppCallback : boo::IApplicationCallback {
break;
}
}
fmt::print(FMT_STRING(_SYS_STR(" {} {} (Group {}, Setup {})\n")), idx++, pair.first, grpId, setupId);
fmt::print(FMT_STRING(" {} {} (Group {}, Setup {})\n"), idx++, pair.first, grpId, setupId);
}
int userSel = 0;
@ -728,11 +732,11 @@ struct AppCallback : boo::IApplicationCallback {
/* Ask user to specify which group in project */
fmt::print(FMT_STRING("Multiple Audio Groups discovered:\n"));
for (const auto& pair : allSFXGroups) {
fmt::print(FMT_STRING(_SYS_STR(" {} {} (SFXGroup) {} sfx-entries\n")), pair.first,
fmt::print(FMT_STRING(" {} {} (SFXGroup) {} sfx-entries\n"), pair.first,
pair.second.first->first, pair.second.second->m_sfxEntries.size());
}
for (const auto& pair : allSongGroups) {
fmt::print(FMT_STRING(_SYS_STR(" {} {} (SongGroup) {} normal-pages, {} drum-pages, {} MIDI-setups\n")),
fmt::print(FMT_STRING(" {} {} (SongGroup) {} normal-pages, {} drum-pages, {} MIDI-setups\n"),
pair.first, pair.second.first->first, pair.second.second->m_normPages.size(),
pair.second.second->m_drumPages.size(), pair.second.second->m_midiSetups.size());
}
@ -821,7 +825,7 @@ struct AppCallback : boo::IApplicationCallback {
void appQuitting(boo::IApplication*) override { m_running = false; }
AppCallback(int argc, const boo::SystemChar** argv)
AppCallback(int argc, char** argv)
: m_argc(argc), m_argv(argv), m_eventRec(*this), m_events(m_eventRec) {}
};
@ -898,37 +902,23 @@ void EventCallback::mouseMove(const boo::SWindowCoord& coord) {
}
}
#if _WIN32
int wmain(int argc, const boo::SystemChar** argv)
#else
int main(int argc, const boo::SystemChar** argv)
#endif
{
int main(int argc, char** argv) {
logvisor::RegisterConsoleLogger();
logvisor::RegisterStandardExceptions();
AppCallback app(argc, argv);
int ret = boo::ApplicationRun(boo::IApplication::EPlatformType::Auto, app, _SYS_STR("amuseplay"),
_SYS_STR("Amuse Player"), argc, argv, {}, 1, 1, false);
fmt::print(FMT_STRING("IM DYING!!\n"));
int ret = boo::ApplicationRun(boo::IApplication::EPlatformType::Auto, app, "amuseplay",
"Amuse Player", argc, argv, {}, 1, 1, false);
return ret;
}
#if _WIN32
#include <shellapi.h>
int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR 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];
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR lpCmdLine, int) {
int argc = 0;
char** argv = nullptr;
nowide::args _(argc, argv);
logvisor::CreateWin32Console();
SetConsoleOutputCP(65001);
return wmain(argc + 1, booArgv);
return main(argc, argv);
}
#endif

View File

@ -19,6 +19,7 @@ static logvisor::Module Log("amuserender");
#if _WIN32
#include <DbgHelp.h>
#include <nowide/args.hpp>
#pragma comment(lib, "Dbghelp.lib")
#include <signal.h>
@ -68,45 +69,15 @@ static void abortHandler(int signum) {
static bool g_BreakLoop = false;
static void SIGINTHandler(int sig) { g_BreakLoop = true; }
#if _WIN32
int wmain(int argc, const boo::SystemChar** argv)
#else
int main(int argc, const boo::SystemChar** argv)
#endif
{
int main(int argc, char** argv) {
logvisor::RegisterConsoleLogger();
std::vector<boo::SystemString> m_args;
std::vector<std::string> m_args;
m_args.reserve(argc);
double rate = NativeSampleRate;
int chCount = 2;
double volume = 1.0;
for (int i = 1; i < argc; ++i) {
#if _WIN32
if (!wcsncmp(argv[i], L"-r", 2)) {
if (argv[i][2])
rate = wcstod(&argv[i][2], nullptr);
else if (argc > (i + 1)) {
rate = wcstod(argv[i + 1], nullptr);
++i;
}
} else if (!wcsncmp(argv[i], L"-c", 2)) {
if (argv[i][2])
chCount = wcstoul(&argv[i][2], nullptr, 0);
else if (argc > (i + 1)) {
chCount = wcstoul(argv[i + 1], nullptr, 0);
++i;
}
} else if (!wcsncmp(argv[i], L"-v", 2)) {
if (argv[i][2])
volume = wcstod(&argv[i][2], nullptr);
else if (argc > (i + 1)) {
volume = wcstod(argv[i + 1], nullptr);
++i;
}
} else
m_args.push_back(argv[i]);
#else
if (!strncmp(argv[i], "-r", 2)) {
if (argv[i][2])
rate = strtod(&argv[i][2], nullptr);
@ -130,7 +101,6 @@ int main(int argc, const boo::SystemChar** argv)
}
} else
m_args.push_back(argv[i]);
#endif
}
/* Load data */
@ -146,9 +116,9 @@ int main(int argc, const boo::SystemChar** argv)
Log.report(logvisor::Error, FMT_STRING("invalid/no data at path argument"));
return 1;
}
Log.report(logvisor::Info, FMT_STRING(_SYS_STR("Found '{}' Audio Group data")), amuse::ContainerRegistry::TypeToName(cType));
Log.report(logvisor::Info, FMT_STRING("Found '{}' Audio Group data"), amuse::ContainerRegistry::TypeToName(cType));
std::vector<std::pair<amuse::SystemString, amuse::IntrusiveAudioGroupData>> data =
std::vector<std::pair<std::string, amuse::IntrusiveAudioGroupData>> data =
amuse::ContainerRegistry::LoadContainer(m_args[0].c_str());
if (data.empty()) {
Log.report(logvisor::Error, FMT_STRING("invalid/no data at path argument"));
@ -157,16 +127,16 @@ int main(int argc, const boo::SystemChar** argv)
int m_groupId = -1;
int m_setupId = -1;
const amuse::SystemString* m_groupName = nullptr;
const amuse::SystemString* m_songName = nullptr;
const std::string* m_groupName = nullptr;
const std::string* m_songName = nullptr;
amuse::ContainerRegistry::SongData* m_arrData = nullptr;
bool m_sfxGroup = false;
std::list<amuse::AudioGroupProject> m_projs;
std::map<amuse::GroupId, std::pair<std::pair<amuse::SystemString, amuse::IntrusiveAudioGroupData>*,
std::map<amuse::GroupId, std::pair<std::pair<std::string, amuse::IntrusiveAudioGroupData>*,
amuse::ObjToken<amuse::SongGroupIndex>>>
allSongGroups;
std::map<amuse::GroupId, std::pair<std::pair<amuse::SystemString, amuse::IntrusiveAudioGroupData>*,
std::map<amuse::GroupId, std::pair<std::pair<std::string, amuse::IntrusiveAudioGroupData>*,
amuse::ObjToken<amuse::SFXGroupIndex>>>
allSFXGroups;
size_t totalGroups = 0;
@ -185,7 +155,7 @@ int main(int argc, const boo::SystemChar** argv)
}
/* Attempt loading song */
std::vector<std::pair<amuse::SystemString, amuse::ContainerRegistry::SongData>> songs;
std::vector<std::pair<std::string, amuse::ContainerRegistry::SongData>> songs;
if (m_args.size() > 1)
songs = amuse::ContainerRegistry::LoadSongs(m_args[1].c_str());
else
@ -236,7 +206,7 @@ int main(int argc, const boo::SystemChar** argv)
break;
}
}
fmt::print(FMT_STRING(_SYS_STR(" {} {} (Group {}, Setup {})\n")), idx++, pair.first, grpId, setupId);
fmt::print(FMT_STRING(" {} {} (Group {}, Setup {})\n"), idx++, pair.first, grpId, setupId);
}
int userSel = 0;
@ -297,11 +267,11 @@ int main(int argc, const boo::SystemChar** argv)
/* Ask user to specify which group in project */
fmt::print(FMT_STRING("Multiple Audio Groups discovered:\n"));
for (const auto& pair : allSFXGroups) {
fmt::print(FMT_STRING(_SYS_STR(" {} {} (SFXGroup) {} sfx-entries\n")), pair.first,
fmt::print(FMT_STRING(" {} {} (SFXGroup) {} sfx-entries\n"), pair.first,
pair.second.first->first, pair.second.second->m_sfxEntries.size());
}
for (const auto& pair : allSongGroups) {
fmt::print(FMT_STRING(_SYS_STR(" {} {} (SongGroup) {} normal-pages, {} drum-pages, {} MIDI-setups\n")),
fmt::print(FMT_STRING(" {} {} (SongGroup) {} normal-pages, {} drum-pages, {} MIDI-setups\n"),
pair.first, pair.second.first->first, pair.second.second->m_normPages.size(),
pair.second.second->m_drumPages.size(), pair.second.second->m_midiSetups.size());
}
@ -392,8 +362,8 @@ int main(int argc, const boo::SystemChar** argv)
}
/* WAV out path */
amuse::SystemString pathOut = fmt::format(FMT_STRING(_SYS_STR("{}-{}.wav")), *m_groupName, *m_songName);
Log.report(logvisor::Info, FMT_STRING(_SYS_STR("Writing to {}")), pathOut);
std::string pathOut = fmt::format(FMT_STRING("{}-{}.wav"), *m_groupName, *m_songName);
Log.report(logvisor::Info, FMT_STRING("Writing to {}"), pathOut);
/* Build voice engine */
std::unique_ptr<boo::IAudioVoiceEngine> voxEngine = boo::NewWAVAudioVoiceEngine(pathOut.c_str(), rate, chCount);
@ -425,25 +395,17 @@ int main(int argc, const boo::SystemChar** argv)
#if _WIN32
#include <shellapi.h>
int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR lpCmdLine, int) {
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR lpCmdLine, int) {
signal(SIGABRT, abortHandler);
signal(SIGSEGV, abortHandler);
signal(SIGILL, abortHandler);
signal(SIGFPE, abortHandler);
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);
logvisor::CreateWin32Console();
SetConsoleOutputCP(65001);
return wmain(argc + 1, booArgv);
return main(argc, argv);
}
#endif

View File

@ -21,26 +21,26 @@ protected:
AudioGroupPool m_pool;
AudioGroupSampleDirectory m_sdir;
const unsigned char* m_samp = nullptr;
SystemString m_groupPath; /* Typically only set by editor */
std::string m_groupPath; /* Typically only set by editor */
bool m_valid;
public:
SystemString getSampleBasePath(SampleId sfxId) const;
std::string getSampleBasePath(SampleId sfxId) const;
explicit operator bool() const { return m_valid; }
AudioGroup() = default;
explicit AudioGroup(const AudioGroupData& data) { assign(data); }
explicit AudioGroup(SystemStringView groupPath) { assign(groupPath); }
explicit AudioGroup(const AudioGroup& data, SystemStringView groupPath) { assign(data, groupPath); }
explicit AudioGroup(std::string_view groupPath) { assign(groupPath); }
explicit AudioGroup(const AudioGroup& data, std::string_view groupPath) { assign(data, groupPath); }
void assign(const AudioGroupData& data);
void assign(SystemStringView groupPath);
void assign(const AudioGroup& data, SystemStringView groupPath);
void setGroupPath(SystemStringView groupPath) { m_groupPath = groupPath; }
void assign(std::string_view groupPath);
void assign(const AudioGroup& data, std::string_view groupPath);
void setGroupPath(std::string_view groupPath) { m_groupPath = groupPath; }
const SampleEntry* getSample(SampleId sfxId) const;
std::pair<ObjToken<SampleEntryData>, const unsigned char*> getSampleData(SampleId sfxId,
const SampleEntry* sample) const;
SampleFileState getSampleFileState(SampleId sfxId, const SampleEntry* sample, SystemString* pathOut = nullptr) const;
SampleFileState getSampleFileState(SampleId sfxId, const SampleEntry* sample, std::string* pathOut = nullptr) const;
void patchSampleMetadata(SampleId sfxId, const SampleEntry* sample) const;
void makeWAVVersion(SampleId sfxId, const SampleEntry* sample) const;
void makeCompressedVersion(SampleId sfxId, const SampleEntry* sample) const;
@ -61,16 +61,16 @@ public:
explicit AudioGroupDatabase(const AudioGroupData& data) {
assign(data);
}
explicit AudioGroupDatabase(SystemStringView groupPath) {
explicit AudioGroupDatabase(std::string_view groupPath) {
assign(groupPath);
}
explicit AudioGroupDatabase(const AudioGroupDatabase& data, SystemStringView groupPath) {
explicit AudioGroupDatabase(const AudioGroupDatabase& data, std::string_view groupPath) {
assign(data, groupPath);
}
void renameSample(SampleId id, std::string_view str);
void deleteSample(SampleId id);
void copySampleInto(const SystemString& basePath, const SystemString& newBasePath);
void copySampleInto(const std::string& basePath, const std::string& newBasePath);
void importCHeader(std::string_view header);
std::string exportCHeader(std::string_view projectName, std::string_view groupName) const;

View File

@ -1196,7 +1196,7 @@ class AudioGroupPool {
public:
AudioGroupPool() = default;
static AudioGroupPool CreateAudioGroupPool(const AudioGroupData& data);
static AudioGroupPool CreateAudioGroupPool(SystemStringView groupPath);
static AudioGroupPool CreateAudioGroupPool(std::string_view groupPath);
const std::unordered_map<SoundMacroId, ObjToken<SoundMacro>>& soundMacros() const { return m_soundMacros; }
const std::unordered_map<TableId, ObjToken<std::unique_ptr<ITable>>>& tables() const { return m_tables; }

View File

@ -190,7 +190,7 @@ class AudioGroupProject {
public:
AudioGroupProject() = default;
static AudioGroupProject CreateAudioGroupProject(const AudioGroupData& data);
static AudioGroupProject CreateAudioGroupProject(SystemStringView groupPath);
static AudioGroupProject CreateAudioGroupProject(std::string_view groupPath);
static AudioGroupProject CreateAudioGroupProject(const AudioGroupProject& oldProj);
static void BootstrapObjectIDs(const AudioGroupData& data);

View File

@ -285,13 +285,13 @@ public:
return ret;
}
void loadLooseDSP(SystemStringView dspPath);
void loadLooseVADPCM(SystemStringView vadpcmPath);
void loadLooseWAV(SystemStringView wavPath);
void loadLooseDSP(std::string_view dspPath);
void loadLooseVADPCM(std::string_view vadpcmPath);
void loadLooseWAV(std::string_view wavPath);
void patchMetadataDSP(SystemStringView dspPath);
void patchMetadataVADPCM(SystemStringView vadpcmPath);
void patchMetadataWAV(SystemStringView wavPath);
void patchMetadataDSP(std::string_view dspPath);
void patchMetadataVADPCM(std::string_view vadpcmPath);
void patchMetadataWAV(std::string_view wavPath);
};
/* This double-wrapper allows Voices to keep a strong reference on
* a single instance of loaded loose data without being unexpectedly
@ -315,16 +315,16 @@ public:
return m_data->toDNA<DNAEn>(id);
}
void loadLooseData(SystemStringView basePath);
SampleFileState getFileState(SystemStringView basePath, SystemString* pathOut = nullptr) const;
void patchSampleMetadata(SystemStringView basePath) const;
void loadLooseData(std::string_view basePath);
SampleFileState getFileState(std::string_view basePath, std::string* pathOut = nullptr) const;
void patchSampleMetadata(std::string_view basePath) const;
};
private:
std::unordered_map<SampleId, ObjToken<Entry>> m_entries;
static void _extractWAV(SampleId id, const EntryData& ent, amuse::SystemStringView destDir,
static void _extractWAV(SampleId id, const EntryData& ent, std::string_view destDir,
const unsigned char* samp);
static void _extractCompressed(SampleId id, const EntryData& ent, amuse::SystemStringView destDir,
static void _extractCompressed(SampleId id, const EntryData& ent, std::string_view destDir,
const unsigned char* samp, bool compressWAV = false);
public:
@ -333,17 +333,17 @@ public:
AudioGroupSampleDirectory(athena::io::IStreamReader& r, const unsigned char* sampData, bool absOffs, N64DataTag);
AudioGroupSampleDirectory(athena::io::IStreamReader& r, bool absOffs, PCDataTag);
static AudioGroupSampleDirectory CreateAudioGroupSampleDirectory(const AudioGroupData& data);
static AudioGroupSampleDirectory CreateAudioGroupSampleDirectory(SystemStringView groupPath);
static AudioGroupSampleDirectory CreateAudioGroupSampleDirectory(std::string_view groupPath);
const std::unordered_map<SampleId, ObjToken<Entry>>& sampleEntries() const { return m_entries; }
std::unordered_map<SampleId, ObjToken<Entry>>& sampleEntries() { return m_entries; }
void extractWAV(SampleId id, amuse::SystemStringView destDir, const unsigned char* samp) const;
void extractAllWAV(amuse::SystemStringView destDir, const unsigned char* samp) const;
void extractCompressed(SampleId id, amuse::SystemStringView destDir, const unsigned char* samp) const;
void extractAllCompressed(amuse::SystemStringView destDir, const unsigned char* samp) const;
void extractWAV(SampleId id, std::string_view destDir, const unsigned char* samp) const;
void extractAllWAV(std::string_view destDir, const unsigned char* samp) const;
void extractCompressed(SampleId id, std::string_view destDir, const unsigned char* samp) const;
void extractAllCompressed(std::string_view destDir, const unsigned char* samp) const;
void reloadSampleData(SystemStringView groupPath);
void reloadSampleData(std::string_view groupPath);
std::pair<std::vector<uint8_t>, std::vector<uint8_t>> toGCNData(const AudioGroupDatabase& group) const;

View File

@ -22,6 +22,7 @@
#define WIN32_LEAN_AND_MEAN 1
#endif
#include <Windows.h>
#include <nowide/stackstring.hpp>
#endif
#if __SWITCH__
@ -325,44 +326,37 @@ inline typename std::enable_if_t<!std::is_base_of_v<IObj, Tp>, ObjToken<Tp>> Mak
#endif
#endif
#ifdef _WIN32
using SystemString = std::wstring;
using SystemStringView = std::wstring_view;
using SystemChar = wchar_t;
#ifndef _SYS_STR
#define _SYS_STR(val) L##val
#endif
typedef struct _stat Sstat;
inline int Mkdir(const wchar_t* path, int) { return _wmkdir(path); }
inline int Stat(const wchar_t* path, Sstat* statout) { return _wstat(path, statout); }
#if _WIN32
static inline int Mkdir(const char* path, int) {
const nowide::wstackstring str(path);
return _wmkdir(str.get());
}
using Sstat = struct ::_stat64;
static inline int Stat(const char* path, Sstat* statout) {
const nowide::wstackstring wpath(path);
return _wstat64(wpath.get(), statout);
}
#else
using SystemString = std::string;
using SystemStringView = std::string_view;
using SystemChar = char;
#ifndef _SYS_STR
#define _SYS_STR(val) val
#endif
static inline int Mkdir(const char* path, mode_t mode) { return CreateDirectoryA(path, mode); }
typedef struct stat Sstat;
inline int Mkdir(const char* path, mode_t mode) { return mkdir(path, mode); }
inline int Stat(const char* path, Sstat* statout) { return stat(path, statout); }
static inline int Stat(const char* path, Sstat* statout) { return stat(path, statout); }
#endif
inline int Rename(const SystemChar* oldpath, const SystemChar* newpath) {
inline int Rename(const char* oldpath, const char* newpath) {
#if _WIN32
// return _wrename(oldpath, newpath);
return MoveFileExW(oldpath, newpath, MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH) == 0;
const nowide::wstackstring woldpath(oldpath);
const nowide::wstackstring wnewpath(newpath);
return MoveFileExW(woldpath.get(), wnewpath.get(), MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH) == 0;
#else
return rename(oldpath, newpath);
#endif
}
inline int CompareCaseInsensitive(const char* a, const char* b) {
#if _WIN32
inline int CompareCaseInsensitive(const char* a, const char* b) { return _stricmp(a, b); }
#endif
inline int CompareCaseInsensitive(const SystemChar* a, const SystemChar* b) {
#if _WIN32
return _wcsicmp(a, b);
return _stricmp(a, b);
#else
return strcasecmp(a, b);
#endif
@ -389,20 +383,12 @@ constexpr T ClampFull(float in) noexcept {
#define M_PIF 3.14159265358979323846f /* pi */
#endif
inline const SystemChar* StrRChr(const SystemChar* str, SystemChar ch) {
#if _WIN32
return wcsrchr(str, ch);
#else
inline const char* StrRChr(const char* str, char ch) {
return strrchr(str, ch);
#endif
}
inline SystemChar* StrRChr(SystemChar* str, SystemChar ch) {
#if _WIN32
return wcsrchr(str, ch);
#else
inline char* StrRChr(char* str, char ch) {
return strrchr(str, ch);
#endif
}
inline int FSeek(FILE* fp, int64_t offset, int whence) {
@ -425,9 +411,11 @@ inline int64_t FTell(FILE* fp) {
#endif
}
inline FILE* FOpen(const SystemChar* path, const SystemChar* mode) {
inline FILE* FOpen(const char* path, const char* mode) {
#if _WIN32
FILE* fp = _wfopen(path, mode);
const nowide::wstackstring wpath(path);
const nowide::wshort_stackstring wmode(mode);
FILE* fp = _wfopen(wpath.get(), wmode.get());
if (!fp)
return nullptr;
#else
@ -438,15 +426,16 @@ inline FILE* FOpen(const SystemChar* path, const SystemChar* mode) {
return fp;
}
inline void Unlink(const SystemChar* file) {
inline void Unlink(const char* file) {
#if _WIN32
_wunlink(file);
const nowide::wstackstring wfile(file);
_wunlink(wfile.get());
#else
unlink(file);
#endif
}
bool Copy(const SystemChar* from, const SystemChar* to);
bool Copy(const char* from, const char* to);
#undef bswap16
#undef bswap32

View File

@ -31,11 +31,11 @@ public:
SongData(std::unique_ptr<uint8_t[]>&& data, size_t size, int16_t groupId, int16_t setupId)
: m_data(std::move(data)), m_size(size), m_groupId(groupId), m_setupId(setupId) {}
};
static const SystemChar* TypeToName(Type tp);
static Type DetectContainerType(const SystemChar* path);
static std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> LoadContainer(const SystemChar* path);
static std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> LoadContainer(const SystemChar* path,
static const char* TypeToName(Type tp);
static Type DetectContainerType(const char* path);
static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadContainer(const char* path);
static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadContainer(const char* path,
Type& typeOut);
static std::vector<std::pair<SystemString, SongData>> LoadSongs(const SystemChar* path);
static std::vector<std::pair<std::string, SongData>> LoadSongs(const char* path);
};
} // namespace amuse

View File

@ -8,49 +8,43 @@
namespace amuse {
/**
* @brief Case-insensitive comparator for std::map sorting
*/
struct CaseInsensitiveCompare {
bool operator()(std::string_view lhs, std::string_view rhs) const {
#if _WIN32
if (_stricmp(lhs.data(), rhs.data()) < 0)
#else
if (strcasecmp(lhs.data(), rhs.data()) < 0)
#endif
return true;
return false;
}
// Allow heterogeneous lookup with maps that use this comparator.
using is_transparent = void;
#if _WIN32
bool operator()(std::wstring_view lhs, std::wstring_view rhs) const {
if (_wcsicmp(lhs.data(), rhs.data()) < 0)
return true;
return false;
bool operator()(std::string_view lhs, std::string_view rhs) const {
return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), [](char lhs, char rhs) {
return std::tolower(static_cast<unsigned char>(lhs)) < std::tolower(static_cast<unsigned char>(rhs));
});
}
#endif
};
class DirectoryEnumerator {
public:
enum class Mode { Native, DirsSorted, FilesSorted, DirsThenFilesSorted };
struct Entry {
SystemString m_path;
SystemString m_name;
std::string m_path;
std::string m_name;
size_t m_fileSz;
bool m_isDir;
Entry(const SystemString& path, const SystemChar* name, size_t sz, bool isDir)
: m_path(path), m_name(name), m_fileSz(sz), m_isDir(isDir) {}
Entry(std::string path, std::string name, size_t sz, bool isDir)
: m_path(std::move(path)), m_name(std::move(name)), m_fileSz(sz), m_isDir(isDir) {}
};
private:
std::vector<Entry> m_entries;
public:
DirectoryEnumerator(SystemStringView path, Mode mode = Mode::DirsThenFilesSorted, bool sizeSort = false,
DirectoryEnumerator(std::string_view path, Mode mode = Mode::DirsThenFilesSorted, bool sizeSort = false,
bool reverse = false, bool noHidden = false);
explicit operator bool() const { return m_entries.size() != 0; }
size_t size() const { return m_entries.size(); }
std::vector<Entry>::const_iterator begin() const { return m_entries.cbegin(); }
std::vector<Entry>::const_iterator end() const { return m_entries.cend(); }
explicit operator bool() const { return !m_entries.empty(); }
[[nodiscard]] size_t size() const { return m_entries.size(); }
[[nodiscard]] std::vector<Entry>::const_iterator begin() const { return m_entries.cbegin(); }
[[nodiscard]] std::vector<Entry>::const_iterator end() const { return m_entries.cend(); }
};
} // namespace amuse

View File

@ -19,7 +19,7 @@ void AudioGroup::assign(const AudioGroupData& data) {
m_sdir = AudioGroupSampleDirectory::CreateAudioGroupSampleDirectory(data);
m_samp = data.getSamp();
}
void AudioGroup::assign(SystemStringView groupPath) {
void AudioGroup::assign(std::string_view groupPath) {
/* Reverse order when loading intermediates */
m_groupPath = groupPath;
m_sdir = AudioGroupSampleDirectory::CreateAudioGroupSampleDirectory(groupPath);
@ -27,7 +27,7 @@ void AudioGroup::assign(SystemStringView groupPath) {
m_proj = AudioGroupProject::CreateAudioGroupProject(groupPath);
m_samp = nullptr;
}
void AudioGroup::assign(const AudioGroup& data, SystemStringView groupPath) {
void AudioGroup::assign(const AudioGroup& data, std::string_view groupPath) {
/* Reverse order when loading intermediates */
m_groupPath = groupPath;
m_sdir = AudioGroupSampleDirectory::CreateAudioGroupSampleDirectory(groupPath);
@ -43,27 +43,23 @@ const SampleEntry* AudioGroup::getSample(SampleId sfxId) const {
return search->second.get();
}
SystemString AudioGroup::getSampleBasePath(SampleId sfxId) const {
#if _WIN32
return m_groupPath + _SYS_STR('/') + athena::utility::utf8ToWide(SampleId::CurNameDB->resolveNameFromId(sfxId));
#else
return m_groupPath + _SYS_STR('/') + SampleId::CurNameDB->resolveNameFromId(sfxId).data();
#endif
std::string AudioGroup::getSampleBasePath(SampleId sfxId) const {
return m_groupPath + '/' + SampleId::CurNameDB->resolveNameFromId(sfxId).data();
}
std::pair<ObjToken<SampleEntryData>, const unsigned char*> AudioGroup::getSampleData(SampleId sfxId,
const SampleEntry* sample) const {
if (sample->m_data->m_looseData) {
SystemString basePath = getSampleBasePath(sfxId);
std::string basePath = getSampleBasePath(sfxId);
const_cast<SampleEntry*>(sample)->loadLooseData(basePath);
return {sample->m_data, sample->m_data->m_looseData.get()};
}
return {sample->m_data, m_samp + sample->m_data->m_sampleOff};
}
SampleFileState AudioGroup::getSampleFileState(SampleId sfxId, const SampleEntry* sample, SystemString* pathOut) const {
SampleFileState AudioGroup::getSampleFileState(SampleId sfxId, const SampleEntry* sample, std::string* pathOut) const {
if (sample->m_data->m_looseData) {
SystemString basePath = getSampleBasePath(sfxId);
std::string basePath = getSampleBasePath(sfxId);
return sample->getFileState(basePath, pathOut);
}
if (sample->m_data->isFormatDSP() || sample->m_data->getSampleFormat() == SampleFormat::N64)
@ -73,7 +69,7 @@ SampleFileState AudioGroup::getSampleFileState(SampleId sfxId, const SampleEntry
void AudioGroup::patchSampleMetadata(SampleId sfxId, const SampleEntry* sample) const {
if (sample->m_data->m_looseData) {
SystemString basePath = getSampleBasePath(sfxId);
std::string basePath = getSampleBasePath(sfxId);
sample->patchSampleMetadata(basePath);
}
}
@ -91,25 +87,25 @@ void AudioGroup::makeCompressedVersion(SampleId sfxId, const SampleEntry* sample
}
void AudioGroupDatabase::renameSample(SampleId id, std::string_view str) {
SystemString oldBasePath = getSampleBasePath(id);
std::string oldBasePath = getSampleBasePath(id);
SampleId::CurNameDB->rename(id, str);
SystemString newBasePath = getSampleBasePath(id);
Rename((oldBasePath + _SYS_STR(".wav")).c_str(), (newBasePath + _SYS_STR(".wav")).c_str());
Rename((oldBasePath + _SYS_STR(".dsp")).c_str(), (newBasePath + _SYS_STR(".dsp")).c_str());
Rename((oldBasePath + _SYS_STR(".vadpcm")).c_str(), (newBasePath + _SYS_STR(".vadpcm")).c_str());
std::string newBasePath = getSampleBasePath(id);
Rename((oldBasePath + ".wav").c_str(), (newBasePath + ".wav").c_str());
Rename((oldBasePath + ".dsp").c_str(), (newBasePath + ".dsp").c_str());
Rename((oldBasePath + ".vadpcm").c_str(), (newBasePath + ".vadpcm").c_str());
}
void AudioGroupDatabase::deleteSample(SampleId id) {
SystemString basePath = getSampleBasePath(id);
Unlink((basePath + _SYS_STR(".wav")).c_str());
Unlink((basePath + _SYS_STR(".dsp")).c_str());
Unlink((basePath + _SYS_STR(".vadpcm")).c_str());
std::string basePath = getSampleBasePath(id);
Unlink((basePath + ".wav").c_str());
Unlink((basePath + ".dsp").c_str());
Unlink((basePath + ".vadpcm").c_str());
}
void AudioGroupDatabase::copySampleInto(const SystemString& basePath, const SystemString& newBasePath) {
Copy((basePath + _SYS_STR(".wav")).c_str(), (newBasePath + _SYS_STR(".wav")).c_str());
Copy((basePath + _SYS_STR(".dsp")).c_str(), (newBasePath + _SYS_STR(".dsp")).c_str());
Copy((basePath + _SYS_STR(".vadpcm")).c_str(), (newBasePath + _SYS_STR(".vadpcm")).c_str());
void AudioGroupDatabase::copySampleInto(const std::string& basePath, const std::string& newBasePath) {
Copy((basePath + ".wav").c_str(), (newBasePath + ".wav").c_str());
Copy((basePath + ".dsp").c_str(), (newBasePath + ".dsp").c_str());
Copy((basePath + ".vadpcm").c_str(), (newBasePath + ".vadpcm").c_str());
}
void AudioGroupDatabase::_recursiveRenameMacro(SoundMacroId id, std::string_view str, int& macroIdx,

View File

@ -204,10 +204,10 @@ AudioGroupPool AudioGroupPool::CreateAudioGroupPool(const AudioGroupData& data)
}
}
AudioGroupPool AudioGroupPool::CreateAudioGroupPool(SystemStringView groupPath) {
AudioGroupPool AudioGroupPool::CreateAudioGroupPool(std::string_view groupPath) {
AudioGroupPool ret;
SystemString poolPath(groupPath);
poolPath += _SYS_STR("/!pool.yaml");
std::string poolPath(groupPath);
poolPath += "/!pool.yaml";
athena::io::FileReader fi(poolPath, 32 * 1024, false);
if (!fi.hasError()) {

View File

@ -383,10 +383,10 @@ void SFXGroupIndex::fromYAML(athena::io::YAMLDocReader& r) {
}
}
AudioGroupProject AudioGroupProject::CreateAudioGroupProject(SystemStringView groupPath) {
AudioGroupProject AudioGroupProject::CreateAudioGroupProject(std::string_view groupPath) {
AudioGroupProject ret;
SystemString projPath(groupPath);
projPath += _SYS_STR("/!project.yaml");
std::string projPath(groupPath);
projPath += "/!project.yaml";
athena::io::FileReader fi(projPath, 32 * 1024, false);
if (!fi.hasError()) {

View File

@ -155,7 +155,7 @@ void AudioGroupSampleDirectory::EntryData::setLoopStartSample(atUint32 sample) {
}
}
void AudioGroupSampleDirectory::EntryData::loadLooseDSP(SystemStringView dspPath) {
void AudioGroupSampleDirectory::EntryData::loadLooseDSP(std::string_view dspPath) {
athena::io::FileReader r(dspPath);
if (!r.hasError()) {
DSPADPCMHeader header;
@ -181,7 +181,7 @@ void AudioGroupSampleDirectory::EntryData::loadLooseDSP(SystemStringView dspPath
}
}
void AudioGroupSampleDirectory::EntryData::loadLooseVADPCM(SystemStringView vadpcmPath) {
void AudioGroupSampleDirectory::EntryData::loadLooseVADPCM(std::string_view vadpcmPath) {
athena::io::FileReader r(vadpcmPath);
if (!r.hasError()) {
VADPCMHeader header;
@ -202,7 +202,7 @@ void AudioGroupSampleDirectory::EntryData::loadLooseVADPCM(SystemStringView vadp
}
}
void AudioGroupSampleDirectory::EntryData::loadLooseWAV(SystemStringView wavPath) {
void AudioGroupSampleDirectory::EntryData::loadLooseWAV(std::string_view wavPath) {
athena::io::FileReader r(wavPath);
if (!r.hasError()) {
atUint32 riffMagic = r.readUint32Little();
@ -242,10 +242,10 @@ void AudioGroupSampleDirectory::EntryData::loadLooseWAV(SystemStringView wavPath
}
}
void AudioGroupSampleDirectory::Entry::loadLooseData(SystemStringView basePath) {
SystemString wavPath = SystemString(basePath) + _SYS_STR(".wav");
SystemString dspPath = SystemString(basePath) + _SYS_STR(".dsp");
SystemString vadpcmPath = SystemString(basePath) + _SYS_STR(".vadpcm");
void AudioGroupSampleDirectory::Entry::loadLooseData(std::string_view basePath) {
std::string wavPath = std::string(basePath) + ".wav";
std::string dspPath = std::string(basePath) + ".dsp";
std::string vadpcmPath = std::string(basePath) + ".vadpcm";
Sstat wavStat, dspStat, vadpcmStat;
bool wavValid = !Stat(wavPath.c_str(), &wavStat) && S_ISREG(wavStat.st_mode);
bool dspValid = !Stat(dspPath.c_str(), &dspStat) && S_ISREG(dspStat.st_mode);
@ -287,10 +287,10 @@ void AudioGroupSampleDirectory::Entry::loadLooseData(SystemStringView basePath)
}
}
SampleFileState AudioGroupSampleDirectory::Entry::getFileState(SystemStringView basePath, SystemString* pathOut) const {
SystemString wavPath = SystemString(basePath) + _SYS_STR(".wav");
SystemString dspPath = SystemString(basePath) + _SYS_STR(".dsp");
SystemString vadpcmPath = SystemString(basePath) + _SYS_STR(".vadpcm");
SampleFileState AudioGroupSampleDirectory::Entry::getFileState(std::string_view basePath, std::string* pathOut) const {
std::string wavPath = std::string(basePath) + ".wav";
std::string dspPath = std::string(basePath) + ".dsp";
std::string vadpcmPath = std::string(basePath) + ".vadpcm";
Sstat wavStat, dspStat, vadpcmStat;
bool wavValid = !Stat(wavPath.c_str(), &wavStat) && S_ISREG(wavStat.st_mode);
bool dspValid = !Stat(dspPath.c_str(), &dspStat) && S_ISREG(dspStat.st_mode);
@ -351,7 +351,7 @@ SampleFileState AudioGroupSampleDirectory::Entry::getFileState(SystemStringView
return SampleFileState::WAVNoCompressed;
}
void AudioGroupSampleDirectory::EntryData::patchMetadataDSP(SystemStringView dspPath) {
void AudioGroupSampleDirectory::EntryData::patchMetadataDSP(std::string_view dspPath) {
athena::io::FileReader r(dspPath);
if (!r.hasError()) {
DSPADPCMHeader head;
@ -394,7 +394,7 @@ void AudioGroupSampleDirectory::EntryData::patchMetadataDSP(SystemStringView dsp
}
}
void AudioGroupSampleDirectory::EntryData::patchMetadataVADPCM(SystemStringView vadpcmPath) {
void AudioGroupSampleDirectory::EntryData::patchMetadataVADPCM(std::string_view vadpcmPath) {
athena::io::FileWriter w(vadpcmPath, false);
if (!w.hasError()) {
w.seek(0, athena::SeekOrigin::Begin);
@ -408,7 +408,7 @@ void AudioGroupSampleDirectory::EntryData::patchMetadataVADPCM(SystemStringView
}
}
void AudioGroupSampleDirectory::EntryData::patchMetadataWAV(SystemStringView wavPath) {
void AudioGroupSampleDirectory::EntryData::patchMetadataWAV(std::string_view wavPath) {
athena::io::FileReader r(wavPath);
if (!r.hasError()) {
atUint32 riffMagic = r.readUint32Little();
@ -513,10 +513,11 @@ void AudioGroupSampleDirectory::EntryData::patchMetadataWAV(SystemStringView wav
}
/* File timestamps reflect actual audio content, not loop/pitch data */
static void SetAudioFileTime(const SystemString& path, const Sstat& stat) {
static void SetAudioFileTime(const std::string& path, const Sstat& stat) {
#if _WIN32
__utimbuf64 times = {stat.st_atime, stat.st_mtime};
_wutime64(path.c_str(), &times);
const nowide::wstackstring wpath(path);
_wutime64(wpath.get(), &times);
#else
#if __APPLE__
struct timespec times[] = {stat.st_atimespec, stat.st_mtimespec};
@ -529,10 +530,10 @@ static void SetAudioFileTime(const SystemString& path, const Sstat& stat) {
#endif
}
void AudioGroupSampleDirectory::Entry::patchSampleMetadata(SystemStringView basePath) const {
SystemString wavPath = SystemString(basePath) + _SYS_STR(".wav");
SystemString dspPath = SystemString(basePath) + _SYS_STR(".dsp");
SystemString vadpcmPath = SystemString(basePath) + _SYS_STR(".vadpcm");
void AudioGroupSampleDirectory::Entry::patchSampleMetadata(std::string_view basePath) const {
std::string wavPath = std::string(basePath) + ".wav";
std::string dspPath = std::string(basePath) + ".dsp";
std::string vadpcmPath = std::string(basePath) + ".vadpcm";
Sstat wavStat, dspStat, vadpcmStat;
bool wavValid = !Stat(wavPath.c_str(), &wavStat) && S_ISREG(wavStat.st_mode);
bool dspValid = !Stat(dspPath.c_str(), &dspStat) && S_ISREG(dspStat.st_mode);
@ -556,32 +557,28 @@ void AudioGroupSampleDirectory::Entry::patchSampleMetadata(SystemStringView base
}
}
AudioGroupSampleDirectory AudioGroupSampleDirectory::CreateAudioGroupSampleDirectory(SystemStringView groupPath) {
AudioGroupSampleDirectory AudioGroupSampleDirectory::CreateAudioGroupSampleDirectory(std::string_view groupPath) {
AudioGroupSampleDirectory ret;
DirectoryEnumerator de(groupPath, DirectoryEnumerator::Mode::FilesSorted);
for (const DirectoryEnumerator::Entry& ent : de) {
if (ent.m_name.size() < 4)
continue;
SystemString baseName;
SystemString basePath;
if (!CompareCaseInsensitive(ent.m_name.data() + ent.m_name.size() - 4, _SYS_STR(".dsp")) ||
!CompareCaseInsensitive(ent.m_name.data() + ent.m_name.size() - 4, _SYS_STR(".wav"))) {
baseName = SystemString(ent.m_name.begin(), ent.m_name.begin() + ent.m_name.size() - 4);
basePath = SystemString(ent.m_path.begin(), ent.m_path.begin() + ent.m_path.size() - 4);
std::string baseName;
std::string basePath;
if (!CompareCaseInsensitive(ent.m_name.data() + ent.m_name.size() - 4, ".dsp") ||
!CompareCaseInsensitive(ent.m_name.data() + ent.m_name.size() - 4, ".wav")) {
baseName = std::string(ent.m_name.begin(), ent.m_name.begin() + ent.m_name.size() - 4);
basePath = std::string(ent.m_path.begin(), ent.m_path.begin() + ent.m_path.size() - 4);
} else if (ent.m_name.size() > 7 &&
!CompareCaseInsensitive(ent.m_name.data() + ent.m_name.size() - 7, _SYS_STR(".vadpcm"))) {
baseName = SystemString(ent.m_name.begin(), ent.m_name.begin() + ent.m_name.size() - 7);
basePath = SystemString(ent.m_path.begin(), ent.m_path.begin() + ent.m_path.size() - 7);
!CompareCaseInsensitive(ent.m_name.data() + ent.m_name.size() - 7, ".vadpcm")) {
baseName = std::string(ent.m_name.begin(), ent.m_name.begin() + ent.m_name.size() - 7);
basePath = std::string(ent.m_path.begin(), ent.m_path.begin() + ent.m_path.size() - 7);
} else
continue;
ObjectId sampleId = SampleId::CurNameDB->generateId(NameDB::Type::Sample);
#ifdef _WIN32
SampleId::CurNameDB->registerPair(athena::utility::wideToUtf8(baseName), sampleId);
#else
SampleId::CurNameDB->registerPair(baseName, sampleId);
#endif
auto& entry = ret.m_entries[sampleId];
entry = MakeObj<Entry>();
@ -591,18 +588,14 @@ AudioGroupSampleDirectory AudioGroupSampleDirectory::CreateAudioGroupSampleDirec
return ret;
}
void AudioGroupSampleDirectory::_extractWAV(SampleId id, const EntryData& ent, amuse::SystemStringView destDir,
void AudioGroupSampleDirectory::_extractWAV(SampleId id, const EntryData& ent, std::string_view destDir,
const unsigned char* samp) {
SystemString path(destDir);
path += _SYS_STR("/");
#ifdef _WIN32
path += athena::utility::utf8ToWide(SampleId::CurNameDB->resolveNameFromId(id));
#else
std::string path(destDir);
path += "/";
path += SampleId::CurNameDB->resolveNameFromId(id);
#endif
SystemString dspPath = path;
path += _SYS_STR(".wav");
dspPath += _SYS_STR(".dsp");
std::string dspPath = path;
path += ".wav";
dspPath += ".dsp";
athena::io::FileWriter w(path);
SampleFormat fmt = SampleFormat(ent.m_numSamples >> 24);
@ -688,7 +681,7 @@ void AudioGroupSampleDirectory::_extractWAV(SampleId id, const EntryData& ent, a
}
}
void AudioGroupSampleDirectory::extractWAV(SampleId id, amuse::SystemStringView destDir,
void AudioGroupSampleDirectory::extractWAV(SampleId id, std::string_view destDir,
const unsigned char* samp) const {
auto search = m_entries.find(id);
if (search == m_entries.cend())
@ -696,12 +689,12 @@ void AudioGroupSampleDirectory::extractWAV(SampleId id, amuse::SystemStringView
_extractWAV(id, *search->second->m_data, destDir, samp + search->second->m_data->m_sampleOff);
}
void AudioGroupSampleDirectory::extractAllWAV(amuse::SystemStringView destDir, const unsigned char* samp) const {
void AudioGroupSampleDirectory::extractAllWAV(std::string_view destDir, const unsigned char* samp) const {
for (const auto& ent : m_entries)
_extractWAV(ent.first, *ent.second->m_data, destDir, samp + ent.second->m_data->m_sampleOff);
}
void AudioGroupSampleDirectory::_extractCompressed(SampleId id, const EntryData& ent, amuse::SystemStringView destDir,
void AudioGroupSampleDirectory::_extractCompressed(SampleId id, const EntryData& ent, std::string_view destDir,
const unsigned char* samp, bool compressWAV) {
SampleFormat fmt = ent.getSampleFormat();
if (!compressWAV && (fmt == SampleFormat::PCM || fmt == SampleFormat::PCM_PC)) {
@ -709,13 +702,9 @@ void AudioGroupSampleDirectory::_extractCompressed(SampleId id, const EntryData&
return;
}
amuse::SystemString path(destDir);
path += _SYS_STR("/");
#ifdef _WIN32
path += athena::utility::utf8ToWide(SampleId::CurNameDB->resolveNameFromId(id));
#else
std::string path(destDir);
path += "/";
path += SampleId::CurNameDB->resolveNameFromId(id);
#endif
uint32_t numSamples = ent.getNumSamples();
atUint64 dataLen = 0;
@ -738,13 +727,13 @@ void AudioGroupSampleDirectory::_extractCompressed(SampleId id, const EntryData&
header.x44_loop_ps = ent.m_ADPCMParms.dsp.m_lps;
header.m_pitch = ent.m_pitch;
path += _SYS_STR(".dsp");
path += ".dsp";
athena::io::FileWriter w(path);
header.write(w);
dataLen = (header.x4_num_nibbles + 1) / 2;
w.writeUBytes(samp, dataLen);
} else if (fmt == SampleFormat::N64) {
path += _SYS_STR(".vadpcm");
path += ".vadpcm";
athena::io::FileWriter w(path);
VADPCMHeader header;
header.m_pitchSampleRate = ent.m_pitch << 24;
@ -780,7 +769,7 @@ void AudioGroupSampleDirectory::_extractCompressed(SampleId id, const EntryData&
}
DSPCorrelateCoefs(samps, numSamples, header.x1c_coef);
path += _SYS_STR(".dsp");
path += ".dsp";
athena::io::FileWriter w(path);
header.write(w);
@ -827,7 +816,7 @@ void AudioGroupSampleDirectory::_extractCompressed(SampleId id, const EntryData&
}
}
void AudioGroupSampleDirectory::extractCompressed(SampleId id, amuse::SystemStringView destDir,
void AudioGroupSampleDirectory::extractCompressed(SampleId id, std::string_view destDir,
const unsigned char* samp) const {
auto search = m_entries.find(id);
if (search == m_entries.cend())
@ -835,38 +824,32 @@ void AudioGroupSampleDirectory::extractCompressed(SampleId id, amuse::SystemStri
_extractCompressed(id, *search->second->m_data, destDir, samp + search->second->m_data->m_sampleOff);
}
void AudioGroupSampleDirectory::extractAllCompressed(amuse::SystemStringView destDir, const unsigned char* samp) const {
void AudioGroupSampleDirectory::extractAllCompressed(std::string_view destDir, const unsigned char* samp) const {
for (const auto& ent : m_entries)
_extractCompressed(ent.first, *ent.second->m_data, destDir, samp + ent.second->m_data->m_sampleOff);
}
void AudioGroupSampleDirectory::reloadSampleData(SystemStringView groupPath) {
void AudioGroupSampleDirectory::reloadSampleData(std::string_view groupPath) {
DirectoryEnumerator de(groupPath, DirectoryEnumerator::Mode::FilesSorted);
for (const DirectoryEnumerator::Entry& ent : de) {
if (ent.m_name.size() < 4)
continue;
SystemString baseName;
SystemString basePath;
if (!CompareCaseInsensitive(ent.m_name.data() + ent.m_name.size() - 4, _SYS_STR(".dsp")) ||
!CompareCaseInsensitive(ent.m_name.data() + ent.m_name.size() - 4, _SYS_STR(".wav"))) {
baseName = SystemString(ent.m_name.begin(), ent.m_name.begin() + ent.m_name.size() - 4);
basePath = SystemString(ent.m_path.begin(), ent.m_path.begin() + ent.m_path.size() - 4);
std::string baseName;
std::string basePath;
if (!CompareCaseInsensitive(ent.m_name.data() + ent.m_name.size() - 4, ".dsp") ||
!CompareCaseInsensitive(ent.m_name.data() + ent.m_name.size() - 4, ".wav")) {
baseName = std::string(ent.m_name.begin(), ent.m_name.begin() + ent.m_name.size() - 4);
basePath = std::string(ent.m_path.begin(), ent.m_path.begin() + ent.m_path.size() - 4);
} else if (ent.m_name.size() > 7 &&
!CompareCaseInsensitive(ent.m_name.data() + ent.m_name.size() - 7, _SYS_STR(".vadpcm"))) {
baseName = SystemString(ent.m_name.begin(), ent.m_name.begin() + ent.m_name.size() - 7);
basePath = SystemString(ent.m_path.begin(), ent.m_path.begin() + ent.m_path.size() - 7);
!CompareCaseInsensitive(ent.m_name.data() + ent.m_name.size() - 7, ".vadpcm")) {
baseName = std::string(ent.m_name.begin(), ent.m_name.begin() + ent.m_name.size() - 7);
basePath = std::string(ent.m_path.begin(), ent.m_path.begin() + ent.m_path.size() - 7);
} else
continue;
#ifdef _WIN32
std::string baseNameStd = athena::utility::wideToUtf8(baseName);
#else
std::string& baseNameStd = baseName;
#endif
if (SampleId::CurNameDB->m_stringToId.find(baseNameStd) == SampleId::CurNameDB->m_stringToId.end()) {
if (SampleId::CurNameDB->m_stringToId.find(baseName) == SampleId::CurNameDB->m_stringToId.end()) {
ObjectId sampleId = SampleId::CurNameDB->generateId(NameDB::Type::Sample);
SampleId::CurNameDB->registerPair(baseNameStd, sampleId);
SampleId::CurNameDB->registerPair(baseName, sampleId);
auto& entry = m_entries[sampleId];
entry = MakeObj<Entry>();
@ -887,8 +870,8 @@ AudioGroupSampleDirectory::toGCNData(const AudioGroupDatabase& group) const {
size_t sampleOffset = 0;
size_t adpcmOffset = 0;
for (const auto& ent : SortUnorderedMap(m_entries)) {
amuse::SystemString path = group.getSampleBasePath(ent.first);
path += _SYS_STR(".dsp");
std::string path = group.getSampleBasePath(ent.first);
path += ".dsp";
SampleFileState state = group.getSampleFileState(ent.first, ent.second.get().get(), &path);
switch (state) {
case SampleFileState::MemoryOnlyWAV:

View File

@ -12,9 +12,11 @@ using namespace std::literals;
namespace amuse {
static logvisor::Module Log("amuse");
bool Copy(const SystemChar* from, const SystemChar* to) {
bool Copy(const char* from, const char* to) {
#if _WIN32
return CopyFileW(from, to, FALSE) != 0;
const nowide::wstackstring wfrom(from);
const nowide::wstackstring wto(to);
return CopyFileW(wfrom.get(), wto.get(), FALSE) != 0;
#else
FILE* fi = fopen(from, "rb");
if (!fi)

View File

@ -94,42 +94,33 @@ static void* memmem(const void* haystack, size_t hlen, const void* needle, size_
return NULL;
}
static amuse::SystemString StrToSys(const std::string& str) {
std::wstring ret;
int len = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.size(), nullptr, 0);
ret.assign(len, L'\0');
MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.size(), &ret[0], len);
return ret;
}
#else
static amuse::SystemString StrToSys(const std::string& str) { return str; }
#endif
static std::string StrToSys(const std::string& str) { return str; }
namespace amuse {
const SystemChar* ContainerRegistry::TypeToName(Type tp) {
const char* ContainerRegistry::TypeToName(Type tp) {
switch (tp) {
case Type::Invalid:
default:
return nullptr;
case Type::Raw4:
return _SYS_STR("4 RAW Chunks");
return "4 RAW Chunks";
case Type::MetroidPrime:
return _SYS_STR("Metroid Prime (GCN)");
return "Metroid Prime (GCN)";
case Type::MetroidPrime2:
return _SYS_STR("Metroid Prime 2 (GCN)");
return "Metroid Prime 2 (GCN)";
case Type::RogueSquadronPC:
return _SYS_STR("Star Wars - Rogue Squadron (PC)");
return "Star Wars - Rogue Squadron (PC)";
case Type::RogueSquadronN64:
return _SYS_STR("Star Wars - Rogue Squadron (N64)");
return "Star Wars - Rogue Squadron (N64)";
case Type::Factor5N64Rev:
return _SYS_STR("Factor5 Revision ROM (N64)");
return "Factor5 Revision ROM (N64)";
case Type::RogueSquadron2:
return _SYS_STR("Star Wars - Rogue Squadron 2 (GCN)");
return "Star Wars - Rogue Squadron 2 (GCN)";
case Type::RogueSquadron3:
return _SYS_STR("Star Wars - Rogue Squadron 3 (GCN)");
return "Star Wars - Rogue Squadron 3 (GCN)";
}
}
@ -140,21 +131,21 @@ static size_t FileLength(FILE* fp) {
return size_t(endPos);
}
static SystemString ReadString(FILE* fp) {
static std::string ReadString(FILE* fp) {
char byte;
SystemString ret;
std::string ret;
while (fread(&byte, 1, 1, fp) == 1 && byte != 0)
ret.push_back(byte);
return ret;
}
static bool IsChunkExtension(const SystemChar* path, const SystemChar*& dotOut) {
const SystemChar* ext = StrRChr(path, _SYS_STR('.'));
static bool IsChunkExtension(const char* path, const char*& dotOut) {
const char* ext = StrRChr(path, '.');
if (ext) {
if (!CompareCaseInsensitive(ext, _SYS_STR(".poo")) || !CompareCaseInsensitive(ext, _SYS_STR(".pool")) ||
!CompareCaseInsensitive(ext, _SYS_STR(".pro")) || !CompareCaseInsensitive(ext, _SYS_STR(".proj")) ||
!CompareCaseInsensitive(ext, _SYS_STR(".sdi")) || !CompareCaseInsensitive(ext, _SYS_STR(".sdir")) ||
!CompareCaseInsensitive(ext, _SYS_STR(".sam")) || !CompareCaseInsensitive(ext, _SYS_STR(".samp"))) {
if (!CompareCaseInsensitive(ext, ".poo") || !CompareCaseInsensitive(ext, ".pool") ||
!CompareCaseInsensitive(ext, ".pro") || !CompareCaseInsensitive(ext, ".proj") ||
!CompareCaseInsensitive(ext, ".sdi") || !CompareCaseInsensitive(ext, ".sdir") ||
!CompareCaseInsensitive(ext, ".sam") || !CompareCaseInsensitive(ext, ".samp")) {
dotOut = ext;
return true;
}
@ -162,11 +153,11 @@ static bool IsChunkExtension(const SystemChar* path, const SystemChar*& dotOut)
return false;
}
static bool IsSongExtension(const SystemChar* path, const SystemChar*& dotOut) {
const SystemChar* ext = StrRChr(path, _SYS_STR('.'));
static bool IsSongExtension(const char* path, const char*& dotOut) {
const char* ext = StrRChr(path, '.');
if (ext) {
if (!CompareCaseInsensitive(ext, _SYS_STR(".son")) || !CompareCaseInsensitive(ext, _SYS_STR(".sng")) ||
!CompareCaseInsensitive(ext, _SYS_STR(".song"))) {
if (!CompareCaseInsensitive(ext, ".son") || !CompareCaseInsensitive(ext, ".sng") ||
!CompareCaseInsensitive(ext, ".song")) {
dotOut = ext;
return true;
}
@ -227,8 +218,8 @@ static bool ValidateMP1(FILE* fp) {
return false;
}
static std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> LoadMP1(FILE* fp) {
std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> ret;
static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadMP1(FILE* fp) {
std::vector<std::pair<std::string, IntrusiveAudioGroupData>> ret;
FileLength(fp);
uint32_t magic;
@ -271,7 +262,7 @@ static std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> LoadMP1(FIL
if (!memcmp(testBuf, "Audio/", 6)) {
FSeek(fp, offset, SEEK_SET);
ReadString(fp);
SystemString name = ReadString(fp);
std::string name = ReadString(fp);
uint32_t poolLen;
fread(&poolLen, 1, 4, fp);
@ -353,8 +344,8 @@ static bool ValidateMP1Songs(FILE* fp) {
return false;
}
static std::vector<std::pair<SystemString, ContainerRegistry::SongData>> LoadMP1Songs(FILE* fp) {
std::vector<std::pair<SystemString, ContainerRegistry::SongData>> ret;
static std::vector<std::pair<std::string, ContainerRegistry::SongData>> LoadMP1Songs(FILE* fp) {
std::vector<std::pair<std::string, ContainerRegistry::SongData>> ret;
FileLength(fp);
uint32_t magic;
@ -368,7 +359,7 @@ static std::vector<std::pair<SystemString, ContainerRegistry::SongData>> LoadMP1
fread(&nameCount, 1, 4, fp);
nameCount = SBig(nameCount);
std::unordered_map<uint32_t, SystemString> names;
std::unordered_map<uint32_t, std::string> names;
names.reserve(nameCount);
for (uint32_t i = 0; i < nameCount; ++i) {
FSeek(fp, 4, SEEK_CUR);
@ -428,7 +419,7 @@ static std::vector<std::pair<SystemString, ContainerRegistry::SongData>> LoadMP1
ret.emplace_back(std::move(search->second),
ContainerRegistry::SongData(std::move(song), sonLength, groupId, midiSetup));
else {
SystemString name = fmt::format(FMT_STRING(_SYS_STR("{:08X}")), id);
std::string name = fmt::format(FMT_STRING("{:08X}"), id);
ret.emplace_back(std::move(name), ContainerRegistry::SongData(std::move(song), sonLength, groupId, midiSetup));
}
@ -504,8 +495,8 @@ static bool ValidateMP2(FILE* fp) {
return false;
}
static std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> LoadMP2(FILE* fp) {
std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> ret;
static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadMP2(FILE* fp) {
std::vector<std::pair<std::string, IntrusiveAudioGroupData>> ret;
FileLength(fp);
uint32_t magic;
@ -565,7 +556,7 @@ static std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> LoadMP2(FIL
rem -= dsz;
}
fp = FOpen(_SYS_STR("amuse_tmp.dat"), _SYS_STR("rw"));
fp = FOpen("amuse_tmp.dat", "rw");
rewind(fp);
fwrite(buf, 1, decompSz, fp);
rewind(fp);
@ -573,7 +564,7 @@ static std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> LoadMP2(FIL
if (fread(testBuf, 1, 4, fp) == 4) {
if (amuse::SBig(*reinterpret_cast<uint32_t*>(testBuf)) == 0x1) {
FSeek(fp, offset + 4, SEEK_SET);
SystemString name = ReadString(fp);
std::string name = ReadString(fp);
FSeek(fp, 2, SEEK_CUR);
uint32_t poolSz;
@ -613,7 +604,7 @@ static std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> LoadMP2(FIL
}
if (compressed) {
fclose(fp);
Unlink(_SYS_STR("amuse_tmp.dat"));
Unlink("amuse_tmp.dat");
}
fp = old_fp;
FSeek(fp, origPos, SEEK_SET);
@ -749,8 +740,8 @@ static bool ValidateRS1PC(FILE* fp) {
return false;
}
static std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> LoadRS1PC(FILE* fp) {
std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> ret;
static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadRS1PC(FILE* fp) {
std::vector<std::pair<std::string, IntrusiveAudioGroupData>> ret;
size_t endPos = FileLength(fp);
uint32_t fstOff;
@ -796,7 +787,7 @@ static std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> LoadRS1PC(F
}
}
ret.emplace_back(_SYS_STR("Group"),
ret.emplace_back("Group",
IntrusiveAudioGroupData{proj.release(), projSz, pool.release(), poolSz, sdir.release(), sdirSz,
samp.release(), sampSz, false, PCDataTag{}});
}
@ -805,8 +796,8 @@ static std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> LoadRS1PC(F
return ret;
}
static std::vector<std::pair<SystemString, ContainerRegistry::SongData>> LoadRS1PCSongs(FILE* fp) {
std::vector<std::pair<SystemString, ContainerRegistry::SongData>> ret;
static std::vector<std::pair<std::string, ContainerRegistry::SongData>> LoadRS1PCSongs(FILE* fp) {
std::vector<std::pair<std::string, ContainerRegistry::SongData>> ret;
size_t endPos = FileLength(fp);
uint32_t fstOff;
@ -825,7 +816,7 @@ static std::vector<std::pair<SystemString, ContainerRegistry::SongData>> LoadRS1
FSeek(fp, entry.offset, SEEK_SET);
fread(song.get(), 1, entry.decompSz, fp);
SystemString name = StrToSys(entry.name);
std::string name = StrToSys(entry.name);
ret.emplace_back(
name, ContainerRegistry::SongData(std::move(song), entry.decompSz, -1, LookupRS1SongId(entry.name)));
}
@ -886,8 +877,8 @@ static bool ValidateRS1N64(FILE* fp) {
return false;
}
static std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> LoadRS1N64(FILE* fp) {
std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> ret;
static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadRS1N64(FILE* fp) {
std::vector<std::pair<std::string, IntrusiveAudioGroupData>> ret;
size_t endPos = FileLength(fp);
std::unique_ptr<uint8_t[]> data(new uint8_t[endPos]);
@ -966,7 +957,7 @@ static std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> LoadRS1N64(
}
}
ret.emplace_back(_SYS_STR("Group"),
ret.emplace_back("Group",
IntrusiveAudioGroupData{proj.release(), projSz, pool.release(), poolSz, sdir.release(), sdirSz,
samp.release(), sampSz, false, N64DataTag{}});
}
@ -974,8 +965,8 @@ static std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> LoadRS1N64(
return ret;
}
static std::vector<std::pair<SystemString, ContainerRegistry::SongData>> LoadRS1N64Songs(FILE* fp) {
std::vector<std::pair<SystemString, ContainerRegistry::SongData>> ret;
static std::vector<std::pair<std::string, ContainerRegistry::SongData>> LoadRS1N64Songs(FILE* fp) {
std::vector<std::pair<std::string, ContainerRegistry::SongData>> ret;
size_t endPos = FileLength(fp);
std::unique_ptr<uint8_t[]> data(new uint8_t[endPos]);
@ -1012,7 +1003,7 @@ static std::vector<std::pair<SystemString, ContainerRegistry::SongData>> LoadRS1
uncompress(song.get(), &outSz, dataSeg + ent.offset, ent.compSz);
}
SystemString name = StrToSys(ent.name);
std::string name = StrToSys(ent.name);
ret.emplace_back(name,
ContainerRegistry::SongData(std::move(song), ent.decompSz, -1, LookupRS1SongId(ent.name)));
}
@ -1072,8 +1063,8 @@ static bool ValidateFactor5N64Rev(FILE* fp) {
return false;
}
static std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> LoadFactor5N64Rev(FILE* fp) {
std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> ret;
static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadFactor5N64Rev(FILE* fp) {
std::vector<std::pair<std::string, IntrusiveAudioGroupData>> ret;
size_t endPos = FileLength(fp);
std::unique_ptr<uint8_t[]> data(new uint8_t[endPos]);
@ -1152,7 +1143,7 @@ static std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> LoadFactor5
}
}
ret.emplace_back(_SYS_STR("Group"),
ret.emplace_back("Group",
IntrusiveAudioGroupData{proj.release(), projSz, pool.release(), poolSz, sdir.release(), sdirSz,
samp.release(), sampSz, true, N64DataTag{}});
}
@ -1160,8 +1151,8 @@ static std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> LoadFactor5
return ret;
}
static std::vector<std::pair<SystemString, ContainerRegistry::SongData>> LoadFactor5N64RevSongs(FILE* fp) {
std::vector<std::pair<SystemString, ContainerRegistry::SongData>> ret;
static std::vector<std::pair<std::string, ContainerRegistry::SongData>> LoadFactor5N64RevSongs(FILE* fp) {
std::vector<std::pair<std::string, ContainerRegistry::SongData>> ret;
size_t endPos = FileLength(fp);
std::unique_ptr<uint8_t[]> data(new uint8_t[endPos]);
@ -1200,7 +1191,7 @@ static std::vector<std::pair<SystemString, ContainerRegistry::SongData>> LoadFac
uncompress(song.get(), &outSz, dataSeg + ent.offset, ent.compSz);
}
SystemString name = StrToSys(ent.name);
std::string name = StrToSys(ent.name);
ret.emplace_back(name, ContainerRegistry::SongData(std::move(song), ent.decompSz, -1, idx));
}
}
@ -1301,8 +1292,8 @@ static bool ValidateRS2(FILE* fp) {
return false;
}
static std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> LoadRS2(FILE* fp) {
std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> ret;
static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadRS2(FILE* fp) {
std::vector<std::pair<std::string, IntrusiveAudioGroupData>> ret;
size_t endPos = FileLength(fp);
uint64_t fstOff;
@ -1347,7 +1338,7 @@ static std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> LoadRS2(FIL
memmove(samp.get(), audData.get() + head.sampOff, head.sampLen);
if (head.projLen && head.poolLen && head.sdirLen && head.sampLen) {
SystemString name = fmt::format(FMT_STRING(_SYS_STR("GroupFile{:02d}")), j);
std::string name = fmt::format(FMT_STRING("GroupFile{:02d}"), j);
ret.emplace_back(std::move(name),
IntrusiveAudioGroupData{proj.release(), head.projLen, pool.release(), head.poolLen,
sdir.release(), head.sdirLen, samp.release(), head.sampLen,
@ -1362,8 +1353,8 @@ static std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> LoadRS2(FIL
return ret;
}
static std::vector<std::pair<SystemString, ContainerRegistry::SongData>> LoadRS2Songs(FILE* fp) {
std::vector<std::pair<SystemString, ContainerRegistry::SongData>> ret;
static std::vector<std::pair<std::string, ContainerRegistry::SongData>> LoadRS2Songs(FILE* fp) {
std::vector<std::pair<std::string, ContainerRegistry::SongData>> ret;
size_t endPos = FileLength(fp);
uint64_t fstOff;
@ -1403,7 +1394,7 @@ static std::vector<std::pair<SystemString, ContainerRegistry::SongData>> LoadRS2
RS23SONHead sonHead = sonData[s];
sonHead.swapBig();
SystemString name = fmt::format(FMT_STRING(_SYS_STR("GroupFile{:02d}-{}")), j, s);
std::string name = fmt::format(FMT_STRING("GroupFile{:02d}-{}"), j, s);
std::unique_ptr<uint8_t[]> song(new uint8_t[sonHead.length]);
memmove(song.get(), audData.get() + sonHead.offset, sonHead.length);
ret.emplace_back(std::move(name),
@ -1460,8 +1451,8 @@ static bool ValidateRS3(FILE* fp) {
return false;
}
static std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> LoadRS3(FILE* fp) {
std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> ret;
static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadRS3(FILE* fp) {
std::vector<std::pair<std::string, IntrusiveAudioGroupData>> ret;
size_t endPos = FileLength(fp);
uint64_t fstOff;
@ -1506,7 +1497,7 @@ static std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> LoadRS3(FIL
memmove(samp.get(), audData.get() + head.sampOff, head.sampLen);
if (head.projLen && head.poolLen && head.sdirLen && head.sampLen) {
SystemString name = fmt::format(FMT_STRING(_SYS_STR("GroupFile{:02d}")), j);
std::string name = fmt::format(FMT_STRING("GroupFile{:02d}"), j);
ret.emplace_back(std::move(name),
IntrusiveAudioGroupData{proj.release(), head.projLen, pool.release(), head.poolLen,
sdir.release(), head.sdirLen, samp.release(), head.sampLen,
@ -1544,8 +1535,8 @@ static bool ValidateStarFoxAdvSongs(FILE* fp) {
return totalLen == endPos;
}
static std::vector<std::pair<SystemString, ContainerRegistry::SongData>> LoadStarFoxAdvSongs(FILE* midifp) {
std::vector<std::pair<SystemString, ContainerRegistry::SongData>> ret;
static std::vector<std::pair<std::string, ContainerRegistry::SongData>> LoadStarFoxAdvSongs(FILE* midifp) {
std::vector<std::pair<std::string, ContainerRegistry::SongData>> ret;
size_t endPos = FileLength(midifp);
if (endPos > 2 * 1024 * 1024)
@ -1569,7 +1560,7 @@ static std::vector<std::pair<SystemString, ContainerRegistry::SongData>> LoadSta
if (len == 0)
break;
SystemString name = fmt::format(FMT_STRING(_SYS_STR("Song{}")), unsigned(i));
std::string name = fmt::format(FMT_STRING("Song{}"), unsigned(i));
std::unique_ptr<uint8_t[]> song(new uint8_t[len]);
memmove(song.get(), data.get() + cur, len);
ret.emplace_back(std::move(name), ContainerRegistry::SongData(std::move(song), len, -1, i));
@ -1601,7 +1592,7 @@ struct TTYDSongDesc {
uint8_t setup;
};
static std::vector<std::pair<SystemString, ContainerRegistry::SongData>> LoadPaperMarioTTYDSongs(FILE* midifp,
static std::vector<std::pair<std::string, ContainerRegistry::SongData>> LoadPaperMarioTTYDSongs(FILE* midifp,
FILE* descFp) {
if (!descFp)
return {};
@ -1623,7 +1614,7 @@ static std::vector<std::pair<SystemString, ContainerRegistry::SongData>> LoadPap
fread(data.get(), 1, endPos, midifp);
uint32_t off = 0;
uint32_t song = 0;
std::vector<std::pair<SystemString, ContainerRegistry::SongData>> ret;
std::vector<std::pair<std::string, ContainerRegistry::SongData>> ret;
while (off < endPos) {
int32_t len = SBig(*(reinterpret_cast<int32_t*>(data.get() + off)));
@ -1642,53 +1633,53 @@ static std::vector<std::pair<SystemString, ContainerRegistry::SongData>> LoadPap
return ret;
}
ContainerRegistry::Type ContainerRegistry::DetectContainerType(const SystemChar* path) {
ContainerRegistry::Type ContainerRegistry::DetectContainerType(const char* path) {
FILE* fp;
/* See if provided file is one of four raw chunks */
const SystemChar* dot = nullptr;
const char* dot = nullptr;
if (IsChunkExtension(path, dot)) {
SystemString newpath;
std::string newpath;
/* Project */
newpath = fmt::format(FMT_STRING(_SYS_STR("{:.{}}.pro")), path, int(dot - path));
fp = FOpen(newpath.c_str(), _SYS_STR("rb"));
newpath = fmt::format(FMT_STRING("{:.{}}.pro"), path, int(dot - path));
fp = FOpen(newpath.c_str(), "rb");
if (!fp) {
newpath = fmt::format(FMT_STRING(_SYS_STR("{:.{}}.proj")), path, int(dot - path));
fp = FOpen(newpath.c_str(), _SYS_STR("rb"));
newpath = fmt::format(FMT_STRING("{:.{}}.proj"), path, int(dot - path));
fp = FOpen(newpath.c_str(), "rb");
if (!fp)
return Type::Invalid;
}
fclose(fp);
/* Pool */
newpath = fmt::format(FMT_STRING(_SYS_STR("{:.{}}.poo")), path, int(dot - path));
fp = FOpen(newpath.c_str(), _SYS_STR("rb"));
newpath = fmt::format(FMT_STRING("{:.{}}.poo"), path, int(dot - path));
fp = FOpen(newpath.c_str(), "rb");
if (!fp) {
newpath = fmt::format(FMT_STRING(_SYS_STR("{:.{}}.pool")), path, int(dot - path));
fp = FOpen(newpath.c_str(), _SYS_STR("rb"));
newpath = fmt::format(FMT_STRING("{:.{}}.pool"), path, int(dot - path));
fp = FOpen(newpath.c_str(), "rb");
if (!fp)
return Type::Invalid;
}
fclose(fp);
/* Sample Directory */
newpath = fmt::format(FMT_STRING(_SYS_STR("{:.{}}.sdi")), path, int(dot - path));
fp = FOpen(newpath.c_str(), _SYS_STR("rb"));
newpath = fmt::format(FMT_STRING("{:.{}}.sdi"), path, int(dot - path));
fp = FOpen(newpath.c_str(), "rb");
if (!fp) {
newpath = fmt::format(FMT_STRING(_SYS_STR("{:.{}}.sdir")), path, int(dot - path));
fp = FOpen(newpath.c_str(), _SYS_STR("rb"));
newpath = fmt::format(FMT_STRING("{:.{}}.sdir"), path, int(dot - path));
fp = FOpen(newpath.c_str(), "rb");
if (!fp)
return Type::Invalid;
}
fclose(fp);
/* Sample */
newpath = fmt::format(FMT_STRING(_SYS_STR("{:.{}}.sam")), path, int(dot - path));
fp = FOpen(newpath.c_str(), _SYS_STR("rb"));
newpath = fmt::format(FMT_STRING("{:.{}}.sam"), path, int(dot - path));
fp = FOpen(newpath.c_str(), "rb");
if (!fp) {
newpath = fmt::format(FMT_STRING(_SYS_STR("{:.{}}.samp")), path, int(dot - path));
fp = FOpen(newpath.c_str(), _SYS_STR("rb"));
newpath = fmt::format(FMT_STRING("{:.{}}.samp"), path, int(dot - path));
fp = FOpen(newpath.c_str(), "rb");
if (!fp)
return Type::Invalid;
}
@ -1698,7 +1689,7 @@ ContainerRegistry::Type ContainerRegistry::DetectContainerType(const SystemChar*
}
/* Now attempt single-file case */
fp = FOpen(path, _SYS_STR("rb"));
fp = FOpen(path, "rb");
if (fp) {
if (ValidateMP1(fp)) {
fclose(fp);
@ -1741,97 +1732,97 @@ ContainerRegistry::Type ContainerRegistry::DetectContainerType(const SystemChar*
return Type::Invalid;
}
std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> ContainerRegistry::LoadContainer(const SystemChar* path) {
std::vector<std::pair<std::string, IntrusiveAudioGroupData>> ContainerRegistry::LoadContainer(const char* path) {
Type typeOut;
return LoadContainer(path, typeOut);
};
std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> ContainerRegistry::LoadContainer(const SystemChar* path,
std::vector<std::pair<std::string, IntrusiveAudioGroupData>> ContainerRegistry::LoadContainer(const char* path,
Type& typeOut) {
FILE* fp;
typeOut = Type::Invalid;
/* See if provided file is one of four raw chunks */
const SystemChar* dot = nullptr;
const char* dot = nullptr;
if (IsChunkExtension(path, dot)) {
std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> ret;
std::vector<std::pair<std::string, IntrusiveAudioGroupData>> ret;
SystemString baseName;
if (const SystemChar* sep = std::max(StrRChr(path, _SYS_STR('/')), StrRChr(path, _SYS_STR('\\'))))
baseName = SystemString(sep + 1, dot - sep - 1);
std::string baseName;
if (const char* sep = std::max(StrRChr(path, '/'), StrRChr(path, '\\')))
baseName = std::string(sep + 1, dot - sep - 1);
else
baseName = SystemString(path, dot - path);
baseName = std::string(path, dot - path);
/* Project */
SystemString projPath;
projPath = fmt::format(FMT_STRING(_SYS_STR("{:.{}}.pro")), path, int(dot - path));
fp = FOpen(projPath.c_str(), _SYS_STR("rb"));
std::string projPath;
projPath = fmt::format(FMT_STRING("{:.{}}.pro"), path, int(dot - path));
fp = FOpen(projPath.c_str(), "rb");
if (!fp) {
projPath = fmt::format(FMT_STRING(_SYS_STR("{:.{}}.proj")), path, int(dot - path));
fp = FOpen(projPath.c_str(), _SYS_STR("rb"));
projPath = fmt::format(FMT_STRING("{:.{}}.proj"), path, int(dot - path));
fp = FOpen(projPath.c_str(), "rb");
if (!fp)
return ret;
}
fclose(fp);
/* Pool */
SystemString poolPath;
poolPath = fmt::format(FMT_STRING(_SYS_STR("{:.{}}.poo")), path, int(dot - path));
fp = FOpen(poolPath.c_str(), _SYS_STR("rb"));
std::string poolPath;
poolPath = fmt::format(FMT_STRING("{:.{}}.poo"), path, int(dot - path));
fp = FOpen(poolPath.c_str(), "rb");
if (!fp) {
poolPath = fmt::format(FMT_STRING(_SYS_STR("{:.{}}.pool")), path, int(dot - path));
fp = FOpen(poolPath.c_str(), _SYS_STR("rb"));
poolPath = fmt::format(FMT_STRING("{:.{}}.pool"), path, int(dot - path));
fp = FOpen(poolPath.c_str(), "rb");
if (!fp)
return ret;
}
fclose(fp);
/* Sample Directory */
SystemString sdirPath;
sdirPath = fmt::format(FMT_STRING(_SYS_STR("{:.{}}.sdi")), path, int(dot - path));
fp = FOpen(sdirPath.c_str(), _SYS_STR("rb"));
std::string sdirPath;
sdirPath = fmt::format(FMT_STRING("{:.{}}.sdi"), path, int(dot - path));
fp = FOpen(sdirPath.c_str(), "rb");
if (!fp) {
sdirPath = fmt::format(FMT_STRING(_SYS_STR("{:.{}}.sdir")), path, int(dot - path));
fp = FOpen(sdirPath.c_str(), _SYS_STR("rb"));
sdirPath = fmt::format(FMT_STRING("{:.{}}.sdir"), path, int(dot - path));
fp = FOpen(sdirPath.c_str(), "rb");
if (!fp)
return ret;
}
fclose(fp);
/* Sample */
SystemString sampPath;
sampPath = fmt::format(FMT_STRING(_SYS_STR("{:.{}}.sam")), path, int(dot - path));
fp = FOpen(sampPath.c_str(), _SYS_STR("rb"));
std::string sampPath;
sampPath = fmt::format(FMT_STRING("{:.{}}.sam"), path, int(dot - path));
fp = FOpen(sampPath.c_str(), "rb");
if (!fp) {
sampPath = fmt::format(FMT_STRING(_SYS_STR("{:.{}}.samp")), path, int(dot - path));
fp = FOpen(sampPath.c_str(), _SYS_STR("rb"));
sampPath = fmt::format(FMT_STRING("{:.{}}.samp"), path, int(dot - path));
fp = FOpen(sampPath.c_str(), "rb");
if (!fp)
return ret;
}
fclose(fp);
fp = FOpen(projPath.c_str(), _SYS_STR("rb"));
fp = FOpen(projPath.c_str(), "rb");
size_t projLen = FileLength(fp);
if (!projLen)
return ret;
std::unique_ptr<uint8_t[]> proj(new uint8_t[projLen]);
fread(proj.get(), 1, projLen, fp);
fp = FOpen(poolPath.c_str(), _SYS_STR("rb"));
fp = FOpen(poolPath.c_str(), "rb");
size_t poolLen = FileLength(fp);
if (!poolLen)
return ret;
std::unique_ptr<uint8_t[]> pool(new uint8_t[poolLen]);
fread(pool.get(), 1, poolLen, fp);
fp = FOpen(sdirPath.c_str(), _SYS_STR("rb"));
fp = FOpen(sdirPath.c_str(), "rb");
size_t sdirLen = FileLength(fp);
if (!sdirLen)
return ret;
std::unique_ptr<uint8_t[]> sdir(new uint8_t[sdirLen]);
fread(sdir.get(), 1, sdirLen, fp);
fp = FOpen(sampPath.c_str(), _SYS_STR("rb"));
fp = FOpen(sampPath.c_str(), "rb");
size_t sampLen = FileLength(fp);
if (!sampLen)
return ret;
@ -1859,7 +1850,7 @@ std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> ContainerRegistry:
}
/* Now attempt single-file case */
fp = FOpen(path, _SYS_STR("rb"));
fp = FOpen(path, "rb");
if (fp) {
if (ValidateMP1(fp)) {
auto ret = LoadMP1(fp);
@ -1916,13 +1907,13 @@ std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> ContainerRegistry:
return {};
}
std::vector<std::pair<SystemString, ContainerRegistry::SongData>> ContainerRegistry::LoadSongs(const SystemChar* path) {
std::vector<std::pair<std::string, ContainerRegistry::SongData>> ContainerRegistry::LoadSongs(const char* path) {
FILE* fp;
/* See if provided file is a raw song */
const SystemChar* dot = nullptr;
const char* dot = nullptr;
if (IsSongExtension(path, dot)) {
fp = FOpen(path, _SYS_STR("rb"));
fp = FOpen(path, "rb");
size_t fLen = FileLength(fp);
if (!fLen) {
fclose(fp);
@ -1932,13 +1923,13 @@ std::vector<std::pair<SystemString, ContainerRegistry::SongData>> ContainerRegis
fread(song.get(), 1, fLen, fp);
fclose(fp);
std::vector<std::pair<SystemString, SongData>> ret;
ret.emplace_back(_SYS_STR("Song"), SongData(std::move(song), fLen, -1, -1));
std::vector<std::pair<std::string, SongData>> ret;
ret.emplace_back("Song", SongData(std::move(song), fLen, -1, -1));
return ret;
}
/* Now attempt archive-file case */
fp = FOpen(path, _SYS_STR("rb"));
fp = FOpen(path, "rb");
if (fp) {
if (ValidateMP1Songs(fp)) {
auto ret = LoadMP1Songs(fp);
@ -1978,9 +1969,9 @@ std::vector<std::pair<SystemString, ContainerRegistry::SongData>> ContainerRegis
if (ValidatePaperMarioTTYDSongs(fp)) {
/* Song Description */
dot = StrRChr(path, _SYS_STR('.'));
SystemString newpath = fmt::format(FMT_STRING(_SYS_STR("{:.{}}.stbl")), path, int(dot - path));
FILE* descFp = FOpen(newpath.c_str(), _SYS_STR("rb"));
dot = StrRChr(path, '.');
std::string newpath = fmt::format(FMT_STRING("{:.{}}.stbl"), path, int(dot - path));
FILE* descFp = FOpen(newpath.c_str(), "rb");
if (descFp) {
auto ret = LoadPaperMarioTTYDSongs(fp, descFp);
fclose(fp);

View File

@ -5,6 +5,7 @@
#include <dirent.h>
#endif
#include <ranges>
#include <sys/stat.h>
#if !defined(S_ISREG) && defined(S_IFMT) && defined(S_IFREG)
@ -21,124 +22,154 @@
namespace amuse {
DirectoryEnumerator::DirectoryEnumerator(SystemStringView path, Mode mode, bool sizeSort, bool reverse, bool noHidden) {
DirectoryEnumerator::DirectoryEnumerator(std::string_view path, Mode mode, bool sizeSort, bool reverse, bool noHidden) {
Sstat theStat;
if (Stat(path.data(), &theStat) || !S_ISDIR(theStat.st_mode))
if (Stat(path.data(), &theStat) || !S_ISDIR(theStat.st_mode)) {
return;
}
#if _WIN32
SystemString wc(path);
wc += _SYS_STR("/*");
std::wstring wc = nowide::widen(path);
wc += L"/*";
WIN32_FIND_DATAW d;
HANDLE dir = FindFirstFileW(wc.c_str(), &d);
if (dir == INVALID_HANDLE_VALUE)
if (dir == INVALID_HANDLE_VALUE) {
return;
}
switch (mode) {
case Mode::Native:
do {
if (!wcscmp(d.cFileName, _SYS_STR(".")) || !wcscmp(d.cFileName, _SYS_STR("..")))
if (!wcscmp(d.cFileName, L".") || !wcscmp(d.cFileName, L"..")) {
continue;
if (noHidden && (d.cFileName[0] == L'.' || (d.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) != 0))
}
if (noHidden && (d.cFileName[0] == L'.' || (d.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) != 0)) {
continue;
SystemString fp(path);
fp += _SYS_STR('/');
fp += d.cFileName;
}
std::string fileName = nowide::narrow(d.cFileName);
std::string fp(path);
fp += '/';
fp += fileName;
Sstat st;
if (Stat(fp.c_str(), &st))
if (Stat(fp.c_str(), &st)) {
continue;
}
size_t sz = 0;
bool isDir = false;
if (S_ISDIR(st.st_mode))
if (S_ISDIR(st.st_mode)) {
isDir = true;
else if (S_ISREG(st.st_mode))
} else if (S_ISREG(st.st_mode)) {
sz = st.st_size;
else
} else {
continue;
}
m_entries.emplace_back(fp, d.cFileName, sz, isDir);
m_entries.emplace_back(fp, fileName, sz, isDir);
} while (FindNextFileW(dir, &d));
break;
case Mode::DirsThenFilesSorted:
case Mode::DirsSorted: {
std::map<SystemString, Entry, CaseInsensitiveCompare> sort;
std::map<std::string, Entry, CaseInsensitiveCompare> sort;
do {
if (!wcscmp(d.cFileName, _SYS_STR(".")) || !wcscmp(d.cFileName, _SYS_STR("..")))
if (!wcscmp(d.cFileName, L".") || !wcscmp(d.cFileName, L"..")) {
continue;
if (noHidden && (d.cFileName[0] == L'.' || (d.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) != 0))
}
if (noHidden && (d.cFileName[0] == L'.' || (d.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) != 0)) {
continue;
SystemString fp(path);
fp += _SYS_STR('/');
fp += d.cFileName;
}
std::string fileName = nowide::narrow(d.cFileName);
std::string fp(path);
fp += '/';
fp += fileName;
Sstat st;
if (Stat(fp.c_str(), &st) || !S_ISDIR(st.st_mode))
if (Stat(fp.c_str(), &st) || !S_ISDIR(st.st_mode)) {
continue;
sort.emplace(std::make_pair(d.cFileName, Entry(fp, d.cFileName, 0, true)));
}
sort.emplace(fileName, Entry{fp, fileName, 0, true});
} while (FindNextFileW(dir, &d));
m_entries.reserve(sort.size());
if (reverse)
for (auto it = sort.crbegin(); it != sort.crend(); ++it)
m_entries.push_back(std::move(it->second));
else
for (auto& e : sort)
m_entries.push_back(std::move(e.second));
if (reverse) {
for (auto& it : std::ranges::reverse_view(sort)) {
m_entries.emplace_back(std::move(it.second));
}
} else {
for (auto& e : sort) {
m_entries.emplace_back(std::move(e.second));
}
}
if (mode == Mode::DirsSorted)
if (mode == Mode::DirsSorted) {
break;
}
FindClose(dir);
dir = FindFirstFileW(wc.c_str(), &d);
}
case Mode::FilesSorted: {
if (mode == Mode::FilesSorted)
if (mode == Mode::FilesSorted) {
m_entries.clear();
}
if (sizeSort) {
std::multimap<size_t, Entry> sort;
do {
if (!wcscmp(d.cFileName, _SYS_STR(".")) || !wcscmp(d.cFileName, _SYS_STR("..")))
if (!wcscmp(d.cFileName, L".") || !wcscmp(d.cFileName, L"..")) {
continue;
if (noHidden && (d.cFileName[0] == L'.' || (d.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) != 0))
}
if (noHidden && (d.cFileName[0] == L'.' || (d.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) != 0)) {
continue;
SystemString fp(path);
fp += _SYS_STR('/');
fp += d.cFileName;
}
std::string fileName = nowide::narrow(d.cFileName);
std::string fp(path);
fp += '/';
fp += fileName;
Sstat st;
if (Stat(fp.c_str(), &st) || !S_ISREG(st.st_mode))
if (Stat(fp.c_str(), &st) || !S_ISREG(st.st_mode)) {
continue;
sort.emplace(std::make_pair(st.st_size, Entry(fp, d.cFileName, st.st_size, false)));
}
sort.emplace(st.st_size, Entry{fp, fileName, static_cast<size_t>(st.st_size), false});
} while (FindNextFileW(dir, &d));
m_entries.reserve(sort.size());
if (reverse)
for (auto it = sort.crbegin(); it != sort.crend(); ++it)
m_entries.push_back(std::move(it->second));
else
for (auto& e : sort)
m_entries.push_back(std::move(e.second));
m_entries.reserve(m_entries.size() + sort.size());
if (reverse) {
for (auto& it : std::ranges::reverse_view(sort)) {
m_entries.emplace_back(std::move(it.second));
}
} else {
for (auto& e : sort) {
m_entries.emplace_back(std::move(e.second));
}
}
} else {
std::map<SystemString, Entry, CaseInsensitiveCompare> sort;
std::map<std::string, Entry, CaseInsensitiveCompare> sort;
do {
if (!wcscmp(d.cFileName, _SYS_STR(".")) || !wcscmp(d.cFileName, _SYS_STR("..")))
if (!wcscmp(d.cFileName, L".") || !wcscmp(d.cFileName, L"..")) {
continue;
if (noHidden && (d.cFileName[0] == L'.' || (d.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) != 0))
}
if (noHidden && (d.cFileName[0] == L'.' || (d.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) != 0)) {
continue;
SystemString fp(path);
fp += _SYS_STR('/');
fp += d.cFileName;
}
std::string fileName = nowide::narrow(d.cFileName);
std::string fp(path);
fp += '/';
fp += fileName;
Sstat st;
if (Stat(fp.c_str(), &st) || !S_ISREG(st.st_mode))
if (Stat(fp.c_str(), &st) || !S_ISREG(st.st_mode)) {
continue;
sort.emplace(std::make_pair(d.cFileName, Entry(fp, d.cFileName, st.st_size, false)));
}
sort.emplace(fileName, Entry{fp, fileName, static_cast<size_t>(st.st_size), false});
} while (FindNextFileW(dir, &d));
m_entries.reserve(sort.size());
if (reverse)
for (auto it = sort.crbegin(); it != sort.crend(); ++it)
m_entries.push_back(std::move(it->second));
else
for (auto& e : sort)
m_entries.push_back(std::move(e.second));
m_entries.reserve(m_entries.size() + sort.size());
if (reverse) {
for (auto& e : std::ranges::reverse_view(sort)) {
m_entries.emplace_back(std::move(e.second));
}
} else {
for (auto& e : sort) {
m_entries.emplace_back(std::move(e.second));
}
}
}
break;
@ -159,7 +190,7 @@ DirectoryEnumerator::DirectoryEnumerator(SystemStringView path, Mode mode, bool
continue;
if (noHidden && d->d_name[0] == '.')
continue;
SystemString fp(path);
std::string fp(path);
fp += '/';
fp += d->d_name;
Sstat st;
@ -180,13 +211,13 @@ DirectoryEnumerator::DirectoryEnumerator(SystemStringView path, Mode mode, bool
break;
case Mode::DirsThenFilesSorted:
case Mode::DirsSorted: {
std::map<SystemString, Entry, CaseInsensitiveCompare> sort;
std::map<std::string, Entry, CaseInsensitiveCompare> sort;
while ((d = readdir(dir))) {
if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
continue;
if (noHidden && d->d_name[0] == '.')
continue;
SystemString fp(path);
std::string fp(path);
fp += '/';
fp += d->d_name;
Sstat st;
@ -219,7 +250,7 @@ DirectoryEnumerator::DirectoryEnumerator(SystemStringView path, Mode mode, bool
continue;
if (noHidden && d->d_name[0] == '.')
continue;
SystemString fp(path);
std::string fp(path);
fp += '/';
fp += d->d_name;
Sstat st;
@ -236,13 +267,13 @@ DirectoryEnumerator::DirectoryEnumerator(SystemStringView path, Mode mode, bool
for (auto& e : sort)
m_entries.push_back(std::move(e.second));
} else {
std::map<SystemString, Entry, CaseInsensitiveCompare> sort;
std::map<std::string, Entry, CaseInsensitiveCompare> sort;
while ((d = readdir(dir))) {
if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
continue;
if (noHidden && d->d_name[0] == '.')
continue;
SystemString fp(path);
std::string fp(path);
fp += '/';
fp += d->d_name;
Sstat st;

View File

@ -1,11 +1,6 @@
#!/bin/sh
git clone https://github.com/AxioDL/boo.git
pushd boo
git submodule update --recursive --init
popd
(cd boo && git submodule update --recursive --init)
git clone https://github.com/libAthena/athena.git
pushd athena
git submodule update --recursive --init
popd
(cd athena && git submodule update --recursive --init)