1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     snd_WaveArchiveFileReader.cpp
4 
5   Copyright (C)2009-2011 Nintendo/HAL Laboratory, Inc.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain proprietary
8   information of Nintendo and/or its licensed developers and are protected by
9   national and international copyright laws. They may not be disclosed to third
10   parties or copied or duplicated in any form, in whole or in part, without the
11   prior written consent of Nintendo.
12 
13   The content herein is highly confidential and should be handled accordingly.
14 
15   $Revision: 31311 $
16  *---------------------------------------------------------------------------*/
17 
18 #include "precompiled.h"
19 #include <nw/snd/snd_WaveArchiveFileReader.h>
20 
21 // #define NW_SND_DEBUG_PRINT_ENABLE
22 
23 namespace nw {
24 namespace snd {
25 namespace internal {
26 
27 namespace
28 {
29 
30 const u32 SIGNATURE_INFO_BLOCK = NW_UT_MAKE_SIGWORD( 'I', 'N', 'F', 'O' );
31 const u32 SIGNATURE_FILE_BLOCK = NW_UT_MAKE_SIGWORD( 'F', 'I', 'L', 'E' );
32 
33 const u32 SUPPORTED_FILE_VERSION = 0x01000000;  // ライブラリがサポートする最低バージョン
34 const u32 CURRENT_FILE_VERSION   = 0x01000000;  // ライブラリがサポートする最新バージョン
35 
IsValidFileHeader(const void * waveArchiveData)36 bool IsValidFileHeader( const void* waveArchiveData )
37 {
38     const ut::BinaryFileHeader& header =
39         *reinterpret_cast<const ut::BinaryFileHeader*>( waveArchiveData );
40 
41     // シグニチャ確認
42     NW_ASSERTMSG( header.signature == WaveArchiveFileReader::SIGNATURE_FILE,
43             "invalid file signature." );
44     if ( header.signature != WaveArchiveFileReader::SIGNATURE_FILE )
45     {
46         return false;
47     }
48 
49     // バージョン確認
50     NW_ASSERTMSG(
51             header.version >= SUPPORTED_FILE_VERSION,
52             "wave archive file is not supported version.\n"
53             "please reconvert file using new version tools.\n"
54             "(SUPPORTED_FILE_VERSION:0x%08x >= your version:0x%08x)\n",
55             SUPPORTED_FILE_VERSION, header.version
56     );
57     if ( header.version < SUPPORTED_FILE_VERSION )
58     {
59         return false;
60     }
61     NW_ASSERTMSG(
62             header.version <= CURRENT_FILE_VERSION,
63             "wave archive file is not supported version.\n"
64             "please reconvert file using new version tools.\n"
65             "(CURRENT_FILE_VERSION:0x%08x <= your version:0x%08x)\n",
66             CURRENT_FILE_VERSION, header.version
67     );
68     if ( header.version > CURRENT_FILE_VERSION )
69     {
70         return false;
71     }
72     return true;
73 }
74 
75 } // anonymous namespace
76 
77 const u32 WaveArchiveFileReader::SIGNATURE_WARC_TABLE = NW_UT_MAKE_SIGWORD( 'C', 'W', 'A', 'T' );
78 
WaveArchiveFileReader(const void * pWaveArchiveFile,bool isIndividual)79 WaveArchiveFileReader::WaveArchiveFileReader(
80         const void* pWaveArchiveFile,
81         bool isIndividual )
82 : m_pHeader( NULL ),
83   m_pInfoBlockBody( NULL ),
84   m_pLoadTable( NULL )
85 {
86     NW_NULL_ASSERT( pWaveArchiveFile );
87 
88     if ( ! IsValidFileHeader( pWaveArchiveFile ) ) return;
89 
90     m_pHeader =
91         reinterpret_cast<const WaveArchiveFile::FileHeader*>( pWaveArchiveFile );
92     m_pInfoBlockBody = &m_pHeader->GetInfoBlock()->body;
93 
94     if ( isIndividual )
95     {
96         m_pLoadTable = reinterpret_cast<IndividualLoadTable*>(
97                 ut::AddOffsetToPtr(
98                     const_cast<void*>( pWaveArchiveFile ),
99                     m_pHeader->GetFileBlockOffset() +
100                     sizeof( SIGNATURE_WARC_TABLE ) ) );
101             // INFO ブロックと FILE ブロックの間に、
102             // アライメントがはさまっているので、その分ムダになるが、
103             // 見通しのよさを優先する。
104     }
105 }
106 
InitializeFileTable()107 void WaveArchiveFileReader::InitializeFileTable()
108 {
109     NW_NULL_ASSERT( m_pInfoBlockBody );
110 
111     // ロード管理用ファイルテーブルの初期化
112     for ( u32 i = 0; i < GetWaveFileCount(); i++ )
113     {
114         m_pLoadTable->waveFile[ i ] = NULL;
115     }
116 }
117 
GetWaveFileCount() const118 u32 WaveArchiveFileReader::GetWaveFileCount() const
119 {
120     NW_NULL_ASSERT( m_pInfoBlockBody );
121     return m_pInfoBlockBody->GetWaveFileCount();
122 }
123 
GetWaveFile(u32 waveIndex) const124 const void* WaveArchiveFileReader::GetWaveFile( u32 waveIndex ) const
125 {
126     NW_NULL_ASSERT( m_pInfoBlockBody );
127     if ( waveIndex >= GetWaveFileCount() ) return NULL;
128 
129     if ( m_pLoadTable != NULL )
130     {
131         return GetWaveFileForIndividual( waveIndex );
132     }
133     return GetWaveFileForWhole( waveIndex );
134 }
135 
GetWaveFileSize(u32 waveIndex) const136 u32 WaveArchiveFileReader::GetWaveFileSize( u32 waveIndex ) const
137 {
138     NW_NULL_ASSERT( m_pInfoBlockBody );
139     return m_pInfoBlockBody->GetSize( waveIndex );
140 }
141 
GetWaveFileOffsetFromFileHead(u32 waveIndex) const142 u32 WaveArchiveFileReader::GetWaveFileOffsetFromFileHead( u32 waveIndex ) const
143 {
144     NW_NULL_ASSERT( m_pInfoBlockBody );
145     u32 result =
146         + m_pHeader->GetFileBlockOffset()
147         + offsetof( WaveArchiveFile::FileBlock, body )
148         + m_pInfoBlockBody->GetOffsetFromFileBlockBody( waveIndex );
149     return result;
150 }
151 
152 const void*
SetWaveFile(u32 waveIndex,const void * pWaveFile)153 WaveArchiveFileReader::SetWaveFile(
154         u32 waveIndex, const void* pWaveFile )
155 {
156     if ( m_pLoadTable == NULL ) return NULL;
157     if ( waveIndex >= GetWaveFileCount() ) return NULL;
158 
159     const void* preAddress = GetWaveFileForIndividual( waveIndex );
160     m_pLoadTable->waveFile[ waveIndex ] = pWaveFile;
161 
162 #ifdef NW_SND_DEBUG_PRINT_ENABLE
163     // デバッグ
164     for ( u32 i = 0; i < GetWaveFileCount(); i++ )
165     {
166         NN_LOG("  [%3d] %p\n", i, m_pLoadTable->waveFile[i] );
167     }
168 #endif /* NW_SND_DEBUG_PRINT_ENABLE */
169 
170     return preAddress;
171 }
172 
HasIndividualLoadTable() const173 bool WaveArchiveFileReader::HasIndividualLoadTable() const
174 {
175     const u32* signature = reinterpret_cast<const u32*>(
176             ut::AddOffsetToPtr( m_pHeader, m_pHeader->GetFileBlockOffset() ) );
177     if ( *signature == SIGNATURE_WARC_TABLE )
178     {
179         return true;
180     }
181     return false;
182 }
183 
184 } // namespace nw::snd::internal
185 } // namespace nw::snd
186 } // namespace nw
187