1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: snd_RomSoundArchive.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: 24309 $
14 *---------------------------------------------------------------------------*/
15
16 #include "precompiled.h"
17
18 #include <nw/snd/snd_RomSoundArchive.h>
19 #include <nw/snd/snd_Util.h>
20
21 // #define NW_SND_DEBUG_PRINT_ENABLE
22
23 namespace nw {
24 namespace snd {
25
26 /*---------------------------------------------------------------------------*
27 Name: RomSoundArchive
28
29 Description: コンストラクタ
30
31 Arguments: None.
32
33 Returns: None.
34 *---------------------------------------------------------------------------*/
RomSoundArchive()35 RomSoundArchive::RomSoundArchive()
36 : m_IsOpened( false )
37 {
38 }
39
40 /*---------------------------------------------------------------------------*
41 Name: ~RomSoundArchive
42
43 Description: デストラクタ
44
45 Arguments: None.
46
47 Returns: None.
48 *---------------------------------------------------------------------------*/
~RomSoundArchive()49 RomSoundArchive::~RomSoundArchive()
50 {
51 Close();
52 }
53
Open(const char * path)54 bool RomSoundArchive::Open( const char* path )
55 {
56 #ifdef NW_PLATFORM_CTRWIN
57 // for PC_SDK
58 {
59 bool result = nn::fs::OpenFile( &m_FileInfo, path );
60 if ( result == false )
61 {
62 NW_WARNING( false, "Cannot open file(%s)\n", path );
63 return false;
64 }
65 m_IsOpened = true;
66 }
67 #else
68 // for CTR_SDK
69 {
70 m_FileReader.Initialize( path );
71 m_IsOpened = true;
72 }
73 #endif
74
75 {
76 bool result = LoadFileHeader();
77 if ( result == false )
78 {
79 NW_WARNING( false, "Cannot load header\n" );
80 return false;
81 }
82 }
83
84 std::size_t len = std::strlen( path );
85 for ( int i = static_cast<int>( len ) - 1; i >= 0; i-- )
86 {
87 const char ch = path[ i ] ;
88 if ( ch == '/' || ch == '\\' )
89 {
90 char dirBuffer[ FILE_PATH_MAX ];
91 NW_ASSERT( i < FILE_PATH_MAX );
92 if ( i >= FILE_PATH_MAX )
93 {
94 return false;
95 }
96
97 ut::strncpy( dirBuffer, FILE_PATH_MAX, path, static_cast<u32>( i ) );
98 dirBuffer[ i ] = '\0';
99
100 SetExternalFileRoot( dirBuffer );
101 break;
102 }
103 }
104
105 return true;
106 }
107 #if 0
108 bool RomSoundArchive::Open( const wchar_t* path )
109 {
110 {
111 m_FileReader.Initialize( path );
112 m_IsOpened = true;
113 }
114
115 {
116 bool result = LoadFileHeader();
117 if ( result == false )
118 {
119 NW_WARNING( false, "Cannot load header\n" );
120 return false;
121 }
122 }
123
124 return true;
125 }
126 #endif
127
128 /*---------------------------------------------------------------------------*
129 Name: Close
130
131 Description: サウンドアーカイブを閉じる
132
133 Arguments: None.
134
135 Returns: None.
136 *---------------------------------------------------------------------------*/
Close()137 void RomSoundArchive::Close()
138 {
139 if ( m_IsOpened )
140 {
141 #ifdef NW_PLATFORM_CTRWIN
142 nn::fs::CloseFile( &m_FileInfo );
143 #else
144 m_FileReader.Finalize();
145 #endif
146 m_ArchiveReader.Finalize();
147 m_IsOpened = false;
148 }
149
150 Finalize();
151 }
152
153 io::FileStream*
OpenStream(void * buffer,int size,u32 begin,u32 length)154 RomSoundArchive::OpenStream( void* buffer, int size, u32 begin, u32 length )
155 {
156 #ifdef NW_PLATFORM_CTRWIN
157 if ( ! m_IsOpened ) return NULL;
158 if ( size < sizeof( RomFileStream ) ) return NULL;
159 RomFileStream* stream = new( buffer ) RomFileStream( &m_FileInfo, begin, length );
160 return stream;
161 #else
162 if ( ! m_IsOpened ) return NULL;
163 if ( size < sizeof( RomFileStream ) ) return NULL;
164 RomFileStream* stream = new( buffer ) RomFileStream( &m_FileReader, begin, length );
165 return stream;
166 #endif
167 }
168
169 io::FileStream*
OpenExtStream(void * buffer,int size,const char * extFilePath,u32 begin,u32 length) const170 RomSoundArchive::OpenExtStream(
171 void* buffer,
172 int size,
173 const char* extFilePath,
174 // const wchar_t* extFilePath,
175 u32 begin,
176 u32 length ) const
177 {
178 if ( ! m_IsOpened ) return NULL;
179 if ( size < sizeof( RomFileStream ) ) return NULL;
180
181 RomFileStream* stream = new( buffer ) RomFileStream( extFilePath, begin, length );
182 return stream;
183 }
184
detail_GetRequiredStreamBufferSize() const185 size_t RomSoundArchive::detail_GetRequiredStreamBufferSize() const
186 {
187 return sizeof( RomFileStream );
188 }
189
190 /*---------------------------------------------------------------------------*
191 Name: LoadFileHeader
192
193 Description: サウンドアーカイブファイルのヘッダをロードする
194
195 Arguments: None.
196
197 Returns: 成功したら true 失敗したら false
198 *---------------------------------------------------------------------------*/
LoadFileHeader()199 bool RomSoundArchive::LoadFileHeader()
200 {
201 NW_ASSERT( m_IsOpened );
202
203 const unsigned long headerAlignSize = static_cast<unsigned long>(
204 ut::RoundUp( sizeof(internal::SoundArchiveFile::FileHeader), 32 )
205 );
206 u8 headerArea[ sizeof(internal::SoundArchiveFile::FileHeader) + 32*2 ]; // 前後32バイトずつの余裕を持つ
207 void* file = ut::RoundUp( headerArea, 32 );
208
209 #ifdef NW_PLATFORM_CTRWIN
210 s32 readSize = nn::fs::ReadFile( &m_FileInfo, file, static_cast<s32>(headerAlignSize) );
211 #else
212 s32 readSize = m_FileReader.Read( file, static_cast<s32>(headerAlignSize) );
213 #endif
214 if ( readSize != headerAlignSize )
215 {
216 NW_WARNING(
217 false,
218 "RomSoundArchive::LoadFileHeader cannot read file.\n"
219 );
220 return false;
221 }
222
223 m_ArchiveReader.Initialize( file );
224 Initialize( &m_ArchiveReader );
225
226 return true;
227 }
228
229 /*---------------------------------------------------------------------------*
230 Name: LoadHeader
231
232 Description: サウンドデータの情報テーブルをロードする
233
234 Arguments: buffer - ロードアドレス
235 size - バッファサイズ
236
237 Returns: 成功したら true 失敗したら false
238 *---------------------------------------------------------------------------*/
LoadHeader(void * buffer,unsigned long size)239 bool RomSoundArchive::LoadHeader( void* buffer, unsigned long size )
240 {
241 NW_ASSERT( m_IsOpened );
242
243 const s32 infoChunkOffset = m_ArchiveReader.GetInfoBlockOffset();
244 const u32 infoChunkSize = m_ArchiveReader.GetInfoBlockSize();
245
246 if ( size < infoChunkSize )
247 {
248 NW_WARNING(
249 size >= infoChunkSize,
250 "RomSoundArchive::LoadHeader buffer size is too small.\n"
251 );
252 return false;
253 }
254
255 //-----------------------------------------------------------------------------
256 // 情報テーブルのロード
257 #ifdef NW_PLATFORM_CTRWIN
258 nn::fs::SeekFile( &m_FileInfo, infoChunkOffset, nn::fs::FS_SEEK_SET );
259 s32 readSize = nn::fs::ReadFile(
260 &m_FileInfo,
261 buffer,
262 static_cast<s32>(infoChunkSize)
263 );
264 #else
265 m_FileReader.Seek( infoChunkOffset, nn::fs::POSITION_BASE_BEGIN );
266 s32 readSize = m_FileReader.Read( buffer, static_cast<s32>(infoChunkSize) );
267 #endif
268 if ( readSize != infoChunkSize )
269 {
270 NW_WARNING(
271 false,
272 "RomSoundArchive::LoadHeader cannot read file.\n"
273 );
274 return false;
275 }
276
277 m_ArchiveReader.SetInfoBlock( buffer /*, infoChunkSize */ );
278
279 #ifdef NW_SND_DEBUG_PRINT_ENABLE
280 // デバッグ出力
281 {
282 // サウンド情報
283 NN_LOG("### Sound INFO(%d)\n", m_ArchiveReader.GetSoundCount() );
284 for ( u32 i = 0; i < m_ArchiveReader.GetSoundCount(); i++ )
285 {
286 // サウンド共通情報
287 SoundArchive::ItemId soundId = GetSoundIdFromIndex( i );
288 SoundArchive::SoundType type = m_ArchiveReader.GetSoundType( soundId );
289 SoundArchive::SoundInfo info;
290 bool ret = m_ArchiveReader.ReadSoundInfo( soundId, &info );
291 NN_LOG("[%08X]?(%d) fileId(%d) playerId(0x%08X) actorId(%d) type(%d)\n",
292 soundId, ret, info.fileId, info.playerId, info.actorPlayerId, type );
293 NN_LOG(" *common* volume(%d) panMode(%d) panCurve (%d)\n",
294 info.volume, info.panMode, info.panCurve );
295
296 // 3D サウンド情報
297 {
298 SoundArchive::Sound3DInfo info3d;
299 if ( ReadSound3DInfo( soundId, &info3d ) )
300 {
301 u32 flag = info3d.flags;
302 NN_LOG(" *3D* ra(%.2f) cv(%d) df(%d) vol(%d) pr(%d) pa(%d) sp(%d) bqf(%d)\n",
303 info3d.decayRatio, info3d.decayCurve, info3d.dopplerFactor,
304 (flag & Sound3DInfo::FLAG_CTRL_VOLUME) > 0,
305 (flag & Sound3DInfo::FLAG_CTRL_PRIORITY) > 0,
306 (flag & Sound3DInfo::FLAG_CTRL_PAN) > 0,
307 (flag & Sound3DInfo::FLAG_CTRL_SPAN) > 0,
308 (flag & Sound3DInfo::FLAG_CTRL_FILTER) > 0 );
309 }
310 else
311 {
312 NN_LOG(" *3D* data not found\n");
313 }
314 }
315
316 // サウンド別個別情報
317 switch ( type )
318 {
319 case SoundArchive::SOUND_TYPE_SEQ:
320 {
321 SoundArchive::SequenceSoundInfo seqInfo;
322 bool retDetail = m_ArchiveReader.ReadSequenceSoundInfo( soundId, &seqInfo );
323 NN_LOG(" *SEQ* ret(%d) ofs(%d) bnk(0x%08X,0x%08X,0x%08X,0x%08X) trk(0x%x) chPrio(%d) rPrioFix(%d)\n",
324 retDetail,
325 seqInfo.startOffset,
326 seqInfo.bankIds[0], seqInfo.bankIds[1],
327 seqInfo.bankIds[2], seqInfo.bankIds[3],
328 seqInfo.allocateTrackFlags,
329 seqInfo.channelPriority, seqInfo.isReleasePriorityFix );
330 }
331 break;
332 case SoundArchive::SOUND_TYPE_STRM:
333 {
334 SoundArchive::StreamSoundInfo strmInfo;
335 bool retDetail = m_ArchiveReader.ReadStreamSoundInfo( soundId, &strmInfo );
336 NN_LOG(" *STRM* ret(%d) trk(%d) channel(%d)\n",
337 retDetail, strmInfo.allocTrackCount, strmInfo.allocChannelCount );
338 }
339 break;
340 case SoundArchive::SOUND_TYPE_WAVE:
341 {
342 SoundArchive::WaveSoundInfo wsdInfo;
343 bool retDetail = m_ArchiveReader.ReadWaveSoundInfo( soundId, &wsdInfo );
344 NN_LOG(" *WSD* ret(%d) index(%d) trk(0x%x) chPrio(%d) rPrioFix(%d)\n",
345 retDetail,
346 wsdInfo.index, wsdInfo.allocTrackCount,
347 wsdInfo.channelPriority, wsdInfo.isReleasePriorityFix );
348 }
349 break;
350 case SoundArchive::SOUND_TYPE_INVALID:
351 {
352 NN_LOG("Invalid SoundType (not STRM/WSD/SEQ)\n");
353 }
354 break;
355 }
356 }
357
358 // バンク情報
359 NN_LOG("### BANK Info(%d)\n", m_ArchiveReader.GetBankCount() );
360 for ( u32 i = 0; i < m_ArchiveReader.GetBankCount(); i++ )
361 {
362 SoundArchive::ItemId bankId = GetBankIdFromIndex( i );
363 SoundArchive::BankInfo info;
364 bool ret = m_ArchiveReader.ReadBankInfo( bankId, &info );
365 NN_LOG("[%08X]?(%d) fileId(%d)\n", bankId, ret, info.fileId );
366 }
367
368 // プレイヤー情報
369 NN_LOG("### PLAYER Info(%d)\n", m_ArchiveReader.GetPlayerCount() );
370 for ( u32 i = 0; i < m_ArchiveReader.GetPlayerCount(); i++ )
371 {
372 SoundArchive::ItemId playerId = GetPlayerIdFromIndex( i );
373 SoundArchive::PlayerInfo info;
374 bool ret = m_ArchiveReader.ReadPlayerInfo( playerId, &info );
375 NN_LOG("[%08X]?(%d) max(%d) heapSize(%d)\n",
376 playerId, ret, info.playableSoundMax, info.playerHeapSize );
377 }
378
379 // サウンドグループ情報
380 NN_LOG("### SOUND-GROUP Info(%d)\n", m_ArchiveReader.GetSoundGroupCount() );
381 for ( u32 i = 0; i < m_ArchiveReader.GetSoundGroupCount(); i++ )
382 {
383 SoundArchive::ItemId soundGroupId = GetSoundGroupIdFromIndex( i );
384 SoundArchive::SoundGroupInfo info;
385 bool ret = m_ArchiveReader.ReadSoundGroupInfo( soundGroupId, &info );
386 NN_LOG("[%08X]?(%d) startId(%08X) end(%08X) fileId:count(%d)",
387 soundGroupId, ret, info.startId, info.endId, info.fileIdTable->count );
388 for ( u32 j = 0; j < info.fileIdTable->count; j++ )
389 {
390 NN_LOG(" [%08X]", info.fileIdTable->item[j]);
391 }
392 NN_LOG("\n");
393 }
394
395 // グループ情報
396 NN_LOG("### GROUP Info(%d)\n", m_ArchiveReader.GetGroupCount() );
397 for ( u32 i = 0; i < m_ArchiveReader.GetGroupCount(); i++ )
398 {
399 SoundArchive::ItemId groupId = GetGroupIdFromIndex( i );
400 SoundArchive::GroupInfo info;
401 bool ret = m_ArchiveReader.ReadGroupInfo( groupId, &info );
402 NN_LOG("[%08X]?(%d) fileId(%d)\n", groupId, ret, info.fileId );
403 }
404
405 // 波形アーカイブ情報
406 NN_LOG("### WAVE-ARCHIVE Info(%d)\n", m_ArchiveReader.GetWaveArchiveCount() );
407 for ( u32 i = 0; i < m_ArchiveReader.GetWaveArchiveCount(); i++ )
408 {
409 SoundArchive::ItemId warcId = GetWaveArchiveIdFromIndex( i );
410 SoundArchive::WaveArchiveInfo info;
411 bool ret = m_ArchiveReader.ReadWaveArchiveInfo( warcId, &info );
412 NN_LOG("[%08X]?(%d) fileId(%d)\n", warcId, ret, info.fileId );
413 }
414
415 // ファイル情報
416 NN_LOG("### FILE Info(%d)\n", m_ArchiveReader.GetFileCount() );
417 for ( u32 i = 0; i < m_ArchiveReader.GetFileCount(); i++ )
418 {
419 SoundArchive::FileInfo info;
420 bool ret = m_ArchiveReader.ReadFileInfo( i, &info );
421 if ( info.externalFilePath != NULL )
422 {
423 NN_LOG("[%4d]?(%d) fileSize(%8d) ofs(%8d) path(%s)\n", i, ret,
424 info.fileSize, info.offsetFromFileBlockHead, info.externalFilePath );
425 }
426 else
427 {
428 NN_LOG("[%4d]?(%d) fileSize(%8d) ofs(%8d) path((null))\n", i, ret,
429 info.fileSize, info.offsetFromFileBlockHead );
430 }
431 }
432
433 // サウンドアーカイブプレイヤー情報
434 NN_LOG("### SOUND-ARCHIVE-PLAYER Info\n");
435 {
436 SoundArchive::SoundArchivePlayerInfo info;
437 bool ret = m_ArchiveReader.ReadSoundArchivePlayerInfo( &info );
438 NN_LOG("sequenceSoundMax (%2d)\n", info.sequenceSoundMax );
439 NN_LOG("sequenceTrackMax (%2d)\n", info.sequenceTrackMax );
440 NN_LOG("streamSoundMax (%2d)\n", info.streamSoundMax );
441 NN_LOG("streamTrackMax (%2d)\n", info.streamTrackMax );
442 NN_LOG("streamChannelMax (%2d)\n", info.streamChannelMax );
443 NN_LOG("waveSoundMax (%2d)\n", info.waveSoundMax );
444 NN_LOG("waveTrackMax (%2d)\n", info.waveTrackMax );
445 }
446 }
447 #endif /* NW_SND_DEBUG_PRINT_ENABLE */
448
449 return true;
450 }
451
452 /*---------------------------------------------------------------------------*
453 Name: LoadLabelStringData
454
455 Description: ラベルデータをロードする
456
457 Arguments: buffer - ロードアドレス
458 size - バッファサイズ
459
460 Returns: 成功したら true 失敗したら false
461 *---------------------------------------------------------------------------*/
LoadLabelStringData(void * buffer,unsigned long size)462 bool RomSoundArchive::LoadLabelStringData( void* buffer, unsigned long size )
463 {
464 NW_ASSERT( m_IsOpened );
465
466 const s32 stringBlockOffset = m_ArchiveReader.GetStringBlockOffset();
467 const u32 stringBlockSize = m_ArchiveReader.GetStringBlockSize();
468
469 if ( stringBlockOffset == internal::Util::Reference::INVALID_OFFSET )
470 {
471 // サウンドアーカイブの文字列ブロックが含まれていない
472 return false;
473 }
474
475 if ( size < stringBlockSize )
476 {
477 NW_WARNING(
478 size >= stringBlockSize,
479 "RomSoundArchive::LoadLabelStringData buffer size is too small."
480 );
481 return false;
482 }
483
484 #ifdef NW_PLATFORM_CTRWIN
485 nn::fs::SeekFile( &m_FileInfo, stringBlockOffset, nn::fs::FS_SEEK_SET );
486 s32 readSize = nn::fs::ReadFile(
487 &m_FileInfo,
488 buffer,
489 static_cast<s32>(stringBlockSize)
490 );
491 #else
492 m_FileReader.Seek( stringBlockOffset, nn::fs::POSITION_BASE_BEGIN );
493 s32 readSize = m_FileReader.Read( buffer, static_cast<s32>(stringBlockSize) );
494 #endif
495 if ( readSize != stringBlockSize )
496 {
497 NW_WARNING(
498 false,
499 "RomSoundArchive::LoadLabelStringData cannot read file.\n"
500 );
501 return false;
502 }
503
504 m_ArchiveReader.SetStringBlock( buffer/*, stringBlockSize*/ );
505
506 #ifdef NW_SND_DEBUG_PRINT_ENABLE
507 // デバッグ出力
508 {
509 NN_LOG("### PATRICIA-TREE Info\n");
510 m_ArchiveReader.DumpTree();
511
512 NN_LOG("### LABEL => ID\n");
513 int count = m_ArchiveReader.GetStringCount();
514 for ( int i = 0; i < count; i++ )
515 {
516 const char* str = m_ArchiveReader.GetString( i );
517 NN_LOG("[%02d] (%-16s) => ItemId(0x%08X)\n", i, str, GetItemId( str ) );
518 #if 0
519 NN_LOG(" as Sound ID: (0x%08X)\n", GetSoundId( str ) );
520 NN_LOG(" as Bank ID: (0x%08X)\n", GetBankId( str ) );
521 NN_LOG(" as Player ID: (0x%08X)\n", GetPlayerId( str ) );
522 NN_LOG(" as SoundGroup ID: (0x%08X)\n", GetSoundGroupId( str ) );
523 NN_LOG(" as Group ID: (0x%08X)\n", GetGroupId( str ) );
524 NN_LOG(" as WaveArchive ID: (0x%08X)\n", GetWaveArchiveId( str ) );
525 #endif
526 }
527
528 NN_LOG("### ID => LABEL\n");
529 NN_LOG("[Sound]\n");
530 for ( u32 i = 0; i < GetSoundCount(); i++ )
531 {
532 u32 id = GetSoundIdFromIndex( i );
533 NN_LOG(" [%08X] (%s)\n", id, GetItemLabel(id) );
534 }
535 NN_LOG("[Bank]\n");
536 for ( u32 i = 0; i < GetBankCount(); i++ )
537 {
538 u32 id = GetBankIdFromIndex( i );
539 NN_LOG(" [%08X] (%s)\n", id, GetItemLabel(id) );
540 }
541 NN_LOG("[Player]\n");
542 for ( u32 i = 0; i < GetPlayerCount(); i++ )
543 {
544 u32 id = GetPlayerIdFromIndex( i );
545 NN_LOG(" [%08X] (%s)\n", id, GetItemLabel(id) );
546 }
547 NN_LOG("[SoundGroup]\n");
548 for ( u32 i = 0; i < GetSoundGroupCount(); i++ )
549 {
550 u32 id = GetSoundGroupIdFromIndex( i );
551 NN_LOG(" [%08X] (%s)\n", id, GetItemLabel(id) );
552 }
553 NN_LOG("[Group]\n");
554 for ( u32 i = 0; i < GetGroupCount(); i++ )
555 {
556 u32 id = GetGroupIdFromIndex( i );
557 NN_LOG(" [%08X] (%s)\n", id, GetItemLabel(id) );
558 }
559 NN_LOG("[WaveArchive]\n");
560 for ( u32 i = 0; i < GetWaveArchiveCount(); i++ )
561 {
562 u32 id = GetWaveArchiveIdFromIndex( i );
563 const char* label = GetItemLabel( id );
564 if ( label != NULL )
565 {
566 NN_LOG(" [%08X] (%s)\n", id, label );
567 }
568 else
569 {
570 NN_LOG(" [%08X] ((anonymous))\n", id );
571 }
572 }
573 }
574 #endif /* NW_SND_DEBUG_PRINT_ENABLE */
575
576 return true;
577 }
578
579 #if 0
580 /*---------------------------------------------------------------------------*
581 Name: RomFileStream
582
583 Description: コンストラクタ
584
585 Arguments: entryNum - DVDエントリ番号
586 offset - DVDファイル先頭からのオフセット
587 size - ストリームサイズ
588
589 Returns: None.
590 *---------------------------------------------------------------------------*/
591 RomSoundArchive::RomFileStream::RomFileStream( s32 entryNum, u32 offset, u32 size )
592 : ut::RomLockedFileStream( entryNum ),
593 m_Offset( static_cast<s32>( offset ) ),
594 m_Size( size )
595 {
596 NW_ASSERT( m_Size <= ut::RomLockedFileStream::GetSize() );
597
598 ut::RomLockedFileStream::Seek( m_Offset, ut::FILE_STREAM_SEEK_BEGIN );
599 }
600 #endif
601
RomFileStream(const char * path,u32 offset,u32 size)602 RomSoundArchive::RomFileStream::RomFileStream( const char* path, u32 offset, u32 size )
603 // RomSoundArchive::RomFileStream::RomFileStream( const wchar_t* path, u32 offset, u32 size )
604 : io::RomFileStream( path ),
605 m_Offset( static_cast<s32>( offset ) ),
606 m_Size( size )
607 {
608 NW_ASSERT( m_Size <= io::RomFileStream::GetSize() );
609 if ( size == 0 )
610 {
611 m_Size = io::RomFileStream::GetSize();
612 }
613 io::RomFileStream::Seek( m_Offset, io::FILE_STREAM_SEEK_BEGIN );
614 }
615
616 #ifdef NW_PLATFORM_CTRWIN
617 // オープン済みのファイルからストリームを作成して内部で持つ
RomFileStream(const nn::fs::File * fileInfo,u32 offset,u32 size)618 RomSoundArchive::RomFileStream::RomFileStream(
619 const nn::fs::File* fileInfo, u32 offset, u32 size )
620 : io::RomFileStream( fileInfo, false ),
621 m_Offset( static_cast<s32>( offset ) ),
622 m_Size( size )
623 {
624 NW_ASSERT( m_Size <= io::RomFileStream::GetSize() );
625 if ( size == 0 )
626 {
627 m_Size = io::RomFileStream::GetSize();
628 }
629 io::RomFileStream::Seek( m_Offset, io::FILE_STREAM_SEEK_BEGIN );
630 }
631 #else
632 // オープン済みのファイルからストリームを作成して内部で持つ
RomFileStream(nn::fs::FileReader * fileReader,u32 offset,u32 size)633 RomSoundArchive::RomFileStream::RomFileStream(
634 nn::fs::FileReader* fileReader, u32 offset, u32 size )
635 : io::RomFileStream( fileReader, false ),
636 m_Offset( static_cast<s32>( offset ) ),
637 m_Size( size )
638 {
639 NW_ASSERT( m_Size <= io::RomFileStream::GetSize() );
640 if ( size == 0 )
641 {
642 m_Size = io::RomFileStream::GetSize();
643 }
644 io::RomFileStream::Seek( m_Offset, io::FILE_STREAM_SEEK_BEGIN );
645 }
646 #endif
647
Read(void * buf,u32 length)648 s32 RomSoundArchive::RomFileStream::Read( void* buf, u32 length )
649 {
650 NW_ALIGN32_ASSERT( buf );
651 NW_ALIGN32_ASSERT( length );
652
653 u32 curPos = io::RomFileStream::Tell();
654 if ( curPos + length > m_Offset + m_Size ) {
655 length = static_cast<u32>( ut::RoundUp( m_Offset + m_Size - curPos, 32 ) );
656 }
657 return io::RomFileStream::Read( buf, length );
658 }
659
Seek(s32 offset,u32 origin)660 void RomSoundArchive::RomFileStream::Seek( s32 offset, u32 origin )
661 {
662 switch( origin ) {
663 case io::FILE_STREAM_SEEK_BEGIN:
664 offset += m_Offset;
665 break;
666 case io::FILE_STREAM_SEEK_CURRENT:
667 offset += io::RomFileStream::Tell();
668 break;
669 case io::FILE_STREAM_SEEK_END:
670 offset = m_Offset + static_cast<s32>( m_Size ) - offset;
671 break;
672 default:
673 NW_ASSERTMSG( false, "Unsupported Seek origin" );
674 return;
675 }
676
677 if ( offset < m_Offset )
678 {
679 offset = m_Offset;
680 }
681 else if ( offset > m_Offset + static_cast<s32>( m_Size ) )
682 {
683 offset = m_Offset + static_cast<s32>( m_Size );
684 }
685
686 io::RomFileStream::Seek( offset, io::FILE_STREAM_SEEK_BEGIN );
687 }
688
689 } // namespace nw::snd
690 } // namespace nw
691
692