1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: snd_WaveArchiveFileReader.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: 28239 $
14 *---------------------------------------------------------------------------*/
15
16 #include "precompiled.h"
17 #include <nw/snd/snd_WaveArchiveFileReader.h>
18
19 // #define NW_SND_DEBUG_PRINT_ENABLE
20
21 namespace nw {
22 namespace snd {
23 namespace internal {
24
25 namespace
26 {
27
28 const u32 SIGNATURE_INFO_BLOCK = NW_UT_MAKE_SIGWORD( 'I', 'N', 'F', 'O' );
29 const u32 SIGNATURE_FILE_BLOCK = NW_UT_MAKE_SIGWORD( 'F', 'I', 'L', 'E' );
30
31 const u32 SUPPORTED_FILE_VERSION = 0x01000000; // ライブラリがサポートする最低バージョン
32 const u32 CURRENT_FILE_VERSION = 0x01000000; // ライブラリがサポートする最新バージョン
33
IsValidFileHeader(const void * waveArchiveData)34 bool IsValidFileHeader( const void* waveArchiveData )
35 {
36 const ut::BinaryFileHeader& header =
37 *reinterpret_cast<const ut::BinaryFileHeader*>( waveArchiveData );
38
39 // シグニチャ確認
40 NW_ASSERTMSG( header.signature == WaveArchiveFileReader::SIGNATURE_FILE,
41 "invalid file signature." );
42 if ( header.signature != WaveArchiveFileReader::SIGNATURE_FILE )
43 {
44 return false;
45 }
46
47 // バージョン確認
48 NW_ASSERTMSG(
49 header.version >= SUPPORTED_FILE_VERSION,
50 "wave archive file is not supported version.\n"
51 "please reconvert file using new version tools.\n"
52 "(SUPPORTED_FILE_VERSION:0x%08x >= your version:0x%08x)\n",
53 SUPPORTED_FILE_VERSION, header.version
54 );
55 if ( header.version < SUPPORTED_FILE_VERSION )
56 {
57 return false;
58 }
59 NW_ASSERTMSG(
60 header.version <= CURRENT_FILE_VERSION,
61 "wave archive file is not supported version.\n"
62 "please reconvert file using new version tools.\n"
63 "(CURRENT_FILE_VERSION:0x%08x <= your version:0x%08x)\n",
64 CURRENT_FILE_VERSION, header.version
65 );
66 if ( header.version > CURRENT_FILE_VERSION )
67 {
68 return false;
69 }
70 return true;
71 }
72
73 } // anonymous namespace
74
75 const u32 WaveArchiveFileReader::SIGNATURE_WARC_TABLE = NW_UT_MAKE_SIGWORD( 'C', 'W', 'A', 'T' );
76
WaveArchiveFileReader(const void * pWaveArchiveFile,bool isIndividual)77 WaveArchiveFileReader::WaveArchiveFileReader(
78 const void* pWaveArchiveFile,
79 bool isIndividual )
80 : m_pHeader( NULL ),
81 m_pInfoBlockBody( NULL ),
82 m_pLoadTable( NULL )
83 {
84 NW_NULL_ASSERT( pWaveArchiveFile );
85
86 if ( ! IsValidFileHeader( pWaveArchiveFile ) ) return;
87
88 m_pHeader =
89 reinterpret_cast<const WaveArchiveFile::FileHeader*>( pWaveArchiveFile );
90 m_pInfoBlockBody = &m_pHeader->GetInfoBlock()->body;
91
92 if ( isIndividual )
93 {
94 m_pLoadTable = reinterpret_cast<IndividualLoadTable*>(
95 ut::AddOffsetToPtr(
96 const_cast<void*>( pWaveArchiveFile ),
97 m_pHeader->GetFileBlockOffset() +
98 sizeof( SIGNATURE_WARC_TABLE ) ) );
99 // INFO ブロックと FILE ブロックの間に、
100 // アライメントがはさまっているので、その分ムダになるが、
101 // 見通しのよさを優先する。
102 }
103 }
104
InitializeFileTable()105 void WaveArchiveFileReader::InitializeFileTable()
106 {
107 NW_NULL_ASSERT( m_pInfoBlockBody );
108
109 // ロード管理用ファイルテーブルの初期化
110 for ( u32 i = 0; i < GetWaveFileCount(); i++ )
111 {
112 m_pLoadTable->waveFile[ i ] = NULL;
113 }
114 }
115
GetWaveFileCount() const116 u32 WaveArchiveFileReader::GetWaveFileCount() const
117 {
118 NW_NULL_ASSERT( m_pInfoBlockBody );
119 return m_pInfoBlockBody->GetWaveFileCount();
120 }
121
GetWaveFile(u32 waveIndex) const122 const void* WaveArchiveFileReader::GetWaveFile( u32 waveIndex ) const
123 {
124 NW_NULL_ASSERT( m_pInfoBlockBody );
125 if ( waveIndex >= GetWaveFileCount() ) return NULL;
126
127 if ( m_pLoadTable != NULL )
128 {
129 return GetWaveFileForIndividual( waveIndex );
130 }
131 return GetWaveFileForWhole( waveIndex );
132 }
133
GetWaveFileSize(u32 waveIndex) const134 u32 WaveArchiveFileReader::GetWaveFileSize( u32 waveIndex ) const
135 {
136 NW_NULL_ASSERT( m_pInfoBlockBody );
137 return m_pInfoBlockBody->GetSize( waveIndex );
138 }
139
GetWaveFileOffsetFromFileHead(u32 waveIndex) const140 u32 WaveArchiveFileReader::GetWaveFileOffsetFromFileHead( u32 waveIndex ) const
141 {
142 NW_NULL_ASSERT( m_pInfoBlockBody );
143 u32 result =
144 + m_pHeader->GetFileBlockOffset()
145 + offsetof( WaveArchiveFile::FileBlock, body )
146 + m_pInfoBlockBody->GetOffsetFromFileBlockBody( waveIndex );
147 return result;
148 }
149
150 const void*
SetWaveFile(u32 waveIndex,const void * pWaveFile)151 WaveArchiveFileReader::SetWaveFile(
152 u32 waveIndex, const void* pWaveFile )
153 {
154 if ( m_pLoadTable == NULL ) return NULL;
155 if ( waveIndex >= GetWaveFileCount() ) return NULL;
156
157 const void* preAddress = GetWaveFileForIndividual( waveIndex );
158 m_pLoadTable->waveFile[ waveIndex ] = pWaveFile;
159
160 #ifdef NW_SND_DEBUG_PRINT_ENABLE
161 // デバッグ
162 for ( u32 i = 0; i < GetWaveFileCount(); i++ )
163 {
164 NN_LOG(" [%3d] %p\n", i, m_pLoadTable->waveFile[i] );
165 }
166 #endif /* NW_SND_DEBUG_PRINT_ENABLE */
167
168 return preAddress;
169 }
170
HasIndividualLoadTable() const171 bool WaveArchiveFileReader::HasIndividualLoadTable() const
172 {
173 const u32* signature = reinterpret_cast<const u32*>(
174 ut::AddOffsetToPtr( m_pHeader, m_pHeader->GetFileBlockOffset() ) );
175 if ( *signature == SIGNATURE_WARC_TABLE )
176 {
177 return true;
178 }
179 return false;
180 }
181
182 } // namespace nw::snd::internal
183 } // namespace nw::snd
184 } // namespace nw
185