Counter Strike : Global Offensive Source Code
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.

303 lines
6.5 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. #if !defined( _GAMECONSOLE )
  9. #include <windows.h>
  10. #endif
  11. #include <stdio.h>
  12. #include "UtlBuffer.h"
  13. #include <vgui/VGUI.h>
  14. #include <vgui_controls/Controls.h>
  15. #include "FileSystem.h"
  16. // dgoodenough - select the correct stubs header based on current console
  17. // PS3_BUILDFIX
  18. #if defined( _PS3 )
  19. #include "ps3/ps3_win32stubs.h"
  20. #endif
  21. #if defined( _X360 )
  22. #include "xbox/xbox_win32stubs.h"
  23. #endif
  24. // memdbgon must be the last include file in a .cpp file!!!
  25. #include "tier0/memdbgon.h"
  26. using namespace vgui;
  27. #define TYP_LUMPY 64 // 64 + grab command number
  28. typedef struct
  29. {
  30. char identification[4]; // should be WAD2 or 2DAW
  31. int numlumps;
  32. int infotableofs;
  33. } wadinfo_t;
  34. typedef struct
  35. {
  36. int filepos;
  37. int disksize;
  38. int size; // uncompressed
  39. char type;
  40. char compression;
  41. char pad1, pad2;
  42. char name[16]; // must be null terminated
  43. } lumpinfo_t;
  44. typedef struct
  45. {
  46. char name[16];
  47. unsigned width, height;
  48. unsigned offsets[4]; // four mip maps stored
  49. } miptex_t;
  50. unsigned char pixdata[256];
  51. float linearpalette[256][3];
  52. float d_red, d_green, d_blue;
  53. int colors_used;
  54. int color_used[256];
  55. float maxdistortion;
  56. unsigned char palLogo[768];
  57. /*
  58. =============
  59. AveragePixels
  60. =============
  61. */
  62. unsigned char AveragePixels (int count)
  63. {
  64. return pixdata[0];
  65. }
  66. /*
  67. ==============
  68. GrabMip
  69. filename MIP x y width height
  70. must be multiples of sixteen
  71. ==============
  72. */
  73. int GrabMip ( HANDLE hdib, unsigned char *lump_p, char *lumpname, COLORREF crf, int *width, int *height)
  74. {
  75. int i,x,y,xl,yl,xh,yh,w,h;
  76. unsigned char *screen_p, *source;
  77. miptex_t *qtex;
  78. int miplevel, mipstep;
  79. int xx, yy;
  80. int count;
  81. int byteimagewidth, byteimageheight;
  82. unsigned char *byteimage;
  83. LPBITMAPINFO lpbmi; // pointer to BITMAPINFO structure (Win3.0)
  84. /* get pointer to BITMAPINFO (Win 3.0) */
  85. // dgoodenough - GlobalLock is win32 specific, skip using it for now, we'll fix this up later
  86. // PS3_BUILDFIX
  87. // FIXME FIXME FIXME - This will need help.
  88. #if defined( _PS3 )
  89. lpbmi = NULL;
  90. #else
  91. lpbmi = (LPBITMAPINFO)::GlobalLock((HGLOBAL)hdib);
  92. #endif
  93. unsigned char *lump_start = lump_p;
  94. xl = yl = 0;
  95. w = lpbmi->bmiHeader.biWidth;
  96. h = lpbmi->bmiHeader.biHeight;
  97. *width = w;
  98. *height = h;
  99. byteimage = (unsigned char *)((LPSTR)lpbmi + sizeof( BITMAPINFOHEADER ) + 256 * sizeof( RGBQUAD ) );
  100. if ( (w & 15) || (h & 15) )
  101. return 0; //Error ("line %i: miptex sizes must be multiples of 16", scriptline);
  102. xh = xl+w;
  103. yh = yl+h;
  104. qtex = (miptex_t *)lump_p;
  105. qtex->width = (unsigned)(w);
  106. qtex->height = (unsigned)(h);
  107. Q_strncpy (qtex->name, lumpname, sizeof( qtex->name) );
  108. lump_p = (unsigned char *)&qtex->offsets[4];
  109. byteimagewidth = w;
  110. byteimageheight = h;
  111. source = (unsigned char *)lump_p;
  112. qtex->offsets[0] = (unsigned)((unsigned char *)lump_p - (unsigned char *)qtex);
  113. // We're reading from a dib, so go bottom up
  114. screen_p = byteimage + (h - 1) * w;
  115. for (y=yl ; y<yh ; y++)
  116. {
  117. for (x=xl ; x<xh ; x++)
  118. *lump_p++ = *screen_p++;
  119. screen_p -= 2 * w;
  120. }
  121. // calculate gamma corrected linear palette
  122. for (i = 0; i < 256; i++)
  123. {
  124. for (int j = 0; j < 3; j++)
  125. {
  126. float f = (float)(palLogo[i*3+j] / 255.0);
  127. linearpalette[i][j] = f; //pow((double)f, 2); // assume textures are done at 2.2, we want to remap them at 1.0
  128. }
  129. }
  130. maxdistortion = 0;
  131. // assume palette full if it's a transparent texture
  132. colors_used = 256;
  133. for (i = 0; i < 256; i++)
  134. color_used[i] = 1;
  135. //
  136. // subsample for greater mip levels
  137. //
  138. for (miplevel = 1 ; miplevel<4 ; miplevel++)
  139. {
  140. d_red = d_green = d_blue = 0; // no distortion yet
  141. qtex->offsets[miplevel] = (unsigned)(lump_p - (unsigned char *)qtex);
  142. mipstep = 1<<miplevel;
  143. for (y=0 ; y<h ; y+=mipstep)
  144. {
  145. for (x = 0 ; x<w ; x+= mipstep)
  146. {
  147. count = 0;
  148. for (yy=0 ; yy<mipstep ; yy++)
  149. {
  150. for (xx=0 ; xx<mipstep ; xx++)
  151. pixdata[count++] = source[(y+yy)*w + x + xx ];
  152. }
  153. *lump_p++ = AveragePixels (count);
  154. }
  155. }
  156. }
  157. // dgoodenough - GlobalUnlock is win32 specific, skip using it for now, we'll fix this up later
  158. // PS3_BUILDFIX
  159. // FIXME FIXME FIXME - This will need help.
  160. #if !defined( _PS3 )
  161. ::GlobalUnlock(lpbmi);
  162. #endif
  163. // Write out palette in 16bit mode
  164. *(unsigned short *) lump_p = 256; // palette size
  165. lump_p += sizeof(short);
  166. memcpy(lump_p, &palLogo[0], 765);
  167. lump_p += 765;
  168. *lump_p++ = (unsigned char)(crf & 0xFF);
  169. *lump_p++ = (unsigned char)((crf >> 8) & 0xFF);
  170. *lump_p++ = (unsigned char)((crf >> 16) & 0xFF);
  171. return lump_p - lump_start;
  172. }
  173. void UpdateLogoWAD( void *phdib, int r, int g, int b )
  174. {
  175. char logoname[ 32 ];
  176. char *pszName;
  177. Q_strncpy( logoname, "LOGO", sizeof( logoname ) );
  178. pszName = &logoname[ 0 ];
  179. HANDLE hdib = (HANDLE)phdib;
  180. COLORREF crf = RGB( r, g, b );
  181. if ((!pszName) || (pszName[0] == 0) || (hdib == NULL))
  182. return;
  183. // Generate lump
  184. unsigned char *buf = (unsigned char *)_alloca( 16384 );
  185. CUtlBuffer buffer( 0, 16384 );
  186. int width, height;
  187. int length = GrabMip (hdib, buf, pszName, crf, &width, &height);
  188. if ( length == 0 )
  189. {
  190. return;
  191. }
  192. bool sizevalid = false;
  193. if ( width == height )
  194. {
  195. if ( width == 16 ||
  196. width == 32 ||
  197. width == 64 )
  198. {
  199. sizevalid = true;
  200. }
  201. }
  202. if ( !sizevalid )
  203. return;
  204. while (length & 3)
  205. length++;
  206. // Write Header
  207. wadinfo_t header;
  208. header.identification[0] = 'W';
  209. header.identification[1] = 'A';
  210. header.identification[2] = 'D';
  211. header.identification[3] = '3';
  212. header.numlumps = 1;
  213. header.infotableofs = 0;
  214. buffer.Put( &header, sizeof( wadinfo_t ) );
  215. // Fill Ino info table
  216. lumpinfo_t info;
  217. Q_memset (&info, 0, sizeof(info));
  218. Q_strncpy(info.name, pszName, sizeof( info.name ) );
  219. info.filepos = (int)sizeof(wadinfo_t);
  220. info.size = info.disksize = length;
  221. info.type = TYP_LUMPY;
  222. info.compression = 0;
  223. // Write Lump
  224. buffer.Put( buf, length );
  225. // Write info table
  226. buffer.Put( &info, sizeof( lumpinfo_t ) );
  227. int savepos = buffer.TellPut();
  228. buffer.SeekPut( CUtlBuffer::SEEK_HEAD, 0 );
  229. header.infotableofs = length + sizeof(wadinfo_t);
  230. buffer.Put( &header, sizeof( wadinfo_t ) );
  231. buffer.SeekPut( CUtlBuffer::SEEK_HEAD, savepos );
  232. // Output to file
  233. FileHandle_t file;
  234. file = g_pFullFileSystem->Open( "pldecal.wad", "wb" );
  235. if ( file != FILESYSTEM_INVALID_HANDLE )
  236. {
  237. g_pFullFileSystem->Write( buffer.Base(), buffer.TellPut(), file );
  238. g_pFullFileSystem->Close( file );
  239. }
  240. }