X360TexConvertor.cpp 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. #ifndef _XBOX
  2. #include "X360TexConvertor.h"
  3. #include "TXX.h"
  4. //c++->general->additional include directories
  5. //C:\Program Files (x86)\Microsoft Xbox 360 SDK\include\win32\vs2005;C:\Program Files\Microsoft Xbox 360 SDK\include\win32\vs2005
  6. //linker->genreal->additional livrary directories
  7. //C:\Program Files (x86)\Microsoft Xbox 360 SDK\lib\win32\vs2005;C:\Program Files\Microsoft Xbox 360 SDK\lib\win32\vs2005
  8. #include <d3d9.h>
  9. #include <xgraphics.h>
  10. #pragma comment(lib, "d3d9.lib")
  11. #pragma comment(lib, "xgraphics.lib")
  12. struct STORMTEXFORMAT
  13. {
  14. TXXFormat txFormat;
  15. D3DFORMAT d3dFormat_tiled;
  16. D3DFORMAT d3dFormat_lin;
  17. bool isSwizzled;
  18. dword pitchDivider;
  19. const char * pFormatName;
  20. };
  21. STORMTEXFORMAT TexFormats[] =
  22. {
  23. {txxf_dxt1, D3DFMT_DXT1, D3DFMT_LIN_DXT1, true, 4, "D3DFMT_DXT1"},
  24. {txxf_dxt3, D3DFMT_DXT3, D3DFMT_LIN_DXT3, true, 4, "D3DFMT_DXT3"},
  25. {txxf_dxt5, D3DFMT_DXT5, D3DFMT_LIN_DXT5, true, 4, "D3DFMT_DXT5"},
  26. {txxf_a8r8g8b8, D3DFMT_A8R8G8B8, D3DFMT_LIN_A8R8G8B8, false, 1, "D3DFMT_A8R8G8B8"},
  27. {txxf_r5g6b5, D3DFMT_R5G6B5, D3DFMT_LIN_R5G6B5, false, 1, "D3DFMT_R5G6B5"},
  28. {txxf_a4r4g4b4, D3DFMT_A4R4G4B4, D3DFMT_LIN_A4R4G4B4, false, 1, "D3DFMT_A4R4G4B4"},
  29. {txxf_a1r5g5b5, D3DFMT_A1R5G5B5, D3DFMT_LIN_A1R5G5B5, false, 1, "D3DFMT_A1R5G5B5"},
  30. {txxf_q8w8v8u8, D3DFMT_Q8W8V8U8, D3DFMT_LIN_Q8W8V8U8, false, 1, "D3DFMT_Q8W8V8U8"},
  31. {txxf_v8u8, D3DFMT_V8U8, D3DFMT_LIN_V8U8, false, 1, "D3DFMT_V8U8"},
  32. {txxf_a8, D3DFMT_A8, D3DFMT_LIN_A8, false, 1, "D3DFMT_A8"},
  33. {txxf_l8, D3DFMT_L8, D3DFMT_LIN_L8, false, 1, "D3DFMT_L8"},
  34. {txxf_unknown, D3DFMT_X8R8G8B8, D3DFMT_LIN_X8R8G8B8, false, 1, "D3DFMT_X8R8G8B8"},
  35. {txxf_unknown, D3DFMT_D24S8, D3DFMT_LIN_D24S8, false, 1, "D3DFMT_D24S8"},
  36. {txxf_unknown, D3DFMT_D16, D3DFMT_LIN_D16, false, 1, "D3DFMT_D16"},
  37. {txxf_unknown, D3DFMT_D24X8, D3DFMT_LIN_D24X8, false, 1, "D3DFMT_D24X8"},
  38. /* X360 unsupported
  39. {txxf_unknown, D3DFMT_D24X4S4, false, 1, "D3DFMT_D24X4S4"},
  40. {txxf_unknown, D3DFMT_D15S1, false, 1, "D3DFMT_D15S1"},
  41. */
  42. {txxf_unknown, D3DFMT_D32, D3DFMT_LIN_D32, false, 1, "D3DFMT_D32"}
  43. };
  44. STORMTEXFORMAT* GetFormat(TXXFormat txFormat)
  45. {
  46. for (dword i=0; i < sizeof(TexFormats) / sizeof(STORMTEXFORMAT); i++)
  47. {
  48. if (TexFormats[i].txFormat == txFormat)
  49. {
  50. return &TexFormats[i];
  51. }
  52. }
  53. return null;
  54. }
  55. void XboxConvert_txx(const char * from, const char * to)
  56. {
  57. IFileService* pFS = (IFileService *)api->GetService("FileService");
  58. ILoadBuffer * txxFile = pFS->LoadData(from, _FL_);
  59. if(!txxFile)
  60. {
  61. api->Trace("TexConvertor: Can't find texture : '%s'", from);
  62. return;
  63. }
  64. const byte * txxData = txxFile->Buffer();
  65. const byte * txxEOF = txxData + txxFile->Size();
  66. if(txxFile->Size() < sizeof(TxxFileHeader))
  67. {
  68. api->Trace("TexConvertor: Texture dont have enught size: '%s'", from);
  69. return;
  70. }
  71. TxxFileHeader & head = *(TxxFileHeader *)txxData;
  72. txxData += sizeof(TxxFileHeader);
  73. XSwizzleULong(head.id);
  74. XSwizzleULong(head.ver);
  75. XSwizzleULong(head.type);
  76. XSwizzleULong(head.format);
  77. XSwizzleULong(head.width);
  78. XSwizzleULong(head.height);
  79. XSwizzleULong(head.depth);
  80. XSwizzleULong(head.num_mips);
  81. XSwizzleULong(head.line_size);
  82. XSwizzleULong(head.bpp);
  83. XSwizzleFloat(head.fps);
  84. if(head.id != TXX_ID || head.ver != TXX_VER)
  85. {
  86. api->Trace("TexConvertor: Texture is damage: '%s'", from);
  87. return;
  88. }
  89. STORMTEXFORMAT * pTexFormat = null;
  90. for (dword i=0; i < sizeof(TexFormats) / sizeof(STORMTEXFORMAT); i++)
  91. {
  92. if (TexFormats[i].txFormat == head.format)
  93. {
  94. pTexFormat = &TexFormats[i];
  95. break;
  96. }
  97. }
  98. if (!pTexFormat)
  99. {
  100. api->Trace("TexConvertor: unknown texture format: %d, texture: %s", head.format, from);
  101. txxFile->Release();
  102. return;
  103. }
  104. if (head.type == txxt_2d && head.type != txxt_rendertarget) // if simple texture
  105. {
  106. UINT m_dwBaseSize_linear = 0;
  107. UINT m_dwMipSize_linear = 0;
  108. UINT m_dwBaseSize_tiled = 0;
  109. UINT m_dwMipSize_tiled = 0;
  110. D3DBaseTexture linearTexture;
  111. D3DBaseTexture tiledTexture;
  112. // Now set the texture header with the information we've obtained so far.
  113. XGSetTextureHeaderEx( head.width, head.height, head.num_mips, 0, pTexFormat->d3dFormat_lin, 0, 0, 0,
  114. XGHEADER_CONTIGUOUS_MIP_OFFSET, 0, ( D3DTexture* )&linearTexture, &m_dwBaseSize_linear, &m_dwMipSize_linear );
  115. // Now set the texture header with the information we've obtained so far.
  116. XGSetTextureHeaderEx( head.width, head.height, head.num_mips, 0, pTexFormat->d3dFormat_tiled, 0, 0, 0,
  117. XGHEADER_CONTIGUOUS_MIP_OFFSET, 0, ( D3DTexture* )&tiledTexture, &m_dwBaseSize_tiled, &m_dwMipSize_tiled );
  118. // Create a buffer to hold the texture data.
  119. byte* m_pBuffer_linear = new byte[ m_dwBaseSize_linear + m_dwMipSize_linear ];
  120. byte* m_pBuffer_tiled = new byte[ m_dwBaseSize_tiled + m_dwMipSize_tiled ];
  121. XGTEXTURE_DESC BaseDesc;
  122. XGGetTextureDesc( &tiledTexture, 0, &BaseDesc );
  123. for (dword dwLevel = 0; dwLevel < head.num_mips; dwLevel++)
  124. {
  125. // Get the description of the current mip level.
  126. XGTEXTURE_DESC mipDesc_lin;
  127. XGGetTextureDesc( &linearTexture, dwLevel, &mipDesc_lin );
  128. XGTEXTURE_DESC mipDesc_tiled;
  129. XGGetTextureDesc( &tiledTexture, dwLevel, &mipDesc_tiled );
  130. // Get the mip level offset within our buffer.
  131. DWORD dwMipLevelOffset_linear = XGGetMipLevelOffset( &linearTexture, 0, dwLevel );
  132. if( ( dwLevel > 0 ) && ( m_dwMipSize_linear > 0 ) )
  133. {
  134. dwMipLevelOffset_linear += m_dwBaseSize_linear;
  135. }
  136. BYTE* mipData_linear = m_pBuffer_linear + dwMipLevelOffset_linear;
  137. // Get the mip level offset within our buffer.
  138. DWORD dwMipLevelOffset_tiled = XGGetMipLevelOffset( &tiledTexture, 0, dwLevel );
  139. if( ( dwLevel > 0 ) && ( m_dwMipSize_tiled > 0 ) )
  140. {
  141. dwMipLevelOffset_tiled += m_dwBaseSize_tiled;
  142. }
  143. BYTE* mipData_tiled = m_pBuffer_tiled + dwMipLevelOffset_tiled;
  144. //load surface....
  145. dword txxLineForRead = head.line_size;
  146. dword txxLines = head.height;
  147. switch (head.format)
  148. {
  149. case txxf_dxt1:
  150. txxLineForRead = (head.width/4)*64/8;
  151. txxLines /= 4;
  152. Assert(txxLines == mipDesc_lin.HeightInBlocks);
  153. break;
  154. case txxf_dxt3:
  155. txxLineForRead = (head.width/4)*64/8*2;
  156. txxLines /= 4;
  157. Assert(txxLines == mipDesc_lin.HeightInBlocks);
  158. break;
  159. case txxf_dxt5:
  160. txxLineForRead = (head.width/4)*64/8*2;
  161. txxLines /= 4;
  162. Assert(txxLines == mipDesc_lin.HeightInBlocks);
  163. break;
  164. }
  165. Assert(mipDesc_lin.RowPitch >= txxLineForRead);
  166. byte* destPtr = mipData_linear;
  167. for (dword line = 0; line < txxLines; line++)
  168. {
  169. Assert(txxData + txxLineForRead <= txxEOF);
  170. memcpy(destPtr, txxData, txxLineForRead);
  171. txxData += txxLineForRead;
  172. destPtr += mipDesc_lin.RowPitch;
  173. }
  174. XGEndianSwapSurface(mipData_linear, mipDesc_lin.RowPitch, mipData_linear, mipDesc_lin.RowPitch, mipDesc_lin.Width, mipDesc_lin.Height, mipDesc_lin.Format);
  175. XGTileTextureLevel(
  176. BaseDesc.Width,
  177. BaseDesc.Height,
  178. dwLevel,
  179. XGGetGpuFormat( mipDesc_tiled.Format ),
  180. 0,
  181. mipData_tiled,
  182. NULL,
  183. mipData_linear,
  184. mipDesc_lin.RowPitch,
  185. NULL );
  186. head.line_size /= 2;
  187. head.width /= 2;
  188. head.height /= 2;
  189. }
  190. //----- тут получили линейную и тайленую текстуры для X360, можно любую писать на диск--------
  191. XGEndianSwapTextureHeader(( D3DTexture* )&tiledTexture);
  192. DWORD dwWritten = 0;
  193. HANDLE hFile = CreateFile(to, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ, null, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, null);
  194. // Write the D3D texture header.
  195. WriteFile( hFile, &tiledTexture, sizeof( tiledTexture ), &dwWritten, NULL );
  196. //Write texture data.
  197. WriteFile( hFile, m_pBuffer_tiled, m_dwBaseSize_tiled + m_dwMipSize_tiled, &dwWritten, NULL);
  198. CloseHandle( hFile );
  199. delete [] m_pBuffer_linear;
  200. delete [] m_pBuffer_tiled;
  201. m_pBuffer_linear = NULL;
  202. m_pBuffer_tiled = NULL;
  203. } else
  204. {
  205. api->Trace("TexConvertor: %s is not simple 2d texture or render target texture !!!", from);
  206. txxFile->Release();
  207. return;
  208. }
  209. txxFile->Release();
  210. }
  211. /*
  212. код загрузки для X360
  213. ============================================================
  214. D3DTexture g_Texture;
  215. HANDLE hFile = CreateFile( "game:\\stonewall.tex", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
  216. DWORD dwSize = GetFileSize( hFile, NULL );
  217. DWORD dwTextureDataSize = dwSize - sizeof( D3DTexture );
  218. // First load the D3DTexture structure contents so we have a valid texture header.
  219. ReadFile( hFile, &g_Texture, sizeof( g_Texture ), &dwRead, NULL );
  220. // Now allocate space for the texture data. This needs to be allocated on 4K boundary in physical memory.
  221. DWORD dwAllocAttributes = MAKE_XALLOC_ATTRIBUTES( 0, FALSE, FALSE, FALSE, 0, XALLOC_PHYSICAL_ALIGNMENT_4K, XALLOC_MEMPROTECT_WRITECOMBINE, FALSE, XALLOC_MEMTYPE_PHYSICAL );
  222. BYTE *g_pTextureData = ( BYTE* )XMemAlloc( dwTextureDataSize, dwAllocAttributes );
  223. ReadFile( hFile, g_pTextureData, dwTextureDataSize, &dwRead, NULL );
  224. CloseHandle( hFile );
  225. // Now fix up the texture header to point to the base and mip addresses inside the texture data.
  226. // This is the final step - once this is done, the texture is ready to be used!
  227. D3DBaseTexture *pBaseTexture = ( D3DBaseTexture* )&g_Texture;
  228. XGOffsetBaseTextureAddress( pBaseTexture, g_pTextureData, g_pTextureData );
  229. ============================================================
  230. готово!!!
  231. */
  232. #endif