home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 27 / IOPROG_27.ISO / SOFT / CDX.ZIP / Src / Cdx / Surface.cpp < prev   
Encoding:
C/C++ Source or Header  |  1998-09-15  |  12.1 KB  |  404 lines

  1. //////////////////////////////////////////////////////////////////////////////////
  2. // Project Name:   [ CDX Class Library - CDX.lib ]
  3. // Author:         [ Dan Farley - 97308096@brookes.ac.uk ]
  4. // Source File:    [ CDX_Surface Implementation ]
  5. // Revision:       [ 1.6 ]
  6. //////////////////////////////////////////////////////////////////////////////////
  7. #include "CDX.h"
  8.  
  9. //////////////////////////////////////////////////////////////////////////////////
  10. // CDX_Surface Constructor
  11. //////////////////////////////////////////////////////////////////////////////////
  12. CDX_Surface::CDX_Surface(void)
  13. {
  14.     Initialise();
  15. }
  16.  
  17. //////////////////////////////////////////////////////////////////////////////////
  18. // CDX_Surface Destructor
  19. //////////////////////////////////////////////////////////////////////////////////
  20. CDX_Surface::~CDX_Surface()
  21. {
  22.     Finalise();
  23. }
  24.  
  25. //////////////////////////////////////////////////////////////////////////////////
  26. // CDX_Surface Initialise
  27. //////////////////////////////////////////////////////////////////////////////////
  28. void CDX_Surface::Initialise(void)
  29. {
  30.     m_Surface = NULL;
  31.     m_DC = NULL;
  32.     m_Font = NULL;
  33.     m_Filename = NULL;
  34.  
  35.     ZeroMemory(&m_Desc, sizeof(DDSURFACEDESC2));
  36.     m_Desc.dwSize = sizeof(DDSURFACEDESC2);
  37.     m_Desc.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
  38.  
  39.     m_Width = 0;
  40.     m_Height = 0;
  41.     SetRect(&m_SrcRect, 0, 0, 0, 0);
  42.     SetRect(&m_DestRect, 0, 0, 0, 0);
  43. }
  44.  
  45. //////////////////////////////////////////////////////////////////////////////////
  46. // CDX_Surface Finalise
  47. //////////////////////////////////////////////////////////////////////////////////
  48. void CDX_Surface::Finalise(void)
  49. {
  50.     DeleteDC(m_DC);
  51.     DeleteObject(m_Font);
  52.     SAFE_RELEASE(m_Surface);
  53. }
  54.  
  55. //////////////////////////////////////////////////////////////////////////////////
  56. // CDX_Surface Create
  57. //////////////////////////////////////////////////////////////////////////////////
  58. HRESULT CDX_Surface::Create(CDX_Screen* engine)
  59. {
  60.     HRESULT rval;
  61.  
  62.     Finalise();
  63.  
  64.     // Create the surface
  65.     rval = engine->GetDD()->CreateSurface(&m_Desc, &m_Surface, NULL);
  66.     if(rval != DD_OK) return rval;
  67.  
  68.     rval = m_Surface->GetSurfaceDesc(&m_Desc);
  69.     if(rval != DD_OK) return rval;
  70.  
  71.     // Initialise some variables
  72.     m_Width = m_Desc.dwWidth;
  73.     m_Height = m_Desc.dwHeight;
  74.     SetRect(&m_SrcRect, 0, 0, m_Width, m_Height);
  75.     SetRect(&m_DestRect, 0, 0, m_Width, m_Height);
  76.  
  77.     return rval;
  78. }
  79.  
  80. //////////////////////////////////////////////////////////////////////////////////
  81. // CDX_Surface Create
  82. //////////////////////////////////////////////////////////////////////////////////
  83. HRESULT CDX_Surface::Create(CDX_Screen *engine, int width, int height)
  84. {
  85.     HRESULT rval;
  86.  
  87.     Finalise();
  88.     Initialise();
  89.  
  90.     // Initialise some variables
  91.     m_Width = width;
  92.     m_Height = height;
  93.     SetRect(&m_SrcRect, 0, 0, m_Width, m_Height);
  94.     SetRect(&m_DestRect, 0, 0, m_Width, m_Height);
  95.  
  96.     // Set the surface description
  97.     m_Desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
  98.     m_Desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
  99.     m_Desc.dwWidth = m_Width;
  100.     m_Desc.dwHeight = m_Height;
  101.  
  102.     // Create the surface
  103.     rval = engine->GetDD()->CreateSurface(&m_Desc, &m_Surface, NULL);
  104.     if(rval != DD_OK) return rval;
  105.  
  106.     return rval;
  107. }
  108.  
  109. //////////////////////////////////////////////////////////////////////////////////
  110. // CDX_Surface LoadBitmap
  111. //////////////////////////////////////////////////////////////////////////////////
  112. HRESULT CDX_Surface::LoadBitmap(CDX_Screen* engine, const char* filename)
  113. {
  114.     HRESULT rval;
  115.     HBITMAP hbm;
  116.     BITMAP  bm;
  117.  
  118.     Finalise();
  119.     Initialise();
  120.  
  121.     // Try to load the bitmap from a resource
  122.     hbm = (HBITMAP)LoadImage(GetModuleHandle(NULL), filename,
  123.                                IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
  124.  
  125.     // Try to load the bitmap from a file
  126.     if(hbm == NULL)
  127.     hbm = (HBITMAP)LoadImage(NULL, filename, IMAGE_BITMAP,
  128.                              0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
  129.  
  130.     if(hbm == NULL) return E_FAIL;
  131.  
  132.     // Get size of the bitmap
  133.     GetObject(hbm, sizeof(bm), &bm);
  134.  
  135.     // Create a DirectDrawSurface for this bitmap
  136.     m_Desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
  137.     m_Desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
  138.     m_Desc.dwWidth = bm.bmWidth;
  139.     m_Desc.dwHeight = bm.bmHeight;
  140.  
  141.     rval = engine->GetDD()->CreateSurface(&m_Desc, &m_Surface, NULL);
  142.     if(rval != DD_OK) return rval;
  143.  
  144.     CopyBitmap(hbm, 0, 0, 0, 0);
  145.     DeleteObject(hbm);
  146.  
  147.     // Initialise some variables
  148.     m_Filename = filename;
  149.     m_Width = m_Desc.dwWidth;
  150.     m_Height = m_Desc.dwHeight;
  151.     SetRect(&m_SrcRect, 0, 0, m_Width, m_Height);
  152.     SetRect(&m_DestRect, 0, 0, m_Width, m_Height);
  153.  
  154.     return rval;
  155. }
  156.  
  157. //////////////////////////////////////////////////////////////////////////////////
  158. // CDX_Surface CopyBitmap
  159. //////////////////////////////////////////////////////////////////////////////////
  160. HRESULT CDX_Surface::CopyBitmap(HBITMAP hbm, int x, int y, int dx, int dy)
  161. {
  162.     HDC Image;
  163.     BITMAP bm;
  164.     HRESULT rval;
  165.  
  166.     if(hbm == NULL || m_Surface == NULL) return E_FAIL;
  167.  
  168.     // Make sure this surface is restored
  169.     m_Surface->Restore();
  170.  
  171.     // Select bitmap into a MemoryDC so we can use it
  172.     Image = CreateCompatibleDC(NULL);
  173.     if(!Image) return E_FAIL;
  174.     SelectObject(Image, hbm);
  175.  
  176.     // Get size of the bitmap
  177.     GetObject(hbm, sizeof(bm), &bm);
  178.     dx = dx == 0 ? bm.bmWidth  : dx;
  179.     dy = dy == 0 ? bm.bmHeight : dy;
  180.  
  181.     // Get size of surface
  182.     m_Desc.dwSize = sizeof(DDSURFACEDESC2);
  183.     m_Desc.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
  184.     m_Surface->GetSurfaceDesc(&m_Desc);
  185.  
  186.     rval = GetDC();
  187.     if(rval == DD_OK)
  188.     {
  189.         StretchBlt(m_DC, 0, 0, m_Desc.dwWidth, m_Desc.dwHeight, Image,
  190.                    x, y, dx, dy, SRCCOPY);
  191.         ReleaseDC();
  192.     }
  193.  
  194.     DeleteDC(Image);
  195.  
  196.     return rval;
  197. }
  198.  
  199. //////////////////////////////////////////////////////////////////////////////////
  200. // CDX_Surface Draw
  201. //////////////////////////////////////////////////////////////////////////////////
  202. HRESULT CDX_Surface::Draw(CDX_Surface* Dest, DWORD Flags)
  203. {
  204.     HRESULT rval;
  205.  
  206.     rval = Dest->m_Surface->Blt(&m_DestRect, m_Surface, &m_SrcRect, Flags, NULL);
  207.     if(rval == DDERR_SURFACELOST) Restore();
  208.  
  209.     return rval;
  210. }
  211.  
  212. //////////////////////////////////////////////////////////////////////////////////
  213. // CDX_Surface DrawFast
  214. //////////////////////////////////////////////////////////////////////////////////
  215. HRESULT CDX_Surface::DrawFast(int X, int Y, CDX_Surface* Dest, DWORD Flags)
  216. {
  217.     HRESULT rval;
  218.  
  219.     rval = Dest->m_Surface->BltFast(X, Y, m_Surface, &m_SrcRect, Flags);
  220.     if(rval == DDERR_SURFACELOST) Restore();
  221.  
  222.     return rval;
  223. }
  224.  
  225. //////////////////////////////////////////////////////////////////////////////////
  226. // CDX_Surface Fill
  227. //////////////////////////////////////////////////////////////////////////////////
  228. HRESULT CDX_Surface::Fill(DWORD color)
  229. {
  230.     DDBLTFX bltfx;
  231.  
  232.     bltfx.dwSize = sizeof(DDBLTFX);
  233.     bltfx.dwFillColor = color;
  234.     return m_Surface->Blt(NULL, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &bltfx);
  235. }
  236.  
  237. /*
  238. //////////////////////////////////////////////////////////////////////////////////
  239. // Clip - clips a destination rectange and modifys X,Y coords appropriatly
  240. //////////////////////////////////////////////////////////////////////////////////
  241. static void Clip(int *DestX, int *DestY, RECT *SrcRect, RECT *DestRect)
  242. {
  243.     // If it's partly off the right side of the screen
  244.     if(*DestX + (SrcRect->right - SrcRect->left) > DestRect->right)
  245.         SrcRect->right -= *DestX + (SrcRect->right-SrcRect->left) - DestRect->right;
  246.  
  247.     // Partly off the left side of the screen
  248.     if(*DestX < DestRect->left)
  249.     {
  250.         SrcRect->left += DestRect->left - *DestX;
  251.         *DestX = DestRect->left;
  252.     }
  253.  
  254.     // Partly off the top of the screen
  255.     if(*DestY < DestRect->top)
  256.     {
  257.         SrcRect->top += DestRect->top - *DestY;
  258.         *DestY = DestRect->top;
  259.     }
  260.  
  261.     // If it's partly off the bottom side of the screen
  262.     if(*DestY + (SrcRect->bottom - SrcRect->top) > DestRect->bottom)
  263.     SrcRect->bottom -= ((SrcRect->bottom-SrcRect->top)+*DestY) - DestRect->bottom;
  264.  
  265.     return;
  266. }
  267.  
  268. //////////////////////////////////////////////////////////////////////////////////
  269. // CDX_Surface DrawClipped
  270. //////////////////////////////////////////////////////////////////////////////////
  271. HRESULT CDX_Surface::DrawClipped(int X, int Y, CDX_Surface* Dest, LPRECT ClipRect)
  272. {
  273.     HRESULT rval;
  274.     RECT ModSrc = m_SrcRect;
  275.     Clip(&X, &Y, &ModSrc, ClipRect);
  276.  
  277.     rval = Dest->m_Surface->BltFast(X, Y, m_Surface, &ModSrc, DDBLTFAST_WAIT | DDBLTFAST_SRCCOLORKEY);
  278.     if(rval == DDERR_SURFACELOST) Restore();
  279.  
  280.     return rval;
  281. }
  282. */
  283.  
  284. //////////////////////////////////////////////////////////////////////////////////
  285. // CDX_Surface SetDest
  286. //////////////////////////////////////////////////////////////////////////////////
  287. void CDX_Surface::SetDest(int t, int l, int b, int r)
  288. {
  289.     m_DestRect.top = t;
  290.     m_DestRect.left = l;
  291.     m_DestRect.bottom = b;
  292.     m_DestRect.right = r;
  293. }
  294.  
  295. //////////////////////////////////////////////////////////////////////////////////
  296. // CDX_Surface SetSrc
  297. //////////////////////////////////////////////////////////////////////////////////
  298. void CDX_Surface::SetSrc(int t, int l, int b, int r)
  299. {
  300.     m_SrcRect.top = t;
  301.     m_SrcRect.left = l;
  302.     m_SrcRect.bottom = b;
  303.     m_SrcRect.right = r;
  304. }
  305.  
  306. //////////////////////////////////////////////////////////////////////////////////
  307. // CDX_Surface SetColorKey
  308. //////////////////////////////////////////////////////////////////////////////////
  309. HRESULT CDX_Surface::SetColorKey(COLORREF col)
  310. {
  311.     COLORREF rgb;
  312.     DDCOLORKEY ddck;
  313.     DWORD dw;
  314.  
  315.     // Use GDI SetPixel to color match for us
  316.     if(GetDC() == DD_OK)
  317.     {
  318.         rgb = GetPixel(m_DC, 0, 0);
  319.         SetPixel(m_DC, 0, 0, col);
  320.         ReleaseDC();
  321.     }
  322.  
  323.     // Now lock the surface so we can read back the converted color
  324.     if(Lock() == DD_OK)
  325.     {
  326.         dw  = *(DWORD *)m_Desc.lpSurface;
  327.         if(m_Desc.ddpfPixelFormat.dwRGBBitCount < 32)
  328.             dw &= (1 << m_Desc.ddpfPixelFormat.dwRGBBitCount) - 1;
  329.         UnLock();
  330.     }
  331.  
  332.     // Now put the color that was there back
  333.     if(GetDC() == DD_OK)
  334.     {
  335.         SetPixel(m_DC, 0, 0, rgb);
  336.         ReleaseDC();
  337.     }
  338.  
  339.     ddck.dwColorSpaceLowValue = dw;
  340.     ddck.dwColorSpaceHighValue = dw;
  341.  
  342.     return m_Surface->SetColorKey(DDCKEY_SRCBLT, &ddck);
  343. }
  344.  
  345. //////////////////////////////////////////////////////////////////////////////////
  346. // CDX_Surface Restore
  347. //////////////////////////////////////////////////////////////////////////////////
  348. HRESULT CDX_Surface::Restore(void)
  349. {
  350.     return m_Surface->Restore();
  351. }
  352.  
  353. //////////////////////////////////////////////////////////////////////////////////
  354. // CDX_Surface Lock
  355. //////////////////////////////////////////////////////////////////////////////////
  356. HRESULT CDX_Surface::Lock(void)
  357. {
  358.     ZeroMemory(&m_Desc, sizeof(m_Desc));
  359.     m_Desc.dwSize = sizeof(m_Desc);
  360.     return m_Surface->Lock(NULL, &m_Desc, DDLOCK_WAIT, NULL);
  361. }
  362.  
  363. //////////////////////////////////////////////////////////////////////////////////
  364. // CDX_Surface UnLock
  365. //////////////////////////////////////////////////////////////////////////////////
  366. HRESULT CDX_Surface::UnLock(void)
  367. {
  368.     return m_Surface->Unlock(NULL);
  369. }
  370.  
  371. //////////////////////////////////////////////////////////////////////////////////
  372. // CDX_Surface SetFont
  373. //////////////////////////////////////////////////////////////////////////////////
  374. HRESULT CDX_Surface::SetFont(const char* FontName, int Width, int Height, int Attributes)
  375. {
  376.     m_Font = CreateFont(Height, Width,
  377.                         0, 0,
  378.                         Attributes,
  379.                         FALSE,
  380.                         FALSE,
  381.                         FALSE,
  382.                         ANSI_CHARSET,
  383.                         OUT_DEFAULT_PRECIS,
  384.                         CLIP_DEFAULT_PRECIS,
  385.                         NONANTIALIASED_QUALITY,
  386.                         VARIABLE_PITCH,
  387.                         FontName);
  388.  
  389.     if(m_Font == NULL) return E_FAIL;
  390.     else return S_OK;
  391. }
  392.  
  393. //////////////////////////////////////////////////////////////////////////////////
  394. // CDX_Surface TextOut
  395. //////////////////////////////////////////////////////////////////////////////////
  396. HRESULT CDX_Surface::TextXY(int x, int y, COLORREF col, const char* pString)
  397. {
  398.     SelectObject(m_DC, m_Font);
  399.     SetBkMode(m_DC, TRANSPARENT);
  400.     SetTextColor(m_DC, col);
  401.     if(!TextOut(m_DC, x, y, pString, strlen(pString))) return E_FAIL;
  402.     else return DD_OK;
  403. }
  404.