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