1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: gfx_ParticleAnimationOption.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: 25048 $
14 *---------------------------------------------------------------------------*/
15
16 #include "precompiled.h"
17
18 #include <nw/gfx/res/gfx_ResParticleAnimationOption.h>
19
20 #include <nw/ut/ut_ResUtil.h>
21 #include <nw/ut/ut_ResDictionary.h>
22 #include <nw/gfx/gfx_ParticleTime.h>
23
24 namespace nw
25 {
26 namespace gfx
27 {
28
29 u32
GetHash(u32 key1,u32 key2,u32 key3,u32 key4)30 ResParticleAnimationOption::GetHash(
31 u32 key1,
32 u32 key2,
33 u32 key3,
34 u32 key4
35 )
36 {
37 union
38 {
39 u32 i;
40 u8 b[4];
41 } u;
42
43 u.i = (key1 * 0x3f81f635u)
44 + (key2 * 0x30a74193u)
45 + (key3 * 0x371097e7u)
46 + (key4 * 0x7b929u)
47 + 0x4bf53u;
48
49 u.b[2] ^= u.b[3];
50 u.b[1] ^= u.b[2];
51 u.b[0] ^= u.b[1];
52
53 return u.i;
54 }
55
56 ParticleTime
EvaluateAnimationFrame(u32 id,ParticleTime birth,ParticleTime life,ParticleTime time,int updaterIndex) const57 ResParticleAnimationOption::EvaluateAnimationFrame(
58 u32 id,
59 ParticleTime birth,
60 ParticleTime life,
61 ParticleTime time,
62 int updaterIndex
63 ) const
64 {
65 if (!this->IsValid())
66 {
67 if (time < birth)
68 {
69 return 0;
70 }
71
72 if (life <= 0)
73 {
74 return 0;
75 }
76
77 return time - birth;
78 }
79
80 switch (this->GetTypeInfo())
81 {
82 case ResParticleFittingAnimationOption::TYPE_INFO:
83 {
84 if (time < birth)
85 {
86 return 0;
87 }
88
89 if (life <= 0)
90 {
91 return 0;
92 }
93
94 #ifdef NW_GFX_PARTICLE_COMPAT_1_1
95 return (time - birth) / life * this->GetAnimationDuration();
96 #else
97 ParticleTime time_birth = time - birth;
98 return time_birth.Interp(life, (int)this->GetAnimationDuration());
99 #endif
100 }
101
102 case ResParticleFrameLoopAnimationOption::TYPE_INFO:
103 {
104 const ResParticleFrameLoopAnimationOption resource =
105 ResDynamicCast<ResParticleFrameLoopAnimationOption>(*this);
106
107 if (time < birth)
108 {
109 return 0;
110 }
111
112 if (resource.GetAnimationDuration() == 0 || resource.GetLoopDuration() == 0)
113 {
114 return 0;
115 }
116
117 ParticleTime delta = time - birth;
118
119 if (resource.GetRandomOffset())
120 {
121 u32 random = GetHash(
122 id,
123 #ifdef NW_GFX_PARTICLE_COMPAT_1_1
124 (u32)birth,
125 #else
126 birth.GetS32Value(),
127 #endif
128 updaterIndex,
129 0x1234);
130
131 #ifdef NW_GFX_PARTICLE_COMPAT_1_1
132 delta += (f32)(random % resource.GetLoopDuration());
133 #else
134 delta += (s32)(random % resource.GetLoopDuration());
135 #endif
136 }
137
138 #ifdef NW_GFX_PARTICLE_COMPAT_1_1
139 delta = nw::math::FMod(delta, (f32)resource.GetLoopDuration());
140 delta /= resource.GetLoopDuration();
141
142 return delta * resource.GetAnimationDuration();
143 #else
144 delta.FMod((int)resource.GetLoopDuration());
145 delta.Interp(ParticleTime((int)resource.GetLoopDuration()), resource.GetAnimationDuration());
146
147 return delta;
148 #endif
149 }
150
151 case ResParticleRandomAnimationOption::TYPE_INFO:
152 {
153 if (this->GetAnimationDuration() == 0)
154 {
155 return 0;
156 }
157
158 u32 random = GetHash(
159 id,
160 #ifdef NW_GFX_PARTICLE_COMPAT_1_1
161 (u32)birth,
162 #else
163 birth.GetS32Value(),
164 #endif
165 updaterIndex,
166 0x4321);
167
168 int offset = (int)(random % (int)(this->GetAnimationDuration() + 1));
169
170 #ifdef NW_GFX_PARTICLE_COMPAT_1_1
171 return (f32)offset;
172 #else
173 return offset;
174 #endif
175 }
176 }
177
178 return 0;
179 }
180
181 } // namespace gfx
182 } // namespace nw
183