mirror of https://github.com/AxioDL/amuse.git
wchar_t support for key path handling functions on Windows
This commit is contained in:
parent
e4ae1f1f88
commit
fa3007b65c
|
@ -255,6 +255,7 @@ void AudioGroupFilePresenter::addCollection(const std::wstring& name,
|
||||||
{
|
{
|
||||||
std::wstring path = m_backend.getUserDir() + L'\\' + name;
|
std::wstring path = m_backend.getUserDir() + L'\\' + name;
|
||||||
AudioGroupCollection& insert = *m_audioGroupCollections.emplace(name, std::make_unique<AudioGroupCollection>(path, name)).first->second;
|
AudioGroupCollection& insert = *m_audioGroupCollections.emplace(name, std::make_unique<AudioGroupCollection>(path, name)).first->second;
|
||||||
|
CreateDirectory(insert.m_path.c_str(), nullptr);
|
||||||
insert.addCollection(*this, std::move(collection));
|
insert.addCollection(*this, std::move(collection));
|
||||||
|
|
||||||
for (std::pair<const std::wstring, std::unique_ptr<AudioGroupDataCollection>>& pair : insert.m_groups)
|
for (std::pair<const std::wstring, std::unique_ptr<AudioGroupDataCollection>>& pair : insert.m_groups)
|
||||||
|
@ -299,11 +300,34 @@ void AudioGroupFilePresenter::addCollection(const std::wstring& name,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AudioGroupCollection::populateFiles(VSTEditor& editor, HTREEITEM colHandle)
|
||||||
|
{
|
||||||
|
TVINSERTSTRUCT ins = {};
|
||||||
|
ins.item.mask = TVIF_TEXT;
|
||||||
|
ins.hParent = colHandle;
|
||||||
|
ins.hInsertAfter = TVI_LAST;
|
||||||
|
|
||||||
|
for (const auto& group : m_groups)
|
||||||
|
{
|
||||||
|
ins.item.pszText = LPWSTR(group.first.c_str());
|
||||||
|
TreeView_InsertItem(editor.m_collectionTree, &ins);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void AudioGroupFilePresenter::populateEditor(VSTEditor& editor)
|
void AudioGroupFilePresenter::populateEditor(VSTEditor& editor)
|
||||||
{
|
{
|
||||||
for (const auto& cgollection : m_audioGroupCollections)
|
TreeView_DeleteAllItems(editor.m_collectionTree);
|
||||||
{
|
TVINSERTSTRUCT ins = {};
|
||||||
|
ins.hParent = TVI_ROOT;
|
||||||
|
ins.hInsertAfter = TVI_LAST;
|
||||||
|
ins.item.mask = TVIF_CHILDREN | TVIF_TEXT;
|
||||||
|
|
||||||
|
for (const auto& collection : m_audioGroupCollections)
|
||||||
|
{
|
||||||
|
ins.item.cChildren = collection.second->m_groups.size() ? 1 : 0;
|
||||||
|
ins.item.pszText = LPWSTR(collection.first.c_str());
|
||||||
|
HTREEITEM item = TreeView_InsertItem(editor.m_collectionTree, &ins);
|
||||||
|
collection.second->populateFiles(editor, item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,10 @@
|
||||||
#include <amuse/amuse.hpp>
|
#include <amuse/amuse.hpp>
|
||||||
#include <athena/FileReader.hpp>
|
#include <athena/FileReader.hpp>
|
||||||
|
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <windows.h>
|
||||||
|
#include <CommCtrl.h>
|
||||||
|
|
||||||
namespace amuse
|
namespace amuse
|
||||||
{
|
{
|
||||||
class VSTBackend;
|
class VSTBackend;
|
||||||
|
@ -70,8 +74,7 @@ struct AudioGroupCollection
|
||||||
void addCollection(AudioGroupFilePresenter& presenter,
|
void addCollection(AudioGroupFilePresenter& presenter,
|
||||||
std::vector<std::pair<std::wstring, amuse::IntrusiveAudioGroupData>>&& collection);
|
std::vector<std::pair<std::wstring, amuse::IntrusiveAudioGroupData>>&& collection);
|
||||||
void update(AudioGroupFilePresenter& presenter);
|
void update(AudioGroupFilePresenter& presenter);
|
||||||
|
void populateFiles(VSTEditor& editor, HTREEITEM colHandle);
|
||||||
//void populate
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class AudioGroupFilePresenter
|
class AudioGroupFilePresenter
|
||||||
|
|
|
@ -130,7 +130,7 @@ namespace amuse
|
||||||
static logvisor::Module Log("amuse::AudioUnitBackend");
|
static logvisor::Module Log("amuse::AudioUnitBackend");
|
||||||
|
|
||||||
VSTBackend::VSTBackend(audioMasterCallback cb)
|
VSTBackend::VSTBackend(audioMasterCallback cb)
|
||||||
: AudioEffectX(cb, 0, 0), m_editor(*this)
|
: AudioEffectX(cb, 0, 0), m_filePresenter(*this), m_editor(*this)
|
||||||
{
|
{
|
||||||
isSynth();
|
isSynth();
|
||||||
setUniqueID(kBackendID);
|
setUniqueID(kBackendID);
|
||||||
|
@ -149,6 +149,8 @@ VSTBackend::VSTBackend(audioMasterCallback cb)
|
||||||
m_userDir = std::wstring(path) + L"\\Amuse";
|
m_userDir = std::wstring(path) + L"\\Amuse";
|
||||||
CreateDirectory(m_userDir.c_str(), nullptr);
|
CreateDirectory(m_userDir.c_str(), nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_filePresenter.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
VSTBackend::~VSTBackend()
|
VSTBackend::~VSTBackend()
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "amuse/IBackendVoice.hpp"
|
#include "amuse/IBackendVoice.hpp"
|
||||||
#include "amuse/IBackendSubmix.hpp"
|
#include "amuse/IBackendSubmix.hpp"
|
||||||
#include "amuse/IBackendVoiceAllocator.hpp"
|
#include "amuse/IBackendVoiceAllocator.hpp"
|
||||||
|
#include "AudioGroupFilePresenter.hpp"
|
||||||
|
|
||||||
namespace amuse
|
namespace amuse
|
||||||
{
|
{
|
||||||
|
@ -32,6 +33,7 @@ class VSTBackend : public AudioEffectX
|
||||||
std::experimental::optional<amuse::Engine> m_engine;
|
std::experimental::optional<amuse::Engine> m_engine;
|
||||||
size_t m_curFrame = 0;
|
size_t m_curFrame = 0;
|
||||||
std::wstring m_userDir;
|
std::wstring m_userDir;
|
||||||
|
AudioGroupFilePresenter m_filePresenter;
|
||||||
VSTEditor m_editor;
|
VSTEditor m_editor;
|
||||||
public:
|
public:
|
||||||
VSTBackend(audioMasterCallback cb);
|
VSTBackend(audioMasterCallback cb);
|
||||||
|
@ -52,6 +54,7 @@ public:
|
||||||
|
|
||||||
amuse::Engine& getAmuseEngine() {return *m_engine;}
|
amuse::Engine& getAmuseEngine() {return *m_engine;}
|
||||||
const std::wstring& getUserDir() const {return m_userDir;}
|
const std::wstring& getUserDir() const {return m_userDir;}
|
||||||
|
AudioGroupFilePresenter& getFilePresenter() {return m_filePresenter;}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,10 @@
|
||||||
#include "FileOpenDialog.hpp"
|
#include "FileOpenDialog.hpp"
|
||||||
#include <Windowsx.h>
|
#include <Windowsx.h>
|
||||||
#include <shellapi.h>
|
#include <shellapi.h>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#undef min
|
||||||
|
#undef max
|
||||||
|
|
||||||
extern void* hInstance;
|
extern void* hInstance;
|
||||||
static WNDPROC OriginalListViewProc = 0;
|
static WNDPROC OriginalListViewProc = 0;
|
||||||
|
@ -294,6 +298,7 @@ bool VSTEditor::open(void* ptr)
|
||||||
ListView_InsertItem(m_pageListView, &item);
|
ListView_InsertItem(m_pageListView, &item);
|
||||||
ShowWindow(m_pageListView, SW_SHOW);
|
ShowWindow(m_pageListView, SW_SHOW);
|
||||||
|
|
||||||
|
m_backend.getFilePresenter().populateEditor(*this);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,21 +315,38 @@ void VSTEditor::update()
|
||||||
|
|
||||||
void VSTEditor::addAction()
|
void VSTEditor::addAction()
|
||||||
{
|
{
|
||||||
VstFileSelect fSelect = {};
|
std::wstring path = openDB();
|
||||||
fSelect.command = kVstFileLoad;
|
if (path.size())
|
||||||
fSelect.type = kVstFileType;
|
|
||||||
strcpy(fSelect.title, "Select Audio Group Archive");
|
|
||||||
if (m_backend.openFileSelector(&fSelect))
|
|
||||||
{
|
{
|
||||||
m_backend.closeFileSelector(&fSelect);
|
amuse::ContainerRegistry::Type containerType;
|
||||||
}
|
std::vector<std::pair<std::wstring, amuse::IntrusiveAudioGroupData>> data =
|
||||||
else
|
amuse::ContainerRegistry::LoadContainer(path.c_str(), containerType);
|
||||||
{
|
if (data.empty())
|
||||||
std::wstring path = openDB();
|
|
||||||
if (path.size())
|
|
||||||
{
|
{
|
||||||
|
wchar_t msg[512];
|
||||||
|
SNPrintf(msg, 512, L"Unable to load Audio Groups from %s", path.c_str());
|
||||||
|
MessageBoxW(nullptr, msg, L"Invalid Data File", MB_OK | MB_ICONERROR);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SystemString name(amuse::ContainerRegistry::TypeToName(containerType));
|
||||||
|
if (containerType == amuse::ContainerRegistry::Type::Raw4)
|
||||||
|
{
|
||||||
|
size_t dotpos = path.rfind(L'.');
|
||||||
|
if (dotpos != std::string::npos)
|
||||||
|
name.assign(path.cbegin(), path.cbegin() + dotpos);
|
||||||
|
size_t slashpos = name.rfind(L'\\');
|
||||||
|
size_t fslashpos = name.rfind(L"/");
|
||||||
|
if (slashpos == std::string::npos)
|
||||||
|
slashpos = fslashpos;
|
||||||
|
else if (fslashpos != std::string::npos)
|
||||||
|
slashpos = std::max(slashpos, fslashpos);
|
||||||
|
if (slashpos != std::string::npos)
|
||||||
|
name.assign(name.cbegin() + slashpos + 1, name.cend());
|
||||||
|
}
|
||||||
|
|
||||||
|
m_backend.getFilePresenter().addCollection(name, std::move(data));
|
||||||
|
m_backend.getFilePresenter().populateEditor(*this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ class VSTBackend;
|
||||||
class VSTEditor : public AEffEditor
|
class VSTEditor : public AEffEditor
|
||||||
{
|
{
|
||||||
friend class AudioGroupFilePresenter;
|
friend class AudioGroupFilePresenter;
|
||||||
|
friend struct AudioGroupCollection;
|
||||||
|
|
||||||
VSTBackend& m_backend;
|
VSTBackend& m_backend;
|
||||||
ERect m_windowRect = {0, 0, 420, 600};
|
ERect m_windowRect = {0, 0, 420, 600};
|
||||||
|
|
|
@ -639,23 +639,16 @@ struct AppCallback : boo::IApplicationCallback
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if _WIN32
|
amuse::ContainerRegistry::Type cType = amuse::ContainerRegistry::DetectContainerType(m_argv[1]);
|
||||||
char utf8Path[1024];
|
|
||||||
WideCharToMultiByte(CP_UTF8, 0, m_argv[1], -1, utf8Path, 1024, nullptr, nullptr);
|
|
||||||
#else
|
|
||||||
const char* utf8Path = m_argv[1];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
amuse::ContainerRegistry::Type cType = amuse::ContainerRegistry::DetectContainerType(utf8Path);
|
|
||||||
if (cType == amuse::ContainerRegistry::Type::Invalid)
|
if (cType == amuse::ContainerRegistry::Type::Invalid)
|
||||||
{
|
{
|
||||||
Log.report(logvisor::Error, "invalid/no data at path argument");
|
Log.report(logvisor::Error, "invalid/no data at path argument");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
Log.report(logvisor::Info, "Found '%s' Audio Group data", amuse::ContainerRegistry::TypeToName(cType));
|
Log.report(logvisor::Info, _S("Found '%s' Audio Group data"), amuse::ContainerRegistry::TypeToName(cType));
|
||||||
|
|
||||||
std::vector<std::pair<std::string, amuse::IntrusiveAudioGroupData>> data =
|
std::vector<std::pair<amuse::SystemString, amuse::IntrusiveAudioGroupData>> data =
|
||||||
amuse::ContainerRegistry::LoadContainer(utf8Path);
|
amuse::ContainerRegistry::LoadContainer(m_argv[1]);
|
||||||
if (data.empty())
|
if (data.empty())
|
||||||
{
|
{
|
||||||
Log.report(logvisor::Error, "invalid/no data at path argument");
|
Log.report(logvisor::Error, "invalid/no data at path argument");
|
||||||
|
@ -663,8 +656,8 @@ struct AppCallback : boo::IApplicationCallback
|
||||||
}
|
}
|
||||||
|
|
||||||
std::list<amuse::AudioGroupProject> m_projs;
|
std::list<amuse::AudioGroupProject> m_projs;
|
||||||
std::map<int, std::pair<std::pair<std::string, amuse::IntrusiveAudioGroupData>*, const amuse::SongGroupIndex*>> allSongGroups;
|
std::map<int, std::pair<std::pair<amuse::SystemString, amuse::IntrusiveAudioGroupData>*, const amuse::SongGroupIndex*>> allSongGroups;
|
||||||
std::map<int, std::pair<std::pair<std::string, amuse::IntrusiveAudioGroupData>*, const amuse::SFXGroupIndex*>> allSFXGroups;
|
std::map<int, std::pair<std::pair<amuse::SystemString, amuse::IntrusiveAudioGroupData>*, const amuse::SFXGroupIndex*>> allSFXGroups;
|
||||||
size_t totalGroups = 0;
|
size_t totalGroups = 0;
|
||||||
|
|
||||||
for (auto& grp : data)
|
for (auto& grp : data)
|
||||||
|
@ -687,19 +680,11 @@ struct AppCallback : boo::IApplicationCallback
|
||||||
m_setupId = -1;
|
m_setupId = -1;
|
||||||
|
|
||||||
/* Attempt loading song */
|
/* Attempt loading song */
|
||||||
std::vector<std::pair<std::string, amuse::ContainerRegistry::SongData>> songs;
|
std::vector<std::pair<amuse::SystemString, amuse::ContainerRegistry::SongData>> songs;
|
||||||
if (m_argc > 2)
|
if (m_argc > 2)
|
||||||
{
|
songs = amuse::ContainerRegistry::LoadSongs(m_argv[2]);
|
||||||
#if _WIN32
|
|
||||||
char utf8Path[1024];
|
|
||||||
WideCharToMultiByte(CP_UTF8, 0, m_argv[2], -1, utf8Path, 1024, nullptr, nullptr);
|
|
||||||
#else
|
|
||||||
const char* utf8Path = m_argv[2];
|
|
||||||
#endif
|
|
||||||
songs = amuse::ContainerRegistry::LoadSongs(utf8Path);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
songs = amuse::ContainerRegistry::LoadSongs(utf8Path);
|
songs = amuse::ContainerRegistry::LoadSongs(m_argv[1]);
|
||||||
|
|
||||||
if (songs.size())
|
if (songs.size())
|
||||||
{
|
{
|
||||||
|
@ -739,8 +724,8 @@ struct AppCallback : boo::IApplicationCallback
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
for (const auto& pair : songs)
|
for (const auto& pair : songs)
|
||||||
{
|
{
|
||||||
printf(" %d %s (Group %d, Setup %d)\n", idx++,
|
amuse::Printf(_S(" %d %s (Group %d, Setup %d)\n"), idx++,
|
||||||
pair.first.c_str(), pair.second.m_groupId, pair.second.m_setupId);
|
pair.first.c_str(), pair.second.m_groupId, pair.second.m_setupId);
|
||||||
}
|
}
|
||||||
|
|
||||||
int userSel = 0;
|
int userSel = 0;
|
||||||
|
@ -791,15 +776,15 @@ struct AppCallback : boo::IApplicationCallback
|
||||||
printf("Multiple Audio Groups discovered:\n");
|
printf("Multiple Audio Groups discovered:\n");
|
||||||
for (const auto& pair : allSFXGroups)
|
for (const auto& pair : allSFXGroups)
|
||||||
{
|
{
|
||||||
printf(" %d %s (SFXGroup) %" PRISize " sfx-entries\n",
|
amuse::Printf(_S(" %d %s (SFXGroup) %" PRISize " sfx-entries\n"),
|
||||||
pair.first, pair.second.first->first.c_str(),
|
pair.first, pair.second.first->first.c_str(),
|
||||||
pair.second.second->m_sfxEntries.size());
|
pair.second.second->m_sfxEntries.size());
|
||||||
}
|
}
|
||||||
for (const auto& pair : allSongGroups)
|
for (const auto& pair : allSongGroups)
|
||||||
{
|
{
|
||||||
printf(" %d %s (SongGroup) %" PRISize " normal-pages, %" PRISize " drum-pages\n",
|
amuse::Printf(_S(" %d %s (SongGroup) %" PRISize " normal-pages, %" PRISize " drum-pages\n"),
|
||||||
pair.first, pair.second.first->first.c_str(),
|
pair.first, pair.second.first->first.c_str(),
|
||||||
pair.second.second->m_normPages.size(), pair.second.second->m_drumPages.size());
|
pair.second.second->m_normPages.size(), pair.second.second->m_drumPages.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
int userSel = 0;
|
int userSel = 0;
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#ifndef _MSC_VER
|
#ifndef _MSC_VER
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
|
@ -21,6 +23,20 @@ namespace amuse
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
using SystemString = std::wstring;
|
||||||
|
using SystemChar = wchar_t;
|
||||||
|
# ifndef _S
|
||||||
|
# define _S(val) L ## val
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
using SystemString = std::string;
|
||||||
|
using SystemChar = char;
|
||||||
|
# ifndef _S
|
||||||
|
# define _S(val) val
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
static inline int CompareCaseInsensitive(const char* a, const char* b)
|
static inline int CompareCaseInsensitive(const char* a, const char* b)
|
||||||
{
|
{
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
|
@ -30,6 +46,15 @@ static inline int CompareCaseInsensitive(const char* a, const char* b)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int CompareCaseInsensitive(const SystemChar* a, const SystemChar* b)
|
||||||
|
{
|
||||||
|
#if _WIN32
|
||||||
|
return _wcsicmp(a, b);
|
||||||
|
#else
|
||||||
|
return strcasecmp(a, b);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static inline T clamp(T a, T val, T b) {return std::max<T>(a, std::min<T>(b, val));}
|
static inline T clamp(T a, T val, T b) {return std::max<T>(a, std::min<T>(b, val));}
|
||||||
|
|
||||||
|
@ -70,6 +95,54 @@ inline float ClampFull<float>(float in)
|
||||||
#define M_PIF 3.14159265358979323846f /* pi */
|
#define M_PIF 3.14159265358979323846f /* pi */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if __GNUC__
|
||||||
|
__attribute__((__format__ (__printf__, 1, 2)))
|
||||||
|
#endif
|
||||||
|
static inline void Printf(const SystemChar* fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
#if _WIN32
|
||||||
|
vwprintf(fmt, args);
|
||||||
|
#else
|
||||||
|
vprintf(fmt, args);
|
||||||
|
#endif
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if __GNUC__
|
||||||
|
__attribute__((__format__ (__printf__, 3, 4)))
|
||||||
|
#endif
|
||||||
|
static inline void SNPrintf(SystemChar* str, size_t maxlen, const SystemChar* format, ...)
|
||||||
|
{
|
||||||
|
va_list va;
|
||||||
|
va_start(va, format);
|
||||||
|
#if _WIN32
|
||||||
|
_vsnwprintf(str, maxlen, format, va);
|
||||||
|
#else
|
||||||
|
vsnprintf(str, maxlen, format, va);
|
||||||
|
#endif
|
||||||
|
va_end(va);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline const SystemChar* StrRChr(const SystemChar* str, SystemChar ch)
|
||||||
|
{
|
||||||
|
#if _WIN32
|
||||||
|
return wcsrchr(str, ch);
|
||||||
|
#else
|
||||||
|
return strrchr(str, ch);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline SystemChar* StrRChr(SystemChar* str, SystemChar ch)
|
||||||
|
{
|
||||||
|
#if _WIN32
|
||||||
|
return wcsrchr(str, ch);
|
||||||
|
#else
|
||||||
|
return strrchr(str, ch);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static inline int FSeek(FILE* fp, int64_t offset, int whence)
|
static inline int FSeek(FILE* fp, int64_t offset, int whence)
|
||||||
{
|
{
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
|
@ -92,6 +165,20 @@ static inline int64_t FTell(FILE* fp)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline FILE* FOpen(const SystemChar* path, const SystemChar* mode)
|
||||||
|
{
|
||||||
|
#if _WIN32
|
||||||
|
FILE* fp = _wfopen(path, mode);
|
||||||
|
if (!fp)
|
||||||
|
return nullptr;
|
||||||
|
#else
|
||||||
|
FILE* fp = fopen(path, mode);
|
||||||
|
if (!fp)
|
||||||
|
return nullptr;
|
||||||
|
#endif
|
||||||
|
return fp;
|
||||||
|
}
|
||||||
|
|
||||||
#undef bswap16
|
#undef bswap16
|
||||||
#undef bswap32
|
#undef bswap32
|
||||||
#undef bswap64
|
#undef bswap64
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define __AMUSE_CONTAINERREGISTRY_HPP__
|
#define __AMUSE_CONTAINERREGISTRY_HPP__
|
||||||
|
|
||||||
#include "AudioGroupData.hpp"
|
#include "AudioGroupData.hpp"
|
||||||
|
#include "Common.hpp"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
@ -34,11 +35,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 char* TypeToName(Type tp);
|
static const SystemChar* TypeToName(Type tp);
|
||||||
static Type DetectContainerType(const char* path);
|
static Type DetectContainerType(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);
|
static std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> LoadContainer(const SystemChar* path, Type& typeOut);
|
||||||
static std::vector<std::pair<std::string, SongData>> LoadSongs(const char* path);
|
static std::vector<std::pair<SystemString, SongData>> LoadSongs(const SystemChar* path);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,10 @@
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
|
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <windows.h>
|
||||||
|
#include <Stringapiset.h>
|
||||||
|
|
||||||
static void *memmem(const void *haystack, size_t hlen, const void *needle, size_t nlen)
|
static void *memmem(const void *haystack, size_t hlen, const void *needle, size_t nlen)
|
||||||
{
|
{
|
||||||
int needle_first;
|
int needle_first;
|
||||||
|
@ -30,12 +34,28 @@ static void *memmem(const void *haystack, size_t hlen, const void *needle, size_
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
amuse::SystemString StrToSys(const std::string& str)
|
||||||
|
{
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace amuse
|
namespace amuse
|
||||||
{
|
{
|
||||||
|
|
||||||
const char* ContainerRegistry::TypeToName(Type tp)
|
const SystemChar* ContainerRegistry::TypeToName(Type tp)
|
||||||
{
|
{
|
||||||
switch (tp)
|
switch (tp)
|
||||||
{
|
{
|
||||||
|
@ -43,23 +63,23 @@ const char* ContainerRegistry::TypeToName(Type tp)
|
||||||
default:
|
default:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
case Type::Raw4:
|
case Type::Raw4:
|
||||||
return "4 RAW Chunks";
|
return _S("4 RAW Chunks");
|
||||||
case Type::MetroidPrime:
|
case Type::MetroidPrime:
|
||||||
return "Metroid Prime (GCN)";
|
return _S("Metroid Prime (GCN)");
|
||||||
case Type::MetroidPrime2:
|
case Type::MetroidPrime2:
|
||||||
return "Metroid Prime 2 (GCN)";
|
return _S("Metroid Prime 2 (GCN)");
|
||||||
case Type::RogueSquadronPC:
|
case Type::RogueSquadronPC:
|
||||||
return "Star Wars - Rogue Squadron (PC)";
|
return _S("Star Wars - Rogue Squadron (PC)");
|
||||||
case Type::RogueSquadronN64:
|
case Type::RogueSquadronN64:
|
||||||
return "Star Wars - Rogue Squadron (N64)";
|
return _S("Star Wars - Rogue Squadron (N64)");
|
||||||
case Type::BattleForNabooPC:
|
case Type::BattleForNabooPC:
|
||||||
return "Star Wars Episode I - Battle for Naboo (PC)";
|
return _S("Star Wars Episode I - Battle for Naboo (PC)");
|
||||||
case Type::BattleForNabooN64:
|
case Type::BattleForNabooN64:
|
||||||
return "Star Wars Episode I - Battle for Naboo (N64)";
|
return _S("Star Wars Episode I - Battle for Naboo (N64)");
|
||||||
case Type::RogueSquadron2:
|
case Type::RogueSquadron2:
|
||||||
return "Star Wars - Rogue Squadron 2 (GCN)";
|
return _S("Star Wars - Rogue Squadron 2 (GCN)");
|
||||||
case Type::RogueSquadron3:
|
case Type::RogueSquadron3:
|
||||||
return "Star Wars - Rogue Squadron 3 (GCN)";
|
return _S("Star Wars - Rogue Squadron 3 (GCN)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,28 +91,28 @@ static size_t FileLength(FILE* fp)
|
||||||
return size_t(endPos);
|
return size_t(endPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string ReadString(FILE* fp)
|
static SystemString ReadString(FILE* fp)
|
||||||
{
|
{
|
||||||
char byte;
|
char byte;
|
||||||
std::string ret;
|
SystemString 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 char* path, const char*& dotOut)
|
static bool IsChunkExtension(const SystemChar* path, const SystemChar*& dotOut)
|
||||||
{
|
{
|
||||||
const char* ext = strrchr(path, '.');
|
const SystemChar* ext = StrRChr(path, _S('.'));
|
||||||
if (ext)
|
if (ext)
|
||||||
{
|
{
|
||||||
if (!CompareCaseInsensitive(ext, ".poo") ||
|
if (!CompareCaseInsensitive(ext, _S(".poo")) ||
|
||||||
!CompareCaseInsensitive(ext, ".pool") ||
|
!CompareCaseInsensitive(ext, _S(".pool")) ||
|
||||||
!CompareCaseInsensitive(ext, ".pro") ||
|
!CompareCaseInsensitive(ext, _S(".pro")) ||
|
||||||
!CompareCaseInsensitive(ext, ".proj") ||
|
!CompareCaseInsensitive(ext, _S(".proj")) ||
|
||||||
!CompareCaseInsensitive(ext, ".sdi") ||
|
!CompareCaseInsensitive(ext, _S(".sdi")) ||
|
||||||
!CompareCaseInsensitive(ext, ".sdir") ||
|
!CompareCaseInsensitive(ext, _S(".sdir")) ||
|
||||||
!CompareCaseInsensitive(ext, ".sam") ||
|
!CompareCaseInsensitive(ext, _S(".sam")) ||
|
||||||
!CompareCaseInsensitive(ext, ".samp"))
|
!CompareCaseInsensitive(ext, _S(".samp")))
|
||||||
{
|
{
|
||||||
dotOut = ext;
|
dotOut = ext;
|
||||||
return true;
|
return true;
|
||||||
|
@ -101,14 +121,14 @@ static bool IsChunkExtension(const char* path, const char*& dotOut)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool IsSongExtension(const char* path, const char*& dotOut)
|
static bool IsSongExtension(const SystemChar* path, const SystemChar*& dotOut)
|
||||||
{
|
{
|
||||||
const char* ext = strrchr(path, '.');
|
const SystemChar* ext = StrRChr(path, _S('.'));
|
||||||
if (ext)
|
if (ext)
|
||||||
{
|
{
|
||||||
if (!CompareCaseInsensitive(ext, ".son") ||
|
if (!CompareCaseInsensitive(ext, _S(".son")) ||
|
||||||
!CompareCaseInsensitive(ext, ".sng") ||
|
!CompareCaseInsensitive(ext, _S(".sng")) ||
|
||||||
!CompareCaseInsensitive(ext, ".song"))
|
!CompareCaseInsensitive(ext, _S(".song")))
|
||||||
{
|
{
|
||||||
dotOut = ext;
|
dotOut = ext;
|
||||||
return true;
|
return true;
|
||||||
|
@ -176,9 +196,9 @@ static bool ValidateMP1(FILE* fp)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadMP1(FILE* fp)
|
static std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> LoadMP1(FILE* fp)
|
||||||
{
|
{
|
||||||
std::vector<std::pair<std::string, IntrusiveAudioGroupData>> ret;
|
std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> ret;
|
||||||
FileLength(fp);
|
FileLength(fp);
|
||||||
|
|
||||||
uint32_t magic;
|
uint32_t magic;
|
||||||
|
@ -227,7 +247,7 @@ static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadMP1(FILE
|
||||||
{
|
{
|
||||||
FSeek(fp, offset, SEEK_SET);
|
FSeek(fp, offset, SEEK_SET);
|
||||||
ReadString(fp);
|
ReadString(fp);
|
||||||
std::string name = ReadString(fp);
|
SystemString name = ReadString(fp);
|
||||||
|
|
||||||
uint32_t poolLen;
|
uint32_t poolLen;
|
||||||
fread(&poolLen, 1, 4, fp);
|
fread(&poolLen, 1, 4, fp);
|
||||||
|
@ -314,9 +334,9 @@ static bool ValidateMP1Songs(FILE* fp)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::vector<std::pair<std::string, ContainerRegistry::SongData>> LoadMP1Songs(FILE* fp)
|
static std::vector<std::pair<SystemString, ContainerRegistry::SongData>> LoadMP1Songs(FILE* fp)
|
||||||
{
|
{
|
||||||
std::vector<std::pair<std::string, ContainerRegistry::SongData>> ret;
|
std::vector<std::pair<SystemString, ContainerRegistry::SongData>> ret;
|
||||||
FileLength(fp);
|
FileLength(fp);
|
||||||
|
|
||||||
uint32_t magic;
|
uint32_t magic;
|
||||||
|
@ -331,7 +351,7 @@ static std::vector<std::pair<std::string, ContainerRegistry::SongData>> LoadMP1S
|
||||||
fread(&nameCount, 1, 4, fp);
|
fread(&nameCount, 1, 4, fp);
|
||||||
nameCount = SBig(nameCount);
|
nameCount = SBig(nameCount);
|
||||||
|
|
||||||
std::unordered_map<uint32_t, std::string> names;
|
std::unordered_map<uint32_t, SystemString> names;
|
||||||
names.reserve(nameCount);
|
names.reserve(nameCount);
|
||||||
for (uint32_t i=0 ; i<nameCount ; ++i)
|
for (uint32_t i=0 ; i<nameCount ; ++i)
|
||||||
{
|
{
|
||||||
|
@ -344,7 +364,7 @@ static std::vector<std::pair<std::string, ContainerRegistry::SongData>> LoadMP1S
|
||||||
nameLen = SBig(nameLen);
|
nameLen = SBig(nameLen);
|
||||||
std::string str(nameLen, '\0');
|
std::string str(nameLen, '\0');
|
||||||
fread(&str[0], 1, nameLen, fp);
|
fread(&str[0], 1, nameLen, fp);
|
||||||
names[id] = std::move(str);
|
names[id] = StrToSys(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t resCount;
|
uint32_t resCount;
|
||||||
|
@ -395,8 +415,8 @@ static std::vector<std::pair<std::string, ContainerRegistry::SongData>> LoadMP1S
|
||||||
ContainerRegistry::SongData(std::move(song), sonLength, groupId, midiSetup));
|
ContainerRegistry::SongData(std::move(song), sonLength, groupId, midiSetup));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char name[128];
|
SystemChar name[128];
|
||||||
snprintf(name, 128, "%08X", id);
|
SNPrintf(name, 128, _S("%08X"), id);
|
||||||
ret.emplace_back(name, ContainerRegistry::SongData(std::move(song), sonLength, groupId, midiSetup));
|
ret.emplace_back(name, ContainerRegistry::SongData(std::move(song), sonLength, groupId, midiSetup));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -468,9 +488,9 @@ static bool ValidateMP2(FILE* fp)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadMP2(FILE* fp)
|
static std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> LoadMP2(FILE* fp)
|
||||||
{
|
{
|
||||||
std::vector<std::pair<std::string, IntrusiveAudioGroupData>> ret;
|
std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> ret;
|
||||||
FileLength(fp);
|
FileLength(fp);
|
||||||
|
|
||||||
uint32_t magic;
|
uint32_t magic;
|
||||||
|
@ -518,7 +538,7 @@ static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadMP2(FILE
|
||||||
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);
|
||||||
std::string name = ReadString(fp);
|
SystemString name = ReadString(fp);
|
||||||
|
|
||||||
FSeek(fp, 2, SEEK_CUR);
|
FSeek(fp, 2, SEEK_CUR);
|
||||||
uint32_t poolSz;
|
uint32_t poolSz;
|
||||||
|
@ -536,7 +556,7 @@ static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadMP2(FILE
|
||||||
uint32_t sampSz;
|
uint32_t sampSz;
|
||||||
fread(&sampSz, 1, 4, fp);
|
fread(&sampSz, 1, 4, fp);
|
||||||
sampSz = SBig(sampSz);
|
sampSz = SBig(sampSz);
|
||||||
|
|
||||||
if (projSz && poolSz && sdirSz && sampSz)
|
if (projSz && poolSz && sdirSz && sampSz)
|
||||||
{
|
{
|
||||||
std::unique_ptr<uint8_t[]> pool(new uint8_t[poolSz]);
|
std::unique_ptr<uint8_t[]> pool(new uint8_t[poolSz]);
|
||||||
|
@ -638,9 +658,9 @@ static bool ValidateRS1PC(FILE* fp)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadRS1PC(FILE* fp)
|
static std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> LoadRS1PC(FILE* fp)
|
||||||
{
|
{
|
||||||
std::vector<std::pair<std::string, IntrusiveAudioGroupData>> ret;
|
std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> ret;
|
||||||
size_t endPos = FileLength(fp);
|
size_t endPos = FileLength(fp);
|
||||||
|
|
||||||
uint32_t fstOff;
|
uint32_t fstOff;
|
||||||
|
@ -695,10 +715,10 @@ static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadRS1PC(FI
|
||||||
fread(samp.get(), 1, entry.decompSz, fp);
|
fread(samp.get(), 1, entry.decompSz, fp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret.emplace_back("Group", IntrusiveAudioGroupData{proj.release(), projSz, pool.release(), poolSz,
|
ret.emplace_back(_S("Group"), IntrusiveAudioGroupData{proj.release(), projSz, pool.release(), poolSz,
|
||||||
sdir.release(), sdirSz, samp.release(), sampSz,
|
sdir.release(), sdirSz, samp.release(), sampSz,
|
||||||
false, PCDataTag{}});
|
false, PCDataTag{}});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -759,9 +779,9 @@ static bool ValidateRS1N64(FILE* fp)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadRS1N64(FILE* fp)
|
static std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> LoadRS1N64(FILE* fp)
|
||||||
{
|
{
|
||||||
std::vector<std::pair<std::string, IntrusiveAudioGroupData>> ret;
|
std::vector<std::pair<SystemString, 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]);
|
||||||
|
@ -862,9 +882,9 @@ static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadRS1N64(F
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret.emplace_back("Group", IntrusiveAudioGroupData{proj.release(), projSz, pool.release(), poolSz,
|
ret.emplace_back(_S("Group"), IntrusiveAudioGroupData{proj.release(), projSz, pool.release(), poolSz,
|
||||||
sdir.release(), sdirSz, samp.release(), sampSz,
|
sdir.release(), sdirSz, samp.release(), sampSz,
|
||||||
false, N64DataTag{}});
|
false, N64DataTag{}});
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -875,7 +895,7 @@ static bool ValidateBFNPC(FILE* fp)
|
||||||
size_t endPos = FileLength(fp);
|
size_t endPos = FileLength(fp);
|
||||||
if (endPos > 100 * 1024 * 1024)
|
if (endPos > 100 * 1024 * 1024)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
uint32_t fstOff;
|
uint32_t fstOff;
|
||||||
uint32_t fstSz;
|
uint32_t fstSz;
|
||||||
if (fread(&fstOff, 1, 4, fp) == 4 && fread(&fstSz, 1, 4, fp) == 4)
|
if (fread(&fstOff, 1, 4, fp) == 4 && fread(&fstSz, 1, 4, fp) == 4)
|
||||||
|
@ -909,9 +929,9 @@ static bool ValidateBFNPC(FILE* fp)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadBFNPC(FILE* fp)
|
static std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> LoadBFNPC(FILE* fp)
|
||||||
{
|
{
|
||||||
std::vector<std::pair<std::string, IntrusiveAudioGroupData>> ret;
|
std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> ret;
|
||||||
size_t endPos = FileLength(fp);
|
size_t endPos = FileLength(fp);
|
||||||
|
|
||||||
uint32_t fstOff;
|
uint32_t fstOff;
|
||||||
|
@ -967,9 +987,9 @@ static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadBFNPC(FI
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret.emplace_back("Group", IntrusiveAudioGroupData{proj.release(), projSz, pool.release(), poolSz,
|
ret.emplace_back(_S("Group"), IntrusiveAudioGroupData{proj.release(), projSz, pool.release(), poolSz,
|
||||||
sdir.release(), sdirSz, samp.release(), sampSz,
|
sdir.release(), sdirSz, samp.release(), sampSz,
|
||||||
true, PCDataTag{}});
|
true, PCDataTag{}});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1030,9 +1050,9 @@ static bool ValidateBFNN64(FILE* fp)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadBFNN64(FILE* fp)
|
static std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> LoadBFNN64(FILE* fp)
|
||||||
{
|
{
|
||||||
std::vector<std::pair<std::string, IntrusiveAudioGroupData>> ret;
|
std::vector<std::pair<SystemString, 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]);
|
||||||
|
@ -1133,9 +1153,9 @@ static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadBFNN64(F
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret.emplace_back("Group", IntrusiveAudioGroupData{proj.release(), projSz, pool.release(), poolSz,
|
ret.emplace_back(_S("Group"), IntrusiveAudioGroupData{proj.release(), projSz, pool.release(), poolSz,
|
||||||
sdir.release(), sdirSz, samp.release(), sampSz,
|
sdir.release(), sdirSz, samp.release(), sampSz,
|
||||||
true, N64DataTag{}});
|
true, N64DataTag{}});
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1215,7 +1235,7 @@ static bool ValidateRS2(FILE* fp)
|
||||||
size_t endPos = FileLength(fp);
|
size_t endPos = FileLength(fp);
|
||||||
if (endPos > 600 * 1024 * 1024)
|
if (endPos > 600 * 1024 * 1024)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
uint64_t fstOff;
|
uint64_t fstOff;
|
||||||
fread(&fstOff, 1, 8, fp);
|
fread(&fstOff, 1, 8, fp);
|
||||||
fstOff = SBig(fstOff);
|
fstOff = SBig(fstOff);
|
||||||
|
@ -1241,9 +1261,9 @@ static bool ValidateRS2(FILE* fp)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadRS2(FILE* fp)
|
static std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> LoadRS2(FILE* fp)
|
||||||
{
|
{
|
||||||
std::vector<std::pair<std::string, IntrusiveAudioGroupData>> ret;
|
std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> ret;
|
||||||
size_t endPos = FileLength(fp);
|
size_t endPos = FileLength(fp);
|
||||||
|
|
||||||
uint64_t fstOff;
|
uint64_t fstOff;
|
||||||
|
@ -1292,8 +1312,8 @@ static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadRS2(FILE
|
||||||
|
|
||||||
if (head.projLen && head.poolLen && head.sdirLen && head.sampLen)
|
if (head.projLen && head.poolLen && head.sdirLen && head.sampLen)
|
||||||
{
|
{
|
||||||
char name[128];
|
SystemChar name[128];
|
||||||
snprintf(name, 128, "GroupFile%02u", j);
|
SNPrintf(name, 128, _S("GroupFile%02u"), j);
|
||||||
ret.emplace_back(name, IntrusiveAudioGroupData{proj.release(), head.projLen, pool.release(), head.poolLen,
|
ret.emplace_back(name, IntrusiveAudioGroupData{proj.release(), head.projLen, pool.release(), head.poolLen,
|
||||||
sdir.release(), head.sdirLen, samp.release(), head.sampLen, GCNDataTag{}});
|
sdir.release(), head.sdirLen, samp.release(), head.sampLen, GCNDataTag{}});
|
||||||
}
|
}
|
||||||
|
@ -1306,9 +1326,9 @@ static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadRS2(FILE
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::vector<std::pair<std::string, ContainerRegistry::SongData>> LoadRS2Songs(FILE* fp)
|
static std::vector<std::pair<SystemString, ContainerRegistry::SongData>> LoadRS2Songs(FILE* fp)
|
||||||
{
|
{
|
||||||
std::vector<std::pair<std::string, ContainerRegistry::SongData>> ret;
|
std::vector<std::pair<SystemString, ContainerRegistry::SongData>> ret;
|
||||||
size_t endPos = FileLength(fp);
|
size_t endPos = FileLength(fp);
|
||||||
|
|
||||||
uint64_t fstOff;
|
uint64_t fstOff;
|
||||||
|
@ -1347,13 +1367,13 @@ static std::vector<std::pair<std::string, ContainerRegistry::SongData>> LoadRS2S
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const RS23SONHead* sonData = reinterpret_cast<const RS23SONHead*>(audData.get() + head.sonIdxBeginOff);
|
const RS23SONHead* sonData = reinterpret_cast<const RS23SONHead*>(audData.get() + head.sonIdxBeginOff);
|
||||||
for (int s=0 ; s<head.sonCount ; ++s)
|
for (uint32_t s=0 ; s<head.sonCount ; ++s)
|
||||||
{
|
{
|
||||||
RS23SONHead sonHead = sonData[s];
|
RS23SONHead sonHead = sonData[s];
|
||||||
sonHead.swapBig();
|
sonHead.swapBig();
|
||||||
|
|
||||||
char name[128];
|
SystemChar name[128];
|
||||||
snprintf(name, 128, "GroupFile%02u-%u", j, s);
|
SNPrintf(name, 128, _S("GroupFile%02u-%u"), 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(name, ContainerRegistry::SongData(std::move(song), sonHead.length,
|
ret.emplace_back(name, ContainerRegistry::SongData(std::move(song), sonHead.length,
|
||||||
|
@ -1390,7 +1410,7 @@ static bool ValidateRS3(FILE* fp)
|
||||||
size_t endPos = FileLength(fp);
|
size_t endPos = FileLength(fp);
|
||||||
if (endPos > 600 * 1024 * 1024)
|
if (endPos > 600 * 1024 * 1024)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
uint64_t fstOff;
|
uint64_t fstOff;
|
||||||
fread(&fstOff, 1, 8, fp);
|
fread(&fstOff, 1, 8, fp);
|
||||||
fstOff = SBig(fstOff);
|
fstOff = SBig(fstOff);
|
||||||
|
@ -1414,9 +1434,9 @@ static bool ValidateRS3(FILE* fp)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadRS3(FILE* fp)
|
static std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> LoadRS3(FILE* fp)
|
||||||
{
|
{
|
||||||
std::vector<std::pair<std::string, IntrusiveAudioGroupData>> ret;
|
std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> ret;
|
||||||
size_t endPos = FileLength(fp);
|
size_t endPos = FileLength(fp);
|
||||||
|
|
||||||
uint64_t fstOff;
|
uint64_t fstOff;
|
||||||
|
@ -1465,8 +1485,8 @@ static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadRS3(FILE
|
||||||
|
|
||||||
if (head.projLen && head.poolLen && head.sdirLen && head.sampLen)
|
if (head.projLen && head.poolLen && head.sdirLen && head.sampLen)
|
||||||
{
|
{
|
||||||
char name[128];
|
SystemChar name[128];
|
||||||
snprintf(name, 128, "GroupFile%02u", j);
|
SNPrintf(name, 128, _S("GroupFile%02u"), j);
|
||||||
ret.emplace_back(name, IntrusiveAudioGroupData{proj.release(), head.projLen, pool.release(), head.poolLen,
|
ret.emplace_back(name, IntrusiveAudioGroupData{proj.release(), head.projLen, pool.release(), head.poolLen,
|
||||||
sdir.release(), head.sdirLen, samp.release(), head.sampLen, GCNDataTag{}});
|
sdir.release(), head.sdirLen, samp.release(), head.sampLen, GCNDataTag{}});
|
||||||
}
|
}
|
||||||
|
@ -1479,59 +1499,59 @@ static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadRS3(FILE
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ContainerRegistry::Type ContainerRegistry::DetectContainerType(const char* path)
|
ContainerRegistry::Type ContainerRegistry::DetectContainerType(const SystemChar* 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 char* dot = nullptr;
|
const SystemChar* dot = nullptr;
|
||||||
if (IsChunkExtension(path, dot))
|
if (IsChunkExtension(path, dot))
|
||||||
{
|
{
|
||||||
char newpath[1024];
|
SystemChar newpath[1024];
|
||||||
|
|
||||||
/* Project */
|
/* Project */
|
||||||
snprintf(newpath, 1024, "%.*s.pro", int(dot - path), path);
|
SNPrintf(newpath, 1024, _S("%.*s.pro"), int(dot - path), path);
|
||||||
fp = fopen(newpath, "rb");
|
fp = FOpen(newpath, _S("rb"));
|
||||||
if (!fp)
|
if (!fp)
|
||||||
{
|
{
|
||||||
snprintf(newpath, 1024, "%.*s.proj", int(dot - path), path);
|
SNPrintf(newpath, 1024, _S("%.*s.proj"), int(dot - path), path);
|
||||||
fp = fopen(newpath, "rb");
|
fp = FOpen(newpath, _S("rb"));
|
||||||
if (!fp)
|
if (!fp)
|
||||||
return Type::Invalid;
|
return Type::Invalid;
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
/* Pool */
|
/* Pool */
|
||||||
snprintf(newpath, 1024, "%.*s.poo", int(dot - path), path);
|
SNPrintf(newpath, 1024, _S("%.*s.poo"), int(dot - path), path);
|
||||||
fp = fopen(newpath, "rb");
|
fp = FOpen(newpath, _S("rb"));
|
||||||
if (!fp)
|
if (!fp)
|
||||||
{
|
{
|
||||||
snprintf(newpath, 1024, "%.*s.pool", int(dot - path), path);
|
SNPrintf(newpath, 1024, _S("%.*s.pool"), int(dot - path), path);
|
||||||
fp = fopen(newpath, "rb");
|
fp = FOpen(newpath, _S("rb"));
|
||||||
if (!fp)
|
if (!fp)
|
||||||
return Type::Invalid;
|
return Type::Invalid;
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
/* Sample Directory */
|
/* Sample Directory */
|
||||||
snprintf(newpath, 1024, "%.*s.sdi", int(dot - path), path);
|
SNPrintf(newpath, 1024, _S("%.*s.sdi"), int(dot - path), path);
|
||||||
fp = fopen(newpath, "rb");
|
fp = FOpen(newpath, _S("rb"));
|
||||||
if (!fp)
|
if (!fp)
|
||||||
{
|
{
|
||||||
snprintf(newpath, 1024, "%.*s.sdir", int(dot - path), path);
|
SNPrintf(newpath, 1024, _S("%.*s.sdir"), int(dot - path), path);
|
||||||
fp = fopen(newpath, "rb");
|
fp = FOpen(newpath, _S("rb"));
|
||||||
if (!fp)
|
if (!fp)
|
||||||
return Type::Invalid;
|
return Type::Invalid;
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
/* Sample */
|
/* Sample */
|
||||||
snprintf(newpath, 1024, "%.*s.sam", int(dot - path), path);
|
SNPrintf(newpath, 1024, _S("%.*s.sam"), int(dot - path), path);
|
||||||
fp = fopen(newpath, "rb");
|
fp = FOpen(newpath, _S("rb"));
|
||||||
if (!fp)
|
if (!fp)
|
||||||
{
|
{
|
||||||
snprintf(newpath, 1024, "%.*s.samp", int(dot - path), path);
|
SNPrintf(newpath, 1024, _S("%.*s.samp"), int(dot - path), path);
|
||||||
fp = fopen(newpath, "rb");
|
fp = FOpen(newpath, _S("rb"));
|
||||||
if (!fp)
|
if (!fp)
|
||||||
return Type::Invalid;
|
return Type::Invalid;
|
||||||
}
|
}
|
||||||
|
@ -1541,7 +1561,7 @@ ContainerRegistry::Type ContainerRegistry::DetectContainerType(const char* path)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now attempt single-file case */
|
/* Now attempt single-file case */
|
||||||
fp = fopen(path, "rb");
|
fp = FOpen(path, _S("rb"));
|
||||||
if (fp)
|
if (fp)
|
||||||
{
|
{
|
||||||
if (ValidateMP1(fp))
|
if (ValidateMP1(fp))
|
||||||
|
@ -1597,100 +1617,100 @@ ContainerRegistry::Type ContainerRegistry::DetectContainerType(const char* path)
|
||||||
|
|
||||||
return Type::Invalid;
|
return Type::Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::pair<std::string, IntrusiveAudioGroupData>>
|
std::vector<std::pair<SystemString, IntrusiveAudioGroupData>>
|
||||||
ContainerRegistry::LoadContainer(const char* path)
|
ContainerRegistry::LoadContainer(const SystemChar* path)
|
||||||
{
|
{
|
||||||
Type typeOut;
|
Type typeOut;
|
||||||
return LoadContainer(path, typeOut);
|
return LoadContainer(path, typeOut);
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<std::pair<std::string, IntrusiveAudioGroupData>>
|
std::vector<std::pair<SystemString, IntrusiveAudioGroupData>>
|
||||||
ContainerRegistry::LoadContainer(const char* path, Type& typeOut)
|
ContainerRegistry::LoadContainer(const SystemChar* path, 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 char* dot = nullptr;
|
const SystemChar* dot = nullptr;
|
||||||
if (IsChunkExtension(path, dot))
|
if (IsChunkExtension(path, dot))
|
||||||
{
|
{
|
||||||
std::vector<std::pair<std::string, IntrusiveAudioGroupData>> ret;
|
std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> ret;
|
||||||
|
|
||||||
/* Project */
|
/* Project */
|
||||||
char projPath[1024];
|
SystemChar projPath[1024];
|
||||||
snprintf(projPath, 1024, "%.*s.pro", int(dot - path), path);
|
SNPrintf(projPath, 1024, _S("%.*s.pro"), int(dot - path), path);
|
||||||
fp = fopen(projPath, "rb");
|
fp = FOpen(projPath, _S("rb"));
|
||||||
if (!fp)
|
if (!fp)
|
||||||
{
|
{
|
||||||
snprintf(projPath, 1024, "%.*s.proj", int(dot - path), path);
|
SNPrintf(projPath, 1024, _S("%.*s.proj"), int(dot - path), path);
|
||||||
fp = fopen(projPath, "rb");
|
fp = FOpen(projPath, _S("rb"));
|
||||||
if (!fp)
|
if (!fp)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
/* Pool */
|
/* Pool */
|
||||||
char poolPath[1024];
|
SystemChar poolPath[1024];
|
||||||
snprintf(poolPath, 1024, "%.*s.poo", int(dot - path), path);
|
SNPrintf(poolPath, 1024, _S("%.*s.poo"), int(dot - path), path);
|
||||||
fp = fopen(poolPath, "rb");
|
fp = FOpen(poolPath, _S("rb"));
|
||||||
if (!fp)
|
if (!fp)
|
||||||
{
|
{
|
||||||
snprintf(poolPath, 1024, "%.*s.pool", int(dot - path), path);
|
SNPrintf(poolPath, 1024, _S("%.*s.pool"), int(dot - path), path);
|
||||||
fp = fopen(poolPath, "rb");
|
fp = FOpen(poolPath, _S("rb"));
|
||||||
if (!fp)
|
if (!fp)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
/* Sample Directory */
|
/* Sample Directory */
|
||||||
char sdirPath[1024];
|
SystemChar sdirPath[1024];
|
||||||
snprintf(sdirPath, 1024, "%.*s.sdi", int(dot - path), path);
|
SNPrintf(sdirPath, 1024, _S("%.*s.sdi"), int(dot - path), path);
|
||||||
fp = fopen(sdirPath, "rb");
|
fp = FOpen(sdirPath, _S("rb"));
|
||||||
if (!fp)
|
if (!fp)
|
||||||
{
|
{
|
||||||
snprintf(sdirPath, 1024, "%.*s.sdir", int(dot - path), path);
|
SNPrintf(sdirPath, 1024, _S("%.*s.sdir"), int(dot - path), path);
|
||||||
fp = fopen(sdirPath, "rb");
|
fp = FOpen(sdirPath, _S("rb"));
|
||||||
if (!fp)
|
if (!fp)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
/* Sample */
|
/* Sample */
|
||||||
char sampPath[1024];
|
SystemChar sampPath[1024];
|
||||||
snprintf(sampPath, 1024, "%.*s.sam", int(dot - path), path);
|
SNPrintf(sampPath, 1024, _S("%.*s.sam"), int(dot - path), path);
|
||||||
fp = fopen(sampPath, "rb");
|
fp = FOpen(sampPath, _S("rb"));
|
||||||
if (!fp)
|
if (!fp)
|
||||||
{
|
{
|
||||||
snprintf(sampPath, 1024, "%.*s.samp", int(dot - path), path);
|
SNPrintf(sampPath, 1024, _S("%.*s.samp"), int(dot - path), path);
|
||||||
fp = fopen(sampPath, "rb");
|
fp = FOpen(sampPath, _S("rb"));
|
||||||
if (!fp)
|
if (!fp)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
fp = fopen(projPath, "rb");
|
fp = FOpen(projPath, _S("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, "rb");
|
fp = FOpen(poolPath, _S("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, "rb");
|
fp = FOpen(sdirPath, _S("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, "rb");
|
fp = FOpen(sampPath, _S("rb"));
|
||||||
size_t sampLen = FileLength(fp);
|
size_t sampLen = FileLength(fp);
|
||||||
if (!sampLen)
|
if (!sampLen)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1701,24 +1721,24 @@ ContainerRegistry::LoadContainer(const char* path, Type& typeOut)
|
||||||
|
|
||||||
/* SDIR-based format detection */
|
/* SDIR-based format detection */
|
||||||
if (*reinterpret_cast<uint32_t*>(sdir.get() + 8) == 0x0)
|
if (*reinterpret_cast<uint32_t*>(sdir.get() + 8) == 0x0)
|
||||||
ret.emplace_back("Group", IntrusiveAudioGroupData{proj.release(), projLen, pool.release(), poolLen,
|
ret.emplace_back(_S("Group"), IntrusiveAudioGroupData{proj.release(), projLen, pool.release(), poolLen,
|
||||||
sdir.release(), sdirLen, samp.release(), sampLen,
|
sdir.release(), sdirLen, samp.release(), sampLen,
|
||||||
GCNDataTag{}});
|
GCNDataTag{}});
|
||||||
else if (sdir[9] == 0x0)
|
else if (sdir[9] == 0x0)
|
||||||
ret.emplace_back("Group", IntrusiveAudioGroupData{proj.release(), projLen, pool.release(), poolLen,
|
ret.emplace_back(_S("Group"), IntrusiveAudioGroupData{proj.release(), projLen, pool.release(), poolLen,
|
||||||
sdir.release(), sdirLen, samp.release(), sampLen,
|
sdir.release(), sdirLen, samp.release(), sampLen,
|
||||||
false, N64DataTag{}});
|
false, N64DataTag{}});
|
||||||
else
|
else
|
||||||
ret.emplace_back("Group", IntrusiveAudioGroupData{proj.release(), projLen, pool.release(), poolLen,
|
ret.emplace_back(_S("Group"), IntrusiveAudioGroupData{proj.release(), projLen, pool.release(), poolLen,
|
||||||
sdir.release(), sdirLen, samp.release(), sampLen,
|
sdir.release(), sdirLen, samp.release(), sampLen,
|
||||||
false, PCDataTag{}});
|
false, PCDataTag{}});
|
||||||
|
|
||||||
typeOut = Type::Raw4;
|
typeOut = Type::Raw4;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now attempt single-file case */
|
/* Now attempt single-file case */
|
||||||
fp = fopen(path, "rb");
|
fp = FOpen(path, _S("rb"));
|
||||||
if (fp)
|
if (fp)
|
||||||
{
|
{
|
||||||
if (ValidateMP1(fp))
|
if (ValidateMP1(fp))
|
||||||
|
@ -1791,16 +1811,16 @@ ContainerRegistry::LoadContainer(const char* path, Type& typeOut)
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::pair<std::string, ContainerRegistry::SongData>>
|
std::vector<std::pair<SystemString, ContainerRegistry::SongData>>
|
||||||
ContainerRegistry::LoadSongs(const char* path)
|
ContainerRegistry::LoadSongs(const SystemChar* path)
|
||||||
{
|
{
|
||||||
FILE* fp;
|
FILE* fp;
|
||||||
|
|
||||||
/* See if provided file is a raw song */
|
/* See if provided file is a raw song */
|
||||||
const char* dot = nullptr;
|
const SystemChar* dot = nullptr;
|
||||||
if (IsSongExtension(path, dot))
|
if (IsSongExtension(path, dot))
|
||||||
{
|
{
|
||||||
fp = fopen(path, "rb");
|
fp = FOpen(path, _S("rb"));
|
||||||
size_t fLen = FileLength(fp);
|
size_t fLen = FileLength(fp);
|
||||||
if (!fLen)
|
if (!fLen)
|
||||||
{
|
{
|
||||||
|
@ -1811,13 +1831,13 @@ ContainerRegistry::LoadSongs(const char* path)
|
||||||
fread(song.get(), 1, fLen, fp);
|
fread(song.get(), 1, fLen, fp);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
std::vector<std::pair<std::string, SongData>> ret;
|
std::vector<std::pair<SystemString, SongData>> ret;
|
||||||
ret.emplace_back("Song", SongData(std::move(song), fLen, -1, -1));
|
ret.emplace_back(_S("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, "rb");
|
fp = FOpen(path, _S("rb"));
|
||||||
if (fp)
|
if (fp)
|
||||||
{
|
{
|
||||||
if (ValidateMP1Songs(fp))
|
if (ValidateMP1Songs(fp))
|
||||||
|
|
Loading…
Reference in New Issue