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