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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,6 +1,5 @@
add_executable(amuse-mkqticon mkqticon.c) add_executable(amuse-mkqticon mkqticon.c)
target_link_libraries(amuse-mkqticon ${PNG_LIBRARIES} ${ZLIB_LIBRARIES}) 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) macro(declare_qticon_target)
add_custom_command(OUTPUT ${amuse_BINARY_DIR}/Editor/platforms/freedesktop/mainicon_qt.bin add_custom_command(OUTPUT ${amuse_BINARY_DIR}/Editor/platforms/freedesktop/mainicon_qt.bin

View File

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

View File

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

View File

@ -5,6 +5,10 @@
#include <map> #include <map>
#if _WIN32
#include <nowide/args.hpp>
#endif
#define EMITTER_TEST 0 #define EMITTER_TEST 0
static logvisor::Module Log("amuseplay"); static logvisor::Module Log("amuseplay");
@ -31,7 +35,7 @@ public:
struct AppCallback : boo::IApplicationCallback { struct AppCallback : boo::IApplicationCallback {
int m_argc; int m_argc;
const boo::SystemChar** m_argv; char** m_argv;
/* Boo window and events */ /* Boo window and events */
EventCallback m_eventRec; EventCallback m_eventRec;
@ -560,7 +564,7 @@ struct AppCallback : boo::IApplicationCallback {
int appMain(boo::IApplication* app) override { int appMain(boo::IApplication* app) override {
/* Event window */ /* Event window */
m_win = app->newWindow(_SYS_STR("amuseplay")); m_win = app->newWindow("amuseplay");
m_win->setCallback(&m_events); m_win->setCallback(&m_events);
m_win->setWindowFrame(100, 100, 100, 100); m_win->setWindowFrame(100, 100, 100, 100);
m_win->setStyle(~boo::EWindowStyle::Resize); 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")); Log.report(logvisor::Error, FMT_STRING("invalid/no data at path argument"));
return 1; 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]); amuse::ContainerRegistry::LoadContainer(m_argv[1]);
if (data.empty()) { if (data.empty()) {
Log.report(logvisor::Error, FMT_STRING("invalid/no data at path argument")); 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::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>>> amuse::ObjToken<amuse::SongGroupIndex>>>
allSongGroups; 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>>> amuse::ObjToken<amuse::SFXGroupIndex>>>
allSFXGroups; allSFXGroups;
size_t totalGroups = 0; size_t totalGroups = 0;
@ -623,7 +627,7 @@ struct AppCallback : boo::IApplicationCallback {
m_setupId = -1; m_setupId = -1;
/* Attempt loading song */ /* 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) if (m_argc > 2)
songs = amuse::ContainerRegistry::LoadSongs(m_argv[2]); songs = amuse::ContainerRegistry::LoadSongs(m_argv[2]);
else else
@ -674,7 +678,7 @@ struct AppCallback : boo::IApplicationCallback {
break; 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; int userSel = 0;
@ -728,11 +732,11 @@ struct AppCallback : boo::IApplicationCallback {
/* Ask user to specify which group in project */ /* Ask user to specify which group in project */
fmt::print(FMT_STRING("Multiple Audio Groups discovered:\n")); fmt::print(FMT_STRING("Multiple Audio Groups discovered:\n"));
for (const auto& pair : allSFXGroups) { 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()); pair.second.first->first, pair.second.second->m_sfxEntries.size());
} }
for (const auto& pair : allSongGroups) { 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.first, pair.second.first->first, pair.second.second->m_normPages.size(),
pair.second.second->m_drumPages.size(), pair.second.second->m_midiSetups.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; } 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) {} : 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 main(int argc, char** argv) {
int wmain(int argc, const boo::SystemChar** argv)
#else
int main(int argc, const boo::SystemChar** argv)
#endif
{
logvisor::RegisterConsoleLogger(); logvisor::RegisterConsoleLogger();
logvisor::RegisterStandardExceptions(); logvisor::RegisterStandardExceptions();
AppCallback app(argc, argv); AppCallback app(argc, argv);
int ret = boo::ApplicationRun(boo::IApplication::EPlatformType::Auto, app, _SYS_STR("amuseplay"), int ret = boo::ApplicationRun(boo::IApplication::EPlatformType::Auto, app, "amuseplay",
_SYS_STR("Amuse Player"), argc, argv, {}, 1, 1, false); "Amuse Player", argc, argv, {}, 1, 1, false);
fmt::print(FMT_STRING("IM DYING!!\n"));
return ret; return ret;
} }
#if _WIN32 #if _WIN32
#include <shellapi.h> #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(); logvisor::CreateWin32Console();
SetConsoleOutputCP(65001); return main(argc, argv);
return wmain(argc + 1, booArgv);
} }
#endif #endif

View File

@ -19,6 +19,7 @@ static logvisor::Module Log("amuserender");
#if _WIN32 #if _WIN32
#include <DbgHelp.h> #include <DbgHelp.h>
#include <nowide/args.hpp>
#pragma comment(lib, "Dbghelp.lib") #pragma comment(lib, "Dbghelp.lib")
#include <signal.h> #include <signal.h>
@ -68,45 +69,15 @@ static void abortHandler(int signum) {
static bool g_BreakLoop = false; static bool g_BreakLoop = false;
static void SIGINTHandler(int sig) { g_BreakLoop = true; } static void SIGINTHandler(int sig) { g_BreakLoop = true; }
#if _WIN32 int main(int argc, char** argv) {
int wmain(int argc, const boo::SystemChar** argv)
#else
int main(int argc, const boo::SystemChar** argv)
#endif
{
logvisor::RegisterConsoleLogger(); logvisor::RegisterConsoleLogger();
std::vector<boo::SystemString> m_args; std::vector<std::string> m_args;
m_args.reserve(argc); m_args.reserve(argc);
double rate = NativeSampleRate; double rate = NativeSampleRate;
int chCount = 2; int chCount = 2;
double volume = 1.0; double volume = 1.0;
for (int i = 1; i < argc; ++i) { 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 (!strncmp(argv[i], "-r", 2)) {
if (argv[i][2]) if (argv[i][2])
rate = strtod(&argv[i][2], nullptr); rate = strtod(&argv[i][2], nullptr);
@ -130,7 +101,6 @@ int main(int argc, const boo::SystemChar** argv)
} }
} else } else
m_args.push_back(argv[i]); m_args.push_back(argv[i]);
#endif
} }
/* Load data */ /* 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")); Log.report(logvisor::Error, FMT_STRING("invalid/no data at path argument"));
return 1; 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()); amuse::ContainerRegistry::LoadContainer(m_args[0].c_str());
if (data.empty()) { if (data.empty()) {
Log.report(logvisor::Error, FMT_STRING("invalid/no data at path argument")); 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_groupId = -1;
int m_setupId = -1; int m_setupId = -1;
const amuse::SystemString* m_groupName = nullptr; const std::string* m_groupName = nullptr;
const amuse::SystemString* m_songName = nullptr; const std::string* m_songName = nullptr;
amuse::ContainerRegistry::SongData* m_arrData = nullptr; amuse::ContainerRegistry::SongData* m_arrData = nullptr;
bool m_sfxGroup = false; bool m_sfxGroup = false;
std::list<amuse::AudioGroupProject> m_projs; 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>>> amuse::ObjToken<amuse::SongGroupIndex>>>
allSongGroups; 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>>> amuse::ObjToken<amuse::SFXGroupIndex>>>
allSFXGroups; allSFXGroups;
size_t totalGroups = 0; size_t totalGroups = 0;
@ -185,7 +155,7 @@ int main(int argc, const boo::SystemChar** argv)
} }
/* Attempt loading song */ /* 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) if (m_args.size() > 1)
songs = amuse::ContainerRegistry::LoadSongs(m_args[1].c_str()); songs = amuse::ContainerRegistry::LoadSongs(m_args[1].c_str());
else else
@ -236,7 +206,7 @@ int main(int argc, const boo::SystemChar** argv)
break; 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; int userSel = 0;
@ -297,11 +267,11 @@ int main(int argc, const boo::SystemChar** argv)
/* Ask user to specify which group in project */ /* Ask user to specify which group in project */
fmt::print(FMT_STRING("Multiple Audio Groups discovered:\n")); fmt::print(FMT_STRING("Multiple Audio Groups discovered:\n"));
for (const auto& pair : allSFXGroups) { 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()); pair.second.first->first, pair.second.second->m_sfxEntries.size());
} }
for (const auto& pair : allSongGroups) { 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.first, pair.second.first->first, pair.second.second->m_normPages.size(),
pair.second.second->m_drumPages.size(), pair.second.second->m_midiSetups.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 */ /* WAV out path */
amuse::SystemString pathOut = fmt::format(FMT_STRING(_SYS_STR("{}-{}.wav")), *m_groupName, *m_songName); std::string pathOut = fmt::format(FMT_STRING("{}-{}.wav"), *m_groupName, *m_songName);
Log.report(logvisor::Info, FMT_STRING(_SYS_STR("Writing to {}")), pathOut); Log.report(logvisor::Info, FMT_STRING("Writing to {}"), pathOut);
/* Build voice engine */ /* Build voice engine */
std::unique_ptr<boo::IAudioVoiceEngine> voxEngine = boo::NewWAVAudioVoiceEngine(pathOut.c_str(), rate, chCount); 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 #if _WIN32
#include <shellapi.h> #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(SIGABRT, abortHandler);
signal(SIGSEGV, abortHandler); signal(SIGSEGV, abortHandler);
signal(SIGILL, abortHandler); signal(SIGILL, abortHandler);
signal(SIGFPE, abortHandler); signal(SIGFPE, abortHandler);
int argc = 0; int argc = 0;
const boo::SystemChar** argv; char** argv = nullptr;
if (lpCmdLine[0]) nowide::args _(argc, argv);
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];
logvisor::CreateWin32Console(); logvisor::CreateWin32Console();
SetConsoleOutputCP(65001); return main(argc, argv);
return wmain(argc + 1, booArgv);
} }
#endif #endif

View File

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

View File

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

View File

@ -190,7 +190,7 @@ class AudioGroupProject {
public: public:
AudioGroupProject() = default; AudioGroupProject() = default;
static AudioGroupProject CreateAudioGroupProject(const AudioGroupData& data); 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 AudioGroupProject CreateAudioGroupProject(const AudioGroupProject& oldProj);
static void BootstrapObjectIDs(const AudioGroupData& data); static void BootstrapObjectIDs(const AudioGroupData& data);

View File

@ -285,13 +285,13 @@ public:
return ret; return ret;
} }
void loadLooseDSP(SystemStringView dspPath); void loadLooseDSP(std::string_view dspPath);
void loadLooseVADPCM(SystemStringView vadpcmPath); void loadLooseVADPCM(std::string_view vadpcmPath);
void loadLooseWAV(SystemStringView wavPath); void loadLooseWAV(std::string_view wavPath);
void patchMetadataDSP(SystemStringView dspPath); void patchMetadataDSP(std::string_view dspPath);
void patchMetadataVADPCM(SystemStringView vadpcmPath); void patchMetadataVADPCM(std::string_view vadpcmPath);
void patchMetadataWAV(SystemStringView wavPath); void patchMetadataWAV(std::string_view wavPath);
}; };
/* This double-wrapper allows Voices to keep a strong reference on /* This double-wrapper allows Voices to keep a strong reference on
* a single instance of loaded loose data without being unexpectedly * a single instance of loaded loose data without being unexpectedly
@ -315,16 +315,16 @@ public:
return m_data->toDNA<DNAEn>(id); return m_data->toDNA<DNAEn>(id);
} }
void loadLooseData(SystemStringView basePath); void loadLooseData(std::string_view basePath);
SampleFileState getFileState(SystemStringView basePath, SystemString* pathOut = nullptr) const; SampleFileState getFileState(std::string_view basePath, std::string* pathOut = nullptr) const;
void patchSampleMetadata(SystemStringView basePath) const; void patchSampleMetadata(std::string_view basePath) const;
}; };
private: private:
std::unordered_map<SampleId, ObjToken<Entry>> m_entries; 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); 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); const unsigned char* samp, bool compressWAV = false);
public: public:
@ -333,17 +333,17 @@ public:
AudioGroupSampleDirectory(athena::io::IStreamReader& r, const unsigned char* sampData, bool absOffs, N64DataTag); AudioGroupSampleDirectory(athena::io::IStreamReader& r, const unsigned char* sampData, bool absOffs, N64DataTag);
AudioGroupSampleDirectory(athena::io::IStreamReader& r, bool absOffs, PCDataTag); AudioGroupSampleDirectory(athena::io::IStreamReader& r, bool absOffs, PCDataTag);
static AudioGroupSampleDirectory CreateAudioGroupSampleDirectory(const AudioGroupData& data); 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; } const std::unordered_map<SampleId, ObjToken<Entry>>& sampleEntries() const { return m_entries; }
std::unordered_map<SampleId, ObjToken<Entry>>& sampleEntries() { 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 extractWAV(SampleId id, std::string_view destDir, const unsigned char* samp) const;
void extractAllWAV(amuse::SystemStringView destDir, const unsigned char* samp) const; void extractAllWAV(std::string_view destDir, const unsigned char* samp) const;
void extractCompressed(SampleId id, amuse::SystemStringView destDir, const unsigned char* samp) const; void extractCompressed(SampleId id, std::string_view destDir, const unsigned char* samp) const;
void extractAllCompressed(amuse::SystemStringView 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; 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 #define WIN32_LEAN_AND_MEAN 1
#endif #endif
#include <Windows.h> #include <Windows.h>
#include <nowide/stackstring.hpp>
#endif #endif
#if __SWITCH__ #if __SWITCH__
@ -325,44 +326,37 @@ inline typename std::enable_if_t<!std::is_base_of_v<IObj, Tp>, ObjToken<Tp>> Mak
#endif #endif
#endif #endif
#ifdef _WIN32 #if _WIN32
using SystemString = std::wstring; static inline int Mkdir(const char* path, int) {
using SystemStringView = std::wstring_view; const nowide::wstackstring str(path);
using SystemChar = wchar_t; return _wmkdir(str.get());
#ifndef _SYS_STR }
#define _SYS_STR(val) L##val
#endif using Sstat = struct ::_stat64;
typedef struct _stat Sstat; static inline int Stat(const char* path, Sstat* statout) {
inline int Mkdir(const wchar_t* path, int) { return _wmkdir(path); } const nowide::wstackstring wpath(path);
inline int Stat(const wchar_t* path, Sstat* statout) { return _wstat(path, statout); } return _wstat64(wpath.get(), statout);
}
#else #else
using SystemString = std::string; static inline int Mkdir(const char* path, mode_t mode) { return CreateDirectoryA(path, mode); }
using SystemStringView = std::string_view;
using SystemChar = char;
#ifndef _SYS_STR
#define _SYS_STR(val) val
#endif
typedef struct stat Sstat; typedef struct stat Sstat;
inline int Mkdir(const char* path, mode_t mode) { return mkdir(path, mode); } static inline int Stat(const char* path, Sstat* statout) { return stat(path, statout); }
inline int Stat(const char* path, Sstat* statout) { return stat(path, statout); }
#endif #endif
inline int Rename(const SystemChar* oldpath, const SystemChar* newpath) { inline int Rename(const char* oldpath, const char* newpath) {
#if _WIN32 #if _WIN32
// return _wrename(oldpath, newpath); const nowide::wstackstring woldpath(oldpath);
return MoveFileExW(oldpath, newpath, MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH) == 0; const nowide::wstackstring wnewpath(newpath);
return MoveFileExW(woldpath.get(), wnewpath.get(), MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH) == 0;
#else #else
return rename(oldpath, newpath); return rename(oldpath, newpath);
#endif #endif
} }
inline int CompareCaseInsensitive(const char* a, const char* b) {
#if _WIN32 #if _WIN32
inline int CompareCaseInsensitive(const char* a, const char* b) { return _stricmp(a, b); } return _stricmp(a, b);
#endif
inline int CompareCaseInsensitive(const SystemChar* a, const SystemChar* b) {
#if _WIN32
return _wcsicmp(a, b);
#else #else
return strcasecmp(a, b); return strcasecmp(a, b);
#endif #endif
@ -389,20 +383,12 @@ constexpr T ClampFull(float in) noexcept {
#define M_PIF 3.14159265358979323846f /* pi */ #define M_PIF 3.14159265358979323846f /* pi */
#endif #endif
inline const SystemChar* StrRChr(const SystemChar* str, SystemChar ch) { inline const char* StrRChr(const char* str, char ch) {
#if _WIN32
return wcsrchr(str, ch);
#else
return strrchr(str, ch); return strrchr(str, ch);
#endif
} }
inline SystemChar* StrRChr(SystemChar* str, SystemChar ch) { inline char* StrRChr(char* str, char ch) {
#if _WIN32
return wcsrchr(str, ch);
#else
return strrchr(str, ch); return strrchr(str, ch);
#endif
} }
inline int FSeek(FILE* fp, int64_t offset, int whence) { inline int FSeek(FILE* fp, int64_t offset, int whence) {
@ -425,9 +411,11 @@ inline int64_t FTell(FILE* fp) {
#endif #endif
} }
inline FILE* FOpen(const SystemChar* path, const SystemChar* mode) { inline FILE* FOpen(const char* path, const char* mode) {
#if _WIN32 #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) if (!fp)
return nullptr; return nullptr;
#else #else
@ -438,15 +426,16 @@ inline FILE* FOpen(const SystemChar* path, const SystemChar* mode) {
return fp; return fp;
} }
inline void Unlink(const SystemChar* file) { inline void Unlink(const char* file) {
#if _WIN32 #if _WIN32
_wunlink(file); const nowide::wstackstring wfile(file);
_wunlink(wfile.get());
#else #else
unlink(file); unlink(file);
#endif #endif
} }
bool Copy(const SystemChar* from, const SystemChar* to); bool Copy(const char* from, const char* to);
#undef bswap16 #undef bswap16
#undef bswap32 #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) 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) {} : m_data(std::move(data)), m_size(size), m_groupId(groupId), m_setupId(setupId) {}
}; };
static const SystemChar* TypeToName(Type tp); static const char* TypeToName(Type tp);
static Type DetectContainerType(const SystemChar* path); static Type DetectContainerType(const char* path);
static std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> LoadContainer(const SystemChar* path); static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadContainer(const char* path);
static std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> LoadContainer(const SystemChar* path, static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadContainer(const char* path,
Type& typeOut); 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 } // namespace amuse

View File

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

View File

@ -19,7 +19,7 @@ void AudioGroup::assign(const AudioGroupData& data) {
m_sdir = AudioGroupSampleDirectory::CreateAudioGroupSampleDirectory(data); m_sdir = AudioGroupSampleDirectory::CreateAudioGroupSampleDirectory(data);
m_samp = data.getSamp(); m_samp = data.getSamp();
} }
void AudioGroup::assign(SystemStringView groupPath) { void AudioGroup::assign(std::string_view groupPath) {
/* Reverse order when loading intermediates */ /* Reverse order when loading intermediates */
m_groupPath = groupPath; m_groupPath = groupPath;
m_sdir = AudioGroupSampleDirectory::CreateAudioGroupSampleDirectory(groupPath); m_sdir = AudioGroupSampleDirectory::CreateAudioGroupSampleDirectory(groupPath);
@ -27,7 +27,7 @@ void AudioGroup::assign(SystemStringView groupPath) {
m_proj = AudioGroupProject::CreateAudioGroupProject(groupPath); m_proj = AudioGroupProject::CreateAudioGroupProject(groupPath);
m_samp = nullptr; 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 */ /* Reverse order when loading intermediates */
m_groupPath = groupPath; m_groupPath = groupPath;
m_sdir = AudioGroupSampleDirectory::CreateAudioGroupSampleDirectory(groupPath); m_sdir = AudioGroupSampleDirectory::CreateAudioGroupSampleDirectory(groupPath);
@ -43,27 +43,23 @@ const SampleEntry* AudioGroup::getSample(SampleId sfxId) const {
return search->second.get(); return search->second.get();
} }
SystemString AudioGroup::getSampleBasePath(SampleId sfxId) const { std::string AudioGroup::getSampleBasePath(SampleId sfxId) const {
#if _WIN32 return m_groupPath + '/' + SampleId::CurNameDB->resolveNameFromId(sfxId).data();
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::pair<ObjToken<SampleEntryData>, const unsigned char*> AudioGroup::getSampleData(SampleId sfxId, std::pair<ObjToken<SampleEntryData>, const unsigned char*> AudioGroup::getSampleData(SampleId sfxId,
const SampleEntry* sample) const { const SampleEntry* sample) const {
if (sample->m_data->m_looseData) { if (sample->m_data->m_looseData) {
SystemString basePath = getSampleBasePath(sfxId); std::string basePath = getSampleBasePath(sfxId);
const_cast<SampleEntry*>(sample)->loadLooseData(basePath); const_cast<SampleEntry*>(sample)->loadLooseData(basePath);
return {sample->m_data, sample->m_data->m_looseData.get()}; return {sample->m_data, sample->m_data->m_looseData.get()};
} }
return {sample->m_data, m_samp + sample->m_data->m_sampleOff}; 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) { if (sample->m_data->m_looseData) {
SystemString basePath = getSampleBasePath(sfxId); std::string basePath = getSampleBasePath(sfxId);
return sample->getFileState(basePath, pathOut); return sample->getFileState(basePath, pathOut);
} }
if (sample->m_data->isFormatDSP() || sample->m_data->getSampleFormat() == SampleFormat::N64) 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 { void AudioGroup::patchSampleMetadata(SampleId sfxId, const SampleEntry* sample) const {
if (sample->m_data->m_looseData) { if (sample->m_data->m_looseData) {
SystemString basePath = getSampleBasePath(sfxId); std::string basePath = getSampleBasePath(sfxId);
sample->patchSampleMetadata(basePath); sample->patchSampleMetadata(basePath);
} }
} }
@ -91,25 +87,25 @@ void AudioGroup::makeCompressedVersion(SampleId sfxId, const SampleEntry* sample
} }
void AudioGroupDatabase::renameSample(SampleId id, std::string_view str) { void AudioGroupDatabase::renameSample(SampleId id, std::string_view str) {
SystemString oldBasePath = getSampleBasePath(id); std::string oldBasePath = getSampleBasePath(id);
SampleId::CurNameDB->rename(id, str); SampleId::CurNameDB->rename(id, str);
SystemString newBasePath = getSampleBasePath(id); std::string newBasePath = getSampleBasePath(id);
Rename((oldBasePath + _SYS_STR(".wav")).c_str(), (newBasePath + _SYS_STR(".wav")).c_str()); Rename((oldBasePath + ".wav").c_str(), (newBasePath + ".wav").c_str());
Rename((oldBasePath + _SYS_STR(".dsp")).c_str(), (newBasePath + _SYS_STR(".dsp")).c_str()); Rename((oldBasePath + ".dsp").c_str(), (newBasePath + ".dsp").c_str());
Rename((oldBasePath + _SYS_STR(".vadpcm")).c_str(), (newBasePath + _SYS_STR(".vadpcm")).c_str()); Rename((oldBasePath + ".vadpcm").c_str(), (newBasePath + ".vadpcm").c_str());
} }
void AudioGroupDatabase::deleteSample(SampleId id) { void AudioGroupDatabase::deleteSample(SampleId id) {
SystemString basePath = getSampleBasePath(id); std::string basePath = getSampleBasePath(id);
Unlink((basePath + _SYS_STR(".wav")).c_str()); Unlink((basePath + ".wav").c_str());
Unlink((basePath + _SYS_STR(".dsp")).c_str()); Unlink((basePath + ".dsp").c_str());
Unlink((basePath + _SYS_STR(".vadpcm")).c_str()); Unlink((basePath + ".vadpcm").c_str());
} }
void AudioGroupDatabase::copySampleInto(const SystemString& basePath, const SystemString& newBasePath) { void AudioGroupDatabase::copySampleInto(const std::string& basePath, const std::string& newBasePath) {
Copy((basePath + _SYS_STR(".wav")).c_str(), (newBasePath + _SYS_STR(".wav")).c_str()); Copy((basePath + ".wav").c_str(), (newBasePath + ".wav").c_str());
Copy((basePath + _SYS_STR(".dsp")).c_str(), (newBasePath + _SYS_STR(".dsp")).c_str()); Copy((basePath + ".dsp").c_str(), (newBasePath + ".dsp").c_str());
Copy((basePath + _SYS_STR(".vadpcm")).c_str(), (newBasePath + _SYS_STR(".vadpcm")).c_str()); Copy((basePath + ".vadpcm").c_str(), (newBasePath + ".vadpcm").c_str());
} }
void AudioGroupDatabase::_recursiveRenameMacro(SoundMacroId id, std::string_view str, int& macroIdx, 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; AudioGroupPool ret;
SystemString poolPath(groupPath); std::string poolPath(groupPath);
poolPath += _SYS_STR("/!pool.yaml"); poolPath += "/!pool.yaml";
athena::io::FileReader fi(poolPath, 32 * 1024, false); athena::io::FileReader fi(poolPath, 32 * 1024, false);
if (!fi.hasError()) { 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; AudioGroupProject ret;
SystemString projPath(groupPath); std::string projPath(groupPath);
projPath += _SYS_STR("/!project.yaml"); projPath += "/!project.yaml";
athena::io::FileReader fi(projPath, 32 * 1024, false); athena::io::FileReader fi(projPath, 32 * 1024, false);
if (!fi.hasError()) { 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); athena::io::FileReader r(dspPath);
if (!r.hasError()) { if (!r.hasError()) {
DSPADPCMHeader header; 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); athena::io::FileReader r(vadpcmPath);
if (!r.hasError()) { if (!r.hasError()) {
VADPCMHeader header; 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); athena::io::FileReader r(wavPath);
if (!r.hasError()) { if (!r.hasError()) {
atUint32 riffMagic = r.readUint32Little(); atUint32 riffMagic = r.readUint32Little();
@ -242,10 +242,10 @@ void AudioGroupSampleDirectory::EntryData::loadLooseWAV(SystemStringView wavPath
} }
} }
void AudioGroupSampleDirectory::Entry::loadLooseData(SystemStringView basePath) { void AudioGroupSampleDirectory::Entry::loadLooseData(std::string_view basePath) {
SystemString wavPath = SystemString(basePath) + _SYS_STR(".wav"); std::string wavPath = std::string(basePath) + ".wav";
SystemString dspPath = SystemString(basePath) + _SYS_STR(".dsp"); std::string dspPath = std::string(basePath) + ".dsp";
SystemString vadpcmPath = SystemString(basePath) + _SYS_STR(".vadpcm"); std::string vadpcmPath = std::string(basePath) + ".vadpcm";
Sstat wavStat, dspStat, vadpcmStat; Sstat wavStat, dspStat, vadpcmStat;
bool wavValid = !Stat(wavPath.c_str(), &wavStat) && S_ISREG(wavStat.st_mode); bool wavValid = !Stat(wavPath.c_str(), &wavStat) && S_ISREG(wavStat.st_mode);
bool dspValid = !Stat(dspPath.c_str(), &dspStat) && S_ISREG(dspStat.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 { SampleFileState AudioGroupSampleDirectory::Entry::getFileState(std::string_view basePath, std::string* pathOut) const {
SystemString wavPath = SystemString(basePath) + _SYS_STR(".wav"); std::string wavPath = std::string(basePath) + ".wav";
SystemString dspPath = SystemString(basePath) + _SYS_STR(".dsp"); std::string dspPath = std::string(basePath) + ".dsp";
SystemString vadpcmPath = SystemString(basePath) + _SYS_STR(".vadpcm"); std::string vadpcmPath = std::string(basePath) + ".vadpcm";
Sstat wavStat, dspStat, vadpcmStat; Sstat wavStat, dspStat, vadpcmStat;
bool wavValid = !Stat(wavPath.c_str(), &wavStat) && S_ISREG(wavStat.st_mode); bool wavValid = !Stat(wavPath.c_str(), &wavStat) && S_ISREG(wavStat.st_mode);
bool dspValid = !Stat(dspPath.c_str(), &dspStat) && S_ISREG(dspStat.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; return SampleFileState::WAVNoCompressed;
} }
void AudioGroupSampleDirectory::EntryData::patchMetadataDSP(SystemStringView dspPath) { void AudioGroupSampleDirectory::EntryData::patchMetadataDSP(std::string_view dspPath) {
athena::io::FileReader r(dspPath); athena::io::FileReader r(dspPath);
if (!r.hasError()) { if (!r.hasError()) {
DSPADPCMHeader head; 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); athena::io::FileWriter w(vadpcmPath, false);
if (!w.hasError()) { if (!w.hasError()) {
w.seek(0, athena::SeekOrigin::Begin); 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); athena::io::FileReader r(wavPath);
if (!r.hasError()) { if (!r.hasError()) {
atUint32 riffMagic = r.readUint32Little(); atUint32 riffMagic = r.readUint32Little();
@ -513,10 +513,11 @@ void AudioGroupSampleDirectory::EntryData::patchMetadataWAV(SystemStringView wav
} }
/* File timestamps reflect actual audio content, not loop/pitch data */ /* 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 #if _WIN32
__utimbuf64 times = {stat.st_atime, stat.st_mtime}; __utimbuf64 times = {stat.st_atime, stat.st_mtime};
_wutime64(path.c_str(), &times); const nowide::wstackstring wpath(path);
_wutime64(wpath.get(), &times);
#else #else
#if __APPLE__ #if __APPLE__
struct timespec times[] = {stat.st_atimespec, stat.st_mtimespec}; struct timespec times[] = {stat.st_atimespec, stat.st_mtimespec};
@ -529,10 +530,10 @@ static void SetAudioFileTime(const SystemString& path, const Sstat& stat) {
#endif #endif
} }
void AudioGroupSampleDirectory::Entry::patchSampleMetadata(SystemStringView basePath) const { void AudioGroupSampleDirectory::Entry::patchSampleMetadata(std::string_view basePath) const {
SystemString wavPath = SystemString(basePath) + _SYS_STR(".wav"); std::string wavPath = std::string(basePath) + ".wav";
SystemString dspPath = SystemString(basePath) + _SYS_STR(".dsp"); std::string dspPath = std::string(basePath) + ".dsp";
SystemString vadpcmPath = SystemString(basePath) + _SYS_STR(".vadpcm"); std::string vadpcmPath = std::string(basePath) + ".vadpcm";
Sstat wavStat, dspStat, vadpcmStat; Sstat wavStat, dspStat, vadpcmStat;
bool wavValid = !Stat(wavPath.c_str(), &wavStat) && S_ISREG(wavStat.st_mode); bool wavValid = !Stat(wavPath.c_str(), &wavStat) && S_ISREG(wavStat.st_mode);
bool dspValid = !Stat(dspPath.c_str(), &dspStat) && S_ISREG(dspStat.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; AudioGroupSampleDirectory ret;
DirectoryEnumerator de(groupPath, DirectoryEnumerator::Mode::FilesSorted); DirectoryEnumerator de(groupPath, DirectoryEnumerator::Mode::FilesSorted);
for (const DirectoryEnumerator::Entry& ent : de) { for (const DirectoryEnumerator::Entry& ent : de) {
if (ent.m_name.size() < 4) if (ent.m_name.size() < 4)
continue; continue;
SystemString baseName; std::string baseName;
SystemString basePath; std::string basePath;
if (!CompareCaseInsensitive(ent.m_name.data() + ent.m_name.size() - 4, _SYS_STR(".dsp")) || if (!CompareCaseInsensitive(ent.m_name.data() + ent.m_name.size() - 4, ".dsp") ||
!CompareCaseInsensitive(ent.m_name.data() + ent.m_name.size() - 4, _SYS_STR(".wav"))) { !CompareCaseInsensitive(ent.m_name.data() + ent.m_name.size() - 4, ".wav")) {
baseName = SystemString(ent.m_name.begin(), ent.m_name.begin() + ent.m_name.size() - 4); baseName = std::string(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); basePath = std::string(ent.m_path.begin(), ent.m_path.begin() + ent.m_path.size() - 4);
} else if (ent.m_name.size() > 7 && } else if (ent.m_name.size() > 7 &&
!CompareCaseInsensitive(ent.m_name.data() + ent.m_name.size() - 7, _SYS_STR(".vadpcm"))) { !CompareCaseInsensitive(ent.m_name.data() + ent.m_name.size() - 7, ".vadpcm")) {
baseName = SystemString(ent.m_name.begin(), ent.m_name.begin() + ent.m_name.size() - 7); baseName = std::string(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); basePath = std::string(ent.m_path.begin(), ent.m_path.begin() + ent.m_path.size() - 7);
} else } else
continue; continue;
ObjectId sampleId = SampleId::CurNameDB->generateId(NameDB::Type::Sample); ObjectId sampleId = SampleId::CurNameDB->generateId(NameDB::Type::Sample);
#ifdef _WIN32
SampleId::CurNameDB->registerPair(athena::utility::wideToUtf8(baseName), sampleId);
#else
SampleId::CurNameDB->registerPair(baseName, sampleId); SampleId::CurNameDB->registerPair(baseName, sampleId);
#endif
auto& entry = ret.m_entries[sampleId]; auto& entry = ret.m_entries[sampleId];
entry = MakeObj<Entry>(); entry = MakeObj<Entry>();
@ -591,18 +588,14 @@ AudioGroupSampleDirectory AudioGroupSampleDirectory::CreateAudioGroupSampleDirec
return ret; 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) { const unsigned char* samp) {
SystemString path(destDir); std::string path(destDir);
path += _SYS_STR("/"); path += "/";
#ifdef _WIN32
path += athena::utility::utf8ToWide(SampleId::CurNameDB->resolveNameFromId(id));
#else
path += SampleId::CurNameDB->resolveNameFromId(id); path += SampleId::CurNameDB->resolveNameFromId(id);
#endif std::string dspPath = path;
SystemString dspPath = path; path += ".wav";
path += _SYS_STR(".wav"); dspPath += ".dsp";
dspPath += _SYS_STR(".dsp");
athena::io::FileWriter w(path); athena::io::FileWriter w(path);
SampleFormat fmt = SampleFormat(ent.m_numSamples >> 24); 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 { const unsigned char* samp) const {
auto search = m_entries.find(id); auto search = m_entries.find(id);
if (search == m_entries.cend()) 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); _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) for (const auto& ent : m_entries)
_extractWAV(ent.first, *ent.second->m_data, destDir, samp + ent.second->m_data->m_sampleOff); _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) { const unsigned char* samp, bool compressWAV) {
SampleFormat fmt = ent.getSampleFormat(); SampleFormat fmt = ent.getSampleFormat();
if (!compressWAV && (fmt == SampleFormat::PCM || fmt == SampleFormat::PCM_PC)) { if (!compressWAV && (fmt == SampleFormat::PCM || fmt == SampleFormat::PCM_PC)) {
@ -709,13 +702,9 @@ void AudioGroupSampleDirectory::_extractCompressed(SampleId id, const EntryData&
return; return;
} }
amuse::SystemString path(destDir); std::string path(destDir);
path += _SYS_STR("/"); path += "/";
#ifdef _WIN32
path += athena::utility::utf8ToWide(SampleId::CurNameDB->resolveNameFromId(id));
#else
path += SampleId::CurNameDB->resolveNameFromId(id); path += SampleId::CurNameDB->resolveNameFromId(id);
#endif
uint32_t numSamples = ent.getNumSamples(); uint32_t numSamples = ent.getNumSamples();
atUint64 dataLen = 0; 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.x44_loop_ps = ent.m_ADPCMParms.dsp.m_lps;
header.m_pitch = ent.m_pitch; header.m_pitch = ent.m_pitch;
path += _SYS_STR(".dsp"); path += ".dsp";
athena::io::FileWriter w(path); athena::io::FileWriter w(path);
header.write(w); header.write(w);
dataLen = (header.x4_num_nibbles + 1) / 2; dataLen = (header.x4_num_nibbles + 1) / 2;
w.writeUBytes(samp, dataLen); w.writeUBytes(samp, dataLen);
} else if (fmt == SampleFormat::N64) { } else if (fmt == SampleFormat::N64) {
path += _SYS_STR(".vadpcm"); path += ".vadpcm";
athena::io::FileWriter w(path); athena::io::FileWriter w(path);
VADPCMHeader header; VADPCMHeader header;
header.m_pitchSampleRate = ent.m_pitch << 24; header.m_pitchSampleRate = ent.m_pitch << 24;
@ -780,7 +769,7 @@ void AudioGroupSampleDirectory::_extractCompressed(SampleId id, const EntryData&
} }
DSPCorrelateCoefs(samps, numSamples, header.x1c_coef); DSPCorrelateCoefs(samps, numSamples, header.x1c_coef);
path += _SYS_STR(".dsp"); path += ".dsp";
athena::io::FileWriter w(path); athena::io::FileWriter w(path);
header.write(w); 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 { const unsigned char* samp) const {
auto search = m_entries.find(id); auto search = m_entries.find(id);
if (search == m_entries.cend()) 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); _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) for (const auto& ent : m_entries)
_extractCompressed(ent.first, *ent.second->m_data, destDir, samp + ent.second->m_data->m_sampleOff); _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); DirectoryEnumerator de(groupPath, DirectoryEnumerator::Mode::FilesSorted);
for (const DirectoryEnumerator::Entry& ent : de) { for (const DirectoryEnumerator::Entry& ent : de) {
if (ent.m_name.size() < 4) if (ent.m_name.size() < 4)
continue; continue;
SystemString baseName; std::string baseName;
SystemString basePath; std::string basePath;
if (!CompareCaseInsensitive(ent.m_name.data() + ent.m_name.size() - 4, _SYS_STR(".dsp")) || if (!CompareCaseInsensitive(ent.m_name.data() + ent.m_name.size() - 4, ".dsp") ||
!CompareCaseInsensitive(ent.m_name.data() + ent.m_name.size() - 4, _SYS_STR(".wav"))) { !CompareCaseInsensitive(ent.m_name.data() + ent.m_name.size() - 4, ".wav")) {
baseName = SystemString(ent.m_name.begin(), ent.m_name.begin() + ent.m_name.size() - 4); baseName = std::string(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); basePath = std::string(ent.m_path.begin(), ent.m_path.begin() + ent.m_path.size() - 4);
} else if (ent.m_name.size() > 7 && } else if (ent.m_name.size() > 7 &&
!CompareCaseInsensitive(ent.m_name.data() + ent.m_name.size() - 7, _SYS_STR(".vadpcm"))) { !CompareCaseInsensitive(ent.m_name.data() + ent.m_name.size() - 7, ".vadpcm")) {
baseName = SystemString(ent.m_name.begin(), ent.m_name.begin() + ent.m_name.size() - 7); baseName = std::string(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); basePath = std::string(ent.m_path.begin(), ent.m_path.begin() + ent.m_path.size() - 7);
} else } else
continue; continue;
#ifdef _WIN32 if (SampleId::CurNameDB->m_stringToId.find(baseName) == SampleId::CurNameDB->m_stringToId.end()) {
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()) {
ObjectId sampleId = SampleId::CurNameDB->generateId(NameDB::Type::Sample); ObjectId sampleId = SampleId::CurNameDB->generateId(NameDB::Type::Sample);
SampleId::CurNameDB->registerPair(baseNameStd, sampleId); SampleId::CurNameDB->registerPair(baseName, sampleId);
auto& entry = m_entries[sampleId]; auto& entry = m_entries[sampleId];
entry = MakeObj<Entry>(); entry = MakeObj<Entry>();
@ -887,8 +870,8 @@ AudioGroupSampleDirectory::toGCNData(const AudioGroupDatabase& group) const {
size_t sampleOffset = 0; size_t sampleOffset = 0;
size_t adpcmOffset = 0; size_t adpcmOffset = 0;
for (const auto& ent : SortUnorderedMap(m_entries)) { for (const auto& ent : SortUnorderedMap(m_entries)) {
amuse::SystemString path = group.getSampleBasePath(ent.first); std::string path = group.getSampleBasePath(ent.first);
path += _SYS_STR(".dsp"); path += ".dsp";
SampleFileState state = group.getSampleFileState(ent.first, ent.second.get().get(), &path); SampleFileState state = group.getSampleFileState(ent.first, ent.second.get().get(), &path);
switch (state) { switch (state) {
case SampleFileState::MemoryOnlyWAV: case SampleFileState::MemoryOnlyWAV:

View File

@ -12,9 +12,11 @@ using namespace std::literals;
namespace amuse { namespace amuse {
static logvisor::Module Log("amuse"); static logvisor::Module Log("amuse");
bool Copy(const SystemChar* from, const SystemChar* to) { bool Copy(const char* from, const char* to) {
#if _WIN32 #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 #else
FILE* fi = fopen(from, "rb"); FILE* fi = fopen(from, "rb");
if (!fi) if (!fi)

View File

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

View File

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

View File

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