/******************************Module*Header*******************************\ * Module Name: texture.c * * Texture handling functions * * Copyright (c) 1994 Microsoft Corporation * \**************************************************************************/ #include #include #include #include #include #include #include #include #include //#include //#include "tk.h" //#include "scrnsave.h" // for hMainInstance //#include "sscommon.h" #include #include "d3dsaver.h" #include "FlyingObjects.h" #include "texture.h" static int VerifyTextureFile( TEXFILE *pTexFile ); static int GetTexFileType( TEXFILE *pTexFile ); static TEX_STRINGS gts = {0}; BOOL gbTextureObjects = FALSE; static BOOL gbEnableErrorMsgs = FALSE; /******************************Public*Routine******************************\ * ss_fOnWin95 * * True if running on Windows 95 * \**************************************************************************/ BOOL ss_fOnWin95( void ) { // Figure out if we're on 9x OSVERSIONINFO osvi; osvi.dwOSVersionInfoSize = sizeof(osvi); GetVersionEx( &osvi ); return (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS); } /******************************Public*Routine******************************\ * * ss_LoadTextureResourceStrings * * Load various messages and strings that are used in processing textures, * into global TEX_STRINGS structure * \**************************************************************************/ BOOL ss_LoadTextureResourceStrings() { LPTSTR pszStr; // title for choose texture File dialog LoadString(NULL, IDS_TEXTUREDIALOGTITLE, gts.szTextureDialogTitle, GEN_STRING_SIZE); LoadString(NULL, IDS_BMP, gts.szBmp, GEN_STRING_SIZE); LoadString(NULL, IDS_DOTBMP, gts.szDotBmp, GEN_STRING_SIZE); // szTextureFilter requires a little more work. Need to assemble the file // name filter string, which is composed of two strings separated by a NULL // and terminated with a double NULL. LoadString(NULL, IDS_TEXTUREFILTER, gts.szTextureFilter, GEN_STRING_SIZE); pszStr = >s.szTextureFilter[lstrlen(gts.szTextureFilter)+1]; LoadString(NULL, IDS_STARDOTBMP, pszStr, GEN_STRING_SIZE); pszStr += lstrlen(pszStr); /* *pszStr++ = TEXT(';'); LoadString(NULL, IDS_STARDOTRGB, pszStr, GEN_STRING_SIZE); pszStr += lstrlen(pszStr); */ pszStr++; *pszStr = TEXT('\0'); LoadString(NULL, IDS_WARNING, gts.szWarningMsg, MAX_PATH); LoadString(NULL, IDS_SELECT_ANOTHER_BITMAP, gts.szSelectAnotherBitmapMsg, MAX_PATH ); LoadString(NULL, IDS_BITMAP_INVALID, gts.szBitmapInvalidMsg, MAX_PATH ); LoadString(NULL, IDS_BITMAP_SIZE, gts.szBitmapSizeMsg, MAX_PATH ); // assumed here that all above calls loaded properly (mf: fix later) return TRUE; } /******************************Public*Routine******************************\ * * \**************************************************************************/ void ss_DisableTextureErrorMsgs() { gbEnableErrorMsgs = FALSE; } /******************************Public*Routine******************************\ * * ss_DeleteTexture * \**************************************************************************/ void ss_DeleteTexture( TEXTURE *pTex ) { if( pTex == NULL ) return; if( gbTextureObjects && pTex->texObj ) { // glDeleteTextures( 1, &pTex->texObj ); pTex->texObj = 0; } if (pTex->pal != NULL) { free(pTex->pal); } if( pTex->data ) free( pTex->data ); } /******************************Public*Routine******************************\ * * ss_VerifyTextureFile * * Validates texture bmp or rgb file, by checking for valid pathname and * correct format. * * History * Apr. 28, 95 : [marcfo] * - Wrote it * * Jul. 25, 95 : [marcfo] * - Suppress warning dialog box in child preview mode, as it will * be continuously brought up. * * Dec. 12, 95 : [marcfo] * - Support .rgb files as well * * Dec. 14, 95 : [marcfo] * - Change to have it only check the file path * \**************************************************************************/ BOOL ss_VerifyTextureFile( TEXFILE *ptf ) { // Make sure the selected texture file is OK. TCHAR szFileName[MAX_PATH]; PTSTR pszString; TCHAR szString[MAX_PATH]; lstrcpy(szFileName, ptf->szPathName); if ( SearchPath(NULL, szFileName, NULL, MAX_PATH, ptf->szPathName, &pszString) ) { ptf->nOffset = (int)((ULONG_PTR)(pszString - ptf->szPathName)); return TRUE; } else { lstrcpy(ptf->szPathName, szFileName); // restore if( !ss_fOnWin95() && gbEnableErrorMsgs ) { wsprintf(szString, gts.szSelectAnotherBitmapMsg, ptf->szPathName); MessageBox(NULL, szString, gts.szWarningMsg, MB_OK); } return FALSE; } } /******************************Public*Routine******************************\ * * ss_SelectTextureFile * * Use the common dialog GetOpenFileName to get the name of a bitmap file * for use as a texture. This function will not return until the user * either selects a valid bitmap or cancels. If a valid bitmap is selected * by the user, the global array szPathName will have the full path * to the bitmap file and the global value nOffset will have the * offset from the beginning of szPathName to the pathless file name. * * If the user cancels, szPathName and nOffset will remain * unchanged. * * History: * 10-May-1994 -by- Gilman Wong [gilmanw] * - Wrote it. * Apr. 28, 95 : [marcfo] * - Modified for common use * Dec. 12, 95 : [marcfo] * - Support .rgb files as well * \**************************************************************************/ BOOL ss_SelectTextureFile( HWND hDlg, TEXFILE *ptf ) { OPENFILENAME ofn; TCHAR dirName[MAX_PATH]; TEXFILE newTexFile; LPTSTR pszFileName = newTexFile.szPathName; TCHAR origPathName[MAX_PATH]; PTSTR pszString; BOOL bTryAgain, bFileSelected; //mf: gbEnableErrorMsgs = TRUE; // Make a copy of the original file path name, so we can tell if // it changed or not lstrcpy( origPathName, ptf->szPathName ); // Make dialog look nice by parsing out the initial path and // file name from the full pathname. If this isn't done, then // dialog has a long ugly name in the file combo box and // directory will end up with the default current directory. if (ptf->nOffset) { // Separate the directory and file names. lstrcpy(dirName, ptf->szPathName); dirName[ptf->nOffset-1] = L'\0'; lstrcpy(pszFileName, &ptf->szPathName[ptf->nOffset]); } else { // If nOffset is zero, then szPathName is not a full path. // Attempt to make it a full path by calling SearchPath. if ( SearchPath(NULL, ptf->szPathName, NULL, MAX_PATH, dirName, &pszString) ) { // Successful. Go ahead a change szPathName to the full path // and compute the filename offset. lstrcpy(ptf->szPathName, dirName); ptf->nOffset = (int)((ULONG_PTR)(pszString - dirName)); // Break the filename and directory paths apart. dirName[ptf->nOffset-1] = TEXT('\0'); lstrcpy(pszFileName, pszString); } // Give up and use the Windows system directory. else { if( !GetWindowsDirectory(dirName, MAX_PATH) ) dirName[0] = TEXT('\0'); lstrcpy(pszFileName, ptf->szPathName); } } ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = hDlg; ofn.hInstance = NULL; ofn.lpstrFilter = gts.szTextureFilter; ofn.lpstrCustomFilter = (LPTSTR) NULL; ofn.nMaxCustFilter = 0; ofn.nFilterIndex = 1; ofn.lpstrFile = pszFileName; ofn.nMaxFile = MAX_PATH; ofn.lpstrFileTitle = (LPTSTR) NULL; ofn.nMaxFileTitle = 0; ofn.lpstrInitialDir = dirName; ofn.lpstrTitle = gts.szTextureDialogTitle; ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; ofn.nFileOffset = 0; ofn.nFileExtension = 0; ofn.lpstrDefExt = gts.szBmp; ofn.lCustData = 0; ofn.lpfnHook = (LPOFNHOOKPROC) NULL; ofn.lpTemplateName = (LPTSTR) NULL; do { // Invoke the common file dialog. If it succeeds, then validate // the bitmap file. If not valid, make user try again until either // they pick a good one or cancel the dialog. bTryAgain = FALSE; if ( bFileSelected = GetOpenFileName(&ofn) ) { newTexFile.nOffset = ofn.nFileOffset; if( VerifyTextureFile( &newTexFile ) ) { // copy in new file and offset *ptf = newTexFile; } else { bTryAgain = TRUE; } } // If need to try again, recompute dir and file name so dialog // still looks nice. if (bTryAgain && ofn.nFileOffset) { lstrcpy(dirName, pszFileName); dirName[ofn.nFileOffset-1] = L'\0'; lstrcpy(pszFileName, &pszFileName[ofn.nFileOffset]); } } while (bTryAgain); gbEnableErrorMsgs = FALSE; if( bFileSelected ) { if( lstrcmpi( origPathName, ptf->szPathName ) ) // a different file was selected return TRUE; } return FALSE; } /******************************Public*Routine******************************\ * * ss_GetDefaultBmpFile * * Determine a default bitmap file to use for texturing, if none * exists yet in the registry. * * Put default in BmpFile parameter. DotBmp parameter is the bitmap * extension (usually .bmp). * * We have to synthesise the name from the ProductType registry entry. * Currently, this can be WinNT, LanmanNT, or Server. If it is * WinNT, the bitmap is winnt.bmp. If it is LanmanNT or Server, * the bitmap is lanmannt.bmp. * * History * Apr. 28, 95 : [marcfo] * - Wrote it * * Jul. 27, 95 : [marcfo] * - Added support for win95 * * Apr. 23, 96 : [marcfo] * - Return NULL string for win95 * \**************************************************************************/ void ss_GetDefaultBmpFile( LPTSTR pszBmpFile ) { HKEY hkey; LONG cjDefaultBitmap = MAX_PATH; if( ss_fOnWin95() ) // There is no 'nice' bmp file on standard win95 installations lstrcpy( pszBmpFile, TEXT("") ); else { if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE, (LPCTSTR) TEXT("System\\CurrentControlSet\\Control\\ProductOptions"), 0, KEY_QUERY_VALUE, &hkey) == ERROR_SUCCESS ) { if ( RegQueryValueEx(hkey, TEXT("ProductType"), (LPDWORD) NULL, (LPDWORD) NULL, (LPBYTE) pszBmpFile, (LPDWORD) &cjDefaultBitmap) == ERROR_SUCCESS && (cjDefaultBitmap / sizeof(TCHAR) + 4) <= MAX_PATH ) lstrcat( pszBmpFile, gts.szDotBmp ); else lstrcpy( pszBmpFile, TEXT("winnt.bmp") ); RegCloseKey(hkey); } else lstrcpy( pszBmpFile, TEXT("winnt.bmp") ); // If its not winnt.bmp, then its lanmannt.bmp. (This would be a lot // cleaner both in the screen savers and for usersrv desktop bitmap // initialization if the desktop bitmap name were stored in the // registry). if ( lstrcmpi( pszBmpFile, TEXT("winnt.bmp") ) != 0 ) lstrcpy( pszBmpFile, TEXT("lanmannt.bmp") ); } } /******************************Public*Routine******************************\ * * VerifyTextureFile * * Verify that a bitmap or rgb file is valid * * Returns: * File type (RGB or BMP) if valid file; otherwise, 0. * * History * Dec. 12, 95 : [marcfo] * - Creation * \**************************************************************************/ static int VerifyTextureFile( TEXFILE *pTexFile ) { int type; // ISIZE size; BOOL bValid = TRUE; TCHAR szString[2 * MAX_PATH]; // May contain a pathname // check for 0 offset and null strings if( (pTexFile->nOffset == 0) || (*pTexFile->szPathName == 0) ) return 0; type = GetTexFileType( pTexFile ); switch( type ) { case TEX_BMP: // bValid = bVerifyDIB( pTexFile->szPathName, &size ); break; /* case TEX_RGB: // bValid = bVerifyRGB( pTexFile->szPathName, &size ); break; */ case TEX_UNKNOWN: default: bValid = FALSE; } if( !bValid ) { if( gbEnableErrorMsgs ) { wsprintf(szString, gts.szSelectAnotherBitmapMsg, pTexFile->szPathName); MessageBox(NULL, szString, gts.szWarningMsg, MB_OK); } return 0; } return type; } /******************************Public*Routine******************************\ * * GetTexFileType * * Determine if a texture file is rgb or bmp, based on extension. This is * good enough, as the open texture dialog only shows files with these * extensions. * \**************************************************************************/ static int GetTexFileType( TEXFILE *pTexFile ) { LPTSTR pszStr; #ifdef UNICODE pszStr = wcsrchr( pTexFile->szPathName + pTexFile->nOffset, (USHORT) L'.' ); #else pszStr = strrchr( pTexFile->szPathName + pTexFile->nOffset, (USHORT) L'.' ); #endif if( !pszStr || (lstrlen(++pszStr) == 0) ) return TEX_UNKNOWN; if( !lstrcmpi( pszStr, TEXT("bmp") ) ) return TEX_BMP; /* else if( !lstrcmpi( pszStr, TEXT("rgb") ) ) return TEX_RGB; */ else return TEX_UNKNOWN; }