Initial commit of Command & Conquer Generals and Command & Conquer Generals Zero Hour source code.

This commit is contained in:
LFeenanEA 2025-02-27 17:34:39 +00:00
parent 2e338c00cb
commit 3d0ee53a05
No known key found for this signature in database
GPG key ID: C6EBE8C2EA08F7E0
6072 changed files with 2283311 additions and 0 deletions

View file

@ -0,0 +1,107 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// FILE: ImageInfo.cpp ////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
//
// Westwood Studios Pacific.
//
// Confidential Information
// Copyright (C) 2001 - All Rights Reserved
//
//-----------------------------------------------------------------------------
//
// Project: ImagePacker
//
// File name: ImageInfo.cpp
//
// Created: Colin Day, August 2001
//
// Desc: Image information struct for images to pack into
// the texture pages
//
//-----------------------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////
// SYSTEM INCLUDES ////////////////////////////////////////////////////////////
#include <stdlib.h>
// USER INCLUDES //////////////////////////////////////////////////////////////
#include "ImageInfo.h"
// DEFINES ////////////////////////////////////////////////////////////////////
// PRIVATE TYPES //////////////////////////////////////////////////////////////
// PRIVATE DATA ///////////////////////////////////////////////////////////////
// PUBLIC DATA ////////////////////////////////////////////////////////////////
// PRIVATE PROTOTYPES /////////////////////////////////////////////////////////
// PRIVATE FUNCTIONS //////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// PUBLIC FUNCTIONS ///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// ImageInfo::ImageInfo =======================================================
/** */
//=============================================================================
ImageInfo::ImageInfo( void )
{
m_area = 0;
m_colorDepth = 0;
m_size.x = 0;
m_size.y = 0;
m_path = NULL;
m_filenameOnly = NULL;
m_filenameOnlyNoExt = NULL;
m_status = UNPACKED;
m_page = NULL;
m_nextPageImage = NULL;
m_prevPageImage = NULL;
m_pagePos.lo.x = 0;
m_pagePos.lo.y = 0;
m_pagePos.hi.x = 0;
m_pagePos.hi.y = 0;
m_fitBits = 0;
m_gutterUsed.x = 0;
m_gutterUsed.y = 0;
} // end ImageInfo
// ImageInfo::~ImageInfo ======================================================
/** */
//=============================================================================
ImageInfo::~ImageInfo( void )
{
// delete path name
if( m_path )
delete [] m_path;
if( m_filenameOnly )
delete [] m_filenameOnly;
if( m_filenameOnlyNoExt )
delete [] m_filenameOnlyNoExt;
} // end ~ImageInfo

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,124 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// FILE: WinMain.cpp //////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
//
// Westwood Studios Pacific.
//
// Confidential Information
// Copyright (C) 2001 - All Rights Reserved
//
//-----------------------------------------------------------------------------
//
// Project: ImagePacker
//
// File name: WinMain.cpp
//
// Created: Colin Day, August 2001
//
// Desc: Application entry point for the image packer tool
//
//-----------------------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////
// SYSTEM INCLUDES ////////////////////////////////////////////////////////////
#include <windows.h>
#include <stdlib.h>
// USER INCLUDES //////////////////////////////////////////////////////////////
#include "Lib/BaseType.h"
#include "Common/GameMemory.h"
#include "Common/Debug.h"
#include "ImagePacker.h"
#include "Resource.h"
#include "WindowProc.h"
// DEFINES ////////////////////////////////////////////////////////////////////
// PRIVATE TYPES //////////////////////////////////////////////////////////////
// PRIVATE DATA ///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// PUBLIC DATA ////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
HINSTANCE ApplicationHInstance = NULL; ///< our application instance
/// just to satisfy the game libraries we link to
HWND ApplicationHWnd = NULL;
const Char *g_strFile = "data\\Generals.str";
const Char *g_csfFile = "data\\%s\\Generals.csf";
// PRIVATE PROTOTYPES /////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// PRIVATE FUNCTIONS //////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// PUBLIC FUNCTIONS ///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// WinMain ====================================================================
/** Application entry point */
//=============================================================================
Int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, Int nCmdShow )
{
// start the log
DEBUG_INIT(DEBUG_FLAGS_DEFAULT);
initMemoryManager();
// save application instance
ApplicationHInstance = hInstance;
// allocate a new image packer system
TheImagePacker = new ImagePacker;
if( TheImagePacker == NULL )
return 0;
// initialize the system
if( TheImagePacker->init() == FALSE )
{
delete TheImagePacker;
TheImagePacker = NULL;
return 0;
} // end if
// load the dialog box
DialogBox( hInstance, (LPCTSTR)IMAGE_PACKER_DIALOG,
NULL, (DLGPROC)ImagePackerProc );
// delete the image packer
delete TheImagePacker;
TheImagePacker = NULL;
// close the log
shutdownMemoryManager();
DEBUG_SHUTDOWN();
// all done
return 0;
} // end WinMain

View file

@ -0,0 +1,387 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// FILE: DirectorySelect.cpp //////////////////////////////////////////////////
//-----------------------------------------------------------------------------
//
// Westwood Studios Pacific.
//
// Confidential Information
// Copyright (C) 2001 - All Rights Reserved
//
//-----------------------------------------------------------------------------
//
// Project: ImagePacker
//
// File name: DirectorySelect.cpp
//
// Created: Colin Day, August 2001
//
// Desc: Directory selection dialog
//
//-----------------------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////
// SYSTEM INCLUDES ////////////////////////////////////////////////////////////
#include <windows.h>
#include <stdio.h>
// USER INCLUDES //////////////////////////////////////////////////////////////
#include "ImagePacker.h"
#include "Resource.h"
// DEFINES ////////////////////////////////////////////////////////////////////
// PRIVATE TYPES //////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// PRIVATE DATA ///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
static char startDir[ _MAX_PATH ];
// PUBLIC DATA ////////////////////////////////////////////////////////////////
// PRIVATE PROTOTYPES /////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// PRIVATE FUNCTIONS //////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// selectDrive ================================================================
/** Based on the drive of the current working directory, select the
* drive item in the COMBO_DRIVE combo box matching the current
* drive letter */
//=============================================================================
static void selectDrive( HWND dialog )
{
char currDir[ _MAX_PATH ];
char drive;
// get current directory
GetCurrentDirectory( _MAX_PATH, currDir );
// drive letter is the first character
drive = currDir[ 0 ];
// construct string to match in the combo
char string[ 32 ];
sprintf( string, "[-%c-]", drive );
// select the string in the combo
Int index;
index = SendDlgItemMessage( dialog, COMBO_DRIVE,
CB_FINDSTRINGEXACT, -1, (LPARAM)string );
if( index != CB_ERR )
SendDlgItemMessage( dialog, COMBO_DRIVE, CB_SETCURSEL, index, 0 );
} // end selectDrive
///////////////////////////////////////////////////////////////////////////////
// PUBLIC FUNCTIONS ///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// DirectorySelectProc ========================================================
/** Directory selection dialog */
//=============================================================================
BOOL CALLBACK DirectorySelectProc( HWND hWndDialog, UINT message,
WPARAM wParam, LPARAM lParam )
{
static char buffer[ _MAX_PATH ];
switch( message )
{
// ------------------------------------------------------------------------
case WM_INITDIALOG:
{
// save our current directory as we start up
GetCurrentDirectory( _MAX_PATH, startDir );
// set the extents for the horizontal scroll bar in the listbox
SendDlgItemMessage( hWndDialog, LIST_DIR,
LB_SETHORIZONTALEXTENT, 1280, 0 );
// load the listbox with directory items
SendDlgItemMessage( hWndDialog, LIST_DIR,
LB_DIR,
DDL_DIRECTORY | DDL_EXCLUSIVE,
(LPARAM)"*.*" );
// set the current directory in the top label
GetCurrentDirectory( _MAX_PATH, buffer );
if( buffer[ strlen( buffer ) - 1 ] != '\\' )
strcat( buffer, "\\" );
SetDlgItemText( hWndDialog, STATIC_CURRENT_DIR, buffer );
// load the drive box
SendDlgItemMessage( hWndDialog, COMBO_DRIVE,
CB_DIR,
DDL_DRIVES | DDL_EXCLUSIVE,
(LPARAM)"*.*" );
// select the right drive in the drive combo box
selectDrive( hWndDialog );
return TRUE;
} // end init
// ------------------------------------------------------------------------
case WM_COMMAND:
{
Int notifyCode = HIWORD( wParam );
Int controlID = LOWORD( wParam );
// HWND hWndControl = (HWND)lParam;
switch( controlID )
{
// --------------------------------------------------------------------
case BUTTON_ADD:
{
Int count;
char text[ _MAX_PATH ];
char toAdd[ _MAX_PATH ];
// get number of items in listbox
count = SendDlgItemMessage( hWndDialog, LIST_DIR, LB_GETCOUNT, 0, 0 );
// for each selected item add that directory
for( Int i = 0; i < count; i++ )
{
// is this item selected
if( SendDlgItemMessage( hWndDialog, LIST_DIR, LB_GETSEL, i, 0 ) > 0 )
{
// get the text
SendDlgItemMessage( hWndDialog, LIST_DIR, LB_GETTEXT,
i, (LPARAM)text );
// remove the brackets on the text
Int j, len = strlen( text );
for( j = 0; j < len - 1; j++ )
text[ j ] = text[ j + 1 ];
text[ len - 2 ] = '\0';
// ignore the ".." directory
if( strcmp( text, ".." ) == 0 )
continue;
//
// construct directory to add, make sure we have a '\' on the
// end cause we assume that in the image file name code
//
sprintf( toAdd, "%s%s\\", buffer, text );
// do not add directory if it's already in the listbox
if( SendDlgItemMessage( TheImagePacker->getWindowHandle(),
LIST_FOLDERS,
LB_FINDSTRINGEXACT, -1, (LPARAM)toAdd ) != LB_ERR )
{
char message[ _MAX_PATH + 32 ];
sprintf( message, "Ignoring folder '%s', already in list.", toAdd );
MessageBox( NULL, message, "Folder Already In List",
MB_OK | MB_ICONINFORMATION );
continue;
} // end if
// add path to the listbox
SendDlgItemMessage( TheImagePacker->getWindowHandle(),
LIST_FOLDERS,
LB_INSERTSTRING, -1, (LPARAM)toAdd );
} // end if
} // end if
SetCurrentDirectory( startDir );
EndDialog( hWndDialog, TRUE );
break;
} // end proceed
// --------------------------------------------------------------------
case BUTTON_CANCEL:
{
SetCurrentDirectory( startDir );
EndDialog( hWndDialog, FALSE );
break;
} // end cancel
// --------------------------------------------------------------------
case COMBO_DRIVE:
{
if( notifyCode == CBN_SELCHANGE )
{
Int selected;
// get selected index
selected = SendDlgItemMessage( hWndDialog, COMBO_DRIVE,
CB_GETCURSEL, 0, 0 );
if( selected != CB_ERR )
{
char string[ 32 ];
SendDlgItemMessage( hWndDialog, COMBO_DRIVE,
CB_GETLBTEXT, selected, (LPARAM)string );
//
// construct a drive letter and colon from the combo
// box strign [-x-]
//
string[ 0 ] = string[ 2 ]; // the drive letter in the form of "[-x-]"
string[ 1 ] = ':';
string[ 2 ] = '\0';
// switch to that drive
SetCurrentDirectory( string );
// construct new direcotry name and update status text
GetCurrentDirectory( _MAX_PATH, buffer );
if( buffer[ strlen( buffer ) - 1 ] != '\\' )
strcat( buffer, "\\" );
SetDlgItemText( hWndDialog, STATIC_CURRENT_DIR, buffer );
EnableWindow( GetDlgItem( hWndDialog, BUTTON_ADD ), FALSE );
// reset the content of the listbox and reload
SendDlgItemMessage( hWndDialog, LIST_DIR,
LB_RESETCONTENT, 0, 0 );
SendDlgItemMessage( hWndDialog, LIST_DIR,
LB_DIR,
DDL_DIRECTORY | DDL_EXCLUSIVE,
(LPARAM)"*.*" );
} // end if
} // end if
break;
} // end drive
// --------------------------------------------------------------------
case LIST_DIR:
{
if( notifyCode == LBN_SELCHANGE )
{
Int selCount;
Bool enable;
// get selected count
selCount = SendDlgItemMessage( hWndDialog, LIST_DIR,
LB_GETSELCOUNT, 0, 0 );
// if we have selected items, enable the add button
if( selCount > 0 )
{
//
// if the selected item is only the ".." directory we won't
// enable it, we know that _IF_ ".." is present it is at the
// top zero index position
//
enable = TRUE;
Int index = 0;
if( selCount == 1 &&
SendDlgItemMessage( hWndDialog, LIST_DIR,
LB_GETSEL, index, 0 ) > 0 )
{
char text[ _MAX_PATH ];
SendDlgItemMessage( hWndDialog, LIST_DIR, LB_GETTEXT,
index, (LPARAM)text );
if( strcmp( text, "[..]" ) == 0 )
enable = FALSE;
} // end if
} // end if
else
enable = FALSE;
// do the enable
EnableWindow( GetDlgItem( hWndDialog, BUTTON_ADD ), enable );
} // end if
if( notifyCode == LBN_DBLCLK )
{
Int selected;
char text[ _MAX_PATH ];
// get currently selected item
selected = SendDlgItemMessage( hWndDialog, LIST_DIR,
LB_GETCURSEL, 0, 0 );
// get text of selected item
SendDlgItemMessage( hWndDialog, LIST_DIR, LB_GETTEXT,
selected, (LPARAM)text );
// strip the backets off the directory listing
Int len = strlen( text );
for( Int i = 0; i < len - 1; i++ )
text[ i ] = text[ i + 1 ];
text[ len - 2 ] = '\0';
// go into that directory
SetCurrentDirectory( text );
// construct new direcotry name and update status text
GetCurrentDirectory( _MAX_PATH, buffer );
if( buffer[ strlen( buffer ) - 1 ] != '\\' )
strcat( buffer, "\\" );
SetDlgItemText( hWndDialog, STATIC_CURRENT_DIR, buffer );
EnableWindow( GetDlgItem( hWndDialog, BUTTON_ADD ), FALSE );
// reset the content of the listbox and reload
SendDlgItemMessage( hWndDialog, LIST_DIR,
LB_RESETCONTENT, 0, 0 );
SendDlgItemMessage( hWndDialog, LIST_DIR,
LB_DIR,
DDL_DIRECTORY | DDL_EXCLUSIVE,
(LPARAM)"*.*" );
} // end if
break;
} // end list command
} // end switch
break;
} // end command
} // end switch message
return 0;
} // end DirectorySelectProc

View file

@ -0,0 +1,175 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// FILE: ImageErrorProc.cpp ///////////////////////////////////////////////////
//-----------------------------------------------------------------------------
//
// Westwood Studios Pacific.
//
// Confidential Information
// Copyright (C) 2001 - All Rights Reserved
//
//-----------------------------------------------------------------------------
//
// Project: ImagePacker
//
// File name: ImageErrorProc.cpp
//
// Created: Colin Day, August 2001
//
// Desc: Window procedure for the error dialog
//
//-----------------------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// SYSTEM INCLUDES ////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <stdio.h>
// USER INCLUDES //////////////////////////////////////////////////////////////
#include "ImagePacker.h"
#include "Resource.h"
// DEFINES ////////////////////////////////////////////////////////////////////
// PRIVATE TYPES //////////////////////////////////////////////////////////////
// PRIVATE DATA ///////////////////////////////////////////////////////////////
// PUBLIC DATA ////////////////////////////////////////////////////////////////
// PRIVATE PROTOTYPES /////////////////////////////////////////////////////////
// PRIVATE FUNCTIONS //////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// PUBLIC FUNCTIONS ///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// ImageErrorProc =============================================================
/** Dialog proc for the error window */
//=============================================================================
BOOL CALLBACK ImageErrorProc( HWND hWndDialog, UINT message,
WPARAM wParam, LPARAM lParam )
{
switch( message )
{
// ------------------------------------------------------------------------
case WM_INITDIALOG:
{
//
// load the listbox with images that could not be processed
// and the reasons for it
//
// sanity
if( TheImagePacker == NULL )
return TRUE;
// go through all images
Int i, count;
HWND list = GetDlgItem( hWndDialog, LIST_IMAGES );
char buffer[ _MAX_PATH + 256 ];
char reason[ 32 ];
ImageInfo *image;
count = TheImagePacker->getImageCount();
for( i = 0; i < count; i++ )
{
// get image
image = TheImagePacker->getImage( i );
// sanity
if( image == NULL )
continue;
// if image can't be processed find out why
if( BitTest( image->m_status, ImageInfo::CANTPROCESS ) )
{
if( BitTest( image->m_status, ImageInfo::TOOBIG ) )
sprintf( reason, "Too Big" );
else if( BitTest( image->m_status, ImageInfo::INVALIDCOLORDEPTH ) )
sprintf( reason, "Unsupported Color Depth" );
else
sprintf( reason, "Unknown Reason" );
sprintf( buffer, "%s: (%dx%dx%d) %s",
reason, image->m_size.x, image->m_size.y, image->m_colorDepth,
image->m_path );
SendMessage( list, LB_INSERTSTRING, -1, (LPARAM)buffer );
} // end if
} // end for i
// set the extents for the horizontal scroll bar in the listbox
SendMessage( list, LB_SETHORIZONTALEXTENT, 1280, 0 );
return TRUE;
} // end init
// ------------------------------------------------------------------------
case WM_COMMAND:
{
Int controlID = LOWORD( wParam );
// Int notifyCode = HIWORD( wParam );
// HWND hWndControl = (HWND)lParam;
switch( controlID )
{
// --------------------------------------------------------------------
case BUTTON_PROCEED:
{
EndDialog( hWndDialog, TRUE );
break;
} // end proceed
// --------------------------------------------------------------------
case BUTTON_CANCEL:
{
EndDialog( hWndDialog, FALSE );
break;
} // end cancel
} // end switch
break;
} // end command
} // end switch message
return 0;
} // end ImageErrorProc

View file

@ -0,0 +1,407 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// FILE: ImagePackerProc.cpp //////////////////////////////////////////////////
//-----------------------------------------------------------------------------
//
// Westwood Studios Pacific.
//
// Confidential Information
// Copyright (C) 2001 - All Rights Reserved
//
//-----------------------------------------------------------------------------
//
// Project: ImagePacker
//
// File name: ImagePackerProc.cpp
//
// Created: Colin Day, August 2001
//
// Desc: Window procedure for the image packer app
//
//-----------------------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////
// SYSTEM INCLUDES ////////////////////////////////////////////////////////////
#include <windows.h>
#include <io.h>
// USER INCLUDES //////////////////////////////////////////////////////////////
#include "ImagePacker.h"
#include "Resource.h"
#include "WindowProc.h"
#include "WinMain.h"
// DEFINES ////////////////////////////////////////////////////////////////////
// PRIVATE TYPES //////////////////////////////////////////////////////////////
// PRIVATE DATA ///////////////////////////////////////////////////////////////
// PUBLIC DATA ////////////////////////////////////////////////////////////////
// PRIVATE PROTOTYPES /////////////////////////////////////////////////////////
// PRIVATE FUNCTIONS //////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// PUBLIC FUNCTIONS ///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// ImagePackerProc ============================================================
/** Dialog procedure for the program flow */
//=============================================================================
BOOL CALLBACK ImagePackerProc( HWND hWndDialog, UINT message,
WPARAM wParam, LPARAM lParam )
{
switch( message )
{
// ------------------------------------------------------------------------
case WM_INITDIALOG:
{
// we must have our program interface to continue
if( TheImagePacker == NULL )
{
MessageBox( NULL, "Internal Error, 'TheImagePacker' not initialized",
"Internal Error", MB_OK );
EndDialog( hWndDialog, FALSE );
} // end if
// save our window handlw
TheImagePacker->setWindowHandle( hWndDialog );
// get size of the screen
Int x, y;
x = GetSystemMetrics( SM_CXFULLSCREEN );
y = GetSystemMetrics( SM_CYFULLSCREEN );
// get size of our dialog
RECT rect;
ICoord2D size;
GetWindowRect( hWndDialog, &rect );
size.x = rect.right - rect.left;
size.y = rect.bottom - rect.top;
// center dialog on screen
MoveWindow( hWndDialog,
(x / 2) - (size.x / 2),
(y / 2) - (size.y / 2),
size.x,
size.y,
TRUE );
// setup the status message
TheImagePacker->statusMessage( "Select options and click 'Start'." );
// set gutter size
SetDlgItemInt( hWndDialog, EDIT_GUTTER, TheImagePacker->getGutter(), FALSE );
// set alpha check
if( TheImagePacker->getOutputAlpha() )
CheckDlgButton( hWndDialog, CHECK_ALPHA, BST_CHECKED );
// set the check for preview using the actual texture
if( TheImagePacker->getUseTexturePreview() )
CheckDlgButton( hWndDialog, CHECK_BITMAP_PREVIEW, BST_CHECKED );
// set the check for creating INI definition
if( TheImagePacker->createINIFile() )
CheckDlgButton( hWndDialog, CHECK_INI, BST_CHECKED );
// check the resursive checkbox by default
CheckDlgButton( hWndDialog, CHECK_USE_SUB_FOLDERS, BST_CHECKED );
// check the default image size radio button
CheckDlgButton( hWndDialog, RADIO_512X512, BST_CHECKED );
// fill out a default target filename
SetDlgItemText( hWndDialog, EDIT_FILENAME, "NewImage" );
// limit the size if the filename edit box
SendDlgItemMessage( hWndDialog, EDIT_FILENAME,
EM_LIMITTEXT, MAX_OUTPUT_FILE_LEN, 0 );
// set options for compressed textures
if( TheImagePacker->getCompressTextures() )
CheckDlgButton( hWndDialog, CHECK_COMPRESS, BST_CHECKED );
// set option checks for gap method
UnsignedInt gapOptions = TheImagePacker->getGapMethod();
if( BitTest( gapOptions, ImagePacker::GAP_METHOD_EXTEND_RGB ) )
CheckDlgButton( hWndDialog, CHECK_GAP_EXTEND_RGB, BST_CHECKED );
if( BitTest( gapOptions, ImagePacker::GAP_METHOD_GUTTER ) )
CheckDlgButton( hWndDialog, CHECK_GAP_GUTTER, BST_CHECKED );
return TRUE;
} // end init dialog
// ------------------------------------------------------------------------
case WM_COMMAND:
{
Int notifyCode = HIWORD( wParam );
Int controlID = LOWORD( wParam );
// HWND hWndControl = (HWND)lParam;
switch( controlID )
{
// --------------------------------------------------------------------
case BUTTON_PREVIOUS:
{
Int page = TheImagePacker->getTargetPreviewPage();
// target preview page back one
if( page > 1 )
{
page--;
TheImagePacker->setTargetPreviewPage( page );
UpdatePreviewWindow();
} // end if
break;
} // end previous
// --------------------------------------------------------------------
case BUTTON_NEXT:
{
UnsignedInt page = TheImagePacker->getTargetPreviewPage();
if( page < TheImagePacker->getPageCount() )
{
page++;
TheImagePacker->setTargetPreviewPage( page );
UpdatePreviewWindow();
} // end if
break;
} // end next
// --------------------------------------------------------------------
case CHECK_BITMAP_PREVIEW:
{
Bool useBitmap;
if( IsDlgButtonChecked( hWndDialog, controlID ) == BST_CHECKED )
useBitmap = TRUE;
else
useBitmap = FALSE;
TheImagePacker->setUseTexturePreview( useBitmap );
UpdatePreviewWindow();
break;
} // end preview using image
// --------------------------------------------------------------------
case CHECK_GAP_GUTTER:
{
Bool enable = FALSE;
if( IsDlgButtonChecked( hWndDialog, controlID ) == BST_CHECKED )
enable = TRUE;
EnableWindow( GetDlgItem( hWndDialog, STATIC_GAP_INFO ), enable );
EnableWindow( GetDlgItem( hWndDialog, EDIT_GUTTER ), enable );
break;
} // end transparent gutter
// --------------------------------------------------------------------
case BUTTON_PREVIEW:
{
HWND preview = TheImagePacker->getPreviewWindow();
if( preview )
{
// delete test display window
DestroyWindow( preview );
TheImagePacker->setPreviewWindow( NULL );
SetDlgItemText( hWndDialog, BUTTON_PREVIEW, "Open Preview" );
} // end if
else
{
HWND preview = MakePreviewDisplay();
if( preview )
{
TheImagePacker->setPreviewWindow( preview );
UpdatePreviewWindow();
SetDlgItemText( hWndDialog, BUTTON_PREVIEW, "Close Preview" );
} // end if
} // end else
break;
} // end test
// --------------------------------------------------------------------
case BUTTON_ADD_FOLDER:
{
// bring up the add directory dialog
DialogBox( ApplicationHInstance,
(LPCTSTR)DIRECTORY_SELECT_DIALOG,
TheImagePacker->getWindowHandle(),
(DLGPROC)DirectorySelectProc );
break;
} // end add folder
// --------------------------------------------------------------------
case BUTTON_REMOVE_FOLDER:
{
HWND folderList;
// get the directory listbox
folderList = GetDlgItem( hWndDialog, LIST_FOLDERS );
if( folderList == NULL )
break;;
// get the selected item in the folder listbox
Int selCount;
selCount = SendMessage( folderList, LB_GETSELCOUNT, 0, 0 );
if( selCount == 0 )
{
MessageBox( NULL, "You must first select a folder to remove it",
"Select Folder First", MB_OK | MB_ICONINFORMATION );
break;
} // end if
//
// start at the end of the listbox, delete any items that
// are selected
//
Int itemCount = SendMessage( folderList, LB_GETCOUNT, 0, 0 );
for( Int i = itemCount - 1; i >= 0; i-- )
if( SendMessage( folderList, LB_GETSEL, i, 0 ) > 0 )
SendMessage( folderList, LB_DELETESTRING, i, 0 );
break;
} // end remove folder
// --------------------------------------------------------------------
case RADIO_128X128:
case RADIO_256X256:
case RADIO_512X512:
case RADIO_TARGET_OTHER:
{
Bool enable;
//
// if this is the other button, enable the first edit box for
// user size, if not, disable that section of the UI
//
enable = IsDlgButtonChecked( hWndDialog, RADIO_TARGET_OTHER );
EnableWindow( GetDlgItem( hWndDialog, EDIT_WIDTH ), enable );
EnableWindow( GetDlgItem( hWndDialog, STATIC_X ), enable );
break;
} // end target image size radio buttons
// --------------------------------------------------------------------
case EDIT_WIDTH:
{
switch( notifyCode )
{
// ----------------------------------------------------------------
case EN_UPDATE:
{
char buffer[ 32 ];
//
// the text of the width has changed, since our requirements
// are that the image must be square automatically update
// the height box as well
//
GetDlgItemText( hWndDialog, EDIT_WIDTH, buffer, 32 );
SetDlgItemText( hWndDialog, EDIT_HEIGHT, buffer );
break;
} // end update
} // end switch
break;
} // end user defined width
// --------------------------------------------------------------------
case BUTTON_START:
{
Bool success;
// get all the options from the dialog into the image packer
success = TheImagePacker->getSettingsFromDialog( hWndDialog );
// run the packer if nothing went wrong
if( success )
TheImagePacker->process();
break;
} // end execute
// --------------------------------------------------------------------
case BUTTON_EXIT:
{
// quit the program
EndDialog( hWndDialog, TRUE );
break;
} // end exit
} // end switch
return 0;
} // end command
} // end switch
return 0;
} // end ImagePackerProc

View file

@ -0,0 +1,163 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// FILE: PageErrorProc.cpp ////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
//
// Westwood Studios Pacific.
//
// Confidential Information
// Copyright (C) 2001 - All Rights Reserved
//
//-----------------------------------------------------------------------------
//
// Project: ImagePacker
//
// File name: PageErrorProc.cpp
//
// Created: Colin Day, August 2001
//
// Desc: Window procedure for the error dialog for texture pages
//
//-----------------------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// SYSTEM INCLUDES ////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <stdio.h>
// USER INCLUDES //////////////////////////////////////////////////////////////
#include "ImagePacker.h"
#include "Resource.h"
// DEFINES ////////////////////////////////////////////////////////////////////
// PRIVATE TYPES //////////////////////////////////////////////////////////////
// PRIVATE DATA ///////////////////////////////////////////////////////////////
// PUBLIC DATA ////////////////////////////////////////////////////////////////
// PRIVATE PROTOTYPES /////////////////////////////////////////////////////////
// PRIVATE FUNCTIONS //////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// PUBLIC FUNCTIONS ///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// PageErrorProc ==============================================================
/** Dialog proc for the error window */
//=============================================================================
BOOL CALLBACK PageErrorProc( HWND hWndDialog, UINT message,
WPARAM wParam, LPARAM lParam )
{
switch( message )
{
// ------------------------------------------------------------------------
case WM_INITDIALOG:
{
//
// load the listbox with pages that could not be processed
// and the reasons for it
//
// sanity
if( TheImagePacker == NULL )
return TRUE;
// go through all pages
TexturePage *page;
HWND list = GetDlgItem( hWndDialog, LIST_PAGES );
char buffer[ _MAX_PATH + 256 ];
char reason[ 32 ];
for( page = TheImagePacker->getFirstTexturePage();
page;
page = page->m_next )
{
// if image can't be processed find out why
if( BitTest( page->m_status, TexturePage::PAGE_ERROR ) )
{
if( BitTest( page->m_status, TexturePage::CANT_ALLOCATE_PACKED_IMAGE ) )
sprintf( reason, "Can't allocate image memory" );
else if( BitTest( page->m_status, TexturePage::CANT_ADD_IMAGE_DATA ) )
sprintf( reason, "Can't add image(s) data" );
else if( BitTest( page->m_status, TexturePage::NO_TEXTURE_DATA ) )
sprintf( reason, "No texture data to write" );
else if( BitTest( page->m_status, TexturePage::ERROR_DURING_SAVE ) )
sprintf( reason, "Error writing texture file" );
else
sprintf( reason, "Unknown Reason" );
sprintf( buffer, "%s: (%dx%d) %s%d",
reason, page->getWidth(), page->getHeight(),
TheImagePacker->getOutputFile(), page->getID() );
SendMessage( list, LB_INSERTSTRING, -1, (LPARAM)buffer );
} // end if
} // end for i
// set the extents for the horizontal scroll bar in the listbox
SendMessage( list, LB_SETHORIZONTALEXTENT, 1280, 0 );
return TRUE;
} // end init
// ------------------------------------------------------------------------
case WM_COMMAND:
{
Int controlID = LOWORD( wParam );
// Int notifyCode = HIWORD( wParam );
// HWND hWndControl = (HWND)lParam;
switch( controlID )
{
// --------------------------------------------------------------------
case IDOK:
{
EndDialog( hWndDialog, TRUE );
break;
} // end proceed
} // end switch
break;
} // end command
} // end switch message
return 0;
} // end PageErrorProc

View file

@ -0,0 +1,267 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// FILE: PreviewProc.cpp //////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
//
// Westwood Studios Pacific.
//
// Confidential Information
// Copyright (C) 2001 - All Rights Reserved
//
//-----------------------------------------------------------------------------
//
// Project: ImagePacker
//
// File name: PreviewProc.cpp
//
// Created: Colin Day, August 2001
//
// Desc: Window procedure for the preview window
//
//-----------------------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////
// SYSTEM INCLUDES ////////////////////////////////////////////////////////////
#include <windows.h>
#include <stdio.h>
// USER INCLUDES //////////////////////////////////////////////////////////////
#include "ImagePacker.h"
#include "WinMain.h"
///////////////////////////////////////////////////////////////////////////////
// DEFINES ////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
#define PREVIEW_STYLE WS_CAPTION
// PRIVATE TYPES //////////////////////////////////////////////////////////////
// PRIVATE DATA ///////////////////////////////////////////////////////////////
// PUBLIC DATA ////////////////////////////////////////////////////////////////
// PRIVATE PROTOTYPES /////////////////////////////////////////////////////////
// PRIVATE FUNCTIONS //////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// PUBLIC FUNCTIONS ///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// PreviewProc ================================================================
/** */
//=============================================================================
LRESULT CALLBACK PreviewProc( HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam )
{
switch( message )
{
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc;
HBRUSH whiteBrush = (HBRUSH)GetStockObject( WHITE_BRUSH );
hdc = BeginPaint(hWnd, &ps);
SelectObject( hdc, GetStockObject( WHITE_PEN ) );
// find the target texture page
TexturePage *page;
for( page = TheImagePacker->getFirstTexturePage();
page;
page = page->m_next )
{
// if this is not the target page, ignore it
if( page->getID() != TheImagePacker->getTargetPreviewPage() )
continue;
// draw image based on the generated texture or silhouette
if( TheImagePacker->getUseTexturePreview() )
{
Int x, y;
Byte r, g, b;
HPEN prevPen, pen;
for( y = 0; y < page->getHeight(); y++ )
{
for( x = 0; x < page->getWidth(); x++ )
{
// get the color here
page->getPixel( x, y, &r, &g, &b );
// create a new pen of the right color
pen = CreatePen( 1, 1, RGB( r, g, b, ) );
// select pen into hdc
prevPen = (HPEN)SelectObject( hdc, pen );
// draw ... what is the Win32 put pixel function???
MoveToEx( hdc, x, y, NULL );
LineTo( hdc, x + 1, y );
// put the old pen back
SelectObject( hdc, prevPen );
// delete the created pen
DeleteObject( pen );
} // end for x
} // end for y
} // end if
else
{
// go through all the images on this page
ImageInfo *image;
for( image = page->getFirstImage();
image;
image = image->m_nextPageImage )
{
RECT rect;
rect.left = image->m_pagePos.lo.x;
rect.top = image->m_pagePos.lo.y;
rect.right = image->m_pagePos.hi.x + 1; // FillRect not inclusive
rect.bottom = image->m_pagePos.hi.y + 1; // FillRect not inclusive
FillRect( hdc, &rect, whiteBrush );
} // end for image
} // end else
} // end for page
EndPaint( hWnd, &ps );
break;
} // end paint
} // end switch
return DefWindowProc( hWnd, message, wParam, lParam );
} // end PreviewProc
// MakePreviewDisplay =========================================================
/** */
//=============================================================================
HWND MakePreviewDisplay( void )
{
WNDCLASSEX wcex;
char *className = "PreviewDisplay";
HWND hWnd;
wcex.cbSize = sizeof( WNDCLASSEX );
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)PreviewProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = ApplicationHInstance;
wcex.hIcon = NULL;
wcex.hCursor = LoadCursor( NULL, IDC_ARROW );
wcex.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH );
wcex.lpszMenuName = NULL;
wcex.lpszClassName = className;
wcex.hIconSm = NULL;
RegisterClassEx( &wcex );
// create app window and keep handle
hWnd = CreateWindowEx( 0, // extended style
className, // window class name
"Preview", // window name
PREVIEW_STYLE, // window styles
30, // x position
30, // y position
TheImagePacker->getTargetWidth(),
TheImagePacker->getTargetHeight(),
NULL, // parent
NULL, // menu
ApplicationHInstance, // instance
NULL ); // creation data
if( hWnd == NULL )
return NULL;
// display the window
ShowWindow( hWnd, SW_SHOW );
return hWnd;
} // end MakePreviewDisplay
// UpdatePreviewWindow ========================================================
/** Update the preview window, if present */
//=============================================================================
void UpdatePreviewWindow( void )
{
HWND preview;
// sanity
if( TheImagePacker == NULL )
return;
// get preview window
preview = TheImagePacker->getPreviewWindow();
// if window not here don't bother
if( preview == NULL )
return;
// make the title
char title[ 256 ];
// construct title
sprintf( title, "Page #%d of %d",
TheImagePacker->getTargetPreviewPage(),
TheImagePacker->getPageCount() );
SetWindowText( preview, title );
// adjust the window rect so the client area is the target packed size
RECT clientRect;
POINT p;
p.x = 0;
p.y = 0;
ClientToScreen( preview, &p );
clientRect.left = p.x;
clientRect.right = clientRect.left + TheImagePacker->getTargetWidth();
clientRect.top = p.y;
clientRect.bottom = clientRect.top + TheImagePacker->getTargetHeight();
AdjustWindowRect( &clientRect, PREVIEW_STYLE, FALSE );
MoveWindow( preview,
clientRect.left,
clientRect.top,
clientRect.right - clientRect.left,
clientRect.bottom - clientRect.top,
TRUE );
// invalidate the client area for redraw
InvalidateRect( preview, NULL, TRUE );
} // end UpdatePreviewWindow