/*---------------------------------------------------------------------------* Project: NintendoWare File: gfx_ParticleAnimationOption.cpp Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Revision: 25048 $ *---------------------------------------------------------------------------*/ #include "precompiled.h" #include #include #include #include namespace nw { namespace gfx { u32 ResParticleAnimationOption::GetHash( u32 key1, u32 key2, u32 key3, u32 key4 ) { union { u32 i; u8 b[4]; } u; u.i = (key1 * 0x3f81f635u) + (key2 * 0x30a74193u) + (key3 * 0x371097e7u) + (key4 * 0x7b929u) + 0x4bf53u; u.b[2] ^= u.b[3]; u.b[1] ^= u.b[2]; u.b[0] ^= u.b[1]; return u.i; } ParticleTime ResParticleAnimationOption::EvaluateAnimationFrame( u32 id, ParticleTime birth, ParticleTime life, ParticleTime time, int updaterIndex ) const { if (!this->IsValid()) { if (time < birth) { return 0; } if (life <= 0) { return 0; } return time - birth; } switch (this->GetTypeInfo()) { case ResParticleFittingAnimationOption::TYPE_INFO: { if (time < birth) { return 0; } if (life <= 0) { return 0; } #ifdef NW_GFX_PARTICLE_COMPAT_1_1 return (time - birth) / life * this->GetAnimationDuration(); #else ParticleTime time_birth = time - birth; return time_birth.Interp(life, (int)this->GetAnimationDuration()); #endif } case ResParticleFrameLoopAnimationOption::TYPE_INFO: { const ResParticleFrameLoopAnimationOption resource = ResDynamicCast(*this); if (time < birth) { return 0; } if (resource.GetAnimationDuration() == 0 || resource.GetLoopDuration() == 0) { return 0; } ParticleTime delta = time - birth; if (resource.GetRandomOffset()) { u32 random = GetHash( id, #ifdef NW_GFX_PARTICLE_COMPAT_1_1 (u32)birth, #else birth.GetS32Value(), #endif updaterIndex, 0x1234); #ifdef NW_GFX_PARTICLE_COMPAT_1_1 delta += (f32)(random % resource.GetLoopDuration()); #else delta += (s32)(random % resource.GetLoopDuration()); #endif } #ifdef NW_GFX_PARTICLE_COMPAT_1_1 delta = nw::math::FMod(delta, (f32)resource.GetLoopDuration()); delta /= resource.GetLoopDuration(); return delta * resource.GetAnimationDuration(); #else delta.FMod((int)resource.GetLoopDuration()); delta.Interp(ParticleTime((int)resource.GetLoopDuration()), resource.GetAnimationDuration()); return delta; #endif } case ResParticleRandomAnimationOption::TYPE_INFO: { if (this->GetAnimationDuration() == 0) { return 0; } u32 random = GetHash( id, #ifdef NW_GFX_PARTICLE_COMPAT_1_1 (u32)birth, #else birth.GetS32Value(), #endif updaterIndex, 0x4321); int offset = (int)(random % (int)(this->GetAnimationDuration() + 1)); #ifdef NW_GFX_PARTICLE_COMPAT_1_1 return (f32)offset; #else return offset; #endif } } return 0; } } // namespace gfx } // namespace nw