#ifdef ATI
extern "C"
{

#include <w100api.h>
U32 VRAMoffset,VRAMoffset2;
U16 VH1,VH2;
ATI_STRETCH stretchOptions;
extern bool Cleared=false;
ATI_OVERLAYPROP OvlWinProp;
U16 OverlayHandle = 0;
extern int xStart=0;
extern int yStart=0;
extern bool ForceFit=false;

}

void 	ATIShowOverlay(int Show)
{
	AtiCore_SetOverlayOnOff(OverlayHandle,Show);
}

void ATIClearOverlay()
{
	U32 regdata;
	AtiCore_SetupMemoryTransfer((U32)OvlWinProp.lpSrcBitmap,&regdata);
	memset((void*)regdata,0,DisplayWidth*DisplayHeight);
	memset((void*)(regdata+(DisplayWidth*DisplayHeight)),0,DisplayWidth*DisplayHeight*3/2);
	AtiCore_TerminateMemoryTransfer();
}

int ATIInitialize()
{
	if (VH1) return 0;
	if (AtiCore_ProcessAttach() != SUCCESS)
	{
		MessageBox(hWndMain,_T("AtiCore attach failed"),_T(""),MB_OK);
		return 1;
	}
	if ( AtiCore_AllocOverlay(&OverlayHandle) != SUCCESS )
	{
		MessageBox(hWndMain,_T("AtiCore AllocOverlay failed"),_T(""),MB_OK);
		return 1;
	}
	int i;
	i=AtiCore_AllocateSurface( &VH2, &VRAMoffset2, ((320) * 240 * 3/2), 0 );
	if (!i) MessageBox(hWndMain,_T("No1"),_T(""),MB_OK);
	i=AtiCore_AllocateSurface( &VH1, &VRAMoffset, (320) * 240, 0 );
	if (!i) MessageBox(hWndMain,_T("No2"),_T(""),MB_OK);
//	VRAMoffset=VRAMoffset2+((320) * 240 * 3/2);
	AtiCore_SetRopOperation( ROP3_SRCCOPY );
	AtiCore_SetDstType( DSTTYPE_8BPP );
	AtiCore_SetSrcType( SRCTYPE_EQU_DST );
	return 0;
}

void ATIDestroy()
{
	if (VH1)
	{
		AtiCore_DestroySurface(VH1);
		VH1=NULL;
		if (VH2) AtiCore_DestroySurface(VH2);
		AtiCore_ReleaseOverlay(OverlayHandle);
		AtiCore_ProcessDetach();
	}
}

static int Display(unsigned char *stream, int length, unsigned char *bmp, int render_flag, int Extra, int refresh)
{
	AVPicture avpict;
	EnterCriticalSection(&cs);
	int d=DecodeFrame(stream,length,(unsigned char*) &avpict,render_flag);
	//render_flag&=d+1;
	bool Rotate=PlayerOptions.Rotate;
	if (!d)
	{
		nDrop++;
		render_flag=0;
	}
	if (render_flag) 
	{

		if (Extra==-1) //||(PlayerOptions.Double))
		{
			if (Extra==-1) Extra=0;
			convert_yuv(avpict.data[0], avpict.linesize[0],
				avpict.data[1], avpict.data[2], avpict.linesize[1],
				(unsigned char*) bmp, g_nWidth,g_nHeight,Extra,0,PlayerOptions.Brightness,avpict.last_picture[0],avpict.last_picture[1],avpict.last_picture[2],lastshow&&(!refresh)&&(avpict.last_picture[0]!=avpict.data[0]), g_bInvert);
			while(AtiCore_SetOverlayOnOff(OverlayHandle,0)!=SUCCESS);
		}
		else
		{
			U32 regdata;
			int xStart;
			int yStart;
		//	ATI_STRETCH stretchOptions;

			while ( AtiCore_WaitComplete( 100 ) != SUCCESS );
			if (PlayerOptions.Double||(ForceFit)) //&&(!Cleared))
			{
					if (!Cleared)
					{
						Cleared=true;
						AtiCore_SetOverlayOnOff(OverlayHandle,1);
						AtiCore_SetupMemoryTransfer((U32)OvlWinProp.lpSrcBitmap,&regdata);
						memset((void*)regdata,16,OvlWinProp.SrcPitch*OvlWinProp.SrcHeight);
						memset((void*)(regdata+(OvlWinProp.SrcPitch*OvlWinProp.SrcHeight)),128,OvlWinProp.SrcPitch*OvlWinProp.SrcHeight*3/2);
						AtiCore_TerminateMemoryTransfer();
						if (PlayerOptions.FitToViewPort)
						{
							RECT rcView;
							HDC hdc=GetDC(hWndMain);
							rcView.left=PlayerSkin.ViewPort.left;
							rcView.top=PlayerSkin.ViewPort.top;
							rcView.right=PlayerSkin.ViewPort.width+PlayerSkin.ViewPort.left;
							rcView.bottom=PlayerSkin.ViewPort.height+PlayerSkin.ViewPort.top;

							HBRUSH hbr=CreateSolidBrush(RGB(0,0,0));
							FillRect(hdc,&rcView,hbr); //(HBRUSH)GetStockObject(BLACK_BRUSH));
							DeleteObject(hbr);
							ReleaseDC(hWndMain,hdc);
						}
					}
					int nWidth;
					int nHeight;
					nWidth=Rotate?g_nHeight:g_nWidth;
					nHeight=Rotate?g_nWidth:g_nHeight;
					if (Rotate&&(nWidth%16)) nWidth-=nWidth%16;
					if (!ForceFit)
					{
						xStart=(OvlWinProp.SrcPitch-(((float)((float)16/(float)stretchOptions.ScaleXFactor))*(nWidth<OvlWinProp.SrcPitch?nWidth:OvlWinProp.SrcPitch)))/2;
						yStart=(OvlWinProp.SrcHeight-(((float)((float)16/(float)stretchOptions.ScaleYFactor))*(nHeight<OvlWinProp.SrcHeight?nHeight:OvlWinProp.SrcHeight)))/2;
					}
					else
					{
						xStart=(OvlWinProp.SrcPitch-(((float)((float)16/(float)stretchOptions.ScaleXFactor))*(nWidth)))/2; 
						yStart=(OvlWinProp.SrcHeight-(((float)((float)16/(float)stretchOptions.ScaleYFactor))*(nHeight)))/2; 
						if (yStart<0) yStart=(OvlWinProp.SrcHeight-(((float)((float)16/(float)stretchOptions.ScaleYFactor))*(nHeight)));
						if (xStart<0) xStart=(OvlWinProp.SrcPitch-(((float)((float)16/(float)stretchOptions.ScaleXFactor))*(nWidth)));
					}


			}
			if (!Rotate)
			{
				

				if (ForceFit)
				{
					ATI_RECT srcRect;
					ATI_CLIPRECT clipRect;
					ATI_POINT dpPoint;
					U32 y=(U32)VRAMoffset2;
					U32 VRAMTemp=VRAMoffset+(320*120);
					int nWidth;
					int nHeight;
					int row;
					int stepwidth=g_nWidth;
					//if (Rotate) stepwidth=g_nHeight;
					if (stepwidth%16) stepwidth+=16-(stepwidth%16);
					clipRect.X_Top_Left = 0;
					clipRect.Y_Top_Left = 0;
					clipRect.X_Bottom_Right = (S16)g_nWidth;
					clipRect.Y_Bottom_Right = (S16)64;
					AtiCore_SetSrcClippingRect( &clipRect );
					clipRect.X_Bottom_Right = (S16)OvlWinProp.SrcPitch;
					clipRect.Y_Bottom_Right = (S16)OvlWinProp.SrcHeight;
					AtiCore_SetDstClippingRect( &clipRect );
					srcRect.XCoord=0;
					srcRect.YCoord=0;
					for (row=0;row<=(g_nHeight/64);row++)
					{
						int size=64;
						if (row==g_nHeight/64)
						{
							size=g_nHeight%64;
							size-=size%16;
							if (!size)
								continue;
						}
						srcRect.Width=g_nWidth;
						srcRect.Height=size;
						AtiCore_SetupMemoryTransfer(VRAMoffset,&regdata);
						convert_yuv(avpict.data[0]+(avpict.linesize[0]*64*row), avpict.linesize[0],
						avpict.data[1], avpict.data[2], avpict.linesize[1],
						(unsigned char*) regdata, g_nWidth,size,stepwidth,0,PlayerOptions.Brightness,avpict.last_picture[0],avpict.last_picture[1],avpict.last_picture[2],0, 1);

						AtiCore_TerminateMemoryTransfer();


						srcRect.Width = stepwidth;
						srcRect.Height = size;

						dpPoint.XCoord =xStart;

						dpPoint.YCoord=((yStart-1)+((16*64*(row))/stretchOptions.ScaleXFactor));
						AtiCore_SetSrcPitchOffset( srcRect.Width, (U32)VRAMoffset );
						AtiCore_SetDstPitchOffset( OvlWinProp.SrcPitch, y);
						AtiCore_StretchBlt( &stretchOptions, &dpPoint, &srcRect );

						srcRect.Width=stepwidth;
						srcRect.Height=size>>1;

						AtiCore_SetupMemoryTransfer(VRAMoffset,&regdata);
						convert_yuv(avpict.data[0], avpict.linesize[0],
							avpict.data[1]+(avpict.linesize[1]*32*row), avpict.data[2]+(avpict.linesize[1]*32*row), avpict.linesize[1],
							(unsigned char*) regdata, g_nWidth,size,stepwidth,0,PlayerOptions.Brightness,avpict.last_picture[0],avpict.last_picture[1],avpict.last_picture[2],0, 2);

						AtiCore_TerminateMemoryTransfer();

						srcRect.Width = stepwidth>>1;
						srcRect.Height = size>>1;

						dpPoint.YCoord >>=1;
        
						dpPoint.XCoord >>=1;

						AtiCore_SetSrcPitchOffset( srcRect.Width, (U32)VRAMoffset);
						AtiCore_SetDstPitchOffset( OvlWinProp.SrcPitch>>1, (U32)y + OvlWinProp.SrcPitch * OvlWinProp.SrcHeight );
						AtiCore_StretchBlt( &stretchOptions, &dpPoint, &srcRect );

						AtiCore_SetSrcPitchOffset( srcRect.Width, (U32)VRAMoffset + srcRect.Width * (size>>1));
						AtiCore_SetDstPitchOffset( OvlWinProp.SrcPitch>>1, (U32)y + OvlWinProp.SrcPitch * OvlWinProp.SrcHeight * 5 / 4 );
						AtiCore_StretchBlt( &stretchOptions, &dpPoint, &srcRect );
					}
				}
				else
				{
					int stepwidth=g_nWidth;
					if (Rotate) stepwidth=g_nHeight;
					if (stepwidth%16) stepwidth+=16-(stepwidth%16);
					AtiCore_SetupMemoryTransfer(VRAMoffset2,&regdata);
					convert_yuv(avpict.data[0], avpict.linesize[0],
						avpict.data[1], avpict.data[2], avpict.linesize[1],
						(unsigned char*) regdata, g_nWidth,g_nHeight,stepwidth,0,PlayerOptions.Brightness,avpict.last_picture[0],avpict.last_picture[1],avpict.last_picture[2],0, 0);

					AtiCore_TerminateMemoryTransfer();
					while ( AtiCore_WaitComplete( 100 ) != SUCCESS );
					if (PlayerOptions.Double)
					{
						//ATI_STRETCH stretchOptions;
						ATI_POINT dpPoint;
						ATI_RECT srcRect;
						int nWidth=(stepwidth<DisplayWidth?stepwidth:DisplayWidth);
						int nHeight=(g_nHeight<DisplayHeight?g_nHeight:DisplayHeight);
						 dpPoint.XCoord = dpPoint.YCoord = 0;

						//AtiCore_SetOverlayPos(OverlayHandle,0,0); 
						srcRect.XCoord = srcRect.YCoord = 0;
						srcRect.Width = nWidth;
						srcRect.Height = nHeight;
						AtiCore_SetRopOperation( ROP3_SRCCOPY );
						AtiCore_SetDstType( DSTTYPE_8BPP );
						AtiCore_SetSrcType( SRCTYPE_EQU_DST );


						// Setting clipping rectangle for stretching.  Note that Src and Dst will have different sizes
						ATI_CLIPRECT clipRect;
						clipRect.X_Top_Left = 0;
						clipRect.Y_Top_Left = 0;
						clipRect.X_Bottom_Right = (S16)(g_nWidth<DisplayWidth?g_nWidth:DisplayWidth);
						clipRect.Y_Bottom_Right = (S16)nHeight;
						AtiCore_SetSrcClippingRect( &clipRect );
						clipRect.X_Bottom_Right = (S16)DisplayWidth;
						clipRect.Y_Bottom_Right = (S16)DisplayHeight;
						AtiCore_SetDstClippingRect( &clipRect );

						U32 y=(U32)OvlWinProp.lpSrcBitmap; 
						dpPoint.XCoord = xStart;
						dpPoint.YCoord =yStart;

						AtiCore_SetSrcPitchOffset( nWidth, (U32)VRAMoffset2 );
						AtiCore_SetDstPitchOffset( DisplayWidth, y);
						AtiCore_StretchBlt( &stretchOptions, &dpPoint, &srcRect );
        
						dpPoint.XCoord >>=1;
						dpPoint.YCoord >>=1;

						srcRect.Width >>=1;
						srcRect.Height>>=1;
						// U & V
						AtiCore_SetSrcPitchOffset( nWidth/2, (U32)VRAMoffset2 + nWidth * nHeight );
						AtiCore_SetDstPitchOffset( DisplayWidth/2, (U32)y + DisplayWidth * DisplayHeight );
						AtiCore_StretchBlt( &stretchOptions, &dpPoint, &srcRect );

						AtiCore_SetSrcPitchOffset( nWidth/2, (U32)VRAMoffset2 + nWidth * nHeight * 5 / 4 );
						AtiCore_SetDstPitchOffset( DisplayWidth/2, (U32)y + DisplayWidth * DisplayHeight * 5 / 4 );
						AtiCore_StretchBlt( &stretchOptions, &dpPoint, &srcRect );


					}
				}
			}
			else
			{
				if (ForceFit)
				{
					ATI_RECT srcRect;
					ATI_RECT dstRect;
					ATI_CLIPRECT clipRect;
					ATI_POINT dpPoint;
					U32 y=(U32)VRAMoffset2;
					U32 VRAMTemp=VRAMoffset+(320*120);
					int nWidth;
					int nHeight;
					int row;
					int step=g_nWidth<320?320:g_nWidth;
					clipRect.X_Top_Left = 0;
					clipRect.Y_Top_Left = 0;
					clipRect.X_Bottom_Right = (S16)step<DisplayHeight?DisplayHeight:step;
					clipRect.Y_Bottom_Right = (S16)DisplayWidth;
					AtiCore_SetSrcClippingRect( &clipRect );
					clipRect.X_Bottom_Right = (S16)DisplayWidth;
					clipRect.Y_Bottom_Right = (S16)step<DisplayHeight?DisplayHeight:step;
					AtiCore_SetDstClippingRect( &clipRect );
					srcRect.XCoord=0;
					srcRect.YCoord=0;
					dstRect.XCoord=0;
					dstRect.YCoord=0;
					for (row=0;row<=(g_nHeight/64);row++)
					{
						int size=64;
						if (row==g_nHeight/64)
						{
							size=g_nHeight%64;
							size-=size%16;
							if (!size)
								continue;
						}
						srcRect.Width=step;
						srcRect.Height=size;
						dstRect.Width=size;
						dstRect.Height=step;
						AtiCore_SetupMemoryTransfer(VRAMoffset,&regdata);
						convert_yuv(avpict.data[0]+(avpict.linesize[0]*64*row), avpict.linesize[0],
						avpict.data[1], avpict.data[2], avpict.linesize[1],
						(unsigned char*) regdata, g_nWidth,size,step,0,PlayerOptions.Brightness,avpict.last_picture[0],avpict.last_picture[1],avpict.last_picture[2],0, 2);

						AtiCore_TerminateMemoryTransfer();


						AtiCore_SetDstPitchOffset(dstRect.Width,VRAMTemp);
						AtiCore_SetSrcPitchOffset(step,VRAMoffset);
						AtiCore_BitBltFilpRotate( blt090Rotate, &dstRect, &srcRect );


						srcRect.Width = size;
						srcRect.Height = g_nWidth;

						dpPoint.YCoord =yStart;

						dpPoint.XCoord=DisplayWidth-((xStart-1)+((16*64*(row)+(16*size))/stretchOptions.ScaleXFactor));
						AtiCore_SetSrcPitchOffset( srcRect.Width, (U32)VRAMTemp );
						AtiCore_SetDstPitchOffset( OvlWinProp.SrcPitch, y);
						AtiCore_StretchBlt( &stretchOptions, &dpPoint, &srcRect );

						srcRect.Width=step;
						dstRect.Height=step;
						srcRect.Height=size>>1;
						dstRect.Width=size>>1;

						AtiCore_SetupMemoryTransfer(VRAMoffset,&regdata);
						convert_yuv(avpict.data[0], avpict.linesize[0],
							avpict.data[1]+(avpict.linesize[1]*32*row), avpict.data[2]+(avpict.linesize[1]*32*row), avpict.linesize[1],
							(unsigned char*) regdata, g_nWidth,size,step,0,PlayerOptions.Brightness,avpict.last_picture[0],avpict.last_picture[1],avpict.last_picture[2],0, 3);

						AtiCore_TerminateMemoryTransfer();

						AtiCore_SetDstPitchOffset(dstRect.Width,VRAMTemp);
						AtiCore_SetSrcPitchOffset(step,VRAMoffset);
						AtiCore_BitBltFilpRotate( blt090Rotate, &dstRect, &srcRect );


						srcRect.Width = size>>1;
						srcRect.Height = g_nWidth>>1;

						dpPoint.YCoord =yStart>>1;
        
						dpPoint.XCoord >>=1;

						AtiCore_SetSrcPitchOffset( srcRect.Width, (U32)VRAMTemp);
						AtiCore_SetDstPitchOffset( OvlWinProp.SrcPitch>>1, (U32)y + OvlWinProp.SrcPitch * OvlWinProp.SrcHeight );
						AtiCore_StretchBlt( &stretchOptions, &dpPoint, &srcRect );

						AtiCore_SetSrcPitchOffset( srcRect.Width, (U32)VRAMTemp + srcRect.Width * (step>>1));
						AtiCore_SetDstPitchOffset( OvlWinProp.SrcPitch>>1, (U32)y + OvlWinProp.SrcPitch * OvlWinProp.SrcHeight * 5 / 4 );
						AtiCore_StretchBlt( &stretchOptions, &dpPoint, &srcRect );
					}


				}
				else
				{
					ATI_RECT srcRect;
					ATI_RECT dstRect;
					srcRect.XCoord=0;
					srcRect.YCoord=0;
					dstRect.XCoord=0;
					dstRect.YCoord=0;
					srcRect.Width=320;
					srcRect.Height=g_nHeight<240?g_nHeight:240;
					dstRect.Width=g_nHeight<240?g_nHeight:240;
					if (dstRect.Width%16) dstRect.Width-=(dstRect.Width%16);
					srcRect.Height=dstRect.Width;
					dstRect.Height=320;
					AtiCore_SetupMemoryTransfer(VRAMoffset,&regdata);
					convert_yuv(avpict.data[0], avpict.linesize[0],
					avpict.data[1], avpict.data[2], avpict.linesize[1],
					(unsigned char*) regdata, g_nWidth,g_nHeight,320,0,PlayerOptions.Brightness,avpict.last_picture[0],avpict.last_picture[1],avpict.last_picture[2],0, 0);

					AtiCore_TerminateMemoryTransfer();

					ATI_CLIPRECT clipRect;
					clipRect.X_Top_Left = 0;
					clipRect.Y_Top_Left = 0;
					clipRect.X_Bottom_Right = (S16)DisplayHeight;//nHeight;
					clipRect.Y_Bottom_Right = (S16)DisplayWidth;
					AtiCore_SetSrcClippingRect( &clipRect );
					clipRect.X_Bottom_Right = (S16)DisplayWidth;
					clipRect.Y_Bottom_Right = (S16)DisplayHeight;
					AtiCore_SetDstClippingRect( &clipRect );

					AtiCore_SetDstPitchOffset(dstRect.Width,VRAMoffset2);
					AtiCore_SetSrcPitchOffset(320,VRAMoffset);
					AtiCore_BitBltFilpRotate( blt090Rotate, &dstRect, &srcRect );

					srcRect.Height>>=1;
					dstRect.Width>>=1;

					AtiCore_SetupMemoryTransfer(VRAMoffset,&regdata);
					convert_yuv(avpict.data[0], avpict.linesize[0],
						avpict.data[1], avpict.data[2], avpict.linesize[1],
						(unsigned char*) regdata, g_nWidth,g_nHeight,320,0,PlayerOptions.Brightness,avpict.last_picture[0],avpict.last_picture[1],avpict.last_picture[2],0, 1);

					AtiCore_TerminateMemoryTransfer();

					AtiCore_SetDstPitchOffset(dstRect.Width,VRAMoffset2+ 320 * (dstRect.Width<<1));
					AtiCore_SetSrcPitchOffset(320,VRAMoffset);
					AtiCore_BitBltFilpRotate( blt090Rotate, &dstRect, &srcRect );

					if (PlayerOptions.Double)
					{
						ATI_POINT dpPoint;
						ATI_RECT srcRect;
						int nWidth=(g_nHeight<DisplayWidth?g_nHeight:DisplayWidth);
						int nHeight=(g_nWidth<DisplayHeight?g_nWidth:DisplayHeight);
						 dpPoint.XCoord = dpPoint.YCoord = 0;
						//AtiCore_SetOverlayPos(OverlayHandle,0,0); 
						if (nWidth%16) nWidth-=(nWidth%16);


						srcRect.XCoord = srcRect.YCoord = 0;
						srcRect.Width = nWidth;
						srcRect.Height = nHeight;
						AtiCore_SetRopOperation( ROP3_SRCCOPY );
						AtiCore_SetDstType( DSTTYPE_8BPP );
						AtiCore_SetSrcType( SRCTYPE_EQU_DST );

						// Setting clipping rectangle for stretching.  Note that Src and Dst will have different sizes

						U32 y=(U32)OvlWinProp.lpSrcBitmap; // + (xStart + DisplayWidth*yStart);
						dpPoint.XCoord = xStart;
						dpPoint.YCoord =yStart;

						AtiCore_SetSrcPitchOffset( nWidth, (U32)VRAMoffset2 );
						AtiCore_SetDstPitchOffset( DisplayWidth, y);
						AtiCore_StretchBlt( &stretchOptions, &dpPoint, &srcRect );
        
						dpPoint.XCoord >>=1;
						dpPoint.YCoord >>=1;

						srcRect.Width >>=1;
						srcRect.Height >>=1;
						// U & V
						AtiCore_SetSrcPitchOffset( nWidth/2, (U32)VRAMoffset2 + nWidth * 320 );
						AtiCore_SetDstPitchOffset( DisplayWidth/2, (U32)y + DisplayWidth * DisplayHeight );
						AtiCore_StretchBlt( &stretchOptions, &dpPoint, &srcRect );

						AtiCore_SetSrcPitchOffset( nWidth/2, (U32)VRAMoffset2 + nWidth * 320 * 5 / 4 );
						AtiCore_SetDstPitchOffset( DisplayWidth/2, (U32)y + DisplayWidth * DisplayHeight * 5 / 4 );
						AtiCore_StretchBlt( &stretchOptions, &dpPoint, &srcRect );

					}
				}
				
			}
			AtiCore_SetOverlayOnOff(OverlayHandle,1);

		}
	}

	else if (Extra==-1)
	{
			while(AtiCore_SetOverlayOnOff(OverlayHandle,0)!=SUCCESS);
	}
	LeaveCriticalSection(&cs);
	return render_flag;
}

#endif