PageRenderTime 51ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/tools/XBMCTex/xbox.cpp

https://github.com/superpea/xbmc-fork
C++ | 225 lines | 188 code | 21 blank | 16 comment | 22 complexity | 9c7b8b600652f4f8eefba24055386aca MD5 | raw file
Possible License(s): AGPL-1.0, GPL-2.0, LGPL-2.1
  1. #include "stdafx.h"
  2. #ifndef min
  3. #define min(a,b) (((a) < (b)) ? (a) : (b))
  4. #endif
  5. bool IsPowerOf2(UINT number)
  6. {
  7. return (number & (~number+1)) == number;
  8. }
  9. int GetLog2(UINT Number)
  10. {
  11. int power = 0;
  12. while (Number)
  13. {
  14. Number >>= 1;
  15. power++;
  16. }
  17. return power-1;
  18. }
  19. BOOL IsPaletted(XB_D3DFORMAT format)
  20. {
  21. switch (format)
  22. {
  23. case XB_D3DFMT_P8:
  24. return true;
  25. default:
  26. return false;
  27. }
  28. }
  29. DWORD SetTextureHeader(UINT Width, UINT Height, UINT Levels, UINT Usage, XB_D3DFORMAT Format, D3DPOOL Pool, D3DTexture *pTexture, UINT Data, UINT Pitch)
  30. {
  31. #ifdef USE_XDK
  32. return XGSetTextureHeader(Width, Height, Levels, Usage, (D3DFORMAT)Format, Pool, (LPDIRECT3DTEXTURE8)pTexture, Data, Pitch);
  33. #else
  34. // TODO: No idea what most of this is.
  35. memset(pTexture, 0, sizeof(D3DTexture));
  36. pTexture->Common = D3DCOMMON_TYPE_TEXTURE + 1; // what does the 1 give??
  37. pTexture->Format |= (Format & 0xFF) << 8;
  38. pTexture->Format |= 0x10029; // no idea why
  39. pTexture->Data = Data; // offset of texture data
  40. if (IsPowerOf2(Width) && IsPowerOf2(Height))
  41. {
  42. pTexture->Format |= (GetLog2(Width) & 0xF) << 20;
  43. pTexture->Format |= (GetLog2(Height) & 0xF) << 24;
  44. }
  45. else
  46. {
  47. pTexture->Size |= (Width - 1) & 0xfff;
  48. pTexture->Size |= ((Height - 1) & 0xfff) << 12;
  49. pTexture->Size |= (((Pitch >> 6) & 0xff) - 1) << 24;
  50. }
  51. static int count=0;
  52. count++;
  53. #endif
  54. return D3D_OK;
  55. }
  56. BOOL IsSwizzledFormat(XB_D3DFORMAT format)
  57. {
  58. #ifdef USE_XDK
  59. return XGIsSwizzledFormat((D3DFORMAT)format);
  60. #else
  61. switch (format)
  62. {
  63. case XB_D3DFMT_A8R8G8B8:
  64. case XB_D3DFMT_P8:
  65. return true;
  66. default:
  67. return false;
  68. }
  69. #endif
  70. }
  71. DWORD BytesPerPixelFromFormat(XB_D3DFORMAT format)
  72. {
  73. #ifdef USE_XDK
  74. return XGBytesPerPixelFromFormat((D3DFORMAT)format);
  75. #else
  76. switch (format)
  77. {
  78. case XB_D3DFMT_A8R8G8B8:
  79. case XB_D3DFMT_LIN_A8R8G8B8:
  80. case XB_D3DFMT_DXT1:
  81. case XB_D3DFMT_DXT4:
  82. return 4;
  83. case XB_D3DFMT_P8:
  84. return 1;
  85. }
  86. return 0;
  87. #endif
  88. }
  89. // Swizzle.
  90. // Format is:
  91. // 00 01 04 05
  92. // 02 03 06 07
  93. // 08 09 12 13
  94. // 10 11 14 15 ...
  95. // Currently only works for 32bit and 8bit textures, with power of 2 width and height
  96. void Swizzle(const void *src, unsigned int depth, unsigned int width, unsigned int height, void *dest)
  97. {
  98. for (UINT y = 0; y < height; y++)
  99. {
  100. UINT sy = 0;
  101. if (y < width)
  102. {
  103. for (int bit = 0; bit < 16; bit++)
  104. sy |= ((y >> bit) & 1) << (2*bit);
  105. sy <<= 1; // y counts twice
  106. }
  107. else
  108. {
  109. UINT y_mask = y % width;
  110. for (int bit = 0; bit < 16; bit++)
  111. sy |= ((y_mask >> bit) & 1) << (2*bit);
  112. sy <<= 1; // y counts twice
  113. sy += (y / width) * width * width;
  114. }
  115. BYTE *s = (BYTE *)src + y * width * depth;
  116. for (UINT x = 0; x < width; x++)
  117. {
  118. UINT sx = 0;
  119. if (x < height * 2)
  120. {
  121. for (int bit = 0; bit < 16; bit++)
  122. sx |= ((x >> bit) & 1) << (2*bit);
  123. }
  124. else
  125. {
  126. int x_mask = x % (2*height);
  127. for (int bit = 0; bit < 16; bit++)
  128. sx |= ((x_mask >> bit) & 1) << (2*bit);
  129. sx += (x / (2 * height)) * 2 * height * height;
  130. }
  131. BYTE *d = (BYTE *)dest + (sx + sy)*depth;
  132. for (unsigned int i = 0; i < depth; ++i)
  133. *d++ = *s++;
  134. }
  135. }
  136. }
  137. VOID SwizzleRect(LPCVOID pSource, DWORD Pitch, LPCRECT pRect, LPVOID pDest, DWORD Width, DWORD Height, CONST LPPOINT pPoint, DWORD BytesPerPixel)
  138. {
  139. #ifdef USE_XDK
  140. XGSwizzleRect(pSource, Pitch, pRect, pDest, Width, Height, pPoint, BytesPerPixel);
  141. #else
  142. // Note: Doesn't listen to pRect or pPoint
  143. // Also, knows nothing about Pitch
  144. Swizzle(pSource, BytesPerPixel, Width, Height, pDest);
  145. #endif
  146. }
  147. extern LPDIRECT3DDEVICE8 pD3DDevice;
  148. // Round a number to the nearest power of 2 rounding up
  149. // runs pretty quickly - the only expensive op is the bsr
  150. // alternive would be to dec the source, round down and double the result
  151. // which is slightly faster but rounds 1 to 2
  152. D3DFORMAT D3DFormat(XB_D3DFORMAT format)
  153. {
  154. switch (format)
  155. {
  156. case XB_D3DFMT_LIN_A8R8G8B8:
  157. return D3DFMT_A8R8G8B8;
  158. case XB_D3DFMT_DXT1:
  159. return D3DFMT_DXT1;
  160. case XB_D3DFMT_DXT3:
  161. return D3DFMT_DXT3;
  162. case XB_D3DFMT_DXT5:
  163. return D3DFMT_DXT5;
  164. default:
  165. return (D3DFORMAT)format;
  166. }
  167. }
  168. HRESULT CompressRect(LPVOID pDestBuf, XB_D3DFORMAT DestFormat, DWORD DestPitch, DWORD Width, DWORD Height, LPVOID pSrcData, XB_D3DFORMAT SrcFormat, DWORD SrcPitch, FLOAT AlphaRef, DWORD Flags)
  169. {
  170. #ifdef USE_XDK
  171. return XGCompressRect(pDestBuf, (D3DFORMAT)DestFormat, DestPitch, Width, Height, pSrcData, (D3DFORMAT)SrcFormat, SrcPitch, AlphaRef, Flags);
  172. #else
  173. // Note: The below doesn't do anything with AlphaRef or Flags
  174. LPDIRECT3DSURFACE8 pSrcSurf, pDestSurf;
  175. HRESULT hr = pD3DDevice->CreateImageSurface(Width, Height, D3DFormat(SrcFormat), &pSrcSurf);
  176. if (FAILED(hr)) return hr;
  177. D3DLOCKED_RECT rect;
  178. pSrcSurf->LockRect(&rect, NULL, 0);
  179. for (UINT y = 0; y < Height; y++)
  180. {
  181. BYTE *src = (BYTE *)pSrcData + y * SrcPitch;
  182. BYTE *dest = (BYTE *)rect.pBits + y * rect.Pitch;
  183. memcpy(dest, src, min((UINT)rect.Pitch, SrcPitch));
  184. }
  185. pSrcSurf->UnlockRect();
  186. int padWidth = PadPow2(Width), padHeight = PadPow2(Height);
  187. hr = pD3DDevice->CreateImageSurface(padWidth, padHeight, D3DFormat(DestFormat), &pDestSurf);
  188. if (FAILED(hr)) return hr;
  189. hr = D3DXLoadSurfaceFromSurface(pDestSurf, NULL, NULL, pSrcSurf, NULL, NULL, D3DX_FILTER_NONE, 0);
  190. if (FAILED(hr)) return hr;
  191. // copy into dest buffer
  192. pDestSurf->LockRect(&rect, NULL, 0);
  193. for (UINT y = 0; y < Height / 4; y++)
  194. {
  195. BYTE *src = (BYTE *)rect.pBits + y * rect.Pitch;
  196. BYTE *dest = (BYTE *)pDestBuf + y * DestPitch;
  197. memcpy(dest, src, min((UINT)rect.Pitch, DestPitch));
  198. }
  199. pDestSurf->UnlockRect();
  200. pSrcSurf->Release();
  201. pDestSurf->Release();
  202. return hr;
  203. #endif
  204. }