/****************************************************************************************/

/*  DrawDecal.H                                                                         */

/*                                                                                      */

/*  Author: Ken Baird, Mike Sandige                                                     */

/*  Description:  This is a simple 2d blitter for the Jet3d software driver.            */

/*                                                                                      */

/*  The contents of this file are subject to the Jet3D Public License                   */

/*  Version 1.02 (the "License"); you may not use this file except in                   */

/*  compliance with the License. You may obtain a copy of the License at                */

/*  http://www.jet3d.com                                                                */

/*                                                                                      */

/*  Software distributed under the License is distributed on an "AS IS"                 */

/*  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See                */

/*  the License for the specific language governing rights and limitations              */

/*  under the License.                                                                  */

/*                                                                                      */

/*  The Original Code is Jet3D, released December 12, 1999.                             */

/*  Copyright (C) 1996-1999 Eclipse Entertainment, L.L.C. All Rights Reserved           */

/*                                                                                      */

/****************************************************************************************/



#include "DrawDecal.h"

#include "SoftDrv.h"

#include "Errorlog.h"



static int32		BWidth, BHeight, BStride;

static int32		DrawWidth, DrawHeight;

static int32		EbpAdd, EdiAdd;

static uint16		*BBitPtr16;

static uint8		*BBitPtr;

static uint16		*pScrPtr16bpp;

static uint32		*pScrPtr32bpp;



jeBoolean DRIVERCC DrawDecal(jeRDriver_THandle *THandle, RECT *SRect, int32 x, int32 y)

{

	jeRDriver_THandleInfo Info;

	uint16 *Bits;



	if(!SD_Active)

	{

		return	JE_TRUE;

	}

	

	if (SWTHandle_GetInfo(THandle,0,&Info)==JE_FALSE)

		{

			jeErrorLog_Add(JE_ERR_INTERNAL_RESOURCE,"Softdrv - DrawDecal: bad texture handle");

			return JE_FALSE;

		}

	if (SWTHandle_LockTextureHandle(THandle,0,(void **)&Bits)==JE_FALSE)

		{

			jeErrorLog_Add(JE_ERR_INTERNAL_RESOURCE,"Softdrv - DrawDecal: unable to lock texture handle (already locked?)");

			return JE_FALSE;

		}





	BWidth		=Info.Width;

	BHeight		=Info.Height;

	DrawWidth	=Info.Width;

	DrawHeight	=Info.Height;

	

	#if 0

	if(SD_ProcessorHas3DNow )

	{

		U32	*PalPtr;

		BBitPtr		= Bits; //(U8 *)THandle->BitPtr[0];



		if ( ! THandle->PalHandle )

			goto finished;



		PalPtr	=(U32 *)THandle->PalHandle->BitPtr[0];



		if(SRect)

		{

			BBitPtr		+=SRect->top * DrawWidth + SRect->left;

			DrawHeight	=(SRect->bottom - SRect->top);

			DrawWidth	=(SRect->right - SRect->left);

		}



		if(x < 0)

		{

			if(x + DrawWidth <= 0)

			{

				goto finished;

			}

			BBitPtr		-=x;

			DrawWidth	+=x;

			x			=0;

		}



		if(y < 0)

		{

			if(y + DrawHeight <= 0)

			{

				goto finished;

			}

			BBitPtr		-=y * BWidth;

			DrawHeight	+=y;

			y			=0;

		}

		

		if(x >= ClientWindow.Width)

		{

			goto finished;

		}

		if(y >= ClientWindow.Height)

		{

			goto finished;

		}



		if(x + DrawWidth >= (ClientWindow.Width-1))

			DrawWidth -= (x+DrawWidth) - (ClientWindow.Width-1);



		if(y + DrawHeight >= (ClientWindow.Height-1))

			DrawHeight -=  (y+DrawHeight)- (ClientWindow.Height-1);



		if(DrawWidth <= 0)

			goto finished;

		

		if(DrawHeight <= 0)

			goto finished;



		pScrPtr32bpp	=(U32 *)(ClientWindow.Buffer);

		pScrPtr32bpp	=&pScrPtr32bpp[y * ClientWindow.Width + x];



		__asm

		{

			push ecx

			push esi

			push edi

			push ebp



			mov	ebx,PalPtr



			mov ebp, pScrPtr32bpp

			mov edi, BBitPtr



			mov ecx, DrawWidth



			mov edx, ClientWindow.PixelPitch

			shl ecx,2

			sub edx, ecx

			mov EbpAdd, edx



			mov edx, BWidth

			mov ecx, DrawHeight

			sub edx, DrawWidth

			mov EdiAdd, edx





		NextHeight:

		

			push ecx

			mov ecx, DrawWidth



			lea	ebp,[4*ecx+ebp]



			add edi, ecx

//			shl ecx, 2

//			add ebp, ecx



			neg ecx



			NextWidth:

				xor	eax,eax

				mov al, [edi+ecx]

				

				cmp al,0ffh

				je Skip



//				cmp al,01h

//				je Skip



				mov	eax,[ebx+eax*4]



				mov [ebp+ecx*4], eax



			Skip:

				inc ecx

				jnz NextWidth



			add ebp, EbpAdd

			add edi, EdiAdd



			pop ecx

			

			sub ecx, 1

			jnz NextHeight



			pop ebp

			pop edi

			pop esi

			pop ecx

		}

	}

	else

	#endif

	{

		BBitPtr16	= Bits; //THandle->BitPtr[0];

		if(SRect)

		{

			BBitPtr16	+=SRect->top * DrawWidth + SRect->left;

			DrawHeight	=(SRect->bottom - SRect->top);

			DrawWidth	=(SRect->right - SRect->left);

		}



		if(x < 0)

		{

			if(x + DrawWidth <= 0)

			{

				goto finished;

			}

			BBitPtr16	-=x;

			DrawWidth	+=x;

			x			=0;

		}



		if(y < 0)

		{

			if(y + DrawHeight <= 0)

			{

				goto finished;

			}

			BBitPtr16	-=y*BWidth;

			DrawHeight	+=y;

			y			=0;

		}

		

		if(x >= ClientWindow.Width)

		{

			goto finished;

		}

		if(y >= ClientWindow.Height)

		{

			goto finished;

		}



		if(x + DrawWidth >= (ClientWindow.Width - 1))

		{

			DrawWidth	-=(x + DrawWidth) - (ClientWindow.Width - 1);

		}

		if(y + DrawHeight >= (ClientWindow.Height - 1))

		{

			DrawHeight	-=(y + DrawHeight) - (ClientWindow.Height - 1);

		}



		if(DrawWidth <= 0)

		{

			goto finished;

		}

		if(DrawHeight <= 0)

		{

			goto finished;

		}



		pScrPtr16bpp	=(U16 *)(ClientWindow.Buffer);

		pScrPtr16bpp	=&pScrPtr16bpp[y * (ClientWindow.PixelPitch >> 1) + x];



#ifdef WIN32

		__asm

		{

			push ecx

			push esi

			push edi

			push ebp



			mov ebp, pScrPtr16bpp

			mov edi, BBitPtr16



			mov ecx, DrawWidth



			mov edx, ClientWindow.PixelPitch

			sub edx, ecx

			sub edx, ecx

			mov EbpAdd, edx



			mov edx, BWidth

			add edx, BWidth

			sub edx, ecx

			sub edx, ecx

			mov EdiAdd, edx



			mov ecx, DrawHeight



		NextHeightA:

		

			push ecx

			mov ecx, DrawWidth



			shl ecx, 1

			add ebp, ecx

			add edi, ecx



			neg ecx



			NextWidthA:

				mov ax, [edi+ecx]

				

				cmp ax, 0x1

				je SkipA



				mov [ebp+ecx], ax



			SkipA:

				add ecx, 2

				jnz NextWidthA



			add ebp, EbpAdd

			add edi, EdiAdd



			pop ecx

			

			sub ecx, 1

			jnz NextHeightA



			pop ebp

			pop edi

			pop esi

			pop ecx

		}

#endif



#ifdef BUILD_BE

	__asm__ __volatile ("

			pushl %%ecx

			pushl %%esi

			pushl %%edi

			pushl %%ebp



			movl %0, %%ebp  //;ebp, pScrPtr16bpp

			movl %1, %%edi  //;edi, BBitPtr16



			movl %2, %%ecx  //;mov ecx, DrawWidth



			movl %3, %%edx  		//;mov edx, ClientWindow.PixelPitch

			sub %%ecx, %%edx 	//;edx, ecx

			sub %%ecx, %%edx 	//;edx, ecx

			movl %%edx , EbpAdd 	//;EbpAdd, edx



			movl BWidth, %%edx  //;mov edx, BWidth

			add BWidth, %%edx  //;add edx, BWidth

			sub %%ecx, %%edx   //;sub edx, ecx

			sub %%ecx, %%edx   //;sub edx, ecx

			movl %%edx, EdiAdd  //;mov EdiAdd, edx



			movl DrawHeight, %%ecx   //;mov ecx, DrawHeight



		NextHeightA:

		

			pushl %%ecx

			movl DrawWidth, %%ecx   //;ecx, DrawWidth



			shl $1, %%ecx     //;shl ecx, 1

			add %%ecx, %%ebp  //; add ebp, ecx

			add %%ecx, %%edi  //;add edi, ecx



			neg %%ecx



			NextWidthA:

				movw (%%ecx,%%edi,1) ,%%ax //;mov ax, [edi+ecx]

				

				cmpw $0x1, %%ax   //;cmp ax, 0x1

				je SkipA



				movw %%ax, (%%ecx,%%ebp,1)  //;mov [ebp+ecx], ax



			SkipA:

				add $2, %%ecx     //;ecx, 2

				jnz NextWidthA



			add EbpAdd, %%ebp      //;add ebp, EbpAdd

			add EdiAdd, %%edi      //;add edi, EdiAdd



			popl %%ecx

			

			sub $1, %%ecx        //;ecx, 1

			jnz NextHeightA



			popl %%ebp

			popl %%edi

			popl %%esi

			popl %%ecx" 

	  : // outputs

	  : "g" (pScrPtr16bpp) , "g" (BBitPtr16),  "g" (DrawWidth), "g" (ClientWindow.PixelPitch)

	  : "%eax");

#endif



	}



	finished:

		SWTHandle_UnLockTextureHandle(THandle,0);

	return JE_TRUE;

}







