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,477 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project name : Buccaneer Bay *
* *
* File name : AlphaModifier.cpp *
* *
* Programmer : Mike Lytle *
* *
* Start date : 11/1/1999 *
* *
* Last update : 11/1/1999 *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "AlphaModifier.h"
enum Alpha_Messages
{
AM_NOTHING,
AM_UPDATE_DATA,
AM_INITIALIZE,
AM_BOX_CHECKED,
};
enum Dialog_Controls
{
DL_EDIT_VALUE,
DL_FIND_CHECK_BOX,
};
void AlphaModifierClass::ModifyObject(TimeValue t, ModContext &mc, ObjectState *os, INode *node)
{
if (!os->obj->IsSubClassOf(triObjectClassID))
{
return;
}
// Get a mesh from input object
TriObject *object = (TriObject*)os->obj;
Mesh *mesh = &object->mesh;
assert(mesh);
int numVert = mesh->getNumVerts();
int i = 0;
float *vdata = NULL;
// Get parameters from pblock
float sparam = 0.0f;
Interval valid = LocalValidity(t);
int pass = 1;
pblock->GetValue(DL_EDIT_VALUE, t, sparam, valid);
// If needed a control could be put into the dialog box to specify which
// pass to apply the alpha values to. At this time, it was decided to
// not implement this because of the complexity to the artist and the
// performance issues in game.
//pblock->GetValue(DL_EDIT_PASS, t, pass, valid);
// Start from 0.
pass -= 1;
assert(pass >= 0);
// Use a channel for each pass.
vdata = mesh->vertexFloat(ALPHA_VERTEX_CHANNEL + pass);
if (!vdata)
{
// Turn on the channel for vertex alpha support.
mesh->setVDataSupport(ALPHA_VERTEX_CHANNEL + pass);
vdata = mesh->vertexFloat(ALPHA_VERTEX_CHANNEL + pass);
assert(vdata);
for (i = 0; i < numVert; i++)
{
if (mesh->VertSel()[i])
{
vdata[i] = 0.0f;
}
}
}
// Tracks the state of the FIND check box.
int box_checked = 0;
if (Message == AM_UPDATE_DATA)
{
// The user has updated the dialog box, so update the data.
assert(vdata);
pblock->GetValue(DL_FIND_CHECK_BOX, t, box_checked, valid);
if (!box_checked)
{
for (i = 0; i < numVert; i++)
{
if (SelectedVertices[i])
{
vdata[i] = sparam;
}
}
}
}
if (Message == AM_BOX_CHECKED)
{
pblock->GetValue(DL_FIND_CHECK_BOX, t, box_checked, valid);
}
// The user is trying to find vertices with certain values.
if (box_checked)
{
assert(vdata);
// Find the vertices that have the user entered value.
for (i = 0; i < numVert; i++)
{
if (vdata[i] == sparam)
{
mesh->VertSel().Set(i);
SelectedVertices.Set(i);
}
else
{
mesh->VertSel().Clear(i);
SelectedVertices.Clear(i);
}
}
}
if (Message == AM_INITIALIZE)
{
assert(vdata);
SelectedVertices = mesh->VertSel();
for (i = 0; i < numVert; i++)
{
if (SelectedVertices[i])
{
// Set the value in the dialog box to the value of the
// first selected vertex.
pblock->SetValue(DL_EDIT_VALUE, t, vdata[i]);
break;
}
}
}
// Always select the vertices that have been saved by the modifier.
// This must be done because the mesh changes each time ModfiyObject is called.
for (i = 0; i < numVert; i++)
{
if (SelectedVertices[i])
{
mesh->VertSel().Set(i);
}
else
{
mesh->VertSel().Clear(i);
}
}
// Display the vertices.
mesh->SetDispFlag(DISP_SELVERTS | DISP_VERTTICKS);
mesh->selLevel = MESH_VERTEX;
object->UpdateValidity(SELECT_CHAN_NUM, object->ChannelValidity (t, SELECT_CHAN_NUM));
// Clear messages.
Message = AM_NOTHING;
}
/*===========================================================================*\
| NotifyInputChanged is called each time the input object is changed in some way
| We can find out how it was changed by checking partID and message
\*===========================================================================*/
void AlphaModifierClass::NotifyInputChanged(Interval changeInt, PartID partID, RefMessage message, ModContext *mc)
{
if( (partID&PART_TOPO) || (partID&PART_GEOM) || (partID&PART_SELECT) )
{
NotifyDependents(FOREVER, PART_OBJ, REFMSG_CHANGE);
}
}
/*===========================================================================*\
| Class Descriptor OSM
\*===========================================================================*/
class AlphaClassDesc : public ClassDesc2 {
public:
int IsPublic() { return TRUE; }
void * Create( BOOL loading ) { return new AlphaModifierClass; }
const TCHAR * ClassName() { return Get_String(IDS_ALPHA_MODIFIER_CLASS); }
SClass_ID SuperClassID() { return OSM_CLASS_ID; }
Class_ID ClassID() { return ALPHA_MODIFIER_CLASSID; }
const TCHAR* Category() { return _T(""); }
HINSTANCE HInstance() { return AppInstance; }
// Hardwired name, used by MAX Script as unique identifier
const TCHAR* InternalName() { return _T("AlphaMod"); }
};
static AlphaClassDesc AlphaCD;
ClassDesc* Get_Alpha_Desc() {return &AlphaCD;}
/*===========================================================================*\
| Paramblock2 Descriptor
\*===========================================================================*/
static ParamBlockDesc2 alpha_param_blk
(
//rollout
0, _T("AlphaModifierParams"), 0, &AlphaCD, P_AUTO_CONSTRUCT + P_AUTO_UI, 0,
IDD_ALPHA_MODIFIER, IDS_PARAMETERS, 0, 0, NULL,
// params
DL_EDIT_VALUE, _T("Custom Data Value"), TYPE_FLOAT, P_ANIMATABLE, IDS_ALPHA_MODIFIER_CLASS,
p_default, 0.0f,
p_range, 0.0f, 100.0f,
p_ui, TYPE_SPINNER, EDITTYPE_FLOAT, IDC_ALPHA_EDIT, IDC_ALPHA_SPIN, 1.0f,
end,
DL_FIND_CHECK_BOX, _T("1 Custom Data Value"), TYPE_BOOL, 0, IDS_ALPHA_MODIFIER_CLASS,
p_default, FALSE,
p_ui, TYPE_SINGLECHEKBOX, IDC_ALPHA_CHECKBOX,
p_enabled, TRUE,
end,
/*
DL_EDIT_PASS, _T("2 Custom Data Value"), TYPE_INT, P_ANIMATABLE, IDS_ALPHA_MODIFIER_CLASS,
p_default, 1,
p_range, 1, 4,
p_ui, TYPE_SPINNER, EDITTYPE_INT, IDC_ALPHA_EDIT2, IDC_ALPHA_SPIN2, 1.0,
end,
*/
end
);
/*===========================================================================*\
| Basic implementation of a dialog handler
\*===========================================================================*/
BOOL AlphaModDlgProc::DlgProc(TimeValue t, IParamMap2 *map, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
int id = LOWORD(wParam);
int code = HIWORD(wParam);
switch (msg)
{
case WM_INITDIALOG:
AlphaModifier->Message = AM_INITIALIZE;
break;
case WM_DESTROY:
break;
case WM_COMMAND:
switch (code)
{
case EN_UPDATE:
break;
case EN_SETFOCUS:
break;
case EN_KILLFOCUS:
break;
case EN_CHANGE:
break;
}
if (id == IDC_ALPHA_EDIT)
{
AlphaModifier->Message = AM_UPDATE_DATA;
}
if (id == IDC_ALPHA_CHECKBOX)
{
AlphaModifier->Message = AM_BOX_CHECKED;
}
break;
case WM_NOTIFY:
if (id == IDC_ALPHA_EDIT)
{
AlphaModifier->Message = AM_UPDATE_DATA;
}
break;
default:
break;
}
return FALSE;
}
/*===========================================================================*\
| Constructor
| Ask the ClassDesc2 to make the AUTO_CONSTRUCT paramblocks and wire them in
\*===========================================================================*/
AlphaModifierClass::AlphaModifierClass()
{
AlphaCD.MakeAutoParamBlocks(this);
assert(pblock);
Message = 0;
}
/*===========================================================================*\
| Invalidate our UI (or the recently changed parameter)
\*===========================================================================*/
void AlphaModifierClass::InvalidateUI()
{
alpha_param_blk.InvalidateUI(pblock->LastNotifyParamID());
}
/*===========================================================================*\
| Open and Close dialog UIs
| We ask the ClassDesc2 to handle Beginning and Ending EditParams for us
\*===========================================================================*/
void AlphaModifierClass::BeginEditParams( IObjParam *ip, ULONG flags,Animatable *prev )
{
AlphaCD.BeginEditParams(ip, this, flags, prev);
alpha_param_blk.SetUserDlgProc(new AlphaModDlgProc(this));
}
void AlphaModifierClass::EndEditParams( IObjParam *ip, ULONG flags,Animatable *next )
{
AlphaCD.EndEditParams(ip, this, flags, next);
}
/*===========================================================================*\
| Standard clone
\*===========================================================================*/
RefTargetHandle AlphaModifierClass::Clone(RemapDir& remap)
{
AlphaModifierClass* newmod = new AlphaModifierClass();
newmod->ReplaceReference(0,pblock->Clone(remap));
return(newmod);
}
/*===========================================================================*\
| Subanim & References support
\*===========================================================================*/
Animatable* AlphaModifierClass::SubAnim(int i)
{
switch (i)
{
case 0: return pblock;
default: return NULL;
}
}
TSTR AlphaModifierClass::SubAnimName(int i)
{
switch (i)
{
case 0: return Get_String(IDS_PARAMETERS);
default: return _T("");
}
}
RefTargetHandle AlphaModifierClass::GetReference(int i)
{
switch (i)
{
case 0: return pblock;
default:
assert(TRUE);
return NULL;
}
}
void AlphaModifierClass::SetReference(int i, RefTargetHandle rtarg)
{
switch (i)
{
case 0: pblock = (IParamBlock2*)rtarg; break;
default:
assert(TRUE);
break;
}
}
RefResult AlphaModifierClass::NotifyRefChanged
(
Interval changeInt,
RefTargetHandle hTarget,
PartID& partID,
RefMessage message
)
{
switch (message)
{
case REFMSG_CHANGE:
{
alpha_param_blk.InvalidateUI();
}
break;
}
return REF_SUCCEED;
}
/*===========================================================================*\
| The validity of our parameters
| Start at FOREVER, and intersect with the validity of each item
\*===========================================================================*/
Interval AlphaModifierClass::GetValidity(TimeValue t)
{
float f;
Interval valid = FOREVER;
pblock->GetValue(DL_EDIT_VALUE, t, f, valid);
return valid;
}
Interval AlphaModifierClass::LocalValidity(TimeValue t)
{
return GetValidity(t);
}

View file

@ -0,0 +1,154 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project name : Buccaneer Bay *
* *
* File name : AlphaModifier.h *
* *
* Programmer : Mike Lytle *
* *
* Start date : 11/1/1999 *
* *
* Last update : 11/1/1999 *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef ALPHA_MODIFIER_H
#define ALPHA_MODIFIER_H
#include <max.h>
#include "iparamm2.h"
#include "istdplug.h"
#include "meshadj.h"
#include "modstack.h"
#include "macrorec.h"
#include "resource.h"
#include "dllmain.h"
#define ALPHA_MODIFIER_CLASSID Class_ID(0x518970b3, 0x37d73373)
extern ClassDesc* Get_Alpha_Desc();
#define ALPHA_VERTEX_CHANNEL 10
class AlphaModifierClass : public Modifier
{
public:
// Global parameter block
IParamBlock2 *pblock;
//Constructor/Destructor
AlphaModifierClass();
~AlphaModifierClass() {}
void DeleteThis() { delete this;}
// Plugin identification
void GetClassName(TSTR& s) { s= TSTR(Get_String(IDS_ALPHA_MODIFIER_CLASS));}
virtual Class_ID ClassID() { return ALPHA_MODIFIER_CLASSID;}
TCHAR *GetObjectName() { return Get_String(IDS_ALPHA_MODIFIER_CLASS);}
// Defines the behavior for this modifier
// This is currently setup to be basic geometry
// modification of deformable objects
ChannelMask ChannelsUsed() {return PART_GEOM|PART_TOPO|PART_SELECT|PART_SUBSEL_TYPE;}
ChannelMask ChannelsChanged() {return PART_GEOM|PART_TOPO|PART_SELECT|PART_SUBSEL_TYPE;}
Class_ID InputType() { return triObjectClassID;}
BOOL ChangeTopology() {return FALSE;}
// Calculate the local validity from the parameters
Interval LocalValidity(TimeValue t);
Interval GetValidity(TimeValue t);
// Object modification and notification of change
void ModifyObject(TimeValue t, ModContext &mc, ObjectState *os, INode *node);
void NotifyInputChanged(Interval changeInt, PartID partID, RefMessage message, ModContext *mc);
// Reference support
int NumRefs() { return 1;}
RefTargetHandle GetReference(int i);
void SetReference(int i, RefTargetHandle rtarg);
RefTargetHandle Clone(RemapDir& remap = NoRemap());
RefResult NotifyRefChanged( Interval changeInt,RefTargetHandle hTarget, PartID& partID, RefMessage message);
// SubAnim support
int NumSubs() { return 0;}
Animatable* SubAnim(int i);
TSTR SubAnimName(int i);
// Direct paramblock access
int NumParamBlocks() {return 1;}
IParamBlock2* GetParamBlock(int i) { return pblock;}
IParamBlock2* GetParamBlockByID(BlockID id) {return (pblock->ID() == id) ? pblock : NULL;}
int GetParamBlockIndex(int id) {return id;}
// Does not use createmouse callbacks
CreateMouseCallBack* GetCreateMouseCallBack() {return NULL;}
// Load and unload our UI
void BeginEditParams(IObjParam *ip, ULONG flags,Animatable *prev);
void EndEditParams(IObjParam *ip, ULONG flags,Animatable *next);
void InvalidateUI();
// Message saved from window messages.
int Message;
// Selected vertices.
BitArray SelectedVertices;
};
/*===========================================================================*\
| Dialog Processor
\*===========================================================================*/
class AlphaModDlgProc : public ParamMap2UserDlgProc
{
public:
AlphaModifierClass *AlphaModifier;
AlphaModDlgProc() {}
AlphaModDlgProc(AlphaModifierClass *alpha_m) {AlphaModifier = alpha_m;}
BOOL DlgProc(TimeValue t, IParamMap2 *map, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
void DeleteThis() {}
void SetThing(ReferenceTarget *m) {AlphaModifier = (AlphaModifierClass*)m;}
};
#endif //ALPHA_MODIFIER_H

View file

@ -0,0 +1,226 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : G *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/AppData.cpp $*
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 9/26/00 4:24p $*
* *
* $Revision:: 4 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*
** AppData.cpp - Implementation of some Westwood
** extensions to the MAXScript language.
*/
#include <MaxScrpt.h> // Main MAXScript header
#include <MaxObj.h> // MAX* Wrapper objects
#include <Strings.h> // MAX String class
#include <definsfn.h> // def_* functions to create static function headers
#include "w3dutil.h" // W3DAppData*Struct accessor functions!
#include "w3ddesc.h"
/*
** Let MAXScript know we're implementing new built-in functions.
*/
def_visible_primitive(copy_app_data, "wwCopyAppData");
def_visible_primitive(set_origin_app_data, "wwSetOriginAppData");
def_visible_primitive(get_hierarchy_file, "wwGetHierarchyFile");
/*
**
** MAXScript Function:
** wwCopyAppData - Usage: wwCopyAppData to_node from_node
**
** Copies all AppData associated with from_node to to_node.
** This is needed for W3D flags such as Export Geometry
** and Export Transform to get passed on to their
** instances/copies/references.
*/
Value * copy_app_data_cf (Value **arg_list, int count)
{
// Verify the number and type of the arguments.
check_arg_count("wwCopyAppData", 2, count);
type_check(arg_list[0], MAXNode, "Target INode");
type_check(arg_list[1], MAXNode, "Source INode");
// Get the INode pointers that were passed in.
INode *dest_node = arg_list[0]->to_node();
INode *src_node = arg_list[1]->to_node();
/*
** Copy W3DAppData0Struct
*/
W3DAppData0Struct *app_data_0 = GetW3DAppData0(src_node);
if (app_data_0 != NULL) {
// App Data 0 is now obsolete, not fatal if we don't find one
W3DAppData0Struct *copy_data_0 = new W3DAppData0Struct;
if (copy_data_0 == NULL)
throw RuntimeError("Out of memory.");
// Copy the app data and give it to the target node.
*copy_data_0 = *app_data_0;
dest_node->AddAppDataChunk(W3DUtilityClassID, UTILITY_CLASS_ID, W3D_APPDATA_0,
sizeof(W3DAppData0Struct), copy_data_0);
}
/*
** Copy W3DAppData1Struct
*/
W3DAppData1Struct *app_data_1 = GetW3DAppData1(src_node);
if (app_data_1 == NULL)
throw RuntimeError("Unable to retrieve W3DAppData1Struct from object: ", arg_list[1]);
W3DAppData1Struct *copy_data_1 = new W3DAppData1Struct;
if (copy_data_1 == NULL)
throw RuntimeError("Out of memory.");
// Copy the app data and give it to the target node.
*copy_data_1 = *app_data_1;
dest_node->AddAppDataChunk(W3DUtilityClassID, UTILITY_CLASS_ID, W3D_APPDATA_1,
sizeof(W3DAppData1Struct), copy_data_1);
/*
** Copy W3DAppData2Struct
*/
W3DAppData2Struct *app_data_2 = GetW3DAppData2(src_node);
if (app_data_2 == NULL)
throw RuntimeError("Unable to retrieve W3DAppData1Struct from object: ", arg_list[1]);
W3DAppData2Struct *copy_data_2 = new W3DAppData2Struct;
if (copy_data_2 == NULL)
throw RuntimeError("Out of memory.");
// Copy the app data and give it to the target node.
*copy_data_2 = *app_data_2;
dest_node->AddAppDataChunk(W3DUtilityClassID, UTILITY_CLASS_ID, W3D_APPDATA_2,
sizeof(W3DAppData2Struct), copy_data_2);
/*
** Copy W3DDazzleAppDataStruct if one is present.
*/
W3DDazzleAppDataStruct *dazzle_app_data = GetW3DDazzleAppData(src_node);
if (dazzle_app_data != NULL) {
W3DDazzleAppDataStruct *copy_dazzle_data = new W3DDazzleAppDataStruct;
if (copy_dazzle_data == NULL)
throw RuntimeError("Out of memory.");
// Copy the app data and give it to the target node.
*copy_dazzle_data = *dazzle_app_data;
dest_node->AddAppDataChunk(W3DUtilityClassID, UTILITY_CLASS_ID, W3D_DAZZLE_APPDATA,
sizeof(W3DDazzleAppDataStruct), copy_dazzle_data);
}
return &ok;
}
/*
**
** MAXScript Function:
** wwSetOriginAppData - Usage: wwSetOriginAppData origin_node
**
** Sets the AppData associated with the given node to values
** appropriate to an origin. (ie. turn off Export Geometry and
** Export Transform)
*/
Value * set_origin_app_data_cf (Value **arg_list, int count)
{
// Check the arguments that were passed to this function.
check_arg_count("wwSetOriginAppData", 1, count);
type_check(arg_list[0], MAXNode, "Origin INode");
// Get the INode that we were given.
INode *origin = arg_list[0]->to_node();
// Get the node's W3DAppData2Struct, and modify it accordingly.
W3DAppData2Struct *data = GetW3DAppData2(origin);
if (data == NULL)
throw RuntimeError("Unable to retrieve W3DAppData0Struct from object: ", arg_list[0]);
// Turn off Export Geometry and Export Hierarchy.
data->Enable_Export_Geometry(false);
data->Enable_Export_Transform(false);
return &ok;
}
/*
**
** MAXScript Function:
** wwGetHierarchyFile - Usage: wwGetHierarchyFile()
**
** Returns the relative pathname of the file that will be loaded
** during W3D export to get the hierarchy tree. If no such file
** will be loaded, the return value is the MAXScript undefined.
**
*/
Value * get_hierarchy_file_cf (Value **arg_list, int count)
{
// Check that we weren't passed any arguments.
check_arg_count("wwGetHierarchyFile", 0, count);
// Retrieve the export options from the scene.
W3dExportOptionsStruct *options = NULL;
AppDataChunk * appdata = MAXScript_interface->GetScenePointer()->GetAppDataChunk(W3D_EXPORTER_CLASS_ID,SCENE_EXPORT_CLASS_ID,0);
if (appdata)
options = (W3dExportOptionsStruct*)(appdata->data);
// If we didn't get any options, return undefined.
if (!options)
return &undefined;
// Return the relative path to the htree file if it's available.
// Otherwise, return the absolute path.
one_typed_value_local(String* htree_file);
if (options->RelativeHierarchyFilename[0] != 0)
vl.htree_file = new String(options->RelativeHierarchyFilename);
else if (options->HierarchyFilename[0] != 0)
vl.htree_file = new String(options->HierarchyFilename);
else
{
// Neither filename is available, return undefined.
pop_value_locals();
return &undefined;
}
return_value(vl.htree_file);
}

View file

@ -0,0 +1,116 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : G *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/ExportAll.cpp $*
* *
* $Author:: Andre_a $*
* *
* $Modtime:: 10/15/99 2:08p $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* wwExportTreeSettings -- Returns the directory to export, and recursive flag. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*
** ExportAll.cpp - Implements wwExportTreeSettings, which presents the user with a dialog
** to allow them to choose which directory they want to export, and whether they want to
** export all subdirectories as well. These settings are then passed back so that a script
** can go through the directory (and maybe the subdirectories) and export all .max files
** it finds.
*/
#include "ExportAllDlg.h"
#undef STRICT
#include <MaxScrpt.h>
#include <Arrays.h>
#include <Strings.h>
#include <definsfn.h>
/*
** Let MAXScript know we're implementing new built-in functions.
*/
def_visible_primitive(export_tree_settings, "wwExportTreeSettings");
/***********************************************************************************************
* export_tree_settings_cf - Returns the directory to export, and recursive flag. *
* *
* wwExportTreeSettings - Usage: wwExportTreeSettings #(<initial path>, <recursive>) *
* *
* INPUT: A MaxScript array containing two values: *
* initial_path (string) - the initial export directory *
* recursive (bool) - the initial recursive setting *
* *
* OUTPUT: An array of the same format containing the values the user chose. *
* *
* WARNINGS: *
* *
* HISTORY: *
* 10/4/1999 AJA : Created. *
*=============================================================================================*/
Value * export_tree_settings_cf (Value **arg_list, int count)
{
// We want an array as an argument
check_arg_count("wwExportAll", 1, count);
type_check(arg_list[0], Array, "Parameter array");
// Grab the two values out of the array.
// First value is a string whose value is the initial value for the directory.
// Second value is a bool, true for a recursive export.
ExportAllDlg dlg(MAXScript_interface);
Array *args = (Array*)(arg_list[0]);
char *temp = (args->get(1))->to_string();
int len = strlen(temp);
if (len < MAX_PATH)
strcpy(dlg.m_Directory, temp);
else
{
strncpy(dlg.m_Directory, temp, MAX_PATH-1);
dlg.m_Directory[MAX_PATH-1] = 0;
}
dlg.m_Recursive = (args->get(2))->to_bool();
// Show the dialog to let the user change the settings.
if (dlg.DoModal() == IDCANCEL)
return &undefined;
// Create the array we will return to MaxScript.
one_typed_value_local(Array *result);
vl.result = new Array(2);
vl.result->append(new String(dlg.m_Directory));
if (dlg.m_Recursive)
vl.result->append(&true_value);
else
vl.result->append(&false_value);
// Return the new values.
return_value(vl.result);
}

View file

@ -0,0 +1,219 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : G *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/ExportAllDlg.cpp $*
* *
* $Author:: Andre_a $*
* *
* $Modtime:: 10/15/99 4:25p $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
// ExportAllDlg.cpp : implementation file
//
#include "ExportAllDlg.h"
#include <Max.h>
#include <assert.h>
#include <shlobj.h> // SHBrowseForFolder
static BOOL CALLBACK _thunk_dialog_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
/////////////////////////////////////////////////////////////////////////////
// ExportAllDlg dialog
ExportAllDlg::ExportAllDlg (Interface *max_interface)
{
m_Directory[0] = '\0';
m_Recursive = TRUE;
m_hWnd = NULL;
assert(max_interface != NULL);
m_MaxInterface = max_interface;
}
/////////////////////////////////////////////////////////////////////////////
// ExportAllDlg Methods
int ExportAllDlg::DoModal (void)
{
// Put up the dialog box.
BOOL result = DialogBoxParam(AppInstance, MAKEINTRESOURCE(IDD_EXPORT_ALL),
m_MaxInterface->GetMAXHWnd(), (DLGPROC)_thunk_dialog_proc,
(LPARAM)this);
// Return IDOK if the user accepted the new settings.
return (result == 1) ? IDOK : IDCANCEL;
}
/////////////////////////////////////////////////////////////////////////////
// ExportAllDlg DialogProc
BOOL CALLBACK _thunk_dialog_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static ExportAllDlg *dialog = NULL;
if (uMsg == WM_INITDIALOG)
{
dialog = (ExportAllDlg*)lParam;
dialog->m_hWnd = hWnd;
}
if (dialog)
return dialog->DialogProc(hWnd, uMsg, wParam, lParam);
else
return 0;
}
BOOL CALLBACK ExportAllDlg::DialogProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
int code = HIWORD(wParam);
switch (uMsg)
{
/*******************************************************************
* WM_INITDIALOG
*
* Initialize all of the custom controls for the dialog box
*
*******************************************************************/
case WM_INITDIALOG:
OnInitDialog();
return TRUE;
/*******************************************************************
* WM_COMMAND
*
*
*******************************************************************/
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
if (OnOK() == FALSE)
return TRUE;
SetCursor(LoadCursor(NULL, IDC_WAIT));
EndDialog(m_hWnd, 1);
break;
case IDCANCEL:
EndDialog(m_hWnd, 0);
break;
case IDC_BROWSE:
OnBrowse();
return FALSE;
}
return TRUE;
}
return FALSE;
}
/////////////////////////////////////////////////////////////////////////////
// ExportAllDlg message handlers
void ExportAllDlg::OnInitDialog (void)
{
CenterWindow(m_hWnd, m_MaxInterface->GetMAXHWnd());
SetCursor(LoadCursor(NULL, IDC_ARROW));
// Set the check box state.
CheckDlgButton(m_hWnd, IDC_RECURSIVE, m_Recursive);
// Set the default directory.
HWND edit = GetDlgItem(m_hWnd, IDC_DIRECTORY);
assert(edit != NULL);
SetWindowText(edit, m_Directory);
}
void ExportAllDlg::OnBrowse()
{
char folder_name[MAX_PATH];
BROWSEINFO bi;
ZeroMemory(&bi, sizeof(bi));
bi.hwndOwner = m_hWnd;
bi.pszDisplayName = folder_name;
bi.lpszTitle = "Select a folder for export...";
bi.ulFlags = BIF_RETURNONLYFSDIRS;
// Browse for a folder.
LPITEMIDLIST il = SHBrowseForFolder(&bi);
if (il)
{
// Get the path of the folder.
if (SHGetPathFromIDList(il, folder_name))
{
HWND edit = GetDlgItem(m_hWnd, IDC_DIRECTORY);
assert(edit != NULL);
SetWindowText(edit, folder_name);
}
else
MessageBox(m_hWnd, "Error getting pathname with SHGetPathFromIDList()",
"Error", MB_OK | MB_ICONSTOP);
}
}
BOOL ExportAllDlg::OnOK (void)
{
// Get the directory chosen by the user. If none is entered,
// freak on the user.
char dir[_MAX_PATH];
HWND edit = GetDlgItem(m_hWnd, IDC_DIRECTORY);
assert(edit != NULL);
if (GetWindowText(edit, dir, sizeof(dir)) == 0)
{
// The edit box is empty, that's not a valid choice.
MessageBox(m_hWnd, "You must choose a directory to export",
"Invalid Directory", MB_OK);
SetFocus(edit);
return FALSE;
}
// TODO: Validate the directory as one that actually exists.
// Store the values from the dialog in our class members.
strcpy(m_Directory, dir);
m_Recursive = (IsDlgButtonChecked(m_hWnd, IDC_RECURSIVE) == BST_CHECKED) ? TRUE : FALSE;
return TRUE;
}

View file

@ -0,0 +1,81 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : G *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/ExportAllDlg.h $*
* *
* $Author:: Andre_a $*
* *
* $Modtime:: 10/15/99 4:25p $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef EXPORTALLDLG_H
#define EXPORTALLDLG_H
#include "dllmain.h"
#include "resource.h"
class Interface;
/////////////////////////////////////////////////////////////////////////////
// ExportAllDlg dialog
class ExportAllDlg
{
public:
// Construction
ExportAllDlg (Interface *max_interface);
// Methods
int DoModal (void);
// DialogProc
BOOL CALLBACK DialogProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
// Dialog data associated with GUI components.
char m_Directory[_MAX_PATH]; // edit box
BOOL m_Recursive; // check box
// Dialog data
enum { IDD = IDD_EXPORT_ALL };
HWND m_hWnd;
Interface *m_MaxInterface;
protected:
// Message Handlers
void OnInitDialog (void);
void OnBrowse (void);
BOOL OnOK (void); // TRUE if ok to close dialog
};
#endif

View file

@ -0,0 +1,234 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : FormClass *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/FormClass.cpp $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 11/09/98 3:02a $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* FormClass::Create_Form -- Loads the dialog template and initializes *
* FormClass::fnFormProc -- windows proc which thunks into the virtual Dialog_Proc *
* FormClass::ExecuteDlgInit -- Initializes controls in the dialog template *
* FormClass::ExecuteDlgInit -- Initializes the controls in the dialog template *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "FormClass.H"
#include "Dllmain.H"
// hard-coded resource id which VC special cases for MFC... >:-)
#define RT_DLGINIT MAKEINTRESOURCE(240)
/***********************************************************************************************
* FormClass::Create_Form -- Loads the dialog template and initializes *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 11/6/98 GTH : Created. *
*=============================================================================================*/
HWND
FormClass::Create_Form
(
HWND parent_wnd,
UINT template_id
)
{
// call PreCreateWindow to get prefered extended style
CREATESTRUCT cs = { 0 };
cs.style = WS_CHILD;
m_hWnd = ::CreateDialogParam( AppInstance,
MAKEINTRESOURCE (template_id),
parent_wnd,
fnFormProc,
(LPARAM)this);
assert(m_hWnd);
// Remove the caption from the dialog (if there was any)
::SetWindowLong (m_hWnd,
GWL_STYLE,
::GetWindowLong (m_hWnd, GWL_STYLE) & (~WS_CAPTION));
::GetWindowRect (m_hWnd, &m_FormRect);
ExecuteDlgInit(MAKEINTRESOURCE(template_id));
return m_hWnd;
}
/***********************************************************************************************
* FormClass::fnFormProc -- windows proc which thunks into the virtual Dialog_Proc *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 11/6/98 GTH : Created. *
*=============================================================================================*/
BOOL WINAPI
FormClass::fnFormProc
(
HWND dlg_wnd,
UINT message,
WPARAM wparam,
LPARAM lparam
)
{
FormClass *pform = (FormClass *)::GetProp (dlg_wnd, "FORMCLASS");
if (message == WM_INITDIALOG) {
pform = (FormClass *)lparam;
::SetProp (dlg_wnd, "FORMCLASS", (HANDLE)pform);
} else if (message == WM_DESTROY) {
::RemoveProp (dlg_wnd, "FORMCLASS");
}
BOOL retval = FALSE;
if (pform) {
retval = pform->Dialog_Proc (dlg_wnd, message, wparam, lparam);
}
return retval;
}
/***********************************************************************************************
* FormClass::ExecuteDlgInit -- Initializes controls in the dialog template *
* *
* This code was lifted straight out of MFC. It does some "interesting" things like putting *
* strings into combo boxes which are typed in the resource editor. *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 11/6/98 GTH : Created. *
*=============================================================================================*/
BOOL FormClass::ExecuteDlgInit(LPCTSTR lpszResourceName)
{
// find resource handle
LPVOID lpResource = NULL;
HGLOBAL hResource = NULL;
if (lpszResourceName != NULL)
{
HINSTANCE hInst = AppInstance;
HRSRC hDlgInit = ::FindResource(hInst, lpszResourceName, RT_DLGINIT);
if (hDlgInit != NULL)
{
// load it
hResource = LoadResource(hInst, hDlgInit);
if (hResource == NULL)
return FALSE;
// lock it
lpResource = LockResource(hResource);
assert(lpResource != NULL);
}
}
// execute it
BOOL bResult = ExecuteDlgInit(lpResource);
// cleanup
if (lpResource != NULL && hResource != NULL)
{
UnlockResource(hResource);
FreeResource(hResource);
}
return bResult;
}
/***********************************************************************************************
* FormClass::ExecuteDlgInit -- Initializes the controls in the dialog template *
* *
* As the above ExecuteDlgInit function, this was lifted from MFC... *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 11/6/98 GTH : Created. *
*=============================================================================================*/
BOOL FormClass::ExecuteDlgInit(LPVOID lpResource)
{
BOOL bSuccess = TRUE;
if (lpResource != NULL)
{
UNALIGNED WORD* lpnRes = (WORD*)lpResource;
while (bSuccess && *lpnRes != 0)
{
WORD nIDC = *lpnRes++;
WORD nMsg = *lpnRes++;
DWORD dwLen = *((UNALIGNED DWORD*&)lpnRes)++;
// In Win32 the WM_ messages have changed. They have
// to be translated from the 32-bit values to 16-bit
// values here.
#define WIN16_LB_ADDSTRING 0x0401
#define WIN16_CB_ADDSTRING 0x0403
if (nMsg == WIN16_LB_ADDSTRING)
nMsg = LB_ADDSTRING;
else if (nMsg == WIN16_CB_ADDSTRING)
nMsg = CB_ADDSTRING;
// check for invalid/unknown message types
assert(nMsg == LB_ADDSTRING || nMsg == CB_ADDSTRING);
if (nMsg == LB_ADDSTRING || nMsg == CB_ADDSTRING)
{
// List/Combobox returns -1 for error
if (::SendDlgItemMessageA(m_hWnd, nIDC, nMsg, 0, (LONG)lpnRes) == -1)
bSuccess = FALSE;
}
// skip past data
lpnRes = (WORD*)((LPBYTE)lpnRes + (UINT)dwLen);
}
}
return bSuccess;
}

View file

@ -0,0 +1,72 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : max2w3d *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/FormClass.h $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 11/13/98 9:34a $*
* *
* $Revision:: 3 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __FORMCLASS_H
#define __FORMCLASS_H
#include <Max.h>
class FormClass : public ParamDlg
{
public:
FormClass (void)
: m_hWnd (NULL) {}
~FormClass (void) {}
HWND Create_Form (HWND parent_wnd, UINT template_id);
void Show (bool show_flag = true) { ::ShowWindow (m_hWnd, show_flag ? SW_SHOW : SW_HIDE); }
virtual BOOL Dialog_Proc (HWND dlg_wnd, UINT message, WPARAM wparam, LPARAM lparam) = 0;
HWND Get_Hwnd(void) { return m_hWnd; }
virtual void Invalidate(void) { InvalidateRect(m_hWnd,NULL,0); }
protected:
BOOL ExecuteDlgInit(LPVOID lpResource);
BOOL ExecuteDlgInit(LPCTSTR lpszResourceName);
static BOOL WINAPI fnFormProc (HWND dlg_wnd, UINT message, WPARAM wparam, LPARAM lparam);
HWND m_hWnd;
RECT m_FormRect;
};
#endif //__FORMCLASS_H

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,685 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Max2W3d *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/GameMtlDlg.cpp $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 12/07/00 5:52p $*
* *
* $Revision:: 12 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include <Max.h>
#include <gport.h>
#include <hsv.h>
#include <bmmlib.h>
#include "GameMtlDlg.h"
#include "GameMtl.h"
#include "GameMtlPassDlg.h"
#include "dllmain.h"
#include "resource.h"
#include "w3d_file.h"
static BOOL CALLBACK DisplacementMapDlgProc(HWND hwndDlg, UINT msg, WPARAM wPara,LPARAM lParam);
static BOOL CALLBACK SurfaceTypePanelDlgProc(HWND hwndDlg, UINT msg, WPARAM wPara,LPARAM lParam);
static BOOL CALLBACK PassCountPanelDlgProc(HWND hwndDlg, UINT msg, WPARAM wPara,LPARAM lParam);
static BOOL CALLBACK PassCountDialogDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam,LPARAM lParam);
static int _Pass_Index_To_Flag[] =
{
GAMEMTL_PASS0_ROLLUP_OPEN,
GAMEMTL_PASS1_ROLLUP_OPEN,
GAMEMTL_PASS2_ROLLUP_OPEN,
GAMEMTL_PASS3_ROLLUP_OPEN,
};
/***********************************************************************************************
* GameMtlDlg::GameMtlDlg -- constructor *
* *
* INPUT: *
* hwMtlEdit - windows handle of the MAX material editor *
* imp - Interface object for MAX materials and textures *
* m - pointer to a GameMtl to be edited *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 06/26/1997 GH : Created. *
*=============================================================================================*/
GameMtlDlg::GameMtlDlg(HWND hwMtlEdit, IMtlParams *imp, GameMtl *m)
{
HwndEdit = hwMtlEdit;
HwndPassCount = NULL;
HwndSurfaceType = NULL;
HwndDisplacementMap = NULL;
HpalOld = NULL;
for (int i=0; i<MAX_PASSES; i++) {
PassDialog[i] = NULL;
}
TheMtl = m;
IParams = imp;
IsActive = 0;
Build_Dialog();
}
/***********************************************************************************************
* GameMtlDlg::~GameMtlDlg -- destructor! *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 06/26/1997 GH : Created. *
*=============================================================================================*/
GameMtlDlg::~GameMtlDlg()
{
if (HwndPassCount) {
HDC hdc = GetDC(HwndPassCount);
GetGPort()->RestorePalette(hdc, HpalOld);
ReleaseDC(HwndPassCount,hdc);
}
#ifdef WANT_DISPLACEMENT_MAPS
TheMtl->Set_Flag(GAMEMTL_DISPLACEMENT_ROLLUP_OPEN,IParams->IsRollupPanelOpen(HwndDisplacementMap));
#endif //WANT_DISPLACEMENT_MAPS
TheMtl->Set_Flag(GAMEMTL_SURFACE_ROLLUP_OPEN,IParams->IsRollupPanelOpen(HwndSurfaceType));
TheMtl->Set_Flag(GAMEMTL_PASSCOUNT_ROLLUP_OPEN,IParams->IsRollupPanelOpen(HwndPassCount));
TheMtl->RollScroll = IParams->GetRollupScrollPos();
IParams->UnRegisterDlgWnd(HwndSurfaceType);
IParams->DeleteRollupPage(HwndSurfaceType);
HwndSurfaceType = NULL;
#ifdef WANT_DISPLACEMENT_MAPS
IParams->UnRegisterDlgWnd(HwndDisplacementMap);
IParams->DeleteRollupPage(HwndDisplacementMap);
HwndDisplacementMap = NULL;
#endif //#ifdef WANT_DISPLACEMENT_MAPS
IParams->UnRegisterDlgWnd(HwndPassCount);
IParams->DeleteRollupPage(HwndPassCount);
HwndPassCount = NULL;
for (int i=0; i<MAX_PASSES; i++) {
if (PassDialog[i]) {
delete PassDialog[i];
}
}
TheMtl->SetParamDlg(NULL);
}
/***********************************************************************************************
* GameMtlDlg::ClassID -- Returns the ClassID of GameMtl *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 06/26/1997 GH : Created. *
*=============================================================================================*/
Class_ID GameMtlDlg::ClassID()
{
return GameMaterialClassID;
}
/***********************************************************************************************
* GameMtlDlg::SetThing -- Sets the material to be edited *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 06/26/1997 GH : Created. *
*=============================================================================================*/
void GameMtlDlg::SetThing(ReferenceTarget *m)
{
assert (m);
assert (m->SuperClassID()==MATERIAL_CLASS_ID);
assert ((m->ClassID()==GameMaterialClassID) || (m->ClassID()==PS2GameMaterialClassID));
assert (TheMtl);
int pass;
// destroy our old pass dialogs
for (pass=0; pass<TheMtl->Get_Pass_Count();pass++) {
delete PassDialog[pass];
PassDialog[pass] = NULL;
}
// install the new material
TheMtl->SetParamDlg(NULL);
TheMtl = (GameMtl *)m;
TheMtl->SetParamDlg(this);
// build a new set of pass dialogs
for (pass=0; pass<TheMtl->Get_Pass_Count(); pass++) {
PassDialog[pass] = new GameMtlPassDlg(HwndEdit, IParams, TheMtl, pass);
}
// refresh the contents of the dialogs
ReloadDialog();
}
/***********************************************************************************************
* GameMtlDlg::SetTime -- Sets the time value, updates the material and the dialog *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 06/26/1997 GH : Created. *
*=============================================================================================*/
void GameMtlDlg::SetTime(TimeValue t)
{
if (t!=CurTime) {
CurTime = t;
// TheMtl->Update(IParams->GetTime(),Valid);
ReloadDialog();
}
}
/***********************************************************************************************
* GameMtlDlg::ReloadDialog -- Updates the values in all of the dialog's controls *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 06/26/1997 GH : Created. *
*=============================================================================================*/
void GameMtlDlg::ReloadDialog()
{
/*
** Init the pass count panel
*/
assert(TheMtl && HwndPassCount && HwndSurfaceType);
/*
** Init the surface count panel
*/
::SendMessage (HwndSurfaceType, WM_USER+101, 0, 0L);
#ifdef WANT_DISPLACEMENT_MAPS
::SendMessage (HwndDisplacementMap, WM_USER+101, 0, 0L);
#endif //WANT_DISPLACEMENT_MAPS
/*
** Init the pass count panel
*/
char a[10];
sprintf(a, "%d", TheMtl->Get_Pass_Count());
SetWindowText(GetDlgItem(HwndPassCount, IDC_GAMEMTL_PASSCOUNT_STATIC), a);
/*
** Init each pass panel
*/
for(int i = 0; i < TheMtl->Get_Pass_Count(); i++)
{
PassDialog[i]->ReloadDialog();
}
}
/***********************************************************************************************
* GameMtlDlg::ActivateDlg -- Activates and deactivates the dialog *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 06/26/1997 GH : Created. *
*=============================================================================================*/
void GameMtlDlg::ActivateDlg(BOOL onoff)
{
for(int i = 0; i < TheMtl->Get_Pass_Count(); i++)
{
assert(PassDialog[i]);
PassDialog[i]->ActivateDlg(onoff);
}
}
/***********************************************************************************************
* GameMtlDlg::Invalidate -- causes the dialog to be redrawn *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 06/26/1997 GH : Created. *
*=============================================================================================*/
void GameMtlDlg::Invalidate()
{
InvalidateRect(HwndSurfaceType,NULL,0);
#ifdef WANT_DISPLACEMENT_MAPS
InvalidateRect(HwndDisplacementMap,NULL,0);
#endif //WANT_DISPLACEMENT_MAPS
InvalidateRect(HwndPassCount,NULL,0);
}
BOOL GameMtlDlg::DisplacementMapProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
//SetupIntSpinner(hDlg, IDC_AMOUNT_SPIN, IDC_AMOUNT_EDIT, -999, 999, 0);
/* no break */
case WM_USER + 101:
{
SetDlgItemInt (hDlg, IDC_AMOUNT_EDIT, TheMtl->Get_Displacement_Amount () * 100, TRUE);
SetupIntSpinner(hDlg, IDC_AMOUNT_SPIN, IDC_AMOUNT_EDIT, -999, 999, TheMtl->Get_Displacement_Amount () * 100);
Texmap *map = TheMtl->Get_Displacement_Map ();
if (map != NULL) {
SetDlgItemText (hDlg, IDC_TEXTURE_BUTTON, map->GetFullName ());
}
}
break;
case CC_SPINNER_CHANGE:
{
ISpinnerControl *control = (ISpinnerControl *)lParam;
TheMtl->Set_Displacement_Amount (((float)control->GetIVal ()) / 100.0F);
}
break;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDC_TEXTURE_BUTTON:
if(HIWORD(wParam) == BN_CLICKED)
{
PostMessage(HwndEdit, WM_TEXMAP_BUTTON, TheMtl->Get_Displacement_Map_Index (), (LPARAM)TheMtl);
}
}
break;
}
return FALSE;
}
BOOL GameMtlDlg::SurfaceTypeProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
{
//
// Fill the combobox with the names of the different surface types
//
for (int index = 0; index < SURFACE_TYPE_MAX; index ++) {
::SendDlgItemMessage ( hDlg,
IDC_SURFACE_TYPE_COMBO,
CB_ADDSTRING,
0,
(LPARAM)SURFACE_TYPE_STRINGS[index]);
}
//
// Limit the range of the static sort level spinner to 0 - MAX_SORT_LEVEL.
//
int sort_level = TheMtl->Get_Sort_Level();
SetupIntSpinner(hDlg, IDC_SORT_LEVEL_SPIN, IDC_SORT_LEVEL, 0, MAX_SORT_LEVEL, sort_level);
// Check the checkbox if sort_level is not SORT_LEVEL_NONE.
::SendDlgItemMessage(hDlg, IDC_ENABLE_SORT_LEVEL, BM_SETCHECK,
sort_level == SORT_LEVEL_NONE ? BST_UNCHECKED : BST_CHECKED, 0);
}
case WM_USER + 101:
{
//
// Select the current surface type
//
::SendDlgItemMessage ( hDlg,
IDC_SURFACE_TYPE_COMBO,
CB_SETCURSEL,
(WPARAM)TheMtl->Get_Surface_Type (),
0L);
//
// Set the correct sort level
//
int sort_level = TheMtl->Get_Sort_Level();
ISpinnerControl *spinner = GetISpinner(::GetDlgItem(hDlg, IDC_SORT_LEVEL_SPIN));
assert(spinner);
spinner->SetValue(sort_level, FALSE);
::SendDlgItemMessage(hDlg, IDC_ENABLE_SORT_LEVEL, BM_SETCHECK,
sort_level == SORT_LEVEL_NONE ? BST_UNCHECKED : BST_CHECKED, 0);
break;
}
case WM_COMMAND:
{
switch(LOWORD(wParam))
{
case IDC_SURFACE_TYPE_COMBO:
if(HIWORD(wParam) == CBN_SELCHANGE)
{
unsigned int type = ::SendDlgItemMessage (hDlg, IDC_SURFACE_TYPE_COMBO, CB_GETCURSEL, 0, 0L);
TheMtl->Set_Surface_Type (type);
}
break;
case IDC_ENABLE_SORT_LEVEL:
if (HIWORD(wParam) == BN_CLICKED)
{
// If the 'enable' checkbox was unchecked, set the sort level to NONE.
int state = ::IsDlgButtonChecked(hDlg, IDC_ENABLE_SORT_LEVEL);
ISpinnerControl *spinner = GetISpinner(::GetDlgItem(hDlg, IDC_SORT_LEVEL_SPIN));
assert(spinner);
if (state == BST_UNCHECKED)
{
spinner->SetValue(SORT_LEVEL_NONE, FALSE);
TheMtl->Set_Sort_Level(SORT_LEVEL_NONE);
}
else if (state == BST_CHECKED)
{
// Sort level was enabled, so set it's level to 1 if it was NONE before.
if (spinner->GetIVal() == SORT_LEVEL_NONE)
{
spinner->SetValue(1, FALSE);
TheMtl->Set_Sort_Level(1);
}
}
}
}
break;
}
case CC_SPINNER_CHANGE:
{
ISpinnerControl *spinner = (ISpinnerControl*)lParam;
switch(LOWORD(wParam))
{
case IDC_SORT_LEVEL_SPIN:
// Check the 'enabled' checkbox if sort level != SORT_LEVEL_NONE, uncheck it otherwise.
::SendDlgItemMessage(hDlg, IDC_ENABLE_SORT_LEVEL, BM_SETCHECK,
spinner->GetIVal() == SORT_LEVEL_NONE ? BST_UNCHECKED : BST_CHECKED, 0);
TheMtl->Set_Sort_Level(spinner->GetIVal());
break;
}
break;
}
}
return FALSE;
}
BOOL GameMtlDlg::PassCountProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
break;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDC_SETPASSCOUNT:
if(HIWORD(wParam) == BN_CLICKED)
{
Set_Pass_Count_Dialog();
}
}
break;
}
return FALSE;
}
static BOOL CALLBACK DisplacementMapDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam,LPARAM lParam)
{
GameMtlDlg * theDlg;
if (msg == WM_INITDIALOG) {
theDlg = (GameMtlDlg*)lParam;
theDlg->HwndDisplacementMap = hwndDlg;
SetWindowLong(hwndDlg, GWL_USERDATA,lParam);
} else {
if ((theDlg = (GameMtlDlg *)GetWindowLong(hwndDlg, GWL_USERDATA) ) == NULL) {
return FALSE;
}
}
theDlg->IsActive = 1;
BOOL res = theDlg->DisplacementMapProc(hwndDlg,msg,wParam,lParam);
theDlg->IsActive = 0;
return res;
}
static BOOL CALLBACK SurfaceTypePanelDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam,LPARAM lParam)
{
GameMtlDlg * theDlg;
if (msg == WM_INITDIALOG) {
theDlg = (GameMtlDlg*)lParam;
theDlg->HwndSurfaceType = hwndDlg;
SetWindowLong(hwndDlg, GWL_USERDATA,lParam);
} else {
if ((theDlg = (GameMtlDlg *)GetWindowLong(hwndDlg, GWL_USERDATA) ) == NULL) {
return FALSE;
}
}
theDlg->IsActive = 1;
BOOL res = theDlg->SurfaceTypeProc(hwndDlg,msg,wParam,lParam);
theDlg->IsActive = 0;
return res;
}
static BOOL CALLBACK PassCountPanelDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam,LPARAM lParam)
{
GameMtlDlg * theDlg;
if (msg == WM_INITDIALOG) {
theDlg = (GameMtlDlg*)lParam;
theDlg->HwndPassCount = hwndDlg;
SetWindowLong(hwndDlg, GWL_USERDATA,lParam);
} else {
if ((theDlg = (GameMtlDlg *)GetWindowLong(hwndDlg, GWL_USERDATA) ) == NULL) {
return FALSE;
}
}
theDlg->IsActive = 1;
BOOL res = theDlg->PassCountProc(hwndDlg,msg,wParam,lParam);
theDlg->IsActive = 0;
return res;
}
void GameMtlDlg::Set_Pass_Count_Dialog(void)
{
int res = DialogBoxParam(
AppInstance,
MAKEINTRESOURCE(IDD_GAMEMTL_PASS_COUNT_DIALOG),
HwndPassCount,
PassCountDialogDlgProc,
(LPARAM)TheMtl->Get_Pass_Count());
if (res>=0)
{
if (res<=0) res = 1;
if (res>4) res = 4;
char a[10];
sprintf(a, "%d", res);
SetWindowText(GetDlgItem(HwndPassCount, IDC_GAMEMTL_PASSCOUNT_STATIC), a);
if(TheMtl->Get_Pass_Count() != res)
{
for(int i = 0; i < TheMtl->Get_Pass_Count(); i++)
{
delete PassDialog[i];
PassDialog[i] = NULL;
}
TheMtl->Set_Pass_Count(res);
for(i = 0; i < TheMtl->Get_Pass_Count(); i++)
{
PassDialog[i] = new GameMtlPassDlg(HwndEdit, IParams, TheMtl, i);
}
ReloadDialog();
}
}
}
static BOOL CALLBACK PassCountDialogDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam,LPARAM lParam)
{
switch (msg)
{
case WM_INITDIALOG:
{
ISpinnerControl *spin = SetupIntSpinner(
hwndDlg,IDC_PASSCOUNT_SPIN, IDC_PASSCOUNT_EDIT,
1,4,(int)lParam);
ReleaseISpinner(spin);
CenterWindow(hwndDlg,GetParent(hwndDlg));
break;
}
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
{
ISpinnerControl *spin = GetISpinner(GetDlgItem(hwndDlg,IDC_PASSCOUNT_SPIN));
EndDialog(hwndDlg,spin->GetIVal());
ReleaseISpinner(spin);
break;
}
case IDCANCEL:
EndDialog(hwndDlg,-1);
break;
}
break;
default:
return FALSE;
}
return TRUE;
}
/***********************************************************************************************
* GameMtlDlg::Build_Dialog -- Adds the dialog to the material editor *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 06/26/1997 GH : Created. *
*=============================================================================================*/
void GameMtlDlg::Build_Dialog()
{
if ((TheMtl->Flags&(GAMEMTL_ROLLUP_FLAGS))==0) {
TheMtl->Set_Flag(GAMEMTL_PASS0_ROLLUP_OPEN,TRUE);
}
HwndSurfaceType = IParams->AddRollupPage(
AppInstance,
MAKEINTRESOURCE(IDD_GAMEMTL_SURFACE_TYPE),
SurfaceTypePanelDlgProc,
Get_String(IDS_SURFACE_TYPE),
(LPARAM)this,
TheMtl->Get_Flag(GAMEMTL_SURFACE_ROLLUP_OPEN) ? 0:APPENDROLL_CLOSED
);
#ifdef WANT_DISPLACEMENT_MAPS
HwndDisplacementMap = IParams->AddRollupPage(
AppInstance,
MAKEINTRESOURCE(IDD_GAMEMTL_DISPLACEMENT_MAP),
DisplacementMapDlgProc,
Get_String(IDS_DISPLACEMENT_MAP),
(LPARAM)this,
TheMtl->Get_Flag(GAMEMTL_DISPLACEMENT_ROLLUP_OPEN) ? 0:APPENDROLL_CLOSED
);
#endif //WANT_DISPLACEMENT_MAPS
HwndPassCount = IParams->AddRollupPage(
AppInstance,
MAKEINTRESOURCE(IDD_GAMEMTL_PASS_COUNT),
PassCountPanelDlgProc,
Get_String(IDS_PASS_COUNT),
(LPARAM)this,
TheMtl->Get_Flag(GAMEMTL_PASSCOUNT_ROLLUP_OPEN) ? 0:APPENDROLL_CLOSED
);
for (int i=0; i<TheMtl->Get_Pass_Count(); i++) {
PassDialog[i] = new GameMtlPassDlg(HwndEdit, IParams, TheMtl, i);
}
IParams->SetRollupScrollPos(TheMtl->RollScroll);
ReloadDialog();
}

View file

@ -0,0 +1,119 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Max2W3d *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/GameMtlDlg.h $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 6/30/99 7:10p $*
* *
* $Revision:: 6 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef GAMEMTLDLG_H
#define GAMEMTLDLG_H
class GameMtl;
class GameMtlPassDlg;
////////////////////////////////////////////////////////////////////////
// GameMtlDlg
//
// Dialog box interface in the material editor for GameMtl
// This is basically a cannibalized version of the Standard
// Max material's dialog.
//
////////////////////////////////////////////////////////////////////////
class GameMtlDlg: public ParamDlg
{
public:
////////////////////////////////////////////////////////////////////////
// Methods
////////////////////////////////////////////////////////////////////////
GameMtlDlg(HWND hwMtlEdit, IMtlParams *imp, GameMtl *m);
~GameMtlDlg();
// From ParamDlg:
Class_ID ClassID(void);
void SetThing(ReferenceTarget *m);
ReferenceTarget* GetThing(void) { return (ReferenceTarget*)TheMtl; }
void DeleteThis() { delete this; }
void SetTime(TimeValue t);
void ReloadDialog(void);
void ActivateDlg(BOOL onOff);
void Invalidate(void);
void Update_Display(void) { IParams->MtlChanged(); }
protected:
void Build_Dialog(void);
BOOL DisplacementMapProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
BOOL SurfaceTypeProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
BOOL PassCountProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
void Set_Pass_Count_Dialog(void);
enum { MAX_PASSES = 4 };
////////////////////////////////////////////////////////////////////////
// Windows handles
////////////////////////////////////////////////////////////////////////
HWND HwndEdit; // window handle of the materials editor dialog
HWND HwndPassCount; // Rollup pass count panel
HWND HwndSurfaceType; // Rollup surface type panel
HWND HwndDisplacementMap;
HPALETTE HpalOld;
GameMtlPassDlg * PassDialog[MAX_PASSES];
////////////////////////////////////////////////////////////////////////
// Material dialog interface
////////////////////////////////////////////////////////////////////////
IMtlParams * IParams; // interface to the material editor
GameMtl * TheMtl; // current mtl being edited.
////////////////////////////////////////////////////////////////////////
// Member variables
////////////////////////////////////////////////////////////////////////
TimeValue CurTime;
int IsActive;
friend BOOL CALLBACK DisplacementMapDlgProc(HWND, UINT, WPARAM,LPARAM);
friend BOOL CALLBACK SurfaceTypePanelDlgProc(HWND, UINT, WPARAM,LPARAM);
friend BOOL CALLBACK PassCountPanelDlgProc(HWND, UINT, WPARAM,LPARAM);
friend class GameMtl;
};
#endif

View file

@ -0,0 +1,164 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Max2W3d *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/GameMtlForm.cpp $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 11/23/98 6:21p $*
* *
* $Revision:: 3 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* GameMtlFormClass::GameMtlFormClass -- constructor *
* GameMtlFormClass::SetThing -- Set the material being edited by this form *
* GameMtlFormClass::GetThing -- get the material being edited by this form *
* GameMtlFormClass::DeleteThis -- delete myself *
* GameMtlFormClass::ClassID -- returns the classID of the object being edited *
* GameMtlFormClass::SetTime -- set the current time *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "GameMtlForm.h"
#include "GameMtl.h"
/***********************************************************************************************
* GameMtlFormClass::GameMtlFormClass -- constructor *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 11/23/98 GTH : Created. *
*=============================================================================================*/
GameMtlFormClass::GameMtlFormClass
(
IMtlParams * imtl_params,
GameMtl * mtl,
int pass
)
{
IParams = imtl_params;
TheMtl = mtl;
PassIndex = pass;
}
/***********************************************************************************************
* GameMtlFormClass::SetThing -- Set the material being edited by this form *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 11/23/98 GTH : Created. *
*=============================================================================================*/
void GameMtlFormClass::SetThing(ReferenceTarget * target)
{
assert (target->SuperClassID()==MATERIAL_CLASS_ID);
assert (target->ClassID()==GameMaterialClassID);
TheMtl = (GameMtl *)target;
}
/***********************************************************************************************
* GameMtlFormClass::GetThing -- get the material being edited by this form *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 11/23/98 GTH : Created. *
*=============================================================================================*/
ReferenceTarget * GameMtlFormClass::GetThing(void)
{
return (ReferenceTarget*)TheMtl;
}
/***********************************************************************************************
* GameMtlFormClass::DeleteThis -- delete myself *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 11/23/98 GTH : Created. *
*=============================================================================================*/
void GameMtlFormClass::DeleteThis(void)
{
delete this;
}
/***********************************************************************************************
* GameMtlFormClass::ClassID -- returns the classID of the object being edited *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 11/23/98 GTH : Created. *
*=============================================================================================*/
Class_ID GameMtlFormClass::ClassID()
{
return GameMaterialClassID;
}
/***********************************************************************************************
* GameMtlFormClass::SetTime -- set the current time *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 11/23/98 GTH : Created. *
*=============================================================================================*/
void GameMtlFormClass::SetTime(TimeValue t)
{
// child dialog classes don't have to support
// the SetTime function.
}

View file

@ -0,0 +1,64 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Max2W3d *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/GameMtlForm.h $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 11/13/98 10:26a $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef GAMEMTLFORM_H
#define GAMEMTLFORM_H
#include "FormClass.h"
class GameMtl;
class GameMtlFormClass : public FormClass
{
public:
GameMtlFormClass(IMtlParams * imtl_params,GameMtl * mtl,int pass);
void SetThing(ReferenceTarget *m);
ReferenceTarget* GetThing(void);
void DeleteThis(void);
Class_ID ClassID(void);
void SetTime(TimeValue t);
protected:
IMtlParams * IParams; // interface to the material editor
GameMtl * TheMtl; // current mtl being edited.
int PassIndex; // material pass that this form edits
};
#endif

View file

@ -0,0 +1,393 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Max2W3d *
* *
* $Archive:: /Bay/Tools/max2w3d/GameMtlPassDlg.cpp $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 10/22/99 9:54a $*
* *
* $Revision:: 9 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* PassDlgProc -- dialog proc which thunks into a GameMtlPassDlg *
* GameMtlPassDlg::GameMtlPassDlg -- constructor *
* GameMtlPassDlg::~GameMtlPassDlg -- destructor *
* GameMtlPassDlg::DialogProc -- windows message handler *
* GameMtlPassDlg::Invalidate -- invalidate the dialog *
* GameMtlPassDlg::ReloadDialog -- update the contents of all of the controls *
* GameMtlPassDlg::ClassID -- returns classID of the object being edited *
* GameMtlPassDlg::SetThing -- set the material being edited *
* GameMtlPassDlg::ActivateDlg -- activate or deactivate the dialog *
* GameMtlPassDlg::SetTime -- set the current time *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "GameMtlPassDlg.h"
#include "dllmain.h"
#include "resource.h"
#include "GameMtl.h"
#include "GameMtlDlg.h"
#include "GameMtlShaderDlg.h"
#include "PS2GameMtlShaderDlg.h"
#include "GameMtlTextureDlg.h"
#include "GameMtlVertexMaterialDlg.h"
#include "w3d_file.h"
static int _Pass_Index_To_Flag[] =
{
GAMEMTL_PASS0_ROLLUP_OPEN,
GAMEMTL_PASS1_ROLLUP_OPEN,
GAMEMTL_PASS2_ROLLUP_OPEN,
GAMEMTL_PASS3_ROLLUP_OPEN,
};
/***********************************************************************************************
* PassDlgProc -- dialog proc which thunks into a GameMtlPassDlg *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 11/23/98 GTH : Created. *
*=============================================================================================*/
static BOOL CALLBACK PassDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
GameMtlPassDlg *theDlg;
if (msg==WM_INITDIALOG) {
theDlg = (GameMtlPassDlg*)lParam;
theDlg->HwndPanel = hwndDlg;
SetWindowLong(hwndDlg, GWL_USERDATA,lParam);
} else {
if ((theDlg = (GameMtlPassDlg *)GetWindowLong(hwndDlg, GWL_USERDATA) ) == NULL) {
return FALSE;
}
}
return theDlg->DialogProc(hwndDlg,msg,wParam,lParam);
}
/***********************************************************************************************
* GameMtlPassDlg::GameMtlPassDlg -- constructor *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 11/23/98 GTH : Created. *
*=============================================================================================*/
GameMtlPassDlg::GameMtlPassDlg(HWND hwMtlEdit, IMtlParams *imp, GameMtl *m,int pass)
{
HwndEdit = hwMtlEdit;
TheMtl = m;
IParams = imp;
PassIndex = pass;
char title[200];
sprintf(title, "Pass %d", pass + 1);
HwndPanel = IParams->AddRollupPage(
AppInstance,
MAKEINTRESOURCE(IDD_GAMEMTL_PASS),
PassDlgProc,
title,
(LPARAM)this,
TheMtl->Get_Flag(_Pass_Index_To_Flag[PassIndex]) ? 0 : APPENDROLL_CLOSED
);
}
/***********************************************************************************************
* GameMtlPassDlg::~GameMtlPassDlg -- destructor *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 11/23/98 GTH : Created. *
*=============================================================================================*/
GameMtlPassDlg::~GameMtlPassDlg()
{
TheMtl->Set_Flag(_Pass_Index_To_Flag[PassIndex],IParams->IsRollupPanelOpen(HwndPanel));
IParams->DeleteRollupPage(HwndPanel);
SetWindowLong(HwndPanel, GWL_USERDATA, NULL);
}
/***********************************************************************************************
* GameMtlPassDlg::DialogProc -- windows message handler *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 11/23/98 GTH : Created. *
*=============================================================================================*/
BOOL GameMtlPassDlg::DialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
int i=0;
int id = LOWORD(wParam);
int code = HIWORD(wParam);
switch (message) {
case WM_INITDIALOG:
{
Page[0] = new GameMtlVertexMaterialDlg(HwndPanel,IParams,TheMtl,PassIndex);
if (TheMtl->Get_Shader_Type() == GameMtl::STE_PC_SHADER) {
Page[1] = new GameMtlShaderDlg(HwndPanel,IParams,TheMtl,PassIndex);
} else {
// The PS2 shader is different.
Page[1] = new PS2GameMtlShaderDlg(HwndPanel,IParams,TheMtl,PassIndex);
}
Page[2] = new GameMtlTextureDlg(HwndPanel,IParams,TheMtl,PassIndex);
for (i=0; i<PAGE_COUNT; i++) {
HWND hwnd = Page[i]->Get_Hwnd();
// set the tab names
char name[64];
::GetWindowText(hwnd,name,sizeof(name));
TC_ITEM tcitem = { TCIF_TEXT,0,0,name,0 };
TabCtrl_InsertItem(GetDlgItem(HwndPanel,IDC_GAMEMTL_TAB),i,&tcitem);
}
// Get the display rectangle of the tab control
RECT rect;
::GetWindowRect(GetDlgItem(HwndPanel,IDC_GAMEMTL_TAB),&rect);
TabCtrl_AdjustRect(GetDlgItem(HwndPanel,IDC_GAMEMTL_TAB),FALSE, &rect);
// Convert the display rectangle from screen to client coords
ScreenToClient(HwndPanel,(POINT *)(&rect));
ScreenToClient(HwndPanel, ((LPPOINT)&rect) + 1);
for (i=0; i<PAGE_COUNT; i++) {
HWND hwnd = Page[i]->Get_Hwnd();
// Loop through all the tabs in the property sheet
// Get a pointer to this tab
SetWindowPos( hwnd,
NULL,
rect.left, rect.top,
rect.right - rect.left, rect.bottom - rect.top,
SWP_NOZORDER);
}
CurPage = 0;
TabCtrl_SetCurSel(GetDlgItem(HwndPanel,IDC_GAMEMTL_TAB),CurPage);
Page[CurPage]->Show();
break;
}
case WM_PAINT:
{
if (!Valid) {
Valid = TRUE;
ReloadDialog();
}
return FALSE;
}
case WM_NOTIFY:
{
NMHDR * header = (NMHDR *)lParam;
switch(header->code) {
case TCN_SELCHANGE:
{
int sel = TabCtrl_GetCurSel(GetDlgItem(HwndPanel,IDC_GAMEMTL_TAB));
Page[sel]->Show();
for (int i=0; i < PAGE_COUNT; i++) {
if (i != sel) Page[i]->Show(false);
}
CurPage = sel;
TheMtl->Set_Current_Page(PassIndex,CurPage);
}
};
break;
}
}
return FALSE;
}
/***********************************************************************************************
* GameMtlPassDlg::Invalidate -- invalidate the dialog *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 11/23/98 GTH : Created. *
*=============================================================================================*/
void GameMtlPassDlg::Invalidate()
{
Valid = FALSE;
InvalidateRect(HwndPanel,NULL,0);
}
/***********************************************************************************************
* GameMtlPassDlg::ReloadDialog -- update the contents of all of the controls *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 11/23/98 GTH : Created. *
*=============================================================================================*/
void GameMtlPassDlg::ReloadDialog()
{
int i;
DebugPrint("GameMtlPassDlg::ReloadDialog\n");
Interval v;
TheMtl->Update(IParams->GetTime(),v);
for (i=0; i<PAGE_COUNT; i++) {
Page[i]->ReloadDialog();
}
CurPage = TheMtl->Get_Current_Page(PassIndex);
TabCtrl_SetCurSel(GetDlgItem(HwndPanel,IDC_GAMEMTL_TAB),CurPage);
Page[CurPage]->Show();
for (i=0; i < PAGE_COUNT; i++) {
if (i != CurPage) Page[i]->Show(false);
}
}
/***********************************************************************************************
* GameMtlPassDlg::ClassID -- returns classID of the object being edited *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 11/23/98 GTH : Created. *
*=============================================================================================*/
Class_ID GameMtlPassDlg::ClassID()
{
return GameMaterialClassID;
}
/***********************************************************************************************
* GameMtlPassDlg::SetThing -- set the material being edited *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 11/23/98 GTH : Created. *
*=============================================================================================*/
void GameMtlPassDlg::SetThing(ReferenceTarget* target)
{
// Note, parent will "reload" when our "thing" changes :-)
assert (target->SuperClassID()==MATERIAL_CLASS_ID);
assert (target->ClassID()==GameMaterialClassID);
TheMtl = (GameMtl *)target;
for (int i=0; i<PAGE_COUNT; i++) {
Page[i]->SetThing(target);
}
}
/***********************************************************************************************
* GameMtlPassDlg::ActivateDlg -- activate or deactivate the dialog *
* *
* some of the custom max controls need to be activated and deactivated *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 11/23/98 GTH : Created. *
*=============================================================================================*/
void GameMtlPassDlg::ActivateDlg(BOOL onoff)
{
for (int i=0; i<PAGE_COUNT; i++) {
Page[i]->ActivateDlg(onoff);
}
}
/***********************************************************************************************
* GameMtlPassDlg::SetTime -- set the current time *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 11/23/98 GTH : Created. *
*=============================================================================================*/
void GameMtlPassDlg::SetTime(TimeValue t)
{
// parent dialog class keeps track of the validty and we
// don't have to do anything in this function (it will never
// be called in fact)
}

View file

@ -0,0 +1,97 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Max2W3d *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/GameMtlPassDlg.h $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 11/17/98 1:32p $*
* *
* $Revision:: 5 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef GAMEMTLPASSDLG_H
#define GAMEMTLPASSDLG_H
#include <Max.h>
class GameMtl;
class GameMtlFormClass;
/*
** The GameMtlPassDlg will contain a Tab Control which switches between
** editing the VertexMaterial parameters, the Shader parameters and the
** Texture parameters.
*/
class GameMtlPassDlg: public ParamDlg
{
public:
GameMtlPassDlg(HWND hwMtlEdit, IMtlParams *imp, GameMtl *m,int pass);
~GameMtlPassDlg();
BOOL DialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
void Invalidate();
void UpdateMtlDisplay() { IParams->MtlChanged(); }
void ReloadDialog();
Class_ID ClassID();
void SetThing(ReferenceTarget* target);
ReferenceTarget * GetThing() { return (ReferenceTarget *)TheMtl; }
void DeleteThis() { delete this; }
void SetTime(TimeValue t);
void ActivateDlg(BOOL onOff);
enum { PAGE_COUNT = 3 };
////////////////////////////////////////////////////////////////////////
// Material dialog interface
////////////////////////////////////////////////////////////////////////
IMtlParams * IParams; // interface to the material editor
GameMtl * TheMtl; // current mtl being edited.
////////////////////////////////////////////////////////////////////////
// Windows handles
////////////////////////////////////////////////////////////////////////
HWND HwndEdit; // window handle of the materials editor dialog
HWND HwndPanel; // Rollup parameters panel
////////////////////////////////////////////////////////////////////////
// Variables
////////////////////////////////////////////////////////////////////////
int PassIndex;
int CurPage;
BOOL Valid;
GameMtlFormClass* Page[PAGE_COUNT];
};
#endif

View file

@ -0,0 +1,397 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Max2W3d *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/GameMtlShaderDlg.cpp $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 2/26/99 7:23p $*
* *
* $Revision:: 13 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* GameMtlShaderDlg::GameMtlShaderDlg -- constructor *
* GameMtlShaderDlg::~GameMtlShaderDlg -- destructor *
* GameMtlShaderDlg::Dialog_Proc -- windows message handler *
* GameMtlShaderDlg::ReloadDialog -- reload the contents of all of the controls *
* GameMtlShaderDlg::ActivateDlg -- activate/deactivate the dialog *
* GameMtlShaderDlg::Apply_Preset -- apply a preset shader setting *
* GameMtlShaderDlg::Set_Preset -- determine preset shader setting from game material *
* GameMtlShaderDlg::CompareShaderToBlendPreset -- compare preset to game material shader *
* GameMtlShaderDlg::Set_Advanced_Defaults -- set advanced settings to defaults *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "GameMtlShaderDlg.h"
#include "GameMtlDlg.h"
#include "GameMtl.h"
#include "resource.h"
/*
** Shader Blend Setting Presets
*/
// Note: the array has NUM_SHADER_BLEND_PRESETS + 1 entries (due to the 'Custom' entry).
#define NUM_SHADER_BLEND_PRESETS 8
static char * _ShaderBlendSettingPresetNames[NUM_SHADER_BLEND_PRESETS + 1] =
{
"Opaque",
"Add",
"Multiply",
"Multiply and Add",
"Screen",
"Alpha Blend",
"Alpha Test",
"Alpha Test and Blend",
"------ Custom -----"
};
struct ShaderBlendSettingPreset
{
int SrcBlend;
int DestBlend;
bool DepthMask;
bool AlphaTest;
};
static const ShaderBlendSettingPreset ShaderBlendSettingPresets[NUM_SHADER_BLEND_PRESETS] = {
{W3DSHADER_SRCBLENDFUNC_ONE, W3DSHADER_DESTBLENDFUNC_ZERO, true, false}, // Opaque
{W3DSHADER_SRCBLENDFUNC_ONE, W3DSHADER_DESTBLENDFUNC_ONE, false, false}, // Add
{W3DSHADER_SRCBLENDFUNC_ZERO, W3DSHADER_DESTBLENDFUNC_SRC_COLOR, false, false}, // Multiply
{W3DSHADER_SRCBLENDFUNC_ONE, W3DSHADER_DESTBLENDFUNC_SRC_COLOR, false, false}, // Multiply and Add
{W3DSHADER_SRCBLENDFUNC_ONE, W3DSHADER_DESTBLENDFUNC_ONE_MINUS_SRC_COLOR, false, false}, // Screen
{W3DSHADER_SRCBLENDFUNC_SRC_ALPHA, W3DSHADER_DESTBLENDFUNC_ONE_MINUS_SRC_ALPHA, false, false}, // Alpha Blend
{W3DSHADER_SRCBLENDFUNC_ONE, W3DSHADER_DESTBLENDFUNC_ZERO, true, true}, // Alpha Test
{W3DSHADER_SRCBLENDFUNC_SRC_ALPHA, W3DSHADER_DESTBLENDFUNC_ONE_MINUS_SRC_ALPHA, true, true} // Alpha Test and Blend
};
/***********************************************************************************************
* GameMtlShaderDlg::GameMtlShaderDlg -- constructor *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 11/23/98 GTH : Created. *
*=============================================================================================*/
GameMtlShaderDlg::GameMtlShaderDlg
(
HWND parent,
IMtlParams * imp,
GameMtl * mtl,
int pass
) :
GameMtlFormClass(imp,mtl,pass)
{
Create_Form(parent,IDD_GAMEMTL_SHADER);
}
/***********************************************************************************************
* GameMtlShaderDlg::~GameMtlShaderDlg -- destructor *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
*=============================================================================================*/
GameMtlShaderDlg::~GameMtlShaderDlg()
{
}
/***********************************************************************************************
* GameMtlShaderDlg::Dialog_Proc -- windows message handler *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 11/23/98 GTH : Created. *
*=============================================================================================*/
BOOL GameMtlShaderDlg::Dialog_Proc (HWND dlg_wnd, UINT message, WPARAM wparam, LPARAM lparam)
{
int cursel;
int i;
int id = LOWORD(wparam);
int code = HIWORD(wparam);
switch (message)
{
case WM_INITDIALOG:
for(i = 0; i <= NUM_SHADER_BLEND_PRESETS; i++) {
SendDlgItemMessage(dlg_wnd,IDC_PRESET_COMBO,CB_ADDSTRING,0,(LONG)_ShaderBlendSettingPresetNames[i]);
}
SendDlgItemMessage(dlg_wnd,IDC_PRESET_COMBO,CB_SETCURSEL,0,0);
break;
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
case WM_MOUSEMOVE:
{
IParams->RollupMouseMessage(dlg_wnd,message,wparam,lparam);
}
return FALSE;
case WM_COMMAND:
{
if (code == CBN_SELCHANGE) {
switch (id)
{
case IDC_DEPTHCOMPARE_COMBO:
cursel = SendDlgItemMessage(dlg_wnd,IDC_DEPTHCOMPARE_COMBO,CB_GETCURSEL,0,0);
TheMtl->Set_Depth_Compare(PassIndex,cursel);
break;
case IDC_DESTBLEND_COMBO:
cursel = SendDlgItemMessage(dlg_wnd,IDC_DESTBLEND_COMBO,CB_GETCURSEL,0,0);
TheMtl->Set_Dest_Blend(PassIndex,cursel);
TheMtl->Notify_Changed();
Set_Preset();
break;
case IDC_PRIGRADIENT_COMBO:
cursel = SendDlgItemMessage(dlg_wnd,IDC_PRIGRADIENT_COMBO,CB_GETCURSEL,0,0);
TheMtl->Set_Pri_Gradient(PassIndex,cursel);
TheMtl->Notify_Changed();
break;
case IDC_SECGRADIENT_COMBO:
cursel = SendDlgItemMessage(dlg_wnd,IDC_SECGRADIENT_COMBO,CB_GETCURSEL,0,0);
TheMtl->Set_Sec_Gradient(PassIndex,cursel);
TheMtl->Notify_Changed();
break;
case IDC_SRCBLEND_COMBO:
cursel = SendDlgItemMessage(dlg_wnd,IDC_SRCBLEND_COMBO,CB_GETCURSEL,0,0);
TheMtl->Set_Src_Blend(PassIndex,cursel);
TheMtl->Notify_Changed();
Set_Preset();
break;
case IDC_DETAILCOLOR_COMBO:
cursel = SendDlgItemMessage(dlg_wnd,IDC_DETAILCOLOR_COMBO,CB_GETCURSEL,0,0);
TheMtl->Set_Detail_Color_Func(PassIndex,cursel);
TheMtl->Notify_Changed();
break;
case IDC_DETAILALPHA_COMBO:
cursel = SendDlgItemMessage(dlg_wnd,IDC_DETAILALPHA_COMBO,CB_GETCURSEL,0,0);
TheMtl->Set_Detail_Alpha_Func(PassIndex,cursel);
TheMtl->Notify_Changed();
break;
case IDC_PRESET_COMBO:
cursel = SendDlgItemMessage(dlg_wnd,IDC_PRESET_COMBO,CB_GETCURSEL,0,0);
Apply_Preset(cursel);
break;
}
} else {
switch(id) {
case IDC_DEPTHMASK_CHECK:
if (SendDlgItemMessage(dlg_wnd,IDC_DEPTHMASK_CHECK,BM_GETCHECK,0,0)) {
TheMtl->Set_Depth_Mask(PassIndex,W3DSHADER_DEPTHMASK_WRITE_ENABLE);
} else {
TheMtl->Set_Depth_Mask(PassIndex,W3DSHADER_DEPTHMASK_WRITE_DISABLE);
}
Set_Preset();
break;
case IDC_ALPHATEST_CHECK:
if (SendDlgItemMessage(dlg_wnd,IDC_ALPHATEST_CHECK,BM_GETCHECK,0,0)) {
TheMtl->Set_Alpha_Test(PassIndex,W3DSHADER_ALPHATEST_ENABLE);
} else {
TheMtl->Set_Alpha_Test(PassIndex,W3DSHADER_ALPHATEST_DISABLE);
}
Set_Preset();
break;
case IDC_SHADER_DEFAULTS_BUTTON:
Set_Advanced_Defaults();
break;
}
}
}
}
return FALSE;
}
/***********************************************************************************************
* GameMtlShaderDlg::ReloadDialog -- reload the contents of all of the controls *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 11/23/98 GTH : Created. *
*=============================================================================================*/
void GameMtlShaderDlg::ReloadDialog(void)
{
DebugPrint("GameMtlShaderDlg::ReloadDialog\n");
SendDlgItemMessage(m_hWnd, IDC_DESTBLEND_COMBO, CB_SETCURSEL, TheMtl->Get_Dest_Blend(PassIndex), 0 );
SendDlgItemMessage(m_hWnd, IDC_SRCBLEND_COMBO, CB_SETCURSEL, TheMtl->Get_Src_Blend(PassIndex), 0 );
SendDlgItemMessage(m_hWnd, IDC_PRIGRADIENT_COMBO, CB_SETCURSEL, TheMtl->Get_Pri_Gradient(PassIndex), 0 );
SendDlgItemMessage(m_hWnd, IDC_SECGRADIENT_COMBO, CB_SETCURSEL, TheMtl->Get_Sec_Gradient(PassIndex), 0 );
SendDlgItemMessage(m_hWnd, IDC_DEPTHCOMPARE_COMBO, CB_SETCURSEL, TheMtl->Get_Depth_Compare(PassIndex), 0 );
SendDlgItemMessage(m_hWnd, IDC_DETAILCOLOR_COMBO, CB_SETCURSEL, TheMtl->Get_Detail_Color_Func(PassIndex), 0 );
SendDlgItemMessage(m_hWnd, IDC_DETAILALPHA_COMBO, CB_SETCURSEL, TheMtl->Get_Detail_Alpha_Func(PassIndex), 0 );
Set_Preset();
SetCheckBox(m_hWnd,IDC_DEPTHMASK_CHECK, TheMtl->Get_Depth_Mask(PassIndex));
SetCheckBox(m_hWnd,IDC_ALPHATEST_CHECK, TheMtl->Get_Alpha_Test(PassIndex));
}
/***********************************************************************************************
* GameMtlShaderDlg::ActivateDlg -- activate/deactivate the dialog *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 11/23/98 GTH : Created. *
*=============================================================================================*/
void GameMtlShaderDlg::ActivateDlg(BOOL onoff)
{
// shader has no color swatches which need to be activated...
}
/***********************************************************************************************
* GameMtlShaderDlg::Apply_Preset -- apply a preset shader setting *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 11/23/98 GTH : Created. *
*=============================================================================================*/
void GameMtlShaderDlg::Apply_Preset(int preset_index)
{
if (preset_index < 0 || preset_index >= NUM_SHADER_BLEND_PRESETS) return;
const ShaderBlendSettingPreset &preset = ShaderBlendSettingPresets[preset_index];
TheMtl->Set_Src_Blend(PassIndex, preset.SrcBlend);
TheMtl->Set_Dest_Blend(PassIndex, preset.DestBlend);
int depth_mask = preset.DepthMask ? W3DSHADER_DEPTHMASK_WRITE_ENABLE : W3DSHADER_DEPTHMASK_WRITE_DISABLE;
TheMtl->Set_Depth_Mask(PassIndex, depth_mask);
int alpha_test = preset.AlphaTest ? W3DSHADER_ALPHATEST_ENABLE : W3DSHADER_ALPHATEST_DISABLE;
TheMtl->Set_Alpha_Test(PassIndex, alpha_test);
TheMtl->Notify_Changed();
ReloadDialog();
}
/***********************************************************************************************
* GameMtlShaderDlg::Set_Preset -- determine preset shader setting from game material *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 02/26/99 NH : Created. *
*=============================================================================================*/
void GameMtlShaderDlg::Set_Preset(void)
{
for (int i = 0; i < NUM_SHADER_BLEND_PRESETS; i++) {
if (CompareShaderToBlendPreset(ShaderBlendSettingPresets[i])) break;
}
SendDlgItemMessage(m_hWnd, IDC_PRESET_COMBO, CB_SETCURSEL, i, 0);
}
/***********************************************************************************************
* GameMtlShaderDlg::CompareShaderToBlendPreset -- compare preset to game material shader *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 02/26/99 NH : Created. *
*=============================================================================================*/
bool GameMtlShaderDlg::CompareShaderToBlendPreset(const ShaderBlendSettingPreset &blend_preset)
{
if (TheMtl->Get_Src_Blend(PassIndex) != blend_preset.SrcBlend) return false;
if (TheMtl->Get_Dest_Blend(PassIndex) != blend_preset.DestBlend) return false;
bool depthmask = TheMtl->Get_Depth_Mask(PassIndex) != W3DSHADER_DEPTHMASK_WRITE_DISABLE;
if (depthmask != blend_preset.DepthMask) return false;
bool alphatest = TheMtl->Get_Alpha_Test(PassIndex) != W3DSHADER_ALPHATEST_DISABLE;
if (alphatest != blend_preset.AlphaTest) return false;
return true;
}
/***********************************************************************************************
* GameMtlShaderDlg::Set_Advanced_Defaults -- set advanced settings to defaults *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 02/26/99 NH : Created. *
*=============================================================================================*/
void GameMtlShaderDlg::Set_Advanced_Defaults(void)
{
TheMtl->Set_Pri_Gradient(PassIndex, W3DSHADER_PRIGRADIENT_DEFAULT);
TheMtl->Set_Sec_Gradient(PassIndex, W3DSHADER_SECGRADIENT_DEFAULT);
TheMtl->Set_Depth_Compare(PassIndex, W3DSHADER_DEPTHCOMPARE_DEFAULT);
TheMtl->Set_Detail_Color_Func(PassIndex, W3DSHADER_DETAILCOLORFUNC_DEFAULT);
TheMtl->Set_Detail_Alpha_Func(PassIndex, W3DSHADER_DETAILALPHAFUNC_DEFAULT);
TheMtl->Notify_Changed();
ReloadDialog();
}

View file

@ -0,0 +1,70 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Max2W3d *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/GameMtlShaderDlg.h $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 2/26/99 7:00p $*
* *
* $Revision:: 5 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef GAMEMTLSHADERDLG_H
#define GAMEMTLSHADERDLG_H
#include <Max.h>
#include "GameMtlForm.h"
class GameMtl;
struct ShaderBlendSettingPreset;
class GameMtlShaderDlg : public GameMtlFormClass
{
public:
GameMtlShaderDlg(HWND parent, IMtlParams * imp, GameMtl * m, int pass);
~GameMtlShaderDlg();
virtual BOOL Dialog_Proc (HWND dlg_wnd, UINT message, WPARAM wparam, LPARAM lparam);
void ActivateDlg(BOOL onOff);
void ReloadDialog(void);
private:
void Apply_Preset(int preset_index);
void Set_Preset(void);
bool CompareShaderToBlendPreset(const ShaderBlendSettingPreset &blend_preset);
void Set_Advanced_Defaults(void);
};
#endif

View file

@ -0,0 +1,667 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Max2W3d *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/GameMtlTextureDlg.cpp $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 8/14/00 1:47p $*
* *
* $Revision:: 15 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* GameMtlTextureDlg::GameMtlTextureDlg -- constructor *
* GameMtlTextureDlg::~GameMtlTextureDlg -- destructor *
* GameMtlTextureDlg::Dialog_Proc -- windows message handler *
* GameMtlTextureDlg::ReloadDialog -- reload the contents of all of the controls in this dia *
* GameMtlTextureDlg::ActivateDlg -- activate/deactivate this dialog *
* GameMtlTextureDlg::Enable_Stage -- enable or disable a texture stage *
* GameMtlTextureDlg::Update_Texture_Buttons -- update the texture buttons text *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "GameMtlTextureDlg.h"
#include "GameMtl.h"
#include "dllmain.h"
#include "resource.h"
#include <Max.h>
#include <bmmlib.h>
#include <stdmat.h>
/***********************************************************************************************
* GameMtlTextureDlg::GameMtlTextureDlg -- constructor *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 11/23/98 GTH : Created. *
*=============================================================================================*/
GameMtlTextureDlg::GameMtlTextureDlg
(
HWND parent,
IMtlParams * imp,
GameMtl * mtl,
int pass
) :
GameMtlFormClass(imp,mtl,pass)
{
Stage0FramesSpin = NULL;
Stage1FramesSpin = NULL;
Stage0RateSpin = NULL;
Stage1RateSpin = NULL;
Stage0PublishButton = NULL;
Stage1PublishButton = NULL;
Stage0ClampUButton = NULL;
Stage1ClampUButton = NULL;
Stage0ClampVButton = NULL;
Stage1ClampVButton = NULL;
Stage0NoLODButton = NULL;
Stage1NoLODButton = NULL;
Stage0AlphaBitmapButton = NULL;
Stage1AlphaBitmapButton = NULL;
Stage0DisplayButton = NULL;
Stage1DisplayButton = NULL;
if (mtl->Get_Shader_Type() == GameMtl::STE_PC_SHADER) {
Create_Form(parent,IDD_GAMEMTL_TEXTURES);
} else {
// Use the PS2 dialog. It is the same but it disables some functions that aren't
// supported yet.
Create_Form(parent,IDD_GAMEMTL_PS2_TEXTURES);
}
}
/***********************************************************************************************
* GameMtlTextureDlg::~GameMtlTextureDlg -- destructor *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 11/23/98 GTH : Created. *
*=============================================================================================*/
GameMtlTextureDlg::~GameMtlTextureDlg()
{
assert(Stage0FramesSpin && Stage1FramesSpin && Stage0RateSpin && Stage1RateSpin);
ReleaseISpinner(Stage0FramesSpin);
ReleaseISpinner(Stage1FramesSpin);
ReleaseISpinner(Stage0RateSpin);
ReleaseISpinner(Stage1RateSpin);
ReleaseICustButton(Stage0PublishButton);
ReleaseICustButton(Stage1PublishButton);
ReleaseICustButton(Stage0ClampUButton);
ReleaseICustButton(Stage1ClampUButton);
ReleaseICustButton(Stage0ClampVButton);
ReleaseICustButton(Stage1ClampVButton);
ReleaseICustButton(Stage0NoLODButton);
ReleaseICustButton(Stage1NoLODButton);
ReleaseICustButton(Stage0AlphaBitmapButton);
ReleaseICustButton(Stage1AlphaBitmapButton);
ReleaseICustButton(Stage0DisplayButton);
ReleaseICustButton(Stage1DisplayButton);
}
/***********************************************************************************************
* GameMtlTextureDlg::Dialog_Proc -- windows message handler *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 11/23/98 GTH : Created. *
* 10/6/1999 MLL: Turned off the display button when the texture is turned off. *
*=============================================================================================*/
BOOL GameMtlTextureDlg::Dialog_Proc (HWND dlg_wnd, UINT message, WPARAM wparam, LPARAM lparam)
{
int cursel;
int id = LOWORD(wparam);
int code = HIWORD(wparam);
switch (message)
{
case WM_INITDIALOG:
{
Stage0FramesSpin = SetupIntSpinner( dlg_wnd,
IDC_STAGE0_FRAMES_SPIN,
IDC_STAGE0_FRAMES_EDIT,
1,999,
TheMtl->Get_Texture_Frame_Count(PassIndex,0) );
Stage0RateSpin = SetupFloatSpinner( dlg_wnd,
IDC_STAGE0_RATE_SPIN,
IDC_STAGE0_RATE_EDIT,
0.0f,60.0f,
TheMtl->Get_Texture_Frame_Rate(PassIndex,0),
1.0f );
Stage1FramesSpin = SetupIntSpinner( dlg_wnd,
IDC_STAGE1_FRAMES_SPIN,
IDC_STAGE1_FRAMES_EDIT,
1,999,
TheMtl->Get_Texture_Frame_Count(PassIndex,1) );
Stage1RateSpin = SetupFloatSpinner( dlg_wnd,
IDC_STAGE1_RATE_SPIN,
IDC_STAGE1_RATE_EDIT,
0.0f,60.0f,
TheMtl->Get_Texture_Frame_Rate(PassIndex,1),
1.0f );
Stage0PublishButton = GetICustButton(GetDlgItem(dlg_wnd, IDC_STAGE0_PUBLISH_BUTTON));
Stage0PublishButton->SetType(CBT_CHECK);
Stage0PublishButton->SetHighlightColor(GREEN_WASH);
Stage0PublishButton->SetCheck(TheMtl->Get_Texture_Publish(PassIndex,0));
Stage0PublishButton->SetText(Get_String(IDS_PUBLISH));
Stage1PublishButton = GetICustButton(GetDlgItem(dlg_wnd, IDC_STAGE1_PUBLISH_BUTTON));
Stage1PublishButton->SetType(CBT_CHECK);
Stage1PublishButton->SetHighlightColor(GREEN_WASH);
Stage1PublishButton->SetCheck(TheMtl->Get_Texture_Publish(PassIndex,1));
Stage1PublishButton->SetText(Get_String(IDS_PUBLISH));
Stage0ClampUButton = GetICustButton(GetDlgItem(dlg_wnd, IDC_STAGE0_CLAMP_U_BUTTON));
Stage0ClampUButton->SetType(CBT_CHECK);
Stage0ClampUButton->SetHighlightColor(GREEN_WASH);
Stage0ClampUButton->SetCheck(TheMtl->Get_Texture_Clamp_U(PassIndex,0));
Stage0ClampUButton->SetText(Get_String(IDS_CLAMP_U));
Stage1ClampUButton = GetICustButton(GetDlgItem(dlg_wnd, IDC_STAGE1_CLAMP_U_BUTTON));
Stage1ClampUButton->SetType(CBT_CHECK);
Stage1ClampUButton->SetHighlightColor(GREEN_WASH);
Stage1ClampUButton->SetCheck(TheMtl->Get_Texture_Clamp_U(PassIndex,1));
Stage1ClampUButton->SetText(Get_String(IDS_CLAMP_U));
Stage0ClampVButton = GetICustButton(GetDlgItem(dlg_wnd, IDC_STAGE0_CLAMP_V_BUTTON));
Stage0ClampVButton->SetType(CBT_CHECK);
Stage0ClampVButton->SetHighlightColor(GREEN_WASH);
Stage0ClampVButton->SetCheck(TheMtl->Get_Texture_Clamp_V(PassIndex,0));
Stage0ClampVButton->SetText(Get_String(IDS_CLAMP_V));
Stage1ClampVButton = GetICustButton(GetDlgItem(dlg_wnd, IDC_STAGE1_CLAMP_V_BUTTON));
Stage1ClampVButton->SetType(CBT_CHECK);
Stage1ClampVButton->SetHighlightColor(GREEN_WASH);
Stage1ClampVButton->SetCheck(TheMtl->Get_Texture_Clamp_V(PassIndex,1));
Stage1ClampVButton->SetText(Get_String(IDS_CLAMP_V));
Stage0NoLODButton = GetICustButton(GetDlgItem(dlg_wnd, IDC_STAGE0_NOLOD_BUTTON));
Stage0NoLODButton->SetType(CBT_CHECK);
Stage0NoLODButton->SetHighlightColor(GREEN_WASH);
Stage0NoLODButton->SetCheck(TheMtl->Get_Texture_No_LOD(PassIndex,0));
Stage0NoLODButton->SetText(Get_String(IDS_NO_LOD));
Stage1NoLODButton = GetICustButton(GetDlgItem(dlg_wnd, IDC_STAGE1_NOLOD_BUTTON));
Stage1NoLODButton->SetType(CBT_CHECK);
Stage1NoLODButton->SetHighlightColor(GREEN_WASH);
Stage1NoLODButton->SetCheck(TheMtl->Get_Texture_No_LOD(PassIndex,0));
Stage1NoLODButton->SetText(Get_String(IDS_NO_LOD));
Stage0AlphaBitmapButton = GetICustButton(GetDlgItem(dlg_wnd, IDC_STAGE0_ALPHA_BITMAP_BUTTON));
Stage0AlphaBitmapButton->SetType(CBT_CHECK);
Stage0AlphaBitmapButton->SetHighlightColor(GREEN_WASH);
Stage0AlphaBitmapButton->SetCheck(TheMtl->Get_Texture_Alpha_Bitmap(PassIndex,0));
Stage0AlphaBitmapButton->SetText(Get_String(IDS_ALPHA_BITMAP));
Stage1AlphaBitmapButton = GetICustButton(GetDlgItem(dlg_wnd, IDC_STAGE1_ALPHA_BITMAP_BUTTON));
Stage1AlphaBitmapButton->SetType(CBT_CHECK);
Stage1AlphaBitmapButton->SetHighlightColor(GREEN_WASH);
Stage1AlphaBitmapButton->SetCheck(TheMtl->Get_Texture_Alpha_Bitmap(PassIndex,1));
Stage1AlphaBitmapButton->SetText(Get_String(IDS_ALPHA_BITMAP));
Stage0DisplayButton = GetICustButton(GetDlgItem(dlg_wnd, IDC_STAGE0_DISPLAY_BUTTON));
Stage0DisplayButton->SetType(CBT_CHECK);
Stage0DisplayButton->SetHighlightColor(GREEN_WASH);
Stage0DisplayButton->SetCheck(TheMtl->Get_Texture_Display(PassIndex,0));
Stage0DisplayButton->SetText(Get_String(IDS_DISPLAY));
Stage1DisplayButton = GetICustButton(GetDlgItem(dlg_wnd, IDC_STAGE1_DISPLAY_BUTTON));
Stage1DisplayButton->SetType(CBT_CHECK);
Stage1DisplayButton->SetHighlightColor(GREEN_WASH);
Stage1DisplayButton->SetCheck(TheMtl->Get_Texture_Display(PassIndex,1));
Stage1DisplayButton->SetText(Get_String(IDS_DISPLAY));
break;
}
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
case WM_MOUSEMOVE:
{
IParams->RollupMouseMessage(dlg_wnd,message,wparam,lparam);
return FALSE;
}
case CC_SPINNER_CHANGE:
{
TheMtl->Set_Texture_Frame_Count( PassIndex, 0,
Stage0FramesSpin->GetIVal());
TheMtl->Set_Texture_Frame_Rate( PassIndex, 0,
Stage0RateSpin->GetFVal());
TheMtl->Set_Texture_Frame_Count( PassIndex, 1,
Stage1FramesSpin->GetIVal());
TheMtl->Set_Texture_Frame_Rate( PassIndex, 1,
Stage1RateSpin->GetFVal());
break;
}
case CC_SPINNER_BUTTONUP:
{
TheMtl->Notify_Changed();
break;
}
case WM_COMMAND:
{
switch (id)
{
case IDC_STAGE0_BUTTON:
{
BitmapInfo bmi;
BitmapTex * texture;
if (TheManager->SelectFileInput(&bmi, m_hWnd)) {
texture = NewDefaultBitmapTex();
if (texture) {
BOOL disp = TheMtl->Get_Texture_Display(PassIndex,0);
if (disp) {
TheMtl->Set_Texture_Display(PassIndex,0,FALSE);
}
texture->SetMapName((char *)bmi.Name());
int texmap_index = TheMtl->pass_stage_to_texmap_index(PassIndex,0);
TheMtl->SetSubTexmap(texmap_index,texture);
Update_Texture_Buttons();
TheMtl->Notify_Changed();
if (disp) {
TheMtl->Set_Texture_Display(PassIndex,0,TRUE);
TheMtl->Notify_Changed();
}
}
}
break;
}
case IDC_STAGE1_BUTTON:
{
BitmapInfo bmi;
BitmapTex * texture;
if (TheManager->SelectFileInput(&bmi, m_hWnd)) {
texture = NewDefaultBitmapTex();
if (texture) {
BOOL disp = TheMtl->Get_Texture_Display(PassIndex,1);
if (disp) {
TheMtl->Set_Texture_Display(PassIndex,1,FALSE);
}
texture->SetMapName((char *)bmi.Name());
int texmap_index = TheMtl->pass_stage_to_texmap_index(PassIndex,1);
TheMtl->SetSubTexmap(texmap_index,texture);
Update_Texture_Buttons();
TheMtl->Notify_Changed();
if (disp) {
TheMtl->Set_Texture_Display(PassIndex,1,TRUE);
TheMtl->Notify_Changed();
}
}
}
break;
}
case IDC_STAGE0_ENABLE:
{
int checkbox = GetCheckBox(dlg_wnd,IDC_STAGE0_ENABLE);
Enable_Stage(0,(checkbox == TRUE ? true : false) );
// If the texture stage is turned off, turn off the Display button so that it won't
// show up in the viewport.
if (checkbox == FALSE) {
TheMtl->Set_Texture_Display(PassIndex, 0, FALSE);
TheMtl->Notify_Changed();
}
break;
}
case IDC_STAGE1_ENABLE:
{
int checkbox = GetCheckBox(dlg_wnd,IDC_STAGE1_ENABLE);
Enable_Stage(1,(checkbox == TRUE ? true : false) );
// If the texture stage is turned off, turn off the Display button so that it won't
// show up in the viewport.
if (checkbox == FALSE) {
TheMtl->Set_Texture_Display(PassIndex, 1, FALSE);
TheMtl->Notify_Changed();
}
break;
}
case IDC_STAGE0_PUBLISH_BUTTON:
{
TheMtl->Set_Texture_Publish(PassIndex,0,(Stage0PublishButton->IsChecked() ? TRUE : FALSE));
break;
}
case IDC_STAGE1_PUBLISH_BUTTON:
{
TheMtl->Set_Texture_Publish(PassIndex,1,(Stage1PublishButton->IsChecked() ? TRUE : FALSE));
break;
}
case IDC_STAGE0_CLAMP_U_BUTTON:
{
TheMtl->Set_Texture_Clamp_U(PassIndex,0,(Stage0ClampUButton->IsChecked() ? TRUE : FALSE));
break;
}
case IDC_STAGE1_CLAMP_U_BUTTON:
{
TheMtl->Set_Texture_Clamp_U(PassIndex,1,(Stage1ClampUButton->IsChecked() ? TRUE : FALSE));
break;
}
case IDC_STAGE0_CLAMP_V_BUTTON:
{
TheMtl->Set_Texture_Clamp_V(PassIndex,0,(Stage0ClampVButton->IsChecked() ? TRUE : FALSE));
break;
}
case IDC_STAGE1_CLAMP_V_BUTTON:
{
TheMtl->Set_Texture_Clamp_V(PassIndex,1,(Stage1ClampVButton->IsChecked() ? TRUE : FALSE));
break;
}
case IDC_STAGE0_NOLOD_BUTTON:
{
TheMtl->Set_Texture_No_LOD(PassIndex,0,(Stage0NoLODButton->IsChecked() ? TRUE : FALSE));
break;
}
case IDC_STAGE1_NOLOD_BUTTON:
{
TheMtl->Set_Texture_No_LOD(PassIndex,1,(Stage1NoLODButton->IsChecked() ? TRUE : FALSE));
break;
}
case IDC_STAGE0_ALPHA_BITMAP_BUTTON:
{
TheMtl->Set_Texture_Alpha_Bitmap(PassIndex,0,(Stage0AlphaBitmapButton->IsChecked() ? TRUE : FALSE));
break;
}
case IDC_STAGE1_ALPHA_BITMAP_BUTTON:
{
TheMtl->Set_Texture_Alpha_Bitmap(PassIndex,1,(Stage0AlphaBitmapButton->IsChecked() ? TRUE : FALSE));
break;
}
case IDC_STAGE0_DISPLAY_BUTTON:
{
TheMtl->Set_Texture_Display(PassIndex,0,(Stage0DisplayButton->IsChecked() ? TRUE : FALSE));
TheMtl->Notify_Changed();
break;
}
case IDC_STAGE1_DISPLAY_BUTTON:
{
TheMtl->Set_Texture_Display(PassIndex,1,(Stage1DisplayButton->IsChecked() ? TRUE : FALSE));
TheMtl->Notify_Changed();
break;
}
case IDC_STAGE0_ANIM_COMBO:
{
if (code == CBN_SELCHANGE) {
cursel = SendDlgItemMessage(dlg_wnd,IDC_STAGE0_ANIM_COMBO,CB_GETCURSEL,0,0);
TheMtl->Set_Texture_Anim_Type(PassIndex,0,cursel);
}
break;
}
case IDC_STAGE1_ANIM_COMBO:
{
if (code == CBN_SELCHANGE) {
cursel = SendDlgItemMessage(dlg_wnd,IDC_STAGE1_ANIM_COMBO,CB_GETCURSEL,0,0);
TheMtl->Set_Texture_Anim_Type(PassIndex,1,cursel);
}
break;
}
case IDC_STAGE0_HINT_COMBO:
{
if (code == CBN_SELCHANGE) {
cursel = SendDlgItemMessage(dlg_wnd,IDC_STAGE0_HINT_COMBO,CB_GETCURSEL,0,0);
TheMtl->Set_Texture_Hint(PassIndex,0,cursel);
}
break;
}
case IDC_STAGE1_HINT_COMBO:
{
if (code == CBN_SELCHANGE) {
cursel = SendDlgItemMessage(dlg_wnd,IDC_STAGE1_HINT_COMBO,CB_GETCURSEL,0,0);
TheMtl->Set_Texture_Hint(PassIndex,1,cursel);
}
break;
}
}
break;
}
}
return FALSE;
}
/***********************************************************************************************
* GameMtlTextureDlg::ReloadDialog -- reload the contents of all of the controls in this dialo *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 11/23/98 GTH : Created. *
*=============================================================================================*/
void GameMtlTextureDlg::ReloadDialog(void)
{
DebugPrint("GameMtlTextureDlg::ReloadDialog\n");
assert(Stage0FramesSpin && Stage1FramesSpin && Stage0RateSpin && Stage1RateSpin);
Stage0FramesSpin->SetValue(TheMtl->Get_Texture_Frame_Count(PassIndex,0),FALSE);
Stage1FramesSpin->SetValue(TheMtl->Get_Texture_Frame_Count(PassIndex,1),FALSE);
Stage0RateSpin->SetValue(TheMtl->Get_Texture_Frame_Rate(PassIndex,0),FALSE);
Stage1RateSpin->SetValue(TheMtl->Get_Texture_Frame_Rate(PassIndex,1),FALSE);
SendDlgItemMessage( m_hWnd,
IDC_STAGE0_ANIM_COMBO,
CB_SETCURSEL,
TheMtl->Get_Texture_Anim_Type(PassIndex,0), 0 );
SendDlgItemMessage( m_hWnd,
IDC_STAGE1_ANIM_COMBO,
CB_SETCURSEL,
TheMtl->Get_Texture_Anim_Type(PassIndex,1), 0 );
SendDlgItemMessage( m_hWnd,
IDC_STAGE0_HINT_COMBO,
CB_SETCURSEL,
TheMtl->Get_Texture_Hint(PassIndex,0), 0 );
SendDlgItemMessage( m_hWnd,
IDC_STAGE1_HINT_COMBO,
CB_SETCURSEL,
TheMtl->Get_Texture_Hint(PassIndex,1), 0 );
SetCheckBox(m_hWnd,IDC_STAGE0_ENABLE, TheMtl->Get_Texture_Enable(PassIndex,0));
SetCheckBox(m_hWnd,IDC_STAGE1_ENABLE, TheMtl->Get_Texture_Enable(PassIndex,1));
Stage0PublishButton->SetCheck(TheMtl->Get_Texture_Publish(PassIndex,0));
Stage1PublishButton->SetCheck(TheMtl->Get_Texture_Publish(PassIndex,1));
Stage0ClampUButton->SetCheck(TheMtl->Get_Texture_Clamp_U(PassIndex,0));
Stage1ClampUButton->SetCheck(TheMtl->Get_Texture_Clamp_U(PassIndex,1));
Stage0ClampVButton->SetCheck(TheMtl->Get_Texture_Clamp_V(PassIndex,0));
Stage1ClampVButton->SetCheck(TheMtl->Get_Texture_Clamp_V(PassIndex,1));
Stage0NoLODButton->SetCheck(TheMtl->Get_Texture_No_LOD(PassIndex,0));
Stage1NoLODButton->SetCheck(TheMtl->Get_Texture_No_LOD(PassIndex,1));
Stage0AlphaBitmapButton->SetCheck(TheMtl->Get_Texture_Alpha_Bitmap(PassIndex,0));
Stage1AlphaBitmapButton->SetCheck(TheMtl->Get_Texture_Alpha_Bitmap(PassIndex,1));
Stage0DisplayButton->SetCheck(TheMtl->Get_Texture_Display(PassIndex,0));
Stage1DisplayButton->SetCheck(TheMtl->Get_Texture_Display(PassIndex,1));
Update_Texture_Buttons();
Enable_Stage(0,TheMtl->Get_Texture_Enable(PassIndex,0));
Enable_Stage(1,TheMtl->Get_Texture_Enable(PassIndex,1));
}
/***********************************************************************************************
* GameMtlTextureDlg::ActivateDlg -- activate/deactivate this dialog *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 11/23/98 GTH : Created. *
*=============================================================================================*/
void GameMtlTextureDlg::ActivateDlg(BOOL onOff)
{
// no color swatches to activate.
}
/***********************************************************************************************
* GameMtlTextureDlg::Enable_Stage -- enable or disable a texture stage *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 11/23/98 GTH : Created. *
*=============================================================================================*/
void GameMtlTextureDlg::Enable_Stage(int stage,BOOL onoff)
{
assert((stage >= 0) && (stage < W3dMaterialClass::MAX_STAGES));
TheMtl->Set_Texture_Enable(PassIndex,stage,(onoff == TRUE ? true : false));
if (stage == 0) {
EnableWindow(GetDlgItem(m_hWnd,IDC_STAGE0_BUTTON),onoff);
// Turn these off if it is a playstation 2 shader.
// These aren't supported yet.
if (TheMtl->Get_Shader_Type() == GameMtl::STE_PC_SHADER) {
EnableWindow(GetDlgItem(m_hWnd,IDC_STAGE0_RATE_SPIN), onoff);
EnableWindow(GetDlgItem(m_hWnd,IDC_STAGE0_RATE_EDIT), onoff);
EnableWindow(GetDlgItem(m_hWnd,IDC_STAGE0_FRAMES_SPIN), onoff);
EnableWindow(GetDlgItem(m_hWnd,IDC_STAGE0_FRAMES_EDIT), onoff);
EnableWindow(GetDlgItem(m_hWnd,IDC_STAGE0_ANIM_COMBO), onoff);
} else {
EnableWindow(GetDlgItem(m_hWnd,IDC_STAGE0_RATE_SPIN), FALSE);
EnableWindow(GetDlgItem(m_hWnd,IDC_STAGE0_RATE_EDIT), FALSE);
EnableWindow(GetDlgItem(m_hWnd,IDC_STAGE0_FRAMES_SPIN), FALSE);
EnableWindow(GetDlgItem(m_hWnd,IDC_STAGE0_FRAMES_EDIT), FALSE);
EnableWindow(GetDlgItem(m_hWnd,IDC_STAGE0_ANIM_COMBO), FALSE);
}
EnableWindow(GetDlgItem(m_hWnd,IDC_STAGE0_PUBLISH_BUTTON),onoff);
EnableWindow(GetDlgItem(m_hWnd,IDC_STAGE0_CLAMP_U_BUTTON),onoff);
EnableWindow(GetDlgItem(m_hWnd,IDC_STAGE0_CLAMP_V_BUTTON),onoff);
EnableWindow(GetDlgItem(m_hWnd,IDC_STAGE0_NOLOD_BUTTON),onoff);
EnableWindow(GetDlgItem(m_hWnd,IDC_STAGE0_ALPHA_BITMAP_BUTTON),onoff);
EnableWindow(GetDlgItem(m_hWnd,IDC_STAGE0_DISPLAY_BUTTON),onoff);
EnableWindow(GetDlgItem(m_hWnd,IDC_STAGE0_HINT_COMBO),onoff);
} else {
EnableWindow(GetDlgItem(m_hWnd,IDC_STAGE1_BUTTON),onoff);
EnableWindow(GetDlgItem(m_hWnd,IDC_STAGE1_RATE_SPIN),onoff);
EnableWindow(GetDlgItem(m_hWnd,IDC_STAGE1_RATE_EDIT),onoff);
EnableWindow(GetDlgItem(m_hWnd,IDC_STAGE1_FRAMES_SPIN),onoff);
EnableWindow(GetDlgItem(m_hWnd,IDC_STAGE1_FRAMES_EDIT),onoff);
EnableWindow(GetDlgItem(m_hWnd,IDC_STAGE1_PUBLISH_BUTTON),onoff);
EnableWindow(GetDlgItem(m_hWnd,IDC_STAGE1_CLAMP_U_BUTTON),onoff);
EnableWindow(GetDlgItem(m_hWnd,IDC_STAGE1_CLAMP_V_BUTTON),onoff);
EnableWindow(GetDlgItem(m_hWnd,IDC_STAGE1_NOLOD_BUTTON),onoff);
EnableWindow(GetDlgItem(m_hWnd,IDC_STAGE1_ALPHA_BITMAP_BUTTON),onoff);
EnableWindow(GetDlgItem(m_hWnd,IDC_STAGE1_DISPLAY_BUTTON),onoff);
EnableWindow(GetDlgItem(m_hWnd,IDC_STAGE1_ANIM_COMBO),onoff);
EnableWindow(GetDlgItem(m_hWnd,IDC_STAGE1_HINT_COMBO),onoff);
}
}
/***********************************************************************************************
* GameMtlTextureDlg::Update_Texture_Buttons -- update the texture buttons text *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 11/23/98 GTH : Created. *
*=============================================================================================*/
void GameMtlTextureDlg::Update_Texture_Buttons(void)
{
Texmap * texmap;
texmap = TheMtl->Get_Texture(PassIndex,0);
TSTR filename;
if (texmap) {
SplitPathFile(texmap->GetFullName(),NULL,&filename);
SetDlgItemText(m_hWnd, IDC_STAGE0_BUTTON,filename);
} else {
SetDlgItemText(m_hWnd, IDC_STAGE0_BUTTON,Get_String(IDS_NONE));
}
texmap = TheMtl->Get_Texture(PassIndex,1);
if (texmap) {
SplitPathFile(texmap->GetFullName(),NULL,&filename);
SetDlgItemText(m_hWnd, IDC_STAGE1_BUTTON,filename);
} else {
SetDlgItemText(m_hWnd, IDC_STAGE1_BUTTON,Get_String(IDS_NONE));
}
}

View file

@ -0,0 +1,90 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Max2W3d *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/GameMtlTextureDlg.h $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 8/14/00 1:47p $*
* *
* $Revision:: 8 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef GAMEMTLTEXTUREDLG_H
#define GAMEMTLTEXTUREDLG_H
#include <Max.h>
#include "GameMtlForm.h"
class GameMtl;
class GameMtlTextureDlg : public GameMtlFormClass
{
public:
GameMtlTextureDlg(HWND parent, IMtlParams * imp, GameMtl * m, int pass);
~GameMtlTextureDlg(void);
virtual BOOL Dialog_Proc (HWND dlg_wnd, UINT message, WPARAM wparam, LPARAM lparam);
void ActivateDlg(BOOL onOff);
void ReloadDialog(void);
private:
void Enable_Stage(int stage,BOOL onoff);
void Update_Texture_Buttons(void);
ISpinnerControl * Stage0FramesSpin;
ISpinnerControl * Stage1FramesSpin;
ISpinnerControl * Stage0RateSpin;
ISpinnerControl * Stage1RateSpin;
ICustButton * Stage0PublishButton;
ICustButton * Stage1PublishButton;
ICustButton * Stage0ClampUButton;
ICustButton * Stage1ClampUButton;
ICustButton * Stage0ClampVButton;
ICustButton * Stage1ClampVButton;
ICustButton * Stage0NoLODButton;
ICustButton * Stage1NoLODButton;
ICustButton * Stage0AlphaBitmapButton;
ICustButton * Stage1AlphaBitmapButton;
ICustButton * Stage0DisplayButton;
ICustButton * Stage1DisplayButton;
};
#endif

View file

@ -0,0 +1,392 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Max2W3d *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/GameMtlVertexMaterialDlg.cpp $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 7/10/00 3:37p $*
* *
* $Revision:: 12 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* GameMtlVertexMaterialDlg::GameMtlVertexMaterialDlg -- constructor *
* GameMtlVertexMaterialDlg::~GameMtlVertexMaterialDlg -- destructor *
* GameMtlVertexMaterialDlg::Dialog_Proc -- windows message handler *
* GameMtlVertexMaterialDlg::ReloadDialog -- reload the contents of the controls *
* GameMtlVertexMaterialDlg::ActivateDlg -- activate / deactivate this dialog *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "GameMtlVertexMaterialDlg.h"
#include "GameMtl.h"
#include "dllmain.h"
#include "resource.h"
/***********************************************************************************************
* GameMtlVertexMaterialDlg::GameMtlVertexMaterialDlg -- constructor *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 11/23/98 GTH : Created. *
*=============================================================================================*/
GameMtlVertexMaterialDlg::GameMtlVertexMaterialDlg
(
HWND parent,
IMtlParams * imp,
GameMtl * mtl,
int pass
) :
GameMtlFormClass(imp,mtl,pass)
{
AmbientSwatch = NULL;
DiffuseSwatch = NULL;
SpecularSwatch = NULL;
EmissiveSwatch = NULL;
OpacitySpin = NULL;
TranslucencySpin = NULL;
ShininessSpin = NULL;
for (int i=0; i<MAX_STAGES; i++) {
UVChannelSpin[i] = NULL;
}
Create_Form(parent,IDD_GAMEMTL_VERTEX_MATERIAL);
}
/***********************************************************************************************
* GameMtlVertexMaterialDlg::~GameMtlVertexMaterialDlg -- destructor *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 11/23/98 GTH : Created. *
*=============================================================================================*/
GameMtlVertexMaterialDlg::~GameMtlVertexMaterialDlg()
{
if (AmbientSwatch) {
ReleaseIColorSwatch(AmbientSwatch);
}
if (DiffuseSwatch) {
ReleaseIColorSwatch(DiffuseSwatch);
}
if (SpecularSwatch) {
ReleaseIColorSwatch(SpecularSwatch);
}
if (EmissiveSwatch) {
ReleaseIColorSwatch(EmissiveSwatch);
}
if (OpacitySpin) {
ReleaseISpinner(OpacitySpin);
}
if (TranslucencySpin) {
ReleaseISpinner(TranslucencySpin);
}
if (ShininessSpin) {
ReleaseISpinner(ShininessSpin);
}
for (int i=0; i<MAX_STAGES; i++) {
if (UVChannelSpin[i] != NULL) {
ReleaseISpinner(UVChannelSpin[i]);
}
}
}
/***********************************************************************************************
* GameMtlVertexMaterialDlg::Dialog_Proc -- windows message handler *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 11/23/98 GTH : Created. *
*=============================================================================================*/
BOOL GameMtlVertexMaterialDlg::Dialog_Proc(HWND dlg_wnd, UINT message, WPARAM wparam, LPARAM lparam)
{
int val;
int id = LOWORD(wparam);
int code = HIWORD(wparam);
switch (message)
{
case WM_INITDIALOG:
{
AmbientSwatch = GetIColorSwatch(GetDlgItem(dlg_wnd, IDC_AMBIENT_COLOR),TheMtl->Get_Ambient(PassIndex,IParams->GetTime()),Get_String(IDS_AMBIENT_COLOR));
DiffuseSwatch = GetIColorSwatch(GetDlgItem(dlg_wnd, IDC_DIFFUSE_COLOR),TheMtl->Get_Diffuse(PassIndex,IParams->GetTime()),Get_String(IDS_DIFFUSE_COLOR));
SpecularSwatch = GetIColorSwatch(GetDlgItem(dlg_wnd, IDC_SPECULAR_COLOR),TheMtl->Get_Specular(PassIndex,IParams->GetTime()),Get_String(IDS_SPECULAR_COLOR));
EmissiveSwatch = GetIColorSwatch(GetDlgItem(dlg_wnd, IDC_EMISSIVE_COLOR),TheMtl->Get_Emissive(PassIndex,IParams->GetTime()),Get_String(IDS_EMISSIVE_COLOR));
OpacitySpin = SetupFloatSpinner(dlg_wnd,IDC_OPACITY_SPIN,IDC_OPACITY_EDIT,0.0f,1.0f,TheMtl->Get_Opacity(PassIndex,IParams->GetTime()),0.01f);
TranslucencySpin = SetupFloatSpinner(dlg_wnd,IDC_TRANSLUCENCY_SPIN,IDC_TRANSULCENCY_EDIT,0.0f,1.0f,TheMtl->Get_Translucency(PassIndex,IParams->GetTime()),0.01f);
ShininessSpin = SetupFloatSpinner(dlg_wnd,IDC_SHININESS_SPIN,IDC_SHININESS_EDIT,1.0f,1000.0f,TheMtl->Get_Shininess(PassIndex,IParams->GetTime()),1.0f);
UVChannelSpin[0] = SetupIntSpinner(dlg_wnd,IDC_STAGE0UVCHAN_SPIN,IDC_STAGE0UVCHAN_EDIT,1,99,1);
UVChannelSpin[1] = SetupIntSpinner(dlg_wnd,IDC_STAGE1UVCHAN_SPIN,IDC_STAGE1UVCHAN_EDIT,1,99,1);
break;
}
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
case WM_MOUSEMOVE:
{
IParams->RollupMouseMessage(dlg_wnd,message,wparam,lparam);
return FALSE;
}
case WM_COMMAND:
{
switch (id)
{
case IDC_COPY_SPECULAR_DIFFUSE:
TheMtl->Set_Copy_Specular_To_Diffuse(PassIndex,GetCheckBox(dlg_wnd, IDC_COPY_SPECULAR_DIFFUSE) == TRUE);
break;
case IDC_MAPPING0_COMBO:
if (code == CBN_SELCHANGE) {
val = SendDlgItemMessage(dlg_wnd,IDC_MAPPING0_COMBO,CB_GETCURSEL,0,0);
TheMtl->Set_Mapping_Type(PassIndex,0,val);
}
break;
case IDC_MAPPING1_COMBO:
if (code == CBN_SELCHANGE) {
val = SendDlgItemMessage(dlg_wnd,IDC_MAPPING1_COMBO,CB_GETCURSEL,0,0);
TheMtl->Set_Mapping_Type(PassIndex,1,val);
}
break;
case IDC_MAPPING0_ARGS_EDIT:
switch (code) {
case EN_SETFOCUS:
DisableAccelerators();
break;
case EN_KILLFOCUS:
EnableAccelerators();
break;
case EN_CHANGE:
int len = GetWindowTextLength(GetDlgItem(dlg_wnd, IDC_MAPPING0_ARGS_EDIT));
char *buffer = TheMtl->Get_Mapping_Arg_Buffer(PassIndex, 0, len);
GetWindowText(GetDlgItem(dlg_wnd, IDC_MAPPING0_ARGS_EDIT), buffer, len + 1);
break;
}
break;
case IDC_MAPPING1_ARGS_EDIT:
switch (code) {
case EN_SETFOCUS:
DisableAccelerators();
break;
case EN_KILLFOCUS:
EnableAccelerators();
break;
case EN_CHANGE:
int len = GetWindowTextLength(GetDlgItem(dlg_wnd, IDC_MAPPING1_ARGS_EDIT));
char *buffer = TheMtl->Get_Mapping_Arg_Buffer(PassIndex, 1, len);
GetWindowText(GetDlgItem(dlg_wnd, IDC_MAPPING1_ARGS_EDIT), buffer, len + 1);
break;
}
break;
case IDC_NO_TRANS:
TheMtl->Set_PSX_Translucency(PassIndex,GAMEMTL_PSX_TRANS_NONE);
break;
case IDC_100_TRANS:
TheMtl->Set_PSX_Translucency(PassIndex,GAMEMTL_PSX_TRANS_100);
break;
case IDC_50_TRANS:
TheMtl->Set_PSX_Translucency(PassIndex,GAMEMTL_PSX_TRANS_50);
break;
case IDC_25_TRANS:
TheMtl->Set_PSX_Translucency(PassIndex,GAMEMTL_PSX_TRANS_25);
break;
case IDC_MINUS_100_TRANS:
TheMtl->Set_PSX_Translucency(PassIndex,GAMEMTL_PSX_TRANS_MINUS_100);
break;
case IDC_NO_RT_LIGHTING:
TheMtl->Set_PSX_Lighting(PassIndex,!GetCheckBox(dlg_wnd, IDC_NO_RT_LIGHTING));
break;
}
break;
}
case CC_COLOR_CHANGE:
{
// just update all of the colors
TheMtl->Set_Ambient(PassIndex,IParams->GetTime(),AmbientSwatch->GetColor());
TheMtl->Set_Diffuse(PassIndex,IParams->GetTime(),DiffuseSwatch->GetColor());
TheMtl->Set_Specular(PassIndex,IParams->GetTime(),SpecularSwatch->GetColor());
TheMtl->Set_Emissive(PassIndex,IParams->GetTime(),EmissiveSwatch->GetColor());
TheMtl->Notify_Changed();
break;
}
case CC_SPINNER_CHANGE:
{
TheMtl->Set_Shininess(PassIndex,IParams->GetTime(),ShininessSpin->GetFVal());
TheMtl->Set_Opacity(PassIndex,IParams->GetTime(),OpacitySpin->GetFVal());
TheMtl->Set_Translucency(PassIndex,IParams->GetTime(),TranslucencySpin->GetFVal());
for (int i=0; i<MAX_STAGES; i++) {
TheMtl->Set_Map_Channel(PassIndex,i,UVChannelSpin[i]->GetIVal());
}
break;
}
case CC_SPINNER_BUTTONUP:
{
TheMtl->Notify_Changed();
break;
}
}
return FALSE;
}
/***********************************************************************************************
* GameMtlVertexMaterialDlg::ReloadDialog -- reload the contents of the controls *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 11/23/98 GTH : Created. *
*=============================================================================================*/
void GameMtlVertexMaterialDlg::ReloadDialog(void)
{
// Vertex Material Controls
DebugPrint("GameMtlVertexMaterialDlg::ReloadDialog\n");
assert(AmbientSwatch && DiffuseSwatch && SpecularSwatch && EmissiveSwatch);
assert(ShininessSpin && OpacitySpin && TranslucencySpin);
AmbientSwatch->InitColor(TheMtl->Get_Ambient(PassIndex,IParams->GetTime()));
DiffuseSwatch->InitColor(TheMtl->Get_Diffuse(PassIndex,IParams->GetTime()));
SpecularSwatch->InitColor(TheMtl->Get_Specular(PassIndex,IParams->GetTime()));
EmissiveSwatch->InitColor(TheMtl->Get_Emissive(PassIndex,IParams->GetTime()));
ShininessSpin->SetValue(TheMtl->Get_Shininess(PassIndex,IParams->GetTime()),FALSE);
OpacitySpin->SetValue(TheMtl->Get_Opacity(PassIndex,IParams->GetTime()),FALSE);
TranslucencySpin->SetValue(TheMtl->Get_Translucency(PassIndex,IParams->GetTime()),FALSE);
for (int i=0; i<MAX_STAGES; i++) {
UVChannelSpin[i]->SetValue(TheMtl->Get_Map_Channel(PassIndex,i),FALSE);
}
SetCheckBox(m_hWnd,IDC_COPY_SPECULAR_DIFFUSE, TheMtl->Get_Copy_Specular_To_Diffuse(PassIndex));
SendDlgItemMessage( m_hWnd,
IDC_MAPPING0_COMBO,
CB_SETCURSEL,
TheMtl->Get_Mapping_Type(PassIndex, 0),
0 );
SendDlgItemMessage( m_hWnd,
IDC_MAPPING1_COMBO,
CB_SETCURSEL,
TheMtl->Get_Mapping_Type(PassIndex, 1),
0 );
// PSX Controls
SetCheckBox(m_hWnd,IDC_NO_RT_LIGHTING, !TheMtl->Get_PSX_Lighting(PassIndex));
SetCheckBox(m_hWnd,IDC_NO_TRANS, false);
SetCheckBox(m_hWnd,IDC_100_TRANS, false);
SetCheckBox(m_hWnd,IDC_50_TRANS, false);
SetCheckBox(m_hWnd,IDC_25_TRANS, false);
SetCheckBox(m_hWnd,IDC_MINUS_100_TRANS, false);
switch (TheMtl->Get_PSX_Translucency(PassIndex)) {
case 0:
SetCheckBox(m_hWnd,IDC_NO_TRANS,true);
break;
case GAMEMTL_PSX_TRANS_100:
SetCheckBox(m_hWnd,IDC_100_TRANS,true);
break;
case GAMEMTL_PSX_TRANS_50:
SetCheckBox(m_hWnd,IDC_50_TRANS,true);
break;
case GAMEMTL_PSX_TRANS_25:
SetCheckBox(m_hWnd,IDC_25_TRANS,true);
break;
case GAMEMTL_PSX_TRANS_MINUS_100:
SetCheckBox(m_hWnd,IDC_MINUS_100_TRANS,true);
break;
}
// Reload contents of mapper args edit box:
char *buffer = TheMtl->Get_Mapping_Arg_Buffer(PassIndex, 0);
SetWindowText(GetDlgItem(m_hWnd, IDC_MAPPING0_ARGS_EDIT), buffer);
buffer = TheMtl->Get_Mapping_Arg_Buffer(PassIndex, 1);
SetWindowText(GetDlgItem(m_hWnd, IDC_MAPPING1_ARGS_EDIT), buffer);
}
/***********************************************************************************************
* GameMtlVertexMaterialDlg::ActivateDlg -- activate / deactivate this dialog *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 11/23/98 GTH : Created. *
*=============================================================================================*/
void GameMtlVertexMaterialDlg::ActivateDlg(BOOL onoff)
{
if (AmbientSwatch) {
AmbientSwatch->Activate(onoff);
}
if (DiffuseSwatch) {
DiffuseSwatch->Activate(onoff);
}
if (SpecularSwatch) {
SpecularSwatch->Activate(onoff);
}
if (EmissiveSwatch) {
EmissiveSwatch->Activate(onoff);
}
}

View file

@ -0,0 +1,76 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Max2W3d *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/GameMtlVertexMaterialDlg.h $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 5/30/00 12:08p $*
* *
* $Revision:: 4 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef GAMEMTLVERTEXMATERIALDLG_H
#define GAMEMTLVERTEXMATERIALDLG_H
#include <Max.h>
#include "GameMtlForm.h"
class GameMtl;
class GameMtlVertexMaterialDlg : public GameMtlFormClass
{
public:
GameMtlVertexMaterialDlg(HWND parent, IMtlParams * imp, GameMtl * m, int pass);
~GameMtlVertexMaterialDlg();
virtual BOOL Dialog_Proc (HWND dlg_wnd, UINT message, WPARAM wparam, LPARAM lparam);
void ActivateDlg(BOOL onoff);
void ReloadDialog(void);
private:
enum { MAX_STAGES = 2 };
IColorSwatch * AmbientSwatch;
IColorSwatch * DiffuseSwatch;
IColorSwatch * SpecularSwatch;
IColorSwatch * EmissiveSwatch;
ISpinnerControl * OpacitySpin;
ISpinnerControl * TranslucencySpin;
ISpinnerControl * ShininessSpin;
ISpinnerControl * UVChannelSpin[MAX_STAGES];
};
#endif

View file

@ -0,0 +1,212 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : G *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/InputDlg.cpp $*
* *
* $Author:: Andre_a $*
* *
* $Modtime:: 5/08/00 1:58p $*
* *
* $Revision:: 1 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
// InputDlg.cpp : implementation file
//
#include "InputDlg.h"
#include <assert.h>
static BOOL CALLBACK _thunk_dialog_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
/////////////////////////////////////////////////////////////////////////////
// InputDlg dialog
InputDlg::InputDlg (HWND hWndParent)
: m_hWndParent(hWndParent),
m_hWnd(NULL)
{
// Set the strings to default values.
SetCaption("Input Value...");
SetLabel("Please enter a value:");
SetValue(NULL);
}
/////////////////////////////////////////////////////////////////////////////
// InputDlg Methods
int InputDlg::DoModal (void)
{
// Put up the dialog box.
BOOL result = DialogBoxParam(AppInstance, MAKEINTRESOURCE(IDD),
m_hWndParent, (DLGPROC)_thunk_dialog_proc,
(LPARAM)this);
// Return IDOK if the user accepted the new settings.
return (result == 1) ? IDOK : IDCANCEL;
}
void InputDlg::SetCaption (const char *caption)
{
if (caption)
{
assert(strlen(caption) < sizeof(m_Caption));
strcpy(m_Caption, caption);
}
else
m_Caption[0] = '\0';
}
void InputDlg::SetLabel (const char *label)
{
if (label)
{
assert(strlen(label) < sizeof(m_Label));
strcpy(m_Label, label);
}
else
m_Label[0] = '\0';
}
void InputDlg::SetValue (const char *value)
{
if (value)
{
assert(strlen(value) < sizeof(m_Value));
strcpy(m_Value, value);
}
else
m_Value[0] = '\0';
}
/////////////////////////////////////////////////////////////////////////////
// InputDlg DialogProc
BOOL CALLBACK _thunk_dialog_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static InputDlg *dialog = NULL;
if (uMsg == WM_INITDIALOG)
{
dialog = (InputDlg*)lParam;
dialog->m_hWnd = hWnd;
}
if (dialog)
return dialog->DialogProc(hWnd, uMsg, wParam, lParam);
else
return 0;
}
BOOL CALLBACK InputDlg::DialogProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
int code = HIWORD(wParam);
switch (uMsg)
{
/*******************************************************************
* WM_INITDIALOG
*
* Initialize all of the custom controls for the dialog box
*
*******************************************************************/
case WM_INITDIALOG:
OnInitDialog(wParam, lParam);
return TRUE;
/*******************************************************************
* WM_COMMAND
*
*
*******************************************************************/
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
if (!OnOK())
return TRUE;
SetCursor(LoadCursor(NULL, IDC_WAIT));
EndDialog(m_hWnd, 1);
break;
case IDCANCEL:
EndDialog(m_hWnd, 0);
break;
}
return TRUE;
}
return FALSE;
}
/////////////////////////////////////////////////////////////////////////////
// InputDlg message handlers
LRESULT InputDlg::OnInitDialog (WPARAM wParam, LPARAM lParam)
{
// Set the cursor to the normal arrow.
SetCursor(LoadCursor(NULL, IDC_ARROW));
// Set the dialog box caption.
SetWindowText(m_hWnd, m_Caption);
// Set the label text.
HWND hLabel = GetDlgItem(m_hWnd, IDC_LABEL);
assert(hLabel != NULL);
SetWindowText(hLabel, m_Label);
// Set the default value.
HWND hEdit = GetDlgItem(m_hWnd, IDC_VALUE);
assert(hEdit != NULL);
SetWindowText(hEdit, m_Value);
// Select all of the text in the edit box.
SendMessage(hEdit, EM_SETSEL, 0, -1);
return 0;
}
BOOL InputDlg::OnOK (void)
{
// Update our copy of what the user typed.
HWND hEdit = GetDlgItem(m_hWnd, IDC_VALUE);
assert(hEdit != NULL);
GetWindowText(hEdit, m_Value, sizeof(m_Value));
// The dialog can be dismissed.
return TRUE;
}

View file

@ -0,0 +1,86 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : G *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/InputDlg.h $*
* *
* $Author:: Andre_a $*
* *
* $Modtime:: 5/08/00 1:36p $*
* *
* $Revision:: 1 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef INPUTDLG_H
#define INPUTDLG_H
#include "dllmain.h"
#include "resource.h"
/////////////////////////////////////////////////////////////////////////////
// InputDlg dialog - a generic input box for MAXScript
class InputDlg
{
friend BOOL CALLBACK _thunk_dialog_proc (HWND, UINT, WPARAM, LPARAM);
public:
// Construction
InputDlg (HWND hWndParent=NULL);
// Methods
int DoModal (void); // returns IDOK or IDCANCEL
void SetCaption (const char *caption);
void SetLabel (const char *label);
void SetValue (const char *value);
// DialogProc
BOOL CALLBACK DialogProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
// Dialog data associated with GUI components.
char m_Value[1024]; // edit box
char m_Label[512]; // description label
char m_Caption[128]; // dialog caption
protected:
// Dialog data
enum { IDD = IDD_INPUT_DIALOG };
HWND m_hWnd;
HWND m_hWndParent;
// Message Handlers
LRESULT OnInitDialog (WPARAM wParam, LPARAM lParam);
BOOL OnOK (void);
};
#endif

View file

@ -0,0 +1,88 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Max2W3D *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/LightGlareSave.cpp $*
* *
* Original Author:: Greg Hjelstrom *
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 8/06/00 11:21a $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "LightGlareSave.h"
#include "w3d_file.h"
#include "util.h"
#include "w3dappdata.h"
#include "errclass.h"
LightGlareSaveClass::LightGlareSaveClass
(
char * mesh_name,
char * container_name,
INode * inode,
Matrix3 & exportspace,
TimeValue curtime,
Progress_Meter_Class & meter
)
{
//////////////////////////////////////////////////////////////////////
// Init the glare info
//////////////////////////////////////////////////////////////////////
memset(&GlareData,0,sizeof(GlareData));
//////////////////////////////////////////////////////////////////////
// Get the position of the pivot point relative to the given
// export coordinate system.
//////////////////////////////////////////////////////////////////////
// Transform the mesh into the desired coordinate system
Matrix3 node_matrix = inode->GetObjectTM(curtime);
Matrix3 offset_matrix = node_matrix * Inverse(exportspace);
GlareData.Position.X = offset_matrix.GetTrans().x;
GlareData.Position.Y = offset_matrix.GetTrans().y;
GlareData.Position.Z = offset_matrix.GetTrans().z;
}
int LightGlareSaveClass::Write_To_File(ChunkSaveClass & csave)
{
csave.Begin_Chunk(W3D_CHUNK_LIGHTGLARE);
csave.Begin_Chunk(W3D_CHUNK_LIGHTGLARE_INFO);
csave.Write(&GlareData,sizeof(GlareData));
csave.End_Chunk();
csave.End_Chunk();
return 0;
}

View file

@ -0,0 +1,84 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Max2W3D *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/LightGlareSave.h $*
* *
* Original Author:: Greg Hjelstrom *
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 8/05/00 10:27a $*
* *
* $Revision:: 1 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef LIGHTGLARESAVE_H
#define LIGHTGLARESAVE_H
#include <Max.h>
#include "w3d_file.h"
#include "chunkio.h"
#include "progress.h"
/*******************************************************************************************
**
** LightGlareSaveClass - Create a Light Glare definition from a Max mesh. In the initial
** implementation, all I need to save is the point at the pivot of the mesh.
**
*******************************************************************************************/
class LightGlareSaveClass
{
public:
enum {
EX_UNKNOWN = 0, // exception error codes
EX_CANCEL = 1
};
LightGlareSaveClass( char * mesh_name,
char * container_name,
INode * inode,
Matrix3 & exportspace,
TimeValue curtime,
Progress_Meter_Class & meter);
int Write_To_File(ChunkSaveClass & csave);
private:
W3dLightGlareStruct GlareData;
};
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,201 @@
/*
** Command & Conquer Generals(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/>.
*/
/* $Header: /Commando/Code/Tools/max2w3d/MeshDeform.h 6 4/24/01 6:02p Greg_h $ */
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando / G 3D engine *
* *
* File Name : MeshDeform.H *
* *
* Programmer : Patrick Smith *
* *
* Start Date : 04/19/99 *
* *
* Last Update :
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef __MESH_DEFORM_H
#define __MESH_DEFORM_H
#include <Max.h>
#include "Vector.H"
// Forward declarations
class MeshDeformPanelClass;
class MeshDeformModData;
///////////////////////////////////////////////////////////////////////////
//
// Prototypes
//
///////////////////////////////////////////////////////////////////////////
ClassDesc *Get_Mesh_Deform_Desc (void);
extern Class_ID _MeshDeformClassID;
///////////////////////////////////////////////////////////////////////////
//
// MeshDeformClass
//
///////////////////////////////////////////////////////////////////////////
class MeshDeformClass : public OSModifier
{
public:
//////////////////////////////////////////////////////////////////////
// Public constructors/destructors
//////////////////////////////////////////////////////////////////////
MeshDeformClass (void)
: m_MaxInterface (NULL),
m_ModeMove (NULL),
m_ModeSelect (NULL),
m_ModeRotate (NULL),
m_ModeUScale (NULL),
m_ModeNUScale (NULL),
m_ModeSquash (NULL),
m_DeformState (1.0F),
m_pPanel (NULL),
m_CurrentSet (0),
m_bSetDirty (true),
m_VertColorChanging (false),
m_MaxSets (0),
m_hRollupWnd (NULL) { SetName ("WW Mesh Deformer"); Set_Max_Deform_Sets (1); }
virtual ~MeshDeformClass (void) { }
#if defined W3D_MAX4 //defined as in the project (.dsp)
NumSubObjTypes();
GetSubObjType();
#endif
//////////////////////////////////////////////////////////////////////
// Public methods
//////////////////////////////////////////////////////////////////////
void Set_Deform_State (float state = 1.0F);
float Get_Deform_State (void) const { return m_DeformState; }
void Set_Vertex_Color (const Point3 &color, bool button_up);
void Get_Vertex_Color (Point3 &color);
void Set_Max_Deform_Sets (int max);
int Get_Max_Deform_Sets (void) const { return m_MaxSets; }
void Set_Current_Set (int index, bool update_selection);
int Get_Current_Set (void) const { return m_CurrentSet; }
void Update_UI (MeshDeformModData *mod_data);
void Auto_Apply (bool auto_apply = true);
//////////////////////////////////////////////////////////////////////
// Base class overrides
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
// From Animatable
//////////////////////////////////////////////////////////////////////
void DeleteThis (void) { delete this; }
void GetClassName (TSTR& s) { s = TSTR(_T("WWDeform")); }
TCHAR * GetObjectName (void) { return _T("WWDamage"); }
SClass_ID SuperClassID (void) { return OSM_CLASS_ID; }
Class_ID ClassID (void) { return _MeshDeformClassID; }
//RefTargetHandle Clone(RemapDir& remap = NoRemap());
void BeginEditParams (IObjParam *ip, ULONG flags,Animatable *prev);
void EndEditParams (IObjParam *ip, ULONG flags,Animatable *next);
//////////////////////////////////////////////////////////////////////
// From Modifier
//////////////////////////////////////////////////////////////////////
ChannelMask ChannelsUsed (void);
ChannelMask ChannelsChanged (void);
void ModifyObject (TimeValue t, ModContext &mod_context, ObjectState* os, INode *node);
BOOL DependOnTopology (ModContext &mod_context) { return TRUE; }
int NeedUseSubselButton (void) { return TRUE; }
Class_ID InputType (void);
//////////////////////////////////////////////////////////////////////
// From ReferenceMaker
//////////////////////////////////////////////////////////////////////
RefResult NotifyRefChanged (Interval time, RefTargetHandle htarget, PartID &part_id, RefMessage mesage);
IOResult SaveLocalData (ISave *save_obj, LocalModData *mod_context);
IOResult LoadLocalData (ILoad *load_obj, LocalModData **mod_context);
//////////////////////////////////////////////////////////////////////
// From BaseObject
//////////////////////////////////////////////////////////////////////
CreateMouseCallBack * GetCreateMouseCallBack (void);
void ActivateSubobjSel (int level, XFormModes &modes);
int HitTest (TimeValue time_value, INode * node, int type, int crossing, int flags, IPoint2 *point, ViewExp *viewport, ModContext *mod_context);
void SelectSubComponent (HitRecord *hit_record, BOOL selected, BOOL all, BOOL invert);
void GetSubObjectCenters (SubObjAxisCallback *cb, TimeValue t, INode *node, ModContext *mc);
void GetSubObjectTMs (SubObjAxisCallback *cb, TimeValue t, INode *node, ModContext *mc);
int SubObjectIndex (HitRecord *hitRec) { return hitRec->hitInfo; }
void ClearSelection (int selLevel);
// Transformation managment
void Move (TimeValue time_val, Matrix3 &parent_tm, Matrix3 &tm_axis, Point3 &point, BOOL local_origin);
void Rotate (TimeValue time_val, Matrix3 &parent_tm, Matrix3 &tm_axis, Quat &rotation, BOOL local_origin);
void Scale (TimeValue time_val, Matrix3 &parent_tm, Matrix3 &tm_axis, Point3 &value, BOOL local_origin);
void TransformStart (TimeValue time_val);
void TransformFinish (TimeValue time_val);
void TransformCancel (TimeValue time_val);
#if defined W3D_MAX4 //defined as in the project (.dsp)
ISubObjType * GetSubObjType(int i) ;
#endif
protected:
//////////////////////////////////////////////////////////////////////
// Protected methods
//////////////////////////////////////////////////////////////////////
void Update_Current_Set (void);
void Update_Set_Count (void);
private:
//////////////////////////////////////////////////////////////////////
// Private member data
//////////////////////////////////////////////////////////////////////
IObjParam * m_MaxInterface;
HWND m_hRollupWnd;
MeshDeformPanelClass * m_pPanel;
float m_DeformState;
bool m_VertColorChanging;
// Mode handlers
SelectModBoxCMode * m_ModeSelect;
MoveModBoxCMode * m_ModeMove;
RotateModBoxCMode * m_ModeRotate;
UScaleModBoxCMode * m_ModeUScale;
NUScaleModBoxCMode * m_ModeNUScale;
SquashModBoxCMode * m_ModeSquash;
// Set managment
bool m_bSetDirty;
int m_CurrentSet;
int m_MaxSets;
// Information
CStr m_OperationName;
};
#endif //__MESH_DEFORM_H

View file

@ -0,0 +1,239 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando / G 3D engine *
* *
* File Name : MeshDeformData.cpp *
* *
* Programmer : Patrick Smith *
* *
* Start Date : 04/26/99 *
* *
* Last Update :
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "MeshDeformData.H"
#include "Util.H"
#include "MeshDeformSaveDefs.H"
///////////////////////////////////////////////////////////////////////////
//
// ~MeshDeformModData
//
///////////////////////////////////////////////////////////////////////////
MeshDeformModData::~MeshDeformModData (void)
{
Free_Sets_List ();
return ;
}
///////////////////////////////////////////////////////////////////////////
//
// Record_Mesh_State
//
///////////////////////////////////////////////////////////////////////////
void
MeshDeformModData::Record_Mesh_State (TriObject &tri_obj, float state, bool update_all)
{
//
// Ask each set to update its state
//
for (int index = 0; index < m_SetsList.Count (); index ++) {
if (index != m_CurrentSet) {
if (update_all) {
m_SetsList[index]->Set_State (state);
}
m_SetsList[index]->Update_Mesh (tri_obj);
}
}
if (m_CurrentSet < m_SetsList.Count ()) {
m_SetsList[m_CurrentSet]->Set_State (state);
m_SetsList[m_CurrentSet]->Update_Mesh (tri_obj);
}
return ;
}
///////////////////////////////////////////////////////////////////////////
//
// Free_Sets_List
//
///////////////////////////////////////////////////////////////////////////
void
MeshDeformModData::Free_Sets_List (void)
{
//
// Delete all the object pointers in the set list
//
for (int index = 0; index < m_SetsList.Count (); index ++) {
MeshDeformSetClass *set = m_SetsList[index];
SAFE_DELETE (set);
}
// Remove all the entries from the list
m_SetsList.Delete_All ();
return ;
}
///////////////////////////////////////////////////////////////////////////
//
// Set_Max_Deform_Sets
//
///////////////////////////////////////////////////////////////////////////
void
MeshDeformModData::Set_Max_Deform_Sets (int max)
{
int current_max = m_SetsList.Count ();
if (max > current_max) {
//
// Add the new sets to the list
//
int sets_to_add = max - current_max;
for (int index = 0; index < sets_to_add; index ++) {
MeshDeformSetClass *set = new MeshDeformSetClass;
m_SetsList.Add (set);
}
} else if (max < current_max) {
//
// Remove the obsolete sets from the list
//
int sets_to_remove = current_max - max;
for (int index = 0; index < sets_to_remove; index ++) {
// Restore the set before we delete it
Restore_Set (max);
// Delete the set
MeshDeformSetClass *set = m_SetsList[max];
SAFE_DELETE (set);
m_SetsList.Delete (max);
}
}
return ;
}
///////////////////////////////////////////////////////////////////////////
//
// Restore_Set
//
///////////////////////////////////////////////////////////////////////////
void
MeshDeformModData::Restore_Set (int set_index)
{
if (set_index == -1) {
// Restore ALL the set
for (int index = 0; index < m_SetsList.Count (); index ++) {
m_SetsList[index]->Restore_Members ();
}
} else {
m_SetsList[set_index]->Restore_Members ();
}
return ;
}
///////////////////////////////////////////////////////////////////////////
//
// Save
//
///////////////////////////////////////////////////////////////////////////
IOResult
MeshDeformModData::Save (ISave *save_obj)
{
DWORD bytes = 0L;
save_obj->BeginChunk (DEFORM_CHUNK_INFO);
//
// Write the set count info to the chunk
//
DeformChunk info = { 0 };
info.SetCount = m_SetsList.Count ();
IOResult result = save_obj->Write (&info, sizeof (info), &bytes);
save_obj->EndChunk ();
//
// Now write a chunk for each set
//
for (int index = 0; (index < m_SetsList.Count ()) && (result == IO_OK); index ++) {
result = m_SetsList[index]->Save (save_obj);
}
// Return IO_OK on success IO_ERROR on failure
return result;
}
///////////////////////////////////////////////////////////////////////////
//
// Load
//
///////////////////////////////////////////////////////////////////////////
IOResult
MeshDeformModData::Load (ILoad *load_obj)
{
Free_Sets_List ();
DWORD bytes = 0L;
//
// Is this the chunk we were expecting?
//
IOResult result = load_obj->OpenChunk ();
if ( (result == IO_OK) &&
(load_obj->CurChunkID () == DEFORM_CHUNK_INFO)) {
DeformChunk info = { 0 };
result = load_obj->Read (&info, sizeof (info), &bytes);
load_obj->CloseChunk ();
//
// Read the set information from the chunk
//
for (unsigned int index = 0; (index < info.SetCount) && (result == IO_OK); index ++) {
MeshDeformSetClass *set = new MeshDeformSetClass;
m_SetsList.Add (set);
result = set->Load (load_obj);
}
}
// Return IO_OK on success IO_ERROR on failure
return result;
}

View file

@ -0,0 +1,128 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando / G 3D engine *
* *
* File Name : MeshDeformData.h *
* *
* Programmer : Patrick Smith *
* *
* Start Date : 04/26/99 *
* *
* Last Update :
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef __MESH_DEFORM_DATA_H
#define __MESH_DEFORM_DATA_H
#include <Max.h>
#include "Vector.H"
#include "MeshDeformSet.H"
///////////////////////////////////////////////////////////////////////////
//
// Typedefs
//
///////////////////////////////////////////////////////////////////////////
typedef DynamicVectorClass<MeshDeformSetClass *> SETS_LIST;
///////////////////////////////////////////////////////////////////////////
//
// MeshDeformModData
//
///////////////////////////////////////////////////////////////////////////
class MeshDeformModData : public LocalModData
{
public:
//////////////////////////////////////////////////////////////////////
// Public constructors/destructors
//////////////////////////////////////////////////////////////////////
MeshDeformModData (void)
: m_CurrentSet (0) { }
virtual ~MeshDeformModData (void);
//////////////////////////////////////////////////////////////////////
// Public methods
//////////////////////////////////////////////////////////////////////
virtual LocalModData * Clone (void) { return new MeshDeformModData; }
void Record_Mesh_State (TriObject &tri_obj, float state, bool update_all);
// Inline accessors
Mesh * Peek_Mesh (void) const { return m_SetsList[m_CurrentSet]->Peek_Mesh (); }
const Point3 * Peek_Orig_Vertex_Array (void) const { return m_SetsList[m_CurrentSet]->Peek_Orig_Vertex_Array (); }
Point3 * Peek_Vertex_OPStart_Array (void) const { return m_SetsList[m_CurrentSet]->Peek_Vertex_OPStart_Array (); }
VertColor * Peek_Vertex_Colors (void) const { return m_SetsList[m_CurrentSet]->Peek_Vertex_Colors (); }
// Auto apply
bool Is_Auto_Apply (void) const { return m_SetsList[m_CurrentSet]->Does_Set_Auto_Apply (); }
void Auto_Apply (bool auto_apply = true) { m_SetsList[m_CurrentSet]->Auto_Apply (auto_apply); }
// Data modifiers
void Update_Current_Data (void) { m_SetsList[m_CurrentSet]->Update_Current_Data (); }
void Set_Vertex_Position (int index, const Point3 &value) { m_SetsList[m_CurrentSet]->Set_Vertex_Position (index, value); }
void Set_Vertex_Color (int index, int color_index, const VertColor &value) { m_SetsList[m_CurrentSet]->Set_Vertex_Color (index, color_index, value); }
// Set managment
void Set_Max_Deform_Sets (int max);
void Set_Current_Set (int set_index) { m_CurrentSet = set_index; }
int Get_Current_Set (void) const { return m_CurrentSet; }
void Select_Set (int set_index) { m_SetsList[set_index]->Select_Members (); }
void Update_Set (int set_index, DEFORM_CHANNELS flags) { m_SetsList[set_index]->Update_Members (flags); }
void Restore_Set (int set_index = -1);
MeshDeformSetClass & Peek_Set (int index) { return *(m_SetsList[index]); }
int Get_Set_Count (void) const { return m_SetsList.Count (); }
// Persistent storage
IOResult Save (ISave *save_obj);
IOResult Load (ILoad *load_obj);
protected:
//////////////////////////////////////////////////////////////////////
// Protected methods
//////////////////////////////////////////////////////////////////////
void Resize_Vertex_Array (int count, int color_count);
void Copy_Vertex_Array (Mesh &mesh);
void Free_Sets_List (void);
void Util_Restore_Set (int set_index);
private:
//////////////////////////////////////////////////////////////////////
// Private member data
//////////////////////////////////////////////////////////////////////
// Set managment
int m_CurrentSet;
SETS_LIST m_SetsList;
};
#endif //__MESH_DEFORM_DATA_H

View file

@ -0,0 +1,100 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando / G 3D engine *
* *
* File Name : MeshDeformDefs.h *
* *
* Programmer : Patrick Smith *
* *
* Start Date : 04/28/99 *
* *
* Last Update :
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef __MESH_DEFORM_DEFS_H
#define __MESH_DEFORM_DEFS_H
#include <Max.H>
#include "Vector.H"
///////////////////////////////////////////////////////////////////////////
//
// Constants
//
///////////////////////////////////////////////////////////////////////////
typedef enum
{
VERT_POSITION = 1,
VERT_COLORS = 2,
BOTH = VERT_POSITION | VERT_COLORS
} DEFORM_CHANNELS;
///////////////////////////////////////////////////////////////////////////
//
// Structures
//
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
//
// VERT_INFO
//
// Used to represent position or color information for a vertex.
//
///////////////////////////////////////////////////////////////////////////
typedef struct _VERT_INFO
{
_VERT_INFO (void)
: index (0),
color_index (0),
value (0,0,0) { }
_VERT_INFO (int vert_index, const Point3 &point, int vert_color_index = 0)
: index (vert_index),
color_index (vert_color_index),
value (point) { }
UINT index;
UINT color_index;
Point3 value;
// Don't care, DynamicVectorClass needs these
bool operator== (const _VERT_INFO &src) { return false; }
bool operator!= (const _VERT_INFO &src) { return true; }
} VERT_INFO;
///////////////////////////////////////////////////////////////////////////
//
// Typedefs
//
///////////////////////////////////////////////////////////////////////////
typedef DynamicVectorClass<VERT_INFO> DEFORM_LIST;
#endif //__MESH_DEFORM_DEFS_H

View file

@ -0,0 +1,365 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando / G 3D engine *
* *
* File Name : MeshDeformPanel.cpp *
* *
* Programmer : Patrick Smith *
* *
* Start Date : 04/22/99 *
* *
* Last Update :
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "MeshDeformPanel.H"
#include "Resource.H"
#include "Util.H"
#include "MeshDeform.H"
///////////////////////////////////////////////////////////////////////////
//
// Local constants
//
///////////////////////////////////////////////////////////////////////////
const char * const PANEL_OBJ_PROP = "WWPANELOBJ";
///////////////////////////////////////////////////////////////////////////
//
// Message_Proc
//
///////////////////////////////////////////////////////////////////////////
BOOL WINAPI
MeshDeformPanelClass::Message_Proc
(
HWND hwnd,
UINT message,
WPARAM wparam,
LPARAM lparam
)
{
// Lookup the controlling object for this panel
MeshDeformPanelClass *panel_obj = MeshDeformPanelClass::Get_Object (hwnd);
BOOL result = FALSE;
switch (message)
{
// Create the controlling panel-object
case WM_INITDIALOG:
panel_obj = new MeshDeformPanelClass (hwnd);
SetProp (hwnd, PANEL_OBJ_PROP, (HANDLE)panel_obj);
break;
case WM_DESTROY:
result = panel_obj->On_Message (message, wparam, lparam);
RemoveProp (hwnd, PANEL_OBJ_PROP);
SAFE_DELETE (panel_obj);
break;
}
// Pass the message onto the controlling panel-object
if (panel_obj != NULL) {
result = panel_obj->On_Message (message, wparam, lparam);
}
// Return the TRUE/FALSE result code
return result;
}
///////////////////////////////////////////////////////////////////////////
//
// Get_Object
//
///////////////////////////////////////////////////////////////////////////
MeshDeformPanelClass *
MeshDeformPanelClass::Get_Object (HWND hwnd)
{
return (MeshDeformPanelClass *)::GetProp (hwnd, PANEL_OBJ_PROP);
}
///////////////////////////////////////////////////////////////////////////
//
// On_Message
//
///////////////////////////////////////////////////////////////////////////
BOOL
MeshDeformPanelClass::On_Message
(
UINT message,
WPARAM wparam,
LPARAM lparam
)
{
switch (message)
{
case WM_INITDIALOG:
m_pColorSwatch = ::GetIColorSwatch (::GetDlgItem (m_hWnd, IDC_VERTEX_COLOR), RGB (0, 0, 0), "Vertex Color");
m_pMaxSetsEdit = ::GetICustEdit (::GetDlgItem (m_hWnd, IDC_MAX_SETS_EDIT));
m_pMaxSetsSpin = ::GetISpinner (::GetDlgItem (m_hWnd, IDC_MAX_SETS_SPIN));
m_pLockSetsButton = ::GetICustButton (::GetDlgItem (m_hWnd, IDC_LOCK_SETS));
//
// Setup the 'max-sets' controls
//
m_pMaxSetsSpin->LinkToEdit (::GetDlgItem (m_hWnd, IDC_MAX_SETS_EDIT), EDITTYPE_INT);
m_pMaxSetsSpin->SetLimits (1, 20);
m_pMaxSetsEdit->SetText (1);
m_pMaxSetsSpin->SetValue (1, FALSE);
::SetDlgItemInt (m_hWnd, IDC_CURRENT_SET_STATIC, 1, FALSE);
//
// Setup the edit button
//
m_pLockSetsButton->SetType (CBT_CHECK);
m_pLockSetsButton->SetCheck (FALSE);
m_pLockSetsButton->SetHighlightColor (GREEN_WASH);
//m_pEditButton->SetType (CBT_CHECK);
//m_pEditButton->SetCheck (FALSE);
//m_pEditButton->SetHighlightColor (GREEN_WASH);
//
// Setup the sliders
//
::SendDlgItemMessage (m_hWnd, IDC_CURRENT_SET_SLIDER, TBM_SETRANGE, (WPARAM)TRUE, MAKELONG (1, 1));
::SendDlgItemMessage (m_hWnd, IDC_CURRENT_SET_SLIDER, TBM_SETPOS, (WPARAM)TRUE, 0L);
::SendDlgItemMessage (m_hWnd, IDC_STATE_SLIDER, TBM_SETRANGE, (WPARAM)FALSE, MAKELONG (0, 10));
::SendDlgItemMessage (m_hWnd, IDC_STATE_SLIDER, TBM_SETPOS, (WPARAM)FALSE, 9L);
//
// Ensure the sliders are repainted
//
//::InvalidateRect (::GetDlgItem (m_hWnd, IDC_STATE_SLIDER), NULL, TRUE);
//::InvalidateRect (::GetDlgItem (m_hWnd, IDC_CURRENT_SET_SLIDER), NULL, TRUE);
break;
case WM_DESTROY:
::ReleaseIColorSwatch (m_pColorSwatch);
::ReleaseICustEdit (m_pMaxSetsEdit);
::ReleaseISpinner (m_pMaxSetsSpin);
//::ReleaseICustButton (m_pEditButton);
m_pColorSwatch = NULL;
m_pMaxSetsEdit = NULL;
m_pMaxSetsSpin = NULL;
//m_pEditButton = NULL;
break;
case WM_COMMAND:
On_Command (wparam, lparam);
break;
case CC_COLOR_CHANGE:
{
// Pass the new color onto the mesh deformer
COLORREF color_ref = m_pColorSwatch->GetColor ();
VertColor color;
color.x = GetRValue (color_ref) / 255.0F;
color.y = GetGValue (color_ref) / 255.0F;
color.z = GetBValue (color_ref) / 255.0F;
m_pMeshDeformer->Set_Vertex_Color (color, HIWORD (wparam) != 0);
}
break;
case WM_CUSTEDIT_ENTER:
case CC_SPINNER_CHANGE:
{
Set_Max_Sets (m_pMaxSetsEdit->GetInt (), true);
}
break;
case WM_HSCROLL:
if ((HWND)lparam == ::GetDlgItem (m_hWnd, IDC_CURRENT_SET_SLIDER)) {
int pos = ::SendDlgItemMessage (m_hWnd, IDC_CURRENT_SET_SLIDER, TBM_GETPOS, 0, 0L);
Set_Current_Set (pos - 1, true);
} else {
int pos = ::SendDlgItemMessage (m_hWnd, IDC_STATE_SLIDER, TBM_GETPOS, 0, 0L);
m_pMeshDeformer->Set_Deform_State (((float)pos) / 10.0F);
if (pos > 0) {
m_pColorSwatch->Enable ();
} else {
m_pColorSwatch->Disable ();
}
}
break;
}
return FALSE;
}
///////////////////////////////////////////////////////////////////////////
//
// On_Command
//
///////////////////////////////////////////////////////////////////////////
void
MeshDeformPanelClass::On_Command
(
WPARAM wparam,
LPARAM lparam
)
{
switch (LOWORD (wparam))
{
case IDC_MANUALAPPLY:
{
m_pMeshDeformer->Auto_Apply (Get_Auto_Apply_Check ());
}
break;
//case IDC_EDIT_BUTTON:
/*if (m_pEditButton->IsChecked ()) {
::SendDlgItemMessage (m_hWnd, IDC_STATE_SLIDER, TBM_SETPOS, (WPARAM)TRUE, 100L);
::EnableWindow (::GetDlgItem (m_hWnd, IDC_STATE_SLIDER), FALSE);
m_pColorSwatch->Enable ();
m_pMeshDeformer->Set_Deform_State (1.0F);
} else {
::EnableWindow (::GetDlgItem (m_hWnd, IDC_STATE_SLIDER), TRUE);
m_pColorSwatch->Disable ();
}*/
//break;
case IDC_MAX_SETS_EDIT:
break;
}
return ;
}
///////////////////////////////////////////////////////////////////////////
//
// Set_Deformer
//
///////////////////////////////////////////////////////////////////////////
void
MeshDeformPanelClass::Set_Deformer (MeshDeformClass *obj)
{
if (m_pMeshDeformer != obj) {
m_pMeshDeformer = obj;
// Set the slider position based on the current state of the deformer
float state = m_pMeshDeformer->Get_Deform_State ();
::SendDlgItemMessage (m_hWnd, IDC_STATE_SLIDER, TBM_SETPOS, (WPARAM)TRUE, LPARAM(state * 10.0F));
// Now update the current vertex color
Update_Vertex_Color ();
}
return ;
}
///////////////////////////////////////////////////////////////////////////
//
// Update_Vertex_Color
//
///////////////////////////////////////////////////////////////////////////
void
MeshDeformPanelClass::Update_Vertex_Color (void)
{
if (m_pMeshDeformer != NULL) {
// Update the color swatch with data from the deformer
Point3 color;
m_pMeshDeformer->Get_Vertex_Color (color);
m_pColorSwatch->SetColor (RGB (int(color.x * 255.0F), int(color.y * 255.0F), int(color.z * 255.0F)), FALSE);
}
return ;
}
///////////////////////////////////////////////////////////////////////////
//
// Set_Max_Sets
//
///////////////////////////////////////////////////////////////////////////
void
MeshDeformPanelClass::Set_Max_Sets
(
int max,
bool notify
)
{
// Update the UI
::SendDlgItemMessage (m_hWnd, IDC_CURRENT_SET_SLIDER, TBM_SETRANGE, (WPARAM)TRUE, MAKELONG (1, max));
::SetDlgItemInt (m_hWnd, IDC_CURRENT_SET_STATIC, max, TRUE);
if (notify == false) {
m_pMaxSetsSpin->SetValue (max, TRUE);
} else if (m_pMeshDeformer != NULL) {
// Update the deformer
m_pMeshDeformer->Set_Max_Deform_Sets (max);
}
return ;
}
///////////////////////////////////////////////////////////////////////////
//
// Set_Current_Set
//
///////////////////////////////////////////////////////////////////////////
void
MeshDeformPanelClass::Set_Current_Set
(
int set,
bool notify
)
{
// Update the UI
::SetDlgItemInt (m_hWnd, IDC_CURRENT_SET_STATIC, set + 1, TRUE);
if (notify == false) {
::SendDlgItemMessage (m_hWnd, IDC_CURRENT_SET_SLIDER, TBM_SETPOS, (WPARAM)TRUE, set + 1);
} else if (m_pMeshDeformer != NULL) {
// Update the deformer
m_pMeshDeformer->Set_Current_Set (set, true);
}
return ;
}
///////////////////////////////////////////////////////////////////////////
//
// Set_Current_State
//
///////////////////////////////////////////////////////////////////////////
void
MeshDeformPanelClass::Set_Current_State (float state)
{
::SendDlgItemMessage (m_hWnd, IDC_STATE_SLIDER, TBM_SETPOS, (WPARAM)TRUE, LPARAM(state * 10.0F));
return ;
}

View file

@ -0,0 +1,117 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando / G 3D engine *
* *
* File Name : MeshDeformPanel.H *
* *
* Programmer : Patrick Smith *
* *
* Start Date : 04/22/99 *
* *
* Last Update :
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef __MESH_DEFORM_PANEL_H
#define __MESH_DEFORM_PANEL_H
#include <Max.h>
#include "Resource.H"
// Forward declarations
class MeshDeformClass;
///////////////////////////////////////////////////////////////////////////
//
// MeshDeformPanelClass
//
///////////////////////////////////////////////////////////////////////////
class MeshDeformPanelClass
{
public:
//////////////////////////////////////////////////////////////////////
// Public constructors/destructors
//////////////////////////////////////////////////////////////////////
MeshDeformPanelClass (HWND hwnd)
: m_hWnd (hwnd),
m_pColorSwatch (NULL),
m_pMaxSetsSpin (NULL),
m_pMeshDeformer (NULL),
m_pLockSetsButton (NULL),
m_pMaxSetsEdit (NULL) { }
virtual ~MeshDeformPanelClass (void) { }
//////////////////////////////////////////////////////////////////////
// Public methods
//////////////////////////////////////////////////////////////////////
// Inline accessors
IColorSwatch * Get_Color_Swatch (void) const { return m_pColorSwatch; }
COLORREF Get_Vertex_Color (void) const { return m_pColorSwatch->GetColor (); }
void Set_Vertex_Color (COLORREF color) { m_pColorSwatch->SetColor (color); }
void Set_Deformer (MeshDeformClass *obj);
BOOL Is_Edit_Mode (void) const { return (::SendDlgItemMessage (m_hWnd, IDC_STATE_SLIDER, TBM_GETPOS, 0, 0L) > 0); }
BOOL Are_Sets_Tied (void) const { return m_pLockSetsButton->IsChecked (); }
int Get_Current_Set (void) const { return ::SendDlgItemMessage (m_hWnd, IDC_CURRENT_SET_SLIDER, TBM_GETPOS, 0, 0L); }
void Set_Current_Set (int set, bool notify = false);
void Set_Max_Sets (int max, bool notify = false);
void Set_Current_State (float state);
void Set_Auto_Apply_Check (bool onoff) { ::SendDlgItemMessage (m_hWnd, IDC_MANUALAPPLY, BM_SETCHECK, (WPARAM)(!onoff), 0L); }
bool Get_Auto_Apply_Check (void) const { return ::SendDlgItemMessage (m_hWnd, IDC_MANUALAPPLY, BM_GETCHECK, 0, 0L) == 0; }
// Update methods
void Update_Vertex_Color (void);
//////////////////////////////////////////////////////////////////////
// Static methods
//////////////////////////////////////////////////////////////////////
static BOOL WINAPI Message_Proc (HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);
static MeshDeformPanelClass * Get_Object (HWND hwnd);
protected:
//////////////////////////////////////////////////////////////////////
// Protected methods
//////////////////////////////////////////////////////////////////////
BOOL On_Message (UINT message, WPARAM wparam, LPARAM lparam);
void On_Command (WPARAM wparam, LPARAM lparam);
private:
//////////////////////////////////////////////////////////////////////
// Private member data
//////////////////////////////////////////////////////////////////////
HWND m_hWnd;
IColorSwatch * m_pColorSwatch;
ICustEdit * m_pMaxSetsEdit;
ISpinnerControl * m_pMaxSetsSpin;
ICustButton * m_pLockSetsButton;
MeshDeformClass * m_pMeshDeformer;
};
#endif //__MESH_DEFORM_PANEL_H

View file

@ -0,0 +1,420 @@
/*
** Command & Conquer Generals(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/>.
*/
/* $Header: /Commando/Code/Tools/max2w3d/MeshDeformSave.cpp 6 11/12/99 11:12a Greg_h $ */
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando / G 3D engine *
* *
* File Name : MeshDeformSafe.CPP
* *
* Programmer : Patrick Smith *
* *
* Start Date : 05/28/99 *
* *
* Last Update :
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "MeshDeform.H"
#include "MeshDeformSave.H"
#include "MeshDeformData.H"
#include "MeshDeformSet.H"
#include "MeshDeformSaveSet.H"
#include "Util.H"
#include "ModStack.H"
#include "MeshBuild.H"
#include "MeshSave.H"
///////////////////////////////////////////////////////////////////////////
//
// Initialize
//
///////////////////////////////////////////////////////////////////////////
void
MeshDeformSaveClass::Initialize
(
MeshBuilderClass &builder,
Object * object,
Mesh & mesh,
Matrix3 * transform
)
{
// Start fresh
Reset ();
//
// Attempt to gain access to the IDerivedObject this node references
//
int test = object->SuperClassID ();
int test2 = GEN_DERIVOB_CLASS_ID;
if ((object != NULL) &&
(object->SuperClassID () == GEN_DERIVOB_CLASS_ID)) {
//
// Loop through all the modifiers and see if we can find the
// Westwood Damage Mesh modifier.
//
IDerivedObject *derived_object = static_cast<IDerivedObject *> (object);
int modifier_count = derived_object->NumModifiers ();
bool found = false;
for (int index = 0; (index < modifier_count) && !found; index ++) {
//
// If this is the right modifier, then initialize using the
// data it contains.
//
Modifier *modifier = derived_object->GetModifier (index);
if ((modifier != NULL) && (modifier->ClassID () == _MeshDeformClassID)) {
//
// Attempt to get at the modifier data for this context
//
ModContext *mod_context = derived_object->GetModContext (index);
if ((mod_context != NULL) && (mod_context->localData != NULL)) {
MeshDeformModData *mod_data = static_cast<MeshDeformModData *> (mod_context->localData);
Initialize (builder, mesh, *mod_data, transform);
}
// Found it!
found = true;
}
}
}
return ;
}
///////////////////////////////////////////////////////////////////////////
//
// Initialize
//
///////////////////////////////////////////////////////////////////////////
void
MeshDeformSaveClass::Initialize
(
MeshBuilderClass & builder,
Mesh & mesh,
MeshDeformModData & mod_data,
Matrix3 * transform
)
{
//
// Loop through all the sets in the modifier
//
for (int index = 0; index < mod_data.Get_Set_Count (); index ++) {
//
// If this set isn't empty then add its data to our list
//
MeshDeformSetClass &deform_set = mod_data.Peek_Set (index);
if (deform_set.Is_Empty () == false) {
//
// Add this set to our list
//
MeshDeformSaveSetClass *save_set = new MeshDeformSaveSetClass;
deform_set.Save (builder, mesh, *save_set, transform);
m_DeformSets.Add (save_set);
}
}
return ;
}
///////////////////////////////////////////////////////////////////////////
//
// Reset
//
///////////////////////////////////////////////////////////////////////////
void
MeshDeformSaveClass::Reset (void)
{
//
// Delete all the damage sets
//
for (int index = 0; index < m_DeformSets.Count (); index ++) {
SAFE_DELETE (m_DeformSets[index]);
}
m_DeformSets.Delete_All ();
return ;
}
///////////////////////////////////////////////////////////////////////////
//
// Export
//
///////////////////////////////////////////////////////////////////////////
bool
MeshDeformSaveClass::Export (ChunkSaveClass &chunk_save)
{
bool retval = true;
if (m_DeformSets.Count() > 0) {
retval = chunk_save.Begin_Chunk (W3D_CHUNK_DEFORM);
if (retval) {
//
// Write the deform header to the file
//
W3dMeshDeform header = { 0 };
header.SetCount = m_DeformSets.Count ();
header.AlphaPasses = m_AlphaPasses;
retval &= (chunk_save.Write (&header, sizeof (header)) == sizeof (header));
if (retval) {
//
// Export all the sets in the deformation
//
retval &= Export_Sets (chunk_save);
}
retval &= chunk_save.End_Chunk ();
}
}
// Return the true/false result code
return retval;
}
///////////////////////////////////////////////////////////////////////////
//
// Export_Sets
//
///////////////////////////////////////////////////////////////////////////
bool
MeshDeformSaveClass::Export_Sets (ChunkSaveClass &chunk_save)
{
bool retval = true;
//
// Loop through all the sets and write them to the file
//
for (int set_index = 0; (set_index < m_DeformSets.Count ()) && retval; set_index ++) {
retval &= chunk_save.Begin_Chunk (W3D_CHUNK_DEFORM_SET);
if (retval) {
//
// Write a chunk of information out for this set
//
MeshDeformSaveSetClass *set_save = m_DeformSets[set_index];
W3dDeformSetInfo set_info = { 0 };
set_info.KeyframeCount = set_save->Get_Keyframe_Count ();
set_info.flags = set_save->Get_Flags ();
retval &= (chunk_save.Write (&set_info, sizeof (set_info)) == sizeof (set_info));
if (retval) {
//
// Export all the keyframes for this chunk
//
retval &= Export_Keyframes (chunk_save, *set_save);
}
retval &= chunk_save.End_Chunk ();
}
}
// Return the true/false result code
return retval;
}
///////////////////////////////////////////////////////////////////////////
//
// Export_Keyframes
//
///////////////////////////////////////////////////////////////////////////
bool
MeshDeformSaveClass::Export_Keyframes
(
ChunkSaveClass & chunk_save,
MeshDeformSaveSetClass &set_save
)
{
bool retval = true;
//
// Loop through all the keyframes in the set
//
int count = set_save.Get_Keyframe_Count ();
for (int keyframe_index = 0; (keyframe_index < count) && retval; keyframe_index ++) {
//
// Write a chunk of information out for this keyframe
//
retval &= chunk_save.Begin_Chunk (W3D_CHUNK_DEFORM_KEYFRAME);
if (retval) {
W3dDeformKeyframeInfo keyframe_info = { 0 };
keyframe_info.DeformPercent = set_save.Get_Deform_State (keyframe_index);
keyframe_info.DataCount = set_save.Get_Deform_Data_Count (keyframe_index);
retval &= (chunk_save.Write (&keyframe_info, sizeof (keyframe_info)) == sizeof (keyframe_info));
if (retval) {
//
// Loop through all the verticies in this keyframe
//
int data_count = set_save.Get_Deform_Data_Count (keyframe_index);
for (int index = 0; (index < data_count) && retval; index ++) {
MeshDeformSaveSetClass::DEFORM_DATA &data = set_save.Get_Deform_Data (keyframe_index, index);
//
// Write a chunk of information out for this vertex
//
retval &= chunk_save.Begin_Chunk (W3D_CHUNK_DEFORM_DATA);
if (retval) {
W3dDeformData data_struct = { 0 };
data_struct.VertexIndex = data.vert_index;
data_struct.Position.X = data.position.x;
data_struct.Position.Y = data.position.y;
data_struct.Position.Z = data.position.z;
data_struct.Color.R = data.color.x * 255;
data_struct.Color.G = data.color.y * 255;
data_struct.Color.B = data.color.z * 255;
// If we are using vertex alpha instead of vertex color, then convert
// the v-color into an alpha setting
data_struct.Color.A = 255;
if (m_AlphaPasses != 0) {
data_struct.Color.A = (data_struct.Color.R + data_struct.Color.G + data_struct.Color.B) / 3.0F;
}
retval &= (chunk_save.Write (&data_struct, sizeof (data_struct)) == sizeof (data_struct));
retval &= chunk_save.End_Chunk ();
}
}
}
retval &= chunk_save.End_Chunk ();
}
}
// Return the true/false result code
return retval;
}
///////////////////////////////////////////////////////////////////////////
//
// Re_Index
//
///////////////////////////////////////////////////////////////////////////
/*void
MeshDeformSaveClass::Re_Index (MeshBuilderClass &builder)
{
DynamicVectorClass<MeshDeformSaveSetClass::DEFORM_DATA> temp_list;
//
// Reindex each set of deform data
//
for (int set_index = 0; set_index < m_DeformSets.Count (); set_index ++) {
MeshDeformSaveSetClass *set_save = m_DeformSets[set_index];
//
// Loop through all the deform entries in this set
//
for (int keyframe_index = 0; keyframe_index < set_save->Get_Keyframe_Count (); keyframe_index ++) {
temp_list.Delete_All ();
for (int index = 0; index < set_save->Get_Deform_Data_Count (keyframe_index); index ++) {
MeshDeformSaveSetClass::DEFORM_DATA &data = set_save->Get_Deform_Data (keyframe_index, index);
//
// Now try to find the 'W3D' index of this vertex (its different than the max version).
//
//bool found = false;
for (int vert_index = 0; vert_index < builder.Get_Vertex_Count (); vert_index++) {
MeshBuilderClass::VertClass &vert = builder.Get_Vertex (vert_index);
//
// Reindex this vertex if its the one we are looking for.
//
if (vert.Id == (int)data.vert_index) {
MeshDeformSaveSetClass::DEFORM_DATA new_data = data;
new_data.vert_index = vert_index;
temp_list.Add (new_data);
//data.vert_index = vert_index;
//found = true;
}
}
}
set_save->Replace_Deform_Data (keyframe_index, temp_list);
}
}
return ;
}*/
///////////////////////////////////////////////////////////////////////////
//
// Does_Deformer_Modify_DCG
//
///////////////////////////////////////////////////////////////////////////
bool
MeshDeformSaveClass::Does_Deformer_Modify_DCG (void)
{
bool retval = false;
//
// Loop through all the sets
//
for (int set_index = 0; (set_index < m_DeformSets.Count ()) && !retval; set_index ++) {
MeshDeformSaveSetClass *set_save = m_DeformSets[set_index];
if (set_save) {
//
// Loop through all the keyframes in this set
//
int count = set_save->Get_Keyframe_Count ();
for (int keyframe_index = 0; (keyframe_index < count) && !retval; keyframe_index ++) {
//
// Loop through all the entries in this keyframe
//
int data_count = set_save->Get_Deform_Data_Count (keyframe_index);
for (int index = 0; (index < data_count) && !retval; index ++) {
MeshDeformSaveSetClass::DEFORM_DATA &data = set_save->Get_Deform_Data (keyframe_index, index);
//
// If the color is not 'white' then we will
// modify the DCG array.
//
if ((data.color.x != 1) ||
(data.color.y != 1) ||
(data.color.z != 1)) {
retval = true;
}
}
}
}
}
// Return the true/false result code
return retval;
}

View file

@ -0,0 +1,110 @@
/*
** Command & Conquer Generals(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/>.
*/
/* $Header: /Commando/Code/Tools/max2w3d/MeshDeformSave.h 4 7/07/99 11:52a Patrick $ */
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando / G 3D engine *
* *
* File Name : MeshDeformSafe.H
* *
* Programmer : Patrick Smith *
* *
* Start Date : 05/28/99 *
* *
* Last Update :
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef __MESH_DEFORM_SAVE_H
#define __MESH_DEFORM_SAVE_H
#include <Max.h>
#include "Vector.H"
// Forward declarations
class ChunkSaveClass;
class MeshDeformModData;
class MeshDeformSaveSetClass;
class MeshBuilderClass;
class MeshDeformSaveSetClass;
///////////////////////////////////////////////////////////////////////////
//
// Typdefs
//
///////////////////////////////////////////////////////////////////////////
typedef DynamicVectorClass<MeshDeformSaveSetClass *> DEFORM_SAVE_LIST;
///////////////////////////////////////////////////////////////////////////
//
// MeshDeformSaveClass
//
///////////////////////////////////////////////////////////////////////////
class MeshDeformSaveClass
{
public:
//////////////////////////////////////////////////////////////////////
// Public constructors/destructors
//////////////////////////////////////////////////////////////////////
MeshDeformSaveClass (void)
: m_AlphaPasses (0) { }
~MeshDeformSaveClass (void) { Reset (); }
//////////////////////////////////////////////////////////////////////
// Public methods
//////////////////////////////////////////////////////////////////////
void Initialize (MeshBuilderClass &builder, Object *object, Mesh &mesh, Matrix3 *transform = NULL);
void Initialize (MeshBuilderClass &builder, Mesh &mesh, MeshDeformModData &mod_data, Matrix3 *transform = NULL);
//void Re_Index (MeshBuilderClass &builder);
bool Export (ChunkSaveClass &chunk_save);
void Reset (void);
bool Is_Empty (void) const { return m_DeformSets.Count () == 0; }
bool Does_Deformer_Modify_DCG (void);
unsigned int Get_Alpha_Passes (void) const { return m_AlphaPasses; }
void Set_Alpha_Passes (unsigned int pass_mask) { m_AlphaPasses = pass_mask; }
protected:
//////////////////////////////////////////////////////////////////////
// Protected methods
//////////////////////////////////////////////////////////////////////
bool Export_Sets (ChunkSaveClass &chunk_save);
bool Export_Keyframes (ChunkSaveClass &chunk_save, MeshDeformSaveSetClass &set_save);
private:
//////////////////////////////////////////////////////////////////////
// Private member data
//////////////////////////////////////////////////////////////////////
DEFORM_SAVE_LIST m_DeformSets;
unsigned int m_AlphaPasses;
};
#endif //__MESH_DEFORM_SAVE_H

View file

@ -0,0 +1,114 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando / G 3D engine *
* *
* File Name : MeshDeformData.cpp *
* *
* Programmer : Patrick Smith *
* *
* Start Date : 06/07/99 *
* *
* Last Update :
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef __MESH_DEFORM_SAVE_DEFS_H
#define __MESH_DEFORM_SAVE_DEFS_H
#include <Max.h>
///////////////////////////////////////////////////////////////////////////
//
// Constants
//
///////////////////////////////////////////////////////////////////////////
typedef enum
{
DEFORM_CHUNK_INFO = 0x000000001,
DEFORM_CHUNK_SET_INFO,
DEFORM_CHUNK_KEYFRAME_INFO,
DEFORM_CHUNK_POSITION_DATA,
DEFORM_CHUNK_POSITION_VERTS,
DEFORM_CHUNK_COLOR_DATA,
DEFORM_CHUNK_COLOR_VERTS
} DEFORM_CHUNK_IDS;
///////////////////////////////////////////////////////////////////////////
//
// Structures
//
///////////////////////////////////////////////////////////////////////////
//
// Deform information. Each mesh can have sets of keyframes of
// deform info associated with it.
//
struct DeformChunk
{
uint32 SetCount;
uint32 reserved[4];
};
//
// Deform set information. Each set is made up of a series
// of keyframes.
//
struct DeformChunkSetInfo
{
uint32 KeyframeCount;
uint32 flags;
uint32 NumVerticies;
uint32 NumVertexColors;
uint32 reserved[2];
};
#define DEFORM_SET_MANUAL_DEFORM 0x00000001 // set is isn't applied during sphere or point tests.
//
// Deform keyframe information. Each keyframe is made up of
// a set of per-vert deform data.
//
struct DeformChunkKeyframeInfo
{
float32 DeformPercent;
uint32 VertexCount;
uint32 ColorCount;
uint32 reserved[2];
};
//
// Deform data. Contains deform information about a vertex
// in the mesh.
//
struct DeformDataChunk
{
uint32 VertexIndex;
uint32 ColorIndex;
Point3 Value;
uint32 reserved[2];
};
#endif //__MESH_DEFORM_SAVE_DEFS_H

View file

@ -0,0 +1,182 @@
/*
** Command & Conquer Generals(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/>.
*/
/* $Header: /Commando/Code/Tools/max2w3d/MeshDeformSaveSet.cpp 2 6/16/99 6:56p Patrick $ */
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando / G 3D engine *
* *
* File Name : MeshDeformSaveSet.CPP
* *
* Programmer : Patrick Smith *
* *
* Start Date : 05/28/99 *
* *
* Last Update :
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "MeshDeformSaveSet.H"
#include "Util.H"
////////////////////////////////////////////////////////////////////////
//
// Reset
//
////////////////////////////////////////////////////////////////////////
void
MeshDeformSaveSetClass::Reset (void)
{
//
// Free all the keyframe pointers in our list
//
for (int index = 0; index < m_DeformData.Count (); index ++) {
SAFE_DELETE (m_DeformData[index]);
}
m_DeformData.Delete_All ();
m_CurrentKeyFrame = NULL;
return ;
}
////////////////////////////////////////////////////////////////////////
//
// Begin_Keyframe
//
////////////////////////////////////////////////////////////////////////
void
MeshDeformSaveSetClass::Begin_Keyframe (float state)
{
//
// Allocate a new keyframe structure
//
m_CurrentKeyFrame = new KEYFRAME;
m_CurrentKeyFrame->state = state;
//
// Add this new keyframe to the end of our list
//
m_DeformData.Add (m_CurrentKeyFrame);
return ;
}
////////////////////////////////////////////////////////////////////////
//
// End_Keyframe
//
////////////////////////////////////////////////////////////////////////
void
MeshDeformSaveSetClass::End_Keyframe (void)
{
m_CurrentKeyFrame = NULL;
return ;
}
////////////////////////////////////////////////////////////////////////
//
// Add_Vert
//
////////////////////////////////////////////////////////////////////////
void
MeshDeformSaveSetClass::Add_Vert
(
UINT vert_index,
const Point3 & position,
const VertColor & color
)
{
// State OK?
assert (m_CurrentKeyFrame != NULL);
if (m_CurrentKeyFrame != NULL) {
//
// Create a structure that will hold the
// vertex information.
//
DEFORM_DATA data;
data.vert_index = vert_index;
data.position = position;
data.color = color;
//
// Add this vertex information to the keyframe list
//
m_CurrentKeyFrame->deform_list.Add (data);
}
return ;
}
////////////////////////////////////////////////////////////////////////
//
// Replace_Deform_Data
//
////////////////////////////////////////////////////////////////////////
void
MeshDeformSaveSetClass::Replace_Deform_Data
(
int keyframe_index,
DynamicVectorClass<DEFORM_DATA> &list
)
{
KEYFRAME *key_frame = m_DeformData[keyframe_index];
if (key_frame != NULL) {
//
// Replace the vertex deformation list for the keyframe
//
key_frame->deform_list.Delete_All ();
key_frame->deform_list = list;
}
return ;
}
////////////////////////////////////////////////////////////////////////
//
// Get_Deform_Count
//
////////////////////////////////////////////////////////////////////////
/*int
MeshDeformSaveSetClass::Get_Deform_Count (void) const
{
//
// Count up all the deform entries for all the keyframes
//
int count = 0;
for (int index = 0; index < m_DeformData.Count (); index ++) {
KEYFRAME *key_frame = m_DeformData[index];
if (key_frame != NULL) {
count += key_frame->deform_list.Count ();
}
}
return count;
}*/

View file

@ -0,0 +1,138 @@
/*
** Command & Conquer Generals(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/>.
*/
/* $Header: /Commando/Code/Tools/max2w3d/MeshDeformSaveSet.h 2 6/16/99 6:56p Patrick $ */
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando / G 3D engine *
* *
* File Name : MeshDeformSaveSet.H
* *
* Programmer : Patrick Smith *
* *
* Start Date : 05/28/99 *
* *
* Last Update :
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef __MESH_DEFORM_SAVE_SET_H
#define __MESH_DEFORM_SAVE_SET_H
#include <Max.h>
#include "Vector.H"
// Forward declarations
class ChunkSaveClass;
///////////////////////////////////////////////////////////////////////////
//
// MeshDeformSaveSetClass
//
///////////////////////////////////////////////////////////////////////////
class MeshDeformSaveSetClass
{
public:
//////////////////////////////////////////////////////////////////////
// Public friends
//////////////////////////////////////////////////////////////////////
friend class MeshDeformSaveClass;
protected:
protected:
//////////////////////////////////////////////////////////////////////
// Protected data types
//////////////////////////////////////////////////////////////////////
typedef struct _DEFORM_DATA
{
UINT vert_index;
Point3 position;
VertColor color;
// Don't care, DynamicVectorClass needs these
bool operator== (const _DEFORM_DATA &src) { return false; }
bool operator!= (const _DEFORM_DATA &src) { return true; }
} DEFORM_DATA;
//////////////////////////////////////////////////////////////////////
// Protected data types
//////////////////////////////////////////////////////////////////////
typedef struct
{
float state;
DynamicVectorClass<DEFORM_DATA> deform_list;
} KEYFRAME;
public:
//////////////////////////////////////////////////////////////////////
// Public constructors/destructors
//////////////////////////////////////////////////////////////////////
MeshDeformSaveSetClass (void)
: m_Flags (0),
m_CurrentKeyFrame (NULL) { }
~MeshDeformSaveSetClass (void) { Reset (); }
//////////////////////////////////////////////////////////////////////
// Public methods
//////////////////////////////////////////////////////////////////////
// Keyframe managment
void Begin_Keyframe (float state);
void End_Keyframe (void);
// Vertex managment
void Add_Vert (UINT vert_index, const Point3 &position, const VertColor &color);
// Misc
void Reset (void);
bool Is_Empty (void) const { return m_DeformData.Count () == 0; }
// Flag support
bool Get_Flag (unsigned int flag) const { return (m_Flags & flag) == flag; }
void Set_Flag (unsigned int flag, bool value) { if (value) (m_Flags |= flag); else (m_Flags &= ~flag); }
unsigned int Get_Flags (void) const { return m_Flags; }
// Enumeration
float Get_Deform_State (int key_frame) const { return m_DeformData[key_frame]->state; }
int Get_Keyframe_Count (void) const { return m_DeformData.Count (); }
int Get_Deform_Data_Count (int key_frame) const { return m_DeformData[key_frame]->deform_list.Count (); }
DEFORM_DATA & Get_Deform_Data (int key_frame, int index) { return m_DeformData[key_frame]->deform_list[index]; }
void Replace_Deform_Data (int keyframe_index, DynamicVectorClass<DEFORM_DATA> &list);
private:
//////////////////////////////////////////////////////////////////////
// Private member data
//////////////////////////////////////////////////////////////////////
DynamicVectorClass<KEYFRAME *> m_DeformData;
KEYFRAME * m_CurrentKeyFrame;
unsigned int m_Flags;
};
#endif //__MESH_DEFORM_SAVE_SET_H

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,185 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando / G 3D engine *
* *
* File Name : MeshDeformSet.h *
* *
* Programmer : Patrick Smith *
* *
* Start Date : 04/26/99 *
* *
* Last Update :
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef __MESH_DEFORM_SET_H
#define __MESH_DEFORM_SET_H
#include <Max.h>
#include "Vector.H"
#include "MeshDeformDefs.H"
// Forward declarations
class MeshDeformSaveSetClass;
class MeshBuilderClass;
///////////////////////////////////////////////////////////////////////////
//
// MeshDeformSetClass
//
///////////////////////////////////////////////////////////////////////////
class MeshDeformSetClass
{
public:
//////////////////////////////////////////////////////////////////////
// Public data types
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
// Public constructors/destructors
//////////////////////////////////////////////////////////////////////
MeshDeformSetClass (void)
: m_pMesh (NULL),
m_pVertexArray (NULL),
m_pVertexOPStartArray (NULL),
m_pVertexColors (NULL),
m_VertexColorCount (0),
m_State (0),
m_CurrentKeyFrame (0),
m_bAutoApply (true),
m_VertexCount (0) { Init_Key_Frames (); }
virtual ~MeshDeformSetClass (void);
//////////////////////////////////////////////////////////////////////
// Public methods
//////////////////////////////////////////////////////////////////////
//virtual LocalModData * Clone (void) { return new MeshDeformSetClass; }
void Update_Mesh (TriObject &tri_obj);
void Set_State (float state);
// Inline accessors
Mesh * Peek_Mesh (void) const { return m_pMesh; }
const Point3 * Peek_Orig_Vertex_Array (void) const { return m_pVertexArray; }
Point3 * Peek_Vertex_OPStart_Array (void) const { return m_pVertexOPStartArray; }
VertColor * Peek_Vertex_Colors (void) const { return m_pVertexColors; }
// Keyframe managment
void Set_Current_Key_Frame (int index);
int Get_Current_Key_Frame (void) const { return m_CurrentKeyFrame; }
void Update_Key_Frame (int key_frame);
void Update_Current_Data (void);
void Update_Set_Members (void);
void Collapse_Keyframe_Data (int keyframe);
void Reset_Key_Frame_Verts (int keyframe);
void Reset_Key_Frame_Colors (int keyframe);
// Data managment
void Set_Vertex_Position (int index, const Point3 &value);
void Set_Vertex_Color (int index, int color_index, const VertColor &value);
// Set managment
void Select_Members (void);
void Update_Members (DEFORM_CHANNELS flags);
void Restore_Members (void);
// Auto apply
bool Does_Set_Auto_Apply (void) const { return m_bAutoApply; }
void Auto_Apply (bool auto_apply = true) { m_bAutoApply = auto_apply; }
// Information
bool Is_Empty (void) const;
int Get_Vertex_Count (int keyframe) const { return m_KeyFrames[keyframe]->verticies.Count (); }
int Get_Color_Count (int keyframe) const { return m_KeyFrames[keyframe]->colors.Count (); }
const VERT_INFO & Get_Vertex_Data (int keyframe, int index) const { return m_KeyFrames[keyframe]->verticies[index]; }
const VERT_INFO & Get_Color_Data (int keyframe, int index) const { return m_KeyFrames[keyframe]->colors[index]; }
// Persistent storage
IOResult Save (ISave *save_obj);
IOResult Load (ILoad *load_obj);
void Save (MeshBuilderClass &builder, Mesh &mesh, MeshDeformSaveSetClass &save_set, Matrix3 *transform = NULL);
protected:
//////////////////////////////////////////////////////////////////////
// Protected methods
//////////////////////////////////////////////////////////////////////
void Resize_Vertex_Array (int count, int color_count);
void Copy_Vertex_Array (Mesh &mesh);
// Keyframe methods
void Init_Key_Frames (void);
void Free_Key_Frames (void);
void Determine_Interpolation_Indicies (int key_frame, bool position, int &from, int &to, float &state);
// Deformation application methods
void Apply_Position_Changes (UINT vert, int frame_to_check, Point3 &position, Matrix3 *transform = NULL);
void Apply_Color_Changes (UINT vert, int frame_to_check, Mesh &mesh);
void Apply_Color_Changes (UINT vert_index, UINT vert_color_index, int frame_to_check, VertColor &color);
private:
//////////////////////////////////////////////////////////////////////
// Private data types
//////////////////////////////////////////////////////////////////////
typedef struct
{
DEFORM_LIST verticies;
DEFORM_LIST colors;
BitArray affected_verts;
BitArray affected_colors;
} KEY_FRAME;
typedef DynamicVectorClass<KEY_FRAME *> KEY_FRAME_LIST;
//////////////////////////////////////////////////////////////////////
// Private member data
//////////////////////////////////////////////////////////////////////
Mesh * m_pMesh;
Point3 * m_pVertexArray;
Point3 * m_pVertexOPStartArray;
VertColor * m_pVertexColors;
int m_VertexCount;
int m_VertexColorCount;
int m_CurrentKeyFrame;
float m_State;
bool m_bAutoApply;
// Array representing which verticies are part of the set
BitArray m_SetMembers;
// List of key frames
KEY_FRAME_LIST m_KeyFrames;
};
#endif //__MESH_DEFORM_DATA_H

View file

@ -0,0 +1,332 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando / G 3D engine *
* *
* File Name : MeshDeformUndo.h *
* *
* Programmer : Patrick Smith *
* *
* Start Date : 06/08/99 *
* *
* Last Update :
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "MeshDeformUndo.H"
#include "Util.H"
#include "MeshDeformData.H"
#include "MeshDeformSet.H"
#include "MeshDeform.H"
///////////////////////////////////////////////////////////////////////////
//
// VertexRestoreClass
//
///////////////////////////////////////////////////////////////////////////
VertexRestoreClass::VertexRestoreClass
(
Mesh * mesh,
MeshDeformClass * modifier,
MeshDeformModData * mod_data
)
: m_pModifier (modifier),
m_pModData (mod_data),
m_pMesh (mesh),
m_SetIndex (0),
m_KeyframeIndex (0)
{
assert (mesh != NULL);
//
// Remember the deformer's current settings
//
m_SetIndex = m_pModData->Get_Current_Set ();
m_KeyframeIndex = m_pModData->Peek_Set (m_SetIndex).Get_Current_Key_Frame ();
return ;
}
///////////////////////////////////////////////////////////////////////////
//
// Free_Vertex_Array
//
///////////////////////////////////////////////////////////////////////////
void
VertexRestoreClass::Free_Vertex_Array (void)
{
m_VertexList.Delete_All ();
m_RedoVertexList.Delete_All ();
return ;
}
///////////////////////////////////////////////////////////////////////////
//
// Restore
//
///////////////////////////////////////////////////////////////////////////
void
VertexRestoreClass::Restore (int is_undo)
{
assert (m_pMesh != NULL);
assert (m_pModData != NULL);
assert (m_pModifier != NULL);
// Is this being called as part of an undo operation?
if (is_undo != 0) {
//
// Ensure the modifier is in the state it was when
// the undo operation was recorded
//
m_pModData->Set_Current_Set (m_SetIndex);
m_pModData->Peek_Set (m_SetIndex).Set_Current_Key_Frame (m_KeyframeIndex);
//
// Apply the original vertex positions to the mesh
//
Apply_Vertex_Data (m_VertexList);
//
// Notify the mesh of geometry changes
//
m_pModifier->NotifyDependents (FOREVER, PART_GEOM | PART_VERTCOLOR, REFMSG_CHANGE);
m_pModifier->Update_UI (m_pModData);
}
return ;
}
///////////////////////////////////////////////////////////////////////////
//
// Redo
//
///////////////////////////////////////////////////////////////////////////
void
VertexRestoreClass::Redo (void)
{
assert (m_pMesh != NULL);
assert (m_pModData != NULL);
assert (m_pModifier != NULL);
//
// Ensure the modifier is in the state it was when
// the undo operation was recorded
//
m_pModData->Set_Current_Set (m_SetIndex);
m_pModData->Peek_Set (m_SetIndex).Set_Current_Key_Frame (m_KeyframeIndex);
//
// Apply the original vertex positions to the mesh
//
Apply_Vertex_Data (m_RedoVertexList);
//
// Notify the mesh of geometry changes
//
m_pModifier->NotifyDependents (FOREVER, PART_GEOM | PART_VERTCOLOR, REFMSG_CHANGE);
m_pModifier->Update_UI (m_pModData);
return ;
}
///////////////////////////////////////////////////////////////////////////
//
// EndHold
//
///////////////////////////////////////////////////////////////////////////
void
VertexRestoreClass::EndHold (void)
{
//
// Record the position of all the verts we are about to change
// (to support redo).
//
Copy_Vertex_State (m_RedoVertexList);
m_pModifier->ClearAFlag (A_HELD);
return ;
}
/***************************************************************************************/
/*
/* End VertexRestoreClass
/*
/***************************************************************************************/
/***************************************************************************************/
/*
/* Start VertexPositionRestoreClass
/*
/***************************************************************************************/
///////////////////////////////////////////////////////////////////////////
//
// VertexPositionRestoreClass
//
///////////////////////////////////////////////////////////////////////////
VertexPositionRestoreClass::VertexPositionRestoreClass
(
Mesh * mesh,
MeshDeformClass * modifier,
MeshDeformModData * mod_data
)
: VertexRestoreClass (mesh, modifier, mod_data)
{
//
// Make a copy of the vertex positions
//
Copy_Vertex_State (m_VertexList);
return ;
}
///////////////////////////////////////////////////////////////////////////
//
// Copy_Vertex_State
//
///////////////////////////////////////////////////////////////////////////
void
VertexPositionRestoreClass::Copy_Vertex_State (DEFORM_LIST &list)
{
//
// Make a copy of each vertex in the current keyframe
//
list.Delete_All ();
MeshDeformSetClass &set_obj = m_pModData->Peek_Set (m_SetIndex);
int count = set_obj.Get_Vertex_Count (m_KeyframeIndex);
for (int index = 0; index < count; index ++) {
const VERT_INFO &data = set_obj.Get_Vertex_Data (m_KeyframeIndex, index);
list.Add (VERT_INFO (data.index, data.value));
}
return ;
}
///////////////////////////////////////////////////////////////////////////
//
// Apply_Vertex_Data
//
///////////////////////////////////////////////////////////////////////////
void
VertexPositionRestoreClass::Apply_Vertex_Data (DEFORM_LIST &list)
{
m_pModData->Peek_Set (m_SetIndex).Reset_Key_Frame_Verts (m_KeyframeIndex);
//
// Apply each vertex in our list
//
for (int index = 0; index < list.Count (); index ++) {
VERT_INFO &info = list[index];
m_pModData->Set_Vertex_Position (info.index, info.value);
}
return ;
}
/***************************************************************************************/
/*
/* End VertexPositionRestoreClass
/*
/***************************************************************************************/
/***************************************************************************************/
/*
/* Start VertexColorRestoreClass
/*
/***************************************************************************************/
///////////////////////////////////////////////////////////////////////////
//
// VertexColorRestoreClass
//
///////////////////////////////////////////////////////////////////////////
VertexColorRestoreClass::VertexColorRestoreClass
(
Mesh * mesh,
MeshDeformClass * modifier,
MeshDeformModData * mod_data
)
: VertexRestoreClass (mesh, modifier, mod_data)
{
//
// Make a copy of the vertex positions
//
Copy_Vertex_State (m_VertexList);
return ;
}
///////////////////////////////////////////////////////////////////////////
//
// Copy_Vertex_State
//
///////////////////////////////////////////////////////////////////////////
void
VertexColorRestoreClass::Copy_Vertex_State (DEFORM_LIST &list)
{
//
// Make a copy of each vertex color in the current keyframe
//
list.Delete_All ();
MeshDeformSetClass &set_obj = m_pModData->Peek_Set (m_SetIndex);
int count = set_obj.Get_Color_Count (m_KeyframeIndex);
for (int index = 0; index < count; index ++) {
const VERT_INFO &data = set_obj.Get_Color_Data (m_KeyframeIndex, index);
list.Add (VERT_INFO (data.index, data.value, data.color_index));
}
return ;
}
///////////////////////////////////////////////////////////////////////////
//
// Apply_Vertex_Data
//
///////////////////////////////////////////////////////////////////////////
void
VertexColorRestoreClass::Apply_Vertex_Data (DEFORM_LIST &list)
{
m_pModData->Peek_Set (m_SetIndex).Reset_Key_Frame_Colors (m_KeyframeIndex);
//
// Apply each vertex in our list
//
for (int index = 0; index < list.Count (); index ++) {
VERT_INFO &info = list[index];
m_pModData->Set_Vertex_Color (info.index, info.color_index, info.value);
}
return ;
}

View file

@ -0,0 +1,155 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando / G 3D engine *
* *
* File Name : MeshDeformUndo.h *
* *
* Programmer : Patrick Smith *
* *
* Start Date : 06/08/99 *
* *
* Last Update :
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef __MESH_DEFORM_UNDO_H
#define __MESH_DEFORM_UNDO_H
#include <Max.H>
#include "Vector.H"
#include "MeshDeformDefs.H"
// Forward declarations
class MeshDeformClass;
class MeshDeformModData;
///////////////////////////////////////////////////////////////////////////
//
// VertexRestoreClass
//
///////////////////////////////////////////////////////////////////////////
class VertexRestoreClass : public RestoreObj
{
public:
//////////////////////////////////////////////////////////////////
// Public constructors/destructor
//////////////////////////////////////////////////////////////////
VertexRestoreClass (Mesh *mesh, MeshDeformClass *modifier, MeshDeformModData *mod_data);
virtual ~VertexRestoreClass (void) { Free_Vertex_Array (); };
//////////////////////////////////////////////////////////////////
// RestoreObj overrides
//////////////////////////////////////////////////////////////////
virtual void Restore (int is_undo);
virtual void Redo (void);
virtual int Size (void) { return (m_VertexList.Count () * sizeof (Point3) * 2) + sizeof (VertexRestoreClass); }
virtual void EndHold (void);
protected:
//////////////////////////////////////////////////////////////////
// Protected methods
//////////////////////////////////////////////////////////////////
virtual void Copy_Vertex_State (DEFORM_LIST &list) = 0;
virtual void Apply_Vertex_Data (DEFORM_LIST &list) = 0;
void Free_Vertex_Array (void);
//////////////////////////////////////////////////////////////////
// Protected member data
//////////////////////////////////////////////////////////////////
Mesh * m_pMesh;
MeshDeformClass * m_pModifier;
MeshDeformModData * m_pModData;
DEFORM_LIST m_VertexList;
DEFORM_LIST m_RedoVertexList;
int m_SetIndex;
int m_KeyframeIndex;
};
///////////////////////////////////////////////////////////////////////////
//
// VertexPositionRestoreClass
//
///////////////////////////////////////////////////////////////////////////
class VertexPositionRestoreClass : public VertexRestoreClass
{
public:
//////////////////////////////////////////////////////////////////
// Public constructors/destructor
//////////////////////////////////////////////////////////////////
VertexPositionRestoreClass (Mesh *mesh, MeshDeformClass *modifier, MeshDeformModData *mod_data);
virtual ~VertexPositionRestoreClass (void) { };
//////////////////////////////////////////////////////////////////
// RestoreObj overrides
//////////////////////////////////////////////////////////////////
TSTR Description (void) { return TSTR(_T("Vertex Position")); }
protected:
//////////////////////////////////////////////////////////////////
// Protected methods
//////////////////////////////////////////////////////////////////
virtual void Copy_Vertex_State (DEFORM_LIST &list);
virtual void Apply_Vertex_Data (DEFORM_LIST &list);
};
///////////////////////////////////////////////////////////////////////////
//
// VertexColorRestoreClass
//
///////////////////////////////////////////////////////////////////////////
class VertexColorRestoreClass : public VertexRestoreClass
{
public:
//////////////////////////////////////////////////////////////////
// Public constructors/destructor
//////////////////////////////////////////////////////////////////
VertexColorRestoreClass (Mesh *mesh, MeshDeformClass *modifier, MeshDeformModData *mod_data);
virtual ~VertexColorRestoreClass (void) { };
//////////////////////////////////////////////////////////////////
// RestoreObj overrides
//////////////////////////////////////////////////////////////////
TSTR Description (void) { return TSTR(_T("Vertex Color")); }
protected:
//////////////////////////////////////////////////////////////////
// Protected methods
//////////////////////////////////////////////////////////////////
virtual void Copy_Vertex_State (DEFORM_LIST &list);
virtual void Apply_Vertex_Data (DEFORM_LIST &list);
};
#endif //__MESH_DEFORM_UNDO_H

View file

@ -0,0 +1,147 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project name : Buccaneer Bay *
* *
* File name : PCToPS2Material.cpp *
* *
* Programmer : Mike Lytle *
* *
* Start date : 10/22/1999 *
* *
* Last update : 10/27/1999 *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* PTPMC::BeginEditParams -- Change all W3D materials in the mesh to be PS2 compatible. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include <Max.h>
#include <gport.h>
#include <hsv.h>
#include "dllmain.h"
#include "resource.h"
#include "util.h"
#include "utilapi.h"
#include "nodelist.h"
#include "gamemtl.h"
Class_ID PCToPS2MaterialClassID(0x40d11cee, 0x68881657);
class PCToPS2MaterialClass : public UtilityObj {
public:
void BeginEditParams(Interface *ip,IUtil *iu);
void EndEditParams(Interface *ip,IUtil *iu) {}
void DeleteThis() {delete this;}
};
/***********************************************************************************************
* PTPMC::BeginEditParams -- Change all W3D materials in the mesh to be PS2 compatible. *
* *
* *
* *
* *
* HISTORY: *
* 10/27/1999MLL: Created. *
*=============================================================================================*/
void PCToPS2MaterialClass::BeginEditParams(Interface *ip,IUtil *iu)
{
// This function is called when the utility is chosen.
// Since we don't need any window gadgets, we'll just go through all the materials right away.
INode *root = ip->GetRootNode();
INodeListClass *meshlist = NULL;
// Change all materials associated with the mesh, starting with the root node.
if (root) {
meshlist = new INodeListClass(root, 0);
if (meshlist) {
int i;
for (i = 0; i < meshlist->Num_Nodes(); i++) {
Mtl *nodemtl = ((*meshlist)[i])->GetMtl();
if (nodemtl == NULL) {
// No material on this node, go to the next.
continue;
}
if (!nodemtl->IsMultiMtl()) {
// Only change those that are W3D materials.
if (nodemtl->ClassID() == GameMaterialClassID) {
int pass;
for (pass = 0; pass < ((GameMtl*)nodemtl)->Get_Pass_Count(); pass++) {
// Change the material for each pass.
((GameMtl*)nodemtl)->Compute_PS2_Shader_From_PC_Shader(pass);
}
}
} else {
// Loop through all sub materials of the multi-material.
for (unsigned mi = 0; mi < nodemtl->NumSubMtls(); mi++) {
// Only change those that are W3D materials.
if (nodemtl->GetSubMtl(mi)->ClassID() == GameMaterialClassID) {
int pass;
for (pass = 0; pass < ((GameMtl*)nodemtl->GetSubMtl(mi))->Get_Pass_Count(); pass++) {
// Change the material for each pass.
((GameMtl*)nodemtl->GetSubMtl(mi))->Compute_PS2_Shader_From_PC_Shader(pass);
}
} else if (nodemtl->GetSubMtl(mi)->ClassID() == PS2GameMaterialClassID) {
}
}
}
}
}
delete meshlist;
}
}
class PCToPS2MaterialClassDesc:public ClassDesc {
public:
int IsPublic() { return 1; }
void * Create(BOOL loading)
{
return ((void*)new PCToPS2MaterialClass);
}
const TCHAR * ClassName() { return Get_String(IDS_PC_TO_PS2_MAT_CONVERTER); }
SClass_ID SuperClassID() { return UTILITY_CLASS_ID; }
Class_ID ClassID() { return PCToPS2MaterialClassID; }
const TCHAR* Category() { return _T(""); }
};
static PCToPS2MaterialClassDesc _PCToPS2MaterialCD;
ClassDesc * Get_PS2_Material_Conversion() { return &_PCToPS2MaterialCD; }

View file

@ -0,0 +1,73 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project name : Buccaneer Bay *
* *
* File name : PS2GameMtl.cpp *
* *
* Programmer : Mike Lytle *
* *
* Start date : 10/12/1999 *
* *
* Last update : 10/12/1999 *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "gamemtl.h"
#include <Max.h>
#include <gport.h>
#include <hsv.h>
#include "dllmain.h"
#include "resource.h"
#include "util.h"
/*****************************************************************
*
* PS2 GameMtl Class Descriptor
*
*****************************************************************/
Class_ID PS2GameMaterialClassID(0x2ed62ad7, 0x50571dfd);
// This adds W3D PS2 choice to the Max material selector.
class PS2GameMaterialClassDesc:public ClassDesc {
public:
int IsPublic() { return 1; }
void * Create(BOOL loading)
{
GameMtl *mtl = new GameMtl(loading);
mtl->Set_Shader_Type(GameMtl::STE_PS2_SHADER);
return ((void*)mtl);
}
const TCHAR * ClassName() { return Get_String(IDS_PS2_GAMEMTL); }
SClass_ID SuperClassID() { return MATERIAL_CLASS_ID; }
Class_ID ClassID() { return PS2GameMaterialClassID; }
const TCHAR* Category() { return _T(""); }
};
static PS2GameMaterialClassDesc _PS2GameMaterialCD;
ClassDesc * Get_PS2_Game_Material_Desc() { return &_PS2GameMaterialCD; }

View file

@ -0,0 +1,371 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project name : Buccaneer Bay *
* *
* File name : PS2GameMtlShaderDlg.cpp *
* *
* Programmer : Mike Lytle *
* *
* Start date : 10/12/1999 *
* *
* Last update : 10/12/1999 *
* *
* Taken from GTH's GameMtlShaderDlg.cpp *
*---------------------------------------------------------------------------------------------*
* Functions: *
* PS2GameMtlShaderDlg -- Constructor. *
* PGMSD::Dialog_Proc -- Respond to user selections. *
* PGMSD::ReloadDialog -- Setup the dialog box. *
* PGMSD::Apply_Preset -- Notify the material of the values for the selected setting. *
* PGMSD::Set_Preset -- Sets the dialog to one of the presets or custom. *
* PGMSD::CompareShaderToBlendPreset -- Determine if the settings conform to one of the prese*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "PS2GameMtlShaderDlg.h"
#include "GameMtlDlg.h"
#include "GameMtl.h"
#include "resource.h"
#define NUM_PS2_SHADER_BLEND_PRESETS 7
static char * _PS2ShaderBlendSettingPresetNames[NUM_PS2_SHADER_BLEND_PRESETS + 1] =
{
"Opaque",
"Additive",
"Source Subtracted",
"Destination Subtracted",
"Alpha Blend",
"Alpha Test",
"Alpha Test and Blend",
"------ Custom -----"
};
struct PS2ShaderBlendSettingPreset
{
int A;
int B;
int C;
int D;
bool DepthMask;
bool AlphaTest;
};
// (A - B) * C + D
static const PS2ShaderBlendSettingPreset PS2ShaderBlendSettingPresets[NUM_PS2_SHADER_BLEND_PRESETS] = {
{PSS_SRC, PSS_ZERO, PSS_ONE, PSS_ZERO, true, false}, // Opaque
{PSS_SRC, PSS_ZERO, PSS_ONE, PSS_DEST, false, false}, // Additive
{PSS_DEST, PSS_SRC, PSS_ONE, PSS_ZERO, false, false}, // Src subtracted
{PSS_SRC, PSS_DEST, PSS_ONE, PSS_ZERO, false, false}, // Dest subtracted
{PSS_SRC, PSS_DEST, PSS_SRC_ALPHA, PSS_DEST, false, false}, // Alpha blend
{PSS_SRC, PSS_ZERO, PSS_ONE, PSS_ZERO, true, true}, // Alpha test
{PSS_SRC, PSS_DEST, PSS_SRC_ALPHA, PSS_DEST, true, true}, // Alpha test & blend
};
/***********************************************************************************************
* PS2GameMtlShaderDlg -- Constructor. *
* *
* *
* *
* *
* HISTORY: *
* 10/12/1999MLL: Created. *
*=============================================================================================*/
PS2GameMtlShaderDlg::PS2GameMtlShaderDlg
(
HWND parent,
IMtlParams * imp,
GameMtl * mtl,
int pass
) : GameMtlFormClass(imp,mtl,pass)
{
Create_Form(parent, IDD_GAMEMTL_PS2_SHADER);
}
/***********************************************************************************************
* PGMSD::Dialog_Proc -- Respond to user selections. *
* *
* *
* *
* *
* HISTORY: *
* 10/12/1999MLL: Created. *
*=============================================================================================*/
BOOL PS2GameMtlShaderDlg::Dialog_Proc (HWND dlg_wnd, UINT message, WPARAM wparam, LPARAM lparam)
{
int cursel;
int i;
int id = LOWORD(wparam);
int code = HIWORD(wparam);
switch (message)
{
case WM_INITDIALOG:
for(i = 0; i <= NUM_PS2_SHADER_BLEND_PRESETS; i++) {
SendDlgItemMessage(dlg_wnd,IDC_PS2_PRESET_COMBO,CB_ADDSTRING,0,(LONG)_PS2ShaderBlendSettingPresetNames[i]);
}
SendDlgItemMessage(dlg_wnd,IDC_PS2_PRESET_COMBO,CB_SETCURSEL,0,0);
break;
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
case WM_MOUSEMOVE:
{
IParams->RollupMouseMessage(dlg_wnd,message,wparam,lparam);
}
return FALSE;
case WM_COMMAND:
{
if (code == CBN_SELCHANGE) {
switch (id)
{
// Shared by both shaders.
case IDC_DEPTHCOMPARE_COMBO:
cursel = SendDlgItemMessage(dlg_wnd,IDC_DEPTHCOMPARE_COMBO,CB_GETCURSEL,0,0);
TheMtl->Set_Depth_Compare(PassIndex,cursel);
break;
case IDC_PRIGRADIENT_COMBO:
cursel = SendDlgItemMessage(dlg_wnd,IDC_PRIGRADIENT_COMBO,CB_GETCURSEL,0,0);
TheMtl->Set_Pri_Gradient(PassIndex,cursel);
TheMtl->Notify_Changed();
break;
case IDC_SECGRADIENT_COMBO:
cursel = SendDlgItemMessage(dlg_wnd,IDC_SECGRADIENT_COMBO,CB_GETCURSEL,0,0);
TheMtl->Set_Sec_Gradient(PassIndex,cursel);
TheMtl->Notify_Changed();
break;
case IDC_DETAILCOLOR_COMBO:
cursel = SendDlgItemMessage(dlg_wnd,IDC_DETAILCOLOR_COMBO,CB_GETCURSEL,0,0);
TheMtl->Set_Detail_Color_Func(PassIndex,cursel);
TheMtl->Notify_Changed();
break;
case IDC_DETAILALPHA_COMBO:
cursel = SendDlgItemMessage(dlg_wnd,IDC_DETAILALPHA_COMBO,CB_GETCURSEL,0,0);
TheMtl->Set_Detail_Alpha_Func(PassIndex,cursel);
TheMtl->Notify_Changed();
break;
// Playstation 2 specific.
case IDC_PS2_PRESET_COMBO:
cursel = SendDlgItemMessage(dlg_wnd,IDC_PS2_PRESET_COMBO,CB_GETCURSEL,0,0);
Apply_Preset(cursel);
break;
case IDC_A_COMBO:
cursel = SendDlgItemMessage(dlg_wnd,IDC_A_COMBO,CB_GETCURSEL,0,0);
TheMtl->Set_PS2_Shader_Param_A(PassIndex,cursel);
TheMtl->Notify_Changed();
Set_Preset();
break;
case IDC_B_COMBO:
cursel = SendDlgItemMessage(dlg_wnd,IDC_B_COMBO,CB_GETCURSEL,0,0);
TheMtl->Set_PS2_Shader_Param_B(PassIndex,cursel);
TheMtl->Notify_Changed();
Set_Preset();
break;
case IDC_C_COMBO:
cursel = SendDlgItemMessage(dlg_wnd,IDC_C_COMBO,CB_GETCURSEL,0,0);
TheMtl->Set_PS2_Shader_Param_C(PassIndex,cursel);
TheMtl->Notify_Changed();
Set_Preset();
break;
case IDC_D_COMBO:
cursel = SendDlgItemMessage(dlg_wnd,IDC_D_COMBO,CB_GETCURSEL,0,0);
TheMtl->Set_PS2_Shader_Param_D(PassIndex,cursel);
TheMtl->Notify_Changed();
Set_Preset();
break;
}
} else {
switch(id) {
case IDC_DEPTHMASK_CHECK:
if (SendDlgItemMessage(dlg_wnd,IDC_DEPTHMASK_CHECK,BM_GETCHECK,0,0)) {
TheMtl->Set_Depth_Mask(PassIndex,W3DSHADER_DEPTHMASK_WRITE_ENABLE);
} else {
TheMtl->Set_Depth_Mask(PassIndex,W3DSHADER_DEPTHMASK_WRITE_DISABLE);
}
Set_Preset();
break;
case IDC_ALPHATEST_CHECK:
if (SendDlgItemMessage(dlg_wnd,IDC_ALPHATEST_CHECK,BM_GETCHECK,0,0)) {
TheMtl->Set_Alpha_Test(PassIndex,W3DSHADER_ALPHATEST_ENABLE);
} else {
TheMtl->Set_Alpha_Test(PassIndex,W3DSHADER_ALPHATEST_DISABLE);
}
Set_Preset();
break;
case IDC_SHADER_DEFAULTS_BUTTON:
Set_Advanced_Defaults();
break;
}
}
}
}
return FALSE;
}
/***********************************************************************************************
* PGMSD::ReloadDialog -- Setup the dialog box. *
* *
* *
* *
* *
* HISTORY: *
* 10/12/1999MLL: Created. *
*=============================================================================================*/
void PS2GameMtlShaderDlg::ReloadDialog(void)
{
DebugPrint("GameMtlShaderDlg::ReloadDialog\n");
SendDlgItemMessage(m_hWnd, IDC_PRIGRADIENT_COMBO, CB_SETCURSEL, TheMtl->Get_Pri_Gradient(PassIndex), 0 );
SendDlgItemMessage(m_hWnd, IDC_SECGRADIENT_COMBO, CB_SETCURSEL, TheMtl->Get_Sec_Gradient(PassIndex), 0 );
SendDlgItemMessage(m_hWnd, IDC_DEPTHCOMPARE_COMBO, CB_SETCURSEL, TheMtl->Get_Depth_Compare(PassIndex), 0 );
SendDlgItemMessage(m_hWnd, IDC_DETAILCOLOR_COMBO, CB_SETCURSEL, TheMtl->Get_Detail_Color_Func(PassIndex), 0 );
SendDlgItemMessage(m_hWnd, IDC_DETAILALPHA_COMBO, CB_SETCURSEL, TheMtl->Get_Detail_Alpha_Func(PassIndex), 0 );
SendDlgItemMessage(m_hWnd, IDC_A_COMBO, CB_SETCURSEL, TheMtl->Get_PS2_Shader_Param_A(PassIndex), 0);
SendDlgItemMessage(m_hWnd, IDC_B_COMBO, CB_SETCURSEL, TheMtl->Get_PS2_Shader_Param_B(PassIndex), 0);
SendDlgItemMessage(m_hWnd, IDC_C_COMBO, CB_SETCURSEL, TheMtl->Get_PS2_Shader_Param_C(PassIndex), 0);
SendDlgItemMessage(m_hWnd, IDC_D_COMBO, CB_SETCURSEL, TheMtl->Get_PS2_Shader_Param_D(PassIndex), 0);
Set_Preset();
SetCheckBox(m_hWnd,IDC_DEPTHMASK_CHECK, TheMtl->Get_Depth_Mask(PassIndex));
SetCheckBox(m_hWnd,IDC_ALPHATEST_CHECK, TheMtl->Get_Alpha_Test(PassIndex));
}
/***********************************************************************************************
* PGMSD::Apply_Preset -- Notify the material of the values for the selected setting. *
* *
* *
* *
* *
* HISTORY: *
* 10/12/1999MLL: Created. *
*=============================================================================================*/
void PS2GameMtlShaderDlg::Apply_Preset(int preset_index)
{
if (preset_index < 0 || preset_index >= NUM_PS2_SHADER_BLEND_PRESETS) return;
const PS2ShaderBlendSettingPreset &preset = PS2ShaderBlendSettingPresets[preset_index];
int depth_mask = preset.DepthMask ? W3DSHADER_DEPTHMASK_WRITE_ENABLE : W3DSHADER_DEPTHMASK_WRITE_DISABLE;
TheMtl->Set_Depth_Mask(PassIndex, depth_mask);
int alpha_test = preset.AlphaTest ? W3DSHADER_ALPHATEST_ENABLE : W3DSHADER_ALPHATEST_DISABLE;
TheMtl->Set_Alpha_Test(PassIndex, alpha_test);
TheMtl->Set_PS2_Shader_Param_A(PassIndex, preset.A);
TheMtl->Set_PS2_Shader_Param_B(PassIndex, preset.B);
TheMtl->Set_PS2_Shader_Param_C(PassIndex, preset.C);
TheMtl->Set_PS2_Shader_Param_D(PassIndex, preset.D);
TheMtl->Notify_Changed();
ReloadDialog();
if (TheMtl->Compute_PC_Shader_From_PS2_Shader(PassIndex))
SetWindowText(GetDlgItem(m_hWnd,IDC_COMPATIBLE), " Compatible");
else
SetWindowText(GetDlgItem(m_hWnd,IDC_COMPATIBLE), " NOT Compatible");
}
/***********************************************************************************************
* PGMSD::Set_Preset -- Sets the dialog to one of the presets or custom. *
* *
* *
* *
* *
* HISTORY: *
* 10/12/1999MLL: Created. *
*=============================================================================================*/
void PS2GameMtlShaderDlg::Set_Preset(void)
{
for (int i = 0; i < NUM_PS2_SHADER_BLEND_PRESETS; i++) {
if (CompareShaderToBlendPreset(PS2ShaderBlendSettingPresets[i])) break;
}
SendDlgItemMessage(m_hWnd, IDC_PS2_PRESET_COMBO, CB_SETCURSEL, i, 0);
if (TheMtl->Compute_PC_Shader_From_PS2_Shader(PassIndex))
SetWindowText(GetDlgItem(m_hWnd,IDC_COMPATIBLE), " Compatible");
else
SetWindowText(GetDlgItem(m_hWnd,IDC_COMPATIBLE), " NOT Compatible");
}
/***********************************************************************************************
* PGMSD::CompareShaderToBlendPreset -- Determine if the settings conform to one of the presets*
* *
* *
* *
* *
* HISTORY: *
* 10/12/1999MLL: Created. *
*=============================================================================================*/
bool PS2GameMtlShaderDlg::CompareShaderToBlendPreset(const PS2ShaderBlendSettingPreset &blend_preset)
{
bool depthmask = TheMtl->Get_Depth_Mask(PassIndex) != W3DSHADER_DEPTHMASK_WRITE_DISABLE;
if (depthmask != blend_preset.DepthMask) return false;
bool alphatest = TheMtl->Get_Alpha_Test(PassIndex) != W3DSHADER_ALPHATEST_DISABLE;
if (alphatest != blend_preset.AlphaTest) return false;
if (TheMtl->Get_PS2_Shader_Param_A(PassIndex) != blend_preset.A) return false;
if (TheMtl->Get_PS2_Shader_Param_B(PassIndex) != blend_preset.B) return false;
if (TheMtl->Get_PS2_Shader_Param_C(PassIndex) != blend_preset.C) return false;
if (TheMtl->Get_PS2_Shader_Param_D(PassIndex) != blend_preset.D) return false;
return true;
}
/***********************************************************************************************
* GameMtlShaderDlg::Set_Advanced_Defaults -- set advanced settings to defaults *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 02/26/99 NH : Created. *
*=============================================================================================*/
void PS2GameMtlShaderDlg::Set_Advanced_Defaults(void)
{
TheMtl->Set_Pri_Gradient(PassIndex, PSS_PRIGRADIENT_MODULATE);
TheMtl->Set_Depth_Compare(PassIndex, PSS_DEPTHCOMPARE_PASS_LEQUAL);
TheMtl->Set_Detail_Color_Func(PassIndex, W3DSHADER_DETAILCOLORFUNC_DEFAULT);
TheMtl->Set_Detail_Alpha_Func(PassIndex, W3DSHADER_DETAILALPHAFUNC_DEFAULT);
TheMtl->Notify_Changed();
ReloadDialog();
}

View file

@ -0,0 +1,71 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project name : Buccaneer Bay *
* *
* File name : PS2GameMtlShaderDlg.h *
* *
* Programmer : Mike Lytle *
* *
* Start date : 10/12/1999 *
* *
* Last update : 10/12/1999 *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef PS2GAMEMTLSHADERDLG_H
#define PS2GAMEMTLSHADERDLG_H
#include <Max.h>
#include "GameMtlForm.h"
// This class was taken from GTH's GameMtlShaderDlg.
class GameMtl;
struct PS2ShaderBlendSettingPreset;
class PS2GameMtlShaderDlg : public GameMtlFormClass
{
public:
PS2GameMtlShaderDlg(HWND parent, IMtlParams * imp, GameMtl * m, int pass);
virtual BOOL Dialog_Proc (HWND dlg_wnd, UINT message, WPARAM wparam, LPARAM lparam);
void ReloadDialog(void);
// Pure virtual that must be defined.
void ActivateDlg(BOOL onOff) {}
private:
void Apply_Preset(int preset_index);
void Set_Preset(void);
bool CompareShaderToBlendPreset(const PS2ShaderBlendSettingPreset &blend_preset);
void Set_Advanced_Defaults(void);
};
#endif

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 822 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 822 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

View file

@ -0,0 +1,123 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : G *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/SceneSetup.cpp $*
* *
* $Author:: Andre_a $*
* *
* $Modtime:: 10/15/99 3:33p $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* wwSceneSetup -- Allows the user to select how many LOD and damage models to create. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*
** SceneSetup.cpp - Implements the "wwSceneSetup" MAXScript function to
** present a nice dialog to the user for getting a number of parameters
** that will governs the number, placement, and type of LOD and Damage
** models created in the scene.
*/
#include "SceneSetupDlg.h"
#undef STRICT
#include <MaxScrpt.h>
#include <Numbers.h>
#include <Arrays.h>
#include <definsfn.h>
/*
** Let MAXScript know we're implementing new built-in functions.
*/
def_visible_primitive(scene_setup, "wwSceneSetup");
/***********************************************************************************************
* scene_setup_cf - MAXScript function wwSceneSetup *
* *
* wwSceneSetup - Usage: wwSceneSetup arg_array *
* *
* INPUT: *
* The contents of the given array is assumed to be as follows: *
* lod_count (int) - the number of LOD models that will be created *
* lod_offset (float) - X offset to move the LODs by *
* lod_clone (int) - 1==copy 2==instance 3==reference *
* damage_count (int) - the number of damage models that will be created *
* damage_offset (float) - Y offset to move the LODs by *
* damage_clone (int) - 1==copy 2==instance 3==reference *
* *
* OUTPUT: *
* The function returns an array of the new values the user selected in the same format as *
* above.
* *
* WARNINGS: *
* *
* HISTORY: *
* 9/27/1999 AJA : Created. *
*=============================================================================================*/
Value * scene_setup_cf (Value **arg_list, int count)
{
// We don't want any arguments for this function.
check_arg_count("wwSceneSetup", 1, count);
type_check(arg_list[0], Array, "Parameter array");
SceneSetupDlg dlg(MAXScript_interface);
one_typed_value_local(Array* result);
// Read the initial values out of the array.
Array *args = (Array*)(arg_list[0]);
dlg.m_LodCount = (args->get(1))->to_int();
dlg.m_LodOffset = (args->get(2))->to_float();
dlg.m_LodProc = (args->get(3))->to_int();
dlg.m_DamageCount = (args->get(4))->to_int();
dlg.m_DamageOffset = (args->get(5))->to_float();
dlg.m_DamageProc = (args->get(6))->to_int();
// Display the dialog
if (dlg.DoModal() == IDCANCEL)
{
pop_value_locals();
return &undefined;
}
// Stuff the values the user chose into the array we'll return.
vl.result = new Array(6);
vl.result->append(Integer::intern(dlg.m_LodCount));
vl.result->append(Float::intern(dlg.m_LodOffset));
vl.result->append(Integer::intern(dlg.m_LodProc));
vl.result->append(Integer::intern(dlg.m_DamageCount));
vl.result->append(Float::intern(dlg.m_DamageOffset));
vl.result->append(Integer::intern(dlg.m_DamageProc));
// Return the array of new values.
return_value(vl.result);
}

View file

@ -0,0 +1,285 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : G *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/SceneSetupDlg.cpp $*
* *
* $Author:: Andre_a $*
* *
* $Modtime:: 10/15/99 3:37p $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
// SceneSetupDlg.cpp : implementation file
//
#include "SceneSetupDlg.h"
#include <Max.h>
#include <assert.h>
static BOOL CALLBACK _thunk_dialog_proc (HWND hWnd, UINT uMsg, WPARAM wAparam, LPARAM lParam);
/////////////////////////////////////////////////////////////////////////////
// SceneSetupDlg dialog
SceneSetupDlg::SceneSetupDlg(Interface *max_interface)
{
m_DamageCount = 0;
m_DamageOffset = -100.0f;
m_LodCount = 0;
m_LodOffset = -100.0f;
m_DamageProc = 3;
m_LodProc = 3;
m_hWnd = NULL;
m_MaxInterface = max_interface;
assert(max_interface != NULL);
}
/////////////////////////////////////////////////////////////////////////////
// SceneSetupDlg Protected Methods
void SceneSetupDlg::SetEditInt (int control_id, int value)
{
char buf[64];
sprintf(buf, "%d", value);
HWND edit = GetDlgItem(m_hWnd, control_id);
assert(edit != NULL);
SetWindowText(edit, buf);
}
void SceneSetupDlg::SetEditFloat (int control_id, float value)
{
char buf[64];
sprintf(buf, "%.0f", value);
HWND edit = GetDlgItem(m_hWnd, control_id);
assert(edit != NULL);
SetWindowText(edit, buf);
}
int SceneSetupDlg::GetEditInt (int control_id)
{
char buf[64];
HWND edit = GetDlgItem(m_hWnd, control_id);
assert(edit != NULL);
GetWindowText(edit, buf, sizeof(buf));
int value = 0;
sscanf(buf, "%d", &value);
return value;
}
float SceneSetupDlg::GetEditFloat (int control_id)
{
char buf[64];
HWND edit = GetDlgItem(m_hWnd, control_id);
assert(edit != NULL);
GetWindowText(edit, buf, sizeof(buf));
float value = 0;
sscanf(buf, "%f", &value);
return value;
}
bool SceneSetupDlg::ValidateEditFloat (int control_id)
{
char buf[64];
HWND edit = GetDlgItem(m_hWnd, control_id);
assert(edit != NULL);
GetWindowText(edit, buf, sizeof(buf));
float value = 0;
if (sscanf(buf, "%f", &value) == 1)
return true;
else
return false;
}
/////////////////////////////////////////////////////////////////////////////
// SceneSetupDlg Public Methods
int SceneSetupDlg::DoModal (void)
{
// Put up the dialog box.
BOOL result = DialogBoxParam(AppInstance, MAKEINTRESOURCE(IDD_SCENE_SETUP),
m_MaxInterface->GetMAXHWnd(), (DLGPROC)_thunk_dialog_proc,
(LPARAM)this);
// Return IDOK if the user accepted the new settings.
return (result == 1) ? IDOK : IDCANCEL;
}
/////////////////////////////////////////////////////////////////////////////
// SceneSetupDlg DialogProc
BOOL CALLBACK _thunk_dialog_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static SceneSetupDlg *dialog = NULL;
if (uMsg == WM_INITDIALOG)
{
dialog = (SceneSetupDlg*)lParam;
dialog->m_hWnd = hWnd;
}
if (dialog)
return dialog->DialogProc(hWnd, uMsg, wParam, lParam);
else
return 0;
}
BOOL CALLBACK SceneSetupDlg::DialogProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
int code = HIWORD(wParam);
switch (uMsg)
{
/*******************************************************************
* WM_INITDIALOG
*
* Initialize all of the custom controls for the dialog box
*
*******************************************************************/
case WM_INITDIALOG:
OnInitDialog();
return TRUE;
/*******************************************************************
* WM_COMMAND
*
*
*******************************************************************/
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
if (OnOK() == FALSE)
return TRUE;
SetCursor(LoadCursor(NULL, IDC_WAIT));
EndDialog(m_hWnd, 1);
break;
case IDCANCEL:
EndDialog(m_hWnd, 0);
break;
}
return TRUE;
}
return FALSE;
}
/////////////////////////////////////////////////////////////////////////////
// SceneSetupDlg message handlers
void SceneSetupDlg::OnInitDialog()
{
CenterWindow(m_hWnd, m_MaxInterface->GetMAXHWnd());
SetCursor(LoadCursor(NULL, IDC_ARROW));
// Select the appropriate radio buttons.
switch (m_LodProc)
{
case 1:
CheckDlgButton(m_hWnd, IDC_LOD_AS_COPY, BST_CHECKED);
break;
case 2:
CheckDlgButton(m_hWnd, IDC_LOD_AS_INSTANCE, BST_CHECKED);
break;
case 3:
CheckDlgButton(m_hWnd, IDC_LOD_AS_REFERENCE, BST_CHECKED);
break;
}
switch (m_DamageProc)
{
case 1:
CheckDlgButton(m_hWnd, IDC_DAMAGE_AS_COPY, BST_CHECKED);
break;
case 2:
CheckDlgButton(m_hWnd, IDC_DAMAGE_AS_INSTANCE, BST_CHECKED);
break;
case 3:
CheckDlgButton(m_hWnd, IDC_DAMAGE_AS_REFERENCE, BST_CHECKED);
break;
}
// Set the text for the edit boxes.
SetEditInt(IDC_LOD_COUNT, m_LodCount);
SetEditFloat(IDC_LOD_OFFSET, m_LodOffset);
SetEditInt(IDC_DAMAGE_COUNT, m_DamageCount);
SetEditFloat(IDC_DAMAGE_OFFSET, m_DamageOffset);
}
BOOL SceneSetupDlg::OnOK()
{
if (!ValidateEditFloat(IDC_LOD_OFFSET))
{
MessageBox(m_hWnd, "You must enter a valid number for the LOD Offset.",
"Not a Number", MB_OK);
SetFocus(GetDlgItem(m_hWnd, IDC_LOD_OFFSET));
return FALSE;
}
if (!ValidateEditFloat(IDC_DAMAGE_OFFSET))
{
MessageBox(m_hWnd, "You must enter a valid number for the Damage Offset.",
"Not a Number", MB_OK);
SetFocus(GetDlgItem(m_hWnd, IDC_DAMAGE_OFFSET));
return FALSE;
}
// Get the clone procedure the user wants to use.
if (IsDlgButtonChecked(m_hWnd, IDC_LOD_AS_COPY))
m_LodProc = 1;
else if (IsDlgButtonChecked(m_hWnd, IDC_LOD_AS_INSTANCE))
m_LodProc = 2;
else if (IsDlgButtonChecked(m_hWnd, IDC_LOD_AS_REFERENCE))
m_LodProc = 3;
if (IsDlgButtonChecked(m_hWnd, IDC_DAMAGE_AS_COPY))
m_DamageProc = 1;
else if (IsDlgButtonChecked(m_hWnd, IDC_DAMAGE_AS_INSTANCE))
m_DamageProc = 2;
else if (IsDlgButtonChecked(m_hWnd, IDC_DAMAGE_AS_REFERENCE))
m_DamageProc = 3;
// Get the other values the user selected.
m_LodCount = GetEditInt(IDC_LOD_COUNT);
m_LodOffset = GetEditFloat(IDC_LOD_OFFSET);
m_DamageCount = GetEditInt(IDC_DAMAGE_COUNT);
m_DamageOffset = GetEditFloat(IDC_DAMAGE_OFFSET);
return TRUE;
}

View file

@ -0,0 +1,95 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : G *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/SceneSetupDlg.h $*
* *
* $Author:: Andre_a $*
* *
* $Modtime:: 10/15/99 4:24p $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef SCENESETUPDLG_H
#define SCENESETUPDLG_H
// SceneSetupDlg.h : header file
//
#include "dllmain.h"
#include "Resource.h"
class Interface;
/////////////////////////////////////////////////////////////////////////////
// SceneSetupDlg dialog
class SceneSetupDlg
{
public:
// Construction
SceneSetupDlg(Interface *max_interface);
// Methods
int DoModal (void);
// DialogProc
BOOL CALLBACK DialogProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
// Dialog data associated with GUI components.
enum { IDD = IDD_SCENE_SETUP };
int m_DamageCount;
float m_DamageOffset;
int m_LodCount;
float m_LodOffset;
int m_LodProc;
int m_DamageProc;
// Dialog Data
HWND m_hWnd;
protected:
// Message Handlers
void OnInitDialog (void);
BOOL OnOK (void); // TRUE if ok to close dialog
// Protected Methods
void SetEditInt (int control_id, int value);
void SetEditFloat (int control_id, float value);
int GetEditInt (int control_id);
float GetEditFloat (int control_id);
bool ValidateEditFloat (int control_id);
// Protected Data
Interface *m_MaxInterface;
};
#endif

View file

@ -0,0 +1,526 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : G *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/SkinCopy.cpp $*
* *
* $Author:: Andre_a $*
* *
* $Modtime:: 11/03/99 11:51a $*
* *
* $Revision:: 3 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* find_skin_binding -- Find the "WWSkin Binding" modifier on this object. *
* find_skin_wsm -- Finds the node for the WWSkin WSM used by this object. *
* get_skin_wsm_obj -- Gets the SkinWSMObjectClass from a WWSkin WSM node. *
* duplicate_wsm -- Duplicates a WWSkin WSM *
* find_equivalent_node -- Searches a hierarchy for an object equivalent to the given one. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*
-- Copy the skin info for this object into the target object.
-- If we haven't copied the WSM yet, it will be copied.
new_wsm = wwCopySkinInfo source_root target_root new_wsm
*/
#include <MaxScrpt.h> // Main MAXScript header
#include <MaxObj.h> // MAX* Wrapper objects
#include <definsfn.h> // def_* functions to create static function headers
#include <Max.h>
#include <modstack.h>
#include "skin.h"
#include "util.h"
#include "w3d_file.h"
/*
** Forward declarations
*/
Value *find_skin_node_in_tree (INode *root);
SkinModifierClass *find_skin_binding (INode *skinned_obj);
INode *find_skin_wsm (INode *skinned_obj);
SkinWSMObjectClass *get_skin_wsm_obj (INode *wsm_node);
INode *duplicate_wsm (INode *skinned_obj, INode *tree_root);
INode *find_equivalent_node (INode *source, INode *tree, bool name_is_valid = false);
Value *copy_skin_info (INode *source, INode *target, INode *wsm);
IDerivedObject *setup_wsm_derived_obj (INode *node);
ModContext *find_skin_mod_context (INode *node);
/*
** Let MAXScript know we're implementing a new built-in function.
*/
def_visible_primitive(find_skin_node, "wwFindSkinNode");
def_visible_primitive(copy_skin_info, "wwCopySkinInfo");
def_visible_primitive(dupe_skin_wsm, "wwDuplicateSkinWSM");
/*
**
** MAXScript Function:
** wwFindSkinNode - Usage: wwFindSkinNode tree_root_node
**
** Searches the given hierarchy tree for the node containing
** the WWSkin WSM. Returns the node if found, otherwise it
** returns undefined.
**
** Used by the SceneSetup MAXScript.
*/
Value *find_skin_node_cf (Value **arg_list, int count)
{
// Verify the number and type of the arguments.
check_arg_count("wwFindSkinNode", 1, count);
type_check(arg_list[0], MAXNode, "Tree Root INode");
// Get the INode that was passed in.
INode *tree_root = arg_list[0]->to_node();
// Search the tree for the WWSkin WSM, and return
// the node which references it.
return find_skin_node_in_tree(tree_root);
}
/*
**
** MAXScript Function:
** wwCopySkinInfo - Usage: wwCopySkinInfo from_node to_node wsm_node to_tree_root
**
** Copies the skin info for the given node to the target node.
** If wsm_node is "undefined" then we will create a new WWSkin WSM
** with the same values as the one being used by from_node.
** If from_node doesn't have a WWSkin binding, the return value
** is "undefined". If the function succeeds, it returns the
** wsm_node (the new WSM if it was created, otherwise the old wsm_node).
**
** Used by the SceneSetup MAXScript.
*/
Value * copy_skin_info_cf (Value **arg_list, int count)
{
// Verify the number and type of the arguments.
check_arg_count("wwCopySkinInfo", 4, count);
type_check(arg_list[0], MAXNode, "Source INode");
type_check(arg_list[1], MAXNode, "Target INode");
type_check(arg_list[3], MAXNode, "Target Tree Root INode");
// Get the INode pointers that were passed in.
INode *src_node = arg_list[0]->to_node();
INode *dest_node = arg_list[1]->to_node();
INode *wsm_node = NULL;
INode *tree_root = arg_list[3]->to_node();
if (arg_list[2] == &undefined)
{
// Duplicate the WSM used by src_node.
wsm_node = duplicate_wsm(find_skin_wsm(src_node), tree_root);
if (wsm_node == NULL)
return &undefined;
}
else
wsm_node = arg_list[2]->to_node();
return copy_skin_info(src_node, dest_node, wsm_node);
}
/*
**
** MAXScript Function:
** wwDuplicateSkinWSM - Usage: wwDuplicateSkinWSM wwskin_wsm_node tree_root
**
** Duplicates the given WWSkin WSM. tree_root is the root node of a hierarchy
** containing bones similar to the ones used by the given WSM. The hierarchy
** will be searched for equivalent bones (ie. names the same except their
** extension), and those bones will be used by the newly duplicated WSM.
**
** Used by the SceneSetup MAXScript.
*/
Value * dupe_skin_wsm_cf (Value **arg_list, int count)
{
// Verify the number and type of the arguments.
check_arg_count("wwDuplicateSkinWSM", 2, count);
type_check(arg_list[0], MAXNode, "WWSkin Object INode");
type_check(arg_list[1], MAXNode, "Target Tree Root INode");
// Get the INode pointers that were passed in.
INode *wsm_node = arg_list[0]->to_node();
INode *root_node = arg_list[1]->to_node();
// Return the duplicated WWSkin WSM.
INode *dupe = duplicate_wsm(wsm_node, root_node);
if (!dupe)
return &undefined;
else
{
// Return the WSM.
one_typed_value_local(Value* wsm_node);
vl.wsm_node = MAXNode::intern(dupe);
return_value(vl.wsm_node);
}
}
Value *find_skin_node_in_tree (INode *root)
{
if (root == NULL)
return &undefined;
// Is this the node we're looking for?
if (get_skin_wsm_obj(root))
{
one_typed_value_local(Value* wsm_node);
vl.wsm_node = MAXNode::intern(root);
return_value(vl.wsm_node);
}
// Search the children of this node.
for (int i = 0; i < root->NumChildren(); i++)
{
Value *retval = find_skin_node_in_tree(root->GetChildNode(i));
if (retval != &undefined)
return retval;
}
// Didn't find it anywhere!
return &undefined;
}
/***********************************************************************************************
* find_skin_binding -- Find the "WWSkin Binding" modifier on this object. *
* *
* INPUT: The skinned object. *
* *
* OUTPUT: The skin modifier, or NULL if one doesn't exist. *
* *
* WARNINGS: *
* *
* HISTORY: *
* 10/19/1999 AJA : Created. *
*=============================================================================================*/
SkinModifierClass *find_skin_binding (INode *skinned_obj)
{
// WWSkin Binding ties us to a space warp, so search the node's
// WSM Derived Object for the WWSkin Binding modifier.
IDerivedObject *dobj = skinned_obj->GetWSMDerivedObject();
if (dobj == NULL)
return NULL; // not bound to a space warp
// Search for the WWSkin Binding modifier on this derived object.
for (int i = 0; i < dobj->NumModifiers(); i++)
{
Modifier *mod = dobj->GetModifier(i);
if (mod->ClassID() != SKIN_MOD_CLASS_ID)
continue;
// We found the skin modifier.
return (SkinModifierClass*)mod;
}
// Skin modifier not found.
return NULL;
}
/***********************************************************************************************
* find_skin_wsm -- Finds the node for the WWSkin WSM used by this object. *
* *
* INPUT: The node of an object with a WWSkin Binding. *
* *
* OUTPUT: The node of the WWSkin WSM referenced by the given object. *
* *
* WARNINGS: *
* *
* HISTORY: *
* 10/18/1999 AJA : Created. *
*=============================================================================================*/
INode *find_skin_wsm (INode *skinned_obj)
{
// Find the skin modifier on this object.
SkinModifierClass *skin_mod = find_skin_binding(skinned_obj);
if (skin_mod == NULL)
return NULL;
// Using the skin modifer, find the WSM's INode.
INode *wsm = (INode*)( skin_mod->GetReference(SkinModifierClass::NODE_REF) );
if (wsm == NULL)
{
char buf[256];
sprintf(buf, "%s has a WWSkin Binding, but I can't find its WWSkin WSM!",
skinned_obj->GetName());
throw RuntimeError(buf);
}
return wsm;
}
/***********************************************************************************************
* get_skin_wsm_obj -- Gets the SkinWSMObjectClass from a WWSkin WSM node. *
* *
* INPUT: The node for the WWSkin WSM's representation in the scene. *
* *
* OUTPUT: The SkinWSMObjectClass. *
* *
* WARNINGS: *
* *
* HISTORY: *
* 10/18/1999 AJA : Created. *
*=============================================================================================*/
SkinWSMObjectClass *get_skin_wsm_obj (INode *wsm_node)
{
// We need a valid node.
if (!wsm_node)
return NULL;
// The node must reference an object.
Object *obj = wsm_node->GetObjectRef();
if (!obj)
return NULL;
// That BASE object must be a SkinWSMObject
while (obj)
{
// If this is a derived object, burrow deeper,
// otherwise we're at the base object.
if (obj->SuperClassID() == GEN_DERIVOB_CLASS_ID)
obj = ((IDerivedObject*)obj)->GetObjRef();
else
break;
}
if (obj->ClassID() != SKIN_OBJ_CLASS_ID)
return NULL;
// Return it.
return (SkinWSMObjectClass*)obj;
}
/***********************************************************************************************
* duplicate_wsm -- Duplicates a WWSkin WSM *
* *
* INPUT: wsm_node - INode of the WWSkin WSM object. *
* tree - The root of a tree containing equivalents of the bones in the WWSkin used *
* by skinned_obj. The bone names must be the same (after being processed by *
* Set_W3D_Name() *
* *
* OUTPUT: The node of the newly duplicated WWSkin WSM. *
* *
* WARNINGS: *
* *
* HISTORY: *
* 10/18/1999 AJA : Created. *
* 11/3/1999 AJA : Changed first argument from skinned_obj to wsm_node. *
*=============================================================================================*/
INode *duplicate_wsm (INode *wsm_node, INode *tree)
{
SkinWSMObjectClass *wsm_obj = get_skin_wsm_obj(wsm_node);
if (!wsm_node || !wsm_obj)
return NULL;
/*
** Duplicate the WSM.
*/
SkinWSMObjectClass *new_wsm_obj =
(SkinWSMObjectClass*)CreateInstance(WSM_OBJECT_CLASS_ID, SKIN_OBJ_CLASS_ID);
if (!new_wsm_obj)
return NULL;
// Create a new node in the scene that points to the new WSM object.
INode *new_wsm_node = MAXScript_interface->CreateObjectNode(new_wsm_obj);
if (!new_wsm_node)
return NULL;
// Copy the bones from one to the other.
for (int i = 0; i < wsm_obj->Num_Bones(); i++)
{
INode *src_bone = wsm_obj->Get_Bone(i);
INode *dst_bone = find_equivalent_node(src_bone, tree);
if (!src_bone || !dst_bone)
return NULL;
new_wsm_obj->Add_Bone(dst_bone);
}
// Return a pointer to the new WSM node.
return new_wsm_node;
}
/***********************************************************************************************
* find_equivalent_node -- Searches a hierarchy for an object equivalent to the given one. *
* *
* INPUT: source - The node to search for an equivalent of. *
* tree - The hierarchy to search in. *
* *
* OUTPUT: The equivalent node, or NULL if none was found. *
* *
* WARNINGS: *
* *
* HISTORY: *
* 10/19/1999 AJA : Created. *
*=============================================================================================*/
INode *find_equivalent_node (INode *source, INode *tree, bool name_is_valid)
{
// We need a valid source and tree.
if (!source || !tree)
return NULL;
// The name of the source object. We'll only evaluate this once as an easy optimization.
static char src_name[W3D_NAME_LEN];
if (!name_is_valid)
Set_W3D_Name(src_name, source->GetName());
// The name of the current object we're examining.
char chk_name[W3D_NAME_LEN];
Set_W3D_Name(chk_name, tree->GetName());
// Is this the node we're looking for?
if (strcmp(src_name, chk_name) == 0)
return tree; // Yup, sure is.
// Nope. Check its children.
for (int i = 0; i < tree->NumberOfChildren(); i++)
{
INode *retval = find_equivalent_node(source, tree->GetChildNode(i), true);
if (retval != NULL)
return retval; // we found the node in our children
}
// No equivalent node was found.
return NULL;
}
Value *copy_skin_info (INode *source, INode *target, INode *wsm)
{
// Get the "WWSkin Binding" modifier on the source object.
SkinModifierClass *source_modifier = find_skin_binding(source);
if (source_modifier == NULL)
return &undefined;
// Get the WSMDerivedObject we can add our skin binding modifier to.
IDerivedObject *dobj = setup_wsm_derived_obj(target);
// Create a new skin modifier and copy the source modifier's settings to it.
SkinModifierClass *new_modifier = new SkinModifierClass(wsm, get_skin_wsm_obj(wsm));
if (new_modifier == NULL)
throw RuntimeError("Out of memory - Unable to allocate a new SkinModifierClass object!");
new_modifier->SubObjSelLevel = source_modifier->SubObjSelLevel;
// Dupe the mod context, especially the local mod data hanging off of it.
ModContext *source_context = find_skin_mod_context(source);
ModContext *new_context = new ModContext(source_context->tm, source_context->box,
source_context->localData);
if (new_context == NULL)
throw RuntimeError("Out of memory - Unable to allocate a new ModContext object!");
// Add a new "WWSkin Binding" modifier to the target object to associate
// the object with the skin WSM. All of the settings should be correct,
// and the target object becomes a "skinned object".
dobj->AddModifier(new_modifier, new_context);
// Return the WSM.
one_typed_value_local(Value* wsm_node);
vl.wsm_node = MAXNode::intern(wsm);
return_value(vl.wsm_node);
}
IDerivedObject *setup_wsm_derived_obj (INode *node)
{
// Check if the target object is already bound to a space warp.
IDerivedObject *dobj = node->GetWSMDerivedObject();
if (dobj != NULL)
{
// It's bound to a space warp. Check if WWSkin is one of the
// space warp bindings. If so, remove it (we don't want to
// be bound to an old skin).
for (int i = 0; i < dobj->NumModifiers(); i++)
{
Modifier *mod = dobj->GetModifier(i);
if (mod->ClassID() != SKIN_MOD_CLASS_ID)
continue;
// We found the skin modifier, remove it.
dobj->DeleteModifier(i);
break;
}
}
else
{
// This object isn't bound to a space warp. Create a
// WSMDerivedObject for the node to play with.
dobj = CreateWSDerivedObject(node->GetObjectRef());
if (dobj == NULL)
{
char msg[128];
sprintf(msg, "Error setting up the WSMDerivedObject for %s", node->GetName());
throw RuntimeError(msg);
}
node->SetObjectRef(dobj);
}
return dobj;
}
ModContext *find_skin_mod_context (INode *node)
{
// We need a valid node
if (node == NULL)
return NULL;
// The node needs to be bound to a space warp (ie. must have
// a WSMDerivedObject).
IDerivedObject *dobj = node->GetWSMDerivedObject();
if (dobj == NULL)
return NULL;
// It's bound to a space warp. Find the WWSkin modifier.
for (int i = 0; i < dobj->NumModifiers(); i++)
{
Modifier *mod = dobj->GetModifier(i);
if (mod->ClassID() != SKIN_MOD_CLASS_ID)
continue;
// We found the skin modifier, return its mod context.
return dobj->GetModContext(i);
}
// We didn't find a WWSkin binding.
return NULL;
}

View file

@ -0,0 +1,98 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Max2W3d *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/SnapPoints.cpp $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 11/23/98 11:05a $*
* *
* $Revision:: 3 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#include "SnapPoints.h"
#include "chunkio.h"
#include "Max.h"
#include "nodelist.h"
#include "w3d_file.h"
class PointFilterClass : public INodeFilterClass
{
public:
PointFilterClass(void) { }
virtual BOOL Accept_Node(INode * node, TimeValue time)
{
if (node == NULL) return FALSE;
Object * obj = node->EvalWorldState(time).obj;
if (obj == NULL) return FALSE;
if
(
obj->ClassID() == Class_ID(POINTHELP_CLASS_ID,0) &&
!node->IsHidden()
)
{
return TRUE;
} else {
return FALSE;
}
}
};
void SnapPointsClass::Export_Points(INode * scene_root,TimeValue time,ChunkSaveClass & csave)
{
if (scene_root == NULL) return;
PointFilterClass pointfilter;
INodeListClass pointlist(scene_root,time,&pointfilter);
if (pointlist.Num_Nodes() > 0) {
csave.Begin_Chunk(W3D_CHUNK_POINTS);
for (unsigned int ci=0; ci<pointlist.Num_Nodes(); ci++) {
W3dVectorStruct vect;
Point3 pos = pointlist[ci]->GetNodeTM(time).GetTrans();
vect.X = pos.x;
vect.Y = pos.y;
vect.Z = pos.z;
csave.Write(&vect,sizeof(vect));
}
csave.End_Chunk();
}
}

View file

@ -0,0 +1,61 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Max2W3D *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/SnapPoints.h $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 11/19/98 4:36p $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef SNAPPOINTS_H
#define SNAPPOINTS_H
#include "Max.h"
class ChunkSaveClass;
class INode;
/*
** This class simply contains static functions which will find
** helper points that should be exported with a w3d render object and
** export them in a chunk using the given ChunkSaveClass object.
*/
class SnapPointsClass
{
public:
static void Export_Points(INode * scene_root,TimeValue time,ChunkSaveClass & csave);
};
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,320 @@
/*
** Command & Conquer Generals(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/>.
*/
#ifndef _TARGA_H_
#define _TARGA_H_
/****************************************************************************
*
* C O N F I D E N T I A L --- W E S T W O O D S T U D I O S
*
*----------------------------------------------------------------------------
*
* FILE
* Targa.h
*
* DESCRIPTION
* Targa image file class definitions.
*
* PROGRAMMER
* Denzil E. Long, Jr.
*
* DATE
* July 15, 1998
*
****************************************************************************/
#pragma pack(push, 1)
// If you wish to display loading error messages call targa functions inside of
// the following macro - for example TARGA_ERROR_HANDLER(targa.Open(filename, TGA_READMODE));
// The error code is returned back from the handler so it can be used in an expression.
long Targa_Error_Handler(long error_code,const char* filename);
#define TARGA_ERROR_HANDLER(call,filename) Targa_Error_Handler(call,filename)
/*---------------------------------------------------------------------------
* STRUCTURES AND RELATED DEFINITIONS
*-------------------------------------------------------------------------*/
/* TGAHeader - Targa Image File header.
*
* IDLength - Size of Image ID field
* ColorMapType - Color map type.
* ImageType - Image type code.
* CMapStart - Color map origin.
* CMapLength - Color map length.
* CMapDepth - Depth of color map entries.
* XOffset - X origin of image.
* YOffset - Y origin of image.
* Width - Width of image.
* Height - Height of image.
* PixelDepth - Image pixel size
* ImageDescriptor - Image descriptor byte.
*/
typedef struct _TGAHeader
{
char IDLength;
char ColorMapType;
char ImageType;
short CMapStart;
short CMapLength;
char CMapDepth;
short XOffset;
short YOffset;
short Width;
short Height;
char PixelDepth;
char ImageDescriptor;
} TGAHeader;
/* ImageType definiton */
#define TGA_NOIMAGE 0 /* No image data included in file */
#define TGA_CMAPPED 1 /* Color-mapped image data */
#define TGA_TRUECOLOR 2 /* Truecolor image data */
#define TGA_MONO 3 /* Monochrome image data */
#define TGA_CMAPPED_ENCODED 9 /* Color-mapped image data (Encoded) */
#define TGA_TRUECOLOR_ENCODED 10 /* Truecolor image data (Encoded) */
#define TGA_MONO_ENCODED 11 /* Monochrome image data (Encoded) */
/* ImageDescriptor definition */
#define TGAIDF_ATTRIB_BITS (0x0F<<0) /* Number of attribute bits per pixel */
#define TGAIDF_XORIGIN (1<<4)
#define TGAIDF_YORIGIN (1<<5)
/* Access modes. */
#define TGA_READMODE 0
#define TGA_WRITEMODE 1
#define TGA_RDWRMODE 2
/* Error codes */
#define TGAERR_OPEN -1
#define TGAERR_READ -2
#define TGAERR_WRITE -3
#define TGAERR_SYNTAX -4
#define TGAERR_NOMEM -5
#define TGAERR_NOTSUPPORTED -6
/* Flags definitions */
#define TGAF_IMAGE (1<<0)
#define TGAF_PAL (1<<1)
#define TGAF_COMPRESS (1<<2)
#define TGAF_TGA2 (1<<3)
/* Macro definitions */
#define TGA_BytesPerPixel(a) ((a+7) >> 3)
/*---------------------------------------------------------------------------
* TARGA 2.0 DEFINITIONS
*-------------------------------------------------------------------------*/
#define TGA2_SIGNATURE "TRUEVISION-XFILE"
/* TGA2Footer - Targa 2.0 footer
*
* Extension - Offset to the Extension area from start of file.
* Developer - Offset to the Developer area from start of file.
* Signature - 16 byte Targa 2.0 signature "TRUEVISION-XFILE"
* RsvdChar - Reserved character, must be ASCII "." (period)
* BZST - Binary Zero String Terminator.
*/
typedef struct _TGA2Footer
{
long Extension;
long Developer;
char Signature[16];
char RsvdChar;
char BZST;
_TGA2Footer() {}
} TGA2Footer;
/* TGA2DateStamp - A series of 3 WORD values which define the integer value
* for the date the image was saved.
*
* Month - Month number (1 - 12)
* Day - Day number (1 - 31)
* Year - Year number (4 digit, ie. 1989)
*/
typedef struct _TGA2DateStamp
{
short Month;
short Day;
short Year;
} TGA2DateStamp;
/* TGA2TimeStamp - A series of 3 WORD values which define the integer value
* for the time the image was saved.
*
* Hour - Hour number, military time (0 - 23)
* Minute - Minute number (0 - 59)
* Second - Second number (0 - 59)
*/
typedef struct _TGA2TimeStamp
{
short Hour;
short Minute;
short Second;
} TGA2TimeStamp;
/* TGA2SoftVer - Define the version of the software used to generate file.
*
* Number - Version number * 100
* Letter - Version letter
*/
typedef struct _TGA2SoftVer
{
short Number;
char Letter;
} TGA2SoftVer;
/* TGA2Ratio - Numerator and denominator which when taken together specify
* a ratio.
*
* Numer - Numerator
* Denom - Denominator (a value of zero indicates no ratio specified)
*/
typedef struct _TGA2Ratio
{
short Numer;
short Denom;
} TGA2Ratio;
/* TGA2Extension - Extension area, provided for additional file information.
* This data is pointed to by the Extension offset in the
* TGA2Footer.
*
* ExtSize - Extension area size. (495 bytes for 2.0)
* AuthName - Name of the person who created image (NULL terminated ASCII)
* AuthComment - Comments of the author (NULL terminated ASCII)
* DateStamp - Date the file was created. (See TGA2DateStamp)
* TimeStamp - Time the file was created. (See TGA2TimeStamp)
* JobName - Name of job image belongs to (NULL terminated ASCII)
* JobTime - Elapsed time of the job.
* SoftID - ID of software used to create image (NULL terminated ASCII)
* SoftVer - Version number of software used.
* KeyColor - Tranparent color value.
* Aspect - Pixel aspect ratio.
* Gamma - Fractional gamma value.
* ColorCor - Color correction table offset.
* PostStamp - Postage stamp image offset.
* ScanLine - Scan line table offset.
* Attributes - Alpha channel attributes. (Set defines below)
*/
typedef struct _TGA2Extension
{
short ExtSize;
char AuthName[41];
char AuthComment[324];
TGA2DateStamp Date;
TGA2TimeStamp Time;
char JobName[41];
TGA2TimeStamp JobTime;
char SoftID[41];
TGA2SoftVer SoftVer;
long KeyColor;
TGA2Ratio Aspect;
TGA2Ratio Gamma;
long ColorCor;
long PostStamp;
long ScanLine;
char Attributes;
} TGA2Extension;
/* Alpha channel attributes (Extension Area) */
#define EXTA_NOALPHA 0 /* No alpha data included */
#define EXTA_IGNORE 1 /* Undefined alpha data, can ignore */
#define EXTA_RETAIN 2 /* Undefined alpha data, should retain */
#define EXTA_USEFUL 3 /* Useful alpha channel */
#define EXTA_PREMULT 4 /* Pre-Multiplied alpha data */
#pragma pack(pop)
/*
** This define changes this code from code that works with standard IO calls,
** to code that uses FileClass and FileFactoryClass.
*/
//#define TGA_USES_WWLIB_FILE_CLASSES
#ifdef TGA_USES_WWLIB_FILE_CLASSES
class FileClass;
#endif
/*---------------------------------------------------------------------------
* CLASS DEFINITION
*-------------------------------------------------------------------------*/
class Targa
{
public:
/* Constructor/destructor */
Targa(void);
~Targa();
/* Function prototypes. */
long Open(const char* name, long mode);
void Close(void);
long Load(const char* name, char* palette, char* image,bool invert_image=true);
long Load(const char* name, long flags, bool invert_image=true);
long Save(const char* name, long flags, bool addextension = false);
void XFlip(void);
void YFlip(void);
char* SetImage(char* buffer);
char* GetImage(void) const {return (mImage);}
char* SetPalette(char* buffer);
char* GetPalette(void) const {return (mPalette);}
bool IsCompressed(void);
TGA2Extension* GetExtension(void);
TGAHeader Header;
protected:
#ifdef TGA_USES_WWLIB_FILE_CLASSES
FileClass *TGAFile;
#else
long mFH;
#endif
long mAccess;
long mFlags;
char* mImage;
char* mPalette;
TGA2Extension mExtension;
private:
// Utility functions
long DecodeImage(void);
long EncodeImage(void);
void InvertImage(void);
// These functions are for ease of ifdef'ing between standard io calls
// and FileClass.
void Clear_File(void);
bool Is_File_Open(void);
bool File_Open_Read(const char* name);
bool File_Open_Write(const char* name);
bool File_Open_ReadWrite(const char* name);
int File_Seek(int pos, int dir);
int File_Read(void *buffer, int size);
int File_Write(void *buffer, int size);
};
#endif /* _TARGA_H_ */

View file

@ -0,0 +1,141 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : G *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/Utility.cpp $*
* *
* $Author:: Andre_a $*
* *
* $Modtime:: 5/08/00 11:51a $*
* *
* $Revision:: 3 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* wwGetAbsolutePath -- Returns the absolute path based on a relative one. *
* wwInputBox -- Retrive a string from the user in a nice friendly manner. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*
** Utility.cpp - Implementation of a some convenient features the WIN32 API provides
** that the MAXScript API doesn't.
*/
#include <MaxScrpt.h>
#include <Arrays.h>
#include <Strings.h>
#include <definsfn.h>
#include "util.h"
#include "InputDlg.h"
/*
** Let MAXScript know we're implementing new built-in functions.
*/
def_visible_primitive(get_absolute_path, "wwGetAbsolutePath");
def_visible_primitive(input_box, "wwInputBox");
/***********************************************************************************************
* get_absolute_path_cf -- Returns the absolute path based on a relative one. *
* *
* wwGetAbsolutePath - Usage: wwGetAbsolutePath <relative_path> <context> *
* *
* INPUT: A string containing a relative path, and its context. *
* *
* OUTPUT: The equivalent absolute path. *
* *
* WARNINGS: *
* *
* HISTORY: *
* 10/4/1999 AJA : Created. *
*=============================================================================================*/
Value * get_absolute_path_cf (Value **arg_list, int count)
{
// We want an array as an argument
check_arg_count("wwGetAbsolutePath", 2, count);
type_check(arg_list[0], String, "Relative path");
type_check(arg_list[1], String, "Context");
// Grab the arguments out of the array.
char absolute[MAX_PATH];
char *relative = arg_list[0]->to_string();
char *context = arg_list[1]->to_string();
// Turn the relative path into an absolute one.
Create_Full_Path(absolute, context, relative);
// Return the absolute path.
one_typed_value_local(String *abs);
vl.abs = new String(absolute);
return_value(vl.abs);
}
/***********************************************************************************************
* input_box_cf -- Retrive a string from the user in a nice friendly manner. *
* *
* wwInputBox - Usage: wwInputBox [caption:'caption'] [label:'label'] [value:'value'] *
* *
* INPUT: Three optional named arguments. If they are not given values, defaults are used. *
* *
* OUTPUT: Returns the string entered by the user. *
* *
* WARNINGS: *
* *
* HISTORY: *
*=============================================================================================*/
Value * input_box_cf (Value **arg_list, int count)
{
// Create the input box (but don't show it yet).
InputDlg input_box(MAXScript_interface->GetMAXHWnd());
Value *param = NULL;
// Check the 'caption' parameter.
param = key_arg(caption);
if (param && param != &unsupplied)
input_box.SetCaption(param->to_string());
// Check the 'label' parameter.
param = key_arg(label);
if (param && param != &unsupplied)
input_box.SetLabel(param->to_string());
// Check the 'value' parameter.
param = key_arg(value);
if (param && param != &unsupplied)
input_box.SetValue(param->to_string());
// Show the dialog and let the user enter a value.
if (input_box.DoModal() == IDCANCEL)
return &undefined;
// Return the value the user entered.
one_typed_value_local(String *val);
vl.val = new String(input_box.m_Value);
return_value(vl.val);
}

View file

@ -0,0 +1,930 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WW3D *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/aabtreebuilder.cpp $*
* *
* Original Author:: Greg Hjelstrom *
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 5/24/00 8:41a $*
* *
* $Revision:: 4 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* AABTreeBuilderClass::AABTreeBuilderClass -- Constructor *
* AABTreeBuilderClass::~AABTreeBuilderClass -- Destructor *
* AABTreeBuilderClass::Reset -- reset the builder, delete all arrays *
* AABTreeBuilderClass::Build_AABTree -- Build an AABTree for the given mesh. *
* AABTreeBuilderClass::Build_Tree -- recursivly builds the culling tree *
* AABTreeBuilderClass::Select_Splitting_Plane -- select a partition for the given polys *
* AABTreeBuilderClass::Compute_Plane_Score -- evaluate the suitability of a partition plane *
* AABTreeBuilderClass::Which_Side -- which side of a plane is the given poly *
* AABTreeBuilderClass::Split_Polys -- partition the polys with a plane *
* AABTreeBuilderClass::Compute_Bounding_Box -- compute bounding boxes for the cull nodes *
* AABTreeBuilderClass::Assign_Index -- assign an array index to each node *
* AABTreeBuilderClass::Node_Count -- Count the nodes in the tree *
* AABTreeBuilderClass::Poly_Count -- returns number of polys *
* AABTreeBuilderClass::Node_Count_Recursive -- internal implementation of Node_Count *
* AABTreeBuilderClass::Submit_Tree -- install nodes into an AABTreeClass *
* AABTreeBuilderClass::Submit_Tree_Recursive -- internal implementation of Submit_Tree *
* AABTreeBuilderClass::Update_Min -- ensure given vector is < min of the poly *
* AABTreeBuilderClass::Update_Max -- ensure given vector is > max of poly *
* AABTreeBuilderClass::Update_Min_Max -- ensure given vector is in min max of poly *
* AABTreeBuilderClass::Export -- Saves this AABTree into a W3D chunk *
* AABTreeBuilderClass::Build_W3D_AABTree_Recursive -- Build array of indices and W3dMeshAAB *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "aabtreebuilder.h"
#include "chunkio.h"
#include "w3d_file.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#define WWASSERT assert // can't use WWASSERT because we use this module in the MAX plugin...
const float COINCIDENCE_EPSILON = 0.001f;
/***********************************************************************************************
* AABTreeBuilderClass::AABTreeBuilderClass -- Constructor *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
*=============================================================================================*/
AABTreeBuilderClass::AABTreeBuilderClass(void) :
Root(NULL),
CurPolyIndex(0),
PolyCount(0),
Polys(NULL),
VertCount(0),
Verts(NULL)
{
}
/***********************************************************************************************
* AABTreeBuilderClass::~AABTreeBuilderClass -- Destructor *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 5/19/2000 gth : Created. *
*=============================================================================================*/
AABTreeBuilderClass::~AABTreeBuilderClass(void)
{
Reset();
}
/***********************************************************************************************
* AABTreeBuilderClass::Reset -- reset the builder, delete all arrays *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 5/19/2000 gth : Created. *
*=============================================================================================*/
void AABTreeBuilderClass::Reset(void)
{
if (Root) {
delete Root; Root = NULL;
}
if (Verts != NULL) {
delete[] Verts;
Verts = NULL;
}
if (Polys != NULL) {
delete[] Polys;
Polys = NULL;
}
}
/***********************************************************************************************
* AABTreeBuilderClass::Build_AABTree -- Build an AABTree for the given mesh. *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 6/19/98 GTH : Created. *
*=============================================================================================*/
void AABTreeBuilderClass::Build_AABTree(int polycount,Vector3i * polys,int vertcount,Vector3 * verts)
{
WWASSERT(polycount > 0);
WWASSERT(vertcount > 0);
WWASSERT(polys != NULL);
WWASSERT(verts != NULL);
/*
** If we already have allocated data, release it
*/
Reset();
/*
** Copy the mesh data
*/
VertCount = vertcount;
PolyCount = polycount;
Verts = new Vector3[VertCount];
Polys = new Vector3i[PolyCount];
for (int vi=0; vi<VertCount; vi++) {
Verts[vi] = verts[vi];
}
for (int pi=0; pi<PolyCount; pi++) {
Polys[pi] = polys[pi];
}
/*
** First, create a list of all of the poly indices
*/
int * polyindices = new int[PolyCount];
for (int i=0; i<PolyCount; i++) {
polyindices[i] = i;
}
/*
** Build the tree, note that the array of poly indices will be
** deleted by the Build_Tree function.
*/
Root = new CullNodeStruct;
Build_Tree(Root,PolyCount,polyindices);
polyindices = NULL;
/*
** fill in the remaining information needed in the tree:
** for example: bounding boxes, index assignments
*/
Compute_Bounding_Box(Root);
Assign_Index(Root,0);
}
/***********************************************************************************************
* AABTreeBuilderClass::Build_Tree -- recursivly builds the culling tree *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 6/19/98 GTH : Created. *
*=============================================================================================*/
void AABTreeBuilderClass::Build_Tree(CullNodeStruct * node,int polycount,int * polyindices)
{
/*
** First, if there are only a few polys left, just terminate the tree
*/
if (polycount <= MIN_POLYS_PER_NODE) {
node->PolyCount = polycount;
node->PolyIndices = polyindices;
return;
}
/*
** Try to find a suitable partitioning plane.
*/
SplitChoiceStruct sc;
sc = Select_Splitting_Plane(polycount,polyindices);
/*
** If the algorithm could not separate any polys, just install the polys
** in this node and terminate. TODO: explore how this happens.
*/
if (sc.FrontCount + sc.BackCount != polycount) {
node->PolyCount = polycount;
node->PolyIndices = polyindices;
return;
}
/*
** Decide whether to actually partition this node. If the partitioning
** will not gain us anything, just install the polys in this node and terminate
** the tree.
*/
#if 0
if (sc.Cost == MAX_COST) {
node->PolyCount = polycount;
node->PolyIndices = polyindices;
return;
}
#endif
/*
** Ok, split the polys
*/
SplitArraysStruct arrays;
Split_Polys(polycount,polyindices,sc,&arrays);
/*
** Free the memory in use by the input tile-list
*/
delete[] polyindices;
/*
** Build a front tree if necessary. Remember that the Build function
** deletes the poly array.
*/
if (arrays.FrontCount) {
WWASSERT(arrays.FrontPolys != NULL);
node->Front = new CullNodeStruct;
Build_Tree(node->Front,arrays.FrontCount,arrays.FrontPolys);
arrays.FrontPolys = NULL;
}
/*
** Build a back tree if necessary. Remember that the build function
** deletes the tile array.
*/
if (arrays.BackCount) {
WWASSERT(arrays.BackPolys != NULL);
node->Back = new CullNodeStruct;
Build_Tree(node->Back,arrays.BackCount,arrays.BackPolys);
arrays.BackPolys = NULL;
}
}
/***********************************************************************************************
* AABTreeBuilderClass::Select_Splitting_Plane -- select a partition for the given polys *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 6/19/98 GTH : Created. *
*=============================================================================================*/
AABTreeBuilderClass::SplitChoiceStruct
AABTreeBuilderClass::Select_Splitting_Plane(int polycount,int * polyindices)
{
WWASSERT(polyindices != NULL);
const int NUM_TRYS = 50;
SplitChoiceStruct best_plane_stats;
SplitChoiceStruct considered_plane_stats;
/*
** Try putting axis-aligned planes through some random vertices
*/
for (int trys = 0; trys < MIN(NUM_TRYS,polycount); trys++) {
AAPlaneClass plane;
/*
** Select a random poly and vertex index;
*/
int poly_index = polyindices[rand() % polycount];
int vert_index = rand() % 3;
const Vector3i * polyverts = Polys + poly_index;
const Vector3 * vert = Verts + (*polyverts)[vert_index];
/*
** Select a random plane
*/
switch(rand() % 3) {
case 0: plane.Set(AAPlaneClass::XNORMAL,vert->X); break;
case 1: plane.Set(AAPlaneClass::YNORMAL,vert->Y); break;
case 2: plane.Set(AAPlaneClass::ZNORMAL,vert->Z); break;
};
/*
** Get the score for this plane
*/
considered_plane_stats = Compute_Plane_Score(polycount,polyindices,plane);
if (considered_plane_stats.Cost < best_plane_stats.Cost) {
best_plane_stats = considered_plane_stats;
}
}
return best_plane_stats;
}
/***********************************************************************************************
* AABTreeBuilderClass::Compute_Plane_Score -- evaluate the suitability of a partition plane *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 6/19/98 GTH : Created. *
*=============================================================================================*/
AABTreeBuilderClass::SplitChoiceStruct
AABTreeBuilderClass::Compute_Plane_Score(int polycount,int * polyindices,const AAPlaneClass & plane)
{
/*
** The score of a splitting plane is based on the following factors:
** - the volumes of the resulting two children volumes,
** - the number of polys in each child volume
*/
SplitChoiceStruct sc;
sc.Plane = plane;
for (int i=0; i<polycount; i++) {
switch(Which_Side(plane,polyindices[i])) {
case FRONT:
case ON:
case BOTH:
{
sc.FrontCount++;
Update_Min_Max(polyindices[i],sc.FMin,sc.FMax );
break;
}
case BACK:
{
sc.BackCount++;
Update_Min_Max(polyindices[i],sc.BMin,sc.BMax );
break;
}
}
}
/*
** Inflate the box a tiny amount so that we never
** get volumes of zero!
*/
sc.BMin -= Vector3(WWMATH_EPSILON,WWMATH_EPSILON,WWMATH_EPSILON);
sc.BMax += Vector3(WWMATH_EPSILON,WWMATH_EPSILON,WWMATH_EPSILON);
/*
** Compute the cost.
*/
float back_cost = (sc.BMax.X - sc.BMin.X) * (sc.BMax.Y - sc.BMin.Y) * (sc.BMax.Z - sc.BMin.Z) * sc.BackCount;
float front_cost = (sc.FMax.X - sc.FMin.X) * (sc.FMax.Y - sc.FMin.Y) * (sc.FMax.Z - sc.FMin.Z) * sc.FrontCount;
sc.Cost = front_cost + back_cost;
if ((sc.FrontCount == 0) || (sc.BackCount == 0)) {
sc.Cost = FLT_MAX;
}
return sc;
}
/***********************************************************************************************
* AABTreeBuilderClass::Which_Side -- which side of a plane is the given poly *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 6/19/98 GTH : Created. *
*=============================================================================================*/
AABTreeBuilderClass::OverlapType
AABTreeBuilderClass::Which_Side(const AAPlaneClass & plane,int poly_index)
{
/*
** Check each vertex to see if it is in front, behind or on the plane
*/
int mask = 0;
for (int vi=0; vi<3; vi++) {
const Vector3 & point = Verts[ Polys[poly_index][vi] ];
float delta = point[plane.Normal] - plane.Dist;
if (delta > COINCIDENCE_EPSILON) {
mask |= POS;
}
if (delta < -COINCIDENCE_EPSILON) {
mask |= NEG;
}
mask |= ON;
}
/*
** Now evaluate the status of all of the verts to determine whether the
** triangle is in front, behind, on or overlapping the plane
*/
/*
** If all verts were ON the plane, the triangle is ON the plane
*/
if (mask == ON) {
return ON;
}
/*
** If all verts were POS or ON, the triangle is POS (IN_FRONT)
*/
if ((mask & ~(POS | ON)) == 0) {
return POS;
}
/*
** If all verts were NEG or ON, the triangle is NEG (BEHIND)
*/
if ((mask & ~(NEG | ON)) == 0) {
return NEG;
}
/*
** Otherwise, the triangle spans the plane
*/
return BOTH;
}
/***********************************************************************************************
* AABTreeBuilderClass::Split_Polys -- partition the polys with a plane *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 6/19/98 GTH : Created. *
*=============================================================================================*/
void AABTreeBuilderClass::Split_Polys
(
int polycount,
int * polyindices,
const SplitChoiceStruct & sc,
SplitArraysStruct * arrays
)
{
/*
** Note that this routine arrays of polygons. The caller is then responsible for keeping
** track of the memory this routine allocates.
*/
if (sc.FrontCount > 0) {
arrays->FrontPolys = new int[sc.FrontCount];
}
if (sc.BackCount > 0) {
arrays->BackPolys = new int[sc.BackCount];
}
arrays->FrontCount = 0;
arrays->BackCount = 0;
for (int i=0; i<polycount; i++) {
switch(Which_Side(sc.Plane,polyindices[i])) {
case FRONT:
case ON:
case BOTH:
arrays->FrontPolys[arrays->FrontCount++] = polyindices[i];
break;
case BACK:
arrays->BackPolys[arrays->BackCount++] = polyindices[i];
break;
}
}
/*
** when we are all done, the counts should match.
*/
WWASSERT(arrays->FrontCount == sc.FrontCount);
WWASSERT(arrays->BackCount == sc.BackCount);
}
/***********************************************************************************************
* AABTreeBuilderClass::Compute_Bounding_Box -- compute bounding boxes for the cull nodes *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 6/19/98 GTH : Created. *
*=============================================================================================*/
void AABTreeBuilderClass::Compute_Bounding_Box(CullNodeStruct * node)
{
/*
** compute bounding volumes of the children
*/
if (node->Front) {
Compute_Bounding_Box(node->Front);
}
if (node->Back) {
Compute_Bounding_Box(node->Back);
}
/*
** compute bounding volume for the polys in this node
*/
node->Min.Set(100000.0f,100000.0f,100000.0f);
node->Max.Set(-100000.0f,-100000.0f,-100000.0f);
for (int poly_index = 0; poly_index < node->PolyCount; poly_index++) {
Update_Min_Max(node->PolyIndices[poly_index],node->Min,node->Max );
}
/*
** bound the polys in the front child node
*/
if (node->Front) {
if (node->Front->Min.X < node->Min.X) node->Min.X = node->Front->Min.X;
if (node->Front->Max.X > node->Max.X) node->Max.X = node->Front->Max.X;
if (node->Front->Min.Y < node->Min.Y) node->Min.Y = node->Front->Min.Y;
if (node->Front->Max.Y > node->Max.Y) node->Max.Y = node->Front->Max.Y;
if (node->Front->Min.Z < node->Min.Z) node->Min.Z = node->Front->Min.Z;
if (node->Front->Max.Z > node->Max.Z) node->Max.Z = node->Front->Max.Z;
}
/*
** bound the polys in the back child node
*/
if (node->Back) {
if (node->Back->Min.X < node->Min.X) node->Min.X = node->Back->Min.X;
if (node->Back->Max.X > node->Max.X) node->Max.X = node->Back->Max.X;
if (node->Back->Min.Y < node->Min.Y) node->Min.Y = node->Back->Min.Y;
if (node->Back->Max.Y > node->Max.Y) node->Max.Y = node->Back->Max.Y;
if (node->Back->Min.Z < node->Min.Z) node->Min.Z = node->Back->Min.Z;
if (node->Back->Max.Z > node->Max.Z) node->Max.Z = node->Back->Max.Z;
}
WWASSERT(node->Min.X != 100000.0f);
WWASSERT(node->Min.Y != 100000.0f);
WWASSERT(node->Min.Z != 100000.0f);
WWASSERT(node->Max.X != -100000.0f);
WWASSERT(node->Max.Y != -100000.0f);
WWASSERT(node->Max.Z != -100000.0f);
}
/***********************************************************************************************
* AABTreeBuilderClass::Assign_Index -- assign an array index to each node *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 6/19/98 GTH : Created. *
*=============================================================================================*/
int AABTreeBuilderClass::Assign_Index(CullNodeStruct * node,int index)
{
/*
** This function is used to assign a sequential index to
** each node in the tree. The AABTree stores its nodes in
** an array so this index is used to determine which slot
** in the array to put each node into.
*/
WWASSERT(node);
node->Index = index;
index++;
if (node->Front) {
index = Assign_Index(node->Front,index);
}
if (node->Back) {
index = Assign_Index(node->Back,index);
}
return index;
}
/***********************************************************************************************
* AABTreeBuilderClass::Node_Count -- Count the nodes in the tree *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 6/19/98 GTH : Created. *
*=============================================================================================*/
int AABTreeBuilderClass::Node_Count(void)
{
if (Root) {
return Node_Count_Recursive(Root,0);
} else {
return 0;
}
}
/***********************************************************************************************
* AABTreeBuilderClass::Poly_Count -- returns number of polys *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 10/23/98 GTH : Created. *
*=============================================================================================*/
int AABTreeBuilderClass::Poly_Count(void)
{
return PolyCount;
}
/***********************************************************************************************
* AABTreeBuilderClass::Node_Count_Recursive -- internal implementation of Node_Count *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 6/19/98 GTH : Created. *
*=============================================================================================*/
int AABTreeBuilderClass::Node_Count_Recursive(CullNodeStruct * node,int curcount)
{
curcount++;
if (node->Front) {
curcount = Node_Count_Recursive(node->Front,curcount);
}
if (node->Back) {
curcount = Node_Count_Recursive(node->Back,curcount);
}
return curcount;
}
/***********************************************************************************************
* AABTreeBuilderClass::Update_Min -- ensure given vector is < min of the poly *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 6/22/98 GTH : Created. *
*=============================================================================================*/
void AABTreeBuilderClass::Update_Min(int poly_index,Vector3 & min)
{
for (int vert_index = 0; vert_index < 3; vert_index++) {
const Vector3i * polyverts = Polys + poly_index;
const Vector3 * point = Verts + (*polyverts)[vert_index];
if (point->X < min.X) min.X = point->X;
if (point->Y < min.Y) min.Y = point->Y;
if (point->Z < min.Z) min.Z = point->Z;
}
}
/***********************************************************************************************
* AABTreeBuilderClass::Update_Max -- ensure given vector is > max of poly *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 6/22/98 GTH : Created. *
*=============================================================================================*/
void AABTreeBuilderClass::Update_Max(int poly_index,Vector3 & max)
{
for (int vert_index = 0; vert_index < 3; vert_index++) {
const Vector3i * polyverts = Polys + poly_index;
const Vector3 * point = Verts + (*polyverts)[vert_index];
if (point->X > max.X) max.X = point->X;
if (point->Y > max.Y) max.Y = point->Y;
if (point->Z > max.Z) max.Z = point->Z;
}
}
/***********************************************************************************************
* AABTreeBuilderClass::Update_Min_Max -- ensure given vector is in min max of poly *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 9/24/98 BMG : Created. *
*=============================================================================================*/
void AABTreeBuilderClass::Update_Min_Max(int poly_index, Vector3 & min, Vector3 & max)
{
for (int vert_index = 0; vert_index < 3; vert_index++) {
const Vector3i * polyverts = Polys + poly_index;
const Vector3 * point = Verts + (*polyverts)[vert_index];
if (point->X < min.X) min.X = point->X;
if (point->Y < min.Y) min.Y = point->Y;
if (point->Z < min.Z) min.Z = point->Z;
if (point->X > max.X) max.X = point->X;
if (point->Y > max.Y) max.Y = point->Y;
if (point->Z > max.Z) max.Z = point->Z;
}
}
/***********************************************************************************************
* AABTreeBuilderClass::Export -- Saves this AABTree into a W3D chunk *
* *
* This function will export the AABTree into a W3D chunk so that it can be loaded by its *
* sister class "AABTreeClass" in the WW3D library. *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 5/22/2000 gth : Created. *
*=============================================================================================*/
void AABTreeBuilderClass::Export(ChunkSaveClass & csave)
{
csave.Begin_Chunk(W3D_CHUNK_AABTREE);
/*
** Pack the tree into an array of W3dMeshAABTreeNode's and polygon indices
*/
W3dMeshAABTreeNode * nodes = new W3dMeshAABTreeNode[Node_Count()];
uint32 * poly_indices = new uint32[Poly_Count()];
int cur_node = 0;
int cur_poly = 0;
Build_W3D_AABTree_Recursive(Root,nodes,poly_indices,cur_node,cur_poly);
/*
** Write out the header
*/
csave.Begin_Chunk(W3D_CHUNK_AABTREE_HEADER);
W3dMeshAABTreeHeader header;
memset(&header,0,sizeof(header));
header.NodeCount = Node_Count();
header.PolyCount = Poly_Count();
csave.Write(&header,sizeof(header));
csave.End_Chunk();
/*
** Write out the array of polygon indices
*/
csave.Begin_Chunk(W3D_CHUNK_AABTREE_POLYINDICES);
csave.Write(poly_indices,Poly_Count() * sizeof(uint32));
csave.End_Chunk();
/*
** Write out the array of nodes
*/
csave.Begin_Chunk(W3D_CHUNK_AABTREE_NODES);
for (int ni=0; ni<Node_Count(); ni++) {
csave.Write(&(nodes[ni]),sizeof(W3dMeshAABTreeNode));
}
csave.End_Chunk();
csave.End_Chunk(); // W3D_CHUNK_AABTREE done
}
/***********************************************************************************************
* AABTreeBuilderClass::Build_W3D_AABTree_Recursive -- Build array of indices and W3dMeshAABTr *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 5/22/2000 gth : Created. *
*=============================================================================================*/
void AABTreeBuilderClass::Build_W3D_AABTree_Recursive
(
AABTreeBuilderClass::CullNodeStruct * node,
W3dMeshAABTreeNode * w3d_nodes,
uint32 * poly_indices,
int & cur_node,
int & cur_poly
)
{
/*
** Copy data from the builder's node into our node
*/
W3dMeshAABTreeNode * newnode = &(w3d_nodes[node->Index]);
newnode->Min.X = node->Min.X;
newnode->Min.Y = node->Min.Y;
newnode->Min.Z = node->Min.Z;
newnode->Max.X = node->Max.X;
newnode->Max.Y = node->Max.Y;
newnode->Max.Z = node->Max.Z;
/*
** If this is a non-leaf node, set up the child indices, otherwise set up the polygon indices
*/
if (node->Front != NULL) {
WWASSERT(node->Back != NULL); // if we have one child, we better have both!
newnode->FrontOrPoly0 = node->Front->Index;
newnode->BackOrPolyCount = node->Back->Index;
} else {
newnode->FrontOrPoly0 = cur_poly | 0x80000000;
newnode->BackOrPolyCount = node->PolyCount;
}
/*
** Copy the polygon indices for this node into our array
*/
for (int pcounter = 0; pcounter < node->PolyCount; pcounter++) {
poly_indices[cur_poly++] = node->PolyIndices[pcounter];
}
/*
** Install the children
*/
if (node->Front) {
Build_W3D_AABTree_Recursive(node->Front,w3d_nodes,poly_indices,cur_node,cur_poly);
}
if (node->Back) {
Build_W3D_AABTree_Recursive(node->Back,w3d_nodes,poly_indices,cur_node,cur_poly);
}
}

View file

@ -0,0 +1,209 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WW3D *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/aabtreebuilder.h $*
* *
* Original Author:: Greg Hjelstrom *
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 5/22/00 2:02p $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef AABTREEBUILDER_H
#define AABTREEBUILDER_H
#include "always.h"
#include "vector3.h"
#include "vector3i.h"
#include "aaplane.h"
#include "bittype.h"
#include <float.h>
class AABTreeClass;
class ChunkSaveClass;
struct W3dMeshAABTreeNode;
/*
** AABTreeBuilderClass
** This class serves simply to build AABTreeClasses. It first builds a tree
** which uses an easier to manage data structure (but uses more memory). Then
** the tree is converted into the representation used in the AABTreeClass.
*/
class AABTreeBuilderClass
{
public:
AABTreeBuilderClass(void);
~AABTreeBuilderClass(void);
void Build_AABTree(int polycount,Vector3i * polys,int vertcount,Vector3 * verts);
void Export(ChunkSaveClass & csave);
int Node_Count(void);
int Poly_Count(void);
enum
{
MIN_POLYS_PER_NODE = 4,
SMALL_VERTEX = -100000,
BIG_VERTEX = 100000
};
private:
/*
** This CullNodeStruct is used in building the AABTree. It is much more
** wasteful in terms of memory footprint and number of allocations than the
** streamlined version found in the actual AABTreeClass.
*/
struct CullNodeStruct
{
CullNodeStruct(void) : Index(0),Min(0,0,0),Max(0,0,0),Front(NULL),Back(NULL),PolyCount(0),PolyIndices(NULL) {}
~CullNodeStruct(void)
{
if (Front) { delete Front; }
if (Back) { delete Back; }
if (PolyIndices) { delete[] PolyIndices; }
}
int Index;
Vector3 Min;
Vector3 Max;
CullNodeStruct * Front;
CullNodeStruct * Back;
int PolyCount;
int * PolyIndices;
};
/*
** SplitChoiceStruct - encapsulates the results of evaluating the suitability of a partition
*/
struct SplitChoiceStruct
{
SplitChoiceStruct(void) :
Cost(FLT_MAX),
FrontCount(0),
BackCount(0),
BMin(BIG_VERTEX,BIG_VERTEX,BIG_VERTEX),
BMax(SMALL_VERTEX,SMALL_VERTEX,SMALL_VERTEX),
FMin(BIG_VERTEX,BIG_VERTEX,BIG_VERTEX),
FMax(SMALL_VERTEX,SMALL_VERTEX,SMALL_VERTEX),
Plane(AAPlaneClass::XNORMAL,0)
{
}
float Cost; // try to minimize this!
int FrontCount; // number of polys in front of the plane
int BackCount; // number of polys behind the plane
Vector3 BMin; // min of the bounding box of the "back" child
Vector3 BMax; // max of the bounding box of the "back" child
Vector3 FMin; // min of the bounding box of the "front" child
Vector3 FMax; // max of the bounding box of the "front" child
AAPlaneClass Plane; // partitioning plane
};
struct SplitArraysStruct
{
SplitArraysStruct(void) :
FrontCount(0),
BackCount(0),
FrontPolys(NULL),
BackPolys(NULL)
{
}
int FrontCount;
int BackCount;
int * FrontPolys;
int * BackPolys;
};
enum OverlapType
{
POS = 0x01,
NEG = 0x02,
ON = 0x04,
BOTH = 0x08,
OUTSIDE = POS,
INSIDE = NEG,
OVERLAPPED = BOTH,
FRONT = POS,
BACK = NEG,
};
/*
** Internal functions
*/
void Reset();
void Build_Tree(CullNodeStruct * node,int polycount,int * polyindices);
SplitChoiceStruct Select_Splitting_Plane(int polycount,int * polyindices);
SplitChoiceStruct Compute_Plane_Score(int polycont,int * polyindices,const AAPlaneClass & plane);
void Split_Polys(int polycount,int * polyindices,const SplitChoiceStruct & sc,SplitArraysStruct * arrays);
OverlapType Which_Side(const AAPlaneClass & plane,int poly_index);
void Compute_Bounding_Box(CullNodeStruct * node);
int Assign_Index(CullNodeStruct * node,int index);
int Node_Count_Recursive(CullNodeStruct * node,int curcount);
void Update_Min(int poly_index,Vector3 & set_min);
void Update_Max(int poly_index,Vector3 & set_max);
void Update_Min_Max(int poly_index, Vector3 & set_min, Vector3 & set_max);
void Build_W3D_AABTree_Recursive(CullNodeStruct * node,
W3dMeshAABTreeNode * w3dnodes,
uint32 * poly_indices,
int & cur_node,
int & cur_poly);
/*
** Tree
*/
CullNodeStruct * Root;
int CurPolyIndex;
/*
** Mesh data
*/
int PolyCount;
Vector3i * Polys;
int VertCount;
Vector3 * Verts;
friend class AABTreeClass;
};
#endif //AABTREEBUILDER_H

View file

@ -0,0 +1,291 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Max2W3d *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/animationcompressionsettings.cpp $*
* *
* Original Author:: Patrick Smith *
* *
* $Author:: Patrick $*
* *
* $Modtime:: 10/30/00 1:57p $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "animationcompressionsettings.h"
#include "dllmain.h"
#include "resource.h"
#include "w3dexp.h"
////////////////////////////////////////////////////////////////////////////////////////
//
// AnimationCompressionSettingsDialogClass
//
////////////////////////////////////////////////////////////////////////////////////////
AnimationCompressionSettingsDialogClass::AnimationCompressionSettingsDialogClass (Interface *maxinterface, HWND parent_wnd) :
MaxInterface (maxinterface),
Options (NULL),
Wnd (NULL),
ParentWnd (parent_wnd)
{
return ;
}
////////////////////////////////////////////////////////////////////////////////////////
//
// ~AnimationCompressionSettingsDialogClass
//
////////////////////////////////////////////////////////////////////////////////////////
AnimationCompressionSettingsDialogClass::~AnimationCompressionSettingsDialogClass (void)
{
return ;
}
////////////////////////////////////////////////////////////////////////////////////////
//
// Do_Modal
//
////////////////////////////////////////////////////////////////////////////////////////
int
AnimationCompressionSettingsDialogClass::Do_Modal (void)
{
int retval = ::DialogBoxParam (AppInstance, MAKEINTRESOURCE (IDD_ANIMATION_COMPRESSION),
ParentWnd, Real_Message_Proc, (LPARAM)this);
return retval;
}
////////////////////////////////////////////////////////////////////////////////////////
//
// Real_Message_Proc
//
////////////////////////////////////////////////////////////////////////////////////////
BOOL CALLBACK
AnimationCompressionSettingsDialogClass::Real_Message_Proc
(
HWND wnd,
UINT message,
WPARAM wparam,
LPARAM lparam
)
{
AnimationCompressionSettingsDialogClass *dialog_obj = NULL;
//
// Setup the framework we need so that the instance
// can process the messages instead of this static callback.
//
if (message == WM_INITDIALOG) {
dialog_obj = (AnimationCompressionSettingsDialogClass *)lparam;
dialog_obj->Wnd = wnd;
::SetProp (wnd, "DIALOG_OBJ", (HANDLE)dialog_obj);
} else {
dialog_obj = (AnimationCompressionSettingsDialogClass *)::GetProp (wnd, "DIALOG_OBJ");
}
//
// Allow the instance to handle the call
//
BOOL retval = FALSE;
if (dialog_obj != NULL) {
retval = dialog_obj->Message_Proc (message, wparam, lparam);
}
//
// Cleanup the framework
//
if (message == WM_DESTROY) {
::RemoveProp (wnd, "DIALOG_OBJ");
}
return retval;
}
////////////////////////////////////////////////////////////////////////////////////////
//
// Message_Proc
//
////////////////////////////////////////////////////////////////////////////////////////
BOOL
AnimationCompressionSettingsDialogClass::Message_Proc
(
UINT message,
WPARAM wparam,
LPARAM lparam
)
{
BOOL retval = FALSE;
switch (message)
{
case WM_INITDIALOG:
{
//
// Center the dialog
//
RECT parent_rect = { 0 };
RECT rect = { 0 };
::GetWindowRect (ParentWnd, &parent_rect);
::GetWindowRect (Wnd, &rect);
int width = parent_rect.right - parent_rect.left;
int height = parent_rect.bottom - parent_rect.top;
::SetWindowPos ( Wnd, NULL,
parent_rect.left + (width / 2) - ((rect.right - rect.left) / 2),
parent_rect.top + (height / 2) - ((rect.bottom - rect.top) / 2),
0, 0, SWP_NOZORDER | SWP_NOSIZE);
//
// Initialize the dialog controls
//
Initialize_Controls ();
}
break;
case WM_COMMAND:
{
switch (LOWORD (wparam))
{
case IDCANCEL:
EndDialog (Wnd, IDCANCEL);
break;
case IDOK:
Save_Settings ();
EndDialog (Wnd, IDOK);
break;
}
}
break;
}
return retval;
}
////////////////////////////////////////////////////////////////////////////////////////
//
// Initialize_Controls
//
////////////////////////////////////////////////////////////////////////////////////////
void
AnimationCompressionSettingsDialogClass::Initialize_Controls (void)
{
SetCheckBox (Wnd, IDC_REDUCE_ANIMATION_CHECK, Options->ReduceAnimation);
char string[128] = { 0 };
//
// Populate the reduction percent combo box
//
HWND percent_combo = ::GetDlgItem (Wnd, IDC_REDUCE_ANIMATION_COMBO);
for (int index = 1; index < 100; index ++) {
sprintf (string, "%d", index);
ComboBox_AddString (percent_combo, string);
}
//
// Populate the animation type combo box
//
HWND flavor_combo = ::GetDlgItem (Wnd, IDC_COMPRESS_ANIMATION_FLAVOR_COMBO);
ComboBox_AddString (flavor_combo, "TimeCoded");
ComboBox_AddString (flavor_combo, "Adaptive Delta");
//
// Bounds check the parameters
//
if ((Options->ReduceAnimationPercent < 1) || (Options->ReduceAnimationPercent > 99)) {
Options->ReduceAnimationPercent = 50;
}
if ((Options->CompressAnimationFlavor < 0) || (Options->CompressAnimationFlavor >= ANIM_FLAVOR_VALID)) {
Options->CompressAnimationFlavor = 0;
}
//
// Select the correct entries in the combo boxes
//
ComboBox_SetCurSel (percent_combo, Options->ReduceAnimationPercent - 1);
ComboBox_SetCurSel (flavor_combo, Options->CompressAnimationFlavor);
//
// Fill in the error fields
//
::sprintf (string, "%f", Options->CompressAnimationTranslationError);
::SetDlgItemText (Wnd, IDC_MAX_TRANS_ERROR_EDIT, string);
::sprintf (string, "%f", Options->CompressAnimationRotationError);
::SetDlgItemText (Wnd, IDC_MAX_ROT_ERROR_EDIT, string);
return ;
}
////////////////////////////////////////////////////////////////////////////////////////
//
// Save_Settings
//
////////////////////////////////////////////////////////////////////////////////////////
void
AnimationCompressionSettingsDialogClass::Save_Settings (void)
{
//
// Read the compression type setting
//
int flavor = ComboBox_GetCurSel (::GetDlgItem (Wnd, IDC_COMPRESS_ANIMATION_FLAVOR_COMBO));
Options->CompressAnimationFlavor = flavor;
//
// Determine whether or not we want to force reduction
//
Options->ReduceAnimation = (IsDlgButtonChecked (Wnd, IDC_REDUCE_ANIMATION_CHECK) == 1);
//
// Read the reduction percent setting
//
int reduce_percent = ComboBox_GetCurSel (::GetDlgItem (Wnd, IDC_REDUCE_ANIMATION_COMBO)) + 1;
Options->ReduceAnimationPercent = reduce_percent;
//
// Read the amount of compression error we'll allow in the translational component
//
char string[128];
::GetDlgItemText (Wnd, IDC_MAX_TRANS_ERROR_EDIT, string, sizeof (string));
float trans_error = ::atof (string);
Options->CompressAnimationTranslationError = trans_error;
//
// Read the amount of compression error we'll allow in the rotational component
//
::GetDlgItemText (Wnd, IDC_MAX_ROT_ERROR_EDIT, string, sizeof (string));
float rot_error = ::atof (string);
Options->CompressAnimationRotationError = rot_error;
return ;
}

View file

@ -0,0 +1,96 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Max2W3d *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/animationcompressionsettings.h $*
* *
* Original Author:: Patrick Smith *
* *
* $Author:: Patrick $*
* *
* $Modtime:: 10/30/00 1:57p $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef __ANIMATION_COMPRESSION_SETTINGS_H
#define __ANIMATION_COMPRESSION_SETTINGS_H
#include <windows.h>
#include <max.h>
#include "w3dutil.h"
////////////////////////////////////////////////////////////////////////////////////////
//
// AnimationCompressionSettingsDialogClass
//
////////////////////////////////////////////////////////////////////////////////////////
class AnimationCompressionSettingsDialogClass
{
public:
//////////////////////////////////////////////////////////////////
// Public constructors/destructors
//////////////////////////////////////////////////////////////////
AnimationCompressionSettingsDialogClass (Interface *maxinterface, HWND parent_wnd = NULL);
~AnimationCompressionSettingsDialogClass (void);
//////////////////////////////////////////////////////////////////
// Public methods
//////////////////////////////////////////////////////////////////
void Set_Options (W3dExportOptionsStruct *options) { Options = options; }
int Do_Modal (void);
private:
//////////////////////////////////////////////////////////////////
// Static methods
//////////////////////////////////////////////////////////////////
static BOOL CALLBACK Real_Message_Proc (HWND wnd, UINT message, WPARAM wparam, LPARAM lparam);
//////////////////////////////////////////////////////////////////
// Private methods
//////////////////////////////////////////////////////////////////
BOOL Message_Proc (UINT message, WPARAM wparam, LPARAM lparam);
void Initialize_Controls (void);
void Save_Settings (void);
//////////////////////////////////////////////////////////////////
// Private member data
//////////////////////////////////////////////////////////////////
W3dExportOptionsStruct * Options;
Interface * MaxInterface;
HWND Wnd;
HWND ParentWnd;
};
#endif //__ANIMATION_COMPRESSION_SETTINGS_H

View file

@ -0,0 +1,319 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : W3D Tools *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/bchannel.cpp $*
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 10/30/00 5:25p $*
* *
* $Revision:: 6 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "bchannel.h"
#include "w3d_file.h"
#include "logdlg.h"
#include "exportlog.h"
BitChannelClass::BitChannelClass
(
uint32 id,
int maxframes,
uint32 chntype,
bool default_val
) :
ID(id),
ChannelType(chntype),
MaxFrames(maxframes),
IsEmpty(true),
DefaultVal(default_val),
Data(maxframes),
Begin(0),
End(0)
{
// start "Begin" at the end of the array, whenever we set a value
// at an index less than "Begin", we push "Begin" back.
Begin = MaxFrames;
End = 0;
}
BitChannelClass::~BitChannelClass(void)
{
}
void BitChannelClass::Set_Bit(int frameidx,bool bit)
{
assert(frameidx >= 0);
assert(frameidx < MaxFrames);
Data[frameidx] = bit;
if (!is_default(bit)) {
IsEmpty = false;
}
}
void BitChannelClass::Set_Bits(BooleanVectorClass & bits)
{
for (int i=0; i<bits.Length(); i++) {
Set_Bit(i,bits[i]);
}
}
bool BitChannelClass::Get_Bit(int frameidx)
{
assert(frameidx >= 0);
assert(frameidx < MaxFrames);
return Data[frameidx];
}
bool BitChannelClass::Save(ChunkSaveClass & csave, bool compress)
{
if (IsEmpty) return true;
if (compress) {
// Save the Channel Data Compressed
// TIMECODED
if (!csave.Begin_Chunk(W3D_CHUNK_COMPRESSED_BIT_CHANNEL)) {
return false;
}
uint32 channelsize = sizeof(W3dTimeCodedBitChannelStruct);
uint32 packetsize = sizeof(uint32);
channelsize += packetsize * MaxFrames;
channelsize -= sizeof(uint32);
W3dTimeCodedBitChannelStruct * chn = (W3dTimeCodedBitChannelStruct *)malloc(channelsize);
if (chn == NULL) {
return false;
}
chn->NumTimeCodes = MaxFrames;
chn->Pivot = ID;
chn->Flags = ChannelType;
chn->DefaultVal = DefaultVal;
// copy data into the channel struct, in timecoded raw format
for (uint32 fcount=0; fcount < chn->NumTimeCodes; fcount++) {
if (Get_Bit(fcount)) {
chn->Data[fcount] = fcount | W3D_TIMECODED_BIT_MASK;
}
else {
chn->Data[fcount] = fcount;
}
}
// Compress the new structure
BitChannelClass::compress( chn );
float originalchannelsize = channelsize;
// Update Channel Size
channelsize = sizeof(W3dTimeCodedBitChannelStruct);
channelsize += packetsize * chn->NumTimeCodes;
channelsize -= sizeof(uint32);
float percent = (((float) channelsize) / originalchannelsize) * 100.0f;
ExportLog::printf("%.0f", percent);
// save
if (csave.Write(chn,channelsize) != channelsize) {
return false;
}
if (chn != NULL) {
free(chn);
}
if (!csave.End_Chunk()) {
return false;
}
}
else {
// Stock Raw Save
if (!csave.Begin_Chunk(W3D_CHUNK_BIT_CHANNEL)) {
return false;
}
compute_range();
int numbits = End - Begin + 1;
assert(numbits > 0);
int numbytes = (numbits + 7) / 8;
unsigned int channelsize = sizeof(W3dBitChannelStruct);
channelsize += numbytes - 1; // one byte inside the W3dBitChannelStruct...
W3dBitChannelStruct * chn = (W3dBitChannelStruct *)malloc(channelsize);
if (chn == NULL) {
return false;
}
chn->FirstFrame = Begin;
chn->LastFrame = End;
chn->Flags = ChannelType;
chn->Pivot = ID;
chn->DefaultVal = DefaultVal;
uint8 * bits = (uint8 *)&(chn->Data[0]);
for (int fcount=0; fcount < End-Begin+1; fcount++) {
::Set_Bit(bits,fcount,Get_Bit(Begin + fcount));
}
if (csave.Write(chn,channelsize) != channelsize) {
return false;
}
if (chn != NULL) {
free(chn);
}
if (!csave.End_Chunk()) {
return false;
}
}
return true;
}
bool BitChannelClass::is_default(bool bit)
{
return (bit == DefaultVal);
}
void BitChannelClass::compute_range(void)
{
Begin = 0;
while ((Begin < MaxFrames) && (is_default(Get_Bit(Begin)))) {
Begin++;
}
End = MaxFrames-1;
while ((End >= 0) && (is_default(Get_Bit(End)))) {
End--;
}
} // compute_range
//
// find a packet that isn't needed, and return the index
// if all packets are necessary, then return back PACKETS_ALL_USEFUL
// a useless packet is defined, as a packet that can be recreated
//
#define PACKETS_ALL_USEFUL (0xFFFFFFFF)
//
uint32 BitChannelClass::find_useless_packet(W3dTimeCodedBitChannelStruct * c)
{
assert( c ); // make sure pointer exists
assert( c->NumTimeCodes ); // make sure some packets exist
if (c->NumTimeCodes > 2) {
for(uint32 try_idx = 0; try_idx < (c->NumTimeCodes - 1); try_idx++) {
if ((c->Data[try_idx] & W3D_TIMECODED_BIT_MASK) ==
(c->Data[try_idx+1] & W3D_TIMECODED_BIT_MASK)) {
return(try_idx + 1);
}
} // for
}
return( PACKETS_ALL_USEFUL );
} // find_useless_packet
//
// Remove a packet from a W3dTimeCodedBitChannelStruct
//
void BitChannelClass::remove_packet(W3dTimeCodedBitChannelStruct * c, uint32 packet_idx)
{
assert( c );
assert( c->NumTimeCodes > 1 );
uint32 packet_size = 1;
uint32 packet_len = packet_size * sizeof(uint32);
uint32 *src, *dst;
dst = (uint32 *) &c->Data[ packet_size * packet_idx ];
src = (uint32 *) &c->Data[ packet_size * (packet_idx + 1) ];
uint32 copy_length = (c->NumTimeCodes - (packet_idx + 1)) * packet_len;
if (copy_length) {
memcpy(dst, src, copy_length);
}
// Decrement Packet Count
c->NumTimeCodes--;
} // remove_packet
//
// Take a non-compressed TimeCoded Bit Channel
// and compress the packets
//
void BitChannelClass::compress(W3dTimeCodedBitChannelStruct * c)
{
while(1) {
uint32 idx = find_useless_packet( c );
if (PACKETS_ALL_USEFUL == idx) break;
remove_packet( c, idx );
}
} // compress
// EOF - bchannel.cpp

View file

@ -0,0 +1,103 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : W3D Tools *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/bchannel.h $*
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 10/30/00 5:25p $*
* *
* $Revision:: 5 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef BCHANNEL_H
#define BCHANNEL_H
#ifndef ALWAYS_H
#include "always.h"
#endif
#ifndef BITTYPE_H
#include "bittype.h"
#endif
#ifndef CHUNKIO_H
#include "chunkio.h"
#endif
#ifndef VECTOR_H
#include "vector.h"
#endif
#ifndef W3D_FILE_H
#include "w3d_file.h"
#endif
class LogDataDialogClass;
class BitChannelClass
{
public:
BitChannelClass(uint32 id,int maxframes,uint32 chntype,bool def_val);
~BitChannelClass(void);
void Set_Bit(int framenumber,bool bit);
void Set_Bits(BooleanVectorClass & bits);
bool Get_Bit(int frameidx);
bool Is_Empty(void) { return IsEmpty; }
bool Save(ChunkSaveClass & csave, bool compress);
private:
uint32 ID;
uint32 ChannelType;
int MaxFrames;
bool IsEmpty;
bool DefaultVal;
BooleanVectorClass Data;
int Begin;
int End;
// Test a bit against the "default" bit
bool is_default(bool bit);
// This function finds the start and end of the "non-default" data
void compute_range(void);
// compress functions
void remove_packet(W3dTimeCodedBitChannelStruct * c, uint32 packet_idx);
uint32 find_useless_packet(W3dTimeCodedBitChannelStruct * c);
void compress(W3dTimeCodedBitChannelStruct * c);
};
#endif

View file

@ -0,0 +1,606 @@
/*
** Command & Conquer Generals(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/>.
*/
/* $Header: /Commando/Code/Tools/max2w3d/boneicon.cpp 6 1/12/98 4:02p Greg_h $ */
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando Tools - WWSkin *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/boneicon.cpp $*
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 1/09/98 3:09p $*
* *
* $Revision:: 6 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "boneicon.h"
const int NumBoneIconVerts = 184;
const int NumBoneIconFaces = 366;
/*
** Don't try this at home :-)
*/
#pragma warning(disable:4305)
VertexStruct BoneIconVerts[NumBoneIconVerts] = {
{ 0.07, -0.37, 0.23 },
{ 0.07, -0.38, 0.22 },
{ 0.07, -0.37, 0.22 },
{ -0.07, -0.38, 0.22 },
{ -0.07, -0.38, 0.22 },
{ -0.05, -0.31, 0.21 },
{ -0.07, -0.38, 0.22 },
{ -0.07, -0.37, 0.21 },
{ 0.07, -0.38, 0.22 },
{ 0.06, -0.34, 0.18 },
{ 0.07, -0.38, 0.23 },
{ -0.07, -0.38, 0.22 },
{ -0.10, -0.42, 0.19 },
{ -0.04, -0.47, 0.11 },
{ -0.04, -0.51, 0.21 },
{ -0.04, -0.36, 0.12 },
{ 0.05, -0.41, 0.10 },
{ 0.05, -0.51, 0.15 },
{ 0.05, -0.49, 0.26 },
{ 0.11, -0.42, 0.19 },
{ -0.05, -0.45, 0.26 },
{ -0.06, -0.43, 0.25 },
{ -0.04, -0.45, 0.27 },
{ -0.07, -0.40, 0.23 },
{ 0.00, -0.46, 0.27 },
{ 0.04, -0.45, 0.27 },
{ 0.05, -0.44, 0.27 },
{ -0.00, -0.46, 0.27 },
{ 0.06, -0.43, 0.25 },
{ 0.07, -0.39, 0.24 },
{ -0.11, -0.37, 0.28 },
{ -0.05, -0.47, 0.30 },
{ -0.05, -0.38, 0.37 },
{ -0.05, -0.29, 0.32 },
{ 0.04, -0.44, 0.35 },
{ 0.04, -0.33, 0.36 },
{ 0.04, -0.28, 0.26 },
{ 0.10, -0.37, 0.28 },
{ 0.04, -0.30, 0.23 },
{ 0.04, -0.29, 0.24 },
{ 0.01, -0.29, 0.24 },
{ -0.03, -0.30, 0.25 },
{ -0.05, -0.31, 0.22 },
{ -0.04, -0.35, 0.15 },
{ -0.03, -0.35, 0.13 },
{ -0.02, -0.35, 0.13 },
{ 0.04, -0.36, 0.14 },
{ 0.05, -0.34, 0.16 },
{ -0.05, 0.36, -0.16 },
{ -0.05, 0.36, -0.15 },
{ -0.07, 0.41, -0.22 },
{ 0.05, 0.33, -0.22 },
{ 0.06, 0.35, -0.21 },
{ 0.07, 0.41, -0.22 },
{ 0.04, 0.38, -0.14 },
{ 0.07, 0.40, -0.20 },
{ 0.07, 0.41, -0.21 },
{ 0.04, 0.38, -0.13 },
{ 0.01, 0.38, -0.13 },
{ -0.03, 0.38, -0.13 },
{ -0.07, 0.40, -0.21 },
{ -0.04, 0.33, -0.22 },
{ -0.07, 0.41, -0.22 },
{ -0.03, 0.32, -0.24 },
{ -0.02, 0.32, -0.24 },
{ 0.04, 0.33, -0.24 },
{ -0.10, 0.40, -0.27 },
{ -0.04, 0.36, -0.35 },
{ -0.04, 0.31, -0.25 },
{ -0.04, 0.47, -0.34 },
{ 0.05, 0.41, -0.36 },
{ 0.05, 0.32, -0.31 },
{ 0.05, 0.50, -0.28 },
{ 0.11, 0.40, -0.27 },
{ -0.06, 0.46, -0.24 },
{ -0.07, 0.42, -0.23 },
{ -0.05, 0.48, -0.25 },
{ -0.04, 0.48, -0.25 },
{ 0.00, 0.49, -0.26 },
{ 0.04, 0.48, -0.25 },
{ 0.05, 0.48, -0.25 },
{ -0.00, 0.49, -0.26 },
{ 0.07, 0.43, -0.21 },
{ 0.06, 0.46, -0.24 },
{ -0.11, 0.45, -0.18 },
{ -0.05, 0.44, -0.08 },
{ -0.05, 0.54, -0.14 },
{ -0.05, 0.52, -0.25 },
{ 0.04, 0.39, -0.11 },
{ 0.04, 0.50, -0.10 },
{ 0.04, 0.54, -0.20 },
{ 0.10, 0.45, -0.18 },
{ 0.07, 0.37, 0.22 },
{ 0.07, 0.37, 0.22 },
{ 0.07, 0.37, 0.21 },
{ -0.07, 0.37, 0.22 },
{ -0.07, 0.37, 0.22 },
{ -0.05, 0.33, 0.17 },
{ -0.07, 0.37, 0.22 },
{ -0.07, 0.36, 0.22 },
{ 0.07, 0.37, 0.22 },
{ 0.06, 0.31, 0.21 },
{ 0.07, 0.37, 0.22 },
{ -0.07, 0.37, 0.22 },
{ -0.10, 0.37, 0.27 },
{ -0.04, 0.32, 0.36 },
{ -0.04, 0.43, 0.34 },
{ -0.04, 0.27, 0.25 },
{ 0.05, 0.28, 0.31 },
{ 0.05, 0.38, 0.37 },
{ 0.05, 0.46, 0.29 },
{ 0.11, 0.37, 0.27 },
{ -0.05, 0.44, 0.26 },
{ -0.06, 0.43, 0.25 },
{ -0.04, 0.45, 0.26 },
{ -0.07, 0.39, 0.24 },
{ 0.00, 0.46, 0.26 },
{ 0.04, 0.45, 0.26 },
{ 0.05, 0.44, 0.25 },
{ -0.00, 0.46, 0.27 },
{ 0.06, 0.42, 0.25 },
{ 0.07, 0.40, 0.22 },
{ -0.11, 0.42, 0.19 },
{ -0.05, 0.48, 0.26 },
{ -0.05, 0.50, 0.15 },
{ -0.05, 0.41, 0.09 },
{ 0.04, 0.51, 0.21 },
{ 0.04, 0.46, 0.10 },
{ 0.04, 0.35, 0.12 },
{ 0.10, 0.42, 0.19 },
{ 0.04, 0.35, 0.15 },
{ 0.04, 0.35, 0.14 },
{ 0.01, 0.34, 0.13 },
{ -0.03, 0.35, 0.14 },
{ -0.05, 0.33, 0.16 },
{ -0.04, 0.30, 0.23 },
{ -0.03, 0.28, 0.24 },
{ -0.02, 0.28, 0.24 },
{ 0.04, 0.29, 0.25 },
{ 0.05, 0.30, 0.22 },
{ -0.05, -0.34, -0.21 },
{ -0.05, -0.34, -0.22 },
{ -0.07, -0.41, -0.22 },
{ 0.05, -0.37, -0.16 },
{ 0.06, -0.37, -0.17 },
{ 0.07, -0.41, -0.22 },
{ 0.04, -0.33, -0.23 },
{ 0.07, -0.40, -0.22 },
{ 0.07, -0.41, -0.23 },
{ 0.04, -0.32, -0.24 },
{ 0.01, -0.32, -0.24 },
{ -0.03, -0.33, -0.24 },
{ -0.07, -0.40, -0.21 },
{ -0.04, -0.38, -0.15 },
{ -0.07, -0.41, -0.22 },
{ -0.03, -0.38, -0.13 },
{ -0.02, -0.38, -0.13 },
{ 0.04, -0.39, -0.14 },
{ -0.10, -0.45, -0.19 },
{ -0.04, -0.50, -0.11 },
{ -0.04, -0.39, -0.12 },
{ -0.04, -0.54, -0.21 },
{ 0.05, -0.54, -0.15 },
{ 0.05, -0.44, -0.10 },
{ 0.05, -0.52, -0.26 },
{ 0.11, -0.45, -0.19 },
{ -0.06, -0.46, -0.26 },
{ -0.07, -0.43, -0.23 },
{ -0.05, -0.48, -0.26 },
{ -0.04, -0.48, -0.27 },
{ 0.00, -0.49, -0.27 },
{ 0.04, -0.48, -0.27 },
{ 0.05, -0.47, -0.27 },
{ -0.00, -0.49, -0.27 },
{ 0.07, -0.42, -0.24 },
{ 0.06, -0.46, -0.25 },
{ -0.11, -0.40, -0.28 },
{ -0.05, -0.32, -0.32 },
{ -0.05, -0.41, -0.37 },
{ -0.05, -0.50, -0.30 },
{ 0.04, -0.31, -0.26 },
{ 0.04, -0.35, -0.36 },
{ 0.04, -0.47, -0.35 },
{ 0.10, -0.40, -0.28 }
};
FaceStruct BoneIconFaces[NumBoneIconFaces] = {
{ 0, 1, 2 },
{ 3, 4, 5 },
{ 6, 3, 7 },
{ 1, 8, 9 },
{ 1, 0, 10 },
{ 4, 3, 11 },
{ 11, 3, 6 },
{ 11, 4, 11 },
{ 10, 8, 1 },
{ 12, 13, 14 },
{ 12, 15, 13 },
{ 13, 16, 17 },
{ 14, 17, 18 },
{ 17, 14, 13 },
{ 16, 13, 15 },
{ 19, 18, 17 },
{ 19, 17, 16 },
{ 12, 14, 20 },
{ 21, 12, 20 },
{ 14, 22, 20 },
{ 22, 14, 18 },
{ 12, 21, 23 },
{ 24, 18, 25 },
{ 18, 26, 25 },
{ 26, 18, 19 },
{ 18, 24, 27 },
{ 22, 18, 27 },
{ 26, 19, 28 },
{ 19, 29, 28 },
{ 30, 31, 32 },
{ 30, 32, 33 },
{ 32, 34, 35 },
{ 33, 35, 36 },
{ 34, 32, 31 },
{ 35, 33, 32 },
{ 37, 35, 34 },
{ 37, 36, 35 },
{ 31, 30, 21 },
{ 20, 31, 21 },
{ 31, 20, 22 },
{ 30, 23, 21 },
{ 34, 31, 24 },
{ 25, 34, 24 },
{ 34, 25, 37 },
{ 37, 25, 26 },
{ 31, 27, 24 },
{ 27, 31, 22 },
{ 28, 37, 26 },
{ 37, 28, 29 },
{ 38, 36, 37 },
{ 37, 2, 38 },
{ 2, 37, 29 },
{ 0, 2, 29 },
{ 36, 38, 39 },
{ 33, 36, 40 },
{ 40, 36, 39 },
{ 33, 40, 41 },
{ 33, 42, 30 },
{ 42, 33, 41 },
{ 5, 30, 42 },
{ 23, 30, 4 },
{ 30, 5, 4 },
{ 12, 23, 6 },
{ 7, 12, 6 },
{ 12, 7, 15 },
{ 43, 15, 7 },
{ 15, 43, 44 },
{ 16, 15, 45 },
{ 45, 15, 44 },
{ 16, 45, 46 },
{ 47, 16, 46 },
{ 16, 47, 19 },
{ 9, 19, 47 },
{ 9, 19, 9 },
{ 29, 19, 8 },
{ 19, 9, 8 },
{ 29, 10, 0 },
{ 6, 23, 11 },
{ 11, 23, 11 },
{ 11, 23, 4 },
{ 10, 29, 8 },
{ 48, 3, 49 },
{ 49, 3, 5 },
{ 50, 3, 48 },
{ 3, 50, 7 },
{ 51, 1, 9 },
{ 1, 51, 52 },
{ 53, 1, 52 },
{ 1, 53, 2 },
{ 56, 38, 2 },
{ 38, 54, 39 },
{ 38, 56, 55 },
{ 38, 55, 54 },
{ 2, 53, 56 },
{ 57, 39, 54 },
{ 39, 57, 40 },
{ 40, 58, 41 },
{ 57, 58, 40 },
{ 59, 41, 58 },
{ 41, 59, 42 },
{ 42, 59, 5 },
{ 49, 5, 59 },
{ 7, 50, 43 },
{ 43, 50, 60 },
{ 43, 60, 61 },
{ 43, 61, 44 },
{ 60, 50, 62 },
{ 63, 44, 61 },
{ 44, 63, 45 },
{ 45, 63, 64 },
{ 45, 64, 46 },
{ 65, 46, 64 },
{ 46, 65, 47 },
{ 47, 65, 9 },
{ 51, 9, 65 },
{ 66, 67, 68 },
{ 66, 69, 67 },
{ 67, 70, 71 },
{ 69, 72, 70 },
{ 71, 68, 67 },
{ 70, 67, 69 },
{ 73, 70, 72 },
{ 73, 71, 70 },
{ 74, 66, 75 },
{ 66, 74, 69 },
{ 69, 74, 76 },
{ 77, 69, 76 },
{ 69, 77, 72 },
{ 72, 78, 79 },
{ 80, 72, 79 },
{ 72, 80, 73 },
{ 78, 72, 81 },
{ 72, 77, 81 },
{ 82, 73, 83 },
{ 73, 80, 83 },
{ 84, 85, 86 },
{ 84, 86, 87 },
{ 85, 88, 89 },
{ 86, 89, 90 },
{ 89, 86, 85 },
{ 90, 87, 86 },
{ 91, 89, 88 },
{ 91, 90, 89 },
{ 75, 84, 87 },
{ 75, 87, 74 },
{ 87, 76, 74 },
{ 76, 87, 77 },
{ 87, 90, 78 },
{ 90, 79, 78 },
{ 79, 90, 91 },
{ 79, 91, 80 },
{ 81, 87, 78 },
{ 87, 81, 77 },
{ 91, 83, 80 },
{ 83, 91, 82 },
{ 84, 48, 85 },
{ 49, 85, 48 },
{ 48, 84, 50 },
{ 84, 75, 50 },
{ 51, 71, 73 },
{ 73, 52, 51 },
{ 52, 73, 53 },
{ 73, 82, 53 },
{ 56, 82, 91 },
{ 88, 54, 91 },
{ 91, 54, 55 },
{ 91, 55, 56 },
{ 56, 53, 82 },
{ 54, 88, 57 },
{ 88, 85, 58 },
{ 57, 88, 58 },
{ 58, 85, 59 },
{ 49, 59, 85 },
{ 66, 60, 75 },
{ 68, 60, 66 },
{ 68, 61, 60 },
{ 62, 75, 60 },
{ 75, 62, 50 },
{ 61, 68, 63 },
{ 64, 68, 71 },
{ 68, 64, 63 },
{ 64, 71, 65 },
{ 51, 65, 71 },
{ 92, 93, 94 },
{ 95, 96, 97 },
{ 98, 95, 99 },
{ 93, 100, 101 },
{ 93, 92, 102 },
{ 96, 95, 103 },
{ 103, 95, 98 },
{ 103, 96, 103 },
{ 102, 100, 93 },
{ 104, 105, 106 },
{ 104, 107, 105 },
{ 105, 108, 109 },
{ 106, 109, 110 },
{ 109, 106, 105 },
{ 108, 105, 107 },
{ 111, 110, 109 },
{ 111, 109, 108 },
{ 104, 106, 112 },
{ 113, 104, 112 },
{ 106, 114, 112 },
{ 114, 106, 110 },
{ 104, 113, 115 },
{ 116, 110, 117 },
{ 110, 118, 117 },
{ 118, 110, 111 },
{ 110, 116, 119 },
{ 114, 110, 119 },
{ 118, 111, 120 },
{ 111, 121, 120 },
{ 122, 123, 124 },
{ 122, 124, 125 },
{ 124, 126, 127 },
{ 125, 127, 128 },
{ 126, 124, 123 },
{ 127, 125, 124 },
{ 129, 127, 126 },
{ 129, 128, 127 },
{ 123, 122, 113 },
{ 112, 123, 113 },
{ 123, 112, 114 },
{ 122, 115, 113 },
{ 126, 123, 116 },
{ 117, 126, 116 },
{ 126, 117, 129 },
{ 129, 117, 118 },
{ 123, 119, 116 },
{ 119, 123, 114 },
{ 120, 129, 118 },
{ 129, 120, 121 },
{ 130, 128, 129 },
{ 129, 94, 130 },
{ 94, 129, 121 },
{ 92, 94, 121 },
{ 128, 130, 131 },
{ 125, 128, 132 },
{ 132, 128, 131 },
{ 125, 132, 133 },
{ 125, 134, 122 },
{ 134, 125, 133 },
{ 97, 122, 134 },
{ 115, 122, 96 },
{ 122, 97, 96 },
{ 104, 115, 98 },
{ 99, 104, 98 },
{ 104, 99, 107 },
{ 135, 107, 99 },
{ 107, 135, 136 },
{ 108, 107, 137 },
{ 137, 107, 136 },
{ 108, 137, 138 },
{ 139, 108, 138 },
{ 108, 139, 111 },
{ 101, 111, 139 },
{ 101, 111, 101 },
{ 121, 111, 100 },
{ 111, 101, 100 },
{ 121, 102, 92 },
{ 98, 115, 103 },
{ 103, 115, 103 },
{ 103, 115, 96 },
{ 102, 121, 100 },
{ 140, 95, 141 },
{ 141, 95, 97 },
{ 142, 95, 140 },
{ 95, 142, 99 },
{ 143, 93, 101 },
{ 93, 143, 144 },
{ 145, 93, 144 },
{ 93, 145, 94 },
{ 148, 130, 94 },
{ 130, 146, 131 },
{ 130, 148, 147 },
{ 130, 147, 146 },
{ 94, 145, 148 },
{ 149, 131, 146 },
{ 131, 149, 132 },
{ 132, 150, 133 },
{ 149, 150, 132 },
{ 151, 133, 150 },
{ 133, 151, 134 },
{ 134, 151, 97 },
{ 141, 97, 151 },
{ 99, 142, 135 },
{ 135, 142, 152 },
{ 135, 152, 153 },
{ 135, 153, 136 },
{ 152, 142, 154 },
{ 155, 136, 153 },
{ 136, 155, 137 },
{ 137, 155, 156 },
{ 137, 156, 138 },
{ 157, 138, 156 },
{ 138, 157, 139 },
{ 139, 157, 101 },
{ 143, 101, 157 },
{ 158, 159, 160 },
{ 158, 161, 159 },
{ 159, 162, 163 },
{ 161, 164, 162 },
{ 163, 160, 159 },
{ 162, 159, 161 },
{ 165, 162, 164 },
{ 165, 163, 162 },
{ 166, 158, 167 },
{ 158, 166, 161 },
{ 161, 166, 168 },
{ 169, 161, 168 },
{ 161, 169, 164 },
{ 164, 170, 171 },
{ 172, 164, 171 },
{ 164, 172, 165 },
{ 170, 164, 173 },
{ 164, 169, 173 },
{ 174, 165, 175 },
{ 165, 172, 175 },
{ 176, 177, 178 },
{ 176, 178, 179 },
{ 177, 180, 181 },
{ 178, 181, 182 },
{ 181, 178, 177 },
{ 182, 179, 178 },
{ 183, 181, 180 },
{ 183, 182, 181 },
{ 167, 176, 179 },
{ 167, 179, 166 },
{ 179, 168, 166 },
{ 168, 179, 169 },
{ 179, 182, 170 },
{ 182, 171, 170 },
{ 171, 182, 183 },
{ 171, 183, 172 },
{ 173, 179, 170 },
{ 179, 173, 169 },
{ 183, 175, 172 },
{ 175, 183, 174 },
{ 176, 140, 177 },
{ 141, 177, 140 },
{ 140, 176, 142 },
{ 176, 167, 142 },
{ 143, 163, 165 },
{ 165, 144, 143 },
{ 144, 165, 145 },
{ 165, 174, 145 },
{ 148, 174, 183 },
{ 180, 146, 183 },
{ 183, 146, 147 },
{ 183, 147, 148 },
{ 148, 145, 174 },
{ 146, 180, 149 },
{ 180, 177, 150 },
{ 149, 180, 150 },
{ 150, 177, 151 },
{ 141, 151, 177 },
{ 158, 152, 167 },
{ 160, 152, 158 },
{ 160, 153, 152 },
{ 154, 167, 152 },
{ 167, 154, 142 },
{ 153, 160, 155 },
{ 156, 160, 163 },
{ 160, 156, 155 },
{ 156, 163, 157 },
{ 143, 157, 163 }
};

View file

@ -0,0 +1,57 @@
/*
** Command & Conquer Generals(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/>.
*/
/* $Header: /Commando/Code/Tools/max2w3d/boneicon.h 5 10/28/97 6:08p Greg_h $ */
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando Tools - WWSkin *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/boneicon.h $*
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 10/21/97 2:06p $*
* *
* $Revision:: 5 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef BONEICON_H
#define BONEICON_H
struct VertexStruct
{
float X,Y,Z;
};
struct FaceStruct
{
int V0,V1,V2;
};
extern const int NumBoneIconVerts;
extern const int NumBoneIconFaces;
extern VertexStruct BoneIconVerts[];
extern FaceStruct BoneIconFaces[];
#endif

View file

@ -0,0 +1,155 @@
/*
** Command & Conquer Generals(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/>.
*/
/* $Header: /Commando/Code/Tools/max2w3d/bpick.cpp 7 1/04/01 11:12a Greg_h $ */
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando Tools - WWSkin *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/bpick.cpp $*
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 1/04/01 11:12a $*
* *
* $Revision:: 7 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* BonePickerClass::Filter -- determine whether the passed node is suitable *
* BonePickerClass::HitTest -- MAX HitTest method *
* BonePickerClass::Pick -- MAX Pick method *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "bpick.h"
#include "dllmain.h"
#include "resource.h"
/*
** Global instance of a bone picker :-)
*/
BonePickerClass TheBonePicker;
/***********************************************************************************************
* BonePickerClass::Filter -- determine whether the passed node is suitable *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 10/26/1997 GH : Created. *
*=============================================================================================*/
BOOL BonePickerClass::Filter(INode *node)
{
if (BoneList == NULL) {
ObjectState os = node->EvalWorldState(0);
if (os.obj) {
return TRUE;
}
} else {
for (int i=0; i<BoneList->Count(); i++) {
if ((*BoneList)[i] == node) return TRUE;
}
}
return FALSE;
}
/***********************************************************************************************
* BonePickerClass::HitTest -- MAX HitTest method *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 10/26/1997 GH : Created. *
*=============================================================================================*/
BOOL BonePickerClass::HitTest(IObjParam *ip,HWND hwnd,ViewExp *vpt,IPoint2 m,int flags)
{
if (ip->PickNode(hwnd,m,GetFilter())) {
return TRUE;
} else {
return FALSE;
}
}
/***********************************************************************************************
* BonePickerClass::Pick -- MAX Pick method *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 10/26/1997 GH : Created. *
*=============================================================================================*/
BOOL BonePickerClass::Pick(IObjParam *ip,ViewExp *vpt)
{
INode *node = vpt->GetClosestHit();
if (node) {
/*
** Tell the "owning" skin modifier about the
** bone which was picked.
*/
assert(User);
User->User_Picked_Bone(node);
User = NULL;
BoneList = NULL;
}
return TRUE;
}
BOOL BonePickerClass::filter(INode * inode)
{
return Filter(inode);
}
void BonePickerClass::proc(INodeTab & nodetab)
{
assert(User != NULL);
User->User_Picked_Bones(nodetab);
User = NULL;
BoneList = NULL;
}
TCHAR * BonePickerClass::dialogTitle(void)
{
return Get_String(IDS_PICK_BONE_DIALOG_TITLE);
}
TCHAR * BonePickerClass::buttonText(void)
{
return Get_String(IDS_PICK_BONE_BUTTON_TEXT);
}

View file

@ -0,0 +1,129 @@
/*
** Command & Conquer Generals(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/>.
*/
/* $Header: /Commando/Code/Tools/max2w3d/bpick.h 6 10/28/97 6:08p Greg_h $ */
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando Tools - WWSkin *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/bpick.h $*
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 10/21/97 2:05p $*
* *
* $Revision:: 6 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef BPICK_H
#define BPICK_H
#include "Max.h"
//#include "dllmain.h"
//#include "resource.h"
/*
** To use the Bone picking class, you should inherit from this class
** and implement the User_Picked... functions.
*/
class BonePickerUserClass
{
public:
virtual void User_Picked_Bone(INode * node) = 0;
virtual void User_Picked_Bones(INodeTab & nodetab) = 0;
};
/*
** BonePickerClass
** Uses Max's interface to let the user pick bones out of the scene
** or by using a dialog box to pick by name.
*/
class BonePickerClass : public PickNodeCallback, public PickModeCallback, public HitByNameDlgCallback
{
public:
BonePickerClass(void) : User(NULL), BoneList(NULL), SinglePick(FALSE) {}
/*
** Tell this class who is using it and optionally the list
** of bones to allow the user to select from.
** Call this before giving this class to MAX...
*/
void Set_User(BonePickerUserClass * user,int singlepick = FALSE, INodeTab * bonelist = NULL) { User = user; SinglePick = singlepick; BoneList = bonelist; }
/*
** From BonePickNodeCallback:
*/
BOOL Filter(INode *node);
/*
** From BonePickModeCallback:
*/
BOOL HitTest(IObjParam *ip,HWND hWnd,ViewExp *vpt,IPoint2 m,int flags);
BOOL Pick(IObjParam *ip,ViewExp *vpt);
void EnterMode(IObjParam *ip) { }
void ExitMode(IObjParam *ip) { }
PickNodeCallback * GetFilter() {return this;}
BOOL RightClick(IObjParam *ip,ViewExp *vpt) { return TRUE; }
/*
** From HitByNameDlgCallback
*/
virtual TCHAR * dialogTitle(void);
virtual TCHAR * buttonText(void);
virtual BOOL singleSelect(void) { return SinglePick; }
virtual BOOL useFilter(void) { return TRUE; }
virtual BOOL useProc(void) { return TRUE; }
virtual BOOL doCustomHilite(void) { return FALSE; }
virtual BOOL filter(INode * inode);
virtual void proc(INodeTab & nodeTab);
protected:
/*
** The bone picker will pass the bones on to the "user" of
** the class.
*/
BonePickerUserClass * User;
/*
** List of bones that the user is being allowed to pick from.
** If this is NULL, then the user can pick any bone
*/
INodeTab * BoneList;
/*
** Flag for whether to allow multiple selection or not
*/
int SinglePick;
};
extern BonePickerClass TheBonePicker;
#endif

View file

@ -0,0 +1,412 @@
Version 1.0.4.70: August 22, 2001
Greg: - Added BumpEnv mapper
- Added NPatch enable flag for meshes (in the w3dtools command panel)
Ian: - Added BumpEnv setting to the shader (in primary gradient)
Version 1.0.4.69: January 4, 2001
Greg: - Modified the "bone picker" that the WWSkin space warp uses to allow Max bones to
be used.
Version 1.0.4.68: December 7, 2000
Andre: - Added a Static Sort Level parameter to the Surface Properties rollup page of the
material editor. This parameter must be the same across all materials assigned to
one mesh, and is enforced on export. The value is written out as part of the mesh
header to which the material is assigned.
Version 1.0.4.67: December 6, 2000
Greg: - Added 'Vehicle' collision bit. This will allow us to create meshes which constrain vehicles
to certain parts of a level without constraining characters or projectiles.
Version 1.0.4.66: November 7, 2000
Greg: - Disabled the "optimize meshes" feature because recent developments in the run-time code
seem to have made it un-necessary (and possibly even undesireable due to the extra mesh overhead)
The main reason for disabling the feature is that the automatic nature of it makes some of
our processes harder to debug. Mesh names are lost so the artist has no way of figuring out
which mesh is causing problems when one of the other tools complains about something.
- modified the mesh export code to reject meshes that are using multi-pass transparent materials.
- fixed error message boxes so they pop on top of all windows (they were appearing behind the log window)
Version 1.0.4.65: October 31, 2000
Greg: - Finished code re-organization.
- Pat provided new UI for the main export dialog
- Fixed the "smooth across meshes" feature
- Added the export log window.
Version 1.0.4.64: October 20, 2000
Greg: - Fixed a bug in the name editing dialog in the W3D utility panel
- Modified the VAlpha behavior so that only the *last* pass with alpha blending
gets the vertex alpha (instead of all passes with alpha blending)
- Added the Aggregate geometry type. This lets you request external
W3D objects to be attached to bones in your model.
- Added preliminary mesh optimization features. During the export, meshes can be split
into single-material meshes and then meshes which use the same materials
can be combined into larger meshes.
Version 1.0.4.63: October 19, 2000
Greg: Re-organized the entire DoExport function.
- First I unified all of the code to go through the "DoOriginBasedExport"
code by using the scene root as the origin when there were no user-defined
origins.
- Re-organized the Export_Geometry function to use a new abstract
class: GeometryExporTaskClass which encapsulates a lot of code that was
cut-and-pasted many times through the w3dexp.cpp module.
- Broke several classes and functions out of w3dexp.cpp into their own
modules.
- Modified/Cleaned HierarchySaveClass and MeshConnections class.
Version 1.0.4.62: October 11, 2000
Greg: Re-organised the W3DUtility plugin. Moved several dialog boxes
used by it into their own modules and created a modeless dialog
containing the w3d settings that can be left up when the user
is not in Max's utility panel.
Version 1.0.4.61: September 26, 2000
Greg: Added copying of the dazzle app data structure to the MaxScript
extensions.
Version 1.0.4.60: September 22, 2000
Greg: Added dazzle exporting to the plugin. Modified MeshConnnections
class and the w3d file format so that HModels are exported in a
slightly simpler manner and so that they can support dazzles. The
"auxiliary" header for hmodels is now obsolete.
Version 1.0.4.59: September 18, 2000
Greg: Modified the code so that collections are exported even when no
meshes or other render objects are present. This is used to create
collections of proxy objects for the renegade level editor. Also
modified the "origin" export code to support exporting collections
with origins.
Version 1.0.4.58: August 25, 2000
Greg: Fixed a crash bug that happens if you create a PS2 material. The
bug was caused by the modifications to the texture pane to replace
the NoMipMap and Resize buttons with a single NoLOD button. For some
reason, the PS2 material uses a separate dialog template for its
texture pane which is the same as the dialog template for the
normal material. Since the PS2 version of the template was not updated,
the code would crash when initializing the NoLOD button.
Version 1.0.4.57: August 18, 2000
Andre: Fixed the loading of version 4 ParameterBlocks so that the value
for Stage1MappingType is correct.
Version 1.0.4.56: August 16,2000
Greg: Removed the texture flags and buttons for No-Mipmapping and enable
resizing. These are all lumped into the setting for No-LOD now.
The GameMtl still has the entries in its parameter block for
No-Mipmapping and Resize and I use the No-Mipmap setting to set
the initial state of the No-LOD flag... This also required a flag
in GameMtl indicating that the conversion had been done. Ug... :-)
Version 1.0.4.55: August 6, 2000
Greg: Added new colliison type: camera. In renegade we have some physically
collideable meshes which the camera should not collide with so I had
to make a separate flag for camera collision. When the appdata chunk
is first converted to the new version, the camera collision flag is
set to the same setting as the current state of physical collision.
Added light-glare geometry type. This currently only exports the
position of the pivot point of the max object. It will be used to
indicate where there should be fancy light glare effects in the level
Added NoLOD option to textures in the W3D material. This setting will
be used on textures which should not scale down even when texture
reduction is being used.
Fixed serious bug in the parameter block description for the W3D
material plugin (GameMtl.cpp)
Version 1.0.4.54: July 13, 2000
Greg: Fixed a bug related to user-defined origins not working when they
are rotate or moved from 0,0,0.
Version 1.0.4.53: July 12, 2000
Andre: Added support for a different mappers on stage 0/1 of the Vertex
Material. Added support for the new silhouette mapper type.
These changes can be found in the VertexMaterial panel in the
W3d material editor.
Version 1.0.4.52: May 30, 2000
Greg: Added support for Max's multiple mapping channels. This can be
found in the VertexMaterial panel in the W3d material editor.
Version 1.0.4.51: May 22, 2000
Greg: Added AABTree exporting so that we don't have to generate AABTrees
at run-time. This is controlled by the "Optimize Collision Detection"
checkbox on the exporter options dialog box.
Added prefix and suffix features to the naming tool.
Added detatch vertices feature to the skin modifier.
Version 1.0.4.50: May 8, 2000
Andre: Added a new MAX Script extension: wwInputBox
This is a generic way of getting user input in a Windows-like
manner (as opposed to typing it in the Listener window as
MAX wants to force you to do).
Version 1.0.4.49: May 2, 2000
Greg: Fixed a bug in vchannel.cpp. Was writing out garbage animation
channels which would crash wdump.
Version 1.0.4.48: May 1, 2000
Greg: Changed the way skins are exported so that their vertices are
sorted with respect to the bone they are attached to. Also
made it so vertices are secondarily sorted by vertex material
(this means that non-skinned meshes will sort by vertex
material only.)
Version 1.0.4.47: April 19 2000
Greg: Added a new geometry option for "shatterable" objects. Wrote
a new W3DAppData2Struct which replaces the old AppData1Struct.
Whenever the old format app data is encountered, a new one
is created to replace it. This new app data chunk has more
space in it for future expansion.
Also fixed a crash bug in the skin modifier related to deleting
bones from the space warp.
Version 1.0.4.46: March 28, 2000
Greg: Added "Transform Nodes" to the collection export. We already had
"Placeholder" objects which were signified by a '~' after the
name. Now we have "Transform Nodes" which are signified by a '*'
after the name. Transform Nodes instruct one of the Renegade tools
to merge another W3D collection into the file at a given transform.
The purpose was to allow us to lightmap certain building interiors
only once and then merge them into many levels...
Version 1.0.4.45: March 8, 2000
Andre: Changed the Is_Origin() test to check for hidden nodes. If a
node is hidden, it will not be accepted as an origin. This
means that hiding an LOD prevents it from being exported (as
you would expect).
Version unchanged: early March
Andre: Fixed a couple of crash bugs related to animation exporting.
Version 1.0.4.43: February 29, 2000
Greg: Fixed a bug which caused all meshes marked to cast shadows to
not get texture coordinates.
Fixed meshsave.cpp to detect and properly handle mirrored meshes.
Version 1.0.4.42: January 24, 2000
Lytle: Added Playstation 2 material support, including converting W3D
materials to PS2 materials. Added support for vertex colors and
vertex alpha to exist concurrently.
Version 1.0.4.41: January 13, 2000
Andre: Fixed a nasty memory overwriting bug in MeshConnectionsClass
that only reared its head under very unique circumstances.
It was a copy/paste bug that would lead to writing a W3D
file with incorrect data. It would manifest itself by crashing
the viewer (and potentially the game engines) when trying to
load the file.
Version 1.0.4.40: December 16, 1999
Ian: Added 'Export Utilites' group to W3D Utility panel and added a
'Export with Std Mtls' button to this group. This button will
first convert all W3D materials in the scene to standard
materials, then call the export feature, then, after export,
convert materials back to W3D materials. The purpose of this
utility is to make it possible to export W3D material attributes
to third party file formats (eg. Lightscape Preparation files).
Version 1.0.4.39: November 15, 1999
Andre: Changed the mesh LOD naming convention so that we use numbers
that correspond to the LOD number (highest-to-lowest) instead
of letters that went from lowest-to-highest.
Version 1.0.4.38: November 12, 1999
Greg: Updated MeshConnections class and the hmodel chunk definitions
in w3d_file class to not treat shadow meshes as a different type
of mesh.
Version 1.0.4.37: November 11, 1999
Greg: Removed the GEOMETRY_TYPE_SHADOW settings and UI. Added a
EXPORT_CAST_SHADOW flag. This basically means that rather than
shadow casting being a completely different "type" of mesh it
is now an option on any mesh. This required some tweaking
of the AppData structure we're saving and to the w3dutil code.
Version 1.0.4.35: November 3, 1999
Andre: Exposed another script extension, called "wwDuplicateSkinWSM".
This extension allows the SceneSetup script to copy bone
information from the base object's skin WSM to the LODs.
Meshes are still unaffected, since the artist will be munging
the meshes to reduce their poly counts.
Version 1.0.4.34: November 2, 1999
Andre: Exposed two new script extensions, named "wwCopySkinInfo" and
"wwFindSkinNode". These extensions allow the SceneSetup script
to copy the skin/vertex/bone binding information from the base
model to the LOD and Damage models.
Version 1.0.4.33: October 18, 1999
Andre: Merged WWScript.dlx into the exporter, so now WWScript is
unnessesary and should be deleted. The code in that DLX was
ported from MFC to Win32 code during the merge. GetW3DAppData0
and GetW3DAppData1 are no longer exported from the DLE.
Version 1.0.4.32: October 11, 1999
Andre: Correct NULL object handling was implemented when exporting HLODs.
NULL object chunks are only written when using the old-style LOD
setup (one per file), otherwise the name "NULL" is put in the HLOD
and no NULL object chunk is written.
Version 1.0.4.31: October 5, 1999
Andre: Fixed a bug in MeshBuilder where a division by zero occurred if the
extents of a triangle was zero in one dimension.
Version 1.0.4.30: October 1, 1999
Andre: - Added support for the "suppressPrompts" flag during export. If
Max passes in a TRUE value, we will go with the previous export
settings instead of showing the export options dialog. This makes
non-interactive batch exporting possible.
- Moved W3dExportOptionsStruct from w3ddlg.h to w3dutil.h so that
WWScript can access it easily.
Version 1.0.4.29: September 27, 1999
Andre: - Fixed a skin bug that occurred in LOD exporting when a vertex in a
skin was not bound to a bone (it would be exported in unmodified
coordinates, creating a "pop").
- Strip off any trailing ".%d" or "." from a name in Set_W3D_Name
(as opposed to just ".%d").
- If the artist sets up damage animations, then the animation on
the base model is no longer exported. (non-damage animations should
still be created in separate files)
- Exporting 2 more symbols from the DLL (GetW3DAppData0 and
GetW3DAppData1). These functions are used by the MAXScript extension
DLL (WWScript.dlx) to copy AppData from one node to another.
Version 1.0.4.28: September 23, 1999
Andre: Fixed a bug in LOD exporting when the base object wasn't centered
at the origin. Added support for placing damage models in the scene.
Renamed "Generate LOD extensions" to "Generate extensions" since
the same extensions are used for damage. Added a "Damage Region"
spinner to the W3D Tools panel. With this spinner you can mark
bones as being part of a given damage region (0 to 15, -1 means
not part of a damage region).
Version 1.0.4.27: September 17, 1999
Greg: Added degenerate triangle removal to MeshBuilderClass.
Version 1.0.4.26: September 17, 1999
Andre: Modified the exporting code to allow artists to define all LODs of
an object in one MAX file. The old way of creating LODs is still
supported so that old art assets are still usable. Added a
"Generate LOD extensions" button to the W3D Tools panel to make
the Origin naming convention less painful.
Version 1.0.4.25: August 21, 1999
Greg: Fixed a bug in Export_Geometry. While exporting skins, one line of
code was referring to the list of normal meshes rather than the list
of skins. When you do an export with only a skin and no meshes, this
causes an access violation.
Version 1.0.4.24: July 27, 1999
Greg: Changed the Hide/Unhide by W3D type buttons into "Select by W3D Type"
buttons. This should be more useable. Also, added select alpha meshes,
select physical, projectile and vis collision meshes.
Added a material naming tool.
Version 1.0.4.23: July 9, 1999
Pat: Changed the default behavior of the collection naming tool to
be 'affect selected' rather than 'affect all'
Version 1.0.4.22: July 7, 1999
Pat: The export code doesn't export the DCG array if all vertex colors
are white (1, 1, 1), however this was a problem when using the
new Mesh Deformer, so I added a check during export to see if
the Deformer was modifying vertex colors. Also modified the
hierarchy export code so it will resize its internal array if
the number of nodes is greater than 512.
Version 1.0.4.21: July 1, 1999
Pat: Added code to optimze the between-mesh smoothing and added a new
button to the export dialog that allows the user to turn this
smoothing feature on/off. Also added displacement maps to the
W3D material, however due to a bug in the NURBS Mesher modifier,
we decided not to expose the functionality in UI at this time.
Version 1.0.4.20: June 24, 1999
Pat: Added code to apply smoothing groups over mesh boundaries. More
work was done on the obj-space mesh deform modifier including save/load,
export, undo, and vertex-alpha support. We fixed a bug where the ErrorClass
object that was used during exception handling was using and freeing a
previously freed pointer. Added a new panel to the material types for
Commando surface types.
Version 1.0.4.19: June 14, 1999
Greg: Added the VAlpha checkbox to the W3D utility panel. Checking this
causes the exporter to convert vertex colors into alpha values and put
them in all passes that are using alpha blending. This might be a temporary
solution; I'm thinking we need to extend the Utility panel (and the AppData
structure that we are saving) to allow for more flexible control over vertex
alpha, vertex color, etc.
Version 1.0.4.18: May 27, 1999
Greg: Fixed a bug in the code which handles loading a hierarchy tree from another
W3D file. Made the W3D utility panel support multiple selection.
Pat: Added the initial mesh deform object space modifier. Currently doesn't
export the data.
Version 1.0.4.17: April 9, 1999
Greg: Fixed a bug related to exporting a mesh with zero vertices. Exporter will
throw an exception which pops up a message box indicating the name of the
mesh. Made the collision boxes behave the same way as meshes when one is
exported with geometry only - it takes on the name of the file. Whew this
part of the exporter code is getting uuuuuugly...
Version 1.0.4.16: April 6, 1999
Greg: Fixed a bug related to the storing of the default export options. If the
user exported a model which uses the hierarchy from another model and then
moves the Max file, the next export would crash Max when the exporter couldn't
find the w3d file which contains the hierarchy.
Version 1.0.4.15: Mar 18, 1999
Greg: Fixed a bug in the AABox export. Was using the wrong coordinate system for
the box. AABoxes actually seem to be of very limited use. Possibly only
useful as an approximation of a cylinder centered at 0,0,0 in object space
(but moved anywhere on the z-axis) and only for objects that *only* rotate
about the z-axis. (characters) Ug.
Version 1.0.4.14: Mar 16, 1999
Greg: Made meshes that are marked as AABox or OBBox export a W3D_CHUNK_BOX instead
of a mesh. The runtime engine can test collision with a box in about the same
amount of time it takes to check a single triangle... so one box is much faster
than a 12 triangle mesh :) These boxes are only for collision detection so
they only export a color, no other rendering information.
Version 1.0.4.13: Mar 11, 1999
Greg: Fixed a bug in the collection exporter. Needed to put the entire name
of the render object into the sub object chunk.
Version 1.0.4.12: Mar 10, 1999
Naty: Fixed minor bug with start/end animation frames in export dialog.
Version 1.0.4.11: Mar 4, 1999
Naty: Added "Camera Oriented" mesh type (and changed the camera aligned button
to read "Camera Parallel"). Export options are now saved in the MAX file
(hierarchy file paths are saved in a relative form).
Version 1,0,4,10: Mar 3, 1999
Greg: Modified so that collections are not exported when there is only a single
mesh and forced that mesh to use the name of the file.
Changed w3d_file.h so that meshes have a "container name" instead of
a "hierarchy model name" and set the container name when a collection is exported
Version 1,0,4,9: Mar 3, 1999
Naty: New Shader (took out colormaks, fogfunc, new dialog and preset system)
Added alphatest support, added Linear offset mapper and mapper argument
string support
Version 1,0,4,8: Feb 9, 1999
Greg: Added the ZNormals option for forcing the normals of a mesh to be 0,0,1
Version 1,0,4,7: Feb 8, 1999
Greg: Fixed 2 bugs in the skin code. Added code to scan the materials used
by a mesh and discard un-used ones.
Naty: Added 'Alpha-Bitmap' button to the texture dialog, added new shader presets
Version 1,0,4,8: Feb 15, 1999
Greg: Improved the strip generation algorithm. Now actually turns a cube into 6
strips instead of 12 individual triangles. Still needs work though...

View file

@ -0,0 +1,156 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Max2W3d *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/colboxsave.cpp $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 12/06/00 4:06p $*
* *
* $Revision:: 7 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "colboxsave.h"
#include "w3d_file.h"
#include "util.h"
#include "w3dappdata.h"
#include "errclass.h"
CollisionBoxSaveClass::CollisionBoxSaveClass
(
char * mesh_name,
char * container_name,
INode * inode,
Matrix3 & exportspace,
TimeValue curtime,
Progress_Meter_Class & meter
)
{
//////////////////////////////////////////////////////////////////////
// wrestle the mesh out of 3dsMAX
//////////////////////////////////////////////////////////////////////
Object * obj = inode->EvalWorldState(curtime).obj;
TriObject * tri = (TriObject *)obj->ConvertToType(curtime, triObjectClassID);
Mesh mesh = tri->mesh;
DWORD wirecolor = inode->GetWireColor();
if (mesh.getNumVerts() == 0) {
throw ErrorClass("Mesh %s has no vertices!\n",mesh_name);
}
//////////////////////////////////////////////////////////////////////
// Generate the AABox or OBBox data.
//////////////////////////////////////////////////////////////////////
memset(&BoxData,0,sizeof(BoxData));
BoxData.Version = W3D_BOX_CURRENT_VERSION;
if ((container_name != NULL) && (strlen(container_name) > 0)) {
strcpy(BoxData.Name,container_name);
strcat(BoxData.Name,".");
}
strcat(BoxData.Name,mesh_name);
BoxData.Attributes = 0;
if (Is_Collision_AABox(inode)) {
BoxData.Attributes |= W3D_BOX_ATTRIBUTE_ALIGNED;
} else {
BoxData.Attributes |= W3D_BOX_ATTRIBUTE_ORIENTED;
}
if (Is_Physical_Collision(inode)) {
BoxData.Attributes |= W3D_BOX_ATTRIBTUE_COLLISION_TYPE_PHYSICAL;
}
if (Is_Projectile_Collision(inode)) {
BoxData.Attributes |= W3D_BOX_ATTRIBTUE_COLLISION_TYPE_PROJECTILE;
}
if (Is_Vis_Collision(inode)) {
BoxData.Attributes |= W3D_BOX_ATTRIBTUE_COLLISION_TYPE_VIS;
}
if (Is_Camera_Collision(inode)) {
BoxData.Attributes |= W3D_BOX_ATTRIBTUE_COLLISION_TYPE_CAMERA;
}
if (Is_Vehicle_Collision(inode)) {
BoxData.Attributes |= W3D_BOX_ATTRIBTUE_COLLISION_TYPE_VEHICLE;
}
BoxData.Color.R = GetRValue(wirecolor);
BoxData.Color.G = GetGValue(wirecolor);
BoxData.Color.B = GetBValue(wirecolor);
// if this is an axis-aligned box, then use the world coord system
if (Is_Collision_AABox(inode)) {
exportspace.NoRot();
}
// Transform the mesh into the desired coordinate system
Matrix3 node_matrix = inode->GetObjectTM(curtime);
Matrix3 offset_matrix = node_matrix * Inverse(exportspace);
int ivert;
for (ivert = 0; ivert < mesh.getNumVerts (); ++ivert) {
mesh.verts[ivert] = mesh.verts[ivert] * offset_matrix;
}
// Find the center and extent of the box.
Point3 min_point = mesh.verts[0];
Point3 max_point = mesh.verts[1];
for (ivert=0; ivert < mesh.getNumVerts(); ++ivert) {
if (mesh.verts[ivert].x < min_point.x) min_point.x = mesh.verts[ivert].x;
if (mesh.verts[ivert].y < min_point.y) min_point.y = mesh.verts[ivert].y;
if (mesh.verts[ivert].z < min_point.z) min_point.z = mesh.verts[ivert].z;
if (mesh.verts[ivert].x > max_point.x) max_point.x = mesh.verts[ivert].x;
if (mesh.verts[ivert].y > max_point.y) max_point.y = mesh.verts[ivert].y;
if (mesh.verts[ivert].z > max_point.z) max_point.z = mesh.verts[ivert].z;
}
Point3 center = (max_point + min_point) / 2.0f;
Point3 extent = (max_point - min_point) / 2.0f;
BoxData.Center.X = center.x;
BoxData.Center.Y = center.y;
BoxData.Center.Z = center.z;
BoxData.Extent.X = extent.x;
BoxData.Extent.Y = extent.y;
BoxData.Extent.Z = extent.z;
}
int CollisionBoxSaveClass::Write_To_File(ChunkSaveClass & csave)
{
csave.Begin_Chunk(W3D_CHUNK_BOX);
csave.Write(&BoxData,sizeof(BoxData));
csave.End_Chunk();
return 0;
}

View file

@ -0,0 +1,84 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Max2W3d *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/colboxsave.h $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 3/16/99 8:37a $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef COLBOXSAVE_H
#define COLBOXSAVE_H
#include <Max.h>
#include "w3d_file.h"
#include "chunkio.h"
#include "progress.h"
/*******************************************************************************************
**
** CollisionBoxSaveClass - Create an AABox or an OBBox from a Max mesh (typically the
** artist should use a 'box' to generate this. In any case, we're just using the bounding
** box).
**
*******************************************************************************************/
class CollisionBoxSaveClass
{
public:
enum {
EX_UNKNOWN = 0, // exception error codes
EX_CANCEL = 1
};
CollisionBoxSaveClass( char * mesh_name,
char * container_name,
INode * inode,
Matrix3 & exportspace,
TimeValue curtime,
Progress_Meter_Class & meter);
int Write_To_File(ChunkSaveClass & csave);
private:
W3dBoxStruct BoxData; // contains same information as the W3dOBBoxStruct
};
#endif //COLBOXSAVE_H

View file

@ -0,0 +1,97 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Max2W3D *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/dazzlesave.cpp $*
* *
* Original Author:: Greg Hjelstrom *
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 9/21/00 4:14p $*
* *
* $Revision:: 1 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "dazzlesave.h"
#include "w3d_file.h"
#include "util.h"
#include "w3dappdata.h"
#include "errclass.h"
DazzleSaveClass::DazzleSaveClass
(
char * mesh_name,
char * container_name,
INode * inode,
Matrix3 & exportspace,
TimeValue curtime,
Progress_Meter_Class & meter
)
{
assert(mesh_name != NULL);
assert(container_name != NULL);
/*
** Set up the render object name
*/
memset(&W3DName,0,sizeof(W3DName));
if ((container_name != NULL) && (strlen(container_name) > 0)) {
strcpy(W3DName,container_name);
strcat(W3DName,".");
}
strcat(W3DName,mesh_name);
/*
** Dig the dazzle-type out of the appropriate App-Data chunk on
** the INode.
*/
W3DDazzleAppDataStruct * dazzle_data = W3DDazzleAppDataStruct::Get_App_Data(inode);
strncpy(DazzleType,dazzle_data->DazzleType,sizeof(DazzleType));
}
int DazzleSaveClass::Write_To_File(ChunkSaveClass & csave)
{
csave.Begin_Chunk(W3D_CHUNK_DAZZLE);
csave.Begin_Chunk(W3D_CHUNK_DAZZLE_NAME);
csave.Write(W3DName,strlen(W3DName) + 1);
csave.End_Chunk();
csave.Begin_Chunk(W3D_CHUNK_DAZZLE_TYPENAME);
csave.Write(DazzleType,strlen(DazzleType) + 1);
csave.End_Chunk();
csave.End_Chunk();
return 0;
}

View file

@ -0,0 +1,90 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Max2W3D *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/dazzlesave.h $*
* *
* Original Author:: Greg Hjelstrom *
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 9/21/00 4:09p $*
* *
* $Revision:: 1 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef DAZZLESAVE_H
#define DAZZLESAVE_H
#include <Max.h>
#include "w3d_file.h"
#include "chunkio.h"
#include "progress.h"
/*******************************************************************************************
**
** DazzleSaveClass - Create a Dazzle definition from an INode. Basically, we just save
** the transform and the dazzle type that the user has selected.
**
*******************************************************************************************/
class DazzleSaveClass
{
public:
enum {
EX_UNKNOWN = 0, // exception error codes
EX_CANCEL = 1
};
DazzleSaveClass( char * mesh_name,
char * container_name,
INode * inode,
Matrix3 & exportspace,
TimeValue curtime,
Progress_Meter_Class & meter);
int Write_To_File(ChunkSaveClass & csave);
private:
char W3DName[128];
char DazzleType[128];
};
#endif //DAZZLESAVE_H

View file

@ -0,0 +1,206 @@
/*
** Command & Conquer Generals(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/>.
*/
/* $Header: /Commando/Code/Tools/max2w3d/dllmain.cpp 8 7/24/01 5:11p Moumine_ballo $ */
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando / G *
* *
* File Name : DLLMAIN.CPP *
* *
* Programmer : Greg Hjelstrom *
* *
* Start Date : 06/09/97 *
* *
* Last Update : June 9, 1997 [GH] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* DllMain -- Entry point for the dll *
* LibDescription -- Returns description of this library *
* LibNumberClasses -- Returns number of classes in this library *
* LibClassDesc -- Returns a ClassDesc for the specified class *
* LibVersion -- Returns the version number of this library *
* GetString -- Gets a string out of the resources *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include <stdio.h>
#include <Max.h>
#include "dllmain.h"
#include "w3ddesc.h"
#include "w3dexp.h"
#include "w3dutil.h"
#include "skin.h"
#include "gamemtl.h"
#include "gamemaps.h"
#include "MeshDeform.H"
#include "AlphaModifier.h"
#include "gridsnapmodifier.h"
#include "resource.h"
#define DLLEXPORT __declspec(dllexport)
/*****************************************************************************
* Globals
*****************************************************************************/
HINSTANCE AppInstance = NULL;
static int ControlsInit = FALSE;
static W3dClassDesc W3d_Export_Class_Descriptor;
/***********************************************************************************************
* DllMain -- Entry point for the dll *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 06/09/1997 GH : Created. *
*=============================================================================================*/
BOOL WINAPI DllMain(HINSTANCE hinstDLL,ULONG /*fdwReason*/,LPVOID /*lpvReserved*/)
{
AppInstance = hinstDLL;
if ( !ControlsInit )
{
ControlsInit = TRUE;
InitCustomControls(AppInstance);
InitCommonControls();
}
return TRUE;
}
/***********************************************************************************************
* LibDescription -- Returns description of this library *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 06/09/1997 GH : Created. *
*=============================================================================================*/
DLLEXPORT const TCHAR * LibDescription()
{
return Get_String(IDS_LIB_DESCRIPTION);
}
/***********************************************************************************************
* LibNumberClasses -- Returns number of classes in this library *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 06/09/1997 GH : Created. *
*=============================================================================================*/
DLLEXPORT int LibNumberClasses()
{
return 9; //Moumine 7/24/2001 4:38:27 PM was 10. Removed Mesh_Deformation(#6)
}
/***********************************************************************************************
* LibClassDesc -- Returns a ClassDesc for the specified class *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 06/09/1997 GH : Created. *
*=============================================================================================*/
DLLEXPORT ClassDesc * LibClassDesc(int i)
{
switch(i)
{
case 0: return & W3d_Export_Class_Descriptor; break;
case 1: return Get_W3D_Utility_Desc(); break;
case 2: return Get_Skin_Obj_Desc(); break;
case 3: return Get_Skin_Mod_Desc(); break;
case 4: return Get_Game_Material_Desc(); break;
case 5: return Get_Game_Maps_Desc(); break;
case 6: return Get_PS2_Game_Material_Desc(); break;
case 7: return Get_PS2_Material_Conversion(); break;
case 8: return Get_Alpha_Desc(); break;
//case 6: return Get_Mesh_Deform_Desc(); break;
//Moumine 7/24/2001 4:33:52 PM Removed #6 and shifted up instead of returning NULL
// NULL causes a crash in "File->Summary info->Plug-in ifo..."
default: return NULL; break;
}
}
/***********************************************************************************************
* LibVersion -- Returns the version number of this library *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 06/09/1997 GH : Created. *
*=============================================================================================*/
DLLEXPORT ULONG LibVersion()
{
return VERSION_3DSMAX;
}
/***********************************************************************************************
* Get_String -- Gets a string out of the resources *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 06/09/1997 GH : Created. *
*=============================================================================================*/
TCHAR * Get_String( int id )
{
static TCHAR buf[256];
if (AppInstance)
return LoadString(AppInstance, id, buf, sizeof(buf)) ? buf : NULL;
return NULL;
}

View file

@ -0,0 +1,51 @@
/*
** Command & Conquer Generals(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/>.
*/
/* $Header: /Commando/Code/Tools/max2w3d/dllmain.h 4 10/28/97 6:08p Greg_h $ */
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando / G *
* *
* File Name : DLLMAIN.H *
* *
* Programmer : Greg Hjelstrom *
* *
* Start Date : 06/09/97 *
* *
* Last Update : June 9, 1997 [GH] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef DLLMAIN_H
#define DLLMAIN_H
#include <windows.h>
extern HINSTANCE AppInstance;
#define MAX_STRING_LENGTH 256
#define MAX_PATH_LENGTH _MAX_PATH
TCHAR * Get_String(int id);
#endif /*DLLMAIN_H*/

View file

@ -0,0 +1,171 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Max2W3d *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/exportlog.cpp $*
* *
* Original Author:: Greg Hjelstrom *
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 11/07/00 3:16p $*
* *
* $Revision:: 3 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* ExportLog::Init -- Initialize the export logging system *
* ExportLog::Shutdown -- Shutdown the export logging system *
* ExportLog::printf -- Print a string to the log window *
* ExportLog::rprintf -- Print a string over the last line printed *
* ExportLog::updatebar -- Set the position of the progress bar *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "exportlog.h"
#include "logdlg.h"
#include <assert.h>
/*
** Static variables
*/
LogDataDialogClass * _LogDialog = NULL;
/*
**
** ExportLog implementation. Note, this is a class which only contains static functions.
**
*/
/***********************************************************************************************
* ExportLog::Init -- Initialize the export logging system *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 10/30/2000 gth : Created. *
*=============================================================================================*/
void ExportLog::Init(HWND parent)
{
assert(_LogDialog == NULL);
_LogDialog = new LogDataDialogClass(parent);
}
/***********************************************************************************************
* ExportLog::Shutdown -- Shutdown the export logging system *
* *
* INPUT: *
* wait_for_ok - should we wait for the user to press OK on the dialog? *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 10/30/2000 gth : Created. *
*=============================================================================================*/
void ExportLog::Shutdown(bool wait_for_ok)
{
if (_LogDialog != NULL) {
if (wait_for_ok) {
_LogDialog->Wait_OK();
}
delete _LogDialog;
_LogDialog = NULL;
}
}
/***********************************************************************************************
* ExportLog::printf -- Print a string to the log window *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 10/30/2000 gth : Created. *
*=============================================================================================*/
void ExportLog::printf(char * format, ...)
{
if (_LogDialog != NULL) {
va_list arguments;
va_start(arguments, format);
_LogDialog->printf(format,arguments);
}
}
/***********************************************************************************************
* ExportLog::rprintf -- Print a string over the last line printed *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 10/30/2000 gth : Created. *
*=============================================================================================*/
void ExportLog::rprintf(char * format, ...)
{
if (_LogDialog != NULL) {
va_list arguments;
va_start(arguments, format);
_LogDialog->rprintf(format,arguments);
}
}
/***********************************************************************************************
* ExportLog::updatebar -- Set the position of the progress bar *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 10/30/2000 gth : Created. *
*=============================================================================================*/
void ExportLog::updatebar(float position, float total)
{
if (_LogDialog != NULL) {
_LogDialog->updatebar(position,total);
}
}

View file

@ -0,0 +1,62 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Max2W3d *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/exportlog.h $*
* *
* Original Author:: Greg Hjelstrom *
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 11/07/00 3:18p $*
* *
* $Revision:: 3 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef EXPORTLOG_H
#define EXPORTLOG_H
#include <windows.h>
/**
** ExportLog
** This is an interface to the export log dialog.
*/
class ExportLog
{
public:
static void Init(HWND parent);
static void Shutdown(bool wait_for_ok);
static void printf(char *, ...);
static void rprintf(char *, ...);
static void updatebar(float position, float total);
};
#endif //EXPORTLOG_H

View file

@ -0,0 +1,233 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Max2W3d *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/floaterdialog.cpp $*
* *
* Original Author:: Greg Hjelstrom *
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 10/30/00 2:58p $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* FloaterDialogClass::FloaterDialogClass -- Constructor *
* FloaterDialogClass::~FloaterDialogClass -- Destructor *
* FloaterDialogClass::Is_Created -- test whether the floater has already been created *
* FloaterDialogClass::Create -- create the window *
* FloaterDialogClass::Dialog_Proc -- Dialog Proc for the floater *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "floaterdialog.h"
#include "dllmain.h"
#include "resource.h"
#include <Max.h>
/**********************************************************************************************
**
** FloaterDialogClass Implementation
**
**********************************************************************************************/
BOOL CALLBACK _floater_dialog_proc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
if (message == WM_INITDIALOG) {
FloaterDialogClass * floater = (FloaterDialogClass *)lParam;
::SetProp(hwnd,"FloaterDialogClass",(HANDLE)floater);
}
FloaterDialogClass * floater = (FloaterDialogClass *)::GetProp(hwnd,"FloaterDialogClass");
if (message == WM_DESTROY) {
::RemoveProp(hwnd,"FloaterDialogClass");
}
if (floater) {
return floater->Dialog_Proc(hwnd,message,wParam,lParam);
} else {
return FALSE;
}
}
/***********************************************************************************************
* FloaterDialogClass::FloaterDialogClass -- Constructor *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
*=============================================================================================*/
FloaterDialogClass::FloaterDialogClass(void) :
Hwnd(NULL),
ChildDialogTemplateID(-1),
ChildDialogProc(NULL)
{
}
/***********************************************************************************************
* FloaterDialogClass::~FloaterDialogClass -- Destructor *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
*=============================================================================================*/
FloaterDialogClass::~FloaterDialogClass(void)
{
if (Hwnd != NULL) {
::DestroyWindow(Hwnd);
}
}
/***********************************************************************************************
* FloaterDialogClass::Is_Created -- test whether the floater has already been created *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 10/11/2000 gth : Created. *
*=============================================================================================*/
bool FloaterDialogClass::Is_Created(void)
{
return (Hwnd != NULL);
}
/***********************************************************************************************
* FloaterDialogClass::Create -- create the window *
* *
* This function will return automatically if the floater has been created already. *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 10/11/2000 gth : Created. *
*=============================================================================================*/
void FloaterDialogClass::Create(Interface * ip, int child_dlg_id, DLGPROC child_dlg_proc)
{
/*
** Don't create multiple ones
*/
if (Is_Created()) {
return;
}
/*
** Copy down the data needed to create the child window later
*/
ChildDialogTemplateID = child_dlg_id;
ChildDialogProc = child_dlg_proc;
/*
** Create the dialog box
*/
Hwnd = CreateDialogParam(
AppInstance,
MAKEINTRESOURCE(IDD_W3DUTILITY_FLOATER_DIALOG),
::GetCOREInterface()->GetMAXHWnd(),
(DLGPROC) _floater_dialog_proc,
(LPARAM) this
);
::GetCOREInterface()->RegisterDlgWnd(Hwnd);
}
/***********************************************************************************************
* FloaterDialogClass::Dialog_Proc -- Dialog Proc for the floater *
* *
* The only thing we need to do here is to create the child dialog and resize ourselves to *
* contain it. *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 10/11/2000 gth : Created. *
*=============================================================================================*/
bool FloaterDialogClass::Dialog_Proc(HWND hWnd,UINT message,WPARAM wParam,LPARAM)
{
switch (message ) {
case WM_INITDIALOG:
{
HWND childhwnd = CreateDialogParam(
AppInstance,
MAKEINTRESOURCE(ChildDialogTemplateID),
hWnd,
ChildDialogProc,
0
);
if (childhwnd!= NULL) {
RECT rect;
LONG style = ::GetWindowLong(hWnd,GWL_STYLE);
::GetWindowRect(childhwnd,&rect);
::AdjustWindowRect(&rect,style,FALSE);
::SetWindowPos(hWnd,NULL,0,0,rect.right - rect.left,rect.bottom - rect.top,SWP_NOZORDER|SWP_NOMOVE);
::SetWindowPos(childhwnd,NULL,0,0,0,0,SWP_NOZORDER|SWP_NOSIZE|SWP_SHOWWINDOW);
}
}
return 1;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDCANCEL:
DestroyWindow(Hwnd);
break;
}
return 1;
case WM_DESTROY:
::GetCOREInterface()->UnRegisterDlgWnd(Hwnd);
Hwnd = NULL;
break;
}
return 0;
}

View file

@ -0,0 +1,75 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Max2W3d *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/floaterdialog.h $*
* *
* Original Author:: Greg Hjelstrom *
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 10/11/00 11:23a $*
* *
* $Revision:: 1 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef FLOATERDIALOG_H
#define FLOATERDIALOG_H
#include <windows.h>
class Interface;
/**
** FloaterDialogClass
** This class is designed to be used by modeless dialog boxes. See w3dutil.cpp for an
** example of how to embed an arbitrary dialog template and dialog proc into a floating
** window.
*/
class FloaterDialogClass
{
public:
FloaterDialogClass(void);
~FloaterDialogClass();
bool Is_Created(void);
void Create(Interface * ip, int child_dialog_id, DLGPROC child_dlg_proc);
bool Dialog_Proc(HWND hWnd,UINT message,WPARAM wParam,LPARAM);
private:
HWND Hwnd;
int ChildDialogTemplateID;
DLGPROC ChildDialogProc;
};
#endif //FLOATERDIALOG_H

View file

@ -0,0 +1,287 @@
/*
** Command & Conquer Generals(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/>.
*/
/* $Header: /Commando/Code/Tools/max2w3d/gamemaps.cpp 5 10/28/97 6:08p Greg_h $ */
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando / G 3D engine *
* *
* File Name : GAMEMAPS.CPP *
* *
* Programmer : Greg Hjelstrom *
* *
* Start Date : 06/26/97 *
* *
* Last Update : June 26, 1997 [GH] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* GameMapsClass::ClassID -- Returns the ClassID for GameMapsClass *
* GameMapsClass::AssignController -- Assigns a controller to one of the Sub-Anims *
* GameMapsClass::NotifyRefChanged -- Max is notifying GameMapsClass that a reference has cha*
* GameMapsClass::Clone -- Create a clone of the GameMapsClass *
* GameMapsClass::Save -- Saves the GameMapsClass data into a MAX file *
* GameMapsClass::Load -- Loads GameMapsClass data from a MAX file *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "gamemaps.h"
/*****************************************************************
*
* Chunk ID's for saving data in the MAX file.
*
*****************************************************************/
#define GAMEMAPS_ONOFF_CHUNK 0x0000
#define GAMEMAPS_AMT0_CHUNK 0x0001
#define GAMEMAPS_AMT1_CHUNK 0x0002
#define GAMEMAPS_AMT2_CHUNK 0x0003
#define GAMEMAPS_AMT3_CHUNK 0x0004
#define GAMEMAPS_AMT4_CHUNK 0x0005
#define GAMEMAPS_AMT5_CHUNK 0x0006
#define GAMEMAPS_AMT6_CHUNK 0x0007
#define GAMEMAPS_AMT7_CHUNK 0x0008
#define GAMEMAPS_AMT8_CHUNK 0x0009
#define GAMEMAPS_AMT9_CHUNK 0x000A
#define GAMEMAPS_AMTA_CHUNK 0x000B
/*****************************************************************
*
* A PostLoadCallback which does nothing...
*
*****************************************************************/
class GameMapsPostLoad : public PostLoadCallback
{
public:
GameMapsClass *tm;
GameMapsPostLoad(GameMapsClass *b) {tm=b;}
void proc(ILoad *iload) { delete this; }
};
/*****************************************************************
*
* GameMapsClass Class Desriptor
*
*****************************************************************/
static Class_ID _GameMapsClassID(0x36d23f7b, 0x79ce63e1);
class GameMapsClassDesc : public ClassDesc
{
public:
int IsPublic() { return 0; }
void * Create(BOOL loading) { return new GameMapsClass(NULL); }
const TCHAR * ClassName() { return _T("GameMaps"); }
SClass_ID SuperClassID() { return REF_MAKER_CLASS_ID; }
Class_ID ClassID() { return _GameMapsClassID; }
const TCHAR* Category() { return _T(""); }
};
static GameMapsClassDesc _GameMapsCD;
ClassDesc * Get_Game_Maps_Desc() { return &_GameMapsCD; }
/***********************************************************************************************
* GameMapsClass::ClassID -- Returns the ClassID for GameMapsClass *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 06/26/1997 GH : Created. *
*=============================================================================================*/
Class_ID GameMapsClass::ClassID()
{
return _GameMapsClassID;
}
/***********************************************************************************************
* GameMapsClass::AssignController -- Assigns a controller to one of the Sub-Anims *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 06/26/1997 GH : Created. *
*=============================================================================================*/
BOOL GameMapsClass::AssignController(Animatable *control,int subAnim)
{
ReplaceReference(SubNumToRefNum(subAnim),(ReferenceTarget *)control);
return TRUE;
}
/***********************************************************************************************
* GameMapsClass::NotifyRefChanged -- Max is notifying GameMapsClass that a reference has chan *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 06/26/1997 GH : Created. *
*=============================================================================================*/
RefResult GameMapsClass::NotifyRefChanged
(
Interval changeInt,
RefTargetHandle hTarget,
PartID & partID,
RefMessage message
)
{
switch (message) {
case REFMSG_GET_PARAM_DIM: {
GetParamDim *gpd = (GetParamDim*)partID;
break;
}
case REFMSG_GET_PARAM_NAME: {
GetParamName *gpn = (GetParamName*)partID;
return REF_STOP;
}
}
return(REF_SUCCEED);
}
/***********************************************************************************************
* GameMapsClass::Clone -- Create a clone of the GameMapsClass *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 06/26/1997 GH : Created. *
*=============================================================================================*/
RefTargetHandle GameMapsClass::Clone(RemapDir &remap)
{
GameMapsClass *tm = new GameMapsClass(NULL);
for (int i=0; i<NTEXMAPS; i++) {
tm->TextureSlot[i].MapOn = TextureSlot[i].MapOn;
tm->TextureSlot[i].Map = NULL;
if (TextureSlot[i].Map) {
tm->ReplaceReference(i,remap.CloneRef(TextureSlot[i].Map));
}
}
return tm;
}
/***********************************************************************************************
* GameMapsClass::Save -- Saves the GameMapsClass data into a MAX file *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 06/26/1997 GH : Created. *
*=============================================================================================*/
IOResult GameMapsClass::Save(ISave * isave)
{
ULONG nb,f=0;
isave->BeginChunk(GAMEMAPS_ONOFF_CHUNK);
for (int i=0; i<NTEXMAPS; i++) {
if (TextureSlot[i].MapOn) f|= (1<<i);
}
isave->Write(&f,sizeof(f),&nb);
isave->EndChunk();
for (i=0; i<NTEXMAPS; i++) {
if (TextureSlot[i].Amount != 1.0f) {
isave->BeginChunk(GAMEMAPS_AMT0_CHUNK + i);
isave->Write(&(TextureSlot[i].Amount),sizeof(float),&nb);
isave->EndChunk();
}
}
return IO_OK;
}
/***********************************************************************************************
* GameMapsClass::Load -- Loads GameMapsClass data from a MAX file *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 06/26/1997 GH : Created. *
*=============================================================================================*/
IOResult GameMapsClass::Load(ILoad * iload)
{
ULONG nb;
int id;
IOResult res;
while (IO_OK==(res=iload->OpenChunk())) {
switch (id = iload->CurChunkID()) {
case GAMEMAPS_ONOFF_CHUNK:
{
ULONG f;
res = iload->Read(&f,sizeof(f), &nb);
for (int i=0; i<NTEXMAPS; i++)
(*this)[i].MapOn = (f&(1<<i))?1:0;
}
break;
case GAMEMAPS_AMT0_CHUNK:
case GAMEMAPS_AMT1_CHUNK:
case GAMEMAPS_AMT2_CHUNK:
case GAMEMAPS_AMT3_CHUNK:
case GAMEMAPS_AMT4_CHUNK:
case GAMEMAPS_AMT5_CHUNK:
case GAMEMAPS_AMT7_CHUNK:
case GAMEMAPS_AMT8_CHUNK:
case GAMEMAPS_AMT9_CHUNK:
case GAMEMAPS_AMTA_CHUNK:
int index = id - GAMEMAPS_AMT0_CHUNK;
res = iload->Read(&(TextureSlot[index].Amount),sizeof(float),&nb);
break;
}
iload->CloseChunk();
if (res!=IO_OK) {
return res;
}
}
return IO_OK;
}

View file

@ -0,0 +1,115 @@
/*
** Command & Conquer Generals(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/>.
*/
/* $Header: /Commando/Code/Tools/max2w3d/gamemaps.h 7 10/28/97 6:08p Greg_h $ */
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando / G 3D engine *
* *
* File Name : GAMEMAPS.H *
* *
* Programmer : Greg Hjelstrom *
* *
* Start Date : 06/26/97 *
* *
* Last Update : June 26, 1997 [GH] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef GAMEMAPS_H
#define GAMEMAPS_H
#include <Max.h>
#include "stdmat.h"
ClassDesc * Get_Game_Maps_Desc();
///////////////////////////////////////////////////////////////////////////
//
// TexmapSlotClass
//
///////////////////////////////////////////////////////////////////////////
class TexmapSlotClass
{
public:
BOOL MapOn;
float Amount;
Texmap * Map;
TexmapSlotClass() : MapOn(FALSE), Amount(1.0f), Map(NULL) {};
RGBA Eval(ShadeContext& sc) { return Map->EvalColor(sc); }
float EvalMono(ShadeContext& sc) { return Map->EvalMono(sc); }
Point3 EvalNormalPerturb(ShadeContext &sc) { return Map->EvalNormalPerturb(sc); }
BOOL IsActive() { return (Map && MapOn); }
void Update(TimeValue t, Interval &ivalid) { if (IsActive()) Map->Update(t,ivalid); };
float GetAmount(TimeValue t) { return Amount; }
};
///////////////////////////////////////////////////////////////////////////
//
// Texture Maps for In-Game material
//
// This class can contain a collection of all of the maps which
// MAX uses but the GameMtl plugin will only give the user access
// to the ones we can actually use in the game.
//
///////////////////////////////////////////////////////////////////////////
class GameMapsClass: public ReferenceTarget
{
public:
MtlBase * Client;
TexmapSlotClass TextureSlot[NTEXMAPS];
GameMapsClass() { Client = NULL; }
GameMapsClass(MtlBase *mb) { Client = mb; }
void DeleteThis() { delete this; }
void SetClientPtr(MtlBase *mb) { Client = mb; }
TexmapSlotClass & operator[](int i) { return TextureSlot[i]; }
Class_ID ClassID();
SClass_ID SuperClassID() { return REF_MAKER_CLASS_ID; }
int NumSubs() { return NTEXMAPS; }
Animatable * SubAnim(int i) { return TextureSlot[i].Map; }
TSTR SubAnimName(int i) { return Client->GetSubTexmapTVName(i); }
int NumRefs() { return NTEXMAPS; }
RefTargetHandle GetReference(int i) { return TextureSlot[i].Map; }
void SetReference(int i, RefTargetHandle rtarg) { TextureSlot[i].Map = (Texmap*)rtarg; }
int SubNumToRefNum(int subNum) { return subNum; }
BOOL AssignController(Animatable *control,int subAnim);
RefTargetHandle Clone(RemapDir &remap);
RefResult NotifyRefChanged( Interval changeInt, RefTargetHandle hTarget, PartID& partID, RefMessage message);
IOResult Save(ISave * isave);
IOResult Load(ILoad * iload);
};
#endif /*GAMEMAPS_H*/

View file

@ -0,0 +1,373 @@
/*
** Command & Conquer Generals(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/>.
*/
/* $Header: /Commando/Code/Tools/max2w3d/gamemtl.h 38 8/22/01 7:56a Greg_h $ */
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando / G 3D engine *
* *
* File Name : GAMEMTL.H *
* *
* Programmer : Greg Hjelstrom *
* *
* Start Date : 06/26/97 *
* *
* Last Update : June 26, 1997 [GH] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef GAMEMTL_H
#define GAMEMTL_H
#include <Max.h>
#include "w3dmtl.h"
#include "w3d_file.h"
// GameMtl flags values
#define GAMEMTL_CONVERTED_TO_NOLOD (1<<0) // this material has been converted to use the NO_LOD flag on textures
#define GAMEMTL_DISPLACEMENT_ROLLUP_OPEN (1<<25)
#define GAMEMTL_SURFACE_ROLLUP_OPEN (1<<26)
#define GAMEMTL_PASSCOUNT_ROLLUP_OPEN (1<<27)
#define GAMEMTL_PASS0_ROLLUP_OPEN (1<<28)
#define GAMEMTL_PASS1_ROLLUP_OPEN (1<<29)
#define GAMEMTL_PASS2_ROLLUP_OPEN (1<<30)
#define GAMEMTL_PASS3_ROLLUP_OPEN (1<<31)
#define GAMEMTL_ROLLUP_FLAGS ( GAMEMTL_SURFACE_ROLLUP_OPEN | \
GAMEMTL_DISPLACEMENT_ROLLUP_OPEN | \
GAMEMTL_PASSCOUNT_ROLLUP_OPEN | \
GAMEMTL_PASS0_ROLLUP_OPEN | \
GAMEMTL_PASS1_ROLLUP_OPEN | \
GAMEMTL_PASS2_ROLLUP_OPEN | \
GAMEMTL_PASS3_ROLLUP_OPEN )
#define GAMEMTL_ID_PARTA 0x29397211
#define GAMEMTL_ID_PARTB 0x28c016c2
///////////////////////////////////////////////////////////////////////////
//
// Mapping types
//
///////////////////////////////////////////////////////////////////////////
#define GAMEMTL_MAPPING_UV 0
#define GAMEMTL_MAPPING_ENV 1
#define GAMEMTL_MAPPING_CHEAP_ENV 2
#define GAMEMTL_MAPPING_SCREEN 3
#define GAMEMTL_MAPPING_LINEAR_OFFSET 4
#define GAMEMTL_MAPPING_SILHOUETTE 5
#define GAMEMTL_MAPPING_SCALE 6
#define GAMEMTL_MAPPING_GRID 7
#define GAMEMTL_MAPPING_ROTATE 8
#define GAMEMTL_MAPPING_SINE_LINEAR_OFFSET 9
#define GAMEMTL_MAPPING_STEP_LINEAR_OFFSET 10
#define GAMEMTL_MAPPING_ZIGZAG_LINEAR_OFFSET 11
#define GAMEMTL_MAPPING_WS_CLASSIC_ENV 12
#define GAMEMTL_MAPPING_WS_ENVIRONMENT 13
#define GAMEMTL_MAPPING_GRID_CLASSIC_ENV 14
#define GAMEMTL_MAPPING_GRID_ENVIRONMENT 15
#define GAMEMTL_MAPPING_RANDOM 16
#define GAMEMTL_MAPPING_EDGE 17
#define GAMEMTL_MAPPING_BUMPENV 18
///////////////////////////////////////////////////////////////////////////
//
// PSX Translucency Type
//
///////////////////////////////////////////////////////////////////////////
#define GAMEMTL_PSX_TRANS_NONE 0
#define GAMEMTL_PSX_TRANS_100 1
#define GAMEMTL_PSX_TRANS_50 2
#define GAMEMTL_PSX_TRANS_25 3
#define GAMEMTL_PSX_TRANS_MINUS_100 4
class GameMtlDlg;
class GameMapsClass;
extern Class_ID GameMaterialClassID;
extern ClassDesc * Get_Game_Material_Desc();
// MLL
// For Playstation 2 materials.
extern Class_ID PS2GameMaterialClassID;
extern ClassDesc * Get_PS2_Game_Material_Desc();
extern Class_ID PCToPS2MaterialClassID;
extern ClassDesc * Get_PS2_Material_Conversion();
///////////////////////////////////////////////////////////////////////////
//
// Game Material
// This is a plugin-material which attempts to emulate the material
// used in our in-game 3D engine. It has varying degrees of success
// at making Max render things like our game but it gives us the
// ability to have control over all parameters in our material.
//
///////////////////////////////////////////////////////////////////////////
class GameMtl: public Mtl
{
public:
enum ShaderTypeEnum
{
STE_PC_SHADER,
STE_PS2_SHADER,
};
GameMtl(BOOL loading = FALSE);
~GameMtl(void);
Class_ID ClassID();
SClass_ID SuperClassID();
// From Animatable
void GetClassName(TSTR& s);
void DeleteThis() { delete this; }
int NumSubs();
Animatable * SubAnim(int i);
TSTR SubAnimName(int i);
// References
int NumRefs() { return REF_COUNT; }
RefTargetHandle Clone(RemapDir &remap = NoRemap());
RefResult NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget, PartID& partID, RefMessage message);
void SetReference(int i, RefTargetHandle rtarg);
RefTargetHandle GetReference(int i);
// From MtlBase and Mtl
void SetAmbient(Color c, TimeValue t) { Set_Ambient(0,t,c); }
void SetDiffuse(Color c, TimeValue t) { Set_Diffuse(0,t,c); }
void SetSpecular(Color c, TimeValue t) { Set_Specular(0,t,c); }
void SetShininess(float v, TimeValue t) { Set_Shininess(0,t,v); }
Color GetAmbient(int mtlNum=0, BOOL backFace=FALSE) { return Get_Ambient(0,0); }
Color GetDiffuse(int mtlNum=0, BOOL backFace=FALSE) { return Get_Diffuse(0,0); }
Color GetSpecular(int mtlNum=0, BOOL backFace=FALSE) { return Get_Specular(0,0); }
float GetXParency(int mtlNum=0, BOOL backFace=FALSE) { return 0.0f; }
float GetShininess(int mtlNum=0, BOOL backFace=FALSE) { return Get_Shininess(0,0); }
float GetShinStr(int mtlNum=0, BOOL backFace=FALSE) { return 1.0f; }
void Reset(void);
void Update(TimeValue t, Interval& validr);
Interval Validity(TimeValue t);
int NumSubTexmaps(void);
void SetSubTexmap(int i, Texmap * m);
Texmap * GetSubTexmap(int i);
float EvalDisplacement(ShadeContext& sc);
Interval DisplacementValidity(TimeValue t);
// Rendering
void Shade(ShadeContext& sc);
ULONG Requirements(int subMtlNum);
//ULONG LocalRequirements(int subMtlNum);
// Material editor
void SetParamDlg(GameMtlDlg * pd) { MaterialDialog = pd; }
ParamDlg* CreateParamDlg(HWND hwMtlEdit, IMtlParams *imp);
// IO stuff
IOResult Save(ISave* iSave);
IOResult Load(ILoad* iLoad);
// Accessors...
void Set_Flag(ULONG f, ULONG val) { if (val) Flags|=f; else Flags &= ~f; }
int Get_Flag(ULONG f) { return ((Flags&f) ? 1 : 0); }
void Set_Surface_Type(unsigned int type) { SurfaceType = type; }
unsigned int Get_Surface_Type(void) const { return SurfaceType; }
void Set_Sort_Level(int level) { SortLevel = level; }
int Get_Sort_Level(void) const { return SortLevel; }
void Set_Pass_Count(int passcount);
int Get_Pass_Count(void);
IParamBlock * Get_Parameter_Block(int pass);
int Get_Current_Page(int pass) { return CurPage[pass]; }
Color Get_Ambient(int pass,TimeValue t);
Color Get_Diffuse(int pass,TimeValue t);
Color Get_Specular(int pass,TimeValue t);
Color Get_Emissive(int pass,TimeValue t);
float Get_Shininess(int pass,TimeValue t);
float Get_Opacity(int pass,TimeValue t);
float Get_Translucency(int pass,TimeValue t);
int Get_Copy_Specular_To_Diffuse(int pass);
int Get_Mapping_Type(int pass, int stage=0);
int Get_PSX_Translucency(int pass);
int Get_PSX_Lighting(int pass);
int Get_Depth_Compare(int pass);
int Get_Depth_Mask(int pass);
int Get_Alpha_Test(int pass);
int Get_Dest_Blend(int pass);
int Get_Pri_Gradient(int pass);
int Get_Sec_Gradient(int pass);
int Get_Src_Blend(int pass);
int Get_Detail_Color_Func(int pass);
int Get_Detail_Alpha_Func(int pass);
int Get_PS2_Shader_Param_A(int pass);
int Get_PS2_Shader_Param_B(int pass);
int Get_PS2_Shader_Param_C(int pass);
int Get_PS2_Shader_Param_D(int pass);
int Get_Texture_Enable(int pass,int stage);
int Get_Texture_Publish(int pass,int stage);
int Get_Texture_Resize(int pass,int stage); // NOTE: obsolete, replaced by Get_Texture_No_LOD
int Get_Texture_No_Mipmap(int pass,int stage); // NOTE: obsolete, replaced by Get_Texture_No_LOD
int Get_Texture_Clamp_U(int pass,int stage);
int Get_Texture_Clamp_V(int pass,int stage);
int Get_Texture_No_LOD(int pass,int stage);
int Get_Texture_Alpha_Bitmap(int pass,int stage);
int Get_Texture_Hint(int pass,int stage);
int Get_Texture_Display(int pass,int stage);
float Get_Texture_Frame_Rate(int pass,int stage);
int Get_Texture_Frame_Count(int pass,int stage);
int Get_Texture_Anim_Type(int pass,int stage);
Texmap * Get_Texture(int pass,int stage);
Texmap * Get_Displacement_Map(void) const { return DisplacementMap; }
float Get_Displacement_Amount(void) const { return DisplacementAmt; }
int Get_Displacement_Map_Index(void) const;
int Get_Map_Channel(int pass,int stage);
void Set_Current_Page(int pass,int page) { CurPage[pass] = page; }
void Set_Ambient(int pass,TimeValue t,Color color);
void Set_Diffuse(int pass,TimeValue t,Color color);
void Set_Specular(int pass,TimeValue t,Color color);
void Set_Emissive(int pass,TimeValue t,Color color);
void Set_Shininess(int pass,TimeValue t,float val);
void Set_Opacity(int pass,TimeValue t,float val);
void Set_Translucency(int pass,TimeValue t,float val);
void Set_Copy_Specular_To_Diffuse(int pass,bool val);
void Set_Mapping_Type(int pass,int stage,int val);
void Set_PSX_Translucency(int pass,int val);
void Set_PSX_Lighting(int pass,bool val);
void Set_Depth_Compare(int pass,int val);
void Set_Depth_Mask(int pass,int val);
void Set_Alpha_Test(int pass,int val);
void Set_Dest_Blend(int pass,int val);
void Set_Pri_Gradient(int pass,int val);
void Set_Sec_Gradient(int pass,int val);
void Set_Src_Blend(int pass,int val);
void Set_Detail_Color_Func(int pass,int val);
void Set_Detail_Alpha_Func(int pass,int val);
void Set_PS2_Shader_Param_A(int pass,int val);
void Set_PS2_Shader_Param_B(int pass,int val);
void Set_PS2_Shader_Param_C(int pass,int val);
void Set_PS2_Shader_Param_D(int pass,int val);
void Set_Texture_Enable(int pass,int stage,bool val);
void Set_Texture_Publish(int pass,int stage,bool val);
void Set_Texture_Resize(int pass,int stage,bool val); // NOTE: obsolete: replaced by Set_Texture_No_LOD
void Set_Texture_No_Mipmap(int pass,int stage,bool val); // NOTE: obsolete: replaced by Set_Texture_No_LOD
void Set_Texture_Clamp_U(int pass,int stage,bool val);
void Set_Texture_Clamp_V(int pass,int stage,bool val);
void Set_Texture_No_LOD(int pass,int stage,bool val);
void Set_Texture_Alpha_Bitmap(int pass,int stage,bool val);
void Set_Texture_Hint(int pass,int stage,int val);
void Set_Texture_Display(int pass,int stage,bool val);
void Set_Texture_Frame_Rate(int pass,int stage,float val);
void Set_Texture_Frame_Count(int pass,int stage,int val);
void Set_Texture_Anim_Type(int pass,int stage,int val);
void Set_Texture(int pass,int stage,Texmap * tex);
void Set_Displacement_Amount(float amount) { DisplacementAmt = amount; Notify_Changed (); }
void Set_Map_Channel(int pass,int stage,int channel);
void Notify_Changed(void);
// This returns the mapping args string buffer for that pass after
// assuring that it is at least of length 'len'.
char * Get_Mapping_Arg_Buffer(int pass, int stage=0, unsigned int len = 0U);
int pass_stage_to_texmap_index(int pass,int stage);
void texmap_index_to_pass_stage(int index,int * set_pass,int * set_stage);
// Set and get the type of shader, PC or PS2.
// MLL
int Get_Shader_Type() {return (ShaderType);}
void Set_Shader_Type(int shadertype) {ShaderType = shadertype;}
// Approximate the PS2 shader on the PC.
int Compute_PC_Shader_From_PS2_Shader(int pass);
int Compute_PS2_Shader_From_PC_Shader(int pass);
// IML: Get/set substitute material.
Mtl* Substitute_Material() {return (SubstituteMaterial);}
void Set_Substitute_Material (Mtl *m) {SubstituteMaterial = m;}
private:
int texture_ref_index(int pass,int stage) { return REF_TEXTURE + pass*W3dMaterialClass::MAX_STAGES + stage; }
int pass_ref_index(int pass) { return REF_PASS_PARAMETERS + pass; }
void update_viewport_display();
// Do the shade functions specific to the Playstation 2.
void ps2_shade(ShadeContext& sc);
unsigned int SurfaceType;
int SortLevel;
Interval Ivalid; // Valid interval
GameMtlDlg * MaterialDialog; // Dialog
ULONG Flags; // Flags
int RollScroll; // Rollup scroll position
int CurPage[W3dMaterialClass::MAX_PASSES]; // which page was last open for each pass
GameMapsClass * Maps; // ref 0 (obsolete...)
IParamBlock * MainParameterBlock;
IParamBlock * PassParameterBlock[W3dMaterialClass::MAX_PASSES];
Texmap * Texture[W3dMaterialClass::MAX_PASSES][W3dMaterialClass::MAX_STAGES];
char * MapperArg[W3dMaterialClass::MAX_PASSES][W3dMaterialClass::MAX_STAGES];
unsigned int MapperArgLen[W3dMaterialClass::MAX_PASSES][W3dMaterialClass::MAX_STAGES];
Texmap * DisplacementMap;
float DisplacementAmt;
// MLL
int ShaderType;
enum
{
REF_MAPS = 0, // obsolete, gamemaps object
REF_MAIN = 1, // main parameter block is ref 1
REF_PASS_PARAMETERS = 2, // pass parameter blocks are refs 2,3,4,5
REF_TEXTURE = 6, // textures are refs 6,7,8,9,10,11,12,13,14 (14 is the displacement map)
REF_COUNT = 15
};
Mtl *SubstituteMaterial; // IML: Temporary material used during game to standard material conversion and vice-versa.
friend class GameMtlDlg;
friend class GameMtlPostLoad;
};
Mtl * CreateGameMtl();
#endif

View file

@ -0,0 +1,208 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Max2W3D *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/genlodextensiondialog.cpp $*
* *
* Original Author:: Greg Hjelstrom *
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 10/10/00 11:14a $*
* *
* $Revision:: 1 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* GenLodExtensionDialogClass::GenLodExtensionDialogClass -- Constructor *
* GenLodExtensionDialogClass::~GenLodExtensionDialogClass -- Destructor *
* GenLodExtensionDialogClass::Get_Options -- Presents the dialog, gets user input *
* GenLodExtensionDialogClass::Dialog_Proc -- Windows message handling *
* _gen_lod_ext_dialog_proc -- windows dialog proc *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "genlodextensiondialog.h"
#include "dllmain.h"
#include "resource.h"
#include <Max.h>
/**********************************************************************************************
**
** GenLodExtensionDialogClass Implementation
**
**********************************************************************************************/
/***********************************************************************************************
* GenLodExtensionDialogClass::GenLodExtensionDialogClass -- Constructor *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
*=============================================================================================*/
GenLodExtensionDialogClass::GenLodExtensionDialogClass(Interface * maxinterface) :
Hwnd(NULL),
Options(NULL),
MaxInterface(maxinterface),
LodIndexSpin(NULL)
{
}
/***********************************************************************************************
* GenLodExtensionDialogClass::~GenLodExtensionDialogClass -- Destructor *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 10/10/2000 gth : Created. *
*=============================================================================================*/
GenLodExtensionDialogClass::~GenLodExtensionDialogClass(void)
{
ReleaseISpinner(LodIndexSpin);
}
/***********************************************************************************************
* GenLodExtensionDialogClass::Get_Options -- Presents the dialog, gets user input *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 10/10/2000 gth : Created. *
*=============================================================================================*/
bool GenLodExtensionDialogClass::Get_Options(OptionsStruct * options)
{
Options = options;
// Put up the options dialog box.
BOOL result = DialogBoxParam
(
AppInstance,
MAKEINTRESOURCE (IDD_GENERATE_LOD_EXTENSION_DIALOG),
MaxInterface->GetMAXHWnd(),
(DLGPROC) _gen_lod_ext_dialog_proc,
(LPARAM) this
);
if (result == TRUE) {
return true;
} else {
return false;
}
}
/***********************************************************************************************
* GenLodExtensionDialogClass::Dialog_Proc -- Windows message handling *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 10/10/2000 gth : Created. *
*=============================================================================================*/
bool GenLodExtensionDialogClass::Dialog_Proc(HWND hWnd,UINT message,WPARAM wParam,LPARAM)
{
switch (message ) {
case WM_INITDIALOG:
// Setup the LOD spinner control.
LodIndexSpin = SetupIntSpinner
(
Hwnd,
IDC_LOD_INDEX_SPIN,
IDC_LOD_INDEX_EDIT,
MIN_LOD_INDEX,MAX_LOD_INDEX,INITIAL_LOD_INDEX
);
return 1;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
Options->LodIndex = LodIndexSpin->GetIVal();
EndDialog(Hwnd, 1);
break;
case IDCANCEL:
EndDialog(Hwnd, 0);
break;
}
return 1;
}
return 0;
}
/***********************************************************************************************
* _gen_lod_ext_dialog_proc -- windows dialog proc *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 10/10/2000 gth : Created. *
*=============================================================================================*/
static BOOL CALLBACK _gen_lod_ext_dialog_proc(HWND hwnd,UINT message,WPARAM wparam,LPARAM lparam)
{
static GenLodExtensionDialogClass * dialog = NULL;
if (message == WM_INITDIALOG) {
dialog = (GenLodExtensionDialogClass *)lparam;
dialog->Hwnd = hwnd;
}
if (dialog) {
return dialog->Dialog_Proc(hwnd, message, wparam, lparam);
} else {
return FALSE;
}
}

View file

@ -0,0 +1,94 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Max2W3d *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/genlodextensiondialog.h $*
* *
* Original Author:: Greg Hjelstrom *
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 10/10/00 11:14a $*
* *
* $Revision:: 1 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef GENLODEXTENSIONDIALOG_H
#define GENLODEXTENSIONDIALOG_H
#include <windows.h>
class Interface;
class ISpinnerControl;
/**********************************************************************************************
**
** GenLodExtensionDialogClass - Dialog box for the LOD extension naming parameters
**
**********************************************************************************************/
class GenLodExtensionDialogClass
{
public:
GenLodExtensionDialogClass(Interface * maxinterface);
~GenLodExtensionDialogClass();
struct OptionsStruct
{
OptionsStruct(void) : LodIndex(0)
{
}
// name options
int LodIndex;
};
bool Get_Options(OptionsStruct * options);
bool Dialog_Proc(HWND hWnd,UINT message,WPARAM wParam,LPARAM);
private:
enum
{
MIN_LOD_INDEX = 0,
MAX_LOD_INDEX = 99,
INITIAL_LOD_INDEX = 0,
};
HWND Hwnd;
OptionsStruct * Options;
Interface * MaxInterface;
ISpinnerControl * LodIndexSpin;
friend BOOL CALLBACK _gen_lod_ext_dialog_proc(HWND Hwnd,UINT message,WPARAM wParam,LPARAM lParam);
};
#endif //GENLODEXTENSIONDIALOG_H

View file

@ -0,0 +1,260 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Max2W3D *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/genmtlnamesdialog.cpp $*
* *
* Original Author:: Greg Hjelstrom *
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 10/10/00 11:12a $*
* *
* $Revision:: 1 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* GenMtlNamesDialogClass::GenMtlNamesDialogClass -- Constructor *
* GenMtlNamesDialogClass::~GenMtlNamesDialogClass -- Destructor *
* GenMtlNamesDialogClass::Get_Options -- present the dialog, get user input *
* GenMtlNamesDialogClass::Ok_To_Exit -- verify that the input is valid *
* GenMtlNamesDialogClass::Dialog_Proc -- windows message handling *
* _gen_mtl_names_dialog_proc -- windows dialog proc for GenMtlNamesDialog *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "genmtlnamesdialog.h"
#include "dllmain.h"
#include "resource.h"
#include "w3d_file.h"
#include <Max.h>
static BOOL CALLBACK _gen_mtl_names_dialog_proc(HWND Hwnd,UINT message,WPARAM wParam,LPARAM lParam);
/**********************************************************************************************
**
** GenMtlNamesDialogClass Implementation
**
**********************************************************************************************/
/***********************************************************************************************
* GenMtlNamesDialogClass::GenMtlNamesDialogClass -- Constructor *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
*=============================================================================================*/
GenMtlNamesDialogClass::GenMtlNamesDialogClass(Interface * maxinterface) :
Hwnd(NULL),
Options(NULL),
MaxInterface(maxinterface),
NameIndexSpin(NULL)
{
}
/***********************************************************************************************
* GenMtlNamesDialogClass::~GenMtlNamesDialogClass -- Destructor *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 10/10/2000 gth : Created. *
*=============================================================================================*/
GenMtlNamesDialogClass::~GenMtlNamesDialogClass(void)
{
ReleaseISpinner(NameIndexSpin);
}
/***********************************************************************************************
* GenMtlNamesDialogClass::Get_Options -- present the dialog, get user input *
* *
* INPUT: *
* options - pointer to structure to hold the user's input *
* *
* OUTPUT: *
* true - user pressed ok and the input is valid *
* *
* WARNINGS: *
* *
* HISTORY: *
* 10/10/2000 gth : Created. *
*=============================================================================================*/
bool GenMtlNamesDialogClass::Get_Options(OptionsStruct * options)
{
Options = options;
// Put up the options dialog box.
BOOL result = DialogBoxParam
(
AppInstance,
MAKEINTRESOURCE (IDD_GENERATE_MTL_NAMES_DIALOG),
MaxInterface->GetMAXHWnd(),
(DLGPROC) _gen_mtl_names_dialog_proc,
(LPARAM) this
);
if (result == TRUE) {
return true;
} else {
return false;
}
}
/***********************************************************************************************
* GenMtlNamesDialogClass::Ok_To_Exit -- verify that the input is valid *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 10/10/2000 gth : Created. *
*=============================================================================================*/
bool GenMtlNamesDialogClass::Ok_To_Exit(void)
{
// just check that the user entered a name
char buf[W3D_NAME_LEN];
GetWindowText(GetDlgItem(Hwnd,IDC_BASE_NAME_EDIT),buf,sizeof(buf));
if (strlen(buf) == 0) {
MessageBox(Hwnd,"Please enter a root name to use.\n","Error",MB_OK);
return false;
} else {
return true;
}
return true;
}
/***********************************************************************************************
* GenMtlNamesDialogClass::Dialog_Proc -- windows message handling *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 10/10/2000 gth : Created. *
*=============================================================================================*/
bool GenMtlNamesDialogClass::Dialog_Proc(HWND hWnd,UINT message,WPARAM wParam,LPARAM)
{
switch (message ) {
case WM_INITDIALOG:
NameIndexSpin = SetupIntSpinner
(
Hwnd,
IDC_NAME_INDEX_SPIN,
IDC_NAME_INDEX_EDIT,
MIN_NAME_INDEX,MAX_NAME_INDEX,INITIAL_NAME_INDEX
);
// limit the edit box characters
SendDlgItemMessage(Hwnd,IDC_BASE_NAME_EDIT,EM_LIMITTEXT,MAX_ROOT_NAME_LEN,0);
// set initial name to root of the filename
char buf[_MAX_FNAME];
_splitpath(MaxInterface->GetCurFileName(),NULL,NULL,buf,NULL);
buf[MAX_ROOT_NAME_LEN+1] = 0;
SetWindowText(GetDlgItem(Hwnd,IDC_BASE_NAME_EDIT),buf);
// init radio buttons
CheckDlgButton(Hwnd,IDC_AFFECT_ALL_RADIO,BST_UNCHECKED);
CheckDlgButton(Hwnd,IDC_AFFECT_SELECTED_RADIO,BST_CHECKED);
return 1;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
if (Ok_To_Exit()) {
// general options
Options->OnlyAffectSelected = (IsDlgButtonChecked(Hwnd,IDC_AFFECT_SELECTED_RADIO) == BST_CHECKED);
// naming options
Options->NameIndex = NameIndexSpin->GetIVal();
GetWindowText(GetDlgItem(Hwnd,IDC_BASE_NAME_EDIT),Options->RootName,sizeof(Options->RootName));
EndDialog(Hwnd, 1);
}
break;
case IDCANCEL:
EndDialog(Hwnd, 0);
break;
}
return 1;
}
return 0;
}
/***********************************************************************************************
* _gen_mtl_names_dialog_proc -- windows dialog proc for GenMtlNamesDialog *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 10/10/2000 gth : Created. *
*=============================================================================================*/
static BOOL CALLBACK _gen_mtl_names_dialog_proc(HWND hwnd,UINT message,WPARAM wparam,LPARAM lparam)
{
static GenMtlNamesDialogClass * dialog = NULL;
if (message == WM_INITDIALOG) {
dialog = (GenMtlNamesDialogClass *)lparam;
dialog->Hwnd = hwnd;
}
if (dialog) {
return dialog->Dialog_Proc(hwnd, message, wparam, lparam);
} else {
return FALSE;
}
}

View file

@ -0,0 +1,102 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Max2W3d *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/genmtlnamesdialog.h $*
* *
* Original Author:: Greg Hjelstrom *
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 10/10/00 11:12a $*
* *
* $Revision:: 1 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef GENMTLNAMESDIALOG_H
#define GENMTLNAMESDIALOG_H
#include <windows.h>
class Interface;
class ISpinnerControl;
/**********************************************************************************************
**
** GenMtlNamesDialogClass - Dialog box for the material naming parameters
**
**********************************************************************************************/
class GenMtlNamesDialogClass
{
public:
GenMtlNamesDialogClass(Interface * maxinterface);
~GenMtlNamesDialogClass();
enum
{
MAX_MATERIAL_NAME_LEN = 32,
MIN_NAME_INDEX = 0,
MAX_NAME_INDEX = 999,
INITIAL_NAME_INDEX = 0,
MAX_ROOT_NAME_LEN = 28,
};
struct OptionsStruct
{
OptionsStruct(void) : OnlyAffectSelected(true), NameIndex(0)
{
memset(RootName,0,sizeof(RootName));
}
// overall options
bool OnlyAffectSelected;
// name options
char RootName[MAX_MATERIAL_NAME_LEN];
int NameIndex;
};
bool Get_Options(OptionsStruct * options);
bool Dialog_Proc(HWND hWnd,UINT message,WPARAM wParam,LPARAM);
bool Ok_To_Exit(void);
private:
HWND Hwnd;
OptionsStruct * Options;
Interface * MaxInterface;
ISpinnerControl * NameIndexSpin;
friend BOOL CALLBACK _gen_mtl_names_dialog_proc(HWND hwnd,UINT message,WPARAM wparam,LPARAM lparam);
};
#endif //GENMTLNAMESDIALOG_H

View file

@ -0,0 +1,357 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Max2W3D *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/gennamesdialog.cpp $*
* *
* Original Author:: Greg Hjelstrom *
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 12/06/00 3:24p $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* GenNamesDialogClass::GenNamesDialogClass -- Constructor *
* GenNamesDialogClass::~GenNamesDialogClass -- Destructor *
* GenNamesDialogClass::Get_Options -- Get_Options *
* GenNamesDialogClass::Ok_To_Exit -- verifies that the input is valid *
* GenNamesDialogClass::Toggle_Name_Assignment -- toggles the controls related to name assig *
* GenNamesDialogClass::Toggle_Collision_Bits_Assignment -- toggles the controls related to *
* GenNamesDialogClass::Dialog_Proc -- windows dialog proc *
* _gen_names_dialog_proc -- dialog proc that "thunks" to the class's dialog proc *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "gennamesdialog.h"
#include "dllmain.h"
#include "resource.h"
static BOOL CALLBACK _gen_names_dialog_proc(HWND Hwnd,UINT message,WPARAM wParam,LPARAM lParam);
/**********************************************************************************************
**
** GenNamesDialogClass Implementation
**
**********************************************************************************************/
/***********************************************************************************************
* GenNamesDialogClass::GenNamesDialogClass -- Constructor *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
*=============================================================================================*/
GenNamesDialogClass::GenNamesDialogClass(Interface * maxinterface) :
Hwnd(NULL),
Options(NULL),
MaxInterface(maxinterface),
NameIndexSpin(NULL)
{
}
/***********************************************************************************************
* GenNamesDialogClass::~GenNamesDialogClass -- Destructor *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 10/10/2000 gth : Created. *
*=============================================================================================*/
GenNamesDialogClass::~GenNamesDialogClass(void)
{
ReleaseISpinner(NameIndexSpin);
}
/***********************************************************************************************
* GenNamesDialogClass::Get_Options -- Get_Options *
* *
* presents the dialog to the user and records his selections into the passed-in options *
* structure. *
* *
* INPUT: *
* options - pointer to a OptionsStruct to store the users input in. *
* *
* OUTPUT: *
* true - user pressed ok and entered valid input *
* *
* WARNINGS: *
* *
* HISTORY: *
* 10/10/2000 gth : Created. *
*=============================================================================================*/
bool GenNamesDialogClass::Get_Options(OptionsStruct * options)
{
Options = options;
// Put up the options dialog box.
BOOL result = DialogBoxParam
(
AppInstance,
MAKEINTRESOURCE (IDD_GENERATE_NAMES_DIALOG),
MaxInterface->GetMAXHWnd(),
(DLGPROC) _gen_names_dialog_proc,
(LPARAM) this
);
if (result == TRUE) {
return true;
} else {
return false;
}
}
/***********************************************************************************************
* GenNamesDialogClass::Ok_To_Exit -- verifies that the input is valid *
* *
* INPUT: *
* *
* OUTPUT: *
* true - dialog contains valid input *
* *
* WARNINGS: *
* *
* HISTORY: *
* 10/10/2000 gth : Created. *
*=============================================================================================*/
bool GenNamesDialogClass::Ok_To_Exit(void)
{
if (IsDlgButtonChecked(Hwnd,IDC_ASSIGN_NAMES_CHECK) == BST_CHECKED) {
// just check that the user entered a name
char buf[W3D_NAME_LEN];
GetWindowText(GetDlgItem(Hwnd,IDC_BASE_NAME_EDIT),buf,sizeof(buf));
if (strlen(buf) == 0) {
MessageBox(Hwnd,"Please enter a root name to use.\n","Error",MB_OK);
return false;
} else {
return true;
}
}
return true;
}
/***********************************************************************************************
* GenNamesDialogClass::Toggle_Name_Assignment -- toggles the controls related to name assignm *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 10/10/2000 gth : Created. *
*=============================================================================================*/
void GenNamesDialogClass::Toggle_Name_Assignment(void)
{
bool onoff = (IsDlgButtonChecked(Hwnd,IDC_ASSIGN_NAMES_CHECK) == BST_CHECKED);
EnableWindow(GetDlgItem(Hwnd,IDC_BASE_NAME_EDIT),onoff);
EnableWindow(GetDlgItem(Hwnd,IDC_LOD_INDEX_EDIT),onoff);
EnableWindow(GetDlgItem(Hwnd,IDC_LOD_INDEX_SPIN),onoff);
EnableWindow(GetDlgItem(Hwnd,IDC_NAME_INDEX_EDIT),onoff);
EnableWindow(GetDlgItem(Hwnd,IDC_NAME_INDEX_SPIN),onoff);
}
/***********************************************************************************************
* GenNamesDialogClass::Toggle_Collision_Bits_Assignment -- toggles the controls related to co *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 10/10/2000 gth : Created. *
*=============================================================================================*/
void GenNamesDialogClass::Toggle_Collision_Bits_Assignment(void)
{
bool onoff = (IsDlgButtonChecked(Hwnd,IDC_ASSIGN_COLLISION_BITS_CHECK) == BST_CHECKED);
EnableWindow(GetDlgItem(Hwnd,IDC_COLLISION_PHYSICAL),onoff);
EnableWindow(GetDlgItem(Hwnd,IDC_COLLISION_PROJECTILE),onoff);
EnableWindow(GetDlgItem(Hwnd,IDC_COLLISION_VIS),onoff);
EnableWindow(GetDlgItem(Hwnd,IDC_COLLISION_CAMERA),onoff);
EnableWindow(GetDlgItem(Hwnd,IDC_COLLISION_VEHICLE),onoff);
}
/***********************************************************************************************
* GenNamesDialogClass::Dialog_Proc -- windows dialog proc *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 10/10/2000 gth : Created. *
*=============================================================================================*/
bool GenNamesDialogClass::Dialog_Proc(HWND hWnd,UINT message,WPARAM wParam,LPARAM)
{
switch (message ) {
case WM_INITDIALOG:
NameIndexSpin = SetupIntSpinner
(
Hwnd,
IDC_NAME_INDEX_SPIN,
IDC_NAME_INDEX_EDIT,
MIN_NAME_INDEX,MAX_NAME_INDEX,INITIAL_NAME_INDEX
);
// limit the base name edit box to 10 characters
SendDlgItemMessage(Hwnd,IDC_BASE_NAME_EDIT,EM_LIMITTEXT,MAX_ROOT_NAME_LEN,0);
// limit the suffix and prefix edit boxes
SendDlgItemMessage(Hwnd,IDC_PREFIX_EDIT,EM_LIMITTEXT,MAX_PREFIX_LEN,0);
SendDlgItemMessage(Hwnd,IDC_SUFFIX_EDIT,EM_LIMITTEXT,MAX_SUFFIX_LEN,0);
// set initial name to root of the filename
char buf[_MAX_FNAME];
_splitpath(MaxInterface->GetCurFileName(),NULL,NULL,buf,NULL);
buf[MAX_ROOT_NAME_LEN+1] = 0;
SetWindowText(GetDlgItem(Hwnd,IDC_BASE_NAME_EDIT),buf);
// init radio buttons
CheckDlgButton(Hwnd,IDC_AFFECT_ALL_RADIO,BST_UNCHECKED);
CheckDlgButton(Hwnd,IDC_AFFECT_SELECTED_RADIO,BST_CHECKED);
// init the check boxes
CheckDlgButton(Hwnd,IDC_ASSIGN_NAMES_CHECK,BST_CHECKED);
CheckDlgButton(Hwnd,IDC_ASSIGN_PREFIX_CHECK,BST_UNCHECKED);
CheckDlgButton(Hwnd,IDC_ASSIGN_SUFFIX_CHECK,BST_UNCHECKED);
CheckDlgButton(Hwnd,IDC_ASSIGN_COLLISION_BITS_CHECK,BST_CHECKED);
CheckDlgButton(Hwnd,IDC_COLLISION_PHYSICAL,BST_CHECKED);
CheckDlgButton(Hwnd,IDC_COLLISION_PROJECTILE,BST_CHECKED);
CheckDlgButton(Hwnd,IDC_COLLISION_VIS,BST_CHECKED);
CheckDlgButton(Hwnd,IDC_COLLISION_CAMERA,BST_CHECKED);
CheckDlgButton(Hwnd,IDC_COLLISION_VEHICLE,BST_CHECKED);
return 1;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
if (Ok_To_Exit()) {
// general options
Options->AssignNames = (IsDlgButtonChecked(Hwnd,IDC_ASSIGN_NAMES_CHECK) == BST_CHECKED);
Options->AssignPrefix = (IsDlgButtonChecked(Hwnd,IDC_ASSIGN_PREFIX_CHECK) == BST_CHECKED);
Options->AssignSuffix = (IsDlgButtonChecked(Hwnd,IDC_ASSIGN_SUFFIX_CHECK) == BST_CHECKED);
Options->AssignCollisionBits = (IsDlgButtonChecked(Hwnd,IDC_ASSIGN_COLLISION_BITS_CHECK) == BST_CHECKED);
Options->OnlyAffectSelected = (IsDlgButtonChecked(Hwnd,IDC_AFFECT_SELECTED_RADIO) == BST_CHECKED);
// naming options
Options->NameIndex = NameIndexSpin->GetIVal();
GetWindowText(GetDlgItem(Hwnd,IDC_BASE_NAME_EDIT),Options->RootName,sizeof(Options->RootName));
GetWindowText(GetDlgItem(Hwnd,IDC_PREFIX_EDIT),Options->PrefixName,sizeof(Options->PrefixName));
GetWindowText(GetDlgItem(Hwnd,IDC_SUFFIX_EDIT),Options->SuffixName,sizeof(Options->SuffixName));
// collision options
Options->PhysicalCollision = (IsDlgButtonChecked(Hwnd,IDC_COLLISION_PHYSICAL) == BST_CHECKED);
Options->ProjectileCollision = (IsDlgButtonChecked(Hwnd,IDC_COLLISION_PROJECTILE) == BST_CHECKED);
Options->VisCollision = (IsDlgButtonChecked(Hwnd,IDC_COLLISION_VIS) == BST_CHECKED);
Options->CameraCollision = (IsDlgButtonChecked(Hwnd,IDC_COLLISION_CAMERA) == BST_CHECKED);
Options->VehicleCollision = (IsDlgButtonChecked(Hwnd,IDC_COLLISION_VEHICLE) == BST_CHECKED);
EndDialog(Hwnd, 1);
}
break;
case IDCANCEL:
EndDialog(Hwnd, 0);
break;
case IDC_ASSIGN_NAMES_CHECK:
Toggle_Name_Assignment();
break;
case IDC_ASSIGN_PREFIX_CHECK:
EnableWindow(GetDlgItem(Hwnd,IDC_PREFIX_EDIT),(IsDlgButtonChecked(Hwnd,IDC_ASSIGN_SUFFIX_CHECK) == BST_CHECKED));
break;
case IDC_ASSIGN_SUFFIX_CHECK:
EnableWindow(GetDlgItem(Hwnd,IDC_SUFFIX_EDIT),(IsDlgButtonChecked(Hwnd,IDC_ASSIGN_SUFFIX_CHECK) == BST_CHECKED));
break;
case IDC_ASSIGN_COLLISION_BITS_CHECK:
Toggle_Collision_Bits_Assignment();
break;
}
return 1;
}
return 0;
}
/***********************************************************************************************
* _gen_names_dialog_proc -- dialog proc that "thunks" to the class's dialog proc *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 10/10/2000 gth : Created. *
*=============================================================================================*/
static BOOL CALLBACK _gen_names_dialog_proc(HWND hwnd,UINT message,WPARAM wparam,LPARAM lparam)
{
static GenNamesDialogClass * dialog = NULL;
if (message == WM_INITDIALOG) {
dialog = (GenNamesDialogClass *)lparam;
dialog->Hwnd = hwnd;
}
if (dialog) {
return dialog->Dialog_Proc(hwnd, message, wparam, lparam);
} else {
return FALSE;
}
}

View file

@ -0,0 +1,113 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Max2W3D *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/gennamesdialog.h $*
* *
* Original Author:: Greg Hjelstrom *
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 12/06/00 3:25p $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include <Max.h>
#include "w3d_file.h"
/**********************************************************************************************
**
** GenNamesDialogClass - Dialog box for the node naming parameters
**
**********************************************************************************************/
class GenNamesDialogClass
{
public:
GenNamesDialogClass(Interface * maxinterface);
~GenNamesDialogClass();
struct OptionsStruct
{
OptionsStruct(void) : OnlyAffectSelected(false), NameIndex(0), AssignCollisionBits(false)
{
memset(RootName,0,sizeof(RootName));
memset(PrefixName,0,sizeof(PrefixName));
memset(SuffixName,0,sizeof(SuffixName));
}
// overall options
bool AssignNames;
bool AssignPrefix;
bool AssignSuffix;
bool AssignCollisionBits;
bool OnlyAffectSelected;
// name options
char RootName[W3D_NAME_LEN];
char PrefixName[W3D_NAME_LEN];
char SuffixName[W3D_NAME_LEN];
int NameIndex;
// collision bit options
bool PhysicalCollision;
bool ProjectileCollision;
bool VisCollision;
bool CameraCollision;
bool VehicleCollision;
};
bool Get_Options(OptionsStruct * options);
bool Dialog_Proc(HWND hWnd,UINT message,WPARAM wParam,LPARAM);
bool Ok_To_Exit(void);
void Toggle_Collision_Bits_Assignment(void);
void Toggle_Name_Assignment(void);
private:
enum
{
MIN_NAME_INDEX = 0,
MAX_NAME_INDEX = 999,
INITIAL_NAME_INDEX = 0,
MAX_ROOT_NAME_LEN = 10,
MAX_PREFIX_LEN = 3,
MAX_SUFFIX_LEN = 3,
};
HWND Hwnd;
OptionsStruct * Options;
Interface * MaxInterface;
ISpinnerControl * NameIndexSpin;
friend BOOL CALLBACK _gen_names_dialog_proc(HWND Hwnd,UINT message,WPARAM wParam,LPARAM lParam);
};

View file

@ -0,0 +1,115 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Max2W3D *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/geometryexportcontext.h $*
* *
* Original Author:: Greg Hjelstrom *
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 10/19/00 11:32a $*
* *
* $Revision:: 1 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef GEOMETRYEXPORTCONTEXT_H
#define GEOMETRYEXPORTCONTEXT_H
#include <Max.h>
class ChunkSaveClass;
class MaxWorldInfoClass;
class HierarchySaveClass;
class INodeListClass;
class Progress_Meter_Class;
struct W3dExportOptionsStruct;
/**
** ExportContextClass
** This class encapsulates a bunch of datastructures needed during the geometry export
** process.
** NOTE: The user must plug in a valid ProgressMeter before each export operation.
*/
class GeometryExportContextClass
{
public:
GeometryExportContextClass( char * model_name,
ChunkSaveClass & csave,
MaxWorldInfoClass & world_info,
W3dExportOptionsStruct & options,
HierarchySaveClass * htree,
INode * origin,
INodeListClass * origin_list,
TimeValue curtime,
unsigned int *materialColors
) :
CSave(csave),
WorldInfo(world_info),
Options(options),
CurTime(curtime),
HTree(htree),
OriginList(origin_list),
Origin(origin),
OriginTransform(1),
ProgressMeter(NULL),
materialColors(materialColors),
numMaterialColors(0),
numHouseColors(0),
materialColorTexture(NULL)
{
ModelName = strdup(model_name);
OriginTransform = Origin->GetNodeTM(CurTime);
}
~GeometryExportContextClass(void)
{
delete[] ModelName;
}
char * ModelName;
ChunkSaveClass & CSave;
MaxWorldInfoClass & WorldInfo;
W3dExportOptionsStruct & Options;
TimeValue CurTime;
HierarchySaveClass * HTree;
INodeListClass * OriginList;
INode * Origin;
Matrix3 OriginTransform;
Progress_Meter_Class * ProgressMeter;
unsigned int * materialColors; ///MW: holds all used material colors.
int numMaterialColors; ///MW: number of used material colors.
int numHouseColors; ///MW: number of used house colors
char * materialColorTexture; //MW: texture to hold material colors
};
#endif //GEOMETRYEXPORTCONTEXT_H

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,155 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Max2W3d *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/geometryexporttask.h $*
* *
* Original Author:: Greg Hjelstrom *
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 10/27/00 5:00p $*
* *
* $Revision:: 6 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef GEOMETRYEXPORTTASK_H
#define GEOMETRYEXPORTTASK_H
#include <string.h>
#include <Max.h>
#include "w3d_file.h"
#include "vector.h"
class GeometryExportContextClass;
/**
** GeometryExportTaskClass
** This abstract base class defines the interface for a geometry export task.
** Derived classes will encapsulate the job of exporting meshes, collision
** boxes, dazzles, etc. The factory function Create_Task will create the
** appropriate task for a given INode.
*/
class GeometryExportTaskClass
{
public:
GeometryExportTaskClass(INode * node,GeometryExportContextClass & context);
GeometryExportTaskClass(const GeometryExportTaskClass & that);
virtual ~GeometryExportTaskClass(void);
virtual void Export_Geometry(GeometryExportContextClass & context) = 0;
/*
** Accessors
*/
char * Get_Name(void) { return Name; }
char * Get_Container_Name(void) { return ContainerName; }
void Get_Full_Name(char * buffer,int size);
int Get_Bone_Index(void) { return BoneIndex; }
INode * Get_Object_Node(void) { return Node; }
Matrix3 Get_Export_Transform(void) { return ExportSpace; }
void Set_Name(char * name) { strncpy(Name,name,sizeof(Name)); }
void Set_Container_Name(char * name) { strncpy(ContainerName,name,sizeof(ContainerName)); }
/*
** Unique Name generation. During optimization, new meshes may get created. When this happens,
** we have to create a unique name for each one. The name will be generated from the original
** mesh's name, the index passed in, and the LOD level of the original mesh.
*/
void Generate_Name(char * root,int index,GeometryExportContextClass & context);
/*
** Get vertex normal. This function should return the normal of a vertex at the
** specified x,y,z and smoothing_group if one exists. It is used in the algorithm which
** smooths the vertex normals on the boundaries of meshes.
*/
virtual Point3 Get_Shared_Vertex_Normal(const Point3 & world_space_point,int smgroup) { return Point3(0,0,0); }
/*
** Aggregate Model Detection. An "aggregate" is an external W3D model that we are requesting
** to be attached to a bone in the model being exported. In order for our LOD system to work
** properly, some special handling of aggregates is required (they must be added into the model
** as "additional models" rather than being placed in the normal LOD arrays). This virtual
** can be used to detect "aggregate" models.
*/
virtual bool Is_Aggregate(void) { return false; }
/*
** Proxy Detection. A "proxy" is a reference (by name) to an external game object that should
** be instantiated at the specified transform. Like the aggregates, these had to unfortunately
** be handled with special cases and therefore have this virtual function devoted solely to them.
*/
virtual bool Is_Proxy(void) { return false; }
/*
** Virtual Constructor
*/
static GeometryExportTaskClass * Create_Task(INode * node,GeometryExportContextClass & context);
/*
** Pre-Export Optimization of a set of geometry export tasks. This does things like
** separating multi-material meshes, combining small meshes which are nearby and use the
** same material, etc.
*/
static void Optimize_Geometry( DynamicVectorClass<GeometryExportTaskClass *> & tasks,
GeometryExportContextClass & context );
protected:
/*
** Internal RTTI
*/
enum
{
MESH = 0,
COLLISIONBOX,
DAZZLE,
NULLOBJ,
AGGREGATE,
PROXY,
};
virtual int Get_Geometry_Type(void) = 0;
protected:
char Name[W3D_NAME_LEN];
char ContainerName[W3D_NAME_LEN];
int BoneIndex;
Matrix3 ExportSpace;
TimeValue CurTime;
INode * Node;
};
#endif //GEOMETRYEXPORTTASK_H

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,282 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Max2W3d *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/gridsnapmodifier.cpp $*
* *
* Original Author:: Greg Hjelstrom *
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 5/01/01 8:29p $*
* *
* $Revision:: 1 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "Max.h"
#include "resource.h"
#include "simpmod.h"
#include "dllmain.h"
#include "iparamb2.h"
/*
WARNING WARNING WARNING PLEASE READ - This modifier was an experiment to see if we could
solve cracks in adjacent meshes by snapping to a world-space grid. It didn't work for a
few reasons:
- I couldn't implement the world space snapping; the SimpleMod code seems to always force
you to work relative to each object.
- Snapping to a grid won't always snap vertices to the same grid. The probability that
it will work is a function of the distance between the points and the grid spacing
*/
#define GRIDSNAPMOD_CLASSID Class_ID(0x7a2d399b, 0x1e3d2004)
/**
** GridSnapModifierClass
** This modifier will snap all vertices in the geometry being modified to a grid. Its motivation is to
** try to help solve the problem of cracks between adjacent meshes in Renegade levels. This will work
** a lot better if the objects have reset-transforms prior to being processed by this modifier.
*/
class GridSnapModifierClass : public SimpleMod2
{
public:
GridSnapModifierClass();
// From Animatable
void DeleteThis() { delete this; }
void GetClassName(TSTR& s) { s = Get_String(IDS_GRIDSNAPMODIFIER); }
virtual Class_ID ClassID() { return GRIDSNAPMOD_CLASSID; }
void BeginEditParams( IObjParam *ip, ULONG flags,Animatable *prev);
void EndEditParams( IObjParam *ip,ULONG flags,Animatable *next);
RefTargetHandle Clone(RemapDir& remap = NoRemap());
TCHAR *GetObjectName() { return Get_String(IDS_GRIDSNAPMODIFIER);}
IOResult Load(ILoad *iload);
// Direct paramblock access
int NumParamBlocks() { return 1; }
IParamBlock2* GetParamBlock(int i) { return pblock2; }
IParamBlock2* GetParamBlockByID(BlockID id) { return (pblock2->ID() == id) ? pblock2 : NULL; }
// From simple mod
Deformer& GetDeformer(TimeValue t,ModContext &mc,Matrix3& mat,Matrix3& invmat);
Interval GetValidity(TimeValue t);
//RefTargetHandle GetReference(int i)
//void SetReference(int i,RefTargetHandle rtar)
//Animatable * SubAnim(int i)
};
/**
** GridSnapDeformerClass
** This is the callback object used by GridSnapModifierClass to implement the actual geometry changes. This
** architecture is required by the SimpleMod base-class. This Deformer simply snaps vertex positions
** to the grid defined by its parameters.
*/
class GridSnapDeformerClass : public Deformer
{
public:
GridSnapDeformerClass(void) : GridDimension(0.001f) {}
void Set_Grid_Dimension(float grid_dim) { GridDimension = grid_dim; }
float Get_Grid_Dimension(void) { return GridDimension; }
void Set_Matrices(const Matrix3 & tm,const Matrix3 & invtm) { Transform = tm; InvTransform = invtm; }
virtual Point3 Map(int i,Point3 p)
{
p = p*Transform;
p.x = floor(p.x / GridDimension) * GridDimension;
p.y = floor(p.y / GridDimension) * GridDimension;
p.z = floor(p.z / GridDimension) * GridDimension;
p = p*InvTransform;
return p;
}
private:
float GridDimension;
Matrix3 Transform;
Matrix3 InvTransform;
};
/**
** GridSnapModifier Class Descriptor
** This object "links" the plugin into Max's plugin system. It links the Class-ID to a virtual construction
** method. The function Get_Grid_Snap_Modifier_Desc is the only hook to external code.
*/
class GridSnapModifierClassDesc:public ClassDesc2
{
public:
int IsPublic() { return 1; }
void * Create(BOOL loading = FALSE) { return new GridSnapModifierClass; }
const TCHAR * ClassName() { return _T("Grid Snap Modifier"); }
SClass_ID SuperClassID() { return OSM_CLASS_ID; }
Class_ID ClassID() { return GRIDSNAPMOD_CLASSID; }
const TCHAR* Category() { return _T("Westwood Modifiers");}
HINSTANCE HInstance() { return AppInstance; }
const TCHAR * InternalName() { return _T("Westwood GridSnap"); }
};
static GridSnapModifierClassDesc _GridSnapModifierDesc;
ClassDesc* Get_Grid_Snap_Modifier_Desc(void)
{
return &_GridSnapModifierDesc;
}
/*
** ParamBlock2 Setup
*/
enum
{
GSM_PARAMS = 0,
};
enum
{
GSM_PARAM_GRIDDIMENSION = 0,
};
static ParamBlockDesc2 _GridSnapParamBlockDesc
(
// parameter block settings
GSM_PARAMS,_T("GridSnap Parameters"), 0, &_GridSnapModifierDesc, P_AUTO_CONSTRUCT + P_AUTO_UI, SIMPMOD_PBLOCKREF,
// dialog box
IDD_GRIDSNAP_PARAMS, IDS_GRIDSNAP_TITLE, 0, 0, NULL,
// parameters
GSM_PARAM_GRIDDIMENSION, _T("Grid Dimension"), TYPE_FLOAT, P_RESET_DEFAULT, IDS_GRID_DIMENSION,
p_default, 0.001f,
p_range, 0.0001f, 10.0f,
p_ui, TYPE_SPINNER, EDITTYPE_FLOAT, IDC_GRIDDIM_EDIT, IDC_GRIDDIM_SPIN, 0.0001f,
end,
end
);
/********************************************************************************************
**
** GridSnapModifierClass Implementation
**
********************************************************************************************/
GridSnapModifierClass::GridSnapModifierClass()
{
// create the parameter block, storing in the base-class's pblock variable
_GridSnapModifierDesc.MakeAutoParamBlocks(this);
assert(pblock2);
}
void GridSnapModifierClass::BeginEditParams( IObjParam *ip, ULONG flags,Animatable *prev)
{
this->ip = ip;
SimpleMod2::BeginEditParams(ip,flags,prev);
_GridSnapModifierDesc.BeginEditParams(ip, this, flags, prev);
}
void GridSnapModifierClass::EndEditParams( IObjParam *ip,ULONG flags,Animatable *next)
{
SimpleMod2::EndEditParams(ip,flags,next);
_GridSnapModifierDesc.EndEditParams(ip, this, flags, next);
this->ip = NULL;
}
RefTargetHandle GridSnapModifierClass::Clone(RemapDir& remap)
{
GridSnapModifierClass * newmod = new GridSnapModifierClass();
newmod->ReplaceReference(SIMPMOD_PBLOCKREF,pblock2->Clone(remap));
newmod->SimpleModClone(this);
return(newmod);
}
IOResult GridSnapModifierClass::Load(ILoad *iload)
{
Modifier::Load(iload);
return IO_OK;
}
Deformer& GridSnapModifierClass::GetDeformer(TimeValue t,ModContext &mc,Matrix3& mat,Matrix3& invmat)
{
float dimension = 0.0f; Interval valid = FOREVER;
pblock2->GetValue(GSM_PARAM_GRIDDIMENSION, t, dimension, FOREVER);
static GridSnapDeformerClass deformer;
deformer.Set_Grid_Dimension(dimension);
deformer.Set_Matrices(mat,invmat);
return deformer;
}
Interval GridSnapModifierClass::GetValidity(TimeValue t)
{
float f;
Interval valid = FOREVER;
pblock2->GetValue(GSM_PARAM_GRIDDIMENSION, t, f, valid);
return valid;
}
RefTargetHandle SimpleMod2::GetReference(int i)
{
switch (i) {
case 0: return tmControl;
case 1: return posControl;
case 2: return pblock2;
default: return NULL;
}
}
void SimpleMod2::SetReference(int i,RefTargetHandle rtarg)
{
switch (i) {
case 0: tmControl = (Control*)rtarg; break;
case 1: posControl = (Control*)rtarg; break;
case 2: pblock2 = (IParamBlock2*)rtarg; break;
}
}
Animatable * SimpleMod2::SubAnim(int i)
{
switch (i) {
case 0: return posControl;
case 1: return tmControl;
case 2: return pblock2;
default: return NULL;
}
}

View file

@ -0,0 +1,47 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Max2W3d *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/gridsnapmodifier.h $*
* *
* Original Author:: Greg Hjelstrom *
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 5/01/01 5:56p $*
* *
* $Revision:: 1 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef GRIDSNAPMODIFIER_H
#define GRIDSNAPMODIFIER_H
class ClassDesc;
ClassDesc * Get_Grid_Snap_Modifier_Desc(void);
#endif //GRIDSNAPMODIFIER_H

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,170 @@
/*
** Command & Conquer Generals(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/>.
*/
/* $Header: /Commando/Code/Tools/max2w3d/hiersave.h 29 10/26/00 5:59p Greg_h $ */
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando / G 3D Engine *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/hiersave.h $*
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 10/26/00 5:09p $*
* *
* $Revision:: 29 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef HIERSAVE_H
#define HIERSAVE_H
#include "always.h"
#include <Max.h>
#include <stdio.h>
#ifndef W3D_FILE_H
#include "w3d_file.h"
#endif
#ifndef PROGRESS_H
#include "progress.h"
#endif
#ifndef CHUNKIO_H
#include "chunkio.h"
#endif
#ifndef NODELIST_H
#include "nodelist.h"
#endif
#ifndef VECTOR_H
#include "vector.h"
#endif
struct HierarchyNodeStruct
{
INode * MaxNode;
W3dPivotStruct Pivot;
W3dPivotFixupStruct Fixup;
bool operator == (const HierarchyNodeStruct & that) { return false; }
bool operator != (const HierarchyNodeStruct & that) { return !(*this == that); }
};
class HierarchySaveClass
{
public:
enum {
MATRIX_FIXUP_NONE = 0,
MATRIX_FIXUP_TRANS = 1,
MATRIX_FIXUP_TRANS_ROT = 2
};
HierarchySaveClass();
HierarchySaveClass(
INode * root,
TimeValue time,
Progress_Meter_Class & treemeter,
char * hname,
int fixup_type = MATRIX_FIXUP_NONE,
HierarchySaveClass * fixuptree = NULL);
HierarchySaveClass(
INodeListClass * rootlist,
TimeValue time,
Progress_Meter_Class & treemeter,
char * hname,
int fixup_type = MATRIX_FIXUP_NONE,
HierarchySaveClass * fixuptree = NULL,
const Matrix3 & origin_offset = Matrix3(1));
~HierarchySaveClass();
bool Save(ChunkSaveClass & csave);
bool Load(ChunkLoadClass & cload);
int Num_Nodes(void) const { return CurNode; }
const char * Get_Name(void) const;
const char * Get_Node_Name(int node) const;
// get ahold of the max inode
INode * Get_Node(int node) const;
// Returns the node's transform from object to world space
Matrix3 Get_Node_Transform(int node) const;
// Returns the node's transform relative to its parent
Matrix3 Get_Node_Relative_Transform(int node) const { return get_relative_transform(node); }
// Get the fixup matrix for the given pivot (always applied to the *relative* transform)
Matrix3 Get_Fixup_Transform(int node) const;
// Finds a node by name
int Find_Named_Node(const char * name) const;
// Get the coordinate system to use when exporting the given INode. Note that this
// function takes into account the multiple skeletons present when exporting LOD models.
void Get_Export_Coordinate_System(INode * node,int * set_bone_index,INode ** set_bone_node,Matrix3 * set_transform);
// Turning on terrian mode will cause all HTrees to force all normal meshes to be
// attached to the RootTransform regardless of the status of their 'Export_Transform' flag
static void Enable_Terrain_Optimization(bool onoff) { TerrainModeEnabled = onoff; }
private:
enum { MAX_PIVOTS = 4096, DEFAULT_NODE_ARRAY_SIZE = 512, NODE_ARRAY_GROWTH_SIZE = 32 };
TimeValue CurTime;
W3dHierarchyStruct HierarchyHeader;
DynamicVectorClass<HierarchyNodeStruct> Node;
int CurNode;
int FixupType;
Matrix3 OriginOffsetTransform; // this transform makes a node relative to the origin
HierarchySaveClass * FixupTree;
static bool TerrainModeEnabled;
void add_tree(INode * node,int pidx);
int add_node(INode * node,int pidx);
bool save_header(ChunkSaveClass & csave);
bool save_pivots(ChunkSaveClass & csave);
bool save_fixups(ChunkSaveClass & csave);
bool load_header(ChunkLoadClass & cload);
bool load_pivots(ChunkLoadClass & cload);
bool load_fixups(ChunkLoadClass & cload);
Matrix3 get_relative_transform(int nodeidx) const;
Matrix3 fixup_matrix(const Matrix3 & src) const;
void Free(void);
};
#endif /*HIERSAVE_H*/

View file

@ -0,0 +1,426 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Renegade / G *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/hlodsave.cpp $*
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 11/07/00 5:24p $*
* *
* $Revision:: 9 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* -- The constructor builds the whole HLOD tree in a *
* -- Destructor blows away the dynamic memory we used. *
* -- Method called when saving to a W3D file. Saves the chunks *
* -- Write the header *
* -- Writes each LOD *
* -- Writes the mesh to bone connectivity info for each mesh in an LOD. *
* HLodSaveClass::save_aggregate_array -- save the aggregates (if any) *
* HLodSaveClass::save_proxy_array -- save the array of proxies (if any) *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "hlodsave.h"
#include "meshcon.h"
#include "errclass.h"
#include "util.h"
#include "w3dappdata.h"
#include "wwmath.h" // NO_MAX_SCREEN_SIZE
#include "exportlog.h"
/* Behold, the applicable snippets of code from w3d_file.h that are applicable to this module!
W3D_CHUNK_HLOD =0x00000700, // description of an HLod object (see HLodClass)
W3D_CHUNK_HLOD_HEADER, // general information such as name and version
W3D_CHUNK_HLOD_LOD_ARRAY, // wrapper around the array of objects for each level of detail
W3D_CHUNK_HLOD_LOD_ARRAY_HEADER, // info on the objects in this level of detail array
W3D_CHUNK_HLOD_SUB_OBJECT, // an object in this level of detail array
struct W3dHLodHeaderStruct
{
uint32 Version;
uint32 LodCount;
char Name[W3D_NAME_LEN];
char HierarchyName[W3D_NAME_LEN]; // name of the hierarchy tree to use (\0 if none)
};
struct W3dHLodArrayHeaderStruct
{
uint32 ModelCount;
float32 MaxScreenSize; // if model is bigger than this, switch to higher lod.
};
struct W3dHLodSubObjectStruct
{
uint32 BoneIndex;
char Name[W3D_NAME_LEN*2];
};
*/
/***********************************************************************************************
* HLodSaveClass -- The constructor builds the whole HLOD tree in a form suitable for saving *
* to a W3D file. *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 9/14/1999 AJA : Created. *
*=============================================================================================*/
HLodSaveClass::HLodSaveClass (MeshConnectionsClass **connections, int lod_count, TimeValue CurTime,
char *name, const char *htree_name, Progress_Meter_Class &meter,
INodeListClass *origin_list)
: lod_array(NULL)
{
/*
** Fill in the W3dHLodHeaderStruct
*/
header.Version = W3D_CURRENT_HLOD_VERSION;
header.LodCount = lod_count;
Set_W3D_Name(header.Name, name);
Set_W3D_Name(header.HierarchyName, htree_name);
ExportLog::printf("\nExporting HLOD object: %s\n",header.Name);
ExportLog::printf(" lod count: %d\n",header.LodCount);
/*
** Create the array of stuff for each LOD.
*/
lod_array = new HLodArrayEntry[lod_count];
if (!lod_array)
throw ErrorClass("Out Of Memory!");
int i;
for (i = 0; i < lod_count; i++)
{
ExportLog::printf(" Exporting LOD Array %d\n",i);
INode *origin = connections[i]->Get_Origin();
int sub_obj_count = connections[i]->Get_Sub_Object_Count();
lod_array[i].Allocate_Sub_Objects(sub_obj_count);
lod_array[i].header.ModelCount = sub_obj_count;
float screen_size = NO_MAX_SCREEN_SIZE;
if (origin)
origin->GetUserPropFloat("MaxScreenSize", screen_size);
lod_array[i].header.MaxScreenSize = screen_size;
/*
** Create the info per mesh in this LOD.
*/
int j;
W3dHLodSubObjectStruct *sub_obj = lod_array[i].sub_obj;
ExportLog::printf(" sub-object count: %d\n",sub_obj_count);
for (j = 0; j < sub_obj_count; j++)
{
char *mesh_name;
int bone_index;
INode *mesh_node;
if (!connections[i]->Get_Sub_Object_Data(j, &mesh_name, &bone_index, &mesh_node))
throw ErrorClass("Model %s is missing connection data!", name);
strcpy(sub_obj[j].Name, mesh_name);
sub_obj[j].BoneIndex = bone_index;
ExportLog::printf(" Sub Object: %s Bone: %d\n",mesh_name,bone_index);
}
}
/*
** Copy aggregates from the Top-Level LOD
*/
int agg_count = connections[lod_count-1]->Get_Aggregate_Count();
aggregate_array.Allocate_Sub_Objects(agg_count);
aggregate_array.header.ModelCount = agg_count;
aggregate_array.header.MaxScreenSize = 0.0f;
ExportLog::printf(" Exporting Aggregates:\n");
ExportLog::printf(" aggregate count: %d\n",agg_count);
for (i=0; i<agg_count; i++) {
char *mesh_name;
int bone_index;
INode *mesh_node;
connections[lod_count-1]->Get_Aggregate_Data(i, &mesh_name, &bone_index, &mesh_node);
W3dHLodSubObjectStruct & sub_obj = aggregate_array.sub_obj[i];
strcpy(sub_obj.Name, mesh_name);
sub_obj.BoneIndex = bone_index;
ExportLog::printf(" Aggregate object: %s Bone: %d\n",mesh_name,bone_index);
}
/*
** Copy the proxy objects from the Top-Level LOD
*/
int proxy_count = connections[lod_count-1]->Get_Proxy_Count();
proxy_array.Allocate_Sub_Objects(proxy_count);
proxy_array.header.ModelCount = proxy_count;
proxy_array.header.MaxScreenSize = 0.0f;
ExportLog::printf(" Exporting Proxies\n");
ExportLog::printf(" proxy count: %d\n",proxy_count);
for (i=0; i<proxy_count; i++) {
char *mesh_name;
int bone_index;
INode *mesh_node;
connections[lod_count-1]->Get_Proxy_Data(i, &mesh_name, &bone_index, &mesh_node);
W3dHLodSubObjectStruct & sub_obj = proxy_array.sub_obj[i];
strcpy(sub_obj.Name, mesh_name);
sub_obj.BoneIndex = bone_index;
ExportLog::printf(" Proxy object: %s Bone: %d\n",mesh_name,bone_index);
}
}
/***********************************************************************************************
* ~HLodSaveClass -- Destructor blows away the dynamic memory we used. *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 9/14/1999 AJA : Created. *
*=============================================================================================*/
HLodSaveClass::~HLodSaveClass (void)
{
if (lod_array)
{
delete []lod_array;
lod_array = NULL;
}
}
/***********************************************************************************************
* HLodSaveClass::Save -- Method called when saving to a W3D file. Saves the chunks that *
* define a HLOD. *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 9/14/1999 AJA : Created. *
*=============================================================================================*/
bool HLodSaveClass::Save(ChunkSaveClass &csave)
{
if (!lod_array)
return false;
if (!csave.Begin_Chunk(W3D_CHUNK_HLOD))
return false;
if (!save_header(csave))
return false;
if (!save_lod_arrays(csave))
return false;
if (!save_aggregate_array(csave))
return false;
if (!save_proxy_array(csave))
return false;
if (!csave.End_Chunk())
return false;
return true;
}
/***********************************************************************************************
* HLodSaveClass::save_header -- Write the header *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 9/14/1999 AJA : Created. *
*=============================================================================================*/
bool HLodSaveClass::save_header (ChunkSaveClass &csave)
{
if (!csave.Begin_Chunk(W3D_CHUNK_HLOD_HEADER))
return false;
if (csave.Write(&header, sizeof(header)) != sizeof(header))
return false;
if (!csave.End_Chunk())
return false;
return true;
}
/***********************************************************************************************
* HLodSaveClass::save_lod_arrays -- Writes each LOD *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 9/14/1999 AJA : Created. *
*=============================================================================================*/
bool HLodSaveClass::save_lod_arrays(ChunkSaveClass &csave)
{
for (int i = 0; i < header.LodCount; i++)
{
if (!csave.Begin_Chunk(W3D_CHUNK_HLOD_LOD_ARRAY))
return false;
if (!save_sub_object_array(csave, lod_array[i]))
return false;
if (!csave.End_Chunk())
return false;
}
return true;
}
/***********************************************************************************************
* HLodSaveClass::save_aggregate_array -- save the aggregates (if any) *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 10/25/2000 gth : Created. *
*=============================================================================================*/
bool HLodSaveClass::save_aggregate_array(ChunkSaveClass & csave)
{
if (aggregate_array.num_sub_objects > 0) {
if (!csave.Begin_Chunk(W3D_CHUNK_HLOD_AGGREGATE_ARRAY))
return false;
if (!save_sub_object_array(csave, aggregate_array))
return false;
if (!csave.End_Chunk())
return false;
}
return true;
}
/***********************************************************************************************
* HLodSaveClass::save_proxy_array -- save the array of proxies (if any) *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 10/27/2000 gth : Created. *
*=============================================================================================*/
bool HLodSaveClass::save_proxy_array(ChunkSaveClass & csave)
{
if (proxy_array.num_sub_objects > 0) {
if (!csave.Begin_Chunk(W3D_CHUNK_HLOD_PROXY_ARRAY))
return false;
if (!save_sub_object_array(csave, proxy_array))
return false;
if (!csave.End_Chunk())
return false;
}
return true;
}
/***********************************************************************************************
* HLodSaveClass::save_sub_object_array -- Writes the mesh to bone connectivity info for each *
* mesh in an LOD. *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 9/14/1999 AJA : Created. *
*=============================================================================================*/
bool HLodSaveClass::save_sub_object_array(ChunkSaveClass &csave, const HLodArrayEntry & array)
{
if (!csave.Begin_Chunk(W3D_CHUNK_HLOD_SUB_OBJECT_ARRAY_HEADER))
return false;
if (csave.Write(&(array.header), sizeof(array.header)) != sizeof(array.header))
return false;
if (!csave.End_Chunk())
return false;
for (int j = 0; j < array.num_sub_objects; j++)
{
if (!csave.Begin_Chunk(W3D_CHUNK_HLOD_SUB_OBJECT))
return false;
if (csave.Write(&(array.sub_obj[j]), sizeof(array.sub_obj[j])) != sizeof(array.sub_obj[j]))
return false;
if (!csave.End_Chunk())
return false;
}
return true;
}

View file

@ -0,0 +1,129 @@
/*
** Command & Conquer Generals(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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Renegade / G *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/hlodsave.h $*
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 10/27/00 10:22a $*
* *
* $Revision:: 4 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef HLODSAVE_H
#define HLODSAVE_H
#include "always.h"
#include <Max.h>
#include <stdio.h>
#include "w3d_file.h"
#include "progress.h"
#include "chunkio.h"
#include "meshcon.h"
class INodeListClass;
class MeshConnectionsClass;
/**
** HLodSaveClass
** This object takes an array of mesh-connections objects and exports an LOD model
** constructed from them.
*/
class HLodSaveClass
{
public:
HLodSaveClass (MeshConnectionsClass **connections, int lod_count, TimeValue CurTime,
char *name, const char *htree_name, Progress_Meter_Class &meter,
INodeListClass *origin_list);
~HLodSaveClass (void);
bool Save (ChunkSaveClass &csave);
protected:
/*
** class HLodArrayEntry hold the HLOD tree that we will save out in the Save() method.
*/
class HLodArrayEntry
{
public:
W3dHLodArrayHeaderStruct header;
W3dHLodSubObjectStruct *sub_obj;
int num_sub_objects;
HLodArrayEntry (int num_sub_objs = 0)
{
sub_obj = NULL;
num_sub_objects = 0;
Allocate_Sub_Objects(num_sub_objs);
}
~HLodArrayEntry (void)
{
if (sub_obj)
{
delete sub_obj;
sub_obj = NULL;
num_sub_objects = 0;
}
}
bool Allocate_Sub_Objects (int num)
{
if (num <= 0) return false;
num_sub_objects = 0;
sub_obj = new W3dHLodSubObjectStruct[num];
if (!sub_obj) return false;
num_sub_objects = num;
return true;
}
bool operator == (const HLodArrayEntry & that) { return false; }
bool operator != (const HLodArrayEntry & that) { return !(*this == that); }
};
bool save_header (ChunkSaveClass &csave);
bool save_lod_arrays (ChunkSaveClass &csave);
bool save_aggregate_array (ChunkSaveClass & csave);
bool save_proxy_array(ChunkSaveClass & csave);
bool save_sub_object_array(ChunkSaveClass & csave, const HLodArrayEntry & array);
W3dHLodHeaderStruct header;
HLodArrayEntry * lod_array;
HLodArrayEntry aggregate_array;
HLodArrayEntry proxy_array;
};
#endif

Some files were not shown because too many files have changed in this diff Show more