pixelformat.cpp 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. #include "pch.h"
  2. //////////////////////////////////////////////////////////////////////////////
  3. //
  4. //
  5. //
  6. //////////////////////////////////////////////////////////////////////////////
  7. PixelFormat::PixelFormat(
  8. int bits,
  9. DWORD redMask,
  10. DWORD greenMask,
  11. DWORD blueMask,
  12. DWORD alphaMask
  13. ) {
  14. m_ddpf.dwSize = sizeof(DDPIXELFORMAT);
  15. m_ddpf.dwFlags = DDPF_RGB;
  16. m_ddpf.dwFourCC = 0;
  17. m_ddpf.dwRGBBitCount = bits;
  18. m_ddpf.dwRBitMask = redMask;
  19. m_ddpf.dwGBitMask = greenMask;
  20. m_ddpf.dwBBitMask = blueMask;
  21. m_ddpf.dwRGBAlphaBitMask = alphaMask;
  22. }
  23. DWORD PixelFormat::RedSize() const { return RedMask() >> RedShift(); }
  24. DWORD PixelFormat::GreenSize() const { return GreenMask() >> GreenShift(); }
  25. DWORD PixelFormat::BlueSize() const { return BlueMask() >> BlueShift(); }
  26. DWORD PixelFormat::AlphaSize() const { return AlphaMask() >> AlphaShift(); }
  27. DWORD PixelFormat::RedShift() const { return GetShift(RedMask()); }
  28. DWORD PixelFormat::GreenShift() const { return GetShift(GreenMask()); }
  29. DWORD PixelFormat::BlueShift() const { return GetShift(BlueMask()); }
  30. DWORD PixelFormat::AlphaShift() const { return GetShift(AlphaMask()); }
  31. Pixel PixelFormat::MakePixel(DWORD red, DWORD green, DWORD blue) const
  32. {
  33. return Pixel::Create(
  34. ((red << RedShift() ) & RedMask() )
  35. | ((green << GreenShift()) & GreenMask())
  36. | ((blue << BlueShift() ) & BlueMask() ));
  37. }
  38. Pixel PixelFormat::MakePixel(const Color& color) const
  39. {
  40. return
  41. MakePixel(
  42. int(color.GetRed() * RedSize() ),
  43. int(color.GetGreen() * GreenSize()),
  44. int(color.GetBlue() * BlueSize() )
  45. );
  46. // !!! this causes all of the artwork to change slightly
  47. // since the rounding mode is different
  48. /*
  49. return
  50. MakePixel(
  51. MakeInt(color.GetRed() * RedSize() ),
  52. MakeInt(color.GetGreen() * GreenSize()),
  53. MakeInt(color.GetBlue() * BlueSize() )
  54. );
  55. */
  56. }
  57. Color PixelFormat::MakeColor(Pixel pixel) const
  58. {
  59. return
  60. Color(
  61. (float)((pixel.Value() & RedMask()) >> RedShift()) / RedSize(),
  62. (float)((pixel.Value() & GreenMask()) >> GreenShift()) / GreenSize(),
  63. (float)((pixel.Value() & BlueMask()) >> BlueShift()) / BlueSize()
  64. );
  65. }
  66. void PixelFormat::SetPixel(BYTE* pb, Pixel pixel) const
  67. {
  68. switch (PixelBytes()) {
  69. case 1: *pb = (BYTE)(pixel.Value()); break;
  70. case 2: *(WORD*)pb = (WORD)(pixel.Value()); break;
  71. case 3:
  72. pb[0] = (BYTE)(((pixel.Value()) >> 0) & 0xff);
  73. pb[1] = (BYTE)(((pixel.Value()) >> 8) & 0xff);
  74. pb[2] = (BYTE)(((pixel.Value()) >> 16) & 0xff);
  75. break;
  76. case 4: *(DWORD*)pb = (pixel.Value()); break;
  77. }
  78. }
  79. Pixel PixelFormat::GetPixel(const BYTE* pb) const
  80. {
  81. switch (PixelBytes()) {
  82. case 1: return Pixel::Create(*pb);
  83. case 2: return Pixel::Create(*(WORD*)pb);
  84. case 3:
  85. return
  86. Pixel::Create(
  87. (DWORD(pb[0]) << 0)
  88. | (DWORD(pb[1]) << 8)
  89. | (DWORD(pb[2]) << 16)
  90. );
  91. case 4: return Pixel::Create(*(DWORD*)pb);
  92. }
  93. return Pixel::Create(0);
  94. }
  95. void PixelFormat::SetColor(BYTE* pb, const Color& color) const
  96. {
  97. SetPixel(pb, MakePixel(color));
  98. }
  99. Color PixelFormat::GetColor(const BYTE* pb) const
  100. {
  101. return MakeColor(GetPixel(pb));
  102. }
  103. bool PixelFormat::ValidGDIFormat() const
  104. {
  105. BitMask mask(m_ddpf.dwFlags);
  106. //
  107. // gdi doesn't support alpha
  108. //
  109. if (mask.Test(BitMask(DDPF_ALPHA | DDPF_ALPHAPIXELS))) {
  110. return false;
  111. }
  112. if (m_ddpf.dwRGBBitCount == 8) {
  113. //
  114. // 8 bpp must be palettized
  115. //
  116. return mask.Test(BitMask(DDPF_PALETTEINDEXED8));
  117. } else if (m_ddpf.dwRGBBitCount > 8) {
  118. //
  119. // 16 bpp must be RGB
  120. //
  121. return mask.Test(BitMask(DDPF_RGB));
  122. }
  123. //
  124. // less than 8 bpp not supported
  125. //
  126. return false;
  127. }
  128. bool PixelFormat::Equivalent(const DDPIXELFORMAT& ddpf)
  129. {
  130. return
  131. m_ddpf.dwFlags == ddpf.dwFlags
  132. && m_ddpf.dwRGBBitCount == ddpf.dwRGBBitCount
  133. && m_ddpf.dwRBitMask == ddpf.dwRBitMask
  134. && m_ddpf.dwGBitMask == ddpf.dwGBitMask
  135. && m_ddpf.dwGBitMask == ddpf.dwGBitMask
  136. && m_ddpf.dwRGBAlphaBitMask == ddpf.dwRGBAlphaBitMask;
  137. }
  138. //////////////////////////////////////////////////////////////////////////////
  139. //
  140. // constructor
  141. //
  142. //////////////////////////////////////////////////////////////////////////////
  143. bool FillDDPF(
  144. DDPixelFormat& ddpf,
  145. IDirectDrawX* pdd,
  146. HDC hdc,
  147. HBITMAP hbitmap,
  148. IDirectDrawPalette** pppalette
  149. ) {
  150. BYTE ajBitmapInfo[sizeof(BITMAPINFO) + 3 * sizeof(DWORD)];
  151. BITMAPINFO* pbmi = (BITMAPINFO*)ajBitmapInfo;
  152. BOOL bRet = FALSE;
  153. memset(pbmi, 0, sizeof(ajBitmapInfo));
  154. pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  155. ZVerify(::GetDIBits(hdc, hbitmap, 0, 0, NULL, pbmi, DIB_RGB_COLORS));
  156. ddpf.dwFlags = DDPF_RGB;
  157. ddpf.dwRGBBitCount = pbmi->bmiHeader.biBitCount;
  158. ddpf.dwRGBAlphaBitMask = 0;
  159. switch(pbmi->bmiHeader.biCompression) {
  160. //
  161. // Default DIB format. Color masks are implicit for each bit depth.
  162. //
  163. case BI_RGB:
  164. switch (ddpf.dwRGBBitCount) {
  165. case 4:
  166. case 8:
  167. {
  168. ddpf.dwFlags |= ((ddpf.dwRGBBitCount == 4) ? DDPF_PALETTEINDEXED4 : DDPF_PALETTEINDEXED8);
  169. //
  170. // Create a palette for the surface
  171. //
  172. RGBQUAD prgb[256];
  173. int ncolors = GetDIBColorTable(hdc, 0, 256, prgb);
  174. ZAssert(ncolors == (1 << ddpf.dwRGBBitCount));
  175. PALETTEENTRY ppe[256];
  176. //
  177. // convert BGR to RGB
  178. //
  179. for (int index = 0; index < ncolors; index++) {
  180. ppe[index].peRed = prgb[index].rgbRed;
  181. ppe[index].peGreen = prgb[index].rgbGreen;
  182. ppe[index].peBlue = prgb[index].rgbBlue;
  183. }
  184. //
  185. // create a DirectDraw palette for the texture.
  186. //
  187. DDCall(pdd->CreatePalette(
  188. (ddpf.dwRGBBitCount == 4) ? DDPCAPS_4BIT : DDPCAPS_8BIT,
  189. ppe,
  190. pppalette,
  191. NULL
  192. ));
  193. return true;
  194. }
  195. case 16:
  196. // 16bpp default is 555 BGR-ordering
  197. ddpf.dwRBitMask = MakeMask(5, 10);
  198. ddpf.dwGBitMask = MakeMask(5, 5);
  199. ddpf.dwBBitMask = MakeMask(5, 0);
  200. return true;
  201. case 24:
  202. case 32:
  203. // 24 and 32bpp default is 888 BGR-ordering
  204. ddpf.dwRBitMask = MakeMask(8, 16);
  205. ddpf.dwGBitMask = MakeMask(8, 8);
  206. ddpf.dwBBitMask = MakeMask(8, 0);
  207. return true;
  208. }
  209. break;
  210. case BI_BITFIELDS:
  211. //
  212. // Call a second time to get the color masks.
  213. // It's a GetDIBits Win32 "feature".
  214. //
  215. ZVerify(::GetDIBits(hdc, hbitmap, 0, pbmi->bmiHeader.biHeight, NULL, pbmi, DIB_RGB_COLORS));
  216. ddpf.dwRBitMask = *(DWORD *)&pbmi->bmiColors[0];
  217. ddpf.dwGBitMask = *(DWORD *)&pbmi->bmiColors[1];
  218. ddpf.dwBBitMask = *(DWORD *)&pbmi->bmiColors[2];
  219. return true;
  220. }
  221. return false;
  222. }