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.

497 lines
14 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: texture.c
  3. *
  4. * Texture handling functions
  5. *
  6. * Copyright (c) 1994 Microsoft Corporation
  7. *
  8. \**************************************************************************/
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include <stdlib.h>
  12. #include <math.h>
  13. #include <sys/types.h>
  14. #include <time.h>
  15. #include <windows.h>
  16. #include <scrnsave.h>
  17. #include <commdlg.h>
  18. //#include <GL/gl.h>
  19. //#include "tk.h"
  20. //#include "scrnsave.h" // for hMainInstance
  21. //#include "sscommon.h"
  22. #include <d3dx8.h>
  23. #include "d3dsaver.h"
  24. #include "FlyingObjects.h"
  25. #include "texture.h"
  26. static int VerifyTextureFile( TEXFILE *pTexFile );
  27. static int GetTexFileType( TEXFILE *pTexFile );
  28. static TEX_STRINGS gts = {0};
  29. BOOL gbTextureObjects = FALSE;
  30. static BOOL gbEnableErrorMsgs = FALSE;
  31. /******************************Public*Routine******************************\
  32. * ss_fOnWin95
  33. *
  34. * True if running on Windows 95
  35. *
  36. \**************************************************************************/
  37. BOOL
  38. ss_fOnWin95( void )
  39. {
  40. // Figure out if we're on 9x
  41. OSVERSIONINFO osvi;
  42. osvi.dwOSVersionInfoSize = sizeof(osvi);
  43. GetVersionEx( &osvi );
  44. return (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS);
  45. }
  46. /******************************Public*Routine******************************\
  47. *
  48. * ss_LoadTextureResourceStrings
  49. *
  50. * Load various messages and strings that are used in processing textures,
  51. * into global TEX_STRINGS structure
  52. *
  53. \**************************************************************************/
  54. BOOL
  55. ss_LoadTextureResourceStrings()
  56. {
  57. LPTSTR pszStr;
  58. // title for choose texture File dialog
  59. LoadString(NULL, IDS_TEXTUREDIALOGTITLE, gts.szTextureDialogTitle,
  60. GEN_STRING_SIZE);
  61. LoadString(NULL, IDS_BMP, gts.szBmp, GEN_STRING_SIZE);
  62. LoadString(NULL, IDS_DOTBMP, gts.szDotBmp, GEN_STRING_SIZE);
  63. // szTextureFilter requires a little more work. Need to assemble the file
  64. // name filter string, which is composed of two strings separated by a NULL
  65. // and terminated with a double NULL.
  66. LoadString(NULL, IDS_TEXTUREFILTER, gts.szTextureFilter,
  67. GEN_STRING_SIZE);
  68. pszStr = &gts.szTextureFilter[lstrlen(gts.szTextureFilter)+1];
  69. LoadString(NULL, IDS_STARDOTBMP, pszStr, GEN_STRING_SIZE);
  70. pszStr += lstrlen(pszStr);
  71. /*
  72. *pszStr++ = TEXT(';');
  73. LoadString(NULL, IDS_STARDOTRGB, pszStr, GEN_STRING_SIZE);
  74. pszStr += lstrlen(pszStr);
  75. */
  76. pszStr++;
  77. *pszStr = TEXT('\0');
  78. LoadString(NULL, IDS_WARNING, gts.szWarningMsg, MAX_PATH);
  79. LoadString(NULL, IDS_SELECT_ANOTHER_BITMAP,
  80. gts.szSelectAnotherBitmapMsg, MAX_PATH );
  81. LoadString(NULL, IDS_BITMAP_INVALID,
  82. gts.szBitmapInvalidMsg, MAX_PATH );
  83. LoadString(NULL, IDS_BITMAP_SIZE,
  84. gts.szBitmapSizeMsg, MAX_PATH );
  85. // assumed here that all above calls loaded properly (mf: fix later)
  86. return TRUE;
  87. }
  88. /******************************Public*Routine******************************\
  89. *
  90. *
  91. \**************************************************************************/
  92. void
  93. ss_DisableTextureErrorMsgs()
  94. {
  95. gbEnableErrorMsgs = FALSE;
  96. }
  97. /******************************Public*Routine******************************\
  98. *
  99. * ss_DeleteTexture
  100. *
  101. \**************************************************************************/
  102. void
  103. ss_DeleteTexture( TEXTURE *pTex )
  104. {
  105. if( pTex == NULL )
  106. return;
  107. if( gbTextureObjects && pTex->texObj ) {
  108. // glDeleteTextures( 1, &pTex->texObj );
  109. pTex->texObj = 0;
  110. }
  111. if (pTex->pal != NULL)
  112. {
  113. free(pTex->pal);
  114. }
  115. if( pTex->data )
  116. free( pTex->data );
  117. }
  118. /******************************Public*Routine******************************\
  119. *
  120. * ss_VerifyTextureFile
  121. *
  122. * Validates texture bmp or rgb file, by checking for valid pathname and
  123. * correct format.
  124. *
  125. * History
  126. * Apr. 28, 95 : [marcfo]
  127. * - Wrote it
  128. *
  129. * Jul. 25, 95 : [marcfo]
  130. * - Suppress warning dialog box in child preview mode, as it will
  131. * be continuously brought up.
  132. *
  133. * Dec. 12, 95 : [marcfo]
  134. * - Support .rgb files as well
  135. *
  136. * Dec. 14, 95 : [marcfo]
  137. * - Change to have it only check the file path
  138. *
  139. \**************************************************************************/
  140. BOOL
  141. ss_VerifyTextureFile( TEXFILE *ptf )
  142. {
  143. // Make sure the selected texture file is OK.
  144. TCHAR szFileName[MAX_PATH];
  145. PTSTR pszString;
  146. TCHAR szString[MAX_PATH];
  147. lstrcpy(szFileName, ptf->szPathName);
  148. if ( SearchPath(NULL, szFileName, NULL, MAX_PATH,
  149. ptf->szPathName, &pszString)
  150. )
  151. {
  152. ptf->nOffset = (int)((ULONG_PTR)(pszString - ptf->szPathName));
  153. return TRUE;
  154. }
  155. else
  156. {
  157. lstrcpy(ptf->szPathName, szFileName); // restore
  158. if( !ss_fOnWin95() && gbEnableErrorMsgs )
  159. {
  160. wsprintf(szString, gts.szSelectAnotherBitmapMsg, ptf->szPathName);
  161. MessageBox(NULL, szString, gts.szWarningMsg, MB_OK);
  162. }
  163. return FALSE;
  164. }
  165. }
  166. /******************************Public*Routine******************************\
  167. *
  168. * ss_SelectTextureFile
  169. *
  170. * Use the common dialog GetOpenFileName to get the name of a bitmap file
  171. * for use as a texture. This function will not return until the user
  172. * either selects a valid bitmap or cancels. If a valid bitmap is selected
  173. * by the user, the global array szPathName will have the full path
  174. * to the bitmap file and the global value nOffset will have the
  175. * offset from the beginning of szPathName to the pathless file name.
  176. *
  177. * If the user cancels, szPathName and nOffset will remain
  178. * unchanged.
  179. *
  180. * History:
  181. * 10-May-1994 -by- Gilman Wong [gilmanw]
  182. * - Wrote it.
  183. * Apr. 28, 95 : [marcfo]
  184. * - Modified for common use
  185. * Dec. 12, 95 : [marcfo]
  186. * - Support .rgb files as well
  187. *
  188. \**************************************************************************/
  189. BOOL
  190. ss_SelectTextureFile( HWND hDlg, TEXFILE *ptf )
  191. {
  192. OPENFILENAME ofn;
  193. TCHAR dirName[MAX_PATH];
  194. TEXFILE newTexFile;
  195. LPTSTR pszFileName = newTexFile.szPathName;
  196. TCHAR origPathName[MAX_PATH];
  197. PTSTR pszString;
  198. BOOL bTryAgain, bFileSelected;
  199. //mf:
  200. gbEnableErrorMsgs = TRUE;
  201. // Make a copy of the original file path name, so we can tell if
  202. // it changed or not
  203. lstrcpy( origPathName, ptf->szPathName );
  204. // Make dialog look nice by parsing out the initial path and
  205. // file name from the full pathname. If this isn't done, then
  206. // dialog has a long ugly name in the file combo box and
  207. // directory will end up with the default current directory.
  208. if (ptf->nOffset) {
  209. // Separate the directory and file names.
  210. lstrcpy(dirName, ptf->szPathName);
  211. dirName[ptf->nOffset-1] = L'\0';
  212. lstrcpy(pszFileName, &ptf->szPathName[ptf->nOffset]);
  213. }
  214. else {
  215. // If nOffset is zero, then szPathName is not a full path.
  216. // Attempt to make it a full path by calling SearchPath.
  217. if ( SearchPath(NULL, ptf->szPathName, NULL, MAX_PATH,
  218. dirName, &pszString) )
  219. {
  220. // Successful. Go ahead a change szPathName to the full path
  221. // and compute the filename offset.
  222. lstrcpy(ptf->szPathName, dirName);
  223. ptf->nOffset = (int)((ULONG_PTR)(pszString - dirName));
  224. // Break the filename and directory paths apart.
  225. dirName[ptf->nOffset-1] = TEXT('\0');
  226. lstrcpy(pszFileName, pszString);
  227. }
  228. // Give up and use the Windows system directory.
  229. else
  230. {
  231. if( !GetWindowsDirectory(dirName, MAX_PATH) )
  232. dirName[0] = TEXT('\0');
  233. lstrcpy(pszFileName, ptf->szPathName);
  234. }
  235. }
  236. ofn.lStructSize = sizeof(OPENFILENAME);
  237. ofn.hwndOwner = hDlg;
  238. ofn.hInstance = NULL;
  239. ofn.lpstrFilter = gts.szTextureFilter;
  240. ofn.lpstrCustomFilter = (LPTSTR) NULL;
  241. ofn.nMaxCustFilter = 0;
  242. ofn.nFilterIndex = 1;
  243. ofn.lpstrFile = pszFileName;
  244. ofn.nMaxFile = MAX_PATH;
  245. ofn.lpstrFileTitle = (LPTSTR) NULL;
  246. ofn.nMaxFileTitle = 0;
  247. ofn.lpstrInitialDir = dirName;
  248. ofn.lpstrTitle = gts.szTextureDialogTitle;
  249. ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
  250. ofn.nFileOffset = 0;
  251. ofn.nFileExtension = 0;
  252. ofn.lpstrDefExt = gts.szBmp;
  253. ofn.lCustData = 0;
  254. ofn.lpfnHook = (LPOFNHOOKPROC) NULL;
  255. ofn.lpTemplateName = (LPTSTR) NULL;
  256. do {
  257. // Invoke the common file dialog. If it succeeds, then validate
  258. // the bitmap file. If not valid, make user try again until either
  259. // they pick a good one or cancel the dialog.
  260. bTryAgain = FALSE;
  261. if ( bFileSelected = GetOpenFileName(&ofn) ) {
  262. newTexFile.nOffset = ofn.nFileOffset;
  263. if( VerifyTextureFile( &newTexFile ) ) {
  264. // copy in new file and offset
  265. *ptf = newTexFile;
  266. }
  267. else {
  268. bTryAgain = TRUE;
  269. }
  270. }
  271. // If need to try again, recompute dir and file name so dialog
  272. // still looks nice.
  273. if (bTryAgain && ofn.nFileOffset) {
  274. lstrcpy(dirName, pszFileName);
  275. dirName[ofn.nFileOffset-1] = L'\0';
  276. lstrcpy(pszFileName, &pszFileName[ofn.nFileOffset]);
  277. }
  278. } while (bTryAgain);
  279. gbEnableErrorMsgs = FALSE;
  280. if( bFileSelected ) {
  281. if( lstrcmpi( origPathName, ptf->szPathName ) )
  282. // a different file was selected
  283. return TRUE;
  284. }
  285. return FALSE;
  286. }
  287. /******************************Public*Routine******************************\
  288. *
  289. * ss_GetDefaultBmpFile
  290. *
  291. * Determine a default bitmap file to use for texturing, if none
  292. * exists yet in the registry.
  293. *
  294. * Put default in BmpFile parameter. DotBmp parameter is the bitmap
  295. * extension (usually .bmp).
  296. *
  297. * We have to synthesise the name from the ProductType registry entry.
  298. * Currently, this can be WinNT, LanmanNT, or Server. If it is
  299. * WinNT, the bitmap is winnt.bmp. If it is LanmanNT or Server,
  300. * the bitmap is lanmannt.bmp.
  301. *
  302. * History
  303. * Apr. 28, 95 : [marcfo]
  304. * - Wrote it
  305. *
  306. * Jul. 27, 95 : [marcfo]
  307. * - Added support for win95
  308. *
  309. * Apr. 23, 96 : [marcfo]
  310. * - Return NULL string for win95
  311. *
  312. \**************************************************************************/
  313. void
  314. ss_GetDefaultBmpFile( LPTSTR pszBmpFile )
  315. {
  316. HKEY hkey;
  317. LONG cjDefaultBitmap = MAX_PATH;
  318. if( ss_fOnWin95() )
  319. // There is no 'nice' bmp file on standard win95 installations
  320. lstrcpy( pszBmpFile, TEXT("") );
  321. else {
  322. if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  323. (LPCTSTR) TEXT("System\\CurrentControlSet\\Control\\ProductOptions"),
  324. 0,
  325. KEY_QUERY_VALUE,
  326. &hkey) == ERROR_SUCCESS )
  327. {
  328. if ( RegQueryValueEx(hkey,
  329. TEXT("ProductType"),
  330. (LPDWORD) NULL,
  331. (LPDWORD) NULL,
  332. (LPBYTE) pszBmpFile,
  333. (LPDWORD) &cjDefaultBitmap) == ERROR_SUCCESS
  334. && (cjDefaultBitmap / sizeof(TCHAR) + 4) <= MAX_PATH )
  335. lstrcat( pszBmpFile, gts.szDotBmp );
  336. else
  337. lstrcpy( pszBmpFile, TEXT("winnt.bmp") );
  338. RegCloseKey(hkey);
  339. }
  340. else
  341. lstrcpy( pszBmpFile, TEXT("winnt.bmp") );
  342. // If its not winnt.bmp, then its lanmannt.bmp. (This would be a lot
  343. // cleaner both in the screen savers and for usersrv desktop bitmap
  344. // initialization if the desktop bitmap name were stored in the
  345. // registry).
  346. if ( lstrcmpi( pszBmpFile, TEXT("winnt.bmp") ) != 0 )
  347. lstrcpy( pszBmpFile, TEXT("lanmannt.bmp") );
  348. }
  349. }
  350. /******************************Public*Routine******************************\
  351. *
  352. * VerifyTextureFile
  353. *
  354. * Verify that a bitmap or rgb file is valid
  355. *
  356. * Returns:
  357. * File type (RGB or BMP) if valid file; otherwise, 0.
  358. *
  359. * History
  360. * Dec. 12, 95 : [marcfo]
  361. * - Creation
  362. *
  363. \**************************************************************************/
  364. static int
  365. VerifyTextureFile( TEXFILE *pTexFile )
  366. {
  367. int type;
  368. // ISIZE size;
  369. BOOL bValid = TRUE;
  370. TCHAR szString[2 * MAX_PATH]; // May contain a pathname
  371. // check for 0 offset and null strings
  372. if( (pTexFile->nOffset == 0) || (*pTexFile->szPathName == 0) )
  373. return 0;
  374. type = GetTexFileType( pTexFile );
  375. switch( type ) {
  376. case TEX_BMP:
  377. // bValid = bVerifyDIB( pTexFile->szPathName, &size );
  378. break;
  379. /*
  380. case TEX_RGB:
  381. // bValid = bVerifyRGB( pTexFile->szPathName, &size );
  382. break;
  383. */
  384. case TEX_UNKNOWN:
  385. default:
  386. bValid = FALSE;
  387. }
  388. if( !bValid ) {
  389. if( gbEnableErrorMsgs ) {
  390. wsprintf(szString, gts.szSelectAnotherBitmapMsg, pTexFile->szPathName);
  391. MessageBox(NULL, szString, gts.szWarningMsg, MB_OK);
  392. }
  393. return 0;
  394. }
  395. return type;
  396. }
  397. /******************************Public*Routine******************************\
  398. *
  399. * GetTexFileType
  400. *
  401. * Determine if a texture file is rgb or bmp, based on extension. This is
  402. * good enough, as the open texture dialog only shows files with these
  403. * extensions.
  404. *
  405. \**************************************************************************/
  406. static int
  407. GetTexFileType( TEXFILE *pTexFile )
  408. {
  409. LPTSTR pszStr;
  410. #ifdef UNICODE
  411. pszStr = wcsrchr( pTexFile->szPathName + pTexFile->nOffset,
  412. (USHORT) L'.' );
  413. #else
  414. pszStr = strrchr( pTexFile->szPathName + pTexFile->nOffset,
  415. (USHORT) L'.' );
  416. #endif
  417. if( !pszStr || (lstrlen(++pszStr) == 0) )
  418. return TEX_UNKNOWN;
  419. if( !lstrcmpi( pszStr, TEXT("bmp") ) )
  420. return TEX_BMP;
  421. /*
  422. else if( !lstrcmpi( pszStr, TEXT("rgb") ) )
  423. return TEX_RGB;
  424. */
  425. else
  426. return TEX_UNKNOWN;
  427. }