code:
/****************************************************************************
Copyright (c) 2010-2011 cocos2d-x.org
Copyright (c) 2008-2010 Ricardo Quesada
Copyright (c) 2011      Zynga Inc.

http://www.cocos2d-x.org

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "CCParticleExamples.h"
#include "CCDirector.h"
#include "CCTextureCache.h"
#include "CCPointExtension.h"
namespace cocos2d {
//
// ParticleFire
//
bool CCParticleFire::initWithTotalParticles(unsigned int numberOfParticles)
{
	if( ARCH_OPTIMAL_PARTICLE_SYSTEM::initWithTotalParticles(numberOfParticles) )
	{
		// duration
		m_fDuration = kCCParticleDurationInfinity;

		// Gravity Mode
		this->m_nEmitterMode = kCCParticleModeGravity;

		// Gravity Mode: gravity
		this->modeA.gravity = ccp(0,0);

		// Gravity Mode: radial acceleration
		this->modeA.radialAccel = 0;
		this->modeA.radialAccelVar = 0;

		// Gravity Mode: speed of particles
		this->modeA.speed = 60;
		this->modeA.speedVar = 20;

		// starting angle
		m_fAngle = 90;
		m_fAngleVar = 10;

		// emitter position
		CCSize winSize = CCDirector::sharedDirector()->getWinSize();
		this->setPosition(ccp(winSize.width/2, 60));
		this->m_tPosVar = ccp(40, 20);

		// life of particles
		m_fLife = 3;
		m_fLifeVar = 0.25f;

		// size, in pixels
		m_fStartSize = 54.0f;
		m_fStartSizeVar = 10.0f;
		m_fEndSize = kCCParticleStartSizeEqualToEndSize;

		// emits per frame
		m_fEmissionRate = m_uTotalParticles/m_fLife;

		// color of particles
		m_tStartColor.r = 0.76f;
		m_tStartColor.g = 0.25f;
		m_tStartColor.b = 0.12f;
		m_tStartColor.a = 1.0f;
		m_tStartColorVar.r = 0.0f;
		m_tStartColorVar.g = 0.0f;
		m_tStartColorVar.b = 0.0f;
		m_tStartColorVar.a = 0.0f;
		m_tEndColor.r = 0.0f;
		m_tEndColor.g = 0.0f;
		m_tEndColor.b = 0.0f;
		m_tEndColor.a = 1.0f;
		m_tEndColorVar.r = 0.0f;
		m_tEndColorVar.g = 0.0f;
		m_tEndColorVar.b = 0.0f;
		m_tEndColorVar.a = 0.0f;

		// additive
		this->setIsBlendAdditive(true);
		return true;
	}
	return false;
}
//
// ParticleFireworks
//
bool CCParticleFireworks::initWithTotalParticles(unsigned int numberOfParticles)
{
	if( ARCH_OPTIMAL_PARTICLE_SYSTEM::initWithTotalParticles(numberOfParticles) )
	{
		// duration
		m_fDuration= kCCParticleDurationInfinity;

		// Gravity Mode
		this->m_nEmitterMode = kCCParticleModeGravity;

		// Gravity Mode: gravity
		this->modeA.gravity = ccp(0,-90);

		// Gravity Mode:  radial
		this->modeA.radialAccel = 0;
		this->modeA.radialAccelVar = 0;

		//  Gravity Mode: speed of particles
		this->modeA.speed = 180;
		this->modeA.speedVar = 50;

		// emitter position
		CCSize winSize = CCDirector::sharedDirector()->getWinSize();
		this->setPosition(ccp(winSize.width/2, winSize.height/2));

		// angle
		this->m_fAngle= 90;
		this->m_fAngleVar = 20;

		// life of particles
		this->m_fLife = 3.5f;
		this->m_fLifeVar = 1;

		// emits per frame
		this->m_fEmissionRate = m_uTotalParticles/m_fLife;

		// color of particles
		m_tStartColor.r = 0.5f;
		m_tStartColor.g = 0.5f;
		m_tStartColor.b = 0.5f;
		m_tStartColor.a = 1.0f;
		m_tStartColorVar.r = 0.5f;
		m_tStartColorVar.g = 0.5f;
		m_tStartColorVar.b = 0.5f;
		m_tStartColorVar.a = 0.1f;
		m_tEndColor.r = 0.1f;
		m_tEndColor.g = 0.1f;
		m_tEndColor.b = 0.1f;
		m_tEndColor.a = 0.2f;
		m_tEndColorVar.r = 0.1f;
		m_tEndColorVar.g = 0.1f;
		m_tEndColorVar.b = 0.1f;
		m_tEndColorVar.a = 0.2f;

		// size, in pixels
		m_fStartSize = 8.0f;
		m_fStartSizeVar = 2.0f;
		m_fEndSize = kCCParticleStartSizeEqualToEndSize;

		// additive
		this->setIsBlendAdditive(false);
		return true;
	}
	return false;
}
//
// ParticleSun
//
bool CCParticleSun::initWithTotalParticles(unsigned int numberOfParticles)
{
	if( ARCH_OPTIMAL_PARTICLE_SYSTEM::initWithTotalParticles(numberOfParticles) )
	{
		// additive
		this->setIsBlendAdditive(true);

		// duration
		m_fDuration = kCCParticleDurationInfinity;

		// Gravity Mode
		m_nEmitterMode = kCCParticleModeGravity;

		// Gravity Mode: gravity
		modeA.gravity = ccp(0,0);

		// Gravity mode: radial acceleration
		modeA.radialAccel = 0;
		modeA.radialAccelVar = 0;

		// Gravity mode: speed of particles
		modeA.speed = 20;
		modeA.speedVar = 5;

		// angle
		m_fAngle = 90;
		m_fAngleVar = 360;

		// emitter position
		CCSize winSize = CCDirector::sharedDirector()->getWinSize();
		this->setPosition(ccp(winSize.width/2, winSize.height/2));
		m_tPosVar = CCPointZero;

		// life of particles
		m_fLife = 1;
		m_fLifeVar = 0.5f;

		// size, in pixels
		m_fStartSize = 30.0f;
		m_fStartSizeVar = 10.0f;
		m_fEndSize = kCCParticleStartSizeEqualToEndSize;

		// emits per seconds
		m_fEmissionRate = m_uTotalParticles/m_fLife;

		// color of particles
		m_tStartColor.r = 0.76f;
		m_tStartColor.g = 0.25f;
		m_tStartColor.b = 0.12f;
		m_tStartColor.a = 1.0f;
		m_tStartColorVar.r = 0.0f;
		m_tStartColorVar.g = 0.0f;
		m_tStartColorVar.b = 0.0f;
		m_tStartColorVar.a = 0.0f;
		m_tEndColor.r = 0.0f;
		m_tEndColor.g = 0.0f;
		m_tEndColor.b = 0.0f;
		m_tEndColor.a = 1.0f;
		m_tEndColorVar.r = 0.0f;
		m_tEndColorVar.g = 0.0f;
		m_tEndColorVar.b = 0.0f;
		m_tEndColorVar.a = 0.0f;

		return true;
	}
	return false;
}

//
// ParticleGalaxy
//
bool CCParticleGalaxy::initWithTotalParticles(unsigned int numberOfParticles)
{
	if( ARCH_OPTIMAL_PARTICLE_SYSTEM::initWithTotalParticles(numberOfParticles) )
	{
		// duration
		m_fDuration = kCCParticleDurationInfinity;

		// Gravity Mode
		m_nEmitterMode = kCCParticleModeGravity;

		// Gravity Mode: gravity
		modeA.gravity = ccp(0,0);

		// Gravity Mode: speed of particles
		modeA.speed = 60;
		modeA.speedVar = 10;

		// Gravity Mode: radial
		modeA.radialAccel = -80;
		modeA.radialAccelVar = 0;

		// Gravity Mode: tagential
		modeA.tangentialAccel = 80;
		modeA.tangentialAccelVar = 0;

		// angle
		m_fAngle = 90;
		m_fAngleVar = 360;

		// emitter position
		CCSize winSize = CCDirector::sharedDirector()->getWinSize();
		this->setPosition(ccp(winSize.width/2, winSize.height/2));
		m_tPosVar = CCPointZero;

		// life of particles
		m_fLife = 4;
		m_fLifeVar = 1;

		// size, in pixels
		m_fStartSize = 37.0f;
		m_fStartSizeVar = 10.0f;
		m_fEndSize = kCCParticleStartSizeEqualToEndSize;

		// emits per second
		m_fEmissionRate = m_uTotalParticles/m_fLife;

		// color of particles
		m_tStartColor.r = 0.12f;
		m_tStartColor.g = 0.25f;
		m_tStartColor.b = 0.76f;
		m_tStartColor.a = 1.0f;
		m_tStartColorVar.r = 0.0f;
		m_tStartColorVar.g = 0.0f;
		m_tStartColorVar.b = 0.0f;
		m_tStartColorVar.a = 0.0f;
		m_tEndColor.r = 0.0f;
		m_tEndColor.g = 0.0f;
		m_tEndColor.b = 0.0f;
		m_tEndColor.a = 1.0f;
		m_tEndColorVar.r = 0.0f;
		m_tEndColorVar.g = 0.0f;
		m_tEndColorVar.b = 0.0f;
		m_tEndColorVar.a = 0.0f;

		// additive
		this->setIsBlendAdditive(true);
		return true;
	}
	return false;
}

//
// ParticleFlower
//
bool CCParticleFlower::initWithTotalParticles(unsigned int numberOfParticles)
{
	if( ARCH_OPTIMAL_PARTICLE_SYSTEM::initWithTotalParticles(numberOfParticles) )
	{
		// duration
		m_fDuration = kCCParticleDurationInfinity;

		// Gravity Mode
		m_nEmitterMode = kCCParticleModeGravity;

		// Gravity Mode: gravity
		modeA.gravity = ccp(0,0);

		// Gravity Mode: speed of particles
		modeA.speed = 80;
		modeA.speedVar = 10;

		// Gravity Mode: radial
		modeA.radialAccel = -60;
		modeA.radialAccelVar = 0;

		// Gravity Mode: tagential
		modeA.tangentialAccel = 15;
		modeA.tangentialAccelVar = 0;

		// angle
		m_fAngle = 90;
		m_fAngleVar = 360;

		// emitter position
		CCSize winSize = CCDirector::sharedDirector()->getWinSize();
		this->setPosition(ccp(winSize.width/2, winSize.height/2));
		m_tPosVar = CCPointZero;

		// life of particles
		m_fLife = 4;
		m_fLifeVar = 1;

		// size, in pixels
		m_fStartSize = 30.0f;
		m_fStartSizeVar = 10.0f;
		m_fEndSize = kCCParticleStartSizeEqualToEndSize;

		// emits per second
		m_fEmissionRate = m_uTotalParticles/m_fLife;

		// color of particles
		m_tStartColor.r = 0.50f;
		m_tStartColor.g = 0.50f;
		m_tStartColor.b = 0.50f;
		m_tStartColor.a = 1.0f;
		m_tStartColorVar.r = 0.5f;
		m_tStartColorVar.g = 0.5f;
		m_tStartColorVar.b = 0.5f;
		m_tStartColorVar.a = 0.5f;
		m_tEndColor.r = 0.0f;
		m_tEndColor.g = 0.0f;
		m_tEndColor.b = 0.0f;
		m_tEndColor.a = 1.0f;
		m_tEndColorVar.r = 0.0f;
		m_tEndColorVar.g = 0.0f;
		m_tEndColorVar.b = 0.0f;
		m_tEndColorVar.a = 0.0f;

		// additive
		this->setIsBlendAdditive(true);
		return true;
	}
	return false;
}
//
// ParticleMeteor
//
bool CCParticleMeteor::initWithTotalParticles(unsigned int numberOfParticles)
{
	if( ARCH_OPTIMAL_PARTICLE_SYSTEM::initWithTotalParticles(numberOfParticles) )
	{
		// duration
		m_fDuration = kCCParticleDurationInfinity;

		// Gravity Mode
		m_nEmitterMode = kCCParticleModeGravity;

		// Gravity Mode: gravity
		modeA.gravity = ccp(-200,200);

		// Gravity Mode: speed of particles
		modeA.speed = 15;
		modeA.speedVar = 5;

		// Gravity Mode: radial
		modeA.radialAccel = 0;
		modeA.radialAccelVar = 0;

		// Gravity Mode: tagential
		modeA.tangentialAccel = 0;
		modeA.tangentialAccelVar = 0;

		// angle
		m_fAngle = 90;
		m_fAngleVar = 360;

		// emitter position
		CCSize winSize = CCDirector::sharedDirector()->getWinSize();
		this->setPosition(ccp(winSize.width/2, winSize.height/2));
		m_tPosVar = CCPointZero;

		// life of particles
		m_fLife = 2;
		m_fLifeVar = 1;

		// size, in pixels
		m_fStartSize = 60.0f;
		m_fStartSizeVar = 10.0f;
		m_fEndSize = kCCParticleStartSizeEqualToEndSize;

		// emits per second
		m_fEmissionRate = m_uTotalParticles/m_fLife;

		// color of particles
		m_tStartColor.r = 0.2f;
		m_tStartColor.g = 0.4f;
		m_tStartColor.b = 0.7f;
		m_tStartColor.a = 1.0f;
		m_tStartColorVar.r = 0.0f;
		m_tStartColorVar.g = 0.0f;
		m_tStartColorVar.b = 0.2f;
		m_tStartColorVar.a = 0.1f;
		m_tEndColor.r = 0.0f;
		m_tEndColor.g = 0.0f;
		m_tEndColor.b = 0.0f;
		m_tEndColor.a = 1.0f;
		m_tEndColorVar.r = 0.0f;
		m_tEndColorVar.g = 0.0f;
		m_tEndColorVar.b = 0.0f;
		m_tEndColorVar.a = 0.0f;

		// additive
		this->setIsBlendAdditive(true);
		return true;
	}
	return false;
}

//
// ParticleSpiral
//
bool CCParticleSpiral::initWithTotalParticles(unsigned int numberOfParticles)
{
	if( ARCH_OPTIMAL_PARTICLE_SYSTEM::initWithTotalParticles(numberOfParticles) )
	{
		// duration
		m_fDuration = kCCParticleDurationInfinity;

		// Gravity Mode
		m_nEmitterMode = kCCParticleModeGravity;

		// Gravity Mode: gravity
		modeA.gravity = ccp(0,0);

		// Gravity Mode: speed of particles
		modeA.speed = 150;
		modeA.speedVar = 0;

		// Gravity Mode: radial
		modeA.radialAccel = -380;
		modeA.radialAccelVar = 0;

		// Gravity Mode: tagential
		modeA.tangentialAccel = 45;
		modeA.tangentialAccelVar = 0;

		// angle
		m_fAngle = 90;
		m_fAngleVar = 0;

		// emitter position
		CCSize winSize = CCDirector::sharedDirector()->getWinSize();
		this->setPosition(ccp(winSize.width/2, winSize.height/2));
		m_tPosVar = CCPointZero;

		// life of particles
		m_fLife = 12;
		m_fLifeVar = 0;

		// size, in pixels
		m_fStartSize = 20.0f;
		m_fStartSizeVar = 0.0f;
		m_fEndSize = kCCParticleStartSizeEqualToEndSize;

		// emits per second
		m_fEmissionRate = m_uTotalParticles/m_fLife;

		// color of particles
		m_tStartColor.r = 0.5f;
		m_tStartColor.g = 0.5f;
		m_tStartColor.b = 0.5f;
		m_tStartColor.a = 1.0f;
		m_tStartColorVar.r = 0.5f;
		m_tStartColorVar.g = 0.5f;
		m_tStartColorVar.b = 0.5f;
		m_tStartColorVar.a = 0.0f;
		m_tEndColor.r = 0.5f;
		m_tEndColor.g = 0.5f;
		m_tEndColor.b = 0.5f;
		m_tEndColor.a = 1.0f;
		m_tEndColorVar.r = 0.5f;
		m_tEndColorVar.g = 0.5f;
		m_tEndColorVar.b = 0.5f;
		m_tEndColorVar.a = 0.0f;

		// additive
		this->setIsBlendAdditive(false);
		return true;
	}
	return false;
}

//
// ParticleExplosion
//
bool CCParticleExplosion::initWithTotalParticles(unsigned int numberOfParticles)
{
	if( ARCH_OPTIMAL_PARTICLE_SYSTEM::initWithTotalParticles(numberOfParticles) )
	{
		// duration
		m_fDuration = 0.1f;

		m_nEmitterMode = kCCParticleModeGravity;

		// Gravity Mode: gravity
		modeA.gravity = ccp(0,0);

		// Gravity Mode: speed of particles
		modeA.speed = 70;
		modeA.speedVar = 40;

		// Gravity Mode: radial
		modeA.radialAccel = 0;
		modeA.radialAccelVar = 0;

		// Gravity Mode: tagential
		modeA.tangentialAccel = 0;
		modeA.tangentialAccelVar = 0;

		// angle
		m_fAngle = 90;
		m_fAngleVar = 360;

		// emitter position
		CCSize winSize = CCDirector::sharedDirector()->getWinSize();
		this->setPosition(ccp(winSize.width/2, winSize.height/2));
		m_tPosVar = CCPointZero;

		// life of particles
		m_fLife = 5.0f;
		m_fLifeVar = 2;

		// size, in pixels
		m_fStartSize = 15.0f;
		m_fStartSizeVar = 10.0f;
		m_fEndSize = kCCParticleStartSizeEqualToEndSize;

		// emits per second
		m_fEmissionRate = m_uTotalParticles/m_fDuration;

		// color of particles
		m_tStartColor.r = 0.7f;
		m_tStartColor.g = 0.1f;
		m_tStartColor.b = 0.2f;
		m_tStartColor.a = 1.0f;
		m_tStartColorVar.r = 0.5f;
		m_tStartColorVar.g = 0.5f;
		m_tStartColorVar.b = 0.5f;
		m_tStartColorVar.a = 0.0f;
		m_tEndColor.r = 0.5f;
		m_tEndColor.g = 0.5f;
		m_tEndColor.b = 0.5f;
		m_tEndColor.a = 0.0f;
		m_tEndColorVar.r = 0.5f;
		m_tEndColorVar.g = 0.5f;
		m_tEndColorVar.b = 0.5f;
		m_tEndColorVar.a = 0.0f;

		// additive
		this->setIsBlendAdditive(false);
		return true;
	}
	return false;
}

//
// ParticleSmoke
//
bool CCParticleSmoke::initWithTotalParticles(unsigned int numberOfParticles)
{
	if( ARCH_OPTIMAL_PARTICLE_SYSTEM::initWithTotalParticles(numberOfParticles) )
	{
		// duration
		m_fDuration = kCCParticleDurationInfinity;

		// Emitter mode: Gravity Mode
		m_nEmitterMode = kCCParticleModeGravity;

		// Gravity Mode: gravity
		modeA.gravity = ccp(0,0);

		// Gravity Mode: radial acceleration
		modeA.radialAccel = 0;
		modeA.radialAccelVar = 0;

		// Gravity Mode: speed of particles
		modeA.speed = 25;
		modeA.speedVar = 10;

		// angle
		m_fAngle = 90;
		m_fAngleVar = 5;

		// emitter position
		CCSize winSize = CCDirector::sharedDirector()->getWinSize();
		this->setPosition(ccp(winSize.width/2, 0));
		m_tPosVar = ccp(20, 0);

		// life of particles
		m_fLife = 4;
		m_fLifeVar = 1;

		// size, in pixels
		m_fStartSize = 60.0f;
		m_fStartSizeVar = 10.0f;
		m_fEndSize = kCCParticleStartSizeEqualToEndSize;

		// emits per frame
		m_fEmissionRate = m_uTotalParticles/m_fLife;

		// color of particles
		m_tStartColor.r = 0.8f;
		m_tStartColor.g = 0.8f;
		m_tStartColor.b = 0.8f;
		m_tStartColor.a = 1.0f;
		m_tStartColorVar.r = 0.02f;
		m_tStartColorVar.g = 0.02f;
		m_tStartColorVar.b = 0.02f;
		m_tStartColorVar.a = 0.0f;
		m_tEndColor.r = 0.0f;
		m_tEndColor.g = 0.0f;
		m_tEndColor.b = 0.0f;
		m_tEndColor.a = 1.0f;
		m_tEndColorVar.r = 0.0f;
		m_tEndColorVar.g = 0.0f;
		m_tEndColorVar.b = 0.0f;
		m_tEndColorVar.a = 0.0f;

		// additive
		this->setIsBlendAdditive(false);
		return true;
	}
	return false;
}
//
// CCParticleSnow
//
bool CCParticleSnow::initWithTotalParticles(unsigned int numberOfParticles)
{
	if( ARCH_OPTIMAL_PARTICLE_SYSTEM::initWithTotalParticles(numberOfParticles) )
	{
		// duration
		m_fDuration = kCCParticleDurationInfinity;

		// set gravity mode.
		m_nEmitterMode = kCCParticleModeGravity;

		// Gravity Mode: gravity
		modeA.gravity = ccp(0,-1);

		// Gravity Mode: speed of particles
		modeA.speed = 5;
		modeA.speedVar = 1;

		// Gravity Mode: radial
		modeA.radialAccel = 0;
		modeA.radialAccelVar = 1;

		// Gravity mode: tagential
		modeA.tangentialAccel = 0;
		modeA.tangentialAccelVar = 1;

		// emitter position
		CCSize winSize = CCDirector::sharedDirector()->getWinSize();
		this->setPosition(ccp(winSize.width/2, winSize.height + 10));
		m_tPosVar = ccp( winSize.width/2, 0 );

		// angle
		m_fAngle = -90;
		m_fAngleVar = 5;

		// life of particles
		m_fLife = 45;
		m_fLifeVar = 15;

		// size, in pixels
		m_fStartSize = 10.0f;
		m_fStartSizeVar = 5.0f;
		m_fEndSize = kCCParticleStartSizeEqualToEndSize;

		// emits per second
		m_fEmissionRate = 10;

		// color of particles
		m_tStartColor.r = 1.0f;
		m_tStartColor.g = 1.0f;
		m_tStartColor.b = 1.0f;
		m_tStartColor.a = 1.0f;
		m_tStartColorVar.r = 0.0f;
		m_tStartColorVar.g = 0.0f;
		m_tStartColorVar.b = 0.0f;
		m_tStartColorVar.a = 0.0f;
		m_tEndColor.r = 1.0f;
		m_tEndColor.g = 1.0f;
		m_tEndColor.b = 1.0f;
		m_tEndColor.a = 0.0f;
		m_tEndColorVar.r = 0.0f;
		m_tEndColorVar.g = 0.0f;
		m_tEndColorVar.b = 0.0f;
		m_tEndColorVar.a = 0.0f;

		// additive
		this->setIsBlendAdditive(false);
		return true;
	}
	return false;
}
//
// CCParticleRain
//
bool CCParticleRain::initWithTotalParticles(unsigned int numberOfParticles)
{
	if( ARCH_OPTIMAL_PARTICLE_SYSTEM::initWithTotalParticles(numberOfParticles) )
	{
		// duration
		m_fDuration = kCCParticleDurationInfinity;

		m_nEmitterMode = kCCParticleModeGravity;

		// Gravity Mode: gravity
		modeA.gravity = ccp(10,-10);

		// Gravity Mode: radial
		modeA.radialAccel = 0;
		modeA.radialAccelVar = 1;

		// Gravity Mode: tagential
		modeA.tangentialAccel = 0;
		modeA.tangentialAccelVar = 1;

		// Gravity Mode: speed of particles
		modeA.speed = 130;
		modeA.speedVar = 30;

		// angle
		m_fAngle = -90;
		m_fAngleVar = 5;

		// emitter position
		CCSize winSize = CCDirector::sharedDirector()->getWinSize();
		this->setPosition(ccp(winSize.width/2, winSize.height));
		m_tPosVar = ccp( winSize.width/2, 0 );

		// life of particles
		m_fLife = 4.5f;
		m_fLifeVar = 0;

		// size, in pixels
		m_fStartSize = 4.0f;
		m_fStartSizeVar = 2.0f;
		m_fEndSize = kCCParticleStartSizeEqualToEndSize;

		// emits per second
		m_fEmissionRate = 20;

		// color of particles
		m_tStartColor.r = 0.7f;
		m_tStartColor.g = 0.8f;
		m_tStartColor.b = 1.0f;
		m_tStartColor.a = 1.0f;
		m_tStartColorVar.r = 0.0f;
		m_tStartColorVar.g = 0.0f;
		m_tStartColorVar.b = 0.0f;
		m_tStartColorVar.a = 0.0f;
		m_tEndColor.r = 0.7f;
		m_tEndColor.g = 0.8f;
		m_tEndColor.b = 1.0f;
		m_tEndColor.a = 0.5f;
		m_tEndColorVar.r = 0.0f;
		m_tEndColorVar.g = 0.0f;
		m_tEndColorVar.b = 0.0f;
		m_tEndColorVar.a = 0.0f;

		// additive
		this->setIsBlendAdditive(false);
		return true;
	}
	return false;
}

}//namespace cocos2d


code:
/****************************************************************************
Copyright (c) 2010-2011 cocos2d-x.org
Copyright (c) 2008-2010 Ricardo Quesada
Copyright (c) 2011      Zynga Inc.

http://www.cocos2d-x.org

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/

// ideas taken from:
//	 . The ocean spray in your face [Jeff Lander]
//		http://www.double.co.nz/dust/col0798.pdf
//	 . Building an Advanced Particle System [John van der Burg]
//		http://www.gamasutra.com/features/20000623/vanderburg_01.htm
//   . LOVE game engine
//		http://love2d.org/
//
//
// Radius mode support, from 71 squared
//		http://particledesigner.71squared.com/
//
// IMPORTANT: Particle Designer is supported by cocos2d, but
// 'Radius Mode' in Particle Designer uses a fixed emit rate of 30 hz. Since that can't be guarateed in cocos2d,
//  cocos2d uses a another approach, but the results are almost identical.
//

#include "CCParticleSystem.h"
#include "ccTypes.h"
#include "CCTextureCache.h"
#include "support/base64.h"
#include "CCPointExtension.h"
#include "CCFileUtils.h"
#include "CCImage.h"
#include "platform/platform.h"
#include "support/zip_support/ZipUtils.h"
#include "CCDirector.h"

// opengl
#include "platform/CCGL.h"

#if CC_ENABLE_PROFILERS
#include "Support/CCProfiling.h"
#endif

namespace cocos2d {

// ideas taken from:
//	 . The ocean spray in your face [Jeff Lander]
//		http://www.double.co.nz/dust/col0798.pdf
//	 . Building an Advanced Particle System [John van der Burg]
//		http://www.gamasutra.com/features/20000623/vanderburg_01.htm
//   . LOVE game engine
//		http://love2d.org/
//
//
// Radius mode support, from 71 squared
//		http://particledesigner.71squared.com/
//
// IMPORTANT: Particle Designer is supported by cocos2d, but
// 'Radius Mode' in Particle Designer uses a fixed emit rate of 30 hz. Since that can't be guarateed in cocos2d,
//  cocos2d uses a another approach, but the results are almost identical.
//

CCParticleSystem::CCParticleSystem()
	:m_sPlistFile("")
	,m_fElapsed(0)
	,m_pParticles(NULL)
	,m_fEmitCounter(0)
	,m_uParticleIdx(0)
#if CC_ENABLE_PROFILERS
	,m_pProfilingTimer(NULL)
#endif
	,m_bIsActive(true)
	,m_uParticleCount(0)
	,m_fDuration(0)
	,m_tSourcePosition(CCPointZero)
	,m_tPosVar(CCPointZero)
	,m_fLife(0)
	,m_fLifeVar(0)
	,m_fAngle(0)
	,m_fAngleVar(0)
	,m_fStartSize(0)
	,m_fStartSizeVar(0)
	,m_fEndSize(0)
	,m_fEndSizeVar(0)
	,m_fStartSpin(0)
	,m_fStartSpinVar(0)
	,m_fEndSpin(0)
	,m_fEndSpinVar(0)
	,m_fEmissionRate(0)
	,m_uTotalParticles(0)
	,m_pTexture(NULL)
	,m_bIsBlendAdditive(false)
	,m_ePositionType(kCCPositionTypeFree)
	,m_bIsAutoRemoveOnFinish(false)
	,m_nEmitterMode(kCCParticleModeGravity)
{
	modeA.gravity = CCPointZero;
	modeA.speed = 0;
	modeA.speedVar = 0;
	modeA.tangentialAccel = 0;
	modeA.tangentialAccelVar = 0;
	modeA.radialAccel = 0;
	modeA.radialAccelVar = 0;
	modeB.startRadius = 0;
	modeB.startRadiusVar = 0;
	modeB.endRadius = 0;
	modeB.endRadiusVar = 0;
	modeB.rotatePerSecond = 0;
	modeB.rotatePerSecondVar = 0;
	m_tBlendFunc.src = CC_BLEND_SRC;
	m_tBlendFunc.dst = CC_BLEND_DST;
}
// implementation CCParticleSystem
CCParticleSystem * CCParticleSystem::particleWithFile(const char *plistFile)
{
	CCParticleSystem *pRet = new CCParticleSystem();
	if (pRet && pRet->initWithFile(plistFile))
	{
		pRet->autorelease();
		return pRet;
	}
	CC_SAFE_DELETE(pRet)
	return pRet;
}
bool CCParticleSystem::initWithFile(const char *plistFile)
{
	bool bRet = false;
	m_sPlistFile = CCFileUtils::fullPathFromRelativePath(plistFile);
	CCDictionary<std::string, CCObject*> *dict = CCFileUtils::dictionaryWithContentsOfFileThreadSafe(m_sPlistFile.c_str());

	CCAssert( dict != NULL, "Particles: file not found");
	bRet = this->initWithDictionary(dict);
	dict->release();

	return bRet;
}

bool CCParticleSystem::initWithDictionary(CCDictionary<std::string, CCObject*> *dictionary)
{
	bool bRet = false;
	unsigned char *buffer = NULL;
	unsigned char *deflated = NULL;
	CCImage *image = NULL;
	do
	{
		int maxParticles = atoi(valueForKey("maxParticles", dictionary));
		// self, not super
		if(this->initWithTotalParticles(maxParticles))
		{
			// angle
			m_fAngle = (float)atof(valueForKey("angle", dictionary));
			m_fAngleVar = (float)atof(valueForKey("angleVariance", dictionary));

			// duration
			m_fDuration = (float)atof(valueForKey("duration", dictionary));

			// blend function
			m_tBlendFunc.src = atoi(valueForKey("blendFuncSource", dictionary));
			m_tBlendFunc.dst = atoi(valueForKey("blendFuncDestination", dictionary));

			// color
			m_tStartColor.r = (float)atof(valueForKey("startColorRed", dictionary));
			m_tStartColor.g = (float)atof(valueForKey("startColorGreen", dictionary));
			m_tStartColor.b = (float)atof(valueForKey("startColorBlue", dictionary));
			m_tStartColor.a = (float)atof(valueForKey("startColorAlpha", dictionary));

			m_tStartColorVar.r = (float)atof(valueForKey("startColorVarianceRed", dictionary));
			m_tStartColorVar.g = (float)atof(valueForKey("startColorVarianceGreen", dictionary));
			m_tStartColorVar.b = (float)atof(valueForKey("startColorVarianceBlue", dictionary));
			m_tStartColorVar.a = (float)atof(valueForKey("startColorVarianceAlpha", dictionary));

			m_tEndColor.r = (float)atof(valueForKey("finishColorRed", dictionary));
			m_tEndColor.g = (float)atof(valueForKey("finishColorGreen", dictionary));
			m_tEndColor.b = (float)atof(valueForKey("finishColorBlue", dictionary));
			m_tEndColor.a = (float)atof(valueForKey("finishColorAlpha", dictionary));

			m_tEndColorVar.r = (float)atof(valueForKey("finishColorVarianceRed", dictionary));
			m_tEndColorVar.g = (float)atof(valueForKey("finishColorVarianceGreen", dictionary));
			m_tEndColorVar.b = (float)atof(valueForKey("finishColorVarianceBlue", dictionary));
			m_tEndColorVar.a = (float)atof(valueForKey("finishColorVarianceAlpha", dictionary));

			// particle size
			m_fStartSize = (float)atof(valueForKey("startParticleSize", dictionary));
			m_fStartSizeVar = (float)atof(valueForKey("startParticleSizeVariance", dictionary));
			m_fEndSize = (float)atof(valueForKey("finishParticleSize", dictionary));
			m_fEndSizeVar = (float)atof(valueForKey("finishParticleSizeVariance", dictionary));

			// position
            float x = (float)atof(valueForKey("sourcePositionx", dictionary));
            float y = (float)atof(valueForKey("sourcePositiony", dictionary));
            this->setPosition( ccp(x,y) );
            m_tPosVar.x = (float)atof(valueForKey("sourcePositionVariancex", dictionary));
			m_tPosVar.y = (float)atof(valueForKey("sourcePositionVariancey", dictionary));

			// Spinning
			m_fStartSpin = (float)atof(valueForKey("rotationStart", dictionary));
			m_fStartSpinVar = (float)atof(valueForKey("rotationStartVariance", dictionary));
			m_fEndSpin= (float)atof(valueForKey("rotationEnd", dictionary));
			m_fEndSpinVar= (float)atof(valueForKey("rotationEndVariance", dictionary));

			m_nEmitterMode = atoi(valueForKey("emitterType", dictionary));

			// Mode A: Gravity + tangential accel + radial accel
			if( m_nEmitterMode == kCCParticleModeGravity )
			{
				// gravity
				modeA.gravity.x = (float)atof(valueForKey("gravityx", dictionary));
				modeA.gravity.y = (float)atof(valueForKey("gravityy", dictionary));

				// speed
				modeA.speed = (float)atof(valueForKey("speed", dictionary));
				modeA.speedVar = (float)atof(valueForKey("speedVariance", dictionary));

                const char * pszTmp = NULL;
				// radial acceleration
                pszTmp = valueForKey("radialAcceleration", dictionary);
                modeA.radialAccel = (pszTmp) ? (float)atof(pszTmp) : 0;

                pszTmp = valueForKey("radialAccelVariance", dictionary);
				modeA.radialAccelVar = (pszTmp) ? (float)atof(pszTmp) : 0;

				// tangential acceleration
                pszTmp = valueForKey("tangentialAcceleration", dictionary);
				modeA.tangentialAccel = (pszTmp) ? (float)atof(pszTmp) : 0;

                pszTmp = valueForKey("tangentialAccelVariance", dictionary);
				modeA.tangentialAccelVar = (pszTmp) ? (float)atof(pszTmp) : 0;
			}

			// or Mode B: radius movement
			else if( m_nEmitterMode == kCCParticleModeRadius )
			{
				modeB.startRadius = (float)atof(valueForKey("maxRadius", dictionary));
				modeB.startRadiusVar = (float)atof(valueForKey("maxRadiusVariance", dictionary));
				modeB.endRadius = (float)atof(valueForKey("minRadius", dictionary));
				modeB.endRadiusVar = 0;
				modeB.rotatePerSecond = (float)atof(valueForKey("rotatePerSecond", dictionary));
				modeB.rotatePerSecondVar = (float)atof(valueForKey("rotatePerSecondVariance", dictionary));

			} else {
				CCAssert( false, "Invalid emitterType in config file");
				CC_BREAK_IF(true);
			}

			// life span
			m_fLife = (float)atof(valueForKey("particleLifespan", dictionary));
			m_fLifeVar = (float)atof(valueForKey("particleLifespanVariance", dictionary));

			// emission Rate
			m_fEmissionRate = m_uTotalParticles / m_fLife;

			// texture
			// Try to get the texture from the cache
			char *textureName = (char *)valueForKey("textureFileName", dictionary);
            std::string fullpath = CCFileUtils::fullPathFromRelativeFile(textureName, m_sPlistFile.c_str());

			CCTexture2D *tex = NULL;

            if (strlen(textureName) > 0)
            {
                // set not pop-up message box when load image failed
                bool bNotify = CCFileUtils::getIsPopupNotify();
                CCFileUtils::setIsPopupNotify(false);
                tex = CCTextureCache::sharedTextureCache()->addImage(fullpath.c_str());

                // reset the value of UIImage notify
                CCFileUtils::setIsPopupNotify(bNotify);
            }

			if (tex)
			{
				this->m_pTexture = tex;
			}
			else
			{
                char *textureData = (char*)valueForKey("textureImageData", dictionary);
				CCAssert(textureData, "");

				int dataLen = strlen(textureData);
				if(dataLen != 0)
				{
					// if it fails, try to get it from the base64-gzipped data
					int decodeLen = base64Decode((unsigned char*)textureData, (unsigned int)dataLen, &buffer);
					CCAssert( buffer != NULL, "CCParticleSystem: error decoding textureImageData");
					CC_BREAK_IF(!buffer);

						int deflatedLen = ZipUtils::ccInflateMemory(buffer, decodeLen, &deflated);
						CCAssert( deflated != NULL, "CCParticleSystem: error ungzipping textureImageData");
						CC_BREAK_IF(!deflated);

						image = new CCImage();
						bool isOK = image->initWithImageData(deflated, deflatedLen);
						CCAssert(isOK, "CCParticleSystem: error init image with Data");
						CC_BREAK_IF(!isOK);

						m_pTexture = CCTextureCache::sharedTextureCache()->addUIImage(image, fullpath.c_str());
				}
			}
			CCAssert( this->m_pTexture != NULL, "CCParticleSystem: error loading the texture");

			CC_BREAK_IF(!m_pTexture);
			this->m_pTexture->retain();
			bRet = true;
		}
	} while (0);
	CC_SAFE_DELETE_ARRAY(buffer);
    CC_SAFE_DELETE_ARRAY(deflated);
	CC_SAFE_DELETE(image);
	return bRet;
}
bool CCParticleSystem::initWithTotalParticles(unsigned int numberOfParticles)
{
	m_uTotalParticles = numberOfParticles;

    CC_SAFE_DELETE_ARRAY(m_pParticles);

	m_pParticles = new tCCParticle[m_uTotalParticles];

	if( ! m_pParticles )
	{
		CCLOG("Particle system: not enough memory");
		this->release();
		return false;
	}

	// default, active
	m_bIsActive = true;

	// default blend function
	m_tBlendFunc.src = CC_BLEND_SRC;
	m_tBlendFunc.dst = CC_BLEND_DST;

	// default movement type;
	m_ePositionType = kCCPositionTypeFree;

	// by default be in mode A:
	m_nEmitterMode = kCCParticleModeGravity;

	// default: modulate
	// XXX: not used
	//	colorModulate = YES;

	m_bIsAutoRemoveOnFinish = false;

	// profiling
#if CC_ENABLE_PROFILERS
	/// @todo _profilingTimer = [[CCProfiler timerWithName:@"particle system" andInstance:self] retain];
#endif

	// Optimization: compile udpateParticle method
	//updateParticleSel = @selector(updateQuadWithParticle:newPosition:);
	//updateParticleImp = (CC_UPDATE_PARTICLE_IMP) [self methodForSelector:updateParticleSel];

	// udpate after action in run!
	this->scheduleUpdateWithPriority(1);

	return true;
}

CCParticleSystem::~CCParticleSystem()
{
    CC_SAFE_DELETE_ARRAY(m_pParticles);
	CC_SAFE_RELEASE(m_pTexture)
	// profiling
#if CC_ENABLE_PROFILERS
	/// @todo [CCProfiler releaseTimer:_profilingTimer];
#endif
}
bool CCParticleSystem::addParticle()
{
	if (this->isFull())
	{
		return false;
	}

	tCCParticle * particle = &m_pParticles[ m_uParticleCount ];
	this->initParticle(particle);
	++m_uParticleCount;

	return true;
}
void CCParticleSystem::initParticle(tCCParticle* particle)
{
	// timeToLive
	// no negative life. prevent division by 0
	particle->timeToLive = m_fLife + m_fLifeVar * CCRANDOM_MINUS1_1();
	particle->timeToLive = MAX(0, particle->timeToLive);

	// position
	particle->pos.x = m_tSourcePosition.x + m_tPosVar.x * CCRANDOM_MINUS1_1();
    particle->pos.x *= CC_CONTENT_SCALE_FACTOR();
	particle->pos.y = m_tSourcePosition.y + m_tPosVar.y * CCRANDOM_MINUS1_1();
    particle->pos.y *= CC_CONTENT_SCALE_FACTOR();

	// Color
	ccColor4F start;
	start.r = clampf(m_tStartColor.r + m_tStartColorVar.r * CCRANDOM_MINUS1_1(), 0, 1);
	start.g = clampf(m_tStartColor.g + m_tStartColorVar.g * CCRANDOM_MINUS1_1(), 0, 1);
	start.b = clampf(m_tStartColor.b + m_tStartColorVar.b * CCRANDOM_MINUS1_1(), 0, 1);
	start.a = clampf(m_tStartColor.a + m_tStartColorVar.a * CCRANDOM_MINUS1_1(), 0, 1);

	ccColor4F end;
	end.r = clampf(m_tEndColor.r + m_tEndColorVar.r * CCRANDOM_MINUS1_1(), 0, 1);
	end.g = clampf(m_tEndColor.g + m_tEndColorVar.g * CCRANDOM_MINUS1_1(), 0, 1);
	end.b = clampf(m_tEndColor.b + m_tEndColorVar.b * CCRANDOM_MINUS1_1(), 0, 1);
	end.a = clampf(m_tEndColor.a + m_tEndColorVar.a * CCRANDOM_MINUS1_1(), 0, 1);

	particle->color = start;
	particle->deltaColor.r = (end.r - start.r) / particle->timeToLive;
	particle->deltaColor.g = (end.g - start.g) / particle->timeToLive;
	particle->deltaColor.b = (end.b - start.b) / particle->timeToLive;
	particle->deltaColor.a = (end.a - start.a) / particle->timeToLive;

	// size
	float startS = m_fStartSize + m_fStartSizeVar * CCRANDOM_MINUS1_1();
	startS = MAX(0, startS); // No negative value
    startS *= CC_CONTENT_SCALE_FACTOR();

	particle->size = startS;

	if( m_fEndSize == kCCParticleStartSizeEqualToEndSize )
	{
		particle->deltaSize = 0;
	}
	else
	{
		float endS = m_fEndSize + m_fEndSizeVar * CCRANDOM_MINUS1_1();
		endS = MAX(0, endS); // No negative values
        endS *= CC_CONTENT_SCALE_FACTOR();
		particle->deltaSize = (endS - startS) / particle->timeToLive;
	}

	// rotation
	float startA = m_fStartSpin + m_fStartSpinVar * CCRANDOM_MINUS1_1();
	float endA = m_fEndSpin + m_fEndSpinVar * CCRANDOM_MINUS1_1();
	particle->rotation = startA;
	particle->deltaRotation = (endA - startA) / particle->timeToLive;

	// position
	if( m_ePositionType == kCCPositionTypeFree )
	{
        CCPoint p = this->convertToWorldSpace(CCPointZero);
		particle->startPos = ccpMult( p, CC_CONTENT_SCALE_FACTOR() );
	}
    else if ( m_ePositionType == kCCPositionTypeRelative )
    {
        particle->startPos = ccpMult( m_tPosition, CC_CONTENT_SCALE_FACTOR() );
    }

	// direction
	float a = CC_DEGREES_TO_RADIANS( m_fAngle + m_fAngleVar * CCRANDOM_MINUS1_1() );

	// Mode Gravity: A
	if( m_nEmitterMode == kCCParticleModeGravity )
	{
		CCPoint v(cosf( a ), sinf( a ));
		float s = modeA.speed + modeA.speedVar * CCRANDOM_MINUS1_1();
        s *= CC_CONTENT_SCALE_FACTOR();

		// direction
		particle->modeA.dir = ccpMult( v, s );

		// radial accel
		particle->modeA.radialAccel = modeA.radialAccel + modeA.radialAccelVar * CCRANDOM_MINUS1_1();
        particle->modeA.radialAccel *= CC_CONTENT_SCALE_FACTOR();

		// tangential accel
		particle->modeA.tangentialAccel = modeA.tangentialAccel + modeA.tangentialAccelVar * CCRANDOM_MINUS1_1();
        particle->modeA.tangentialAccel *= CC_CONTENT_SCALE_FACTOR();
    }

	// Mode Radius: B
	else {
		// Set the default diameter of the particle from the source position
		float startRadius = modeB.startRadius + modeB.startRadiusVar * CCRANDOM_MINUS1_1();
		float endRadius = modeB.endRadius + modeB.endRadiusVar * CCRANDOM_MINUS1_1();
        startRadius *= CC_CONTENT_SCALE_FACTOR();
        endRadius *= CC_CONTENT_SCALE_FACTOR();

		particle->modeB.radius = startRadius;

		if( modeB.endRadius == kCCParticleStartRadiusEqualToEndRadius )
			particle->modeB.deltaRadius = 0;
		else
			particle->modeB.deltaRadius = (endRadius - startRadius) / particle->timeToLive;

		particle->modeB.angle = a;
		particle->modeB.degreesPerSecond = CC_DEGREES_TO_RADIANS(modeB.rotatePerSecond + modeB.rotatePerSecondVar * CCRANDOM_MINUS1_1());
	}
}
void CCParticleSystem::stopSystem()
{
	m_bIsActive = false;
	m_fElapsed = m_fDuration;
	m_fEmitCounter = 0;
}
void CCParticleSystem::resetSystem()
{
	m_bIsActive = true;
	m_fElapsed = 0;
	for (m_uParticleIdx = 0; m_uParticleIdx < m_uParticleCount; ++m_uParticleIdx)
	{
		tCCParticle *p = &m_pParticles[m_uParticleIdx];
		p->timeToLive = 0;
	}
}
bool CCParticleSystem::isFull()
{
	return (m_uParticleCount == m_uTotalParticles);
}

// ParticleSystem - MainLoop
void CCParticleSystem::update(ccTime dt)
{
	if( m_bIsActive && m_fEmissionRate )
	{
		float rate = 1.0f / m_fEmissionRate;
		m_fEmitCounter += dt;
		while( m_uParticleCount < m_uTotalParticles && m_fEmitCounter > rate )
		{
			this->addParticle();
			m_fEmitCounter -= rate;
		}

		m_fElapsed += dt;
		if(m_fDuration != -1 && m_fDuration < m_fElapsed)
		{
			this->stopSystem();
		}
	}

	m_uParticleIdx = 0;

#if CC_ENABLE_PROFILERS
	/// @todo CCProfilingBeginTimingBlock(_profilingTimer);
#endif

	CCPoint currentPosition = CCPointZero;
	if( m_ePositionType == kCCPositionTypeFree )
	{
		currentPosition = this->convertToWorldSpace(CCPointZero);
        currentPosition.x *= CC_CONTENT_SCALE_FACTOR();
        currentPosition.y *= CC_CONTENT_SCALE_FACTOR();
	}
    else if ( m_ePositionType == kCCPositionTypeRelative )
    {
        currentPosition = m_tPosition;
        currentPosition.x *= CC_CONTENT_SCALE_FACTOR();
        currentPosition.y *= CC_CONTENT_SCALE_FACTOR();
    }

	while( m_uParticleIdx < m_uParticleCount )
	{
		tCCParticle *p = &m_pParticles[m_uParticleIdx];

		// life
		p->timeToLive -= dt;

		if( p->timeToLive > 0 )
		{
			// Mode A: gravity, direction, tangential accel & radial accel
			if( m_nEmitterMode == kCCParticleModeGravity )
			{
				CCPoint tmp, radial, tangential;

				radial = CCPointZero;
				// radial acceleration
				if(p->pos.x || p->pos.y)
					radial = ccpNormalize(p->pos);
				tangential = radial;
				radial = ccpMult(radial, p->modeA.radialAccel);

				// tangential acceleration
				float newy = tangential.x;
				tangential.x = -tangential.y;
				tangential.y = newy;
				tangential = ccpMult(tangential, p->modeA.tangentialAccel);

				// (gravity + radial + tangential) * dt
				tmp = ccpAdd( ccpAdd( radial, tangential), modeA.gravity);
				tmp = ccpMult( tmp, dt);
				p->modeA.dir = ccpAdd( p->modeA.dir, tmp);
				tmp = ccpMult(p->modeA.dir, dt);
				p->pos = ccpAdd( p->pos, tmp );
			}

			// Mode B: radius movement
			else {
				// Update the angle and radius of the particle.
				p->modeB.angle += p->modeB.degreesPerSecond * dt;
				p->modeB.radius += p->modeB.deltaRadius * dt;

				p->pos.x = - cosf(p->modeB.angle) * p->modeB.radius;
				p->pos.y = - sinf(p->modeB.angle) * p->modeB.radius;
			}

			// color
			p->color.r += (p->deltaColor.r * dt);
			p->color.g += (p->deltaColor.g * dt);
			p->color.b += (p->deltaColor.b * dt);
			p->color.a += (p->deltaColor.a * dt);

			// size
			p->size += (p->deltaSize * dt);
			p->size = MAX( 0, p->size );

			// angle
			p->rotation += (p->deltaRotation * dt);

			//
			// update values in quad
			//

			CCPoint	newPos;

			if( m_ePositionType == kCCPositionTypeFree || m_ePositionType == kCCPositionTypeRelative )
			{
				CCPoint diff = ccpSub( currentPosition, p->startPos );
				newPos = ccpSub(p->pos, diff);
			}
			else
			{
				newPos = p->pos;
			}

			updateQuadWithParticle(p, newPos);
			//updateParticleImp(self, updateParticleSel, p, newPos);

			// update particle counter
			++m_uParticleIdx;

		}
		else
		{
			// life < 0
			if( m_uParticleIdx != m_uParticleCount-1 )
			{
				m_pParticles[m_uParticleIdx] = m_pParticles[m_uParticleCount-1];
			}
			--m_uParticleCount;

			if( m_uParticleCount == 0 && m_bIsAutoRemoveOnFinish )
			{
				this->unscheduleUpdate();
				m_pParent->removeChild(this, true);
				return;
			}
		}
	}

#if CC_ENABLE_PROFILERS
	/// @todo CCProfilingEndTimingBlock(_profilingTimer);
#endif

//#ifdef CC_USES_VBO
	this->postStep();
//#endif
}
void CCParticleSystem::updateQuadWithParticle(tCCParticle* particle, const CCPoint& newPosition)
{
    CC_UNUSED_PARAM(particle);
    CC_UNUSED_PARAM(newPosition);
	// should be overriden
}
void CCParticleSystem::postStep()
{
	// should be overriden
}

// ParticleSystem - CCTexture protocol
void CCParticleSystem::setTexture(CCTexture2D* var)
{
	CC_SAFE_RETAIN(var);
	CC_SAFE_RELEASE(m_pTexture)
	m_pTexture = var;

	// If the new texture has No premultiplied alpha, AND the blendFunc hasn't been changed, then update it
	if( m_pTexture && ! m_pTexture->getHasPremultipliedAlpha() &&
		( m_tBlendFunc.src == CC_BLEND_SRC && m_tBlendFunc.dst == CC_BLEND_DST ) )
	{
		m_tBlendFunc.src = GL_SRC_ALPHA;
		m_tBlendFunc.dst = GL_ONE_MINUS_SRC_ALPHA;
	}
}
CCTexture2D * CCParticleSystem::getTexture()
{
	return m_pTexture;
}

// ParticleSystem - Additive Blending
void CCParticleSystem::setIsBlendAdditive(bool additive)
{
	if( additive )
	{
		m_tBlendFunc.src = GL_SRC_ALPHA;
		m_tBlendFunc.dst = GL_ONE;
	}
	else
	{
		if( m_pTexture && ! m_pTexture->getHasPremultipliedAlpha() )
		{
			m_tBlendFunc.src = GL_SRC_ALPHA;
			m_tBlendFunc.dst = GL_ONE_MINUS_SRC_ALPHA;
		}
		else
		{
			m_tBlendFunc.src = CC_BLEND_SRC;
			m_tBlendFunc.dst = CC_BLEND_DST;
		}
	}
}
bool CCParticleSystem::getIsBlendAdditive()
{
	return( m_tBlendFunc.src == GL_SRC_ALPHA && m_tBlendFunc.dst == GL_ONE);
}

// ParticleSystem - Properties of Gravity Mode
void CCParticleSystem::setTangentialAccel(float t)
{
	CCAssert( m_nEmitterMode == kCCParticleModeGravity, "Particle Mode should be Gravity");
	modeA.tangentialAccel = t;
}
float CCParticleSystem::getTangentialAccel()
{
	CCAssert( m_nEmitterMode == kCCParticleModeGravity, "Particle Mode should be Gravity");
	return modeA.tangentialAccel;
}
void CCParticleSystem::setTangentialAccelVar(float t)
{
	CCAssert( m_nEmitterMode == kCCParticleModeGravity, "Particle Mode should be Gravity");
	modeA.tangentialAccelVar = t;
}
float CCParticleSystem::getTangentialAccelVar()
{
	CCAssert( m_nEmitterMode == kCCParticleModeGravity, "Particle Mode should be Gravity");
	return modeA.tangentialAccelVar;
}
void CCParticleSystem::setRadialAccel(float t)
{
	CCAssert( m_nEmitterMode == kCCParticleModeGravity, "Particle Mode should be Gravity");
	modeA.radialAccel = t;
}
float CCParticleSystem::getRadialAccel()
{
	CCAssert( m_nEmitterMode == kCCParticleModeGravity, "Particle Mode should be Gravity");
	return modeA.radialAccel;
}
void CCParticleSystem::setRadialAccelVar(float t)
{
	CCAssert( m_nEmitterMode == kCCParticleModeGravity, "Particle Mode should be Gravity");
	modeA.radialAccelVar = t;
}
float CCParticleSystem::getRadialAccelVar()
{
	CCAssert( m_nEmitterMode == kCCParticleModeGravity, "Particle Mode should be Gravity");
	return modeA.radialAccelVar;
}
void CCParticleSystem::setGravity(const CCPoint& g)
{
	CCAssert( m_nEmitterMode == kCCParticleModeGravity, "Particle Mode should be Gravity");
	modeA.gravity = g;
}
const CCPoint& CCParticleSystem::getGravity()
{
	CCAssert( m_nEmitterMode == kCCParticleModeGravity, "Particle Mode should be Gravity");
	return modeA.gravity;
}
void CCParticleSystem::setSpeed(float speed)
{
	CCAssert( m_nEmitterMode == kCCParticleModeGravity, "Particle Mode should be Gravity");
	modeA.speed = speed;
}
float CCParticleSystem::getSpeed()
{
	CCAssert( m_nEmitterMode == kCCParticleModeGravity, "Particle Mode should be Gravity");
	return modeA.speed;
}
void CCParticleSystem::setSpeedVar(float speedVar)
{
	CCAssert( m_nEmitterMode == kCCParticleModeGravity, "Particle Mode should be Gravity");
	modeA.speedVar = speedVar;
}
float CCParticleSystem::getSpeedVar()
{
	CCAssert( m_nEmitterMode == kCCParticleModeGravity, "Particle Mode should be Gravity");
	return modeA.speedVar;
}

// ParticleSystem - Properties of Radius Mode
void CCParticleSystem::setStartRadius(float startRadius)
{
	CCAssert( m_nEmitterMode == kCCParticleModeRadius, "Particle Mode should be Radius");
	modeB.startRadius = startRadius;
}
float CCParticleSystem::getStartRadius()
{
	CCAssert( m_nEmitterMode == kCCParticleModeRadius, "Particle Mode should be Radius");
	return modeB.startRadius;
}
void CCParticleSystem::setStartRadiusVar(float startRadiusVar)
{
	CCAssert( m_nEmitterMode == kCCParticleModeRadius, "Particle Mode should be Radius");
	modeB.startRadiusVar = startRadiusVar;
}
float CCParticleSystem::getStartRadiusVar()
{
	CCAssert( m_nEmitterMode == kCCParticleModeRadius, "Particle Mode should be Radius");
	return modeB.startRadiusVar;
}
void CCParticleSystem::setEndRadius(float endRadius)
{
	CCAssert( m_nEmitterMode == kCCParticleModeRadius, "Particle Mode should be Radius");
	modeB.endRadius = endRadius;
}
float CCParticleSystem::getEndRadius()
{
	CCAssert( m_nEmitterMode == kCCParticleModeRadius, "Particle Mode should be Radius");
	return modeB.endRadius;
}
void CCParticleSystem::setEndRadiusVar(float endRadiusVar)
{
	CCAssert( m_nEmitterMode == kCCParticleModeRadius, "Particle Mode should be Radius");
	modeB.endRadiusVar = endRadiusVar;
}
float CCParticleSystem::getEndRadiusVar()
{
	CCAssert( m_nEmitterMode == kCCParticleModeRadius, "Particle Mode should be Radius");
	return modeB.endRadiusVar;
}
void CCParticleSystem::setRotatePerSecond(float degrees)
{
	CCAssert( m_nEmitterMode == kCCParticleModeRadius, "Particle Mode should be Radius");
	modeB.rotatePerSecond = degrees;
}
float CCParticleSystem::getRotatePerSecond()
{
	CCAssert( m_nEmitterMode == kCCParticleModeRadius, "Particle Mode should be Radius");
	return modeB.rotatePerSecond;
}
void CCParticleSystem::setRotatePerSecondVar(float degrees)
{
	CCAssert( m_nEmitterMode == kCCParticleModeRadius, "Particle Mode should be Radius");
	modeB.rotatePerSecondVar = degrees;
}
float CCParticleSystem::getRotatePerSecondVar()
{
	CCAssert( m_nEmitterMode == kCCParticleModeRadius, "Particle Mode should be Radius");
	return modeB.rotatePerSecondVar;
}
bool CCParticleSystem::getIsActive()
{
	return m_bIsActive;
}
unsigned int CCParticleSystem::getParticleCount()
{
	return m_uParticleCount;
}
float CCParticleSystem::getDuration()
{
	return m_fDuration;
}
void CCParticleSystem::setDuration(float var)
{
	m_fDuration = var;
}
const CCPoint& CCParticleSystem::getSourcePosition()
{
	return m_tSourcePosition;
}
void CCParticleSystem::setSourcePosition(const CCPoint& var)
{
	m_tSourcePosition = var;
}
const CCPoint& CCParticleSystem::getPosVar()
{
	return m_tPosVar;
}
void CCParticleSystem::setPosVar(const CCPoint& var)
{
	m_tPosVar = var;
}
float CCParticleSystem::getLife()
{
	return m_fLife;
}
void CCParticleSystem::setLife(float var)
{
	m_fLife = var;
}
float CCParticleSystem::getLifeVar()
{
	return m_fLifeVar;
}
void CCParticleSystem::setLifeVar(float var)
{
	m_fLifeVar = var;
}
float CCParticleSystem::getAngle()
{
	return m_fAngle;
}
void CCParticleSystem::setAngle(float var)
{
	m_fAngle = var;
}
float CCParticleSystem::getAngleVar()
{
	return m_fAngleVar;
}
void CCParticleSystem::setAngleVar(float var)
{
	m_fAngleVar = var;
}
float CCParticleSystem::getStartSize()
{
	return m_fStartSize;
}
void CCParticleSystem::setStartSize(float var)
{
	m_fStartSize = var;
}
float CCParticleSystem::getStartSizeVar()
{
	return m_fStartSizeVar;
}
void CCParticleSystem::setStartSizeVar(float var)
{
	m_fStartSizeVar = var;
}
float CCParticleSystem::getEndSize()
{
	return m_fEndSize;
}
void CCParticleSystem::setEndSize(float var)
{
	m_fEndSize = var;
}
float CCParticleSystem::getEndSizeVar()
{
	return m_fEndSizeVar;
}
void CCParticleSystem::setEndSizeVar(float var)
{
	m_fEndSizeVar = var;
}
const ccColor4F& CCParticleSystem::getStartColor()
{
	return m_tStartColor;
}
void CCParticleSystem::setStartColor(const ccColor4F& var)
{
	m_tStartColor = var;
}
const ccColor4F& CCParticleSystem::getStartColorVar()
{
	return m_tStartColorVar;
}
void CCParticleSystem::setStartColorVar(const ccColor4F& var)
{
	m_tStartColorVar = var;
}
const ccColor4F& CCParticleSystem::getEndColor()
{
	return m_tEndColor;
}
void CCParticleSystem::setEndColor(const ccColor4F& var)
{
	m_tEndColor = var;
}
const ccColor4F& CCParticleSystem::getEndColorVar()
{
	return m_tEndColorVar;
}
void CCParticleSystem::setEndColorVar(const ccColor4F& var)
{
	m_tEndColorVar = var;
}
float CCParticleSystem::getStartSpin()
{
	return m_fStartSpin;
}
void CCParticleSystem::setStartSpin(float var)
{
	m_fStartSpin = var;
}
float CCParticleSystem::getStartSpinVar()
{
	return m_fStartSpinVar;
}
void CCParticleSystem::setStartSpinVar(float var)
{
	m_fStartSpinVar = var;
}
float CCParticleSystem::getEndSpin()
{
	return m_fEndSpin;
}
void CCParticleSystem::setEndSpin(float var)
{
	m_fEndSpin = var;
}
float CCParticleSystem::getEndSpinVar()
{
	return m_fEndSpinVar;
}
void CCParticleSystem::setEndSpinVar(float var)
{
	m_fEndSpinVar = var;
}
float CCParticleSystem::getEmissionRate()
{
	return m_fEmissionRate;
}
void CCParticleSystem::setEmissionRate(float var)
{
	m_fEmissionRate = var;
}
unsigned int CCParticleSystem::getTotalParticles()
{
	return m_uTotalParticles;
}
void CCParticleSystem::setTotalParticles(unsigned int var)
{
	m_uTotalParticles = var;
}
ccBlendFunc CCParticleSystem::getBlendFunc()
{
	return m_tBlendFunc;
}
void CCParticleSystem::setBlendFunc(ccBlendFunc var)
{
	m_tBlendFunc = var;
}
tCCPositionType CCParticleSystem::getPositionType()
{
	return m_ePositionType;
}
void CCParticleSystem::setPositionType(tCCPositionType var)
{
	m_ePositionType = var;
}
bool CCParticleSystem::getIsAutoRemoveOnFinish()
{
	return m_bIsAutoRemoveOnFinish;
}
void CCParticleSystem::setIsAutoRemoveOnFinish(bool var)
{
	m_bIsAutoRemoveOnFinish = var;
}
int CCParticleSystem::getEmitterMode()
{
	return m_nEmitterMode;
}
void CCParticleSystem::setEmitterMode(int var)
{
	m_nEmitterMode = var;
}

}// namespace cocos2d

license: mit


code:
/****************************************************************************
Copyright (c) 2010-2011 cocos2d-x.org
Copyright (c) 2008-2010 Ricardo Quesada
Copyright (c) 2011      Zynga Inc.

http://www.cocos2d-x.org

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "CCParticleSystemPoint.h"
#include "platform/CCGL.h"

namespace cocos2d {

#if (CC_TARGET_PLATFORM != CC_PLATFORM_LINUX) && (CC_TARGET_PLATFORM != CC_PLATFORM_QNX)

//implementation CCParticleSystemPoint
bool CCParticleSystemPoint::initWithTotalParticles(unsigned int numberOfParticles)
{
	if( CCParticleSystem::initWithTotalParticles(numberOfParticles) )
	{
		m_pVertices = new ccPointSprite[m_uTotalParticles];

		if( ! m_pVertices )
		{
			CCLOG("cocos2d: Particle system: not enough memory");
			this->release();
			return false;
		}

#if CC_USES_VBO
		glGenBuffers(1, &m_uVerticesID);

		// initial binding
		glBindBuffer(GL_ARRAY_BUFFER, m_uVerticesID);
		glBufferData(GL_ARRAY_BUFFER, sizeof(ccPointSprite)*m_uTotalParticles, m_pVertices, GL_DYNAMIC_DRAW);
		glBindBuffer(GL_ARRAY_BUFFER, 0);
#endif
		return true;
	}
	return false;
}
CCParticleSystemPoint::~CCParticleSystemPoint()
{
    CC_SAFE_DELETE(m_pVertices);
#if CC_USES_VBO
	glDeleteBuffers(1, &m_uVerticesID);
#endif
}

// implementation CCParticleSystemPoint
CCParticleSystemPoint * CCParticleSystemPoint::particleWithFile(const char *plistFile)
{
    CCParticleSystemPoint *pRet = new CCParticleSystemPoint();
    if (pRet && pRet->initWithFile(plistFile))
    {
        pRet->autorelease();
        return pRet;
    }
    CC_SAFE_DELETE(pRet)
        return pRet;
}

void CCParticleSystemPoint::updateQuadWithParticle(tCCParticle* particle, const CCPoint& newPosition)
{
	// place vertices and colos in array
    m_pVertices[m_uParticleIdx].pos = vertex2(newPosition.x, newPosition.y);
	m_pVertices[m_uParticleIdx].size = particle->size;
	ccColor4B color = {(GLubyte)(particle->color.r * 255), (GLubyte)(particle->color.g * 255), (GLubyte)(particle->color.b * 255),
		(GLubyte)(particle->color.a * 255)};
	m_pVertices[m_uParticleIdx].color = color;
}
void CCParticleSystemPoint::postStep()
{
#if CC_USES_VBO
	glBindBuffer(GL_ARRAY_BUFFER, m_uVerticesID);
	glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(ccPointSprite)*m_uParticleCount, m_pVertices);
	glBindBuffer(GL_ARRAY_BUFFER, 0);
#endif
}
void CCParticleSystemPoint::draw()
{
	CCParticleSystem::draw();

	if (m_uParticleIdx==0)
	{
		return;
	}

	// Default GL states: GL_TEXTURE_2D, GL_VERTEX_ARRAY, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY
	// Needed states: GL_TEXTURE_2D, GL_VERTEX_ARRAY, GL_COLOR_ARRAY
	// Unneeded states: GL_TEXTURE_COORD_ARRAY
	glDisableClientState(GL_TEXTURE_COORD_ARRAY);

	glBindTexture(GL_TEXTURE_2D, m_pTexture->getName());

	glEnable(GL_POINT_SPRITE_OES);
	glTexEnvi( GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, GL_TRUE );

#define kPointSize sizeof(m_pVertices[0])

#if CC_USES_VBO
	glBindBuffer(GL_ARRAY_BUFFER, m_uVerticesID);

#if CC_ENABLE_CACHE_TEXTTURE_DATA
    glBufferData(GL_ARRAY_BUFFER, sizeof(ccPointSprite)*m_uTotalParticles, m_pVertices, GL_DYNAMIC_DRAW);
#endif

	glVertexPointer(2,GL_FLOAT,kPointSize,0);

	glColorPointer(4, GL_UNSIGNED_BYTE, kPointSize,(GLvoid*)offsetof(ccPointSprite,color) );

	glEnableClientState(GL_POINT_SIZE_ARRAY_OES);

	glPointSizePointerOES(GL_FLOAT,kPointSize,(GLvoid*) offsetof(ccPointSprite,size) );

#else // Uses Vertex Array List
    int offset = (int)m_pVertices;
    glVertexPointer(2,GL_FLOAT, kPointSize, (GLvoid*) offset);

    int diff = offsetof(ccPointSprite, color);
    glColorPointer(4, GL_UNSIGNED_BYTE, kPointSize, (GLvoid*) (offset+diff));

    glEnableClientState(GL_POINT_SIZE_ARRAY_OES);
    diff = offsetof(ccPointSprite, size);
    glPointSizePointerOES(GL_FLOAT, kPointSize, (GLvoid*) (offset+diff));
#endif

    bool newBlend = (m_tBlendFunc.src != CC_BLEND_SRC || m_tBlendFunc.dst != CC_BLEND_DST) ? true : false;
	if( newBlend )
	{
		glBlendFunc( m_tBlendFunc.src, m_tBlendFunc.dst );
	}

	glDrawArrays(GL_POINTS, 0, m_uParticleIdx);

	// restore blend state
	if( newBlend )
		glBlendFunc( CC_BLEND_SRC, CC_BLEND_DST);

#if CC_USES_VBO
	// unbind VBO buffer
	glBindBuffer(GL_ARRAY_BUFFER, 0);
#endif

	glDisableClientState(GL_POINT_SIZE_ARRAY_OES);
	glDisable(GL_POINT_SPRITE_OES);

	// restore GL default state
	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
}

// Non supported properties

//
// SPIN IS NOT SUPPORTED
//
void CCParticleSystemPoint::setStartSpin(float var)
{
	CCAssert(var == 0, "PointParticleSystem doesn't support spinning");
	CCParticleSystem::setStartSpin(var);
}
void CCParticleSystemPoint::setStartSpinVar(float var)
{
	CCAssert(var == 0, "PointParticleSystem doesn't support spinning");
	CCParticleSystem::setStartSpinVar(var);
}
void CCParticleSystemPoint::setEndSpin(float var)
{
	CCAssert(var == 0, "PointParticleSystem doesn't support spinning");
	CCParticleSystem::setEndSpin(var);
}
void CCParticleSystemPoint::setEndSpinVar(float var)
{
	CCAssert(var == 0, "PointParticleSystem doesn't support spinning");
	CCParticleSystem::setEndSpinVar(var);
}
//
// SIZE > 64 IS NOT SUPPORTED
//
void CCParticleSystemPoint::setStartSize(float size)
{
	CCAssert(size >= 0 && size <= CC_MAX_PARTICLE_SIZE, "PointParticleSystem only supports 0 <= size <= 64");
	CCParticleSystem::setStartSize(size);
}
void CCParticleSystemPoint::setEndSize(float size)
{
	CCAssert( (size == kCCParticleStartSizeEqualToEndSize) ||
		( size >= 0 && size <= CC_MAX_PARTICLE_SIZE), "PointParticleSystem only supports 0 <= size <= 64");
	CCParticleSystem::setEndSize(size);
}

#endif // (CC_TARGET_PLATFORM != CC_PLATFORM_LINUX)

}// namespace cocos2d


code:
/****************************************************************************
Copyright (c) 2010-2011 cocos2d-x.org
Copyright (c) 2008-2010 Ricardo Quesada
Copyright (c) 2009		Leonardo Kasperavičius
Copyright (c) 2011      Zynga Inc.

http://www.cocos2d-x.org

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/

#include "platform/CCGL.h"

#include "CCParticleSystemQuad.h"
#include "CCSpriteFrame.h"
#include "CCDirector.h"

namespace cocos2d {

//implementation CCParticleSystemQuad
// overriding the init method
bool CCParticleSystemQuad::initWithTotalParticles(unsigned int numberOfParticles)
{
	// base initialization
	if( CCParticleSystem::initWithTotalParticles(numberOfParticles) )
	{
		// allocating data space
		m_pQuads = new ccV2F_C4B_T2F_Quad[m_uTotalParticles];
		m_pIndices = new GLushort[m_uTotalParticles * 6];

		if( !m_pQuads || !m_pIndices)
		{
			CCLOG("cocos2d: Particle system: not enough memory");
			if( m_pQuads )
				delete [] m_pQuads;
			if(m_pIndices)
				delete [] m_pIndices;
			this->release();
			return NULL;
		}

		// initialize only once the texCoords and the indices
        if (m_pTexture)
        {
            this->initTexCoordsWithRect(CCRectMake((float)0, (float)0, (float)m_pTexture->getPixelsWide(), (float)m_pTexture->getPixelsHigh()));
        }
        else
        {
            this->initTexCoordsWithRect(CCRectMake((float)0, (float)0, (float)1, (float)1));
        }

		this->initIndices();

#if CC_USES_VBO
		glEnable(GL_VERTEX_ARRAY);

		// create the VBO buffer
		glGenBuffers(1, &m_uQuadsID);

		// initial binding
		glBindBuffer(GL_ARRAY_BUFFER, m_uQuadsID);
		glBufferData(GL_ARRAY_BUFFER, sizeof(m_pQuads[0])*m_uTotalParticles, m_pQuads, GL_DYNAMIC_DRAW);
		glBindBuffer(GL_ARRAY_BUFFER, 0);
#endif
		return true;
	}
	return false;
}
CCParticleSystemQuad::~CCParticleSystemQuad()
{
	CC_SAFE_DELETE_ARRAY(m_pQuads);
	CC_SAFE_DELETE_ARRAY(m_pIndices);
#if CC_USES_VBO
    glDeleteBuffers(1, &m_uQuadsID);
#endif
}

// implementation CCParticleSystemQuad
CCParticleSystemQuad * CCParticleSystemQuad::particleWithFile(const char *plistFile)
{
    CCParticleSystemQuad *pRet = new CCParticleSystemQuad();
    if (pRet && pRet->initWithFile(plistFile))
    {
        pRet->autorelease();
        return pRet;
    }
    CC_SAFE_DELETE(pRet)
        return pRet;
}

// pointRect should be in Texture coordinates, not pixel coordinates
void CCParticleSystemQuad::initTexCoordsWithRect(const CCRect& pointRect)
{
    // convert to pixels coords

    CCRect rect = CCRectMake(
        pointRect.origin.x * CC_CONTENT_SCALE_FACTOR(),
        pointRect.origin.y * CC_CONTENT_SCALE_FACTOR(),
        pointRect.size.width * CC_CONTENT_SCALE_FACTOR(),
        pointRect.size.height * CC_CONTENT_SCALE_FACTOR());

    GLfloat wide = (GLfloat) pointRect.size.width;
    GLfloat high = (GLfloat) pointRect.size.height;

    if (m_pTexture)
    {
        wide = (GLfloat)m_pTexture->getPixelsWide();
        high = (GLfloat)m_pTexture->getPixelsHigh();
    }

#if CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL
    GLfloat left = (rect.origin.x*2+1) / (wide*2);
    GLfloat bottom = (rect.origin.y*2+1) / (high*2);
    GLfloat right = left + (rect.size.width*2-2) / (wide*2);
    GLfloat top = bottom + (rect.size.height*2-2) / (high*2);
#else
    GLfloat left = rect.origin.x / wide;
    GLfloat bottom = rect.origin.y / high;
    GLfloat right = left + rect.size.width / wide;
    GLfloat top = bottom + rect.size.height / high;
#endif // ! CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL

	// Important. Texture in cocos2d are inverted, so the Y component should be inverted
	CC_SWAP( top, bottom, float);

	for(unsigned int i=0; i<m_uTotalParticles; i++)
	{
		// bottom-left vertex:
		m_pQuads[i].bl.texCoords.u = left;
		m_pQuads[i].bl.texCoords.v = bottom;
		// bottom-right vertex:
		m_pQuads[i].br.texCoords.u = right;
		m_pQuads[i].br.texCoords.v = bottom;
		// top-left vertex:
		m_pQuads[i].tl.texCoords.u = left;
		m_pQuads[i].tl.texCoords.v = top;
		// top-right vertex:
		m_pQuads[i].tr.texCoords.u = right;
		m_pQuads[i].tr.texCoords.v = top;
	}
}
void CCParticleSystemQuad::setTextureWithRect(CCTexture2D *texture, const CCRect& rect)
{
	// Only update the texture if is different from the current one
	if( !m_pTexture || texture->getName() != m_pTexture->getName() )
	{
		CCParticleSystem::setTexture(texture);
	}

	this->initTexCoordsWithRect(rect);
}
void CCParticleSystemQuad::setTexture(CCTexture2D* texture)
{
	const CCSize& s = texture->getContentSize();
	this->setTextureWithRect(texture, CCRectMake(0, 0, s.width, s.height));
}
void CCParticleSystemQuad::setDisplayFrame(CCSpriteFrame *spriteFrame)
{
	CCAssert( CCPoint::CCPointEqualToPoint( spriteFrame->getOffsetInPixels() , CCPointZero ), "QuadParticle only supports SpriteFrames with no offsets");

	// update texture before updating texture rect
	if ( !m_pTexture || spriteFrame->getTexture()->getName() != m_pTexture->getName())
	{
		this->setTexture(spriteFrame->getTexture());
	}
}
void CCParticleSystemQuad::initIndices()
{
	for(unsigned int i = 0; i < m_uTotalParticles; ++i)
	{
        const unsigned int i6 = i*6;
        const unsigned int i4 = i*4;
		m_pIndices[i6+0] = (GLushort) i4+0;
		m_pIndices[i6+1] = (GLushort) i4+1;
		m_pIndices[i6+2] = (GLushort) i4+2;

		m_pIndices[i6+5] = (GLushort) i4+1;
		m_pIndices[i6+4] = (GLushort) i4+2;
		m_pIndices[i6+3] = (GLushort) i4+3;
	}
}
void CCParticleSystemQuad::updateQuadWithParticle(tCCParticle* particle, const CCPoint& newPosition)
{
	// colors
    ccV2F_C4B_T2F_Quad *quad = &(m_pQuads[m_uParticleIdx]);

	ccColor4B color = {(GLubyte)(particle->color.r * 255), (GLubyte)(particle->color.g * 255), (GLubyte)(particle->color.b * 255),
		(GLubyte)(particle->color.a * 255)};
	quad->bl.colors = color;
	quad->br.colors = color;
	quad->tl.colors = color;
	quad->tr.colors = color;

	// vertices
	GLfloat size_2 = particle->size/2;
	if( particle->rotation )
	{
		GLfloat x1 = -size_2;
		GLfloat y1 = -size_2;

		GLfloat x2 = size_2;
		GLfloat y2 = size_2;
		GLfloat x = newPosition.x;
		GLfloat y = newPosition.y;

		GLfloat r = (GLfloat)-CC_DEGREES_TO_RADIANS(particle->rotation);
		GLfloat cr = cosf(r);
		GLfloat sr = sinf(r);
		GLfloat ax = x1 * cr - y1 * sr + x;
		GLfloat ay = x1 * sr + y1 * cr + y;
		GLfloat bx = x2 * cr - y1 * sr + x;
		GLfloat by = x2 * sr + y1 * cr + y;
		GLfloat cx = x2 * cr - y2 * sr + x;
		GLfloat cy = x2 * sr + y2 * cr + y;
		GLfloat dx = x1 * cr - y2 * sr + x;
		GLfloat dy = x1 * sr + y2 * cr + y;

		// bottom-left
		quad->bl.vertices.x = ax;
		quad->bl.vertices.y = ay;

		// bottom-right vertex:
		quad->br.vertices.x = bx;
		quad->br.vertices.y = by;

		// top-left vertex:
		quad->tl.vertices.x = dx;
		quad->tl.vertices.y = dy;

		// top-right vertex:
		quad->tr.vertices.x = cx;
		quad->tr.vertices.y = cy;
	} else {
		// bottom-left vertex:
		quad->bl.vertices.x = newPosition.x - size_2;
		quad->bl.vertices.y = newPosition.y - size_2;

		// bottom-right vertex:
		quad->br.vertices.x = newPosition.x + size_2;
		quad->br.vertices.y = newPosition.y - size_2;

		// top-left vertex:
		quad->tl.vertices.x = newPosition.x - size_2;
		quad->tl.vertices.y = newPosition.y + size_2;

		// top-right vertex:
		quad->tr.vertices.x = newPosition.x + size_2;
		quad->tr.vertices.y = newPosition.y + size_2;
	}
}
void CCParticleSystemQuad::postStep()
{
#if CC_USES_VBO
	glBindBuffer(GL_ARRAY_BUFFER, m_uQuadsID);
	glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(m_pQuads[0])*m_uParticleCount, m_pQuads);
	glBindBuffer(GL_ARRAY_BUFFER, 0);
#endif
}

// overriding draw method
void CCParticleSystemQuad::draw()
{	CCParticleSystem::draw();

	// Default GL states: GL_TEXTURE_2D, GL_VERTEX_ARRAY, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY
	// Needed states: GL_TEXTURE_2D, GL_VERTEX_ARRAY, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY
	// Unneeded states: -
	glBindTexture(GL_TEXTURE_2D, m_pTexture->getName());

#define kQuadSize sizeof(m_pQuads[0].bl)

#if CC_USES_VBO
    glBindBuffer(GL_ARRAY_BUFFER, m_uQuadsID);

#if CC_ENABLE_CACHE_TEXTTURE_DATA
    glBufferData(GL_ARRAY_BUFFER, sizeof(m_pQuads[0])*m_uTotalParticles, m_pQuads, GL_DYNAMIC_DRAW);
#endif

	glVertexPointer(2,GL_FLOAT, kQuadSize, 0);

	glColorPointer(4, GL_UNSIGNED_BYTE, kQuadSize, (GLvoid*) offsetof(ccV2F_C4B_T2F,colors) );

	glTexCoordPointer(2, GL_FLOAT, kQuadSize, (GLvoid*) offsetof(ccV2F_C4B_T2F,texCoords) );
#else   // vertex array list

    int offset = (int) m_pQuads;

    // vertex
    int diff = offsetof( ccV2F_C4B_T2F, vertices);
    glVertexPointer(2,GL_FLOAT, kQuadSize, (GLvoid*) (offset+diff) );

    // color
    diff = offsetof( ccV2F_C4B_T2F, colors);
    glColorPointer(4, GL_UNSIGNED_BYTE, kQuadSize, (GLvoid*)(offset + diff));

    // tex coords
    diff = offsetof( ccV2F_C4B_T2F, texCoords);
    glTexCoordPointer(2, GL_FLOAT, kQuadSize, (GLvoid*)(offset + diff));

#endif // ! CC_USES_VBO

    bool newBlend = (m_tBlendFunc.src != CC_BLEND_SRC || m_tBlendFunc.dst != CC_BLEND_DST) ? true : false;
	if( newBlend )
	{
		glBlendFunc( m_tBlendFunc.src, m_tBlendFunc.dst );
	}

    CCAssert( m_uParticleIdx == m_uParticleCount, "Abnormal error in particle quad");

	glDrawElements(GL_TRIANGLES, (GLsizei)(m_uParticleIdx*6), GL_UNSIGNED_SHORT, m_pIndices);

	// restore blend state
	if( newBlend )
		glBlendFunc( CC_BLEND_SRC, CC_BLEND_DST );

#if CC_USES_VBO
	glBindBuffer(GL_ARRAY_BUFFER, 0);
#endif

	// restore GL default state
	// -
}

}// namespace cocos2d


code:
/****************************************************************************
Copyright (c) 2010 cocos2d-x.org

http://www.cocos2d-x.org

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#ifndef __CC_UIACCELEROMETER_PLATFORM_H__
#define __CC_UIACCELEROMETER_PLATFORM_H__

#include "CCPlatformConfig.h"

#if (CC_TARGET_PLATFORM == CC_PLATFORM_WOPHONE)
    #include "wophone/CCAccelerometer_wophone.h"
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
    #include "win32/CCAccelerometer_win32.h"
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
    #include "android/CCAccelerometer_android.h"
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
    #include "ios/CCAccelerometer_ios.h"
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_MARMALADE)
	#include "marmalade/CCAccelerometer_marmalade.h"
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_LINUX)
	#include "linux/CCAccelerometer_linux.h"
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_BADA)
	#include "bada/CCAccelerometer_bada.h"
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_QNX)
    #include "qnx/CCAccelerometer_qnx.h"
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_QT)
    #include "qt/CCAccelerometer_qt.h"
#else
    #error
#endif

#endif // __CC_UIACCELEROMETER_PLATFORM_H__


code:
/****************************************************************************
Copyright (c) 2010 cocos2d-x.org

http://www.cocos2d-x.org

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/

#ifndef __CC_APPLICATION_PLATFORM_H__
#define __CC_APPLICATION_PLATFORM_H__

#include "CCPlatformConfig.h"

#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
    #include "win32/CCApplication_win32.h"
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
    #include "android/CCApplication_android.h"
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
    # include "ios/CCApplication_ios.h"
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_WOPHONE)
    #include "wophone/CCApplication_wophone.h"
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_MARMALADE)
	#include "marmalade/CCApplication_marmalade.h"
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_LINUX)
	#include "linux/CCApplication_linux.h"
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_BADA)
	#include "bada/CCApplication_bada.h"
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_QNX)
    #include "qnx/CCApplication_qnx.h"
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_QT)
    #include "qt/CCApplication_qt.h"
#else
    #error
#endif

#endif	// __CC_APPLICATION_PLATFORM_H__


code:
/*
* cocos2d for iPhone: http://www.cocos2d-iphone.org
*
* Copyright (c) 2008-2010 Ricardo Quesada
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/

#include "CCPlatformConfig.h"

// build each architecture with the optimal particle system

// ARMv7, Mac or Simulator use "Quad" particle
#if defined(__ARM_NEON__) ||  \
	(CC_TARGET_PLATFORM == CC_PLATFORM_MARMALADE) || \
	(CC_TARGET_PLATFORM == CC_PLATFORM_IOS)		|| \
	(CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)	|| \
	(CC_TARGET_PLATFORM == CC_PLATFORM_WOPHONE) || \
	(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) || \
	(CC_TARGET_PLATFORM == CC_PLATFORM_LINUX) || \
	(CC_TARGET_PLATFORM == CC_PLATFORM_BADA) || \
    (CC_TARGET_PLATFORM == CC_PLATFORM_QNX) || \
    (CC_TARGET_PLATFORM == CC_PLATFORM_QT)

#include "CCParticleSystemQuad.h"
#define ARCH_OPTIMAL_PARTICLE_SYSTEM CCParticleSystemQuad

// ARMv6 use "Point" particle
#elif __arm__
#include "CCParticleSystemPoint.h"
#define ARCH_OPTIMAL_PARTICLE_SYSTEM CCParticleSystemPoint

#else
#error "unknown architecture"
#endif


code:
/****************************************************************************
Copyright (c) 2010 cocos2d-x.org

http://www.cocos2d-x.org

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/

#include "CCCommon.h"

#define MAX_LEN         (cocos2d::kMaxLogLen + 1)

/****************************************************
 * win32
 ***************************************************/
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
#include <Windows.h>

#include "CCStdC.h"

NS_CC_BEGIN;

void CCLog(const char * pszFormat, ...)
{
    char szBuf[MAX_LEN];

    va_list ap;
    va_start(ap, pszFormat);
    vsnprintf_s(szBuf, MAX_LEN, MAX_LEN, pszFormat, ap);
    va_end(ap);

    WCHAR wszBuf[MAX_LEN] = {0};
    MultiByteToWideChar(CP_UTF8, 0, szBuf, -1, wszBuf, sizeof(wszBuf));
    OutputDebugStringW(wszBuf);
    OutputDebugStringA("\n");
}

void CCMessageBox(const char * pszMsg, const char * pszTitle)
{
    MessageBoxA(NULL, pszMsg, pszTitle, MB_OK);
}

NS_CC_END;

#endif  // CC_PLATFORM_WIN32

/****************************************************
 * wophone
 ***************************************************/
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WOPHONE)
#include "TG3.h"

static char s_szLogFilePath[EOS_FILE_MAX_PATH] = {0};

NS_CC_BEGIN;

void CCLog(const char * pszFormat, ...)
{
    if (! s_szLogFilePath[0])
    {
        // save the log file named "Cocos2dxLog.txt" to the directory which the app.so in.
        TUChar AppID[EOS_FILE_MAX_PATH] = {0};
        UInt32 nCmdType = 0;
        Int32  nRet = SS_AppRequest_GetAppName(AppID, &nCmdType);
        if (nRet < 0)
        {
            return;
        }

        TUChar AppPath[EOS_FILE_MAX_PATH] = {0};
        if (SS_GetApplicationPath(AppID, SS_APP_PATH_TYPE_EXECUTABLE, AppPath) < 0)
        {
            return;
        }
        char szAppPath[EOS_FILE_MAX_PATH] = {0};
        TUString::StrUnicodeToStrUtf8((Char*) szAppPath, AppPath);
#ifndef _TRANZDA_VM_
        strcpy(s_szLogFilePath, "");
#else
        strcpy(s_szLogFilePath, "D:/Work7");
#endif
        strcat(s_szLogFilePath, szAppPath);
        strcat(s_szLogFilePath, "Cocos2dxLog.txt");
    }

    char szBuf[MAX_LEN];

    va_list ap;
    va_start(ap, pszFormat);
#ifdef _TRANZDA_VM_
    vsprintf_s(szBuf, MAX_LEN, pszFormat, ap);
#else
    vsnprintf(szBuf, MAX_LEN, pszFormat, ap);
#endif
    va_end(ap);

#ifdef _TRANZDA_VM_
    WCHAR wszBuf[MAX_LEN] = {0};
    MultiByteToWideChar(CP_UTF8, 0, szBuf, -1, wszBuf, sizeof(wszBuf));
    OutputDebugStringW(wszBuf);
    OutputDebugStringA("\n");
#else
    FILE * pf = fopen(s_szLogFilePath, "a+");
    if (! pf)
    {
        return;
    }

    fwrite(szBuf, 1, strlen(szBuf), pf);
    fwrite("\r\n", 1, strlen("\r\n"), pf);
    fflush(pf);
    fclose(pf);
#endif
}

void CCMessageBox(const char * pszMsg, const char * pszTitle)
{
    TUChar tszMsg[MAX_LEN] = { 0 };
    TUChar tszTitle[MAX_LEN] = { 0 };
    TUString::StrUtf8ToStrUnicode(tszMsg,(Char*)pszMsg);
    TUString::StrUtf8ToStrUnicode(tszTitle,(Char*)pszTitle);
    TMessageBox box(tszMsg, tszTitle, WMB_OK);
    box.Show();
}

NS_CC_END;

#endif  // CC_PLATFORM_WOPHONE

/****************************************************
 * ios
 ***************************************************/
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)

// implement in CCCommon_iso.mm

#endif  // CC_PLATFORM_IOS

/****************************************************
 * android
 ***************************************************/
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)

#include <android/log.h>
#include <stdio.h>
#include <jni.h>

#include "android/jni/MessageJni.h"

NS_CC_BEGIN;

void CCLog(const char * pszFormat, ...)
{
	char buf[MAX_LEN];

	va_list args;
	va_start(args, pszFormat);
	vsprintf(buf, pszFormat, args);
	va_end(args);

	__android_log_print(ANDROID_LOG_DEBUG, "cocos2d-x debug info",  buf);
}

void CCMessageBox(const char * pszMsg, const char * pszTitle)
{
	showMessageBoxJNI(pszMsg, pszTitle);
}

NS_CC_END;

#endif // CC_PLATFORM_ANDROID
/****************************************************
 * linux
 ***************************************************/
#if (CC_TARGET_PLATFORM == CC_PLATFORM_LINUX)

#include <stdio.h>
#include "CCStdC.h"

NS_CC_BEGIN;

void CCLog(const char * pszFormat, ...)
{
	char buf[MAX_LEN];

	va_list args;
	va_start(args, pszFormat);
	vsprintf(buf, pszFormat, args);
	va_end(args);

	//TODO will copy how orx do
	printf(buf);
}

// marmalade no MessageBox, use CCLog instead
void CCMessageBox(const char * pszMsg, const char * pszTitle)
{
    CCLog("%s: %s", pszTitle, pszMsg);
}

NS_CC_END;
#endif
/****************************************************
 * marmalade
 ***************************************************/
#if (CC_TARGET_PLATFORM == CC_PLATFORM_MARMALADE)

#include <s3e.h>
#include "IwUtil.h"
#include "IwUtilInitTerm.h"
#include <IwMemBucketHelpers.h>
#include <stdio.h>

NS_CC_BEGIN;

void CCLog(const char * pszFormat, ...)
{
	char buf[MAX_LEN];

	va_list args;
	va_start(args, pszFormat);
	vsprintf(buf, pszFormat, args);
	va_end(args);

	IwTrace(GAME, (buf));
}

// marmalade no MessageBox, use CCLog instead
void CCMessageBox(const char * pszMsg, const char * pszTitle)
{
    CCLog("%s: %s", pszTitle, pszMsg);
}

NS_CC_END;

#endif // CC_PLATFORM_MARMALADE

/****************************************************
 * bada
 ***************************************************/
#if (CC_TARGET_PLATFORM == CC_PLATFORM_BADA)
#include <FBaseSys.h>
#include <FUi.h>
#include <stdio.h>
#include <stdarg.h>

using namespace Osp::Ui::Controls;

NS_CC_BEGIN;

void CCLog(const char * pszFormat, ...)
{
	char buf[MAX_LEN] = {0};

	va_list args;
	va_start(args, pszFormat);
	vsnprintf(buf, MAX_LEN, pszFormat, args);
	va_end(args);
	__App_info(__PRETTY_FUNCTION__ , __LINE__, buf);
}

void CCMessageBox(const char * pszMsg, const char * pszTitle)
{
	if (pszMsg != NULL && pszTitle != NULL)
	{
		int iRet = 0;
		MessageBox msgBox;
		msgBox.Construct(pszTitle, pszMsg, MSGBOX_STYLE_OK);
		msgBox.ShowAndWait(iRet);
	}
}

NS_CC_END;

#endif // CC_PLATFORM_BADA

/****************************************************
 * qnx
 ***************************************************/
#if (CC_TARGET_PLATFORM == CC_PLATFORM_QNX)
#include <cstdio>
#include <cstdarg>
#include <stdio.h>
#include <stdarg.h>
using namespace std;

NS_CC_BEGIN;

void CCLog(const char * pszFormat, ...)
{
	char buf[MAX_LEN];

	va_list args;
	va_start(args, pszFormat);
	vsprintf(buf, pszFormat, args);
	va_end(args);

	fprintf(stderr, "cocos2d-x debug info [%s]\n",  buf);
}

void CCMessageBox(const char * pszMsg, const char * pszTitle)
{
	CCLog("%s: %s", pszTitle, pszMsg);
}

NS_CC_END;

#endif // CC_PLATFORM_QNX

/****************************************************
 * qt
 ***************************************************/
#if (CC_TARGET_PLATFORM == CC_PLATFORM_QT)
#include <QDebug>

NS_CC_BEGIN;

void CCLog(const char * pszFormat, ...)
{
    char buf[MAX_LEN];

    va_list args;
    va_start(args, pszFormat);
    vsprintf(buf, pszFormat, args);
    va_end(args);

    qDebug() << "cocos2d-x debug info [" << buf << "]";
}

void CCMessageBox(const char * pszMsg, const char * pszTitle)
{
    // TODO: implement
    qDebug() << QString(pszMsg) << QString(pszTitle);
}

NS_CC_END;

#endif  // CC_PLATFORM_QT


code:
/****************************************************************************
Copyright (c) 2010 cocos2d-x.org

http://www.cocos2d-x.org

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/

#ifndef __CC_COMMON_H__
#define __CC_COMMON_H__

#include "CCPlatformMacros.h"

NS_CC_BEGIN;

/// The max length of CCLog message.
static const int kMaxLogLen = 16*1024;

/**
@brief Output Debug message.
*/
void CC_DLL CCLog(const char * pszFormat, ...);

/**
 * lua can not deal with ...
 */
inline void CC_DLL CCLuaLog(const char * pszFormat)
{
	CCLog(pszFormat);
}

/**
@brief Pop out a message box
*/
void CC_DLL CCMessageBox(const char * pszMsg, const char * pszTitle);

/**
@brief Enum the language type supportted now
*/
typedef enum LanguageType
{
    kLanguageEnglish = 0,
    kLanguageChinese,
    kLanguageFrench,
    kLanguageItalian,
    kLanguageGerman,
    kLanguageSpanish,
    kLanguageRussian
} ccLanguageType;

NS_CC_END;

#endif	// __CC_COMMON_H__


code:
/****************************************************************************
Copyright (c) 2010 cocos2d-x.org

http://www.cocos2d-x.org

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/

#ifndef __CC_EGLVIEW_PLATFORM_H__
#define __CC_EGLVIEW_PLATFORM_H__

#include "CCPlatformConfig.h"

#if (CC_TARGET_PLATFORM == CC_PLATFORM_WOPHONE)
    #include "wophone/CCEGLView_wophone.h"
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
    #include "win32/CCEGLView_win32.h"
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
    #include "android/CCEGLView_android.h"
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
    #include "ios/CCEGLView_ios.h"
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_MARMALADE)
	#include "marmalade/CCEGLView_marmalade.h"
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_LINUX)
	#include "linux/CCEGLView_linux.h"
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_BADA)
	#include "bada/CCEGLView_bada.h"
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_QNX)
    #include "qnx/CCEGLView_qnx.h"
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_QT)
    #include "qt/CCEGLView_qt.h"
#else
    #error
#endif

#endif	// end of __CC_EGLVIEW_PLATFORM_H__


code:
/****************************************************************************
Copyright (c) 2010 cocos2d-x.org

http://www.cocos2d-x.org

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/

#include "CCFileUtils.h"
#include "CCDirector.h"

#if (CC_TARGET_PLATFORM != CC_PLATFORM_IOS)

#include <stack>
#if (CC_TARGET_PLATFORM != CC_PLATFORM_QT)
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/xmlmemory.h>
#include "CCLibxml2.h"
#endif
#include "CCString.h"
#include "CCSAXParser.h"
#include "support/zip_support/unzip.h"

NS_CC_BEGIN;

static const char *__suffixiPhoneRetinaDisplay = "-hd";
static const char *__suffixiPad = "-ipad";
static const char *__suffixiPadRetinaDisplay = "-ipadhd";

typedef enum
{
    SAX_NONE = 0,
    SAX_KEY,
    SAX_DICT,
    SAX_INT,
    SAX_REAL,
    SAX_STRING,
    SAX_ARRAY
}CCSAXState;

class CCDictMaker : public CCSAXDelegator
{
public:
    CCDictionary<std::string, CCObject*> *m_pRootDict;
    CCDictionary<std::string, CCObject*> *m_pCurDict;
    std::stack<CCDictionary<std::string, CCObject*>*> m_tDictStack;
    std::string m_sCurKey;///< parsed key
    CCSAXState m_tState;
    CCMutableArray<CCObject*> *m_pArray;

    std::stack<CCMutableArray<CCObject*>*> m_tArrayStack;
    std::stack<CCSAXState>  m_tStateStack;

public:
    CCDictMaker()
		: m_pRootDict(NULL),
		  m_pCurDict(NULL),
          m_tState(SAX_NONE),
          m_pArray(NULL)
    {
    }

    ~CCDictMaker()
    {
    }

    CCDictionary<std::string, CCObject*> *dictionaryWithContentsOfFile(const char *pFileName)
    {
        CCSAXParser parser;

        if (false == parser.init("UTF-8"))
        {
            return NULL;
        }
        parser.setDelegator(this);

        parser.parse(pFileName);
        return m_pRootDict;
    }

    void startElement(void *ctx, const char *name, const char **atts)
    {
        CC_UNUSED_PARAM(ctx);
        CC_UNUSED_PARAM(atts);
        std::string sName((char*)name);
        if( sName == "dict" )
        {
            m_pCurDict = new CCDictionary<std::string, CCObject*>();
            if(! m_pRootDict)
            {
				// Because it will call m_pCurDict->release() later, so retain here.
                m_pRootDict = m_pCurDict;
				m_pRootDict->retain();
            }
            m_tState = SAX_DICT;

            CCSAXState preState = SAX_NONE;
            if (! m_tStateStack.empty())
            {
                preState = m_tStateStack.top();
            }

            if (SAX_ARRAY == preState)
            {
                // add the dictionary into the array
                m_pArray->addObject(m_pCurDict);
            }
            else if (SAX_DICT == preState)
            {
                // add the dictionary into the pre dictionary
                CCAssert(! m_tDictStack.empty(), "The state is wrong!");
                CCDictionary<std::string, CCObject*>* pPreDict = m_tDictStack.top();
                pPreDict->setObject(m_pCurDict, m_sCurKey);
            }

			m_pCurDict->release();

            // record the dict state
            m_tStateStack.push(m_tState);
            m_tDictStack.push(m_pCurDict);
        }
        else if(sName == "key")
        {
            m_tState = SAX_KEY;
        }
        else if(sName == "integer")
        {
            m_tState = SAX_INT;
        }
        else if(sName == "real")
        {
            m_tState = SAX_REAL;
        }
        else if(sName == "string")
        {
            m_tState = SAX_STRING;
        }
        else if (sName == "array")
        {
            m_tState = SAX_ARRAY;
            m_pArray = new CCMutableArray<CCObject*>();

            CCSAXState preState = m_tStateStack.empty() ? SAX_DICT : m_tStateStack.top();
            if (preState == SAX_DICT)
            {
                m_pCurDict->setObject(m_pArray, m_sCurKey);
            }
            else if (preState == SAX_ARRAY)
            {
                CCAssert(! m_tArrayStack.empty(), "The state is worng!");
                CCMutableArray<CCObject*>* pPreArray = m_tArrayStack.top();
                pPreArray->addObject(m_pArray);
            }
            m_pArray->release();
            // record the array state
            m_tStateStack.push(m_tState);
            m_tArrayStack.push(m_pArray);
        }
        else
        {
            m_tState = SAX_NONE;
        }
    }

    void endElement(void *ctx, const char *name)
    {
        CC_UNUSED_PARAM(ctx);
        CCSAXState curState = m_tStateStack.empty() ? SAX_DICT : m_tStateStack.top();
        std::string sName((char*)name);
        if( sName == "dict" )
        {
            m_tStateStack.pop();
            m_tDictStack.pop();
            if ( !m_tDictStack.empty())
            {
                m_pCurDict = m_tDictStack.top();
            }
        }
        else if (sName == "array")
        {
            m_tStateStack.pop();
            m_tArrayStack.pop();
            if (! m_tArrayStack.empty())
            {
                m_pArray = m_tArrayStack.top();
            }
        }
        else if (sName == "true")
        {
            CCString *str = new CCString("1");
            if (SAX_ARRAY == curState)
            {
                m_pArray->addObject(str);
            }
            else if (SAX_DICT == curState)
            {
                m_pCurDict->setObject(str, m_sCurKey);
            }
            str->release();
        }
        else if (sName == "false")
        {
            CCString *str = new CCString("0");
            if (SAX_ARRAY == curState)
            {
                m_pArray->addObject(str);
            }
            else if (SAX_DICT == curState)
            {
                m_pCurDict->setObject(str, m_sCurKey);
            }
            str->release();
        }
        m_tState = SAX_NONE;
    }

    void textHandler(void *ctx, const char *ch, int len)
    {
        CC_UNUSED_PARAM(ctx);
        if (m_tState == SAX_NONE)
        {
            return;
        }

        CCSAXState curState = m_tStateStack.empty() ? SAX_DICT : m_tStateStack.top();
        CCString *pText = new CCString();
        pText->m_sString = std::string((char*)ch,0,len);

        switch(m_tState)
        {
        case SAX_KEY:
            m_sCurKey = pText->m_sString;
            break;
        case SAX_INT:
        case SAX_REAL:
        case SAX_STRING:
            {
                CCAssert(!m_sCurKey.empty(), "not found key : <integet/real>");

                if (SAX_ARRAY == curState)
                {
                    m_pArray->addObject(pText);
                }
                else if (SAX_DICT == curState)
                {
                    m_pCurDict->setObject(pText, m_sCurKey);
                }
                break;
            }
        default:
            break;
        }
        pText->release();
    }
};

std::string& CCFileUtils::removeSuffixFromFile(std::string& path)
{
	// XXX win32 now can only support iphone retina, because
	// we don't know it is ipad retina or iphone retina.
	// fixe me later
    if( CC_CONTENT_SCALE_FACTOR() == 2 )
    {
        std::string::size_type pos = path.rfind("/") + 1; // the begin index of last part of path

        std::string::size_type suffixPos = path.rfind(__suffixiPhoneRetinaDisplay);
        if (std::string::npos != suffixPos && suffixPos > pos)
        {
            CCLog("cocos2d: FilePath(%s) contains suffix(%s), remove it.", path.c_str(),
                __suffixiPhoneRetinaDisplay);
            path.replace(suffixPos, strlen(__suffixiPhoneRetinaDisplay), "");
        }
    }

    return path;
}

CCDictionary<std::string, CCObject*> *CCFileUtils::dictionaryWithContentsOfFile(const char *pFileName)
{
	CCDictionary<std::string, CCObject*> *ret = dictionaryWithContentsOfFileThreadSafe(pFileName);
	ret->autorelease();

	return ret;
}

CCDictionary<std::string, CCObject*> *CCFileUtils::dictionaryWithContentsOfFileThreadSafe(const char *pFileName)
{
	CCDictMaker tMaker;
    return tMaker.dictionaryWithContentsOfFile(pFileName);
}

unsigned char* CCFileUtils::getFileDataFromZip(const char* pszZipFilePath, const char* pszFileName, unsigned long * pSize)
{
    unsigned char * pBuffer = NULL;
    unzFile pFile = NULL;
    *pSize = 0;

    do
    {
        CC_BREAK_IF(!pszZipFilePath || !pszFileName);
        CC_BREAK_IF(strlen(pszZipFilePath) == 0);

        pFile = unzOpen(pszZipFilePath);
        CC_BREAK_IF(!pFile);

        int nRet = unzLocateFile(pFile, pszFileName, 1);
        CC_BREAK_IF(UNZ_OK != nRet);

        char szFilePathA[260];
        unz_file_info FileInfo;
        nRet = unzGetCurrentFileInfo(pFile, &FileInfo, szFilePathA, sizeof(szFilePathA), NULL, 0, NULL, 0);
        CC_BREAK_IF(UNZ_OK != nRet);

        nRet = unzOpenCurrentFile(pFile);
        CC_BREAK_IF(UNZ_OK != nRet);

        pBuffer = new unsigned char[FileInfo.uncompressed_size];
        int nSize = 0;
        nSize = unzReadCurrentFile(pFile, pBuffer, FileInfo.uncompressed_size);
        CCAssert(nSize == 0 || nSize == (int)FileInfo.uncompressed_size, "the file size is wrong");

        *pSize = FileInfo.uncompressed_size;
        unzCloseCurrentFile(pFile);
    } while (0);

    if (pFile)
    {
        unzClose(pFile);
    }

    return pBuffer;
}

/// functions iOS specific
const char* CCFileUtils::fullPathFromRelativePath(const char *pszRelativePath, ccResolutionType *pResolutionType)
{
	return "";
}

void CCFileUtils::setiPhoneRetinaDisplaySuffix(const char *suffix)
{
}

void CCFileUtils::setiPadSuffix(const char *suffix)
{
}

void CCFileUtils::setiPadRetinaDisplaySuffix(const char *suffix)
{
}

bool CCFileUtils::iPadFileExistsAtPath(const char *filename)
{
	return false;
}

bool CCFileUtils::iPadRetinaDisplayFileExistsAtPath(const char *filename)
{
	return false;
}

bool CCFileUtils::iPhoneRetinaDisplayFileExistsAtPath(const char *filename)
{
	return false;
}

//////////////////////////////////////////////////////////////////////////
// Notification support when getFileData from invalid file path.
//////////////////////////////////////////////////////////////////////////
static bool s_bPopupNotify = true;

void CCFileUtils::setIsPopupNotify(bool bNotify)
{
    s_bPopupNotify = bNotify;
}

bool CCFileUtils::getIsPopupNotify()
{
    return s_bPopupNotify;
}

NS_CC_END;

#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
#include "win32/CCFileUtils_win32.cpp"
#endif

#if (CC_TARGET_PLATFORM == CC_PLATFORM_WOPHONE)
#include "wophone/CCFileUtils_wophone.cpp"
#endif

#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include "android/CCFileUtils_android.cpp"
#endif

#if (CC_TARGET_PLATFORM == CC_PLATFORM_MARMALADE)
#include "marmalade/CCFileUtils_marmalade.cpp"
#endif

#if (CC_TARGET_PLATFORM == CC_PLATFORM_BADA)
#include "bada/CCFileUtils_bada.cpp"
#endif

#if (CC_TARGET_PLATFORM == CC_PLATFORM_QNX)
#include "qnx/CCFileUtils_qnx.cpp"
#endif

#if (CC_TARGET_PLATFORM == CC_PLATFORM_LINUX)
#include "linux/CCFileUtils_linux.cpp"
#endif

#endif // (CC_TARGET_PLATFORM != CC_PLATFORM_IOS)