1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     anim_ResUtil.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: 31860 $
16  *---------------------------------------------------------------------------*/
17 
18 #include "../precompiled.h"
19 #include <string.h>
20 
21 #include <nw/anim/res/anim_ResUtil.h>
22 
23 namespace {
24 
25 //---------------------------------------------------------------------------
26 //! @brief        テクスチャパターンアニメのリソースの複製を作成します。
27 //!
28 //!               アニメーションカーブ、テクスチャのパスは、クローン元のアドレスを参照します。
29 //!               ひとつのテクスチャパターンアニメを共有する際に使用することを想定しています。
30 //!
31 //! @return       複製したリソースを返します。
32 //---------------------------------------------------------------------------
CloneTextureAnimMember(nw::os::IAllocator * allocator,const nw::anim::ResTextureAnim & src)33 nw::anim::ResTextureAnim CloneTextureAnimMember(
34     nw::os::IAllocator* allocator,
35     const nw::anim::ResTextureAnim& src
36 )
37 {
38     const int texturesCount = src.GetTexturesCount();
39     void* texturesTableMemory =
40         allocator->Alloc(sizeof(nw::ut::Offset) * texturesCount);
41     nw::ut::Offset* texturesTable =
42         reinterpret_cast<nw::ut::Offset*>(texturesTableMemory);
43 
44     void* texturesMemory =
45         allocator->Alloc(sizeof(nw::gfx::ResReferenceTextureData) * texturesCount);
46     nw::gfx::ResReferenceTextureData* textures =
47         reinterpret_cast<nw::gfx::ResReferenceTextureData*>(texturesMemory);
48 
49     for (int i = 0; i < texturesCount; ++i)
50     {
51         nw::gfx::ResReferenceTextureData& texture = textures[i];
52         const nw::gfx::ResReferenceTextureData* srcTexture = src.GetTextures(i).ptr();
53 
54         // ResSceneObject
55         texture.typeInfo = srcTexture->typeInfo;
56         texture.m_Header.signature = srcTexture->m_Header.signature;
57         texture.m_Header.revision = srcTexture->m_Header.revision;
58         texture.toName.set_ptr(srcTexture->toName.to_ptr());
59         texture.m_UserDataDicCount = srcTexture->m_UserDataDicCount;
60         texture.toUserDataDic.set_ptr(srcTexture->toUserDataDic.to_ptr());
61 
62         // ResTextureは空
63         // ResReferenveTexture
64         texture.toPath.set_ptr(srcTexture->toPath.to_ptr());
65         texture.toTargetTexture.set_ptr(NULL); // ここはsetupで解決される
66 
67         texturesTable[i].set_ptr(&texture);
68     }
69 
70     void* animMemory = allocator->Alloc(sizeof(nw::anim::ResTextureAnimData));
71     nw::anim::ResTextureAnimData* anim = new(animMemory) nw::anim::ResTextureAnimData;
72 
73     if (nw::ut::CheckFlag(src.ptr()->m_Flags, nw::anim::ResTextureAnimData::FLAG_CONSTANT))
74     {
75         anim->constantValueCurve = src.ptr()->constantValueCurve;
76     }
77     else
78     {
79         anim->toCurve.set_ptr(src.ptr()->toCurve.to_ptr());
80     }
81 
82     anim->m_TexturesTableCount = texturesCount;
83     anim->toTexturesTable.set_ptr(texturesTable);
84 
85     anim->m_Flags = src.GetFlags();
86     anim->toPath.set_ptr(src.ptr()->toPath.to_ptr());
87     anim->m_PrimitiveType = src.GetPrimitiveType();
88 
89     return nw::anim::ResTextureAnim(anim);
90 }
91 
DestroyTextureAnimMember(nw::os::IAllocator * allocator,nw::anim::ResTextureAnim anim)92 void DestroyTextureAnimMember(
93     nw::os::IAllocator* allocator,
94     nw::anim::ResTextureAnim anim
95 )
96 {
97     const int texturesCount = anim.GetTexturesCount();
98 
99     // メモリ確保時には先頭のポインタでサイズ分確保しているので、先頭を解放
100     allocator->Free(anim.GetTextures(0).ptr());
101     allocator->Free(anim.ptr()->toTexturesTable.to_ptr());
102     allocator->Free(anim.ptr());
103 }
104 
105 }
106 
107 namespace nw {
108 namespace anim {
109 namespace res {
110 
111 //----------------------------------------
CloneTextureAnim(os::IAllocator * allocator,const ResAnim & src)112 ResAnim CloneTextureAnim(os::IAllocator* allocator, const ResAnim& src)
113 {
114     // MaterialAnimationでなければならない
115     NW_ASSERT(strcmp(src.GetTargetAnimGroupName(), "MaterialAnimation") == 0);
116 
117     // NOTE:
118     // シーケンシャルなメモリ配置になっていません。
119     // 問題が起こるならば対処の必要があります。
120 
121     // ResAnimをクローンします。
122     void* animMemory = allocator->Alloc(sizeof(ResAnimData));
123     ResAnimData* animData = reinterpret_cast<ResAnimData*>(animMemory);
124 
125     animData->m_Header.revision = src.ptr()->m_Header.revision;
126     animData->m_Header.signature = src.ptr()->m_Header.signature;
127     animData->toName.set_ptr(src.ptr()->toName.to_ptr());
128     animData->toTargetAnimGroupName.set_ptr(src.ptr()->toTargetAnimGroupName.to_ptr());
129     animData->m_LoopMode = src.ptr()->m_LoopMode;
130     animData->m_FrameSize = src.ptr()->m_FrameSize;
131     animData->m_MemberAnimSetDicCount = src.ptr()->m_MemberAnimSetDicCount;
132     //animData->toMemberAnimSetDic には後でクローンした辞書を登録します
133     animData->m_UserDataDicCount = src.ptr()->m_UserDataDicCount;
134     animData->toUserDataDic.set_ptr(src.ptr()->toUserDataDic.to_ptr());
135 
136     // MemberAnimSetをクローンします。
137     const int memberCount = src.ptr()->m_MemberAnimSetDicCount;
138     const size_t size =
139         sizeof(ut::ResDicPatriciaData) + (sizeof(ut::ResDicPatriciaData::ResDicNodeData) * memberCount);
140     void* memberMemory = allocator->Alloc(size);
141 
142     memcpy(memberMemory, src.ptr()->toMemberAnimSetDic.to_ptr(), size);
143     ut::ResDicPatriciaData* memberDic = reinterpret_cast<ut::ResDicPatriciaData*>(memberMemory);
144 
145     const ut::ResDicPatriciaData* origDic =
146         reinterpret_cast<const ut::ResDicPatriciaData*>(src.ptr()->toMemberAnimSetDic.to_ptr());
147 
148     for (int i = 0; i < memberCount; ++i)
149     {
150         // dictionary->data[0]はルートノードが入っている(ResDicPatriciaの実装参照)
151         // なので、変更を行うdataテーブルのindexは[i+1]が正しい値になる
152         const int idx = i+1;
153 
154         // memcpyでResU32やResU16の値はオリジナルと同じ値がコピーされるが、
155         // Dictionary内のOffsetは関係ないポインタを指してしまう。
156         // (Offsetの値がコピーされても、その基準になるポインタがずれるため。)
157         // なので、オリジナルと同じポインタへのオフセットになるように修正が必要。
158         memberDic->data[idx].ofsString.set_ptr( origDic->data[idx].ofsString.to_ptr() );
159         memberDic->data[idx].ofsData.set_ptr( origDic->data[idx].ofsData.to_ptr() );
160 
161         // Textureのアニメの場合のみ、ofsDataに独自にクローンしたデータを登録する
162         if (src.GetMemberAnimSet(i).GetPrimitiveType() ==
163             ResMemberAnim::PRIMITIVETYPE_TEXTURE)
164         {
165             ResTextureAnim dup = CloneTextureAnimMember(allocator, src.GetMemberAnimSet(i));
166             memberDic->data[idx].ofsData.set_ptr(dup.ptr());
167         }
168     }
169 
170     animData->toMemberAnimSetDic.set_ptr(memberDic);
171 
172     return ResAnim(animData);
173 }
174 
175 //----------------------------------------
DestroyClonedTextureAnim(os::IAllocator * allocator,ResAnim anim)176 void DestroyClonedTextureAnim(os::IAllocator* allocator, ResAnim anim)
177 {
178     if (!anim.IsValid())
179     {
180         return;
181     }
182 
183     // 渡されたanimがCloneの結果である時しか考慮しない。
184 
185     // 複製したmemberAnim(ResTextureAnim)を破棄する。
186     for (int i = 0; i < anim.GetMemberAnimSetCount(); ++i)
187     {
188         if (anim.GetMemberAnimSet(i).GetPrimitiveType() ==
189             ResMemberAnim::PRIMITIVETYPE_TEXTURE)
190         {
191             DestroyTextureAnimMember(allocator, anim.GetMemberAnimSet(i));
192         }
193     }
194 
195     // MemberAnimSetを破棄する。
196     allocator->Free(anim.ptr()->toMemberAnimSetDic.to_ptr());
197 
198     // ResAnim本体を破棄する。
199     // 個別に解放した箇所以外はoriginalへのポインタを保持するのみなので、解放しない。
200     allocator->Free(anim.ptr());
201 }
202 
203 } /* namespace res */
204 } /* namespace anim */
205 } /* namespace nw */
206