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: 22284 $
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 
171 } // namespace nw::snd::internal
172 } // namespace nw::snd
173 } // namespace nw
174