Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

224 lines
6.0 KiB

  1. /*************************************************
  2. * phsprite.cpp *
  3. * *
  4. * Copyright (C) 1995-1999 Microsoft Inc. *
  5. * *
  6. *************************************************/
  7. // phsprite.cpp : implementation file
  8. //
  9. #include "stdafx.h"
  10. #include "dib.h"
  11. #include "spriteno.h"
  12. #include "sprite.h"
  13. #include "phsprite.h"
  14. #ifdef _DEBUG
  15. #undef THIS_FILE
  16. static char BASED_CODE THIS_FILE[] = __FILE__;
  17. #endif
  18. /////////////////////////////////////////////////////////////////////////////
  19. // CPhasedSprite
  20. IMPLEMENT_SERIAL(CPhasedSprite, CSprite, 0 /* schema number*/ )
  21. CPhasedSprite::CPhasedSprite()
  22. {
  23. m_iNumCellRows = 1;
  24. m_iNumCellColumns = 1;
  25. m_iCellRow = 0;
  26. m_iCellColumn = 0;
  27. m_iCellHeight = CSprite::GetHeight();
  28. m_iCellWidth = CSprite::GetWidth();
  29. }
  30. CPhasedSprite::~CPhasedSprite()
  31. {
  32. }
  33. /////////////////////////////////////////////////////////////////////////////
  34. // CPhasedSprite serialization
  35. void CPhasedSprite::Serialize(CArchive& ar)
  36. {
  37. CSprite::Serialize(ar);
  38. if (ar.IsStoring())
  39. {
  40. ar << (DWORD) m_iNumCellRows;
  41. ar << (DWORD) m_iNumCellColumns;
  42. ar << (DWORD) m_iCellRow;
  43. ar << (DWORD) m_iCellColumn;
  44. }
  45. else
  46. {
  47. DWORD dw;
  48. ar >> dw;
  49. SetNumCellRows(dw);
  50. ar >> dw;
  51. SetNumCellColumns(dw);
  52. ar >> dw;
  53. SetCellRow(dw);
  54. ar >> dw;
  55. SetCellColumn(dw);
  56. }
  57. }
  58. /////////////////////////////////////////////////////////////////////////////
  59. // CPhasedSprite commands
  60. // Do any initialization after file load of a new image etc.
  61. void CPhasedSprite::Initialize()
  62. {
  63. CSprite::Initialize();
  64. m_iNumCellRows = 1;
  65. m_iNumCellColumns = 1;
  66. m_iCellRow = 0;
  67. m_iCellColumn = 0;
  68. m_iCellHeight = CSprite::GetHeight();
  69. m_iCellWidth = CSprite::GetWidth();
  70. }
  71. // Divide the image into a given number of rows
  72. BOOL CPhasedSprite::SetNumCellRows(int iRows)
  73. {
  74. if (iRows < 1) {
  75. TRACE("Invalid number of rows");
  76. return FALSE;
  77. }
  78. // compute the height of each row
  79. int iCellHeight = CSprite::GetHeight() / iRows;
  80. if (iCellHeight < 1) {
  81. TRACE("Can't make them that small");
  82. return FALSE;
  83. }
  84. // set the new height and row count
  85. m_iNumCellRows = iRows;
  86. m_iCellRow = 0;
  87. m_iCellHeight = iCellHeight;
  88. return TRUE;
  89. }
  90. // Divide the image into a given number of columns
  91. BOOL CPhasedSprite::SetNumCellColumns(int iColumns)
  92. {
  93. if (iColumns < 1) {
  94. TRACE("Invalid number of columns");
  95. return FALSE;
  96. }
  97. // compute the width of each column
  98. int iCellWidth = CSprite::GetWidth() / iColumns;
  99. if (iCellWidth < 1) {
  100. TRACE("Can't make them that small");
  101. return FALSE;
  102. }
  103. // set the new width and column count
  104. m_iNumCellColumns = iColumns;
  105. m_iCellColumn = 0;
  106. m_iCellWidth = iCellWidth;
  107. return TRUE;
  108. }
  109. // set the current row
  110. BOOL CPhasedSprite::SetCellRow(int iRow)
  111. {
  112. if ((iRow >= m_iNumCellRows)
  113. || (iRow < 0)) {
  114. TRACE("Invalid row");
  115. return FALSE;
  116. }
  117. if (iRow == m_iCellRow) return FALSE; // nothing to do
  118. m_iCellRow = iRow;
  119. // send a notification to redraw
  120. if (m_pNotifyObj) {
  121. CRect rcPos;
  122. GetRect(&rcPos);
  123. m_pNotifyObj->Change(this,
  124. CSpriteNotifyObj::IMAGE,
  125. &rcPos);
  126. }
  127. return TRUE;
  128. }
  129. // set the current column
  130. BOOL CPhasedSprite::SetCellColumn(int iColumn)
  131. {
  132. if ((iColumn >= m_iNumCellColumns)
  133. || (iColumn < 0)) {
  134. TRACE("Invalid column");
  135. return FALSE;
  136. }
  137. if (iColumn == m_iCellColumn) return FALSE; // nothing to do
  138. m_iCellColumn = iColumn;
  139. // send a notification to redraw
  140. if (m_pNotifyObj) {
  141. CRect rcPos;
  142. GetRect(&rcPos);
  143. m_pNotifyObj->Change(this,
  144. CSpriteNotifyObj::IMAGE,
  145. &rcPos);
  146. }
  147. return TRUE;
  148. }
  149. // get the bounding rectangle
  150. void CPhasedSprite::GetRect(CRect* pRect)
  151. {
  152. ASSERT(pRect);
  153. pRect->left = m_x;
  154. pRect->top = m_y;
  155. pRect->right = m_x + GetWidth();
  156. pRect->bottom = m_y + GetHeight();
  157. }
  158. // Test for a hit in a non-transparent area
  159. BOOL CPhasedSprite::HitTest(CPoint point)
  160. {
  161. // Test if the point is inside the sprite rectangle
  162. if ((point.x > m_x)
  163. && (point.x < m_x + GetWidth())
  164. && (point.y > m_y)
  165. && (point.y < m_y + GetHeight())) {
  166. // Hit is in sprite rect
  167. // See if this point is transparent by testing to
  168. // see if the pixel value is the same as the top
  169. // left corner value. Note that top left of the
  170. // image is bottom left in the DIB.
  171. // Get the address of the top, left pixel
  172. BYTE* p = (BYTE*)GetPixelAddress(point.x - m_x, point.y - m_y);
  173. ASSERT(p);
  174. if ( ( p != NULL) && (*p != m_bTransIndex) ) {
  175. return TRUE;
  176. }
  177. }
  178. return FALSE;
  179. }
  180. // Render a sprite to a DIB
  181. void CPhasedSprite::Render(CDIB *pDIB, CRect* pClipRect)
  182. {
  183. ASSERT(pDIB);
  184. ASSERT(pClipRect);
  185. // Get the sprite rect and see if it's visible
  186. CRect rcDraw;
  187. GetRect(&rcDraw);
  188. if (!rcDraw.IntersectRect(pClipRect, &rcDraw)) {
  189. return; // not visible
  190. }
  191. // modify the source x and y values for the current phase of the sprite
  192. int xs = rcDraw.left - m_x + m_iCellColumn * m_iCellWidth;
  193. int ys = rcDraw.top - m_y + m_iCellRow * m_iCellHeight;
  194. ASSERT(xs >= 0 && xs < CSprite::GetWidth());
  195. ASSERT(ys >= 0 && ys < CSprite::GetHeight());
  196. CopyBits(pDIB, // dest DIB
  197. rcDraw.left, // dest x
  198. rcDraw.top, // dest y
  199. rcDraw.right - rcDraw.left, // width
  200. rcDraw.bottom - rcDraw.top, // height
  201. xs, // source x
  202. ys, // source y
  203. PALETTEINDEX(m_bTransIndex)); // trans color index
  204. }