/*---------------------------------------------------------------------------* Project: NintendoWare File: gfx_ParticleAnimationOption.cpp Copyright (C)2009-2011 Nintendo/HAL Laboratory, Inc. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo and/or its licensed developers and are protected by national and international copyright laws. 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. The content herein is highly confidential and should be handled accordingly. $Revision: 31311 $ *---------------------------------------------------------------------------*/ #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