1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: snd_SoundArchive.cpp
4
5 Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Revision: 13420 $
14 *---------------------------------------------------------------------------*/
15
16 #include "precompiled.h"
17
18 #include <nw/snd/snd_SoundArchive.h>
19
20 #include <cstring> // strlen, etc...
21 #include <nw/assert.h>
22 #include <nw/io/io_FileStream.h>
23 #include <nw/snd/snd_SoundArchiveFileReader.h>
24
25 namespace nw {
26 namespace snd {
27
28 /* ========================================================================
29 static variables
30 ======================================================================== */
31
32 namespace {
33 const char sNullString = '\0';
34 } // namespace
35
36 /*---------------------------------------------------------------------------*
37 Name: SoundArchive
38
39 Description: コンストラクタ
40
41 Arguments: None.
42
43 Returns: None.
44 *---------------------------------------------------------------------------*/
SoundArchive()45 SoundArchive::SoundArchive()
46 : m_pFileReader( NULL )
47 {
48 m_ExtFileRoot[0] = '/';
49 m_ExtFileRoot[1] = '\0';
50 }
51
52 /*---------------------------------------------------------------------------*
53 Name: ~SoundArchive
54
55 Description: デストラクタ
56
57 Arguments: None.
58
59 Returns: None.
60 *---------------------------------------------------------------------------*/
~SoundArchive()61 SoundArchive::~SoundArchive()
62 {
63 }
64
IsAvailable() const65 bool SoundArchive::IsAvailable() const
66 {
67 if ( m_pFileReader == NULL ) return false;
68 return true;
69 }
70
Initialize(internal::SoundArchiveFileReader * fileReader)71 void SoundArchive::Initialize( internal::SoundArchiveFileReader* fileReader )
72 {
73 NW_NULL_ASSERT( fileReader );
74 m_pFileReader = fileReader;
75 m_FileBlockOffset = m_pFileReader->GetFileBlockOffset();
76 }
77
78 /*---------------------------------------------------------------------------*
79 Name: Shutdown
80
81 Description: シャットダウン
82
83 Arguments: None.
84
85 Returns: None.
86 *---------------------------------------------------------------------------*/
Finalize()87 void SoundArchive::Finalize()
88 {
89 m_pFileReader = NULL;
90 m_ExtFileRoot[0] = '/';
91 m_ExtFileRoot[1] = '\0';
92 }
93
GetSoundCount() const94 u32 SoundArchive::GetSoundCount() const
95 {
96 return m_pFileReader->GetSoundCount();
97 }
GetPlayerCount() const98 u32 SoundArchive::GetPlayerCount() const
99 {
100 return m_pFileReader->GetPlayerCount();
101 }
GetSoundGroupCount() const102 u32 SoundArchive::GetSoundGroupCount() const
103 {
104 return m_pFileReader->GetSoundGroupCount();
105 }
GetGroupCount() const106 u32 SoundArchive::GetGroupCount() const
107 {
108 return m_pFileReader->GetGroupCount();
109 }
GetBankCount() const110 u32 SoundArchive::GetBankCount() const
111 {
112 return m_pFileReader->GetBankCount();
113 }
GetWaveArchiveCount() const114 u32 SoundArchive::GetWaveArchiveCount() const
115 {
116 return m_pFileReader->GetWaveArchiveCount();
117 }
detail_GetFileCount() const118 u32 SoundArchive::detail_GetFileCount() const
119 {
120 return m_pFileReader->GetFileCount();
121 }
122
GetItemLabel(ItemId id) const123 const char* SoundArchive::GetItemLabel( ItemId id ) const
124 {
125 return m_pFileReader->GetItemLabel( id );
126 }
GetItemId(const char * pStr) const127 SoundArchive::ItemId SoundArchive::GetItemId( const char* pStr ) const
128 {
129 return m_pFileReader->GetItemId( pStr );
130 }
GetItemFileId(ItemId id) const131 SoundArchive::FileId SoundArchive::GetItemFileId( ItemId id ) const
132 {
133 return m_pFileReader->GetItemFileId( id );
134 }
135
GetSoundUserParam(ItemId soundId) const136 u32 SoundArchive::GetSoundUserParam( ItemId soundId ) const
137 {
138 return m_pFileReader->GetSoundUserParam( soundId );
139 }
140
GetSoundType(ItemId soundId) const141 SoundArchive::SoundType SoundArchive::GetSoundType( ItemId soundId ) const
142 {
143 return m_pFileReader->GetSoundType( soundId );
144 }
ReadSoundInfo(ItemId soundId,SoundInfo * info) const145 bool SoundArchive::ReadSoundInfo( ItemId soundId, SoundInfo* info ) const
146 {
147 return m_pFileReader->ReadSoundInfo( soundId, info );
148 }
ReadSequenceSoundInfo(ItemId soundId,SequenceSoundInfo * info) const149 bool SoundArchive::ReadSequenceSoundInfo( ItemId soundId, SequenceSoundInfo* info ) const
150 {
151 return m_pFileReader->ReadSequenceSoundInfo( soundId, info );
152 }
detail_ReadStreamSoundInfo(ItemId soundId,StreamSoundInfo * info) const153 bool SoundArchive::detail_ReadStreamSoundInfo( ItemId soundId, StreamSoundInfo* info ) const
154 {
155 return m_pFileReader->ReadStreamSoundInfo( soundId, info );
156 }
detail_ReadWaveSoundInfo(ItemId soundId,WaveSoundInfo * info) const157 bool SoundArchive::detail_ReadWaveSoundInfo( ItemId soundId, WaveSoundInfo* info ) const
158 {
159 return m_pFileReader->ReadWaveSoundInfo( soundId, info );
160 }
ReadPlayerInfo(ItemId playerId,PlayerInfo * info) const161 bool SoundArchive::ReadPlayerInfo( ItemId playerId, PlayerInfo* info ) const
162 {
163 return m_pFileReader->ReadPlayerInfo( playerId, info );
164 }
ReadSoundArchivePlayerInfo(SoundArchivePlayerInfo * info) const165 bool SoundArchive::ReadSoundArchivePlayerInfo( SoundArchivePlayerInfo* info ) const
166 {
167 return m_pFileReader->ReadSoundArchivePlayerInfo( info );
168 }
ReadSound3DInfo(ItemId soundId,Sound3DInfo * info) const169 bool SoundArchive::ReadSound3DInfo( ItemId soundId, Sound3DInfo* info ) const
170 {
171 return m_pFileReader->ReadSound3DInfo( soundId, info );
172 }
ReadBankInfo(ItemId bankId,BankInfo * info) const173 bool SoundArchive::ReadBankInfo( ItemId bankId, BankInfo* info ) const
174 {
175 return m_pFileReader->ReadBankInfo( bankId, info );
176 }
ReadWaveArchiveInfo(ItemId warcId,WaveArchiveInfo * info) const177 bool SoundArchive::ReadWaveArchiveInfo( ItemId warcId, WaveArchiveInfo* info ) const
178 {
179 return m_pFileReader->ReadWaveArchiveInfo( warcId, info );
180 }
detail_ReadSoundGroupInfo(ItemId soundGroupId,SoundGroupInfo * info) const181 bool SoundArchive::detail_ReadSoundGroupInfo( ItemId soundGroupId, SoundGroupInfo* info ) const
182 {
183 return m_pFileReader->ReadSoundGroupInfo( soundGroupId, info );
184 }
detail_ReadGroupInfo(ItemId groupId,GroupInfo * info) const185 bool SoundArchive::detail_ReadGroupInfo( ItemId groupId, GroupInfo* info ) const
186 {
187 return m_pFileReader->ReadGroupInfo( groupId, info );
188 }
189 #if 0
190 bool SoundArchive::detail_ReadGroupItemInfo( GroupId groupId, unsigned long index, GroupItemInfo* info ) const
191 {
192 return m_pFileReader->ReadGroupItemInfo( groupId, index, info );
193 }
194 #endif
detail_ReadFileInfo(FileId fileId,FileInfo * info) const195 bool SoundArchive::detail_ReadFileInfo( FileId fileId, FileInfo* info ) const
196 {
197 return m_pFileReader->ReadFileInfo( fileId, info );
198 }
199 #if 0
200 bool SoundArchive::detail_ReadFilePos( FileId fileId, unsigned long index, FilePos* info ) const
201 {
202 return m_pFileReader->ReadFilePos( fileId, index, info );
203 }
204 #endif
205
206 const internal::Util::Table<u32>*
detail_GetWaveArchiveIdTable(ItemId id) const207 SoundArchive::detail_GetWaveArchiveIdTable( ItemId id ) const
208 {
209 // id にはウェーブサウンドの ID か、バンクの ID しか入らない
210 return m_pFileReader->GetWaveArchiveIdTable( id );
211 }
212
detail_OpenFileStream(FileId fileId,void * buffer,int size)213 io::FileStream* SoundArchive::detail_OpenFileStream(
214 FileId fileId, void* buffer, int size )
215 {
216 // ファイル情報取得
217 FileInfo fileInfo;
218 if ( ! detail_ReadFileInfo( fileId, &fileInfo ) )
219 {
220 return NULL;
221 }
222
223 // 外部参照ファイル
224 if ( fileInfo.externalFilePath != NULL )
225 {
226 io::FileStream* stream =
227 OpenExtStreamImpl( buffer, size, fileInfo.externalFilePath, 0, 0 );
228 return stream;
229 }
230
231 // サウンドアーカイブ内ファイル
232 io::FileStream* stream = OpenStream(
233 buffer,
234 size,
235 fileInfo.offsetFromFileBlockHead + m_FileBlockOffset,
236 fileInfo.fileSize
237 );
238 return stream;
239 }
240
241 #if 0
242 io::FileStream* SoundArchive::detail_OpenFileWaveDataStream( FileId fileId, void* buffer, int size ) const
243 {
244 // ファイル情報取得
245 FileInfo fileInfo;
246 if ( ! detail_ReadFileInfo( fileId, &fileInfo ) )
247 {
248 return NULL;
249 }
250
251 // ファイル位置情報取得
252 FilePos filePos;
253 if ( ! detail_ReadFilePos( fileId, 0, &filePos ) )
254 {
255 return NULL;
256 }
257
258 // グループ情報取得
259 GroupInfo groupInfo;
260 if ( ! detail_ReadGroupInfo( filePos.groupId, &groupInfo ) )
261 {
262 return NULL;
263 }
264 GroupItemInfo itemInfo;
265 if ( ! detail_ReadGroupItemInfo( filePos.groupId, filePos.index, &itemInfo ) )
266 {
267 return NULL;
268 }
269
270 const u32 itemOffset = groupInfo.waveDataOffset + itemInfo.waveDataOffset;
271 const u32 itemSize = itemInfo.waveDataSize;
272
273 if ( groupInfo.externalFilePath != NULL )
274 {
275 // 外部参照グループ
276 io::FileStream* stream = OpenExtStreamImpl( buffer, size, groupInfo.externalFilePath, itemOffset, itemSize );
277 return stream;
278 }
279
280 io::FileStream* stream = OpenStream( buffer, size, itemOffset, itemSize );
281 return stream;
282 }
283
284 io::FileStream* SoundArchive::detail_OpenGroupStream( GroupId groupId, void* buffer, int size ) const
285 {
286 GroupInfo groupInfo;
287 if ( ! detail_ReadGroupInfo( groupId, &groupInfo ) ) return NULL;
288
289 if ( groupInfo.externalFilePath != NULL )
290 {
291 io::FileStream* stream = OpenExtStreamImpl( buffer, size, groupInfo.externalFilePath, groupInfo.offset, groupInfo.size );
292 return stream;
293 }
294
295 io::FileStream* stream = OpenStream( buffer, size, groupInfo.offset, groupInfo.size );
296 return stream;
297 }
298
299 io::FileStream* SoundArchive::detail_OpenGroupWaveDataStream( GroupId groupId, void* buffer, int size ) const
300 {
301 GroupInfo groupInfo;
302 if ( ! detail_ReadGroupInfo( groupId, &groupInfo ) ) return NULL;
303
304 if ( groupInfo.externalFilePath != NULL )
305 {
306 io::FileStream* stream = OpenExtStreamImpl( buffer, size, groupInfo.externalFilePath, groupInfo.waveDataOffset, groupInfo.waveDataSize );
307 return stream;
308 }
309
310 io::FileStream* stream = OpenStream( buffer, size, groupInfo.waveDataOffset, groupInfo.waveDataSize );
311 return stream;
312 }
313 #endif
314
OpenExtStreamImpl(void * buffer,int size,const char * externalFilePath,u32 begin,u32 length) const315 io::FileStream* SoundArchive::OpenExtStreamImpl(
316 void* buffer,
317 int size,
318 const char* externalFilePath,
319 // const wchar_t* externalFilePath,
320 u32 begin,
321 u32 length
322 ) const
323 {
324 const char* fullPath;
325 char pathBuffer[ FILE_PATH_MAX ];
326
327 if ( externalFilePath[0] == '/' )
328 {
329 fullPath = externalFilePath;
330 }
331 else
332 {
333 std::size_t fileLen = std::strlen( externalFilePath );
334 std::size_t dirLen = std::strlen( m_ExtFileRoot );
335 if ( fileLen + dirLen >= sizeof( pathBuffer ) / sizeof( pathBuffer[0] ) )
336 {
337 NW_WARNING( false, "Too long file path \"%s/%s\"",
338 m_ExtFileRoot, externalFilePath );
339 return NULL;
340 }
341 ut::strncpy( pathBuffer, FILE_PATH_MAX, m_ExtFileRoot, dirLen+1 );
342 ut::strncat( pathBuffer, FILE_PATH_MAX, externalFilePath, fileLen+1 );
343 fullPath = pathBuffer;
344 }
345
346 return OpenExtStream( buffer, size, fullPath, begin, length );
347 }
348
SetExternalFileRoot(const char * extFileRoot)349 void SoundArchive::SetExternalFileRoot( const char* extFileRoot )
350 {
351 std::size_t len = std::strlen( extFileRoot );
352 std::size_t nullPos = len;
353
354 ut::strncpy( m_ExtFileRoot, FILE_PATH_MAX, extFileRoot, len );
355
356 if ( extFileRoot[ len-1 ] != '/' )
357 {
358 m_ExtFileRoot[ len ] = '/';
359 nullPos++;
360 }
361
362 NW_ASSERT( nullPos < FILE_PATH_MAX );
363 m_ExtFileRoot[ nullPos ] = '\0';
364 }
365
366
367 } // namespace nw::snd
368 } // namespace nw
369
370