| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006 |
- /*
- ** Command & Conquer Generals(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** This program is free software: you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation, either version 3 of the License, or
- ** (at your option) any later version.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- /***********************************************************************************************
- *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
- ***********************************************************************************************
- * *
- * Project Name : WW3D *
- * *
- * $Archive:: /VSS_Sync/ww3d2/surfaceclass.cpp $*
- * *
- * Original Author:: Nathaniel Hoffman *
- * *
- * $Author:: Vss_sync $*
- * *
- * $Modtime:: 8/29/01 7:29p $*
- * *
- * $Revision:: 24 $*
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * SurfaceClass::Clear -- Clears a surface to 0 *
- * SurfaceClass::Copy -- Copies a region from one surface to another of the same format *
- * SurfaceClass::FindBBAlpha -- Finds the bounding box of non zero pixels in the region (x0, *
- * PixelSize -- Helper Function to find the size in bytes of a pixel *
- * SurfaceClass::Is_Transparent_Column -- Tests to see if the column is transparent or not *
- * SurfaceClass::Copy -- Copies from a byte array to the surface *
- * SurfaceClass::CreateCopy -- Creates a byte array copy of the surface *
- * SurfaceClass::DrawHLine -- draws a horizontal line *
- * SurfaceClass::DrawPixel -- draws a pixel *
- * SurfaceClass::Copy -- Copies a block of system ram to the surface *
- * SurfaceClass::Hue_Shift -- changes the hue of the surface *
- * SurfaceClass::Is_Monochrome -- Checks if surface is monochrome or not *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include "surfaceclass.h"
- #include "formconv.h"
- #include "dx8wrapper.h"
- #include "vector2i.h"
- #include "colorspace.h"
- #include "bound.h"
- #include <d3dx8.h>
- /***********************************************************************************************
- * PixelSize -- Helper Function to find the size in bytes of a pixel *
- * *
- * *
- * *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 2/13/2001 hy : Created. *
- *=============================================================================================*/
- unsigned int PixelSize(const SurfaceClass::SurfaceDescription &sd)
- {
- unsigned int size=0;
- switch (sd.Format)
- {
- case WW3D_FORMAT_A8R8G8B8:
- case WW3D_FORMAT_X8R8G8B8:
- size=4;
- break;
- case WW3D_FORMAT_R8G8B8:
- size=3;
- break;
- case WW3D_FORMAT_R5G6B5:
- case WW3D_FORMAT_X1R5G5B5:
- case WW3D_FORMAT_A1R5G5B5:
- case WW3D_FORMAT_A4R4G4B4:
- case WW3D_FORMAT_A8R3G3B2:
- case WW3D_FORMAT_X4R4G4B4:
- case WW3D_FORMAT_A8P8:
- case WW3D_FORMAT_A8L8:
- size=2;
- break;
- case WW3D_FORMAT_R3G3B2:
- case WW3D_FORMAT_A8:
- case WW3D_FORMAT_P8:
- case WW3D_FORMAT_L8:
- case WW3D_FORMAT_A4L4:
- size=1;
- break;
- }
- return size;
- }
- void Convert_Pixel(Vector3 &rgb, const SurfaceClass::SurfaceDescription &sd, const unsigned char * pixel)
- {
- const float scale=1/255.0f;
- switch (sd.Format)
- {
- case WW3D_FORMAT_A8R8G8B8:
- case WW3D_FORMAT_X8R8G8B8:
- case WW3D_FORMAT_R8G8B8:
- {
- rgb.X=pixel[2]; // R
- rgb.Y=pixel[1]; // G
- rgb.Z=pixel[0]; // B
- }
- break;
- case WW3D_FORMAT_A4R4G4B4:
- {
- unsigned short tmp;
- tmp=*(unsigned short*)&pixel[0];
- rgb.X=((tmp&0x0f00)>>4); // R
- rgb.Y=((tmp&0x00f0)); // G
- rgb.Z=((tmp&0x000f)<<4); // B
- }
- break;
- case WW3D_FORMAT_A1R5G5B5:
- {
- unsigned short tmp;
- tmp=*(unsigned short*)&pixel[0];
- rgb.X=(tmp>>7)&0xf8; // R
- rgb.Y=(tmp>>2)&0xf8; // G
- rgb.Z=(tmp<<3)&0xf8; // B
- }
- break;
- case WW3D_FORMAT_R5G6B5:
- {
- unsigned short tmp;
- tmp=*(unsigned short*)&pixel[0];
- rgb.X=(tmp>>8)&0xf8;
- rgb.Y=(tmp>>3)&0xfc;
- rgb.Z=(tmp<<3)&0xf8;
- }
- break;
- default:
- // TODO: Implement other pixel formats
- WWASSERT(0);
- }
- rgb*=scale;
- }
- // Note: This function must never overwrite the original alpha
- void Convert_Pixel(unsigned char * pixel,const SurfaceClass::SurfaceDescription &sd, const Vector3 &rgb)
- {
- unsigned char r,g,b;
- r=(unsigned char) (rgb.X*255.0f);
- g=(unsigned char) (rgb.Y*255.0f);
- b=(unsigned char) (rgb.Z*255.0f);
- switch (sd.Format)
- {
- case WW3D_FORMAT_A8R8G8B8:
- case WW3D_FORMAT_X8R8G8B8:
- case WW3D_FORMAT_R8G8B8:
- pixel[0]=b;
- pixel[1]=g;
- pixel[2]=r;
- break;
- case WW3D_FORMAT_A4R4G4B4:
- {
- unsigned short tmp;
- tmp=*(unsigned short*)&pixel[0];
- tmp&=0xF000;
- tmp|=(r&0xF0) << 4;
- tmp|=(g&0xF0);
- tmp|=(b&0xF0) >> 4;
- *(unsigned short*)&pixel[0]=tmp;
- }
- break;
- case WW3D_FORMAT_A1R5G5B5:
- {
- unsigned short tmp;
- tmp=*(unsigned short*)&pixel[0];
- tmp&=0x8000;
- tmp|=(r&0xF8) << 7;
- tmp|=(g&0xF8) << 2;
- tmp|=(b&0xF8) >> 3;
- *(unsigned short*)&pixel[0]=tmp;
- }
- break;
- case WW3D_FORMAT_R5G6B5:
- {
- unsigned short tmp;
- tmp=(r&0xf8) << 8;
- tmp|=(g&0xfc) << 3;
- tmp|=(b&0xf8) >> 3;
- *(unsigned short*)&pixel[0]=tmp;
- }
- break;
- default:
- // TODO: Implement other pixel formats
- WWASSERT(0);
- }
- }
- /*************************************************************************
- ** SurfaceClass
- *************************************************************************/
- SurfaceClass::SurfaceClass(unsigned width, unsigned height, WW3DFormat format):
- D3DSurface(NULL),
- SurfaceFormat(format)
- {
- WWASSERT(width);
- WWASSERT(height);
- D3DSurface = DX8Wrapper::_Create_DX8_Surface(width, height, format);
- }
- SurfaceClass::SurfaceClass(const char *filename):
- D3DSurface(NULL)
- {
- D3DSurface = DX8Wrapper::_Create_DX8_Surface(filename);
- SurfaceDescription desc;
- Get_Description(desc);
- SurfaceFormat=desc.Format;
- }
- SurfaceClass::SurfaceClass(IDirect3DSurface8 *d3d_surface) :
- D3DSurface (NULL)
- {
- Attach (d3d_surface);
- SurfaceDescription desc;
- Get_Description(desc);
- SurfaceFormat=desc.Format;
- }
- SurfaceClass::~SurfaceClass(void)
- {
- if (D3DSurface) {
- D3DSurface->Release();
- D3DSurface = NULL;
- }
- }
- void SurfaceClass::Get_Description(SurfaceDescription &surface_desc)
- {
- D3DSURFACE_DESC d3d_desc;
- ::ZeroMemory(&d3d_desc, sizeof(D3DSURFACE_DESC));
- DX8_ErrorCode(D3DSurface->GetDesc(&d3d_desc));
- surface_desc.Format = D3DFormat_To_WW3DFormat(d3d_desc.Format);
- surface_desc.Height = d3d_desc.Height;
- surface_desc.Width = d3d_desc.Width;
- }
- void * SurfaceClass::Lock(int * pitch)
- {
- D3DLOCKED_RECT lock_rect;
- ::ZeroMemory(&lock_rect, sizeof(D3DLOCKED_RECT));
- DX8_ErrorCode(D3DSurface->LockRect(&lock_rect, 0, 0));
- *pitch = lock_rect.Pitch;
- return (void *)lock_rect.pBits;
- }
- void SurfaceClass::Unlock(void)
- {
- DX8_ErrorCode(D3DSurface->UnlockRect());
- }
- /***********************************************************************************************
- * SurfaceClass::Clear -- Clears a surface to 0 *
- * *
- * *
- * *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 2/13/2001 hy : Created. *
- *=============================================================================================*/
- void SurfaceClass::Clear()
- {
- SurfaceDescription sd;
- Get_Description(sd);
- // size of each pixel in bytes
- unsigned int size=PixelSize(sd);
- D3DLOCKED_RECT lock_rect;
- ::ZeroMemory(&lock_rect, sizeof(D3DLOCKED_RECT));
- DX8_ErrorCode(D3DSurface->LockRect(&lock_rect,0,0));
- unsigned int i;
- unsigned char *mem=(unsigned char *) lock_rect.pBits;
- for (i=0; i<sd.Height; i++)
- {
- memset(mem,0,size*sd.Width);
- mem+=lock_rect.Pitch;
- }
-
- DX8_ErrorCode(D3DSurface->UnlockRect());
- }
- /***********************************************************************************************
- * SurfaceClass::Copy -- Copies from a byte array to the surface *
- * *
- * *
- * *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 3/15/2001 hy : Created. *
- *=============================================================================================*/
- void SurfaceClass::Copy(const unsigned char *other)
- {
- SurfaceDescription sd;
- Get_Description(sd);
- // size of each pixel in bytes
- unsigned int size=PixelSize(sd);
- D3DLOCKED_RECT lock_rect;
- ::ZeroMemory(&lock_rect, sizeof(D3DLOCKED_RECT));
- DX8_ErrorCode(D3DSurface->LockRect(&lock_rect,0,0));
- unsigned int i;
- unsigned char *mem=(unsigned char *) lock_rect.pBits;
- for (i=0; i<sd.Height; i++)
- {
- memcpy(mem,&other[i*sd.Width*size],size*sd.Width);
- mem+=lock_rect.Pitch;
- }
-
- DX8_ErrorCode(D3DSurface->UnlockRect());
- }
- /***********************************************************************************************
- * SurfaceClass::Copy -- Copies a block of system ram to the surface *
- * *
- * *
- * *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 5/2/2001 hy : Created. *
- *=============================================================================================*/
- void SurfaceClass::Copy(Vector2i &min,Vector2i &max, const unsigned char *other)
- {
- SurfaceDescription sd;
- Get_Description(sd);
- // size of each pixel in bytes
- unsigned int size=PixelSize(sd);
- D3DLOCKED_RECT lock_rect;
- ::ZeroMemory(&lock_rect, sizeof(D3DLOCKED_RECT));
- RECT rect;
- rect.left=min.I;
- rect.right=max.I;
- rect.top=min.J;
- rect.bottom=max.J;
- DX8_ErrorCode(D3DSurface->LockRect(&lock_rect,&rect,0));
- int i;
- unsigned char *mem=(unsigned char *) lock_rect.pBits;
- int dx=max.I-min.I;
- for (i=min.J; i<max.J; i++)
- {
- memcpy(mem,&other[(i*sd.Width+min.I)*size],size*dx);
- mem+=lock_rect.Pitch;
- }
-
- DX8_ErrorCode(D3DSurface->UnlockRect());
- }
- /***********************************************************************************************
- * SurfaceClass::CreateCopy -- Creates a byte array copy of the surface *
- * *
- * *
- * *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 3/16/2001 hy : Created. *
- *=============================================================================================*/
- unsigned char *SurfaceClass::CreateCopy(int *width,int *height,int*size,bool flip)
- {
- SurfaceDescription sd;
- Get_Description(sd);
- // size of each pixel in bytes
- unsigned int mysize=PixelSize(sd);
- *width=sd.Width;
- *height=sd.Height;
- *size=mysize;
- unsigned char *other=W3DNEWARRAY unsigned char [sd.Height*sd.Width*mysize];
- D3DLOCKED_RECT lock_rect;
- ::ZeroMemory(&lock_rect, sizeof(D3DLOCKED_RECT));
- DX8_ErrorCode(D3DSurface->LockRect(&lock_rect,0,D3DLOCK_READONLY));
- unsigned int i;
- unsigned char *mem=(unsigned char *) lock_rect.pBits;
- for (i=0; i<sd.Height; i++)
- {
- if (flip)
- {
- memcpy(&other[(sd.Height-i-1)*sd.Width*mysize],mem,mysize*sd.Width);
- } else
- {
- memcpy(&other[i*sd.Width*mysize],mem,mysize*sd.Width);
- }
- mem+=lock_rect.Pitch;
- }
-
- DX8_ErrorCode(D3DSurface->UnlockRect());
- return other;
- }
- /***********************************************************************************************
- * SurfaceClass::Copy -- Copies a region from one surface to another *
- * *
- * *
- * *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 2/13/2001 hy : Created. *
- *=============================================================================================*/
- void SurfaceClass::Copy(
- unsigned int dstx, unsigned int dsty,
- unsigned int srcx, unsigned int srcy,
- unsigned int width, unsigned int height,
- const SurfaceClass *other)
- {
- WWASSERT(other);
- WWASSERT(width);
- WWASSERT(height);
- SurfaceDescription sd,osd;
- Get_Description(sd);
- const_cast <SurfaceClass*>(other)->Get_Description(osd);
- RECT src;
- src.left=srcx;
- src.right=srcx+width;
- src.top=srcy;
- src.bottom=srcy+height;
- if (src.right>int(osd.Width)) src.right=int(osd.Width);
- if (src.bottom>int(osd.Height)) src.bottom=int(osd.Height);
- if (sd.Format==osd.Format && sd.Width==osd.Width && sd.Height==osd.Height)
- {
- POINT dst;
- dst.x=dstx;
- dst.y=dsty;
- DX8Wrapper::_Copy_DX8_Rects(other->D3DSurface,&src,1,D3DSurface,&dst);
- }
- else
- {
- RECT dest;
- dest.left=dstx;
- dest.right=dstx+width;
- dest.top=dsty;
- dest.bottom=dsty+height;
- if (dest.right>int(sd.Width)) dest.right=int(sd.Width);
- if (dest.bottom>int(sd.Height)) dest.bottom=int(sd.Height);
- DX8_ErrorCode(D3DXLoadSurfaceFromSurface(D3DSurface,NULL,&dest,other->D3DSurface,NULL,&src,D3DX_FILTER_NONE,0));
- }
- }
- /***********************************************************************************************
- * SurfaceClass::Copy -- Copies a region from one surface to another *
- * *
- * *
- * *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 2/13/2001 hy : Created. *
- *=============================================================================================*/
- void SurfaceClass::Stretch_Copy(
- unsigned int dstx, unsigned int dsty, unsigned int dstwidth, unsigned int dstheight,
- unsigned int srcx, unsigned int srcy, unsigned int srcwidth, unsigned int srcheight,
- const SurfaceClass *other)
- {
- WWASSERT(other);
- SurfaceDescription sd,osd;
- Get_Description(sd);
- const_cast <SurfaceClass*>(other)->Get_Description(osd);
- RECT src;
- src.left=srcx;
- src.right=srcx+srcwidth;
- src.top=srcy;
- src.bottom=srcy+srcheight;
- RECT dest;
- dest.left=dstx;
- dest.right=dstx+dstwidth;
- dest.top=dsty;
- dest.bottom=dsty+dstheight;
- DX8_ErrorCode(D3DXLoadSurfaceFromSurface(D3DSurface,NULL,&dest,other->D3DSurface,NULL,&src,D3DX_FILTER_TRIANGLE ,0));
- }
- /***********************************************************************************************
- * SurfaceClass::FindBB -- Finds the bounding box of non zero pixels in the region *
- * *
- * *
- * *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 2/13/2001 hy : Created. *
- *=============================================================================================*/
- void SurfaceClass::FindBB(Vector2i *min,Vector2i*max)
- {
- SurfaceDescription sd;
- Get_Description(sd);
- WWASSERT(Has_Alpha(sd.Format));
- int alphabits=Alpha_Bits(sd.Format);
- int mask=0;
- switch (alphabits)
- {
- case 1: mask=1;
- break;
- case 4: mask=0xf;
- break;
- case 8: mask=0xff;
- break;
- }
- D3DLOCKED_RECT lock_rect;
- ::ZeroMemory(&lock_rect, sizeof(D3DLOCKED_RECT));
- RECT rect;
- ::ZeroMemory(&rect, sizeof(RECT));
- rect.bottom=max->J;
- rect.top=min->J;
- rect.left=min->I;
- rect.right=max->I;
- DX8_ErrorCode(D3DSurface->LockRect(&lock_rect,&rect,D3DLOCK_READONLY));
- int x,y;
- unsigned int size=PixelSize(sd);
- Vector2i realmin=*max;
- Vector2i realmax=*min;
-
- // the assumption here is that whenever a pixel has alpha it's in the MSB
- for (y = min->J; y < max->J; y++) {
- for (x = min->I; x < max->I; x++) {
- unsigned char *alpha=(unsigned char*) ((unsigned int)lock_rect.pBits+(y-min->J)*lock_rect.Pitch+(x-min->I)*size);
- #pragma MESSAGE("HY - this is not endian safe")
- unsigned char myalpha=alpha[size-1];
- myalpha=(myalpha>>(8-alphabits)) & mask;
- if (myalpha) {
- realmin.I = MIN(realmin.I, x);
- realmax.I = MAX(realmax.I, x);
- realmin.J = MIN(realmin.J, y);
- realmax.J = MAX(realmax.J, y);
- }
- }
- }
- DX8_ErrorCode(D3DSurface->UnlockRect());
- *max=realmax;
- *min=realmin;
- }
- /***********************************************************************************************
- * SurfaceClass::Is_Transparent_Column -- Tests to see if the column is transparent or not *
- * *
- * *
- * *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 2/13/2001 hy : Created. *
- *=============================================================================================*/
- bool SurfaceClass::Is_Transparent_Column(unsigned int column)
- {
- SurfaceDescription sd;
- Get_Description(sd);
- WWASSERT(column<sd.Width);
- WWASSERT(Has_Alpha(sd.Format));
- int alphabits=Alpha_Bits(sd.Format);
- int mask=0;
- switch (alphabits)
- {
- case 1: mask=1;
- break;
- case 4: mask=0xf;
- break;
- case 8: mask=0xff;
- break;
- }
- unsigned int size=PixelSize(sd);
- D3DLOCKED_RECT lock_rect;
- ::ZeroMemory(&lock_rect, sizeof(D3DLOCKED_RECT));
- RECT rect;
- ::ZeroMemory(&rect, sizeof(RECT));
- rect.bottom=sd.Height;
- rect.top=0;
- rect.left=column;
- rect.right=column+1;
- DX8_ErrorCode(D3DSurface->LockRect(&lock_rect,&rect,D3DLOCK_READONLY));
- int y;
-
- // the assumption here is that whenever a pixel has alpha it's in the MSB
- for (y = 0; y < (int) sd.Height; y++)
- {
- unsigned char *alpha=(unsigned char*) ((unsigned int)lock_rect.pBits+y*lock_rect.Pitch);
- #pragma MESSAGE("HY - this is not endian safe")
- unsigned char myalpha=alpha[size-1];
- myalpha=(myalpha>>(8-alphabits)) & mask;
- if (myalpha) {
- DX8_ErrorCode(D3DSurface->UnlockRect());
- return false;
- }
- }
- DX8_ErrorCode(D3DSurface->UnlockRect());
- return true;
- }
- /***********************************************************************************************
- * SurfaceClass::Get_Pixel -- Returns the pixel's RGB valus to the caller *
- * *
- * *
- * *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 2/13/2001 hy : Created. *
- *=============================================================================================*/
- void SurfaceClass::Get_Pixel(Vector3 &rgb, int x,int y)
- {
- SurfaceDescription sd;
- Get_Description(sd);
- x = min(x,(int)sd.Width - 1);
- y = min(y,(int)sd.Height - 1);
- D3DLOCKED_RECT lock_rect;
- ::ZeroMemory(&lock_rect, sizeof(D3DLOCKED_RECT));
- RECT rect;
- ::ZeroMemory(&rect, sizeof(RECT));
- rect.bottom=y+1;
- rect.top=y;
- rect.left=x;
- rect.right=x+1;
- DX8_ErrorCode(D3DSurface->LockRect(&lock_rect,&rect,D3DLOCK_READONLY));
- Convert_Pixel(rgb,sd,(unsigned char *) lock_rect.pBits);
- DX8_ErrorCode(D3DSurface->UnlockRect());
- }
- /***********************************************************************************************
- * SurfaceClass::Attach -- Attaches a surface pointer to the object, releasing the current ptr.*
- * *
- * *
- * *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 3/27/2001 pds : Created. *
- *=============================================================================================*/
- void SurfaceClass::Attach (IDirect3DSurface8 *surface)
- {
- Detach ();
- D3DSurface = surface;
-
- //
- // Lock a reference onto the object
- //
- if (D3DSurface != NULL) {
- D3DSurface->AddRef ();
- }
- return ;
- }
- /***********************************************************************************************
- * SurfaceClass::Detach -- Releases the reference on the internal surface ptr, and NULLs it. .*
- * *
- * *
- * *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 3/27/2001 pds : Created. *
- *=============================================================================================*/
- void SurfaceClass::Detach (void)
- {
- //
- // Release the hold we have on the D3D object
- //
- if (D3DSurface != NULL) {
- D3DSurface->Release ();
- }
- D3DSurface = NULL;
- return ;
- }
- /***********************************************************************************************
- * SurfaceClass::DrawPixel -- draws a pixel *
- * *
- * *
- * *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- *=============================================================================================*/
- void SurfaceClass::DrawPixel(const unsigned int x,const unsigned int y, unsigned int color)
- {
- SurfaceDescription sd;
- Get_Description(sd);
- unsigned int size=PixelSize(sd);
- D3DLOCKED_RECT lock_rect;
- ::ZeroMemory(&lock_rect, sizeof(D3DLOCKED_RECT));
- RECT rect;
- ::ZeroMemory(&rect, sizeof(RECT));
- rect.bottom=y+1;
- rect.top=y;
- rect.left=x;
- rect.right=x+1;
- DX8_ErrorCode(D3DSurface->LockRect(&lock_rect,&rect,0));
- unsigned char *cptr=(unsigned char*)lock_rect.pBits;
- unsigned short *sptr=(unsigned short*)lock_rect.pBits;
- unsigned int *lptr=(unsigned int*)lock_rect.pBits;
- switch (size)
- {
- case 1:
- *cptr=(unsigned char) (color & 0xFF);
- break;
- case 2:
- *sptr=(unsigned short) (color & 0xFFFF);
- break;
- case 4:
- *lptr=color;
- break;
- }
- DX8_ErrorCode(D3DSurface->UnlockRect());
- }
- /***********************************************************************************************
- * SurfaceClass::DrawHLine -- draws a horizontal line *
- * *
- * *
- * *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 4/9/2001 hy : Created. *
- * 4/9/2001 hy : Created. *
- *=============================================================================================*/
- void SurfaceClass::DrawHLine(const unsigned int y,const unsigned int x1, const unsigned int x2, unsigned int color)
- {
- SurfaceDescription sd;
- Get_Description(sd);
- unsigned int size=PixelSize(sd);
- D3DLOCKED_RECT lock_rect;
- ::ZeroMemory(&lock_rect, sizeof(D3DLOCKED_RECT));
- RECT rect;
- ::ZeroMemory(&rect, sizeof(RECT));
- rect.bottom=y+1;
- rect.top=y;
- rect.left=x1;
- rect.right=x2+1;
- DX8_ErrorCode(D3DSurface->LockRect(&lock_rect,&rect,0));
- unsigned char *cptr=(unsigned char*)lock_rect.pBits;
- unsigned short *sptr=(unsigned short*)lock_rect.pBits;
- unsigned int *lptr=(unsigned int*)lock_rect.pBits;
- unsigned int x;
- // the assumption here is that whenever a pixel has alpha it's in the MSB
- for (x=x1; x<=x2; x++)
- {
- switch (size)
- {
- case 1:
- *cptr++=(unsigned char) (color & 0xFF);
- break;
- case 2:
- *sptr++=(unsigned short) (color & 0xFFFF);
- break;
- case 4:
- *lptr++=color;
- break;
- }
- }
- DX8_ErrorCode(D3DSurface->UnlockRect());
- }
- /***********************************************************************************************
- * SurfaceClass::Is_Monochrome -- Checks if surface is monochrome or not *
- * *
- * *
- * *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 7/5/2001 hy : Created. *
- *=============================================================================================*/
- bool SurfaceClass::Is_Monochrome(void)
- {
- unsigned int x,y;
- SurfaceDescription sd;
- Get_Description(sd);
- switch (sd.Format)
- {
- case WW3D_FORMAT_A8L8:
- case WW3D_FORMAT_A8:
- case WW3D_FORMAT_L8:
- case WW3D_FORMAT_A4L4:
- return true;
- break;
- }
- int pitch,size;
- size=PixelSize(sd);
- unsigned char *bits=(unsigned char*) Lock(&pitch);
- Vector3 rgb;
- bool mono=true;
- for (y=0; y<sd.Height; y++)
- {
- for (x=0; x<sd.Width; x++)
- {
- Convert_Pixel(rgb,sd,&bits[x*size]);
- mono&=(rgb.X==rgb.Y);
- mono&=(rgb.X==rgb.Z);
- mono&=(rgb.Z==rgb.Y);
- if (!mono)
- {
- Unlock();
- return false;
- }
- }
- bits+=pitch;
- }
- Unlock();
- return true;
- }
- /***********************************************************************************************
- * SurfaceClass::Hue_Shift -- changes the hue of the surface *
- * *
- * *
- * *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 7/3/2001 hy : Created. *
- *=============================================================================================*/
- void SurfaceClass::Hue_Shift(const Vector3 &hsv_shift)
- {
- unsigned int x,y;
- SurfaceDescription sd;
- Get_Description(sd);
- int pitch,size;
- size=PixelSize(sd);
- unsigned char *bits=(unsigned char*) Lock(&pitch);
- Vector3 rgb;
- for (y=0; y<sd.Height; y++)
- {
- for (x=0; x<sd.Width; x++)
- {
- Convert_Pixel(rgb,sd,&bits[x*size]);
- Recolor(rgb,hsv_shift);
- rgb.X=Bound(rgb.X,0.0f,1.0f);
- rgb.Y=Bound(rgb.Y,0.0f,1.0f);
- rgb.Z=Bound(rgb.Z,0.0f,1.0f);
- Convert_Pixel(&bits[x*size],sd,rgb);
- }
- bits+=pitch;
- }
- Unlock();
- }
|