home *** CD-ROM | disk | FTP | other *** search
- //////////////////////////////////////////////////////////////////////////////////
- // Project Name: [ CDX Class Library - CDX.lib ]
- // Author: [ Dan Farley - 97308096@brookes.ac.uk ]
- // Source File: [ CDX_Surface Implementation ]
- // Revision: [ 1.6 ]
- //////////////////////////////////////////////////////////////////////////////////
- #include "CDX.h"
-
- //////////////////////////////////////////////////////////////////////////////////
- // CDX_Surface Constructor
- //////////////////////////////////////////////////////////////////////////////////
- CDX_Surface::CDX_Surface(void)
- {
- Initialise();
- }
-
- //////////////////////////////////////////////////////////////////////////////////
- // CDX_Surface Destructor
- //////////////////////////////////////////////////////////////////////////////////
- CDX_Surface::~CDX_Surface()
- {
- Finalise();
- }
-
- //////////////////////////////////////////////////////////////////////////////////
- // CDX_Surface Initialise
- //////////////////////////////////////////////////////////////////////////////////
- void CDX_Surface::Initialise(void)
- {
- m_Surface = NULL;
- m_DC = NULL;
- m_Font = NULL;
- m_Filename = NULL;
-
- ZeroMemory(&m_Desc, sizeof(DDSURFACEDESC2));
- m_Desc.dwSize = sizeof(DDSURFACEDESC2);
- m_Desc.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
-
- m_Width = 0;
- m_Height = 0;
- SetRect(&m_SrcRect, 0, 0, 0, 0);
- SetRect(&m_DestRect, 0, 0, 0, 0);
- }
-
- //////////////////////////////////////////////////////////////////////////////////
- // CDX_Surface Finalise
- //////////////////////////////////////////////////////////////////////////////////
- void CDX_Surface::Finalise(void)
- {
- DeleteDC(m_DC);
- DeleteObject(m_Font);
- SAFE_RELEASE(m_Surface);
- }
-
- //////////////////////////////////////////////////////////////////////////////////
- // CDX_Surface Create
- //////////////////////////////////////////////////////////////////////////////////
- HRESULT CDX_Surface::Create(CDX_Screen* engine)
- {
- HRESULT rval;
-
- Finalise();
-
- // Create the surface
- rval = engine->GetDD()->CreateSurface(&m_Desc, &m_Surface, NULL);
- if(rval != DD_OK) return rval;
-
- rval = m_Surface->GetSurfaceDesc(&m_Desc);
- if(rval != DD_OK) return rval;
-
- // Initialise some variables
- m_Width = m_Desc.dwWidth;
- m_Height = m_Desc.dwHeight;
- SetRect(&m_SrcRect, 0, 0, m_Width, m_Height);
- SetRect(&m_DestRect, 0, 0, m_Width, m_Height);
-
- return rval;
- }
-
- //////////////////////////////////////////////////////////////////////////////////
- // CDX_Surface Create
- //////////////////////////////////////////////////////////////////////////////////
- HRESULT CDX_Surface::Create(CDX_Screen *engine, int width, int height)
- {
- HRESULT rval;
-
- Finalise();
- Initialise();
-
- // Initialise some variables
- m_Width = width;
- m_Height = height;
- SetRect(&m_SrcRect, 0, 0, m_Width, m_Height);
- SetRect(&m_DestRect, 0, 0, m_Width, m_Height);
-
- // Set the surface description
- m_Desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
- m_Desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
- m_Desc.dwWidth = m_Width;
- m_Desc.dwHeight = m_Height;
-
- // Create the surface
- rval = engine->GetDD()->CreateSurface(&m_Desc, &m_Surface, NULL);
- if(rval != DD_OK) return rval;
-
- return rval;
- }
-
- //////////////////////////////////////////////////////////////////////////////////
- // CDX_Surface LoadBitmap
- //////////////////////////////////////////////////////////////////////////////////
- HRESULT CDX_Surface::LoadBitmap(CDX_Screen* engine, const char* filename)
- {
- HRESULT rval;
- HBITMAP hbm;
- BITMAP bm;
-
- Finalise();
- Initialise();
-
- // Try to load the bitmap from a resource
- hbm = (HBITMAP)LoadImage(GetModuleHandle(NULL), filename,
- IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
-
- // Try to load the bitmap from a file
- if(hbm == NULL)
- hbm = (HBITMAP)LoadImage(NULL, filename, IMAGE_BITMAP,
- 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
-
- if(hbm == NULL) return E_FAIL;
-
- // Get size of the bitmap
- GetObject(hbm, sizeof(bm), &bm);
-
- // Create a DirectDrawSurface for this bitmap
- m_Desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
- m_Desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
- m_Desc.dwWidth = bm.bmWidth;
- m_Desc.dwHeight = bm.bmHeight;
-
- rval = engine->GetDD()->CreateSurface(&m_Desc, &m_Surface, NULL);
- if(rval != DD_OK) return rval;
-
- CopyBitmap(hbm, 0, 0, 0, 0);
- DeleteObject(hbm);
-
- // Initialise some variables
- m_Filename = filename;
- m_Width = m_Desc.dwWidth;
- m_Height = m_Desc.dwHeight;
- SetRect(&m_SrcRect, 0, 0, m_Width, m_Height);
- SetRect(&m_DestRect, 0, 0, m_Width, m_Height);
-
- return rval;
- }
-
- //////////////////////////////////////////////////////////////////////////////////
- // CDX_Surface CopyBitmap
- //////////////////////////////////////////////////////////////////////////////////
- HRESULT CDX_Surface::CopyBitmap(HBITMAP hbm, int x, int y, int dx, int dy)
- {
- HDC Image;
- BITMAP bm;
- HRESULT rval;
-
- if(hbm == NULL || m_Surface == NULL) return E_FAIL;
-
- // Make sure this surface is restored
- m_Surface->Restore();
-
- // Select bitmap into a MemoryDC so we can use it
- Image = CreateCompatibleDC(NULL);
- if(!Image) return E_FAIL;
- SelectObject(Image, hbm);
-
- // Get size of the bitmap
- GetObject(hbm, sizeof(bm), &bm);
- dx = dx == 0 ? bm.bmWidth : dx;
- dy = dy == 0 ? bm.bmHeight : dy;
-
- // Get size of surface
- m_Desc.dwSize = sizeof(DDSURFACEDESC2);
- m_Desc.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
- m_Surface->GetSurfaceDesc(&m_Desc);
-
- rval = GetDC();
- if(rval == DD_OK)
- {
- StretchBlt(m_DC, 0, 0, m_Desc.dwWidth, m_Desc.dwHeight, Image,
- x, y, dx, dy, SRCCOPY);
- ReleaseDC();
- }
-
- DeleteDC(Image);
-
- return rval;
- }
-
- //////////////////////////////////////////////////////////////////////////////////
- // CDX_Surface Draw
- //////////////////////////////////////////////////////////////////////////////////
- HRESULT CDX_Surface::Draw(CDX_Surface* Dest, DWORD Flags)
- {
- HRESULT rval;
-
- rval = Dest->m_Surface->Blt(&m_DestRect, m_Surface, &m_SrcRect, Flags, NULL);
- if(rval == DDERR_SURFACELOST) Restore();
-
- return rval;
- }
-
- //////////////////////////////////////////////////////////////////////////////////
- // CDX_Surface DrawFast
- //////////////////////////////////////////////////////////////////////////////////
- HRESULT CDX_Surface::DrawFast(int X, int Y, CDX_Surface* Dest, DWORD Flags)
- {
- HRESULT rval;
-
- rval = Dest->m_Surface->BltFast(X, Y, m_Surface, &m_SrcRect, Flags);
- if(rval == DDERR_SURFACELOST) Restore();
-
- return rval;
- }
-
- //////////////////////////////////////////////////////////////////////////////////
- // CDX_Surface Fill
- //////////////////////////////////////////////////////////////////////////////////
- HRESULT CDX_Surface::Fill(DWORD color)
- {
- DDBLTFX bltfx;
-
- bltfx.dwSize = sizeof(DDBLTFX);
- bltfx.dwFillColor = color;
- return m_Surface->Blt(NULL, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &bltfx);
- }
-
- /*
- //////////////////////////////////////////////////////////////////////////////////
- // Clip - clips a destination rectange and modifys X,Y coords appropriatly
- //////////////////////////////////////////////////////////////////////////////////
- static void Clip(int *DestX, int *DestY, RECT *SrcRect, RECT *DestRect)
- {
- // If it's partly off the right side of the screen
- if(*DestX + (SrcRect->right - SrcRect->left) > DestRect->right)
- SrcRect->right -= *DestX + (SrcRect->right-SrcRect->left) - DestRect->right;
-
- // Partly off the left side of the screen
- if(*DestX < DestRect->left)
- {
- SrcRect->left += DestRect->left - *DestX;
- *DestX = DestRect->left;
- }
-
- // Partly off the top of the screen
- if(*DestY < DestRect->top)
- {
- SrcRect->top += DestRect->top - *DestY;
- *DestY = DestRect->top;
- }
-
- // If it's partly off the bottom side of the screen
- if(*DestY + (SrcRect->bottom - SrcRect->top) > DestRect->bottom)
- SrcRect->bottom -= ((SrcRect->bottom-SrcRect->top)+*DestY) - DestRect->bottom;
-
- return;
- }
-
- //////////////////////////////////////////////////////////////////////////////////
- // CDX_Surface DrawClipped
- //////////////////////////////////////////////////////////////////////////////////
- HRESULT CDX_Surface::DrawClipped(int X, int Y, CDX_Surface* Dest, LPRECT ClipRect)
- {
- HRESULT rval;
- RECT ModSrc = m_SrcRect;
- Clip(&X, &Y, &ModSrc, ClipRect);
-
- rval = Dest->m_Surface->BltFast(X, Y, m_Surface, &ModSrc, DDBLTFAST_WAIT | DDBLTFAST_SRCCOLORKEY);
- if(rval == DDERR_SURFACELOST) Restore();
-
- return rval;
- }
- */
-
- //////////////////////////////////////////////////////////////////////////////////
- // CDX_Surface SetDest
- //////////////////////////////////////////////////////////////////////////////////
- void CDX_Surface::SetDest(int t, int l, int b, int r)
- {
- m_DestRect.top = t;
- m_DestRect.left = l;
- m_DestRect.bottom = b;
- m_DestRect.right = r;
- }
-
- //////////////////////////////////////////////////////////////////////////////////
- // CDX_Surface SetSrc
- //////////////////////////////////////////////////////////////////////////////////
- void CDX_Surface::SetSrc(int t, int l, int b, int r)
- {
- m_SrcRect.top = t;
- m_SrcRect.left = l;
- m_SrcRect.bottom = b;
- m_SrcRect.right = r;
- }
-
- //////////////////////////////////////////////////////////////////////////////////
- // CDX_Surface SetColorKey
- //////////////////////////////////////////////////////////////////////////////////
- HRESULT CDX_Surface::SetColorKey(COLORREF col)
- {
- COLORREF rgb;
- DDCOLORKEY ddck;
- DWORD dw;
-
- // Use GDI SetPixel to color match for us
- if(GetDC() == DD_OK)
- {
- rgb = GetPixel(m_DC, 0, 0);
- SetPixel(m_DC, 0, 0, col);
- ReleaseDC();
- }
-
- // Now lock the surface so we can read back the converted color
- if(Lock() == DD_OK)
- {
- dw = *(DWORD *)m_Desc.lpSurface;
- if(m_Desc.ddpfPixelFormat.dwRGBBitCount < 32)
- dw &= (1 << m_Desc.ddpfPixelFormat.dwRGBBitCount) - 1;
- UnLock();
- }
-
- // Now put the color that was there back
- if(GetDC() == DD_OK)
- {
- SetPixel(m_DC, 0, 0, rgb);
- ReleaseDC();
- }
-
- ddck.dwColorSpaceLowValue = dw;
- ddck.dwColorSpaceHighValue = dw;
-
- return m_Surface->SetColorKey(DDCKEY_SRCBLT, &ddck);
- }
-
- //////////////////////////////////////////////////////////////////////////////////
- // CDX_Surface Restore
- //////////////////////////////////////////////////////////////////////////////////
- HRESULT CDX_Surface::Restore(void)
- {
- return m_Surface->Restore();
- }
-
- //////////////////////////////////////////////////////////////////////////////////
- // CDX_Surface Lock
- //////////////////////////////////////////////////////////////////////////////////
- HRESULT CDX_Surface::Lock(void)
- {
- ZeroMemory(&m_Desc, sizeof(m_Desc));
- m_Desc.dwSize = sizeof(m_Desc);
- return m_Surface->Lock(NULL, &m_Desc, DDLOCK_WAIT, NULL);
- }
-
- //////////////////////////////////////////////////////////////////////////////////
- // CDX_Surface UnLock
- //////////////////////////////////////////////////////////////////////////////////
- HRESULT CDX_Surface::UnLock(void)
- {
- return m_Surface->Unlock(NULL);
- }
-
- //////////////////////////////////////////////////////////////////////////////////
- // CDX_Surface SetFont
- //////////////////////////////////////////////////////////////////////////////////
- HRESULT CDX_Surface::SetFont(const char* FontName, int Width, int Height, int Attributes)
- {
- m_Font = CreateFont(Height, Width,
- 0, 0,
- Attributes,
- FALSE,
- FALSE,
- FALSE,
- ANSI_CHARSET,
- OUT_DEFAULT_PRECIS,
- CLIP_DEFAULT_PRECIS,
- NONANTIALIASED_QUALITY,
- VARIABLE_PITCH,
- FontName);
-
- if(m_Font == NULL) return E_FAIL;
- else return S_OK;
- }
-
- //////////////////////////////////////////////////////////////////////////////////
- // CDX_Surface TextOut
- //////////////////////////////////////////////////////////////////////////////////
- HRESULT CDX_Surface::TextXY(int x, int y, COLORREF col, const char* pString)
- {
- SelectObject(m_DC, m_Font);
- SetBkMode(m_DC, TRANSPARENT);
- SetTextColor(m_DC, col);
- if(!TextOut(m_DC, x, y, pString, strlen(pString))) return E_FAIL;
- else return DD_OK;
- }
-