mirror of https://github.com/AxioDL/amuse.git
Support for absolute PROJ offsets introduced in Battle for Naboo
This commit is contained in:
parent
3056426afc
commit
494a39e76a
|
@ -0,0 +1,97 @@
|
||||||
|
if (APPLE AND (NOT CMAKE_OSX_DEPLOYMENT_TARGET OR CMAKE_OSX_DEPLOYMENT_TARGET VERSION_GREATER 10.10))
|
||||||
|
set(APPLE_DEV_ID "" CACHE STRING "Mac Developer ID string 'Mac Developer: John Smith (XXXXXXXXXX)'")
|
||||||
|
set(APPLE_TEAM_ID "" CACHE STRING "Team ID string provisioned within Xcode / Apple's portal")
|
||||||
|
find_library(AVFOUNDATION_LIBRARY AVFoundation)
|
||||||
|
find_library(AUDIOUNIT_LIBRARY AudioUnit)
|
||||||
|
find_library(COREAUDIOKIT_LIBRARY CoreAudioKit)
|
||||||
|
if (NOT (AUDIOUNIT_LIBRARY STREQUAL AUDIOUNIT_LIBRARY-NOTFOUND))
|
||||||
|
set(CMAKE_INSTALL_PREFIX "${CMAKE_CURRENT_BINARY_DIR}")
|
||||||
|
|
||||||
|
# Search for provision profile to make AudioUnit extension on OS X
|
||||||
|
unset(PROV_PROFILE)
|
||||||
|
file(GLOB PROV_FILES "$ENV{HOME}/Library/MobileDevice/Provisioning Profiles/*.provisionprofile")
|
||||||
|
foreach(FILE ${PROV_FILES})
|
||||||
|
file(STRINGS "${FILE}" NAME REGEX ${APPLE_TEAM_ID})
|
||||||
|
if(NAME)
|
||||||
|
set(PROV_PROFILE "${FILE}")
|
||||||
|
break()
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
if(EXISTS "${PROV_PROFILE}")
|
||||||
|
|
||||||
|
# Extension App
|
||||||
|
add_executable(amuse-au MACOSX_BUNDLE AudioUnitBackend.hpp AudioUnitBackend.mm
|
||||||
|
AudioUnitViewController.hpp AudioUnitViewController.mm
|
||||||
|
AudioGroupFilePresenter.hpp AudioGroupFilePresenter.mm)
|
||||||
|
|
||||||
|
set(APPLE_BUNDLE_ID "io.github.axiodl.Amuse.AudioUnit")
|
||||||
|
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/AmuseExtension.entitlements.in
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/AmuseExtension.entitlements)
|
||||||
|
|
||||||
|
target_link_libraries(amuse-au amuse boo soxr ${AUDIOUNIT_LIBRARY} ${COREAUDIOKIT_LIBRARY}
|
||||||
|
${AVFOUNDATION_LIBRARY} ${BOO_SYS_LIBS} logvisor athena-core)
|
||||||
|
set_target_properties(amuse-au PROPERTIES
|
||||||
|
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/ExtensionInfo.plist"
|
||||||
|
BUNDLE_EXTENSION "appex" BUNDLE TRUE
|
||||||
|
XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${CMAKE_CURRENT_BINARY_DIR}/AmuseExtension.entitlements"
|
||||||
|
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "${APPLE_DEV_ID}"
|
||||||
|
LINK_FLAGS "-e _NSExtensionMain -fobjc-arc -fobjc-link-runtime -fapplication-extension")
|
||||||
|
|
||||||
|
|
||||||
|
# Containing App
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/AmuseContainerMainMenu.nib
|
||||||
|
COMMAND ibtool --errors --warnings --notices --module amuse_au_container --auto-activate-custom-fonts
|
||||||
|
--target-device mac --minimum-deployment-target 10.11 --output-format human-readable-text --compile
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/AmuseContainerMainMenu.nib
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/AmuseContainerMainMenu.xib
|
||||||
|
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/AmuseContainerMainMenu.xib
|
||||||
|
)
|
||||||
|
add_executable(amuse-au-container MACOSX_BUNDLE AmuseContainingApp.mm
|
||||||
|
AudioUnitBackend.hpp AudioUnitBackend.mm
|
||||||
|
AudioUnitViewController.hpp AudioUnitViewController.mm
|
||||||
|
AudioGroupFilePresenter.hpp AudioGroupFilePresenter.mm
|
||||||
|
AmuseContainerMainMenu.nib)
|
||||||
|
set_source_files_properties(AudioUnitBackend.mm AudioUnitViewController.mm
|
||||||
|
AmuseContainingApp.mm AudioGroupFilePresenter.mm
|
||||||
|
PROPERTIES COMPILE_FLAGS -fobjc-arc)
|
||||||
|
target_link_libraries(amuse-au-container amuse boo soxr ${AUDIOUNIT_LIBRARY} ${COREAUDIOKIT_LIBRARY}
|
||||||
|
${AVFOUNDATION_LIBRARY} ${BOO_SYS_LIBS} logvisor athena-core)
|
||||||
|
|
||||||
|
set(APPLE_BUNDLE_ID "io.github.axiodl.Amuse")
|
||||||
|
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/AmuseContainer.entitlements.in
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/AmuseContainer.entitlements)
|
||||||
|
|
||||||
|
set_target_properties(amuse-au-container PROPERTIES
|
||||||
|
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/ContainerInfo.plist"
|
||||||
|
XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${CMAKE_CURRENT_BINARY_DIR}/AmuseContainer.entitlements"
|
||||||
|
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "${APPLE_DEV_ID}")
|
||||||
|
|
||||||
|
add_custom_command(TARGET amuse-au POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy "${PROV_PROFILE}" "$<TARGET_FILE_DIR:amuse-au>/../embedded.provisionprofile"
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E remove_directory "$<TARGET_FILE_DIR:amuse-au-container>/../PlugIns/amuse-au.appex"
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy_directory "$<TARGET_FILE_DIR:amuse-au>/../.."
|
||||||
|
"$<TARGET_FILE_DIR:amuse-au-container>/../PlugIns/amuse-au.appex"
|
||||||
|
COMMAND codesign --force --sign
|
||||||
|
${APPLE_DEV_ID} --entitlements "${CMAKE_CURRENT_BINARY_DIR}/AmuseExtension.entitlements"
|
||||||
|
"$<TARGET_FILE_DIR:amuse-au-container>/../PlugIns/amuse-au.appex"
|
||||||
|
COMMAND codesign --force --sign ${APPLE_DEV_ID}
|
||||||
|
"$<TARGET_FILE_DIR:amuse-au-container>/../.."
|
||||||
|
VERBATIM
|
||||||
|
)
|
||||||
|
|
||||||
|
add_custom_command(TARGET amuse-au-container POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/AmuseContainerMainMenu.nib"
|
||||||
|
"$<TARGET_FILE_DIR:amuse-au-container>/../Resources/AmuseContainerMainMenu.nib"
|
||||||
|
COMMAND codesign --force --sign
|
||||||
|
${APPLE_DEV_ID} "$<TARGET_FILE_DIR:amuse-au-container>/../.."
|
||||||
|
VERBATIM
|
||||||
|
)
|
||||||
|
|
||||||
|
else()
|
||||||
|
message(WARNING "Unable to find developer provision profile; skipping Amuse-AU")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endif()
|
102
CMakeLists.txt
102
CMakeLists.txt
|
@ -75,105 +75,13 @@ add_library(amuse
|
||||||
${EXTRAS})
|
${EXTRAS})
|
||||||
|
|
||||||
if(TARGET boo)
|
if(TARGET boo)
|
||||||
# AudioUnit Target
|
# AudioUnit Target (OS X only)
|
||||||
if (APPLE AND (NOT CMAKE_OSX_DEPLOYMENT_TARGET OR CMAKE_OSX_DEPLOYMENT_TARGET VERSION_GREATER 10.10))
|
add_subdirectory(AudioUnit)
|
||||||
set(APPLE_DEV_ID "" CACHE STRING "Mac Developer ID string 'Mac Developer: John Smith (XXXXXXXXXX)'")
|
|
||||||
set(APPLE_TEAM_ID "" CACHE STRING "Team ID string provisioned within Xcode / Apple's portal")
|
|
||||||
find_library(AVFOUNDATION_LIBRARY AVFoundation)
|
|
||||||
find_library(AUDIOUNIT_LIBRARY AudioUnit)
|
|
||||||
find_library(COREAUDIOKIT_LIBRARY CoreAudioKit)
|
|
||||||
if (NOT (AUDIOUNIT_LIBRARY STREQUAL AUDIOUNIT_LIBRARY-NOTFOUND))
|
|
||||||
set(CMAKE_INSTALL_PREFIX "${CMAKE_CURRENT_BINARY_DIR}")
|
|
||||||
|
|
||||||
# Search for provision profile to make AudioUnit extension on OS X
|
# VST Target
|
||||||
unset(PROV_PROFILE)
|
add_subdirectory(VST)
|
||||||
file(GLOB PROV_FILES "$ENV{HOME}/Library/MobileDevice/Provisioning Profiles/*.provisionprofile")
|
|
||||||
foreach(FILE ${PROV_FILES})
|
|
||||||
file(STRINGS "${FILE}" NAME REGEX ${APPLE_TEAM_ID})
|
|
||||||
if(NAME)
|
|
||||||
set(PROV_PROFILE "${FILE}")
|
|
||||||
break()
|
|
||||||
endif()
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
if(EXISTS "${PROV_PROFILE}")
|
|
||||||
|
|
||||||
# Extension App
|
|
||||||
add_executable(amuse-au MACOSX_BUNDLE AudioUnit/AudioUnitBackend.hpp AudioUnit/AudioUnitBackend.mm
|
|
||||||
AudioUnit/AudioUnitViewController.hpp AudioUnit/AudioUnitViewController.mm
|
|
||||||
AudioUnit/AudioGroupFilePresenter.hpp AudioUnit/AudioGroupFilePresenter.mm)
|
|
||||||
|
|
||||||
set(APPLE_BUNDLE_ID "io.github.axiodl.Amuse.AudioUnit")
|
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/AudioUnit/AmuseExtension.entitlements.in
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/AmuseExtension.entitlements)
|
|
||||||
|
|
||||||
target_link_libraries(amuse-au amuse boo soxr ${AUDIOUNIT_LIBRARY} ${COREAUDIOKIT_LIBRARY}
|
|
||||||
${AVFOUNDATION_LIBRARY} ${BOO_SYS_LIBS} logvisor athena-core)
|
|
||||||
set_target_properties(amuse-au PROPERTIES
|
|
||||||
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/AudioUnit/ExtensionInfo.plist"
|
|
||||||
BUNDLE_EXTENSION "appex" BUNDLE TRUE
|
|
||||||
XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${CMAKE_CURRENT_BINARY_DIR}/AmuseExtension.entitlements"
|
|
||||||
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "${APPLE_DEV_ID}"
|
|
||||||
LINK_FLAGS "-e _NSExtensionMain -fobjc-arc -fobjc-link-runtime -fapplication-extension")
|
|
||||||
|
|
||||||
|
|
||||||
# Containing App
|
|
||||||
add_custom_command(
|
|
||||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/AmuseContainerMainMenu.nib
|
|
||||||
COMMAND ibtool --errors --warnings --notices --module amuse_au_container --auto-activate-custom-fonts
|
|
||||||
--target-device mac --minimum-deployment-target 10.11 --output-format human-readable-text --compile
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/AmuseContainerMainMenu.nib
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/AudioUnit/AmuseContainerMainMenu.xib
|
|
||||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/AudioUnit/AmuseContainerMainMenu.xib
|
|
||||||
)
|
|
||||||
add_executable(amuse-au-container MACOSX_BUNDLE AudioUnit/AmuseContainingApp.mm
|
|
||||||
AudioUnit/AudioUnitBackend.hpp AudioUnit/AudioUnitBackend.mm
|
|
||||||
AudioUnit/AudioUnitViewController.hpp AudioUnit/AudioUnitViewController.mm
|
|
||||||
AudioUnit/AudioGroupFilePresenter.hpp AudioUnit/AudioGroupFilePresenter.mm
|
|
||||||
AmuseContainerMainMenu.nib)
|
|
||||||
set_source_files_properties(AudioUnit/AudioUnitBackend.mm AudioUnit/AudioUnitViewController.mm
|
|
||||||
AudioUnit/AmuseContainingApp.mm AudioUnit/AudioGroupFilePresenter.mm
|
|
||||||
PROPERTIES COMPILE_FLAGS -fobjc-arc)
|
|
||||||
target_link_libraries(amuse-au-container amuse boo soxr ${AUDIOUNIT_LIBRARY} ${COREAUDIOKIT_LIBRARY}
|
|
||||||
${AVFOUNDATION_LIBRARY} ${BOO_SYS_LIBS} logvisor athena-core)
|
|
||||||
|
|
||||||
set(APPLE_BUNDLE_ID "io.github.axiodl.Amuse")
|
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/AudioUnit/AmuseContainer.entitlements.in
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/AmuseContainer.entitlements)
|
|
||||||
|
|
||||||
set_target_properties(amuse-au-container PROPERTIES
|
|
||||||
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/AudioUnit/ContainerInfo.plist"
|
|
||||||
XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${CMAKE_CURRENT_BINARY_DIR}/AmuseContainer.entitlements"
|
|
||||||
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "${APPLE_DEV_ID}")
|
|
||||||
|
|
||||||
add_custom_command(TARGET amuse-au POST_BUILD
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy "${PROV_PROFILE}" "$<TARGET_FILE_DIR:amuse-au>/../embedded.provisionprofile"
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E remove_directory "$<TARGET_FILE_DIR:amuse-au-container>/../PlugIns/amuse-au.appex"
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_directory "$<TARGET_FILE_DIR:amuse-au>/../.."
|
|
||||||
"$<TARGET_FILE_DIR:amuse-au-container>/../PlugIns/amuse-au.appex"
|
|
||||||
COMMAND codesign --force --sign
|
|
||||||
${APPLE_DEV_ID} --entitlements "${CMAKE_CURRENT_BINARY_DIR}/AmuseExtension.entitlements"
|
|
||||||
"$<TARGET_FILE_DIR:amuse-au-container>/../PlugIns/amuse-au.appex"
|
|
||||||
COMMAND codesign --force --sign ${APPLE_DEV_ID}
|
|
||||||
"$<TARGET_FILE_DIR:amuse-au-container>/../.."
|
|
||||||
VERBATIM
|
|
||||||
)
|
|
||||||
|
|
||||||
add_custom_command(TARGET amuse-au-container POST_BUILD
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy
|
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/AmuseContainerMainMenu.nib"
|
|
||||||
"$<TARGET_FILE_DIR:amuse-au-container>/../Resources/AmuseContainerMainMenu.nib"
|
|
||||||
COMMAND codesign --force --sign
|
|
||||||
${APPLE_DEV_ID} "$<TARGET_FILE_DIR:amuse-au-container>/../.."
|
|
||||||
VERBATIM
|
|
||||||
)
|
|
||||||
|
|
||||||
else()
|
|
||||||
message(WARNING "Unable to find developer provision profile; skipping Amuse-AU")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
# Multi-platform CLI tool
|
||||||
add_executable(amuseplay WIN32 driver/main.cpp)
|
add_executable(amuseplay WIN32 driver/main.cpp)
|
||||||
target_link_libraries(amuseplay amuse boo ${BOO_SYS_LIBS} logvisor athena-core ${ZLIB_LIBRARIES})
|
target_link_libraries(amuseplay amuse boo ${BOO_SYS_LIBS} logvisor athena-core ${ZLIB_LIBRARIES})
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -24,8 +24,8 @@ class AudioGroup
|
||||||
public:
|
public:
|
||||||
operator bool() const {return m_valid;}
|
operator bool() const {return m_valid;}
|
||||||
AudioGroup(const AudioGroupData& data, GCNDataTag);
|
AudioGroup(const AudioGroupData& data, GCNDataTag);
|
||||||
AudioGroup(const AudioGroupData& data, N64DataTag);
|
AudioGroup(const AudioGroupData& data, bool absOffs, N64DataTag);
|
||||||
AudioGroup(const AudioGroupData& data, PCDataTag);
|
AudioGroup(const AudioGroupData& data, bool absOffs, PCDataTag);
|
||||||
|
|
||||||
const Sample* getSample(int sfxId) const;
|
const Sample* getSample(int sfxId) const;
|
||||||
const unsigned char* getSampleData(uint32_t offset) const;
|
const unsigned char* getSampleData(uint32_t offset) const;
|
||||||
|
|
|
@ -16,20 +16,26 @@ protected:
|
||||||
unsigned char* m_sdir;
|
unsigned char* m_sdir;
|
||||||
unsigned char* m_samp;
|
unsigned char* m_samp;
|
||||||
DataFormat m_fmt;
|
DataFormat m_fmt;
|
||||||
|
bool m_absOffs;
|
||||||
|
|
||||||
AudioGroupData(unsigned char* proj, unsigned char* pool,
|
AudioGroupData(unsigned char* proj, unsigned char* pool,
|
||||||
unsigned char* sdir, unsigned char* samp, DataFormat fmt)
|
unsigned char* sdir, unsigned char* samp,
|
||||||
: m_proj(proj), m_pool(pool), m_sdir(sdir), m_samp(samp), m_fmt(fmt) {}
|
DataFormat fmt, bool absOffs)
|
||||||
|
: m_proj(proj), m_pool(pool), m_sdir(sdir), m_samp(samp),
|
||||||
|
m_fmt(fmt), m_absOffs(absOffs) {}
|
||||||
public:
|
public:
|
||||||
AudioGroupData(unsigned char* proj, unsigned char* pool,
|
AudioGroupData(unsigned char* proj, unsigned char* pool,
|
||||||
unsigned char* sdir, unsigned char* samp, GCNDataTag)
|
unsigned char* sdir, unsigned char* samp, GCNDataTag)
|
||||||
: m_proj(proj), m_pool(pool), m_sdir(sdir), m_samp(samp), m_fmt(DataFormat::GCN) {}
|
: m_proj(proj), m_pool(pool), m_sdir(sdir), m_samp(samp),
|
||||||
|
m_fmt(DataFormat::GCN), m_absOffs(true) {}
|
||||||
AudioGroupData(unsigned char* proj, unsigned char* pool,
|
AudioGroupData(unsigned char* proj, unsigned char* pool,
|
||||||
unsigned char* sdir, unsigned char* samp, N64DataTag)
|
unsigned char* sdir, unsigned char* samp, bool absOffs, N64DataTag)
|
||||||
: m_proj(proj), m_pool(pool), m_sdir(sdir), m_samp(samp), m_fmt(DataFormat::N64) {}
|
: m_proj(proj), m_pool(pool), m_sdir(sdir), m_samp(samp),
|
||||||
|
m_fmt(DataFormat::N64), m_absOffs(absOffs) {}
|
||||||
AudioGroupData(unsigned char* proj, unsigned char* pool,
|
AudioGroupData(unsigned char* proj, unsigned char* pool,
|
||||||
unsigned char* sdir, unsigned char* samp, PCDataTag)
|
unsigned char* sdir, unsigned char* samp, bool absOffs, PCDataTag)
|
||||||
: m_proj(proj), m_pool(pool), m_sdir(sdir), m_samp(samp), m_fmt(DataFormat::PC) {}
|
: m_proj(proj), m_pool(pool), m_sdir(sdir), m_samp(samp),
|
||||||
|
m_fmt(DataFormat::PC), m_absOffs(absOffs) {}
|
||||||
|
|
||||||
const unsigned char* getProj() const {return m_proj;}
|
const unsigned char* getProj() const {return m_proj;}
|
||||||
const unsigned char* getPool() const {return m_pool;}
|
const unsigned char* getPool() const {return m_pool;}
|
||||||
|
@ -42,6 +48,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
DataFormat getDataFormat() const {return m_fmt;}
|
DataFormat getDataFormat() const {return m_fmt;}
|
||||||
|
bool getAbsoluteProjOffsets() const {return m_absOffs;}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A buffer-owning version of AudioGroupData */
|
/** A buffer-owning version of AudioGroupData */
|
||||||
|
|
|
@ -76,13 +76,13 @@ class AudioGroupProject
|
||||||
std::unique_ptr<SongGroupIndex::PageEntry[]> m_convNormalPages;
|
std::unique_ptr<SongGroupIndex::PageEntry[]> m_convNormalPages;
|
||||||
std::unique_ptr<SongGroupIndex::PageEntry[]> m_convDrumPages;
|
std::unique_ptr<SongGroupIndex::PageEntry[]> m_convDrumPages;
|
||||||
std::unique_ptr<std::array<SongGroupIndex::MIDISetup, 16>[]> m_convMidiSetups;
|
std::unique_ptr<std::array<SongGroupIndex::MIDISetup, 16>[]> m_convMidiSetups;
|
||||||
void _allocateConvBuffers(const unsigned char* data, N64DataTag);
|
void _allocateConvBuffers(const unsigned char* data, bool absOffs, N64DataTag);
|
||||||
void _allocateConvBuffers(const unsigned char* data, PCDataTag);
|
void _allocateConvBuffers(const unsigned char* data, bool absOffs, PCDataTag);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AudioGroupProject(const unsigned char* data, GCNDataTag);
|
AudioGroupProject(const unsigned char* data, GCNDataTag);
|
||||||
AudioGroupProject(const unsigned char* data, N64DataTag);
|
AudioGroupProject(const unsigned char* data, bool absOffs, N64DataTag);
|
||||||
AudioGroupProject(const unsigned char* data, PCDataTag);
|
AudioGroupProject(const unsigned char* data, bool absOffs, PCDataTag);
|
||||||
static AudioGroupProject CreateAudioGroupProject(const AudioGroupData& data);
|
static AudioGroupProject CreateAudioGroupProject(const AudioGroupData& data);
|
||||||
|
|
||||||
const SongGroupIndex* getSongGroupIndex(int groupId) const;
|
const SongGroupIndex* getSongGroupIndex(int groupId) const;
|
||||||
|
|
|
@ -48,8 +48,9 @@ private:
|
||||||
std::unordered_map<uint16_t, std::pair<Entry, ADPCMParms>> m_entries;
|
std::unordered_map<uint16_t, std::pair<Entry, ADPCMParms>> m_entries;
|
||||||
public:
|
public:
|
||||||
AudioGroupSampleDirectory(const unsigned char* data, GCNDataTag);
|
AudioGroupSampleDirectory(const unsigned char* data, GCNDataTag);
|
||||||
AudioGroupSampleDirectory(const unsigned char* data, const unsigned char* sampData, N64DataTag);
|
AudioGroupSampleDirectory(const unsigned char* data, const unsigned char* sampData,
|
||||||
AudioGroupSampleDirectory(const unsigned char* data, PCDataTag);
|
bool absOffs, N64DataTag);
|
||||||
|
AudioGroupSampleDirectory(const unsigned char* data, bool absOffs, PCDataTag);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,8 @@ public:
|
||||||
MetroidPrime2,
|
MetroidPrime2,
|
||||||
RogueSquadronPC,
|
RogueSquadronPC,
|
||||||
RogueSquadronN64,
|
RogueSquadronN64,
|
||||||
|
BattleForNabooPC,
|
||||||
|
BattleForNabooN64,
|
||||||
RogueSquadron2,
|
RogueSquadron2,
|
||||||
RogueSquadron3
|
RogueSquadron3
|
||||||
};
|
};
|
||||||
|
|
|
@ -12,18 +12,18 @@ AudioGroup::AudioGroup(const AudioGroupData& data, GCNDataTag)
|
||||||
m_fmt(DataFormat::GCN)
|
m_fmt(DataFormat::GCN)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
AudioGroup::AudioGroup(const AudioGroupData& data, N64DataTag)
|
AudioGroup::AudioGroup(const AudioGroupData& data, bool absOffs, N64DataTag)
|
||||||
: m_proj(data.getProj(), N64DataTag{}),
|
: m_proj(data.getProj(), absOffs, N64DataTag{}),
|
||||||
m_pool(data.getPool()),
|
m_pool(data.getPool()),
|
||||||
m_sdir(data.getSdir(), data.getSamp(), N64DataTag{}),
|
m_sdir(data.getSdir(), data.getSamp(), absOffs, N64DataTag{}),
|
||||||
m_samp(data.getSamp()),
|
m_samp(data.getSamp()),
|
||||||
m_fmt(DataFormat::N64)
|
m_fmt(DataFormat::N64)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
AudioGroup::AudioGroup(const AudioGroupData& data, PCDataTag)
|
AudioGroup::AudioGroup(const AudioGroupData& data, bool absOffs, PCDataTag)
|
||||||
: m_proj(data.getProj(), PCDataTag{}),
|
: m_proj(data.getProj(), absOffs, PCDataTag{}),
|
||||||
m_pool(data.getPool(), PCDataTag{}),
|
m_pool(data.getPool(), PCDataTag{}),
|
||||||
m_sdir(data.getSdir(), PCDataTag{}),
|
m_sdir(data.getSdir(), absOffs, PCDataTag{}),
|
||||||
m_samp(data.getSamp()),
|
m_samp(data.getSamp()),
|
||||||
m_fmt(DataFormat::PC)
|
m_fmt(DataFormat::PC)
|
||||||
{}
|
{}
|
||||||
|
|
|
@ -15,7 +15,7 @@ IntrusiveAudioGroupData::~IntrusiveAudioGroupData()
|
||||||
}
|
}
|
||||||
|
|
||||||
IntrusiveAudioGroupData::IntrusiveAudioGroupData(IntrusiveAudioGroupData&& other)
|
IntrusiveAudioGroupData::IntrusiveAudioGroupData(IntrusiveAudioGroupData&& other)
|
||||||
: AudioGroupData(other.m_proj, other.m_pool, other.m_sdir, other.m_samp, other.m_fmt)
|
: AudioGroupData(other.m_proj, other.m_pool, other.m_sdir, other.m_samp, other.m_fmt, other.m_absOffs)
|
||||||
{
|
{
|
||||||
m_owns = other.m_owns;
|
m_owns = other.m_owns;
|
||||||
other.m_owns = false;
|
other.m_owns = false;
|
||||||
|
@ -39,6 +39,7 @@ IntrusiveAudioGroupData& IntrusiveAudioGroupData::operator=(IntrusiveAudioGroupD
|
||||||
m_sdir = other.m_sdir;
|
m_sdir = other.m_sdir;
|
||||||
m_samp = other.m_samp;
|
m_samp = other.m_samp;
|
||||||
m_fmt = other.m_fmt;
|
m_fmt = other.m_fmt;
|
||||||
|
m_absOffs = other.m_absOffs;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,7 +152,7 @@ struct MusyX1MIDISetup
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void AudioGroupProject::_allocateConvBuffers(const unsigned char* data, N64DataTag)
|
void AudioGroupProject::_allocateConvBuffers(const unsigned char* data, bool absOffs, N64DataTag)
|
||||||
{
|
{
|
||||||
size_t normPageCount = 0;
|
size_t normPageCount = 0;
|
||||||
size_t drumPageCount = 0;
|
size_t drumPageCount = 0;
|
||||||
|
@ -161,7 +161,7 @@ void AudioGroupProject::_allocateConvBuffers(const unsigned char* data, N64DataT
|
||||||
const GroupHeader* group = reinterpret_cast<const GroupHeader*>(data);
|
const GroupHeader* group = reinterpret_cast<const GroupHeader*>(data);
|
||||||
while (group->groupEndOff != 0xffffffff)
|
while (group->groupEndOff != 0xffffffff)
|
||||||
{
|
{
|
||||||
const unsigned char* subData = data + 8;
|
const unsigned char* subData = absOffs ? data : data + 8;
|
||||||
GroupHeader header = *group;
|
GroupHeader header = *group;
|
||||||
header.swapBig();
|
header.swapBig();
|
||||||
|
|
||||||
|
@ -194,9 +194,14 @@ void AudioGroupProject::_allocateConvBuffers(const unsigned char* data, N64DataT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (absOffs)
|
||||||
|
group = reinterpret_cast<const GroupHeader*>(data + header.groupEndOff);
|
||||||
|
else
|
||||||
|
{
|
||||||
data += header.groupEndOff;
|
data += header.groupEndOff;
|
||||||
group = reinterpret_cast<const GroupHeader*>(data);
|
group = reinterpret_cast<const GroupHeader*>(data);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (normPageCount)
|
if (normPageCount)
|
||||||
m_convNormalPages.reset(new SongGroupIndex::PageEntry[normPageCount]);
|
m_convNormalPages.reset(new SongGroupIndex::PageEntry[normPageCount]);
|
||||||
|
@ -206,9 +211,9 @@ void AudioGroupProject::_allocateConvBuffers(const unsigned char* data, N64DataT
|
||||||
m_convMidiSetups.reset(new std::array<SongGroupIndex::MIDISetup, 16>[midiSetupCount]);
|
m_convMidiSetups.reset(new std::array<SongGroupIndex::MIDISetup, 16>[midiSetupCount]);
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioGroupProject::AudioGroupProject(const unsigned char* data, N64DataTag)
|
AudioGroupProject::AudioGroupProject(const unsigned char* data, bool absOffs, N64DataTag)
|
||||||
{
|
{
|
||||||
_allocateConvBuffers(data, N64DataTag{});
|
_allocateConvBuffers(data, absOffs, N64DataTag{});
|
||||||
SongGroupIndex::PageEntry* normPagesBuf = m_convNormalPages.get();
|
SongGroupIndex::PageEntry* normPagesBuf = m_convNormalPages.get();
|
||||||
SongGroupIndex::PageEntry* drumPagesBuf = m_convDrumPages.get();
|
SongGroupIndex::PageEntry* drumPagesBuf = m_convDrumPages.get();
|
||||||
std::array<SongGroupIndex::MIDISetup, 16>* midiSetupsBuf = m_convMidiSetups.get();
|
std::array<SongGroupIndex::MIDISetup, 16>* midiSetupsBuf = m_convMidiSetups.get();
|
||||||
|
@ -216,7 +221,7 @@ AudioGroupProject::AudioGroupProject(const unsigned char* data, N64DataTag)
|
||||||
const GroupHeader* group = reinterpret_cast<const GroupHeader*>(data);
|
const GroupHeader* group = reinterpret_cast<const GroupHeader*>(data);
|
||||||
while (group->groupEndOff != 0xffffffff)
|
while (group->groupEndOff != 0xffffffff)
|
||||||
{
|
{
|
||||||
const unsigned char* subData = data + 8;
|
const unsigned char* subData = absOffs ? data : data + 8;
|
||||||
GroupHeader header = *group;
|
GroupHeader header = *group;
|
||||||
header.swapBig();
|
header.swapBig();
|
||||||
|
|
||||||
|
@ -289,12 +294,17 @@ AudioGroupProject::AudioGroupProject(const unsigned char* data, N64DataTag)
|
||||||
bIdx->m_layersIndex = reinterpret_cast<const uint16_t*>(subData + header.layerIdsOff);
|
bIdx->m_layersIndex = reinterpret_cast<const uint16_t*>(subData + header.layerIdsOff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (absOffs)
|
||||||
|
group = reinterpret_cast<const GroupHeader*>(data + header.groupEndOff);
|
||||||
|
else
|
||||||
|
{
|
||||||
data += header.groupEndOff;
|
data += header.groupEndOff;
|
||||||
group = reinterpret_cast<const GroupHeader*>(data);
|
group = reinterpret_cast<const GroupHeader*>(data);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioGroupProject::_allocateConvBuffers(const unsigned char* data, PCDataTag)
|
void AudioGroupProject::_allocateConvBuffers(const unsigned char* data, bool absOffs, PCDataTag)
|
||||||
{
|
{
|
||||||
size_t normPageCount = 0;
|
size_t normPageCount = 0;
|
||||||
size_t drumPageCount = 0;
|
size_t drumPageCount = 0;
|
||||||
|
@ -303,7 +313,7 @@ void AudioGroupProject::_allocateConvBuffers(const unsigned char* data, PCDataTa
|
||||||
const GroupHeader* group = reinterpret_cast<const GroupHeader*>(data);
|
const GroupHeader* group = reinterpret_cast<const GroupHeader*>(data);
|
||||||
while (group->groupEndOff != 0xffffffff)
|
while (group->groupEndOff != 0xffffffff)
|
||||||
{
|
{
|
||||||
const unsigned char* subData = data + 8;
|
const unsigned char* subData = absOffs ? data : data + 8;
|
||||||
|
|
||||||
if (group->type == GroupType::Song)
|
if (group->type == GroupType::Song)
|
||||||
{
|
{
|
||||||
|
@ -334,9 +344,14 @@ void AudioGroupProject::_allocateConvBuffers(const unsigned char* data, PCDataTa
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (absOffs)
|
||||||
|
group = reinterpret_cast<const GroupHeader*>(data + group->groupEndOff);
|
||||||
|
else
|
||||||
|
{
|
||||||
data += group->groupEndOff;
|
data += group->groupEndOff;
|
||||||
group = reinterpret_cast<const GroupHeader*>(data);
|
group = reinterpret_cast<const GroupHeader*>(data);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (normPageCount)
|
if (normPageCount)
|
||||||
m_convNormalPages.reset(new SongGroupIndex::PageEntry[normPageCount]);
|
m_convNormalPages.reset(new SongGroupIndex::PageEntry[normPageCount]);
|
||||||
|
@ -346,9 +361,9 @@ void AudioGroupProject::_allocateConvBuffers(const unsigned char* data, PCDataTa
|
||||||
m_convMidiSetups.reset(new std::array<SongGroupIndex::MIDISetup, 16>[midiSetupCount]);
|
m_convMidiSetups.reset(new std::array<SongGroupIndex::MIDISetup, 16>[midiSetupCount]);
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioGroupProject::AudioGroupProject(const unsigned char* data, PCDataTag)
|
AudioGroupProject::AudioGroupProject(const unsigned char* data, bool absOffs, PCDataTag)
|
||||||
{
|
{
|
||||||
_allocateConvBuffers(data, PCDataTag{});
|
_allocateConvBuffers(data, absOffs, PCDataTag{});
|
||||||
SongGroupIndex::PageEntry* normPagesBuf = m_convNormalPages.get();
|
SongGroupIndex::PageEntry* normPagesBuf = m_convNormalPages.get();
|
||||||
SongGroupIndex::PageEntry* drumPagesBuf = m_convDrumPages.get();
|
SongGroupIndex::PageEntry* drumPagesBuf = m_convDrumPages.get();
|
||||||
std::array<SongGroupIndex::MIDISetup, 16>* midiSetupsBuf = m_convMidiSetups.get();
|
std::array<SongGroupIndex::MIDISetup, 16>* midiSetupsBuf = m_convMidiSetups.get();
|
||||||
|
@ -356,7 +371,7 @@ AudioGroupProject::AudioGroupProject(const unsigned char* data, PCDataTag)
|
||||||
const GroupHeader* group = reinterpret_cast<const GroupHeader*>(data);
|
const GroupHeader* group = reinterpret_cast<const GroupHeader*>(data);
|
||||||
while (group->groupEndOff != 0xffffffff)
|
while (group->groupEndOff != 0xffffffff)
|
||||||
{
|
{
|
||||||
const unsigned char* subData = data + 8;
|
const unsigned char* subData = absOffs ? data : data + 8;
|
||||||
|
|
||||||
AudioGroupIndex* bIdx = nullptr;
|
AudioGroupIndex* bIdx = nullptr;
|
||||||
|
|
||||||
|
@ -427,9 +442,14 @@ AudioGroupProject::AudioGroupProject(const unsigned char* data, PCDataTag)
|
||||||
bIdx->m_layersIndex = reinterpret_cast<const uint16_t*>(subData + group->layerIdsOff);
|
bIdx->m_layersIndex = reinterpret_cast<const uint16_t*>(subData + group->layerIdsOff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (absOffs)
|
||||||
|
group = reinterpret_cast<const GroupHeader*>(data + group->groupEndOff);
|
||||||
|
else
|
||||||
|
{
|
||||||
data += group->groupEndOff;
|
data += group->groupEndOff;
|
||||||
group = reinterpret_cast<const GroupHeader*>(data);
|
group = reinterpret_cast<const GroupHeader*>(data);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioGroupProject AudioGroupProject::CreateAudioGroupProject(const AudioGroupData& data)
|
AudioGroupProject AudioGroupProject::CreateAudioGroupProject(const AudioGroupData& data)
|
||||||
|
@ -439,9 +459,9 @@ AudioGroupProject AudioGroupProject::CreateAudioGroupProject(const AudioGroupDat
|
||||||
case DataFormat::GCN:
|
case DataFormat::GCN:
|
||||||
return AudioGroupProject(data.getProj(), GCNDataTag{});
|
return AudioGroupProject(data.getProj(), GCNDataTag{});
|
||||||
case DataFormat::N64:
|
case DataFormat::N64:
|
||||||
return AudioGroupProject(data.getProj(), N64DataTag{});
|
return AudioGroupProject(data.getProj(), data.getAbsoluteProjOffsets(), N64DataTag{});
|
||||||
case DataFormat::PC:
|
case DataFormat::PC:
|
||||||
return AudioGroupProject(data.getProj(), PCDataTag{});
|
return AudioGroupProject(data.getProj(), data.getAbsoluteProjOffsets(), PCDataTag{});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -94,10 +94,65 @@ struct MusyX1SdirEntry
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct MusyX1AbsSdirEntry
|
||||||
|
{
|
||||||
|
uint16_t m_sfxId;
|
||||||
|
uint32_t m_sampleOff;
|
||||||
|
uint32_t m_unk;
|
||||||
|
uint32_t m_pitchSampleRate;
|
||||||
|
uint32_t m_numSamples;
|
||||||
|
uint32_t m_loopStartSample;
|
||||||
|
uint32_t m_loopLengthSamples;
|
||||||
|
|
||||||
|
void swapBig()
|
||||||
|
{
|
||||||
|
m_sfxId = SBig(m_sfxId);
|
||||||
|
m_sampleOff = SBig(m_sampleOff);
|
||||||
|
m_unk = SBig(m_unk);
|
||||||
|
m_pitchSampleRate = SBig(m_pitchSampleRate);
|
||||||
|
m_numSamples = SBig(m_numSamples);
|
||||||
|
m_loopStartSample = SBig(m_loopStartSample);
|
||||||
|
m_loopLengthSamples = SBig(m_loopLengthSamples);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setIntoMusyX2(AudioGroupSampleDirectory::Entry& ent) const
|
||||||
|
{
|
||||||
|
ent.m_sfxId = m_sfxId;
|
||||||
|
ent.m_sampleOff = m_sampleOff;
|
||||||
|
ent.m_unk = m_unk;
|
||||||
|
ent.m_pitch = m_pitchSampleRate >> 24;
|
||||||
|
ent.m_sampleRate = m_pitchSampleRate & 0xffff;
|
||||||
|
ent.m_numSamples = m_numSamples;
|
||||||
|
ent.m_loopStartSample = m_loopStartSample;
|
||||||
|
ent.m_loopLengthSamples = m_loopLengthSamples;
|
||||||
|
ent.m_adpcmParmOffset = 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
AudioGroupSampleDirectory::AudioGroupSampleDirectory(const unsigned char* data,
|
AudioGroupSampleDirectory::AudioGroupSampleDirectory(const unsigned char* data,
|
||||||
const unsigned char* sampData, N64DataTag)
|
const unsigned char* sampData,
|
||||||
|
bool absOffs, N64DataTag)
|
||||||
{
|
{
|
||||||
const unsigned char* cur = data;
|
const unsigned char* cur = data;
|
||||||
|
|
||||||
|
if (absOffs)
|
||||||
|
{
|
||||||
|
while (*reinterpret_cast<const uint32_t*>(cur) != 0xffffffff)
|
||||||
|
{
|
||||||
|
MusyX1AbsSdirEntry ent = *reinterpret_cast<const MusyX1AbsSdirEntry*>(cur);
|
||||||
|
ent.swapBig();
|
||||||
|
|
||||||
|
std::pair<Entry, ADPCMParms>& store = m_entries[ent.m_sfxId];
|
||||||
|
ent.setIntoMusyX2(store.first);
|
||||||
|
|
||||||
|
memcpy(&store.second.vadpcm.m_coefs, sampData + ent.m_sampleOff, 256);
|
||||||
|
store.second.swapBigVADPCM();
|
||||||
|
|
||||||
|
cur += 28;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
while (*reinterpret_cast<const uint32_t*>(cur) != 0xffffffff)
|
while (*reinterpret_cast<const uint32_t*>(cur) != 0xffffffff)
|
||||||
{
|
{
|
||||||
MusyX1SdirEntry ent = *reinterpret_cast<const MusyX1SdirEntry*>(cur);
|
MusyX1SdirEntry ent = *reinterpret_cast<const MusyX1SdirEntry*>(cur);
|
||||||
|
@ -111,11 +166,28 @@ AudioGroupSampleDirectory::AudioGroupSampleDirectory(const unsigned char* data,
|
||||||
|
|
||||||
cur += 24;
|
cur += 24;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioGroupSampleDirectory::AudioGroupSampleDirectory(const unsigned char* data, PCDataTag)
|
AudioGroupSampleDirectory::AudioGroupSampleDirectory(const unsigned char* data,
|
||||||
|
bool absOffs, PCDataTag)
|
||||||
{
|
{
|
||||||
const unsigned char* cur = data;
|
const unsigned char* cur = data;
|
||||||
|
|
||||||
|
if (absOffs)
|
||||||
|
{
|
||||||
|
while (*reinterpret_cast<const uint32_t*>(cur) != 0xffffffff)
|
||||||
|
{
|
||||||
|
const MusyX1AbsSdirEntry* ent = reinterpret_cast<const MusyX1AbsSdirEntry*>(cur);
|
||||||
|
|
||||||
|
std::pair<Entry, ADPCMParms>& store = m_entries[ent->m_sfxId];
|
||||||
|
ent->setIntoMusyX2(store.first);
|
||||||
|
|
||||||
|
cur += 28;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
while (*reinterpret_cast<const uint32_t*>(cur) != 0xffffffff)
|
while (*reinterpret_cast<const uint32_t*>(cur) != 0xffffffff)
|
||||||
{
|
{
|
||||||
const MusyX1SdirEntry* ent = reinterpret_cast<const MusyX1SdirEntry*>(cur);
|
const MusyX1SdirEntry* ent = reinterpret_cast<const MusyX1SdirEntry*>(cur);
|
||||||
|
@ -125,6 +197,7 @@ AudioGroupSampleDirectory::AudioGroupSampleDirectory(const unsigned char* data,
|
||||||
|
|
||||||
cur += 24;
|
cur += 24;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,10 @@ const char* ContainerRegistry::TypeToName(Type tp)
|
||||||
return "Star Wars: Rogue Squadron (PC)";
|
return "Star Wars: Rogue Squadron (PC)";
|
||||||
case Type::RogueSquadronN64:
|
case Type::RogueSquadronN64:
|
||||||
return "Star Wars: Rogue Squadron (N64)";
|
return "Star Wars: Rogue Squadron (N64)";
|
||||||
|
case Type::BattleForNabooPC:
|
||||||
|
return "Star Wars Episode I: Battle for Naboo (PC)";
|
||||||
|
case Type::BattleForNabooN64:
|
||||||
|
return "Star Wars Episode I: Battle for Naboo (N64)";
|
||||||
case Type::RogueSquadron2:
|
case Type::RogueSquadron2:
|
||||||
return "Star Wars: Rogue Squadron 2 (GCN)";
|
return "Star Wars: Rogue Squadron 2 (GCN)";
|
||||||
case Type::RogueSquadron3:
|
case Type::RogueSquadron3:
|
||||||
|
@ -371,13 +375,13 @@ static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadMP2(FILE
|
||||||
fread(pool.get(), 1, poolSz, fp);
|
fread(pool.get(), 1, poolSz, fp);
|
||||||
|
|
||||||
std::unique_ptr<uint8_t[]> proj(new uint8_t[projSz]);
|
std::unique_ptr<uint8_t[]> proj(new uint8_t[projSz]);
|
||||||
fread(pool.get(), 1, projSz, fp);
|
fread(proj.get(), 1, projSz, fp);
|
||||||
|
|
||||||
std::unique_ptr<uint8_t[]> sdir(new uint8_t[sdirSz]);
|
std::unique_ptr<uint8_t[]> sdir(new uint8_t[sdirSz]);
|
||||||
fread(pool.get(), 1, sdirSz, fp);
|
fread(sdir.get(), 1, sdirSz, fp);
|
||||||
|
|
||||||
std::unique_ptr<uint8_t[]> samp(new uint8_t[sampSz]);
|
std::unique_ptr<uint8_t[]> samp(new uint8_t[sampSz]);
|
||||||
fread(pool.get(), 1, sampSz, fp);
|
fread(samp.get(), 1, sampSz, fp);
|
||||||
|
|
||||||
ret.emplace_back(std::move(name), IntrusiveAudioGroupData{proj.release(), pool.release(),
|
ret.emplace_back(std::move(name), IntrusiveAudioGroupData{proj.release(), pool.release(),
|
||||||
sdir.release(), samp.release(), GCNDataTag{}});
|
sdir.release(), samp.release(), GCNDataTag{}});
|
||||||
|
@ -410,7 +414,14 @@ struct RS1FSTEntry
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static void SwapN64Rom(void* data, size_t size)
|
static void SwapN64Rom16(void* data, size_t size)
|
||||||
|
{
|
||||||
|
uint16_t* words = reinterpret_cast<uint16_t*>(data);
|
||||||
|
for (size_t i=0 ; i<size/2 ; ++i)
|
||||||
|
words[i] = SBig(words[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SwapN64Rom32(void* data, size_t size)
|
||||||
{
|
{
|
||||||
uint32_t* words = reinterpret_cast<uint32_t*>(data);
|
uint32_t* words = reinterpret_cast<uint32_t*>(data);
|
||||||
for (size_t i=0 ; i<size/4 ; ++i)
|
for (size_t i=0 ; i<size/4 ; ++i)
|
||||||
|
@ -505,7 +516,8 @@ static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadRS1PC(FI
|
||||||
}
|
}
|
||||||
|
|
||||||
ret.emplace_back("Group", IntrusiveAudioGroupData{proj.release(), pool.release(),
|
ret.emplace_back("Group", IntrusiveAudioGroupData{proj.release(), pool.release(),
|
||||||
sdir.release(), samp.release(), PCDataTag{}});
|
sdir.release(), samp.release(),
|
||||||
|
false, PCDataTag{}});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -522,11 +534,15 @@ static bool ValidateRS1N64(FILE* fp)
|
||||||
fread(data.get(), 1, endPos, fp);
|
fread(data.get(), 1, endPos, fp);
|
||||||
|
|
||||||
if ((data[0] & 0x80) != 0x80 && (data[3] & 0x80) == 0x80)
|
if ((data[0] & 0x80) != 0x80 && (data[3] & 0x80) == 0x80)
|
||||||
SwapN64Rom(data.get(), endPos);
|
SwapN64Rom32(data.get(), endPos);
|
||||||
|
else if ((data[0] & 0x80) != 0x80 && (data[1] & 0x80) == 0x80)
|
||||||
|
SwapN64Rom16(data.get(), endPos);
|
||||||
|
|
||||||
|
#if 0
|
||||||
const uint32_t* gameId = reinterpret_cast<const uint32_t*>(&data[59]);
|
const uint32_t* gameId = reinterpret_cast<const uint32_t*>(&data[59]);
|
||||||
if (*gameId != 0x4e525345 && *gameId != 0x4553524e)
|
if (*gameId != 0x4553524e && *gameId != 0x4a53524e && *gameId != 0x5053524e)
|
||||||
return false; /* GameId not 'NRSE' */
|
return false; /* GameId not 'NRSE', 'NRSJ', or 'NRSP' */
|
||||||
|
#endif
|
||||||
|
|
||||||
const uint8_t* dataSeg = reinterpret_cast<const uint8_t*>(memmem(data.get(), endPos,
|
const uint8_t* dataSeg = reinterpret_cast<const uint8_t*>(memmem(data.get(), endPos,
|
||||||
"dbg_data\0\0\0\0\0\0\0\0", 16));
|
"dbg_data\0\0\0\0\0\0\0\0", 16));
|
||||||
|
@ -571,7 +587,9 @@ static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadRS1N64(F
|
||||||
fread(data.get(), 1, endPos, fp);
|
fread(data.get(), 1, endPos, fp);
|
||||||
|
|
||||||
if ((data[0] & 0x80) != 0x80 && (data[3] & 0x80) == 0x80)
|
if ((data[0] & 0x80) != 0x80 && (data[3] & 0x80) == 0x80)
|
||||||
SwapN64Rom(data.get(), endPos);
|
SwapN64Rom32(data.get(), endPos);
|
||||||
|
else if ((data[0] & 0x80) != 0x80 && (data[1] & 0x80) == 0x80)
|
||||||
|
SwapN64Rom16(data.get(), endPos);
|
||||||
|
|
||||||
const uint8_t* dataSeg = reinterpret_cast<const uint8_t*>(memmem(data.get(), endPos,
|
const uint8_t* dataSeg = reinterpret_cast<const uint8_t*>(memmem(data.get(), endPos,
|
||||||
"dbg_data\0\0\0\0\0\0\0\0", 16));
|
"dbg_data\0\0\0\0\0\0\0\0", 16));
|
||||||
|
@ -656,7 +674,261 @@ static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadRS1N64(F
|
||||||
}
|
}
|
||||||
|
|
||||||
ret.emplace_back("Group", IntrusiveAudioGroupData{proj.release(), pool.release(),
|
ret.emplace_back("Group", IntrusiveAudioGroupData{proj.release(), pool.release(),
|
||||||
sdir.release(), samp.release(), N64DataTag{}});
|
sdir.release(), samp.release(),
|
||||||
|
false, N64DataTag{}});
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ValidateBFNPC(FILE* fp)
|
||||||
|
{
|
||||||
|
size_t endPos = FileLength(fp);
|
||||||
|
|
||||||
|
uint32_t fstOff;
|
||||||
|
uint32_t fstSz;
|
||||||
|
if (fread(&fstOff, 1, 4, fp) == 4 && fread(&fstSz, 1, 4, fp) == 4)
|
||||||
|
{
|
||||||
|
if (fstOff + fstSz <= endPos)
|
||||||
|
{
|
||||||
|
FSeek(fp, fstOff, SEEK_SET);
|
||||||
|
uint32_t elemCount = fstSz / 32;
|
||||||
|
std::unique_ptr<RS1FSTEntry[]> entries(new RS1FSTEntry[elemCount]);
|
||||||
|
fread(entries.get(), fstSz, 1, fp);
|
||||||
|
|
||||||
|
uint8_t foundComps = 0;
|
||||||
|
for (uint32_t i=0 ; i<elemCount ; ++i)
|
||||||
|
{
|
||||||
|
RS1FSTEntry& entry = entries[i];
|
||||||
|
if (!strncmp("proj", entry.name, 16))
|
||||||
|
foundComps |= 1;
|
||||||
|
else if (!strncmp("pool", entry.name, 16))
|
||||||
|
foundComps |= 2;
|
||||||
|
else if (!strncmp("sdir", entry.name, 16))
|
||||||
|
foundComps |= 4;
|
||||||
|
else if (!strncmp("samp", entry.name, 16))
|
||||||
|
foundComps |= 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (foundComps == 0xf)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadBFNPC(FILE* fp)
|
||||||
|
{
|
||||||
|
std::vector<std::pair<std::string, IntrusiveAudioGroupData>> ret;
|
||||||
|
size_t endPos = FileLength(fp);
|
||||||
|
|
||||||
|
uint32_t fstOff;
|
||||||
|
uint32_t fstSz;
|
||||||
|
if (fread(&fstOff, 1, 4, fp) == 4 && fread(&fstSz, 1, 4, fp) == 4)
|
||||||
|
{
|
||||||
|
if (fstOff + fstSz <= endPos)
|
||||||
|
{
|
||||||
|
FSeek(fp, fstOff, SEEK_SET);
|
||||||
|
uint32_t elemCount = fstSz / 32;
|
||||||
|
std::unique_ptr<RS1FSTEntry[]> entries(new RS1FSTEntry[elemCount]);
|
||||||
|
fread(entries.get(), fstSz, 1, fp);
|
||||||
|
|
||||||
|
std::unique_ptr<uint8_t[]> proj;
|
||||||
|
std::unique_ptr<uint8_t[]> pool;
|
||||||
|
std::unique_ptr<uint8_t[]> sdir;
|
||||||
|
std::unique_ptr<uint8_t[]> samp;
|
||||||
|
|
||||||
|
for (uint32_t i=0 ; i<elemCount ; ++i)
|
||||||
|
{
|
||||||
|
RS1FSTEntry& entry = entries[i];
|
||||||
|
if (!strncmp("proj", entry.name, 16))
|
||||||
|
{
|
||||||
|
proj.reset(new uint8_t[entry.decompSz]);
|
||||||
|
FSeek(fp, entry.offset, SEEK_SET);
|
||||||
|
fread(proj.get(), 1, entry.decompSz, fp);
|
||||||
|
}
|
||||||
|
else if (!strncmp("pool", entry.name, 16))
|
||||||
|
{
|
||||||
|
pool.reset(new uint8_t[entry.decompSz]);
|
||||||
|
FSeek(fp, entry.offset, SEEK_SET);
|
||||||
|
fread(pool.get(), 1, entry.decompSz, fp);
|
||||||
|
}
|
||||||
|
else if (!strncmp("sdir", entry.name, 16))
|
||||||
|
{
|
||||||
|
sdir.reset(new uint8_t[entry.decompSz]);
|
||||||
|
FSeek(fp, entry.offset, SEEK_SET);
|
||||||
|
fread(sdir.get(), 1, entry.decompSz, fp);
|
||||||
|
}
|
||||||
|
else if (!strncmp("samp", entry.name, 16))
|
||||||
|
{
|
||||||
|
samp.reset(new uint8_t[entry.decompSz]);
|
||||||
|
FSeek(fp, entry.offset, SEEK_SET);
|
||||||
|
fread(samp.get(), 1, entry.decompSz, fp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret.emplace_back("Group", IntrusiveAudioGroupData{proj.release(), pool.release(),
|
||||||
|
sdir.release(), samp.release(),
|
||||||
|
true, PCDataTag{}});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ValidateBFNN64(FILE* fp)
|
||||||
|
{
|
||||||
|
size_t endPos = FileLength(fp);
|
||||||
|
if (endPos > 32 * 1024 * 1024)
|
||||||
|
return false; /* N64 ROM definitely won't exceed 32MB */
|
||||||
|
|
||||||
|
std::unique_ptr<uint8_t[]> data(new uint8_t[endPos]);
|
||||||
|
fread(data.get(), 1, endPos, fp);
|
||||||
|
|
||||||
|
if ((data[0] & 0x80) != 0x80 && (data[3] & 0x80) == 0x80)
|
||||||
|
SwapN64Rom32(data.get(), endPos);
|
||||||
|
else if ((data[0] & 0x80) != 0x80 && (data[1] & 0x80) == 0x80)
|
||||||
|
SwapN64Rom16(data.get(), endPos);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
const uint32_t* gameId = reinterpret_cast<const uint32_t*>(&data[59]);
|
||||||
|
if (*gameId != 0x4553524e && *gameId != 0x4a53524e && *gameId != 0x5053524e)
|
||||||
|
return false; /* GameId not 'NRSE', 'NRSJ', or 'NRSP' */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const uint8_t* dataSeg = reinterpret_cast<const uint8_t*>(memmem(data.get(), endPos,
|
||||||
|
"dbg_data\0\0\0\0\0\0\0\0", 16));
|
||||||
|
if (dataSeg)
|
||||||
|
{
|
||||||
|
dataSeg += 28;
|
||||||
|
size_t fstEnd = SBig(*reinterpret_cast<const uint32_t*>(dataSeg));
|
||||||
|
dataSeg += 4;
|
||||||
|
size_t fstOff = SBig(*reinterpret_cast<const uint32_t*>(dataSeg));
|
||||||
|
if (endPos <= size_t(dataSeg - data.get()) + fstOff || endPos <= size_t(dataSeg - data.get()) + fstEnd)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const RS1FSTEntry* entry = reinterpret_cast<const RS1FSTEntry*>(dataSeg + fstOff);
|
||||||
|
const RS1FSTEntry* lastEnt = reinterpret_cast<const RS1FSTEntry*>(dataSeg + fstEnd);
|
||||||
|
|
||||||
|
uint8_t foundComps = 0;
|
||||||
|
for (; entry != lastEnt ; ++entry)
|
||||||
|
{
|
||||||
|
if (!strncmp("proj", entry->name, 16))
|
||||||
|
foundComps |= 1;
|
||||||
|
else if (!strncmp("pool", entry->name, 16))
|
||||||
|
foundComps |= 2;
|
||||||
|
else if (!strncmp("sdir", entry->name, 16))
|
||||||
|
foundComps |= 4;
|
||||||
|
else if (!strncmp("samp", entry->name, 16))
|
||||||
|
foundComps |= 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (foundComps == 0xf)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadBFNN64(FILE* fp)
|
||||||
|
{
|
||||||
|
std::vector<std::pair<std::string, IntrusiveAudioGroupData>> ret;
|
||||||
|
size_t endPos = FileLength(fp);
|
||||||
|
|
||||||
|
std::unique_ptr<uint8_t[]> data(new uint8_t[endPos]);
|
||||||
|
fread(data.get(), 1, endPos, fp);
|
||||||
|
|
||||||
|
if ((data[0] & 0x80) != 0x80 && (data[3] & 0x80) == 0x80)
|
||||||
|
SwapN64Rom32(data.get(), endPos);
|
||||||
|
else if ((data[0] & 0x80) != 0x80 && (data[1] & 0x80) == 0x80)
|
||||||
|
SwapN64Rom16(data.get(), endPos);
|
||||||
|
|
||||||
|
const uint8_t* dataSeg = reinterpret_cast<const uint8_t*>(memmem(data.get(), endPos,
|
||||||
|
"dbg_data\0\0\0\0\0\0\0\0", 16));
|
||||||
|
if (dataSeg)
|
||||||
|
{
|
||||||
|
dataSeg += 28;
|
||||||
|
size_t fstEnd = SBig(*reinterpret_cast<const uint32_t*>(dataSeg));
|
||||||
|
dataSeg += 4;
|
||||||
|
size_t fstOff = SBig(*reinterpret_cast<const uint32_t*>(dataSeg));
|
||||||
|
if (endPos <= size_t(dataSeg - data.get()) + fstOff || endPos <= size_t(dataSeg - data.get()) + fstEnd)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
const RS1FSTEntry* entry = reinterpret_cast<const RS1FSTEntry*>(dataSeg + fstOff);
|
||||||
|
const RS1FSTEntry* lastEnt = reinterpret_cast<const RS1FSTEntry*>(dataSeg + fstEnd);
|
||||||
|
|
||||||
|
std::unique_ptr<uint8_t[]> proj;
|
||||||
|
std::unique_ptr<uint8_t[]> pool;
|
||||||
|
std::unique_ptr<uint8_t[]> sdir;
|
||||||
|
std::unique_ptr<uint8_t[]> samp;
|
||||||
|
|
||||||
|
for (; entry != lastEnt ; ++entry)
|
||||||
|
{
|
||||||
|
RS1FSTEntry ent = *entry;
|
||||||
|
ent.swapBig();
|
||||||
|
|
||||||
|
if (!strncmp("proj", ent.name, 16))
|
||||||
|
{
|
||||||
|
if (ent.compSz == 0xffffffff)
|
||||||
|
{
|
||||||
|
proj.reset(new uint8_t[ent.decompSz]);
|
||||||
|
memcpy(proj.get(), dataSeg + ent.offset, ent.decompSz);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
proj.reset(new uint8_t[ent.decompSz]);
|
||||||
|
uLongf outSz = ent.decompSz;
|
||||||
|
uncompress(proj.get(), &outSz, dataSeg + ent.offset, ent.compSz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!strncmp("pool", ent.name, 16))
|
||||||
|
{
|
||||||
|
if (ent.compSz == 0xffffffff)
|
||||||
|
{
|
||||||
|
pool.reset(new uint8_t[ent.decompSz]);
|
||||||
|
memcpy(pool.get(), dataSeg + ent.offset, ent.decompSz);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pool.reset(new uint8_t[ent.decompSz]);
|
||||||
|
uLongf outSz = ent.decompSz;
|
||||||
|
uncompress(pool.get(), &outSz, dataSeg + ent.offset, ent.compSz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!strncmp("sdir", ent.name, 16))
|
||||||
|
{
|
||||||
|
if (ent.compSz == 0xffffffff)
|
||||||
|
{
|
||||||
|
sdir.reset(new uint8_t[ent.decompSz]);
|
||||||
|
memcpy(sdir.get(), dataSeg + ent.offset, ent.decompSz);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sdir.reset(new uint8_t[ent.decompSz]);
|
||||||
|
uLongf outSz = ent.decompSz;
|
||||||
|
uncompress(sdir.get(), &outSz, dataSeg + ent.offset, ent.compSz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!strncmp("samp", ent.name, 16))
|
||||||
|
{
|
||||||
|
if (ent.compSz == 0xffffffff)
|
||||||
|
{
|
||||||
|
samp.reset(new uint8_t[ent.decompSz]);
|
||||||
|
memcpy(samp.get(), dataSeg + ent.offset, ent.decompSz);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
samp.reset(new uint8_t[ent.decompSz]);
|
||||||
|
uLongf outSz = ent.decompSz;
|
||||||
|
uncompress(samp.get(), &outSz, dataSeg + ent.offset, ent.compSz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret.emplace_back("Group", IntrusiveAudioGroupData{proj.release(), pool.release(),
|
||||||
|
sdir.release(), samp.release(),
|
||||||
|
true, N64DataTag{}});
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -989,6 +1261,18 @@ ContainerRegistry::Type ContainerRegistry::DetectContainerType(const char* path)
|
||||||
return Type::RogueSquadronN64;
|
return Type::RogueSquadronN64;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ValidateBFNPC(fp))
|
||||||
|
{
|
||||||
|
fclose(fp);
|
||||||
|
return Type::BattleForNabooPC;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ValidateBFNN64(fp))
|
||||||
|
{
|
||||||
|
fclose(fp);
|
||||||
|
return Type::BattleForNabooN64;
|
||||||
|
}
|
||||||
|
|
||||||
if (ValidateRS2(fp))
|
if (ValidateRS2(fp))
|
||||||
{
|
{
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
@ -1103,13 +1387,16 @@ ContainerRegistry::LoadContainer(const char* path)
|
||||||
/* 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(), pool.release(),
|
ret.emplace_back("Group", IntrusiveAudioGroupData{proj.release(), pool.release(),
|
||||||
sdir.release(), samp.release(), GCNDataTag{}});
|
sdir.release(), samp.release(),
|
||||||
|
GCNDataTag{}});
|
||||||
else if (sdir[9] == 0x0)
|
else if (sdir[9] == 0x0)
|
||||||
ret.emplace_back("Group", IntrusiveAudioGroupData{proj.release(), pool.release(),
|
ret.emplace_back("Group", IntrusiveAudioGroupData{proj.release(), pool.release(),
|
||||||
sdir.release(), samp.release(), N64DataTag{}});
|
sdir.release(), samp.release(),
|
||||||
|
false, N64DataTag{}});
|
||||||
else
|
else
|
||||||
ret.emplace_back("Group", IntrusiveAudioGroupData{proj.release(), pool.release(),
|
ret.emplace_back("Group", IntrusiveAudioGroupData{proj.release(), pool.release(),
|
||||||
sdir.release(), samp.release(), PCDataTag{}});
|
sdir.release(), samp.release(),
|
||||||
|
false, PCDataTag{}});
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1146,6 +1433,20 @@ ContainerRegistry::LoadContainer(const char* path)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ValidateBFNPC(fp))
|
||||||
|
{
|
||||||
|
auto ret = LoadBFNPC(fp);
|
||||||
|
fclose(fp);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ValidateBFNN64(fp))
|
||||||
|
{
|
||||||
|
auto ret = LoadBFNN64(fp);
|
||||||
|
fclose(fp);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
if (ValidateRS2(fp))
|
if (ValidateRS2(fp))
|
||||||
{
|
{
|
||||||
auto ret = LoadRS2(fp);
|
auto ret = LoadRS2(fp);
|
||||||
|
|
|
@ -205,10 +205,10 @@ const AudioGroup* Engine::addAudioGroup(const AudioGroupData& data)
|
||||||
grp = std::make_unique<AudioGroup>(data, GCNDataTag{});
|
grp = std::make_unique<AudioGroup>(data, GCNDataTag{});
|
||||||
break;
|
break;
|
||||||
case DataFormat::N64:
|
case DataFormat::N64:
|
||||||
grp = std::make_unique<AudioGroup>(data, N64DataTag{});
|
grp = std::make_unique<AudioGroup>(data, data.m_absOffs, N64DataTag{});
|
||||||
break;
|
break;
|
||||||
case DataFormat::PC:
|
case DataFormat::PC:
|
||||||
grp = std::make_unique<AudioGroup>(data, PCDataTag{});
|
grp = std::make_unique<AudioGroup>(data, data.m_absOffs, PCDataTag{});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!grp)
|
if (!grp)
|
||||||
|
|
Loading…
Reference in New Issue