/********************************************************************
 *
 *   Author:			Robert Karlsson
 *
 *   Module:			CDXSurfaceFilter.cpp
 *
 *   $Workfile: $
 *   $Revision: 1.1.1.1 $
 *   $Date: 2000/04/22 16:49:13 $
 *
 *   Description:		Implementation of the CDXSurfaceFilter class.
 *
 *   Usage:		
 *
 *   Dependencies:	
 *
 ********************************************************************/

/*** Include files **************************************************/
#include "stdafx.h"
#include "CDXSurfaceFilter.h"
#include "CDX.h"
#include "CDXSurface.h"
#include <math.h>

/*** Defines ********************************************************/

/*** Macros *********************************************************/

/*** Data types definitions and typedefs ****************************/

/*** Global variables ***********************************************/
static const double PI = 3.1415926535897932384626433832795;

/********************************************************************/
/*** Class constructor/destructor ***********************************/
/********************************************************************/
/*********************************************************************
 *
 *   Purpose:			Ctor
 *
 *   Inparameters:	pSurface			Pointer to CDXSurface to filter
 *
 *   Outparameters:	None.
 *
 *   Return value:	N/A
 *
 *   Note:				The CDXSurface's copy constructor copies the
 *							inparameters surface data for the m_pSurfaceCopy member.
 *							In other words, a snapshot is beeing made in the ctor.
 *
 */
CDXSurfaceFilter::CDXSurfaceFilter(CDXSurface* pSurface) : m_pSurface(pSurface)
{
	
	// Initialize member variables
	m_nWidth		= pSurface->m_DDSD.dwWidth;
	m_nHeight	= pSurface->m_DDSD.dwHeight;
	m_nCenterX	= m_nWidth/2;
	m_nCenterY	= m_nHeight/2;
	m_nColorKey	= pSurface->m_ColorKey;
	
	// Allocate memory for the surface copy (used for restoring / snapshotting)
	m_pSurfaceCopy = new CDXSurface(*pSurface);
}

/*********************************************************************
 *
 *   Purpose:			Dtor
 *
 *   Inparameters:	None.
 *
 *   Outparameters:	None.
 *
 *   Return value:	N/A
 *
 *   Note:
 *
 */
CDXSurfaceFilter::~CDXSurfaceFilter()
{
	delete m_pSurfaceCopy;
}

/********************************************************************/
/*** Public Member Functions ****************************************/
/********************************************************************/
/*********************************************************************
 *
 *   Purpose:			Take a snapshot of the surface that this filter is 
 *							"attached" to an internal surface copy.
 *
 *   Inparameters:	None.
 *
 *   Outparameters:	None.
 *
 *   Return value:	void
 *
 *   Note:
 *
 */
void CDXSurfaceFilter::Snapshot()
{
	// Copy contents from m_pSurface to m_pSurfaceCopy
	m_pSurface->DrawFast(0,0, m_pSurfaceCopy);
}

/*********************************************************************
 *
 *   Purpose:			Restore the surface copy to the "attached" surface.
 *
 *   Inparameters:	None.
 *
 *   Outparameters:	None.
 *
 *   Return value:	void
 *
 *   Note:
 *
 */
void CDXSurfaceFilter::Reset()
{
	// Restore contents in m_pSurfaceCopy to m_pSurface
	m_pSurfaceCopy->DrawFast(0,0, m_pSurface);

}

/*********************************************************************
 *
 *   Purpose:			Zoom the "attached image" using inparameter as scale factor
 *
 *   Inparameters:	percent			The amount to zoom the surface
 *
 *   Outparameters:	None.
 *
 *   Return value:	void
 *
 *   Note:
 *
 */
void CDXSurfaceFilter::Zoom(int percent)
{
	// Make a copy of the surface
	CDXSurface SurfaceCopy(*m_pSurface);

	UCHAR*	m_pSrcPixels8;
	UCHAR*	m_pSrcCopyPixels8;
	USHORT*	m_pSrcPixels16;
	USHORT*	m_pSrcCopyPixels16;
	WORD*		m_pSrcPixels32;
	WORD*		m_pSrcCopyPixels32;

	// Lock both surfaces
	m_pSurface->Lock();	
	SurfaceCopy.Lock();

	// Get pointers to surfaces
	switch(m_pSurface->m_RGB.bpp)
	{
		case 8:
			m_pSrcPixels8		= (UCHAR*)	m_pSurface->m_DDSD.lpSurface;
			m_pSrcCopyPixels8	= (UCHAR*)	SurfaceCopy.m_DDSD.lpSurface;
			break;
		case 15:
		case 16:
			m_pSrcPixels16		 = (USHORT*) m_pSurface->m_DDSD.lpSurface;
			m_pSrcCopyPixels16 = (USHORT*) SurfaceCopy.m_DDSD.lpSurface;
			break;
		case 24:
		case 32:
			m_pSrcPixels32		 = (WORD*)	m_pSurface->m_DDSD.lpSurface;
			m_pSrcCopyPixels32 = (WORD*)	SurfaceCopy.m_DDSD.lpSurface;
			break;
		default:
			break;
	}


	int index=0;
	int x_index = 0;
	int y_index = 0;
	for (int y=-m_nCenterY;y<m_nCenterY;y++)
	{
		x_index = 0;
		for (int x=-m_nCenterX;x<m_nCenterX;x++)
		{
			int xs=(x*percent)/100+m_nCenterX;
			int ys=(y*percent)/100+m_nCenterY;
			
			// Get the source color
			switch(m_pSurface->m_RGB.bpp)
			{
			case 8:
				if (xs>=0&&xs<m_nWidth&&ys>=0&&ys<m_nHeight)
					m_pSrcPixels8[x_index + y_index*(m_pSurface->m_DDSD.lPitch)]=m_pSrcCopyPixels8[SurfaceCopy.m_DDSD.lPitch*ys+xs];
				else
					m_pSrcPixels8[x_index + y_index*(m_pSurface->m_DDSD.lPitch)]=m_nColorKey;
				break;
			case 15:
			case 16:
				if (xs>=0&&xs<m_nWidth&&ys>=0&&ys<m_nHeight)
					m_pSrcPixels16[x_index + y_index*(m_pSurface->m_DDSD.lPitch >> 1)]=m_pSrcCopyPixels16[(SurfaceCopy.m_DDSD.lPitch >> 1)*ys+xs];
				else
					m_pSrcPixels16[x_index + y_index*(m_pSurface->m_DDSD.lPitch >> 1)]=m_nColorKey;
				break;
			case 24:
			case 32:
				if (xs>=0&&xs<m_nWidth&&ys>=0&&ys<m_nHeight)
					m_pSrcPixels32[x_index + y_index*(m_pSurface->m_DDSD.lPitch >> 2)]=m_pSrcCopyPixels32[(SurfaceCopy.m_DDSD.lPitch >> 2)*ys+xs];
				else
					m_pSrcPixels32[x_index + y_index*(m_pSurface->m_DDSD.lPitch >> 2)]=m_nColorKey;
				break;
			default:
				break;
			}
			
			x_index++;
		}
		y_index++;
	}

	// Unlock the surfaces
	m_pSurface->UnLock();
	SurfaceCopy.UnLock();

}

/*********************************************************************
 *
 *   Purpose:			Rotate the surface a specific angle
 *
 *   Inparameters:	angle			The angle to rotate the image
 *
 *   Outparameters:	None.
 *
 *   Return value:	void
 *
 *   Note:
 *
 */
void CDXSurfaceFilter::Rotate(double angle)
{
	// Make a copy of the surface
	CDXSurface pSurfaceCopy(*m_pSurface);

	UCHAR*	m_pSrcPixels8;
	UCHAR*	m_pSrcCopyPixels8;
	USHORT*	m_pSrcPixels16;
	USHORT*	m_pSrcCopyPixels16;
	WORD*		m_pSrcPixels32;
	WORD*		m_pSrcCopyPixels32;

	// Skip processing if no rotation is to be performed
	// ?? Should it do it anyway to keep a steady framerate?
	// It is useful if pre rendering images though...
	if ((int)angle%360!=0)
	{
      //Convert from degrees to radians and calculate cos and sin of angle
      //Negate the angle to make sure the rotation is clockwise
      double angleRadians=-angle/(180.0/PI);
      double ca=cos(angleRadians);
      double sa=sin(angleRadians);

		// Lock both surfaces
		m_pSurface->Lock();	
		pSurfaceCopy.Lock();

		// Get pointers to surface
		switch(m_pSurface->m_RGB.bpp)
		{
			case 8:
				m_pSrcPixels8		= (UCHAR*)	m_pSurface->m_DDSD.lpSurface;
				m_pSrcCopyPixels8	= (UCHAR*)	pSurfaceCopy.m_DDSD.lpSurface;
				break;
			case 15:
			case 16:
				m_pSrcPixels16		 = (USHORT*) m_pSurface->m_DDSD.lpSurface;
				m_pSrcCopyPixels16 = (USHORT*) pSurfaceCopy.m_DDSD.lpSurface;
				break;
			case 24:
			case 32:
				m_pSrcPixels32		 = (WORD*)	m_pSurface->m_DDSD.lpSurface;
				m_pSrcCopyPixels32 = (WORD*)	pSurfaceCopy.m_DDSD.lpSurface;
				break;
			default:
				break;
		}


		int index=0;
		int x_index = 0;
		int y_index = 0;
		for (int y=-m_nCenterY;y<m_nCenterY;y++)
		{
			x_index = 0;
			for (int x=-m_nCenterX;x<m_nCenterX;x++)
			{
           int xs=(int)(x*ca-y*sa)+m_nCenterX;
           int ys=(int)(y*ca+x*sa)+m_nCenterY;
				
				// Plot
				switch(m_pSurface->m_RGB.bpp)
				{
				case 8:
					if (xs>=0&&xs<m_nWidth&&ys>=0&&ys<m_nHeight)
						m_pSrcPixels8[x_index + y_index*(m_pSurface->m_DDSD.lPitch)]=m_pSrcCopyPixels8[pSurfaceCopy.m_DDSD.lPitch*ys+xs];
					else
						m_pSrcPixels8[x_index + y_index*(m_pSurface->m_DDSD.lPitch)]=m_nColorKey;
					break;
				case 15:
				case 16:
					if (xs>=0&&xs<m_nWidth&&ys>=0&&ys<m_nHeight)
						m_pSrcPixels16[x_index + y_index*(m_pSurface->m_DDSD.lPitch >> 1)]=m_pSrcCopyPixels16[(pSurfaceCopy.m_DDSD.lPitch >> 1)*ys+xs];
					else
						m_pSrcPixels16[x_index + y_index*(m_pSurface->m_DDSD.lPitch >> 1)]=m_nColorKey;
					break;
				case 24:
				case 32:
					if (xs>=0&&xs<m_nWidth&&ys>=0&&ys<m_nHeight)
						m_pSrcPixels32[x_index + y_index*(m_pSurface->m_DDSD.lPitch >> 2)]=m_pSrcCopyPixels32[(pSurfaceCopy.m_DDSD.lPitch >> 2)*ys+xs];
					else
						m_pSrcPixels32[x_index + y_index*(m_pSurface->m_DDSD.lPitch >> 2)]=m_nColorKey;
					break;
				default:
					break;
				}
				
				x_index++;
			}
			y_index++;
		}

		// Unlock the surfaces
		m_pSurface->UnLock();
		pSurfaceCopy.UnLock();
	}
}

/*********************************************************************
 *
 *   Purpose:			
 *
 *   Inparameters:	
 *
 *   Outparameters:	
 *
 *   Return value:
 *
 *   Note:
 *
 */
void CDXSurfaceFilter::Spiral(double angle)
{
	// Make a copy of the surface
	CDXSurface pSurfaceCopy(*m_pSurface);
	
	UCHAR*	m_pSrcPixels8;
	UCHAR*	m_pSrcCopyPixels8;
	USHORT*	m_pSrcPixels16;
	USHORT*	m_pSrcCopyPixels16;
	WORD*		m_pSrcPixels32;
	WORD*		m_pSrcCopyPixels32;
	
	double angleRadians=-angle/(180.0/PI);
	double maxDist=sqrt(m_nWidth+m_nHeight*m_nHeight);
	double scale=angleRadians/maxDist;
	  
	// Lock both surfaces
	m_pSurface->Lock();	
	pSurfaceCopy.Lock();
	  
	// Get pointers to surface
	switch(m_pSurface->m_RGB.bpp)
	{
	case 8:
	  m_pSrcPixels8		= (UCHAR*)	m_pSurface->m_DDSD.lpSurface;
	  m_pSrcCopyPixels8	= (UCHAR*)	pSurfaceCopy.m_DDSD.lpSurface;
	  break;
	case 15:
	case 16:
	  m_pSrcPixels16		 = (USHORT*) m_pSurface->m_DDSD.lpSurface;
	  m_pSrcCopyPixels16 = (USHORT*) pSurfaceCopy.m_DDSD.lpSurface;
	  break;
	case 24:
	case 32:
	  m_pSrcPixels32		 = (WORD*)	m_pSurface->m_DDSD.lpSurface;
	  m_pSrcCopyPixels32 = (WORD*)	pSurfaceCopy.m_DDSD.lpSurface;
	  break;
	default:
	  break;
	}
	  

	int index=0;
	int x_index = 0;
	int y_index = 0;
	for (int y=-m_nCenterY;y<m_nCenterY;y++)
	{
		x_index = 0;
		for (int x=-m_nCenterX;x<m_nCenterX;x++)
		{
			double a=sqrt(x*x+y*y)*scale;
			double ca=cos(a);
			double sa=sin(a);

			int xs=(int)(x*ca-y*sa)+m_nCenterX;
			int ys=(int)(y*ca+x*sa)+m_nCenterY;

			// Plot
			switch(m_pSurface->m_RGB.bpp)
			{
			case 8:
			  if (xs>=0&&xs<m_nWidth&&ys>=0&&ys<m_nHeight)
				  m_pSrcPixels8[x_index + y_index*(m_pSurface->m_DDSD.lPitch)]=m_pSrcCopyPixels8[pSurfaceCopy.m_DDSD.lPitch*ys+xs];
			  else
				  m_pSrcPixels8[x_index + y_index*(m_pSurface->m_DDSD.lPitch)]=m_nColorKey;
			  break;
			case 15:
			case 16:
			  if (xs>=0&&xs<m_nWidth&&ys>=0&&ys<m_nHeight)
				  m_pSrcPixels16[x_index + y_index*(m_pSurface->m_DDSD.lPitch >> 1)]=m_pSrcCopyPixels16[(pSurfaceCopy.m_DDSD.lPitch >> 1)*ys+xs];
			  else
				  m_pSrcPixels16[x_index + y_index*(m_pSurface->m_DDSD.lPitch >> 1)]=m_nColorKey;
			  break;
			case 24:
			case 32:
			  if (xs>=0&&xs<m_nWidth&&ys>=0&&ys<m_nHeight)
				  m_pSrcPixels32[x_index + y_index*(m_pSurface->m_DDSD.lPitch >> 2)]=m_pSrcCopyPixels32[(pSurfaceCopy.m_DDSD.lPitch >> 2)*ys+xs];
			  else
				  m_pSrcPixels32[x_index + y_index*(m_pSurface->m_DDSD.lPitch >> 2)]=m_nColorKey;
			  break;
			default:
			  break;
			}
			x_index++;
		}
		y_index++;
	}
	  
	// Unlock the surfaces
	m_pSurface->UnLock();
	pSurfaceCopy.UnLock();
}

/*********************************************************************
 *
 *   Purpose:			
 *
 *   Inparameters:	
 *
 *   Outparameters:	
 *
 *   Return value:
 *
 *   Note:
 *
 */
void CDXSurfaceFilter::VerticalWave3D(double nWaves, double percent, double offset)
{
	// Make a copy of the surface
	CDXSurface pSurfaceCopy(*m_pSurface);
	
	UCHAR*	m_pSrcPixels8;
	UCHAR*	m_pSrcCopyPixels8;
	USHORT*	m_pSrcPixels16;
	USHORT*	m_pSrcCopyPixels16;
	WORD*		m_pSrcPixels32;
	WORD*		m_pSrcCopyPixels32;
	
	double angleRadians=(offset*3.6)/(180.0/PI);
	double angleStep=((PI*2)*nWaves)/m_nHeight;
	double amplitude=(percent*m_nHeight/2)/100.0;


	// Lock both surfaces
	m_pSurface->Lock();	
	pSurfaceCopy.Lock();
	  
	// Get pointers to surface
	switch(m_pSurface->m_RGB.bpp)
	{
	case 8:
	  m_pSrcPixels8		= (UCHAR*)	m_pSurface->m_DDSD.lpSurface;
	  m_pSrcCopyPixels8	= (UCHAR*)	pSurfaceCopy.m_DDSD.lpSurface;
	  break;
	case 15:
	case 16:
	  m_pSrcPixels16		 = (USHORT*) m_pSurface->m_DDSD.lpSurface;
	  m_pSrcCopyPixels16 = (USHORT*) pSurfaceCopy.m_DDSD.lpSurface;
	  break;
	case 24:
	case 32:
	  m_pSrcPixels32		 = (WORD*)	m_pSurface->m_DDSD.lpSurface;
	  m_pSrcCopyPixels32 = (WORD*)	pSurfaceCopy.m_DDSD.lpSurface;
	  break;
	default:
	  break;
	}
	  

	int y=0;
	int offset1;
	int offset2;

	// Plot
	switch(m_pSurface->m_RGB.bpp)
	{
	case 8:
		for (offset1=0;offset1<m_nWidth*m_nHeight;offset1+=(m_pSurface->m_DDSD.lPitch))
		{
			offset2=(__max(__min((int)(  (cos(angleRadians)*amplitude+y)  ),m_nHeight-1),0))*(m_pSurface->m_DDSD.lPitch);
			y++;
			memcpy(&m_pSrcPixels8[offset1], &m_pSrcCopyPixels8[offset2], m_pSurface->m_DDSD.lPitch );
			angleRadians+=angleStep;
		}
		break;
	case 15:
	case 16:
		for (offset1=0;offset1<m_nWidth*m_nHeight;offset1+=(m_pSurface->m_DDSD.lPitch >> 1))
		{
			offset2=(__max(__min((int)(  (cos(angleRadians)*amplitude+y)  ),m_nHeight-1),0))*(m_pSurface->m_DDSD.lPitch >> 1);
			y++;
			memcpy(&m_pSrcPixels16[offset1], &m_pSrcCopyPixels16[offset2], m_pSurface->m_DDSD.lPitch );
			angleRadians+=angleStep;
		}
		break;
	case 24:
	case 32:
		for (offset1=0;offset1<m_nWidth*m_nHeight;offset1+=(m_pSurface->m_DDSD.lPitch >> 2))
		{
			offset2=(__max(__min((int)(  (cos(angleRadians)*amplitude+y)  ),m_nHeight-1),0))*(m_pSurface->m_DDSD.lPitch >> 2);
			y++;
			memcpy(&m_pSrcPixels32[offset1], &m_pSrcCopyPixels32[offset2], m_pSurface->m_DDSD.lPitch );
			angleRadians+=angleStep;
		}
		break;
	default:
		break;
	}
			
	// Unlock the surfaces
	m_pSurface->UnLock();
	pSurfaceCopy.UnLock();
}


/*********************************************************************
 *
 *   Purpose:			
 *
 *   Inparameters:	
 *
 *   Outparameters:	
 *
 *   Return value:
 *
 *   Note:
 *
 */
void CDXSurfaceFilter::HorizontalWave3D(double nWaves, double percent, double offset)
{
	// Make a copy of the surface
	CDXSurface pSurfaceCopy(*m_pSurface);
	
	UCHAR*	m_pSrcPixels8;
	UCHAR*	m_pSrcCopyPixels8;
	USHORT*	m_pSrcPixels16;
	USHORT*	m_pSrcCopyPixels16;
	WORD*		m_pSrcPixels32;
	WORD*		m_pSrcCopyPixels32;
	
	double angleRadians=(offset*3.6)/(180.0/PI);
	double angleStep=((PI*2)*nWaves)/m_nWidth;
	double amplitude=(percent*m_nHeight/2)/100.0;


	// Lock both surfaces
	m_pSurface->Lock();	
	pSurfaceCopy.Lock();
	  
	// Get pointers to surface
	switch(m_pSurface->m_RGB.bpp)
	{
	case 8:
	  m_pSrcPixels8		= (UCHAR*)	m_pSurface->m_DDSD.lpSurface;
	  m_pSrcCopyPixels8	= (UCHAR*)	pSurfaceCopy.m_DDSD.lpSurface;
	  break;
	case 15:
	case 16:
	  m_pSrcPixels16		 = (USHORT*) m_pSurface->m_DDSD.lpSurface;
	  m_pSrcCopyPixels16 = (USHORT*) pSurfaceCopy.m_DDSD.lpSurface;
	  break;
	case 24:
	case 32:
	  m_pSrcPixels32		 = (WORD*)	m_pSurface->m_DDSD.lpSurface;
	  m_pSrcCopyPixels32 = (WORD*)	pSurfaceCopy.m_DDSD.lpSurface;
	  break;
	default:
	  break;
	}


	for (int x=0;x<m_nWidth;x++)
	{
		int xOffset=__max(__min((int)( (cos(angleRadians)*amplitude+x) ),m_nWidth-1),0);
		for (int y=0;y<m_nHeight;y++)
		{
			// Plot
			switch(m_pSurface->m_RGB.bpp)
			{
			case 8:
				m_pSrcPixels8[x+y*(m_pSurface->m_DDSD.lPitch )]=m_pSrcCopyPixels8[xOffset+y*(m_pSurface->m_DDSD.lPitch )];
				break;
			case 15:
			case 16:
				m_pSrcPixels16[x+y*(m_pSurface->m_DDSD.lPitch >> 1)]=m_pSrcCopyPixels16[xOffset+y*(m_pSurface->m_DDSD.lPitch >> 1)];
				break;
			case 24:
			case 32:
				m_pSrcPixels32[x+y*(m_pSurface->m_DDSD.lPitch >> 2)]=m_pSrcCopyPixels32[xOffset+y*(m_pSurface->m_DDSD.lPitch >> 2)];
				break;
			default:
				break;
			}
		}
		angleRadians+=angleStep;
	}

	  
	// Unlock the surfaces
	m_pSurface->UnLock();
	pSurfaceCopy.UnLock();

}

/*********************************************************************
 *
 *   Purpose:			
 *
 *   Inparameters:	
 *
 *   Outparameters:	
 *
 *   Return value:
 *
 *   Note:
 *
 */
void CDXSurfaceFilter::HorizontalWave(double nWaves, double percent, double offset)
{
	// Make a copy of the surface
	CDXSurface pSurfaceCopy(*m_pSurface);
	
	UCHAR*	m_pSrcPixels8;
	UCHAR*	m_pSrcCopyPixels8;
	USHORT*	m_pSrcPixels16;
	USHORT*	m_pSrcCopyPixels16;
	WORD*		m_pSrcPixels32;
	WORD*		m_pSrcCopyPixels32;
	
	double waveFrequency=(nWaves*PI*2.0)/m_nHeight;
  	double waveOffset=(offset*nWaves*PI*2.0)/100.0;
  	double radius=(m_nWidth*percent)/100.0;

	// Lock both surfaces
	m_pSurface->Lock();	
	pSurfaceCopy.Lock();
	  
	// Get pointers to surface
	switch(m_pSurface->m_RGB.bpp)
	{
	case 8:
	  m_pSrcPixels8		= (UCHAR*)	m_pSurface->m_DDSD.lpSurface;
	  m_pSrcCopyPixels8	= (UCHAR*)	pSurfaceCopy.m_DDSD.lpSurface;
	  break;
	case 15:
	case 16:
	  m_pSrcPixels16		 = (USHORT*) m_pSurface->m_DDSD.lpSurface;
	  m_pSrcCopyPixels16 = (USHORT*) pSurfaceCopy.m_DDSD.lpSurface;
	  break;
	case 24:
	case 32:
	  m_pSrcPixels32		 = (WORD*)	m_pSurface->m_DDSD.lpSurface;
	  m_pSrcCopyPixels32 = (WORD*)	pSurfaceCopy.m_DDSD.lpSurface;
	  break;
	default:
	  break;
	}

	for (int y=0;y<m_nHeight;y++)
	{
		int xOffset=(int)/*Math.round*/(sin(y*waveFrequency+waveOffset)*radius);
    	for (int x=0;x<m_nWidth;x++)
    	{
			// Plot
			switch(m_pSurface->m_RGB.bpp)
			{
			case 8:
    			if (xOffset>=0&&xOffset<m_nWidth)
    				 m_pSrcPixels8[x+y*(m_pSurface->m_DDSD.lPitch)]=m_pSrcCopyPixels8[xOffset+(m_pSurface->m_DDSD.lPitch)*y];
    			else
    				 m_pSrcPixels8[x+y*(m_pSurface->m_DDSD.lPitch)]=m_nColorKey;
    			xOffset++;
				break;
			case 15:
			case 16:
    			if (xOffset>=0&&xOffset<m_nWidth)
    				 m_pSrcPixels16[x+y*(m_pSurface->m_DDSD.lPitch >> 1)]=m_pSrcCopyPixels16[xOffset+(m_pSurface->m_DDSD.lPitch >> 1)*y];
    			else
    				 m_pSrcPixels16[x+y*(m_pSurface->m_DDSD.lPitch >> 1)]=m_nColorKey;
    			xOffset++;
				break;
			case 24:
			case 32:
    			if (xOffset>=0&&xOffset<m_nWidth)
    				 m_pSrcPixels32[x+y*(m_pSurface->m_DDSD.lPitch >> 2)]=m_pSrcCopyPixels32[xOffset+(m_pSurface->m_DDSD.lPitch >> 2)*y];
    			else
    				 m_pSrcPixels32[x+y*(m_pSurface->m_DDSD.lPitch >> 2)]=m_nColorKey;
    			xOffset++;
				break;
			default:
				break;
			}
		}
	}
	  
	// Unlock the surfaces
	m_pSurface->UnLock();
	pSurfaceCopy.UnLock();

}

/*********************************************************************
 *
 *   Purpose:			
 *
 *   Inparameters:	
 *
 *   Outparameters:	
 *
 *   Return value:
 *
 *   Note:
 *
 */
void CDXSurfaceFilter::VerticalWave(double nWaves, double percent, double offset)
{
	// Make a copy of the surface
	CDXSurface pSurfaceCopy(*m_pSurface);
	
	UCHAR*	m_pSrcPixels8;
	UCHAR*	m_pSrcCopyPixels8;
	USHORT*	m_pSrcPixels16;
	USHORT*	m_pSrcCopyPixels16;
	WORD*		m_pSrcPixels32;
	WORD*		m_pSrcCopyPixels32;
	
	double waveFrequency=(nWaves*PI*2.0)/m_nHeight;
	double waveOffset=(offset*nWaves*PI*2.0)/100.0;
	double radius=(m_nWidth*percent)/100.0;

	// Lock both surfaces
	m_pSurface->Lock();	
	pSurfaceCopy.Lock();
	  
	// Get pointers to surface
	switch(m_pSurface->m_RGB.bpp)
	{
	case 8:
	  m_pSrcPixels8		= (UCHAR*)	m_pSurface->m_DDSD.lpSurface;
	  m_pSrcCopyPixels8	= (UCHAR*)	pSurfaceCopy.m_DDSD.lpSurface;
	  break;
	case 15:
	case 16:
	  m_pSrcPixels16		 = (USHORT*) m_pSurface->m_DDSD.lpSurface;
	  m_pSrcCopyPixels16 = (USHORT*) pSurfaceCopy.m_DDSD.lpSurface;
	  break;
	case 24:
	case 32:
	  m_pSrcPixels32		 = (WORD*)	m_pSurface->m_DDSD.lpSurface;
	  m_pSrcCopyPixels32 = (WORD*)	pSurfaceCopy.m_DDSD.lpSurface;
	  break;
	default:
	  break;
	}

	for (int x=0;x<m_nWidth;x++)
	{
		int yOffset=(int)/*Math.round*/(sin(x*waveFrequency+waveOffset)*radius);
    	for (int y=0;y<m_nHeight;y++)
    	{
			// Plot
			switch(m_pSurface->m_RGB.bpp)
			{
			case 8:
    			if (yOffset>=0&&yOffset<m_nHeight)
    				 m_pSrcPixels8[x+y*(m_pSurface->m_DDSD.lPitch)]=m_pSrcCopyPixels8[x+yOffset*(m_pSurface->m_DDSD.lPitch)];
    			else
    				 m_pSrcPixels8[x+y*(m_pSurface->m_DDSD.lPitch)]=m_nColorKey;
    			yOffset++;
				break;
			case 15:
			case 16:
    			if (yOffset>=0&&yOffset<m_nHeight)
    				 m_pSrcPixels16[x+y*(m_pSurface->m_DDSD.lPitch >> 1)]=m_pSrcCopyPixels16[x+yOffset*(m_pSurface->m_DDSD.lPitch >> 1)];
    			else
    				 m_pSrcPixels16[x+y*(m_pSurface->m_DDSD.lPitch >> 1)]=m_nColorKey;
    			yOffset++;
				break;
			case 24:
			case 32:
    			if (yOffset>=0&&yOffset<m_nHeight)
    				 m_pSrcPixels32[x+y*(m_pSurface->m_DDSD.lPitch >> 2)]=m_pSrcCopyPixels32[x+yOffset*(m_pSurface->m_DDSD.lPitch >> 2)];
    			else
    				 m_pSrcPixels32[x+y*(m_pSurface->m_DDSD.lPitch >> 2)]=m_nColorKey;
    			yOffset++;
				break;
			default:
				break;
			}
		}
	}
	  
	// Unlock the surfaces
	m_pSurface->UnLock();
	pSurfaceCopy.UnLock();

}

/*********************************************************************
 *
 *   Purpose:			
 *
 *   Inparameters:	
 *
 *   Outparameters:	
 *
 *   Return value:
 *
 *   Note:
 *
 */
void CDXSurfaceFilter::Disolve(const unsigned int percent)
{

	// Make a copy of the surface
	CDXSurface pSurfaceCopy(*m_pSurface);
	
	UCHAR*	m_pSrcPixels8;
	UCHAR*	m_pSrcCopyPixels8;
	USHORT*	m_pSrcPixels16;
	USHORT*	m_pSrcCopyPixels16;
	WORD*		m_pSrcPixels32;
	WORD*		m_pSrcCopyPixels32;
	
	// Lock both surfaces
	m_pSurface->Lock();	
	pSurfaceCopy.Lock();
	  
	// Get pointers to surface
	switch(m_pSurface->m_RGB.bpp)
	{
	case 8:
	  m_pSrcPixels8		= (UCHAR*)	m_pSurface->m_DDSD.lpSurface;
	  m_pSrcCopyPixels8	= (UCHAR*)	pSurfaceCopy.m_DDSD.lpSurface;
	  break;
	case 15:
	case 16:
	  m_pSrcPixels16		 = (USHORT*) m_pSurface->m_DDSD.lpSurface;
	  m_pSrcCopyPixels16 = (USHORT*) pSurfaceCopy.m_DDSD.lpSurface;
	  break;
	case 24:
	case 32:
	  m_pSrcPixels32		 = (WORD*)	m_pSurface->m_DDSD.lpSurface;
	  m_pSrcCopyPixels32 = (WORD*)	pSurfaceCopy.m_DDSD.lpSurface;
	  break;
	default:
	  break;
	}

	int set = 0;

	int offset=0; 
	  
	// Plot
	switch(m_pSurface->m_RGB.bpp)
	{
	case 8:
		set = (m_pSurface->m_PixelHeight*m_pSurface->m_DDSD.lPitch) * percent/100;
		for(offset=0; offset < set;offset++)
		  m_pSrcPixels8[rand()%m_pSurface->m_PixelWidth + (rand()%m_pSurface->m_PixelHeight)*(m_pSurface->m_DDSD.lPitch)]=0;
	  break;
	case 15:
	case 16:
		set = (m_pSurface->m_PixelHeight*(m_pSurface->m_DDSD.lPitch >> 1)) * percent/100;
		for(offset=0; offset < set;offset++)
		  m_pSrcPixels16[rand()%m_pSurface->m_PixelWidth + (rand()%m_pSurface->m_PixelHeight)*(m_pSurface->m_DDSD.lPitch >> 1)]=0;
	  break;
	case 24:
	case 32:
		set = (m_pSurface->m_PixelHeight*(m_pSurface->m_DDSD.lPitch >> 2)) * percent/100;
		for(offset=0; offset < set;offset++)
		  m_pSrcPixels32[rand()%m_pSurface->m_PixelWidth + (rand()%m_pSurface->m_PixelHeight)*(m_pSurface->m_DDSD.lPitch >> 2)]=0;
	  break;
	default:
	  break;
	}
	  
	// Unlock the surfaces
	m_pSurface->UnLock();
	pSurfaceCopy.UnLock();
}


/*********************************************************************
 *
 *   Purpose:			Return pointer to "attached" surface
 *
 *   Inparameters:	None.
 *
 *   Outparameters:	None.
 *
 *   Return value:	CDXSurface*			Pointer to "attached" surface
 *
 *   Note:				Provided for helper classes(e.g. CDXSurfaceFilterAnimation)
 *
 */
CDXSurface* CDXSurfaceFilter::GetSurface()
{
	return m_pSurface;
}

/********************************************************************/
/*** Protected Member Functions *************************************/
/********************************************************************/

/********************************************************************/
/*** Private Member Functions ***************************************/
/********************************************************************/

/*
 * $History: $
 *
 */

/* EOF */





