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