1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: snd_SoundArchiveLoader.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: 22506 $
14 *---------------------------------------------------------------------------*/
15
16 #include "precompiled.h"
17
18 #include <nw/snd/snd_SoundArchiveLoader.h>
19 #include <nw/snd/snd_SoundMemoryAllocatable.h>
20
21 namespace nw {
22 namespace snd {
23 namespace internal {
24
25 namespace
26 {
27
28 class FileStreamHandle
29 {
30 public:
FileStreamHandle(io::FileStream * stream)31 FileStreamHandle( io::FileStream* stream ) : m_pStream( stream ) { }
~FileStreamHandle()32 ~FileStreamHandle() { if ( m_pStream != NULL ) m_pStream->Close(); }
33
GetFileStream()34 io::FileStream* GetFileStream() { return m_pStream; }
operator ->()35 io::FileStream* operator->() { return m_pStream; }
operator bool() const36 operator bool() const { return m_pStream != NULL; }
37
38 private:
39 io::FileStream* m_pStream;
40 };
41
42 } // anonymous namespace
43
44 /*---------------------------------------------------------------------------*
45 Name: SoundArchiveLoader
46
47 Description: コンストラクタ
48
49 Arguments: arc - ローダで使用するサウンドアーカイブ
50
51 Returns: なし
52 *---------------------------------------------------------------------------*/
SoundArchiveLoader(const SoundArchive & arc)53 SoundArchiveLoader::SoundArchiveLoader( const SoundArchive& arc )
54 : m_Arc( arc )
55 {
56 m_CriticalSection.Initialize();
57 }
58
59 /*---------------------------------------------------------------------------*
60 Name: SoundArchiveLoader
61
62 Description: デストラクタ
63
64 Arguments: なし
65
66 Returns: なし
67 *---------------------------------------------------------------------------*/
~SoundArchiveLoader()68 SoundArchiveLoader::~SoundArchiveLoader()
69 {
70 m_CriticalSection.Finalize();
71 }
72
73 /*---------------------------------------------------------------------------*
74 Name: ReadFile
75
76 Description: サウンドアーカイブ内のファイルの一部をメモリ上に読み出します。
77 ID が fileId のファイルの offset バイト目から size だけ読み出します。
78
79 Arguments: fileId - サウンドアーカイブ内のファイル ID です。
80 buffer - ロードするバッファの先頭アドレスです。
81 size - 読み出すサイズです。
82 offset - ファイル「ファイル ID」の先頭からのオフセットです。
83
84 Returns: 読み込んだサイズを返します。
85 失敗したときは、-1 を返します。
86 *---------------------------------------------------------------------------*/
ReadFile(SoundArchive::FileId fileId,void * buffer,size_t size,s32 offset,size_t loadBlockSize)87 s32 SoundArchiveLoader::ReadFile(
88 SoundArchive::FileId fileId,
89 void* buffer,
90 size_t size,
91 s32 offset,
92 size_t loadBlockSize )
93 {
94 nn::os::CriticalSection::ScopedLock lock(m_CriticalSection); // 他スレッドからのデータロードを考慮
95
96 FileStreamHandle stream = const_cast<SoundArchive&>(m_Arc).detail_OpenFileStream(
97 fileId, m_StreamArea, sizeof(m_StreamArea) );
98 if ( ! stream )
99 {
100 return -1;
101 }
102 if ( ! stream->CanSeek() || ! stream->CanRead() )
103 {
104 return -1;
105 }
106
107 stream->Seek( offset, io::FILE_STREAM_SEEK_BEGIN );
108
109 if ( loadBlockSize == 0 )
110 {
111 // 一括ロード
112 s32 readByte = stream->Read( buffer, ut::RoundUp( static_cast<u32>( size ), 32 ) );
113 if ( readByte < 0 )
114 {
115 return -1;
116 }
117 }
118 else
119 {
120 // 分割ロード
121 u8* ptr = reinterpret_cast<u8*>( buffer );
122 u32 restSize = size;
123 while ( restSize > 0 )
124 {
125 u32 curReadingSize = ut::RoundUp( ut::Min<u32>( loadBlockSize, restSize ), 32 );
126 s32 readByte = stream->Read( ptr, curReadingSize );
127 if ( readByte < 0 )
128 {
129 return -1;
130 }
131 if ( restSize > readByte )
132 {
133 restSize -= readByte;
134 ptr += readByte;
135 }
136 else
137 {
138 restSize = 0;
139 }
140 }
141 }
142
143 return size;
144 }
145
146 /*---------------------------------------------------------------------------*
147 Name: LoadFile
148
149 Description: サウンドアーカイブ内のファイルをロードします。
150
151 Arguments: fileId - サウンドアーカイブ内のファイル ID です。
152 allocator - ファイルを格納するメモリを確保するアロケータです。
153 loadBlockSize - 分割ロード時、1回の Read で読み取るサイズ。
154 0 だと一括ロードする。
155 needDeviceMemory - デバイスメモリへのロードが必要かどうかのフラグです。
156
157 Returns: ロードしたメモリアドレス
158 ロード失敗時には NULL を返す
159 *---------------------------------------------------------------------------*/
LoadFile(SoundArchive::FileId fileId,SoundMemoryAllocatable * allocator,size_t loadBlockSize,bool needDeviceMemory)160 void* SoundArchiveLoader::LoadFile(
161 SoundArchive::FileId fileId,
162 SoundMemoryAllocatable* allocator,
163 size_t loadBlockSize,
164 bool needDeviceMemory )
165 {
166 NW_NULL_ASSERT( allocator );
167
168 SoundArchive::FileInfo fileInfo;
169 if ( ! m_Arc.detail_ReadFileInfo( fileId, &fileInfo ) )
170 {
171 return NULL;
172 }
173 u32 fileSize = fileInfo.fileSize;
174 if ( fileSize == 0 )
175 {
176 return NULL;
177 }
178
179 void* buffer = allocator->Alloc( fileSize );
180 if ( buffer == NULL )
181 {
182 return NULL;
183 }
184 if ( needDeviceMemory )
185 {
186 if ( ! Util::IsDeviceMemory( reinterpret_cast<uptr>(buffer), fileSize ) )
187 {
188 NW_ASSERTMSG( false, "buffer, buffer + fileSize is not Device Memory.");
189 return false;
190 }
191 }
192
193 if ( ReadFile( fileId, buffer, (s32)fileSize, 0, loadBlockSize ) != fileSize )
194 {
195 return NULL;
196 }
197 #ifdef NW_PLATFORM_CTR
198 nn::snd::FlushDataCache( reinterpret_cast<uptr>(buffer), fileSize );
199 #endif
200
201 return buffer;
202 }
203
204 } // namespace nw::snd::internal
205 } // namespace nw::snd
206 } // namespace nw
207
208