dsrc isn't necessary for this repo
[client-tools.git] / src / external / 3rd / application / UiBuilder / ImportImage.cpp
blob60feaf8380baa0dea2e8d1b8932e0722ae5faf50
1 #include "FirstUiBuilder.h"
3 #include "resource.h"
4 #include "UIImageFrame.h"
5 #include "UIImageStyle.h"
6 #include "UITypes.h"
7 #include "UIUtils.h"
9 #include <commctrl.h>
10 #include <ddraw.h>
11 #include <list>
12 #include <math.h>
13 #include <shlwapi.h>
14 #include <stdio.h>
16 typedef std::list<UIRect> FragmentRectangleList;
18 static bool gGenerateFragments = true;
19 static bool gCompressFragments = true;
20 static bool gUseWholeImage = true;
21 static UIRect gSubImageRect;
22 static int gTileMaxIndex = 3;
23 static int gTileMinIndex = 1;
25 static long gTileSizes[] = {32, 64, 128, 256, 512, 1024, 2048};
27 static char gSourceFile[_MAX_PATH];
28 static char gAlphaFile[_MAX_PATH];
29 static long gCompressionMethodIndex = 0;
30 static char *gCompressionMethods[] = {"DXT1", "DXT2", "DXT3", "DXT4", "DXT5"};
31 static char gParentPath[_MAX_PATH];
33 static bool gFileIsValid = false;
34 static bool gFileIsBitmap = false;
35 static bool gAlphaFileIsValid = false;
36 static long gFileWidth = 0;
37 static long gFileHeight = 0;
38 static FragmentRectangleList gFragmentRectangles;
40 void SaveBitmapToFile( HDC hdc, HBITMAP hbmp, const char *Filename )
42 BITMAPFILEHEADER Header;
43 BITMAPINFO bmi;
44 BITMAP bm;
45 long datasize;
47 GetObject( hbmp, sizeof( bm ), &bm );
49 ZeroMemory( &bmi, sizeof( bmi ) );
50 bmi.bmiHeader.biSize = sizeof( bmi.bmiHeader );
51 bmi.bmiHeader.biWidth = bm.bmWidth;
52 bmi.bmiHeader.biHeight = bm.bmHeight;
53 bmi.bmiHeader.biPlanes = 1;
54 bmi.bmiHeader.biBitCount = 24;
55 bmi.bmiHeader.biCompression = BI_RGB;
57 datasize = bm.bmWidth * bm.bmHeight * 3;
59 char *mem = new char[datasize];
60 GetDIBits( hdc, hbmp, 0, bm.bmHeight, mem, &bmi, DIB_RGB_COLORS );
62 ZeroMemory( &Header, sizeof( Header ) );
63 Header.bfType = 'MB'; // BM reversed due to byte ordering
64 Header.bfSize = sizeof( Header ) + sizeof( bmi.bmiHeader ) + datasize;
65 Header.bfOffBits = sizeof( Header ) + sizeof( bmi.bmiHeader );
67 FILE *fp = fopen( Filename, "wb" );
69 if( fp )
71 fwrite( &Header, sizeof( Header ), 1, fp );
72 fwrite( &bmi.bmiHeader, sizeof( bmi.bmiHeader ), 1, fp );
73 fwrite( mem, datasize, 1, fp );
74 fclose( fp );
77 delete mem;
80 static void SliceImagesToFiles( HWND hwndDlg )
82 if( gFileIsValid && gFileIsBitmap && gUseWholeImage )
84 HBITMAP hSourceBitmap = 0;
85 HBITMAP hAlphaBitmap = 0;
86 int CurrentFragmentNumber = 1;
88 SendDlgItemMessage( hwndDlg, IDC_PROGRESS, PBM_SETRANGE, 0, MAKELPARAM( 1, gFragmentRectangles.size() ) );
90 hSourceBitmap = (HBITMAP)LoadImage( GetModuleHandle(0), gSourceFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );
92 if( gAlphaFileIsValid )
93 hAlphaBitmap = (HBITMAP)LoadImage( GetModuleHandle(0), gAlphaFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );
95 HDC ScreenDC = GetDC( NULL );
96 HDC SourceDC = CreateCompatibleDC( NULL );
97 HDC AlphaDC = CreateCompatibleDC( NULL );
98 HDC ScratchDC = CreateCompatibleDC( NULL );
100 SelectObject( SourceDC, hSourceBitmap );
102 if( hAlphaBitmap )
103 SelectObject( AlphaDC, hAlphaBitmap );
105 SelectObject( ScratchDC, GetStockObject( BLACK_BRUSH ) );
106 SelectObject( ScratchDC, GetStockObject( BLACK_PEN ) );
108 char *pDot = strrchr( gSourceFile, '.' );
110 if( pDot )
111 *pDot = '\0';
113 for( FragmentRectangleList::iterator i = gFragmentRectangles.begin(); i != gFragmentRectangles.end(); ++i )
115 HBITMAP Scratch;
116 long TileSize;
118 TileSize = i->Width();
120 if( TileSize < i->Height() )
121 TileSize = i->Height();
123 TileSize = (long)pow( 2.0, ceil( log( (double)TileSize ) / log( 2.0 ) ) );
125 Scratch = CreateCompatibleBitmap( ScreenDC, TileSize, TileSize );
127 if( Scratch )
129 HBITMAP OldBMP = (HBITMAP)SelectObject( ScratchDC, Scratch );
130 char Buffer[_MAX_PATH+1];
132 sprintf( Buffer, "Processing fragment %d of %d...", CurrentFragmentNumber, gFragmentRectangles.size() );
133 SetDlgItemText( hwndDlg, IDC_STATUS, Buffer );
134 SendDlgItemMessage( hwndDlg, IDC_PROGRESS, PBM_SETPOS, CurrentFragmentNumber, 0 );
136 Rectangle( ScratchDC, 0, 0, TileSize, TileSize );
138 UIRect rc = *i;
139 BitBlt( ScratchDC, 0, 0, i->Width(), i->Height(), SourceDC, i->left, i->top, SRCCOPY );
141 sprintf( Buffer, "%s_%02d.bmp", gSourceFile, CurrentFragmentNumber-1 );
142 SaveBitmapToFile( ScratchDC, Scratch, Buffer );
144 if( hAlphaBitmap )
146 Rectangle( ScratchDC, 0, 0, TileSize, TileSize );
147 BitBlt( ScratchDC, 0, 0, i->Width(), i->Height(), AlphaDC, i->left, i->top, SRCCOPY );
149 sprintf( Buffer, "%s_%02d_a.bmp", gSourceFile, CurrentFragmentNumber-1 );
150 SaveBitmapToFile( ScratchDC, Scratch, Buffer );
153 if( gCompressFragments )
155 sprintf( Buffer, "dxtex.exe \"%s_%02d.bmp\" %s \"%s_%02d.dds", gSourceFile, CurrentFragmentNumber - 1,
156 gCompressionMethods[gCompressionMethodIndex], gSourceFile, CurrentFragmentNumber - 1 );
158 STARTUPINFO si = {sizeof(si)};
159 PROCESS_INFORMATION pi;
161 GetStartupInfo( &si );
162 si.wShowWindow = SW_HIDE;
164 if( !CreateProcess( 0, Buffer, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi ) )
166 MessageBox(0, "Operation aborted because the texture compressor could not be run.\nCheck that dxtex.exe is on the path and retry.", 0, MB_OK );
168 sprintf( Buffer, "%s_%02d.bmp", gSourceFile, CurrentFragmentNumber-1 );
169 DeleteFile( Buffer );
171 if( hAlphaBitmap )
173 sprintf( Buffer, "%s_%02d_a.bmp", gSourceFile, CurrentFragmentNumber-1 );
174 DeleteFile( Buffer );
177 SelectObject( ScratchDC, OldBMP );
178 DeleteObject( Scratch );
179 DeleteDC( ScratchDC );
180 DeleteDC( AlphaDC );
181 DeleteDC( SourceDC );
182 ReleaseDC( 0, ScreenDC );
183 return;
186 WaitForSingleObject( pi.hProcess, INFINITE );
187 CloseHandle( pi.hProcess );
188 CloseHandle( pi.hThread );
190 sprintf( Buffer, "%s_%02d.bmp", gSourceFile, CurrentFragmentNumber-1 );
191 DeleteFile( Buffer );
193 if( hAlphaBitmap )
195 sprintf( Buffer, "%s_%02d_a.bmp", gSourceFile, CurrentFragmentNumber-1 );
196 DeleteFile( Buffer );
200 ++CurrentFragmentNumber;
201 SelectObject( ScratchDC, OldBMP );
202 DeleteObject( Scratch );
206 DeleteDC( ScratchDC );
207 DeleteDC( AlphaDC );
208 DeleteDC( SourceDC );
209 ReleaseDC( 0, ScreenDC );
213 static UIImageFrame *GenerateImageFrameFromData( void )
215 UIImageFrame *theFrame = new UIImageFrame;
217 if( gFragmentRectangles.size() == 1 )
219 char Buffer[_MAX_PATH+1];
221 if( gFileIsBitmap )
222 sprintf( Buffer, "%s_00", gSourceFile );
223 else
225 strcpy( Buffer, gSourceFile );
227 char *ext = strrchr( Buffer, '.' );
229 if( ext )
230 *ext = '\0';
233 theFrame->SetSourceResource( UIUnicode::narrowToWide (Buffer) );
234 theFrame->SetSourceRect( gFragmentRectangles.front() );
236 else
238 int CurrentFragmentNumber = 0;
240 for( FragmentRectangleList::iterator i = gFragmentRectangles.begin(); i != gFragmentRectangles.end(); ++i )
242 UIImageFragment *theFragment = new UIImageFragment;
243 char Buffer[_MAX_PATH+1];
245 sprintf( Buffer, "%s_%02d", gSourceFile, CurrentFragmentNumber );
247 theFragment->SetSourceResource( UIUnicode::narrowToWide (Buffer) );
248 theFragment->SetSourceRect( UIRect( 0, 0, i->Width(), i->Height() ) );
249 theFragment->SetOffset( i->left, i->top );
251 theFrame->AddChild( theFragment );
253 ++CurrentFragmentNumber;
256 return theFrame;
259 static void EnableControls( HWND hwndDlg )
261 if( gFileIsValid )
263 EnableWindow( GetDlgItem( hwndDlg, IDC_USESUBIMAGE ), TRUE );
264 EnableWindow( GetDlgItem( hwndDlg, IDC_SUBIMAGERECT ), !gUseWholeImage );
265 EnableWindow( GetDlgItem( hwndDlg, IDC_VIEWIMAGE ), !gUseWholeImage );
267 EnableWindow( GetDlgItem( hwndDlg, IDC_USEWHOLEIMAGE ), TRUE );
269 EnableWindow( GetDlgItem( hwndDlg, IDC_GENERATEFRAGMENTS ), gFileIsBitmap && gUseWholeImage );
270 EnableWindow( GetDlgItem( hwndDlg, IDC_TILEMAX ), gFileIsBitmap && gUseWholeImage && gGenerateFragments );
271 EnableWindow( GetDlgItem( hwndDlg, IDC_TILEMIN ), gFileIsBitmap && gUseWholeImage && gGenerateFragments );
273 EnableWindow( GetDlgItem( hwndDlg, IDC_COMPRESSFRAGMENTS ), gFileIsBitmap && gUseWholeImage && gGenerateFragments );
274 EnableWindow( GetDlgItem( hwndDlg, IDC_COMPRESSIONFORMAT ), gFileIsBitmap && gUseWholeImage && gGenerateFragments && gCompressFragments );
276 else
278 EnableWindow( GetDlgItem( hwndDlg, IDC_USESUBIMAGE ), FALSE );
279 EnableWindow( GetDlgItem( hwndDlg, IDC_SUBIMAGERECT ), FALSE );
280 EnableWindow( GetDlgItem( hwndDlg, IDC_VIEWIMAGE ), FALSE );
282 EnableWindow( GetDlgItem( hwndDlg, IDC_USEWHOLEIMAGE ), FALSE );
283 EnableWindow( GetDlgItem( hwndDlg, IDC_GENERATEFRAGMENTS ), FALSE );
284 EnableWindow( GetDlgItem( hwndDlg, IDC_TILEMAX ), FALSE );
285 EnableWindow( GetDlgItem( hwndDlg, IDC_TILEMIN ), FALSE );
287 EnableWindow( GetDlgItem( hwndDlg, IDC_COMPRESSFRAGMENTS ), FALSE );
288 EnableWindow( GetDlgItem( hwndDlg, IDC_COMPRESSIONFORMAT ), FALSE );
292 static void CalculateRectangleSlices( const UIRect &r, long TileSize )
294 if( !gFileIsBitmap )
296 gFragmentRectangles.push_back( r );
297 return;
300 if( TileSize == gTileSizes[gTileMinIndex] )
302 // Generate only full size, clipped tiles
303 int x, y;
305 for( y = r.top; y < r.bottom; y += TileSize )
307 for( x = r.left; x < r.right; x += TileSize )
309 long right = x + TileSize;
310 long bottom = y + TileSize;
312 if( right > r.right )
313 right = r.right;
315 if( bottom > r.bottom )
316 bottom = r.bottom;
318 gFragmentRectangles.push_back( UIRect( x, y, right, bottom ) );
322 else if( ((r.right - r.left) > (TileSize / 2)) && ((r.bottom - r.top) > (TileSize / 2)) )
324 int TilesHigh = 0;
325 int TilesAcross = 0;
326 int x, y;
328 // Generate some full size unclipped tiles
329 for( y = r.top; y <= r.bottom - TileSize; y += TileSize )
331 ++TilesHigh;
332 TilesAcross = 0;
334 for( x = r.left; x <= r.right - TileSize; x += TileSize )
336 ++TilesAcross;
337 gFragmentRectangles.push_back( UIRect( x, y, x + TileSize, y + TileSize ) );
341 // Right edge
342 CalculateRectangleSlices( UIRect( r.left + TilesAcross * TileSize, r.top, r.right, r.top + TilesHigh * TileSize ), TileSize / 2 );
344 // Bottom edge and corner
345 CalculateRectangleSlices( UIRect( r.left, r.top + TilesHigh * TileSize, r.right, r.bottom ), TileSize / 2 );
347 else
349 // Generate only smaller tiles
350 CalculateRectangleSlices( r, TileSize / 2 );
354 static void UpdateFragmentData( HWND hwndDlg )
356 gFragmentRectangles.clear();
358 if( gFileIsValid )
360 UIRect SmallestFragment;
361 UIRect LargestFragment;
362 long TotalFragmentArea;
363 char buffer[1024];
365 if( gUseWholeImage )
366 CalculateRectangleSlices( UIRect( 0, 0, gFileWidth, gFileHeight ), gTileSizes[gTileMaxIndex] );
367 else
369 long BufferLength = SendDlgItemMessage( hwndDlg, IDC_SUBIMAGERECT, WM_GETTEXTLENGTH, 0, 0 ) + 1;
370 char *Buffer = new char [ BufferLength ];
372 SendDlgItemMessage( hwndDlg, IDC_SUBIMAGERECT, WM_GETTEXT, BufferLength, (LPARAM) Buffer );
374 UIRect rc;
376 if( UIUtils::ParseRect( Buffer, rc ) )
377 gFragmentRectangles.push_back( rc );
379 delete Buffer;
382 sprintf( buffer, "%d", gFragmentRectangles.size() );
383 SetDlgItemText( hwndDlg, IDC_NUMFRAGMENTS, buffer );
385 if( gFragmentRectangles.size() > 0 )
387 FragmentRectangleList::iterator i = gFragmentRectangles.begin();
389 SmallestFragment = *i;
390 LargestFragment = *i;
391 TotalFragmentArea = i->Width() * i->Height();
393 for( ++i; i != gFragmentRectangles.end(); ++i )
395 if( i->Width() < SmallestFragment.Width() )
396 SmallestFragment = *i;
398 if( i->Width() > LargestFragment.Width() )
399 LargestFragment = *i;
401 TotalFragmentArea += i->Width() * i->Height();
404 sprintf( buffer, "%dx%d", LargestFragment.Width(), LargestFragment.Width() );
405 SetDlgItemText( hwndDlg, IDC_LARGESTFRAGMENT, buffer );
407 sprintf( buffer, "%dx%d", SmallestFragment.Width(), SmallestFragment.Width() );
408 SetDlgItemText( hwndDlg, IDC_SMALLESTFRAGMENT, buffer );
410 float memoryused = float(TotalFragmentArea * 2) / 4.0f + gFragmentRectangles.size() * ( sizeof(DWORD) + sizeof( DDSURFACEDESC2 ) );
411 float memorywasted = memoryused - float(gFileWidth * gFileHeight * 2) / 4.0f;
413 sprintf( buffer, "%.1f KB", memoryused / 1024.0f );
414 SetDlgItemText( hwndDlg, IDC_TOTALMEMORY, buffer );
416 sprintf( buffer, "%.1f KB", memorywasted / 1024.0f );
417 SetDlgItemText( hwndDlg, IDC_MEMORYWASTED, buffer );
419 else
421 SetDlgItemText( hwndDlg, IDC_LARGESTFRAGMENT, "" );
422 SetDlgItemText( hwndDlg, IDC_SMALLESTFRAGMENT, "" );
423 SetDlgItemText( hwndDlg, IDC_TOTALMEMORY, "" );
424 SetDlgItemText( hwndDlg, IDC_MEMORYWASTED, "" );
427 else
429 SetDlgItemText( hwndDlg, IDC_NUMFRAGMENTS, "0" );
430 SetDlgItemText( hwndDlg, IDC_LARGESTFRAGMENT, "" );
431 SetDlgItemText( hwndDlg, IDC_SMALLESTFRAGMENT, "" );
432 SetDlgItemText( hwndDlg, IDC_TOTALMEMORY, "" );
433 SetDlgItemText( hwndDlg, IDC_MEMORYWASTED, "" );
437 static void LoadData( HWND hwndDlg )
439 GetCurrentDirectory( sizeof( gParentPath ), gParentPath );
441 gFileIsValid = false;
442 gFileIsBitmap = false;
443 gAlphaFileIsValid = false;
445 SendDlgItemMessage( hwndDlg, IDC_BROWSESOURCE, BM_SETIMAGE, IMAGE_ICON,
446 (LPARAM)LoadImage( GetModuleHandle(0), MAKEINTRESOURCE(IDI_FOLDER), IMAGE_ICON, 16, 16, 0 ) );
448 SendDlgItemMessage( hwndDlg, IDC_VIEWIMAGE, BM_SETIMAGE, IMAGE_ICON,
449 (LPARAM)LoadImage( GetModuleHandle(0), MAKEINTRESOURCE(IDI_VIEWIMAGE), IMAGE_ICON, 16, 16, 0 ) );
451 if( gUseWholeImage )
452 CheckRadioButton( hwndDlg, IDC_USEWHOLEIMAGE, IDC_USESUBIMAGE, IDC_USEWHOLEIMAGE );
453 else
454 CheckRadioButton( hwndDlg, IDC_USEWHOLEIMAGE, IDC_USESUBIMAGE, IDC_USESUBIMAGE );
456 if( gGenerateFragments )
457 CheckDlgButton( hwndDlg, IDC_GENERATEFRAGMENTS, BST_CHECKED );
458 else
459 CheckDlgButton( hwndDlg, IDC_GENERATEFRAGMENTS, BST_UNCHECKED );
461 if( gCompressFragments )
462 CheckDlgButton( hwndDlg, IDC_COMPRESSFRAGMENTS, BST_CHECKED );
463 else
464 CheckDlgButton( hwndDlg, IDC_COMPRESSFRAGMENTS, BST_UNCHECKED );
466 SendDlgItemMessage( hwndDlg, IDC_TILEMAX, TBM_SETRANGE, FALSE, MAKELONG( 1, 6 ) );
467 SendDlgItemMessage( hwndDlg, IDC_TILEMAX, TBM_SETPOS, TRUE, gTileMaxIndex );
469 SendDlgItemMessage( hwndDlg, IDC_TILEMIN, TBM_SETRANGE, FALSE, MAKELONG( 0, 5 ) );
470 SendDlgItemMessage( hwndDlg, IDC_TILEMIN, TBM_SETPOS, TRUE, gTileMinIndex );
472 for( int i = 0; i < sizeof( gCompressionMethods ) / sizeof( *gCompressionMethods ); ++i )
474 int ItemID = SendDlgItemMessage( hwndDlg, IDC_COMPRESSIONFORMAT, CB_ADDSTRING, 0, (LPARAM)gCompressionMethods[i] );
475 SendDlgItemMessage( hwndDlg, IDC_COMPRESSIONFORMAT, CB_SETITEMDATA, ItemID, i );
478 for( int i = 0; i < sizeof( gCompressionMethods ) / sizeof( *gCompressionMethods ); ++i )
480 if( gCompressionMethodIndex == SendDlgItemMessage( hwndDlg, IDC_COMPRESSIONFORMAT, CB_GETITEMDATA, i, 0 ) )
482 SendDlgItemMessage( hwndDlg, IDC_COMPRESSIONFORMAT, CB_SETCURSEL, i, 0 );
483 break;
487 EnableControls( hwndDlg );
490 static BOOL CALLBACK NullDialogProc( HWND, UINT, WPARAM, LPARAM )
492 return FALSE;
495 static void SaveData( HWND hwndDlg )
497 // All data items are updated from the controls when they change so we don't need
498 // to get them here
499 ShowWindow( hwndDlg, SW_HIDE );
500 HWND hwndProgress = CreateDialog( GetModuleHandle(0), MAKEINTRESOURCE( IDD_PROGRESS ), NULL, NullDialogProc );
501 SliceImagesToFiles( hwndProgress );
502 DestroyWindow( hwndProgress );
505 static void Cleanup( void )
509 BOOL CALLBACK ImportImageDlgProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
511 switch( uMsg )
513 case WM_INITDIALOG:
514 LoadData( hwndDlg );
515 return TRUE;
517 case WM_CLOSE:
518 // Equivalent to pressing cancel
519 EndDialog( hwndDlg, 0 );
520 Cleanup();
521 return 0;
523 case WM_COMMAND:
524 if( LOWORD( wParam ) == IDOK )
526 SaveData( hwndDlg );
527 EndDialog( hwndDlg, (long)GenerateImageFrameFromData() );
528 Cleanup();
530 else if( LOWORD( wParam ) == IDCANCEL )
532 EndDialog( hwndDlg, 0 );
533 Cleanup();
535 else if( LOWORD( wParam ) == IDC_SUBIMAGERECT )
537 if( HIWORD( wParam ) == EN_CHANGE )
538 UpdateFragmentData( hwndDlg );
540 else if( LOWORD( wParam ) == IDC_SOURCEFILE )
542 if( HIWORD( wParam ) == EN_CHANGE )
544 char Buffer[_MAX_PATH + 1];
546 SendMessage( (HWND)lParam, WM_GETTEXT, sizeof( Buffer ), (LPARAM)Buffer );
547 strcpy( gSourceFile, Buffer );
549 char *ext = strrchr( Buffer, '.' );
551 if( ext && !strcmp( ext, ".dds" ) )
553 FILE *fp = fopen( Buffer, "r" );
555 gFileIsValid = false;
557 if( fp )
559 DDSURFACEDESC2 ddsd2;
560 char hdr[4];
562 gFileIsValid = true;
563 gFileIsBitmap = false;
564 gAlphaFileIsValid = false;
566 if( (fread( &hdr, sizeof( hdr ), 1, fp ) == 1) && !memcmp( hdr, "DDS ", 4 ) )
568 if( fread( &ddsd2, sizeof( ddsd2 ), 1, fp ) == 1 )
570 gFileWidth = ddsd2.dwWidth;
571 gFileHeight = ddsd2.dwHeight;
573 gFileIsValid = true;
577 fclose( fp );
580 else
582 FILE *fp = fopen( Buffer, "r" );
584 if( fp )
586 BITMAPFILEHEADER FileHeader;
587 BITMAPINFOHEADER BitmapInfoHeader;
589 if( !fread( &FileHeader, sizeof( FileHeader ), 1, fp ) )
590 gFileIsValid = false;
591 else
593 if( !fread( &BitmapInfoHeader, sizeof( BitmapInfoHeader ), 1, fp ) )
594 gFileIsValid = false;
595 else
597 if( FileHeader.bfType != 'MB' )
598 gFileIsValid = false;
599 else
601 gFileWidth = BitmapInfoHeader.biWidth;
602 gFileHeight = BitmapInfoHeader.biHeight;
603 gFileIsValid = true;
604 gFileIsBitmap = true;
609 fclose( fp );
612 if( ext )
613 *ext = '\0';
615 strcat( Buffer, "_a.bmp" );
616 strcpy( gAlphaFile, Buffer );
618 gAlphaFileIsValid = false;
619 fp = fopen( Buffer, "r" );
621 if( fp )
623 BITMAPFILEHEADER FileHeader;
624 BITMAPINFOHEADER BitmapInfoHeader;
626 if( fread( &FileHeader, sizeof( FileHeader ), 1, fp ) )
628 if( fread( &BitmapInfoHeader, sizeof( BitmapInfoHeader ), 1, fp ) )
630 if( FileHeader.bfType == 'MB' &&
631 (gFileWidth == BitmapInfoHeader.biWidth) &&
632 (gFileHeight == BitmapInfoHeader.biHeight) )
634 gAlphaFileIsValid = true;
639 fclose( fp );
643 EnableControls( hwndDlg );
644 UpdateFragmentData( hwndDlg );
647 else if( LOWORD( wParam ) == IDC_BROWSESOURCE )
649 if( HIWORD( wParam ) == BN_CLICKED )
651 OPENFILENAME ofn = {sizeof(ofn)};
652 char Buffer[_MAX_PATH+1];
654 Buffer[0] = '\0';
656 ofn.lpstrInitialDir = ".";
657 ofn.hwndOwner = hwndDlg;
658 ofn.lpstrFilter = "24 Bit Windows Bitmap Image Files (.bmp)\0*.bmp\0S3 Compressed Textures (.dds)\0*.dds\024 Bit Targa Files (.tga)\0*.tga\0";
659 ofn.nFilterIndex = 1;
660 ofn.lpstrFile = Buffer;
661 ofn.nMaxFile = sizeof( Buffer );
662 ofn.lpstrTitle = "Select Image to Import";
663 ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_NOCHANGEDIR;
665 if( GetOpenFileName( &ofn ) )
667 char RelPath[_MAX_PATH+1];
668 PathRelativePathTo( RelPath, gParentPath, FILE_ATTRIBUTE_DIRECTORY, Buffer, 0 );
670 if( (RelPath[0] == '.') && (RelPath[1] == '\\') )
671 memmove( RelPath, RelPath + 2, strlen( RelPath + 2 ) + 1 );
673 SendDlgItemMessage( hwndDlg, IDC_SOURCEFILE, WM_SETTEXT, 0, (LPARAM)RelPath );
677 else if( (LOWORD( wParam ) == IDC_USESUBIMAGE) || (LOWORD( wParam ) == IDC_USEWHOLEIMAGE) )
679 if( HIWORD( wParam ) == BN_CLICKED )
681 if( IsDlgButtonChecked( hwndDlg, IDC_USEWHOLEIMAGE ) )
682 gUseWholeImage = true;
683 else
684 gUseWholeImage = false;
686 EnableControls( hwndDlg );
687 UpdateFragmentData( hwndDlg );
690 else if( LOWORD( wParam ) == IDC_COMPRESSFRAGMENTS )
692 if( HIWORD( wParam ) == BN_CLICKED )
694 gCompressFragments = IsDlgButtonChecked( hwndDlg, IDC_COMPRESSFRAGMENTS ) != 0;
695 EnableControls( hwndDlg );
698 else if( LOWORD( wParam ) == IDC_GENERATEFRAGMENTS )
700 if( HIWORD( wParam ) == BN_CLICKED )
702 gGenerateFragments = IsDlgButtonChecked( hwndDlg, IDC_GENERATEFRAGMENTS ) != 0;
703 EnableControls( hwndDlg );
706 else if( LOWORD( wParam ) == IDC_COMPRESSIONFORMAT )
708 if( HIWORD( wParam ) == CBN_SELCHANGE )
710 int SelectedItem = SendDlgItemMessage( hwndDlg, IDC_COMPRESSIONFORMAT, CB_GETCURSEL, 0, 0 );
711 gCompressionMethodIndex = SendDlgItemMessage( hwndDlg, IDC_COMPRESSIONFORMAT, CB_GETITEMDATA, SelectedItem, 0 );
712 EnableControls( hwndDlg );
715 return 0;
717 case WM_HSCROLL:
718 // We get this from the track bars
719 if( (HWND)lParam == GetDlgItem( hwndDlg, IDC_TILEMAX ) )
721 gTileMaxIndex = SendDlgItemMessage( hwndDlg, IDC_TILEMAX, TBM_GETPOS, 0, 0 );
723 if( gTileMaxIndex < gTileMinIndex )
725 gTileMinIndex = gTileMaxIndex;
726 SendDlgItemMessage( hwndDlg, IDC_TILEMIN, TBM_SETPOS, TRUE, gTileMinIndex );
729 UpdateFragmentData( hwndDlg );
731 else
733 gTileMinIndex = SendDlgItemMessage( hwndDlg, IDC_TILEMIN, TBM_GETPOS, 0, 0 );
735 if( gTileMaxIndex < gTileMinIndex )
737 gTileMaxIndex = gTileMinIndex;
738 SendDlgItemMessage( hwndDlg, IDC_TILEMAX, TBM_SETPOS, TRUE, gTileMaxIndex );
741 UpdateFragmentData( hwndDlg );
744 return 0;
746 default:
747 return 0;