/*---------------------------------------------------------------------------* Project: NintendoWare File: snd_SoundArchiveFile.cpp Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Revision: 20997 $ *---------------------------------------------------------------------------*/ #include "precompiled.h" #include #include // std::strcmp #include // ut::AddOffsetToPtr #include #include #include namespace nw { namespace snd { namespace internal { namespace { const u32 DEFAULT_STRING_ID = SoundArchive::INVALID_ID; const PanMode DEFAULT_PAN_MODE = PAN_MODE_DUAL; const PanCurve DEFAULT_PAN_CURVE = PAN_CURVE_SQRT; const u8 DEFAULT_PLAYER_PRIORITY = 64; const u8 DEFAULT_CHANNEL_PRIORITY = 64; const u8 DEFAULT_ACTOR_PLAYER_ID = 0; const u8 DEFAULT_IS_RELEASE_PRIORITY_FIX = 0; const bool DEFAULT_IS_FRONT_BYPASS = false; const u32 DEFAULT_USER_PARAM = 0xffffffff; // 無効値だとわかるように const u32 DEFAULT_EXTRA_USER_PARAM_COUNT = 0; const u32 DEFAULT_SEQ_START_OFFSET = 0; const u32 DEFAULT_WARC_WAVE_COUNT = 0; const u32 DEFAULT_PLAYER_HEAP_SIZE = 0; // optionParameter の各ビットの意味 enum SoundInfoBitFlag { SOUND_INFO_STRING_ID = 0x00, SOUND_INFO_PAN_PARAM, // u8 PanMode, u8 PanCurve SOUND_INFO_PLAYER_PARAM, // u8 PlayerPriority, u8 ActorPlayerId SOUND_INFO_OFFSET_TO_3D_PARAM = 0x08, SOUND_INFO_OFFSET_TO_SEND_PARAM, SOUND_INFO_OFFSET_TO_MOD_PARAM, SOUND_INFO_OFFSET_TO_RVL_PARAM = 0x10, SOUND_INFO_OFFSET_TO_CTR_PARAM, SOUND_INFO_REFERENCE_TO_EXTRA_USER_PARAM_TABLE = 0x1e, SOUND_INFO_USER_PARAM = 0x1f }; enum WaveSoundInfoBitFlag { WAVE_SOUND_INFO_PRIORITY = 0x00 }; enum SequenceSoundInfoBitFlag { SEQ_SOUND_INFO_START_OFFSET = 0x00, SEQ_SOUND_INFO_PRIORITY }; enum BankInfoBitFlag { BANK_INFO_STRING_ID = 0x00 }; enum PlayerInfoBitFlag { PLAYER_INFO_STRING_ID = 0x00, PLAYER_INFO_HEAP_SIZE // プレイヤーヒープサイズ }; enum SoundGroupInfoBitFlag { SOUND_GROUP_INFO_STRING_ID = 0x00 }; enum GroupInfoBitFlag { GROUP_INFO_STRING_ID = 0x00 }; enum WaveArchiveInfoBitFlag { WAVE_ARCHIVE_INFO_STRING_ID = 0x00, WAVE_ARCHIVE_INFO_WAVE_COUNT }; ItemType GetItemTypeEnum( u32 id ) { return static_cast( Util::GetItemType(id) ); } } // anonymous namespace // // SoundArchiveFile::FileHeader // const Util::ReferenceWithSize* SoundArchiveFile::FileHeader::GetReferenceBy( u16 typeId ) const { for ( int i = 0; i < BLOCK_SIZE; i++ ) { if ( toBlocks[ i ].typeId == typeId ) { return &toBlocks[ i ]; } } return NULL; } #if 0 const SoundArchiveFile::StringBlock* SoundArchiveFile::FileHeader::GetStringBlock() const { // return reinterpret_cast( GetBlock( SoundArchiveFile_StringBlock ) ); return NULL; } const SoundArchiveFile::InfoBlock* SoundArchiveFile::FileHeader::GetInfoBlock() const { // return reinterpret_cast( GetBlock( SoundArchiveFile_InfoBlock ) ); return NULL; } const SoundArchiveFile::FileBlock* SoundArchiveFile::FileHeader::GetFileBlock() const { // return reinterpret_cast( GetBlock( SoundArchiveFile_FileBlock ) ); return NULL; } #endif // ブロックサイズの取得 u32 SoundArchiveFile::FileHeader::GetStringBlockSize() const { return GetReferenceBy( ElementType_SoundArchiveFile_StringBlock )->size; } u32 SoundArchiveFile::FileHeader::GetInfoBlockSize() const { return GetReferenceBy( ElementType_SoundArchiveFile_InfoBlock )->size; } u32 SoundArchiveFile::FileHeader::GetFileBlockSize() const { return GetReferenceBy( ElementType_SoundArchiveFile_FileBlock )->size; } // ブロックへのオフセットの取得 s32 SoundArchiveFile::FileHeader::GetStringBlockOffset() const { return GetReferenceBy( ElementType_SoundArchiveFile_StringBlock )->offset; } s32 SoundArchiveFile::FileHeader::GetInfoBlockOffset() const { return GetReferenceBy( ElementType_SoundArchiveFile_InfoBlock )->offset; } s32 SoundArchiveFile::FileHeader::GetFileBlockOffset() const { return GetReferenceBy( ElementType_SoundArchiveFile_FileBlock )->offset; } // // SoundArchiveFile::StringBlock // const void* SoundArchiveFile::StringBlockBody::GetSection( Sections section ) const { if ( section > Sections_Max ) return NULL; return ut::AddOffsetToPtr( this, toSection[section].offset ); } const char* SoundArchiveFile::StringBlockBody::GetString( SoundArchive::ItemId stringId ) const { if ( stringId == SoundArchive::INVALID_ID ) { return NULL; } const StringTable* table = GetStringTable(); if ( table == NULL ) return NULL; return table->GetString( stringId ); } u32 SoundArchiveFile::StringBlockBody::GetItemIdImpl( Sections section, const char* str ) const { const PatriciaTree* tree = GetPatriciaTree( section ); const PatriciaTree::NodeData* nodeData = tree->GetNodeDataBy( str ); if ( nodeData == NULL ) { return SoundArchive::INVALID_ID; } if ( std::strcmp( str, GetString( nodeData->stringId ) ) == 0 ) { return nodeData->itemId; } return SoundArchive::INVALID_ID; } void SoundArchiveFile::StringBlockBody::DumpTree() const { for ( int section = Sections_PatriciaTree; section <= Sections_Max; section++ ) { const PatriciaTree* tree = GetPatriciaTree( (Sections)section ); NN_LOG("Section[%d] rootIdx(%d) count(%d)\n", section, tree->rootIdx, tree->nodeTable.count ); for ( u32 i = 0; i < tree->nodeTable.count; i++ ) { const PatriciaTree::Node* node = &tree->nodeTable.item[i]; const PatriciaTree::NodeData* data = &node->nodeData; NN_LOG(" idx(%4d) str(%4d) itemId(0x%08X) left(%4d) right(%4d)\n", i, data->stringId, data->itemId, node->leftIdx, node->rightIdx ); } } } const SoundArchiveFile::PatriciaTree::NodeData* SoundArchiveFile::PatriciaTree::GetNodeDataBy( const char* str, std::size_t len ) const { if ( rootIdx >= nodeTable.count ) { return NULL; } const Node* node = &nodeTable.item[ rootIdx ]; if ( len == 0 ) { len = std::strlen( str ); // TODO: strnlen ? } while( ( node->flags & Node::FLAG_LEAF ) == 0 ) { const int pos = ( node->bit >> 3 ); const int bit = ( node->bit & 7 ); u32 nodeIdx; if ( pos < static_cast(len) && str[pos] & ( 1 << ( 7 - bit ) ) ) { nodeIdx = node->rightIdx; } else { nodeIdx = node->leftIdx; } node = &nodeTable.item[ nodeIdx ]; } return &node->nodeData; } // // SoundArchiveFile::InfoBlockBody // const SoundArchiveFile::SoundInfo* SoundArchiveFile::InfoBlockBody::GetSoundInfo( SoundArchive::ItemId itemId ) const { if ( GetItemTypeEnum( itemId ) != ItemType_Sound ) { return NULL; } u32 index = Util::GetItemIndex( itemId ); const Util::ReferenceTable& table = GetSoundInfoReferenceTable(); if ( index >= table.count ) { return NULL; } return reinterpret_cast( table.GetReferedItem( index ) ); } const SoundArchiveFile::BankInfo* SoundArchiveFile::InfoBlockBody::GetBankInfo( SoundArchive::ItemId itemId ) const { if ( GetItemTypeEnum( itemId ) != ItemType_Bank ) { return NULL; } u32 index = Util::GetItemIndex( itemId ); const Util::ReferenceTable& table = GetBankInfoReferenceTable(); if ( index >= table.count ) { return NULL; } return reinterpret_cast( table.GetReferedItem( index ) ); } const SoundArchiveFile::PlayerInfo* SoundArchiveFile::InfoBlockBody::GetPlayerInfo( SoundArchive::ItemId itemId ) const { if ( GetItemTypeEnum( itemId ) != ItemType_Player ) { return NULL; } u32 index = Util::GetItemIndex( itemId ); const Util::ReferenceTable& table = GetPlayerInfoReferenceTable(); if ( index >= table.count ) { return NULL; } return reinterpret_cast( table.GetReferedItem( index ) ); } const SoundArchiveFile::SoundGroupInfo* SoundArchiveFile::InfoBlockBody::GetSoundGroupInfo( SoundArchive::ItemId itemId ) const { if ( GetItemTypeEnum( itemId ) != ItemType_SoundGroup ) { return NULL; } u32 index = Util::GetItemIndex( itemId ); const Util::ReferenceTable& table = GetSoundGroupInfoReferenceTable(); if ( index >= table.count ) { return NULL; } return reinterpret_cast( table.GetReferedItem( index ) ); } const SoundArchiveFile::GroupInfo* SoundArchiveFile::InfoBlockBody::GetGroupInfo( SoundArchive::ItemId itemId ) const { if ( GetItemTypeEnum( itemId ) != ItemType_Group ) { return NULL; } u32 index = Util::GetItemIndex( itemId ); const Util::ReferenceTable& table = GetGroupInfoReferenceTable(); if ( index >= table.count ) { return NULL; } return reinterpret_cast( table.GetReferedItem( index ) ); } const SoundArchiveFile::WaveArchiveInfo* SoundArchiveFile::InfoBlockBody::GetWaveArchiveInfo( SoundArchive::ItemId itemId ) const { if ( GetItemTypeEnum( itemId ) != ItemType_WaveArchive ) { return NULL; } u32 index = Util::GetItemIndex( itemId ); const Util::ReferenceTable& table = GetWaveArchiveInfoReferenceTable(); if ( index >= table.count ) { return NULL; } return reinterpret_cast( table.GetReferedItem( index ) ); } const SoundArchiveFile::FileInfo* SoundArchiveFile::InfoBlockBody::GetFileInfo( SoundArchive::FileId itemId ) const { u32 index = Util::GetItemIndex( itemId ); const Util::ReferenceTable& table = GetFileInfoReferenceTable(); if ( index >= table.count ) { return NULL; } return reinterpret_cast( table.GetReferedItem( index ) ); } SoundArchive::FileId SoundArchiveFile::InfoBlockBody::GetItemFileId( SoundArchive::ItemId id ) const { SoundArchive::FileId fileId = SoundArchive::INVALID_ID; switch ( Util::GetItemType( id ) ) { case ItemType_Sound: { const SoundInfo* info = GetSoundInfo( id ); if ( info != NULL ) { fileId = info->fileId; } } break; case ItemType_Bank: { const BankInfo* info = GetBankInfo( id ); if ( info != NULL ) { fileId = info->fileId; } } break; case ItemType_WaveArchive: { const WaveArchiveInfo* info = GetWaveArchiveInfo( id ); if ( info != NULL ) { fileId = info->fileId; } } break; case ItemType_Group: { const GroupInfo* info = GetGroupInfo( id ); if ( info != NULL ) { fileId = info->fileId; } } break; case ItemType_SoundGroup: // 複数個の FileId を持つことがあるため、別関数を使う必要がある。 break; case ItemType_Player: // ファイル ID は無い break; } return fileId; } SoundArchive::StringId SoundArchiveFile::InfoBlockBody::GetItemStringId( SoundArchive::ItemId id ) const { SoundArchive::FileId stringId = SoundArchive::INVALID_ID; switch ( Util::GetItemType( id ) ) { case ItemType_Sound: { const SoundInfo* info = GetSoundInfo( id ); if ( info != NULL ) { stringId = info->GetStringId(); } } break; case ItemType_Bank: { const BankInfo* info = GetBankInfo( id ); if ( info != NULL ) { stringId = info->GetStringId(); } } break; case ItemType_WaveArchive: { const WaveArchiveInfo* info = GetWaveArchiveInfo( id ); if ( info != NULL ) { stringId = info->GetStringId(); } } break; case ItemType_SoundGroup: { const SoundGroupInfo* info = GetSoundGroupInfo( id ); if ( info != NULL ) { stringId = info->GetStringId(); } } break; case ItemType_Group: { const GroupInfo* info = GetGroupInfo( id ); if ( info != NULL ) { stringId = info->GetStringId(); } } break; case ItemType_Player: { const PlayerInfo* info = GetPlayerInfo( id ); if ( info != NULL ) { stringId = info->GetStringId(); } } break; } return stringId; } const SoundArchiveFile::SoundArchivePlayerInfo* SoundArchiveFile::InfoBlockBody::GetSoundArchivePlayerInfo() const { return reinterpret_cast( ut::AddOffsetToPtr( this, toSoundArchivePlayerInfo.offset ) ); } const Util::ReferenceTable& SoundArchiveFile::InfoBlockBody::GetSoundInfoReferenceTable() const { return *reinterpret_cast( ut::AddOffsetToPtr( this, toSoundInfoReferenceTable.offset ) ); } const Util::ReferenceTable& SoundArchiveFile::InfoBlockBody::GetBankInfoReferenceTable() const { return *reinterpret_cast( ut::AddOffsetToPtr( this, toBankInfoReferenceTable.offset ) ); } const Util::ReferenceTable& SoundArchiveFile::InfoBlockBody::GetPlayerInfoReferenceTable() const { return *reinterpret_cast( ut::AddOffsetToPtr( this, toPlayerInfoReferenceTable.offset ) ); } const Util::ReferenceTable& SoundArchiveFile::InfoBlockBody::GetSoundGroupInfoReferenceTable() const { return *reinterpret_cast( ut::AddOffsetToPtr( this, toSoundGroupInfoReferenceTable.offset ) ); } const Util::ReferenceTable& SoundArchiveFile::InfoBlockBody::GetGroupInfoReferenceTable() const { return *reinterpret_cast( ut::AddOffsetToPtr( this, toGroupInfoReferenceTable.offset ) ); } const Util::ReferenceTable& SoundArchiveFile::InfoBlockBody::GetWaveArchiveInfoReferenceTable() const { return *reinterpret_cast( ut::AddOffsetToPtr( this, toWaveArchiveInfoReferenceTable.offset ) ); } const Util::ReferenceTable& SoundArchiveFile::InfoBlockBody::GetFileInfoReferenceTable() const { return *reinterpret_cast( ut::AddOffsetToPtr( this, toFileInfoReferenceTable.offset ) ); } // // SoundArchiveFile::SoundInfo // SoundArchive::SoundType SoundArchiveFile::SoundInfo::GetSoundType() const { switch ( toDetailSoundInfo.typeId ) { case ElementType_SoundArchiveFile_StreamSoundInfo: return SoundArchive::SOUND_TYPE_STRM; case ElementType_SoundArchiveFile_WaveSoundInfo: return SoundArchive::SOUND_TYPE_WAVE; case ElementType_SoundArchiveFile_SequenceSoundInfo: return SoundArchive::SOUND_TYPE_SEQ; default: return SoundArchive::SOUND_TYPE_INVALID; } } const SoundArchiveFile::StreamSoundInfo& SoundArchiveFile::SoundInfo::GetStreamSoundInfo() const { NW_ASSERT( toDetailSoundInfo.typeId == ElementType_SoundArchiveFile_StreamSoundInfo ); return *reinterpret_cast( ut::AddOffsetToPtr( this, toDetailSoundInfo.offset ) ); } const SoundArchiveFile::WaveSoundInfo& SoundArchiveFile::SoundInfo::GetWaveSoundInfo() const { NW_ASSERT( toDetailSoundInfo.typeId == ElementType_SoundArchiveFile_WaveSoundInfo ); return *reinterpret_cast( ut::AddOffsetToPtr( this, toDetailSoundInfo.offset ) ); } const SoundArchiveFile::SequenceSoundInfo& SoundArchiveFile::SoundInfo::GetSequenceSoundInfo() const { NW_ASSERT( toDetailSoundInfo.typeId == ElementType_SoundArchiveFile_SequenceSoundInfo ); return *reinterpret_cast( ut::AddOffsetToPtr( this, toDetailSoundInfo.offset ) ); } const SoundArchiveFile::Sound3DInfo* SoundArchiveFile::SoundInfo::GetSound3DInfo() const { u32 offset; bool result = optionParameter.GetValue( &offset, SOUND_INFO_OFFSET_TO_3D_PARAM ); if ( result == false ) { return NULL; // 3D パラメータが省かれている (格納されていない) } return reinterpret_cast( ut::AddOffsetToPtr( this, offset ) ); } u32 SoundArchiveFile::SoundInfo::GetStringId() const { u32 value; bool result = optionParameter.GetValue( &value, SOUND_INFO_STRING_ID ); if ( result == false ) { return DEFAULT_STRING_ID; } return value; } PanMode SoundArchiveFile::SoundInfo::GetPanMode() const { u32 value; bool result = optionParameter.GetValue( &value, SOUND_INFO_PAN_PARAM ); if ( result == false ) { return DEFAULT_PAN_MODE; } return static_cast( Util::DevideBy8bit( value, 0 ) ); } PanCurve SoundArchiveFile::SoundInfo::GetPanCurve() const { u32 value; bool result = optionParameter.GetValue( &value, SOUND_INFO_PAN_PARAM ); if ( result == false ) { return DEFAULT_PAN_CURVE; } return static_cast( Util::DevideBy8bit( value, 1 ) ); } u8 SoundArchiveFile::SoundInfo::GetPlayerPriority() const { u32 value; bool result = optionParameter.GetValue( &value, SOUND_INFO_PLAYER_PARAM ); if ( result == false ) { return DEFAULT_PLAYER_PRIORITY; } return Util::DevideBy8bit( value, 0 ); } u8 SoundArchiveFile::SoundInfo::GetActorPlayerId() const { u32 value; bool result = optionParameter.GetValue( &value, SOUND_INFO_PLAYER_PARAM ); if ( result == false ) { return DEFAULT_ACTOR_PLAYER_ID; } return Util::DevideBy8bit( value, 1 ); } u32 SoundArchiveFile::SoundInfo::GetUserParam() const { u32 value; bool result = optionParameter.GetValue( &value, SOUND_INFO_USER_PARAM ); if ( result == false ) { return DEFAULT_USER_PARAM; } return value; } bool SoundArchiveFile::SoundInfo::IsFrontBypass() const { u32 value; bool result = optionParameter.GetValue( &value, SOUND_INFO_OFFSET_TO_CTR_PARAM ); if ( result == false ) { return DEFAULT_IS_FRONT_BYPASS; } return ( value & ( 1 << 0 ) ); } #if 0 u32 SoundArchiveFile::SoundInfo::GetUserExtraParamCount() { u32 value = optionParameter.GetValue( SOUND_INFO_REFERENCE_TO_EXTRA_USER_PARAM_TABLE ); if ( value == 0 ) { return DEFAULT_EXTRA_USER_PARAM_COUNT; } return value; } u32 SoundArchiveFile::SoundInfo::GetUserExtraParam( int index ) { u32 value = optionParameter.GetValue( SOUND_INFO_REFERENCE_TO_EXTRA_USER_PARAM_TABLE ); if ( value == 0 ) { return DEFAULT_USER_PARAM; } // value 先のアドレスに、値が書かれている? } #endif // // SoundArchiveFile::WaveSoundInfo // u8 SoundArchiveFile::WaveSoundInfo::GetChannelPriority() const { u32 value; bool result = optionParameter.GetValue( &value, WAVE_SOUND_INFO_PRIORITY ); if ( result == false ) { return DEFAULT_CHANNEL_PRIORITY; } return Util::DevideBy8bit( value, 0 ); } u8 SoundArchiveFile::WaveSoundInfo::GetIsReleasePriorityFix() const { u32 value; bool result = optionParameter.GetValue( &value, WAVE_SOUND_INFO_PRIORITY ); if ( result == false ) { return DEFAULT_IS_RELEASE_PRIORITY_FIX; } return Util::DevideBy8bit( value, 1 ); } // // SoundArchiveFile::SequenceSoundInfo // const Util::Table& SoundArchiveFile::SequenceSoundInfo::GetBankIdTable() const { return *reinterpret_cast*>( ut::AddOffsetToPtr( this, toBankIdTable.offset ) ); } void SoundArchiveFile::SequenceSoundInfo::GetBankIds( u32* bankIds ) const { const Util::Table& table = GetBankIdTable(); for ( u32 i = 0; i < SoundArchive::SEQ_BANK_MAX; i++ ) { if ( i >= table.count ) { bankIds[ i ] = SoundArchive::INVALID_ID; } else { bankIds[ i ] = table.item[ i ]; } } } u32 SoundArchiveFile::SequenceSoundInfo::GetStartOffset() const { u32 value; bool result = optionParameter.GetValue( &value, SEQ_SOUND_INFO_START_OFFSET ); if ( result == false ) { return DEFAULT_SEQ_START_OFFSET; } return value; } u8 SoundArchiveFile::SequenceSoundInfo::GetChannelPriority() const { u32 value; bool result = optionParameter.GetValue( &value, SEQ_SOUND_INFO_PRIORITY ); if ( result == false ) { return DEFAULT_CHANNEL_PRIORITY; } return Util::DevideBy8bit( value, 0 ); } bool SoundArchiveFile::SequenceSoundInfo::IsReleasePriorityFix() const { u32 value; bool result = optionParameter.GetValue( &value, SEQ_SOUND_INFO_PRIORITY ); if ( result == false ) { return DEFAULT_CHANNEL_PRIORITY; } if ( Util::DevideBy8bit( value, 1 ) > 0 ) return true; return false; } // // SoundArchiveFile::BankInfo // u32 SoundArchiveFile::BankInfo::GetStringId() const { u32 value; bool result = optionParameter.GetValue( &value, BANK_INFO_STRING_ID ); if ( result == false ) { return DEFAULT_STRING_ID; } return value; } // // SoundArchiveFile::PlayerInfo // u32 SoundArchiveFile::PlayerInfo::GetStringId() const { u32 value; bool result = optionParameter.GetValue( &value, PLAYER_INFO_STRING_ID ); if ( result == false ) { return DEFAULT_STRING_ID; } return value; } u32 SoundArchiveFile::PlayerInfo::GetPlayerHeapSize() const { u32 value; bool result = optionParameter.GetValue( &value, PLAYER_INFO_HEAP_SIZE ); if ( result == false ) { return DEFAULT_PLAYER_HEAP_SIZE; } return value; } // // SoundArchiveFile::SoundGroupInfo // u32 SoundArchiveFile::SoundGroupInfo::GetStringId() const { u32 value; bool result = optionParameter.GetValue( &value, SOUND_GROUP_INFO_STRING_ID ); if ( result == false ) { return DEFAULT_STRING_ID; } return value; } // // SoundArchiveFile::GroupInfo // u32 SoundArchiveFile::GroupInfo::GetStringId() const { u32 value; bool result = optionParameter.GetValue( &value, GROUP_INFO_STRING_ID ); if ( result == false ) { return DEFAULT_STRING_ID; } return value; } // // SoundArchiveFile::WaveArchiveInfo // u32 SoundArchiveFile::WaveArchiveInfo::GetStringId() const { u32 value; bool result = optionParameter.GetValue( &value, WAVE_ARCHIVE_INFO_STRING_ID ); if ( result == false ) { return DEFAULT_STRING_ID; } return value; } u32 SoundArchiveFile::WaveArchiveInfo::GetWaveCount() const { u32 value; bool result = optionParameter.GetValue( &value, WAVE_ARCHIVE_INFO_WAVE_COUNT ); if ( result == false ) { return DEFAULT_WARC_WAVE_COUNT; } return value; } // // SoundArchiveFile::FileInfo // SoundArchiveFile::FileLocationType SoundArchiveFile::FileInfo::GetFileLocationType() const { switch ( toFileLocation.typeId ) { case ElementType_SoundArchiveFile_InternalFileInfo: return FILE_LOCATION_TYPE_INTERNAL; case ElementType_SoundArchiveFile_ExternalFileInfo: return FILE_LOCATION_TYPE_EXTERNAL; case 0: return FILE_LOCATION_TYPE_NONE; default: NW_ASSERTMSG( false, "invalid file location type"); return FILE_LOCATION_TYPE_NONE; } } const SoundArchiveFile::InternalFileInfo* SoundArchiveFile::FileInfo::GetInternalFileInfo() const { if ( GetFileLocationType() != FILE_LOCATION_TYPE_INTERNAL ) { return NULL; } return reinterpret_cast( ut::AddOffsetToPtr( this, toFileLocation.offset ) ); } const SoundArchiveFile::ExternalFileInfo* SoundArchiveFile::FileInfo::GetExternalFileInfo() const { if ( GetFileLocationType() != FILE_LOCATION_TYPE_EXTERNAL ) { return NULL; } return reinterpret_cast( ut::AddOffsetToPtr( this, toFileLocation.offset ) ); } #if 0 const void* SoundArchiveFile::FileInfo::GetFileAddress( const void* dataBlockBodyAddress ) const { // TODO: toFileImage.typeId には、 // (1) FILE ブロックに入っていることを示す ID ((* この関数で扱う *)) // (2) 外部ファイルパスを示す ID [サウンドアーカイブファイル外] // (3) 「グループ埋め込みファイル」テーブルを示す ID がありえる。 // // 1-3 のうち、1/2/3 とも同時に存在しうる。 // ([1,3] と [2] は、同時に存在しない気もする。同時に存在する意味がないから。 ) // // TODO としては、typeId で 1 でないなら、この関数は NULL を返す必要がある return reinterpret_cast( ut::AddOffsetToPtr( dataBlockBodyAddress, toFileImage.offset ) ); } #endif } // namespace nw::snd::internal } // namespace nw::snd } // namespace nw