1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: snd_SoundArchive.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
20 #include <nw/snd/snd_SoundArchive.h>
21
22 #include <cstring> // strlen, etc...
23 #include <nw/assert.h>
24 #include <nw/io/io_FileStream.h>
25 #include <nw/snd/snd_SoundArchiveFileReader.h>
26
27 namespace nw {
28 namespace snd {
29
30 /* ========================================================================
31 static variables
32 ======================================================================== */
33
34 namespace {
35 const char sNullString = '\0';
36 } // namespace
37
38 /*---------------------------------------------------------------------------*
39 Name: SoundArchive
40
41 Description: コンストラクタ
42
43 Arguments: None.
44
45 Returns: None.
46 *---------------------------------------------------------------------------*/
SoundArchive()47 SoundArchive::SoundArchive()
48 : m_pFileReader( NULL )
49 {
50 m_ExtFileRoot[0] = '/';
51 m_ExtFileRoot[1] = '\0';
52 }
53
54 /*---------------------------------------------------------------------------*
55 Name: ~SoundArchive
56
57 Description: デストラクタ
58
59 Arguments: None.
60
61 Returns: None.
62 *---------------------------------------------------------------------------*/
~SoundArchive()63 SoundArchive::~SoundArchive()
64 {
65 }
66
IsAvailable() const67 bool SoundArchive::IsAvailable() const
68 {
69 if ( m_pFileReader == NULL ) return false;
70 return true;
71 }
72
Initialize(internal::SoundArchiveFileReader * fileReader)73 void SoundArchive::Initialize( internal::SoundArchiveFileReader* fileReader )
74 {
75 NW_NULL_ASSERT( fileReader );
76 m_pFileReader = fileReader;
77 m_FileBlockOffset = m_pFileReader->GetFileBlockOffset();
78 }
79
80 /*---------------------------------------------------------------------------*
81 Name: Shutdown
82
83 Description: シャットダウン
84
85 Arguments: None.
86
87 Returns: None.
88 *---------------------------------------------------------------------------*/
Finalize()89 void SoundArchive::Finalize()
90 {
91 m_pFileReader = NULL;
92 m_ExtFileRoot[0] = '/';
93 m_ExtFileRoot[1] = '\0';
94 }
95
GetSoundCount() const96 u32 SoundArchive::GetSoundCount() const
97 {
98 return m_pFileReader->GetSoundCount();
99 }
GetPlayerCount() const100 u32 SoundArchive::GetPlayerCount() const
101 {
102 return m_pFileReader->GetPlayerCount();
103 }
GetSoundGroupCount() const104 u32 SoundArchive::GetSoundGroupCount() const
105 {
106 return m_pFileReader->GetSoundGroupCount();
107 }
GetGroupCount() const108 u32 SoundArchive::GetGroupCount() const
109 {
110 return m_pFileReader->GetGroupCount();
111 }
GetBankCount() const112 u32 SoundArchive::GetBankCount() const
113 {
114 return m_pFileReader->GetBankCount();
115 }
GetWaveArchiveCount() const116 u32 SoundArchive::GetWaveArchiveCount() const
117 {
118 return m_pFileReader->GetWaveArchiveCount();
119 }
detail_GetFileCount() const120 u32 SoundArchive::detail_GetFileCount() const
121 {
122 return m_pFileReader->GetFileCount();
123 }
124
GetItemLabel(ItemId id) const125 const char* SoundArchive::GetItemLabel( ItemId id ) const
126 {
127 return m_pFileReader->GetItemLabel( id );
128 }
GetItemId(const char * pStr) const129 SoundArchive::ItemId SoundArchive::GetItemId( const char* pStr ) const
130 {
131 return m_pFileReader->GetItemId( pStr );
132 }
GetItemFileId(ItemId id) const133 SoundArchive::FileId SoundArchive::GetItemFileId( ItemId id ) const
134 {
135 return m_pFileReader->GetItemFileId( id );
136 }
137
GetSoundUserParam(ItemId soundId) const138 u32 SoundArchive::GetSoundUserParam( ItemId soundId ) const
139 {
140 return m_pFileReader->GetSoundUserParam( soundId );
141 }
142
GetSoundType(ItemId soundId) const143 SoundArchive::SoundType SoundArchive::GetSoundType( ItemId soundId ) const
144 {
145 return m_pFileReader->GetSoundType( soundId );
146 }
ReadSoundInfo(ItemId soundId,SoundInfo * info) const147 bool SoundArchive::ReadSoundInfo( ItemId soundId, SoundInfo* info ) const
148 {
149 return m_pFileReader->ReadSoundInfo( soundId, info );
150 }
ReadSequenceSoundInfo(ItemId soundId,SequenceSoundInfo * info) const151 bool SoundArchive::ReadSequenceSoundInfo( ItemId soundId, SequenceSoundInfo* info ) const
152 {
153 return m_pFileReader->ReadSequenceSoundInfo( soundId, info );
154 }
detail_ReadStreamSoundInfo(ItemId soundId,StreamSoundInfo * info) const155 bool SoundArchive::detail_ReadStreamSoundInfo( ItemId soundId, StreamSoundInfo* info ) const
156 {
157 return m_pFileReader->ReadStreamSoundInfo( soundId, info );
158 }
detail_ReadWaveSoundInfo(ItemId soundId,WaveSoundInfo * info) const159 bool SoundArchive::detail_ReadWaveSoundInfo( ItemId soundId, WaveSoundInfo* info ) const
160 {
161 return m_pFileReader->ReadWaveSoundInfo( soundId, info );
162 }
ReadPlayerInfo(ItemId playerId,PlayerInfo * info) const163 bool SoundArchive::ReadPlayerInfo( ItemId playerId, PlayerInfo* info ) const
164 {
165 return m_pFileReader->ReadPlayerInfo( playerId, info );
166 }
ReadSoundArchivePlayerInfo(SoundArchivePlayerInfo * info) const167 bool SoundArchive::ReadSoundArchivePlayerInfo( SoundArchivePlayerInfo* info ) const
168 {
169 return m_pFileReader->ReadSoundArchivePlayerInfo( info );
170 }
ReadSound3DInfo(ItemId soundId,Sound3DInfo * info) const171 bool SoundArchive::ReadSound3DInfo( ItemId soundId, Sound3DInfo* info ) const
172 {
173 return m_pFileReader->ReadSound3DInfo( soundId, info );
174 }
ReadBankInfo(ItemId bankId,BankInfo * info) const175 bool SoundArchive::ReadBankInfo( ItemId bankId, BankInfo* info ) const
176 {
177 return m_pFileReader->ReadBankInfo( bankId, info );
178 }
ReadWaveArchiveInfo(ItemId warcId,WaveArchiveInfo * info) const179 bool SoundArchive::ReadWaveArchiveInfo( ItemId warcId, WaveArchiveInfo* info ) const
180 {
181 return m_pFileReader->ReadWaveArchiveInfo( warcId, info );
182 }
detail_ReadSoundGroupInfo(ItemId soundGroupId,SoundGroupInfo * info) const183 bool SoundArchive::detail_ReadSoundGroupInfo( ItemId soundGroupId, SoundGroupInfo* info ) const
184 {
185 return m_pFileReader->ReadSoundGroupInfo( soundGroupId, info );
186 }
detail_ReadGroupInfo(ItemId groupId,GroupInfo * info) const187 bool SoundArchive::detail_ReadGroupInfo( ItemId groupId, GroupInfo* info ) const
188 {
189 return m_pFileReader->ReadGroupInfo( groupId, info );
190 }
191 #if 0
192 bool SoundArchive::detail_ReadGroupItemInfo( GroupId groupId, unsigned long index, GroupItemInfo* info ) const
193 {
194 return m_pFileReader->ReadGroupItemInfo( groupId, index, info );
195 }
196 #endif
detail_ReadFileInfo(FileId fileId,FileInfo * info) const197 bool SoundArchive::detail_ReadFileInfo( FileId fileId, FileInfo* info ) const
198 {
199 return m_pFileReader->ReadFileInfo( fileId, info );
200 }
201 #if 0
202 bool SoundArchive::detail_ReadFilePos( FileId fileId, unsigned long index, FilePos* info ) const
203 {
204 return m_pFileReader->ReadFilePos( fileId, index, info );
205 }
206 #endif
207
208 const internal::Util::Table<u32>*
detail_GetWaveArchiveIdTable(ItemId id) const209 SoundArchive::detail_GetWaveArchiveIdTable( ItemId id ) const
210 {
211 // id にはウェーブサウンドの ID か、バンクの ID しか入らない
212 return m_pFileReader->GetWaveArchiveIdTable( id );
213 }
214
detail_OpenFileStream(FileId fileId,void * buffer,int size)215 io::FileStream* SoundArchive::detail_OpenFileStream(
216 FileId fileId, void* buffer, int size )
217 {
218 // ファイル情報取得
219 FileInfo fileInfo;
220 if ( ! detail_ReadFileInfo( fileId, &fileInfo ) )
221 {
222 return NULL;
223 }
224
225 // 外部参照ファイル
226 if ( fileInfo.externalFilePath != NULL )
227 {
228 io::FileStream* stream =
229 OpenExtStreamImpl( buffer, size, fileInfo.externalFilePath, 0, 0 );
230 return stream;
231 }
232
233 // サウンドアーカイブ内ファイル
234 io::FileStream* stream = OpenStream(
235 buffer,
236 size,
237 fileInfo.offsetFromFileBlockHead + m_FileBlockOffset,
238 fileInfo.fileSize
239 );
240 return stream;
241 }
242
243 #if 0
244 io::FileStream* SoundArchive::detail_OpenFileWaveDataStream( FileId fileId, void* buffer, int size ) const
245 {
246 // ファイル情報取得
247 FileInfo fileInfo;
248 if ( ! detail_ReadFileInfo( fileId, &fileInfo ) )
249 {
250 return NULL;
251 }
252
253 // ファイル位置情報取得
254 FilePos filePos;
255 if ( ! detail_ReadFilePos( fileId, 0, &filePos ) )
256 {
257 return NULL;
258 }
259
260 // グループ情報取得
261 GroupInfo groupInfo;
262 if ( ! detail_ReadGroupInfo( filePos.groupId, &groupInfo ) )
263 {
264 return NULL;
265 }
266 GroupItemInfo itemInfo;
267 if ( ! detail_ReadGroupItemInfo( filePos.groupId, filePos.index, &itemInfo ) )
268 {
269 return NULL;
270 }
271
272 const u32 itemOffset = groupInfo.waveDataOffset + itemInfo.waveDataOffset;
273 const u32 itemSize = itemInfo.waveDataSize;
274
275 if ( groupInfo.externalFilePath != NULL )
276 {
277 // 外部参照グループ
278 io::FileStream* stream = OpenExtStreamImpl( buffer, size, groupInfo.externalFilePath, itemOffset, itemSize );
279 return stream;
280 }
281
282 io::FileStream* stream = OpenStream( buffer, size, itemOffset, itemSize );
283 return stream;
284 }
285
286 io::FileStream* SoundArchive::detail_OpenGroupStream( GroupId groupId, void* buffer, int size ) const
287 {
288 GroupInfo groupInfo;
289 if ( ! detail_ReadGroupInfo( groupId, &groupInfo ) ) return NULL;
290
291 if ( groupInfo.externalFilePath != NULL )
292 {
293 io::FileStream* stream = OpenExtStreamImpl( buffer, size, groupInfo.externalFilePath, groupInfo.offset, groupInfo.size );
294 return stream;
295 }
296
297 io::FileStream* stream = OpenStream( buffer, size, groupInfo.offset, groupInfo.size );
298 return stream;
299 }
300
301 io::FileStream* SoundArchive::detail_OpenGroupWaveDataStream( GroupId groupId, void* buffer, int size ) const
302 {
303 GroupInfo groupInfo;
304 if ( ! detail_ReadGroupInfo( groupId, &groupInfo ) ) return NULL;
305
306 if ( groupInfo.externalFilePath != NULL )
307 {
308 io::FileStream* stream = OpenExtStreamImpl( buffer, size, groupInfo.externalFilePath, groupInfo.waveDataOffset, groupInfo.waveDataSize );
309 return stream;
310 }
311
312 io::FileStream* stream = OpenStream( buffer, size, groupInfo.waveDataOffset, groupInfo.waveDataSize );
313 return stream;
314 }
315 #endif
316
OpenExtStreamImpl(void * buffer,int size,const char * externalFilePath,u32 begin,u32 length) const317 io::FileStream* SoundArchive::OpenExtStreamImpl(
318 void* buffer,
319 int size,
320 const char* externalFilePath,
321 // const wchar_t* externalFilePath,
322 u32 begin,
323 u32 length
324 ) const
325 {
326 const char* fullPath;
327 char pathBuffer[ FILE_PATH_MAX ];
328
329 if ( externalFilePath[0] == '/' )
330 {
331 fullPath = externalFilePath;
332 }
333 else
334 {
335 std::size_t fileLen = std::strlen( externalFilePath );
336 std::size_t dirLen = std::strlen( m_ExtFileRoot );
337 if ( fileLen + dirLen >= sizeof( pathBuffer ) / sizeof( pathBuffer[0] ) )
338 {
339 NW_WARNING( false, "Too long file path \"%s/%s\"",
340 m_ExtFileRoot, externalFilePath );
341 return NULL;
342 }
343 ut::strncpy( pathBuffer, FILE_PATH_MAX, m_ExtFileRoot, dirLen+1 );
344 ut::strncat( pathBuffer, FILE_PATH_MAX, externalFilePath, fileLen+1 );
345 fullPath = pathBuffer;
346 }
347
348 return OpenExtStream( buffer, size, fullPath, begin, length );
349 }
350
SetExternalFileRoot(const char * extFileRoot)351 void SoundArchive::SetExternalFileRoot( const char* extFileRoot )
352 {
353 std::size_t len = std::strlen( extFileRoot );
354 std::size_t nullPos = len;
355
356 ut::strncpy( m_ExtFileRoot, FILE_PATH_MAX, extFileRoot, len );
357
358 if ( extFileRoot[ len-1 ] != '/' )
359 {
360 m_ExtFileRoot[ len ] = '/';
361 nullPos++;
362 }
363
364 NW_ASSERT( nullPos < FILE_PATH_MAX );
365 m_ExtFileRoot[ nullPos ] = '\0';
366 }
367
368
369 } // namespace nw::snd
370 } // namespace nw
371
372